Neo4j Spatial使用指南(一)

  • Post author:
  • Post category:其他




译者声明

你好!

本中文版Neo4j Spatial使用指南仅供学习交流使用而翻译,转载请注明出处,所有权利归原作者。

译者才疏学浅,还在学习中,欢迎捉虫指正和讨论!

这篇中文指南基于

Neo4j Spatial v0.24-neo4j-3.1.4

文档翻译。



引言 Introduction

Neo4j Spatial是Neo4j的实用程序库,它可以便利地对数据进行空间操作,尤其是对已定位数据添加空间索引,并对数据执行空间操作。比如说,您可以在指定区域内或兴趣点指定距离内搜索数据。

此外,Neo4j Spatial还提供了一些类,这些类可以将数据传送到GeoTools。借此,GeoTools可以将数据提供给支持GeoTools的应用程序使用,如GeoServer和uDig。

在这里插入图片描述

Neo4j Spatial的主要功能包括:

  • 导入数据的实用程序(Utilities):能导入ESRI Shapefile以及Open Street Map文件数据;
  • 支持所有常见的几何类型:点(Point),线串(LineString),多边形(Polygon)等;
  • RTree索引,可快速搜索几何图形;
  • 支持搜索过程中的拓扑操作(包含contains,内部within,相交intersects,覆盖covers,不相交disjoint等)
  • 无论怎样存储空间数据,只要能为地图提供从图谱(graph)到几何图形(geometries)的提供适配器,Neo4j Spatial就可以在任何数据图上启用空间操作;
  • Neo4j Spatial能够使用预先配置的过滤器,将单个层或数据集拆分为多个子层(sub-layers)或视图(views)。



开始使用 Get Started

开始使用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的简单示例。



索引和查询 Index and Querying

Neo4j Spatial当前使用的索引是RTree,但它已经以可扩展的方式开发过,如有必要,允许添加其他索引。



加载和索引 Loading and Indexing

在加载过程中,可以将数据导入到数据库中,然后将其添加到索引中。稍后也可以将现有空间数据添加到索引。这是两种截然不同的场景,实际上会产生不同的图结构,我们将依次对这两种情况进行解释。

要将数据直接加载到索引中,最简单的方法是从创建适合您数据的图层(Layer)开始。 Neo4j-Spatial内置了许多可能的选项,而两个常见的选项是:

  • SimplePointLayer – 一个可编辑的层,仅允许您将点添加到数据库。如果您只有点数据并且主要对邻近搜索感兴趣,那么这是一个不错的选择。该层包括专门针对该情况的实用程序方法。
  • EditableLayer(Impl)- 这是默认的可编辑图层实现接口(the default editable layer implementation),可以处理任何类型的简单几何。简单几何包括Point,LineString和Polygon,以及Multi-Point,Multi-LineString和Multi-Polygon。由于它是通用实现接口,并且无法了解数据模型的拓扑,因此它将每个几何图形分别存储在单个节点的单个属性中。存储格式为WKB(Well Known Binary),这是一种针对地理几何的二进制格式。流行的开源空间数据库PostGIS也使用这种格式。



图层和几何编码器 Layers and GeometryEncoders

定义几何集合的主要类型是图层。图层包含用于查询的索引。此外,如果可以在图层中添加和修改几何图形,则该图层可以是可编辑图层,即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过程 Neo4j Spatial Procedures

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?)”