def test_envelope(self): eq_( session.scalar(functions.wkt(self.r.road_geom.envelope)), u"POLYGON((-88.674841 42.936306, -88.439093 42.936306, -88.439093 43.103503, -88.674841 43.103503, -88.674841 42.936306))", ) env = WKBSpatialElement(session.scalar(func.AsBinary(self.r.road_geom.envelope))) eq_(env.geom_type(session), "Polygon")
def test_envelope(self): eq_( session.scalar(functions.wkt(self.r.road_geom.envelope)), 'POLYGON((-88.674841 42.936306, -88.439093 42.936306, -88.439093 43.103503, -88.674841 43.103503, -88.674841 42.936306))' ) env = WKBSpatialElement( session.scalar(func.AsBinary(self.r.road_geom.envelope))) eq_(env.geom_type(session), 'Polygon')
def test_wkb(self): eq_( session.scalar( WKBSpatialElement(session.scalar(self.r.road_geom.wkb)).wkt), u'LINESTRING (-88.6748409363057 43.1035032292994, -88.6464173694267 42.9981688343949, -88.607961955414 42.9680732929936, -88.5160033566879 42.9363057770701, -88.4390925286624 43.0031847579618)' ) eq_(session.scalar(self.r.road_geom.wkb), self.r.road_geom.geom_wkb) ok_(not session.query(Spot).filter( Spot.spot_location.wkb == '101').first()) centroid_geom = DBSpatialElement( session.scalar(session.query(Lake).first().lake_geom.centroid)) eq_( session.scalar( WKBSpatialElement(session.scalar(centroid_geom.wkb)).wkt), u'POINT (-88.757840057564835 43.193797540630335)')
def test_envelope(self): eq_( b2a_hex(session.scalar(self.r.road_geom.envelope)), 'e610000001030000000100000005000000d7db0998302b56c036c921ded877454078a18c171a1c56c036c921ded877454078a18c171a1c56c0876f04983f8d4540d7db0998302b56c0876f04983f8d4540d7db0998302b56c036c921ded8774540' ) env = WKBSpatialElement( session.scalar(func.AsBinary(self.r.road_geom.envelope))) eq_(env.geom_type(session), 'Polygon') eq_( session.scalar( functions.wkt( functions.envelope( 'POINT(-88.5945861592357 42.9480095987261)'))), 'POLYGON((-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261))' )
def __update__(self, feature): """ Called by the protocol on object update. Arguments: * ``feature`` The GeoJSON feature as received from the client. """ for p in class_mapper(self.__class__).iterate_properties: if not isinstance(p, ColumnProperty): continue col = p.columns[0] if isinstance(col.type, Geometry): geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): srid = col.type.srid shape = asShape(geom) setattr(self, p.key, WKBSpatialElement(buffer(shape.wkb), srid=srid)) self._shape = shape elif not col.primary_key: if p.key in feature.properties: setattr(self, p.key, feature.properties[p.key]) if self.__add_properties__: for k in self.__add_properties__: setattr(self, k, feature.properties.get(k))
def read_one(request): layer = _get_layer_for_request(request) protocol = _get_protocol_for_layer(layer) feature_id = request.matchdict.get('feature_id', None) feature = protocol.read(request, id=feature_id) if not isinstance(feature, Feature): return feature if layer.public: return feature if request.user is None: raise HTTPNotFound() geom = feature.geometry if not geom or isinstance(geom, geojson.geometry.Default): # pragma: no cover return feature # pragma: no cover shape = asShape(geom) srid = _get_geom_col_info(layer)[1] spatial_elt = WKBSpatialElement(buffer(shape.wkb), srid=srid) allowed = DBSession.query( RestrictionArea.area.collect.gcontains(spatial_elt)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.area.area > 0) allowed = allowed.filter(Role.id == request.user.role.id) allowed = allowed.filter(Layer.id == layer.id).scalar() if not allowed: raise HTTPNotFound() return feature
def read_one(self): layer = self._get_layer_for_request() protocol = self._get_protocol_for_layer(layer) feature_id = self.request.matchdict.get('feature_id', None) feature = protocol.read(self.request, id=feature_id) if not isinstance(feature, Feature): return feature if layer.public: return feature if self.request.user is None: raise HTTPForbidden() geom = feature.geometry if not geom or isinstance( geom, geojson.geometry.Default): # pragma: no cover return feature shape = asShape(geom) srid = self._get_geom_col_info(layer)[1] spatial_elt = WKBSpatialElement(buffer(shape.wkb), srid=srid) none = None # the only way I found to remove the pep8 warning allowed = DBSession.query(func.count(RestrictionArea.id)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(Role.id == self.request.user.role.id) allowed = allowed.filter(Layer.id == layer.id) allowed = allowed.filter( or_(RestrictionArea.area == none, RestrictionArea.area.gcontains(spatial_elt))) if allowed.scalar() == 0: raise HTTPForbidden() return feature
def __update__(self, feature): geometry = feature.geometry if geometry is not None and \ not isinstance(geometry, Default): shape = asShape(feature.geometry) self.geom = WKBSpatialElement(buffer(shape.wkb), srid=4326) self.geom.shape = shape self.text = feature.properties.get('text', None)
def geom_filter(cls, geometry, geometryType, imageDisplay, mapExtent, tolerance): myFilter = None tolerance = tolerance*0.0254 scale = getScale(imageDisplay, mapExtent) if scale is None or (scale >= cls.__minscale__ and scale <= cls.__maxscale__): geom = esriRest2Shapely(geometry, geometryType) wkb_geometry = WKBSpatialElement(buffer(geom.wkb), 21781) geom_column = cls.geometry_column() myFilter = functions.within_distance(geom_column, wkb_geometry, tolerance) return myFilter
def create_geom_filter(request, mapped_class, geom_attr, within_distance_additional_params={}): """Create MapFish geometry filter based on the request params. Either a box or within or geometry filter, depending on the request params. Additional named arguments are passed to the spatial filter. Arguments: request the request. mapped_class the SQLAlchemy mapped class. geom_attr the key of the geometry property as defined in the SQLAlchemy mapper. If you use ``declarative_base`` this is the name of the geometry attribute as defined in the mapped class. within_distance_additional_params additional_params to pass to the ``within_distance`` function. """ tolerance = float(request.params.get('tolerance', 0.0)) epsg = None if 'epsg' in request.params: epsg = int(request.params['epsg']) box = request.params.get('bbox') geometry = None if box is not None: box = map(float, box.split(',')) geometry = Polygon( ((box[0], box[1]), (box[0], box[3]), (box[2], box[3]), (box[2], box[1]), (box[0], box[1]))) elif 'lon' and 'lat' in request.params: geometry = Point(float(request.params['lon']), float(request.params['lat'])) elif 'geometry' in request.params: geometry = loads(request.params['geometry'], object_hook=GeoJSON.to_instance) geometry = asShape(geometry) if geometry is None: return None column_epsg = _get_col_epsg(mapped_class, geom_attr) geom_attr = getattr(mapped_class, geom_attr) epsg = column_epsg if epsg is None else epsg if epsg != column_epsg: geom_attr = functions.transform(geom_attr, epsg) wkb_geometry = WKBSpatialElement(buffer(geometry.wkb), epsg) return functions._within_distance(geom_attr, wkb_geometry, tolerance, within_distance_additional_params)
def __copy_attributes(self, json_feature, obj): """Updates the passed-in object with the values from the GeoJSON feature.""" # create a Shapely geometry from GeoJSON and persist the geometry # using WKB shape = asShape(json_feature.geometry) srid = self.mapped_class.geometry_column().type.srid obj.geometry = WKBSpatialElement(buffer(shape.wkb), srid=srid) # also store the Shapely geometry so that we can use it to return the # geometry as GeoJSON and avoid a SELECT obj._mf_shape = shape for key in json_feature.properties: obj[key] = json_feature.properties[key]
def geom_filter(cls, geometry, geometryType, imageDisplay, mapExtent, tolerance): toleranceMeters = getToleranceMeters(imageDisplay, mapExtent, tolerance) scale = None minScale = cls.__minscale__ if hasattr(cls, '__minscale__') else None maxScale = cls.__maxscale__ if hasattr(cls, '__maxscale__') else None if minScale is not None and maxScale is not None and toleranceMeters != 0.0: scale = getScale(imageDisplay, mapExtent) if scale is None or (scale > cls.__minscale__ and scale <= cls.__maxscale__): geom = esriRest2Shapely(geometry, geometryType) wkbGeometry = WKBSpatialElement(buffer(geom.wkb), 21781) geomColumn = cls.geometry_column() geomFilter = functions.within_distance(geomColumn, wkbGeometry, toleranceMeters) return geomFilter return None
def create_geom_filter(request, mapped_class, **kwargs): """Create MapFish geometry filter based on the request params. Either a box or within or geometry filter, depending on the request params. Additional named arguments are passed to the spatial filter.""" tolerance = 0 if 'tolerance' in request.params: tolerance = float(request.params['tolerance']) epsg = None if 'epsg' in request.params: epsg = int(request.params['epsg']) box = None if 'bbox' in request.params: box = request.params['bbox'] geometry = None if box is not None: box = map(float, box.split(',')) geometry = Polygon( ((box[0], box[1]), (box[0], box[3]), (box[2], box[3]), (box[2], box[1]), (box[0], box[1]))) elif 'lon' and 'lat' in request.params: geometry = Point(float(request.params['lon']), float(request.params['lat'])) elif 'geometry' in request.params: factory = lambda ob: GeoJSON.to_instance(ob) geometry = loads(request.params['geometry'], object_hook=factory) geometry = asShape(geometry) if geometry is None: return None geom_column = mapped_class.geometry_column() epsg = geom_column.type.srid if epsg is None else epsg if epsg != geom_column.type.srid: geom_column = functions.transform(geom_column, epsg) wkb_geometry = WKBSpatialElement(buffer(geometry.wkb), epsg) if 'additional_params' in kwargs: return functions._within_distance(geom_column, wkb_geometry, tolerance, kwargs['additional_params']) else: return functions._within_distance(geom_column, wkb_geometry, tolerance)
def security_cb(r, feature, o): geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): shape = asShape(geom) srid = _get_geom_col_info(layer)[1] spatial_elt = WKBSpatialElement(buffer(shape.wkb), srid=srid) allowed = DBSession.query( RestrictionArea.area.collect.gcontains(spatial_elt)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.area.area > 0) allowed = allowed.filter(RestrictionArea.readwrite == True) allowed = allowed.filter(Role.id == request.user.role.id) allowed = allowed.filter(Layer.id == layer.id).scalar() if not allowed: raise HTTPForbidden()
def security_cb(r, feature, o): geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): shape = asShape(geom) srid = self._get_geom_col_info(layer)[1] spatial_elt = WKBSpatialElement(buffer(shape.wkb), srid=srid) none = None # the only way I found to remove the pep8 warning allowed = DBSession.query(func.count(RestrictionArea.id)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.readwrite == True) allowed = allowed.filter(Role.id == self.request.user.role.id) allowed = allowed.filter(Layer.id == layer.id) allowed = allowed.filter( or_(RestrictionArea.area == none, RestrictionArea.area.gcontains(spatial_elt))) if allowed.scalar() == 0: raise HTTPForbidden()
def security_cb(r, feature, o): # we need both the "original" and "new" geometry to be # within the restriction area geom_attr, srid = _get_geom_col_info(layer) geom_attr = getattr(o, geom_attr) and_clauses = [RestrictionArea.area.collect.gcontains(geom_attr)] geom = feature.geometry if geom and not isinstance(geom, geojson.geometry.Default): shape = asShape(geom) spatial_elt = WKBSpatialElement(buffer(shape.wkb), srid=srid) and_clauses.append( RestrictionArea.area.collect.gcontains(spatial_elt)) allowed = DBSession.query(and_(*and_clauses)) allowed = allowed.join(RestrictionArea.roles) allowed = allowed.join(RestrictionArea.layers) allowed = allowed.filter(RestrictionArea.area.area > 0) allowed = allowed.filter(RestrictionArea.readwrite == True) allowed = allowed.filter(Role.id == request.user.role.id) allowed = allowed.filter(Layer.id == layer.id).scalar() if not allowed: raise HTTPForbidden()
def test_envelope(self): eq_(b2a_hex(session.scalar(self.r.road_geom.envelope)), 'e610000001030000000100000005000000d7db0998302b56c036c921ded877454078a18c171a1c56c036c921ded877454078a18c171a1c56c0876f04983f8d4540d7db0998302b56c0876f04983f8d4540d7db0998302b56c036c921ded8774540') env = WKBSpatialElement(session.scalar(func.AsBinary(self.r.road_geom.envelope))) eq_(env.geom_type(session), 'Polygon') eq_(session.scalar(functions.wkt(functions.envelope('POINT(-88.5945861592357 42.9480095987261)'))), 'POLYGON((-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261,-88.5945861592357 42.9480095987261))')
def index(self): if "lat" in request.params: lat = float( request.params["lat"] ) else: return { "error": True, "message": "No \"lat\" parameter was found." } if "lon" in request.params: lon = float( request.params["lon"] ) else: return { "error": True, "message": "No \"lon\" parameter was found." } if "zoom" in request.params: zoom = int( request.params["zoom"] ) else: return { "error": True, "message": "No \"zoom\" parameter was found." } is_mobile = False if "mobile" in request.params: if request.params["mobile"] == "true": is_mobile = True point = Point(lon, lat) wkb_point = WKBSpatialElement( buffer( point.wkb ), 4326 ) meters_to_search = 1.8 if is_mobile: meters_to_search = 2.1 distance_meters = pow( meters_to_search, ( 20 - zoom ) ) tolerance = metersToDegrees( distance_meters, lat ) features = [] # # Query points first # # # These layers aren't visible until we hit zoom 9 # if zoom >= 9: # # Light Rail Stop query # lightRailFilter = func.ST_DWithin( wkb_point, LightRail.geometry_column(), tolerance ) lightRailQuery = Session.query( LightRail ).filter( lightRailFilter ) for row in lightRailQuery: feature = row.toFeature() feature.properties["feature_type"] = "Light Rail Stop" features.append( feature ) if len( features ) > 0: return FeatureCollection(features) if zoom >= 16: # # These layers aren't visible until we hit zoom 16 # # # Bar/Pub query # barPubFilter = func.ST_DWithin( wkb_point, BarPub.geometry_column(), tolerance ) barPubQuery = Session.query( BarPub ).filter ( barPubFilter ) for row in barPubQuery: feature = row.toFeature() feature.properties["feature_type"] = "Bar/Pub" features.append( feature ) if len( features ) > 0: return FeatureCollection( features ) # # Cafe query # cafeFilter = func.ST_DWithin( wkb_point, Cafe.geometry_column(), tolerance ) cafeQuery = Session.query( Cafe ).filter ( cafeFilter ) for row in cafeQuery: feature = row.toFeature() feature.properties["feature_type"] = "Cafe" features.append( feature ) if len( features ) > 0: return FeatureCollection( features ) # # Restaurant query # restaurantFilter = func.ST_DWithin( wkb_point, Restaurant.geometry_column(), tolerance ) restaurantQuery = Session.query( Restaurant ).filter ( restaurantFilter ) for row in restaurantQuery: feature = row.toFeature() feature.properties["feature_type"] = "Restaurant" features.append( feature ) if len( features ) > 0: return FeatureCollection( features ) # # Bicycle Rental query # bicycleRentalFilter = func.ST_DWithin( wkb_point, BicycleRental.geometry_column(), tolerance ) bicycleRentalQuery = Session.query( BicycleRental ).filter ( bicycleRentalFilter ) for row in bicycleRentalQuery: feature = row.toFeature() feature.properties["feature_type"] = "Bicycle Rental" features.append( feature ) if len( features ) > 0: return FeatureCollection( features ) # # If no points, query lines # # # Light Rail Line query # lightRailLineFilter = func.ST_DWithin( wkb_point, LightRailLine.geometry_column(), tolerance ) lightRailLineQuery = Session.query( LightRailLine ).filter( lightRailLineFilter ) for row in lightRailLineQuery: feature = row.toFeature() feature.properties["feature_type"] = "Light Rail Line" features.append( feature ) if len( features ) > 0: return FeatureCollection( features ) # # Free Bus query # freeBusFilter = func.ST_DWithin( wkb_point, FreeBus.geometry_column(), tolerance ) freeBusQuery = Session.query( FreeBus ).filter( freeBusFilter ) for row in freeBusQuery: feature = row.toFeature() feature.properties["feature_type"] = "Free Bus" features.append( feature ) if len( features ) > 0: return FeatureCollection( features ) return FeatureCollection( features )