你好! 本中文版Neo4j Spatial使用指南仅供学习交流使用而翻译,转载请注明出处,所有权利归原作者。 译者才疏学浅,还在学习中,欢迎捉虫指正和讨论!
这篇中文指南基于Neo4j Spatial v0.24-neo4j-3.1.4文档翻译。
Neo4j Spatial是Neo4j的实用程序库,它可以便利地对数据进行空间操作,尤其是对已定位数据添加空间索引,并对数据执行空间操作。比如说,您可以在指定区域内或兴趣点指定距离内搜索数据。
此外,Neo4j Spatial还提供了一些类,这些类可以将数据传送到GeoTools。借此,GeoTools可以将数据提供给支持GeoTools的应用程序使用,如GeoServer和uDig。
Neo4j Spatial的主要功能包括:
开始使用neo4j-spatial的最简单方法是从最新版本中获取server-plugin-*。jar,将其复制到$ NEO4J_HOME / plugins并重新启动Neo4j服务器。
在那里,您可以在Cypher查询中使用所有Neo4j Spatia过程(Neo4j Spatial Procedures,见第四节)将结点(Node)添加到空间索引中,并执行许多空间点,距离和交叉点查询操作。
Simple Example
//Simple Example
CALL spatial.addPointLayer('geom');
CALL spatial.layers();
CREATE (n:Node {latitude:60.1,longitude:15.2})
WITH n
CALL spatial.addNode('geom',n) YIELD node
RETURN node;
CALL spatial.bbox('geom',{lon:15.0,lat:60.0}, {lon:15.3, lat:61.0});
接下来是三篇示例文章。
一篇很好的示例博客文章:关于如何用一种neo4j驱动程序使用这些过程,由William Lyon在(Part 1)撰写的Spatial Procedures in Legis Graph。
Max de Marzi在他的两篇关于餐厅推荐的博客文章中解释了如何使用Neo4j Spatial Server插件。
Craig Taverner在博客文章中对Neo4j Spatial进行了简单介绍,并做了有关如何使用Spatial Java API的简单示例。
Neo4j Spatial当前使用的索引是RTree,但它已经以可扩展的方式开发过,如有必要,允许添加其他索引。
在加载过程中,可以将数据导入到数据库中,然后将其添加到索引中。稍后也可以将现有空间数据添加到索引。这是两种截然不同的场景,实际上会产生不同的图结构,我们将依次对这两种情况进行解释。
要将数据直接加载到索引中,最简单的方法是从创建适合您数据的图层(Layer)开始。 Neo4j-Spatial内置了许多可能的选项,而两个常见的选项是:
定义几何集合的主要类型是图层。图层包含用于查询的索引。此外,如果可以在图层中添加和修改几何图形,则该图层可以是可编辑图层,即EditableLayer。
下一个最重要的接口是几何编码器,即GeometryEncoder。
DefaultLayer是标准层,利用WKBGeometryEncoder将所有几何类型存储为每个几何实例一个节点的byte []属性。
OSMLayer是一种特殊层,可以支持Open Street Map并将OSM模型存储为单个完全连接的图形。该层提供的几何集包括Points, LineStrings和Polygons,从而不能导出为Shapefile格式,因为该格式仅允许每层一个几何。但是,OMSLayer继承了DynamicLayer,这使得OMSLayer可以提供任意数量的子层,每个子层都基于一个OSM标签过滤器(OSM tag filter),具有特定的几何类型。例如,您可以创建一个以LineStrings形式绘制所有自行车道的层,或一个以Polygons形式绘制所有湖泊的层。在它们的下方,它们仍然由相同的完全连接的图支持,但是作为明显独立的几何层动态展示。
Neo4j Spatial也被打包成了ZIP文件,可以解压缩到Neo4j服务器的$NEO4J_HOME/plugins目录中。重新启动服务器后,您应该能够使用以下来自Cypher查询语言的过程调用。
Table 1. Available Spatial Procedures
name | description | signature |
---|---|---|
“spatial.addLayer” | “Adds a new layer with the given type (see spatial.getAllLayerTypes) and configuration, returns the layer root node” | “spatial.addLayer(name :: STRING?, type :: STRING?, encoderConfig :: STRING?) :: (node :: NODE?)” |
“spatial.addLayerWithEncoder” | “Adds a new layer with the given encoder class and configuration, returns the layer root node” | “spatial.addLayerWithEncoder(name :: STRING?, encoder :: STRING?, encoderConfig :: STRING?) :: (node :: NODE?)” |
“spatial.addNode” | “Adds the given node to the layer, returns the geometry-node” | “spatial.addNode(layerName :: STRING?, node :: NODE?) :: (node :: NODE?)” |
“spatial.addNodes” | “Adds the given nodes list to the layer, returns the count” | “spatial.addNodes(layerName :: STRING?, nodes :: LIST? OF NODE?) :: (count :: INTEGER?)” |
“spatial.addPointLayer” | “Adds a new simple point layer, returns the layer root node” | “spatial.addPointLayer(name :: STRING?) :: (node :: NODE?)” |
“spatial.addPointLayerWithConfig” | “Adds a new simple point layer with the given configuration, returns the layer root node” | “spatial.addPointLayerWithConfig(name :: STRING?, encoderConfig :: STRING?) :: (node :: NODE?)” |
“spatial.addPointLayerXY” | “Adds a new simple point layer with the given properties for x and y coordinates, returns the layer root node” | “spatial.addPointLayerXY(name :: STRING?, xProperty :: STRING?, yProperty :: STRING?) :: (node :: NODE?)” |
“spatial.addWKT” | “Adds the given WKT string to the layer, returns the created geometry node” | “spatial.addWKT(layerName :: STRING?, geometry :: STRING?) :: (node :: NODE?)” |
“spatial.addWKTLayer” | “Adds a new WKT layer with the given node property to hold the WKT string, returns the layer root node” | “spatial.addWKTLayer(name :: STRING?, nodePropertyName :: STRING?) :: (node :: NODE?)” |
“spatial.addWKTs” | “Adds the given WKT string list to the layer, returns the created geometry nodes” | “spatial.addWKTs(layerName :: STRING?, geometry :: LIST? OF STRING?) :: (node :: NODE?)” |
“spatial.asExternalGeometry” | “Returns a geometry object as an external geometry type to be returned to a client” | “spatial.asExternalGeometry(geometry :: ANY?) :: (geometry :: ANY?)” |
“spatial.asGeometry” | “Returns a geometry object as an internal cypher geometry type, to be passed to other procedures but not returned to a client” | “spatial.asGeometry(geometry :: ANY?) :: (geometry :: ANY?)” |
“spatial.bbox” | “Finds all geometry nodes in the given layer within the lower left and upper right coordinates of a box” | “spatial.bbox(layerName :: STRING?, min :: ANY?, max :: ANY?) :: (node :: NODE?)” |
“spatial.closest” | “Finds all geometry nodes in the layer within the distance to the given coordinate” | “spatial.closest(layerName :: STRING?, coordinate :: ANY?, distanceInKm :: FLOAT?) :: (node :: NODE?)” |
“spatial.decodeGeometry” | “Returns a geometry of a layer node as internal cypher geometry type, to be passed to other procedures but not returned to a client” | “spatial.decodeGeometry(layerName :: STRING?, node :: NODE?) :: (geometry :: ANY?)” |
“spatial.getFeatureAttributes” | “Returns feature attributes of the given layer” | “spatial.getFeatureAttributes(name :: STRING?) :: (name :: STRING?)” |
“spatial.importOSM” | “Imports the the provided osm-file from URI to a layer of the same name, returns the count of data added” | “spatial.importOSM(uri :: STRING?) :: (count :: INTEGER?)” |
“spatial.importOSMToLayer” | “Imports the the provided osm-file from URI to a layer, returns the count of data added” | “spatial.importOSMToLayer(layerName :: STRING?, uri :: STRING?) :: (count :: INTEGER?)” |
“spatial.importShapefile” | “Imports the the provided shape-file from URI to a layer of the same name, returns the count of data added” | “spatial.importShapefile(uri :: STRING?) :: (count :: INTEGER?)” |
“spatial.importShapefileToLayer” | “Imports the the provided shape-file from URI to the given layer, returns the count of data added” | “spatial.importShapefileToLayer(layerName :: STRING?, uri :: STRING?) :: (count :: INTEGER?)” |
“spatial.intersects” | “Returns all geometry nodes that intersect the given geometry (shape, polygon) in the layer” | “spatial.intersects(layerName :: STRING?, geometry :: ANY?) :: (node :: NODE?)” |
“spatial.layer” | “Returns the layer root node for the given layer name” | “spatial.layer(name :: STRING?) :: (node :: NODE?)” |
“spatial.layerTypes” | “Returns the different registered layer types” | “spatial.layerTypes() :: (name :: STRING?, signature :: STRING?)” |
“spatial.layers” | “Returns name, and details for all layers” | “spatial.layers() :: (name :: STRING?, signature :: STRING?)” |
“spatial.procedures” | “Lists all spatial procedures with name and signature” | “spatial.procedures() :: (name :: STRING?, signature :: STRING?)” |
“spatial.removeLayer” | “Removes the given layer” | “spatial.removeLayer(name :: STRING?) :: VOID” |
“spatial.setFeatureAttributes” | “Sets the feature attributes of the given layer” | “spatial.setFeatureAttributes(name :: STRING?, attributeNames :: LIST? OF STRING?) :: (node :: NODE?)” |
“spatial.updateFromWKT” | “Internal procedure, updates the geometry node with the given id with a new WKT string” | “spatial.updateFromWKT(layerName :: STRING?, geometry :: STRING?, geometryNodeId :: INTEGER?) :: (node :: NODE?)” |
“spatial.withinDistance” | “Returns all geometry nodes and their ordered distance in the layer within the distance to the given coordinate” | “spatial.withinDistance(layerName :: STRING?, coordinate :: ANY?, distanceInKm :: FLOAT?) :: (node :: NODE?, distance :: FLOAT?)” |