예제 #1
0
  /**
   * Determine if a polygon contains a point.
   *
   * @param polygon is a simple closed polygon defined by a set of points. A line is drawn from the
   *     last point to the first one; the array should not contain the first/last point twice.
   * @param pt is a point which is tested for enclosure in the polygon
   */
  public static boolean contains(GeoPt[] polygon, GeoPt pt) {
    int crossings = 0;
    for (int i = 0; i < polygon.length; i++) {
      GeoPt p1 = polygon[i];
      GeoPt p2 = polygon[(i + 1) == polygon.length ? 0 : i + 1];

      double slope =
          (p2.getLongitude() - p1.getLongitude()) / (p2.getLatitude() - p1.getLatitude());
      boolean cond1 =
          (p1.getLatitude() <= pt.getLatitude()) && (pt.getLatitude() < p2.getLatitude());
      boolean cond2 =
          (p2.getLatitude() <= pt.getLatitude()) && (pt.getLatitude() < p1.getLatitude());
      boolean cond3 =
          pt.getLongitude() < slope * (pt.getLatitude() - p1.getLatitude()) + p1.getLongitude();
      if ((cond1 || cond2) && cond3) crossings++;
    }

    return (crossings % 2 != 0);
  }
예제 #2
0
  public ConnectionProxy indirectSearch(
      GeoPt start, GeoPt dest, Set<Key<Line>> tabuTrainsSet, Set<Key<Line>> mlkSet, Objectify ofy) {
    final String functionName = "newIndirectSearch()";
    final int plusMinus = 8;
    final int maxAlternatives = 8;
    HashSet<Key<PQA>> PQsForAStar = new HashSet<Key<PQA>>();
    Logger.getLogger(location)
        .log(Level.INFO, functionName + ": " + "fetching PQAs for " + mlkSet.size() + " lines.");
    try {
      Cache cache =
          CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
      for (Key<Line> k : mlkSet) {
        Query<PQA> q = ofy.query(PQA.class).filter("lineKeys", k);
        @SuppressWarnings("unchecked")
        List<Key<PQA>> rl = (List<Key<PQA>>) cache.get(q.toString());
        if (rl == null) {
          rl = q.listKeys();
          cache.put(q.toString(), rl);
        }
        PQsForAStar.addAll(rl);
      }
    } catch (CacheException e) {
      Logger.getLogger(location).log(Level.SEVERE, functionName + ": Cache error: " + e);
      e.printStackTrace();
    }
    Logger.getLogger(location)
        .log(Level.FINER, functionName + ": " + "Got " + PQsForAStar.size() + " PQs.");
    /*for(PlanQuadrat pq : PQsForAStar) {
    	System.err.print("\"" + pq.getGeoCell() + "\",");
    }
    System.err.println();*/
    HashSet<String> setBusKey = new HashSet<String>();
    for (Key<PQA> pq : PQsForAStar) {
      setBusKey.add(pq.getName());
    }
    //		HashMap<String, PlanQuadrat> mapBus = new HashMap<String, PlanQuadrat>();
    WayHolder wh =
        new AStarImpl()
            .aStarSearch(
                Utils.computeGeoCell(
                    new com.beoui.geocell.model.Point(start.getLatitude(), start.getLongitude())),
                Utils.computeGeoCell(
                    new com.beoui.geocell.model.Point(dest.getLatitude(), dest.getLongitude())),
                setBusKey,
                mlkSet,
                tabuTrainsSet,
                ofy); // erste Cell jeweils aus Liste Start und Liste Dest Cells. das gehört noch
                      // überarbeitet
    /*
    for(AStarNode asn : wh.getWay()) {
    	System.err.print("\"" + asn.getGeoCell() + "\", ");
    }
    System.err.println();
    for(AStarNode asn : wh.getWay()) {
    	System.err.print("\"" + asn.getOwningLine() + "\", ");
    }
    System.err.println();*/
    if (wh != null && wh.getWay().size() > 1) {
      List<AStarNode> way = wh.getWay();
      List<AStarNode> umsteigen = wh.getCombinationPoints();
      int index = 0;
      if (way.get(0).getOwningLine() == null) {
        index = 1;
      }
      Collection<Point> pointsStart;
      if (way.get(index).getClass() == AStarNodeImpl.class) {
        pointsStart =
            getSearchPointsForLine(
                way.get(index).getOwningLine(), way.get(index).getPointGeoCell(), plusMinus, ofy);
      } else {
        Line tempLine = getLineByKey(way.get(index).getOwningLine(), ofy);
        if (tempLine.getType() == 11 || tempLine.getType() == 13 || tempLine.getType() == 15) {
          pointsStart =
              getSearchPointsForLine(
                  way.get(index).getOwningLine(), way.get(index).getPointGeoCell(), 1, ofy);
        } else {
          pointsStart =
              getSearchPointsForLine(
                  way.get(index).getOwningLine(), way.get(index).getPointGeoCell(), 0, ofy);
        }
      }
      //			System.err.println("pointsStart.size: " + pointsStart.size());
      Point startPoint = Utils.closestPoint(start, pointsStart);
      List<LineProxy> lineProxies = new LinkedList<LineProxy>();
      LineProxy walk =
          Utils.walk(new Point(null, start.getLatitude(), start.getLongitude(), null), startPoint);
      lineProxies.add(walk);

      Point lastPoint = startPoint;
      AStarNode lastNode = way.get(index);
      for (int i = index; i < way.size(); i++) {
        AStarNode an = way.get(i);
        if (umsteigen.contains(an)) {
          Collection<Point> pointsLine1;
          if (an.getClass() == AStarNodeImpl.class) {
            pointsLine1 =
                getSearchPointsForLine(lastPoint.getOwner(), an.getPointGeoCell(), plusMinus, ofy);
          } else {
            Line tempLine = getLineByKey(an.getOwningLine(), ofy);
            if (tempLine.getType() == 11 || tempLine.getType() == 13 || tempLine.getType() == 15) {
              pointsLine1 =
                  getSearchPointsForLine(an.getOwningLine(), an.getPointGeoCell(), 1, ofy);
            } else {
              pointsLine1 =
                  getSearchPointsForLine(an.getOwningLine(), an.getPointGeoCell(), 0, ofy);
            }
          }
          AStarNode next = way.get(i + 1);
          Collection<Point> pointsLine2;
          if (next.getClass() == AStarNodeImpl.class) {
            //						System.err.println("Line: " + next.getOwningLine() + " / " +
            // Dao.getInstance().getLineByKey(next.getOwningLine(), ofy) + " / " +
            // next.getPointGeoCell());
            pointsLine2 =
                getSearchPointsForLine(
                    next.getOwningLine(), next.getPointGeoCell(), plusMinus, ofy);
          } else {
            Line tempLine = getLineByKey(next.getOwningLine(), ofy);
            if (tempLine.getType() == 11 || tempLine.getType() == 13 || tempLine.getType() == 15) {
              pointsLine2 =
                  getSearchPointsForLine(next.getOwningLine(), next.getPointGeoCell(), 1, ofy);
            } else {
              pointsLine2 =
                  getSearchPointsForLine(next.getOwningLine(), next.getPointGeoCell(), 0, ofy);
            }
          }
          Logger.getLogger(location)
              .log(
                  Level.FINE,
                  functionName
                      + ": Umsteigen von "
                      + an.getOwningLine()
                      + " zu "
                      + next.getOwningLine()
                      + " in "
                      + an.getPointGeoCell()
                      + " und "
                      + next.getPointGeoCell()
                      + ". Results: "
                      + pointsLine1.size()
                      + " und "
                      + pointsLine2.size());

          Iterator<Point> j1 = pointsLine1.iterator();
          double min_distance = 999999999.9;
          Tuple<Point, Point> tuple_min = null;
          while (j1.hasNext()) {
            Point outerPoint = j1.next();
            Iterator<Point> j2 = pointsLine2.iterator();
            while (j2
                .hasNext()) { // für jeden Punkt (innerhalb der errechneten cells) von Line inner
                              // distanz zu jedem Punkt von outer berechnen, das kürzeste Paar
                              // speichern
              Point innerPoint = j2.next();
              double distance = Utils.distanceApprox(innerPoint, outerPoint);
              if (innerPoint.isIgnore()
                  || outerPoint
                      .isIgnore()) { // absolutely avoid points that are set as ignore. Related to
                                     // the dirty hack that searches any point, if none were found
                                     // that are not "ignore"-flagged. Theoretically there shouldn't
                                     // be any case where this is necessary, but right now there is
                                     // (rarely).
                distance += 10000;
              }
              if (distance < min_distance) {
                min_distance = distance;
                tuple_min = new Tuple<Point, Point>(outerPoint, innerPoint);
              }
            }
          }
          LineProxy c = Utils.getConnection(lastPoint, tuple_min.getFirst(), ofy);
          lineProxies.add(c);
          Line lastPointOwner1 = ofy.get(lastPoint.getOwner());
          if (lastPointOwner1.getType() == 1) { // wenn bus, alternativen suchen
            List<Key<Line>> alternativesK = new LinkedList<Key<Line>>();
            PlanQuadrat pq1 = Dao.getInstance().getPlanQuadrat(lastPoint.getDefaultGeoCell(), ofy);
            PlanQuadrat pq2 =
                Dao.getInstance().getPlanQuadrat(tuple_min.getFirst().getDefaultGeoCell(), ofy);
            int counter = 0;
            for (Key<Line> k1 : pq1.getDirectLineKeys()) {
              if (k1.getId()
                      != lastPoint.getOwner().getId() // nicht der bus der eh schon genommen wird
                  && pq2.getDirectLineKeys()
                      .contains(k1) // in anfangs und end PQ gleichermaßen enthalten
                  && pq1.getIndices().get(pq1.getDirectLineKeys().indexOf(k1))
                      <= pq2.getIndices().get(pq2.getDirectLineKeys().indexOf(k1))
                  && counter < maxAlternatives) {
                alternativesK.add(k1);
                counter++;
                // Logger.getLogger("ListPointsServiceImpl").log(Level.INFO, functionName + ":
                // Matching line: " + KeyFactory.keyToString(k1));
              }
            }
            for (Key<Line> k : alternativesK) {
              Line l = getLineByKey(k, ofy);
              c.addAlternativeLine(l.getLinenum() + " " + l.getRamal());
            }
          } else if (lastPointOwner1.getType() == 21) { // auch für züge alternativen suchen
            List<Key<Line>> alternativesK = new LinkedList<Key<Line>>();
            Set<TrainNode> tns1 = Dao.getTrainNodes().get(lastNode.getGeoCell());
            Set<TrainNode> tns2 = Dao.getTrainNodes().get(an.getGeoCell());
            for (TrainNode tn1 : tns1) {
              if (!tn1.getLineKey()
                  .equals(lastPoint.getOwner())) { // nicht der Zug der eh schon genommen wird
                for (TrainNode tn2 : tns2) {
                  if (tn1.getLineKey().equals(tn2.getLineKey()) // gehören zum gleichen zug
                      && tn1.getIndex() < tn2.getIndex()) { // und der index steig
                    alternativesK.add(tn1.getLineKey());
                  }
                }
              }
            }
            for (Key<Line> k : alternativesK) {
              Line l = getLineByKey(k, ofy);
              if (!l.getRamal().equals(c.getRamal())) {
                c.addAlternativeLine("Ramal a " + l.getRamal());
              }
            }
          }
          walk = Utils.walk(tuple_min.getFirst(), tuple_min.getSecond());
          lineProxies.add(walk);
          lastPoint = tuple_min.getSecond();
          lastNode = next;
        }
      }
      index = way.size() - 1;
      if (way.get(index).getOwningLine() == null) {
        index = way.size() - 2;
      }
      Collection<Point> pointsDest;
      if (way.get(index).getClass() == AStarNodeImpl.class) {
        pointsDest =
            getSearchPointsForLine(
                way.get(index).getOwningLine(), way.get(index).getPointGeoCell(), plusMinus, ofy);
      } else {
        Line tempLine = getLineByKey(way.get(index).getOwningLine(), ofy);
        if (tempLine.getType() == 11 || tempLine.getType() == 13 || tempLine.getType() == 15) {
          pointsDest =
              getSearchPointsForLine(
                  way.get(index).getOwningLine(), way.get(index).getPointGeoCell(), 1, ofy);
        } else {
          pointsDest =
              getSearchPointsForLine(
                  way.get(index).getOwningLine(), way.get(index).getPointGeoCell(), 0, ofy);
        }
      }
      Point destPoint = Utils.closestPoint(dest, pointsDest);
      LineProxy c = Utils.getConnection(lastPoint, destPoint, ofy);
      lineProxies.add(c);
      Line lastPointOwner2 = ofy.get(lastPoint.getOwner());
      if (lastPointOwner2.getType() == 1) { // wenn bus, alternativen suchen
        List<Key<Line>> alternativesK = new LinkedList<Key<Line>>();
        PlanQuadrat pq1 = Dao.getInstance().getPlanQuadrat(lastPoint.getDefaultGeoCell(), ofy);
        PlanQuadrat pq2 = Dao.getInstance().getPlanQuadrat(destPoint.getDefaultGeoCell(), ofy);
        int counter = 0;
        for (Key<Line> k1 : pq1.getDirectLineKeys()) {
          if (k1.getId() != lastPoint.getOwner().getId() // nicht der bus der eh schon genommen wird
              && pq2.getDirectLineKeys()
                  .contains(k1) // in anfangs und end PQ gleichermaßen enthalten
              && pq1.getIndices().get(pq1.getDirectLineKeys().indexOf(k1))
                  <= pq2.getIndices().get(pq2.getDirectLineKeys().indexOf(k1))
              && counter < maxAlternatives) {
            alternativesK.add(k1);
            counter++;
            // Logger.getLogger("ListPointsServiceImpl").log(Level.INFO, functionName + ": Matching
            // line: " + KeyFactory.keyToString(k1));
          }
        }
        for (Key<Line> k : alternativesK) {
          Line l = getLineByKey(k, ofy);
          c.addAlternativeLine(l.getLinenum() + " " + l.getRamal());
        }
      } else if (lastPointOwner2.getType() == 21) { // auch für züge alternativen suchen
        //				System.err.println(lastPoint.getOwner() + " " + lastPointOwner2 + " " +
        // lastPoint.getDefaultGeoCell());
        List<Key<Line>> alternativesK = new LinkedList<Key<Line>>();
        Set<TrainNode> tns1 = Dao.getTrainNodes().get(lastNode.getGeoCell());
        Set<TrainNode> tns2 = Dao.getTrainNodes().get(way.get(index).getGeoCell());
        for (TrainNode tn1 : tns1) {
          if (!tn1.getLineKey()
              .equals(lastPoint.getOwner())) { // nicht der Zug der eh schon genommen wird
            for (TrainNode tn2 : tns2) {
              if (tn1.getLineKey().equals(tn2.getLineKey()) // gehören zum gleichen zug
                  && tn1.getIndex() < tn2.getIndex()) { // und der index steig
                alternativesK.add(tn1.getLineKey());
              }
            }
          }
        }
        for (Key<Line> k : alternativesK) {
          Line l = getLineByKey(k, ofy);
          if (!l.getRamal().equals(c.getRamal())) {
            c.addAlternativeLine("Ramal " + l.getRamal());
          }
        }
      }

      walk = Utils.walk(destPoint, new Point(null, dest.getLatitude(), dest.getLongitude(), null));
      lineProxies.add(walk);

      ConnectionProxy cp = new ConnectionProxy(lineProxies);
      return cp;
    } else {
      Logger.getLogger(location).log(Level.INFO, functionName + ": no indirect connection found.");
      return null;
    }
  }
예제 #3
0
 /** Convert to the geocell version */
 public static Point toPoint(GeoPt geoPt) {
   return new Point(geoPt.getLatitude(), geoPt.getLongitude());
 }