char *msudf_pointOnSurface(UDF_INIT *initid,UDF_ARGS *args, char *buf, unsigned long *length, char *is_null, char *error) { char *result; GEOSGeom geom1,geom2; DEBUG("msudf_pointOnSurface"); geom1 = msudf_getGeometry((unsigned char *)args->args[0],args->lengths[0]); if (geom1 == NULL) { strcpy(error,"Invalid geometry."); *is_null = 1; return NULL; } geom2 = GEOSPointOnSurface(geom1); if (geom2 != NULL) { GEOSSetSRID(geom2,GEOSGetSRID(geom1)); result = msudf_returnGeometry(initid,length,geom2); GEOSGeom_destroy(geom1); GEOSGeom_destroy(geom2); return result; } else { GEOSGeom_destroy(geom1); *is_null = 1; return NULL; } }
int OGRPolygon::PointOnSurface( OGRPoint *poPoint ) const { if( poPoint == NULL ) return OGRERR_FAILURE; #ifndef HAVE_GEOS return OGRERR_FAILURE; #else GEOSGeom hThisGeosGeom = NULL; GEOSGeom hOtherGeosGeom = NULL; hThisGeosGeom = exportToGEOS(); if( hThisGeosGeom != NULL ) { hOtherGeosGeom = GEOSPointOnSurface( hThisGeosGeom ); GEOSGeom_destroy( hThisGeosGeom ); if( hOtherGeosGeom == NULL ) return OGRERR_FAILURE; OGRGeometry *poInsidePointGeom = (OGRGeometry *) OGRGeometryFactory::createFromGEOS( hOtherGeosGeom ); GEOSGeom_destroy( hOtherGeosGeom ); if (poInsidePointGeom == NULL) return OGRERR_FAILURE; if (wkbFlatten(poInsidePointGeom->getGeometryType()) != wkbPoint) { delete poInsidePointGeom; return OGRERR_FAILURE; } OGRPoint *poInsidePoint = (OGRPoint *) poInsidePointGeom; poPoint->setX( poInsidePoint->getX() ); poPoint->setY( poInsidePoint->getY() ); delete poInsidePointGeom; return OGRERR_NONE; } else { return OGRERR_FAILURE; } #endif /* HAVE_GEOS */ }
void object::test<2>() { geom1_ = GEOSGeomFromWKT("LINESTRING(0 0, 5 0, 10 0)"); ensure( 0 != geom1_ ); geom2_ = GEOSPointOnSurface(geom1_); ensure( 0 != geom2_ ); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); ensure_equals(std::string(wkt_), std::string( "POINT (5 0)")); }
void object::test<3>() { geom1_ = GEOSGeomFromWKT("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))"); ensure( 0 != geom1_ ); geom2_ = GEOSPointOnSurface(geom1_); ensure( 0 != geom2_ ); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); ensure_equals(std::string(wkt_), std::string( "POINT (5 5)")); }
/* Initializes and uses GEOS internally */ static LWGEOM* lwpoly_split_by_line(const LWPOLY* lwpoly_in, const LWLINE* blade_in) { LWCOLLECTION* out; GEOSGeometry* g1; GEOSGeometry* g2; GEOSGeometry* g1_bounds; GEOSGeometry* polygons; const GEOSGeometry *vgeoms[1]; int i,n; int hasZ = FLAGS_GET_Z(lwpoly_in->flags); /* Possible outcomes: * * 1. The line does not split the polygon * -> Return a collection with single element * 2. The line does split the polygon * -> Return a collection of all elements resulting from the split */ initGEOS(lwgeom_geos_error, lwgeom_geos_error); g1 = LWGEOM2GEOS((LWGEOM*)lwpoly_in, 0); if ( NULL == g1 ) { lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg); return NULL; } g1_bounds = GEOSBoundary(g1); if ( NULL == g1_bounds ) { GEOSGeom_destroy(g1); lwerror("GEOSBoundary: %s", lwgeom_geos_errmsg); return NULL; } g2 = LWGEOM2GEOS((LWGEOM*)blade_in, 0); if ( NULL == g2 ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g1_bounds); lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg); return NULL; } vgeoms[0] = GEOSUnion(g1_bounds, g2); if ( NULL == vgeoms[0] ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); lwerror("GEOSUnion: %s", lwgeom_geos_errmsg); return NULL; } polygons = GEOSPolygonize(vgeoms, 1); if ( NULL == polygons ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); lwerror("GEOSPolygonize: %s", lwgeom_geos_errmsg); return NULL; } #if PARANOIA_LEVEL > 0 if ( GEOSGeomTypeId(polygons) != COLLECTIONTYPE ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); lwerror("%s [%s] Unexpected return from GEOSpolygonize", __FILE__, __LINE__); return 0; } #endif /* We should now have all polygons, just skip * the ones which are in holes of the original * geometries and return the rest in a collection */ n = GEOSGetNumGeometries(polygons); out = lwcollection_construct_empty(COLLECTIONTYPE, lwpoly_in->srid, hasZ, 0); /* Allocate space for all polys */ out->geoms = lwrealloc(out->geoms, sizeof(LWGEOM*)*n); assert(0 == out->ngeoms); for (i=0; i<n; ++i) { GEOSGeometry* pos; /* point on surface */ const GEOSGeometry* p = GEOSGetGeometryN(polygons, i); int contains; pos = GEOSPointOnSurface(p); if ( ! pos ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); lwerror("GEOSPointOnSurface: %s", lwgeom_geos_errmsg); return NULL; } contains = GEOSContains(g1, pos); if ( 2 == contains ) { GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); GEOSGeom_destroy(pos); lwerror("GEOSContains: %s", lwgeom_geos_errmsg); return NULL; } GEOSGeom_destroy(pos); if ( 0 == contains ) { /* Original geometry doesn't contain * a point in this ring, must be an hole */ continue; } out->geoms[out->ngeoms++] = GEOS2LWGEOM(p, hasZ); } GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); GEOSGeom_destroy(g1_bounds); GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]); GEOSGeom_destroy(polygons); return (LWGEOM*)out; }
// Tiny triangle, see http://trac.osgeo.org/geos/ticket/559 template<> template<> void object::test<4>() { geom1_ = GEOSGeomFromWKT( "POLYGON(( \ 56.528666666700 25.2101666667, \ 56.529000000000 25.2105000000, \ 56.528833333300 25.2103333333, \ 56.528666666700 25.2101666667))"); ensure( 0 != geom1_ ); geom2_ = GEOSPointOnSurface(geom1_); ensure( 0 != geom2_ ); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); ensure_equals(std::string(wkt_), std::string( "POINT (56.528917 25.210417)" ) ); } // Empty geometry -- see http://trac.osgeo.org/geos/ticket/560 template<> template<> void object::test<5>() { geom1_ = GEOSGeomFromWKT("LINESTRING EMPTY");