图形数据库非常适合用于路径查找,尤其是 FrobberOfBits 提到的 shortestPath。
只要您有可以形成路径的节点,这就会很好地工作。根据我对您的 cmets 的了解,实际上您需要首先根据用户驾驶偏好动态构建这些节点。
另外,显然您目前没有 A 点到 B 点的数据模型?
这就是我将如何进行,简单地说:
用例是点 A 是我的家,点 2 是 Neo4j 社区看护者的住所,在地图上应该是:
从A到B的路径中的所有小白点都可以是Neo4j节点。
现在您说,例如,有一个很棒的女孩,她的驾驶偏好为 50 公里,以便加入该路线,因此必须更改当前路线。
在您的应用程序中,您不会强迫用户选择一个中间点,您必须即时创建它。
所以我的快速解决方案是在半径上找到最接近初始路线目标点的点。
要实现它,首先你需要从女孩当前位置到目的地(这里是德累斯顿)的初始方位
其中lat1和lon1是女孩的位置,lat2、lon2是德累斯顿的位置
然后,给定这个初始方位,您可以计算从方位 bearing 和 50 公里距离中的女孩开始的位置,例如
在 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 函数用于计算地球距离,不过我没怎么玩过
因此,您可以添加一个节点来代表女孩想要的位置,以便加入旅行。
到目前为止,我们现在有 3 个适合 Neo4j 的节点:
现在我认为剩下的过程取决于您的数据模型,如果从 A 到 B 的路径尚未在您的数据库中形成 Neo4j 节点,您可以通过计算与所有节点的距离来动态构建它使用 Google Maps API 和设置的点作为关系属性。
然后你可以做一个 Cypher shortestPath 并减少关系距离属性。
如果您已经有代表从 A 到 B 的初始路线的多个中间点的节点,您可以使用 Neo4j Spatial 并获取从女孩所需位置到路线中间节点的最近点,并与距离。
再次为最佳映射路线的最短路径。
第二种解决方案会更好,因为您将立即拥有一个图表来玩:
如果您想获得公里数最少的路径,还有一个简单的 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 来确定最好的
路线,你需要帮助他处理数据库中的一些数据;-)