def mm(self, points): bbox = self.calculate_bbox_for_points(points) if self.method == 'bbox': bbox = self.adjust_bbox(bbox, .5) self.bbox = bbox dims = ModestMaps.Core.Point(self.width, self.height) sw = ModestMaps.Geo.Location(bbox[0], bbox[1]) ne = ModestMaps.Geo.Location(bbox[2], bbox[3]) provider = ModestMaps.builtinProviders[ 'MICROSOFT_AERIAL' ]() if self.method == 'bbox': mm_obj = ModestMaps.mapByExtentZoom(provider, sw, ne, self.zoom) else: mm_obj = ModestMaps.mapByExtent(provider, sw, ne, dims) self.mm_provider = provider self.mm_obj = mm_obj self.mm_markers = modestMMarkers.modestMMarkers(self.mm_obj) return True
def project(self): ''' Set map extent from lnglat bounds and zoom ''' bnds = self.map.lngLatBounds sw = MM.Geo.Location(bnds.b, bnds.l) ne = MM.Geo.Location(bnds.t, bnds.r) z = self.opts['zoom'] #provider = MM.Microsoft.RoadProvider() provider = MM.OpenStreetMap.Provider() mm = MM.mapByExtentZoom(provider, sw, ne, z) self.mm = mm epsg3857 = pyproj.Proj(init='epsg:3857') epsg4326 = pyproj.Proj(init='epsg:4326') # Resize map to dimensions of tiles psw = pyproj.transform(epsg4326, epsg3857, bnds.l, bnds.b) pne = pyproj.transform(epsg4326, epsg3857, bnds.r, bnds.t) self.map.projBounds.set(psw[0], psw[1], pne[0], pne[1]) self.map.canvasW = self.viewW = mm.dimensions.x self.map.canvasH = self.viewH = mm.dimensions.y self.map.projToViewScale = self.map.viewW / self.map.projBounds.width self.map.setViewBounds()
def coords_to_bbox_mmap(self, z, x, y): # set up bounding box from coord coord = ModestMaps.Core.Coordinate(y, x, z) tl = self.projection.coordinateLocation(coord) br = self.projection.coordinateLocation(coord.right().down()) bbox = Polygon.from_bbox((tl.lon, tl.lat, br.lon, br.lat)) bbox.srid = self.srid modest_map = ModestMaps.mapByExtentZoom(self.provider, tl, br, z) return bbox, modest_map
def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom): # first, figure out the bounding box of the tile we're rendering nw = self.layer.projection.projLocation( ModestMaps.Core.Point(xmin, ymin)) se = self.layer.projection.projLocation( ModestMaps.Core.Point(xmax, ymax)) max_lat = max(nw.lat, se.lat) min_lat = min(nw.lat, se.lat) max_lon = max(nw.lon, se.lon) min_lon = min(nw.lon, se.lon) bbox = Polygon.from_bbox((min_lon, min_lat, max_lon, max_lat)) # this obj is used to translate between lat/lon and pixel space bound1 = ModestMaps.Geo.Location(min_lat, min_lon) bound2 = ModestMaps.Geo.Location(max_lat, max_lon) mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom) # start drawing each block pil_map = Image.new("RGBA", (width, height), (255, 255, 255, 0)) pil_draw = ImageDraw.Draw(pil_map) for block in Block.objects.filter(poly__intersects=bbox): # shape locs = [] for c in block.poly.coords[0]: pt = ModestMaps.Geo.Location(c[1], c[0]) loc = mmap.locationPoint(pt) locs.append((loc.x, loc.y)) # color count = Crime.objects.filter(pt__within=block.poly).count() if count <= HEATMAP_MIN: h, s, l = GREEN elif count >= HEATMAP_MAX: h, s, l = RED else: scale = float(count - HEATMAP_MIN) / float(HEATMAP_MAX - HEATMAP_MIN) # scale all channels linearly between START_COLOR and END_COLOR h, s, l = [ int(scale * (end - start) + start) for start, end in zip(GREEN, RED) ] block_color = "hsl(%s, %s%%, %s%%)" % (h, s, l) pil_draw.polygon(locs, fill=block_color) return pil_map
def draw_map_bbox (self) : if self.ctx.has_key('adjust') : self.ctx['bbox'] = self.__adjust_bbox(self.ctx['bbox'], self.ctx['adjust']) # provider = self.load_provider(self.ctx['provider']) sw = ModestMaps.Geo.Location(self.ctx['bbox'][0], self.ctx['bbox'][1]) ne = ModestMaps.Geo.Location(self.ctx['bbox'][2], self.ctx['bbox'][3]) zoom = self.ctx['zoom'] self.ctx['map'] = ModestMaps.mapByExtentZoom(provider, sw, ne, zoom) return self.ctx['map'].draw()
def draw_map_bbox(self): if self.ctx.has_key('adjust'): self.ctx['bbox'] = self.__adjust_bbox(self.ctx['bbox'], self.ctx['adjust']) # provider = self.load_provider(self.ctx['provider']) sw = ModestMaps.Geo.Location(self.ctx['bbox'][0], self.ctx['bbox'][1]) ne = ModestMaps.Geo.Location(self.ctx['bbox'][2], self.ctx['bbox'][3]) zoom = self.ctx['zoom'] self.ctx['map'] = ModestMaps.mapByExtentZoom(provider, sw, ne, zoom) return self.ctx['map'].draw()
def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom): # first, figure out the bounding box of the tile we're rendering nw = self.layer.projection.projLocation(ModestMaps.Core.Point(xmin, ymin)) se = self.layer.projection.projLocation(ModestMaps.Core.Point(xmax, ymax)) max_lat = max(nw.lat, se.lat) min_lat = min(nw.lat, se.lat) max_lon = max(nw.lon, se.lon) min_lon = min(nw.lon, se.lon) bbox = Polygon.from_bbox((min_lon, min_lat, max_lon, max_lat)) # this obj is used to translate between lat/lon and pixel space bound1 = ModestMaps.Geo.Location(min_lat, min_lon) bound2 = ModestMaps.Geo.Location(max_lat, max_lon) mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom) # start drawing each block pil_map = Image.new("RGBA", (width, height), (255,255,255, 0)) pil_draw = ImageDraw.Draw(pil_map) for block in Block.objects.filter(geom__intersects=bbox): # shape locs = [] for c in block.geom.coords[0]: pt = ModestMaps.Geo.Location(c[1], c[0]) loc = mmap.locationPoint(pt) locs.append((loc.x, loc.y)) # color count = Crime.objects.filter(pt__within=block.geom).count() if count <= HEATMAP_MIN: h, s, l = GREEN elif count >= HEATMAP_MAX: h, s, l = RED else: scale = float(count - HEATMAP_MIN) / float(HEATMAP_MAX - HEATMAP_MIN) # scale all channels linearly between START_COLOR and END_COLOR h, s, l = [int(scale*(end-start) + start) for start, end in zip(GREEN, RED)] block_color = "hsl(%s, %s%%, %s%%)" % (h, s, l) pil_draw.polygon(locs, fill=block_color) return pil_map
def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom): nw = self.layer.projection.projLocation(ModestMaps.Core.Point(xmin, ymin)) se = self.layer.projection.projLocation(ModestMaps.Core.Point(xmax, ymax)) max_lat = max(nw.lat, se.lat) min_lat = min(nw.lat, se.lat) max_lon = max(nw.lon, se.lon) min_lon = min(nw.lon, se.lon) bound1 = ModestMaps.Geo.Location(min_lat, min_lon) bound2 = ModestMaps.Geo.Location(max_lat, max_lon) mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom) pil_map = Image.new("RGBA", (width, height), (255,255,255, 0)) pil_draw = ImageDraw.Draw(pil_map) bbox = Polygon.from_bbox((min_lon, min_lat, max_lon, max_lat)) for block in Block.objects.filter(poly__intersects=bbox): # shape locs = [] for c in block.poly.coords[0]: pt = ModestMaps.Geo.Location(c[1], c[0]) loc = mmap.locationPoint(pt) locs.append((loc.x, loc.y)) # color count = Crime.objects.filter(pt__within=block.poly).count() if count <= HEATMAP_MIN: h, s, l = START_COLOR elif count >= HEATMAP_MAX: h, s, l = END_COLOR else: scale = float(count - HEATMAP_MIN) / float(HEATMAP_MAX - HEATMAP_MIN) # scale all channels linearly between START_COLOR and END_COLOR h, s, l = [int(scale*(end-start) + start) for start, end in zip(START_COLOR, END_COLOR)] pil_draw.polygon(locs, fill="hsl(%s, %s%%, %s%%)" % (h, s, l), outline="rgb(255, 255, 255)") return pil_map
dimensions = ModestMaps.Core.Point(width, height) locationA = ModestMaps.Geo.Location(latA, lonA) locationB = ModestMaps.Geo.Location(latB, lonB) map = ModestMaps.mapByExtent(provider, locationA, locationB, dimensions) elif options.extent and options.zoom: latA, lonA = options.extent[0], options.extent[1] latB, lonB = options.extent[2], options.extent[3] locationA = ModestMaps.Geo.Location(latA, lonA) locationB = ModestMaps.Geo.Location(latB, lonB) zoom = options.zoom map = ModestMaps.mapByExtentZoom(provider, locationA, locationB, zoom) else: raise BadComposure("Error: not really sure what's going on.") except BadComposure, e: print >> sys.stderr, parser.usage print >> sys.stderr, '' print >> sys.stderr, '%s --help for possible options.' % __file__ print >> sys.stderr, '' print >> sys.stderr, e sys.exit(1) if options.verbose: print map.coordinate, map.offset, '->', outfile, (map.dimensions.x, map.dimensions.y)
dimensions = ModestMaps.Core.Point(width, height) locationA = ModestMaps.Geo.Location(latA, lonA) locationB = ModestMaps.Geo.Location(latB, lonB) map = ModestMaps.mapByExtent(provider, locationA, locationB, dimensions) elif options.extent and options.zoom: latA, lonA = options.extent[0], options.extent[1] latB, lonB = options.extent[2], options.extent[3] locationA = ModestMaps.Geo.Location(latA, lonA) locationB = ModestMaps.Geo.Location(latB, lonB) zoom = options.zoom map = ModestMaps.mapByExtentZoom(provider, locationA, locationB, zoom) else: raise BadComposure("Error: not really sure what's going on.") except BadComposure, e: print >> stderr, parser.usage print >> stderr, '' print >> stderr, '%s --help for possible options.' % __file__ print >> stderr, '' print >> stderr, e exit(1) if options.verbose: print map.coordinate, map.offset, '->', outfile, (map.dimensions.x, map.dimensions.y)
def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom): # start drawing each block pil_map = Image.new("RGBA", (width, height), (255,255,255, 0)) pil_draw = ImageDraw.Draw(pil_map) # return empty images if zoom < 11: return pil_map # first, figure out the bounding box of the tile we're rendering nw = self.layer.projection.projLocation(ModestMaps.Core.Point(xmin, ymin)) se = self.layer.projection.projLocation(ModestMaps.Core.Point(xmax, ymax)) max_lat = max(nw.lat, se.lat) min_lat = min(nw.lat, se.lat) max_lon = max(nw.lon, se.lon) min_lon = min(nw.lon, se.lon) # Converting polygon to OSGB36 in order to compare with the ones we have in # the database shp = ShpParser() min_p = shp.convert_point_to_OSGB36(min_lat, min_lon) max_p = shp.convert_point_to_OSGB36(max_lat, max_lon) bbox = Polygon.from_bbox((min_p[0], min_p[1], max_p[0], max_p[1])) # this obj is used to translate between lat/lon and pixel space bound1 = ModestMaps.Geo.Location(min_lat, min_lon) bound2 = ModestMaps.Geo.Location(max_lat, max_lon) mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom) neighbourhoods = False polys = None max_x = None min_x = None try: # If zoom < 15 we draw postcode polygons, otherwise neighbourhoods if zoom < 15 or self.type == "None": polys = Neighbourhood.objects.filter(poly__intersects=bbox) neighbourhoods = True else: polys = Postcode.objects.filter(poly__intersects=bbox) print "Painting", polys.count(), "blocks" # Have to find the city where the polygons belong in _city = None if self.type != "None": for poly in polys: if _city is not None: break if poly.poly and isinstance(poly.poly, geos.MultiPolygon): for inside_poly in poly.poly: if _city is None: # Find the city if we haven't found it yet cities = Council.objects.filter(poly__intersects=inside_poly) if len(cities) > 0: _city = cities[0].convexhull.name break else: # Probably unneeded as eventually we only have Multipolygons in our db if _city is None: # Find the city if we haven't found it yet cities = Council.objects.filter(poly__intersects=inside_poly) if len(cities) > 0: _city = cities[0].convexhull.name break print "City:", _city if len(polys) > 0 and self.type != "None": if neighbourhoods: _name = _city+"_neighbourhood_max_"+self.type max_x = float(Statistics.objects.filter(name=_name).all()[0].stat) _name = _city+"_neighbourhood_min_"+self.type min_x = float(Statistics.objects.filter(name=_name).all()[0].stat) else: _name = _city+"_postcode_max_"+self.type max_x = float(Statistics.objects.filter(name=_name).all()[0].stat) _name = _city+"_postcode_min_"+self.type min_x = float(Statistics.objects.filter(name=_name).all()[0].stat) print "max:", max_x, "min:", min_x # For all the polygons we've retrieved from the database (in OSGB36 format) for poly in polys: _city = None if poly.poly and isinstance(poly.poly, geos.MultiPolygon): for inside_poly in poly.poly: if _city is None: # Find the city if we haven't found it yet cities = Council.objects.filter(poly__intersects=inside_poly) if len(cities) > 0: _city = cities[0].convexhull.name self._paint_poly(inside_poly, shp, mmap, pil_draw, _city, max_x, min_x, neighbourhoods) else: # Probably unneeded as eventually we only have Multipolygons in our db if _city is None: # Find the city if we haven't found it yet cities = Council.objects.filter(poly__intersects=inside_poly) if len(cities) > 0: _city = cities[0].convexhull.name self._paint_poly(poly.poly, shp, mmap, pil_draw, _city, max_x, min_x, neighbourhoods) except Exception, err: print err
def make_map(provider, area, zoom, by_centre, map_size=(1200,800), verbose=False): """ zoom: integer, the zoom level (altitude) min 12; max 15 in this case Returns a map instance (not image!) """ if type(area) in (str, unicode): area = area.lower() zoom = int(zoom) provider = PROVIDERS[provider.lower()] if verbose: title = 'Making map with the following characteristics:' print '\n%s' % title print '-' * len(title) if type(area) in (str, unicode): print 'Area: %s' % area.title() else: print 'Area: %s' % area print 'Zoom: %d' % zoom if type(provider) == str: print 'Provider: %s' % provider.title().replace('_', ' ') else: print 'Provider: %s' % provider.__name__ print 'Height: %dpx' % map_size[1] print 'Width: %dpx' % map_size[0] print if type(provider) == str: provider = MM.builtinProviders[provider]() else: # it must be a custom provider provider = provider() if by_centre: if type(area) in (str, unicode): centre = CENTRE[area] elif type(area) == tuple: centre = area width = map_size[0] height = map_size[1] m = MM.mapByCenterZoom( provider, MM.Geo.Location(*centre), zoom, MM.Core.Point(width, height)) if verbose: print m.pointLocation(MM.Core.Point(0,0)) # to get the upper left corner geo coordinates print m.pointLocation(MM.Core.Point(width,height)) # to get the lower right corner geo coordinates else: # by box if type(area) in (str, unicode): map_box = MAP_BOX[area] elif type(area) == tuple: map_box = area left_upper_corner = MM.Geo.Location(*map_box[0]) right_lower_corner = MM.Geo.Location(*map_box[1]) m = MM.mapByExtentZoom( provider, left_upper_corner, right_lower_corner, zoom) return m
def main(apibase, password, print_id, paper_size, orientation=None, layout=None, provider=None, bounds=None, zoom=None, geotiff_url=None): """ """ yield 60 print 'Print:', print_id print 'Paper:', paper_size if orientation and bounds and zoom and provider and layout: print 'Orientation:', orientation print 'Bounds:', bounds print 'Layout:', layout print 'Provider:', provider print 'Size:', get_preview_map_size(orientation, paper_size) print_data = {'pages': []} print_pages = print_data['pages'] north, west, south, east = bounds width, height = get_preview_map_size(orientation, paper_size) northwest = mm.Geo.Location(north, west) southeast = mm.Geo.Location(south, east) # we need it to cover a specific area mmap = mm.mapByExtentZoom(TemplatedMercatorProvider(provider), northwest, southeast, zoom) # but we also we need it at a specific size mmap = mm.Map(mmap.provider, mm.Core.Point(width, height), mmap.coordinate, mmap.offset) out = StringIO() mmap.draw(fatbits_ok=True).save(out, format='JPEG') preview_url = append_print_file(print_id, 'preview.jpg', out.getvalue(), apibase, password) print 'Sent preview.jpg' yield 60 zdiff = min(18, zoom + 2) - zoom print 'Zoom diff:', zdiff # we need it to cover a specific area mmap = mm.mapByExtentZoom(TemplatedMercatorProvider(provider), northwest, southeast, zoom + zdiff) # but we also we need it at a specific size mmap = mm.Map(mmap.provider, mm.Core.Point(width * 2**zdiff, height * 2**zdiff), mmap.coordinate, mmap.offset) out = StringIO() mmap.draw(fatbits_ok=True).save(out, format='JPEG') print_url = append_print_file(print_id, 'print.jpg', out.getvalue(), apibase, password) print 'Sent print.jpg' page_nw = mmap.pointLocation(mm.Core.Point(0, 0)) page_se = mmap.pointLocation(mmap.dimensions) page_data = {'print': 'print.jpg', 'preview': 'preview.jpg', 'bounds': {}} page_data['bounds'].update({'north': page_nw.lat, 'west': page_nw.lon}) page_data['bounds'].update({'south': page_se.lat, 'east': page_se.lon}) print_pages.append(page_data) rows, cols = map(int, layout.split(',')) if rows > 1 and cols > 1: for (row, col) in product(range(rows), range(cols)): yield 60 sub_mmap = get_mmap_page(mmap, row, col, rows, cols) sub_part = '%(row)d,%(col)d' % locals() sub_name = 'print-%(sub_part)s.jpg' % locals() out = StringIO() sub_mmap.draw(fatbits_ok=True).save(out, format='JPEG') append_print_file(print_id, sub_name, out.getvalue(), apibase, password) print 'Sent', sub_name prev_cen = sub_mmap.pointLocation(mm.Core.Point(sub_mmap.dimensions.x / 2, sub_mmap.dimensions.y / 2)) prev_dim = mm.Core.Point(sub_mmap.dimensions.x / 2**zdiff, sub_mmap.dimensions.y / 2**zdiff) prev_mmap = mm.mapByCenterZoom(sub_mmap.provider, prev_cen, sub_mmap.coordinate.zoom - zdiff, prev_dim) prev_name = 'preview-%(sub_part)s.jpg' % locals() out = StringIO() prev_mmap.draw(fatbits_ok=True).save(out, format='JPEG') append_print_file(print_id, prev_name, out.getvalue(), apibase, password) print 'Sent', prev_name page_nw = sub_mmap.pointLocation(mm.Core.Point(0, 0)) page_se = sub_mmap.pointLocation(sub_mmap.dimensions) page_data = {'part': sub_part, 'print': sub_name, 'preview': prev_name, 'bounds': {}} page_data['bounds'].update({'north': page_nw.lat, 'west': page_nw.lon}) page_data['bounds'].update({'south': page_se.lat, 'east': page_se.lon}) print_pages.append(page_data) print_data_url = append_print_file(print_id, 'print-data.json', json.dumps(print_data, indent=2), apibase, password) print 'Sent', print_data_url elif geotiff_url: # we'll need pages_data, a few other things raise Exception("I'm pretty sure support for geotiffs is currently broken, with the new atlas feature.") print 'URL:', geotiff_url filename = prepare_geotiff(geotiff_url) print_img, preview_img, (north, west, south, east), orientation = adjust_geotiff(filename, paper_size) os.unlink(filename) print_img.save(os.path.dirname(filename)+'/out.jpg') out = StringIO() print_img.save(out, format='JPEG') append_print_file(print_id, 'print.jpg', out.getvalue(), apibase, password) out = StringIO() preview_img.save(out, format='JPEG') preview_url = append_print_file(print_id, 'preview.jpg', out.getvalue(), apibase, password) zoom = infer_zoom(print_img.size[0], print_img.size[1], north, west, south, east) else: print 'Missing orientation, bounds, zoom, provider, layout and geotiff_url' yield ALL_FINISHED return yield 10 paper = '%(orientation)s-%(paper_size)s' % locals() print 'Finishing...' finish_print(apibase, password, print_id, north, west, south, east, zoom, paper, print_data_url) print '-' * 80 yield ALL_FINISHED