예제 #1
0
  public void testEqualsExactForGeometryCollections() throws Exception {
    Geometry polygon1 = (Polygon) reader.read("POLYGON ((0 0, 0 50, 50 50, 50 0, 0 0))");
    Geometry polygon2 = (Polygon) reader.read("POLYGON ((50 50, 50 0, 0 0, 0 50, 50 50))");
    GeometryCollection x =
        geometryFactory.createGeometryCollection(new Geometry[] {polygon1, polygon2});
    GeometryCollection somethingExactlyEqual =
        geometryFactory.createGeometryCollection(new Geometry[] {polygon1, polygon2});
    GeometryCollection somethingNotEqualButSameClass =
        geometryFactory.createGeometryCollection(new Geometry[] {polygon2});
    GeometryCollection sameClassButEmpty = geometryFactory.createGeometryCollection(null);
    GeometryCollection anotherSameClassButEmpty = geometryFactory.createGeometryCollection(null);
    CollectionFactory collectionFactory =
        new CollectionFactory() {
          public Geometry createCollection(Geometry[] geometries) {
            return geometryFactory.createGeometryCollection(geometries);
          }
        };

    doTestEqualsExact(
        x,
        somethingExactlyEqual,
        somethingNotEqualButSameClass,
        sameClassButEmpty,
        anotherSameClassButEmpty,
        collectionFactory);
  }
예제 #2
0
 /**
  * Test created to check that we effectively retrieve a good representation of empty
  * multipolygons. indeed, a NullPointerException used to happen...
  *
  * @throws Exception
  */
 @Test
 public void testGeometryCollectionStringRepresentation() throws Exception {
   GeometryCollection mp = gf.createMultiPolygon(new Polygon[] {});
   Value val = ValueFactory.createValue(mp);
   String str = val.toString();
   assertEquals(str, "MULTIPOLYGON EMPTY");
   Polygon poly = gf.createPolygon(gf.createLinearRing(new Coordinate[] {}), new LinearRing[] {});
   assertTrue(poly.isEmpty());
   mp =
       gf.createMultiPolygon(
           new Polygon[] {
             poly,
           });
   val = ValueFactory.createValue(mp);
   str = val.toString();
   assertNotNull(str);
   Polygon polyBis =
       gf.createPolygon(
           gf.createLinearRing(
               new Coordinate[] {
                 new Coordinate(0, 0, 0),
                 new Coordinate(1, 1, 0),
                 new Coordinate(3, 4, 0),
                 new Coordinate(0, 0, 0),
               }),
           new LinearRing[] {});
   mp = gf.createMultiPolygon(new Polygon[] {poly, polyBis});
   val = ValueFactory.createValue(mp);
   str = val.toString();
   assertNotNull(str);
   GeometryCollection coll =
       gf.createGeometryCollection(
           new Geometry[] {
             gf.createPolygon(gf.createLinearRing(new Coordinate[] {}), new LinearRing[] {}),
             gf.createPolygon(
                 gf.createLinearRing(
                     new Coordinate[] {
                       new Coordinate(0, 0, 0),
                       new Coordinate(1, 1, 0),
                       new Coordinate(3, 4, 0),
                       new Coordinate(0, 0, 0),
                     }),
                 new LinearRing[] {})
           });
   mp = gf.createGeometryCollection(new Geometry[] {poly, coll, polyBis});
   val = ValueFactory.createValue(mp);
   str = val.toString();
   assertNotNull(str);
 }
예제 #3
0
  private FeatureCollection convexHhull(TaskMonitor monitor, FeatureCollection fc) {
    monitor.allowCancellationRequests();
    monitor.report(I18N.get("ui.plugin.analysis.ConvexHullPlugIn.Computing-Convex-Hull") + "...");

    int size = fc.size();
    GeometryFactory geomFact = null;

    if (size == 0) {
      return null;
    }
    int count = 0;
    Geometry[] geoms = new Geometry[size];

    for (Iterator i = fc.iterator(); i.hasNext(); ) {
      Feature f = (Feature) i.next();
      Geometry geom = f.getGeometry();
      if (geom == null) {
        continue;
      }
      if (geomFact == null) {
        geomFact = geom.getFactory();
      }

      geoms[count++] = geom;
    }
    GeometryCollection gc = geomFact.createGeometryCollection(geoms);
    Geometry hull = gc.convexHull();
    List hullList = new ArrayList();
    hullList.add(hull);

    return FeatureDatasetFactory.createFromGeometry(hullList);
  }
예제 #4
0
  public void testBounds() throws Exception {
    PrecisionModel pm = new PrecisionModel();
    Geometry[] g = new Geometry[4];
    GeometryFactory gf = new GeometryFactory(pm);

    g[0] = gf.createPoint(new Coordinate(0, 0));
    g[1] = gf.createPoint(new Coordinate(0, 10));
    g[2] = gf.createPoint(new Coordinate(10, 0));
    g[3] = gf.createPoint(new Coordinate(10, 10));

    GeometryCollection gc = gf.createGeometryCollection(g);

    SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
    tb.setName("bounds");
    tb.setCRS(null);
    tb.add("p1", Point.class);

    SimpleFeatureType t = tb.buildFeatureType();

    TreeSetFeatureCollection fc = new TreeSetFeatureCollection(null, t);
    SimpleFeatureBuilder b = new SimpleFeatureBuilder(t);
    for (int i = 0; i < g.length; i++) {
      b.add(g[i]);
      fc.add(b.buildFeature(null));
    }
    assertEquals(gc.getEnvelopeInternal(), fc.getBounds());
  }
  private Geometry parseGeometry(JsonNode root) {
    String typeName = root.get("type").asText();
    if (typeName.equals("Point")) {
      return gf.createPoint(parseCoordinate((ArrayNode) root.get("coordinates")));

    } else if (typeName.equals("MultiPoint")) {
      return gf.createMultiPoint(parseLineString(root.get("coordinates")));

    } else if (typeName.equals("LineString")) {
      return gf.createLineString(parseLineString(root.get("coordinates")));

    } else if (typeName.equals("MultiLineString")) {
      return gf.createMultiLineString(parseLineStrings(root.get("coordinates")));

    } else if (typeName.equals("Polygon")) {
      JsonNode arrayOfRings = root.get("coordinates");
      return parsePolygonCoordinates(arrayOfRings);

    } else if (typeName.equals("MultiPolygon")) {
      JsonNode arrayOfPolygons = root.get("coordinates");
      return gf.createMultiPolygon(parsePolygons(arrayOfPolygons));

    } else if (typeName.equals("GeometryCollection")) {
      return gf.createGeometryCollection(parseGeometries(root.get("geometries")));
    } else {
      throw new UnsupportedOperationException();
    }
  }
예제 #6
0
 private GeometryCollection readGeometryCollection() throws IOException, ParseException {
   int numGeom = dis.readInt();
   Geometry[] geoms = new Geometry[numGeom];
   for (int i = 0; i < numGeom; i++) {
     geoms[i] = readGeometry();
   }
   return factory.createGeometryCollection(geoms);
 }
 @Test
 public void geometryCollection() throws Exception {
   GeometryCollection collection =
       gf.createGeometryCollection(
           new Geometry[] {gf.createPoint(new Coordinate(1.2345678, 2.3456789))});
   assertRoundTrip(collection);
   assertThat(
       toJson(collection),
       equalTo(
           "{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[1.2345678,2.3456789]}]}"));
 }
예제 #8
0
 protected GeometryCollection decodeGeometryCollection(JsonNode node, GeometryFactory fac)
     throws GeoJSONException {
   final JsonNode geometries = node.path(GEOMETRIES);
   if (!geometries.isArray()) {
     throw new GeoJSONException("expected 'geometries' array");
   }
   Geometry[] geoms = new Geometry[geometries.size()];
   for (int i = 0; i < geometries.size(); ++i) {
     geoms[i] = decodeGeometry(geometries.get(i), fac);
   }
   return fac.createGeometryCollection(geoms);
 }
예제 #9
0
 protected Geometry transformGeometryCollection(GeometryCollection geom, Geometry parent) {
   List transGeomList = new ArrayList();
   for (int i = 0; i < geom.getNumGeometries(); i++) {
     Geometry transformGeom = transform(geom.getGeometryN(i));
     if (transformGeom == null) continue;
     if (pruneEmptyGeometry && transformGeom.isEmpty()) continue;
     transGeomList.add(transformGeom);
   }
   if (preserveGeometryCollectionType)
     return factory.createGeometryCollection(GeometryFactory.toGeometryArray(transGeomList));
   return factory.buildGeometry(transGeomList);
 }
예제 #10
0
  /** decimates JTS geometries. */
  public final Geometry decimate(Geometry geom) {
    GeometryFactory gFac = new GeometryFactory(geom.getPrecisionModel(), geom.getSRID());
    if (spanx == -1) return geom;
    if (geom instanceof MultiPoint) {
      // TODO check geometry and if its bbox is too small turn it into a 1
      // point geom
      return geom;
    }
    if (geom instanceof GeometryCollection) {
      // TODO check geometry and if its bbox is too small turn it into a
      // 1-2 point geom
      // takes a bit of work because the geometry will need to be
      // recreated.
      GeometryCollection collection = (GeometryCollection) geom;
      Geometry[] result = new Geometry[collection.getDimension()];
      final int numGeometries = collection.getNumGeometries();
      for (int i = 0; i < numGeometries; i++) {
        result[i] = decimate(collection.getGeometryN(i));
      }
      return gFac.createGeometryCollection(result);

    } else if (geom instanceof LineString) {
      LineString line = (LineString) geom;
      CoordinateSequence seq = (CoordinateSequence) line.getCoordinateSequence();
      LiteCoordinateSequence lseq = new LiteCoordinateSequence(seq.toCoordinateArray());

      if (decimateOnEnvelope(line, lseq)) {
        if (lseq.size() >= 2) return gFac.createLineString(lseq);
      }
      if (lseq.size() >= 2) return gFac.createLineString(decimate(lseq));
      return null;
    } else if (geom instanceof Polygon) {
      Polygon line = (Polygon) geom;
      Coordinate[] exterior = decimate(line.getExteriorRing()).getCoordinates();
      forceClosed(exterior);
      if (exterior.length > 3) {
        LinearRing ring = gFac.createLinearRing(exterior);

        final int numRings = line.getNumInteriorRing();
        List<LinearRing> rings = new ArrayList<LinearRing>();

        for (int i = 0; i < numRings; i++) {
          Coordinate[] interior = decimate(line.getInteriorRingN(i)).getCoordinates();
          forceClosed(interior);
          if (interior.length > 3) rings.add(gFac.createLinearRing(interior));
        }
        return gFac.createPolygon(ring, rings.toArray(new LinearRing[] {}));
      }
      return null;
    }
    return geom;
  }
예제 #11
0
  public static GeometryCollection createBoxesGeometry(List<Node> leafs, Envelope bound) {
    GeometryFactory factory = new GeometryFactory();

    Geometry[] boxes = new Geometry[leafs.size()];
    for (int i = 0; i < leafs.size(); i++) {
      Node leaf = leafs.get(i);
      Envelope envelope = leaf.getEnvelope().intersection(bound);
      Geometry g = factory.toGeometry(envelope);
      boxes[i] = g;
    }

    return factory.createGeometryCollection(boxes);
  }
예제 #12
0
  private void doTestEqualsExact(
      Geometry x,
      Geometry somethingExactlyEqual,
      Geometry somethingNotEqualButSameClass,
      Geometry sameClassButEmpty,
      Geometry anotherSameClassButEmpty,
      CollectionFactory collectionFactory)
      throws Exception {
    Geometry emptyDifferentClass;

    if (x instanceof Point) {
      emptyDifferentClass = geometryFactory.createGeometryCollection(null);
    } else {
      emptyDifferentClass = geometryFactory.createPoint((Coordinate) null);
    }

    Geometry somethingEqualButNotExactly =
        geometryFactory.createGeometryCollection(new Geometry[] {x});

    doTestEqualsExact(
        x,
        somethingExactlyEqual,
        collectionFactory.createCollection(new Geometry[] {x}),
        somethingNotEqualButSameClass);

    doTestEqualsExact(sameClassButEmpty, anotherSameClassButEmpty, emptyDifferentClass, x);

    /** Test comparison of non-empty versus empty. */
    doTestEqualsExact(x, somethingExactlyEqual, sameClassButEmpty, sameClassButEmpty);

    doTestEqualsExact(
        collectionFactory.createCollection(new Geometry[] {x, x}),
        collectionFactory.createCollection(new Geometry[] {x, somethingExactlyEqual}),
        somethingEqualButNotExactly,
        collectionFactory.createCollection(new Geometry[] {x, somethingNotEqualButSameClass}));
  }
예제 #13
0
 /**
  * Extracts all Geometry object substrings and reads them
  *
  * @param s
  * @throws ParseException
  */
 private Geometry readFeatureCollection(String s) throws ParseException {
   Pattern p = Pattern.compile("\\{[^\\{\\}]+?\\}");
   Matcher m = p.matcher(s);
   List geoms = new ArrayList();
   while (true) {
     boolean isFound = m.find();
     if (!isFound) break;
     String substr = m.group();
     if (isGeometry(substr)) {
       geoms.add(readGeometry(substr));
     }
     // System.out.println(sgeom);
   }
   return geomFact.createGeometryCollection(GeometryFactory.toGeometryArray(geoms));
 }
  private Shape createSelectedItemsShape() throws NoninvertibleTransformException {
    Collection selectedGeos = (getPanel().getSelectionManager().getSelectedItems());
    Geometry geo = ((Geometry) selectedGeos.iterator().next());
    Geometry[] allGeoms = new Geometry[selectedGeos.size()];
    int i = 0;
    for (Iterator j = selectedGeos.iterator(); j.hasNext(); ) allGeoms[i++] = (Geometry) j.next();

    GeometryFactory geoFac = new GeometryFactory();
    geo = geoFac.createGeometryCollection(allGeoms);

    if (centerCoord == null) {
      centerCoord = geo.getCentroid().getCoordinate();
    }
    return getPanel().getJava2DConverter().toShape(geo);
  }
 public Object convert(Object obj) {
   GeometryFactory fac = new GeometryFactory();
   if (getBinding() == MultiPolygon.class && obj instanceof Polygon) {
     return fac.createMultiPolygon(new Polygon[] {(Polygon) obj});
   }
   if (getBinding() == MultiPoint.class && obj instanceof Point) {
     return fac.createMultiPoint(new Point[] {(Point) obj});
   }
   if (getBinding() == MultiLineString.class && obj instanceof LineString) {
     return fac.createMultiLineString(new LineString[] {(LineString) obj});
   }
   if (getBinding() == GeometryCollection.class && obj instanceof Geometry) {
     return fac.createGeometryCollection(
         new com.vividsolutions.jts.geom.Geometry[] {(com.vividsolutions.jts.geom.Geometry) obj});
   }
   return obj;
 }
예제 #16
0
 static GeometryCollection multiGeometry() {
   return gf.createGeometryCollection(new Geometry[] {point(), lineString(), polygon()});
 }
예제 #17
0
  /**
   * Calculates walksheds for a given location, based on time given to walk and the walk speed.
   *
   * <p>Depending on the value for the "output" parameter (i.e. "POINTS", "SHED" or "EDGES"), a
   * different type of GeoJSON geometry is returned. If a SHED is requested, then a ConcaveHull of
   * the EDGES/roads is returned. If that fails, a ConvexHull will be returned.
   *
   * <p>The ConcaveHull parameter is set to 0.005 degrees. The offroad walkspeed is assumed to be
   * 0.83333 m/sec (= 3km/h) until a road is hit.
   *
   * <p>Note that the set of EDGES/roads returned as well as POINTS returned may contain duplicates.
   * If POINTS are requested, then not the end-points are returned at which the max time is reached,
   * but instead all the graph nodes/crossings that are within the time limits.
   *
   * <p>In case there is no road near by within the given time, then a circle for the walktime limit
   * is created and returned for the SHED parameter. Otherwise the edge with the direction towards
   * the closest road. Note that the circle is calculated in Euclidian 2D coordinates, and
   * distortions towards an ellipse will appear if it is transformed/projected to the user location.
   *
   * <p>An example request may look like this:
   * localhost:8080/otp-rest-servlet/ws/iso?layers=traveltime&styles=mask&batch=true&fromPlace=51.040193121307176
   * %2C-114.04471635818481&toPlace
   * =51.09098935%2C-113.95179705&time=2012-06-06T08%3A00%3A00&mode=WALK&maxWalkDistance=10000&walkSpeed=1.38&walkTime=10.7&output=EDGES
   * Though the first parameters (i) layer, (ii) styles and (iii) batch could be discarded.
   *
   * @param walkmins Maximum number of minutes to walk.
   * @param output Can be set to "POINTS", "SHED" or "EDGES" to return different types of GeoJSON
   *     geometry. SHED returns a ConcaveHull or ConvexHull of the edges/roads. POINTS returns all
   *     graph nodes that are within the time limit.
   * @return a JSON document containing geometries (either points, lineStrings or a polygon).
   * @throws Exception
   * @author sstein---geo.uzh.ch
   */
  @GET
  @Produces({MediaType.APPLICATION_JSON})
  public String getIsochrone(
      @QueryParam("walkTime") @DefaultValue("15") double walkmins,
      @QueryParam("output") @DefaultValue("POINTS") String output)
      throws Exception {

    this.debugGeoms = new ArrayList();
    this.tooFastTraversedEdgeGeoms = new ArrayList();

    RoutingRequest sptRequestA = buildRequest(0);
    String from = sptRequestA.getFrom().toString();
    int pos = 1;
    float lat = 0;
    float lon = 0;
    for (String s : from.split(",")) {
      if (s.isEmpty()) {
        // no location
        Response.status(Status.BAD_REQUEST).entity("no position").build();
        return null;
      }
      try {
        float num = Float.parseFloat(s);
        if (pos == 1) {
          lat = num;
        }
        if (pos == 2) {
          lon = num;
        }
      } catch (Exception e) {
        throw new WebApplicationException(
            Response.status(Status.BAD_REQUEST)
                .entity(
                    "Could not parse position string to number. Require numerical lat & long coords.")
                .build());
      }
      pos++;
    }

    GeometryFactory gf = new GeometryFactory();

    Coordinate dropPoint = new Coordinate(lon, lat);

    int walkInMin = (int) Math.floor(walkmins);
    double walkInSec = walkmins * 60;
    LOG.debug(
        "given travel time: " + walkInMin + " mins + " + (walkInSec - (60 * walkInMin)) + " sec");
    // restrict the evaluated SPT size to 30mins for requests with walking < 30min
    // if larger walking times are requested we adjust the evaluated
    // graph dynamically by 1.3 * min -> this should save processing time
    if (walkInMin < 30) {
      sptRequestA.worstTime = sptRequestA.dateTime + (30 * 60);
    } else {
      sptRequestA.worstTime = sptRequestA.dateTime + Math.round(walkInMin * 1.3 * 60);
    }
    // set the switch-time for shed/area calculation, i.e. to decide if the hull is calculated based
    // on points or on edges
    TraverseModeSet modes = sptRequestA.modes;
    LOG.debug("mode(s): " + modes);
    if ((modes.contains(TraverseMode.TRANSIT))
        || (modes.contains(TraverseMode.BUSISH))
        || (modes.contains(TraverseMode.TRAINISH))) {
      shedCalcMethodSwitchTimeInSec =
          60 * 20; // 20min (use 20min for transit, since buses may not come all the time)
    } else if (modes.contains(TraverseMode.CAR)) {
      shedCalcMethodSwitchTimeInSec = 60 * 10; // 10min
    } else if (modes.contains(TraverseMode.BICYCLE)) {
      shedCalcMethodSwitchTimeInSec = 60 * 10; // 10min
    } else {
      shedCalcMethodSwitchTimeInSec = 60 * 20; // 20min
    }
    // set the maxUserSpeed, which is used later to check for u-type streets/crescents when
    // calculating sub-edges;
    // Note, that the car speed depends on the edge itself, so this value may be replaced later
    this.usesCar = false;
    int numberOfModes = modes.getModes().size();
    if (numberOfModes == 1) {
      if (modes.getWalk()) {
        this.maxUserSpeed = sptRequestA.getWalkSpeed();
      } else if (modes.getBicycle()) {
        this.maxUserSpeed = sptRequestA.getBikeSpeed();
      } else if (modes.getDriving()) {
        this.maxUserSpeed = sptRequestA.getCarSpeed();
        this.usesCar = true;
      }
    } else { // for all other cases (multiple-modes)
      // sstein: I thought I may set it to 36.111 m/sec = 130 km/h,
      // but maybe it is better to assume walk speed for transit, i.e. treat it like if the
      // person gets off the bus on the last crossing and walks the "last mile".
      this.maxUserSpeed = sptRequestA.getWalkSpeed();
    }

    if (doSpeedTest) {
      LOG.debug("performing angle and speed based test to detect u-shapes");
    } else {
      LOG.debug("performing only angle based test to detect u-shapes");
    }

    // TODO: OTP prefers to snap to car-roads/ways, which is not so nice, when walking,
    // and a footpath is closer by. So far there is no option to switch that off

    // create the ShortestPathTree
    try {
      sptRequestA.setRoutingContext(graphService.getGraph());
    } catch (Exception e) {
      // if we get an exception here, and in particular a VertexNotFoundException,
      // then it is likely that we chose a (transit) mode without having that (transit) modes data
      LOG.debug("cannot set RoutingContext: " + e.toString());
      LOG.debug("cannot set RoutingContext: setting mode=WALK");
      sptRequestA.setMode(TraverseMode.WALK); // fall back to walk mode
      sptRequestA.setRoutingContext(graphService.getGraph());
    }
    ShortestPathTree sptA = sptService.getShortestPathTree(sptRequestA);
    StreetLocation origin = (StreetLocation) sptRequestA.rctx.fromVertex;
    sptRequestA.cleanup(); // remove inserted points

    // create a LineString for display
    Coordinate pathToStreetCoords[] = new Coordinate[2];
    pathToStreetCoords[0] = dropPoint;
    pathToStreetCoords[1] = origin.getCoordinate();
    LineString pathToStreet = gf.createLineString(pathToStreetCoords);

    // get distance between origin and drop point for time correction
    double distanceToRoad =
        this.distanceLibrary.distance(origin.getY(), origin.getX(), dropPoint.y, dropPoint.x);
    long offRoadTimeCorrection = (long) (distanceToRoad / this.offRoadWalkspeed);

    //
    // --- filter the states ---
    //
    Set<Coordinate> visitedCoords = new HashSet<Coordinate>();
    ArrayList<Edge> allConnectingEdges = new ArrayList<Edge>();
    Coordinate coords[] = null;
    long maxTime = (long) walkInSec - offRoadTimeCorrection;
    // System.out.println("Reducing walktime from: " + (int)(walkmins * 60) + "sec to " + maxTime +
    // "sec due to initial walk of " + distanceToRoad
    // + "m");

    // if the initial walk is already to long, there is no need to parse...
    if (maxTime <= 0) {
      noRoadNearBy = true;
      long timeToWalk = (long) walkInSec;
      long timeBetweenStates = offRoadTimeCorrection;
      long timeMissing = timeToWalk;
      double fraction = (double) timeMissing / (double) timeBetweenStates;
      pathToStreet = getSubLineString(pathToStreet, fraction);
      LOG.debug(
          "no street found within giving travel time (for off-road walkspeed: {} m/sec)",
          this.offRoadWalkspeed);
    } else {
      noRoadNearBy = false;
      Map<ReversibleLineStringWrapper, Edge> connectingEdgesMap = Maps.newHashMap();
      for (State state : sptA.getAllStates()) {
        long et = state.getElapsedTimeSeconds();
        if (et <= maxTime) {
          // -- filter points, as the same coordinate may be passed several times due to the graph
          // structure
          // in a Calgary suburb family homes neighborhood with a 15min walkshed it filtered about
          // 250 points away (while 145 were finally displayed)
          if (visitedCoords.contains(state.getVertex().getCoordinate())) {
            continue;
          } else {
            visitedCoords.add(state.getVertex().getCoordinate());
          }
          // -- get all Edges needed later for the edge representation
          // and to calculate an edge-based walkshed
          // Note, it can happen that we get a null geometry here, e.g. for hop-edges!
          Collection<Edge> vertexEdgesIn = state.getVertex().getIncoming();
          for (Iterator<Edge> iterator = vertexEdgesIn.iterator(); iterator.hasNext(); ) {
            Edge edge = (Edge) iterator.next();
            Geometry edgeGeom = edge.getGeometry();
            if (edgeGeom != null) { // make sure we get only real edges
              if (edgeGeom instanceof LineString) {
                // allConnectingEdges.add(edge); // instead of this, use a map now, so we don't have
                // similar edge many times
                connectingEdgesMap.put(
                    new ReversibleLineStringWrapper((LineString) edgeGeom), edge);
              }
            }
          }
          Collection<Edge> vertexEdgesOut = state.getVertex().getOutgoing();
          for (Iterator<Edge> iterator = vertexEdgesOut.iterator(); iterator.hasNext(); ) {
            Edge edge = (Edge) iterator.next();
            Geometry edgeGeom = edge.getGeometry();
            if (edgeGeom != null) {
              if (edgeGeom instanceof LineString) {
                // allConnectingEdges.add(edge); // instead of this, use a map now, so we don't
                // similar edge many times
                connectingEdgesMap.put(
                    new ReversibleLineStringWrapper((LineString) edgeGeom), edge);
              }
            }
          }
        } // end : if(et < maxTime)
      }
      // --
      // points from list to array, for later
      coords = new Coordinate[visitedCoords.size()];
      int i = 0;
      for (Coordinate c : visitedCoords) coords[i++] = c;

      // connection edges from Map to List
      allConnectingEdges.clear();
      for (Edge tedge : connectingEdgesMap.values()) allConnectingEdges.add(tedge);
    }
    StringWriter sw = new StringWriter();
    GeoJSONBuilder json = new GeoJSONBuilder(sw);
    //
    // -- create the different outputs ---
    //
    try {
      if (output.equals(IsoChrone.RESULT_TYPE_POINTS)) {
        // in case there was no road we create a circle and
        // and return those points
        if (noRoadNearBy) {
          Geometry circleShape = createCirle(dropPoint, pathToStreet);
          coords = circleShape.getCoordinates();
        }
        // -- the states/nodes with time elapsed <= X min.
        LOG.debug("write multipoint geom with {} points", coords.length);
        json.writeGeom(gf.createMultiPoint(coords));
        LOG.debug("done");
      } else if (output.equals(IsoChrone.RESULT_TYPE_SHED)) {

        Geometry geomsArray[] = null;
        // in case there was no road we create a circle
        if (noRoadNearBy) {
          Geometry circleShape = createCirle(dropPoint, pathToStreet);
          json.writeGeom(circleShape);
        } else {
          if (maxTime > shedCalcMethodSwitchTimeInSec) { // eg., walkshed > 20 min
            // -- create a point-based walkshed
            // less exact and should be used for large walksheds with many edges
            LOG.debug("create point-based shed (not from edges)");
            geomsArray = new Geometry[coords.length];
            for (int j = 0; j < geomsArray.length; j++) {
              geomsArray[j] = gf.createPoint(coords[j]);
            }
          } else {
            // -- create an edge-based walkshed
            // it is more exact and should be used for short walks
            LOG.debug("create edge-based shed (not from points)");
            Map<ReversibleLineStringWrapper, LineString> walkShedEdges = Maps.newHashMap();
            // add the walk from the pushpin to closest street point
            walkShedEdges.put(new ReversibleLineStringWrapper(pathToStreet), pathToStreet);
            // get the edges and edge parts within time limits
            ArrayList<LineString> withinTimeEdges =
                this.getLinesAndSubEdgesWithinMaxTime(
                    maxTime,
                    allConnectingEdges,
                    sptA,
                    angleLimitForUShapeDetection,
                    distanceToleranceForUShapeDetection,
                    maxUserSpeed,
                    usesCar,
                    doSpeedTest);
            for (LineString ls : withinTimeEdges) {
              walkShedEdges.put(new ReversibleLineStringWrapper(ls), ls);
            }
            geomsArray = new Geometry[walkShedEdges.size()];
            int k = 0;
            for (LineString ls : walkShedEdges.values()) geomsArray[k++] = ls;
          } // end if-else: maxTime condition
          GeometryCollection gc = gf.createGeometryCollection(geomsArray);
          // create the concave hull, but in case it fails we just return the convex hull
          Geometry outputHull = null;
          LOG.debug(
              "create concave hull from {} geoms with edge length limit of about {} m (distance on meridian)",
              geomsArray.length,
              concaveHullAlpha * 111132);
          // 1deg at Latitude phi = 45deg is about 111.132km
          // (see wikipedia:
          // http://en.wikipedia.org/wiki/Latitude#The_length_of_a_degree_of_latitude)
          try {
            ConcaveHull hull = new ConcaveHull(gc, concaveHullAlpha);
            outputHull = hull.getConcaveHull();
          } catch (Exception e) {
            outputHull = gc.convexHull();
            LOG.debug("Could not generate ConcaveHull for WalkShed, using ConvexHull instead.");
          }
          LOG.debug("write shed geom");
          json.writeGeom(outputHull);
          LOG.debug("done");
        }
      } else if (output.equals(IsoChrone.RESULT_TYPE_EDGES)) {
        // in case there was no road we return only the suggested path to the street
        if (noRoadNearBy) {
          json.writeGeom(pathToStreet);
        } else {
          // -- if we would use only the edges from the paths to the origin we will miss
          // some edges that will be never on the shortest path (e.g. loops/crescents).
          // However, we can retrieve all edges by checking the times for each
          // edge end-point
          Map<ReversibleLineStringWrapper, LineString> walkShedEdges = Maps.newHashMap();
          // add the walk from the pushpin to closest street point
          walkShedEdges.put(new ReversibleLineStringWrapper(pathToStreet), pathToStreet);
          // get the edges and edge parts within time limits
          ArrayList<LineString> withinTimeEdges =
              this.getLinesAndSubEdgesWithinMaxTime(
                  maxTime,
                  allConnectingEdges,
                  sptA,
                  angleLimitForUShapeDetection,
                  distanceToleranceForUShapeDetection,
                  maxUserSpeed,
                  usesCar,
                  doSpeedTest);
          for (LineString ls : withinTimeEdges) {
            walkShedEdges.put(new ReversibleLineStringWrapper(ls), ls);
          }
          Geometry mls = null;
          LineString edges[] = new LineString[walkShedEdges.size()];
          int k = 0;
          for (LineString ls : walkShedEdges.values()) edges[k++] = ls;
          LOG.debug("create multilinestring from {} geoms", edges.length);
          mls = gf.createMultiLineString(edges);
          LOG.debug("write geom");
          json.writeGeom(mls);
          LOG.debug("done");
        }
      } else if (output.equals("DEBUGEDGES")) {
        // -- for debugging, i.e. display of detected u-shapes/crescents
        ArrayList<LineString> withinTimeEdges =
            this.getLinesAndSubEdgesWithinMaxTime(
                maxTime,
                allConnectingEdges,
                sptA,
                angleLimitForUShapeDetection,
                distanceToleranceForUShapeDetection,
                maxUserSpeed,
                usesCar,
                doSpeedTest);
        if (this.showTooFastEdgesAsDebugGeomsANDnotUShapes) {
          LOG.debug("displaying edges that are traversed too fast");
          this.debugGeoms = this.tooFastTraversedEdgeGeoms;
        } else {
          LOG.debug("displaying detected u-shaped roads/crescents");
        }
        LineString edges[] = new LineString[this.debugGeoms.size()];
        int k = 0;
        for (Iterator iterator = debugGeoms.iterator(); iterator.hasNext(); ) {
          LineString ls = (LineString) iterator.next();
          edges[k] = ls;
          k++;
        }
        Geometry mls = gf.createMultiLineString(edges);
        LOG.debug("write debug geom");
        json.writeGeom(mls);
        LOG.debug("done");
      }
    } catch (org.codehaus.jettison.json.JSONException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return sw.toString();
  }
예제 #18
0
  @Before
  public void setUp() throws Exception {
    super.setUpTestsWithoutEdition();
    wktReader = new WKTReader();
    JTSMultiPolygon2D = wktReader.read("MULTIPOLYGON (((0 0, 1 1, 0 1, 0 0)))");
    JTSMultiLineString2D = wktReader.read("MULTILINESTRING ((0 0, 1 1, 0 1, 0 0))");
    JTSMultiPoint2D = wktReader.read("MULTIPOINT (0 0, 1 1, 0 1, 0 0)");
    JTSPolygon2D =
        wktReader.read(
            "POLYGON ((181 124, 87 162, 76 256, 166 315, 286 325, 373 255, 387 213, 377 159, 351 121, 298 101, 234 56, 181 124), (165 244, 227 219, 234 300, 168 288, 165 244), (244 130, 305 135, 324 186, 306 210, 272 206, 206 174, 244 130))");

    JTSLineString2D = wktReader.read("LINESTRING (1 1, 2 1, 2 2, 1 2, 1 1)");
    JTSLineString3D = wktReader.read("LINESTRING (1 1 1, 2 1 2, 2 2 3, 1 2 4, 1 1 5)");
    JTSPoint3D = wktReader.read("POINT(0 10 20)");
    JTSPoint2D = wktReader.read("POINT(0 10)");

    JTSPolygonWith2Holes =
        wktReader.read(
            "POLYGON ((85 55, 85 306, 366 306, 366 55, 85 55), (153 205, 212 173, 241 190, 251 253, 235 278, 147 254, 153 205), (262 88, 321 97, 324 153, 303 177, 240 138, 262 88))");

    GeometryFactory gf = new GeometryFactory();
    JTSGeometryCollection =
        gf.createGeometryCollection(
            new Geometry[] {JTSMultiPolygon2D, JTSMultiLineString2D, JTSPolygon2D});
    JTS3DCollection =
        gf.createGeometryCollection(new Geometry[] {JTSMultiPolygon2D, JTSLineString3D});

    // first datasource
    final MemoryDataSetDriver driver1 =
        new MemoryDataSetDriver(
            new String[] {"pk", "geom"},
            new Type[] {
              TypeFactory.createType(Type.INT, new PrimaryKeyConstraint()),
              TypeFactory.createType(Type.GEOMETRY)
            });

    // insert all filled rows...
    driver1.addValues(
        new Value[] {ValueFactory.createValue(1), ValueFactory.createValue(JTSMultiPolygon2D)});
    driver1.addValues(
        new Value[] {ValueFactory.createValue(2), ValueFactory.createValue(JTSMultiLineString2D)});
    driver1.addValues(
        new Value[] {ValueFactory.createValue(3), ValueFactory.createValue(JTSLineString2D)});
    driver1.addValues(
        new Value[] {ValueFactory.createValue(4), ValueFactory.createValue(JTSPolygon2D)});
    // and register this new driver...

    dsf.getSourceManager().register("ds1", driver1);

    // second datasource
    final MemoryDataSetDriver driver2 =
        new MemoryDataSetDriver(
            new String[] {"pk", "geom"},
            new Type[] {
              TypeFactory.createType(Type.INT, new PrimaryKeyConstraint()),
              TypeFactory.createType(Type.GEOMETRY)
            });

    driver1.addValues(
        new Value[] {ValueFactory.createValue(1), ValueFactory.createValue(JTSMultiPolygon2D)});
    // and register this new driver...
    dsf.getSourceManager().register("ds2", driver2);
  }
예제 #19
0
 @Test
 public void testGeometryType() throws Exception {
   // We test the point
   Value val = ValueFactory.createValue(gf.createPoint(new Coordinate(2, 1)));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue(val.getType() == Type.POINT);
   // We test the multipoint
   val = ValueFactory.createValue(gf.createMultiPoint(new Coordinate[] {new Coordinate(2, 1)}));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue(val.getType() == Type.MULTIPOINT);
   // We test the LineString
   val =
       ValueFactory.createValue(
           gf.createLineString(new Coordinate[] {new Coordinate(2, 1), new Coordinate(2, 2)}));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue(val.getType() == Type.LINESTRING);
   // We test the MultiLineString
   val =
       ValueFactory.createValue(
           gf.createMultiLineString(
               new LineString[] {
                 gf.createLineString(new Coordinate[] {new Coordinate(2, 1), new Coordinate(2, 2)})
               }));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue(val.getType() == Type.MULTILINESTRING);
   // We test the Polygon
   val =
       ValueFactory.createValue(
           gf.createPolygon(
               gf.createLinearRing(
                   new Coordinate[] {
                     new Coordinate(2, 1),
                     new Coordinate(2, 2),
                     new Coordinate(4, 3),
                     new Coordinate(2, 1)
                   }),
               null));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue(val.getType() == Type.POLYGON);
   // We test the MultiPolygon
   val =
       ValueFactory.createValue(
           gf.createMultiPolygon(
               new Polygon[] {
                 gf.createPolygon(
                     gf.createLinearRing(
                         new Coordinate[] {
                           new Coordinate(2, 1),
                           new Coordinate(2, 2),
                           new Coordinate(4, 3),
                           new Coordinate(2, 1)
                         }),
                     null),
                 gf.createPolygon(
                     gf.createLinearRing(
                         new Coordinate[] {
                           new Coordinate(2, 1),
                           new Coordinate(2, 2),
                           new Coordinate(6, 3),
                           new Coordinate(2, 1)
                         }),
                     null)
               }));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue(val.getType() == Type.MULTIPOLYGON);
   // We test the GeometryCollection
   val =
       ValueFactory.createValue(
           gf.createGeometryCollection(
               new Geometry[] {
                 gf.createPolygon(
                     gf.createLinearRing(
                         new Coordinate[] {
                           new Coordinate(2, 1),
                           new Coordinate(2, 2),
                           new Coordinate(4, 3),
                           new Coordinate(2, 1)
                         }),
                     null),
                 gf.createPoint(new Coordinate(2, 1))
               }));
   assertTrue((val.getType() & Type.GEOMETRY) != 0);
   assertTrue((val.getType() & Type.GEOMETRYCOLLECTION) != 0);
 }
예제 #20
0
 public static Geometry getGeometryCollection() {
   return gf.createGeometryCollection(
       new Geometry[] {
         getLinearRing(), getMultiPoint3D(), getMultilineString3D(), getMultiPolygon2D()
       });
 }
예제 #21
0
 GeometryCollection createGeometryCollection(List geoms) {
   return gf.createGeometryCollection((Geometry[]) geoms.toArray(new Geometry[geoms.size()]));
 }