FeatureCursorOGR::FeatureCursorOGR(OGRDataSourceH dsHandle, OGRLayerH layerHandle, const FeatureProfile* profile, const Symbology::Query& query, const FeatureFilterList& filters ) : _dsHandle( dsHandle ), _layerHandle( layerHandle ), _resultSetHandle( 0L ), _profile( profile ), _query( query ), _filters( filters ), _chunkSize( 500 ), _nextHandleToQueue( 0L ), _spatialFilter( 0L ) { //_resultSetHandle = _layerHandle; { OGR_SCOPED_LOCK; std::string expr; std::string from = OGR_FD_GetName( OGR_L_GetLayerDefn( _layerHandle )); from = std::string("'") + from + std::string("'"); if ( query.expression().isSet() ) { // build the SQL: allow the Query to include either a full SQL statement or // just the WHERE clause. expr = query.expression().value(); // if the expression is just a where clause, expand it into a complete SQL expression. std::string temp = expr; std::transform( temp.begin(), temp.end(), temp.begin(), ::tolower ); bool complete = temp.find( "select" ) == 0; if ( temp.find( "select" ) != 0 ) { std::stringstream buf; buf << "SELECT * FROM " << from << " WHERE " << expr; std::string bufStr; bufStr = buf.str(); expr = bufStr; } } else { std::stringstream buf; buf << "SELECT * FROM " << from; expr = buf.str(); } // if there's a spatial extent in the query, build the spatial filter: if ( query.bounds().isSet() ) { OGRGeometryH ring = OGR_G_CreateGeometry( wkbLinearRing ); OGR_G_AddPoint(ring, query.bounds()->xMin(), query.bounds()->yMin(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMin(), query.bounds()->yMax(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMax(), query.bounds()->yMax(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMax(), query.bounds()->yMin(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMin(), query.bounds()->yMin(), 0 ); _spatialFilter = OGR_G_CreateGeometry( wkbPolygon ); OGR_G_AddGeometryDirectly( _spatialFilter, ring ); // note: "Directly" above means _spatialFilter takes ownership if ring handle } _resultSetHandle = OGR_DS_ExecuteSQL( _dsHandle, expr.c_str(), _spatialFilter, 0L ); if ( _resultSetHandle ) { OGR_L_ResetReading( _resultSetHandle ); } } readChunk(); }
FeatureCursorOGR::FeatureCursorOGR(OGRDataSourceH dsHandle, OGRLayerH layerHandle, const FeatureSource* source, const FeatureProfile* profile, const Symbology::Query& query, const FeatureFilterList& filters ) : _source ( source ), _dsHandle ( dsHandle ), _layerHandle ( layerHandle ), _resultSetHandle ( 0L ), _spatialFilter ( 0L ), _query ( query ), _chunkSize ( 500 ), _nextHandleToQueue( 0L ), _profile ( profile ), _filters ( filters ) { { OGR_SCOPED_LOCK; std::string expr; std::string from = OGR_FD_GetName( OGR_L_GetLayerDefn( _layerHandle )); std::string driverName = OGR_Dr_GetName( OGR_DS_GetDriver( dsHandle ) ); // Quote the layer name if it is a shapefile, so we can handle any weird filenames like those with spaces or hyphens. // Or quote any layers containing spaces for PostgreSQL if (driverName == "ESRI Shapefile" || from.find(" ") != std::string::npos) { std::string delim = "'"; //Use single quotes by default if (driverName.compare("PostgreSQL") == 0) { //PostgreSQL uses double quotes as identifier delimeters delim = "\""; } from = delim + from + delim; } if ( query.expression().isSet() ) { // build the SQL: allow the Query to include either a full SQL statement or // just the WHERE clause. expr = query.expression().value(); // if the expression is just a where clause, expand it into a complete SQL expression. std::string temp = expr; std::transform( temp.begin(), temp.end(), temp.begin(), ::tolower ); //bool complete = temp.find( "select" ) == 0; if ( temp.find( "select" ) != 0 ) { std::stringstream buf; buf << "SELECT * FROM " << from << " WHERE " << expr; std::string bufStr; bufStr = buf.str(); expr = bufStr; } } else { std::stringstream buf; buf << "SELECT * FROM " << from; expr = buf.str(); } //Include the order by clause if it's set if (query.orderby().isSet()) { std::string orderby = query.orderby().value(); std::string temp = orderby; std::transform( temp.begin(), temp.end(), temp.begin(), ::tolower ); if ( temp.find( "order by" ) != 0 ) { std::stringstream buf; buf << "ORDER BY " << orderby; std::string bufStr; bufStr = buf.str(); orderby = buf.str(); } expr += (" " + orderby ); } // if there's a spatial extent in the query, build the spatial filter: if ( query.bounds().isSet() ) { OGRGeometryH ring = OGR_G_CreateGeometry( wkbLinearRing ); OGR_G_AddPoint(ring, query.bounds()->xMin(), query.bounds()->yMin(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMin(), query.bounds()->yMax(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMax(), query.bounds()->yMax(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMax(), query.bounds()->yMin(), 0 ); OGR_G_AddPoint(ring, query.bounds()->xMin(), query.bounds()->yMin(), 0 ); _spatialFilter = OGR_G_CreateGeometry( wkbPolygon ); OGR_G_AddGeometryDirectly( _spatialFilter, ring ); // note: "Directly" above means _spatialFilter takes ownership if ring handle } OE_DEBUG << LC << "SQL: " << expr << std::endl; _resultSetHandle = OGR_DS_ExecuteSQL( _dsHandle, expr.c_str(), _spatialFilter, 0L ); if ( _resultSetHandle ) { OGR_L_ResetReading( _resultSetHandle ); } } readChunk(); }