void object::test<11> () { // Coincident vertext at -753.167968418005 93709.4279185742 //POLYGON ((-753.167968418005 93754.0955183194,-816.392328351464 93754.0955183194,-816.392328351464 93709.4279185742,-753.167968418005 93709.4279185742,-753.167968418005 93754.0955183194)) std::string const outer("01030000800100000005000000bd70d3ff578987c09e373e87a1e3f6400000000000000000a9f60b7d238389c09e373e87a1e3f6400000000000000000a9f60b7d238389c09625c1d8d6e0f6400000000000000000bd70d3ff578987c09625c1d8d6e0f6400000000000000000bd70d3ff578987c09e373e87a1e3f6400000000000000000"); //POLYGON ((-753.167968418005 93747.6909727677,-799.641978447015 93747.6909727677,-799.641978447015 93709.4279185742,-753.167968418005 93709.4279185742,-753.167968418005 93747.6909727677)) std::string const inner("01030000800100000005000000bd70d3ff578987c0f875390e3be3f6400000000000000000579598c522fd88c0f875390e3be3f6400000000000000000579598c522fd88c09625c1d8d6e0f6400000000000000000bd70d3ff578987c09625c1d8d6e0f6400000000000000000bd70d3ff578987c0f875390e3be3f6400000000000000000"); // A contains B if precision is limited to 1e+10 { geos::geom::PrecisionModel pm(1e+10); geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create(&pm); geos::io::WKBReader reader(*factory); std::istringstream sOuter(outer); geom1_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sOuter)); std::istringstream sInner(inner); geom2_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sInner)); ensure(nullptr != geom1_); ensure(nullptr != geom2_); prepGeom1_ = GEOSPrepare(geom1_); ensure(nullptr != prepGeom1_); int ret = GEOSPreparedContains(prepGeom1_, geom2_); ensure_equals(ret, 1); ret = GEOSPreparedContainsProperly(prepGeom1_, geom2_); ensure_equals(ret, 0); GEOSGeom_destroy(geom1_); GEOSGeom_destroy(geom2_); GEOSPreparedGeom_destroy(prepGeom1_); } // A contains B if FLOATING PM is used with extended precision { geos::geom::PrecisionModel pm; geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create(&pm); geos::io::WKBReader reader(*factory); std::istringstream sOuter(outer); geom1_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sOuter)); std::istringstream sInner(inner); geom2_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sInner)); ensure(nullptr != geom1_); ensure(nullptr != geom2_); prepGeom1_ = GEOSPrepare(geom1_); ensure(nullptr != prepGeom1_); int ret = GEOSPreparedContains(prepGeom1_, geom2_); ensure_equals(ret, 1); ret = GEOSPreparedContainsProperly(prepGeom1_, geom2_); ensure_equals(ret, 0); } }
void object::test<10> () { // Coincident vertives of both polygons at // -700.67089999181 93743.4218587986, -713.450135807349 93754.1677576647, std::string const outer("01030000800100000009000000af9dd0005ee585c0f802efbff6e2f6400000000000000000955acde0994b86c039a922afa2e3f64000000000000000002af6fb4f5d1887c07adb1c4071e3f6400000000000000000e5962b388d4f87c0bd3aeda7bae2f640000000000000000087c61344030887c07d585e6ff6e1f6400000000000000000fc8a31b5166186c0230588b20ae1f640000000000000000034733daf050186c0ed9f3ac98ae1f6400000000000000000f190aef659b385c0df2876538ce2f6400000000000000000af9dd0005ee585c0f802efbff6e2f6400000000000000000"); std::string const inner("0103000080010000000a000000ac21f88bbaff86c05f45d8c7b4e2f6400000000000000000467f1177ebf386c05de1971187e2f6400000000000000000fcf677888fc886c04e855a544be2f6400000000000000000c61226e540b686c0c0662d1fe7e1f640000000000000000042dc1bece8a486c09b85529f8ae1f6400000000000000000891047cde55e86c038cfa59c4ee1f6400000000000000000ae9dd0005ee585c0fa02efbff6e2f6400000000000000000975acde0994b86c038a922afa2e3f6400000000000000000287e339b09f986c01b1a083a10e3f6400000000000000000ac21f88bbaff86c05f45d8c7b4e2f6400000000000000000"); // A contains B if precision is limited to 1e+10 { geos::geom::PrecisionModel pm(1e+10); // NOTE: higher precision fails this test case geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create(&pm); geos::io::WKBReader reader(*factory); std::istringstream sOuter(outer); geom1_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sOuter)); std::istringstream sInner(inner); geom2_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sInner)); ensure(nullptr != geom1_); ensure(nullptr != geom2_); prepGeom1_ = GEOSPrepare(geom1_); ensure(nullptr != prepGeom1_); int ret = GEOSPreparedContains(prepGeom1_, geom2_); ensure_equals(ret, 1); ret = GEOSPreparedContainsProperly(prepGeom1_, geom2_); ensure_equals(ret, 0); GEOSGeom_destroy(geom1_); GEOSGeom_destroy(geom2_); GEOSPreparedGeom_destroy(prepGeom1_); } // A does NOT contain B if precision is extended to 1e+11 or beyond { geos::geom::PrecisionModel pm(1e+11); geos::geom::GeometryFactory::Ptr factory = geos::geom::GeometryFactory::create(&pm); geos::io::WKBReader reader(*factory); std::istringstream sOuter(outer); geom1_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sOuter)); std::istringstream sInner(inner); geom2_ = reinterpret_cast<GEOSGeometry*>(reader.readHEX(sInner)); ensure(nullptr != geom1_); ensure(nullptr != geom2_); prepGeom1_ = GEOSPrepare(geom1_); ensure(nullptr != prepGeom1_); int ret = GEOSPreparedContains(prepGeom1_, geom2_); ensure_equals(ret, 0); ret = GEOSPreparedContainsProperly(prepGeom1_, geom2_); ensure_equals(ret, 0); } }
void object::test<6> () { geom1_ = GEOSGeomFromWKT("POLYGON((0 0, 0 10, 10 11, 10 0, 0 0))"); geom2_ = GEOSGeomFromWKT("POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))"); prepGeom1_ = GEOSPrepare(geom1_); ensure(nullptr != prepGeom1_); int ret = GEOSPreparedContains(prepGeom1_, geom2_); ensure_equals(ret, 1); }
int main(void) { GEOSWKTReader *reader; GEOSGeometry *mp; GEOSGeometry *p; const GEOSPreparedGeometry *prep_mp; unsigned long int i; unsigned long int count = 1e6; initGEOS(NULL, NULL); reader = GEOSWKTReader_create(); mp = GEOSWKTReader_read(reader, "MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))"); p = GEOSWKTReader_read(reader, "POLYGON((2 2, 6 2, 6 6, 2 6, 2 2))"); assert(GEOSisValid(mp)); assert(GEOSisValid(p)); prep_mp = GEOSPrepare(mp); for (i=0; i<count; i++) { if ( !(i%100) ) printf("%lu iterations\n", i); /* does not leak */ /* GEOSContains(mp, p); */ /* leaks */ GEOSPreparedContains(prep_mp, p); } printf("%lu iterations (END)\n", i); return 0; }
Datum containsPrepared(PG_FUNCTION_ARGS) { #ifndef PREPARED_GEOM elog(ERROR,"Not implemented in this version!"); PG_RETURN_NULL(); #else PG_LWGEOM * geom1; PG_LWGEOM * geom2; bool result; BOX2DFLOAT4 box1, box2; PrepGeomCache * prep_cache; int32 key1; geom1 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); geom2 = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); key1 = PG_GETARG_INT32(2); errorIfGeometryCollection(geom1,geom2); errorIfSRIDMismatch(pglwgeom_getSRID(geom1), pglwgeom_getSRID(geom2)); POSTGIS_DEBUG(3, "containsPrepared: entered function"); /* * short-circuit: if geom2 bounding box is not completely inside * geom1 bounding box we can prematurely return FALSE. * Do the test IFF BOUNDING BOX AVAILABLE. */ if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) && getbox2d_p(SERIALIZED_FORM(geom2), &box2) ) { if (( box2.xmin < box1.xmin ) || ( box2.xmax > box1.xmax ) || ( box2.ymin < box1.ymin ) || ( box2.ymax > box1.ymax )) PG_RETURN_BOOL(FALSE); } prep_cache = GetPrepGeomCache( fcinfo, geom1, 0 ); initGEOS(lwnotice, lwnotice); if ( prep_cache && prep_cache->prepared_geom && prep_cache->argnum == 1 ) { GEOSGeom g = POSTGIS2GEOS(geom2); POSTGIS_DEBUG(4, "containsPrepared: cache is live, running preparedcontains"); result = GEOSPreparedContains( prep_cache->prepared_geom, g); GEOSGeom_destroy(g); } else { GEOSGeom g1 = POSTGIS2GEOS(geom1); GEOSGeom g2 = POSTGIS2GEOS(geom2); POSTGIS_DEBUG(4, "containsPrepared: cache is not ready, running standard contains"); result = GEOSContains( g1, g2); GEOSGeom_destroy(g1); GEOSGeom_destroy(g2); } if (result == 2) { elog(ERROR,"GEOS contains() threw an error!"); PG_RETURN_NULL(); /* never get here */ } PG_FREE_IF_COPY(geom1, 0); PG_FREE_IF_COPY(geom2, 1); PG_RETURN_BOOL(result); #endif /* PREPARED_GEOM */ }