Add border line indexing

This commit is contained in:
Victor Shcherb 2012-10-22 21:44:54 +02:00
parent b6a7320aa6
commit ec56bac4cb
3 changed files with 191 additions and 17 deletions

View file

@ -741,10 +741,10 @@ public class IndexCreator {
public static void main(String[] args) throws IOException, SAXException, SQLException, InterruptedException {
long time = System.currentTimeMillis();
IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$
creator.setIndexMap(true);
creator.setIndexAddress(true);
creator.setIndexPOI(true);
creator.setIndexTransport(true);
// creator.setIndexMap(true);
// creator.setIndexAddress(true);
// creator.setIndexPOI(true);
// creator.setIndexTransport(true);
creator.setIndexRouting(true);
// creator.deleteDatabaseIndexes = false;
@ -755,8 +755,8 @@ public class IndexCreator {
MapRenderingTypes rt = MapRenderingTypes.getDefault();
MapZooms zooms = MapZooms.getDefault(); // MapZooms.parseZooms("15-");
String file = "/home/victor/projects/OsmAnd/temp/map.osm";
// String file = "/home/victor/projects/OsmAnd/temp/belgium.osm.pbf";
// String file = "/home/victor/projects/OsmAnd/temp/map.osm";
String file = "/home/victor/projects/OsmAnd/temp/luxembourg.osm.pbf";
// String file = "/home/victor/projects/OsmAnd/temp/warsaw-map.osm.pbf";
int st = file.lastIndexOf('/');
int e = file.indexOf('.', st);

View file

@ -2,8 +2,10 @@ package net.osmand.data.preparation;
import gnu.trove.TIntCollection;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.list.array.TByteArrayList;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.list.array.TLongArrayList;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import gnu.trove.set.hash.TIntHashSet;
import gnu.trove.set.hash.TLongHashSet;
@ -18,7 +20,10 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -32,6 +37,7 @@ import java.util.Set;
import net.osmand.Algoritms;
import net.osmand.IProgress;
import net.osmand.binary.OsmandOdb.IdTable;
import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteBorderPoint;
import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteDataBlock;
import net.osmand.binary.OsmandOdb.RestrictionData;
import net.osmand.binary.OsmandOdb.RestrictionData.Builder;
@ -61,6 +67,8 @@ import rtree.RTreeException;
import rtree.RTreeInsertException;
import rtree.Rect;
import com.google.protobuf.ByteString;
public class IndexRouteCreator extends AbstractIndexPartCreator {
private Connection mapConnection;
@ -83,6 +91,8 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
TLongObjectHashMap<GeneralizedCluster> generalClusters = new TLongObjectHashMap<GeneralizedCluster>();
private RouteBorderLines routeBorders = new RouteBorderLines(14, false);
private RouteBorderLines baseRouteBorders = new RouteBorderLines(12, true);
private PreparedStatement mapRouteInsertStat;
private PreparedStatement basemapRouteInsertStat;
@ -104,8 +114,14 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
// Load point with tags!
ctx.loadEntityWay(e);
routeTypes.encodePointTypes(e, pointTypes);
// addWayToIndex(e.getId(), e.getNodes(), mapRouteInsertStat, routeTree);
// generalizeWay(e);
routeBorders.addWay(e, outTypes);
addWayToIndex(e.getId(), e.getNodes(), mapRouteInsertStat, routeTree);
}
encoded = routeTypes.encodeBaseEntity(e, outTypes, names) && e.getNodes().size() >= 2;
if (encoded ) {
baseRouteBorders.addWay(e, outTypes);
generalizeWay(e);
}
}
@ -201,9 +217,6 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
public void generalizeWay(Way e) throws SQLException {
if (!routeTypes.encodeBaseEntity(e, outTypes, names) || e.getNodes().size() < 2) {
return;
}
List<Node> ns = e.getNodes();
GeneralizedWay w = new GeneralizedWay(e.getId());
@ -409,8 +422,8 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
routeTree, false);
TLongObjectHashMap<BinaryFileReference> base = writeBinaryRouteIndexHeader(writer,
baserouteTree, true);
writeBorderBox(false);
writeBorderBox(true);
writeBorderBox(writer, routeBorders);
writeBorderBox(writer, baseRouteBorders);
writeBinaryRouteIndexBlocks(writer, routeTree, false, route);
writeBinaryRouteIndexBlocks(writer, baserouteTree, true, base);
@ -422,8 +435,88 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
}
}
private void writeBorderBox(boolean basemap) {
// TODO Auto-generated method stub
private void sortBorderPoints(List<RouteBorderPointCreator> pnts, final boolean x){
Collections.sort(pnts, new Comparator<RouteBorderPointCreator>() {
@Override
public int compare(RouteBorderPointCreator o1, RouteBorderPointCreator o2) {
int t1 = x ? o1.x : o1.y;
int t2 = x ? o2.x : o2.y;
if(t1 == t2) {
return 0;
}
return t1 < t2 ? -1 : 1;
}
});
}
private void writeBorderBox(BinaryMapIndexWriter writer, RouteBorderLines routeBorders) throws IOException {
writer.startWriteRouteBorderBox(routeBorders.leftX, routeBorders.rightX, routeBorders.topY, routeBorders.bottomY,
routeBorders.zoomToSplit, routeBorders.basemap);
Map<BinaryFileReference, List<RouteBorderPointCreator>> refs = new LinkedHashMap<BinaryFileReference, List<RouteBorderPointCreator>>();
int[] keys = routeBorders.bx.keys();
int pntsCount = 0;
Arrays.sort(keys);
for(int j=0; j<keys.length; j++) {
int key = keys[j];
List<RouteBorderPointCreator> pnts = routeBorders.bx.get(key);
sortBorderPoints(pnts, true);
BinaryFileReference ref = writer.writeRouteBorderLine(key, pnts.get(0).y, -1, pnts.get(pnts.size() - 1).y);
// System.out.println("Line x -> " + (key >> (31 - routeBorders.zoomToSplit)) + " points " + pnts.size());
pntsCount += pnts.size();
refs.put(ref, pnts);
}
keys = routeBorders.by.keys();
Arrays.sort(keys);
for(int j=0; j<keys.length; j++) {
int key = keys[j];
List<RouteBorderPointCreator> pnts = routeBorders.by.get(key);
sortBorderPoints(pnts, false);
BinaryFileReference ref = writer.writeRouteBorderLine(pnts.get(0).x, key, pnts.get(pnts.size() - 1).x, -1);
// System.out.println("Line y -> " + (key >> (31 - routeBorders.zoomToSplit)) + " points " + pnts.size());
refs.put(ref, pnts);
pntsCount += pnts.size();
}
if(logMapDataWarn != null) {
logMapDataWarn.info("Total border lines " + (routeBorders.by.size() + routeBorders.bx.size()) + " total points " + pntsCount);
}
writeRoutePointBlocks(writer, refs);
writer.endWriteRouteBorderBox();
}
private void writeRoutePointBlocks(BinaryMapIndexWriter writer, Map<BinaryFileReference, List<RouteBorderPointCreator>> refs) throws IOException {
Iterator<Entry<BinaryFileReference, List<RouteBorderPointCreator>>> it = refs.entrySet().iterator();
while(it.hasNext()) {
Entry<BinaryFileReference, List<RouteBorderPointCreator>> entry = it.next();
BinaryFileReference ref = entry.getKey();
List<RouteBorderPointCreator> list = entry.getValue();
long baseId = list.get(0).id;
int x = list.get(0).x;
int y = list.get(0).y;
List<RouteBorderPoint> points = new ArrayList<RouteBorderPoint>();
int px = x;
int py = y;
long pid = baseId;
for(RouteBorderPointCreator pnt : list) {
RouteBorderPoint.Builder bld = RouteBorderPoint.newBuilder();
bld.setDx(pnt.x - px);
bld.setDy(pnt.y - py);
bld.setDirection(pnt.direction ? 1 : 0);
bld.setRoadId(pnt.id - pid);
TByteArrayList bs = new TByteArrayList();
for(int k = 0; k < pnt.types.length ; k++) {
writer.writeRawVarint32(bs, routeTypes.getTypeByInternalId(pnt.types[k]).getTargetId());
}
bld.setTypes(ByteString.copyFrom(bs.toArray()));
points.add(bld.build());
px = pnt.x;
py = pnt.y;
pid = pnt.id;
}
writer.writeRouteBorderPointBlock(x, y, list.get(0).id, points, ref);
}
}
private Node convertBaseToNode(long s) {
@ -1028,9 +1121,89 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
writer.endRouteTreeElement();
}
static class RouteBorderPointCreator {
int x;
int y;
boolean direction;
long id;
int[] types;
}
static class RouteBorderLines {
public int leftX = -1;
public int rightX = -1;
public int topY = -1;
public int bottomY = -1;
public final int zoomToSplit;
public final boolean basemap;
public final TIntObjectHashMap<List<RouteBorderPointCreator>> bx = new TIntObjectHashMap<List<RouteBorderPointCreator>>();
public final TIntObjectHashMap<List<RouteBorderPointCreator>> by = new TIntObjectHashMap<List<RouteBorderPointCreator>>();
public RouteBorderLines(int zoomToSplit, boolean basemap) {
this.zoomToSplit = zoomToSplit;
this.basemap = basemap;
}
private void addBorderPoint( TIntObjectHashMap<List<RouteBorderPointCreator>> b, int key,
boolean direction, int x, int y, long id, TIntArrayList outTypes) {
List<RouteBorderPointCreator> list = b.get(key);
if(list == null) {
list = new ArrayList<IndexRouteCreator.RouteBorderPointCreator>();
b.put(key, list);
}
RouteBorderPointCreator pnt = new RouteBorderPointCreator();
pnt.id = id;
pnt.x = pnt.x;
pnt.y = pnt.y;
pnt.direction = direction;
pnt.types = outTypes.toArray();
list.add(pnt);
}
public void addWay(Way e, TIntArrayList outTypes) {
if(leftX == -1) {
Node n = e.getNodes().get(0);
leftX = rightX = MapUtils.get31TileNumberX(n.getLongitude());
topY = bottomY = MapUtils.get31TileNumberY(n.getLatitude());
}
int pzx = -1;
int pzy = -1;
int px = -1;
int py = -1;
for(int i = 0; i<e.getNodes().size(); i++) {
Node n = e.getNodes().get(i);
if(n != null) {
int x = MapUtils.get31TileNumberX(n.getLongitude());
int y = MapUtils.get31TileNumberY(n.getLatitude());
leftX = Math.min(leftX, x);
rightX = Math.max(rightX, x);
bottomY = Math.max(bottomY, y);
topY = Math.min(topY, y);
int zx = x >> (31 - zoomToSplit);
int zy = y >> (31 - zoomToSplit);
if(i > 0) {
if(zx != pzx) {
int cx = Math.max(pzx, zx) << (31 - zoomToSplit);
int cy = (int) (py + ((float)y - py) * ((float) cx - px) / ((float) x - px));
addBorderPoint(bx, cx, zx < pzx, cx, cy, e.getId(), outTypes);
}
if(zy != pzy) {
int cy = Math.max(pzy, zy) << (31 - zoomToSplit);
int cx = (int) (px + ((float)x - py) * ((float) cy - py) / ((float) y - py));
addBorderPoint(by, cy, zy < pzy, cx, cy, e.getId(), outTypes);
}
}
pzx = zx;
pzy = zy;
px = x;
py = y;
}
}
}
}
/*private*/ static class GeneralizedCluster {

View file

@ -577,6 +577,7 @@ message OsmAndRoutingIndex {
// direction from left or top
optional int32 direction = 3;
optional bytes types = 4;
// delta from previous point
optional sint64 roadId = 7;
}