PaulJohnson / geodetics

Haskell library of data types and calculations for positions on planet Earth
Other
18 stars 10 forks source link

Anyone like to define all the UTM grid zones #14

Open sebeaumont opened 5 years ago

sebeaumont commented 5 years ago

I guess a helper function to select appropriate zone from WSG84 ground position and do the translation would be nice too. If this is generally useful then I guess I just volunteered... I'm only working with UTM zones relevant to UK at moment for nautical purposes but should be reasonable to extend this across all zones.

PaulJohnson commented 5 years ago

Thanks for looking into this. If you'd like to volunteer then that would be great, and I'd certainly accept the pull request. I'd suggest defining a type UTMZone and then define instance GridClass UTMZone WGS84. Internally the UTMZone will have a value of GridTM which it uses to do the actual arithmetic, with unsafeGridCoerce used to switch between the UTMZone and the internal GridTM frames of reference. Make UTMZone an instance of Eq as well.

As you say, a function of type Geodetic WGS84 -> Maybe UTMZone would be good, as would a couple of functions of type String -> Maybe UTMZone, one for the A-Z latitude bands and one for the N/S notation. Finally, functions to and from the text representation of a UTM position (like for the UK national grid) would be the finishing touch.

I did look at this a while ago. The hairiest part was coding up the UTM grid with all the special cases.

sebeaumont commented 5 years ago

I've not forgotten this -- just been busy making the application -- I've enough experience of the UTM Zones to make a job of this now -- In fact I've been prototyping based on my charting requirements. As an aside and something that I need to solve for my application, I have been trying to interpolate a UTM graticule (it's a great test case for above work) and to do this I have been using the nFromTo function from Dimensional to interpolate 60 minutes in each degree (I want a minute resolution graticule) but find by the time this is mapped back to Geodetic WGS84 positions it is quite inaccurate (direct plotting of the exact lat, long positions seems accurate enough however). I wonder is there an easy way of defining such a graticule which can then be mapped (transformed) by the relevant UTMZone grid for plotting?

PaulJohnson commented 5 years ago

I'm not entirely sure what you mean by "interpolate a UTM graticule". Let me see if I understand. On your UTM map you want to draw a graticule for lat and long with subdivisions along the lines to show the degrees and minutes of latitude and longitude. You have been drawing lines between whole degrees, but this is not accurate enough because the latitude lines map to curves on the UTM grid. Hence you want to map the lines more accurately to produce accurate curves. Have I got that right?

For the lines you might look at the Geodetics.Path module. A Path is effectively a parametric function of distance to geodetic point (note that the distance may not be precise). There are paths predefined for latitude and longitude. Hence you could generate a list of points along a line of latitude every 10km, or whatever distance seems best (probably a function of the latitude). You can then map this to points on your UTM projection using toGrid, and hence obtain a series of points to connect up using a polyline.

If you want to draw tick marks along these lines then I suggest you generate their WGS84 positions separately, map them to the grid using toGrid, and then draw them at the specified positions. To get these tick marks at the right angles I would suggest that for each one you generate the Path that it is to follow (i.e. a latitude Path for a tick on a longitude line and vice versa) and then get end points for a tick that is e.g. 1km long.

sebeaumont commented 5 years ago

I was interpolating to 1NM (1 arc minute) but the interpolation of 60 minutes per degree does not seem accurate -- I think the Geodetics.Path module might be of use here but I need to work in nautical miles or (preferably arc minutes). I think my next step will be to define the range of latitude and longitude for each UTM Zone as this is necessary. I can then see how I go with the graticule. I'll be back on to mapping next week. I've just reviewed the Path module and it seems exactly what I need.