Small data tile manager refactoring

This commit is contained in:
Victor Shcherb 2012-10-15 22:05:41 +02:00
parent 5d1e5ea54d
commit 48fcb7d1dc
10 changed files with 222 additions and 207 deletions

View file

@ -79,7 +79,9 @@ public class NativeLibrary {
public RouteDataObject[] getDataObjects(NativeRouteSearchResult rs, int x31, int y31) {
if(rs.nativeHandler == 0) {
throw new IllegalStateException("Native route handler is 0");
// do not throw exception because it is expected situation
return new RouteDataObject[0];
// throw new IllegalStateException("Native route handler is 0");
}
return getRouteDataObjects(rs.region.routeReg, rs.nativeHandler, x31, y31);
}

View file

@ -1,26 +1,22 @@
package net.osmand.data;
import gnu.trove.map.hash.TLongObjectHashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.osmand.osm.MapUtils;
/**
*
* @param <T> - object to store in that manager
*/
public class DataTileManager<T> {
private int zoom = 15;
private final int zoom;
/**
* map for objects stores as 'xTile_yTile' -> List<T>
*/
private Map<String, List<T>> objects = new HashMap<String, List<T>>();
private TLongObjectHashMap<List<T>> objects = new TLongObjectHashMap<List<T>>();
public DataTileManager(){
zoom = 15;
@ -34,29 +30,17 @@ public class DataTileManager<T> {
return zoom;
}
public void setZoom(int zoom) {
// it is required to reindex all stored objects
if(!isEmpty()){
throw new UnsupportedOperationException();
}
this.zoom = zoom;
}
public boolean isEmpty(){
for(String s : objects.keySet()){
if(!objects.get(s).isEmpty()){
return false;
}
}
return true;
return getObjectsCount() == 0;
}
@SuppressWarnings("rawtypes")
public int getObjectsCount(){
int x = 0;
for(String s : objects.keySet()){
x += objects.get(s).size();
for(List s : objects.values()){
x += s.size();
}
return x;
}
@ -66,10 +50,11 @@ public class DataTileManager<T> {
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<T> getAllObjects(){
List<T> l = new ArrayList<T>();
for(String s : objects.keySet()){
l.addAll(objects.get(s));
for(List s : objects.values()){
l.addAll(s);
}
return l;
}
@ -146,27 +131,29 @@ public class DataTileManager<T> {
return result;
}
private String evTile(int tileX, int tileY){
return tileX +"_"+tileY; //$NON-NLS-1$
private long evTile(int tileX, int tileY){
long tx = tileX;
long ty = tileY;
return ((tx) << zoom) + ty;
}
public String evaluateTile(double latitude, double longitude){
public long evaluateTile(double latitude, double longitude){
int tileX = (int) MapUtils.getTileNumberX(zoom, longitude);
int tileY = (int) MapUtils.getTileNumberY(zoom, latitude);
return evTile(tileX, tileY);
}
public void unregisterObject(double latitude, double longitude, T object){
String tile = evaluateTile(latitude, longitude);
long tile = evaluateTile(latitude, longitude);
if(objects.containsKey(tile)){
objects.get(tile).remove(object);
}
}
public String registerObject(double latitude, double longitude, T object){
String tile = evaluateTile(latitude, longitude);
public long registerObject(double latitude, double longitude, T object){
long tile = evaluateTile(latitude, longitude);
if(!objects.containsKey(tile)){
objects.put(tile, new ArrayList<T>());
}

View file

@ -167,6 +167,7 @@ public class MapRoutingTypes {
if(value.startsWith("trunk") || value.startsWith("motorway")
|| value.startsWith("primary") || value.startsWith("secondary")
|| value.startsWith("tertiary")
|| value.startsWith("ferry")
) {
init = true;
break;

View file

@ -224,8 +224,7 @@ public class MinskTransReader {
OsmBaseStorage storage = new OsmBaseStorage();
final Map<String, Relation> definedRoutes = new HashMap<String, Relation>();
final DataTileManager<Node> busStops = new DataTileManager<Node>();
busStops.setZoom(17);
final DataTileManager<Node> busStops = new DataTileManager<Node>(17);
storage.getFilters().add(new IOsmStorageFilter(){
@Override

View file

@ -0,0 +1,35 @@
package net.osmand.router;
import java.util.List;
import net.osmand.data.DataTileManager;
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
public class BaseRouteResult {
private final List<RouteSegmentResult> baseResult;
private DataTileManager<RouteSegmentResult> indexedData = new DataTileManager<RouteSegmentResult>(15);
public BaseRouteResult(List<RouteSegmentResult> baseResult) {
this.baseResult = baseResult;
indexData();
}
private void indexData() {
for(RouteSegmentResult r : baseResult){
// r.getObject().getPoint31XTile(i);
// indexedData.evaluateTile(latitude, longitude)
}
}
public float getOrthogonalDistance(RouteSegment r){
float dist = 0;
int x = r.getRoad().getPoint31XTile(r.getSegmentStart());
int y = r.getRoad().getPoint31YTile(r.getSegmentStart());
return dist;
}
}

View file

@ -130,6 +130,7 @@ public class BinaryRoutePlanner {
ctx.timeToLoad += local.timeToLoad;
ctx.timeToLoadHeaders += local.timeToLoadHeaders;
ctx.relaxedSegments += local.relaxedSegments;
ctx.routingTime += local.routingTime;
local.unloadAllData(ctx);
if(restPartRecalculatedRoute != null) {
@ -385,16 +386,16 @@ public class BinaryRoutePlanner {
RouteSegment s = iterator.next();
// statStart.addNumber((float) s.distanceFromStart);
// statEnd.addNumber((float) s.distanceToEnd);
if (s.distanceToEnd < mine) {
mine = s.distanceToEnd;
if (s.distanceFromStart > mine) {
mine = s.distanceFromStart;
}
}
double d = mine + 5000; // ctx.config.RELAX_NODES_IF_START_DIST_COEF;
double d = mine - 50000; // ctx.config.RELAX_NODES_IF_START_DIST_COEF;
if (d > 0) {
iterator = graphSegments.iterator();
while (iterator.hasNext()) {
RouteSegment s = iterator.next();
if (s.distanceToEnd > d) {
if (s.distanceFromStart < d) {
ctx.relaxedSegments++;
iterator.remove();
}

View file

@ -54,6 +54,7 @@ public class RoutingContext {
public Interruptable interruptable;
public List<RouteSegmentResult> previouslyCalculatedRoute;
public BaseRouteResult baseRouteResult;
// 2. Routing memory cache (big objects)
TLongObjectHashMap<List<RoutingSubregionTile>> indexedSubregions = new TLongObjectHashMap<List<RoutingSubregionTile>>();

View file

@ -10,7 +10,7 @@
<attribute name="zoomToLoadTiles" value="16" />
<!-- by default it is 30. Value specified here overwrites all others
(don't specify here ! it is device dependent) -->
<attribute name="memoryLimitInMB" value="" />
<attribute name="memoryLimitInMB" value="50" />
<!-- 1.2 Dynamic road prioritizing (heuristic) -->
<attribute name="useDynamicRoadPrioritising" value="false" />
@ -57,49 +57,48 @@
<specialization input="avoid_motorway" speed="0"/>
</road>
<road tag="highway" value="trunk" speed="100" priority="1.2" dynamicPriority="1"/>
<road tag="highway" value="trunk_link" speed="75" priority="1.2" dynamicPriority="1"/>
<road tag="highway" value="trunk" speed="100" priority="1.2" dynamicPriority="0.9"/>
<road tag="highway" value="trunk_link" speed="75" priority="1.2" dynamicPriority="0.9"/>
<!-- generally linking larger towns. -->
<road tag="highway" value="primary" speed="65" priority="1.1" dynamicPriority="1"/>
<road tag="highway" value="primary_link" speed="50" priority="1.1" dynamicPriority="1"/>
<road tag="highway" value="primary" speed="65" priority="1.1" dynamicPriority="0.7"/>
<road tag="highway" value="primary_link" speed="50" priority="1.1" dynamicPriority="0.7"/>
<!-- generally linking smaller towns and villages -->
<road tag="highway" value="secondary" speed="60" priority="1.05" dynamicPriority="1"/>
<road tag="highway" value="secondary_link" speed="50" priority="1.05" dynamicPriority="1"/>
<road tag="highway" value="secondary" speed="60" priority="1.05" dynamicPriority="0.6"/>
<road tag="highway" value="secondary_link" speed="50" priority="1.05" dynamicPriority="0.6"/>
<!-- important urban roads -->
<road tag="highway" value="tertiary" speed="45" priority="1" dynamicPriority="0.9"/>
<road tag="highway" value="tertiary_link" speed="40" priority="1" dynamicPriority="0.9"/>
<road tag="highway" value="tertiary" speed="45" priority="1" dynamicPriority="0.5"/>
<road tag="highway" value="tertiary_link" speed="40" priority="1" dynamicPriority="0.5"/>
<!-- lowest form of grid network, usually 90% of urban roads -->
<road tag="highway" value="unclassified" speed="35" priority="0.7" dynamicPriority="0.7">
<road tag="highway" value="unclassified" speed="35" priority="0.7" dynamicPriority="0.3">
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
</road>
<!-- road = no type, no review and may be not accurate -->
<road tag="highway" value="road" speed="35" priority="0.7" dynamicPriority="0.7">
<road tag="highway" value="road" speed="35" priority="0.7" dynamicPriority="0.3">
<specialization input="short_way" priority="1" speed="45"/>
</road>
<!-- primarily for access to properties, small roads with 1/2 intersections -->
<road tag="highway" value="residential" speed="35" priority="0.7" dynamicPriority="0.7">
<road tag="highway" value="residential" speed="35" priority="0.7" dynamicPriority="0.3">
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
</road>
<!-- parking + private roads -->
<road tag="highway" value="service" speed="30" priority="0.5" dynamicPriority="0.5">
<road tag="highway" value="service" speed="30" priority="0.5" dynamicPriority="0.3">
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
</road>
<!-- very bad roads -->
<road tag="highway" value="track" speed="15" priority="0.3" dynamicPriority="0.5">
<road tag="highway" value="track" speed="15" priority="0.3" dynamicPriority="0.2">
<specialization input="short_way" priority="0.7" speed="45" dynamicPriority="0.7" />
<specialization input="avoid_unpaved" priority="0.1"/>
</road>
<!-- too small for cars usually -->
<road tag="highway" value="living_street" speed="25" priority="0.5" dynamicPriority="0.5">
<road tag="highway" value="living_street" speed="25" priority="0.5" dynamicPriority="0.3">
<specialization input="short_way" priority="1" dynamicPriority="1" speed="35"/>
</road>
<!-- car are able to enter in highway=pedestrian with restrictions -->
<!-- Time actually is uknown. Currently unsupported -->
<road tag="route" value="ferry" speed="15" priority="1.0" dynamicPriority="0.7">
<road tag="route" value="ferry" speed="15" priority="1.0" dynamicPriority="0.9">
<specialization input="avoid_ferries" speed="0"/>
</road>

View file

@ -39,14 +39,11 @@ import org.apache.commons.logging.LogFactory;
public class MapClusterLayer implements MapPanelLayer {
private /*final */ static boolean ANIMATE_CLUSTERING = false;
private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 5;
private Log log = LogFactory.getLog(MapClusterLayer.class);
private MapPanel map;
@Override
public void destroyLayer() {
@ -70,8 +67,26 @@ public class MapClusterLayer implements MapPanelLayer {
};
menu.add(clustering);
}
private class ClusteringContext {
// final
boolean ANIMATE_CLUSTERING = true;
boolean BASEMAP_CLUSTERING = true;
int ZOOM_LIMIT = BASEMAP_CLUSTERING ? 15 : 13;
int TILE_BOUNDARIES = BASEMAP_CLUSTERING? 1 : 10;
int LOCAL_TILE_BOUNDARIES = BASEMAP_CLUSTERING? 4 : 2;
int zm = 31 - ZOOM_LIMIT;
// variable
int outOfTile = 0;
int outOfDistance = 0;
int roadProcessed = 0;
int segmentsProcessed = 0;
float minRatio = 1f;
int roadMinProcessed = 0;
}
@ -81,27 +96,25 @@ public class MapClusterLayer implements MapPanelLayer {
double fx = (popupMenuPoint.x - map.getCenterPointX()) / map.getTileSize();
final double latitude = MapUtils.getLatitudeFromTile(map.getZoom(), map.getYTile() + fy);
final double longitude = MapUtils.getLongitudeFromTile(map.getZoom(), map.getXTile() + fx);
final ClusteringContext clusterCtx = new ClusteringContext();
new Thread(new Runnable() {
@Override
public void run() {
try {
List<RouteSegment> ways = clustering(latitude, longitude);
if (!ANIMATE_CLUSTERING) {
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
for (RouteSegment s : ways) {
Way w = new Way(-1);
for (int i = 0; i < s.getRoad().getPointsLength(); i++) {
double lat = MapUtils.get31LatitudeY(s.getRoad().getPoint31YTile(i));
double lon = MapUtils.get31LongitudeX(s.getRoad().getPoint31XTile(i));
w.addNode(new Node(lat, lon, -1));
}
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
final DataTileManager<Way> points = new DataTileManager<Way>(11);
List<RouteSegment> ways = clustering(clusterCtx, latitude, longitude, points);
for (RouteSegment s : ways) {
Way w = new Way(-1);
for (int i = 0; i < s.getRoad().getPointsLength(); i++) {
double lat = MapUtils.get31LatitudeY(s.getRoad().getPoint31YTile(i));
double lon = MapUtils.get31LongitudeX(s.getRoad().getPoint31XTile(i));
w.addNode(new Node(lat, lon, -1));
}
map.setPoints(points);
map.repaint();
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
}
map.setPoints(points);
map.repaint();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@ -111,7 +124,8 @@ public class MapClusterLayer implements MapPanelLayer {
}).start();
}
private List<RouteSegment> clustering(double lat, double lon) throws IOException{
private List<RouteSegment> clustering(final ClusteringContext clusterCtx, double lat, double lon,
final DataTileManager<Way> points ) throws IOException{
List<BinaryMapIndexReader> rs = new ArrayList<BinaryMapIndexReader>();
for (File f : new File(DataExtractionSettings.getSettings().getBinaryFilesDir()).listFiles()) {
if (f.getName().endsWith(".obf")) {
@ -123,7 +137,7 @@ public class MapClusterLayer implements MapPanelLayer {
Builder builder = RoutingConfiguration.getDefault();
RoutingConfiguration config = builder.build("car", RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3);
RoutingContext ctx = new RoutingContext(config, NativeSwingRendering.getDefaultFromSettings(),
rs.toArray(new BinaryMapIndexReader[rs.size()]));
rs.toArray(new BinaryMapIndexReader[rs.size()]), clusterCtx.BASEMAP_CLUSTERING);
// find closest way
RouteSegment st = router.findRouteSegment(lat, lon, ctx);
if (st != null) {
@ -132,8 +146,6 @@ public class MapClusterLayer implements MapPanelLayer {
log.info("ROAD TO START " + highway + " " + //road.getName() + " "
+ road.id);
}
final DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
map.setPoints(points);
ctx.setVisitor(new RouteSegmentVisitor() {
@ -141,7 +153,7 @@ public class MapClusterLayer implements MapPanelLayer {
@Override
public void visitSegment(RouteSegment s, int endSegment, boolean poll) {
if(!ANIMATE_CLUSTERING){
if(!clusterCtx.ANIMATE_CLUSTERING){
return;
}
cache.add(s);
@ -150,11 +162,18 @@ public class MapClusterLayer implements MapPanelLayer {
}
for (RouteSegment segment : cache) {
Way way = new Way(-1);
for (int i = 0; i < segment.getRoad().getPointsLength(); i++) {
boolean d = segment.getSegmentStart() <segment.getParentSegmentEnd() ;
for (int i = segment.getSegmentStart(); i != segment.getParentSegmentEnd(); ) {
net.osmand.osm.Node n = new net.osmand.osm.Node(MapUtils.get31LatitudeY(segment.getRoad()
.getPoint31YTile(i)), MapUtils.get31LongitudeX(segment.getRoad().getPoint31XTile(i)), -1);
way.addNode(n);
if(d) {
i++;
} else {
i--;
}
}
way.putTag("color", "white");
LatLon n = way.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), way);
}
@ -174,7 +193,7 @@ public class MapClusterLayer implements MapPanelLayer {
}
});
List<RouteSegment> results = searchCluster(ctx, st);
List<RouteSegment> results = searchCluster(clusterCtx, ctx, st);
return results;
}
@ -182,139 +201,111 @@ public class MapClusterLayer implements MapPanelLayer {
private long calculateId(RouteSegment r, int segment){
return (r.getRoad().getId() << 8) + segment;
private long calculateId(RouteSegment r){
return (r.getRoad().getId() /*<< 8*/) /*+ segment*/;
}
private List<RouteSegment> searchCluster(RoutingContext ctx, RouteSegment st) throws IOException {
Queue<List<RouteSegment>> queue = new LinkedList<List<RouteSegment>>();
private List<RouteSegment> searchCluster(ClusteringContext cCtx, RoutingContext ctx, RouteSegment st) throws IOException {
Queue<RouteSegment> queue = new LinkedList<RouteSegment>();
List<RouteSegment> result = new ArrayList<BinaryRoutePlanner.RouteSegment>();
TLongHashSet visitedIds = new TLongHashSet();
ArrayList<RouteSegment> start = new ArrayList<RouteSegment>();
start.add(st);
queue.add(start);
queue.add(st);
RouteDataObject startRoad = st.getRoad();
int ZOOM_LIMIT = 13;
int TILE_BOUNDARIES = 10;
int LOCAL_TILE_BOUNDARIES = 2;
int zm = 31 - ZOOM_LIMIT;
int tileX = startRoad.getPoint31XTile(st.getSegmentStart()) >> zm;
int tileY = startRoad.getPoint31YTile(st.getSegmentStart()) >> zm;
int outOfTile = 0;
int outOfDistance = 0;
int segmentsProcessed = 0;
float minRatio = 1f;
int segmentsMinProcessed = 0;
TLongHashSet onTheMap = new TLongHashSet();
while(!queue.isEmpty()){
List<RouteSegment> segments = queue.peek();
if(segments.size() == 0) {
queue.poll();
int tileX = startRoad.getPoint31XTile(st.getSegmentStart()) >> cCtx.zm;
int tileY = startRoad.getPoint31YTile(st.getSegmentStart()) >> cCtx.zm;
while (!queue.isEmpty()) {
RouteSegment segment = queue.poll();
if (visitedIds.contains(calculateId(segment))) {
// System.out.println("contains " + segment.getRoad());
continue;
}
RouteSegment segment = segments.remove(segments.size() - 1);
RouteDataObject road = segment.getRoad();
if(visitedIds.contains(calculateId(segment, segment.getSegmentStart()))){
continue;
// System.out.println(segment.getRoad());
visitedIds.add(calculateId(segment));
// Visualization of steps !
if (ctx.getVisitor() != null) {
ctx.getVisitor().visitSegment(segment, -1, true);
}
segmentsProcessed++;
if(segmentsProcessed > 50) {
float ratio = (float) (queue.size() + outOfTile + outOfDistance) / segmentsProcessed;
if(ratio < minRatio) {
minRatio = ratio;
segmentsMinProcessed = segmentsProcessed;
}
}
visitedIds.add(calculateId(segment, segment.getSegmentStart()));
boolean minusAllowed = true;
boolean plusAllowed = true;
int d = 1;
while (minusAllowed || plusAllowed) {
int segmentEnd = segment.getSegmentStart() + d;
int currentD = d;
if (!minusAllowed && d > 0) {
d++;
} else if (!plusAllowed && d < 0) {
d--;
} else {
if (d <= 0) {
d = -d + 1;
} else {
d = -d;
}
}
if (segmentEnd < 0) {
minusAllowed = false;
continue;
}
if (segmentEnd >= road.getPointsLength()) {
plusAllowed = false;
continue;
}
if (visitedIds.contains(calculateId(segment, segmentEnd))) {
if (currentD > 0) {
plusAllowed = false;
} else {
minusAllowed = false;
}
continue;
}
visitedIds.add(calculateId(segment, segmentEnd));
int x = road.getPoint31XTile(segmentEnd);
int y = road.getPoint31YTile(segmentEnd);
RouteSegment next = ctx.loadRouteSegment(x, y, 0);
RouteSegment toAdd = segment;
if (!onTheMap.contains(toAdd.getRoad().getId())) {
onTheMap.add(toAdd.getRoad().getId());
// Visualization of steps !
ctx.getVisitor().visitSegment(toAdd, -1, true);
}
List<RouteSegment> nextSegments = new ArrayList<BinaryRoutePlanner.RouteSegment>();
boolean out = false;
boolean outDistance = false;
while (next != null) {
if (!visitedIds.contains(calculateId(next, next.getSegmentStart()))) {
int tX = next.getRoad().getPoint31XTile(next.getSegmentStart()) >> zm;
int tY = next.getRoad().getPoint31YTile(next.getSegmentStart()) >> zm;
String highway = next.getRoad().getHighway();
if(notClusterAtAll(next.getRoad())) {
out = true;
} else if(Math.abs(tX - tileX) < LOCAL_TILE_BOUNDARIES && Math.abs(tY - tileY) < LOCAL_TILE_BOUNDARIES) {
nextSegments.add(next);
} else {
if (!isMajorHighway(highway) && Math.abs(tX - tileX) < TILE_BOUNDARIES && Math.abs(tY - tileY) < TILE_BOUNDARIES) {
nextSegments.add(next);
} else {
outDistance = true;
}
}
}
next = next.getNext();
}
if(out) {
outOfTile++;
result.add(segment);
} else if(outDistance) {
outOfDistance++;
result.add(segment);
} else if(nextSegments.size() > 0) {
queue.add(nextSegments);
cCtx.roadProcessed++;
if (cCtx.roadProcessed > 50) {
float ratio = (float) (queue.size() + cCtx.outOfTile + cCtx.outOfDistance) / cCtx.roadProcessed;
if (ratio < cCtx.minRatio) {
cCtx.minRatio = ratio;
cCtx.roadMinProcessed = cCtx.roadProcessed;
}
}
processSegment(cCtx, ctx, segment, queue, result, tileX, tileY, true);
processSegment(cCtx, ctx, segment, queue, result, tileX, tileY, false);
}
log.info("Current ratio " + ((float) (queue.size() + outOfTile + outOfDistance) / segmentsProcessed) + " min ratio " + minRatio
+ " min segments procesed " + segmentsMinProcessed );
String res = "Processed " + segmentsProcessed + " and borders are " + outOfTile + " out because of distance " + outOfDistance;
log.info("Current ratio " + ((float) (queue.size() + cCtx.outOfTile + cCtx.outOfDistance) / cCtx.roadProcessed) + " min ratio " + cCtx.minRatio
+ " min segments procesed " + cCtx.roadMinProcessed );
String res = "Processed " + cCtx.roadProcessed + " / " + cCtx.segmentsProcessed+ " and borders are " + cCtx.outOfTile + " out because of distance " + cCtx.outOfDistance;
log.info(res);
System.out.println(res);
return result;
}
public boolean notClusterAtAll(RouteDataObject obj) {
private void addSegmentResult(List<RouteSegment> result , RouteSegment sgm, int segmentSt, int segmentEnd) {
RouteSegment r = new RouteSegment(sgm.getRoad(), segmentSt);
r.setParentSegmentEnd(segmentEnd);
result.add(r);
}
private void processSegment(ClusteringContext cCtx, RoutingContext ctx, RouteSegment segment, Queue<RouteSegment> queue, List<RouteSegment> result,
int tileX, int tileY, boolean direction ) {
int d = 1;
boolean directionAllowed = true;
int prev = segment.getSegmentStart();
while (directionAllowed) {
int segmentEnd = segment.getSegmentStart() + (direction?d : -d);
d++;
if (segmentEnd < 0 || segmentEnd >= segment.getRoad().getPointsLength()) {
directionAllowed = false;
continue;
}
int x = segment.getRoad().getPoint31XTile(segmentEnd);
int y = segment.getRoad().getPoint31YTile(segmentEnd);
int tX = x >> cCtx.zm;
int tY = y >> cCtx.zm;
cCtx.segmentsProcessed ++;
if(notClusterAtAll(cCtx, segment.getRoad())) {
cCtx.outOfTile++;
addSegmentResult(result, segment, prev, segmentEnd);
return;
}
if (isMajorHighway(cCtx, segment.getRoad().getHighway()) && (Math.abs(tX - tileX) > cCtx.TILE_BOUNDARIES || Math.abs(tY - tileY) <
cCtx.TILE_BOUNDARIES)) {
cCtx.outOfDistance++;
// System.out.println("Res Major " + segment.getRoad());
addSegmentResult(result, segment, prev, segmentEnd);
return;
} else if(Math.abs(tX - tileX) > cCtx.LOCAL_TILE_BOUNDARIES || Math.abs(tY - tileY) >
cCtx.LOCAL_TILE_BOUNDARIES) {
// System.out.println("Res " + segment.getRoad());
cCtx.outOfDistance++;
addSegmentResult(result, segment, prev, segmentEnd);
return;
}
RouteSegment next = ctx.loadRouteSegment(x, y, 0);
while (next != null) {
// System.out.println(" >> " + next.getRoad());
queue.add(next);
next = next.getNext();
}
prev = segmentEnd;
}
}
public boolean notClusterAtAll(ClusteringContext clusterCtx, RouteDataObject obj) {
if(clusterCtx.BASEMAP_CLUSTERING) {
return false;
}
String highway = obj.getHighway();
if(highway != null) {
return highway.equals("trunk") || highway.equals("motorway")
@ -329,10 +320,13 @@ public class MapClusterLayer implements MapPanelLayer {
return false;
}
public boolean isMajorHighway(String h) {
public boolean isMajorHighway(ClusteringContext clusterCtx, String h) {
if(h == null) {
return false;
}
if(clusterCtx.BASEMAP_CLUSTERING) {
return h.equals("motorway") || h.equals("trunk");
}
return h.equals("primary")
|| h.equals("secondary");
}

View file

@ -214,8 +214,7 @@ public class MapRouterLayer implements MapPanelLayer {
@Override
public void run() {
List<Way> ways = route_YOURS(startRoute, endRoute);
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
DataTileManager<Way> points = new DataTileManager<Way>(11);
for(Way w : ways){
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
@ -235,8 +234,7 @@ public class MapRouterLayer implements MapPanelLayer {
@Override
public void run() {
List<Way> ways = route_CloudMate(startRoute, endRoute);
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
DataTileManager<Way> points = new DataTileManager<Way>(11);
for (Way w : ways) {
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
@ -295,8 +293,7 @@ public class MapRouterLayer implements MapPanelLayer {
public void run() {
List<Way> ways = selfRoute(startRoute, endRoute, intermediates, previousRoute, useBasemap);
if (ways != null) {
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
DataTileManager<Way> points = new DataTileManager<Way>(11);
for (Way w : ways) {
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
@ -647,8 +644,7 @@ public class MapRouterLayer implements MapPanelLayer {
}
}
final DataTileManager<Entity> points = new DataTileManager<Entity>();
points.setZoom(11);
final DataTileManager<Entity> points = new DataTileManager<Entity>(11);
map.setPoints(points);
ctx.setVisitor(new RouteSegmentVisitor() {