static const GEOSPreparedGeometry* rgeo_request_prepared_geometry(RGeo_GeometryData* object_data) { const GEOSPreparedGeometry* prep; prep = object_data->prep; if (prep == (const GEOSPreparedGeometry*)1) { object_data->prep = (GEOSPreparedGeometry*)2; prep = NULL; } else if (prep == (const GEOSPreparedGeometry*)2) { if (object_data->geom) { prep = GEOSPrepare_r(object_data->geos_context, object_data->geom); } else { prep = NULL; } if (prep) { object_data->prep = prep; } else { object_data->prep = (const GEOSPreparedGeometry*)3; } } else if (prep == (const GEOSPreparedGeometry*)3) { prep = NULL; } return prep; }
void QgsZonalStatistics::statisticsFromMiddlePointTest( void* band, QgsGeometry* poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, double& sum, double& count ) { double cellCenterX, cellCenterY; float* scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX ); cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; count = 0; sum = 0; const GEOSGeometry* polyGeos = poly->asGeos(); if ( !polyGeos ) { return; } GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler(); const GEOSPreparedGeometry* polyGeosPrepared = GEOSPrepare_r( geosctxt, poly->asGeos() ); if ( !polyGeosPrepared ) { return; } GEOSCoordSequence* cellCenterCoords = 0; GEOSGeometry* currentCellCenter = 0; for ( int i = 0; i < nCellsY; ++i ) { if ( GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 ) != CPLE_None ) { continue; } cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2; for ( int j = 0; j < nCellsX; ++j ) { GEOSGeom_destroy_r( geosctxt, currentCellCenter ); cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 ); GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX ); GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY ); currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords ); if ( scanLine[j] != mInputNodataValue ) //don't consider nodata values { if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) ) { if ( !qIsNaN( scanLine[j] ) ) { sum += scanLine[j]; } ++count; } } cellCenterX += cellSizeX; } cellCenterY -= cellSizeY; } CPLFree( scanLine ); GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared ); }
GEOSGeometry *_project_line_string(GEOSContextHandle_t handle, GEOSGeometry *g_line_string, Interpolator *interpolator, GEOSGeometry *g_domain, double threshold) { const GEOSCoordSequence *src_coords = GEOSGeom_getCoordSeq_r(handle, g_line_string); unsigned int src_size, src_idx; const GEOSPreparedGeometry *gp_domain = GEOSPrepare_r(handle, g_domain); GEOSCoordSeq_getSize_r(handle, src_coords, &src_size); // check exceptions LineAccumulator lines; for(src_idx = 1; src_idx < src_size; src_idx++) { _project_segment(handle, src_coords, src_idx - 1, src_idx, interpolator, gp_domain, threshold, lines); } GEOSPreparedGeom_destroy_r(handle, gp_domain); return lines.as_geom(handle); }
void QgsZonalStatistics::statisticsFromMiddlePointTest( void* band, const QgsGeometry& poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, FeatureStats &stats ) { double cellCenterX, cellCenterY; float* scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX ); cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; stats.reset(); GEOSGeometry* polyGeos = poly.exportToGeos(); if ( !polyGeos ) { return; } GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler(); const GEOSPreparedGeometry* polyGeosPrepared = GEOSPrepare_r( geosctxt, polyGeos ); if ( !polyGeosPrepared ) { GEOSGeom_destroy_r( geosctxt, polyGeos ); return; } GEOSCoordSequence* cellCenterCoords = nullptr; GEOSGeometry* currentCellCenter = nullptr; for ( int i = 0; i < nCellsY; ++i ) { if ( GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 ) != CPLE_None ) { continue; } cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2; for ( int j = 0; j < nCellsX; ++j ) { if ( validPixel( scanLine[j] ) ) { GEOSGeom_destroy_r( geosctxt, currentCellCenter ); cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 ); GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX ); GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY ); currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords ); if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) ) { stats.addValue( scanLine[j] ); } } cellCenterX += cellSizeX; } cellCenterY -= cellSizeY; } GEOSGeom_destroy_r( geosctxt, currentCellCenter ); CPLFree( scanLine ); GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared ); GEOSGeom_destroy_r( geosctxt, polyGeos ); }
void Polygon::prepare() { if (m_geom) { m_prepGeom = GEOSPrepare_r(m_ctx, m_geom); if (!m_prepGeom) throw pdal_error("unable to prepare geometry for index-accelerated access"); } }
void QgsZonalStatistics::statisticsFromMiddlePointTest( const QgsGeometry &poly, int pixelOffsetX, int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats ) { double cellCenterX, cellCenterY; cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2; stats.reset(); GEOSGeometry *polyGeos = poly.exportToGeos(); if ( !polyGeos ) { return; } GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler(); const GEOSPreparedGeometry *polyGeosPrepared = GEOSPrepare_r( geosctxt, polyGeos ); if ( !polyGeosPrepared ) { GEOSGeom_destroy_r( geosctxt, polyGeos ); return; } GEOSCoordSequence *cellCenterCoords = nullptr; GEOSGeometry *currentCellCenter = nullptr; QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox ); QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox ); QgsRasterBlock *block = mRasterProvider->block( mRasterBand, intersectBBox, nCellsX, nCellsY ); for ( int i = 0; i < nCellsY; ++i ) { cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2; for ( int j = 0; j < nCellsX; ++j ) { if ( validPixel( block->value( i, j ) ) ) { GEOSGeom_destroy_r( geosctxt, currentCellCenter ); cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 ); GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX ); GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY ); currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords ); if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) ) { stats.addValue( block->value( i, j ) ); } } cellCenterX += cellSizeX; } cellCenterY -= cellSizeY; } GEOSGeom_destroy_r( geosctxt, currentCellCenter ); GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared ); GEOSGeom_destroy_r( geosctxt, polyGeos ); delete block; }
void Crop::ready(PointContext ctx) { #ifdef PDAL_HAVE_GEOS if (!m_poly.empty()) { m_geosEnvironment = initGEOS_r(pdal::geos::_GEOSWarningHandler, pdal::geos::_GEOSErrorHandler); m_geosGeometry = GEOSGeomFromWKT_r(m_geosEnvironment, m_poly.c_str()); if (!m_geosGeometry) throw pdal_error("unable to import polygon WKT"); int gtype = GEOSGeomTypeId_r(m_geosEnvironment, m_geosGeometry); if (!(gtype == GEOS_POLYGON || gtype == GEOS_MULTIPOLYGON)) throw pdal_error("input WKT was not a POLYGON or MULTIPOLYGON"); char* out_wkt = GEOSGeomToWKT_r(m_geosEnvironment, m_geosGeometry); log()->get(LogLevel::Debug2) << "Ingested WKT for filters.crop: " << std::string(out_wkt) <<std::endl; GEOSFree_r(m_geosEnvironment, out_wkt); if (!GEOSisValid_r(m_geosEnvironment, m_geosGeometry)) { char* reason = GEOSisValidReason_r(m_geosEnvironment, m_geosGeometry); std::ostringstream oss; oss << "WKT is invalid: " << std::string(reason) << std::endl; GEOSFree_r(m_geosEnvironment, reason); throw pdal_error(oss.str()); } m_geosPreparedGeometry = GEOSPrepare_r(m_geosEnvironment, m_geosGeometry); if (!m_geosPreparedGeometry) throw pdal_error("unable to prepare geometry for " "index-accelerated intersection"); m_bounds = computeBounds(m_geosGeometry); log()->get(LogLevel::Debug) << "Computed bounds from given WKT: " << m_bounds <<std::endl; } else { log()->get(LogLevel::Debug) << "Using simple bounds for " "filters.crop: " << m_bounds << std::endl; } #endif }
static geos_prepared_geometry_t *get_geos_prepared_geom(sqlite3_context *context, const geos_context_t *geos_context, sqlite3_value *value, errorstream_t *error) { geom_blob_header_t header; uint8_t *blob = (uint8_t *)sqlite3_value_blob(value); size_t blob_length = (size_t) sqlite3_value_bytes(value); if (blob == NULL) { return NULL; } binstream_t stream; binstream_init(&stream, blob, blob_length); geos_writer_t writer; geos_writer_init_srid(&writer, geos_context->geos_handle, header.srid); geos_context->spatialdb->read_blob_header(&stream, &header, error); geos_context->spatialdb->read_geometry(&stream, geos_writer_geom_consumer(&writer), error); GEOSGeometry *g = geos_writer_getgeometry(&writer); geos_writer_destroy(&writer, g == NULL); if (g == NULL) { return NULL; } struct GEOSPrepGeom_t const *prepared_g = GEOSPrepare_r(geos_context->geos_handle, g); if (prepared_g == NULL) { return NULL; } geos_prepared_geometry_t *result = sqlite3_malloc(sizeof(geos_prepared_geometry_t)); if (result == NULL) { GEOSPreparedGeom_destroy_r(geos_context->geos_handle, prepared_g); return NULL; } result->context = geos_context->geos_handle; result->geometry = prepared_g; result->srid = header.srid; return result; }
static VALUE method_geometry_prepare(VALUE self) { RGeo_GeometryData* self_data; const GEOSPreparedGeometry* prep; self_data = RGEO_GEOMETRY_DATA_PTR(self); if (self_data->geom) { prep = self_data->prep; if (!prep || prep == (const GEOSPreparedGeometry*)1 || prep == (const GEOSPreparedGeometry*)2) { prep = GEOSPrepare_r(self_data->geos_context, self_data->geom); if (prep) { self_data->prep = prep; } else { self_data->prep = (const GEOSPreparedGeometry*)3; } } } return self; }
void QgsLabelFeature::setPermissibleZone( const QgsGeometry &geometry ) { mPermissibleZone = geometry; if ( mPermissibleZoneGeosPrepared ) { mPermissibleZoneGeosPrepared.reset(); mPermissibleZoneGeos.reset(); mPermissibleZoneGeosPrepared = nullptr; } if ( mPermissibleZone.isNull() ) return; mPermissibleZoneGeos = QgsGeos::asGeos( mPermissibleZone ); if ( !mPermissibleZoneGeos ) return; mPermissibleZoneGeosPrepared.reset( GEOSPrepare_r( QgsGeos::getGEOSHandler(), mPermissibleZoneGeos.get() ) ); }
void AttributeFilter::UpdateGEOSBuffer(PointBuffer& buffer, AttributeInfo& info) { QuadIndex idx(buffer); idx.build(); if (!info.lyr) // wake up the layer { if (info.layer.size()) info.lyr = OGR_DS_GetLayerByName(info.ds.get(), info.layer.c_str()); else if (info.query.size()) { info.lyr = OGR_DS_ExecuteSQL(info.ds.get(), info.query.c_str(), 0, 0); } else info.lyr = OGR_DS_GetLayer(info.ds.get(), 0); if (!info.lyr) { std::ostringstream oss; oss << "Unable to select layer '" << info.layer << "'"; throw pdal_error(oss.str()); } } OGRFeaturePtr feature = OGRFeaturePtr(OGR_L_GetNextFeature(info.lyr), OGRFeatureDeleter()); int field_index(1); // default to first column if nothing was set if (info.column.size()) { field_index = OGR_F_GetFieldIndex(feature.get(), info.column.c_str()); if (field_index == -1) { std::ostringstream oss; oss << "No column name '" << info.column << "' was found."; throw pdal_error(oss.str()); } } while(feature) { OGRGeometryH geom = OGR_F_GetGeometryRef(feature.get()); OGRwkbGeometryType t = OGR_G_GetGeometryType(geom); int f_count = OGR_F_GetFieldCount (feature.get()); if (!(t == wkbPolygon || t == wkbMultiPolygon || t == wkbPolygon25D || t == wkbMultiPolygon25D)) { std::ostringstream oss; oss << "Geometry is not Polygon or MultiPolygon!"; throw pdal::pdal_error(oss.str()); } OGRGeometry* ogr_g = (OGRGeometry*) geom; GEOSGeometry* geos_g (0); if (!m_geosEnvironment) { #if (GDAL_VERSION_MINOR < 11) && (GDAL_VERSION_MAJOR == 1) geos_g = ogr_g->exportToGEOS(); #else m_geosEnvironment = ogr_g->createGEOSContext(); geos_g = ogr_g->exportToGEOS(m_geosEnvironment); #endif } GEOSPreparedGeometry const* geos_pg = GEOSPrepare_r(m_geosEnvironment, geos_g); if (!geos_pg) throw pdal_error("unable to prepare geometry for index-accelerated intersection"); // Compute a total bounds for the geometry. Query the QuadTree to // find out the points that are inside the bbox. Then test each // point in the bbox against the prepared geometry. BOX3D box = computeBounds(m_geosEnvironment, geos_g); std::vector<std::size_t> ids = idx.getPoints(box); for (const auto& i : ids) { double x = buffer.getFieldAs<double>(Dimension::Id::X, i); double y = buffer.getFieldAs<double>(Dimension::Id::Y, i); double z = buffer.getFieldAs<double>(Dimension::Id::Z, i); GEOSGeometry* p = createGEOSPoint(m_geosEnvironment, x, y ,z); if (static_cast<bool>(GEOSPreparedContains_r(m_geosEnvironment, geos_pg, p))) { // We're in the poly, write the attribute value int32_t v = OGR_F_GetFieldAsInteger(feature.get(), field_index); buffer.setField(info.dim, i, v); // log()->get(LogLevel::Debug) << "Setting value: " << v << std::endl; } GEOSGeom_destroy_r(m_geosEnvironment, p); } feature = OGRFeaturePtr(OGR_L_GetNextFeature(info.lyr), OGRFeatureDeleter()); } }