Skip to content

Instantly share code, notes, and snippets.

@cpatdowling
Created April 5, 2017 20:16
Show Gist options
  • Save cpatdowling/84b9e2bd1c31d5abb446b2a407b87bab to your computer and use it in GitHub Desktop.
Save cpatdowling/84b9e2bd1c31d5abb446b2a407b87bab to your computer and use it in GitHub Desktop.
A native python 2.7+ class that projects WSG84 latitude/longitude coordinates to pixel positions in a Web Mercator map image with known coordination.
#Example usage
"""
upleft = [47.6197793,-122.3592749] Upper left coordinate of map image
bttmright = [47.607274, -122.334786] Lower right coordinate of map image
imgsize = [1135,864] Pixel size of map image
mp = MapOverlay(upleft, bttmright, imgsize)
#then given a list of latitude/longitude pairs , we can get their relative positions on the image of the map, note
#that image pixel positions start with (0,0) at the top left of the image, so plotting will require inverting the y-axis
#the image of the map can be uploaded to the background of a matplotlib figure with matplotlib.pyplot.imread("yourimage.png")
pixpos = np.asarray([ mp.to_image_pixel_position(list(meanLatLongs[i,:])) for i in range(len(meanLatLongs)) ])
"""
import math
class MapOverlay:
def __init__(self, topleft_latlong, bottomright_latlong, pixels, resolution=1024.0):
#resolution is the projected resolution of the latitude and longitude coordinates
#to integer pixel values--a higher projected resolution results in coordinate resolution
#per pixel
#topleft_latlong and bottomright_latlong coorespond to the upper right and bottom left
#latitude and longitude coordinates visible in your Mercator projected map image
self.res = resolution
self.topleft = self.to_web_mercator(topleft_latlong)
self.bottomright = self.to_web_mercator(bottomright_latlong)
#the following returns the vertical and horizontal scaling factor of the projected coordinates to
#the pixel size of the map image
#ex: pixels = [256,256]
self.horzscale = pixels[0]/(abs(self.bottomright[1] - self.topleft[1]))
self.vertscale = pixels[1]/(abs(self.topleft[0] - self.bottomright[0]))
def to_web_mercator(self, coord, zoomlvl=1):
#raw latitude longitude pair to web mercator pixel position
#https://en.wikipedia.org/wiki/Web_Mercator
#1024x1024 base pixel image
#x = longitude
#y = latitude, all converted coordinate pairs are read as [latitude, longitude]
lat = coord[0]
lon = coord[1]
#latitude conversion
lat_rad = lat * math.pi/180.0
yit = math.pi - math.log(math.tan( (0.25*math.pi) + (0.5*lat_rad) ))
y = (self.res)/math.pi * math.pow(2,zoomlvl) * yit
#longitude conversion
lon_rad = lon * math.pi/180.0
x = (self.res)/math.pi * math.pow(2,zoomlvl) * (lon_rad + math.pi)
return([y,x])
def to_image_pixel_position(self, coord):
#raw latitude longitude pair to image pixel position
#lat --> vertical scale
#long --> horizontal scale
webmcoord = self.to_web_mercator(coord)
horz = abs(webmcoord[0] - self.topleft[0])*self.horzscale
vert = abs(webmcoord[1] - self.topleft[1])*self.vertscale
position = [int(round(vert)), int(round(horz))]
return(position)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment