예제 #1
0
  int addEdge(int fromIndex, int toIndex, PointList pointList, int flags) {
    double towerNodeDistance = 0;
    double prevLat = pointList.latitude(0);
    double prevLon = pointList.longitude(0);
    double lat;
    double lon;
    PointList pillarNodes = new PointList(pointList.size() - 2);
    int nodes = pointList.size();
    for (int i = 1; i < nodes; i++) {
      lat = pointList.latitude(i);
      lon = pointList.longitude(i);
      towerNodeDistance += callback.calcDist(prevLat, prevLon, lat, lon);
      prevLat = lat;
      prevLon = lon;
      if (nodes > 2 && i < nodes - 1) pillarNodes.add(lat, lon);
    }
    if (towerNodeDistance == 0) {
      // As investigation shows often two paths should have crossed via one identical point
      // but end up in two very close points. later this will be removed/fixed while
      // removing short edges where one node is of degree 2
      zeroCounter++;
      towerNodeDistance = 0.0001;
    }

    EdgeIterator iter = g.edge(fromIndex, toIndex, towerNodeDistance, flags);
    if (nodes > 2) iter.wayGeometry(pillarNodes);
    return nodes;
  }
예제 #2
0
  @Test
  public void testBoth() throws Exception {
    PointList list =
        Helper.createPointList(
            38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 50.3139, 10.612793, 50.04303, 9.497681);
    String str = WebHelper.encodePolyline(list);
    assertEquals(list, WebHelper.decodePolyline(str, list.size()));

    list =
        Helper.createPointList(38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 40.70001, -120.95001);
    str = WebHelper.encodePolyline(list);
    assertEquals(list, WebHelper.decodePolyline(str, list.size()));
  }
  @Override
  public int addEdge(TLongList osmIds, int flags) {
    PointList pointList = new PointList(osmIds.size());
    int successfullyAdded = 0;
    int firstNode = -1;
    int lastIndex = osmIds.size() - 1;
    int lastInBoundsPillarNode = -1;
    for (int i = 0; i < osmIds.size(); i++) {
      long osmId = osmIds.get(i);
      int tmpNode = osmIdToIndexMap.get(osmId);
      if (tmpNode == EMPTY) continue;
      // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds)
      if (tmpNode == TOWER_NODE) continue;
      if (tmpNode == PILLAR_NODE) {
        // In some cases no node information is saved for the specified osmId.
        // ie. a way references a <node> which does not exist in the current file.
        // => if the node before was a pillar node then convert into to tower node (as it is also
        // end-standing).
        if (!pointList.isEmpty() && lastInBoundsPillarNode > -TOWER_NODE) {
          // transform the pillar node to a tower node
          tmpNode = lastInBoundsPillarNode;
          tmpNode = handlePillarNode(tmpNode, osmId, null, true);
          tmpNode = -tmpNode - 3;
          if (pointList.size() > 1 && firstNode >= 0) {
            // TOWER node
            successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
            pointList.clear();
            pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
          }
          firstNode = tmpNode;
          lastInBoundsPillarNode = -1;
        }
        continue;
      }

      if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE)
        throw new AssertionError("Mapped index not in correct bounds " + tmpNode + ", " + osmId);

      if (tmpNode > -TOWER_NODE) {
        boolean convertToTowerNode = i == 0 || i == lastIndex;
        if (!convertToTowerNode) lastInBoundsPillarNode = tmpNode;

        // PILLAR node, but convert to towerNode if end-standing
        tmpNode = handlePillarNode(tmpNode, osmId, pointList, convertToTowerNode);
      }

      if (tmpNode < TOWER_NODE) {
        // TOWER node
        tmpNode = -tmpNode - 3;
        pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        if (firstNode >= 0) {
          successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
          pointList.clear();
          pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        }
        firstNode = tmpNode;
      }
    }
    return successfullyAdded;
  }
  @Override
  public int addEdge(TLongList nodes, int flags) {
    PointList pointList = new PointList(nodes.size());
    int successfullyAdded = 0;
    int firstNode = -1;
    int lastIndex = nodes.size() - 1;
    int lastInBoundsPillarNode = -1;
    for (int i = 0; i < nodes.size(); i++) {
      long osmId = nodes.get(i);
      int tmpNode = osmIdToIndexMap.get(osmId);
      if (tmpNode == EMPTY) continue;
      // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds)
      if (tmpNode == TOWER_NODE) continue;
      if (tmpNode == PILLAR_NODE) {
        // no pillarLats,pillarLons was saved for tmpNode
        // so if there are any existing pillar nodes we need to create an edge out of them
        if (!pointList.isEmpty() && lastInBoundsPillarNode >= 3) {
          // transform the pillar node to a tower node
          tmpNode = lastInBoundsPillarNode;
          tmpNode = handlePillarNode(tmpNode, osmId, null, true);
          tmpNode = -tmpNode - 3;
          if (pointList.size() > 1 && firstNode >= 0) {
            // TOWER node
            successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
            pointList.clear();
            pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
          }
          firstNode = tmpNode;
          lastInBoundsPillarNode = -1;
        }
        continue;
      }

      if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE)
        throw new AssertionError("Mapped index not in correct bounds " + tmpNode);

      if (tmpNode > -TOWER_NODE) {
        lastInBoundsPillarNode = tmpNode;
        // PILLAR node, but convert to towerNode if end-standing
        tmpNode = handlePillarNode(tmpNode, osmId, pointList, i == 0 || i == lastIndex);
      }

      if (tmpNode < TOWER_NODE) {
        // TOWER node
        tmpNode = -tmpNode - 3;
        pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        if (firstNode >= 0) {
          successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags);
          pointList.clear();
          pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode));
        }
        firstNode = tmpNode;
      }
    }
    return successfullyAdded;
  }
 public void suggest(File locationFile, int locationListSize, File outputFile, int hubSize) {
   // WARNING: this code is VERY DIRTY.
   // It's JUST good enough to generate the hubs for Belgium once (because we only need to
   // determine them once).
   // Further research to generate good hubs is needed.
   List<AirLocation> locationList = readAirLocationFile(locationFile);
   if (locationListSize > locationList.size()) {
     throw new IllegalArgumentException(
         "The locationListSize ("
             + locationListSize
             + ") is larger than the locationList size ("
             + locationList.size()
             + ").");
   }
   locationList = subselectLocationList(locationListSize, locationList);
   Map<Point, Point> fromPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10);
   Map<Point, Point> toPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10);
   int rowIndex = 0;
   double maxAirDistance = 0.0;
   for (AirLocation fromAirLocation : locationList) {
     for (AirLocation toAirLocation : locationList) {
       double airDistance = fromAirLocation.getAirDistanceDouble(toAirLocation);
       if (airDistance > maxAirDistance) {
         maxAirDistance = airDistance;
       }
     }
   }
   double airDistanceThreshold = maxAirDistance / 10.0;
   for (AirLocation fromAirLocation : locationList) {
     for (AirLocation toAirLocation : locationList) {
       double distance;
       if (fromAirLocation != toAirLocation) {
         GHRequest request =
             new GHRequest(
                     fromAirLocation.getLatitude(),
                     fromAirLocation.getLongitude(),
                     toAirLocation.getLatitude(),
                     toAirLocation.getLongitude())
                 .setVehicle("car");
         GHResponse response = graphHopper.route(request);
         if (response.hasErrors()) {
           throw new IllegalStateException(
               "GraphHopper gave " + response.getErrors().size() + " errors. First error chained.",
               response.getErrors().get(0));
         }
         // Distance should be in km, not meter
         distance = response.getDistance() / 1000.0;
         if (distance == 0.0) {
           throw new IllegalArgumentException(
               "The fromAirLocation ("
                   + fromAirLocation
                   + ") and toAirLocation ("
                   + toAirLocation
                   + ") are the same.");
         }
         PointList ghPointList = response.getPoints();
         PointPart previousFromPointPart = null;
         PointPart previousToPointPart = null;
         double previousLatitude = Double.NaN;
         double previousLongitude = Double.NaN;
         for (int i = 0; i < ghPointList.size(); i++) {
           double latitude = ghPointList.getLatitude(i);
           double longitude = ghPointList.getLongitude(i);
           if (latitude == previousLatitude && longitude == previousLongitude) {
             continue;
           }
           if (calcAirDistance(
                   latitude,
                   longitude,
                   fromAirLocation.getLatitude(),
                   fromAirLocation.getLongitude())
               < airDistanceThreshold) {
             Point fromPoint = new Point(latitude, longitude);
             Point oldFromPoint = fromPointMap.get(fromPoint);
             if (oldFromPoint == null) {
               // Initialize fromPoint instance
               fromPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>();
               fromPointMap.put(fromPoint, fromPoint);
             } else {
               // Reuse existing fromPoint instance
               fromPoint = oldFromPoint;
             }
             PointPart fromPointPart = fromPoint.pointPartMap.get(fromAirLocation);
             if (fromPointPart == null) {
               fromPointPart = new PointPart(fromPoint, fromAirLocation);
               fromPoint.pointPartMap.put(fromAirLocation, fromPointPart);
               fromPointPart.previousPart = previousFromPointPart;
             }
             fromPointPart.count++;
             previousFromPointPart = fromPointPart;
           }
           if (calcAirDistance(
                   latitude, longitude, toAirLocation.getLatitude(), toAirLocation.getLongitude())
               < airDistanceThreshold) {
             Point toPoint = new Point(latitude, longitude);
             Point oldToPoint = toPointMap.get(toPoint);
             if (oldToPoint == null) {
               // Initialize toPoint instance
               toPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>();
               toPointMap.put(toPoint, toPoint);
             } else {
               // Reuse existing toPoint instance
               toPoint = oldToPoint;
             }
             // Basically do the same as fromPointPart, but while traversing in the other direction
             PointPart toPointPart = toPoint.pointPartMap.get(toAirLocation);
             boolean newToPointPart = false;
             if (toPointPart == null) {
               toPointPart = new PointPart(toPoint, toAirLocation);
               toPoint.pointPartMap.put(toAirLocation, toPointPart);
               newToPointPart = true;
             }
             if (previousToPointPart != null) {
               previousToPointPart.previousPart = toPointPart;
             }
             toPointPart.count++;
             if (newToPointPart) {
               previousToPointPart = toPointPart;
             } else {
               previousToPointPart = null;
             }
           }
           previousLatitude = latitude;
           previousLongitude = longitude;
         }
       }
     }
     logger.debug("  Finished routes for rowIndex {}/{}", rowIndex, locationList.size());
     rowIndex++;
   }
   Set<Point> hubPointList = new LinkedHashSet<Point>(20);
   extractFromHubs(new ArrayList<Point>(fromPointMap.values()), hubPointList, (hubSize + 1) / 2);
   extractFromHubs(new ArrayList<Point>(toPointMap.values()), hubPointList, hubSize / 2);
   logger.info("Writing hubs...");
   BufferedWriter vrpWriter = null;
   try {
     vrpWriter =
         new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"));
     vrpWriter.write("HUB_COORD_SECTION\n");
     int id = 0;
     for (Point point : hubPointList) {
       vrpWriter.write("" + id + " " + point.latitude + " " + point.longitude + " " + id + "\n");
       id++;
     }
     vrpWriter.write("\n\nGOOGLE MAPS\n");
     for (Point point : hubPointList) {
       vrpWriter.write("" + id + "\t0\t" + point.latitude + "," + point.longitude + "\n");
       id++;
     }
   } catch (IOException e) {
     throw new IllegalArgumentException(
         "Could not read the locationFile ("
             + locationFile.getName()
             + ") or write the vrpOutputFile ("
             + outputFile.getName()
             + ").",
         e);
   } finally {
     IOUtils.closeQuietly(vrpWriter);
   }
   // Throw in google docs spreadsheet and use add-on Mapping Sheets to visualize.
 }