示例#1
0
    def delete_layer(self, layer_name):
        """ Remove a GIS map Layer.

        .. note ::
            There is no Resource for this action so in the meantime we
            use the core py2neo cypher api.

        This will remove a representation of a GIS map Layer from the Neo4j
        data store - it will not remove any nodes you may have added to it.

        The operation removes the layer data from the internal GIS R-tree
        model and removes the layer's label from all nodes that exist on it.
        It does not destroy any Nodes on the DB - use the standard py2neo
        library for these actions.

        :Raises:
            LayerNotFoundError if the index does not exist.

        """
        if not self._layer_exists(layer_name):
            raise LayerNotFoundError(
                'Layer Not Found: "{}"'.format(layer_name))

        graph = self.graph

        # remove labels and properties on Nodes relating to this layer
        query = ("MATCH (n:{layer_name}) "
                 "REMOVE n:{default_label} "
                 "REMOVE n:{layer_name} "
                 "REMOVE n:{point_label} "
                 "REMOVE n:{multipolygon_label} "
                 "REMOVE n.{internal_name}".format(
                     layer_name=layer_name,
                     default_label=DEFAULT_LABEL,
                     point_label=POINT,
                     multipolygon_label=MULTIPOLYGON,
                     internal_name=NAME_PROPERTY))

        graph.cypher.execute(query)

        # remove the bounding box, metadata and root from the rtree index
        query = (
            "MATCH (l { layer:{layer_name} })-[r_layer:LAYER]-(), "
            "(metadata)<-[r_meta:RTREE_METADATA]-(l), "
            "()-[locate_rel:LOCATES]-(geometry_node)-[r_ref:RTREE_REFERENCE]-"
            "(bounding_box)-[r_root:RTREE_ROOT]-(l) "
            "DELETE locate_rel, r_meta, r_layer, r_ref, r_root, "
            "metadata, geometry_node, bounding_box, l")

        params = {'layer_name': layer_name}

        graph.cypher.execute(query, params)
示例#2
0
    def delete_geometry(self, geometry_name, wkt_string, layer_name):
        """ Remove a geometry node from a GIS map layer.

        .. note ::
            There is no Resource for this action so in the meantime we
            use the core py2neo cypher api.

        :Params:
            geometry_name : str
                The unique name of the geometry to delete.
            wkt_string : str
                A Well Known Text string of any geometry
            layer_name : str
                The name of the layer/index to remove the geometry from.

        :Raises:
            LayerNotFoundError if the index does not exist.
            InvalidWKTError if the WKT cannot be read.

        """
        if not self._layer_exists(layer_name):
            raise LayerNotFoundError(
                'Layer Not Found: "{}"'.format(layer_name))

        graph = self.graph
        shape = self._get_shape_from_wkt(wkt_string)

        # remove the node from the graph
        match = "MATCH (n:{label}".format(label=shape.type)
        query = match + ("{ _py2neo_geometry_name:{geometry_name} }) "
                         "OPTIONAL MATCH n<-[r]-() "
                         "DELETE r, n")
        params = {
            'label': shape.type,
            'geometry_name': geometry_name,
        }
        graph.cypher.execute(query, params)

        # tidy up the index. This will remove the node,
        # it's bounding box node, and the relationship between them.
        query = ("MATCH (l { layer:{layer_name} }), "
                 "(n { wkt:{wkt} })-[ref:RTREE_REFERENCE]-() "
                 "DELETE ref, n")
        params = {
            'layer_name': layer_name,
            'wkt': shape.wkt,
        }
        graph.cypher.execute(query, params)
示例#3
0
文件: plugin.py 项目: LiuYuQ/beifen
    def find_within_distance(self, layer_name, coords, distance):
        """ Find all points of interest (poi) within a given distance from
        a lat-lon location coord.

        :Params:
            layer_name : str
                The name of the layer/index to remove the geometry from.
            coords : tuple
                WGS84 (EPSG 4326) lat, lon pair
                Latitude is a decimal number between -90.0 and 90.0
                Longitude is a decimal number between -180.0 and 180.0
            distance : int
                The radius of the search area in Kilometres (km)

        :Raises:
            LayerNotFoundError if the index does not exist.

        :Returns:
            a list of all matched nodes

        """
        if not self._layer_exists(layer_name):
            raise LayerNotFoundError(
                'Layer Not Found: "{}"'.format(layer_name))

        resource = self.resources['findGeometriesWithinDistance']
        shape = parse_lat_long(coords)
        spatial_data = {
            'pointX': shape.x,
            'pointY': shape.y,
            'layer': layer_name,
            'distanceInKm': distance,
        }

        nodes = self._execute_spatial_request(resource, spatial_data)
        return nodes
示例#4
0
文件: plugin.py 项目: LiuYuQ/beifen
    def create_geometry(self,
                        geometry_name,
                        wkt_string,
                        layer_name,
                        labels=None,
                        node_id=None,
                        spatial_id=None):
        """ Create a geometry of type Well Known Text (WKT).

        Internally this creates a node in your graph with a wkt property
        and also adds it to a GIS map layer (an index). Optionaly add
        Labels to the Node.

        :Params:
            geometry_name : str
                A unique name for the geometry.
            wkt_string : str
                A Well Known Text string of any geometry
            layer_name : str
                The name of the layer to add the geometry to.
            labels : list
                Optional list of Label names to apply to the geometry Node.

            node_id : int
                Optional - the internal ID used by neo4j to uniquely identify
                a Node. When provided, an update operation in the application
                graph will be carried out instead of the usual create, making
                this Node spatially aware by adding a 'wkt' property to it.
                It is then added to the Layer (indexed) as normal.

        :Raises:
            LayerNotFoundError if the index does not exist.
            InvalidWKTError if the WKT cannot be read.

        """
        if not self._layer_exists(layer_name):
            raise LayerNotFoundError(
                'Layer Not Found: "{0}".',
                'Use ``create_layer(layer_name="{0}"")`` first.'.format(
                    layer_name))

        shape = self._get_shape_from_wkt(wkt_string)

        if self._geometry_exists(shape, geometry_name):
            raise GeometryExistsError(
                'geometry already exists. ignoring request.')

        graph = self.graph
        resource = self.resources['addGeometryWKTToLayer']

        labels = labels or []
        labels.extend([DEFAULT_LABEL, layer_name, shape.type])
        wkt = self._get_wkt_from_shape(shape)

        params = {
            NAME_PROPERTY: geometry_name,
        }

        if node_id:
            query = 'MATCH (n) WHERE id(n) = {node_id} RETURN n'
            params = {'node_id': node_id}
            results = graph.cypher.execute(query, params)
            if not results:
                raise NodeNotFoundError('Node not found: "{}"'.format(node_id))

            record = results[0]
            node = record[0]
            node[NAME_PROPERTY] = geometry_name
            node.add_labels(*tuple(labels))
            node.push()

        else:
            node = Node(*labels, **params)
            graph.create(node)

        spatial_data = {
            'geometry': wkt,
            'layer': layer_name,
        }

        resource.post(spatial_data)

        # now relate the geometry to our application node
        query = (
            "MATCH (l { layer:{layer_name} })<-[r_layer:LAYER]-"
            "(root { name:'spatial_root' }), "
            "(bbox)-[r_root:RTREE_ROOT]-(l), "
            "(geometry_node)-[r_ref:RTREE_REFERENCE]-(bbox), "
            "(application_node { _py2neo_geometry_name:{geometry_name} }) "
            "WHERE geometry_node.wkt = {wkt} "
            "CREATE UNIQUE (geometry_node)-[:LOCATES]->(application_node)")

        params = {
            'wkt': wkt,
            'layer_name': layer_name,
            'geometry_name': geometry_name,
        }

        graph.cypher.execute(query, params)