NADCON5-ng  0.0.2
NADCON5 Next Generation Documentation
getmapbounds.f
Go to the documentation of this file.
1 c> \ingroup core
2 c> \if MANPAGE
3 c> \page getmapbounds
4 c> \endif
5 c>
6 c> Subroutine to collect up the MAP boundaries
7 c> for use in creating NADCON 5
8 c>
9 c> This CAN BE different than the GRID boundaries
10 c> as such:
11 c>
12 c> GRID boundaries will be just four values (n/s/w/e) for any region
13 c>
14 c> MAP boundaries will allow multiple maps to be made and may or may
15 c> not align with the GRID boundaries. Used to allow for more
16 c> "close up" maps and such, without the need to screw up the
17 c> MAP boundaries.
18 c>
19 c> \param[in] mapflag Map Generation Flag
20 c> \param[in] maxplots
21 c> \param[in] region region to get map bounds
22 c> \param[out] nplots number of plots generated
23 c> \param[in] olddtm source datum
24 c> \param[in] newdtm target datum
25 c> \param[out] bw western bound of plot (Array of length `maxplots`)
26 c> \param[out] be eastern bound of plot (Array of length `maxplots`)
27 c> \param[out] bs southern bound of plot (Array of length `maxplots`)
28 c> \param[out] bn northern bound of plot (Array of length `maxplots`)
29 c> \param[out] jm (Array of length `maxplots`)
30 c> \param[out] b1 (Array of length `maxplots`)
31 c> \param[out] b2 (Array of length `maxplots`)
32 c> \param[out] fn (Array of length `maxplots`)
33 c> \param[out] lrv (Array of length `maxplots`)
34 c> \param[out] rv0x (Array of length `maxplots`)
35 c> \param[out] rv0y (Array of length `maxplots`)
36 c> \param[out] rl0y (Array of length `maxplots`)
37 c>
38 c> Version for NADCON 5
39 c> Built upon the original version used in GEOCON v2.0
40 c> Do not use with GEOCON v2.0
41 c>
42 c> Broken down into sub-subroutines to make it easier
43 c> to swap out when I make different choices.
44 c>
45 c>
46 c> ## Changelog
47 c>
48 c>
49 c> ### 2016 08 29:
50 c> Taking in olddtm and newdtm now, and adding
51 c> code to use that to filter out "Saint" regions in Alaska
52 c> when plotting transformations not supported in those regions.
53 c>
54 c> ### 2016 08 26:
55 c> Used actual mercator projection math to compute
56 c> the exact reference vector and label locations 1/2 inch and
57 c> 3/4 inch respectively below the S/W corner of the plot.
58 c>
59 c> ### 2016 07 21:
60 c> Two new columns added to "map.parameters", which
61 c> have the location of the reference vector. Return a logical "lrv"
62 c> as true if there is an optional special location for the reverence vector.
63 c> Return as false if not. If true, return lon/lat coords of ref vector
64 c> origin in rv0x/rv0y. If false, return zeros in those fields.
65 c>
66 c> Also, compute "jm" on the fly, ignoring what is in the table. All plots
67 c> will now be forced PORTRAIT and forced no wider than 6" and no taller
68 c> than 8", while maintaining proper X/Y ratios in a Mercator projection.
69 c> That means, make the biggest plot possible, with the right ratio, that
70 c> is neither wider than 6" nor taller than 8" and then, whatever the width
71 c> of that largest plot is -- return that width in the "jm" field.
72 c>
73 
74  subroutine getmapbounds(mapflag,maxplots,region,nplots,
75  *olddtm,newdtm,
76  *bw,be,bs,bn,jm,b1,b2,fn,lrv,rv0x,rv0y,rl0y)
77 
78 c - 2016 08 29: Taking in olddtm and newdtm now, and adding
79 c - code to use that to filter out "Saint" regions in Alaska
80 c - when plotting transformations not supported in those regions.
81 
82 c - 2016 08 26: Used actual mercator projection math to compute
83 c - the exact reference vector and label locations 1/2 inch and
84 c - 3/4 inch respectively below the S/W corner of the plot.
85 
86 c - Updated 2016 07 21: Two new columns added to "map.parameters", which
87 c - have the location of the reference vector. Return a logical "lrv"
88 c - as true if there is an optional special location for the reverence vector.
89 c - Return as false if not. If true, return lon/lat coords of ref vector
90 c - origin in rv0x/rv0y. If false, return zeros in those fields.
91 c -
92 c - Also, compute "jm" on the fly, ignoring what is in the table. All plots
93 c - will now be forced PORTRAIT and forced no wider than 6" and no taller
94 c - than 8", while maintaining proper X/Y ratios in a Mercator projection.
95 c - That means, make the biggest plot possible, with the right ratio, that
96 c - is neither wider than 6" nor taller than 8" and then, whatever the width
97 c - of that largest plot is -- return that width in the "jm" field.
98 
99 c
100 c - Subroutine to collect up the MAP boundaries
101 c - for use in creating NADCON 5
102 c
103 c - This CAN BE different than the GRID boundaries
104 c - as such:
105 c
106 c - GRID boundaries will be just four values (n/s/w/e) for any region
107 c
108 c - MAP boundaries will allow multiple maps to be made and may or may
109 c - not align with the GRID boundaries. Used to allow for more
110 c - "close up" maps and such, without the need to screw up the
111 c - MAP boundaries.
112 
113 c - Input:
114 c region, maxplots, mapflag
115 c olddtm, newdtm
116 c - Output:
117 c number of plots, their bounds, their GMT scales and
118 c label deltas
119 
120 c - Version for NADCON 5
121 c - Built upon the original version used in GEOCON v2.0
122 c - Do not use with GEOCON v2.0
123 
124 c - Broken down into sub-subroutines to make it easier
125 c - to swap out when I make different choices.
126 
127  character*10 region,olddtm,newdtm
128  real*8 bw(maxplots),be(maxplots),bs(maxplots),bn(maxplots)
129  real*4 jm(maxplots)
130  real*4 b1(maxplots),b2(maxplots)
131  character*10 fn(maxplots)
132  character*1 mapflag
133 
134 
135 c - 2016 07 21:
136  logical lrv(maxplots)
137  real*8 rv0x(maxplots),rv0y(maxplots),rl0y(maxplots)
138  character*3 c3x,c3y
139  character*2 c2x,c2y
140  real*8 pi,d2r
141 
142  character*200 card
143 
144 
145  pi = 2.d0*dasin(1.d0)
146  d2r = pi/180.d0
147 
148  ifile = 3
149 
150  open(ifile,
151  *file='Data/map.parameters',
152  *status='old',form='formatted')
153 
154 c - Get numerical version of mapflag
155  read(mapflag,*)iflag
156 
157 c - Get the header out of the way
158  read(ifile,'(a)')card
159  read(ifile,'(a)')card
160 
161 c - Loop over all map parameters, finding the ones relevant to
162 c - our region and mapflag.
163  i = 0
164  1 read(ifile,'(a)',end=2)card
165  if(card( 1:10).ne.region)goto 1
166  read(card(14:14),*)iflag0
167  if(iflag0.gt.iflag)goto 1
168 
169 c - 2016 08 29:
170 c - Specific to the case where we are looking at region=alaska,
171 c - and NOT region=<some saint island>, then for the specific
172 c - case of transforming from NAD 27 forward, let's skip
173 c - the <saint islands>
174  if(region.eq.'alaska' .and.
175  * iflag.eq.2 .and.
176  * iflag0.eq.2 .and.
177  * (card(16:25).eq.'stpaul' .or.
178  * card(16:25).eq.'stgeorge' .or.
179  * card(16:25).eq.'stlawrence' .or.
180  * card(16:25).eq.'stmatthew') .and.
181  * olddtm.eq.'nad27' )goto 1
182 
183  i = i + 1
184  fn(i) = trim(card( 16: 25))
185  read(card( 27: 30),*)iwd
186  read(card( 32: 33),*)iwm
187  read(card( 35: 38),*)ied
188  read(card( 40: 41),*)iem
189  read(card( 43: 45),*)isd
190  read(card( 47: 48),*)ism
191  read(card( 50: 52),*)ind
192  read(card( 54: 55),*)inm
193  read(card( 57: 60),*)xjm
194  read(card( 62: 64),*)ib1d
195  read(card( 66: 67),*)ib1m
196  read(card( 69: 71),*)ib2d
197  read(card( 73: 74),*)ib2m
198 c - 2016 07 21:
199  read(card( 76: 78),'(a3)')c3x
200  read(card( 80: 81),'(a2)')c2x
201  read(card( 83: 85),'(a3)')c3y
202  read(card( 87: 88),'(a2)')c2y
203 
204  bw(i) = dble(iwd) + dble(iwm)/60.d0
205  be(i) = dble(ied) + dble(iem)/60.d0
206  if(ind.lt.0)inm = -inm
207  if(isd.lt.0)ism = -ism
208  bn(i) = dble(ind) + dble(inm)/60.d0
209  bs(i) = dble(isd) + dble(ism)/60.d0
210  jm(i) = xjm
211  b1(i) = dble(ib1d) + dble(ib1m)/60.d0
212  b2(i) = dble(ib2d) + dble(ib2m)/60.d0
213 
214 c - 2016 07 21 (Optional reference vector locations):
215  if(c3x.eq.'---')then
216  lrv(i) = .false.
217  rv0x(i) = 0
218  rv0y(i) = 0
219  else
220  lrv(i) = .true.
221  read(c3x,*)rv0xd
222  read(c2x,*)rv0xm
223  read(c3y,*)rv0yd
224  read(c2y,*)rv0ym
225  rv0x(i) = dble(rv0xd) + dble(rv0xm)/60.d0
226  rv0y(i) = dble(rv0yd) + dble(rv0ym)/60.d0
227  endif
228 
229 c - 2016 07 21 (Forcing the map to keep its proper Mercator-projected X/Y ratio,
230 c - while filling the maximum space that does not exceed 6" wide nor 8" high)
231  dx = (be(i) - bw(i)) * d2r
232 
233  q1 = dtan(bn(i)*d2r)
234  q2 = 1.d0 / dcos(bn(i)*d2r) ! Secant
235  yn = log(q1 + q2)
236 
237  q1 = dtan(bs(i)*d2r)
238  q2 = 1.d0 / dcos(bs(i)*d2r) ! Secant
239  ys = log(q1 + q2)
240 
241  dy = yn - ys
242 
243  ratio = dx/dy
244 
245 c - Max height and width
246 c xmxht = 8
247  xmxht = 6
248  xmxwd = 6
249 
250  if(xmxht*ratio .gt. xmxwd)then
251  jm(i) = xmxwd
252 c - And height = xmxwd / ratio...
253  else
254  jm(i) = xmxht*ratio
255 c - And height = xmxht
256  endif
257 
258 c - 2016 08 26
259 c See DRU-12, p. 56-57
260 c - dy/dphi is linear for latitudes south of 65. All of our plots
261 c - have at most a 65 degree south border. So I can use that for
262 c - a pretty good approximation to compute the latitude of the
263 c - reference vector, in degrees, to send back as "rv0y".
264 
265 c First, get the ratio of dx/dy in the lower left part of the
266 c - plot. Use 1% of the E/W span and apply that both ways.
267  ddum = 0.01d0*(be(i) - bw(i))
268  ydum = bs(i) + ddum
269  xdum = bw(i) + ddum
270 
271  xw = bw(i) * d2r
272  xe = xdum * d2r
273 
274  dx = (xe - xw)
275 
276  q1 = dtan(ydum*d2r)
277  q2 = 1.d0 / dcos(ydum*d2r) ! Secant
278  yn = log(q1 + q2)
279 
280  q1 = dtan(bs(i)*d2r)
281  q2 = 1.d0 / dcos(bs(i)*d2r) ! Secant
282  ys = log(q1 + q2)
283 
284 c - dy is in radians
285  dy = yn - ys
286 
287 c - Now I have a new "dx" and "dy" representing the lower left 1% of the plot,
288 c - in radians/radians. Compute the new ratio for this part.
289  ratio = dx/dy
290 
291 c - Since radians to inches does NOT change in the E/W direction, and since
292 c - I know exactly how wide the plot is, I can compute a radians/inch conversion
293 c - in E/W, for 1% of the width of the plot.
294  r2iew = (0.01d0 * jm(i)) / dx
295 
296 c - The ratio of dx/dy, is going to be identical to the ratio of r2iew/r2ins:
297  r2ins = r2iew / ratio
298 
299 c - Convert r2ins into degrees-to-inches
300  d2ins = r2ins * d2r
301 
302 c - Now, the south edge is known in degrees. I want the reference vector
303 c - to be 1/2 inch below that. I want the reference vector label to
304 c - be an additional 1/4 inches down.
305  rv0y(i) = bs(i) - (0.50d0)/d2ins
306  rl0y(i) = bs(i) - (0.65d0)/d2ins
307 
308 c - And set the reference vector's left edge to equal the left edge of the plot
309  rv0x(i) = bw(i)
310 
311 c - Flags for debugging
312  write(6,8) trim(fn(i))
313  8 format('***************************',/,
314  * 'Reference Vector Computations for',
315  * 'Sub-Region: ',a)
316 
317  write(6,*) ' yn,ys,dy = ',yn,ys,dy
318  write(6,*) ' xe,xw,dx = ',xe,xw,dx
319  write(6,*) ' E/W width (jm) = ',jm(i)
320  write(6,*) ' SW ratio = ',ratio
321  write(6,*) ' SW bounds,Lat = ',ydum,bs(i)
322  write(6,*) ' SW bounds,Lon = ',xdum,bw(i)
323  write(6,*) ' r2i E/W = ',r2iew
324  write(6,*) ' r2i N/S = ',r2ins
325  write(6,*) ' d2i N/S = ',d2ins
326  write(6,*) ' Southwest corner = ',bs(i),bw(i)
327  write(6,*) ' Ref Vector = ',rv0y(i),rv0x(i)
328  write(6,*) ' Ref Label = ',rl0y(i),rv0x(i)
329 
330  goto 1
331 
332  2 nplots = i
333 
334  close(ifile)
335 
336  if(nplots.eq.0)then
337  write(6,100)trim(region)
338  stop 10001
339  endif
340  100 format(6x,'FATAL Subroutine getmapbounds: Unknown region: ',a)
341  return
342  end
subroutine getmapbounds(mapflag, maxplots, region, nplots, olddtm, newdtm, bw, be, bs, bn, jm, b1, b2, fn, lrv, rv0x, rv0y, rl0y)
Subroutine to collect up the MAP boundaries for use in creating NADCON 5.
Definition: getmapbounds.f:77