From 03f30de16c57bca967b59ce19ca3b0a1a3e7d305 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sun, 5 Feb 2012 22:03:09 +0100 Subject: [PATCH] Improve binary inspecctor to represent more information about binary maps in verbose mode --- .../net/osmand/binary/BinaryInspector.java | 198 +++++++++++++++--- .../osmand/binary/BinaryMapIndexReader.java | 36 +++- 2 files changed, 193 insertions(+), 41 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java b/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java index 2b3e802b24..2912393550 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java @@ -1,5 +1,8 @@ package net.osmand.binary; + +import gnu.trove.list.array.TIntArrayList; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -13,14 +16,19 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import net.osmand.ResultMatcher; import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion; import net.osmand.binary.BinaryMapIndexReader.MapIndex; import net.osmand.binary.BinaryMapIndexReader.MapRoot; +import net.osmand.binary.BinaryMapIndexReader.SearchFilter; +import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion; import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex; 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; @@ -56,6 +64,65 @@ public class BinaryInspector { private static void print(String s) { System.out.print(s); } + + protected static class VerboseInfo { + boolean vaddress; + boolean vtransport; + boolean vpoi; + boolean vmap; + double lattop = 85; + double latbottom = -85; + double lonleft = -180; + double lonright = 180; + int zoom = 15; + + public boolean isVaddress() { + return vaddress; + } + + public int getZoom() { + return zoom; + } + + public boolean isVmap() { + return vmap; + } + public boolean isVpoi() { + return vpoi; + } + + public boolean isVtransport() { + return vtransport; + } + + public VerboseInfo(String[] params){ + for(int i=0;i= o.getLocation().getLatitude() && latbottom >= o.getLocation().getLatitude() + && lonleft <= o.getLocation().getLongitude() && lonright >= o.getLocation().getLongitude(); + + } + } public static void inspector(String[] args) throws IOException { if(args == null || args.length == 0){ @@ -63,10 +130,10 @@ public class BinaryInspector { return; } String f = args[0]; - if(f.charAt(0) == '-'){ + if (f.charAt(0) == '-') { // command - if(f.equals("-c") || f.equals("-combine")) { - if(args.length < 4){ + if (f.equals("-c") || f.equals("-combine")) { + if (args.length < 4) { printUsage("Too few parameters to extract (require minimum 4)"); } else { Map parts = new LinkedHashMap(); @@ -77,29 +144,30 @@ public class BinaryInspector { return; } parts.put(file, null); - if(i < args.length - 1){ - if(args[i+1].startsWith("-") || args[i+1].startsWith("+")){ - parts.put(file, args[i+1]); + if (i < args.length - 1) { + if (args[i + 1].startsWith("-") || args[i + 1].startsWith("+")) { + parts.put(file, args[i + 1]); i++; - } + } } } List extracted = combineParts(new File(args[1]), parts); - if(extracted != null){ - println("\n"+extracted.size()+" parts were successfully extracted to " + args[1]); + if (extracted != null) { + println("\n" + extracted.size() + " parts were successfully extracted to " + args[1]); } - } - } else if (f.equals("-v")) { + } + } else if (f.startsWith("-v")) { if (args.length < 2) { printUsage("Missing file parameter"); } else { - printFileInformation(args[1],true); + VerboseInfo vinfo = new VerboseInfo(args); + printFileInformation(args[args.length - 1], vinfo); } } else { - printUsage("Unknown command : "+ f); + printUsage("Unknown command : " + f); } } else { - printFileInformation(f,false); + printFileInformation(f, null); } } public static final void writeInt(CodedOutputStream ous, int v) throws IOException { @@ -297,7 +365,7 @@ public class BinaryInspector { return format.format(new Object[]{l, t, r, b}); } - public static void printFileInformation(String fileName,boolean verbose) throws IOException { + public static void printFileInformation(String fileName,VerboseInfo verbose) throws IOException { File file = new File(fileName); if(!file.exists()){ println("Binary OsmAnd index " + fileName + " was not found."); @@ -306,7 +374,25 @@ public class BinaryInspector { printFileInformation(file,verbose); } - public static void printFileInformation(File file, boolean verbose) throws IOException { + private static void formatPoint(BinaryMapDataObject o, int ind, StringBuilder b){ + b.append((float)MapUtils.get31LongitudeX(o.getPoint31XTile(ind))).append(",").append((float)MapUtils.get31LatitudeY(o.getPoint31YTile(ind))); + } + + + 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"); try { BinaryMapIndexReader index = new BinaryMapIndexReader(r); @@ -339,31 +425,73 @@ public class BinaryInspector { formatBounds(mi.getLeft(), mi.getRight(), mi.getTop(), mi.getBottom()), i, j++)); } - } else if (p instanceof AddressRegion && verbose) { + if((verbose != null && verbose.isVmap())){ + final StringBuilder b = new StringBuilder(); + SearchRequest req = BinaryMapIndexReader.buildSearchRequest(MapUtils.get31TileNumberX(verbose.lonleft), + MapUtils.get31TileNumberX(verbose.lonright), + MapUtils.get31TileNumberY(verbose.lattop), + MapUtils.get31TileNumberY(verbose.latbottom), verbose.getZoom(), + new SearchFilter() { + @Override + public boolean accept(TIntArrayList types, MapIndex index) { + return true; + } + }, + new ResultMatcher() { + @Override + public boolean publish(BinaryMapDataObject object) { + boolean way = object.getPointsLength() > 1; + b.setLength(0); + b.append(way ? "Way " : "Point "); + if(object.getName() != null){ + b.append(object.getName()); + } + 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); + } + println(b.toString()); + return false; + } + @Override + public boolean isCancelled() { + return false; + } + }); + index.searchMapIndex(req); + } + } else if (p instanceof AddressRegion && (verbose != null && verbose.isVaddress())) { for(String region : index.getRegionNames()){ println("\tRegion:" + region); for (City c : index.getCities(region, null)) { index.preloadStreets(c, null); - println("\t\tCity:" + c.getName()); + println("\t\tCity:" + c.getName() + getId(c)); for (Street t : c.getStreets()) { - print("\t\t\t" + t.getName()); - index.preloadBuildings(t, null); - List buildings = t.getBuildings(); - if (buildings != null && !buildings.isEmpty()) { - print(" ("); - for (Building b : buildings) { - print(b.getName() + ","); + if (verbose.contains(t)) { + print("\t\t\t" + t.getName() + getId(t)); + index.preloadBuildings(t, null); + List buildings = t.getBuildings(); + if (buildings != null && !buildings.isEmpty()) { + print("\t\t\t\t ("); + for (Building b : buildings) { + print(b.getName() + ","); + } + print(")"); } - print(")"); + println(""); } - println(""); } } for (City c : index.getVillages(region, null,null,false)) { - index.preloadStreets(c, null); - println("\t\tVillage:" + c.getName()); - for (Street t : c.getStreets()) { - println("\t\t\t" + t.getName()); + if (verbose.contains(c)) { + index.preloadStreets(c, null); + println("\t\tVillage:" + c.getName() + getId(c)); + for (Street t : c.getStreets()) { + println("\t\t\t" + t.getName() + getId(t)); + } } } } @@ -378,6 +506,10 @@ public class BinaryInspector { } } + + private static String getId(MapObject o ){ + return " " + (o.getId() >> 1); + } public static void printUsage(String warning) { if(warning != null){ @@ -385,9 +517,9 @@ public class BinaryInspector { } println("Inspector is console utility for working with binary indexes of OsmAnd."); println("It allows print info about file, extract parts and merge indexes."); - println("\nUsage for print info : inspector [-v] [file]"); + println("\nUsage for print info : inspector [-vaddress] [-vmap] [-vpoi] [-vtransport] [-zoom=Zoom] [-bbox=LeftLon,TopLat,RightLon,BottomLan] [file]"); println(" Prints information about [file] binary index of OsmAnd."); - println(" -v more verbouse output (like all cities and their streets)"); + println(" -v.. more verbouse output (like all cities and their streets or all map objects with tags/values and coordinates)"); println("\nUsage for combining indexes : inspector -c file_to_create (file_from_extract ((+|-)parts_to_extract)? )*"); println("\tCreate new file of extracted parts from input file. [parts_to_extract] could be parts to include or exclude."); println(" Example : inspector -c output_file input_file +1,2,3\n\tExtracts 1, 2, 3 parts (could be find in print info)"); diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java index 31bb99331e..5d66eaa3ae 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java @@ -789,6 +789,7 @@ public class BinaryMapIndexReader { int ctop = 0; int cbottom = 0; req.numberOfReadSubtrees++; + List tempResults = null; while(true){ if(req.isCancelled()){ return; @@ -806,6 +807,11 @@ 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 OsmandOdb.MapTree.BOTTOM_FIELD_NUMBER : cbottom = codedIS.readSInt32() + pbottom; @@ -831,8 +837,10 @@ public class BinaryMapIndexReader { } BinaryMapDataObject mapObject = readMapDataObject(cleft, cright, ctop, cbottom, req, root); if(mapObject != null){ - req.searchResults.add(mapObject); - + if(tempResults == null){ + tempResults = new ArrayList(); + } + tempResults.add(mapObject); } codedIS.popLimit(oldLimit); break; @@ -851,9 +859,9 @@ public class BinaryMapIndexReader { case OsmandOdb.MapTree.BASEID_FIELD_NUMBER : case OsmandOdb.MapTree.OLDBASEID_FIELD_NUMBER : long baseId = codedIS.readUInt64(); - if (lastIndexResult != -1) { - for (int i = lastIndexResult; i < req.searchResults.size(); i++) { - BinaryMapDataObject rs = req.searchResults.get(i); + 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++) { @@ -870,9 +878,9 @@ public class BinaryMapIndexReader { List stringTable = readStringTable(); codedIS.popLimit(oldLimit); - if (lastIndexResult != -1) { - for (int i = lastIndexResult; i < req.searchResults.size(); i++) { - BinaryMapDataObject rs = req.searchResults.get(i); + 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); } @@ -1085,6 +1093,18 @@ public class BinaryMapIndexReader { return poiIndexes; } + public static SearchRequest buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom, + SearchFilter searchFilter, ResultMatcher matcher) { + SearchRequest request = new SearchRequest(); + request.left = sleft; + request.right = sright; + request.top = stop; + request.bottom = sbottom; + request.zoom = zoom; + request.resultMatcher = matcher; + request.searchFilter = searchFilter; + return request; + } public static SearchRequest buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom, SearchFilter searchFilter){ SearchRequest request = new SearchRequest();