static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig) { // Clear out any existing value RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self); GEOSGeometry* self_geom = self_data->geom; if (self_geom) { GEOSGeom_destroy_r(self_data->geos_context, self_geom); self_data->geom = NULL; self_data->geos_context = NULL; self_data->factory = Qnil; self_data->klasses = Qnil; } // Copy value from orig const GEOSGeometry* geom = rgeo_get_geos_geometry_safe(orig); if (geom) { RGeo_GeometryData* orig_data = RGEO_GEOMETRY_DATA_PTR(orig); GEOSContextHandle_t orig_context = orig_data->geos_context; GEOSGeometry* clone_geom = GEOSGeom_clone_r(orig_context, geom); if (clone_geom) { GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom)); self_data->geom = clone_geom; self_data->geos_context = orig_context; self_data->factory = orig_data->factory; self_data->klasses = orig_data->klasses; } } return self; }
static VALUE method_geometry_srid(VALUE self) { VALUE result = Qnil; RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self); const GEOSGeometry* self_geom = self_data->geom; if (self_geom) { result = INT2NUM(GEOSGetSRID_r(self_data->geos_context, self_geom)); } return result; }
static VALUE method_geometry_initialize_copy(VALUE self, VALUE orig) { RGeo_GeometryData* self_data; const GEOSPreparedGeometry* prep; const GEOSGeometry* geom; RGeo_GeometryData* orig_data; GEOSContextHandle_t orig_context; GEOSGeometry* clone_geom; RGeo_FactoryData* factory_data; // Clear out any existing value self_data = RGEO_GEOMETRY_DATA_PTR(self); if (self_data->geom) { GEOSGeom_destroy_r(self_data->geos_context, self_data->geom); self_data->geom = NULL; } prep = self_data->prep; if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) { GEOSPreparedGeom_destroy_r(self_data->geos_context, prep); } self_data->prep = NULL; self_data->geos_context = NULL; self_data->factory = Qnil; self_data->klasses = Qnil; // Copy value from orig geom = rgeo_get_geos_geometry_safe(orig); if (geom) { orig_data = RGEO_GEOMETRY_DATA_PTR(orig); orig_context = orig_data->geos_context; clone_geom = GEOSGeom_clone_r(orig_context, geom); if (clone_geom) { factory_data = RGEO_FACTORY_DATA_PTR(orig_data->factory); GEOSSetSRID_r(orig_context, clone_geom, GEOSGetSRID_r(orig_context, geom)); self_data->geom = clone_geom; self_data->geos_context = orig_context; self_data->prep = factory_data && (factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC != 0) ? (GEOSPreparedGeometry*)1 : NULL; self_data->factory = orig_data->factory; self_data->klasses = orig_data->klasses; } } return self; }
static int set_geos_geom_result(sqlite3_context *context, const geos_context_t *geos_context, const GEOSGeometry *geom, errorstream_t *error) { int result = SQLITE_OK; if (geom == NULL) { sqlite3_result_null(context); return result; } else { geom_blob_writer_t writer; geos_context->spatialdb->writer_init_srid(&writer, GEOSGetSRID_r(geos_context->geos_handle, geom)); result = geos_read_geometry(geos_context->geos_handle, geom, geom_blob_writer_geom_consumer(&writer), error); if (result == SQLITE_OK) { sqlite3_result_blob(context, geom_blob_writer_getdata(&writer), geom_blob_writer_length(&writer), sqlite3_free); } else { sqlite3_result_error(context, error_message(error), -1); } geos_context->spatialdb->writer_destroy(&writer, 0); return result; } }
Q_NOWARN_UNREACHABLE_PUSH static GEOSGeometry *LWGEOM_GEOS_buildArea( const GEOSGeometry *geom_in, QString &errorMessage ) { GEOSContextHandle_t handle = QgsGeos::getGEOSHandler(); GEOSGeometry *tmp = nullptr; GEOSGeometry *shp = nullptr; GEOSGeometry *geos_result = nullptr; int srid = GEOSGetSRID_r( handle, geom_in ); GEOSGeometry const *vgeoms[1]; vgeoms[0] = geom_in; try { geos_result = GEOSPolygonize_r( handle, vgeoms, 1 ); } catch ( GEOSException &e ) { errorMessage = QStringLiteral( "GEOSPolygonize(): %1" ).arg( e.what() ); return nullptr; } // We should now have a collection #if PARANOIA_LEVEL > 0 if ( GEOSGeometryTypeId_r( handle, geos_result ) != COLLECTIONTYPE ) { GEOSGeom_destroy_r( handle, geos_result ); errorMessage = "Unexpected return from GEOSpolygonize"; return nullptr; } #endif int ngeoms = GEOSGetNumGeometries_r( handle, geos_result ); // No geometries in collection, early out if ( ngeoms == 0 ) { GEOSSetSRID_r( handle, 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_r( handle, geos_result, 0 ); if ( ! tmp ) { GEOSGeom_destroy_r( handle, geos_result ); return nullptr; } shp = GEOSGeom_clone_r( handle, tmp ); GEOSGeom_destroy_r( handle, geos_result ); // only safe after the clone above GEOSSetSRID_r( handle, shp, srid ); return shp; } /* * Polygonizer returns a polygon for each face in the built topology. * * This means that for any face with holes we'll have other faces * representing each hole. We can imagine a parent-child relationship * between these faces. * * In order to maximize the number of visible rings in output we * only use those faces which have an even number of parents. * * Example: * * +---------------+ * | L0 | L0 has no parents * | +---------+ | * | | L1 | | L1 is an hole of L0 * | | +---+ | | * | | |L2 | | | L2 is an hole of L1 (which is an hole of L0) * | | | | | | * | | +---+ | | * | +---------+ | * | | * +---------------+ * * See http://trac.osgeo.org/postgis/ticket/1806 * */ // Prepare face structures for later analysis Face **geoms = new Face*[ngeoms]; for ( int i = 0; i < ngeoms; ++i ) geoms[i] = newFace( GEOSGetGeometryN_r( handle, geos_result, i ) ); // Find faces representing other faces holes findFaceHoles( geoms, ngeoms ); // Build a MultiPolygon composed only by faces with an // even number of ancestors tmp = collectFacesWithEvenAncestors( geoms, ngeoms ); // Cleanup face structures for ( int i = 0; i < ngeoms; ++i ) delFace( geoms[i] ); delete [] geoms; // Faces referenced memory owned by geos_result. // It is safe to destroy geos_result after deleting them. GEOSGeom_destroy_r( handle, geos_result ); // Run a single overlay operation to dissolve shared edges shp = GEOSUnionCascaded_r( handle, tmp ); if ( !shp ) { GEOSGeom_destroy_r( handle, tmp ); return nullptr; } GEOSGeom_destroy_r( handle, tmp ); GEOSSetSRID_r( handle, shp, srid ); return shp; }