コード例 #1
0
  public Geometry createHullFromGeometry(
      Geometry clusterGeometry, Collection<Coordinate> additionalPoints, boolean fast) {

    if (additionalPoints.isEmpty()) return clusterGeometry;
    final Set<Coordinate> batchCoords = new HashSet<Coordinate>();

    for (final Coordinate coordinate : clusterGeometry.getCoordinates()) {
      batchCoords.add(coordinate);
    }
    for (final Coordinate coordinate : additionalPoints) {
      batchCoords.add(coordinate);
    }

    final Coordinate[] actualCoords = batchCoords.toArray(new Coordinate[batchCoords.size()]);

    if (batchCoords.size() == 2) {
      return clusterGeometry.getFactory().createLineString(actualCoords);
    }

    final ConvexHull convexHull = new ConvexHull(actualCoords, clusterGeometry.getFactory());

    final Geometry convexHullGeo = convexHull.getConvexHull();

    try {
      // does this shape benefit from concave hulling?
      // it cannot be a line string
      if (batchCoords.size() > 5 && convexHullGeo.getArea() > 0.0) {
        final Geometry concaveHull =
            fast
                ? concaveHull(convexHullGeo, batchCoords)
                : this.concaveHullParkOhMethod(convexHullGeo, batchCoords);
        if (!concaveHull.isSimple()) {
          LOGGER.warn("Produced non simple hull", concaveHull.toText());
          return convexHullGeo;
        }
        return concaveHull;
      } else {
        return convexHullGeo;
      }
    } catch (final Exception ex) {

      /*
       * Geometry[] points = new Geometry[actualCoords.length + 1]; for
       * (int i = 0; i < actualCoords.length; i++) points[i] =
       * hull.getFactory().createPoint( actualCoords[i]);
       * points[points.length - 1] = hull; try { ShapefileTool.writeShape(
       * "test_perf_xh", new File( "./targettest_perf_xh"), points); }
       * catch (IOException e) { e.printStackTrace(); }
       */
      LOGGER.error("Failed to compute hull", ex);

      return convexHullGeo;
    }
  }
コード例 #2
0
ファイル: Drawing.java プロジェクト: BestSolution-at/uDig
  /**
   * Finds the geometric attribute requested by the symbolizer.
   *
   * @param feature The victim
   * @param symbolizer The symbolizer
   * @param style the resolved style for the specified victim
   * @return The geometry requested in the symbolizer, or the default geometry if none is specified
   */
  private com.vividsolutions.jts.geom.Geometry findGeometry(
      SimpleFeature feature, Symbolizer symbolizer) {
    String geomName = getGeometryPropertyName(symbolizer);
    // get the geometry
    com.vividsolutions.jts.geom.Geometry geometry;
    if (geomName == null || feature.getType().getDescriptor(geomName) == null) {
      geometry = (Geometry) feature.getDefaultGeometry();
    } else {
      geometry = (com.vividsolutions.jts.geom.Geometry) feature.getAttribute(geomName);
    }
    if (geometry == null) {
      return null; // nothing to see here
    }
    // if the symbolizer is a point or text symbolizer generate a suitable
    // location to place the
    // point in order to avoid recomputing that location at each rendering
    // step

    if ((symbolizer instanceof PointSymbolizer || symbolizer instanceof TextSymbolizer)
        && !(geometry instanceof Point)) {
      if (geometry instanceof LineString && !(geometry instanceof LinearRing)) {
        // use the mid point to represent the point/text symbolizer
        // anchor
        Coordinate[] coordinates = geometry.getCoordinates();
        Coordinate start = coordinates[0];
        Coordinate end = coordinates[1];
        Coordinate mid = new Coordinate((start.x + end.x) / 2, (start.y + end.y) / 2);
        geometry = geometry.getFactory().createPoint(mid);
      } else {
        // otherwise use the centroid of the polygon
        geometry = geometry.getCentroid();
      }
    }
    return geometry;
  }
コード例 #3
0
  /**
   * split intersection segments have interior location at both left and right
   *
   * @param utilSplitLine
   * @param polygon
   * @param holesList
   */
  private void addSplitLineIntoGraph(
      final Geometry utilSplitLine, final Polygon polygon, List<LineString> holesList) {

    // split intersection segments have interior location at both left
    // and right
    Geometry intersectingLineStrings = utilSplitLine.intersection(polygon);

    if (intersectingLineStrings.getNumGeometries() > 1) {
      // If points exist, then remove them.
      intersectingLineStrings = filterLineString(intersectingLineStrings);
    }

    // use the same input used to create hole edges
    Geometry holeCollection =
        intersectingLineStrings
            .getFactory()
            .createMultiLineString(holesList.toArray(new LineString[holesList.size()]));
    Geometry holeGeometries = holeCollection.difference(utilSplitLine);
    insertEdge(
        intersectingLineStrings,
        holeGeometries,
        Location.BOUNDARY,
        Location.INTERIOR,
        Location.INTERIOR);
  }
コード例 #4
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);
  }
コード例 #5
0
 private Geometry polygonize(Geometry geometry) {
   List lines = LineStringExtracter.getLines(geometry);
   Polygonizer polygonizer = new Polygonizer();
   polygonizer.add(lines);
   Collection polys = polygonizer.getPolygons();
   Polygon[] polyArray = GeometryFactory.toPolygonArray(polys);
   return geometry.getFactory().createGeometryCollection(polyArray);
 }
コード例 #6
0
  private Geometry intersectionWithSegment(
      Coordinate[] holeCoords, int i, Geometry intersectingSegment) {

    Coordinate[] holeSegmentCoord = new Coordinate[] {holeCoords[i], holeCoords[i + 1]};

    LineString holeSegment;
    GeometryFactory geomFact = intersectingSegment.getFactory();
    holeSegment = geomFact.createLineString(holeSegmentCoord);
    Geometry intersection = holeSegment.intersection(intersectingSegment);

    return intersection;
  }
コード例 #7
0
  @Override
  public void encodeGeometryValue(Geometry value, int srid, StringBuffer sql) throws IOException {
    if (value == null || value.isEmpty()) {
      sql.append("NULL");
    } else {
      if (value instanceof LinearRing) {
        // postgis does not handle linear rings, convert to just a line string
        value = value.getFactory().createLineString(((LinearRing) value).getCoordinateSequence());
      }

      sql.append("ST_GeomFromText('" + value.toText() + "', " + srid + ")");
    }
  }
コード例 #8
0
 protected Geometry distillSameTypeGeometries(GeometryCollection coll, Geometry original) {
   if (original instanceof Polygon || original instanceof MultiPolygon) {
     List<Polygon> polys = new ArrayList<Polygon>();
     accumulateGeometries(polys, coll, Polygon.class);
     return original
         .getFactory()
         .createMultiPolygon(((Polygon[]) polys.toArray(new Polygon[polys.size()])));
   } else if (original instanceof LineString || original instanceof MultiLineString) {
     List<LineString> ls = new ArrayList<LineString>();
     accumulateGeometries(ls, coll, LineString.class);
     return original
         .getFactory()
         .createMultiLineString((LineString[]) ls.toArray(new LineString[ls.size()]));
   } else if (original instanceof Point || original instanceof MultiPoint) {
     List<LineString> points = new ArrayList<LineString>();
     accumulateGeometries(points, coll, LineString.class);
     return original
         .getFactory()
         .createMultiPoint((Point[]) points.toArray(new Point[points.size()]));
   } else {
     return original;
   }
 }
コード例 #9
0
  @Override
  public void setGeometryValue(
      Geometry g, int srid, Class binding, PreparedStatement ps, int column) throws SQLException {
    if (g != null) {
      if (g instanceof LinearRing) {
        // ingres does not handle linear rings, convert to just a line string
        g = g.getFactory().createLineString(((LinearRing) g).getCoordinateSequence());
      }

      byte[] bytes = new WKBWriter().write(g);
      ps.setBytes(column, bytes);
    } else {
      ps.setBytes(column, null);
    }
  }
コード例 #10
0
  @Override
  @SuppressWarnings("rawtypes")
  public void setGeometryValue(
      Geometry g, int srid, Class binding, PreparedStatement ps, int column) throws SQLException {
    if (g != null) {
      if (g instanceof LinearRing) {
        // WKT does not support linear rings
        g = g.getFactory().createLineString(((LinearRing) g).getCoordinateSequence());
      }

      byte[] bytes = new WKBWriter().write(g);
      ps.setBytes(column, bytes);
    } else {
      ps.setNull(column, Types.OTHER, "Geometry");
    }
  }
コード例 #11
0
  public Geometry buffer(Geometry g, double distance) {
    PrecisionModel precisionModel = workingPrecisionModel;
    if (precisionModel == null) precisionModel = g.getPrecisionModel();

    // factory must be the same as the one used by the input
    geomFact = g.getFactory();

    OffsetCurveBuilder curveBuilder = new OffsetCurveBuilder(precisionModel, bufParams);

    OffsetCurveSetBuilder curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder);

    List bufferSegStrList = curveSetBuilder.getCurves();

    // short-circuit test
    if (bufferSegStrList.size() <= 0) {
      return createEmptyResultGeometry();
    }

    // BufferDebug.runCount++;
    // String filename = "run" + BufferDebug.runCount + "_curves";
    // System.out.println("saving " + filename);
    // BufferDebug.saveEdges(bufferEdgeList, filename);
    // DEBUGGING ONLY
    // WKTWriter wktWriter = new WKTWriter();
    // Debug.println("Rings: " + wktWriter.write(convertSegStrings(bufferSegStrList.iterator())));
    // wktWriter.setMaxCoordinatesPerLine(10);
    // System.out.println(wktWriter.writeFormatted(convertSegStrings(bufferSegStrList.iterator())));

    computeNodedEdges(bufferSegStrList, precisionModel);
    graph = new PlanarGraph(new OverlayNodeFactory());
    graph.addEdges(edgeList.getEdges());

    List subgraphList = createSubgraphs(graph);
    PolygonBuilder polyBuilder = new PolygonBuilder(geomFact);
    buildSubgraphs(subgraphList, polyBuilder);
    List resultPolyList = polyBuilder.getPolygons();

    // just in case...
    if (resultPolyList.size() <= 0) {
      return createEmptyResultGeometry();
    }

    Geometry resultGeom = geomFact.buildGeometry(resultPolyList);
    return resultGeom;
  }
コード例 #12
0
ファイル: MapTransform.java プロジェクト: agouge/orbisgis
 /**
  * Gets the AWT {@link Shape} we'll use to represent {@code geom} on the map.
  *
  * @param geom The geometry we want to draw.
  * @param generalize If true we'll perform generalization
  * @return An AWT Shape instance.
  */
 public Shape getShape(Geometry geom, boolean generalize) {
   if (generalize) {
     Rectangle2DDouble rectangle2dDouble = toPixel(geom.getEnvelopeInternal());
     if ((rectangle2dDouble.getHeight() <= MAXPIXEL_DISPLAY)
         && (rectangle2dDouble.getWidth() <= MAXPIXEL_DISPLAY)) {
       if (geom.getDimension() == 1) {
         Coordinate[] coords = geom.getCoordinates();
         return getShapeWriter()
             .toShape(
                 geom.getFactory()
                     .createLineString(new Coordinate[] {coords[0], coords[coords.length - 1]}));
       } else {
         return rectangle2dDouble;
       }
     }
   }
   return getShapeWriter().toShape(geom);
 }
コード例 #13
0
  public final Geometry transform(Geometry inputGeom) {
    this.inputGeom = inputGeom;
    this.factory = inputGeom.getFactory();

    if (inputGeom instanceof Point) return transformPoint((Point) inputGeom, null);
    if (inputGeom instanceof MultiPoint) return transformMultiPoint((MultiPoint) inputGeom, null);
    if (inputGeom instanceof LinearRing) return transformLinearRing((LinearRing) inputGeom, null);
    if (inputGeom instanceof LineString) return transformLineString((LineString) inputGeom, null);
    if (inputGeom instanceof MultiLineString)
      return transformMultiLineString((MultiLineString) inputGeom, null);
    if (inputGeom instanceof Polygon) return transformPolygon((Polygon) inputGeom, null);
    if (inputGeom instanceof MultiPolygon)
      return transformMultiPolygon((MultiPolygon) inputGeom, null);
    if (inputGeom instanceof GeometryCollection)
      return transformGeometryCollection((GeometryCollection) inputGeom, null);

    throw new IllegalArgumentException(
        "Unknown Geometry subtype: " + inputGeom.getClass().getName());
  }
コード例 #14
0
  /**
   * Only return the lines contained on the given geometry, the non lines geometry are rejected.
   *
   * @param geometry Intersection geometry between split line and source geometry.
   * @return The valid geometries needed for the graph, those are lines and multiLines.
   */
  private Geometry filterLineString(Geometry geometry) {

    List<Geometry> filteredLines = new ArrayList<Geometry>();
    for (int i = 0; i < geometry.getNumGeometries(); i++) {

      Geometry possibleLine = geometry.getGeometryN(i);

      // if there are point geometries, discard it.
      if (possibleLine instanceof LineString || possibleLine instanceof MultiLineString) {

        // also remove very very short liens.
        if (possibleLine.getLength() > UsefulSplitLineBuilder.DEPRECIATE_VALUE) {

          filteredLines.add(possibleLine);
        }
      }
    }
    GeometryFactory gf = geometry.getFactory();

    return gf.buildGeometry(filteredLines);
  }
コード例 #15
0
  protected Geometry connect(
      final Geometry shape1,
      final Geometry shape2,
      final Pair<Integer, Integer> closestCoordinates) {
    Coordinate[] leftCoords = shape1.getCoordinates(), rightCoords = shape2.getCoordinates();
    int startLeft, startRight;
    if ((leftCoords[closestCoordinates.getLeft()].x
        < rightCoords[closestCoordinates.getRight()].x)) {
      startLeft = closestCoordinates.getLeft();
      startRight = closestCoordinates.getRight();
    } else {
      leftCoords = shape2.getCoordinates();
      rightCoords = shape1.getCoordinates();
      startLeft = closestCoordinates.getRight();
      startRight = closestCoordinates.getLeft();
    }
    final HashSet<Coordinate> visitedSet = new HashSet<Coordinate>();

    visitedSet.add(leftCoords[startLeft]);
    visitedSet.add(rightCoords[startRight]);

    final boolean leftClockwise = clockwise(leftCoords);
    final boolean rightClockwise = clockwise(rightCoords);

    final Pair<Integer, Integer> upperCoords =
        walk(
            visitedSet,
            leftCoords,
            rightCoords,
            startLeft,
            startRight,
            new DirectionFactory() {

              @Override
              public Direction createLeftFootDirection(final int start, final int max) {
                return leftClockwise
                    ? new IncreaseDirection(start, max, true)
                    : new DecreaseDirection(start, max, true);
              }

              @Override
              public Direction createRightFootDirection(final int start, final int max) {
                return rightClockwise
                    ? new DecreaseDirection(start, max, false)
                    : new IncreaseDirection(start, max, false);
              }
            });

    final Pair<Integer, Integer> lowerCoords =
        walk(
            visitedSet,
            leftCoords,
            rightCoords,
            startLeft,
            startRight,
            new DirectionFactory() {

              @Override
              public Direction createLeftFootDirection(final int start, final int max) {
                return leftClockwise
                    ? new DecreaseDirection(start, max, false)
                    : new IncreaseDirection(start, max, false);
              }

              @Override
              public Direction createRightFootDirection(final int start, final int max) {
                return rightClockwise
                    ? new IncreaseDirection(start, max, true)
                    : new DecreaseDirection(start, max, true);
              }
            });

    final List<Coordinate> newCoordinateSet = new ArrayList<Coordinate>();
    final Direction leftSet =
        leftClockwise
            ? new IncreaseDirection(
                upperCoords.getLeft(), lowerCoords.getLeft() + 1, leftCoords.length)
            : new DecreaseDirection(
                upperCoords.getLeft(), lowerCoords.getLeft() - 1, leftCoords.length);
    newCoordinateSet.add(leftCoords[upperCoords.getLeft()]);
    while (leftSet.hasNext()) {
      newCoordinateSet.add(leftCoords[leftSet.next()]);
    }
    final Direction rightSet =
        rightClockwise
            ? new IncreaseDirection(
                lowerCoords.getRight(), upperCoords.getRight() + 1, rightCoords.length)
            : new DecreaseDirection(
                lowerCoords.getRight(), upperCoords.getRight() - 1, rightCoords.length);
    newCoordinateSet.add(rightCoords[lowerCoords.getRight()]);
    while (rightSet.hasNext()) {
      newCoordinateSet.add(rightCoords[rightSet.next()]);
    }
    newCoordinateSet.add(leftCoords[upperCoords.getLeft()]);
    return shape1
        .getFactory()
        .createPolygon(newCoordinateSet.toArray(new Coordinate[newCoordinateSet.size()]));
  }
コード例 #16
0
  /**
   * Checks if the intersecting segment intersects with a hole in two points. In that case, the
   * segment might be adjusted following the orientation of the intersected hole.
   *
   * @param intersectingSegment this segment that could intersect with a hole
   * @param holeGeometries the polygon hole list
   */
  private LineString adjustSegmentToHoleDirection(
      final Geometry intersectingSegment, final Geometry holeGeometries) {

    LineString intersectedHole = intersectionHole(intersectingSegment, holeGeometries);

    if (intersectedHole == null) {
      return (LineString) intersectingSegment; // it does not require
      // adjust orientation
    }

    // Traverses the hole-segments until the second intersection with the
    // intersectingSegment is found
    // a ring will be created with those segments between first intersection
    // and second intersection.
    Coordinate secondIntersection = null;
    Coordinate firstIntersection = null;
    int j = -1;
    Coordinate[] holeCoords = intersectedHole.getCoordinates();
    List<Coordinate> ring = new LinkedList<Coordinate>();
    for (int i = 0; i < holeCoords.length - 1; i++) {

      Geometry intersection = intersectionWithSegment(holeCoords, i, intersectingSegment);
      if (intersection instanceof Point) {

        // store first and second coordinates
        if (firstIntersection == null) {

          firstIntersection = intersection.getCoordinate();
          ring.add(firstIntersection);
          ring.add(holeCoords[i + 1]);
          j = i + 1;
          break;
        }
        // Adds the rest of segments in the ring until found a second
        // intersection
      }
    }
    assert firstIntersection != null && j != -1;

    while (true) {
      Geometry intersection = intersectionWithSegment(holeCoords, j, intersectingSegment);

      if (intersection instanceof Point
          && !intersection.getCoordinate().equals2D(firstIntersection)) {
        secondIntersection = intersection.getCoordinate();
        ring.add(secondIntersection);
        // close the ring
        ring.add(firstIntersection);
        break;

      } else {
        ring.add(holeCoords[j + 1]);
      }
      j++;
    }

    assert secondIntersection != null;

    // Creates the adjusted line following this rules:
    // - if the ring is CW then the result line must be this: first
    // intersection coordinate--> second intersection coordinate.
    // - if the ring is CCW the the result line must be this: second
    // intersection coordinate --> first intersection coordinate.
    GeometryFactory factory = intersectingSegment.getFactory();
    LinearRing linearRing = factory.createLinearRing(ring.toArray(new Coordinate[ring.size()]));

    LineString adjustedSegment = null;
    if (isCW(linearRing)) {

      adjustedSegment = createAdjustedSegment(firstIntersection, secondIntersection, factory);

    } else {

      adjustedSegment = createAdjustedSegment(secondIntersection, firstIntersection, factory);
    }
    return adjustedSegment;
  }
コード例 #17
0
ファイル: ImportarUtils.java プロジェクト: e-admin/allocalgis
  public static Geometry obtenerGeometriaParcela(String dxf, WorkbenchContext context) {

    Geometry geometryParcela = null;

    GeopistaLoadDxfQueryChooser dxfLoad =
        new GeopistaLoadDxfQueryChooser(Dxf.class, "GEOPISTA dxf", extensions(Dxf.class), context);

    InputStream fileDXF = ImportarUtils_LCGIII.parseStringToIS(dxf);

    try {
      Assert.isTrue(!dxfLoad.getDataSourceQueries(fileDXF).isEmpty());
    } catch (AssertionFailedException e) {
      throw new AssertionFailedException(I18N.get("FileEmpty"));
    }

    fileDXF = ImportarUtils_LCGIII.parseStringToIS(dxf);

    boolean exceptionsEncountered = false;
    for (Iterator i = dxfLoad.getDataSourceQueries(fileDXF).iterator(); i.hasNext(); ) {
      DataSourceQuery dataSourceQuery = (DataSourceQuery) i.next();

      ArrayList exceptions = new ArrayList();
      Assert.isTrue(dataSourceQuery.getDataSource().isReadable());

      Connection connection = dataSourceQuery.getDataSource().getConnection();
      try {
        FeatureCollection dataset =
            dataSourceQuery
                .getDataSource()
                .installCoordinateSystem(
                    connection.executeQuery(dataSourceQuery.getQuery(), exceptions, null), null);
        if (dataset != null) {

          String layerName = dataSourceQuery.toString();
          Geometry geometriaInicial = null;
          GeopistaFeature featureInicial = null;

          if (layerName.startsWith("PG-LP")) {
            // Obtener el borde con las features de la capa
            ArrayList lstFeatures = new ArrayList();
            for (Iterator features = dataset.getFeatures().iterator(); features.hasNext(); ) {
              GeopistaFeature feature = (GeopistaFeature) features.next();
              lstFeatures.add(feature);
            }
            ArrayList coordenadas = new ArrayList();

            if (lstFeatures != null && lstFeatures.size() > 0) {

              featureInicial = (GeopistaFeature) lstFeatures.iterator().next();
              lstFeatures.remove(featureInicial);
              geometriaInicial = featureInicial.getGeometry();
              for (int indice = 0; indice < geometriaInicial.getCoordinates().length; indice++)
                coordenadas.add(geometriaInicial.getCoordinates()[indice]);

              if (geometriaInicial instanceof LineString) {

                Point puntoFinal = ((LineString) geometriaInicial).getEndPoint();
                GeopistaFeature feature = null;
                Geometry geometria = null;
                int indice;

                while (lstFeatures.size() > 0) {
                  boolean encontrado = false;
                  Iterator features = lstFeatures.iterator();
                  while (features.hasNext() && !encontrado) {

                    feature = (GeopistaFeature) features.next();
                    geometria = feature.getGeometry();
                    if (geometria instanceof LineString) {

                      if (puntoFinal.distance(((LineString) geometria).getStartPoint()) == 0) {

                        for (indice = 1; indice < geometria.getCoordinates().length; indice++)
                          coordenadas.add(geometria.getCoordinates()[indice]);
                        puntoFinal = ((LineString) geometria).getEndPoint();
                        encontrado = true;

                      } else if (puntoFinal.distance(((LineString) geometria).getEndPoint()) == 0) {
                        for (indice = geometria.getCoordinates().length - 2; indice >= 0; indice--)
                          coordenadas.add(geometria.getCoordinates()[indice]);

                        puntoFinal = ((LineString) geometria).getStartPoint();
                        encontrado = true;
                      }
                    }
                  }
                  if (encontrado) {
                    lstFeatures.remove(feature);
                  }
                }
                Coordinate[] coordenadasParcela = new Coordinate[coordenadas.size()];
                indice = 0;
                for (Iterator coordenada = coordenadas.iterator(); coordenada.hasNext(); ) {
                  coordenadasParcela[indice] = (Coordinate) coordenada.next();
                  indice++;
                }

                if (coordenadasParcela[0].equals3D(
                    coordenadasParcela[coordenadasParcela.length - 1])) {
                  LinearRing lineaParcela =
                      geometriaInicial.getFactory().createLinearRing(coordenadasParcela);
                  Polygon poligonoParcela = null;
                  poligonoParcela = geometriaInicial.getFactory().createPolygon(lineaParcela, null);
                  geometryParcela = poligonoParcela;
                }
              }
            }
          }
        }
      } finally {
        connection.close();
      }
      if (!exceptions.isEmpty()) {
        if (!exceptionsEncountered) {
          context.getIWorkbench().getFrame().getOutputFrame().createNewDocument();
          exceptionsEncountered = true;
        }
        reportExceptions(exceptions, dataSourceQuery, context);
      }
    }
    if (exceptionsEncountered) {
      context
          .getIWorkbench()
          .getGuiComponent()
          .warnUser("Problems were encountered. See Output Window for details.");
    }

    return geometryParcela;
  }
コード例 #18
0
  /**
   * Gift unwrapping (e.g. dig) concept, taking a convex hull and a set of inner points, add inner
   * points to the hull without violating hull invariants--all points must reside on the hull or
   * inside the hull. Based on: Jin-Seo Park and Se-Jong Oh. "A New Concave Algorithm and
   * Concaveness Measure for n-dimensional Datasets" . Department of Nanobiomedical Science. Dankook
   * University". 2010.
   *
   * <p>Per the paper, N = concaveThreshold
   *
   * @param geometry
   * @param providedInnerPoints
   * @return
   */
  public Geometry concaveHullParkOhMethod(
      final Geometry geometry, final Collection<Coordinate> providedInnerPoints) {

    final Set<Coordinate> innerPoints = new HashSet<Coordinate>(providedInnerPoints);
    final TreeSet<Edge> edges = new TreeSet<Edge>();
    final Coordinate[] geoCoordinateList = geometry.getCoordinates();
    final int s = geoCoordinateList.length - 1;
    final Edge firstEdge =
        createEdgeWithSideEffects(geoCoordinateList[0], geoCoordinateList[1], innerPoints, edges);
    Edge lastEdge = firstEdge;
    for (int i = 1; i < s; i++) {
      final Edge newEdge =
          createEdgeWithSideEffects(
              geoCoordinateList[i], geoCoordinateList[i + 1], innerPoints, edges);
      newEdge.connectLast(lastEdge);
      lastEdge = newEdge;
    }
    firstEdge.connectLast(lastEdge);
    while (!edges.isEmpty() && !innerPoints.isEmpty()) {
      final Edge edge = edges.pollLast();
      lastEdge = edge;
      double score = Double.MAX_VALUE;
      Coordinate selectedCandidate = null;
      for (final Coordinate candidate : innerPoints) {
        final double dist = calcDistance(edge.start, edge.end, candidate);
        // on the hull
        if (MathUtils.equals(dist, 0.0, 0.000000001)) {
          score = 0.0;
          selectedCandidate = candidate;
          break;
        }
        if ((dist > 0) && (dist < score)) {
          score = dist;
          selectedCandidate = candidate;
        }
      }
      if (selectedCandidate == null) {
        continue;
      }
      // if one a line segment of the hull, then remove candidate
      if (score == 0.0) {
        innerPoints.remove(selectedCandidate);
        edges.add(edge);
        continue;
      }
      // Park and Oh look only at the neighbor edges
      // but this fails in some cases.
      if (isCandidateCloserToAnotherEdge(score, edge, edges, selectedCandidate)) {
        continue;
      }

      innerPoints.remove(selectedCandidate);
      final double eh = edge.distance;
      final double startToCandidate =
          distanceFnForCoordinate.measure(edge.start, selectedCandidate);
      final double endToCandidate = distanceFnForCoordinate.measure(edge.end, selectedCandidate);
      final double min = Math.min(startToCandidate, endToCandidate);
      // protected against duplicates
      if ((eh / min) > concaveThreshold) {
        final Edge newEdge1 = new Edge(edge.start, selectedCandidate, startToCandidate);
        final Edge newEdge2 = new Edge(selectedCandidate, edge.end, endToCandidate);
        // need to replace this with something more intelligent. This
        // occurs in cases of sharp angles. An angular approach may also
        // work
        // look for an angle to flip in the reverse direction.
        if (!intersectAnotherEdge(newEdge1, edge)
            && !intersectAnotherEdge(newEdge2, edge)
            && !intersectAnotherEdge(newEdge1, edge.last)
            && !intersectAnotherEdge(newEdge2, edge.next)) {
          edges.add(newEdge2);
          edges.add(newEdge1);
          newEdge1.connectLast(edge.last);
          newEdge2.connectLast(newEdge1);
          edge.next.connectLast(newEdge2);
          lastEdge = newEdge1;
        }
      }
    }
    return geometry.getFactory().createPolygon(reassemble(lastEdge));
  }
コード例 #19
0
  /**
   * Gift unwrapping (e.g. dig) concept, taking a convex hull and a set of inner points, add inner
   * points to the hull without violating hull invariants--all points must reside on the hull or
   * inside the hull. Based on: Jin-Seo Park and Se-Jong Oh. "A New Concave Algorithm and
   * Concaveness Measure for n-dimensional Datasets" . Department of Nanobiomedical Science. Dankook
   * University". 2010.
   *
   * <p>Per the paper, N = concaveThreshold.
   *
   * <p>This algorithm evaluates remarkably faster than Park and Oh, but the quality of the result
   * is marginally less. If it is acceptable to have some small number of points fall outside of the
   * hull and speed is critical, use this method. The measure of error is difficult to calculate
   * since it is not directly calculated based on the number of inner points. Rather, the measure is
   * based on some number of points in proximity the optimal concave hull.
   *
   * @param geometry
   * @param providedInnerPoints
   * @return
   */
  public Geometry concaveHull(
      final Geometry geometry, final Collection<Coordinate> providedInnerPoints) {
    final Set<Coordinate> innerPoints =
        (providedInnerPoints instanceof Set)
            ? (Set<Coordinate>) providedInnerPoints
            : new HashSet<Coordinate>(providedInnerPoints);
    final TreeSet<Edge> edges = new TreeSet<Edge>();
    final Coordinate[] geoCoordinateList = geometry.getCoordinates();
    final int s = geoCoordinateList.length - 1;
    final Edge firstEdge =
        createEdgeWithSideEffects(geoCoordinateList[0], geoCoordinateList[1], innerPoints, edges);
    Edge lastEdge = firstEdge;
    for (int i = 1; i < s; i++) {
      final Edge newEdge =
          createEdgeWithSideEffects(
              geoCoordinateList[i], geoCoordinateList[i + 1], innerPoints, edges);
      newEdge.connectLast(lastEdge);
      lastEdge = newEdge;
    }
    firstEdge.connectLast(lastEdge);
    for (final Coordinate candidate : innerPoints) {
      double min = Double.MAX_VALUE;
      Edge bestEdge = null;
      for (final Edge edge : edges) {
        final double dist = calcDistance(edge.start, edge.end, candidate);
        if ((dist > 0) && (dist < min)) {
          min = dist;
          bestEdge = edge;
        }
      }
      if (bestEdge != null) {
        bestEdge.getPoints().add(new NeighborData<Coordinate>(candidate, null, min));
      }
    }
    while (!edges.isEmpty()) {
      final Edge edge = edges.pollLast();
      lastEdge = edge;
      NeighborData<Coordinate> candidate = edge.getPoints().pollFirst();
      while (candidate != null) {
        if (!MathUtils.equals(candidate.getDistance(), 0.0, 0.000000001)) {
          final Coordinate selectedCandidate = candidate.getElement();
          final double eh = edge.distance;
          final double startToCandidate =
              distanceFnForCoordinate.measure(edge.start, selectedCandidate);
          final double endToCandidate =
              distanceFnForCoordinate.measure(edge.end, selectedCandidate);
          final double min = Math.min(startToCandidate, endToCandidate);
          // protected against duplicates
          if ((eh / min) > concaveThreshold) {
            final Edge newEdge1 = new Edge(edge.start, selectedCandidate, startToCandidate);
            final Edge newEdge2 = new Edge(selectedCandidate, edge.end, endToCandidate);
            edges.add(newEdge2);
            edges.add(newEdge1);
            newEdge1.connectLast(edge.last);
            newEdge2.connectLast(newEdge1);
            edge.next.connectLast(newEdge2);
            lastEdge = newEdge1;
            for (final NeighborData<Coordinate> otherPoint : edge.getPoints()) {
              final double[] distProfile1 =
                  calcDistanceSegment(newEdge1.start, newEdge1.end, otherPoint.getElement());
              final double[] distProfile2 =
                  calcDistanceSegment(newEdge2.start, newEdge2.end, otherPoint.getElement());
              if (distProfile1[0] >= 0.0 && distProfile1[0] <= 1.0) {
                if (distProfile1[0] < 0.0
                    || distProfile1[0] > 1.0
                    || distProfile2[1] > distProfile1[1]) {
                  otherPoint.setDistance(distProfile1[1]);
                  newEdge1.getPoints().add(otherPoint);
                } else {
                  otherPoint.setDistance(distProfile2[1]);
                  newEdge2.getPoints().add(otherPoint);
                }
              } else if (distProfile2[0] >= 0.0 && distProfile2[0] <= 1.0) {

                otherPoint.setDistance(distProfile2[1]);
                newEdge2.getPoints().add(otherPoint);
              }
            }
            edge.getPoints().clear(); // forces this loop to end
          }
        }
        candidate = edge.getPoints().pollFirst();
      }
    }
    return geometry.getFactory().createPolygon(reassemble(lastEdge));
  }