예제 #1
0
  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;
    }
  }
예제 #2
0
  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;
  }
예제 #3
0
  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;
  }
예제 #4
0
  @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);
 }