Skip to content

Commit

Permalink
refactor tile connect/disconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
mg4gh committed May 11, 2024
1 parent 027a602 commit 2f89a33
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 266 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,10 @@ MultiPointModelImpl calcRouting(RoutePointModel source, RoutePointModel target,

sourceApproachModel = validateApproachModel(source.selectedApproach);
targetApproachModel = validateApproachModel(target.selectedApproach);
multi.connect(gStart,sourceApproachModel.getNode1());
multi.connect(gStart,sourceApproachModel.getNode2());
multi.connect(gEnd,targetApproachModel.getNode1());
multi.connect(gEnd,targetApproachModel.getNode2());
gStart.bidirectionalConnect(sourceApproachModel.getNode1());
gStart.bidirectionalConnect(sourceApproachModel.getNode2());
gEnd.bidirectionalConnect(targetApproachModel.getNode1());
gEnd.bidirectionalConnect(targetApproachModel.getNode2());

double distLimit = Math.min(routingContext.maxBeelineDistance, routingContext.maxRouteLengthFactor * routingProfile.heuristic(gStart, gEnd) + 500);

Expand Down
106 changes: 2 additions & 104 deletions mgmap/src/main/java/mg/mgmap/generic/graph/GGraphMulti.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
*/
package mg.mgmap.generic.graph;

import mg.mgmap.generic.model.WriteablePointModel;
import mg.mgmap.generic.model.WriteablePointModelImpl;
import mg.mgmap.generic.util.basic.MGLog;
import mg.mgmap.generic.model.PointModelUtil;
import mg.mgmap.generic.util.basic.MemoryUtil;

import java.lang.invoke.MethodHandles;
Expand All @@ -34,14 +31,12 @@ public class GGraphMulti extends GGraph {
private static final MGLog mgLog = new MGLog(MethodHandles.lookup().lookupClass().getName());

private final GGraphTileFactory gGraphTileFactory;
// ArrayList<GOverlayNeighbour> overlayNeighbours = new ArrayList<>(); // used for neighbour tile connections and for approaches
private int useCnt = 0;

public GGraphMulti(GGraphTileFactory gGraphTileFactory, ArrayList<GGraphTile> gGraphTiles){
this.gGraphTileFactory = gGraphTileFactory;
for (GGraphTile gGraphTile : gGraphTiles){
use(gGraphTile);
connectGGraphTile(gGraphTile);
}
}

Expand All @@ -50,10 +45,8 @@ public int getTileCount(){
}

/**
* Redefines getNodes() implementation og GGraph, which simply returns the ArrayList of its nodes.
* Here we get a new ArrayList Object with all nodes from each included GGraphTile plus additionally the
* nodes that were created due to connecting neighbour GGraphTile instances, plus the additional
* overlay nodes from approaches for start and end point of a routing access.
* Redefines getNodes() implementation of GGraph, which simply returns the ArrayList of its nodes.
* Here we get a new ArrayList Object with all nodes from each included GGraphTile
* @return all node ot the multi graph
*/
@Override
Expand Down Expand Up @@ -102,109 +95,14 @@ private boolean checkGGraphTileNeighbour(GNode node, byte border){
if (gGraphTileNeighbour == null){
mgLog.d(String.format(Locale.ENGLISH, "border=%d tileX=%d tileY=%d",border,tileXn,tileYn));
gGraphTileNeighbour = gGraphTileFactory.getGGraphTile(tileXn, tileYn, true);
connectGGraphTile(gGraphTileNeighbour);
bRes = true;
} else if (!gGraphTileNeighbour.used){
connectGGraphTile(gGraphTileNeighbour);
}
use(gGraphTileNeighbour);
}

return bRes;
}

private void connectGGraphTile(GGraphTile newGGraphTile){
connectTiles(gGraphTileFactory.getGGraphTile(newGGraphTile.getTileX()-1,newGGraphTile.getTileY(), false), newGGraphTile, true);
connectTiles(newGGraphTile, gGraphTileFactory.getGGraphTile(newGGraphTile.getTileX()+1,newGGraphTile.getTileY(),false), true);
connectTiles(gGraphTileFactory.getGGraphTile(newGGraphTile.getTileX(),newGGraphTile.getTileY()-1, false), newGGraphTile, false);
connectTiles(newGGraphTile, gGraphTileFactory.getGGraphTile(newGGraphTile.getTileX(),newGGraphTile.getTileY()+1, false), false);
}

private void connectTiles(GGraphTile gGraphTile1, GGraphTile gGraphTile2,boolean horizontal){ // horizontal true: gGraphTile1 is left, gGraphTile2 is right - false: gGraphTile1 is above, gGraphTile2 is below
if ((gGraphTile1 == null) || (gGraphTile2 == null)) return; // cannot connect yet
if ((gGraphTile1.neighbourTiles[horizontal?GNode.BORDER_NODE_EAST:GNode.BORDER_NODE_SOUTH] == gGraphTile2) &&
(gGraphTile2.neighbourTiles[horizontal?GNode.BORDER_NODE_WEST:GNode.BORDER_NODE_NORTH] == gGraphTile1)){ // tiles already connected
return;
}
if ((gGraphTile1.neighbourTiles[horizontal?GNode.BORDER_NODE_EAST:GNode.BORDER_NODE_SOUTH] != null) ||
(gGraphTile2.neighbourTiles[horizontal?GNode.BORDER_NODE_WEST:GNode.BORDER_NODE_NORTH] != null)){ // inconsistency detected!!!!
mgLog.e("connectTiles failed"+gGraphTile1.getTileX()+","+gGraphTile1.getTileY()+" "+gGraphTile2.getTileX()+","+gGraphTile2.getTileY()+" "+horizontal);
mgLog.e("found="+gGraphTile1.neighbourTiles[horizontal?GNode.BORDER_NODE_EAST:GNode.BORDER_NODE_SOUTH]+" expected="+gGraphTile2);
mgLog.e("found="+gGraphTile2.neighbourTiles[horizontal?GNode.BORDER_NODE_WEST:GNode.BORDER_NODE_NORTH]+" expected="+gGraphTile1);
throw new IllegalArgumentException("inconsistent neighbour tiles - check logfile for more details.");
}
double connectAt = (horizontal)?gGraphTile1.tbBox.maxLongitude:gGraphTile1.tbBox.minLatitude;
if (horizontal? (connectAt!=gGraphTile2.tbBox.minLongitude):(connectAt!=gGraphTile2.tbBox.maxLatitude)){
throw new IllegalArgumentException("cannot connectHorizontal Tiles with BB " + gGraphTile1.tbBox +" and "+gGraphTile2.tbBox);
}
ArrayList<GNode> borderNodes1 = new ArrayList<>();
for (GNode node : gGraphTile1.getNodes()){
if ((horizontal)?(node.getLon() == connectAt):(node.getLat() == connectAt)){
borderNodes1.add(node);
}
}
ArrayList<GNode> borderNodes2 = new ArrayList<>();
for (GNode node : gGraphTile2.getNodes()){
if ((horizontal)?(node.getLon() == connectAt):(node.getLat() == connectAt)){
borderNodes2.add(node);
}
}
final ArrayList<GNode> remainingNodes1 = new ArrayList<>(borderNodes1);
final ArrayList<GNode> remainingNodes2 = new ArrayList<>(borderNodes2);
double threshold = (horizontal)?PointModelUtil.latitudeDistance(CONNECT_THRESHOLD_METER):PointModelUtil.longitudeDistance(CONNECT_THRESHOLD_METER, connectAt);
for (GNode node1 : borderNodes1){
for (GNode node2 : borderNodes2){
if ( (horizontal?Math.abs( node1.getLat() - node2.getLat() ):Math.abs( node1.getLon() - node2.getLon() )) <= threshold){ //distance less than 0.5m -> connect nodes
connect(node1, node2);
remainingNodes1.remove(node1);
remainingNodes2.remove(node2);
}
}
}
if ((remainingNodes1.size() > 0) && ((remainingNodes2.size() > 0))){
ArrayList<GNode> stillRemainingNodes1 = new ArrayList<>(remainingNodes1);
ArrayList<GNode> stillRemainingNodes2 = new ArrayList<>(remainingNodes2);
mgLog.v(remainingNodes1::toString);
mgLog.v(remainingNodes2::toString);
for (GNode node1 : remainingNodes1){
for (GNode node2 : remainingNodes2){
if ((node1.countNeighbours() == 1) && (node2.countNeighbours() == 1) && (PointModelUtil.distance(node1,node2)<CONNECT_THRESHOLD_METER*20)){
GNode node1Neighbour = node1.getNeighbour().getNextNeighbour().getNeighbourNode();
GNode node2Neighbour = node2.getNeighbour().getNextNeighbour().getNeighbourNode();
WriteablePointModel approachPoint = new WriteablePointModelImpl();
if (!PointModelUtil.findApproach(node1,node1Neighbour,node2Neighbour,approachPoint,0)) continue; // approach not found try next points
if (PointModelUtil.distance(approachPoint,node1) > CONNECT_THRESHOLD_METER) continue;
if (!PointModelUtil.findApproach(node2,node1Neighbour,node2Neighbour,approachPoint,0)) continue; // approach not found try next points
if (PointModelUtil.distance(approachPoint,node2) > CONNECT_THRESHOLD_METER) continue;
mgLog.d(()->"OK, connect: node1 " + node1 + " node1neighbour " + node1Neighbour + " node2 " + node2 + " node2neighbour " + node2Neighbour);
connect(node1, node2);
stillRemainingNodes1.remove(node1);
stillRemainingNodes2.remove(node2);
}
}
}
remainingNodes1.clear();
remainingNodes1.addAll(stillRemainingNodes1);
remainingNodes2.clear();
remainingNodes2.addAll(stillRemainingNodes2);
}
if ((remainingNodes1.size() > 0) || ((remainingNodes2.size() > 0))){
mgLog.d(()->"remainings1 " + remainingNodes1);
mgLog.d(()->"remainings2 " + remainingNodes2);
}
gGraphTile1.neighbourTiles[horizontal?GNode.BORDER_NODE_EAST:GNode.BORDER_NODE_SOUTH] = gGraphTile2;
gGraphTile2.neighbourTiles[horizontal?GNode.BORDER_NODE_WEST:GNode.BORDER_NODE_NORTH] = gGraphTile1;
}

public void connect(GNode node1, GNode node2){
GNeighbour n12 = new GNeighbour(node2,null);
GNeighbour n21 = new GNeighbour(node1,null);
n12.setReverse(n21);
n21.setReverse(n12);
node1.addNeighbour(n12);
node2.addNeighbour(n21);
}

private void use(GGraphTile gGraphTile){
if (!gGraphTile.used){
gGraphTile.resetNodeRefs();
Expand Down
17 changes: 1 addition & 16 deletions mgmap/src/main/java/mg/mgmap/generic/graph/GGraphTile.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,24 +159,9 @@ void resetNodeRefs(){
}
}

/**
* @param tileIdx Tile to be dropped from cache - so drop all references to this tileIdx
* @param border tileIdx border that point to this gGraphTile
*/
void dropNeighboursToTile(int tileIdx, byte border){
byte ownBorder = GNode.oppositeBorder(border);
for (GNode node : getNodes()){
if ((node.borderNode & ownBorder) != 0){
node.removeNeighbourNode(tileIdx);
}
}
assert (neighbourTiles[ownBorder].tileIdx == tileIdx):"neighbourTiles[ownBorder].tileIdx"+neighbourTiles[ownBorder].tileIdx+" tileIdx="+tileIdx;
neighbourTiles[ownBorder] = null;
}

@NonNull
@Override
public String toString() {
return "GGraphTile-"+tbBox.toString();
return "GGraphTile-("+getTileX()+","+getTileY()+")";
}
}
127 changes: 0 additions & 127 deletions mgmap/src/main/java/mg/mgmap/generic/graph/GGraphTileCache.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ public GGraphTile getGGraphTile(int tileX, int tileY){
return getGGraphTile(tileX, tileY, true);
}
public GGraphTile getGGraphTile(int tileX, int tileY, boolean load){
GGraphTile gGraphTile = gTileCache.get(getKey(tileX, tileY));
GGraphTile gGraphTile = gTileCache.get(tileX, tileY);
if (load && (gGraphTile == null)){
gGraphTile = loadGGraphTile(tileX, tileY);
gTileCache.put(GGraphTileFactory.getKey(tileX, tileY), gGraphTile);
gTileCache.put(tileX, tileY, gGraphTile);
}
return gGraphTile;
}
Expand Down
9 changes: 9 additions & 0 deletions mgmap/src/main/java/mg/mgmap/generic/graph/GNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ public void resetNodeRefs(){
nodeReverseRef = null;
}

public void bidirectionalConnect(GNode neighbourNode){
GNeighbour neighbour = new GNeighbour(neighbourNode,null);
GNeighbour reverseNeighbour = new GNeighbour(this,null);
neighbour.setReverse(reverseNeighbour);
reverseNeighbour.setReverse(neighbour);
this.addNeighbour(neighbour);
neighbourNode.addNeighbour(reverseNeighbour);
}

public void removeNeighbourNode(GNode neighbourNode){
GNeighbour nextNeighbour = this.neighbour;
while (nextNeighbour.getNextNeighbour() != null) {
Expand Down
Loading

0 comments on commit 2f89a33

Please sign in to comment.