根据坐标计算距离

时间:2019-06-01 16:47:50

标签: neo4j cypher

我的任务是计算距城市的道路总长度。我正在使用OSM数据。将其导入数据库后,我具有以下结构(对我来说这似乎是逻辑,但是如果您认为有更好的方法,我可以更改):

  • 每个骑行段(OSM XML中的路标)都有一个根节点,该根节点保存一个ID和一个类型(我也有其他类型,但现在它们已经不相关了)
  • 到根节点以“定义”关系连接到道路的第一个节点
  • 每个节点都通过名为“ connected”的关系连接到下一个节点,该关系具有属性“ entity_id”(即根节点id)。 (一个节点可以出现在更多的路段中,例如交叉路口,因此我试图避免使用具有此属性的圆形。

我对Neo4J很陌生。我只有SQL数据库方面的经验,但是基于此,我觉得即使我的方法行得通,也会失去查询语言的优势(指速度)。

这就是我到目前为止所拥有的,但是还差得远。它多次输出相同的数字(错误的数字),而不是一个总数。我很确定我没有完全理解 with ,但不知道解决方案是什么:

CREATE (t:Tmp {total:0})
with t
MATCH (e:Entity {type:'road'})
with collect(e) as es, t
    unwind es as entity
        match p = ()-[r:connected {entity_id:entity.int_id}]->()
        with entity, p,t 
        SET entity.lng = 0
        with entity, p, t
        unwind nodes(p) as nd
            with  t,nd,point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as point1, entity
                SET entity.lng = entity.lng + distance(entity.p, point1)
            with  t,nd,point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as point1, entity
                SET entity.p = point1
        with entity, t
        SET t.total = t.total + entity.lng
return t.total

1 个答案:

答案 0 :(得分:0)

您的查询返回的是每个节点的当前t.total结果,而不是总的总价值。而且似乎错误地计算了段中第一个节点的距离(第一个节点的距离应为0)。这也是非常低效的。例如,不必费心利用defines关系。在neo4j查询中,至关重要的是要利用关系的力量来避免扫描大量不相关的数据。

此外,没有提及特定的“城市”。您的查询针对所有Entity节点。如果您的数据库仅包含一个城市的Entity个节点,那就可以了。否则,您将需要修改查询以仅匹配特定城市的Entity个节点。

下面的查询可以使用defines关系来有效地匹配{{1}(根据我从您的问题中收集的信息,并假设您的数据库仅具有单个城市的数据)每个start段的}}节点,并使用该Entity节点有效地找到感兴趣的start节点:

connected

aggregating function MATCH (entity:Entity {type:'road'})-[:defines]->(start) MATCH p=(start)-[:connected* {entity_id:entity.id}]->(end) WHERE NOT EXISTS((end)-[:connected {entity_id:entity.id}]->()) SET entity.lng = 0 SET entity.p = point({longitude:toFloat(start.lon), latitude: toFloat(start.lat)}) WITH entity, p UNWIND TAIL(NODES(p)) AS nd WITH point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as pt, entity SET entity.lng = entity.lng + distance(entity.p, pt) SET entity.p = pt RETURN SUM(entity.lng) AS total 用于返回所有实体的总SUM()。不需要lng节点。 t子句仅匹配组成完整段的路径。该查询还将WHERE初始化为entity.p节点的point,并将start节点之后的UNWINDS节点初始化。

如果有许多start个节点,其值不是{road},而是Entity,那么您可能还想在type上创建一个index