Beispiel #1
0
 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")
Beispiel #2
0
 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')
Beispiel #3
0
 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)')
Beispiel #4
0
 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))'
     )
Beispiel #5
0
    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))
Beispiel #6
0
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
Beispiel #7
0
    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
Beispiel #8
0
 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)
Beispiel #9
0
 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
Beispiel #10
0
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)
Beispiel #11
0
 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]
Beispiel #12
0
 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
Beispiel #13
0
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)
Beispiel #14
0
 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()
Beispiel #15
0
 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()
Beispiel #16
0
 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()
Beispiel #17
0
 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))')
Beispiel #18
0
 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 )