def render_image(self, extent, size, padding=0): res_x = (extent[2] - extent[0]) / size[0] res_y = (extent[3] - extent[1]) / size[1] # Экстент с учетом отступа extended = ( extent[0] - res_x * padding, extent[1] - res_y * padding, extent[2] + res_x * padding, extent[3] + res_y * padding, ) # Размер изображения с учетом отступа render_size = ( size[0] + 2 * padding, size[1] + 2 * padding ) # Фрагмент изображения размера size target_box = ( padding, padding, size[0] + padding, size[1] + padding ) # Выбираем объекты по экстенту feature_query = self.layer.feature_query() feature_query.intersects(box(*extended, srid=self.layer.srs_id)) feature_query.geom() features = feature_query() mapobj = self._mapobj(features) # Получаем картинку эмулируя WMS запрос req = mapscript.OWSRequest() req.setParameter("bbox", ','.join(map(str, extended))) req.setParameter("width", str(render_size[0])) req.setParameter("height", str(render_size[1])) req.setParameter("srs", 'EPSG:%d' % self.layer.srs_id) req.setParameter("format", 'image/png') req.setParameter("layers", 'main') req.setParameter("request", "GetMap") req.setParameter('transparent', 'TRUE') mapobj.loadOWSParameters(req) gdimg = mapobj.draw() # Преобразуем изображение из PNG в объект PIL buf = StringIO() buf.write(gdimg.getBytes()) buf.seek(0) img = Image.open(buf) # Вырезаем нужный нам кусок изображения return img.crop(target_box)
def select(self, params): if self.query is None: self._setup_query() self.query.filter_by() # Startfeature+maxfeature if params.startfeature is None: params.startfeature = 0 if params.maxfeatures: maxfeatures = params.maxfeatures else: maxfeatures = self.maxfeatures self.query.limit(maxfeatures, params.startfeature) # BBOX if params.bbox: coords = params.bbox['coords'] srs_id = params.bbox[ 'srs_id'] if 'srs_id' in params.bbox else self.srid_out geom = box(*coords, srid=srs_id) self.query.intersects(geom) srid = params.srsname if params.srsname else self.srid_out self.query.srs(Bunch({'id': srid})) self.query.geom() result = self.query() features = [] fields_checked = False for row in result: # Check if names contains characters that can't be used in XML tags if not fields_checked: for field_name in row.fields: if '<' in field_name or '>' in field_name or '&' in field_name or '@' in field_name: raise OperationProcessingFailedException( message='Field name %s contains unsupported symbol' % (field_name, )) fields_checked = True feature = Feature(id=row.id, props=row.fields, srs=srid) feature.geometry_attr = self.geom_col geom = geojson.dumps(row.geom) # featureserver.feature.geometry is a dict, so convert str->dict: feature.set_geo(geojson.loads(geom)) features.append(feature) return features
def render_image(self, extent, size, padding=0): res_x = (extent[2] - extent[0]) / size[0] res_y = (extent[3] - extent[1]) / size[1] # Экстент с учетом отступа extended = ( extent[0] - res_x * padding, extent[1] - res_y * padding, extent[2] + res_x * padding, extent[3] + res_y * padding, ) # Размер изображения с учетом отступа render_size = (size[0] + 2 * padding, size[1] + 2 * padding) # Фрагмент изображения размера size target_box = (padding, padding, size[0] + padding, size[1] + padding) # Выбираем объекты по экстенту feature_query = self.layer.feature_query() feature_query.intersects(box(*extended, srid=self.layer.srs_id)) feature_query.geom() features = feature_query() mapobj = self._mapobj(features) # Получаем картинку эмулируя WMS запрос req = mapscript.OWSRequest() req.setParameter("bbox", ','.join(map(str, extended))) req.setParameter("width", str(render_size[0])) req.setParameter("height", str(render_size[1])) req.setParameter("srs", 'EPSG:%d' % self.layer.srs_id) req.setParameter("format", 'image/png') req.setParameter("layers", 'main') req.setParameter("request", "GetMap") req.setParameter('transparent', 'TRUE') mapobj.loadOWSParameters(req) gdimg = mapobj.draw() # Преобразуем изображение из PNG в объект PIL buf = StringIO() buf.write(gdimg.getBytes()) buf.seek(0) img = Image.open(buf) # Вырезаем нужный нам кусок изображения return img.crop(target_box)
def geocollection(request): try: date = str(request.GET.get('datetime', datetime.now())) if 'layers' in request.GET: qlayers = map(int, request.GET['layers'].split(',')) print qlayers layers = DBSession.query(VectorLayer)\ .filter(VectorLayer.id.in_(qlayers))\ .all() else: layers = DBSession.query(VectorLayer)\ .all() layers = filter(lambda layer: layer.has_permission(PD_READ, request.user), layers) print layers except Exception as e: raise HTTPBadRequest(e.message) features = GeoJsonFeatureList() # Запрос коллекции GeoJSON объектов, попадающих в заданную область видимости if 'bbox' in request.GET: try: bbox = map(float, request.GET['bbox'].split(',')) print bbox geometry = box(*bbox, srid=3857) for layer in layers: query = layer.feature_query() query.geom() query.intersects(geometry) for feature in query(): print feature feature.fields['__layer__'] = feature.layer.id features.append(feature) except Exception as e: print e raise HTTPBadRequest(e.message) else: raise HTTPBadRequest() print len(features) for f in features: f._geom = geometry_transform(f.geom, f.layer.srs_id, 4326) result = geojson.dumps(features, cls=ComplexEncoder) return Response(result, content_type='application/json')
def render_image(self, extent, img_size, settings): # Выбираем объекты по экстенту feature_query = self.layer.feature_query() feature_query.intersects(box(*extent, srid=self.layer.srs_id)) feature_query.geom() features = feature_query() ds = mapnik.MemoryDatasource() for (id, f) in enumerate(features): if mapnik.mapnik_version() < 200100: feature = mapnik.Feature(id) else: feature = mapnik.Feature(mapnik.Context(), id) feature.add_geometries_from_wkb(f.geom.wkb) ds.add_feature(feature) style_content = str(self.style_content) m = mapnik.Map(img_size[0], img_size[1]) mapnik.load_map_from_string(m, style_content) m.zoom_to_box(mapnik.Box2d(*extent)) layer = mapnik.Layer('main') layer.datasource = ds root = ET.fromstring(style_content) styles = [s.attrib.get('name') for s in root.iter('Style')] for s in styles: layer.styles.append(s) m.layers.append(layer) img = mapnik.Image(img_size[0], img_size[1]) mapnik.render(m, img) data = img.tostring('png') # Преобразуем изображение из PNG в объект PIL buf = StringIO() buf.write(data) buf.seek(0) img = Image.open(buf) return img
def _render_image(self, srs, extent, size, cond, padding=0): extended, render_size, target_box = _render_bounds( extent, size, padding) # Выбираем объекты по экстенту feature_query = self.parent.feature_query() # Отфильтровываем объекты по условию if cond is not None: feature_query.filter_by(**cond) # FIXME: Тоже самое, но через интерфейсы if hasattr(feature_query, 'srs'): feature_query.srs(srs) feature_query.intersects(box(*extended, srid=srs.id)) feature_query.geom() features = feature_query() options = VectorRenderOptions( self, features, render_size, extended, target_box) return env.qgis.renderer_job(options)
def _render_image(self, srs, extent, size, padding=0): res_x = (extent[2] - extent[0]) / size[0] res_y = (extent[3] - extent[1]) / size[1] # Экстент с учетом отступов extended = ( max(srs.minx, extent[0] - res_x * padding), max(srs.miny, extent[1] - res_y * padding), min(srs.maxx, extent[2] + res_x * padding), min(srs.maxy, extent[3] + res_y * padding), ) # Маска отступов pmask = ( extended[0] != srs.minx, extended[1] != srs.miny, extended[2] != srs.maxx, extended[3] != srs.maxy ) # Размер изображения с учетом отступов render_size = ( size[0] + int(pmask[0] + pmask[2]) * padding, size[1] + int(pmask[1] + pmask[3]) * padding ) # Фрагмент изображения размера size target_box = ( pmask[0] * padding, pmask[3] * padding, size[0] + pmask[0] * padding, size[1] + pmask[3] * padding ) # Выбираем объекты по экстенту feature_query = self.parent.feature_query() # FIXME: Тоже самое, но через интерфейсы if hasattr(feature_query, 'srs'): feature_query.srs(srs) feature_query.intersects(box(*extended, srid=srs.id)) feature_query.geom() features = feature_query() res_img = None try: dirname, fndata, fnstyle = None, None, None dirname = mkdtemp() fndata = os.path.join(dirname, 'layer.geojson') with open(fndata, 'wb') as fd: fd.write(geojson.dumps(features)) fnstyle = os.path.join(dirname, 'layer.qml') os.symlink(env.file_storage.filename(self.qml_fileobj), fnstyle) result = Queue() env.qgis.queue.put((fndata, self.srs, render_size, extended, target_box, result)) render_timeout = int(env.qgis.settings.get('render_timeout')) res_img = result.get(block=True, timeout=render_timeout) finally: if fndata and os.path.isfile(fndata): os.unlink(fndata) if fnstyle and os.path.isfile(fnstyle): os.unlink(fnstyle) if dirname and os.path.isdir(dirname): os.rmdir(dirname) return res_img
def _render_image(self, srs, extent, size, padding=0): res_x = (extent[2] - extent[0]) / size[0] res_y = (extent[3] - extent[1]) / size[1] # Экстент с учетом отступов extended = ( max(srs.minx, extent[0] - res_x * padding), max(srs.miny, extent[1] - res_y * padding), min(srs.maxx, extent[2] + res_x * padding), min(srs.maxy, extent[3] + res_y * padding), ) # Маска отступов pmask = (extended[0] != srs.minx, extended[1] != srs.miny, extended[2] != srs.maxx, extended[3] != srs.maxy) # Размер изображения с учетом отступов render_size = (size[0] + int(pmask[0] + pmask[2]) * padding, size[1] + int(pmask[1] + pmask[3]) * padding) # Фрагмент изображения размера size target_box = (pmask[0] * padding, pmask[3] * padding, size[0] + pmask[0] * padding, size[1] + pmask[3] * padding) # Выбираем объекты по экстенту feature_query = self.parent.feature_query() # FIXME: Тоже самое, но через интерфейсы if hasattr(feature_query, 'srs'): feature_query.srs(srs) feature_query.intersects(box(*extended, srid=srs.id)) feature_query.geom() features = feature_query() res_img = None try: dirname, fndata, fnstyle = None, None, None dirname = mkdtemp() fndata = os.path.join(dirname, 'layer.geojson') with open(fndata, 'wb') as fd: fd.write(geojson.dumps(features)) fnstyle = os.path.join(dirname, 'layer.qml') os.symlink(env.file_storage.filename(self.qml_fileobj), fnstyle) result = Queue() env.qgis.queue.put( (fndata, self.srs, render_size, extended, target_box, result)) render_timeout = int(env.qgis.settings.get('render_timeout')) res_img = result.get(block=True, timeout=render_timeout) finally: if fndata and os.path.isfile(fndata): os.unlink(fndata) if fnstyle and os.path.isfile(fnstyle): os.unlink(fnstyle) if dirname and os.path.isdir(dirname): os.rmdir(dirname) return res_img
def _render_image(self, srs, extent, size, cond, padding=0): extended, render_size, target_box = _render_bounds( extent, size, padding) feature_query = self.parent.feature_query() # Apply filter condition if cond is not None: feature_query.filter_by(**cond) # TODO: Do this via interfaces if hasattr(feature_query, 'srs'): feature_query.srs(srs) feature_query.intersects(box(*extended, srid=srs.id)) feature_query.geom() env.qgis.qgis_init() crs = CRS.from_epsg(srs.id) mreq = MapRequest() mreq.set_dpi(96) mreq.set_crs(crs) def path_resolver(name): for skip_path in SKIP_PATHS: if name.startswith(skip_path): name = name.replace(skip_path, '', 1) break if path.isabs(name): raise ValueError("Absolute paths are not allowed.") name = path.normpath(name) if name[-4:].lower() == '.svg': name = name[:-4] items = name.split(path.sep) for i in range(len(items)): candidate = path.sep.join(items[i:]) filename = env.svg_marker_library.lookup( candidate, self.svg_marker_library) if filename is not None: return filename return name style = Style.from_string( _qml_cache(env.file_storage.filename(self.qml_fileobj)), path_resolver) style_attrs = style.used_attributes() qhl_fields = list() cnv_fields = list() qry_fields = list() for field in self.parent.fields: fkeyname = field.keyname if (style_attrs is not None) and (fkeyname not in style_attrs): continue field_to_qgis = _FIELD_TYPE_TO_QGIS[field.datatype] qhl_fields.append((fkeyname, field_to_qgis[0])) cnv_fields.append((fkeyname, field_to_qgis[1])) qry_fields.append(fkeyname) feature_query.fields(*qry_fields) features = list() for feat in feature_query(): features.append((feat.id, feat.geom.wkb, tuple([ convert(feat.fields[field]) for field, convert in cnv_fields ]))) if len(features) == 0: return None layer = Layer.from_data(_GEOM_TYPE_TO_QGIS[self.parent.geometry_type], crs, tuple(qhl_fields), tuple(features)) mreq.add_layer(layer, style) res = mreq.render_image(extent, size) return qgis_image_to_pil(res)