Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generating raster maps in Python for use in Leaflet
// This covers the full web-mercator range
imageBounds = [[-85.051129, -180], [85.051129, 180]]
L.imageOverlay('/test.png', imageBounds).addTo(map)
from flask import Flask
from flask import send_file
from StringIO import StringIO
import numpy as np
from PIL import Image
import pyproj
from pyproj import Proj
from math import radians, cos, sin, asin, sqrt, acos, degrees
def serve_pil_image(pil_img):
img_io = StringIO()
pil_img.save(img_io, 'PNG', quality=70)
img_io.seek(0)
return send_file(img_io, mimetype='image/png')
def haversine(lonLat1, lonLat2):
lon1, lat1 = map(radians, lonLat1)
lon2, lat2 = map(radians, lonLat2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
earth_radius_miles = 3964
return c * earth_radius_miles
def sp_law_of_cosines(lonLat1, lonLat2):
lon1, lat1 = lonLat1
lon2, lat2 = lonLat2
try:
delta = lon2 - lon1
a = radians(lat1)
b = radians(lat2)
C = radians(delta)
x = sin(a) * sin(b) + cos(a) * cos(b) * cos(C)
distance = acos(x) # in radians
distance = degrees(distance) # in degrees
distance = distance * 60 # 60 nautical miles / lat degree
return distance;
except:
return 0
def create_heatmap():
p1 = Proj(proj='latlong',datum='WGS84')
p2 = Proj(init='epsg:3857')
# WebMercator cuts off at 85.051129 lat and 180 long.
# The magic number was determined experimentally by
# finding the constant that makes the lat long cutoffs
# correspond to the image size cutoffs.
MAGIC_NUMBER = 40000000
height=256
width=256
data = np.zeros((height, width, 4), dtype=np.uint8)
for x in range(width):
for y in range(height):
pixel_in_webmerc = (
(-x + float(width)/2) * MAGIC_NUMBER / width,
(-y + float(height)/2) * MAGIC_NUMBER / height)
projected_point = pyproj.transform(p2, p1,
pixel_in_webmerc[0],
pixel_in_webmerc[1])
distance = sp_law_of_cosines((122.3, 47.6), projected_point)
data[y, x] += map(np.uint8, [0,255,0, 255 / (distance/100 + 1)])
i = Image.fromarray(data, 'RGBA')
return i
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/test.png')
def test():
return serve_pil_image(create_heatmap())
if __name__ == '__main__':
app.run(host='0.0.0.0')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment