def rpc_renderArea(self, minlat, minlon, maxlat, maxlon): """ Renders a map for the given coordin """ Map = None LandmassShapefile = 'cape/Interface/ne_110m_admin_0_countries.shp' merc = mapnik.Projection( '+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 ' '+no_defs +over') # long/lat in degrees, aka ESPG:4326 and "WGS 84" longlat = mapnik.Projection( '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') # can also be constructed as: #longlat = mapnik.Projection('+init=epsg:4326') im = mapnik.Image(self.mapsize) m = self.rendermap m.srs = merc.params() bbox = mapnik.Box2d(minlat, minlon, maxlat, maxlon) transform = mapnik.ProjTransform(longlat, merc) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) mapnik.render(m, im) Map = im.tostring('png') return (True, Map)
def render_location(self): # spherical mercator (most common target map projection of osm data imported with osm2pgsql) merc = mapnik.Projection('+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 +no_defs +over') longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') mapfile = "renderer/map_data/styles/bs_complete.xml" bounds = (self.lon-self.size, self.lat-self.size, self.lon+self.size,self.lat+self.size) z = 1 imgx = 224 * z imgy = 224 * z m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) m.srs = merc.params() if hasattr(mapnik,'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) transform = mapnik.ProjTransform(longlat,merc) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) #render the map to an image im = mapnik.Image(imgx,imgy) mapnik.render(m, im) img = im.tostring('png256') img = cv2.imdecode(np.fromstring(img, dtype=np.uint8), 1) img =np.asarray(img) window_name = "Location" cv2.imshow(window_name, img) cv2.waitKey(0)
def rendertiles(self, bounds, data, item, label, lat, layer, lon, num_items, projec): z = 1 imgx = 128 * z imgy = 128 * z mapfile = "/map_data/styles/bs_" + layer + ".xml" m = mapnik.Map(imgx, imgy) mapnik.load_map(m, mapfile) # ensure the target map projection is mercator m.srs = projec.params() if hasattr(mapnik, 'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) transform = mapnik.ProjTransform(longlat, projec) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) # render the map to an image im = mapnik.Image(imgx, imgy) mapnik.render(m, im) img = im.tostring('png256') data[(item, layer)] = img
def render_location_with_variants(self, variants): # target projection #merc = mapnik.Projection('+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 +no_defs +over') data = [] for item in range(0,variants): if item == 0: teta = 0 zoom = 20 shift_lat = 0 shift_lon = 0 else: shift_lat = 0.1*self.size*(random.random()-random.random()) shift_lon = 0.1*self.size*(random.random()-random.random()) teta = 45 * (random.random()-random.random()) zoom = random.randint(17,21) layer = "complete" projec = mapnik.Projection('+proj=aeqd +ellps=WGS84 +lat_0=90 +lon_0='+str(teta)) # WGS lat/long source projection of centre longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') # make a new Map object for the given mapfile m = mapnik.Map(self.width, self.height) mapfile = "renderer/map_data/styles/bs_" + layer + ".xml" mapnik.load_map(m, mapfile) # ensure the target map projection is mercator m.srs = projec.params() # transform the centre point into the target coord sys centre = mapnik.Coord(self.lon+shift_lon, self.lat+shift_lat) transform = mapnik.ProjTransform(longlat, projec) merc_centre = transform.forward(centre) # 360/(2**zoom) degrees = 256 px # so in merc 1px = (20037508.34*2) / (256 * 2**zoom) # hence to find the bounds of our rectangle in projected coordinates + and - half the image width worth of projected coord units dx = ((20037508.34*2*(self.width/2)))/(256*(2 ** (zoom))) minx = merc_centre.x - dx maxx = merc_centre.x + dx # grow the height bbox, as we only accurately set the width bbox m.aspect_fix_mode = mapnik.aspect_fix_mode.ADJUST_BBOX_HEIGHT bounds = mapnik.Box2d(minx, merc_centre.y-10, maxx, merc_centre.y+10) # the y bounds will be fixed by mapnik due to ADJUST_BBOX_HEIGHT m.zoom_to_box(bounds) # render the map image to a file # mapnik.render_to_file(m, output) #render the map to an image im = mapnik.Image(self.width,self.height) mapnik.render(m, im) img = im.tostring('png256') img = cv2.imdecode(np.fromstring(img, dtype=np.uint8), 1) img =np.asarray(img) data.append(img) data = np.stack(data) return data
def __init__(self, areas): self.areas = areas self.tiles = None self.style = None # Set up projections # long/lat in degrees, aka ESPG:4326 and "WGS 84" # we get data in this projection longlat = mapnik2.Projection( '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') # Map uses spherical mercator (most common target map projection of osm data imported with osm2pgsql) self.merc = mapnik2.Projection( '+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 +no_defs +over' ) # transform objects (Box2d and Coord) to another projection self.lnglat_to_merc_transform = mapnik2.ProjTransform( longlat, self.merc) self.merc_to_lnglat_transform = mapnik2.ProjTransform( self.merc, longlat)
def rpc_renderCoordOld(self, lat, lon, zoom): """ Renders a map for the given coordinates. """ Map = None LandmassShapefile = 'cape/Interface/ne_110m_admin_0_countries.shp' im = mapnik.Image(self.mapsize[0], self.mapsize[1]) m = mapnik.Map(self.mapsize[0], self.mapsize[1]) m.background = mapnik.Color(self.backgroundColor) s = mapnik.Style() r = mapnik.Rule() polygon_symbolizer = mapnik.PolygonSymbolizer( mapnik.Color(self.foregroundColor)) r.symbols.append(polygon_symbolizer) line_symbolizer = mapnik.LineSymbolizer( mapnik.Color('rgb(50%,50%,50%)'), 0.1) r.symbols.append(line_symbolizer) s.rules.append(r) m.append_style('My Style', s) ds = mapnik.Shapefile(file=LandmassShapefile) layer = mapnik.Layer('world') layer.datasource = ds layer.styles.append('My Style') m.layers.append(layer) center = mapnik.Coord(lat, lon) transform = mapnik.ProjTransform(self.longlat, self.merc) merc_center = transform.forward(center) dx = (20037508.34 * 2 * (self.mapsize[0] / 2)) / (256 * (2**(zoom))) minx = merc_center.x - dx maxx = merc_center.x + dx m.aspect_fix_mode = mapnik.aspect_fix_mode.ADJUST_BBOX_HEIGHT merc_bbox = mapnik.Box2d(minx, merc_center.y - 1, maxx, merc_center.y + 1) m.zoom_to_box(merc_bbox) mapnik.render(m, im) Map = im.tostring('png') return (True, Map)
def rendertiles(self, cpoint, data, item, label, lat, layer, lon, num_items, projec, zoom): # target projection #merc = mapnik.Projection('+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 +no_defs +over') merc = projec # WGS lat/long source projection of centre longlat = mapnik.Projection( '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') # make a new Map object for the given mapfile m = mapnik.Map(self.width, self.height) mapfile = "/map_data/styles/bs_" + layer + ".xml" mapnik.load_map(m, mapfile) # ensure the target map projection is mercator m.srs = merc.params() # transform the centre point into the target coord sys centre = mapnik.Coord(cpoint[0], cpoint[1]) transform = mapnik.ProjTransform(longlat, merc) merc_centre = transform.forward(centre) # 360/(2**zoom) degrees = 256 px # so in merc 1px = (20037508.34*2) / (256 * 2**zoom) # hence to find the bounds of our rectangle in projected coordinates + and - half the image width worth of projected coord units dx = ((20037508.34 * 2 * (self.width / 2))) / (256 * (2**(zoom))) minx = merc_centre.x - dx maxx = merc_centre.x + dx # grow the height bbox, as we only accurately set the width bbox m.aspect_fix_mode = mapnik.aspect_fix_mode.ADJUST_BBOX_HEIGHT bounds = mapnik.Box2d( minx, merc_centre.y - 10, maxx, merc_centre.y + 10 ) # the y bounds will be fixed by mapnik due to ADJUST_BBOX_HEIGHT m.zoom_to_box(bounds) # render the map image to a file # mapnik.render_to_file(m, output) #render the map to an image im = mapnik.Image(self.width, self.height) mapnik.render(m, im) img = im.tostring('png256') data[(item, layer)] = img
def render_location_with_zoom(self, zoom): # target projection merc = mapnik.Projection('+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 +no_defs +over') # WGS lat/long source projection of centrel longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') # make a new Map object for the given mapfile m = mapnik.Map(self.width, self.height) mapnik.load_map(m, self.mapfile) # ensure the target map projection is mercator m.srs = merc.params() # transform the centre point into the target coord sys centre = mapnik.Coord(self.lon, self.lat) transform = mapnik.ProjTransform(longlat, merc) merc_centre = transform.forward(centre) # 360/(2**zoom) degrees = 256 px # so in merc 1px = (20037508.34*2) / (256 * 2**zoom) # hence to find the bounds of our rectangle in projected coordinates + and - half the image width worth of projected coord units dx = ((20037508.34*2*(self.width/2)))/(256*(2 ** (zoom))) minx = merc_centre.x - dx maxx = merc_centre.x + dx # grow the height bbox, as we only accurately set the width bbox m.aspect_fix_mode = mapnik.aspect_fix_mode.ADJUST_BBOX_HEIGHT bounds = mapnik.Box2d(minx, merc_centre.y-10, maxx, merc_centre.y+10) # the y bounds will be fixed by mapnik due to ADJUST_BBOX_HEIGHT m.zoom_to_box(bounds) # render the map image to a file # mapnik.render_to_file(m, output) #render the map to an image im = mapnik.Image(self.width,self.height) mapnik.render(m, im) img = im.tostring('png256') img = cv2.imdecode(np.fromstring(img, dtype=np.uint8), 1) img =np.asarray(img) window_name = "Location" cv2.imshow(window_name, img) cv2.waitKey(1)
def rpc_renderCoord(self, lat, lon, zoom): im = mapnik.Image(self.mapsize[0], self.mapsize[1]) center = mapnik.Coord(lat, lon) transform = mapnik.ProjTransform(self.longlat, self.merc) merc_center = transform.forward(center) dx = (20037508.34 * 2 * (self.mapsize[0] / 2)) / (256 * (2**(zoom))) minx = merc_center.x - dx maxx = merc_center.x + dx self.rendermap.aspect_fix_mode = mapnik.aspect_fix_mode.ADJUST_BBOX_HEIGHT merc_bbox = mapnik.Box2d(minx, merc_center.y - 1, maxx, merc_center.y + 1) self.rendermap.zoom_to_box(merc_bbox) mapnik.render(self.rendermap, im) Map = im.tostring('png') return (True, Map)
def rendertiles( bounds, item, label, lat, layers, lon, projec, writer): z = 1 imgx = 128 * z imgy = 128 * z for layer in layers: index = layers.index(layer) mapfile = "/map_data/styles/bs_" + layer + ".xml" m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) # ensure the target map projection is mercator m.srs = projec.params() if hasattr(mapnik,'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) transform = mapnik.ProjTransform(longlat,projec) merc_bbox = transform.forward(bbox) m.zoom_to_box(merc_bbox) # render the map to an image im = mapnik.Image(imgx,imgy) mapnik.render(m, im) img = im.tostring('png256') if index == 0: data=[img] #data = np.expand_dims(data, 0) else: data.append(img) save_data(data, layers, item, label, lat, lon, writer)
m = mapnik.Map(imgx,imgy) mapnik.load_map(m,mapfile) # ensure the target map projection is mercator m.srs = merc.params() if hasattr(mapnik,'Box2d'): bbox = mapnik.Box2d(*bounds) else: bbox = mapnik.Envelope(*bounds) # Our bounds above are in long/lat, but our map # is in spherical mercator, so we need to transform # the bounding box to mercator to properly position # the Map when we call `zoom_to_box()` transform = mapnik.ProjTransform(longlat,merc) merc_bbox = transform.forward(bbox) # Mapnik internally will fix the aspect ratio of the bounding box # to match the aspect ratio of the target image width and height # This behavior is controlled by setting the `m.aspect_fix_mode` # and defaults to GROW_BBOX, but you can also change it to alter # the target image size by setting aspect_fix_mode to GROW_CANVAS #m.aspect_fix_mode = mapnik.GROW_CANVAS # Note: aspect_fix_mode is only available in Mapnik >= 0.6.0 m.zoom_to_box(merc_bbox) # render the map to an image im = mapnik.Image(imgx,imgy) mapnik.render(m, im) im.save(map_uri,'png')
def render_map(self, lat, lon, angle=None, angle_offset=0, zoom=None, overwrite=False, img_width=None, img_height=None, zoom_to_layer=False, layer_padding=10): """Renders map with help of mapnik If maps_cache is used it is first checked if image already exists in cache. Image name is created with self._make_name which creates name from lat_lon rounded to 5 decimals and width height if they are provided. If image exists and overwrite is False image is returned as ImageClip. If overwrite is True image is deleted and image is rendered and also returned as ImageClip. Parameters --------- lat : float Latitude in WGS84 - center point of a map (around 46 in Europe) lon : float Longitude in WGS84 - center point of a map (around 15 in Europe) angle : float If we want to rotate map. It should show where up is. AKA bearing angle_offset : int How much offset is between camera and forward direction so that map is correctly oriented zoom : float Mapnik zoom from 0-19 (higher number higher zoom) If we want different zoom then what was set in constructor overwrite : bool If we are using map cache do we want to overwrite existing images img_width : int If we want different size of map then what was set in constructor img_height : int If we want different size of map then what was set in constructor zoom_to_layer: bool If true it shows whole gpx layer in a map. lat, lon, zoom, angle are ignored layer_padding: int How much padding to add between edges of layer and image Returns ------- moviepy.video.VideoClip.ImageClip, tuple Rendered image as clip, and tuple with x and y coordinate of center in pixel units. (Used to add point on current location) """ map_uri = None width = self.map_width if img_width is None else img_width height = self.map_height if img_height is None else img_height if zoom is None: if self.map_zoom is None: raise Exception("One of map_zoom or zoom needs to be set!") zoom = self.map_zoom if angle is None: # spherical mercator (most common target map projection of osm data imported with osm2pgsql) merc = self.mercator_projection else: #Map rotation https://gis.stackexchange.com/questions/183175/rotating-90-using-two-point-equidistant-projection-with-proj4 merc = mapnik.Projection( '+proj=aeqd +ellps=sphere +lat_0=90 +lon_0=-' + str(angle + angle_offset)) self._lazy_init_map() # ensure the target map projection is mercator self.m.srs = merc.params() centre = mapnik.Coord(lon, lat) transform = mapnik.ProjTransform(MapnikRenderer.longlat, merc) merc_centre = transform.forward(centre) if img_width is not None and img_height is not None: self.m.resize(width, height) if not zoom_to_layer: # 360/(2**zoom) degrees = 256 px # so in merc 1px = (20037508.34*2) / (256 * 2**zoom) # hence to find the bounds of our rectangle in projected coordinates + and - half the image width worth of projected coord units dx = ((20037508.34 * 2 * (width / 2))) / (256 * (2**(zoom))) minx = merc_centre.x - dx maxx = merc_centre.x + dx # grow the height bbox, as we only accurately set the width bbox self.m.aspect_fix_mode = mapnik.aspect_fix_mode.ADJUST_BBOX_HEIGHT bounds = mapnik.Box2d( minx, merc_centre.y - 10, maxx, merc_centre.y + 10 ) # the y bounds will be fixed by mapnik due to ADJUST_BBOX_HEIGHT else: names = ["gpx"] ppmm = 90.7 / 25.4 self.m.aspect_fix_mode = mapnik.aspect_fix_mode.GROW_BBOX #Next for loop is from Zverik/Nik4 app #Calculate extent of given layers and bbox for layer in (l for l in self.m.layers if l.name in names): # it may as well be a GPX layer in WGS84 proj = mapnik.Projection(layer.srs) bbox = layer.envelope() \ .inverse(proj).forward(self.mercator_projection) tscale = min((bbox.maxx - bbox.minx) / max(width, 0.01), (bbox.maxy - bbox.miny) / max(height, 0.01)) bbox.pad(layer_padding * ppmm * tscale) bounds = bbox # Note: aspect_fix_mode is only available in Mapnik >= 0.6.0 self.m.zoom_to_box(bounds) center_pixel_coord = self.m.view_transform().forward(merc_centre) #print ("img_width: {} map_width:{} width:{}".format(img_width, self.map_width, width)) if self.maps_cache is not None: zoom_name = zoom if self.zoom_changeable else None fn = self._make_name(lat, lon, width, height, zoom_name, zoom_to_layer) #print ("Rendering " + fn) map_uri = os.path.join(self.maps_cache, "{}.png".format(fn)) #If we don't want to overwrite and file already exists skip map rendering if not overwrite and os.path.isfile(map_uri): return ImageClip(map_uri), (center_pixel_coord.x, center_pixel_coord.y) #If we want to overwrite and file exists we remove file if overwrite and os.path.isfile(map_uri): os.remove(map_uri) #start = time.perf_counter() if self.maps_cache is not None: mapnik.render_to_file(self.m, map_uri) map_data = map_uri else: #Renders map to image in memory saves it to buffer and reads in numpy im = mapnik.Image(self.m.width, self.m.height) mapnik.render(self.m, im) #im.save("/tmp/tmp.png", 'png256') #Saving image to bytes buffer needs to be nonpalletted image otherwise it needs #to be converted to RGB when reading in numpy anyways string_image = im.tostring('png32') buffer = BytesIO(string_image) #with open("/tmp/tmp1.png", "wb") as o: #o.write(buffer.getvalue()) pil_image = ImagePIL.open(buffer) #print (pil_image.format, pil_image.mode, pil_image.size, #pil_image.palette) map_data = np.asarray(pil_image) #map_data = "/tmp/tmp.png" if img_width is not None and img_height is not None: self.m.resize(self.map_width, self.map_height) #print ("render took %r s" % (time.perf_counter()-start,)) return ImageClip(map_data), (center_pixel_coord.x, center_pixel_coord.y)