Fix map parser

This commit is contained in:
Victor Shcherb 2012-03-18 22:08:47 +01:00
parent 03ad5809fa
commit 8a2a0a2d08
13 changed files with 776 additions and 828 deletions

View file

@ -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();

View file

@ -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

View file

@ -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;

View file

@ -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 void setName(String name) {
this.name = name;
}
public String getName(){
return name;
if(objectNames == null){
return null;
}
return objectNames.get(mapIndex.nameEncodingType);
}
public TIntObjectHashMap<String> getObjectNames() {
return objectNames;
}
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;

View file

@ -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);
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();
@ -1247,6 +1340,10 @@ public class BinaryMapIndexReader {
this.additionalAttribute = additionalAttribute;
}
public boolean isAdditional(){
return additionalAttribute % 2 == 1;
}
@Override
public int hashCode() {
final int prime = 31;
@ -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;
public int getLength() {
return length;
}
public int getFilePointer() {
return filePointer;
}
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;
}
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

View file

@ -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();
@ -392,13 +399,20 @@ 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();

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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,6 +160,7 @@ public class MapRenderingTypes {
}
}
if (!rType.onlyNameRef) {
if (rType.additional) {
outaddTypes.add(rType.id);
} else {
@ -155,6 +168,7 @@ public class MapRenderingTypes {
}
}
}
}
for(MapRulType mt : tempList){
String val = e.getTag(mt.tag);
if(val != null && val.length() > 0){
@ -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

View file

@ -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" />

View file

@ -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;
}