apoc.algo.PathFindingUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apoc-common Show documentation
Show all versions of apoc-common Show documentation
Data types package for Neo4j Procedures
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package apoc.algo;
import apoc.path.RelationshipTypeAndDirections;
import org.apache.commons.lang3.tuple.Pair;
import org.neo4j.graphalgo.EstimateEvaluator;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PathExpander;
import org.neo4j.graphdb.PathExpanderBuilder;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.values.storable.PointValue;
public class PathFindingUtils {
public static class GeoEstimateEvaluatorPointCustom implements EstimateEvaluator {
// -- from org.neo4j.graphalgo.impl.util.GeoEstimateEvaluator
private static final double EARTH_RADIUS = 6371 * 1000; // Meters
private Node cachedGoal;
private final String pointPropertyKey;
private double[] cachedGoalCoordinates;
public GeoEstimateEvaluatorPointCustom(String pointPropertyKey) {
this.pointPropertyKey = pointPropertyKey;
}
@Override
public Double getCost(Node node, Node goal) {
double[] nodeCoordinates = getCoordinates(node);
if (cachedGoal == null || !cachedGoal.equals(goal)) {
cachedGoalCoordinates = getCoordinates(goal);
cachedGoal = goal;
}
return distance(nodeCoordinates[0], nodeCoordinates[1], cachedGoalCoordinates[0], cachedGoalCoordinates[1]);
}
private static double distance(double latitude1, double longitude1, double latitude2, double longitude2) {
latitude1 = Math.toRadians(latitude1);
longitude1 = Math.toRadians(longitude1);
latitude2 = Math.toRadians(latitude2);
longitude2 = Math.toRadians(longitude2);
double cLa1 = Math.cos(latitude1);
double xA = EARTH_RADIUS * cLa1 * Math.cos(longitude1);
double yA = EARTH_RADIUS * cLa1 * Math.sin(longitude1);
double zA = EARTH_RADIUS * Math.sin(latitude1);
double cLa2 = Math.cos(latitude2);
double xB = EARTH_RADIUS * cLa2 * Math.cos(longitude2);
double yB = EARTH_RADIUS * cLa2 * Math.sin(longitude2);
double zB = EARTH_RADIUS * Math.sin(latitude2);
return Math.sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB) + (zA - zB) * (zA - zB));
}
// -- end from org.neo4j.graphalgo.impl.util.GeoEstimateEvaluator
private double[] getCoordinates(Node node) {
return ((PointValue) node.getProperty(pointPropertyKey)).coordinate();
}
}
public static PathExpander buildPathExpander(String relationshipsAndDirections) {
PathExpanderBuilder builder = PathExpanderBuilder.empty();
for (Pair pair : RelationshipTypeAndDirections.parse(relationshipsAndDirections)) {
if (pair.getLeft() == null) {
if (pair.getRight() == null) {
builder = PathExpanderBuilder.allTypesAndDirections();
} else {
builder = PathExpanderBuilder.allTypes(pair.getRight());
}
} else {
if (pair.getRight() == null) {
builder = builder.add(pair.getLeft());
} else {
builder = builder.add(pair.getLeft(), pair.getRight());
}
}
}
return builder.build();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy