Search code examples
python-3.xlatitude-longitudecoordinate-systemsmap-projections

Projecting a set of lat/lon points that spans on multiple UTM zones into a single grid


I'm working on a project where I need to transpose a lot of geographic locations (given by their latitude/longitude), all of them in a relatively small region (the size of a country like Nederlands for instance), into a grid in order to run some clustering algorithms and other stuff on them.

My current implementation uses the utm and geopy modules. It works like a charm for some instances (south korea is nicely centered on a single UTM zone), but does not as soon as the points span on several distinct UTM zones (which is the case of Nederlands).

I've been thinking of clumsy/inelegant methods to do so (like shifting all points' longitude of a couple of degrees to try and 'recenter' it, or trying to 'stick back' zones to each other), but then I've been searching a bit and I realized that there actually exists many coordinates system, and several python modules (pyproj, basemap, ...) that deal with them.
So I'd rather not reinvent the wheel, if you see what I mean, especially not reinvent a square one.

I do not need a great accuracy, a variation of 5% from the real distances is definitely acceptable for me. But what I need is to be able to transpose a region of earth (given bounds on latitude and longitude) into a single coherent grid.

I don't think performance would be an issue, since I have about 1 million points at most, and I'm not in a hurry (if it takes a couple of minutes to convert, so be it).

What would you advice me ?
I favor an out-of-the box solution rather than implementing myself a coords converter, and since the project is coded in Python3, sticking to the language would definitely be a plus.


Solution

  • Note that the solution Google Maps came up back in 2005, with, to solve these kind of constraints was creating what is called Web Mercator, currently known by the EPSG: 3857.

    I do not need a great accuracy, a variation of 5% from the real distances is definitely acceptable for me

    In this case you can definitely use Web Mercator.

    Possible implementation in Python:

    import math
    
    def merc_x(lon):
      r_major=6378137.000
      return r_major*math.radians(lon)
    
    def merc_y(lat):
      if lat>89.5:lat=89.5
      if lat<-89.5:lat=-89.5
      r_major=6378137.000
      r_minor=6356752.3142
      temp=r_minor/r_major
      eccent=math.sqrt(1-temp**2)
      phi=math.radians(lat)
      sinphi=math.sin(phi)
      con=eccent*sinphi
      com=eccent/2
      con=((1.0-con)/(1.0+con))**com
      ts=math.tan((math.pi/2-phi)/2)/con
      y=0-r_major*math.log(ts)
      return y 
    

    Note that Web Mercator implementation is much simpler than, for example, UTM, so the performance will be much better.