Java Code Examples for org.locationtech.jts.geom.Geometry#getCoordinates()

The following examples show how to use org.locationtech.jts.geom.Geometry#getCoordinates() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GeoFunctions.java    From presto with Apache License 2.0 6 votes vote down vote up
private static void buildPointsBlock(Geometry geometry, BlockBuilder blockBuilder)
{
    GeometryType type = GeometryType.getForJtsGeometryType(geometry.getGeometryType());
    if (type == GeometryType.POINT) {
        GEOMETRY.writeSlice(blockBuilder, JtsGeometrySerde.serialize(geometry));
    }
    else if (type == GeometryType.GEOMETRY_COLLECTION) {
        GeometryCollection collection = (GeometryCollection) geometry;
        for (int i = 0; i < collection.getNumGeometries(); i++) {
            Geometry entry = collection.getGeometryN(i);
            buildPointsBlock(entry, blockBuilder);
        }
    }
    else {
        GeometryFactory geometryFactory = geometry.getFactory();
        Coordinate[] vertices = geometry.getCoordinates();
        for (Coordinate coordinate : vertices) {
            GEOMETRY.writeSlice(blockBuilder, JtsGeometrySerde.serialize(geometryFactory.createPoint(coordinate)));
        }
    }
}
 
Example 2
Source File: BoundaryPartitioner.java    From geowave with Apache License 2.0 6 votes vote down vote up
@Override
public void partition(final Object entry, final PartitionDataCallback callback) throws Exception {
  final Geometry geom = extractor.getGeometry((SimpleFeature) entry);
  System.out.println(geom.toString());
  final Coordinate[] coords = (geom.getCoordinates());
  if (coords.length < 2) {
    super.partition(geom, callback);
  } else {
    for (int i = 0; i < (coords.length - 1); i++) {

      super.partition(
          geom.getFactory().createLineString(new Coordinate[] {coords[i], coords[i + 1]}),
          callback);
    }
  }
}
 
Example 3
Source File: ReverseOf.java    From arctic-sea with Apache License 2.0 6 votes vote down vote up
@Override
public boolean matches(Object item) {
    if (item == null || item.getClass() != original.getClass()) {
        return false;
    }
    Geometry geom = (Geometry) item;
    Coordinate[] orig = original.getCoordinates();
    Coordinate[] switched = geom.getCoordinates();
    if (orig.length != switched.length) {
        return false;
    }
    for (int i = 0; i < orig.length; ++i) {
        if (!isSwitched(orig[i], switched[i])) {
            return false;
        }
    }
    return true;
}
 
Example 4
Source File: ConvexHullMapReduce.java    From geowave with Apache License 2.0 6 votes vote down vote up
private static <T> Geometry compress(
    final GeoWaveInputKey key,
    final List<Coordinate> batchCoords) {
  final Coordinate[] actualCoords = batchCoords.toArray(new Coordinate[batchCoords.size()]);

  // generate convex hull for current batch of points
  final ConvexHull convexHull = new ConvexHull(actualCoords, new GeometryFactory());
  final Geometry hullGeometry = convexHull.getConvexHull();

  final Coordinate[] hullCoords = hullGeometry.getCoordinates();
  batchCoords.clear();
  for (final Coordinate hullCoord : hullCoords) {
    batchCoords.add(hullCoord);
  }

  return hullGeometry;
}
 
Example 5
Source File: GeometryUtilsTest.java    From geowave with Apache License 2.0 6 votes vote down vote up
@Test
public void test2DGeometryBinaryConversion() {

  // convert 2D point to binary representation
  final byte[] bytes =
      GeometryUtils.geometryToBinary(point2D, GeometryUtils.MAX_GEOMETRY_PRECISION);

  // load the converted 2D geometry
  final Geometry convGeo =
      GeometryUtils.geometryFromBinary(bytes, GeometryUtils.MAX_GEOMETRY_PRECISION);

  // get the coordinates for each version
  final Coordinate origCoords = point2D.getCoordinates()[0];
  final Coordinate convCoords = convGeo.getCoordinates()[0];

  Assert.assertEquals(origCoords.x, convCoords.x, DELTA);

  Assert.assertEquals(origCoords.y, convCoords.y, DELTA);

  Assert.assertTrue(Double.isNaN(convCoords.getZ()));
}
 
Example 6
Source File: GeometryHullToolTest.java    From geowave with Apache License 2.0 5 votes vote down vote up
private static boolean coversPoints(final Geometry coverer, final Geometry pointsToCover) {
  for (final Coordinate coordinate : pointsToCover.getCoordinates()) {
    if (!coverer.covers(coverer.getFactory().createPoint(coordinate))) {
      return false;
    }
  }
  return true;
}
 
Example 7
Source File: GeopackageVectorLayer.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
private void addLine( Geometry geometry, BasicShapeAttributes shapeAttributes, boolean convert ) {
        if (geometry == null) {
            return;
        }
        Coordinate[] coordinates = geometry.getCoordinates();
        if (coordinates.length < 2)
            return;

        int numGeometries = geometry.getNumGeometries();
        for( int i = 0; i < numGeometries; i++ ) {
            Geometry geometryN = geometry.getGeometryN(i);
            if (geometryN instanceof LineString) {
                LineString line = (LineString) geometryN;
                Coordinate[] lineCoords = line.getCoordinates();
                int numVertices = lineCoords.length;
                List<Position> verticesList = new ArrayList<>(numVertices);
                for( int j = 0; j < numVertices; j++ ) {
                    Coordinate c = lineCoords[j];
                    if (convert) {
                        c = MercatorUtils.convert3857To4326(c);
                    }
                    bounds.expandToInclude(c);
                    verticesList.add(Position.fromDegrees(c.y, c.x));
                }
                FeatureLine path = new FeatureLine(verticesList, null);
//                path.setFeature(lineFeature);
                path.setAltitudeMode(mElevationMode);
                path.setAttributes(shapeAttributes);
                path.setHighlightAttributes(highlightAttrs);

                addRenderable(path);
            }
        }
    }
 
Example 8
Source File: TestLineSmootherMcMaster.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
public void testVectorReader() throws Exception {

        SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
        b.setName("test");
        b.setCRS(DefaultGeographicCRS.WGS84);
        b.add("the_geom", LineString.class);
        b.add("id", Integer.class);

        DefaultFeatureCollection newCollection = new DefaultFeatureCollection();
        SimpleFeatureType type = b.buildFeatureType();

        Geometry line = new WKTReader().read("LINESTRING (0 0, 1 1, 2 2, 3 3, 4 4, 5 3, 6 2, 7 1, 8 0)");
        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
        Object[] values = new Object[]{line, 0};
        builder.addAll(values);
        SimpleFeature feature = builder.buildFeature(type.getTypeName() + ".0");
        newCollection.add(feature);

        OmsLineSmootherMcMaster smoother = new OmsLineSmootherMcMaster();
        smoother.inVector = newCollection;
        smoother.pLookahead = 3;
        smoother.pSlide = 0.9;
        smoother.pDensify = 0.9;
        smoother.process();
        SimpleFeatureCollection outFeatures = smoother.outVector;

        List<Geometry> geomList = FeatureUtilities.featureCollectionToGeometriesList(outFeatures, false, null);
        Geometry geometry = geomList.get(0);

        int newLength = geometry.getCoordinates().length;

        Geometry densifiedline = new WKTReader()
                .read("LINESTRING (0 0, 0.5 0.5, 1 1, 1.5 1.5, 2 2, 2.5 2.5, 3 3, 3.5 3.5, 4 4, 4.5 3.5, 5 3, 5.5 2.5, 6 2, 6.5 1.5, 7 1, 7.5 0.5, 8 0)");
        int expectedLength = densifiedline.getCoordinates().length;

        assertEquals(expectedLength, newLength);

    }
 
Example 9
Source File: ENU.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Converts a geometry from WGS to ENU. 
 * 
 * <p>Note that the geometry is internally converted. Use clone() if you need a copy.</p>
 * 
 * @param geometryWgs
 */
public void convertGeometryFromWgsToEnu( Geometry geometryWgs ) {
    Coordinate[] coordinates = geometryWgs.getCoordinates();
    for( int i = 0; i < coordinates.length; i++ ) {
        Coordinate enu = wgs84ToEnu(coordinates[i]);
        coordinates[i].x = enu.x;
        coordinates[i].y = enu.y;
        coordinates[i].z = enu.z;
    }
}
 
Example 10
Source File: OmsLineSmootherMcMaster.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Checks if the given geometry is connected to any other line.
 * 
 * @param geometryN the geometry to test.
 * @return true if the geometry is alone in the space, i.e. not connected at
 *              one of the ends to any other geometry.
 */
private boolean isAlone( Geometry geometryN ) {
    Coordinate[] coordinates = geometryN.getCoordinates();
    if (coordinates.length > 1) {
        Coordinate first = coordinates[0];
        Coordinate last = coordinates[coordinates.length - 1];
        for( SimpleFeature line : linesList ) {
            Geometry lineGeom = (Geometry) line.getDefaultGeometry();
            int numGeometries = lineGeom.getNumGeometries();
            for( int i = 0; i < numGeometries; i++ ) {
                Geometry subGeom = lineGeom.getGeometryN(i);
                Coordinate[] lineCoordinates = subGeom.getCoordinates();
                if (lineCoordinates.length < 2) {
                    continue;
                } else {
                    Coordinate tmpFirst = lineCoordinates[0];
                    Coordinate tmpLast = lineCoordinates[lineCoordinates.length - 1];
                    if (tmpFirst.distance(first) < SAMEPOINTTHRESHOLD || tmpFirst.distance(last) < SAMEPOINTTHRESHOLD
                            || tmpLast.distance(first) < SAMEPOINTTHRESHOLD || tmpLast.distance(last) < SAMEPOINTTHRESHOLD) {
                        return false;
                    }
                }
            }
        }
    }
    // 1 point line or no connection, mark it as alone for removal
    return true;
}
 
Example 11
Source File: FeatureLayerType.java    From snap-desktop with GNU General Public License v3.0 5 votes vote down vote up
@Override
public void convertValueToDom(Object value, DomElement parentElement) throws ConversionException {
    Geometry geom = (Geometry) value;
    final Coordinate[] coordinates = geom.getCoordinates();
    final DefaultDomConverter domConverter = new DefaultDomConverter(Coordinate.class);
    for (Coordinate coordinate : coordinates) {
        final DomElement child = parentElement.createChild("coordinate");
        domConverter.convertValueToDom(coordinate, child);
    }
}
 
Example 12
Source File: JTSHelper.java    From arctic-sea with Apache License 2.0 5 votes vote down vote up
/**
 * Get the coordinates of a Geometry as String.
 *
 * @param geom
 *            Geometry to get coordinates
 * @return Coordinates as String
 */
public static String getCoordinatesString(Geometry geom) {
    StringBuilder builder = new StringBuilder();
    Coordinate[] sourceCoords = geom.getCoordinates();
    if (sourceCoords.length > 0) {
        getCoordinateString(builder, sourceCoords[0]);
        for (int i = 1; i < sourceCoords.length; ++i) {
            getCoordinateString(builder.append(' '), sourceCoords[i]);
        }
    }
    return builder.toString();
}
 
Example 13
Source File: GeometrySimpOptionProvider.java    From geowave with Apache License 2.0 4 votes vote down vote up
public boolean filterGeometry(final Geometry geom) {
  return ((geom.getCoordinates().length < maxVertices) && !geom.isEmpty() && geom.isValid());
}
 
Example 14
Source File: ConvexHullMapReduce.java    From geowave with Apache License 2.0 4 votes vote down vote up
@Override
protected void reduceNativeValues(
    final GeoWaveInputKey key,
    final Iterable<Object> values,
    final Reducer<GeoWaveInputKey, ObjectWritable, GeoWaveOutputKey, SimpleFeature>.Context context)
    throws IOException, InterruptedException {
  // limit on new points per convex hull run (batch)
  int batchThreshold = 10000;

  batchCoords.clear();

  Geometry currentHull = null;

  final String groupID = StringUtils.stringFromBinary(key.getDataId().getBytes());
  final AnalyticItemWrapper<T> centroid = centroidManager.getCentroid(groupID);
  for (final Object value : values) {
    currentHull = null;
    @SuppressWarnings("unchecked")
    final Geometry geo = projectionFunction.getProjection((T) value);
    final Coordinate[] coords = geo.getCoordinates();
    if ((coords.length + batchCoords.size()) > pointCloudThreshold) {
      break;
    }
    for (final Coordinate coordinate : coords) {
      batchCoords.add(coordinate);
    }
    if (coords.length > batchThreshold) {
      batchThreshold = coords.length;
    }
    if (batchCoords.size() > batchThreshold) {
      currentHull = compress(key, batchCoords);
    }
  }
  currentHull = (currentHull == null) ? compress(key, batchCoords) : currentHull;

  if (ConvexHullMapReduce.LOGGER.isTraceEnabled()) {
    ConvexHullMapReduce.LOGGER.trace(centroid.getGroupID() + " contains " + groupID);
  }

  final SimpleFeature newPolygonFeature =
      AnalyticFeature.createGeometryFeature(
          outputAdapter.getFeatureType(),
          centroid.getBatchID(),
          UUID.randomUUID().toString(),
          centroid.getName(),
          centroid.getGroupID(),
          centroid.getCost(),
          currentHull,
          new String[0],
          new double[0],
          centroid.getZoomLevel(),
          centroid.getIterationID(),
          centroid.getAssociationCount());
  // new center
  context.write(
      new GeoWaveOutputKey(outputAdapter.getTypeName(), indexNames),
      newPolygonFeature);
}
 
Example 15
Source File: OmsRiverSectionsExtractor.java    From hortonmachine with GNU General Public License v3.0 4 votes vote down vote up
@Execute
public void process() throws Exception {
    checkNull(inElev, inRiver);

    gf = GeometryUtilities.gf();

    List<SimpleFeature> riverFeatures = FeatureUtilities.featureCollectionToList(inRiver);
    SimpleFeature riverFeature = riverFeatures.get(0);

    Geometry geometry = (Geometry) riverFeature.getDefaultGeometry();
    Coordinate[] riverCoordinates = geometry.getCoordinates();

    RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inElev);
    Envelope envelope = regionMap.toEnvelope();
    pm.beginTask("Building 3D reach geometry...", riverCoordinates.length);
    Point2D.Double point = new Point2D.Double();
    double[] extracted = new double[1];
    for( int i = 0; i < riverCoordinates.length; i++ ) {
        Coordinate coordinate = riverCoordinates[i];
        if (!envelope.intersects(coordinate.x, coordinate.y)) {
            pm.worked(1);
            continue;
        }
        point.setLocation(coordinate.x, coordinate.y);
        inElev.evaluate(point, extracted);

        riverCoordinates[i] = new Coordinate(coordinate.x, coordinate.y, extracted[0]);
        pm.worked(1);
    }
    pm.done();

    LineString riverGeometry3d = gf.createLineString(riverCoordinates);

    ARiverSectionsExtractor sectionsExtractor;
    if (inSections == null) {
        List<FeatureMate> bridgePoints = new ArrayList<>();
        if (inBridges != null) {
            bridgePoints = FeatureUtilities.featureCollectionToMatesList(inBridges);
        }

        if (inRiverPoints != null) {
            List<SimpleFeature> riverPointsList = FeatureUtilities.featureCollectionToList(inRiverPoints);
            Coordinate[] riverPointCoordinates = new Coordinate[riverPointsList.size()];
            int[] riverPointIds = new int[riverPointsList.size()];
            double[] riverPointKs = new double[riverPointsList.size()];

            for( int i = 0; i < riverPointIds.length; i++ ) {
                SimpleFeature riverPointFeature = riverPointsList.get(i);
                Coordinate riverPointCoordinate = ((Geometry) riverPointFeature.getDefaultGeometry()).getCoordinate();
                int id = ((Number) riverPointFeature.getAttribute(LWFields.LINKID)).intValue();
                riverPointCoordinates[i] = riverPointCoordinate;
                riverPointIds[i] = id;
                Object attribute = riverPointFeature.getAttribute(LWFields.GAUKLER);
                if (attribute != null) {
                    double ks = ((Number) attribute).doubleValue();
                    riverPointKs[i] = ks;
                } else {
                    riverPointKs[i] = 30.0;
                }
            }
            sectionsExtractor = new RiverSectionsFromDtmExtractor(riverGeometry3d, //
                    riverPointCoordinates, riverPointIds, riverPointKs, //
                    inElev, pSectionsIntervalDistance, pSectionsWidth, bridgePoints, fBridgeWidth, pBridgeBuffer, pm);
        } else {
            sectionsExtractor = new RiverSectionsFromDtmExtractor(riverGeometry3d, //
                    inElev, pSectionsIntervalDistance, pSectionsWidth, bridgePoints, fBridgeWidth, pBridgeBuffer, pm);
        }

    } else {
        List<SimpleFeature> sectionsList = FeatureUtilities.featureCollectionToList(inSections);
        sectionsExtractor = new RiverSectionsFromFeaturesExtractor(riverGeometry3d, inElev, sectionsList, pm);
    }

    outSections = sectionsExtractor.getSectionsCollection();
    outSectionPoints = sectionsExtractor.getSectionPointsCollection();
    outRiverPoints = sectionsExtractor.getRiverPointsCollection();
}
 
Example 16
Source File: OmsPointsRasterizer.java    From hortonmachine with GNU General Public License v3.0 4 votes vote down vote up
@Execute
public void process() throws Exception {
    checkNull(inGrid, inVector);

    SimpleFeatureType schema = inVector.getSchema();
    if (!EGeometryType.isPoint(schema.getGeometryDescriptor())) {
        throw new ModelsRuntimeException("The module works only with point vectors.", this);
    }

    RegionMap regionMap = CoverageUtilities.gridGeometry2RegionParamsMap(inGrid);
    double n = regionMap.getNorth();
    double s = regionMap.getSouth();
    double e = regionMap.getEast();
    double w = regionMap.getWest();

    WritableRaster outWR = CoverageUtilities.createWritableRaster(regionMap.getCols(), regionMap.getRows(), null, null,
            HMConstants.doubleNovalue);
    WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);

    List<FeatureMate> matesList = FeatureUtilities.featureCollectionToMatesList(inVector);
    double value = 0;
    pm.beginTask("Rasterizing points...", matesList.size());
    for( FeatureMate featureMate : matesList ) {
        Geometry geometry = featureMate.getGeometry();

        if (fCat == null) {
            Double cat = featureMate.getAttribute(fCat, Double.class);
            if (cat != null) {
                value = cat;
            }
        }

        Coordinate[] coordinates = geometry.getCoordinates();

        for( Coordinate coordinate : coordinates ) {
            if (!NumericsUtilities.isBetween(coordinate.x, w, e) || !NumericsUtilities.isBetween(coordinate.y, s, n)) {
                continue;
            }

            GridCoordinates2D onGrid = inGrid.worldToGrid(new DirectPosition2D(coordinate.x, coordinate.y));
            outIter.setSample(onGrid.x, onGrid.y, 0, value);
        }
        pm.worked(1);
    }
    pm.done();

    outRaster = CoverageUtilities.buildCoverage("pointsraster", outWR, regionMap, inVector.getSchema()
            .getCoordinateReferenceSystem());
}
 
Example 17
Source File: TestBasinShape.java    From hortonmachine with GNU General Public License v3.0 4 votes vote down vote up
@SuppressWarnings("nls")
public void testBasinShape() throws Exception {
    HashMap<String, Double> envelopeParams = HMTestMaps.getEnvelopeparams();
    CoordinateReferenceSystem crs = HMTestMaps.getCrs();

    double[][] pitData = HMTestMaps.pitData;
    GridCoverage2D pitCoverage = CoverageUtilities.buildCoverage("pit", pitData, envelopeParams, crs, true);
    double[][] basinsData = HMTestMaps.basinShapeData;
    GridCoverage2D basinsCoverage = CoverageUtilities.buildCoverage("basins", basinsData, envelopeParams, crs, true);

    OmsBasinShape basin = new OmsBasinShape();
    basin.inElev = pitCoverage;
    basin.inBasins = basinsCoverage;
    basin.pm = pm;

    basin.process();

    SimpleFeatureCollection basinsFC = basin.outBasins;

    FeatureIterator<SimpleFeature> basinsIter = basinsFC.features();
    while( basinsIter.hasNext() ) {
        SimpleFeature feature = basinsIter.next();
        Geometry line = (Geometry) feature.getDefaultGeometry();

        int numGeometries = line.getNumGeometries();
        for( int i = 0; i < numGeometries; i++ ) {
            Geometry geometryN = line.getGeometryN(i);
            int length = geometryN.getCoordinates().length;
            if (length == 9) {
                Geometry g1 = new WKTReader().read(geom1Txt);
                assertTrue(geometryN.equals(g1));
            }
            if (length == 5) {
                Geometry g2 = new WKTReader().read(geom2Txt);
                assertTrue(geometryN.equals(g2));
            }
        }
    }
    basinsIter.close();

}
 
Example 18
Source File: SubsetUI.java    From snap-desktop with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void initParameters() {

    OperatorUIUtils.initParamList(bandList, getBandNames(), (Object[])paramMap.get("sourceBands"));

    String _oldSelected = (String) referenceCombo.getSelectedItem();
    referenceCombo.removeAllItems();
    for (int i = 0 ; i < bandList.getModel().getSize() ; i++) {
        String string = (String) bandList.getModel().getElementAt(i);
        referenceCombo.addItem(string);
        if (string.equals(_oldSelected)) {
            referenceCombo.setSelectedItem(string);
        }
    }

    //enable or disable referenceCombo depending on sourceProduct
    if(sourceProducts == null || sourceProducts.length == 0 || !sourceProducts[0].isMultiSize()) {
        referenceCombo.setEnabled(false);
    } else {
        referenceCombo.setEnabled(true);
    }

    final Rectangle region = (Rectangle)paramMap.get("region");
    if(region != null) {
        regionX.setText(String.valueOf(region.x));
        regionY.setText(String.valueOf(region.y));
        width.setText(String.valueOf(region.width));
        height.setText(String.valueOf(region.height));
    }
    if (sourceProducts != null && sourceProducts.length > 0) {
        if (region == null || region.width == 0)
            width.setText(String.valueOf(sourceProducts[0].getSceneRasterWidth()));
        if (region == null || region.height == 0)
            height.setText(String.valueOf(sourceProducts[0].getSceneRasterHeight()));

        worldMapUI.getModel().setAutoZoomEnabled(true);
        worldMapUI.getModel().setProducts(sourceProducts);
        worldMapUI.getModel().setSelectedProduct(sourceProducts[0]);
        worldMapUI.getWorlMapPane().zoomToProduct(sourceProducts[0]);
    }

    Integer subSamplingXVal = (Integer) paramMap.get("subSamplingX");
    if(subSamplingXVal != null) {
        subSamplingX.setText(subSamplingXVal.toString());
    }
    Integer subSamplingYVal = (Integer) paramMap.get("subSamplingY");
    if(subSamplingYVal != null) {
        subSamplingY.setText(subSamplingYVal.toString());
    }

    geoRegion = (Geometry) paramMap.get("geoRegion");
    if (geoRegion != null) {

        final Coordinate coord[] = geoRegion.getCoordinates();
        worldMapUI.setSelectionStart((float) coord[0].y, (float) coord[0].x);
        worldMapUI.setSelectionEnd((float) coord[2].y, (float) coord[2].x);

        getGeoRegion();

        geoCoordRadio.setSelected(true);
        pixelPanel.setVisible(false);
        geoPanel.setVisible(true);
    }
}
 
Example 19
Source File: GeometryHullTool.java    From geowave with Apache License 2.0 4 votes vote down vote up
/**
 * 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
 */
public Geometry concaveHullParkOhMethod(
    final Geometry geometry,
    final Collection<Coordinate> providedInnerPoints) {

  final Set<Coordinate> innerPoints = new HashSet<>(providedInnerPoints);
  final TreeSet<Edge> edges = new TreeSet<>();
  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 (FloatCompareUtils.checkDoublesEqual(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));
}
 
Example 20
Source File: GeometrySimpOptionProvider.java    From geowave with Apache License 2.0 4 votes vote down vote up
public Geometry simplifyGeometry(final Geometry geom) {
  if (geom.getCoordinates().length > simpVertMin) {
    return DouglasPeuckerSimplifier.simplify(geom, tolerance);
  }
  return geom;
}