diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java b/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java index c34d07f3d2..2e58961e6c 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryInspector.java @@ -31,6 +31,7 @@ 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.BinaryMapPoiReaderAdapter.PoiSubType; import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion; import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex; import net.osmand.data.Amenity; @@ -54,11 +55,11 @@ public class BinaryInspector { BinaryInspector in = new BinaryInspector(); in.inspector(args); // test cases show info - /*in.inspector(new String[]{ - //"-vpoi", - "-vmap", "-vmapobjects", + in.inspector(new String[]{ + "-vpoi", + //"-vmap", "-vmapobjects", //"-vstreets", "-bbox=14.4,50.1,14.5,50.01", - "/home/victor/projects/osmand/osm-gen/Map.obf"});*/ + "/home/victor/projects/osmand/osm-gen/Map.obf"}); } private void printToFile(String s) throws IOException { @@ -777,6 +778,7 @@ public class BinaryInspector { public boolean accept(AmenityType type, String subcategory) { return true; } + }, new ResultMatcher() { @Override @@ -801,6 +803,11 @@ public class BinaryInspector { for(int j = 0; j < p.subcategories.get(i).size(); j++) println("\t\t\t\t" + p.subcategories.get(i).get(j)); } + println("\t\tSubtypes:"); + for(int i =0; i< p.subTypes.size(); i++) { + PoiSubType st = p.subTypes.get(i); + println("\t\t\t" + st.name + " " + (st.text ? "text":(" encoded " + st.possibleValues.size()))); + } req.poiTypeFilter = null;//TODO: for test only index.searchPoi(p, req); diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java index 17e2ff1799..a6807a9a5a 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java @@ -1833,9 +1833,9 @@ public class BinaryMapIndexReader { SearchRequest req = buildSearchPoiRequest(sleft, sright, stop, sbottom, -1, new SearchPoiTypeFilter() { @Override public boolean accept(AmenityType type, String subcategory) { -// return type == AmenityType.TRANSPORTATION && "fuel".equals(subcategory); return true; } + }, null); List results = reader.searchPoi(req); for (Amenity a : results) { diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java index 8bd5e9b62e..80a66e15c2 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.LinkedList; import java.util.List; import net.osmand.Collator; @@ -36,11 +37,19 @@ public class BinaryMapPoiReaderAdapter { private static final int ZOOM_TO_SKIP_FILTER = 3; private static final int BUCKET_SEARCH_BY_NAME = 5; + public static class PoiSubType { + boolean text; + String name; + //int estiatedSize; + List possibleValues = null; + } + public static class PoiRegion extends BinaryIndexPart { List categories = new ArrayList(); List categoriesType = new ArrayList(); List > subcategories = new ArrayList >(); + List subTypes = new ArrayList(); double leftLongitude; double rightLongitude; @@ -51,6 +60,26 @@ public class BinaryMapPoiReaderAdapter { return leftLongitude; } + public PoiSubType getSubtypeFromId(int id, StringBuilder returnValue) { + int tl; + int sl; + if(id % 2 == 0) { + tl = (id >> 1) & ((1 << 5) -1); + sl = id >> 6; + } else { + tl = (id >> 1) & ((1 << 16) -1); + sl = id >> 16; + } + if(subTypes.size() > tl) { + PoiSubType st = subTypes.get(tl); + if(!st.text && st.possibleValues != null && st.possibleValues.size() > sl) { + returnValue.append(st.possibleValues.get(sl)); + return st; + } + } + return null; + } + public double getRightLongitude() { return rightLongitude; } @@ -135,6 +164,16 @@ public class BinaryMapPoiReaderAdapter { readCategory(region); codedIS.popLimit(oldLimit); break; + case OsmandOdb.OsmAndPoiIndex.SUBTYPESTABLE_FIELD_NUMBER : + if(!readCategories){ + codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); + return; + } + length = codedIS.readRawVarint32(); + oldLimit = codedIS.pushLimit(length); + readSubtypes(region); + codedIS.popLimit(oldLimit); + break; case OsmandOdb.OsmAndPoiIndex.BOXES_FIELD_NUMBER : codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); return; @@ -168,6 +207,50 @@ public class BinaryMapPoiReaderAdapter { } } + private void readSubtypes(PoiRegion region) throws IOException { + while(true){ + int outT = codedIS.readTag(); + int outTag = WireFormat.getTagFieldNumber(outT); + switch(outTag) { + case 0: + return; + case OsmandOdb.OsmAndSubtypesTable.SUBTYPES_FIELD_NUMBER : + int length = codedIS.readRawVarint32(); + int oldLimit = codedIS.pushLimit(length); + PoiSubType st = new PoiSubType(); + cycle: while(true){ + int inT = codedIS.readTag(); + int inTag = WireFormat.getTagFieldNumber(inT); + switch(inTag) { + case 0: + break cycle; + case OsmandOdb.OsmAndPoiSubtype.NAME_FIELD_NUMBER: + st.name = codedIS.readString().intern(); + break; + case OsmandOdb.OsmAndPoiSubtype.SUBTYPEVALUE_FIELD_NUMBER: + if(st.possibleValues == null) { + st.possibleValues = new ArrayList(); + } + st.possibleValues.add(codedIS.readString().intern()); + break; + case OsmandOdb.OsmAndPoiSubtype.ISTEXT_FIELD_NUMBER: + st.text = codedIS.readBool(); + break; + default: + skipUnknownField(inT); + break; + } + } + region.subTypes.add(st); + codedIS.popLimit(oldLimit); + break; + default: + skipUnknownField(outT); + break; + } + } + } + public void initCategories(PoiRegion region) throws IOException { if(region.categories.isEmpty()) { codedIS.seek(region.filePointer); @@ -508,7 +591,9 @@ public class BinaryMapPoiReaderAdapter { Amenity am = null; int x = 0; int y = 0; + StringBuilder retValue = new StringBuilder(); AmenityType amenityType = null; + LinkedList textTags = null; while(true){ int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); @@ -538,6 +623,31 @@ public class BinaryMapPoiReaderAdapter { am = new Amenity(); am.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x)); break; + case OsmandOdb.OsmAndPoiBoxDataAtom.SUBCATEGORIES_FIELD_NUMBER : + int subtypev = codedIS.readUInt32(); + retValue.setLength(0); + PoiSubType st = region.getSubtypeFromId(subtypev, retValue); + if(st != null) { + am.setAdditionalInfo(st.name, retValue.toString()); + } + break; + case OsmandOdb.OsmAndPoiBoxDataAtom.TEXTCATEGORIES_FIELD_NUMBER : + int texttypev = codedIS.readUInt32(); + retValue.setLength(0); + PoiSubType textt = region.getSubtypeFromId(texttypev, retValue); + if(textt != null && textt.text) { + if(textTags == null) { + textTags = new LinkedList(); + } + textTags.add(textt.name); + } + break; + case OsmandOdb.OsmAndPoiBoxDataAtom.TEXTVALUES_FIELD_NUMBER : + String str = codedIS.readString(); + if(textTags != null && !textTags.isEmpty()) { + am.setAdditionalInfo(textTags.poll(), str); + } + break; case OsmandOdb.OsmAndPoiBoxDataAtom.CATEGORIES_FIELD_NUMBER : int cat = codedIS.readUInt32(); int subcatId = cat >> SHIFT_BITS_CATEGORY; @@ -591,12 +701,24 @@ public class BinaryMapPoiReaderAdapter { } private boolean checkCategories(SearchRequest req, PoiRegion region) throws IOException { + StringBuilder subType = new StringBuilder(); while(true){ int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: return false; +// case OsmandOdb.OsmAndPoiCategories.SUBCATEGORIES_FIELD_NUMBER: +// int subcatvl = codedIS.readUInt32(); +// if(req.poiTypeFilter.filterSubtypes()) { +// subType.setLength(0); +// PoiSubType pt = region.getSubtypeFromId(subcatvl, subType); +// if(pt != null && req.poiTypeFilter.accept(pt.name, subType.toString())) { +// codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); +// return true; +// } +// } +// break; case OsmandOdb.OsmAndPoiCategories.CATEGORIES_FIELD_NUMBER: AmenityType type = AmenityType.OTHER; String subcat = ""; diff --git a/OsmAnd-java/src/net/osmand/osm/MapRenderingTypes.java b/OsmAnd-java/src/net/osmand/osm/MapRenderingTypes.java index 51903b34c9..040cb7e087 100644 --- a/OsmAnd-java/src/net/osmand/osm/MapRenderingTypes.java +++ b/OsmAnd-java/src/net/osmand/osm/MapRenderingTypes.java @@ -642,6 +642,9 @@ public class MapRenderingTypes { if(catId <= 31) { this.targetPoiId = (valueId << 6) | (catId << 1) ; } else { + if(catId > (1 << 15)) { + throw new IllegalArgumentException("Refer source code"); + } this.targetPoiId = (valueId << 16) | (catId << 1) | 1; } }