Графические базы данных хорошо подходят для поиска путей, особенно с помощью shortestPath
, как упомянуто FrobberOfBits.
Это работает хорошо, если у вас есть узлы, которые могут образовывать путь. Из того, что я понимаю в ваших комментариях, на самом деле вам нужно будет создавать эти узлы динамически сначала в зависимости от предпочтений вождения пользователя.
Кроме того, по-видимому, в настоящее время у вас нет модели данных для точки A до точки B?
Это, как я хотел бы продолжить, кратко:
Прецедент является точка А мой дом, и точка 2, где живут Neo4j Community смотритель, на карте было бы:
Все маленькие белые точки в маршруте от А до В могут быть узлами 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
);
}
NB: Существует также функция haversin в Cypher для вычисления расстояния земли, я не играл так много с ней, хотя
Таким образом, вы можете добавить узел, который будет представлять желаемую позицию для девушки, чтобы присоединиться к поездке.
До сих пор мы теперь имеем 3 хороших узлов для Neo4j:
Теперь я думаю, что это будет до вашей модели данных для остальной части процесса, если маршрут от А до В не создавайте уже узлы Neo4j в своей базе данных, вы можете построить его динамически, вычислив расстояние от всех точек с помощью API Карт Google и установите его как свойство отношения. Затем вы можете сделать Cypher shortestPath и уменьшить свойство отношения расстояния.
Если у вас уже есть узлы, представляющие несколько промежуточных точек исходного маршрута от A до B, вы можете использовать Neo4j Spatial и получить ближайшую точку от желаемой позиции девушки до промежуточных узлов маршрута и создать связь с расстоянием. И снова shortestPath за лучший сопоставленный маршрут.
Второе решение было бы лучше, потому что вы будете немедленно иметь график, чтобы играть с:
И простой 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 для определения наилучшего маршрут, вам нужно помочь ему с некоторыми данными в базе данных ;-)
Можете ли вы уточнить, что вы подразумеваете под «отметкой маршрутов к нескольким точкам на карте»? Вы позже упомянете путь от А до В, но это всего лишь 2 очка. – cybersam