merge route parts implementation
This commit is contained in:
parent
d3d55cec4b
commit
3ec03040ea
3 changed files with 276 additions and 225 deletions
|
@ -2639,6 +2639,7 @@ public class BinaryMapIndexReader {
|
||||||
public net.osmand.data.IncompleteTransportRoute getIncompleteRoutePointers(long id) {
|
public net.osmand.data.IncompleteTransportRoute getIncompleteRoutePointers(long id) {
|
||||||
return incompleteRoutes.get(id);
|
return incompleteRoutes.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<net.osmand.data.IncompleteTransportRoute> getIncompleteRoutes() {
|
public Collection<net.osmand.data.IncompleteTransportRoute> getIncompleteRoutes() {
|
||||||
return incompleteRoutes.valueCollection();
|
return incompleteRoutes.valueCollection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
|
|
||||||
public class TransportRoute extends MapObject {
|
public class TransportRoute extends MapObject {
|
||||||
|
@ -30,7 +32,7 @@ public class TransportRoute extends MapObject {
|
||||||
public TransportRoute() {
|
public TransportRoute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportRoute(TransportRoute r, boolean combined) {
|
public TransportRoute(TransportRoute r, List<TransportStop> mergedSegment, List<Way> ways) {
|
||||||
this.name = r.name;
|
this.name = r.name;
|
||||||
this.enName = r.enName;
|
this.enName = r.enName;
|
||||||
this.names = r.names;
|
this.names = r.names;
|
||||||
|
@ -38,14 +40,12 @@ public class TransportRoute extends MapObject {
|
||||||
this.operator = r.operator;
|
this.operator = r.operator;
|
||||||
this.ref = r.ref;
|
this.ref = r.ref;
|
||||||
this.type = r.type;
|
this.type = r.type;
|
||||||
this.dist = r.dist;
|
|
||||||
this.color = r.color;
|
this.color = r.color;
|
||||||
this.schedule = r.schedule;
|
this.schedule = r.schedule;
|
||||||
this.combined = combined;
|
this.combined = true;
|
||||||
|
this.forwardStops = mergedSegment;
|
||||||
if (combined) {
|
this.dist = calculateDistance();
|
||||||
this.addRoutePart(r, true);
|
this.forwardWays = ways; //TODO check
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportSchedule getSchedule() {
|
public TransportSchedule getSchedule() {
|
||||||
|
@ -63,46 +63,19 @@ public class TransportRoute extends MapObject {
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer calculateDistance() {
|
||||||
|
int distance = 0;
|
||||||
|
for (int i = 0; i < forwardStops.size()-1; i++) {
|
||||||
|
if (!forwardStops.get(i).isMissingStop() || !forwardStops.get(i+1).isMissingStop())
|
||||||
|
distance += MapUtils.getDistance(forwardStops.get(i).getLocation(), forwardStops.get(i+1).getLocation());
|
||||||
|
}
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isIncomplete() {
|
public boolean isIncomplete() {
|
||||||
return forwardStops.get(0).isMissingStop() || forwardStops.get(forwardStops.size()-1).isMissingStop();
|
return forwardStops.get(0).isMissingStop() || forwardStops.get(forwardStops.size()-1).isMissingStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCombined(boolean combined) {
|
|
||||||
this.combined = combined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransportStop getMissingStartStop() {
|
|
||||||
return forwardStops.get(0).isMissingStop() ? forwardStops.get(0) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransportStop getMissingEndStop() {
|
|
||||||
return forwardStops.get(forwardStops.size()-1).isMissingStop() ? forwardStops.get(forwardStops.size()-1) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean addRoutePart(TransportRoute part, boolean forward) {
|
|
||||||
//TODO chec stop validity and combine ways
|
|
||||||
int addCount = 0;
|
|
||||||
if (forward) {
|
|
||||||
routeParts.add(part);
|
|
||||||
for (int i = 0; i < part.getForwardStops().size(); i++) {
|
|
||||||
if (!part.getForwardStops().get(i).isMissingStop() && !forwardStops.contains(part.getForwardStops().get(i))) {
|
|
||||||
forwardStops.add(part.getForwardStops().get(i));
|
|
||||||
addCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
routeParts.add(0, part);
|
|
||||||
for (int i = part.getForwardStops().size() - 1; i >= 0 ; i--) {
|
|
||||||
if (!part.getForwardStops().get(i).isMissingStop() && !forwardStops.contains(part.getForwardStops().get(i))) {
|
|
||||||
forwardStops.add(part.getForwardStops().get(i));
|
|
||||||
addCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addCount > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List<TransportRoute> getRouteParts() {
|
public List<TransportRoute> getRouteParts() {
|
||||||
return routeParts;
|
return routeParts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -821,9 +821,13 @@ public class TransportRoutePlanner {
|
||||||
if (rrs != null && !multifileStop.isDeleted()) {
|
if (rrs != null && !multifileStop.isDeleted()) {
|
||||||
for (int rr : rrs) {
|
for (int rr : rrs) {
|
||||||
// here we should assign only complete routes:
|
// here we should assign only complete routes:
|
||||||
TransportRoute combinedRoute = getCombinedRoute(localFileRoutes.get(rr), r.getFile().getName());
|
TransportRoute route = localFileRoutes.get(rr);
|
||||||
|
if (route == null) {
|
||||||
|
System.err.println(String.format("Something went wrong by loading combined route %d for stop %s", route.getId(), stop));
|
||||||
|
} else {
|
||||||
|
TransportRoute combinedRoute = getCombinedRoute(route, r.getFile().getName());
|
||||||
if (combinedRoute == null) {
|
if (combinedRoute == null) {
|
||||||
System.err.println(String.format("Something went wrong by loading route %d for stop %s", rr, stop));
|
System.err.println(String.format("Something went wrong by loading combined route %d for stop %s", route.getId(), stop));
|
||||||
} else if (multifileStop == stop ||
|
} else if (multifileStop == stop ||
|
||||||
(!multifileStop.hasRoute(combinedRoute.getId()) &&
|
(!multifileStop.hasRoute(combinedRoute.getId()) &&
|
||||||
!multifileStop.isRouteDeleted(combinedRoute.getId()))) {
|
!multifileStop.isRouteDeleted(combinedRoute.getId()))) {
|
||||||
|
@ -835,6 +839,7 @@ public class TransportRoutePlanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//there should go stops with complete routes:
|
//there should go stops with complete routes:
|
||||||
loadTransportSegments(loadedTransportStops.valueCollection(), lst);
|
loadTransportSegments(loadedTransportStops.valueCollection(), lst);
|
||||||
|
|
||||||
|
@ -932,197 +937,269 @@ public class TransportRoutePlanner {
|
||||||
TransportRoute c = combinedRoutesCache.get(route.getId());
|
TransportRoute c = combinedRoutesCache.get(route.getId());
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
c = combineRoute(route, fileName);
|
c = combineRoute(route, fileName);
|
||||||
|
|
||||||
combinedRoutesCache.put(route.getId(), c);
|
combinedRoutesCache.put(route.getId(), c);
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
Comparator<TransportRoute> compareByDist = (TransportRoute tr1, TransportRoute tr2)
|
|
||||||
-> ((Integer)tr1.getDistance()).compareTo((Integer)tr2.getDistance());
|
|
||||||
|
|
||||||
|
|
||||||
private TransportRoute combineRoute(TransportRoute route, String fileName) throws IOException {
|
private TransportRoute combineRoute(TransportRoute route, String fileName) throws IOException {
|
||||||
List<TransportRoute> result = new ArrayList<>(findIncompleteRouteParts(route, fileName));
|
//1.Get all available route parts;
|
||||||
List<TransportRoute> acceptedCandidates = new ArrayList<TransportRoute>();
|
List<TransportRoute> result = new ArrayList<>(findIncompleteRouteParts(route));
|
||||||
|
// List<TransportRoute> acceptedCandidates = new ArrayList<TransportRoute>();
|
||||||
|
List<Way> allWays = getAllWays(result);
|
||||||
|
|
||||||
TransportRoute baseRoute = route;
|
//2. Get massive of segments:
|
||||||
|
List<List<TransportStop>> segments = parseRoutePartsToSegments(result);
|
||||||
|
Collections.sort(segments, compareSegsBySize.reversed());
|
||||||
|
|
||||||
if (result.size() > 1) {
|
//3. Merge segments and remove excess missingStops (when they are closer then MISSING_STOP_SEARCH_RADIUS):
|
||||||
//1. Sort by longest piece:
|
//4. Check for missingStops. If they present in the middle/there more then one segment - we have a hole in the map data
|
||||||
Collections.sort(result, compareByDist);
|
List<List<TransportStop>> mergedSegments = combineSegments(segments);
|
||||||
|
|
||||||
//2. Check if any route's part contains more stops, then "base" route,
|
//5. Create combined TransportRoute and return it
|
||||||
//so we could find longest part (and remove subsets and copies):
|
if (mergedSegments.size() > 1) {
|
||||||
Iterator<TransportRoute> itr = result.iterator();
|
//TODO what will we do with incomplete route?
|
||||||
boolean containsAllStops = false;
|
return null;
|
||||||
while (itr.hasNext()) {
|
|
||||||
TransportRoute candidate = itr.next();
|
|
||||||
if (candidate.compareRoute(baseRoute)) {
|
|
||||||
itr.remove();
|
|
||||||
continue;
|
|
||||||
} else if (candidate.getForwardStops().size() > baseRoute.getForwardStops().size()) {
|
|
||||||
for (TransportStop s : baseRoute.getForwardStops()) {
|
|
||||||
for (TransportStop cs : candidate.getForwardStops()) {
|
|
||||||
if (!s.isMissingStop() && !cs.isMissingStop()) {
|
|
||||||
if (s.getId() == cs.getId()) {
|
|
||||||
containsAllStops = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
containsAllStops = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (containsAllStops) {
|
|
||||||
baseRoute = candidate;
|
|
||||||
itr.remove();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (TransportStop cs : candidate.getForwardStops()) {
|
return new TransportRoute(route, mergedSegments.get(0), allWays);
|
||||||
for (TransportStop s: baseRoute.getForwardStops()) {
|
|
||||||
if (!s.isMissingStop() && !cs.isMissingStop()) {
|
|
||||||
if(s.getId() == cs.getId()) {
|
|
||||||
containsAllStops = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
containsAllStops = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (containsAllStops) {
|
|
||||||
itr.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
acceptedCandidates = result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//3. Connect routes in right order (stops/ways)
|
private List<Way> getAllWays(List<TransportRoute> parts) {
|
||||||
TransportRoute cr = new TransportRoute(baseRoute, true);
|
List<Way> w = new ArrayList<Way>();
|
||||||
|
for (TransportRoute t : parts) {
|
||||||
TransportStop missingStart = baseRoute.getMissingStartStop();
|
w.addAll(t.getForwardWays());
|
||||||
TransportStop missingEnd = baseRoute.getMissingEndStop();
|
|
||||||
|
|
||||||
List<TransportStop> stops = baseRoute.getForwardStops();
|
|
||||||
List<Way> ways = route.getForwardWays();
|
|
||||||
Iterator<TransportRoute> itr = result.iterator();
|
|
||||||
while(result.size() > 0) {
|
|
||||||
boolean success = false;
|
|
||||||
double distFromMissingEnd = -1;
|
|
||||||
double distFromMissingStart = -1;
|
|
||||||
TransportRoute part = itr.next();
|
|
||||||
if (baseRoute.getMissingEndStop() != null && part.getMissingStartStop() != null) {
|
|
||||||
distFromMissingEnd =
|
|
||||||
MapUtils.getDistance(baseRoute.getMissingEndStop().getLocation(), part.getMissingStartStop().getLocation());
|
|
||||||
}
|
}
|
||||||
if (baseRoute.getMissingStartStop() != null && part.getMissingEndStop() != null) {
|
return w;
|
||||||
distFromMissingStart =
|
}
|
||||||
MapUtils.getDistance(baseRoute.getMissingStartStop().getLocation(), part.getMissingEndStop().getLocation());
|
|
||||||
|
Comparator<List<TransportStop>> compareSegsBySize = new Comparator<List<TransportStop>>() {
|
||||||
|
public int compare(List<TransportStop> s1, List<TransportStop> s2) {
|
||||||
|
return ((Integer)s1.size()).compareTo((Integer)s2.size());
|
||||||
}
|
}
|
||||||
if (distFromMissingEnd != -1) {
|
|
||||||
if ((distFromMissingStart == -1 || distFromMissingStart > distFromMissingEnd) && distFromMissingEnd < MISSING_STOP_SEARCH_RADIUS) {
|
|
||||||
//try to attach route part to end of baseRoute
|
|
||||||
if (!cr.addRoutePart(part, true)) {
|
|
||||||
//else assume that part of the route is missing and we need to attach it later
|
|
||||||
//TODO (how to check if missing part is exist at all? If there no some part of map
|
|
||||||
//we will fall in endless loop)
|
|
||||||
result.add(part);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private List<List<TransportStop>> combineSegments(List<List<TransportStop>> segments) {
|
||||||
|
List<List<TransportStop>> rawSegments = segments;
|
||||||
|
|
||||||
|
|
||||||
|
List<List<TransportStop>> partsToDelete = new ArrayList<List<TransportStop>>();
|
||||||
|
List<List<TransportStop>> partsToReturn = new ArrayList<List<TransportStop>>();
|
||||||
|
List<TransportStop> base;
|
||||||
|
int startSize = 0;
|
||||||
|
|
||||||
|
Iterator<List<TransportStop>> segItr = rawSegments.iterator();
|
||||||
|
while (segItr.hasNext()) {
|
||||||
|
startSize = rawSegments.size();
|
||||||
|
partsToDelete.clear();
|
||||||
|
partsToReturn.clear();
|
||||||
|
base = segItr.next();
|
||||||
|
segItr.remove();
|
||||||
|
|
||||||
|
TransportStop firstStopMissing = base.get(0).isMissingStop() ? base.get(0) : null;
|
||||||
|
TransportStop lastStopMissing = base.get(base.size() - 1).isMissingStop() ? base.get(base.size() - 1)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
for (int i = 0; i < segments.size(); i++) {
|
||||||
|
// compare every other piece of route with base (largest part so far)
|
||||||
|
// and if it has common stops or close missing stops try to combine
|
||||||
|
List<TransportStop> candidate = rawSegments.get(i);
|
||||||
|
TransportStop cmss = candidate.get(0).isMissingStop() ? candidate.get(0) : null;
|
||||||
|
TransportStop cmse = candidate.get(candidate.size() - 1).isMissingStop()
|
||||||
|
? candidate.get(candidate.size() - 1)
|
||||||
|
: null;
|
||||||
|
int csStopCount = candidate.size();
|
||||||
|
if (cmss != null) {
|
||||||
|
csStopCount--;
|
||||||
}
|
}
|
||||||
} else if (distFromMissingStart != -1) {
|
if (cmse != null) {
|
||||||
if ((distFromMissingEnd == -1 || distFromMissingStart < distFromMissingEnd) && distFromMissingStart < MISSING_STOP_SEARCH_RADIUS) {
|
csStopCount--;
|
||||||
if (!cr.addRoutePart(part, false)) {
|
}
|
||||||
//same thing here, need to exit loop somehow
|
int csSameStopsCount = 0;
|
||||||
result.add(part);
|
for (TransportStop s : base) {
|
||||||
|
if (!s.isMissingStop()) {
|
||||||
|
for (TransportStop cs : candidate) {
|
||||||
|
if (!cs.isMissingStop() && s.getId().equals(cs.getId())) {
|
||||||
|
csSameStopsCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (csStopCount == csSameStopsCount) {
|
||||||
|
// all stops of candidate inside base, delete candidate
|
||||||
|
partsToDelete.add(candidate);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (csSameStopsCount > 0 && firstStopMissing != null && lastStopMissing == null
|
||||||
|
&& cmse != null) {
|
||||||
|
// parts intersecting and we know what sides to connect, attach to start
|
||||||
|
base = mergeSegments(base, candidate, false);
|
||||||
|
|
||||||
|
} else if (csSameStopsCount > 0 && lastStopMissing != null && firstStopMissing == null
|
||||||
|
&& cmss != null) {
|
||||||
|
// parts intersecting and we know what sides to connect, attach to end
|
||||||
|
base = mergeSegments(base, candidate, true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// check for missing stops in candidate and attach accordingly
|
||||||
|
double distStartToEnd = MISSING_STOP_SEARCH_RADIUS + 1;
|
||||||
|
double distEndToStart = MISSING_STOP_SEARCH_RADIUS + 1;
|
||||||
|
if (cmss != null && lastStopMissing != null) {
|
||||||
|
distStartToEnd = MapUtils.getDistance(cmss.getLocation(),
|
||||||
|
lastStopMissing.getLocation());
|
||||||
|
}
|
||||||
|
if (cmse != null && firstStopMissing != null) {
|
||||||
|
distEndToStart = MapUtils.getDistance(cmse.getLocation(),
|
||||||
|
firstStopMissing.getLocation());
|
||||||
|
}
|
||||||
|
if (distStartToEnd < distEndToStart && distStartToEnd <= MISSING_STOP_SEARCH_RADIUS) {
|
||||||
|
base = mergeSegments(base, candidate, true);
|
||||||
|
} else if (distEndToStart < distStartToEnd && distEndToStart <= MISSING_STOP_SEARCH_RADIUS) {
|
||||||
|
base = mergeSegments(base, candidate, false);
|
||||||
|
} else {
|
||||||
|
if (csSameStopsCount == 0) {
|
||||||
|
// it's OK, we should look for other parts first
|
||||||
|
partsToReturn.add(candidate);
|
||||||
|
System.out.println("Candidate is not connected to Base, continue search");
|
||||||
|
} else {
|
||||||
|
// it's not OK, if there is intersecting stops and too long distance between
|
||||||
|
// missingStops, there is some error in data
|
||||||
|
System.out.println("MERGING ERROR. THERE IS SOMETHING WRONG WITH DATA");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
partsToDelete.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (List<TransportStop> p : partsToDelete) {
|
||||||
|
rawSegments.remove(p);
|
||||||
|
}
|
||||||
|
rawSegments.addAll(partsToReturn);
|
||||||
|
rawSegments.add(base);
|
||||||
|
//Check if all is merged:
|
||||||
|
if (rawSegments.size() == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//If we still have several segments, but after iteration they number didn't dwindle,
|
||||||
|
//check if we still could merge some of them or do we have a hole in the data
|
||||||
|
boolean hasValidCandidate = false;
|
||||||
|
if (rawSegments.size() == startSize) {
|
||||||
|
for (int i = 0; i < rawSegments.size()-1; i++) {
|
||||||
|
TransportStop ms = rawSegments.get(i).get(0).isMissingStop() ? rawSegments.get(i).get(0) : null;
|
||||||
|
TransportStop me = rawSegments.get(i).get(rawSegments.get(i).size()-1).isMissingStop()
|
||||||
|
? rawSegments.get(i).get(rawSegments.get(i).size()-1) : null;
|
||||||
|
for (int j = 1; j < rawSegments.size(); j++) {
|
||||||
|
TransportStop cms = rawSegments.get(j).get(0).isMissingStop() ? rawSegments.get(j).get(0) : null;
|
||||||
|
TransportStop cme = rawSegments.get(j).get(rawSegments.get(j).size()-1).isMissingStop()
|
||||||
|
? rawSegments.get(j).get(rawSegments.get(j).size()-1) : null;
|
||||||
|
if (ms != null && cme != null && MapUtils.getDistance(ms.getLocation(), cme.getLocation()) <= MISSING_STOP_SEARCH_RADIUS) {
|
||||||
|
hasValidCandidate = true;
|
||||||
|
}
|
||||||
|
if (me != null && cms != null && MapUtils.getDistance(me.getLocation(), cms.getLocation()) <= MISSING_STOP_SEARCH_RADIUS) {
|
||||||
|
hasValidCandidate = true;
|
||||||
|
}
|
||||||
|
//we has at least one valid pair of segments for merging
|
||||||
|
if (hasValidCandidate) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if we could not merge any more segments - break;
|
||||||
|
if (rawSegments.size() == 1 || (rawSegments.size() == startSize && !hasValidCandidate)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rawSegments;
|
||||||
|
}
|
||||||
|
|
||||||
return cr;
|
private List<TransportStop> mergeSegments(List<TransportStop> base, List<TransportStop> candidate, boolean forward) {
|
||||||
|
List<TransportStop> result;
|
||||||
|
if (forward) {
|
||||||
|
result = new ArrayList<>(base.subList(0, base.size()-1));
|
||||||
|
for (int i = 1; i < candidate.size(); i++) {
|
||||||
|
if (!result.contains(candidate.get(i))) {
|
||||||
|
result.add(candidate.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = new ArrayList<>(candidate.subList(0, candidate.size()-1));
|
||||||
|
for (int i = 1; i < base.size(); i++) {
|
||||||
|
if (!result.contains(base.get(i))) {
|
||||||
|
result.add(base.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<TransportRoute> findIncompleteRouteParts(TransportRoute baseRoute, String fileName) throws IOException {
|
private List<List<TransportStop>> parseRoutePartsToSegments(List<TransportRoute> routeParts) {
|
||||||
|
List<List<TransportStop>> segs = new ArrayList<List<TransportStop>>();
|
||||||
|
for (TransportRoute part : routeParts) {
|
||||||
|
List<TransportStop> newSeg = new ArrayList<TransportStop>();
|
||||||
|
for (TransportStop s : part.getForwardStops()) {
|
||||||
|
if (s.isMissingStop()) {
|
||||||
|
if (newSeg.isEmpty()) {
|
||||||
|
newSeg.add(s);
|
||||||
|
} else {
|
||||||
|
newSeg.add(s);
|
||||||
|
segs.add(newSeg);
|
||||||
|
newSeg = new ArrayList<TransportStop>();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newSeg.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!newSeg.isEmpty()) {
|
||||||
|
segs.add(newSeg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return segs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Collection<TransportRoute> findIncompleteRouteParts(TransportRoute baseRoute) throws IOException {
|
||||||
IncompleteTransportRoute ptr;
|
IncompleteTransportRoute ptr;
|
||||||
TIntObjectHashMap<TransportRoute> res = new TIntObjectHashMap<TransportRoute>();
|
TIntObjectHashMap<TransportRoute> res = new TIntObjectHashMap<TransportRoute>();
|
||||||
TIntObjectHashMap<TransportRoute> localRes = new TIntObjectHashMap<TransportRoute>();
|
//TODO search only routes from bbox?
|
||||||
|
|
||||||
for (BinaryMapIndexReader bmir: routeMap.keySet()) {
|
for (BinaryMapIndexReader bmir: routeMap.keySet()) {
|
||||||
// if (!bmir.getFile().getName().equals(fileName)) {
|
|
||||||
localRes.clear();
|
|
||||||
/**
|
/**
|
||||||
* What about situation when one route has several parts in map?
|
* TODO: Should I check if those routes already loaded? But they shouldn't,
|
||||||
* MB check all readers and then sort it out?
|
|
||||||
*
|
|
||||||
* Should I check if those routes already loaded? But they shouldn't,
|
|
||||||
* else we will already had a combined route and never get there!
|
* else we will already had a combined route and never get there!
|
||||||
*/
|
*/
|
||||||
ptr = bmir.getIncompleteRoutePointers(baseRoute.getId());
|
ptr = bmir.getIncompleteRoutePointers(baseRoute.getId());
|
||||||
if (ptr != null && ptr.getRouteOffset() != -1) {
|
if (ptr != null && ptr.getRouteOffset() != -1) {
|
||||||
localRes = bmir.getTransportRoutes(new int[] {ptr.getRouteOffset()});
|
res.putAll(bmir.getTransportRoutes(new int[] {ptr.getRouteOffset()}));
|
||||||
res.putAll(localRes);
|
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
return res.valueCollection();
|
return res.valueCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private TransportRoute loadMissingTransportRoute(int sx, int sy, TransportRoute route) throws IOException {
|
// private TIntObjectHashMap<TransportRoute> getRouteParts(int x, int y) throws IOException {
|
||||||
// long nanoTime = System.nanoTime();
|
// int pz = (31 - cfg.ZOOM_TO_LOAD_TILES);
|
||||||
// List<TransportRoute> res = new ArrayList<TransportRoute>();
|
// SearchRequest<TransportStop> sr = BinaryMapIndexReader.buildSearchTransportRequest(x << pz, (x + 1) << pz,
|
||||||
// TIntObjectHashMap<TransportRoute> tr = new TIntObjectHashMap<TransportRoute>();
|
// y << pz, (y + 1) << pz, -1, null);
|
||||||
// int d = missingStopRadiusIn31;
|
|
||||||
// int lx = (sx - d ) >> (31 - cfg.ZOOM_TO_LOAD_TILES);
|
|
||||||
// int rx = (sx + d ) >> (31 - cfg.ZOOM_TO_LOAD_TILES);
|
|
||||||
// int ty = (sy - d ) >> (31 - cfg.ZOOM_TO_LOAD_TILES);
|
|
||||||
// int by = (sy + d ) >> (31 - cfg.ZOOM_TO_LOAD_TILES);
|
|
||||||
// for(int x = lx; x <= rx; x++) {
|
|
||||||
// for(int y = ty; y <= by; y++) {
|
|
||||||
// long tileId = (((long)x) << (cfg.ZOOM_TO_LOAD_TILES + 1)) + y;
|
|
||||||
//// List<TransportRouteSegment> list = quadTree.get(tileId);
|
|
||||||
//// if(list == null) {
|
|
||||||
// tr = getRouteParts(x, y);
|
|
||||||
//// quadTree.put(tileId, list);
|
|
||||||
//// }
|
|
||||||
// if (!tr.isEmpty()) {
|
|
||||||
// res.addAll(tr.valueCollection());
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// }
|
// TLongObjectHashMap<TransportStop> loadedTransportStops = new TLongObjectHashMap<TransportStop>();
|
||||||
// }
|
// TIntObjectHashMap<TransportRoute> localFileRoutes = new TIntObjectHashMap<>();
|
||||||
// for (TransportRoute trr : res) {
|
// TIntObjectHashMap<TransportRoute> res = new TIntObjectHashMap<TransportRoute>();
|
||||||
// if ((long)trr.getId() == (long)route.getId()) {
|
// for (BinaryMapIndexReader r : routeMap.keySet()) {
|
||||||
// if (trr.getForwardStops() != route.getForwardStops()) {
|
// sr.clearSearchResults();
|
||||||
// return trr;
|
// List<TransportStop> stops = r.searchTransportIndex(sr);
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// return null;
|
// localFileRoutes.clear();
|
||||||
|
// //search routes here:
|
||||||
|
// mergeTransportStops(r, loadedTransportStops, stops, localFileRoutes, routeMap.get(r));
|
||||||
|
// if (!localFileRoutes.isEmpty()) {
|
||||||
|
// res.putAll(localFileRoutes);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return res;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private TIntObjectHashMap<TransportRoute> getRouteParts(int x, int y) throws IOException {
|
|
||||||
int pz = (31 - cfg.ZOOM_TO_LOAD_TILES);
|
|
||||||
SearchRequest<TransportStop> sr = BinaryMapIndexReader.buildSearchTransportRequest(x << pz, (x + 1) << pz,
|
|
||||||
y << pz, (y + 1) << pz, -1, null);
|
|
||||||
|
|
||||||
TLongObjectHashMap<TransportStop> loadedTransportStops = new TLongObjectHashMap<TransportStop>();
|
|
||||||
TIntObjectHashMap<TransportRoute> localFileRoutes = new TIntObjectHashMap<>();
|
|
||||||
TIntObjectHashMap<TransportRoute> res = new TIntObjectHashMap<TransportRoute>();
|
|
||||||
for (BinaryMapIndexReader r : routeMap.keySet()) {
|
|
||||||
sr.clearSearchResults();
|
|
||||||
List<TransportStop> stops = r.searchTransportIndex(sr);
|
|
||||||
|
|
||||||
localFileRoutes.clear();
|
|
||||||
//search routes here:
|
|
||||||
mergeTransportStops(r, loadedTransportStops, stops, localFileRoutes, routeMap.get(r));
|
|
||||||
if (!localFileRoutes.isEmpty()) {
|
|
||||||
res.putAll(localFileRoutes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void loadTransportSegments(Collection<TransportStop> stops, List<TransportRouteSegment> lst) throws IOException {
|
private void loadTransportSegments(Collection<TransportStop> stops, List<TransportRouteSegment> lst) throws IOException {
|
||||||
|
|
Loading…
Reference in a new issue