Removes duplicated coordinates within a MultiPolygon.

@param multiPolygon
@param tolerance to delete the coordinates
@return
@throws java.sql.SQLException
174172
public static MultiPolygon removeDuplicateCoordinates(MultiPolygon multiPolygon, double tolerance) throws SQLException {
        ArrayList<Polygon> polys = new ArrayList<Polygon>();
        for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
            Polygon poly = (Polygon) multiPolygon.getGeometryN(i);
            polys.add(removeDuplicateCoordinates(poly, tolerance));
        }
        return FACTORY.createMultiPolygon(GeometryFactory.toPolygonArray(polys));
    }
598938
private MultiPoint parseMultiPoint(JsonParser jp) throws IOException, SQLException {
        jp.nextToken(); // FIELD_NAME coordinates        
        String coordinatesField = jp.getText();
        if (coordinatesField.equalsIgnoreCase(GeoJsonField.COORDINATES)) {
            jp.nextToken(); // START_ARRAY [ coordinates
            MultiPoint mPoint = GF.createMultiPoint(parseCoordinates(jp));
            jp.nextToken();//END_OBJECT } geometry
            return mPoint;
        } else {
            throw new SQLException("Malformed GeoJSON file. Expected 'coordinates', found '" + coordinatesField + "'");
        }
    }
800103
private static String multiPolygonCoordinatesFromWkt(String wkt) {
        wkt = removeBrackets(wkt,1);
        String polygonsWithPipeSeparator = wkt.replaceAll("\\s*\\)\\s*\\)\\s*,\\s*\\(\\s*\\(\\s*","))|((");
        String[] polygons = polygonsWithPipeSeparator.split("\\|");
        String[] polygonsCoordinates = new String[polygons.length];
        for (int i=0;i<polygons.length;i++){
            polygonsCoordinates[i] = polygonCoordinatesFromWkt(polygons[i]);
        }
        String coordinates = Joiner.on(",").join(polygonsCoordinates);
        return String.format("[%s]", coordinates);
    }
521486
function polygonRemoveDuplicatePoints(polygon, precision){
    for(var i=polygon.length-1; i>=1; --i){
        var pi = polygon[i];
        for(var j=i-1; j>=0; --j){
            if(points_eq(pi, polygon[j], precision)){
                polygon.splice(i,1);
                continue;
            }
        }
    }
}
656439
public static MultiPolygon removeHolesMultiPolygon(MultiPolygon multiPolygon) {
        int num = multiPolygon.getNumGeometries();
        Polygon[] polygons = new Polygon[num];
        for (int i = 0; i < num; i++) {
            polygons[i] = removeHolesPolygon((Polygon) multiPolygon.getGeometryN(i));
        }
        return multiPolygon.getFactory().createMultiPolygon(polygons);
    }
1249620
private static boolean polygonDisjointMultiPoint_(Polygon polygon_a,
			MultiPoint multipoint_b, double tolerance,
			boolean bIncludeBoundaryA, ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint,
		// or if one is contained in the other.
		int relation = tryRasterizedContainsOrDisjoint_(polygon_a,
				multipoint_b, tolerance, false);

		if (relation == Relation.disjoint)
			return true;

		if (relation == Relation.contains)
			return false;

		Envelope2D env_a_inflated = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a_inflated);
		env_a_inflated.inflate(tolerance, tolerance);
		Point2D ptB = new Point2D();

		for (int i = 0; i < multipoint_b.getPointCount(); i++) {
			multipoint_b.getXY(i, ptB);

			if (!env_a_inflated.contains(ptB))
				continue;

			PolygonUtils.PiPResult result = PolygonUtils.isPointInPolygon2D(
					polygon_a, ptB, tolerance);

			if (result == PolygonUtils.PiPResult.PiPInside
					|| (bIncludeBoundaryA && result == PolygonUtils.PiPResult.PiPBoundary))
				return false;
		}

		return true;
	}
254840
public static MultiPoint removeCoordinates(MultiPoint g) {
        Coordinate[] coords = CoordinateUtils.removeDuplicatedCoordinates(g.getCoordinates(),false);
        return FACTORY.createMultiPoint(coords);
    }
371505
public MultiPolygon createMultiPolygon(Polygon[] polygons) {
		if (polygons == null) {
			return new MultiPolygon(srid, precision);
		}
		Polygon[] clones = new Polygon[polygons.length];
		for (int i = 0; i < polygons.length; i++) {
			clones[i] = (Polygon) polygons[i].clone();
		}
		return new MultiPolygon(srid, precision, clones);
	}
1163938
private static void makeEnvelopes(Statement st, double tolerance, boolean isH2, int srid) throws SQLException {
        st.execute("DROP TABLE IF EXISTS"+ PTS_TABLE + ";");
        if (tolerance > 0) {
            LOGGER.info("Calculating envelopes around coordinates...");            
            if (isH2) {
                // Putting all points and their envelopes together...
                st.execute("CREATE  TABLE "+ PTS_TABLE +"( "
                        + "ID SERIAL PRIMARY KEY, "
                        + "THE_GEOM POINT, "
                        + "AREA POLYGON "
                        + ") AS "
                        + "SELECT NULL, START_POINT, START_POINT_EXP FROM "+ COORDS_TABLE
                        + " UNION ALL "
                        + "SELECT NULL, END_POINT, END_POINT_EXP FROM "+ COORDS_TABLE+";");
                // Putting a spatial index on the envelopes...
                st.execute("CREATE SPATIAL INDEX ON "+ PTS_TABLE +"(AREA);");
            } else {
                // Putting all points and their envelopes together...
                st.execute("CREATE  TABLE "+ PTS_TABLE + "( ID SERIAL PRIMARY KEY, "
                        + "THE_GEOM GEOMETRY(POINT,"+srid+"),"
                        + "AREA GEOMETRY(POLYGON, "+srid+")"
                        + ") ");
                 st.execute("INSERT INTO " + PTS_TABLE +" (SELECT (row_number() over())::int , a.THE_GEOM, A.AREA FROM  "
                        + "(SELECT  START_POINT AS THE_GEOM, START_POINT_EXP as AREA FROM "+ COORDS_TABLE
                        + " UNION ALL "
                        + "SELECT  END_POINT AS THE_GEOM, END_POINT_EXP as AREA FROM "+ COORDS_TABLE+") as a);");
                // Putting a spatial index on the envelopes...
                st.execute("CREATE INDEX ON "+ PTS_TABLE +" USING GIST(AREA);");
            }
        } else {
            LOGGER.info("Preparing temporary nodes table from coordinates...");
            if (isH2) {
                // If the tolerance is zero, we just put all points together
                st.execute("CREATE  TABLE "+ PTS_TABLE +"( "
                        + "ID SERIAL PRIMARY KEY, "
                        + "THE_GEOM POINT"
                        + ") AS "
                        + "SELECT NULL, START_POINT FROM "+ COORDS_TABLE
                        + " UNION ALL "
                        + "SELECT NULL, END_POINT FROM "+ COORDS_TABLE+";");
                // Putting a spatial index on the points themselves...
                st.execute("CREATE SPATIAL INDEX ON "+ PTS_TABLE +"(THE_GEOM);");
            } else {
                // If the tolerance is zero, we just put all points together
                st.execute("CREATE  TABLE "+ PTS_TABLE +"( "
                        + "ID SERIAL PRIMARY KEY, "
                        + "THE_GEOM GEOMETRY(POINT,"+srid+")"
                        + ")");
                st.execute("INSERT INTO "+ PTS_TABLE +" (SELECT (row_number() over())::int , a.the_geom FROM "
                        + "(SELECT  START_POINT as THE_GEOM FROM "+ COORDS_TABLE
                        + " UNION ALL "
                        + "SELECT  END_POINT as THE_GEOM FROM "+ COORDS_TABLE+") as a);");
                // Putting a spatial index on the points themselves...
                st.execute("CREATE INDEX ON "+ PTS_TABLE + " USING GIST(THE_GEOM);");
            }            
        }
    }
488097
function( tolerance ){
            //if tolerance is 0, it will be faster to just use 'equals' method
            var equals = tolerance ? 'equalsWithTolerance' : 'equals';
            var p, prev, i = 0, num = this.vertices.length;
            var last;
            for( ; i<num; i++ ){
                p = this.vertices[i];
                //if its the 'equals' method tolerance will just be ingored
                if( p[equals]( prev, tolerance ) ){
                    //remove from array, step back counter
                    this.vertices.splice( i, 1 );
                    i--;
                    num--;
                } else {
                    prev = p;
                }
            }
            num = this.vertices.length;
            if( num >  0 ){
                last = this.vertices[num-1];
                if( last[equals]( this.vertices[0], tolerance ) ){
                    this.vertices.splice( num-1, 1 );
                }
            }
            return this;
        }
1345720
static boolean polygonRelateMultiPoint_(Polygon polygon_a,
			MultiPoint multipoint_b, double tolerance, String scl,
			ProgressTracker progress_tracker) {
		RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
		relOps.resetMatrix_();
		relOps.setPredicates_(scl);
		relOps.setAreaPointPredicates_();

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		polygon_a.queryEnvelope2D(env_a);
		multipoint_b.queryEnvelope2D(env_b);

		boolean bRelationKnown = false;
		boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
				env_a, env_b, tolerance, progress_tracker);

		if (b_disjoint) {
			relOps.areaPointDisjointPredicates_(polygon_a);
			bRelationKnown = true;
		}

		if (!bRelationKnown) {
			// Quick rasterize test to see whether the the geometries are
			// disjoint, or if one is contained in the other.
			int relation = RelationalOperations
					.tryRasterizedContainsOrDisjoint_(polygon_a, multipoint_b,
							tolerance, false);

			if (relation == RelationalOperations.Relation.disjoint) {
				relOps.areaPointDisjointPredicates_(polygon_a);
				bRelationKnown = true;
			} else if (relation == RelationalOperations.Relation.contains) {
				relOps.areaPointContainsPredicates_(polygon_a);
				bRelationKnown = true;
			}
		}

		if (!bRelationKnown) {
			EditShape edit_shape = new EditShape();
			int geom_a = edit_shape.addGeometry(polygon_a);
			int geom_b = edit_shape.addGeometry(multipoint_b);
			relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
					progress_tracker);
			relOps.computeMatrixTopoGraphClusters_(geom_a, geom_b);
			relOps.m_topo_graph.removeShape();
		}

		boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
		return bRelation;
	}
1029527
private static MultiLineString splitLineWithPoint(LineString line, Point pointToSplit, double tolerance) {
        return FACTORY.createMultiLineString(splitLineStringWithPoint(line, pointToSplit, tolerance));
    }
312273
public static LinearRing removeDuplicateCoordinates(LinearRing linearRing, double tolerance) {
        Coordinate[] coords = CoordinateUtils.removeRepeatedCoordinates(linearRing.getCoordinates(), tolerance, true);
        return FACTORY.createLinearRing(coords);
    }
1126397
static boolean multiPointRelateMultiPoint_(MultiPoint multipoint_a,
			MultiPoint multipoint_b, double tolerance, String scl,
			ProgressTracker progress_tracker) {
		RelationalOperationsMatrix relOps = new RelationalOperationsMatrix();
		relOps.resetMatrix_();
		relOps.setPredicates_(scl);
		relOps.setPointPointPredicates_();

		Envelope2D env_a = new Envelope2D(), env_b = new Envelope2D();
		multipoint_a.queryEnvelope2D(env_a);
		multipoint_b.queryEnvelope2D(env_b);

		boolean bRelationKnown = false;
		boolean b_disjoint = RelationalOperations.envelopeDisjointEnvelope_(
				env_a, env_b, tolerance, progress_tracker);

		if (b_disjoint) {
			relOps.pointPointDisjointPredicates_();
			bRelationKnown = true;
		}

		if (!bRelationKnown) {
			EditShape edit_shape = new EditShape();
			int geom_a = edit_shape.addGeometry(multipoint_a);
			int geom_b = edit_shape.addGeometry(multipoint_b);
			relOps.setEditShapeCrackAndCluster_(edit_shape, tolerance,
					progress_tracker);
			relOps.computeMatrixTopoGraphClusters_(geom_a, geom_b);
			relOps.m_topo_graph.removeShape();
		}

		boolean bRelation = relationCompare_(relOps.m_matrix, relOps.m_scl);
		return bRelation;
	}
1103363
static boolean linearPathIntersectsPoint_(MultiPath multipathA,
			Point2D ptB, double tolerance) {
		Point2D closest = new Point2D();
		double toleranceSq = tolerance * tolerance;
		SegmentIteratorImpl segIterA = ((MultiPathImpl) multipathA._getImpl())
				.querySegmentIterator();

		GeometryAccelerators accel = ((MultiPathImpl) multipathA._getImpl())
				._getAccelerators();

		if (accel != null) {
			QuadTreeImpl quadTreeA = accel.getQuadTree();
			if (quadTreeA != null) {
				Envelope2D env_b = new Envelope2D();
				env_b.setCoords(ptB);

				QuadTreeImpl.QuadTreeIteratorImpl qt_iter = quadTreeA
						.getIterator(env_b, tolerance);

				for (int e = qt_iter.next(); e != -1; e = qt_iter.next()) {
					segIterA.resetToVertex(quadTreeA.getElement(e));

					if (segIterA.hasNextSegment()) {
						Segment segmentA = segIterA.nextSegment();

						double t = segmentA.getClosestCoordinate(ptB, false);
						segmentA.getCoord2D(t, closest);

						if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
							return true;
						}
					}
				}

				return false;
			}
		}
		Envelope2D env_a = new Envelope2D();

		while (segIterA.nextPath()) {
			while (segIterA.hasNextSegment()) {
				Segment segmentA = segIterA.nextSegment();
				segmentA.queryEnvelope2D(env_a);
				env_a.inflate(tolerance, tolerance);

				if (!env_a.contains(ptB)) {
					continue;
				}

				double t = segmentA.getClosestCoordinate(ptB, false);
				segmentA.getCoord2D(t, closest);

				if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
					return true;
				}
			}
		}

		return false;
	}
287456
private static boolean multiPointRelateMultiPoint_(MultiPoint multipoint_a,
			MultiPoint multipoint_b, double tolerance, int relation,
			ProgressTracker progress_tracker) {
		switch (relation) {
		case Relation.disjoint:
			return multiPointDisjointMultiPoint_(multipoint_a, multipoint_b,
					tolerance, progress_tracker);

		case Relation.within:
			return multiPointContainsMultiPoint_(multipoint_b, multipoint_a,
					tolerance, progress_tracker);

		case Relation.contains:
			return multiPointContainsMultiPoint_(multipoint_a, multipoint_b,
					tolerance, progress_tracker);

		case Relation.equals:
			return multiPointEqualsMultiPoint_(multipoint_a, multipoint_b,
					tolerance, progress_tracker);

		case Relation.overlaps:
			return multiPointOverlapsMultiPoint_(multipoint_a, multipoint_b,
					tolerance, progress_tracker);

		default:
			break; // warning fix
		}

		return false;
	}
1272525
static boolean _isRingInRing2D(MultiPath polygon, int iRing1, int iRing2,
			double tolerance, QuadTree quadTree) {
		MultiPathImpl polygonImpl = (MultiPathImpl) polygon._getImpl();
		SegmentIteratorImpl segIter = polygonImpl.querySegmentIterator();
		segIter.resetToPath(iRing1);
		if (!segIter.nextPath() || !segIter.hasNextSegment())
			throw new GeometryException("corrupted geometry");

		int res = 2;

		while (res == 2 && segIter.hasNextSegment()) {
			Segment segment = segIter.nextSegment();
			Point2D point = segment.getCoord2D(0.5);
			res = PointInPolygonHelper.isPointInRing(polygonImpl, iRing2,
					point, tolerance, quadTree);
		}

		if (res == 2)
			throw GeometryException.GeometryInternalError();
		if (res == 1)
			return true;

		return false;
	}