Small data tile manager refactoring
This commit is contained in:
parent
5d1e5ea54d
commit
48fcb7d1dc
10 changed files with 222 additions and 207 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -33,30 +29,18 @@ public class DataTileManager<T> {
|
|||
public int getZoom() {
|
||||
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>());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
35
DataExtractionOSM/src/net/osmand/router/BaseRouteResult.java
Normal file
35
DataExtractionOSM/src/net/osmand/router/BaseRouteResult.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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>>();
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
Loading…
Reference in a new issue