public static void printFileInformation(File file) throws IOException { RandomAccessFile r = new RandomAccessFile(file.getAbsolutePath(), "r"); try { BinaryMapIndexReader index = new BinaryMapIndexReader(r); int i = 1; System.out.println("Binary index " + file.getName() + " version = " + index.getVersion()); for (BinaryIndexPart p : index.getIndexes()) { String partname = ""; if (p instanceof MapIndex) { partname = "Map"; } else if (p instanceof TransportIndex) { partname = "Transport"; } else if (p instanceof AddressRegion) { partname = "Address"; } String name = p.getName() == null ? "" : p.getName(); System.out.println( MessageFormat.format( "{0}. {1} data {3} - {2} bytes", i, partname, p.getLength(), name)); if (p instanceof TransportIndex) { TransportIndex ti = ((TransportIndex) p); int sh = (31 - BinaryMapIndexReader.TRANSPORT_STOP_ZOOM); System.out.println( "\t Bounds " + formatBounds( ti.getLeft() << sh, ti.getRight() << sh, ti.getTop() << sh, ti.getBottom() << sh)); } else if (p instanceof MapIndex) { MapIndex m = ((MapIndex) p); int j = 1; for (MapRoot mi : m.getRoots()) { System.out.println( MessageFormat.format( "\t{4}.{5} Map level minZoom = {0}, maxZoom = {1}, size = {2} bytes \n\t\tBounds {3}", mi.getMinZoom(), mi.getMaxZoom(), mi.getLength(), formatBounds(mi.getLeft(), mi.getRight(), mi.getTop(), mi.getBottom()), i, j++)); } } i++; } } catch (IOException e) { System.err.println("File is not valid index : " + file.getAbsolutePath()); throw e; } }
private List<GeocodingResult> loadStreetBuildings( final GeocodingResult road, BinaryMapIndexReader reader, GeocodingResult street) throws IOException { final List<GeocodingResult> streetBuildings = new ArrayList<GeocodingResult>(); reader.preloadBuildings(street.street, null); log.info( "Preload buildings " + street.street.getName() + " " + street.city.getName() + " " + street.street.getId()); for (Building b : street.street.getBuildings()) { if (b.getLatLon2() != null) { double slat = b.getLocation().getLatitude(); double slon = b.getLocation().getLongitude(); double tolat = b.getLatLon2().getLatitude(); double tolon = b.getLatLon2().getLongitude(); double coeff = MapUtils.getProjectionCoeff( road.searchPoint.getLatitude(), road.searchPoint.getLongitude(), slat, slon, tolat, tolon); double plat = slat + (tolat - slat) * coeff; double plon = slon + (tolon - slon) * coeff; if (MapUtils.getDistance(road.searchPoint, plat, plon) < DISTANCE_BUILDING_PROXIMITY) { GeocodingResult bld = new GeocodingResult(street); bld.building = b; bld.connectionPoint = b.getLocation(); streetBuildings.add(bld); if (!Algorithms.isEmpty(b.getName2())) { int fi = Algorithms.extractFirstIntegerNumber(b.getName()); int si = Algorithms.extractFirstIntegerNumber(b.getName2()); if (si != 0 && fi != 0) { int num = (int) (fi + (si - fi) * coeff); BuildingInterpolation type = b.getInterpolationType(); if (type == BuildingInterpolation.EVEN || type == BuildingInterpolation.ODD) { if (num % 2 == (type == BuildingInterpolation.EVEN ? 1 : 0)) { num--; } } else if (b.getInterpolationInterval() > 0) { int intv = b.getInterpolationInterval(); if ((num - fi) % intv != 0) { num = ((num - fi) / intv) * intv + fi; } } bld.buildingInterpolation = num + ""; } } } } else if (MapUtils.getDistance(b.getLocation(), road.searchPoint) < DISTANCE_BUILDING_PROXIMITY) { GeocodingResult bld = new GeocodingResult(street); bld.building = b; bld.connectionPoint = b.getLocation(); streetBuildings.add(bld); } } return streetBuildings; }
public List<GeocodingResult> justifyReverseGeocodingSearch( final GeocodingResult road, BinaryMapIndexReader reader, double knownMinBuildingDistance, final ResultMatcher<GeocodingResult> result) throws IOException { // test address index search final List<GeocodingResult> streetsList = new ArrayList<GeocodingResult>(); final List<String> streetNamePacked = prepareStreetName(road.streetName); if (streetNamePacked.size() > 0) { log.info("Search street by name " + road.streetName + " " + streetNamePacked); String mainWord = ""; for (int i = 0; i < streetNamePacked.size(); i++) { String s = streetNamePacked.get(i); if (!getSuffixesSet().contains(s) && s.length() > mainWord.length()) { mainWord = s; } } if (Algorithms.isEmpty(mainWord)) { mainWord = streetNamePacked.get(0); } SearchRequest<MapObject> req = BinaryMapIndexReader.buildAddressByNameRequest( new ResultMatcher<MapObject>() { @Override public boolean publish(MapObject object) { if (object instanceof Street && prepareStreetName(object.getName()).equals(streetNamePacked)) { double d = MapUtils.getDistance( object.getLocation(), road.searchPoint.getLatitude(), road.searchPoint.getLongitude()); // double check to suport old format if (d < DISTANCE_STREET_NAME_PROXIMITY_BY_NAME) { GeocodingResult rs = new GeocodingResult(road); rs.street = (Street) object; // set connection point to sort rs.connectionPoint = rs.street.getLocation(); rs.city = rs.street.getCity(); streetsList.add(rs); return true; } return false; } return false; } @Override public boolean isCancelled() { return result != null && result.isCancelled(); } }, mainWord, StringMatcherMode.CHECK_EQUALS_FROM_SPACE); req.setBBoxRadius( road.getLocation().getLatitude(), road.getLocation().getLongitude(), DISTANCE_STREET_NAME_PROXIMITY_BY_NAME); reader.searchAddressDataByName(req); } final List<GeocodingResult> res = new ArrayList<GeocodingResult>(); if (streetsList.size() == 0) { res.add(road); } else { Collections.sort(streetsList, DISTANCE_COMPARATOR); double streetDistance = 0; for (GeocodingResult street : streetsList) { if (streetDistance == 0) { streetDistance = street.getDistance(); } else if (street.getDistance() > streetDistance + DISTANCE_STREET_FROM_CLOSEST_WITH_SAME_NAME) { continue; } street.connectionPoint = road.connectionPoint; final List<GeocodingResult> streetBuildings = loadStreetBuildings(road, reader, street); Collections.sort(streetBuildings, DISTANCE_COMPARATOR); if (streetBuildings.size() > 0) { Iterator<GeocodingResult> it = streetBuildings.iterator(); if (knownMinBuildingDistance == 0) { GeocodingResult firstBld = it.next(); knownMinBuildingDistance = firstBld.getDistance(); res.add(firstBld); } while (it.hasNext()) { GeocodingResult nextBld = it.next(); if (nextBld.getDistance() > knownMinBuildingDistance * THRESHOLD_MULTIPLIER_SKIP_BUILDINGS_AFTER) { break; } res.add(nextBld); } } res.add(street); } } Collections.sort(res, DISTANCE_COMPARATOR); return res; }
@SuppressWarnings("unchecked") public static List<Float> combineParts(File fileToExtract, Map<File, String> partsToExtractFrom) throws IOException { BinaryMapIndexReader[] indexes = new BinaryMapIndexReader[partsToExtractFrom.size()]; RandomAccessFile[] rafs = new RandomAccessFile[partsToExtractFrom.size()]; LinkedHashSet<Float>[] partsSet = new LinkedHashSet[partsToExtractFrom.size()]; int c = 0; Set<String> addressNames = new LinkedHashSet<String>(); int version = -1; // Go through all files and validate conistency for (File f : partsToExtractFrom.keySet()) { if (f.getAbsolutePath().equals(fileToExtract.getAbsolutePath())) { System.err.println("Error : Input file is equal to output file " + f.getAbsolutePath()); return null; } rafs[c] = new RandomAccessFile(f, "r"); indexes[c] = new BinaryMapIndexReader(rafs[c]); partsSet[c] = new LinkedHashSet<Float>(); if (version == -1) { version = indexes[c].getVersion(); } else { if (indexes[c].getVersion() != version) { System.err.println( "Error : Different input files has different input versions " + indexes[c].getVersion() + " != " + version); return null; } } LinkedHashSet<Float> temp = new LinkedHashSet<Float>(); String pattern = partsToExtractFrom.get(f); boolean minus = true; for (int i = 0; i < indexes[c].getIndexes().size(); i++) { partsSet[c].add(i + 1f); BinaryIndexPart part = indexes[c].getIndexes().get(i); if (part instanceof MapIndex) { List<MapRoot> roots = ((MapIndex) part).getRoots(); for (int j = 0; j < roots.size(); j++) { partsSet[c].add((i + 1f) + (j + 1) / 10f); } } } if (pattern != null) { minus = pattern.startsWith("-"); String[] split = pattern.substring(1).split(","); for (String s : split) { temp.add(Float.parseFloat(s)); } } if (minus) { partsSet[c].removeAll(temp); } else { partsSet[c].retainAll(temp); } c++; } // write files FileOutputStream fout = new FileOutputStream(fileToExtract); CodedOutputStream ous = CodedOutputStream.newInstance(fout, BUFFER_SIZE); List<Float> list = new ArrayList<Float>(); byte[] BUFFER_TO_READ = new byte[BUFFER_SIZE]; ous.writeInt32(OsmandOdb.OsmAndStructure.VERSION_FIELD_NUMBER, version); for (int k = 0; k < indexes.length; k++) { LinkedHashSet<Float> partSet = partsSet[k]; BinaryMapIndexReader index = indexes[k]; RandomAccessFile raf = rafs[k]; for (int i = 0; i < index.getIndexes().size(); i++) { if (!partSet.contains(i + 1f)) { continue; } list.add(i + 1f); BinaryIndexPart part = index.getIndexes().get(i); String map; if (part instanceof MapIndex) { ous.writeTag( OsmandOdb.OsmAndStructure.MAPINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED); map = "Map"; List<MapRoot> roots = ((MapIndex) part).getRoots(); List<MapRoot> toSkip = new ArrayList<MapRoot>(); int newL = 0; int tagAndFieldSize = CodedOutputStream.computeTagSize(OsmandOdb.OsmAndMapIndex.LEVELS_FIELD_NUMBER) + 4; for (int j = 0; j < roots.size(); j++) { if (!partSet.contains(i + 1f + (j + 1) * 0.1f)) { newL -= (roots.get(j).getLength() + tagAndFieldSize); toSkip.add(roots.get(j)); } } writeInt(ous, part.getLength() + newL); long seek = part.getFilePointer(); while (seek < (part.getFilePointer() + part.getLength())) { MapRoot next = null; for (MapRoot r : toSkip) { if (seek < r.getFilePointer()) { if (next == null || next.getFilePointer() > r.getFilePointer()) { next = r; } } } if (next == null) { copyBinaryPart( ous, BUFFER_TO_READ, raf, seek, (int) (part.getLength() - (seek - part.getFilePointer()))); break; } else { int l = (int) (next.getFilePointer() - seek - tagAndFieldSize); if (l > 0) { copyBinaryPart(ous, BUFFER_TO_READ, raf, seek, l); } seek += next.getLength() + tagAndFieldSize + l; } } System.out.println( MessageFormat.format( "{2} part {0} is extracted {1} bytes", part.getName(), part.getLength() + newL, map)); } else { if (part instanceof AddressRegion) { ous.writeTag( OsmandOdb.OsmAndStructure.ADDRESSINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED); map = "Address"; if (addressNames.contains(part.getName())) { System.err.println( "Error : going to merge 2 addresses with same names. Skip " + part.getName()); continue; } addressNames.add(part.getName()); } else if (part instanceof TransportIndex) { ous.writeTag( OsmandOdb.OsmAndStructure.TRANSPORTINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED); map = "Transport"; } else { throw new UnsupportedOperationException(); } writeInt(ous, part.getLength()); copyBinaryPart(ous, BUFFER_TO_READ, raf, part.getFilePointer(), part.getLength()); System.out.println( MessageFormat.format( "{2} part {0} is extracted {1} bytes", part.getName(), part.getLength(), map)); } } } ous.writeInt32(OsmandOdb.OsmAndStructure.VERSIONCONFIRM_FIELD_NUMBER, version); ous.flush(); fout.close(); return list; }
private void readRouteTreeData( RouteSubregion routeTree, TLongArrayList idTables, TLongObjectHashMap<TLongArrayList> restrictions) throws IOException { routeTree.dataObjects = new ArrayList<RouteDataObject>(); idTables.clear(); restrictions.clear(); List<String> stringTable = null; while (true) { int t = codedIS.readTag(); int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: TLongObjectIterator<TLongArrayList> it = restrictions.iterator(); while (it.hasNext()) { it.advance(); int from = (int) it.key(); RouteDataObject fromr = routeTree.dataObjects.get(from); fromr.restrictions = new long[it.value().size()]; for (int k = 0; k < fromr.restrictions.length; k++) { int to = (int) (it.value().get(k) >> RouteDataObject.RESTRICTION_SHIFT); long valto = (idTables.get(to) << RouteDataObject.RESTRICTION_SHIFT) | ((long) it.value().get(k) & RouteDataObject.RESTRICTION_MASK); fromr.restrictions[k] = valto; } } for (RouteDataObject o : routeTree.dataObjects) { if (o != null) { if (o.id < idTables.size()) { o.id = idTables.get((int) o.id); } if (o.names != null && stringTable != null) { int[] keys = o.names.keys(); for (int j = 0; j < keys.length; j++) { o.names.put(keys[j], stringTable.get(o.names.get(keys[j]).charAt(0))); } } } } return; case RouteDataBlock.DATAOBJECTS_FIELD_NUMBER: int length = codedIS.readRawVarint32(); int oldLimit = codedIS.pushLimit(length); RouteDataObject obj = readRouteDataObject(routeTree.routeReg, routeTree.left, routeTree.top); while (obj.id >= routeTree.dataObjects.size()) { routeTree.dataObjects.add(null); } routeTree.dataObjects.set((int) obj.id, obj); codedIS.popLimit(oldLimit); break; case RouteDataBlock.IDTABLE_FIELD_NUMBER: long routeId = 0; length = codedIS.readRawVarint32(); oldLimit = codedIS.pushLimit(length); idLoop: while (true) { int ts = codedIS.readTag(); int tags = WireFormat.getTagFieldNumber(ts); switch (tags) { case 0: break idLoop; case IdTable.ROUTEID_FIELD_NUMBER: routeId += codedIS.readSInt64(); idTables.add(routeId); break; default: skipUnknownField(ts); break; } } codedIS.popLimit(oldLimit); break; case RouteDataBlock.RESTRICTIONS_FIELD_NUMBER: length = codedIS.readRawVarint32(); oldLimit = codedIS.pushLimit(length); long from = 0; long to = 0; long type = 0; idLoop: while (true) { int ts = codedIS.readTag(); int tags = WireFormat.getTagFieldNumber(ts); switch (tags) { case 0: break idLoop; case RestrictionData.FROM_FIELD_NUMBER: from = codedIS.readInt32(); break; case RestrictionData.TO_FIELD_NUMBER: to = codedIS.readInt32(); break; case RestrictionData.TYPE_FIELD_NUMBER: type = codedIS.readInt32(); break; default: skipUnknownField(ts); break; } } if (!restrictions.containsKey(from)) { restrictions.put(from, new TLongArrayList()); } restrictions.get(from).add((to << RouteDataObject.RESTRICTION_SHIFT) + type); codedIS.popLimit(oldLimit); break; case RouteDataBlock.STRINGTABLE_FIELD_NUMBER: length = codedIS.readRawVarint32(); oldLimit = codedIS.pushLimit(length); stringTable = map.readStringTable(); // codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); codedIS.popLimit(oldLimit); break; default: skipUnknownField(t); break; } } }
private int readInt() throws IOException { return map.readInt(); }
private void skipUnknownField(int t) throws IOException { map.skipUnknownField(t); }