GEOSCoordSequence *Geometry::ApplyPointTransformationToCoordSequence(PointTransformer *t, const GEOSCoordSequence *seq) { GEOSCoordSequence *ret = GEOSCoordSeq_clone(seq); unsigned int sz; GEOSCoordSeq_getSize(ret, &sz); for (unsigned int i = 0; i < sz; i++) { double x, y; GEOSCoordSeq_getX(ret, i, &x); GEOSCoordSeq_getY(ret, i, &y); t->Transform(&x, &y, NULL); GEOSCoordSeq_setX(ret, i, x); GEOSCoordSeq_setY(ret, i, y); } return ret; }
GEOSGeometry* LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in) { GEOSGeometry *tmp; GEOSGeometry *geos_result, *shp; GEOSGeometry const *vgeoms[1]; uint32_t i, ngeoms; int srid = GEOSGetSRID(geom_in); vgeoms[0] = geom_in; geos_result = GEOSPolygonize(vgeoms, 1); LWDEBUGF(3, "GEOSpolygonize returned @ %p", geos_result); /* Null return from GEOSpolygonize (an exception) */ if ( ! geos_result ) return 0; /* * We should now have a collection */ #if PARANOIA_LEVEL > 0 if ( GEOSGeometryTypeId(geos_result) != COLLECTIONTYPE ) { GEOSGeom_destroy(geos_result); lwerror("Unexpected return from GEOSpolygonize"); return 0; } #endif ngeoms = GEOSGetNumGeometries(geos_result); LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms); LWDEBUGF(3, "GEOSpolygonize: polygonized:%s", lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0))); /* * No geometries in collection, early out */ if ( ngeoms == 0 ) { GEOSSetSRID(geos_result, srid); return geos_result; } /* * Return first geometry if we only have one in collection, * to avoid the unnecessary Geometry clone below. */ if ( ngeoms == 1 ) { tmp = (GEOSGeometry *)GEOSGetGeometryN(geos_result, 0); if ( ! tmp ) { GEOSGeom_destroy(geos_result); return 0; /* exception */ } shp = GEOSGeom_clone(tmp); GEOSGeom_destroy(geos_result); /* only safe after the clone above */ GEOSSetSRID(shp, srid); return shp; } /* * Iteratively invoke symdifference on outer rings * as suggested by Carl Anderson: * postgis-devel/2005-December/001805.html */ shp = NULL; for (i=0; i<ngeoms; ++i) { GEOSGeom extring; GEOSCoordSeq sq; /* * Construct a Polygon from geometry i exterior ring * We don't use GEOSGeom_clone on the ExteriorRing * due to a bug in CAPI contained in GEOS 2.2 branch * failing to properly return a LinearRing from * a LinearRing clone. */ sq=GEOSCoordSeq_clone(GEOSGeom_getCoordSeq( GEOSGetExteriorRing(GEOSGetGeometryN( geos_result, i)) )); extring = GEOSGeom_createPolygon( GEOSGeom_createLinearRing(sq), NULL, 0 ); if ( extring == NULL ) /* exception */ { lwerror("GEOSCreatePolygon threw an exception"); return 0; } if ( shp == NULL ) { shp = extring; LWDEBUGF(3, "GEOSpolygonize: shp:%s", lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0))); } else { tmp = GEOSSymDifference(shp, extring); LWDEBUGF(3, "GEOSpolygonize: SymDifference(%s, %s):%s", lwgeom_to_ewkt(GEOS2LWGEOM(shp, 0)), lwgeom_to_ewkt(GEOS2LWGEOM(extring, 0)), lwgeom_to_ewkt(GEOS2LWGEOM(tmp, 0)) ); GEOSGeom_destroy(shp); GEOSGeom_destroy(extring); shp = tmp; } } GEOSGeom_destroy(geos_result); GEOSSetSRID(shp, srid); return shp; }
void VertexSnapper::snapVertices(MyGEOSGeom *geom, GEOSCoordSequence *closeCoord) { qDebug("VertexSnapper::snapVertices: ENTERING SNAP VERTICES"); // tested geometry as coordination sequence //GEOSGeometry* points = GEOSGeom_extractUniquePoints( geom->getGEOSGeom() ); const GEOSCoordSequence *s = GEOSGeom_getCoordSeq( geom->getGEOSGeom() ); GEOSCoordSequence *coord = GEOSCoordSeq_clone( s ); qDebug("VertexSnapper::snapVertices: GEOSCoordSequence cloned from geom Geometry"); // get dimension of geometry int dim = GEOSGeom_getDimensions( geom->getGEOSGeom() ); // get number of points unsigned int cSize; GEOSCoordSeq_getSize( coord, &cSize ); unsigned int ccSize; GEOSCoordSeq_getSize( closeCoord, &ccSize ); // find closest point from closeCoord for ( unsigned int i = 0; i < cSize; i++) { // get point from coordinate sequence double x, y; GEOSCoordSeq_getX( coord, i, &x); GEOSCoordSeq_getY( coord, i, &y); GEOSCoordSequence *point = GEOSCoordSeq_create( 1, dim ); GEOSCoordSeq_setX( point, 0, x); GEOSCoordSeq_setY( point, 0, y); GEOSGeometry * pointGeom = GEOSGeom_createPoint( point ); // minimal distance double minDist = tolDistance;// = coord->getAt(i).distance( closeCoord.getAt(0) ); unsigned int indMin = 0; bool isMin = false; for ( unsigned int j = 0; j < ccSize; j++ ) { // get point from coordinate sequence double xx, yy; GEOSCoordSeq_getX( closeCoord, j, &xx); GEOSCoordSeq_getY( closeCoord, j, &yy); GEOSCoordSequence *pointj = GEOSCoordSeq_create( 1, dim ); GEOSCoordSeq_setX( pointj, 0, xx); GEOSCoordSeq_setY( pointj, 0, yy); GEOSGeometry * pointGeomj = GEOSGeom_createPoint( pointj ); // compute distance between two tested points double dist = GEOSDistance( pointGeomj, pointGeom, &minDist ); //coord->getAt(i).distance( closeCoord.getAt(j) ); if( dist <= minDist ) { minDist = dist; indMin = j; isMin = true; } GEOSGeom_destroy(pointGeomj); } // set new coordinate to the closest point if there is some if ( isMin ) { double newX, newY; GEOSCoordSeq_getX( closeCoord, indMin, &newX); GEOSCoordSeq_getY( closeCoord, indMin, &newY); GEOSCoordSeq_setX( coord, i, newX); GEOSCoordSeq_setY( coord, i, newY); //coord->setAt( closeCoord.getAt(indMin), i ); } //GEOSCoordSeq_destroy(point); GEOSGeom_destroy(pointGeom); } // edit geometry editGeometry( geom, coord); //GEOSCoordSeq_destroy(coord); //GEOSCoordSeq_destroy(point0); //GEOSGeom_destroy(pointGeom0); } // MyGEOSGeom& VertexSnapper::snapVertices(MyGEOSGeom &geom, CoordinateSequence &closeCoord)