Skip to content

Instantly share code, notes, and snippets.

@mapbutcher
Last active December 17, 2015 14:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mapbutcher/5623849 to your computer and use it in GitHub Desktop.
Save mapbutcher/5623849 to your computer and use it in GitHub Desktop.
Python class which uses mapnik to create a static map based upon a coordinate.
import mapnik
from shapely.geometry import *
class StaticMap:
srs = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs'
wgs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
stylesheet = 'REA_Bright_Local.xml'
markername = 'rea.png'
exportpath = 'output/'
imagetype = 'png'
longlat = mapnik.Projection(wgs)
merc = mapnik.Projection(srs)
m = mapnik.Map(500, 500,srs)
def __init__(self, stylesheet):
self.stylesheet = stylesheet
#initialise the map
mapnik.load_map(self.m, stylesheet)
#set up the icon
self.createMarkerStyle()
def transformToWebMercator(self, x, y):
coord = mapnik.Coord(y,x)
transform = mapnik.ProjTransform(self.longlat,self.merc)
return transform.forward(coord)
def createMarkerStyle(self):
s = mapnik.Style()
r = mapnik.Rule()
sym = mapnik.PointSymbolizer(mapnik.PathExpression(self.markername))
r.symbols.append(sym)
s.rules.append(r)
self.m.append_style('point_style',s)
def createMap(self, id, x, y):
#tranform the input wgs84 coord to web mercator and create WKT
transformedCoord = self.transformToWebMercator(float(x),float(y))
wkt = "POINT("+str(transformedCoord.x)+" "+str(transformedCoord.y)+")"
#buffer the point to give us an envelope to zoomm to.
shapelyPntBuffer = Point(transformedCoord.x, transformedCoord.y).buffer(600.0)
e = mapnik.Box2d(float(shapelyPntBuffer.bounds[0]),float(shapelyPntBuffer.bounds[1]),float(shapelyPntBuffer.bounds[2]),float(shapelyPntBuffer.bounds[3]))
#add feature to memory data source
ds = mapnik.MemoryDatasource()
f = mapnik.Feature(mapnik.Context(), int(id))
f.add_geometries_from_wkt(wkt)
ds.add_feature(f)
#create a mapnik lyr and set it's datasource to be our memory datasource.
icons = mapnik.Layer('icons',self.srs)
icons.datasource = ds
icons.styles.append('point_style')
self.m.layers.append(icons)
#reset the map extent and export
self.m.zoom_to_box(e)
mapname = self.exportpath+str(id)+"."+self.imagetype
mapnik.render_to_file(self.m,mapname, self.imagetype)
#dump the icons layer
self.m.layers.__delitem__(29)
return str(id)+"."+self.imagetype
@rcoup
Copy link

rcoup commented May 23, 2013

Any reason why m = mapnik.Map(500, 500,srs) is in the class declaration rather than the initialiser? I can see you adding tonnes of layers to the same map by calling StaticMap() a few times.

What's the output you're seeing?

@mapbutcher
Copy link
Author

I create a single instance of the StaticMap class - but yes m = mapnik.Map(500, 500,srs) should be in the init. What I'm seeing is that the icons layer gets added\removed each time I call createMap on the the StaticMap instance - which is what I want, but on some calls the layer does not render, on others it does.

@rcoup
Copy link

rcoup commented May 23, 2013

Can you give me a list of example datapoints? Nothing near the anti-meridian?

I presume you're using mapnik 2.1? Linux?

@mapbutcher
Copy link
Author

-31.896665 152.497463
-37.564001 143.834026
-37.856527 145.236776
-29.3149959 151.6941479
-33.744679 150.910469
-37.812278 144.886932
-37.848785 144.66121
-38.3827659 142.4844995
-33.968852 151.104412
-35.357152 145.730707
-27.5510948 153.036698

  • mapnik version: 2.1.0
  • seen the issue on OS X 10.7.5
  • seen the issue on Ubuntu 12.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment