private void writeRouteStops(TransportRoute r, List<TransportStop> stops, boolean direction)
     throws SQLException {
   int i = 0;
   for (TransportStop s : stops) {
     if (!visitedStops.contains(s.getId())) {
       transStopsStat.setLong(1, s.getId());
       transStopsStat.setDouble(2, s.getLocation().getLatitude());
       transStopsStat.setDouble(3, s.getLocation().getLongitude());
       transStopsStat.setString(4, s.getName());
       transStopsStat.setString(5, s.getEnName());
       int x = (int) MapUtils.getTileNumberX(24, s.getLocation().getLongitude());
       int y = (int) MapUtils.getTileNumberY(24, s.getLocation().getLatitude());
       addBatch(transStopsStat);
       try {
         transportStopsTree.insert(new LeafElement(new Rect(x, y, x, y), s.getId()));
       } catch (RTreeInsertException e) {
         throw new IllegalArgumentException(e);
       } catch (IllegalValueException e) {
         throw new IllegalArgumentException(e);
       }
       visitedStops.add(s.getId());
     }
     transRouteStopsStat.setLong(1, r.getId());
     transRouteStopsStat.setLong(2, s.getId());
     transRouteStopsStat.setInt(3, direction ? 1 : 0);
     transRouteStopsStat.setInt(4, i++);
     addBatch(transRouteStopsStat);
   }
 }
  private TransportStop readTransportStop(
      int shift, int cleft, int cright, int ctop, int cbottom, SearchRequest<TransportStop> req)
      throws IOException {
    int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
    if (OsmandOdb.TransportStop.DX_FIELD_NUMBER != tag) {
      throw new IllegalArgumentException();
    }
    int x = codedIS.readSInt32() + cleft;

    tag = WireFormat.getTagFieldNumber(codedIS.readTag());
    if (OsmandOdb.TransportStop.DY_FIELD_NUMBER != tag) {
      throw new IllegalArgumentException();
    }
    int y = codedIS.readSInt32() + ctop;
    if (req.right < x || req.left > x || req.top > y || req.bottom < y) {
      codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
      return null;
    }

    req.numberOfAcceptedObjects++;
    req.cacheTypes.clear();

    TransportStop dataObject = new TransportStop();
    dataObject.setLocation(
        MapUtils.getLatitudeFromTile(TRANSPORT_STOP_ZOOM, y),
        MapUtils.getLongitudeFromTile(TRANSPORT_STOP_ZOOM, x));
    dataObject.setFileOffset(shift);
    while (true) {
      int t = codedIS.readTag();
      tag = WireFormat.getTagFieldNumber(t);
      switch (tag) {
        case 0:
          dataObject.setReferencesToRoutes(req.cacheTypes.toArray());
          if (dataObject.getEnName().length() == 0) {
            dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
          }
          return dataObject;
        case OsmandOdb.TransportStop.ROUTES_FIELD_NUMBER:
          req.cacheTypes.add(shift - codedIS.readUInt32());
          break;
        case OsmandOdb.TransportStop.NAME_EN_FIELD_NUMBER:
          dataObject.setEnName("" + ((char) codedIS.readUInt32())); // $NON-NLS-1$
          break;
        case OsmandOdb.TransportStop.NAME_FIELD_NUMBER:
          int i = codedIS.readUInt32();
          dataObject.setName("" + ((char) i)); // $NON-NLS-1$
          break;
        case OsmandOdb.TransportStop.ID_FIELD_NUMBER:
          dataObject.setId(codedIS.readSInt64());
          break;
        default:
          skipUnknownField(t);
          break;
      }
    }
  }
 private TransportStop readTransportRouteStop(int dx, int dy, long did) throws IOException {
   TransportStop dataObject = new TransportStop();
   boolean end = false;
   while (!end) {
     int t = codedIS.readTag();
     int tag = WireFormat.getTagFieldNumber(t);
     switch (tag) {
       case 0:
         if (dataObject.getEnName().length() == 0) {
           dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
         }
         end = true;
         break;
       case OsmandOdb.TransportRouteStop.NAME_EN_FIELD_NUMBER:
         dataObject.setEnName("" + ((char) codedIS.readUInt32())); // $NON-NLS-1$
         break;
       case OsmandOdb.TransportRouteStop.NAME_FIELD_NUMBER:
         dataObject.setName("" + ((char) codedIS.readUInt32())); // $NON-NLS-1$
         break;
       case OsmandOdb.TransportRouteStop.ID_FIELD_NUMBER:
         did += codedIS.readSInt64();
         break;
       case OsmandOdb.TransportRouteStop.DX_FIELD_NUMBER:
         dx += codedIS.readSInt32();
         break;
       case OsmandOdb.TransportRouteStop.DY_FIELD_NUMBER:
         dy += codedIS.readSInt32();
         break;
       default:
         skipUnknownField(t);
         break;
     }
   }
   dataObject.setId(did);
   dataObject.setLocation(
       MapUtils.getLatitudeFromTile(TRANSPORT_STOP_ZOOM, dy),
       MapUtils.getLongitudeFromTile(TRANSPORT_STOP_ZOOM, dx));
   return dataObject;
 }
  public net.osmand.data.TransportRoute getTransportRoute(int filePointer, TransportIndex ind)
      throws IOException {
    codedIS.seek(filePointer);
    int routeLength = codedIS.readRawVarint32();
    int old = codedIS.pushLimit(routeLength);
    net.osmand.data.TransportRoute dataObject = new net.osmand.data.TransportRoute();
    boolean end = false;
    int name = -1;
    int nameEn = -1;
    int operator = -1;
    int type = -1;
    long rid = 0;
    int rx = 0;
    int ry = 0;
    long did = 0;
    int dx = 0;
    int dy = 0;
    while (!end) {
      int t = codedIS.readTag();
      int tag = WireFormat.getTagFieldNumber(t);
      switch (tag) {
        case 0:
          end = true;
          break;
        case OsmandOdb.TransportRoute.DISTANCE_FIELD_NUMBER:
          dataObject.setDistance(codedIS.readUInt32());
          break;
        case OsmandOdb.TransportRoute.ID_FIELD_NUMBER:
          dataObject.setId(codedIS.readUInt64());
          break;
        case OsmandOdb.TransportRoute.REF_FIELD_NUMBER:
          dataObject.setRef(codedIS.readString());
          break;
        case OsmandOdb.TransportRoute.TYPE_FIELD_NUMBER:
          type = codedIS.readUInt32();
          break;
        case OsmandOdb.TransportRoute.NAME_EN_FIELD_NUMBER:
          nameEn = codedIS.readUInt32();
          break;
        case OsmandOdb.TransportRoute.NAME_FIELD_NUMBER:
          name = codedIS.readUInt32();
          break;
        case OsmandOdb.TransportRoute.OPERATOR_FIELD_NUMBER:
          operator = codedIS.readUInt32();
          break;
        case OsmandOdb.TransportRoute.REVERSESTOPS_FIELD_NUMBER:
          int length = codedIS.readRawVarint32();
          int olds = codedIS.pushLimit(length);
          TransportStop stop = readTransportRouteStop(dx, dy, did);
          dataObject.getBackwardStops().add(stop);
          did = stop.getId();
          dx =
              (int) MapUtils.getTileNumberX(TRANSPORT_STOP_ZOOM, stop.getLocation().getLongitude());
          dy = (int) MapUtils.getTileNumberY(TRANSPORT_STOP_ZOOM, stop.getLocation().getLatitude());
          codedIS.popLimit(olds);
          break;
        case OsmandOdb.TransportRoute.DIRECTSTOPS_FIELD_NUMBER:
          length = codedIS.readRawVarint32();
          olds = codedIS.pushLimit(length);
          stop = readTransportRouteStop(rx, ry, rid);
          dataObject.getForwardStops().add(stop);
          rid = stop.getId();
          rx =
              (int) MapUtils.getTileNumberX(TRANSPORT_STOP_ZOOM, stop.getLocation().getLongitude());
          ry = (int) MapUtils.getTileNumberY(TRANSPORT_STOP_ZOOM, stop.getLocation().getLatitude());
          codedIS.popLimit(olds);
          break;
        default:
          skipUnknownField(t);
          break;
      }
    }
    codedIS.popLimit(old);
    if (name != -1) {
      dataObject.setName(getStringFromStringTable(ind.stringTable, name));
    }
    if (nameEn != -1) {
      dataObject.setEnName(getStringFromStringTable(ind.stringTable, nameEn));
    } else {
      dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
    }

    if (operator != -1) {
      dataObject.setOperator(getStringFromStringTable(ind.stringTable, operator));
    }
    if (type != -1) {
      dataObject.setType(getStringFromStringTable(ind.stringTable, type));
    }
    for (int i = 0; i < 2; i++) {
      List<TransportStop> stops =
          i == 0 ? dataObject.getForwardStops() : dataObject.getBackwardStops();
      for (TransportStop s : stops) {
        if (s.getName().length() > 0) {
          s.setName(getStringFromStringTable(ind.stringTable, s.getName().charAt(0)));
        }
        if (s.getEnName().length() > 0) {
          s.setEnName(getStringFromStringTable(ind.stringTable, s.getEnName().charAt(0)));
        } else {
          s.setEnName(Junidecode.unidecode(s.getName()));
        }
      }
    }

    return dataObject;
  }