Refactor rendering types. Remove polyline/point/polygon concept
This commit is contained in:
parent
c9b9466f2e
commit
2612e665ad
4 changed files with 783 additions and 783 deletions
|
@ -215,7 +215,7 @@ public class BinaryMapIndexWriter {
|
|||
int highestTargetId = types.size();
|
||||
// 1. prepare map rule type to write
|
||||
for (MapRulType t : types.values()) {
|
||||
if (!t.isMapIndexed() || t.getTargetTagValue() != null || t.getFreq() == 0) {
|
||||
if (t.getTargetTagValue() != null || t.getFreq() == 0) {
|
||||
t.setTargetId(highestTargetId++);
|
||||
} else {
|
||||
out.add(t);
|
||||
|
@ -348,7 +348,6 @@ public class BinaryMapIndexWriter {
|
|||
byte[] additionalTypes, Map<MapRulType, String> names, Map<String, Integer> stringTable,
|
||||
MapDataBlock.Builder dataBlock) throws IOException{
|
||||
|
||||
Bounds bounds = stackBounds.peek();
|
||||
|
||||
MapData.Builder data = MapData.newBuilder();
|
||||
// calculate size
|
||||
|
@ -359,7 +358,7 @@ public class BinaryMapIndexWriter {
|
|||
int x = Algoritms.parseIntFromBytes(coordinates, i * 8);
|
||||
int y = Algoritms.parseIntFromBytes(coordinates, i * 8 + 4);
|
||||
int tx = (x - pcalcx) >> SHIFT_COORDINATES;
|
||||
int ty = (x - pcalcy) >> SHIFT_COORDINATES;
|
||||
int ty = (y - pcalcy) >> SHIFT_COORDINATES;
|
||||
|
||||
writeRawVarint32(mapDataBuf, tx);
|
||||
writeRawVarint32(mapDataBuf, ty);
|
||||
|
@ -389,7 +388,7 @@ public class BinaryMapIndexWriter {
|
|||
pcalcy = ptop;
|
||||
} else {
|
||||
int tx = (x - pcalcx) >> SHIFT_COORDINATES;
|
||||
int ty = (x - pcalcy) >> SHIFT_COORDINATES;
|
||||
int ty = (y - pcalcy) >> SHIFT_COORDINATES;
|
||||
|
||||
writeRawVarint32(mapDataBuf, tx);
|
||||
writeRawVarint32(mapDataBuf, ty);
|
||||
|
|
|
@ -36,6 +36,7 @@ import net.osmand.osm.Relation;
|
|||
import net.osmand.osm.Way;
|
||||
import net.osmand.osm.Entity.EntityId;
|
||||
import net.osmand.osm.Entity.EntityType;
|
||||
import net.osmand.osm.MapRenderingTypes.MapRulType;
|
||||
import net.osmand.osm.OSMSettings.OSMTagKey;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -57,7 +58,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
private MapRenderingTypes renderingTypes;
|
||||
private MapZooms mapZooms;
|
||||
|
||||
|
||||
// MEMORY map : save it in memory while that is allowed
|
||||
private Map<Long, Set<Integer>>[] multiPolygonsWays;
|
||||
private Map<Long, String> multiPolygonsNames = new LinkedHashMap<Long, String>();
|
||||
|
@ -68,8 +68,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
TIntArrayList typeUse = new TIntArrayList(8);
|
||||
List<Long> restrictionsUse = new ArrayList<Long>(8);
|
||||
|
||||
|
||||
|
||||
private PreparedStatement mapBinaryStat;
|
||||
private PreparedStatement mapLowLevelBinaryStat;
|
||||
private int lowLevelWays = -1;
|
||||
|
@ -79,7 +77,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
private int zoomWaySmothness = 0;
|
||||
private final Log logMapDataWarn;
|
||||
|
||||
|
||||
public IndexVectorMapCreator(Log logMapDataWarn, MapZooms mapZooms, MapRenderingTypes renderingTypes, int zoomWaySmothness) {
|
||||
this.logMapDataWarn = logMapDataWarn;
|
||||
this.mapZooms = mapZooms;
|
||||
|
@ -116,7 +113,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(!outerFound){
|
||||
if (!outerFound) {
|
||||
logMapDataWarn.warn("Probably map bug: Multipoligon id=" + e.getId() + " contains only inner ways : "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return;
|
||||
}
|
||||
|
@ -136,7 +133,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
// skip incompleted rings and do not add whole relation ?
|
||||
if (!incompletedRings.isEmpty()) {
|
||||
logMapDataWarn.warn("In multipolygon " + e.getId() + " there are incompleted ways : " + incompletedRings);
|
||||
logMapDataWarn.warn("In multipolygon " + e.getId() + " there are incompleted ways : " + incompletedRings);
|
||||
return;
|
||||
// completedRings.addAll(incompletedRings);
|
||||
}
|
||||
|
@ -147,16 +144,19 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
for (Way way : l) {
|
||||
boolean inner = "inner".equals(entities.get(way)); //$NON-NLS-1$
|
||||
if (innerType != inner) {
|
||||
logMapDataWarn.warn("Probably map bug: Multipoligon contains outer and inner ways.\n" + //$NON-NLS-1$
|
||||
"Way:" + way.getId() + " is strange part of completed ring. InnerType:" + innerType + " way inner: " + inner + " way inner string:" + entities.get(way)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
logMapDataWarn
|
||||
.warn("Probably map bug: Multipoligon contains outer and inner ways.\n" + //$NON-NLS-1$
|
||||
"Way:"
|
||||
+ way.getId()
|
||||
+ " is strange part of completed ring. InnerType:" + innerType + " way inner: " + inner + " way inner string:" + entities.get(way)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Node nodeOut = checkOuterWaysEncloseInnerWays(completedRings, entities);
|
||||
if(nodeOut != null){
|
||||
logMapDataWarn.warn("Map bug: Multipoligon contains 'inner' way point outside of 'outer' border.\n" + //$NON-NLS-1$
|
||||
if (nodeOut != null) {
|
||||
logMapDataWarn.warn("Map bug: Multipoligon contains 'inner' way point outside of 'outer' border.\n" + //$NON-NLS-1$
|
||||
"Multipolygon id : " + e.getId() + ", inner node out id : " + nodeOut.getId()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
|
@ -185,15 +185,13 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Node checkOuterWaysEncloseInnerWays(List<List<Way>> completedRings, Map<Entity, String> entities) {
|
||||
List<List<Way>> innerWays = new ArrayList<List<Way>>();
|
||||
Boundary outerBoundary = new Boundary(true);
|
||||
Node toReturn = null;
|
||||
for(List<Way> ring : completedRings){
|
||||
for (List<Way> ring : completedRings) {
|
||||
boolean innerType = "inner".equals(entities.get(ring.get(0))); //$NON-NLS-1$
|
||||
if(!innerType){
|
||||
if (!innerType) {
|
||||
outerBoundary.getOuterWays().addAll(ring);
|
||||
} else {
|
||||
innerWays.add(ring);
|
||||
|
@ -216,7 +214,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
private void putMultipolygonType(Map<Long, Set<Integer>> multiPolygonsWays, long baseId, int mtType, boolean inverse) {
|
||||
if (mtType == 0) {
|
||||
return;
|
||||
|
@ -275,96 +272,23 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
|
||||
|
||||
|
||||
private void writeBinaryEntityToMapDatabase(Entity e, long baseId, boolean inverse, int level) throws SQLException {
|
||||
int type = renderingTypes.encodeEntityWithType(e, mapZooms.getLevel(level).getMaxZoom(), false, typeUse);
|
||||
Map<Long, Set<Integer>> multiPolygonsWays = this.multiPolygonsWays[level];
|
||||
boolean hasMulti = e instanceof Way && multiPolygonsWays.containsKey(e.getId());
|
||||
if (hasMulti) {
|
||||
Set<Integer> set = multiPolygonsWays.get(e.getId());
|
||||
boolean first = true;
|
||||
for (Integer i : set) {
|
||||
if (first && type == 0) {
|
||||
type = i;
|
||||
first = false;
|
||||
} else {
|
||||
// do not compare direction
|
||||
int k = i & 0x7fff;
|
||||
int ks = k | MapRenderingTypes.POLYGON_TYPE;
|
||||
// turn of polygon type 3 ^ (suppose polygon = multipolygon)
|
||||
if (ks == type) {
|
||||
type = i;
|
||||
} else {
|
||||
int ind = typeUse.indexOf(ks);
|
||||
if (ind == -1) {
|
||||
typeUse.add(i);
|
||||
} else {
|
||||
typeUse.set(ind, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
restrictionsUse.clear();
|
||||
// try to find restrictions only for max zoom level
|
||||
if (level == 0 && highwayRestrictions.containsKey(baseId)) {
|
||||
restrictionsUse.addAll(highwayRestrictions.get(baseId));
|
||||
}
|
||||
|
||||
boolean point = (type & 3) == MapRenderingTypes.POINT_TYPE;
|
||||
RTree rtree = null;
|
||||
long id = convertBaseIdToGeneratedId(baseId, level);
|
||||
rtree = mapTree[level];
|
||||
|
||||
boolean skip = false;
|
||||
|
||||
String eName = renderingTypes.getEntityName(e);
|
||||
if (eName == null) {
|
||||
eName = multiPolygonsNames.get(baseId);
|
||||
}
|
||||
int highwayAttributes = 0;
|
||||
if (e.getTag(OSMTagKey.HIGHWAY) != null) {
|
||||
highwayAttributes = MapRenderingTypes.getHighwayAttributes(e);
|
||||
}
|
||||
|
||||
if (e instanceof Way) {
|
||||
id |= 1;
|
||||
// simplify route
|
||||
int zoomToSimplify = mapZooms.getLevel(level).getMaxZoom() - 1;
|
||||
if (zoomToSimplify < 15) {
|
||||
e = simplifyWay((Way) e, id, hasMulti, zoomToSimplify, eName, type, level);
|
||||
skip = e == null;
|
||||
}
|
||||
|
||||
}
|
||||
if (!skip) {
|
||||
insertBinaryMapRenderObjectIndex(rtree, e, eName, id, type, typeUse, highwayAttributes, restrictionsUse, inverse, point, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private long encodeTypesToOneLong(int mainType) {
|
||||
long i = 0;
|
||||
int ind = 0;
|
||||
int sh = 0;
|
||||
if(typeUse.size() > 3){
|
||||
if (typeUse.size() > 3) {
|
||||
logMapDataWarn.error("Types for low index way more than 4"); //$NON-NLS-1$
|
||||
}
|
||||
i |= (mainType << sh);
|
||||
if (typeUse.size() > ind) {
|
||||
sh += 16;
|
||||
i |= ((long)typeUse.get(ind++) << sh );
|
||||
i |= ((long) typeUse.get(ind++) << sh);
|
||||
if (typeUse.size() > ind) {
|
||||
sh += 16;
|
||||
i |= ((long)typeUse.get(ind++) << sh );
|
||||
i |= ((long) typeUse.get(ind++) << sh);
|
||||
if (typeUse.size() > ind) {
|
||||
sh += 16;
|
||||
i |= ((long)typeUse.get(ind++) << sh);
|
||||
i |= ((long) typeUse.get(ind++) << sh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -398,7 +322,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
protected Way simplifyWay(Way originalE, long id, boolean hasMulti, int zoom, String name, int type, int level) throws SQLException {
|
||||
List<Node> nodes = originalE.getNodes();
|
||||
Way way = new Way(id);
|
||||
|
@ -409,7 +332,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
long longType = encodeTypesToOneLong(type);
|
||||
|
||||
if (cycle) {
|
||||
if(checkForSmallAreas(nodes, zoom + Math.min(zoomWaySmothness / 2, 3), 1, 4)){
|
||||
if (checkForSmallAreas(nodes, zoom + Math.min(zoomWaySmothness / 2, 3), 1, 4)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -422,7 +345,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
// nothing to do
|
||||
return way;
|
||||
} else {
|
||||
lowLevelWays ++;
|
||||
lowLevelWays++;
|
||||
insertLowLevelMapBinaryObject(level, longType, id, way.getNodes(), name);
|
||||
return null;
|
||||
}
|
||||
|
@ -433,7 +356,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
return lowLevelWays;
|
||||
}
|
||||
|
||||
private void loadNodes(byte[] nodes, List<Float> toPut){
|
||||
private void loadNodes(byte[] nodes, List<Float> toPut) {
|
||||
toPut.clear();
|
||||
for (int i = 0; i < nodes.length;) {
|
||||
int lat = Algoritms.parseIntFromBytes(nodes, i);
|
||||
|
@ -461,12 +384,12 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
ResultSet rs = selectStatement.executeQuery("SELECT id, start_node, end_node, name, nodes, type, level FROM low_level_map_objects");
|
||||
Set<Long> visitedWays = new LinkedHashSet<Long>();
|
||||
ArrayList<Float> list = new ArrayList<Float>(100);
|
||||
while(rs.next()){
|
||||
if(lowLevelWays != -1){
|
||||
while (rs.next()) {
|
||||
if (lowLevelWays != -1) {
|
||||
progress.progress(1);
|
||||
}
|
||||
long id = rs.getLong(1);
|
||||
if(visitedWays.contains(id)){
|
||||
if (visitedWays.contains(id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -482,7 +405,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
loadNodes(rs.getBytes(5), list);
|
||||
ArrayList<Float> wayNodes = new ArrayList<Float>(list);
|
||||
|
||||
|
||||
// combine startPoint with EndPoint
|
||||
boolean combined = true;
|
||||
while (combined) {
|
||||
|
@ -541,7 +463,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
boolean skip = false;
|
||||
boolean cycle = startNode == endNode;
|
||||
boolean hasMulti = multiPolygonsWays[level].containsKey(id >> 3);
|
||||
if(cycle || !hasMulti){
|
||||
if (cycle || !hasMulti) {
|
||||
skip = checkForSmallAreas(wNodes, zoom - 1 + Math.min(zoomWaySmothness / 2, 3), 1, 4);
|
||||
}
|
||||
|
||||
|
@ -550,8 +472,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
MapAlgorithms.simplifyDouglasPeucker(wNodes, zoom - 1 + 8 + zoomWaySmothness, 3, newWs);
|
||||
|
||||
int type = decodeTypesFromOneLong(ltype);
|
||||
insertBinaryMapRenderObjectIndex(mapTree[level], newWs, name,
|
||||
id, type, typeUse, 0, restrictionsUse, false, false, false);
|
||||
insertBinaryMapRenderObjectIndex(mapTree[level], newWs, name, id, type, typeUse, 0, restrictionsUse, false, false, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -579,20 +500,84 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
if (c < 2) {
|
||||
return true;
|
||||
}
|
||||
return ((maxX - minX) <= minz && (maxY - minY) <= maxz) ||
|
||||
((maxX - minX) <= maxz && (maxY - minY) <= minz);
|
||||
return ((maxX - minX) <= minz && (maxY - minY) <= maxz) || ((maxX - minX) <= maxz && (maxY - minY) <= minz);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void iterateMainEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException {
|
||||
if (e instanceof Way || e instanceof Node) {
|
||||
// manipulate what kind of way to load
|
||||
ctx.loadEntityData(e);
|
||||
boolean oneway = "-1".equals(e.getTag(OSMTagKey.ONEWAY)); //$NON-NLS-1$
|
||||
for (int i = 0; i < mapZooms.size(); i++) {
|
||||
boolean inverse = i == 0 ? oneway : false;
|
||||
writeBinaryEntityToMapDatabase(e, e.getId(), inverse, i);
|
||||
int type = renderingTypes.encodeEntityWithType(e, mapZooms.getLevel(level).getMaxZoom(), false, typeUse);
|
||||
Map<Long, Set<Integer>> multiPolygonsWays = this.multiPolygonsWays[level];
|
||||
boolean hasMulti = e instanceof Way && multiPolygonsWays.containsKey(e.getId());
|
||||
if (hasMulti) {
|
||||
Set<Integer> set = multiPolygonsWays.get(e.getId());
|
||||
boolean first = true;
|
||||
for (Integer i : set) {
|
||||
if (first && type == 0) {
|
||||
type = i;
|
||||
first = false;
|
||||
} else {
|
||||
// do not compare direction
|
||||
int k = i & 0x7fff;
|
||||
int ks = k | MapRenderingTypes.POLYGON_TYPE;
|
||||
// turn of polygon type 3 ^ (suppose polygon = multipolygon)
|
||||
if (ks == type) {
|
||||
type = i;
|
||||
} else {
|
||||
int ind = typeUse.indexOf(ks);
|
||||
if (ind == -1) {
|
||||
typeUse.add(i);
|
||||
} else {
|
||||
typeUse.set(ind, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
restrictionsUse.clear();
|
||||
// try to find restrictions only for max zoom level
|
||||
if (level == 0 && highwayRestrictions.containsKey(baseId)) {
|
||||
restrictionsUse.addAll(highwayRestrictions.get(baseId));
|
||||
}
|
||||
|
||||
boolean point = (type & 3) == MapRenderingTypes.POINT_TYPE;
|
||||
RTree rtree = null;
|
||||
long id = convertBaseIdToGeneratedId(baseId, level);
|
||||
rtree = mapTree[level];
|
||||
|
||||
boolean skip = false;
|
||||
|
||||
String eName = renderingTypes.getEntityName(e);
|
||||
if (eName == null) {
|
||||
eName = multiPolygonsNames.get(baseId);
|
||||
}
|
||||
int highwayAttributes = 0;
|
||||
if (e.getTag(OSMTagKey.HIGHWAY) != null) {
|
||||
highwayAttributes = MapRenderingTypes.getHighwayAttributes(e);
|
||||
}
|
||||
|
||||
if (e instanceof Way) {
|
||||
id |= 1;
|
||||
// simplify route
|
||||
int zoomToSimplify = mapZooms.getLevel(level).getMaxZoom() - 1;
|
||||
if (zoomToSimplify < 15) {
|
||||
e = simplifyWay((Way) e, id, hasMulti, zoomToSimplify, eName, type, level);
|
||||
skip = e == null;
|
||||
}
|
||||
|
||||
}
|
||||
if (!skip) {
|
||||
insertBinaryMapRenderObjectIndex(rtree, e, eName, id, type, typeUse, highwayAttributes, restrictionsUse, inverse, point, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -614,10 +599,11 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
Rect rootBounds = calcBounds(root);
|
||||
if (rootBounds != null) {
|
||||
boolean last = nodeIsLastSubTree(rtree, rootIndex);
|
||||
writer.startWriteMapLevelIndex(mapZooms.getLevel(i).getMinZoom(), mapZooms.getLevel(i).getMaxZoom(), rootBounds
|
||||
.getMinX(), rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY());
|
||||
writer.startWriteMapLevelIndex(mapZooms.getLevel(i).getMinZoom(), mapZooms.getLevel(i).getMaxZoom(),
|
||||
rootBounds.getMinX(), rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY());
|
||||
if (last) {
|
||||
BinaryFileReference ref = writer.startMapTreeElement(rootBounds.getMinX(), rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY(), true);
|
||||
BinaryFileReference ref = writer.startMapTreeElement(rootBounds.getMinX(), rootBounds.getMaxX(),
|
||||
rootBounds.getMinY(), rootBounds.getMaxY(), true);
|
||||
bounds.put(rootIndex, ref);
|
||||
}
|
||||
writeBinaryMapTree(root, rtree, writer, bounds);
|
||||
|
@ -629,18 +615,20 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
// write map data blocks
|
||||
PreparedStatement selectData = mapConnection.prepareStatement("SELECT nodes, types, name FROM binary_map_objects WHERE id = ?"); //$NON-NLS-1$
|
||||
|
||||
PreparedStatement selectData = mapConnection
|
||||
.prepareStatement("SELECT area, coordinates, innerPolygons, types, additionalTypes, name FROM binary_map_objects WHERE id = ?");
|
||||
for (int i = 0; i < mapZooms.size(); i++) {
|
||||
RTree rtree = mapTree[i];
|
||||
long rootIndex = rtree.getFileHdr().getRootIndex();
|
||||
rtree.Node root = rtree.getReadNode(rootIndex);
|
||||
Rect rootBounds = calcBounds(root);
|
||||
if (rootBounds != null) {
|
||||
writeBinaryMapBlock(root, rtree, writer, selectData, bounds);
|
||||
writeBinaryMapBlock(root, rtree, writer, selectData, bounds, new LinkedHashMap<String, Integer>(),
|
||||
new LinkedHashMap<MapRenderingTypes.MapRulType, String>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selectData.close();
|
||||
|
||||
writer.endWriteMapIndex();
|
||||
|
@ -651,55 +639,72 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
|
||||
private long convertBaseIdToGeneratedId(long baseId, int level) {
|
||||
if(level >= MAP_LEVELS_MAX){
|
||||
if (level >= MAP_LEVELS_MAX) {
|
||||
throw new IllegalArgumentException("Number of zoom levels " + level + " exceeds allowed maximum : " + MAP_LEVELS_MAX);
|
||||
}
|
||||
return ((baseId << MAP_LEVELS_POWER) | level) << 1;
|
||||
}
|
||||
|
||||
public long convertGeneratedIdToObfWrite(long id){
|
||||
public long convertGeneratedIdToObfWrite(long id) {
|
||||
return (id >> (MAP_LEVELS_POWER)) + (id & 1);
|
||||
}
|
||||
|
||||
public void writeBinaryMapBlock(rtree.Node parent, RTree r, BinaryMapIndexWriter writer, PreparedStatement selectData, TLongObjectHashMap<BinaryFileReference> bounds) throws IOException, RTreeException, SQLException {
|
||||
private static final char SPECIAL_CHAR = ((char) 0x60000);
|
||||
|
||||
private void decodeNames(String name, Map<MapRulType, String> tempNames) {
|
||||
int i = name.indexOf(SPECIAL_CHAR);
|
||||
while (i != -1) {
|
||||
int n = name.indexOf(SPECIAL_CHAR, i + 2);
|
||||
char ch = name.charAt(i + 1);
|
||||
MapRulType rt = renderingTypes.getTypeByInternalId(ch);
|
||||
if (n == -1) {
|
||||
tempNames.put(rt, name.substring(i + 2));
|
||||
} else {
|
||||
tempNames.put(rt, name.substring(i + 2, n));
|
||||
}
|
||||
i = n;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBinaryMapBlock(rtree.Node parent, RTree r, BinaryMapIndexWriter writer, PreparedStatement selectData,
|
||||
TLongObjectHashMap<BinaryFileReference> bounds, Map<String, Integer> tempStringTable, Map<MapRulType, String> tempNames)
|
||||
throws IOException, RTreeException, SQLException {
|
||||
Element[] e = parent.getAllElements();
|
||||
|
||||
Map<String, Integer> stringTable = null;
|
||||
MapDataBlock.Builder dataBlock = null;
|
||||
BinaryFileReference ref = bounds.get(parent.getNodeIndex());
|
||||
long baseId = 0;
|
||||
for (int i = 0; i < parent.getTotalElements(); i++) {
|
||||
Rect re = e[i].getRect();
|
||||
if (e[i].getElementType() == rtree.Node.LEAF_NODE) {
|
||||
|
||||
|
||||
long id = ((LeafElement) e[i]).getPtr();
|
||||
selectData.setLong(1, id);
|
||||
ResultSet rs = selectData.executeQuery();
|
||||
if (rs.next()) {
|
||||
long cid = convertGeneratedIdToObfWrite(id);
|
||||
if(dataBlock == null){
|
||||
if (dataBlock == null) {
|
||||
baseId = cid;
|
||||
dataBlock = writer.createWriteMapDataBlock(baseId);
|
||||
tempStringTable.clear();
|
||||
|
||||
}
|
||||
renderingTypes.getEncodingRuleTypes()
|
||||
// mapConnection.prepareStatement("SELECT nodes, types, name FROM binary_map_objects WHERE id = ?");
|
||||
writer.writeMapData(cid - id, rs.getBytes(1),
|
||||
rs.getBytes(2), rs.getString(3));
|
||||
tempNames.clear();
|
||||
decodeNames(rs.getString(6), tempNames);
|
||||
writer.writeMapData(cid - baseId, re.getMinX(), re.getMinY(), rs.getBoolean(1), rs.getBytes(2), rs.getBytes(3),
|
||||
rs.getBytes(4), rs.getBytes(5), tempNames, tempStringTable, dataBlock);
|
||||
} else {
|
||||
logMapDataWarn.error("Something goes wrong with id = " + id); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
if(dataBlock != null){
|
||||
writer.writeMapDataBlock(dataBlock, stringTable, ref);
|
||||
if (dataBlock != null) {
|
||||
writer.writeMapDataBlock(dataBlock, tempStringTable, ref);
|
||||
}
|
||||
for (int i = 0; i < parent.getTotalElements(); i++) {
|
||||
Rect re = e[i].getRect();
|
||||
if (e[i].getElementType() != rtree.Node.LEAF_NODE) {
|
||||
long ptr = ((NonLeafElement) e[i]).getPtr();
|
||||
rtree.Node ns = r.getReadNode(ptr);
|
||||
writeBinaryMapBlock(ns, r, writer, selectData, bounds);
|
||||
writeBinaryMapBlock(ns, r, writer, selectData, bounds, tempStringTable, tempNames);
|
||||
writer.endWriteMapTreeElement();
|
||||
}
|
||||
}
|
||||
|
@ -746,8 +751,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
return r;
|
||||
}
|
||||
|
||||
public void createDatabaseStructure(Connection mapConnection, DBDialect dialect,
|
||||
String rtreeMapIndexNonPackFileName) throws SQLException, IOException {
|
||||
public void createDatabaseStructure(Connection mapConnection, DBDialect dialect, String rtreeMapIndexNonPackFileName)
|
||||
throws SQLException, IOException {
|
||||
createMapIndexStructure(mapConnection);
|
||||
this.mapConnection = mapConnection;
|
||||
mapBinaryStat = createStatementMapBinaryInsert(mapConnection);
|
||||
|
@ -770,31 +775,31 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
pStatements.put(mapLowLevelBinaryStat, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void createMapIndexStructure(Connection conn) throws SQLException{
|
||||
private void createMapIndexStructure(Connection conn) throws SQLException {
|
||||
Statement stat = conn.createStatement();
|
||||
stat.executeUpdate("create table binary_map_objects (id bigint primary key, name varchar(1024), " +
|
||||
"types binary, restrictions binary, nodes binary, highway int)");
|
||||
stat.executeUpdate("create index binary_map_objects_ind on binary_map_objects (id)");
|
||||
stat.executeUpdate("create table binary_map_objects (id bigint primary key, name varchar(4096), "
|
||||
+ "area smallint, types binary, additionalTypes binary, coordinates binary, innerPolygons binary)");
|
||||
stat.executeUpdate("create index binary_map_objects_ind on binary_map_objects (id)");
|
||||
|
||||
stat.executeUpdate("create table low_level_map_objects (id bigint primary key, start_node bigint, " +
|
||||
"end_node bigint, name varchar(1024), nodes binary, type bigint, level smallint)");
|
||||
stat.executeUpdate("create index low_level_map_objects_ind on low_level_map_objects (id)");
|
||||
stat.executeUpdate("create index low_level_map_objects_ind_st on low_level_map_objects (start_node, type)");
|
||||
stat.executeUpdate("create index low_level_map_objects_ind_end on low_level_map_objects (end_node, type)");
|
||||
stat.close();
|
||||
stat.executeUpdate("create table low_level_map_objects (id bigint primary key, start_node bigint, "
|
||||
+ "end_node bigint, name varchar(1024), nodes binary, type bigint, level smallint)");
|
||||
stat.executeUpdate("create index low_level_map_objects_ind on low_level_map_objects (id)");
|
||||
stat.executeUpdate("create index low_level_map_objects_ind_st on low_level_map_objects (start_node, type)");
|
||||
stat.executeUpdate("create index low_level_map_objects_ind_end on low_level_map_objects (end_node, type)");
|
||||
stat.close();
|
||||
}
|
||||
|
||||
private PreparedStatement createStatementMapBinaryInsert(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement("insert into binary_map_objects(id, name, types, restrictions, nodes, highway) values(?, ?, ?, ?, ?, ?)");
|
||||
private PreparedStatement createStatementMapBinaryInsert(Connection conn) throws SQLException {
|
||||
return conn
|
||||
.prepareStatement("insert into binary_map_objects(id, area, coordinates, innerPolygons, types, additionalTypes, name) values(?, ?, ?, ?, ?, ?, ?)");
|
||||
}
|
||||
|
||||
private PreparedStatement createStatementLowLevelMapBinaryInsert(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement("insert into low_level_map_objects(id, start_node, end_node, name, nodes, type, level) values(?, ?, ?, ?, ?, ?, ?)");
|
||||
private PreparedStatement createStatementLowLevelMapBinaryInsert(Connection conn) throws SQLException {
|
||||
return conn
|
||||
.prepareStatement("insert into low_level_map_objects(id, start_node, end_node, name, nodes, type, level) values(?, ?, ?, ?, ?, ?, ?)");
|
||||
}
|
||||
|
||||
private void insertLowLevelMapBinaryObject(int level,long types, long id, List<Node> nodes, String name) throws SQLException{
|
||||
private void insertLowLevelMapBinaryObject(int level, long types, long id, List<Node> nodes, String name) throws SQLException {
|
||||
boolean first = true;
|
||||
long firstId = -1;
|
||||
long lastId = -1;
|
||||
|
@ -814,7 +819,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
if(firstId == -1){
|
||||
if (firstId == -1) {
|
||||
return;
|
||||
}
|
||||
// conn.prepareStatement("insert into binary_map_objects(id, name, types, restrictions, nodes, highway) values(?, ?, ?, ?, ?, ?)");
|
||||
|
@ -886,7 +891,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
throw new IllegalStateException(es);
|
||||
}
|
||||
if (init) {
|
||||
// conn.prepareStatement("insert into binary_map_objects(id, name, types, restrictions, nodes, highway) values(?, ?, ?, ?, ?, ?)");
|
||||
TODO;
|
||||
// conn.prepareStatement("insert into binary_map_objects(id, area, coordinates, innerPolygons, types, additionalTypes, name) values(?, ?, ?, ?, ?, ?, ?)");
|
||||
mapBinaryStat.setLong(1, id);
|
||||
mapBinaryStat.setString(2, name);
|
||||
mapBinaryStat.setBytes(3, btypes.toByteArray());
|
||||
|
@ -919,7 +925,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
|
||||
public void commitAndCloseFiles(String rTreeMapIndexNonPackFileName, String rTreeMapIndexPackFileName, boolean deleteDatabaseIndexes) throws IOException, SQLException {
|
||||
public void commitAndCloseFiles(String rTreeMapIndexNonPackFileName, String rTreeMapIndexPackFileName, boolean deleteDatabaseIndexes)
|
||||
throws IOException, SQLException {
|
||||
|
||||
// delete map rtree files
|
||||
if (mapTree != null) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import gnu.trove.list.array.TIntArrayList;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -58,6 +59,7 @@ public class MapRenderingTypes {
|
|||
|
||||
// stored information to convert from osm tags to int type
|
||||
private Map<String, MapRulType> types = null;
|
||||
private List<MapRulType> typeList = new ArrayList<MapRenderingTypes.MapRulType>();
|
||||
|
||||
private Map<AmenityType, Map<String, String>> amenityTypeNameToTagVal = null;
|
||||
private Map<String, AmenityType> amenityNameToType = null;
|
||||
|
@ -81,67 +83,75 @@ public class MapRenderingTypes {
|
|||
public Map<String, MapRulType> getEncodingRuleTypes(){
|
||||
if (types == null) {
|
||||
types = new LinkedHashMap<String, MapRulType>();
|
||||
nameRuleType = new MapRulType(types.size());
|
||||
typeList.clear();
|
||||
nameRuleType = new MapRulType();
|
||||
nameRuleType.tag = "name";
|
||||
nameRuleType.additional = true;
|
||||
types.put(constructRuleKey("name", null), nameRuleType);
|
||||
|
||||
registerRuleType("name", null, nameRuleType);
|
||||
init();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
public MapRulType getTypeByInternalId(int id) {
|
||||
return typeList.get(id);
|
||||
}
|
||||
|
||||
private void registerRuleType(String tag, String val, MapRulType rt){
|
||||
rt.id = types.size();
|
||||
String keyVal = constructRuleKey(tag, val);
|
||||
if(types.containsKey(keyVal)){
|
||||
throw new RuntimeException("Duplicate " + keyVal);
|
||||
}
|
||||
types.put(keyVal, rt);
|
||||
typeList.add(rt);
|
||||
}
|
||||
|
||||
|
||||
// if type equals 0 no need to save that point
|
||||
public int encodeEntityWithType(Entity e, int zoom, boolean multipolygon, TIntArrayList types) {
|
||||
Map<String, MapRulType> rules = getEncodingRuleTypes();
|
||||
types.clear();
|
||||
if ("coastline".equals(e.getTag(OSMTagKey.NATURAL))) { //$NON-NLS-1$
|
||||
multipolygon = false;
|
||||
}
|
||||
public boolean encodeEntityWithType(Entity e, int zoom, boolean multipolygon, TIntArrayList outTypes,
|
||||
TIntArrayList outaddTypes, Map<MapRulType, String> namesToEncode, List<MapRulType> tempList) {
|
||||
Map<String, MapRulType> types = getEncodingRuleTypes();
|
||||
outTypes.clear();
|
||||
outaddTypes.clear();
|
||||
namesToEncode.clear();
|
||||
tempList.clear();
|
||||
tempList.add(nameRuleType);
|
||||
|
||||
boolean point = e instanceof Node;
|
||||
boolean polygon = multipolygon || "yes".equals(e.getTag("area"));
|
||||
if (!point && !polygon) {
|
||||
// determining area or path
|
||||
boolean highway = e.getTag("highway") != null; //$NON-NLS-1$
|
||||
if (!highway) {
|
||||
List<Long> ids = ((Way) e).getNodeIds();
|
||||
if (ids.size() > 1) {
|
||||
polygon = ((long) ids.get(0) == (long) ids.get(ids.size() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean area = multipolygon || "yes".equals(e.getTag("area"));
|
||||
|
||||
Collection<String> tagKeySet = e.getTagKeySet();
|
||||
int type = -1;
|
||||
for (String tag : tagKeySet) {
|
||||
String val = e.getTag(tag);
|
||||
MapRulType rType = rules.get(constructRuleKey(tag, val));
|
||||
MapRulType rType = types.get(constructRuleKey(tag, val));
|
||||
if (rType == null) {
|
||||
rType = rules.get(constructRuleKey(tag, null));
|
||||
rType = types.get(constructRuleKey(tag, null));
|
||||
}
|
||||
if (rType != null) {
|
||||
if (rType.minzoom > zoom) {
|
||||
continue;
|
||||
}
|
||||
boolean accept;
|
||||
if (point) {
|
||||
accept = rType.point;
|
||||
} else if (polygon) {
|
||||
accept = rType.point || rType.polygon;
|
||||
} else {
|
||||
accept = rType.polyline;
|
||||
}
|
||||
if (accept) {
|
||||
rType.freq++;
|
||||
types.add(rType.id);
|
||||
type = point ? POINT_TYPE : (polygon ? POLYGON_TYPE : POLYLINE_TYPE);
|
||||
rType.freq++;
|
||||
if (rType.names != null) {
|
||||
for (int i = 0; i < rType.names.length; i++) {
|
||||
tempList.add(rType.names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (rType.additional) {
|
||||
outaddTypes.add(rType.id);
|
||||
} else {
|
||||
outTypes.add(rType.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
for(MapRulType mt : tempList){
|
||||
String val = e.getTag(mt.tag);
|
||||
if(val != null && val.length() > 0){
|
||||
namesToEncode.put(mt, val);
|
||||
}
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,15 +247,15 @@ public class MapRenderingTypes {
|
|||
poiParentPrefix = attributes.getValue("poi:prefix");
|
||||
String tag = attributes.getValue("poi:tag");
|
||||
if (tag != null) {
|
||||
MapRulType rtype = new MapRulType(types.size());
|
||||
MapRulType rtype = new MapRulType();
|
||||
rtype.poiCategory = AmenityType.valueOf(poiParentCategory.toUpperCase());
|
||||
rtype.poiSpecified = true;
|
||||
rtype.poiPrefix = poiParentPrefix;
|
||||
rtype.tag = tag;
|
||||
types.put(constructRuleKey(tag, null), rtype);
|
||||
registerRuleType(tag, null, rtype);
|
||||
}
|
||||
} else if (name.equals("type")) { //$NON-NLS-1$
|
||||
MapRulType rtype = new MapRulType(types.size());
|
||||
MapRulType rtype = new MapRulType();
|
||||
String val = attributes.getValue("minzoom"); //$NON-NLS-1$
|
||||
rtype.minzoom = 15;
|
||||
if (val != null) {
|
||||
|
@ -256,15 +266,7 @@ public class MapRenderingTypes {
|
|||
if (rtype.value != null && rtype.value.length() == 0) { //$NON-NLS-1$
|
||||
rtype.value = null;
|
||||
}
|
||||
String keyVal = constructRuleKey(rtype.tag, rtype.value);
|
||||
if(types.containsKey(keyVal)){
|
||||
throw new RuntimeException("Duplicate " + keyVal);
|
||||
}
|
||||
types.put(keyVal, rtype);
|
||||
|
||||
rtype.polygon = Boolean.parseBoolean(attributes.getValue("polygon")); //$NON-NLS-1$
|
||||
rtype.polyline= Boolean.parseBoolean(attributes.getValue("polyline")); //$NON-NLS-1$
|
||||
rtype.point = Boolean.parseBoolean(attributes.getValue("point")); //$NON-NLS-1$
|
||||
registerRuleType(rtype.tag, rtype.value, rtype);
|
||||
rtype.additional = Boolean.parseBoolean(attributes.getValue("additional")); //$NON-NLS-1$
|
||||
String v = attributes.getValue("nameTags");
|
||||
if(v != null) {
|
||||
|
@ -273,10 +275,10 @@ public class MapRenderingTypes {
|
|||
for(int i=0; i<names.length; i++){
|
||||
MapRulType mt = types.get(constructRuleKey(names[i], null));
|
||||
if(mt == null){
|
||||
mt = new MapRulType(types.size());
|
||||
mt = new MapRulType();
|
||||
mt.tag = names[i];
|
||||
mt.additional = true;
|
||||
types.put(constructRuleKey(names[i], null), mt);
|
||||
registerRuleType(names[i], null, mt);
|
||||
}
|
||||
rtype.names[i] = mt;
|
||||
}
|
||||
|
@ -406,7 +408,8 @@ public class MapRenderingTypes {
|
|||
boolean additional;
|
||||
MapRulType targetTagValue;
|
||||
|
||||
final int id;
|
||||
// inner id
|
||||
private int id;
|
||||
int freq;
|
||||
int targetId;
|
||||
|
||||
|
@ -414,16 +417,8 @@ public class MapRenderingTypes {
|
|||
AmenityType poiCategory;
|
||||
boolean poiSpecified;
|
||||
|
||||
boolean polyline;
|
||||
boolean point;
|
||||
boolean polygon;
|
||||
|
||||
public MapRulType(int id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isMapIndexed(){
|
||||
return polygon || polyline || polygon;
|
||||
public MapRulType(){
|
||||
}
|
||||
|
||||
public String poiPrefix(){
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue