Fix map parser
This commit is contained in:
parent
03ad5809fa
commit
8a2a0a2d08
13 changed files with 776 additions and 828 deletions
|
@ -76,7 +76,6 @@ public final class CodedInputStreamRAF {
|
|||
|
||||
lastTag = readRawVarint32();
|
||||
if (WireFormat.getTagFieldNumber(lastTag) == 0) {
|
||||
System.out.println(getTotalBytesRead());
|
||||
// If we actually read zero (or any tag number corresponding to field
|
||||
// number zero), that's not a valid tag.
|
||||
throw InvalidProtocolBufferException.invalidTag();
|
||||
|
|
|
@ -9,11 +9,14 @@ public class ToDoConstants {
|
|||
|
||||
|
||||
// Index
|
||||
|
||||
// Map QuadTree (skip small areas!!!)
|
||||
// POI index exclude building hno from categories!!!
|
||||
// slightly changed POI (check it)!
|
||||
// Routing index
|
||||
// Identify coastline areas and pure ocean areas
|
||||
// Identify coastline areas and pure ocean areas !!!
|
||||
|
||||
// Polish UI with new builiding style
|
||||
// Test images in the map
|
||||
|
||||
|
||||
// TODO
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.osmand.binary;
|
|||
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -23,6 +24,7 @@ import net.osmand.binary.BinaryMapIndexReader.MapRoot;
|
|||
import net.osmand.binary.BinaryMapIndexReader.SearchFilter;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
||||
import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion;
|
||||
import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex;
|
||||
import net.osmand.data.Amenity;
|
||||
|
@ -31,7 +33,6 @@ import net.osmand.data.Building;
|
|||
import net.osmand.data.City;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
|
@ -49,7 +50,7 @@ public class BinaryInspector {
|
|||
// inspector(new String[]{"-v","C:\\Users\\tpd\\osmand\\Housenumbers.obf"});
|
||||
//inspector(new String[]{"/home/victor/projects/OsmAnd/data/osm-gen/saved/Belarus-newzooms-new-rt.obf"});
|
||||
// inspector(new String[]{"/home/victor/projects/OsmAnd/download/spain/Spain_europe_1_small.obf"});
|
||||
inspector(new String[]{"-vpoi", "/home/victor/projects/OsmAnd/data/osm-gen/Luxembourg.obf"});
|
||||
inspector(new String[]{/*"-vmap", */"/home/victor/projects/OsmAnd/data/osm-gen/Luxembourg.obf"});
|
||||
|
||||
|
||||
// test case extract parts
|
||||
|
@ -386,18 +387,7 @@ public class BinaryInspector {
|
|||
}
|
||||
|
||||
|
||||
private static void formatTags(BinaryMapDataObject o, StringBuilder b){
|
||||
for (int i = 0; i < o.getTypes().length; i++) {
|
||||
if (i > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
b.append(o.getTagValue(i).tag + "=" + o.getTagValue(i).value);
|
||||
if ((o.getTypes()[i] & 3) == MapRenderingTypes.MULTY_POLYGON_TYPE) {
|
||||
b.append("(multipolygon)");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void printFileInformation(File file, VerboseInfo verbose) throws IOException {
|
||||
RandomAccessFile r = new RandomAccessFile(file.getAbsolutePath(), "r");
|
||||
|
@ -507,19 +497,66 @@ public class BinaryInspector {
|
|||
},
|
||||
new ResultMatcher<BinaryMapDataObject>() {
|
||||
@Override
|
||||
public boolean publish(BinaryMapDataObject object) {
|
||||
boolean way = object.getPointsLength() > 1;
|
||||
public boolean publish(BinaryMapDataObject obj) {
|
||||
b.setLength(0);
|
||||
b.append(way ? "Way " : "Point ");
|
||||
if(object.getName() != null){
|
||||
b.append(object.getName());
|
||||
boolean multipolygon = obj.getPolygonInnerCoordinates() != null && obj.getPolygonInnerCoordinates().length > 0;
|
||||
if(multipolygon ) {
|
||||
b.append("Multipolygon");
|
||||
} else {
|
||||
b.append(obj.area? "Area" : (obj.getPointsLength() > 1? "Way" : "Point"));
|
||||
}
|
||||
b.append(" ").append((object.getId() >> 1)).append(" ");
|
||||
formatTags(object, b);
|
||||
b.append(" ");
|
||||
for (int i = 0; i < object.getPointsLength(); i++) {
|
||||
b.append(" ");
|
||||
formatPoint(object, i, b);
|
||||
int[] types = obj.getTypes();
|
||||
b.append(" types [");
|
||||
for(int j = 0; j<types.length; j++){
|
||||
if(j > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
TagValuePair pair = obj.getMapIndex().decodeType(types[j]);
|
||||
if(pair == null) {
|
||||
throw new NullPointerException("Type " + types[j] + "was not found");
|
||||
}
|
||||
b.append(pair.toSimpleString()+"("+types[j]+")");
|
||||
}
|
||||
b.append("]");
|
||||
if(obj.getAdditionalTypes() != null){
|
||||
b.append(" add_types [");
|
||||
for(int j = 0; j<obj.getAdditionalTypes().length; j++){
|
||||
if(j > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
TagValuePair pair = obj.getMapIndex().decodeType(obj.getAdditionalTypes()[j]);
|
||||
if(pair == null) {
|
||||
throw new NullPointerException("Type " + obj.getAdditionalTypes()[j] + "was not found");
|
||||
}
|
||||
b.append(pair.toSimpleString()+"("+obj.getAdditionalTypes()[j]+")");
|
||||
|
||||
}
|
||||
b.append("]");
|
||||
}
|
||||
TIntObjectHashMap<String> names = obj.getObjectNames();
|
||||
if(names != null && !names.isEmpty()) {
|
||||
b.append(" Names [");
|
||||
int[] keys = names.keys();
|
||||
for(int j = 0; j<keys.length; j++){
|
||||
if(j > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
TagValuePair pair = obj.getMapIndex().decodeType(keys[j]);
|
||||
if(pair == null) {
|
||||
throw new NullPointerException("Type " + keys[j] + "was not found");
|
||||
}
|
||||
b.append(pair.toSimpleString()+"("+keys[j]+")");
|
||||
b.append(" - ").append(names.get(keys[j]));
|
||||
}
|
||||
b.append("]");
|
||||
}
|
||||
|
||||
b.append(" id ").append((obj.getId() >> 1));
|
||||
b.append(" lat/lon : ");
|
||||
for(int i=0; i<obj.getPointsLength(); i++) {
|
||||
float x = (float) MapUtils.get31LongitudeX(obj.getPoint31XTile(i));
|
||||
float y = (float) MapUtils.get31LatitudeY(obj.getPoint31YTile(i));
|
||||
b.append(x).append(" / ").append(y).append(" , ");
|
||||
}
|
||||
println(b.toString());
|
||||
return false;
|
||||
|
|
|
@ -1,48 +1,60 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
||||
|
||||
public class BinaryMapDataObject {
|
||||
protected int[] coordinates = null;
|
||||
protected int[][] polygonInnerCoordinates = null;
|
||||
protected boolean area = false;
|
||||
protected int[] types = null;
|
||||
protected int[] additionalTypes = null;
|
||||
|
||||
protected int stringId = -1;
|
||||
protected TIntObjectHashMap<String> objectNames = null;
|
||||
protected long id = 0;
|
||||
|
||||
protected String name;
|
||||
|
||||
protected MapIndex mapIndex = null;
|
||||
|
||||
|
||||
public BinaryMapDataObject(){
|
||||
}
|
||||
|
||||
protected void setStringId(int stringId) {
|
||||
this.stringId = stringId;
|
||||
}
|
||||
|
||||
|
||||
protected void setCoordinates(int[] coordinates) {
|
||||
this.coordinates = coordinates;
|
||||
}
|
||||
|
||||
protected int getStringId() {
|
||||
return stringId;
|
||||
public String getName(){
|
||||
if(objectNames == null){
|
||||
return null;
|
||||
}
|
||||
return objectNames.get(mapIndex.nameEncodingType);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public TIntObjectHashMap<String> getObjectNames() {
|
||||
return objectNames;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public int[][] getPolygonInnerCoordinates() {
|
||||
return polygonInnerCoordinates;
|
||||
}
|
||||
|
||||
public int[] getTypes(){
|
||||
return types;
|
||||
}
|
||||
|
||||
public int[] getAdditionalTypes() {
|
||||
return additionalTypes;
|
||||
}
|
||||
|
||||
public boolean isArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
public void setArea(boolean area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public TagValuePair getTagValue(int indType){
|
||||
if(mapIndex == null){
|
||||
return null;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.list.array.TLongArrayList;
|
||||
import gnu.trove.map.TIntObjectMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
|
@ -24,13 +23,12 @@ import net.osmand.Algoritms;
|
|||
import net.osmand.CollatorStringMatcher;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.StringMatcher;
|
||||
import net.osmand.CollatorStringMatcher.StringMatcherMode;
|
||||
import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion;
|
||||
import net.osmand.binary.BinaryMapAddressReaderAdapter.CitiesBlock;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion;
|
||||
import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex;
|
||||
import net.osmand.binary.OsmandOdb.MapDataBlock;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapDataBox;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapEncodingRule;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapRootLevel;
|
||||
|
@ -43,8 +41,6 @@ import net.osmand.data.Street;
|
|||
import net.osmand.data.TransportRoute;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MapRenderingTypes.MapRulType;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -524,9 +520,11 @@ public class BinaryMapIndexReader {
|
|||
*/
|
||||
|
||||
private void readMapIndex(MapIndex index) throws IOException {
|
||||
int defaultId = 1;
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
|
||||
switch (tag) {
|
||||
case 0:
|
||||
// encoding rules are required!
|
||||
|
@ -540,7 +538,7 @@ public class BinaryMapIndexReader {
|
|||
case OsmandOdb.OsmAndMapIndex.RULES_FIELD_NUMBER :
|
||||
int len = codedIS.readInt32();
|
||||
int oldLimit = codedIS.pushLimit(len);
|
||||
readMapEncodingRule(index);
|
||||
readMapEncodingRule(index, defaultId++);
|
||||
codedIS.popLimit(oldLimit);
|
||||
break;
|
||||
case OsmandOdb.OsmAndMapIndex.LEVELS_FIELD_NUMBER :
|
||||
|
@ -566,16 +564,18 @@ public class BinaryMapIndexReader {
|
|||
index.encodingRules.put(tag, new LinkedHashMap<String, Integer>());
|
||||
}
|
||||
index.encodingRules.get(tag).put(val, id);
|
||||
if("name".equals(tag)){
|
||||
index.nameEncodingType = id;
|
||||
}
|
||||
if(!index.decodingRules.containsKey(id)){
|
||||
index.decodingRules.put(id, new TagValuePair(tag, val));
|
||||
index.decodingRules.put(id, new TagValuePair(tag, val, type));
|
||||
}
|
||||
}
|
||||
|
||||
private void readMapEncodingRule(MapIndex index) throws IOException {
|
||||
private void readMapEncodingRule(MapIndex index, int id) throws IOException {
|
||||
int type = 0;
|
||||
String tags = null;
|
||||
String val = null;
|
||||
int id = 0;
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
|
@ -691,6 +691,7 @@ public class BinaryMapIndexReader {
|
|||
req.numberOfAcceptedObjects = 0;
|
||||
req.numberOfAcceptedSubtrees = 0;
|
||||
req.numberOfReadSubtrees = 0;
|
||||
List<MapTree> foundSubtrees = new ArrayList<MapTree>();
|
||||
for (MapIndex mapIndex : mapIndexes) {
|
||||
for (MapRoot index : mapIndex.getRoots()) {
|
||||
if (index.minZoom <= req.zoom && index.maxZoom >= req.zoom) {
|
||||
|
@ -712,12 +713,31 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
codedIS.seek(tree.filePointer);
|
||||
int oldLimit = codedIS.pushLimit(tree.length);
|
||||
searchMapTreeBounds(index.left, index.right, index.top, index.bottom, req, mapIndex);
|
||||
searchMapTreeBounds(tree, index, req, foundSubtrees);
|
||||
codedIS.popLimit(oldLimit);
|
||||
}
|
||||
|
||||
Collections.sort(foundSubtrees, new Comparator<MapTree>() {
|
||||
@Override
|
||||
public int compare(MapTree o1, MapTree o2) {
|
||||
return o1.mapDataBlock < o2.mapDataBlock ? -1 : (o1.mapDataBlock == o2.mapDataBlock ? 0 : 1);
|
||||
}
|
||||
});
|
||||
for(MapTree tree : foundSubtrees) {
|
||||
if(!req.isCancelled()){
|
||||
codedIS.seek(tree.mapDataBlock);
|
||||
int length = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
readMapDataBlocks(req, tree, mapIndex);
|
||||
codedIS.popLimit(oldLimit);
|
||||
}
|
||||
}
|
||||
foundSubtrees.clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Search is done. Visit " + req.numberOfVisitedObjects + " objects. Read " + req.numberOfAcceptedObjects + " objects."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
log.info("Read " + req.numberOfReadSubtrees + " subtrees. Go through " + req.numberOfAcceptedSubtrees + " subtrees."); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
|
||||
return req.getSearchResults();
|
||||
|
@ -725,17 +745,78 @@ public class BinaryMapIndexReader {
|
|||
|
||||
|
||||
|
||||
|
||||
protected void searchMapTreeBounds(int pleft, int pright, int ptop, int pbottom,
|
||||
SearchRequest<BinaryMapDataObject> req, MapIndex root) throws IOException {
|
||||
int init = 0;
|
||||
int lastIndexResult = -1;
|
||||
int cright = 0;
|
||||
int cleft = 0;
|
||||
int ctop = 0;
|
||||
int cbottom = 0;
|
||||
req.numberOfReadSubtrees++;
|
||||
protected void readMapDataBlocks(SearchRequest<BinaryMapDataObject> req, MapTree tree, MapIndex root) throws IOException {
|
||||
List<BinaryMapDataObject> tempResults = null;
|
||||
long baseId = 0;
|
||||
while (true) {
|
||||
if (req.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
if(tempResults != null) {
|
||||
for(BinaryMapDataObject obj : tempResults) {
|
||||
req.publish(obj);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case MapDataBlock.BASEID_FIELD_NUMBER:
|
||||
baseId = codedIS.readUInt64();
|
||||
break;
|
||||
// case MapDataBlock.RASTERTYPE_FIELD_NUMBER:
|
||||
// // not used now
|
||||
// codedIS.readUInt32();
|
||||
// break;
|
||||
// case MapDataBlock.RASTERIMAGE_FIELD_NUMBER:
|
||||
// // not used now
|
||||
// codedIS.readBytes();
|
||||
// break;
|
||||
case MapDataBlock.DATAOBJECTS_FIELD_NUMBER:
|
||||
int length = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
BinaryMapDataObject mapObject = readMapDataObject(tree, req, root);
|
||||
if (mapObject != null) {
|
||||
mapObject.setId(mapObject.getId() + baseId);
|
||||
if (tempResults == null) {
|
||||
tempResults = new ArrayList<BinaryMapDataObject>();
|
||||
}
|
||||
tempResults.add(mapObject);
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
break;
|
||||
case MapDataBlock.STRINGTABLE_FIELD_NUMBER:
|
||||
length = codedIS.readRawVarint32();
|
||||
oldLimit = codedIS.pushLimit(length);
|
||||
if (tempResults != null) {
|
||||
List<String> stringTable = readStringTable();
|
||||
for (int i = 0; i < tempResults.size(); i++) {
|
||||
BinaryMapDataObject rs = tempResults.get(i);
|
||||
if (rs.objectNames != null) {
|
||||
int[] keys = rs.objectNames.keys();
|
||||
for (int j = 0; j < keys.length; j++) {
|
||||
rs.objectNames.put(keys[j], stringTable.get(rs.objectNames.get(keys[j]).charAt(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void searchMapTreeBounds(MapTree current, MapTree parent,
|
||||
SearchRequest<BinaryMapDataObject> req, List<MapTree> foundSubtrees) throws IOException {
|
||||
int init = 0;
|
||||
req.numberOfReadSubtrees++;
|
||||
while(true){
|
||||
if(req.isCancelled()){
|
||||
return;
|
||||
|
@ -745,7 +826,7 @@ public class BinaryMapIndexReader {
|
|||
if(init == 0xf){
|
||||
init = 0;
|
||||
// coordinates are init
|
||||
if(cright < req.left || cleft > req.right || ctop > req.bottom || cbottom < req.top){
|
||||
if(current.right < req.left || current.left > req.right || current.top > req.bottom || current.bottom < req.top){
|
||||
return;
|
||||
} else {
|
||||
req.numberOfAcceptedSubtrees++;
|
||||
|
@ -753,85 +834,43 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
switch (tag) {
|
||||
case 0:
|
||||
if (tempResults != null) {
|
||||
for (int i = 0; i < tempResults.size(); i++) {
|
||||
req.publish(tempResults.get(i));
|
||||
}
|
||||
}
|
||||
return;
|
||||
case MapDataBox.BOTTOM_FIELD_NUMBER :
|
||||
cbottom = codedIS.readSInt32() + pbottom;
|
||||
current.bottom = codedIS.readSInt32() + parent.bottom;
|
||||
init |= 1;
|
||||
break;
|
||||
case MapDataBox.LEFT_FIELD_NUMBER :
|
||||
cleft = codedIS.readSInt32() + pleft;
|
||||
current.left = codedIS.readSInt32() + parent.left;
|
||||
init |= 2;
|
||||
break;
|
||||
case MapDataBox.RIGHT_FIELD_NUMBER :
|
||||
cright = codedIS.readSInt32() + pright;
|
||||
current.right = codedIS.readSInt32() + parent.right;
|
||||
init |= 4;
|
||||
break;
|
||||
case MapDataBox.TOP_FIELD_NUMBER :
|
||||
ctop = codedIS.readSInt32() + ptop;
|
||||
current.top = codedIS.readSInt32() + parent.top;
|
||||
init |= 8;
|
||||
break;
|
||||
case MapDataBox.LEAFS_FIELD_NUMBER :
|
||||
int length = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
if(lastIndexResult == -1){
|
||||
lastIndexResult = req.searchResults.size();
|
||||
}
|
||||
BinaryMapDataObject mapObject = readMapDataObject(cleft, cright, ctop, cbottom, req, root);
|
||||
if(mapObject != null){
|
||||
if(tempResults == null){
|
||||
tempResults = new ArrayList<BinaryMapDataObject>();
|
||||
}
|
||||
tempResults.add(mapObject);
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
case MapDataBox.SHIFTTOMAPDATA_FIELD_NUMBER :
|
||||
req.numberOfAcceptedSubtrees ++;
|
||||
current.mapDataBlock = readInt() + current.filePointer;
|
||||
foundSubtrees.add(current);
|
||||
break;
|
||||
case MapDataBox.OCEAN_FIELD_NUMBER :
|
||||
current.ocean = codedIS.readBool();
|
||||
break;
|
||||
case MapDataBox.BOXES_FIELD_NUMBER :
|
||||
// left, ... already initialized
|
||||
length = readInt();
|
||||
int filePointer = codedIS.getTotalBytesRead();
|
||||
oldLimit = codedIS.pushLimit(length);
|
||||
searchMapTreeBounds(cleft, cright, ctop, cbottom, req, root);
|
||||
// left, ... already initialized
|
||||
MapTree child = new MapTree();
|
||||
child.length = readInt();
|
||||
child.filePointer = codedIS.getTotalBytesRead();
|
||||
int oldLimit = codedIS.pushLimit(child.length);
|
||||
if(current.ocean){
|
||||
child.ocean = true;
|
||||
}
|
||||
searchMapTreeBounds(child, current, req, foundSubtrees);
|
||||
codedIS.popLimit(oldLimit);
|
||||
codedIS.seek(filePointer + length);
|
||||
if(lastIndexResult >= 0){
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.MapTree.BASEID_FIELD_NUMBER :
|
||||
case OsmandOdb.MapTree.OLDBASEID_FIELD_NUMBER :
|
||||
long baseId = codedIS.readUInt64();
|
||||
if (tempResults != null) {
|
||||
for (int i = 0; i < tempResults.size(); i++) {
|
||||
BinaryMapDataObject rs = tempResults.get(i);
|
||||
rs.id += baseId;
|
||||
if (rs.restrictions != null) {
|
||||
for (int j = 0; j < rs.restrictions.length; j++) {
|
||||
rs.restrictions[j] += baseId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.MapTree.STRINGTABLE_FIELD_NUMBER :
|
||||
case OsmandOdb.MapTree.OLDSTRINGTABLE_FIELD_NUMBER :
|
||||
length = codedIS.readRawVarint32();
|
||||
oldLimit = codedIS.pushLimit(length);
|
||||
List<String> stringTable = readStringTable();
|
||||
codedIS.popLimit(oldLimit);
|
||||
|
||||
if (tempResults != null) {
|
||||
for (int i = 0; i < tempResults.size(); i++) {
|
||||
BinaryMapDataObject rs = tempResults.get(i);
|
||||
if (rs.stringId != -1) {
|
||||
rs.name = stringTable.get(rs.stringId);
|
||||
}
|
||||
}
|
||||
}
|
||||
codedIS.seek(child.filePointer + child.length);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
@ -841,17 +880,18 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
|
||||
private int MASK_TO_READ = ~((1 << SHIFT_COORDINATES) - 1);
|
||||
private BinaryMapDataObject readMapDataObject(int left, int right, int top, int bottom, SearchRequest<BinaryMapDataObject> req,
|
||||
private BinaryMapDataObject readMapDataObject(MapTree tree , SearchRequest<BinaryMapDataObject> req,
|
||||
MapIndex root) throws IOException {
|
||||
int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
|
||||
if(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER != tag) {
|
||||
boolean area = OsmandOdb.MapData.AREACOORDINATES_FIELD_NUMBER == tag;
|
||||
if(!area && OsmandOdb.MapData.COORDINATES_FIELD_NUMBER != tag) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
req.cacheCoordinates.clear();
|
||||
int size = codedIS.readRawVarint32();
|
||||
int old = codedIS.pushLimit(size);
|
||||
int px = left & MASK_TO_READ;
|
||||
int py = top & MASK_TO_READ;
|
||||
int px = tree.left & MASK_TO_READ;
|
||||
int py = tree.top & MASK_TO_READ;
|
||||
boolean contains = false;
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int maxX = 0;
|
||||
|
@ -887,53 +927,108 @@ public class BinaryMapIndexReader {
|
|||
return null;
|
||||
}
|
||||
|
||||
// READ types
|
||||
tag = WireFormat.getTagFieldNumber(codedIS.readTag());
|
||||
if(OsmandOdb.MapData.TYPES_FIELD_NUMBER != tag) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
req.cacheTypes.clear();
|
||||
int sizeL = codedIS.readRawVarint32();
|
||||
byte[] types = codedIS.readRawBytes(sizeL);
|
||||
for(int i=0; i<sizeL/2; i++){
|
||||
req.cacheTypes.add(Algoritms.parseSmallIntFromBytes(types, i*2));
|
||||
}
|
||||
// read
|
||||
|
||||
boolean accept = true;
|
||||
if (req.searchFilter != null) {
|
||||
accept = req.searchFilter.accept(req.cacheTypes, root);
|
||||
}
|
||||
List<TIntArrayList> innercoordinates = null;
|
||||
TIntArrayList additionalTypes = null;
|
||||
TIntObjectHashMap<String> stringNames = null;
|
||||
long id = 0;
|
||||
|
||||
|
||||
if(!accept){
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
return null;
|
||||
}
|
||||
|
||||
req.numberOfAcceptedObjects++;
|
||||
|
||||
BinaryMapDataObject dataObject = new BinaryMapDataObject();
|
||||
dataObject.coordinates = req.cacheCoordinates.toArray();
|
||||
dataObject.types = req.cacheTypes.toArray();
|
||||
dataObject.mapIndex = root;
|
||||
|
||||
while(true){
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
int t = codedIS.readTag();
|
||||
tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return dataObject;
|
||||
case OsmandOdb.MapData.ID_FIELD_NUMBER :
|
||||
dataObject.id = codedIS.readSInt64();
|
||||
loop = false;
|
||||
break;
|
||||
case OsmandOdb.MapData.STRINGID_FIELD_NUMBER :
|
||||
dataObject.stringId = codedIS.readUInt32();
|
||||
case OsmandOdb.MapData.POLYGONINNERCOORDINATES_FIELD_NUMBER:
|
||||
if (innercoordinates == null) {
|
||||
innercoordinates = new ArrayList<TIntArrayList>();
|
||||
}
|
||||
TIntArrayList polygon = new TIntArrayList();
|
||||
innercoordinates.add(polygon);
|
||||
px = tree.left & MASK_TO_READ;
|
||||
py = tree.top & MASK_TO_READ;
|
||||
size = codedIS.readRawVarint32();
|
||||
old = codedIS.pushLimit(size);
|
||||
while (codedIS.getBytesUntilLimit() > 0) {
|
||||
int x = (codedIS.readSInt32() << SHIFT_COORDINATES) + px;
|
||||
int y = (codedIS.readSInt32() << SHIFT_COORDINATES) + py;
|
||||
polygon.add(x);
|
||||
polygon.add(y);
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
break;
|
||||
case OsmandOdb.MapData.ADDITIONALTYPES_FIELD_NUMBER:
|
||||
additionalTypes = new TIntArrayList();
|
||||
int sizeL = codedIS.readRawVarint32();
|
||||
old = codedIS.pushLimit(sizeL);
|
||||
while (codedIS.getBytesUntilLimit() > 0) {
|
||||
additionalTypes.add(codedIS.readRawVarint32());
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
break;
|
||||
case OsmandOdb.MapData.TYPES_FIELD_NUMBER:
|
||||
req.cacheTypes.clear();
|
||||
sizeL = codedIS.readRawVarint32();
|
||||
old = codedIS.pushLimit(sizeL);
|
||||
while (codedIS.getBytesUntilLimit() > 0) {
|
||||
req.cacheTypes.add(codedIS.readRawVarint32());
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
boolean accept = true;
|
||||
if (req.searchFilter != null) {
|
||||
accept = req.searchFilter.accept(req.cacheTypes, root);
|
||||
}
|
||||
if (!accept) {
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
return null;
|
||||
}
|
||||
req.numberOfAcceptedObjects++;
|
||||
break;
|
||||
case OsmandOdb.MapData.ID_FIELD_NUMBER:
|
||||
id = codedIS.readSInt64();
|
||||
break;
|
||||
case OsmandOdb.MapData.STRINGNAMES_FIELD_NUMBER:
|
||||
stringNames = new TIntObjectHashMap<String>();
|
||||
sizeL = codedIS.readRawVarint32();
|
||||
old = codedIS.pushLimit(sizeL);
|
||||
while (codedIS.getBytesUntilLimit() > 0) {
|
||||
int stag = codedIS.readRawVarint32();
|
||||
int pId = codedIS.readRawVarint32();
|
||||
stringNames.put(stag, ((char)pId)+"");
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BinaryMapDataObject dataObject = new BinaryMapDataObject();
|
||||
dataObject.area = area;
|
||||
dataObject.coordinates = req.cacheCoordinates.toArray();
|
||||
dataObject.objectNames = stringNames;
|
||||
if (innercoordinates == null) {
|
||||
dataObject.polygonInnerCoordinates = new int[0][0];
|
||||
} else {
|
||||
dataObject.polygonInnerCoordinates = new int[innercoordinates.size()][];
|
||||
for (int i = 0; i < innercoordinates.size(); i++) {
|
||||
dataObject.polygonInnerCoordinates[i] = innercoordinates.get(i).toArray();
|
||||
}
|
||||
}
|
||||
dataObject.types = req.cacheTypes.toArray();
|
||||
if (additionalTypes != null) {
|
||||
dataObject.additionalTypes = additionalTypes.toArray();
|
||||
} else {
|
||||
dataObject.additionalTypes = new int[0];
|
||||
}
|
||||
dataObject.id = id;
|
||||
dataObject.mapIndex = root;
|
||||
return dataObject;
|
||||
}
|
||||
|
||||
public List<MapObject> searchAddressDataByName(SearchRequest<MapObject> req) throws IOException {
|
||||
|
@ -1217,15 +1312,17 @@ public class BinaryMapIndexReader {
|
|||
|
||||
public static class MapIndex extends BinaryIndexPart {
|
||||
List<MapRoot> roots = new ArrayList<MapRoot>();
|
||||
|
||||
Map<String, Map<String, Integer>> encodingRules = new LinkedHashMap<String, Map<String, Integer>>();
|
||||
TIntObjectMap<TagValuePair> decodingRules = new TIntObjectHashMap<TagValuePair>();
|
||||
int nameEncodingType = 0;
|
||||
|
||||
public List<MapRoot> getRoots() {
|
||||
return roots;
|
||||
}
|
||||
|
||||
public TagValuePair decodeType(int type, int subtype){
|
||||
return decodingRules.get(((subtype << 5) | type));
|
||||
public TagValuePair decodeType(int type){
|
||||
return decodingRules.get(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1234,11 +1331,7 @@ public class BinaryMapIndexReader {
|
|||
public String tag;
|
||||
public String value;
|
||||
public int additionalAttribute;
|
||||
public TagValuePair(String tag, String value) {
|
||||
super();
|
||||
this.tag = tag;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public TagValuePair(String tag, String value, int additionalAttribute) {
|
||||
super();
|
||||
|
@ -1246,6 +1339,10 @@ public class BinaryMapIndexReader {
|
|||
this.value = value;
|
||||
this.additionalAttribute = additionalAttribute;
|
||||
}
|
||||
|
||||
public boolean isAdditional(){
|
||||
return additionalAttribute % 2 == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
@ -1257,6 +1354,13 @@ public class BinaryMapIndexReader {
|
|||
return result;
|
||||
}
|
||||
|
||||
public String toSimpleString(){
|
||||
if(value == null){
|
||||
return tag;
|
||||
}
|
||||
return tag+"-"+value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TagValuePair : " + tag + " - " + value;
|
||||
|
@ -1289,22 +1393,33 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
|
||||
|
||||
public static class MapRoot extends BinaryIndexPart {
|
||||
public static class MapRoot extends MapTree {
|
||||
int minZoom = 0;
|
||||
int maxZoom = 0;
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
|
||||
|
||||
public int getMinZoom() {
|
||||
return minZoom;
|
||||
}
|
||||
|
||||
public int getMaxZoom() {
|
||||
return maxZoom;
|
||||
}
|
||||
|
||||
private List<MapTree> trees = null;
|
||||
}
|
||||
|
||||
private static class MapTree {
|
||||
int filePointer = 0;
|
||||
int length = 0;
|
||||
|
||||
long mapDataBlock = 0;
|
||||
boolean ocean = false;
|
||||
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
|
||||
public int getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
@ -1318,31 +1433,25 @@ public class BinaryMapIndexReader {
|
|||
return bottom;
|
||||
}
|
||||
|
||||
private List<MapTree> trees = null;
|
||||
}
|
||||
|
||||
private static class MapTree {
|
||||
int filePointer = 0;
|
||||
int length = 0;
|
||||
|
||||
long mapDataBlock = 0;
|
||||
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
public int getFilePointer() {
|
||||
return filePointer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static boolean testMapSearch = false;
|
||||
private static boolean testMapSearch = true;
|
||||
private static boolean testAddressSearch = false;
|
||||
private static boolean testPoiSearch = false;
|
||||
private static boolean testTransportSearch = false;
|
||||
private static int sleft = MapUtils.get31TileNumberX(6.3);
|
||||
private static int sright = MapUtils.get31TileNumberX(6.5);
|
||||
private static int stop = MapUtils.get31TileNumberY(49.8);
|
||||
private static int sbottom = MapUtils.get31TileNumberY(49.3);
|
||||
private static int sright = MapUtils.get31TileNumberX(6.4);
|
||||
private static int stop = MapUtils.get31TileNumberY(49.5);
|
||||
private static int sbottom = MapUtils.get31TileNumberY(49.4);
|
||||
private static int szoom = 15;
|
||||
|
||||
private static void println(String s){
|
||||
System.out.println(s);
|
||||
|
@ -1567,11 +1676,75 @@ public class BinaryMapIndexReader {
|
|||
println(reader.mapIndexes.get(0).encodingRules + "");
|
||||
println("SEARCH " + sleft + " " + sright + " " + stop + " " + sbottom);
|
||||
|
||||
for (BinaryMapDataObject obj : reader.searchMapIndex(buildSearchRequest(sleft, sright, stop, sbottom, 8, null))) {
|
||||
if (obj.getName() != null) {
|
||||
println(" " + obj.getName());
|
||||
reader.searchMapIndex(buildSearchRequest(sleft, sright, stop, sbottom, szoom, null, new ResultMatcher<BinaryMapDataObject>() {
|
||||
|
||||
@Override
|
||||
public boolean publish(BinaryMapDataObject obj) {
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(obj.area? "Area" : (obj.getPointsLength() > 1? "Way" : "Point"));
|
||||
int[] types = obj.getTypes();
|
||||
b.append(" types [");
|
||||
for(int j = 0; j<types.length; j++){
|
||||
if(j > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
TagValuePair pair = obj.getMapIndex().decodeType(types[j]);
|
||||
if(pair == null) {
|
||||
throw new NullPointerException("Type " + types[j] + "was not found");
|
||||
}
|
||||
b.append(pair.toSimpleString()+"("+types[j]+")");
|
||||
}
|
||||
b.append("]");
|
||||
if(obj.getAdditionalTypes() != null){
|
||||
b.append(" add_types [");
|
||||
for(int j = 0; j<obj.getAdditionalTypes().length; j++){
|
||||
if(j > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
TagValuePair pair = obj.getMapIndex().decodeType(obj.getAdditionalTypes()[j]);
|
||||
if(pair == null) {
|
||||
throw new NullPointerException("Type " + obj.getAdditionalTypes()[j] + "was not found");
|
||||
}
|
||||
b.append(pair.toSimpleString()+"("+obj.getAdditionalTypes()[j]+")");
|
||||
|
||||
}
|
||||
b.append("]");
|
||||
}
|
||||
TIntObjectHashMap<String> names = obj.getObjectNames();
|
||||
if(names != null && !names.isEmpty()) {
|
||||
b.append(" Names [");
|
||||
int[] keys = names.keys();
|
||||
for(int j = 0; j<keys.length; j++){
|
||||
if(j > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
TagValuePair pair = obj.getMapIndex().decodeType(keys[j]);
|
||||
if(pair == null) {
|
||||
throw new NullPointerException("Type " + keys[j] + "was not found");
|
||||
}
|
||||
b.append(pair.toSimpleString()+"("+keys[j]+")");
|
||||
b.append(" - ").append(names.get(keys[j]));
|
||||
}
|
||||
b.append("]");
|
||||
}
|
||||
|
||||
b.append(" id ").append((obj.getId() >> 1));
|
||||
b.append(" lat/lon : ");
|
||||
for(int i=0; i<obj.getPointsLength(); i++) {
|
||||
float x = (float) MapUtils.get31LongitudeX(obj.getPoint31XTile(i));
|
||||
float y = (float) MapUtils.get31LatitudeY(obj.getPoint31YTile(i));
|
||||
b.append(x).append(" / ").append(y).append(" , ");
|
||||
}
|
||||
println(b.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -226,14 +226,14 @@ public class BinaryMapIndexWriter {
|
|||
Collections.sort(out, new Comparator<MapRulType>() {
|
||||
@Override
|
||||
public int compare(MapRulType o1, MapRulType o2) {
|
||||
return o1.getFreq() - o2.getFreq();
|
||||
return o2.getFreq() - o1.getFreq();
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < out.size(); i++) {
|
||||
MapEncodingRule.Builder builder = OsmandOdb.OsmAndMapIndex.MapEncodingRule.newBuilder();
|
||||
MapRulType rule = out.get(i);
|
||||
rule.setTargetId(i);
|
||||
rule.setTargetId(i + 1);
|
||||
|
||||
builder.setTag(rule.getTag());
|
||||
if (rule.getValue() != null) {
|
||||
|
@ -242,8 +242,11 @@ public class BinaryMapIndexWriter {
|
|||
builder.setMinZoom(rule.getMinzoom());
|
||||
if (rule.isAdditional()) {
|
||||
builder.setType(1);
|
||||
} else if(rule.isOnlyNameRef()) {
|
||||
builder.setType(2);
|
||||
}
|
||||
codedOutStream.writeMessage(OsmandOdb.OsmAndMapIndex.RULES_FIELD_NUMBER, builder.build());
|
||||
MapEncodingRule rulet = builder.build();
|
||||
codedOutStream.writeMessage(OsmandOdb.OsmAndMapIndex.RULES_FIELD_NUMBER, rulet);
|
||||
}
|
||||
long newfp = getFilePointer();
|
||||
System.out.println("RENDERING SCHEMA takes " + (newfp - fp));
|
||||
|
@ -297,6 +300,7 @@ public class BinaryMapIndexWriter {
|
|||
|
||||
public void writeMapDataBlock(MapDataBlock.Builder builder, Map<String, Integer> stringTable, BinaryFileReference ref)
|
||||
throws IOException {
|
||||
|
||||
checkPeekState(MAP_ROOT_LEVEL_INIT);
|
||||
StringTable.Builder bs = OsmandOdb.StringTable.newBuilder();
|
||||
for (String s : stringTable.keySet()) {
|
||||
|
@ -307,11 +311,14 @@ public class BinaryMapIndexWriter {
|
|||
int size = st.getSerializedSize();
|
||||
STRING_TABLE_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapDataBlock.STRINGTABLE_FIELD_NUMBER)
|
||||
+ CodedOutputStream.computeRawVarint32Size(size) + size;
|
||||
|
||||
codedOutStream.writeTag(OsmAndMapIndex.MapRootLevel.BLOCKS_FIELD_NUMBER, FieldType.MESSAGE.getWireType());
|
||||
|
||||
codedOutStream.flush();
|
||||
ref.writeReference(raf, getFilePointer());
|
||||
MapDataBlock block = builder.build();
|
||||
MAP_DATA_SIZE += block.getSerializedSize();
|
||||
codedOutStream.writeMessage(OsmAndMapIndex.MapRootLevel.BLOCKS_FIELD_NUMBER, block);
|
||||
codedOutStream.writeMessageNoTag(block);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -336,8 +343,8 @@ public class BinaryMapIndexWriter {
|
|||
|
||||
private TByteArrayList mapDataBuf = new TByteArrayList();
|
||||
|
||||
public MapData writeMapData(long diffId, int pleft, int ptop, boolean area, byte[] coordinates, byte[] innerPolygonTypes, byte[] types,
|
||||
byte[] additionalTypes, Map<MapRulType, String> names, Map<String, Integer> stringTable, MapDataBlock.Builder dataBlock)
|
||||
public MapData writeMapData(long diffId, int pleft, int ptop, boolean area, byte[] coordinates, byte[] innerPolygonTypes, TIntArrayList typeUse,
|
||||
TIntArrayList addtypeUse, Map<MapRulType, String> names, Map<String, Integer> stringTable, MapDataBlock.Builder dataBlock)
|
||||
throws IOException {
|
||||
|
||||
MapData.Builder data = MapData.newBuilder();
|
||||
|
@ -391,14 +398,21 @@ public class BinaryMapIndexWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.setTypes(ByteString.copyFrom(types));
|
||||
|
||||
mapDataBuf.clear();
|
||||
for (int i = 0; i < typeUse.size() ; i++) {
|
||||
writeRawVarint32(mapDataBuf, typeUse.get(i));;
|
||||
}
|
||||
data.setTypes(ByteString.copyFrom(mapDataBuf.toArray()));
|
||||
TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER)
|
||||
+ CodedOutputStream.computeRawVarint32Size(types.length) + types.length;
|
||||
if (additionalTypes != null && additionalTypes.length > 0) {
|
||||
data.setAdditionalTypes(ByteString.copyFrom(additionalTypes));
|
||||
TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.ADDITIONALTYPES_FIELD_NUMBER)
|
||||
+ CodedOutputStream.computeRawVarint32Size(additionalTypes.length) + additionalTypes.length;
|
||||
+ CodedOutputStream.computeRawVarint32Size(mapDataBuf.size()) + mapDataBuf.size();
|
||||
if (addtypeUse != null && addtypeUse.size() > 0) {
|
||||
mapDataBuf.clear();
|
||||
for (int i = 0; i < addtypeUse.size() ; i++) {
|
||||
writeRawVarint32(mapDataBuf, addtypeUse.get(i));;
|
||||
}
|
||||
data.setAdditionalTypes(ByteString.copyFrom(mapDataBuf.toArray()));
|
||||
TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.ADDITIONALTYPES_FIELD_NUMBER);
|
||||
}
|
||||
|
||||
mapDataBuf.clear();
|
||||
|
|
|
@ -625,7 +625,7 @@ public class IndexCreator {
|
|||
|
||||
long time = System.currentTimeMillis();
|
||||
IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$
|
||||
creator.setIndexMap(false);
|
||||
creator.setIndexMap(true);
|
||||
creator.setIndexAddress(true);
|
||||
creator.setIndexPOI(true);
|
||||
creator.setIndexTransport(true);
|
||||
|
|
|
@ -320,17 +320,11 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
|
||||
private void parseAndSort(TIntArrayList ts, byte[] bs, byte[] bt) {
|
||||
private void parseAndSort(TIntArrayList ts, byte[] bs) {
|
||||
ts.clear();
|
||||
if (bs != null && bs.length > 0) {
|
||||
for (int j = 0; j < bs.length; j += 4) {
|
||||
ts.add(Algoritms.parseIntFromBytes(bs, j));
|
||||
}
|
||||
}
|
||||
|
||||
if (bt != null && bt.length > 0) {
|
||||
for (int j = 0; j < bt.length; j += 4) {
|
||||
ts.add(Algoritms.parseIntFromBytes(bt, j));
|
||||
for (int j = 0; j < bs.length; j += 2) {
|
||||
ts.add(Algoritms.parseSmallIntFromBytes(bs, j));
|
||||
}
|
||||
}
|
||||
ts.sort();
|
||||
|
@ -353,6 +347,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
TLongHashSet visitedWays = new TLongHashSet();
|
||||
ArrayList<Float> list = new ArrayList<Float>(100);
|
||||
TIntArrayList temp = new TIntArrayList();
|
||||
TIntArrayList tempAdd = new TIntArrayList();
|
||||
while (rs.next()) {
|
||||
if (lowLevelWays != -1) {
|
||||
progress.progress(1);
|
||||
|
@ -370,7 +365,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
long endNode = rs.getLong(3);
|
||||
|
||||
String name = rs.getString(5);
|
||||
parseAndSort(typeUse, rs.getBytes(6), rs.getBytes(7));
|
||||
parseAndSort(typeUse, rs.getBytes(6));
|
||||
parseAndSort(addtypeUse, rs.getBytes(7));
|
||||
|
||||
loadNodes(rs.getBytes(4), list);
|
||||
ArrayList<Float> wayNodes = new ArrayList<Float>(list);
|
||||
|
@ -385,8 +381,9 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
// search by exact name
|
||||
while (fs.next() && !combined) {
|
||||
if (!visitedWays.contains(fs.getLong(1))) {
|
||||
parseAndSort(temp, rs.getBytes(6), rs.getBytes(7));
|
||||
if(temp.equals(namesUse)){
|
||||
parseAndSort(temp, rs.getBytes(6));
|
||||
parseAndSort(tempAdd, rs.getBytes(7));
|
||||
if(temp.equals(typeUse) && tempAdd.equals(addtypeUse)){
|
||||
combined = true;
|
||||
long lid = fs.getLong(1);
|
||||
startNode = fs.getLong(2);
|
||||
|
@ -416,8 +413,9 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
ResultSet fs = startStat.executeQuery();
|
||||
while (fs.next() && !combined) {
|
||||
if (!visitedWays.contains(fs.getLong(1))) {
|
||||
parseAndSort(temp, rs.getBytes(6), rs.getBytes(7));
|
||||
if (temp.equals(namesUse)) {
|
||||
parseAndSort(temp, rs.getBytes(6));
|
||||
parseAndSort(tempAdd, rs.getBytes(7));
|
||||
if(temp.equals(typeUse) && tempAdd.equals(addtypeUse)){
|
||||
combined = true;
|
||||
long lid = fs.getLong(1);
|
||||
if (!Algoritms.objectEquals(rs.getString(5), name)) {
|
||||
|
@ -443,6 +441,11 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
boolean cycle = startNode == endNode;
|
||||
if (cycle) {
|
||||
skip = checkForSmallAreas(wNodes, zoom + Math.min(zoomWaySmothness / 2, 3), 3, 4);
|
||||
} else {
|
||||
// coastline
|
||||
if(!typeUse.contains(renderingTypes.getCoastlineRuleType().getInternalId())) {
|
||||
skip = checkForSmallAreas(wNodes, zoom + Math.min(zoomWaySmothness / 2, 3), 2, 8);
|
||||
}
|
||||
}
|
||||
if (!skip) {
|
||||
List<Node> res = new ArrayList<Node>();
|
||||
|
@ -546,7 +549,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
.prepareStatement("SELECT area, coordinates, innerPolygons, types, additionalTypes, name FROM binary_map_objects WHERE id = ?");
|
||||
|
||||
// write map levels and map index
|
||||
TLongObjectHashMap<BinaryFileReference> bounds = new TLongObjectHashMap<BinaryFileReference>();
|
||||
TLongObjectHashMap<BinaryFileReference> treeHeader = new TLongObjectHashMap<BinaryFileReference>();
|
||||
for (int i = 0; i < mapZooms.size(); i++) {
|
||||
RTree rtree = mapTree[i];
|
||||
long rootIndex = rtree.getFileHdr().getRootIndex();
|
||||
|
@ -555,9 +558,9 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
if (rootBounds != null) {
|
||||
writer.startWriteMapLevelIndex(mapZooms.getLevel(i).getMinZoom(), mapZooms.getLevel(i).getMaxZoom(),
|
||||
rootBounds.getMinX(), rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY());
|
||||
writeBinaryMapTree(root, rootBounds, rtree, writer, bounds);
|
||||
writeBinaryMapTree(root, rootBounds, rtree, writer, treeHeader);
|
||||
|
||||
writeBinaryMapBlock(root, rtree, writer, selectData, bounds, new LinkedHashMap<String, Integer>(),
|
||||
writeBinaryMapBlock(root, rootBounds, rtree, writer, selectData, treeHeader, new LinkedHashMap<String, Integer>(),
|
||||
new LinkedHashMap<MapRenderingTypes.MapRulType, String>());
|
||||
|
||||
writer.endWriteMapLevelIndex();
|
||||
|
@ -591,7 +594,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
StringBuilder b = new StringBuilder();
|
||||
for (Map.Entry<MapRulType, String> e : tempNames.entrySet()) {
|
||||
if (e.getValue() != null) {
|
||||
b.append(SPECIAL_CHAR).append(e.getKey().getInternalId()).append(e.getValue());
|
||||
b.append(SPECIAL_CHAR).append((char)e.getKey().getInternalId()).append(e.getValue());
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
|
@ -601,7 +604,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
int i = name.indexOf(SPECIAL_CHAR);
|
||||
while (i != -1) {
|
||||
int n = name.indexOf(SPECIAL_CHAR, i + 2);
|
||||
char ch = name.charAt(i + 1);
|
||||
int ch = (short) name.charAt(i + 1);
|
||||
MapRulType rt = renderingTypes.getTypeByInternalId(ch);
|
||||
if (n == -1) {
|
||||
tempNames.put(rt, name.substring(i + 2));
|
||||
|
@ -612,7 +615,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
}
|
||||
|
||||
public void writeBinaryMapBlock(rtree.Node parent, RTree r, BinaryMapIndexWriter writer, PreparedStatement selectData,
|
||||
public void writeBinaryMapBlock(rtree.Node parent, Rect parentBounds, 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();
|
||||
|
@ -621,10 +624,10 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
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);
|
||||
// selectData = mapConnection.prepareStatement("SELECT area, coordinates, innerPolygons, types, additionalTypes, name FROM binary_map_objects WHERE id = ?");
|
||||
ResultSet rs = selectData.executeQuery();
|
||||
if (rs.next()) {
|
||||
long cid = convertGeneratedIdToObfWrite(id);
|
||||
|
@ -636,8 +639,24 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
}
|
||||
tempNames.clear();
|
||||
decodeNames(rs.getString(6), tempNames);
|
||||
MapData mapData = 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);
|
||||
byte[] types = rs.getBytes(4);
|
||||
typeUse.clear();
|
||||
for (int j = 0; j < types.length; j += 2) {
|
||||
int ids = Algoritms.parseSmallIntFromBytes(types, j);
|
||||
typeUse.add(renderingTypes.getTypeByInternalId(ids).getTargetId());
|
||||
}
|
||||
byte[] addTypes = rs.getBytes(5);
|
||||
addtypeUse.clear();
|
||||
if (addTypes != null) {
|
||||
for (int j = 0; j < addTypes.length; j += 2) {
|
||||
int ids = Algoritms.parseSmallIntFromBytes(addTypes, j);
|
||||
addtypeUse.add(renderingTypes.getTypeByInternalId(ids).getTargetId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MapData mapData = writer.writeMapData(cid - baseId, parentBounds.getMinX(), parentBounds.getMinY(), rs.getBoolean(1), rs.getBytes(2), rs.getBytes(3),
|
||||
typeUse, addtypeUse, tempNames, tempStringTable, dataBlock);
|
||||
if(mapData != null) {
|
||||
dataBlock.addDataObjects(mapData);
|
||||
}
|
||||
|
@ -653,7 +672,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
|
|||
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, tempStringTable, tempNames);
|
||||
writeBinaryMapBlock(ns, e[i].getRect(), r, writer, selectData, bounds, tempStringTable, tempNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class ConsoleProgressImplementation implements IProgress {
|
|||
this.lastPercentPrint = getCurrentPercent();
|
||||
long now = System.currentTimeMillis();
|
||||
if(now - lastTimePrinted >= deltaTimeToPrint || deltaTime < 0){
|
||||
log.debug(MessageFormat.format("Done {0} %.", getCurrentPercent())); //$NON-NLS-1$
|
||||
log.info(MessageFormat.format("Done {0} %.", getCurrentPercent())); //$NON-NLS-1$
|
||||
lastTimePrinted = now;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ public class MapRenderingTypes {
|
|||
private Map<String, AmenityType> amenityNameToType = null;
|
||||
|
||||
private MapRulType nameRuleType;
|
||||
private MapRulType coastlineRuleType;
|
||||
|
||||
public MapRenderingTypes(String fileName){
|
||||
this.resourceName = fileName;
|
||||
|
@ -86,7 +87,8 @@ public class MapRenderingTypes {
|
|||
typeList.clear();
|
||||
nameRuleType = new MapRulType();
|
||||
nameRuleType.tag = "name";
|
||||
nameRuleType.additional = true;
|
||||
nameRuleType.onlyNameRef = true;
|
||||
nameRuleType.additional = false;
|
||||
registerRuleType("name", null, nameRuleType);
|
||||
init();
|
||||
}
|
||||
|
@ -97,19 +99,25 @@ public class MapRenderingTypes {
|
|||
return typeList.get(id);
|
||||
}
|
||||
|
||||
private void registerRuleType(String tag, String val, MapRulType rt){
|
||||
rt.id = types.size();
|
||||
private MapRulType registerRuleType(String tag, String val, MapRulType rt){
|
||||
String keyVal = constructRuleKey(tag, val);
|
||||
if("natural".equals(tag) && "coastline".equals(val)) {
|
||||
coastlineRuleType = rt;
|
||||
}
|
||||
if(types.containsKey(keyVal)){
|
||||
if(types.get(keyVal).nameCreated ) {
|
||||
if(types.get(keyVal).onlyNameRef ) {
|
||||
rt.id = types.get(keyVal).id;
|
||||
types.put(keyVal, rt);
|
||||
typeList.set(rt.id, rt);
|
||||
return rt;
|
||||
} else {
|
||||
throw new RuntimeException("Duplicate " + keyVal);
|
||||
}
|
||||
} else {
|
||||
rt.id = types.size();
|
||||
types.put(keyVal, rt);
|
||||
typeList.add(rt);
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +125,10 @@ public class MapRenderingTypes {
|
|||
return nameRuleType;
|
||||
}
|
||||
|
||||
public MapRulType getCoastlineRuleType() {
|
||||
return coastlineRuleType;
|
||||
}
|
||||
|
||||
|
||||
// if type equals 0 no need to save that point
|
||||
public boolean encodeEntityWithType(Entity e, int zoom, TIntArrayList outTypes,
|
||||
|
@ -148,10 +160,12 @@ public class MapRenderingTypes {
|
|||
}
|
||||
}
|
||||
|
||||
if (rType.additional) {
|
||||
outaddTypes.add(rType.id);
|
||||
} else {
|
||||
outTypes.add(rType.id);
|
||||
if (!rType.onlyNameRef) {
|
||||
if (rType.additional) {
|
||||
outaddTypes.add(rType.id);
|
||||
} else {
|
||||
outTypes.add(rType.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +258,6 @@ public class MapRenderingTypes {
|
|||
}
|
||||
long time = System.currentTimeMillis();
|
||||
final SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
types = new LinkedHashMap<String, MapRenderingTypes.MapRulType>();
|
||||
parser.parse(is, new DefaultHandler(){
|
||||
|
||||
String poiParentCategory = null;
|
||||
|
@ -287,8 +300,8 @@ public class MapRenderingTypes {
|
|||
if(mt == null){
|
||||
mt = new MapRulType();
|
||||
mt.tag = names[i];
|
||||
mt.additional = true;
|
||||
mt.nameCreated = true;
|
||||
mt.onlyNameRef = true;
|
||||
mt.additional = false;
|
||||
registerRuleType(names[i], null, mt);
|
||||
}
|
||||
rtype.names[i] = mt;
|
||||
|
@ -418,7 +431,7 @@ public class MapRenderingTypes {
|
|||
int minzoom;
|
||||
boolean additional;
|
||||
MapRulType targetTagValue;
|
||||
boolean nameCreated;
|
||||
boolean onlyNameRef;
|
||||
|
||||
// inner id
|
||||
private int id;
|
||||
|
@ -473,6 +486,10 @@ public class MapRenderingTypes {
|
|||
return additional;
|
||||
}
|
||||
|
||||
public boolean isOnlyNameRef() {
|
||||
return onlyNameRef;
|
||||
}
|
||||
|
||||
public int getFreq() {
|
||||
return freq;
|
||||
}
|
||||
|
@ -481,6 +498,10 @@ public class MapRenderingTypes {
|
|||
return ++freq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tag + " " + value;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Move to Routing Attributes and finalize
|
||||
|
|
|
@ -206,7 +206,7 @@
|
|||
|
||||
<category name="man_made" poi:tag="man_made" poi:category="man_made">
|
||||
<type tag="building" minzoom="16" poi:category="" nameTags="addr:housenumber"/>
|
||||
<type tag="addr:housenumber" minzoom="16" nameTags="addr:housenumber"/>
|
||||
<type tag="addr:housenumber" minzoom="16" poi:category="" nameTags="addr:housenumber"/>
|
||||
<type tag="man_made" value="wastewater_plant" minzoom="16" />
|
||||
<type tag="man_made" value="water_works" minzoom="16" />
|
||||
<type tag="man_made" value="works" minzoom="15" />
|
||||
|
|
|
@ -97,13 +97,7 @@ message OsmAndMapIndex {
|
|||
|
||||
repeated MapDataBox boxes = 7;
|
||||
|
||||
repeated MapDataBlocks blocks = 8;
|
||||
}
|
||||
|
||||
message MapDataBlocks {
|
||||
// based coordinates can be specified
|
||||
// for an array of blocks
|
||||
repeated MapDataBlock block = 6;
|
||||
repeated MapDataBlock blocks = 15;
|
||||
}
|
||||
|
||||
message MapDataBox {
|
||||
|
@ -133,10 +127,6 @@ message MapDataBlock {
|
|||
// in future here can be optional raster tile
|
||||
repeated MapData dataObjects = 12;
|
||||
|
||||
optional uint32 rasterType = 13;
|
||||
|
||||
optional bytes rasterImage = 14;
|
||||
|
||||
optional StringTable stringTable = 15;
|
||||
|
||||
|
||||
|
@ -157,9 +147,15 @@ message MapData {
|
|||
required bytes types = 7;
|
||||
|
||||
// repeated array<pair<tagId : raw_var_int, indexOfStringInParent : raw_var_int> >
|
||||
optional bytes stringNames = 10; // in parent blocku
|
||||
optional bytes stringNames = 10; // in parent block
|
||||
|
||||
|
||||
required sint64 id = 12; // delta encoded
|
||||
|
||||
optional uint32 rasterTileX = 13;
|
||||
optional uint32 rasterTileY = 14;
|
||||
optional bytes rasterBytes = 15;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue