使用neo4j查找/导航

时间:2015-06-06 16:31:14

标签: php neo4j

我知道我可能因为问这个问题而被责骂但我希望有人可以帮我指出正确的方向。

我正在尝试创建一种寻找谷歌地图应用程序的方法,但是它会将路线标记到地图上的多个点。

我正在尝试制作一种动物运输工具,允许多人在从A点到B点的路径中相遇。我想我读过你可以用图表数据库来做这件事。

有人可以提供地图数据库,文章等方面的资源来帮助我吗?我一直试图谷歌搜索文章,但可以找到任何匹配,所以我假设我使用错误的术语,如'寻找'或'方向'

谢谢!

3 个答案:

答案 0 :(得分:4)

图形数据库适用于路径查找,尤其是FrobberOfBits提到的shortestPath

只要您有可以形成路径的节点,这就可以正常工作。根据我在您的评论中的理解,实际上您需要根据用户的驾驶偏好动态地动态构建这些节点。

另外,显然你目前没有点A到点B的数据模型?

这是我将如何继续,简要说明:

用例是A点是我的家,第2点是Neo4j Community CareTaker的地方,它将在地图上显示:

enter image description here

从A到B的路线中的所有小白点都可以是Neo4j节点。

现在你说,例如,为了加入这条路线,有一个驾驶偏好为50公里的女孩,所以目前的路线必须改变。

enter image description here

在您的应用程序中,您不会强制用户选择中间点,您必须动态创建它。

所以我的快速解决方案是获得最接近初始路线目的地点的半径点。

要实现它,首先你需要从女孩当前位置到目的地的初始方位(这里是德累斯顿)

其中lat1和lon1是女孩的位置,而lat2,lon2是德累斯顿的位置

然后,给定这个初始方位,您可以计算从女孩开始的位置bearing50公里距离,例如

在PHP中看起来像(测试过):

// Function that calculate new coordinates from point A
// Given a bearing and a distance to point B
function getAwayPosition($lat1, $lon1, $lat2, $lon2, $distance)
{
    // Getting true course from point A to point B
    $la1 = deg2rad($lat1);
    $la2 = deg2rad($lat2);
    $lo1 = deg2rad($lon1);
    $lo2 = deg2rad($lon2);

    $y = sin($la2-$la1)*cos($lo1);
    $x = cos($lo1*sin($lo2))-sin($lo1)*cos($lo2)*cos($la2-$la1);
    $course = fmod(rad2deg(atan2($y, $x)+360), 360);

    // Getting the new lat/lon points from lat1/lon1 given the course and the distance
    $bearing = deg2rad($course); //back to radians for the coordinates calculation
    $laa = asin(sin($la1 * cos($distance/6371 + $la1 * cos($course))));
    $loo = $lo1 + atan2(sin($bearing) * sin($distance/6371) * cos($la1), cos($distance/6371) - sin($la1) * sin($laa));

    return array(
        'lat' => rad2deg($laa),
        'lon' => rad2deg($loo),
        'bearing' => $course
    );
}

注意:Cypher中还有haversin函数用于计算地球距离,虽然我没有那么多玩法

因此,您可以添加一个节点,代表该女孩所需的位置,以便加入此行程。

到目前为止,我们现在为Neo4j提供了3个好的节点:

enter image description here

现在我认为这将取决于您的数据模型,如果从A到B的路由没有在数据库中形成Neo4j节点,您可以通过计算距离所有节点的距离动态构建它使用Google Maps API设置的点数为关系属性。 然后你可以做一个Cypher shortestPath并减少关系距离属性。

如果您已经有节点代表从A到B的初始路线的多个中间点,您可以使用Neo4j Spatial并从女孩的所需位置到路线的中间节点获得最近的点,并与之建立关系距离。 并且再次使用shortestPath作为最佳映射路径。

第二种解决方案会更好,因为你会立即得到一个图表:

enter image description here

如果你想获得最小公里数的路径,那就是一个简单的Cypher查询:

MATCH (a:Point {id:'A'}), (b:Point {id:'B'})
MATCH p=allShortestPaths((a)-[:NEXT_POINT]-(b))
RETURN p, reduce(totalKm = 0, x in relationships(p)| totalKm + x.kilometers) as distance
ORDER BY distance ASC

还有一种具有成本属性的Djikstra算法,可用于Neo4j ReST API http://neo4j.com/docs/stable/rest-api-graph-algos.html

一些资源:

  

所以作为结论,如果你想用Neo4j来确定最好的   路线,你需要帮助他掌握数据库中的一些数据; - )

答案 1 :(得分:3)

您似乎描述的是通过不同路点(人员的位置)从A到B的路线,但目标是从A到B的总距离最小化。具有这些特征的图中的路径称为Minimum Spanning Tree。至关重要的是,人们可以去旅行以满足主要路线#34;简单介绍其他方法点,它不会改变整体问题,也不会改变它的经典解决方式。

Cypher和REST API都没有计算最小生成树的功能,不幸的是,只是收集各个节点之间的最短路径(例如使用Dijkstra算法),然后尝试从这些最短路径段创建路径将在一般情况下不是最佳的。

然而,通过Neo4j中的服务器插件或非托管扩展来实现Prim's algorithm并不困难,我建议你研究一下。

答案 2 :(得分:2)

start with this article。要提出更具体的问题,您需要一个数据模型以及您尝试做的事情的示例。

但一般来说,使用的语言可能是"最短路径"。一般来说,如果您正在尝试找到从A点到B点的路径,那么您正在寻找"最短路径"其中"路径成本"是最小的。有时费用是距离,有时费用是时间 - 但无论哪种方式,你通常都会寻找最短的路径,而不仅仅是寻找任何路径。