int S57_ogrLoadLayer(const char *layername, void *ogrlayer, S52_loadObject_cb loadObject_cb) { if (NULL==layername || NULL==ogrlayer) { PRINTF("ERROR: layername || ogrlayer || S52_loadLayer_cb is NULL\n"); g_assert(0); } if (NULL == loadObject_cb) { static int silent = FALSE; if (FALSE == silent) { PRINTF("NOTE: using default S52_loadObject() callback\n"); PRINTF(" (this msg will not repeat)\n"); silent = TRUE; } loadObject_cb = S52_loadObject; } OGRFeatureH feature = NULL; while ( NULL != (feature = OGR_L_GetNextFeature((OGRLayerH)ogrlayer))) { // debug //PRINTF("layer:feature %X:%X\n", ogrlayer, feature); #ifdef _MINGW // on Windows 32 the callback is broken S52_loadObject(layername, feature); #else loadObject_cb(layername, (void*)feature); #endif OGR_F_Destroy(feature); } return TRUE; }
void object::test<7>() { OGRErr err = OGRERR_NONE; // Read feature without geometry std::string tmp(data_tmp_); tmp += SEP; tmp += "tpoly.shp"; OGRDataSourceH ds = OGR_Dr_Open(drv_, tmp.c_str(), false); ensure("Can't open layer", NULL != ds); OGRLayerH lyr = OGR_DS_GetLayer(ds, 0); ensure("Can't get layer", NULL != lyr); err = OGR_L_SetAttributeFilter(lyr, "PRFEDEA = 'nulled'"); ensure_equals("Can't set attribute filter", OGRERR_NONE, err); // Fetch feature without geometry OGRFeatureH featNonSpatial = OGR_L_GetNextFeature(lyr); ensure("Didnt get feature with null geometry back", NULL != featNonSpatial); // Null geometry is expected OGRGeometryH nonGeom = OGR_F_GetGeometryRef(featNonSpatial); ensure("Didnt get null geometry as expected", NULL == nonGeom); OGR_F_Destroy(featNonSpatial); OGR_DS_Destroy(ds); }
void GDALWPrintRecords(GDALWConnection conn) { char * wkt; int i; OGRFeatureH feature; OGRGeometryH geometry; OGRFeatureDefnH featureDefn; featureDefn = OGR_L_GetLayerDefn(conn.layer); OGR_L_ResetReading(conn.layer); while( (feature = OGR_L_GetNextFeature(conn.layer)) != NULL ) { for(i = 0; i < OGR_FD_GetFieldCount(featureDefn); i++ ) { OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( featureDefn, i ); if( OGR_Fld_GetType(hFieldDefn) == OFTInteger ) printf( "%d,", OGR_F_GetFieldAsInteger( feature, i ) ); else if( OGR_Fld_GetType(hFieldDefn) == OFTReal ) printf( "%.3f,", OGR_F_GetFieldAsDouble( feature, i) ); else printf( "%s,", OGR_F_GetFieldAsString( feature, i) ); } geometry = OGR_F_GetGeometryRef(feature); OGR_G_ExportToWkt(geometry, &wkt); printf("%s", wkt); printf("\n"); CPLFree(wkt); OGR_F_Destroy(feature); } }
void object::test<5>() { // Original shapefile std::string orig(data_); orig += SEP; orig += "poly.shp"; OGRDataSourceH dsOrig = OGR_Dr_Open(drv_, orig.c_str(), false); ensure("Can't open layer", NULL != dsOrig); OGRLayerH lyrOrig = OGR_DS_GetLayer(dsOrig, 0); ensure("Can't get layer", NULL != lyrOrig); // Copied shapefile std::string tmp(data_tmp_); tmp += SEP; tmp += "tpoly.shp"; OGRDataSourceH dsTmp = OGR_Dr_Open(drv_, tmp.c_str(), false); ensure("Can't open layer", NULL != dsTmp); OGRLayerH lyrTmp = OGR_DS_GetLayer(dsTmp, 0); ensure("Can't get layer", NULL != lyrTmp); // Iterate through features and compare geometries OGRFeatureH featOrig = OGR_L_GetNextFeature(lyrOrig); OGRFeatureH featTmp = OGR_L_GetNextFeature(lyrTmp); while (NULL != featOrig && NULL != featTmp) { OGRGeometryH lhs = OGR_F_GetGeometryRef(featOrig); OGRGeometryH rhs = OGR_F_GetGeometryRef(featTmp); ensure_equal_geometries(lhs, rhs, 0.000000001); // TODO: add ensure_equal_attributes() OGR_F_Destroy(featOrig); OGR_F_Destroy(featTmp); // Move to next feature featOrig = OGR_L_GetNextFeature(lyrOrig); featTmp = OGR_L_GetNextFeature(lyrTmp); } OGR_DS_Destroy(dsOrig); OGR_DS_Destroy(dsTmp); }
/** * \brief Convenience function to check if a geometry is contained in a OGR * datasource for a given layer. * * The passed geometry is a wkt representation of a geometry of type GeomType. * pszFile is opened, and the passed geometry is queried against all * geometries in pszLayer. If the passed geometry is contained in *any* of the * geomtries in the layer, TRUE is returned. FALSE is returned otherwise, * including errors. The SRS of all geometries is assumed to be the same. * * \param pszWkt Well-known text representation of a geometry. * \param pszFile File to open * \param pszLayer Layer to extract geometry from, if NULL, use layer 0. * \return TRUE if pszWkt is contained in any geometry in pszLayer, FALSE * otherwise, include errors */ int NinjaOGRContain(const char *pszWkt, const char *pszFile, const char *pszLayer) { int bContains = FALSE; if( pszWkt == NULL || pszFile == NULL ) { return FALSE; } CPLDebug( "WINDNINJA", "Checking for containment of %s in %s:%s", pszWkt, pszFile, pszLayer ? pszLayer : "" ); OGRGeometryH hTestGeometry = NULL; int err = OGR_G_CreateFromWkt( (char**)&pszWkt, NULL, &hTestGeometry ); if( hTestGeometry == NULL || err != CE_None ) { return FALSE; } OGRDataSourceH hDS = OGROpen( pszFile, 0, NULL ); if( hDS == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to open datasource: %s", pszFile ); OGR_G_DestroyGeometry( hTestGeometry ); bContains = FALSE; return bContains; } OGRLayerH hLayer; if( pszLayer == NULL ) { hLayer = OGR_DS_GetLayer( hDS, 0 ); } else { hLayer = OGR_DS_GetLayerByName( hDS, pszLayer ); } OGRFeatureH hFeature; if( hLayer != NULL ) { OGRGeometryH hGeometry; OGR_L_ResetReading( hLayer ); while( ( hFeature = OGR_L_GetNextFeature( hLayer ) ) != NULL ) { hGeometry = OGR_F_GetGeometryRef( hFeature ); if( OGR_G_Contains( hGeometry, hTestGeometry ) ) { bContains = TRUE; OGR_F_Destroy( hFeature ); break; } OGR_F_Destroy( hFeature ); } } OGR_G_DestroyGeometry( hTestGeometry ); OGR_DS_Destroy( hDS ); return bContains; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed || !ogrLayer ) return false; if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { bool result = fetchFeatureWithId( mRequest.filterFid(), feature ); close(); // the feature has been read or was not found: we have finished here return result; } else if ( mRequest.filterType() == QgsFeatureRequest::FilterFids ) { while ( mFilterFidsIt != mFilterFids.constEnd() ) { QgsFeatureId nextId = *mFilterFidsIt; mFilterFidsIt++; if ( fetchFeatureWithId( nextId, feature ) ) return true; } close(); return false; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) continue; else OGR_F_Destroy( fet ); if ( !mRequest.filterRect().isNull() && !feature.hasGeometry() ) continue; // we have a feature, end this cycle feature.setValid( true ); return true; } // while close(); return false; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) continue; // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while QgsDebugMsg( "Feature is null" ); close(); return false; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) continue; if ( !mRequest.filterRect().isNull() && !feature.constGeometry() ) continue; // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while close(); return false; }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr ); if ( !hDS ) { VSIUnlink( TO8( randomFileName ) ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 ); if ( !ogrLayer ) { OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; } OGRFeatureH oFeat; while (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) ) { QgsFeature feat = readOgrFeature( oFeat, fields, encoding ); if ( feat.isValid() ) features << feat; OGR_F_Destroy( oFeat ); } OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; }
void OgrFileImport::importLayer(MapPart* map_part, OGRLayerH layer) { Q_ASSERT(map_part); auto feature_definition = OGR_L_GetLayerDefn(layer); OGR_L_ResetReading(layer); while (auto feature = ogr::unique_feature(OGR_L_GetNextFeature(layer))) { auto geometry = OGR_F_GetGeometryRef(feature.get()); if (!geometry || OGR_G_IsEmpty(geometry)) { ++empty_geometries; continue; } OGR_G_FlattenTo2D(geometry); importFeature(map_part, feature_definition, feature.get(), geometry); } }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString &string, const QgsFields &fields, QTextCodec *encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QStringLiteral( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(), reinterpret_cast< GByte * >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); gdal::ogr_datasource_unique_ptr hDS( OGROpen( randomFileName.toUtf8().constData(), false, nullptr ) ); if ( !hDS ) { VSIUnlink( randomFileName.toUtf8().constData() ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 ); if ( !ogrLayer ) { hDS.reset(); VSIUnlink( randomFileName.toUtf8().constData() ); return features; } gdal::ogr_feature_unique_ptr oFeat; while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat ) { QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding ); if ( feat.isValid() ) features << feat; } hDS.reset(); VSIUnlink( randomFileName.toUtf8().constData() ); return features; }
bool CUtils::insideInPolygons(OGRDataSourceH poDS, double x, double y) { bool res = false; OGRGeometryH pt = OGR_G_CreateGeometry(wkbPoint); OGR_G_AddPoint_2D(pt, x, y); for(int iLayer = 0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++) { OGRLayerH poLayer = OGR_DS_GetLayer(poDS, iLayer); if(poLayer!=NULL) { OGREnvelope layerBounds; OGR_L_GetExtent(poLayer, &layerBounds, 1); if( (layerBounds.MinX <= x) && (layerBounds.MinY <= y) && (layerBounds.MaxX >= x) && (layerBounds.MaxY >= y) ) { OGR_L_ResetReading(poLayer); if(OGR_FD_GetGeomType( OGR_L_GetLayerDefn(poLayer) ) == wkbPolygon) { OGRFeatureH poFeat; while((poFeat = OGR_L_GetNextFeature(poLayer))!= NULL) { OGRGeometryH hGeom = OGR_F_GetGeometryRef(poFeat); if(OGR_G_Within(pt, hGeom)) { res = true; break; } } if(res) { OGR_L_ResetReading(poLayer); break; } } } } } OGR_G_DestroyGeometry(pt); return res; }
void object::test<9>() { // Open directory as a datasource OGRDataSourceH ds = OGR_Dr_Open(drv_, data_tmp_ .c_str(), false); ensure("Can't open datasource", NULL != ds); std::string sql("select * from tpoly where prfedea = '35043413'"); OGRLayerH lyr = OGR_DS_ExecuteSQL(ds, sql.c_str(), NULL, NULL); ensure("Can't create layer from query", NULL != lyr); // Prepare tester collection std::vector<std::string> list; list.push_back("35043413"); // Test attributes ensure_equal_attributes(lyr, "prfedea", list); // Test geometry const char* wkt = "POLYGON ((479750.688 4764702.000,479658.594 4764670.000," "479640.094 4764721.000,479735.906 4764752.000," "479750.688 4764702.000))"; OGRGeometryH testGeom = NULL; OGRErr err = OGR_G_CreateFromWkt((char**) &wkt, NULL, &testGeom); ensure_equals("Can't create geometry from WKT", OGRERR_NONE, err); OGR_L_ResetReading(lyr); OGRFeatureH feat = OGR_L_GetNextFeature(lyr); ensure("Can't featch feature", NULL != feat); ensure_equal_geometries(OGR_F_GetGeometryRef(feat), testGeom, 0.001); OGR_F_Destroy(feat); OGR_G_DestroyGeometry(testGeom); OGR_DS_ReleaseResultSet(ds, lyr); OGR_DS_Destroy(ds); }
/* OGRFeatureH OGR_L_GetNextFeature(OGRLayerH hLayer) {ok, DataSource} = lgeo_ogr:open("test/polygon.shp"), {ok, Layer} = lgeo_ogr:ds_get_layer(DataSource, 0), {ok, Feature} = lgeo_ogr:l_get_next_feature(Layer). */ static ERL_NIF_TERM l_get_next_feature(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { EnvLayer_t **layer; ERL_NIF_TERM eterm; if(argc != 1) { return enif_make_badarg(env); } if(!enif_get_resource(env, argv[0], OGR_L_RESOURCE, (void**)&layer)) { return enif_make_badarg(env); } OGRFeatureH feat = OGR_L_GetNextFeature((**layer).obj); if(feat == NULL) { eterm = enif_make_string(env, "No more features", ERL_NIF_LATIN1); return enif_make_tuple2(env, enif_make_atom(env, "error"), eterm); } EnvFeature_t **feature = \ enif_alloc_resource(OGR_F_RESOURCE, sizeof(EnvFeature_t*)); ErlNifEnv *feature_env = enif_alloc_env(); *feature = (EnvFeature_t*) enif_alloc(sizeof(EnvFeature_t)); (**feature).env = feature_env; (**feature).obj = feat; // Save copy of layer so is not garbage collected enif_make_copy(feature_env, argv[0]); eterm = enif_make_resource(env, feature); enif_release_resource(feature); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
/* What we need: specific condition, is walk in , tactic, distance elevation * minsteps, maxsteps, waterdrops, pump/roll, fwa id. */ int main( int argc, char *argv[] ) { GDALAllRegister(); OGRRegisterAll(); const char *pszInputfile = NULL; const char *pszOutputfile = NULL; const char *pszOutputFormat = "CSV"; char **papszCreateOptions = NULL; const char *pszDataPath = NULL; const char *pszFpuCode = NULL; int nLimit = 0; int bProgress = TRUE; double dfMaxX, dfMinX, dfMaxY, dfMinY; int bLimit = FALSE; double dfBuffer = 0.0; int i = 1; while( i < argc ) { if( EQUAL( argv[i], "-p" ) ) { bProgress = TRUE; } else if( EQUAL( argv[i], "-d" ) ) { pszDataPath = argv[++i]; } else if( EQUAL( argv[i], "-of" ) ) { pszOutputFormat = argv[++i]; } else if( EQUAL( argv[i], "-co" ) ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL( argv[i], "-sl" ) ) { dfMaxX = atof(argv[++i]); dfMinX = atof(argv[++i]); dfMaxY = atof(argv[++i]); dfMinY = atof(argv[++i]); bLimit = TRUE; } else if( EQUAL( argv[i], "-fpu" ) ) { pszFpuCode = argv[++i]; } else if( EQUAL( argv[i], "-b" ) ) { dfBuffer = atof( argv[++i] ); } else if( EQUAL( argv[i], "-l" ) ) { nLimit = atoi( argv[++i] ); } else if( EQUAL( argv[i], "-h" ) ) { Usage(); } else if( pszInputfile == NULL ) { pszInputfile = argv[i]; } else if( pszOutputfile == NULL ) { pszOutputfile = argv[i]; } else { Usage(); } i++; } if( pszInputfile == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "No input file provided\n"); Usage(); } if( pszOutputfile == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Invalid output selected, " "use database and table or output file\n" ); Usage(); } pszDataPath = CPLGetConfigOption( "OMFFR_DATA", NULL ); OGRDataSourceH hInputDS = OGROpen( pszInputfile, FALSE, NULL ); if( hInputDS == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Cannot open input file\n" ); Usage(); } int year, num, day; const char *dow, *disc_time; int bi; double ros; int fuel; const char *spec_cond; int slope, walkin; const char *tactic; double dist; int elev; double ltow; int minsteps = 250; int maxsteps = 10000; const char *sunrise, *sunset; int waterdrops, pumproll; char *abyFwa; const char *fwaid; double lon, lat; OGRLayerH hInputLayer; hInputLayer = OGR_DS_GetLayerByName( hInputDS, CPLGetBasename( pszInputfile ) ); OGRFeatureDefnH hInputFeatureDefn; OGRFeatureH hInputFeature; OGRGeometryH hGeometry; hInputFeatureDefn = OGR_L_GetLayerDefn( hInputLayer ); const char *pszTmpFilename =CPLFormFilename( pszDataPath, "irs/FWA", ".dat" ); std::vector<CFWA>fwas = LoadFwas( pszTmpFilename ); int nFeatures = OGR_L_GetFeatureCount( hInputLayer, TRUE ); FILE *fout = fopen( pszOutputfile, "w" ); //CFWA *fwa; Random random; char pszDb[8192]; sprintf( pszDb, "%s/omffr.sqlite", pszDataPath ); IRSDataAccess *poDA = IRSDataAccess::Create( 0, pszDb ); int rc; sqlite3 *db; rc = sqlite3_open_v2( pszDb, &db, SQLITE_OPEN_READONLY, NULL ); rc = sqlite3_enable_load_extension( db, 1 ); rc = sqlite3_load_extension( db, "/usr/local/lib/libspatialite.so", 0, NULL ); sqlite3_stmt *stmt; rc = sqlite3_prepare_v2( db, "SELECT * from fwa join fwa_bndry USING(fwa_gis_id) " \ "WHERE ST_Contains(fwa_bndry.geometry, MakePoint(?, ?, 4269))", -1, &stmt, NULL ); if(rc) { CPLError( CE_Failure, CPLE_AppDefined, "Could not open DB"); } GDALTermProgress( 0.0, NULL, NULL ); OGR_L_ResetReading( hInputLayer ); const char *pszFwaName; int nDone = 0; while( ( hInputFeature = OGR_L_GetNextFeature( hInputLayer ) ) != NULL ) { /* fwaid = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "fwa_name" ) ); abyFwa = CPLStrdup( fwaid ); LaunderFwaName( abyFwa ); fwa = FindFwa( fwas, abyFwa ); if( fwa == NULL ) { CPLError( CE_Warning, CPLE_FileIO, "Could not load fwa (%s)from file, missing\n", abyFwa ); continue; } */ /* Get fwa by point */ hGeometry = OGR_F_GetGeometryRef( hInputFeature ); /* Try to handle non-geometry types (csv) */ if( hGeometry != NULL ) { lat = OGR_G_GetY( hGeometry, 0 ); lon = OGR_G_GetX( hGeometry, 0 ); } else { lat = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "Y") ); lon = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "X") ); } std::string oFwaName = poDA->PointQuery( "fwa_bndry", "fwa_lndr_name", lon, lat ); rc = sqlite3_bind_double( stmt, 1, lon ); rc = sqlite3_bind_double( stmt, 2, lat ); //sqlite3_bind_text( stmt, 1, oFwaName.c_str(), -1, SQLITE_TRANSIENT); rc = sqlite3_step( stmt ); if( rc != SQLITE_ROW && rc != SQLITE_DONE ) { CPLError( CE_Warning, CPLE_FileIO, "Could not load fwa (%s)from file, missing\n", oFwaName.c_str() ); sqlite3_reset(stmt); continue; } int nFwaWalkIn, nFwaHead, nFwaTail, nFwaPara, nFwaAttackD; int nFwaWaterDrop, nFwaPumpRoll; nFwaWalkIn = sqlite3_column_int( stmt, 4 ); nFwaHead = sqlite3_column_int( stmt, 6 ); nFwaTail = sqlite3_column_int( stmt, 7 ); nFwaPara = sqlite3_column_int( stmt, 8 ); nFwaAttackD = sqlite3_column_int( stmt, 9 ); nFwaWaterDrop = sqlite3_column_int( stmt, 10 ); nFwaPumpRoll = sqlite3_column_int( stmt, 5 ); year = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "year" ) ); num = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "fire_num" ) ); day = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "day" ) ); dow = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "week_day" ) ); disc_time = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "disc_time" ) ); bi = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "bi" ) ); ros = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "ros" ) ); fuel = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "fuel" ) ); spec_cond = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "spec_cond" ) ); slope = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "slope_perc" ) ); //if( random.rand3() * 100 > fwa->GetWalkInPct() ) if( random.rand3() * 100 > nFwaWalkIn ) walkin = 0; else walkin = 1; //if( fwa->GetHead() == 100 ) if( nFwaHead == 100 ) tactic = "HEAD\0"; //else if( fwa->GetTail() == 100 ) else if( nFwaTail == 100 ) tactic = "TAIL\0"; //else if( fwa->GetParallel() == 100 ) else if( nFwaTail == 100 ) tactic = "PARALLEL\0"; else { int r = (int)(random.rand3() * 100 ); int total = 0; if( r < nFwaHead ) tactic = "HEAD\0"; else if( r < nFwaTail + nFwaTail ) tactic = "TAIL\0"; else tactic = "PARALLEL\0"; } //dist = fwa->GetAttackDist(); dist = nFwaAttackD; elev = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "elev" ) ); ltow = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "ratio" ) ); sunrise = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "sunrise" ) ); sunset = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "sunset" ) ); //if( fwa->GetWaterDrops() ) if( nFwaWaterDrop ) waterdrops = TRUE; else waterdrops = FALSE; //if( fwa->GetPumpnRoll() ) if( nFwaPumpRoll ) pumproll = TRUE; else pumproll = FALSE; fprintf( fout, "%d %d %d %s %s " "%d %lf %d %s %d " "%d %s %lf %d %lf " "%d %d %s %s %d " "%d %s %lf %lf\n", year, num, day, dow, disc_time, bi, ros, fuel, spec_cond, slope, walkin, tactic, dist, elev, ltow, minsteps, maxsteps, sunrise, sunset, waterdrops, pumproll, /* abyFwa */ oFwaName.c_str(), lat, lon ); sqlite3_reset(stmt); nDone++; GDALTermProgress( (float)nDone / (float)nFeatures, NULL, NULL ); } GDALTermProgress( 1.0, NULL, NULL ); fclose( fout ); OGR_DS_Destroy( hInputDS ); return 0; }
static int RasterliteInsertSRID(OGRDataSourceH hDS, const char* pszWKT) { CPLString osSQL; int nAuthorityCode = 0; CPLString osAuthorityName, osProjCS, osProj4; if (pszWKT != NULL && strlen(pszWKT) != 0) { OGRSpatialReferenceH hSRS = OSRNewSpatialReference(pszWKT); if (hSRS) { const char* pszAuthorityName = OSRGetAuthorityName(hSRS, NULL); if (pszAuthorityName) osAuthorityName = pszAuthorityName; const char* pszProjCS = OSRGetAttrValue(hSRS, "PROJCS", 0); if (pszProjCS) osProjCS = pszProjCS; const char* pszAuthorityCode = OSRGetAuthorityCode(hSRS, NULL); if (pszAuthorityCode) nAuthorityCode = atoi(pszAuthorityCode); char *pszProj4 = NULL; if( OSRExportToProj4( hSRS, &pszProj4 ) != OGRERR_NONE ) pszProj4 = CPLStrdup(""); osProj4 = pszProj4; CPLFree(pszProj4); } OSRDestroySpatialReference(hSRS); } int nSRSId = -1; if (nAuthorityCode != 0 && osAuthorityName.size() != 0) { osSQL.Printf ("SELECT srid FROM spatial_ref_sys WHERE auth_srid = %d", nAuthorityCode); OGRLayerH hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hLyr == NULL) { nSRSId = nAuthorityCode; if ( osProjCS.size() != 0 ) osSQL.Printf( "INSERT INTO spatial_ref_sys " "(srid, auth_name, auth_srid, ref_sys_name, proj4text) " "VALUES (%d, '%s', '%d', '%s', '%s')", nSRSId, osAuthorityName.c_str(), nAuthorityCode, osProjCS.c_str(), osProj4.c_str() ); else osSQL.Printf( "INSERT INTO spatial_ref_sys " "(srid, auth_name, auth_srid, proj4text) " "VALUES (%d, '%s', '%d', '%s')", nSRSId, osAuthorityName.c_str(), nAuthorityCode, osProj4.c_str() ); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } else { OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr); if (hFeat) { nSRSId = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hLyr); } } return nSRSId; }
OGRDataSourceH RasterliteCreateTables(OGRDataSourceH hDS, const char* pszTableName, int nSRSId, int bWipeExistingData) { CPLString osSQL; CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLString osDBName = OGR_DS_GetName(hDS); CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", pszTableName); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", pszTableName); OGRLayerH hLyr; if (OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()) == NULL) { /* -------------------------------------------------------------------- */ /* The table don't exist. Create them */ /* -------------------------------------------------------------------- */ /* Create _rasters table */ osSQL.Printf ("CREATE TABLE \"%s\" (" "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," "raster BLOB NOT NULL)", osRasterLayer.c_str()); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Create _metadata table */ osSQL.Printf ("CREATE TABLE \"%s\" (" "id INTEGER NOT NULL PRIMARY KEY," "source_name TEXT NOT NULL," "tile_id INTEGER NOT NULL," "width INTEGER NOT NULL," "height INTEGER NOT NULL," "pixel_x_size DOUBLE NOT NULL," "pixel_y_size DOUBLE NOT NULL)", osMetatadataLayer.c_str()); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Add geometry column to _metadata table */ osSQL.Printf("SELECT AddGeometryColumn('%s', 'geometry', %d, 'POLYGON', 2)", osMetatadataLayer.c_str(), nSRSId); if ((hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL)) == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Check that the OGR SQLite driver has Spatialite support"); OGRReleaseDataSource(hDS); return NULL; } OGR_DS_ReleaseResultSet(hDS, hLyr); /* Create spatial index on _metadata table */ osSQL.Printf("SELECT CreateSpatialIndex('%s', 'geometry')", osMetatadataLayer.c_str()); if ((hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL)) == NULL) { OGRReleaseDataSource(hDS); return NULL; } OGR_DS_ReleaseResultSet(hDS, hLyr); /* Re-open the DB to take into account the new tables*/ OGRReleaseDataSource(hDS); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); hDS = OGROpen(osDBName.c_str(), TRUE, NULL); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); } else { /* Check that the existing SRS is consistent with the one of the new */ /* data to be inserted */ osSQL.Printf("SELECT srid FROM geometry_columns WHERE f_table_name = '%s'", osMetatadataLayer.c_str()); hLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hLyr) { int nExistingSRID = -1; OGRFeatureH hFeat = OGR_L_GetNextFeature(hLyr); if (hFeat) { nExistingSRID = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hLyr); if (nExistingSRID != nSRSId) { if (bWipeExistingData) { osSQL.Printf("UPDATE geometry_columns SET srid = %d " "WHERE f_table_name = \"%s\"", nSRSId, osMetatadataLayer.c_str()); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Re-open the DB to take into account the change of SRS */ OGRReleaseDataSource(hDS); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); hDS = OGROpen(osDBName.c_str(), TRUE, NULL); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); } else { CPLError(CE_Failure, CPLE_NotSupported, "New data has not the same SRS as existing data"); OGRReleaseDataSource(hDS); return NULL; } } } if (bWipeExistingData) { osSQL.Printf("DELETE FROM \"%s\"", osRasterLayer.c_str()); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); osSQL.Printf("DELETE FROM \"%s\"", osMetatadataLayer.c_str()); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } } return hDS; }
GDALDataset * RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0"); return NULL; } const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if ( hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return NULL; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return NULL; } int nXSize = GDALGetRasterXSize(poSrcDS); int nYSize = GDALGetRasterYSize(poSrcDS); double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { adfGeoTransform[0] = 0; adfGeoTransform[1] = 1; adfGeoTransform[2] = 0; adfGeoTransform[3] = 0; adfGeoTransform[4] = 0; adfGeoTransform[5] = -1; } else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms"); return NULL; } int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nXSize; nBlockYSize = nYSize; } /* -------------------------------------------------------------------- */ /* Analyze arguments */ /* -------------------------------------------------------------------- */ CPLString osDBName; CPLString osTableName; VSIStatBuf sBuf; int bExists; /* Skip optionnal RASTERLITE: prefix */ const char* pszFilenameWithoutPrefix = pszFilename; if (EQUALN(pszFilename, "RASTERLITE:", 11)) pszFilenameWithoutPrefix += 11; char** papszTokens = CSLTokenizeStringComplex( pszFilenameWithoutPrefix, ", ", FALSE, FALSE ); int nTokens = CSLCount(papszTokens); if (nTokens == 0) { osDBName = pszFilenameWithoutPrefix; osTableName = CPLGetBasename(pszFilenameWithoutPrefix); } else { osDBName = papszTokens[0]; int i; for(i=1;i<nTokens;i++) { if (EQUALN(papszTokens[i], "table=", 6)) osTableName = papszTokens[i] + 6; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid option : %s", papszTokens[i]); } } } CSLDestroy(papszTokens); papszTokens = NULL; bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0); if (osTableName.size() == 0) { if (bExists) { CPLError(CE_Failure, CPLE_AppDefined, "Database already exists. Explicit table name must be specified"); return NULL; } osTableName = CPLGetBasename(osDBName.c_str()); } CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); /* -------------------------------------------------------------------- */ /* Create or open the SQLite DB */ /* -------------------------------------------------------------------- */ if (OGRGetDriverCount() == 0) OGRRegisterAll(); OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite"); if (hSQLiteDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver"); return NULL; } OGRDataSourceH hDS; CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); if (!bExists) { char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES"); hDS = OGR_Dr_CreateDataSource(hSQLiteDriver, osDBName.c_str(), papszOGROptions); CSLDestroy(papszOGROptions); } else { hDS = OGROpen(osDBName.c_str(), TRUE, NULL); } CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); if (hDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load or create SQLite database"); return NULL; } CPLString osSQL; /* -------------------------------------------------------------------- */ /* Get the SRID for the SRS */ /* -------------------------------------------------------------------- */ int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef()); /* -------------------------------------------------------------------- */ /* Create or wipe existing tables */ /* -------------------------------------------------------------------- */ int bWipeExistingData = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO")); hDS = RasterliteCreateTables(hDS, osTableName.c_str(), nSRSId, bWipeExistingData); if (hDS == NULL) return NULL; OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); if (hRasterLayer == NULL || hMetadataLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find metadata and/or raster tables"); OGRReleaseDataSource(hDS); return NULL; } /* -------------------------------------------------------------------- */ /* Check if there is overlapping data and warn the user */ /* -------------------------------------------------------------------- */ double minx = adfGeoTransform[0]; double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; double maxy = adfGeoTransform[3]; double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" " "WHERE rowid IN " "(SELECT pkid FROM \"idx_%s_metadata_geometry\" " "WHERE xmin < %.15f AND xmax > %.15f " "AND ymin < %.15f AND ymax > %.15f) " "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), osTableName.c_str(), maxx, minx, maxy, miny, adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15, - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15); int nOverlappingGeoms = 0; OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hCountLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr); if (hFeat) { nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hCountLyr); } if (nOverlappingGeoms != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Raster tiles already exist in the %s table within " "the extent of the data to be inserted in", osTableName.c_str()); } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { OGRReleaseDataSource(hDS); return NULL; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) nReqXSize = nXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nYSize) nReqYSize = nYSize - nBlockYOff * nBlockYSize; eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszMEMDSOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszMEMDSOptions); CSLDestroy(papszMEMDSOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS)); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]); OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]); minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * adfGeoTransform[1]; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1]; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * adfGeoTransform[5]; miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5]; OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); CSLDestroy(papszTileDriverOptions); VSIFree(pabyMEMDSBuffer); OGRReleaseDataSource(hDS); return (GDALDataset*) GDALOpen(pszFilename, GA_Update); }
int main( int nArgc, char ** papszArgv ) { NITFFile *psFile; int iSegment, iFile; char szTemp[100]; int bDisplayTRE = FALSE; int bExtractSHP = FALSE, bExtractSHPInMem = FALSE; if( nArgc < 2 ) { printf( "Usage: nitfdump [-tre] [-extractshp | -extractshpinmem] <nitf_filename>*\n" ); exit( 1 ); } for( iFile = 1; iFile < nArgc; iFile++ ) { if ( EQUAL(papszArgv[iFile], "-tre") ) bDisplayTRE = TRUE; else if ( EQUAL(papszArgv[iFile], "-extractshp") ) bExtractSHP = TRUE; else if ( EQUAL(papszArgv[iFile], "-extractshpinmem") ) { bExtractSHP = TRUE; bExtractSHPInMem = TRUE; } } /* ==================================================================== */ /* Loop over all files. */ /* ==================================================================== */ for( iFile = 1; iFile < nArgc; iFile++ ) { int bHasFoundLocationTable = FALSE; if ( EQUAL(papszArgv[iFile], "-tre") ) continue; if ( EQUAL(papszArgv[iFile], "-extractshp") ) continue; if ( EQUAL(papszArgv[iFile], "-extractshpinmem") ) continue; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ psFile = NITFOpen( papszArgv[iFile], FALSE ); if( psFile == NULL ) exit( 2 ); printf( "Dump for %s\n", papszArgv[iFile] ); /* -------------------------------------------------------------------- */ /* Dump first TRE list. */ /* -------------------------------------------------------------------- */ if( psFile->pachTRE != NULL ) { int nTREBytes = psFile->nTREBytes; const char *pszTREData = psFile->pachTRE; printf( "File TREs:" ); while( nTREBytes > 10 ) { int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 )); if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11) { NITFGetField(szTemp, pszTREData, 0, 6 ); printf(" Invalid size (%d) for TRE %s", nThisTRESize, szTemp); break; } printf( " %6.6s(%d)", pszTREData, nThisTRESize ); pszTREData += nThisTRESize + 11; nTREBytes -= (nThisTRESize + 11); } printf( "\n" ); if (bDisplayTRE) { nTREBytes = psFile->nTREBytes; pszTREData = psFile->pachTRE; while( nTREBytes > 10 ) { char *pszEscaped; int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 )); if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11) { break; } pszEscaped = CPLEscapeString( pszTREData + 11, nThisTRESize, CPLES_BackslashQuotable ); printf( "TRE '%6.6s' : %s\n", pszTREData, pszEscaped); CPLFree(pszEscaped); pszTREData += nThisTRESize + 11; nTREBytes -= (nThisTRESize + 11); } } } /* -------------------------------------------------------------------- */ /* Dump Metadata */ /* -------------------------------------------------------------------- */ DumpMetadata( "File Metadata:", " ", psFile->papszMetadata ); /* -------------------------------------------------------------------- */ /* Dump general info about segments. */ /* -------------------------------------------------------------------- */ NITFCollectAttachments( psFile ); NITFReconcileAttachments( psFile ); for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ ) { NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment; printf( "Segment %d (Type=%s):\n", iSegment + 1, psSegInfo->szSegmentType ); printf( " HeaderStart=" CPL_FRMT_GUIB ", HeaderSize=%u, DataStart=" CPL_FRMT_GUIB ", DataSize=" CPL_FRMT_GUIB "\n", psSegInfo->nSegmentHeaderStart, psSegInfo->nSegmentHeaderSize, psSegInfo->nSegmentStart, psSegInfo->nSegmentSize ); printf( " DLVL=%d, ALVL=%d, LOC=C%d,R%d, CCS=C%d,R%d\n", psSegInfo->nDLVL, psSegInfo->nALVL, psSegInfo->nLOC_C, psSegInfo->nLOC_R, psSegInfo->nCCS_C, psSegInfo->nCCS_R ); printf( "\n" ); } /* -------------------------------------------------------------------- */ /* Report details of images. */ /* -------------------------------------------------------------------- */ for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ ) { NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment; NITFImage *psImage; NITFRPC00BInfo sRPCInfo; int iBand; char **papszMD; if( !EQUAL(psSegInfo->szSegmentType,"IM") ) continue; psImage = NITFImageAccess( psFile, iSegment ); if( psImage == NULL ) { printf( "NITFAccessImage(%d) failed!\n", iSegment ); continue; } printf( "Image Segment %d, %dPx%dLx%dB x %dbits:\n", iSegment + 1, psImage->nCols, psImage->nRows, psImage->nBands, psImage->nBitsPerSample ); printf( " PVTYPE=%s, IREP=%s, ICAT=%s, IMODE=%c, IC=%s, COMRAT=%s, ICORDS=%c\n", psImage->szPVType, psImage->szIREP, psImage->szICAT, psImage->chIMODE, psImage->szIC, psImage->szCOMRAT, psImage->chICORDS ); if( psImage->chICORDS != ' ' ) { printf( " UL=(%.15g,%.15g), UR=(%.15g,%.15g) Center=%d\n LL=(%.15g,%.15g), LR=(%.15g,%.15g)\n", psImage->dfULX, psImage->dfULY, psImage->dfURX, psImage->dfURY, psImage->bIsBoxCenterOfPixel, psImage->dfLLX, psImage->dfLLY, psImage->dfLRX, psImage->dfLRY ); } printf( " IDLVL=%d, IALVL=%d, ILOC R=%d,C=%d, IMAG=%s\n", psImage->nIDLVL, psImage->nIALVL, psImage->nILOCRow, psImage->nILOCColumn, psImage->szIMAG ); printf( " %d x %d blocks of size %d x %d\n", psImage->nBlocksPerRow, psImage->nBlocksPerColumn, psImage->nBlockWidth, psImage->nBlockHeight ); if( psImage->pachTRE != NULL ) { int nTREBytes = psImage->nTREBytes; const char *pszTREData = psImage->pachTRE; printf( " Image TREs:" ); while( nTREBytes > 10 ) { int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 )); if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11) { NITFGetField(szTemp, pszTREData, 0, 6 ); printf(" Invalid size (%d) for TRE %s", nThisTRESize, szTemp); break; } printf( " %6.6s(%d)", pszTREData, nThisTRESize ); pszTREData += nThisTRESize + 11; nTREBytes -= (nThisTRESize + 11); } printf( "\n" ); if (bDisplayTRE) { nTREBytes = psImage->nTREBytes; pszTREData = psImage->pachTRE; while( nTREBytes > 10 ) { char *pszEscaped; int nThisTRESize = atoi(NITFGetField(szTemp, pszTREData, 6, 5 )); if (nThisTRESize < 0 || nThisTRESize > nTREBytes - 11) { break; } pszEscaped = CPLEscapeString( pszTREData + 11, nThisTRESize, CPLES_BackslashQuotable ); printf( " TRE '%6.6s' : %s\n", pszTREData, pszEscaped); CPLFree(pszEscaped); pszTREData += nThisTRESize + 11; nTREBytes -= (nThisTRESize + 11); } } } /* Report info from location table, if found. */ if( psImage->nLocCount > 0 ) { int i; bHasFoundLocationTable = TRUE; printf( " Location Table\n" ); for( i = 0; i < psImage->nLocCount; i++ ) { printf( " LocName=%s, LocId=%d, Offset=%d, Size=%d\n", GetLocationNameFromId(psImage->pasLocations[i].nLocId), psImage->pasLocations[i].nLocId, psImage->pasLocations[i].nLocOffset, psImage->pasLocations[i].nLocSize ); } printf( "\n" ); } if( strlen(psImage->pszComments) > 0 ) printf( " Comments:\n%s\n", psImage->pszComments ); for( iBand = 0; iBand < psImage->nBands; iBand++ ) { NITFBandInfo *psBandInfo = psImage->pasBandInfo + iBand; printf( " Band %d: IREPBAND=%s, ISUBCAT=%s, %d LUT entries.\n", iBand + 1, psBandInfo->szIREPBAND, psBandInfo->szISUBCAT, psBandInfo->nSignificantLUTEntries ); } if( NITFReadRPC00B( psImage, &sRPCInfo ) ) { DumpRPC( psImage, &sRPCInfo ); } papszMD = NITFReadUSE00A( psImage ); if( papszMD != NULL ) { DumpMetadata( " USE00A TRE:", " ", papszMD ); CSLDestroy( papszMD ); } papszMD = NITFReadBLOCKA( psImage ); if( papszMD != NULL ) { DumpMetadata( " BLOCKA TRE:", " ", papszMD ); CSLDestroy( papszMD ); } papszMD = NITFReadSTDIDC( psImage ); if( papszMD != NULL ) { DumpMetadata( " STDIDC TRE:", " ", papszMD ); CSLDestroy( papszMD ); } DumpMetadata( " Image Metadata:", " ", psImage->papszMetadata ); printf("\n"); } /* ==================================================================== */ /* Report details of graphic segments. */ /* ==================================================================== */ for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ ) { NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment; char achSubheader[298]; int nSTYPEOffset; if( !EQUAL(psSegInfo->szSegmentType,"GR") && !EQUAL(psSegInfo->szSegmentType,"SY") ) continue; /* -------------------------------------------------------------------- */ /* Load the graphic subheader. */ /* -------------------------------------------------------------------- */ if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentHeaderStart, SEEK_SET ) != 0 || VSIFReadL( achSubheader, 1, sizeof(achSubheader), psFile->fp ) < 258 ) { CPLError( CE_Warning, CPLE_FileIO, "Failed to read graphic subheader at " CPL_FRMT_GUIB ".", psSegInfo->nSegmentHeaderStart ); continue; } // NITF 2.0. (also works for NITF 2.1) nSTYPEOffset = 200; if( STARTS_WITH_CI(achSubheader+193, "999998") ) nSTYPEOffset += 40; /* -------------------------------------------------------------------- */ /* Report some standard info. */ /* -------------------------------------------------------------------- */ printf( "Graphic Segment %d, type=%2.2s, sfmt=%c, sid=%10.10s\n", iSegment + 1, achSubheader + 0, achSubheader[nSTYPEOffset], achSubheader + 2 ); printf( " sname=%20.20s\n", achSubheader + 12 ); printf("\n"); } /* ==================================================================== */ /* Report details of text segments. */ /* ==================================================================== */ for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ ) { char *pabyHeaderData; char *pabyTextData; NITFSegmentInfo *psSegment = psFile->pasSegmentInfo + iSegment; if( !EQUAL(psSegment->szSegmentType,"TX") ) continue; printf( "Text Segment %d\n", iSegment + 1); /* -------------------------------------------------------------------- */ /* Load the text header */ /* -------------------------------------------------------------------- */ /* Allocate one extra byte for the NULL terminating character */ pabyHeaderData = (char *) CPLCalloc(1, (size_t) psSegment->nSegmentHeaderSize + 1); if (VSIFSeekL(psFile->fp, psSegment->nSegmentHeaderStart, SEEK_SET) != 0 || VSIFReadL(pabyHeaderData, 1, (size_t) psSegment->nSegmentHeaderSize, psFile->fp) != psSegment->nSegmentHeaderSize) { CPLError( CE_Warning, CPLE_FileIO, "Failed to read %d bytes of text header data at " CPL_FRMT_GUIB ".", psSegment->nSegmentHeaderSize, psSegment->nSegmentHeaderStart); CPLFree(pabyHeaderData); continue; } printf(" Header : %s\n", pabyHeaderData); CPLFree(pabyHeaderData); /* -------------------------------------------------------------------- */ /* Load the raw TEXT data itself. */ /* -------------------------------------------------------------------- */ /* Allocate one extra byte for the NULL terminating character */ pabyTextData = (char *) CPLCalloc(1,(size_t)psSegment->nSegmentSize+1); if( VSIFSeekL( psFile->fp, psSegment->nSegmentStart, SEEK_SET ) != 0 || VSIFReadL( pabyTextData, 1, (size_t)psSegment->nSegmentSize, psFile->fp ) != psSegment->nSegmentSize ) { CPLError( CE_Warning, CPLE_FileIO, "Failed to read " CPL_FRMT_GUIB " bytes of text data at " CPL_FRMT_GUIB ".", psSegment->nSegmentSize, psSegment->nSegmentStart ); CPLFree( pabyTextData ); continue; } printf(" Data : %s\n", pabyTextData); printf("\n"); CPLFree( pabyTextData ); } /* -------------------------------------------------------------------- */ /* Report details of DES. */ /* -------------------------------------------------------------------- */ for( iSegment = 0; iSegment < psFile->nSegmentCount; iSegment++ ) { NITFSegmentInfo *psSegInfo = psFile->pasSegmentInfo + iSegment; NITFDES *psDES; int nOffset = 0; char szTREName[7]; int nThisTRESize; int nRPFDESOffset = -1; if( !EQUAL(psSegInfo->szSegmentType,"DE") ) continue; psDES = NITFDESAccess( psFile, iSegment ); if( psDES == NULL ) { printf( "NITFDESAccess(%d) failed!\n", iSegment ); continue; } printf( "DE Segment %d:\n", iSegment + 1 ); printf( " Segment TREs:" ); nOffset = 0; while (NITFDESGetTRE( psDES, nOffset, szTREName, NULL, &nThisTRESize)) { printf( " %6.6s(%d)", szTREName, nThisTRESize ); if (strcmp(szTREName, "RPFDES") == 0) nRPFDESOffset = nOffset + 11; nOffset += 11 + nThisTRESize; } printf( "\n" ); if (bDisplayTRE) { char* pabyTREData = NULL; nOffset = 0; while (NITFDESGetTRE( psDES, nOffset, szTREName, &pabyTREData, &nThisTRESize)) { char* pszEscaped = CPLEscapeString( pabyTREData, nThisTRESize, CPLES_BackslashQuotable ); printf( " TRE '%6.6s' : %s\n", szTREName, pszEscaped); CPLFree(pszEscaped); nOffset += 11 + nThisTRESize; NITFDESFreeTREData(pabyTREData); } } /* Report info from location table, if found. */ if( !bHasFoundLocationTable && nRPFDESOffset >= 0 ) { int i; int nLocCount = 0; NITFLocation* pasLocations; VSIFSeekL(psFile->fp, psSegInfo->nSegmentStart + nRPFDESOffset, SEEK_SET); pasLocations = NITFReadRPFLocationTable(psFile->fp, &nLocCount); if (pasLocations) { printf( " Location Table\n" ); for( i = 0; i < nLocCount; i++ ) { printf( " LocName=%s, LocId=%d, Offset=%d, Size=%d\n", GetLocationNameFromId(pasLocations[i].nLocId), pasLocations[i].nLocId, pasLocations[i].nLocOffset, pasLocations[i].nLocSize ); } CPLFree(pasLocations); printf( "\n" ); } } DumpMetadata( " DES Metadata:", " ", psDES->papszMetadata ); if ( bExtractSHP && CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE_USE") != NULL ) { char szFilename[32]; char szRadix[32]; if (bExtractSHPInMem) snprintf(szRadix, sizeof(szRadix), "/vsimem/nitf_segment_%d", iSegment + 1); else snprintf(szRadix, sizeof(szRadix), "nitf_segment_%d", iSegment + 1); if (NITFDESExtractShapefile(psDES, szRadix)) { OGRDataSourceH hDS; OGRRegisterAll(); snprintf(szFilename, sizeof(szFilename), "%s.SHP", szRadix); hDS = OGROpen(szFilename, FALSE, NULL); if (hDS) { int nGeom = 0; OGRLayerH hLayer = OGR_DS_GetLayer(hDS, 0); if (hLayer) { OGRFeatureH hFeat; printf("\n"); while ( (hFeat = OGR_L_GetNextFeature(hLayer)) != NULL ) { OGRGeometryH hGeom = OGR_F_GetGeometryRef(hFeat); if (hGeom) { char* pszWKT = NULL; OGR_G_ExportToWkt(hGeom, &pszWKT); if (pszWKT) printf(" Geometry %d : %s\n", nGeom ++, pszWKT); CPLFree(pszWKT); } OGR_F_Destroy(hFeat); } } OGR_DS_Destroy(hDS); } } if (bExtractSHPInMem) { snprintf(szFilename, sizeof(szFilename), "%s.SHP", szRadix); VSIUnlink(szFilename); snprintf(szFilename, sizeof(szFilename), "%s.SHX", szRadix); VSIUnlink(szFilename); snprintf(szFilename, sizeof(szFilename), "%s.DBF", szRadix); VSIUnlink(szFilename); } } } /* -------------------------------------------------------------------- */ /* Close. */ /* -------------------------------------------------------------------- */ NITFClose( psFile ); } CPLFinderClean(); CPLCleanupTLS(); VSICleanupFileManager(); OGRCleanupAll(); exit( 0 ); }
static CPLErr ProcessLayer( OGRLayerH hSrcLayer, int bSRSIsSet, GDALDatasetH hDstDS, std::vector<int> anBandList, const std::vector<double> &adfBurnValues, int b3D, int bInverse, const char *pszBurnAttribute, char **papszRasterizeOptions, GDALProgressFunc pfnProgress, void* pProgressData ) { /* -------------------------------------------------------------------- */ /* Checkout that SRS are the same. */ /* If -a_srs is specified, skip the test */ /* -------------------------------------------------------------------- */ OGRCoordinateTransformationH hCT = NULL; if (!bSRSIsSet) { OGRSpatialReferenceH hDstSRS = NULL; if( GDALGetProjectionRef( hDstDS ) != NULL ) { char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDstDS ); hDstSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hDstSRS, &pszProjection ) != OGRERR_NONE ) { OSRDestroySpatialReference(hDstSRS); hDstSRS = NULL; } } OGRSpatialReferenceH hSrcSRS = OGR_L_GetSpatialRef(hSrcLayer); if( hDstSRS != NULL && hSrcSRS != NULL ) { if( OSRIsSame(hSrcSRS, hDstSRS) == FALSE ) { hCT = OCTNewCoordinateTransformation(hSrcSRS, hDstSRS); if( hCT == NULL ) { CPLError(CE_Warning, CPLE_AppDefined, "The output raster dataset and the input vector layer do not have the same SRS.\n" "And reprojection of input data did not work. Results might be incorrect."); } } } else if( hDstSRS != NULL && hSrcSRS == NULL ) { CPLError(CE_Warning, CPLE_AppDefined, "The output raster dataset has a SRS, but the input vector layer SRS is unknown.\n" "Ensure input vector has the same SRS, otherwise results might be incorrect."); } else if( hDstSRS == NULL && hSrcSRS != NULL ) { CPLError(CE_Warning, CPLE_AppDefined, "The input vector layer has a SRS, but the output raster dataset SRS is unknown.\n" "Ensure output raster dataset has the same SRS, otherwise results might be incorrect."); } if( hDstSRS != NULL ) { OSRDestroySpatialReference(hDstSRS); } } /* -------------------------------------------------------------------- */ /* Get field index, and check. */ /* -------------------------------------------------------------------- */ int iBurnField = -1; if( pszBurnAttribute ) { iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ), pszBurnAttribute ); if( iBurnField == -1 ) { CPLError(CE_Failure, CPLE_AppDefined, "Failed to find field %s on layer %s, skipping.", pszBurnAttribute, OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) ); if( hCT != NULL ) OCTDestroyCoordinateTransformation(hCT); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Collect the geometries from this layer, and build list of */ /* burn values. */ /* -------------------------------------------------------------------- */ OGRFeatureH hFeat; std::vector<OGRGeometryH> ahGeometries; std::vector<double> adfFullBurnValues; OGR_L_ResetReading( hSrcLayer ); while( (hFeat = OGR_L_GetNextFeature( hSrcLayer )) != NULL ) { OGRGeometryH hGeom; if( OGR_F_GetGeometryRef( hFeat ) == NULL ) { OGR_F_Destroy( hFeat ); continue; } hGeom = OGR_G_Clone( OGR_F_GetGeometryRef( hFeat ) ); if( hCT != NULL ) { if( OGR_G_Transform(hGeom, hCT) != OGRERR_NONE ) { OGR_F_Destroy( hFeat ); OGR_G_DestroyGeometry(hGeom); continue; } } ahGeometries.push_back( hGeom ); for( unsigned int iBand = 0; iBand < anBandList.size(); iBand++ ) { if( adfBurnValues.size() > 0 ) adfFullBurnValues.push_back( adfBurnValues[MIN(iBand,adfBurnValues.size()-1)] ); else if( pszBurnAttribute ) { adfFullBurnValues.push_back( OGR_F_GetFieldAsDouble( hFeat, iBurnField ) ); } /* I have made the 3D option exclusive to other options since it can be used to modify the value from "-burn value" or "-a attribute_name" */ if( b3D ) { // TODO: get geometry "z" value /* Points and Lines will have their "z" values collected at the point and line levels respectively. However filled polygons (GDALdllImageFilledPolygon) can use some help by getting their "z" values here. */ adfFullBurnValues.push_back( 0.0 ); } } OGR_F_Destroy( hFeat ); } if( hCT != NULL ) OCTDestroyCoordinateTransformation(hCT); /* -------------------------------------------------------------------- */ /* If we are in inverse mode, we add one extra ring around the */ /* whole dataset to invert the concept of insideness and then */ /* merge everything into one geometry collection. */ /* -------------------------------------------------------------------- */ if( bInverse ) { if( ahGeometries.size() == 0 ) { for( unsigned int iBand = 0; iBand < anBandList.size(); iBand++ ) { if( adfBurnValues.size() > 0 ) adfFullBurnValues.push_back( adfBurnValues[MIN(iBand,adfBurnValues.size()-1)] ); else /* FIXME? Not sure what to do exactly in the else case, but we must insert a value */ adfFullBurnValues.push_back( 0.0 ); } } InvertGeometries( hDstDS, ahGeometries ); } /* -------------------------------------------------------------------- */ /* Perform the burn. */ /* -------------------------------------------------------------------- */ CPLErr eErr = GDALRasterizeGeometries( hDstDS, static_cast<int>(anBandList.size()), &(anBandList[0]), static_cast<int>(ahGeometries.size()), &(ahGeometries[0]), NULL, NULL, &(adfFullBurnValues[0]), papszRasterizeOptions, pfnProgress, pProgressData ); /* -------------------------------------------------------------------- */ /* Cleanup geometries. */ /* -------------------------------------------------------------------- */ int iGeom; for( iGeom = static_cast<int>(ahGeometries.size())-1; iGeom >= 0; iGeom-- ) OGR_G_DestroyGeometry( ahGeometries[iGeom] ); return eErr; }
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()); } }
CPLErr RasterliteDataset::ReloadOverviews() { if (nLevel != 0) return CE_Failure; /* -------------------------------------------------------------------- */ /* Fetch resolutions */ /* -------------------------------------------------------------------- */ CPLString osSQL; OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr) { osSQL.Printf("SELECT pixel_x_size, pixel_y_size " "FROM raster_pyramids WHERE table_prefix = '%s' " "ORDER BY pixel_x_size ASC", osTableName.c_str()); } else { osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size " "FROM \"%s_metadata\" WHERE pixel_x_size != 0 " "ORDER BY pixel_x_size ASC", osTableName.c_str()); } OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr == NULL) { if (hRasterPyramidsLyr == NULL) return CE_Failure; osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size " "FROM \"%s_metadata\" WHERE pixel_x_size != 0 " "ORDER BY pixel_x_size ASC", osTableName.c_str()); hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr == NULL) return CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ int i; for(i=1;i<nResolutions;i++) delete papoOverviews[i-1]; CPLFree(papoOverviews); papoOverviews = NULL; CPLFree(padfXResolutions); padfXResolutions = NULL; CPLFree(padfYResolutions); padfYResolutions = NULL; /* -------------------------------------------------------------------- */ /* Rebuild arrays */ /* -------------------------------------------------------------------- */ nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE); padfXResolutions = (double*)CPLMalloc(sizeof(double) * nResolutions); padfYResolutions = (double*)CPLMalloc(sizeof(double) * nResolutions); i = 0; OGRFeatureH hFeat; while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL) { padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0); padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1); OGR_F_Destroy(hFeat); i ++; } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); hSQLLyr = NULL; /* -------------------------------------------------------------------- */ /* Add overview levels as internal datasets */ /* -------------------------------------------------------------------- */ if (nResolutions > 1) { CPLString osRasterTableName = osTableName; osRasterTableName += "_rasters"; OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str()); papoOverviews = (RasterliteDataset**) CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*)); int nLev; for(nLev=1;nLev<nResolutions;nLev++) { int nOvrBands; GDALDataType eOvrDataType; int nBlockXSize, nBlockYSize; if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType, &nBlockXSize, &nBlockYSize)) { if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3) nOvrBands = 3; papoOverviews[nLev-1] = new RasterliteDataset(this, nLev); int iBand; for(iBand=0;iBand<nBands;iBand++) { papoOverviews[nLev-1]->SetBand(iBand+1, new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType, nBlockXSize, nBlockYSize)); } } else { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find block characteristics for overview %d", nLev); papoOverviews[nLev-1] = NULL; } } } return CE_None; }
CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor, GDALProgressFunc pfnProgress, void * pProgressData) { double dfXResolution = padfXResolutions[0] * nOvrFactor; double dfYResolution = padfXResolutions[0] * nOvrFactor; CPLString osSQL; int nBlockXSize = 256; int nBlockYSize = 256; int nOvrXSize = nRasterXSize / nOvrFactor; int nOvrYSize = nRasterYSize / nOvrFactor; if (nOvrXSize == 0 || nOvrYSize == 0) return CE_Failure; int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize; const char* pszDriverName = "GTiff"; GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if (hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return CE_Failure; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return CE_Failure; } GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { return CE_Failure; } char** papszTileDriverOptions = NULL; CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); CPLString osSourceName = "unknown"; osSQL.Printf("SELECT source_name FROM \"%s\" WHERE " "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1", osMetatadataLayer.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0); if (pszVal) osSourceName = pszVal; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } /* -------------------------------------------------------------------- */ /* Compute up to which existing overview level we can use for */ /* computing the requested overview */ /* -------------------------------------------------------------------- */ int iLev; nLimitOvrCount = 0; for(iLev=1;iLev<nResolutions;iLev++) { if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 && padfYResolutions[iLev] < dfYResolution - 1e-10)) { break; } nLimitOvrCount++; } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nOvrXSize) nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nOvrYSize) nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize; eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszOptions); CSLDestroy(papszOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, osSourceName); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, dfXResolution); OGR_F_SetFieldDouble(hFeat, 5, dfYResolution); double minx, maxx, maxy, miny; minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * dfXResolution; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * (-dfYResolution); miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution); OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } nLimitOvrCount = -1; if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); VSIFree(pabyMEMDSBuffer); /* -------------------------------------------------------------------- */ /* Update raster_pyramids table */ /* -------------------------------------------------------------------- */ if (eErr == CE_None) { OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr == NULL) { osSQL.Printf ("CREATE TABLE raster_pyramids (" "table_prefix TEXT NOT NULL," "pixel_x_size DOUBLE NOT NULL," "pixel_y_size DOUBLE NOT NULL," "tile_count INTEGER NOT NULL)"); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Re-open the DB to take into account the new tables*/ OGRReleaseDataSource(hDS); CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); hDS = OGROpen(osFileName.c_str(), TRUE, NULL); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); } /* Insert base resolution into raster_pyramids if not already done */ int bHasBaseResolution = FALSE; osSQL.Printf("SELECT * FROM raster_pyramids WHERE " "table_prefix = '%s' AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osTableName.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { bHasBaseResolution = TRUE; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } if (!bHasBaseResolution) { osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE " "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); int nBlocksMainRes = 0; hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } osSQL.Printf("INSERT INTO raster_pyramids " "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) " "VALUES ( '%s', %.18f, %.18f, %d )", osTableName.c_str(), padfXResolutions[0], padfYResolutions[0], nBlocksMainRes); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } osSQL.Printf("INSERT INTO raster_pyramids " "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) " "VALUES ( '%s', %.18f, %.18f, %d )", osTableName.c_str(), dfXResolution, dfYResolution, nTotalBlocks); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } return eErr; }
static CPLErr ProcessLayer( OGRLayerH hSrcLayer, GDALDatasetH hDstDS, OGRGeometry *poClipSrc, GUInt32 nXSize, GUInt32 nYSize, int nBand, int& bIsXExtentSet, int& bIsYExtentSet, double& dfXMin, double& dfXMax, double& dfYMin, double& dfYMax, const char *pszBurnAttribute, const double dfIncreaseBurnValue, const double dfMultiplyBurnValue, GDALDataType eType, GDALGridAlgorithm eAlgorithm, void *pOptions, int bQuiet, GDALProgressFunc pfnProgress ) { /* -------------------------------------------------------------------- */ /* Get field index, and check. */ /* -------------------------------------------------------------------- */ int iBurnField = -1; if ( pszBurnAttribute ) { iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ), pszBurnAttribute ); if( iBurnField == -1 ) { printf( "Failed to find field %s on layer %s, skipping.\n", pszBurnAttribute, OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Collect the geometries from this layer, and build list of */ /* values to be interpolated. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeat; std::vector<double> adfX, adfY, adfZ; OGR_L_ResetReading( hSrcLayer ); while( (poFeat = (OGRFeature *)OGR_L_GetNextFeature( hSrcLayer )) != NULL ) { OGRGeometry *poGeom = poFeat->GetGeometryRef(); double dfBurnValue = 0.0; if ( iBurnField >= 0 ) dfBurnValue = poFeat->GetFieldAsDouble( iBurnField ); ProcessCommonGeometry(poGeom, poClipSrc, iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ); OGRFeature::DestroyFeature( poFeat ); } if ( adfX.size() == 0 ) { printf( "No point geometry found on layer %s, skipping.\n", OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) ); return CE_None; } /* -------------------------------------------------------------------- */ /* Compute grid geometry. */ /* -------------------------------------------------------------------- */ if ( !bIsXExtentSet || !bIsYExtentSet ) { OGREnvelope sEnvelope; OGR_L_GetExtent( hSrcLayer, &sEnvelope, TRUE ); if ( !bIsXExtentSet ) { dfXMin = sEnvelope.MinX; dfXMax = sEnvelope.MaxX; bIsXExtentSet = TRUE; } if ( !bIsYExtentSet ) { dfYMin = sEnvelope.MinY; dfYMax = sEnvelope.MaxY; bIsYExtentSet = TRUE; } } /* -------------------------------------------------------------------- */ /* Perform gridding. */ /* -------------------------------------------------------------------- */ const double dfDeltaX = ( dfXMax - dfXMin ) / nXSize; const double dfDeltaY = ( dfYMax - dfYMin ) / nYSize; if ( !bQuiet ) { printf( "Grid data type is \"%s\"\n", GDALGetDataTypeName(eType) ); printf( "Grid size = (%lu %lu).\n", (unsigned long)nXSize, (unsigned long)nYSize ); printf( "Corner coordinates = (%f %f)-(%f %f).\n", dfXMin - dfDeltaX / 2, dfYMax + dfDeltaY / 2, dfXMax + dfDeltaX / 2, dfYMin - dfDeltaY / 2 ); printf( "Grid cell size = (%f %f).\n", dfDeltaX, dfDeltaY ); printf( "Source point count = %lu.\n", (unsigned long)adfX.size() ); PrintAlgorithmAndOptions( eAlgorithm, pOptions ); printf("\n"); } GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, nBand ); if (adfX.size() == 0) { // FIXME: Shoulda' set to nodata value instead GDALFillRaster( hBand, 0.0 , 0.0 ); return CE_None; } GUInt32 nXOffset, nYOffset; int nBlockXSize, nBlockYSize; int nDataTypeSize = GDALGetDataTypeSize(eType) / 8; // Try to grow the work buffer up to 16 MB if it is smaller GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); const GUInt32 nDesiredBufferSize = 16*1024*1024; if( (GUInt32)nBlockXSize < nXSize && (GUInt32)nBlockYSize < nYSize && (GUInt32)nBlockXSize < nDesiredBufferSize / (nBlockYSize * nDataTypeSize) ) { int nNewBlockXSize = nDesiredBufferSize / (nBlockYSize * nDataTypeSize); nBlockXSize = (nNewBlockXSize / nBlockXSize) * nBlockXSize; if( (GUInt32)nBlockXSize > nXSize ) nBlockXSize = nXSize; } else if( (GUInt32)nBlockXSize == nXSize && (GUInt32)nBlockYSize < nYSize && (GUInt32)nBlockYSize < nDesiredBufferSize / (nXSize * nDataTypeSize) ) { int nNewBlockYSize = nDesiredBufferSize / (nXSize * nDataTypeSize); nBlockYSize = (nNewBlockYSize / nBlockYSize) * nBlockYSize; if( (GUInt32)nBlockYSize > nYSize ) nBlockYSize = nYSize; } CPLDebug("GDAL_GRID", "Work buffer: %d * %d", nBlockXSize, nBlockYSize); void *pData = VSIMalloc3( nBlockXSize, nBlockYSize, nDataTypeSize ); if( pData == NULL ) { CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate work buffer"); return CE_Failure; } GUInt32 nBlock = 0; GUInt32 nBlockCount = ((nXSize + nBlockXSize - 1) / nBlockXSize) * ((nYSize + nBlockYSize - 1) / nBlockYSize); CPLErr eErr = CE_None; for ( nYOffset = 0; nYOffset < nYSize && eErr == CE_None; nYOffset += nBlockYSize ) { for ( nXOffset = 0; nXOffset < nXSize && eErr == CE_None; nXOffset += nBlockXSize ) { void *pScaledProgress; pScaledProgress = GDALCreateScaledProgress( (double)nBlock / nBlockCount, (double)(nBlock + 1) / nBlockCount, pfnProgress, NULL ); nBlock ++; int nXRequest = nBlockXSize; if (nXOffset + nXRequest > nXSize) nXRequest = nXSize - nXOffset; int nYRequest = nBlockYSize; if (nYOffset + nYRequest > nYSize) nYRequest = nYSize - nYOffset; eErr = GDALGridCreate( eAlgorithm, pOptions, adfX.size(), &(adfX[0]), &(adfY[0]), &(adfZ[0]), dfXMin + dfDeltaX * nXOffset, dfXMin + dfDeltaX * (nXOffset + nXRequest), dfYMin + dfDeltaY * nYOffset, dfYMin + dfDeltaY * (nYOffset + nYRequest), nXRequest, nYRequest, eType, pData, GDALScaledProgress, pScaledProgress ); if( eErr == CE_None ) eErr = GDALRasterIO( hBand, GF_Write, nXOffset, nYOffset, nXRequest, nYRequest, pData, nXRequest, nYRequest, eType, 0, 0 ); GDALDestroyScaledProgress( pScaledProgress ); } } CPLFree( pData ); return eErr; }
MAIN_START(argc, argv) { // Check that we are running against at least GDAL 1.4. // Note to developers: if we use newer API, please change the requirement. if( atoi(GDALVersionInfo("VERSION_NUM")) < 1400 ) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Get commandline arguments other than the GDAL raster filenames. */ /* -------------------------------------------------------------------- */ const char* pszIndexLayerName = nullptr; const char *index_filename = nullptr; const char *tile_index = "location"; const char* pszDriverName = nullptr; size_t nMaxFieldSize = 254; bool write_absolute_path = false; char* current_path = nullptr; bool skip_different_projection = false; const char *pszTargetSRS = ""; bool bSetTargetSRS = false; const char* pszSrcSRSName = nullptr; int i_SrcSRSName = -1; bool bSrcSRSFormatSpecified = false; SrcSRSFormat eSrcSRSFormat = FORMAT_AUTO; int iArg = 1; // Used after for. for( ; iArg < argc; iArg++ ) { if( EQUAL(argv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against " "GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy( argv ); return 0; } else if( EQUAL(argv[iArg],"--help") ) Usage(nullptr); else if( (strcmp(argv[iArg],"-f") == 0 || strcmp(argv[iArg],"-of") == 0) ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszDriverName = argv[++iArg]; } else if( strcmp(argv[iArg],"-lyr_name") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszIndexLayerName = argv[++iArg]; } else if( strcmp(argv[iArg],"-tileindex") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); tile_index = argv[++iArg]; } else if( strcmp(argv[iArg],"-t_srs") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszTargetSRS = argv[++iArg]; bSetTargetSRS = true; } else if ( strcmp(argv[iArg],"-write_absolute_path") == 0 ) { write_absolute_path = true; } else if ( strcmp(argv[iArg],"-skip_different_projection") == 0 ) { skip_different_projection = true; } else if( strcmp(argv[iArg], "-src_srs_name") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszSrcSRSName = argv[++iArg]; } else if( strcmp(argv[iArg], "-src_srs_format") == 0 ) { const char* pszFormat; bSrcSRSFormatSpecified = true; CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszFormat = argv[++iArg]; if( EQUAL(pszFormat, "AUTO") ) eSrcSRSFormat = FORMAT_AUTO; else if( EQUAL(pszFormat, "WKT") ) eSrcSRSFormat = FORMAT_WKT; else if( EQUAL(pszFormat, "EPSG") ) eSrcSRSFormat = FORMAT_EPSG; else if( EQUAL(pszFormat, "PROJ") ) eSrcSRSFormat = FORMAT_PROJ; } else if( argv[iArg][0] == '-' ) Usage(CPLSPrintf("Unknown option name '%s'", argv[iArg])); else if( index_filename == nullptr ) { index_filename = argv[iArg]; iArg++; break; } } if( index_filename == nullptr ) Usage("No index filename specified."); if( iArg == argc ) Usage("No file to index specified."); if( bSrcSRSFormatSpecified && pszSrcSRSName == nullptr ) Usage("-src_srs_name must be specified when -src_srs_format is " "specified."); /* -------------------------------------------------------------------- */ /* Create and validate target SRS if given. */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hTargetSRS = nullptr; if( bSetTargetSRS ) { if( skip_different_projection ) { fprintf( stderr, "Warning : -skip_different_projection does not apply " "when -t_srs is requested.\n" ); } hTargetSRS = OSRNewSpatialReference(""); OSRSetAxisMappingStrategy(hTargetSRS, OAMS_TRADITIONAL_GIS_ORDER); // coverity[tainted_data] if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None ) { OSRDestroySpatialReference( hTargetSRS ); fprintf( stderr, "Invalid target SRS `%s'.\n", pszTargetSRS ); exit(1); } } /* -------------------------------------------------------------------- */ /* Open or create the target datasource */ /* -------------------------------------------------------------------- */ GDALDatasetH hTileIndexDS = GDALOpenEx( index_filename, GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr ); OGRLayerH hLayer = nullptr; CPLString osFormat; if( hTileIndexDS != nullptr ) { GDALDriverH hDriver = GDALGetDatasetDriver(hTileIndexDS); if( hDriver ) osFormat = GDALGetDriverShortName(hDriver); if( GDALDatasetGetLayerCount(hTileIndexDS) == 1 ) { hLayer = GDALDatasetGetLayer(hTileIndexDS, 0); } else { if( pszIndexLayerName == nullptr ) { printf( "-lyr_name must be specified.\n" ); exit( 1 ); } CPLPushErrorHandler(CPLQuietErrorHandler); hLayer = GDALDatasetGetLayerByName(hTileIndexDS, pszIndexLayerName); CPLPopErrorHandler(); } } else { printf( "Creating new index file...\n" ); if( pszDriverName == nullptr ) { std::vector<CPLString> aoDrivers = GetOutputDriversFor(index_filename, GDAL_OF_VECTOR); if( aoDrivers.empty() ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot guess driver for %s", index_filename); exit( 10 ); } else { if( aoDrivers.size() > 1 ) { CPLError( CE_Warning, CPLE_AppDefined, "Several drivers matching %s extension. Using %s", CPLGetExtension(index_filename), aoDrivers[0].c_str() ); } osFormat = aoDrivers[0]; } } else { osFormat = pszDriverName; } if( !EQUAL(osFormat, "ESRI Shapefile") ) nMaxFieldSize = 0; GDALDriverH hDriver = GDALGetDriverByName( osFormat.c_str() ); if( hDriver == nullptr ) { printf( "%s driver not available.\n", osFormat.c_str() ); exit( 1 ); } hTileIndexDS = GDALCreate( hDriver, index_filename, 0, 0, 0, GDT_Unknown, nullptr ); } if( hTileIndexDS != nullptr && hLayer == nullptr ) { OGRSpatialReferenceH hSpatialRef = nullptr; char* pszLayerName = nullptr; if( pszIndexLayerName == nullptr ) { VSIStatBuf sStat; if( EQUAL(osFormat, "ESRI Shapefile") || VSIStat(index_filename, &sStat) == 0 ) { pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); } else { printf( "-lyr_name must be specified.\n" ); exit( 1 ); } } else { pszLayerName = CPLStrdup(pszIndexLayerName); } /* get spatial reference for output file from target SRS (if set) */ /* or from first input file */ if( bSetTargetSRS ) { hSpatialRef = OSRClone( hTargetSRS ); } else { GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly ); if( hDS ) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != nullptr && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); OSRSetAxisMappingStrategy(hSpatialRef, OAMS_TRADITIONAL_GIS_ORDER); } GDALClose(hDS); } } hLayer = GDALDatasetCreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, nullptr ); CPLFree(pszLayerName); if( hSpatialRef ) OSRRelease(hSpatialRef); if( hLayer ) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); if( nMaxFieldSize ) OGR_Fld_SetWidth( hFieldDefn, static_cast<int>(nMaxFieldSize)); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); if( pszSrcSRSName != nullptr ) { hFieldDefn = OGR_Fld_Create( pszSrcSRSName, OFTString ); if( nMaxFieldSize ) OGR_Fld_SetWidth(hFieldDefn, static_cast<int>(nMaxFieldSize)); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == nullptr || hLayer == nullptr ) { fprintf( stderr, "Unable to open/create shapefile `%s'.\n", index_filename ); exit(2); } OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hLayer); const int ti_field = OGR_FD_GetFieldIndex( hFDefn, tile_index ); if( ti_field < 0 ) { fprintf( stderr, "Unable to find field `%s' in file `%s'.\n", tile_index, index_filename ); exit(2); } if( pszSrcSRSName != nullptr ) i_SrcSRSName = OGR_FD_GetFieldIndex( hFDefn, pszSrcSRSName ); // Load in memory existing file names in SHP. int nExistingFiles = static_cast<int>(OGR_L_GetFeatureCount(hLayer, FALSE)); if( nExistingFiles < 0) nExistingFiles = 0; char** existingFilesTab = nullptr; bool alreadyExistingProjectionRefValid = false; char* alreadyExistingProjectionRef = nullptr; if( nExistingFiles > 0 ) { OGRFeatureH hFeature = nullptr; existingFilesTab = static_cast<char **>( CPLMalloc(nExistingFiles * sizeof(char*))); for( int i = 0; i < nExistingFiles; i++ ) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if( i == 0 ) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if( hDS ) { alreadyExistingProjectionRefValid = true; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if( write_absolute_path ) { current_path = CPLGetCurrentDir(); if (current_path == nullptr) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n" ); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ for( ; iArg < argc; iArg++ ) { char *fileNameToWrite = nullptr; VSIStatBuf sStatBuf; // Make sure it is a file before building absolute path name. if( write_absolute_path && CPLIsFilenameRelative( argv[iArg] ) && VSIStat( argv[iArg], &sStatBuf ) == 0 ) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[iArg])); } else { fileNameToWrite = CPLStrdup(argv[iArg]); } // Checks that file is not already in tileindex. { int i = 0; // Used after for. for( ; i < nExistingFiles; i++ ) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } } GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly ); if( hDS == nullptr ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv[iArg] ); CPLFree(fileNameToWrite); continue; } double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && std::abs(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv[iArg] ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } const char *projectionRef = GDALGetProjectionRef(hDS); // If not set target srs, test that the current file uses same // projection as others. if( !bSetTargetSRS ) { if( alreadyExistingProjectionRefValid ) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf( stderr, "Warning : %s is not using the same projection system " "as other files in the tileindex.\n" "This may cause problems when using it in MapServer " "for example.\n" "Use -t_srs option to set target projection system " "(not supported by MapServer).\n" "%s\n", argv[iArg], skip_different_projection ? "Skipping this file." : ""); if( skip_different_projection ) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = true; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } } const int nXSize = GDALGetRasterXSize( hDS ); const int nYSize = GDALGetRasterYSize( hDS ); double adfX[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; double adfY[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; OGRSpatialReferenceH hSourceSRS = nullptr; if( (bSetTargetSRS || i_SrcSRSName >= 0) && projectionRef != nullptr && projectionRef[0] != '\0' ) { hSourceSRS = OSRNewSpatialReference( projectionRef ); OSRSetAxisMappingStrategy(hSourceSRS, OAMS_TRADITIONAL_GIS_ORDER); } // If set target srs, do the forward transformation of all points. if( bSetTargetSRS && projectionRef != nullptr && projectionRef[0] != '\0' ) { OGRCoordinateTransformationH hCT = nullptr; if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) ) { hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS ); if( hCT == nullptr || !OCTTransform( hCT, 5, adfX, adfY, nullptr ) ) { fprintf( stderr, "Warning : unable to transform points from source " "SRS `%s' to target SRS `%s'\n" "for file `%s' - file skipped\n", projectionRef, pszTargetSRS, fileNameToWrite ); if( hCT ) OCTDestroyCoordinateTransformation( hCT ); if( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); continue; } if( hCT ) OCTDestroyCoordinateTransformation( hCT ); } } OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); if( i_SrcSRSName >= 0 && hSourceSRS != nullptr ) { const char* pszAuthorityCode = OSRGetAuthorityCode(hSourceSRS, nullptr); const char* pszAuthorityName = OSRGetAuthorityName(hSourceSRS, nullptr); if( eSrcSRSFormat == FORMAT_AUTO ) { if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, CPLSPrintf("%s:%s", pszAuthorityName, pszAuthorityCode) ); } else if( nMaxFieldSize == 0 || strlen(projectionRef) <= nMaxFieldSize ) { OGR_F_SetFieldString(hFeature, i_SrcSRSName, projectionRef); } else { char* pszProj4 = nullptr; if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 ); CPLFree(pszProj4); } else { OGR_F_SetFieldString( hFeature, i_SrcSRSName, projectionRef ); } } } else if( eSrcSRSFormat == FORMAT_WKT ) { if( nMaxFieldSize == 0 || strlen(projectionRef) <= nMaxFieldSize ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, projectionRef ); } else { fprintf(stderr, "Cannot write WKT for file %s as it is too long!\n", fileNameToWrite); } } else if( eSrcSRSFormat == FORMAT_PROJ ) { char* pszProj4 = nullptr; if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 ); CPLFree(pszProj4); } } else if( eSrcSRSFormat == FORMAT_EPSG ) { if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr ) OGR_F_SetFieldString( hFeature, i_SrcSRSName, CPLSPrintf("%s:%s", pszAuthorityName, pszAuthorityCode) ); } } if( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); OGRGeometryH hPoly = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hRing = OGR_G_CreateGeometry(wkbLinearRing); for( int k = 0; k < 5; k++ ) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { printf( "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } CPLFree(current_path); if (nExistingFiles) { for( int i = 0; i < nExistingFiles; i++ ) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); if ( hTargetSRS ) OSRDestroySpatialReference( hTargetSRS ); GDALClose( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy(argv); exit( 0 ); }
bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } // skip features without geometry if ( !OGR_F_GetGeometryRef( fet ) && !P->mFetchFeaturesWithoutGeom ) { OGR_F_Destroy( fet ); close(); return false; } readFeature( fet, feature ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; QgsRectangle selectionRect; while (( fet = OGR_L_GetNextFeature( P->ogrLayer ) ) ) { // skip features without geometry if ( !P->mFetchFeaturesWithoutGeom && !OGR_F_GetGeometryRef( fet ) ) { OGR_F_Destroy( fet ); continue; } readFeature( fet, feature ); if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) { //precise test for intersection with search rectangle //first make QgsRectangle from OGRPolygon OGREnvelope env; memset( &env, 0, sizeof( env ) ); if ( mSelectionRectangle ) OGR_G_GetEnvelope( mSelectionRectangle, &env ); if ( env.MinX != 0 || env.MinY != 0 || env.MaxX != 0 || env.MaxY != 0 ) //if envelope is invalid, skip the precise intersection test { selectionRect.set( env.MinX, env.MinY, env.MaxX, env.MaxY ); if ( !feature.geometry() || !feature.geometry()->intersects( selectionRect ) ) { OGR_F_Destroy( fet ); continue; } } } // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while QgsDebugMsg( "Feature is null" ); close(); return false; }
int readoutlets(char *outletsds,char *lyrname, int uselayername,int outletslyr,OGRSpatialReferenceH hSRSRaster,int *noutlets, double*& x, double*& y,int*& id) { // initializing datasoruce,layer,feature, geomtery, spatial reference OGRSFDriverH driver; OGRDataSourceH hDS1; OGRLayerH hLayer1; OGRFeatureDefnH hFDefn1; OGRFieldDefnH hFieldDefn1; OGRFeatureH hFeature1; OGRGeometryH geometry, line; OGRSpatialReferenceH hRSOutlet; // register all ogr driver related to OGR OGRRegisterAll(); // open data source hDS1 = OGROpen(outletsds, FALSE, NULL ); if( hDS1 == NULL ) { printf( "Error Opening OGR Data Source .\n" ); return 1; } //get layer from layer name if(uselayername==1) { hLayer1 = OGR_DS_GetLayerByName(hDS1,lyrname);} //get layerinfo from layer number else { hLayer1 = OGR_DS_GetLayer(hDS1,outletslyr);} // get layerinfo from layername if(hLayer1 == NULL)getlayerfail(hDS1,outletsds,outletslyr); OGRwkbGeometryType gtype; gtype=OGR_L_GetGeomType(hLayer1); // Test that the type is a point if(gtype != wkbPoint)getlayerfail(hDS1,outletsds,outletslyr); const char* RasterProjectionName; const char* sprs; const char* sprso; const char* OutletProjectionName; int pj_raster,pj_outlet; // Spatial reference of outlet hRSOutlet = OGR_L_GetSpatialRef(hLayer1); if(hSRSRaster!=NULL){ pj_raster=OSRIsProjected(hSRSRaster); // find if projected or not if(pj_raster==0) {sprs="GEOGCS";} else { sprs="PROJCS"; } RasterProjectionName = OSRGetAttrValue(hSRSRaster,sprs,0); // get projection name } if(hRSOutlet!=NULL){ pj_outlet=OSRIsProjected(hRSOutlet); if(pj_outlet==0) {sprso="GEOGCS";} else { sprso="PROJCS"; } OutletProjectionName = OSRGetAttrValue(hRSOutlet,sprso,0); } //Write warnings where projections may not match if(hRSOutlet!=NULL && hSRSRaster!=NULL){ if (pj_raster==pj_outlet){ int rc= strcmp(RasterProjectionName,OutletProjectionName); // compare string if(rc!=0){ printf( "Warning: Projection of Outlet feature and Raster data may be different.\n" ); printf("Projection of Raster datasource %s.\n",RasterProjectionName); printf("Projection of Outlet feature %s.\n",OutletProjectionName); } } else { printf( "Warning: Spatial References of Outlet feature and Raster data are different.\n" ); printf("Projection of Raster datasource %s.\n",RasterProjectionName); printf("Projection of Outlet feature %s.\n",OutletProjectionName); } } else if(hSRSRaster==NULL && hRSOutlet!=NULL) { printf( "Warning: Spatial Reference of Raster is missing.\n" ); printf("Projection of Outlet feature %s.\n",OutletProjectionName); } else if(hSRSRaster!=NULL && hRSOutlet==NULL) { printf( "Warning: Spatial Reference of Outlet feature is missing.\n" ); printf("Projection of Raster datasource %s.\n",RasterProjectionName); } else { printf( "Warning: Spatial References of Outlet feature and Raster data are missing.\n" ); } long countPts=0; // count number of feature countPts=OGR_L_GetFeatureCount(hLayer1,0); // get schema i.e geometry, properties (e.g. ID) hFDefn1 = OGR_L_GetLayerDefn(hLayer1); x = new double[countPts]; y = new double[countPts]; int iField; int nxy=0; id = new int[countPts]; // loop through each feature and get lat,lon and id information OGR_L_ResetReading(hLayer1); while( (hFeature1 = OGR_L_GetNextFeature(hLayer1)) != NULL ) { //hFeature1=OGR_L_GetFeature(hLayer1,j); // get feature info geometry = OGR_F_GetGeometryRef(hFeature1); // get geometry x[nxy] = OGR_G_GetX(geometry, 0); y[nxy] = OGR_G_GetY(geometry, 0); int idfld =OGR_F_GetFieldIndex(hFeature1,"id"); if (idfld >= 0) { hFieldDefn1 = OGR_FD_GetFieldDefn( hFDefn1,idfld); // get field definiton based on index if( OGR_Fld_GetType(hFieldDefn1) == OFTInteger ) { id[nxy] =OGR_F_GetFieldAsInteger( hFeature1, idfld );} // get id value } else { id[nxy]=1;// if there is no id field } nxy++; // count number of outlets point OGR_F_Destroy( hFeature1 ); // destroy feature } *noutlets=nxy; OGR_DS_Destroy( hDS1); // destroy data source return 0; }
int OGRCDump(const char *pszFname) { OGRDataSourceH datasource; int i, numLayers; /* Register all OGR drivers */ OGRRegisterAll(); /* Open data source */ datasource = OGROpen(pszFname, 0 /* bUpdate */, NULL); if (datasource == NULL) { printf("Unable to open %s\n", pszFname); return -1; } /* Loop through layers and dump their contents */ numLayers = OGR_DS_GetLayerCount(datasource); for(i=0; i<numLayers; i++) { OGRLayerH layer; int j, numFields; OGRFeatureH feature; OGRFeatureDefnH layerDefn; layer = OGR_DS_GetLayer( datasource, i ); /* Dump info about this layer */ layerDefn = OGR_L_GetLayerDefn( layer ); numFields = OGR_FD_GetFieldCount( layerDefn ); printf("\n===================\n"); printf("Layer %d: '%s'\n\n", i, OGR_FD_GetName(layerDefn)); for(j=0; j<numFields; j++) { OGRFieldDefnH fieldDefn; fieldDefn = OGR_FD_GetFieldDefn( layerDefn, j ); printf(" Field %d: %s (%s)\n", j, OGR_Fld_GetNameRef(fieldDefn), OGR_GetFieldTypeName(OGR_Fld_GetType(fieldDefn)) ); } printf("\n"); /* And dump each feature individually */ while( (feature = OGR_L_GetNextFeature( layer )) != NULL ) { OGR_F_DumpReadable( feature, stdout ); OGR_F_Destroy( feature ); } /* No need to free layer handle, it belongs to the datasource */ } /* Close data source */ OGR_DS_Destroy( datasource ); return 0; }
void object::test<3>() { OGRErr err = OGRERR_NONE; OGRDataSourceH ds = NULL; ds = OGR_Dr_CreateDataSource(drv_, data_tmp_.c_str(), NULL); ensure("Can't open or create data source", NULL != ds); // Create memory Layer OGRLayerH lyr = NULL; lyr = OGR_DS_CreateLayer(ds, "tpoly", NULL, wkbPolygon, NULL); ensure("Can't create layer", NULL != lyr); // Create schema OGRFieldDefnH fld = NULL; fld = OGR_Fld_Create("AREA", OFTReal); err = OGR_L_CreateField(lyr, fld, true); OGR_Fld_Destroy(fld); ensure_equals("Can't create field", OGRERR_NONE, err); fld = OGR_Fld_Create("EAS_ID", OFTInteger); err = OGR_L_CreateField(lyr, fld, true); OGR_Fld_Destroy(fld); ensure_equals("Can't create field", OGRERR_NONE, err); fld = OGR_Fld_Create("PRFEDEA", OFTString); err = OGR_L_CreateField(lyr, fld, true); OGR_Fld_Destroy(fld); ensure_equals("Can't create field", OGRERR_NONE, err); // Check schema OGRFeatureDefnH featDefn = OGR_L_GetLayerDefn(lyr); ensure("Layer schema is NULL", NULL != featDefn); ensure_equals("Fields creation failed", 3, OGR_FD_GetFieldCount(featDefn)); // Copy ogr/poly.shp to temporary layer OGRFeatureH featDst = OGR_F_Create(featDefn); ensure("Can't create empty feature", NULL != featDst); std::string source(data_); source += SEP; source += "poly.shp"; OGRDataSourceH dsSrc = OGR_Dr_Open(drv_, source.c_str(), false); ensure("Can't open source layer", NULL != dsSrc); OGRLayerH lyrSrc = OGR_DS_GetLayer(dsSrc, 0); ensure("Can't get source layer", NULL != lyrSrc); OGRFeatureH featSrc = NULL; while (NULL != (featSrc = OGR_L_GetNextFeature(lyrSrc))) { err = OGR_F_SetFrom(featDst, featSrc, true); ensure_equals("Can't set festure from source", OGRERR_NONE, err); err = OGR_L_CreateFeature(lyr, featDst); ensure_equals("Can't write feature to layer", OGRERR_NONE, err); OGR_F_Destroy(featSrc); } // Release and close resources OGR_F_Destroy(featDst); OGR_DS_Destroy(dsSrc); OGR_DS_Destroy(ds); }
int main(int argc, char *argv[]) { struct GModule *module; struct _param { struct Option *dsn, *out, *layer, *spat, *where, *min_area; struct Option *snap, *type, *outloc, *cnames; } param; struct _flag { struct Flag *list, *tlist, *no_clean, *z, *notab, *region; struct Flag *over, *extend, *formats, *tolower, *no_import; } flag; int i, j, layer, arg_s_num, nogeom, ncnames; float xmin, ymin, xmax, ymax; int ncols = 0, type; double min_area, snap; char buf[2000], namebuf[2000], tempvect[GNAME_MAX]; char *separator; struct Key_Value *loc_proj_info, *loc_proj_units; struct Key_Value *proj_info, *proj_units; struct Cell_head cellhd, loc_wind, cur_wind; char error_msg[8192]; /* Vector */ struct Map_info Map, Tmp, *Out; int cat; /* Attributes */ struct field_info *Fi; dbDriver *driver; dbString sql, strval; int dim, with_z; /* OGR */ OGRDataSourceH Ogr_ds; OGRLayerH Ogr_layer; OGRFieldDefnH Ogr_field; char *Ogr_fieldname; OGRFieldType Ogr_ftype; OGRFeatureH Ogr_feature; OGRFeatureDefnH Ogr_featuredefn; OGRGeometryH Ogr_geometry, Ogr_oRing, poSpatialFilter; OGRSpatialReferenceH Ogr_projection; OGREnvelope oExt; OGRwkbGeometryType Ogr_geom_type; int OFTIntegerListlength; char *output; char **layer_names; /* names of layers to be imported */ int *layers; /* layer indexes */ int nlayers; /* number of layers to import */ char **available_layer_names; /* names of layers to be imported */ int navailable_layers; int layer_id; unsigned int n_features, feature_count; int overwrite; double area_size; int use_tmp_vect; xmin = ymin = xmax = ymax = 0.0; loc_proj_info = loc_proj_units = NULL; Ogr_ds = Ogr_oRing = poSpatialFilter = NULL; OFTIntegerListlength = 40; /* hack due to limitation in OGR */ area_size = 0.0; use_tmp_vect = FALSE; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("import")); module->description = _("Converts vector data into a GRASS vector map using OGR library."); param.dsn = G_define_option(); param.dsn->key = "dsn"; param.dsn->type = TYPE_STRING; param.dsn->required =YES; param.dsn->label = _("OGR datasource name"); param.dsn->description = _("Examples:\n" "\t\tESRI Shapefile: directory containing shapefiles\n" "\t\tMapInfo File: directory containing mapinfo files"); param.layer = G_define_option(); param.layer->key = "layer"; param.layer->type = TYPE_STRING; param.layer->required = NO; param.layer->multiple = YES; param.layer->label = _("OGR layer name. If not given, all available layers are imported"); param.layer->description = _("Examples:\n" "\t\tESRI Shapefile: shapefile name\n" "\t\tMapInfo File: mapinfo file name"); param.layer->guisection = _("Selection"); param.out = G_define_standard_option(G_OPT_V_OUTPUT); param.out->required = NO; param.out->guisection = _("Output"); param.spat = G_define_option(); param.spat->key = "spatial"; param.spat->type = TYPE_DOUBLE; param.spat->multiple = YES; param.spat->required = NO; param.spat->key_desc = "xmin,ymin,xmax,ymax"; param.spat->label = _("Import subregion only"); param.spat->guisection = _("Selection"); param.spat->description = _("Format: xmin,ymin,xmax,ymax - usually W,S,E,N"); param.where = G_define_standard_option(G_OPT_DB_WHERE); param.where->guisection = _("Selection"); param.min_area = G_define_option(); param.min_area->key = "min_area"; param.min_area->type = TYPE_DOUBLE; param.min_area->required = NO; param.min_area->answer = "0.0001"; param.min_area->label = _("Minimum size of area to be imported (square units)"); param.min_area->guisection = _("Selection"); param.min_area->description = _("Smaller areas and " "islands are ignored. Should be greater than snap^2"); param.type = G_define_standard_option(G_OPT_V_TYPE); param.type->options = "point,line,boundary,centroid"; param.type->answer = ""; param.type->description = _("Optionally change default input type"); param.type->descriptions = _("point;import area centroids as points;" "line;import area boundaries as lines;" "boundary;import lines as area boundaries;" "centroid;import points as centroids"); param.type->guisection = _("Selection"); param.snap = G_define_option(); param.snap->key = "snap"; param.snap->type = TYPE_DOUBLE; param.snap->required = NO; param.snap->answer = "-1"; param.snap->label = _("Snapping threshold for boundaries"); param.snap->description = _("'-1' for no snap"); param.outloc = G_define_option(); param.outloc->key = "location"; param.outloc->type = TYPE_STRING; param.outloc->required = NO; param.outloc->description = _("Name for new location to create"); param.outloc->key_desc = "name"; param.cnames = G_define_option(); param.cnames->key = "cnames"; param.cnames->type = TYPE_STRING; param.cnames->required = NO; param.cnames->multiple = YES; param.cnames->description = _("List of column names to be used instead of original names, " "first is used for category column"); param.cnames->guisection = _("Attributes"); flag.list = G_define_flag(); flag.list->key = 'l'; flag.list->description = _("List available OGR layers in data source and exit"); flag.list->suppress_required = YES; flag.list->guisection = _("Print"); flag.tlist = G_define_flag(); flag.tlist->key = 'a'; flag.tlist->description = _("List available OGR layers including feature types " "in data source and exit"); flag.tlist->suppress_required = YES; flag.tlist->guisection = _("Print"); flag.formats = G_define_flag(); flag.formats->key = 'f'; flag.formats->description = _("List supported formats and exit"); flag.formats->suppress_required = YES; flag.formats->guisection = _("Print"); /* if using -c, you lose topological information ! */ flag.no_clean = G_define_flag(); flag.no_clean->key = 'c'; flag.no_clean->description = _("Do not clean polygons (not recommended)"); flag.no_clean->guisection = _("Output"); flag.z = G_define_flag(); flag.z->key = 'z'; flag.z->description = _("Create 3D output"); flag.z->guisection = _("Output"); flag.notab = G_define_flag(); flag.notab->key = 't'; flag.notab->description = _("Do not create attribute table"); flag.notab->guisection = _("Attributes"); flag.over = G_define_flag(); flag.over->key = 'o'; flag.over->description = _("Override dataset projection (use location's projection)"); flag.region = G_define_flag(); flag.region->key = 'r'; flag.region->guisection = _("Selection"); flag.region->description = _("Limit import to the current region"); flag.extend = G_define_flag(); flag.extend->key = 'e'; flag.extend->description = _("Extend location extents based on new dataset"); flag.tolower = G_define_flag(); flag.tolower->key = 'w'; flag.tolower->description = _("Change column names to lowercase characters"); flag.tolower->guisection = _("Attributes"); flag.no_import = G_define_flag(); flag.no_import->key = 'i'; flag.no_import->description = _("Create the location specified by the \"location\" parameter and exit." " Do not import the vector data."); /* The parser checks if the map already exists in current mapset, this is * wrong if location options is used, so we switch out the check and do it * in the module after the parser */ overwrite = G_check_overwrite(argc, argv); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_begin_polygon_area_calculations(); /* Used in geom() */ OGRRegisterAll(); /* list supported formats */ if (flag.formats->answer) { int iDriver; G_message(_("Available OGR Drivers:")); for (iDriver = 0; iDriver < OGRGetDriverCount(); iDriver++) { OGRSFDriverH poDriver = OGRGetDriver(iDriver); const char *pszRWFlag; if (OGR_Dr_TestCapability(poDriver, ODrCCreateDataSource)) pszRWFlag = "rw"; else pszRWFlag = "ro"; fprintf(stdout, " %s (%s): %s\n", OGR_Dr_GetName(poDriver), pszRWFlag, OGR_Dr_GetName(poDriver)); } exit(EXIT_SUCCESS); } if (param.dsn->answer == NULL) { G_fatal_error(_("Required parameter <%s> not set"), param.dsn->key); } min_area = atof(param.min_area->answer); snap = atof(param.snap->answer); type = Vect_option_to_types(param.type); ncnames = 0; if (param.cnames->answers) { i = 0; while (param.cnames->answers[i++]) { ncnames++; } } /* Open OGR DSN */ Ogr_ds = NULL; if (strlen(param.dsn->answer) > 0) Ogr_ds = OGROpen(param.dsn->answer, FALSE, NULL); if (Ogr_ds == NULL) G_fatal_error(_("Unable to open data source <%s>"), param.dsn->answer); /* Make a list of available layers */ navailable_layers = OGR_DS_GetLayerCount(Ogr_ds); available_layer_names = (char **)G_malloc(navailable_layers * sizeof(char *)); if (flag.list->answer || flag.tlist->answer) G_message(_("Data source <%s> (format '%s') contains %d layers:"), param.dsn->answer, OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)), navailable_layers); for (i = 0; i < navailable_layers; i++) { Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i); Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer); Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn); available_layer_names[i] = G_store((char *)OGR_FD_GetName(Ogr_featuredefn)); if (flag.tlist->answer) fprintf(stdout, "%s (%s)\n", available_layer_names[i], OGRGeometryTypeToName(Ogr_geom_type)); else if (flag.list->answer) fprintf(stdout, "%s\n", available_layer_names[i]); } if (flag.list->answer || flag.tlist->answer) { fflush(stdout); exit(EXIT_SUCCESS); } /* Make a list of layers to be imported */ if (param.layer->answer) { /* From option */ nlayers = 0; while (param.layer->answers[nlayers]) nlayers++; layer_names = (char **)G_malloc(nlayers * sizeof(char *)); layers = (int *)G_malloc(nlayers * sizeof(int)); for (i = 0; i < nlayers; i++) { layer_names[i] = G_store(param.layer->answers[i]); /* Find it in the source */ layers[i] = -1; for (j = 0; j < navailable_layers; j++) { if (strcmp(available_layer_names[j], layer_names[i]) == 0) { layers[i] = j; break; } } if (layers[i] == -1) G_fatal_error(_("Layer <%s> not available"), layer_names[i]); } } else { /* use list of all layers */ nlayers = navailable_layers; layer_names = available_layer_names; layers = (int *)G_malloc(nlayers * sizeof(int)); for (i = 0; i < nlayers; i++) layers[i] = i; } if (param.out->answer) { output = G_store(param.out->answer); } else { if (nlayers < 1) G_fatal_error(_("No OGR layers available")); output = G_store(layer_names[0]); G_message(_("All available OGR layers will be imported into vector map <%s>"), output); } if (!param.outloc->answer) { /* Check if the map exists */ if (G_find_vector2(output, G_mapset()) && !overwrite) G_fatal_error(_("Vector map <%s> already exists"), output); } /* Get first imported layer to use for extents and projection check */ Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[0]); if (flag.region->answer) { if (param.spat->answer) G_fatal_error(_("Select either the current region flag or the spatial option, not both")); G_get_window(&cur_wind); xmin = cur_wind.west; xmax = cur_wind.east; ymin = cur_wind.south; ymax = cur_wind.north; } if (param.spat->answer) { /* See as reference: gdal/ogr/ogr_capi_test.c */ /* cut out a piece of the map */ /* order: xmin,ymin,xmax,ymax */ arg_s_num = 0; i = 0; while (param.spat->answers[i]) { if (i == 0) xmin = atof(param.spat->answers[i]); if (i == 1) ymin = atof(param.spat->answers[i]); if (i == 2) xmax = atof(param.spat->answers[i]); if (i == 3) ymax = atof(param.spat->answers[i]); arg_s_num++; i++; } if (arg_s_num != 4) G_fatal_error(_("4 parameters required for 'spatial' parameter")); } if (param.spat->answer || flag.region->answer) { G_debug(2, "cut out with boundaries: xmin:%f ymin:%f xmax:%f ymax:%f", xmin, ymin, xmax, ymax); /* in theory this could be an irregular polygon */ poSpatialFilter = OGR_G_CreateGeometry(wkbPolygon); Ogr_oRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0); OGR_G_AddPoint(Ogr_oRing, xmin, ymax, 0.0); OGR_G_AddPoint(Ogr_oRing, xmax, ymax, 0.0); OGR_G_AddPoint(Ogr_oRing, xmax, ymin, 0.0); OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0); OGR_G_AddGeometryDirectly(poSpatialFilter, Ogr_oRing); OGR_L_SetSpatialFilter(Ogr_layer, poSpatialFilter); } if (param.where->answer) { /* select by attribute */ OGR_L_SetAttributeFilter(Ogr_layer, param.where->answer); } /* fetch boundaries */ if ((OGR_L_GetExtent(Ogr_layer, &oExt, 1)) == OGRERR_NONE) { G_get_window(&cellhd); cellhd.north = oExt.MaxY; cellhd.south = oExt.MinY; cellhd.west = oExt.MinX; cellhd.east = oExt.MaxX; cellhd.rows = 20; /* TODO - calculate useful values */ cellhd.cols = 20; cellhd.ns_res = (cellhd.north - cellhd.south) / cellhd.rows; cellhd.ew_res = (cellhd.east - cellhd.west) / cellhd.cols; } else { cellhd.north = 1.; cellhd.south = 0.; cellhd.west = 0.; cellhd.east = 1.; cellhd.top = 1.; cellhd.bottom = 1.; cellhd.rows = 1; cellhd.rows3 = 1; cellhd.cols = 1; cellhd.cols3 = 1; cellhd.depths = 1; cellhd.ns_res = 1.; cellhd.ns_res3 = 1.; cellhd.ew_res = 1.; cellhd.ew_res3 = 1.; cellhd.tb_res = 1.; } /* suppress boundary splitting ? */ if (flag.no_clean->answer) { split_distance = -1.; } else { split_distance = 0.; area_size = sqrt((cellhd.east - cellhd.west) * (cellhd.north - cellhd.south)); } /* Fetch input map projection in GRASS form. */ proj_info = NULL; proj_units = NULL; Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer); /* should not be freed later */ /* Do we need to create a new location? */ if (param.outloc->answer != NULL) { /* Convert projection information non-interactively as we can't * assume the user has a terminal open */ if (GPJ_osr_to_grass(&cellhd, &proj_info, &proj_units, Ogr_projection, 0) < 0) { G_fatal_error(_("Unable to convert input map projection to GRASS " "format; cannot create new location.")); } else { G_make_location(param.outloc->answer, &cellhd, proj_info, proj_units, NULL); G_message(_("Location <%s> created"), param.outloc->answer); } /* If the i flag is set, clean up? and exit here */ if(flag.no_import->answer) { exit(EXIT_SUCCESS); } } else { int err = 0; /* Projection only required for checking so convert non-interactively */ if (GPJ_osr_to_grass(&cellhd, &proj_info, &proj_units, Ogr_projection, 0) < 0) G_warning(_("Unable to convert input map projection information to " "GRASS format for checking")); /* Does the projection of the current location match the dataset? */ /* G_get_window seems to be unreliable if the location has been changed */ G__get_window(&loc_wind, "", "DEFAULT_WIND", "PERMANENT"); /* fetch LOCATION PROJ info */ if (loc_wind.proj != PROJECTION_XY) { loc_proj_info = G_get_projinfo(); loc_proj_units = G_get_projunits(); } if (flag.over->answer) { cellhd.proj = loc_wind.proj; cellhd.zone = loc_wind.zone; G_message(_("Over-riding projection check")); } else if (loc_wind.proj != cellhd.proj || (err = G_compare_projections(loc_proj_info, loc_proj_units, proj_info, proj_units)) != TRUE) { int i_value; strcpy(error_msg, _("Projection of dataset does not" " appear to match current location.\n\n")); /* TODO: output this info sorted by key: */ if (loc_wind.proj != cellhd.proj || err != -2) { if (loc_proj_info != NULL) { strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n")); for (i_value = 0; i_value < loc_proj_info->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", loc_proj_info->key[i_value], loc_proj_info->value[i_value]); strcat(error_msg, "\n"); } if (proj_info != NULL) { strcat(error_msg, _("Import dataset PROJ_INFO is:\n")); for (i_value = 0; i_value < proj_info->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", proj_info->key[i_value], proj_info->value[i_value]); } else { strcat(error_msg, _("Import dataset PROJ_INFO is:\n")); if (cellhd.proj == PROJECTION_XY) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (unreferenced/unknown)\n", cellhd.proj); else if (cellhd.proj == PROJECTION_LL) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (lat/long)\n", cellhd.proj); else if (cellhd.proj == PROJECTION_UTM) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (UTM), zone = %d\n", cellhd.proj, cellhd.zone); else if (cellhd.proj == PROJECTION_SP) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (State Plane), zone = %d\n", cellhd.proj, cellhd.zone); else sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (unknown), zone = %d\n", cellhd.proj, cellhd.zone); } } else { if (loc_proj_units != NULL) { strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n"); for (i_value = 0; i_value < loc_proj_units->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", loc_proj_units->key[i_value], loc_proj_units->value[i_value]); strcat(error_msg, "\n"); } if (proj_units != NULL) { strcat(error_msg, "Import dataset PROJ_UNITS is:\n"); for (i_value = 0; i_value < proj_units->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", proj_units->key[i_value], proj_units->value[i_value]); } } sprintf(error_msg + strlen(error_msg), _("\nYou can use the -o flag to %s to override this projection check.\n"), G_program_name()); strcat(error_msg, _("Consider generating a new location with 'location' parameter" " from input data set.\n")); G_fatal_error(error_msg); } else { G_message(_("Projection of input dataset and current location " "appear to match")); } } db_init_string(&sql); db_init_string(&strval); /* open output vector */ /* strip any @mapset from vector output name */ G_find_vector(output, G_mapset()); Vect_open_new(&Map, output, flag.z->answer != 0); Out = ⤅ n_polygon_boundaries = 0; if (!flag.no_clean->answer) { /* check if we need a tmp vector */ /* estimate distance for boundary splitting --> */ for (layer = 0; layer < nlayers; layer++) { layer_id = layers[layer]; Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id); Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer); n_features = feature_count = 0; n_features = OGR_L_GetFeatureCount(Ogr_layer, 1); OGR_L_ResetReading(Ogr_layer); /* count polygons and isles */ G_message(_("Counting polygons for %d features (OGR layer <%s>)..."), n_features, layer_names[layer]); while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) { G_percent(feature_count++, n_features, 1); /* show something happens */ /* Geometry */ Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature); if (Ogr_geometry != NULL) { poly_count(Ogr_geometry, (type & GV_BOUNDARY)); } OGR_F_Destroy(Ogr_feature); } } G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries); if (n_polygon_boundaries > 50) { split_distance = area_size / log(n_polygon_boundaries); /* divisor is the handle: increase divisor to decrease split_distance */ split_distance = split_distance / 5.; G_debug(1, "root of area size: %f", area_size); G_verbose_message(_("Boundary splitting distance in map units: %G"), split_distance); } /* <-- estimate distance for boundary splitting */ use_tmp_vect = n_polygon_boundaries > 0; if (use_tmp_vect) { /* open temporary vector, do the work in the temporary vector * at the end copy alive lines to output vector * in case of polygons this reduces the coor file size by a factor of 2 to 5 * only needed when cleaning polygons */ sprintf(tempvect, "%s_tmp", output); G_verbose_message(_("Using temporary vector <%s>"), tempvect); Vect_open_new(&Tmp, tempvect, flag.z->answer != 0); Out = &Tmp; } } Vect_hist_command(&Map); /* Points and lines are written immediately with categories. Boundaries of polygons are * written to the vector then cleaned and centroids are calculated for all areas in cleaan vector. * Then second pass through finds all centroids in each polygon feature and adds its category * to the centroid. The result is that one centroids may have 0, 1 ore more categories * of one ore more (more input layers) fields. */ with_z = 0; for (layer = 0; layer < nlayers; layer++) { layer_id = layers[layer]; Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id); Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer); /* Add DB link */ if (!flag.notab->answer) { char *cat_col_name = GV_KEY_COLUMN; if (nlayers == 1) { /* one layer only */ Fi = Vect_default_field_info(&Map, layer + 1, NULL, GV_1TABLE); } else { Fi = Vect_default_field_info(&Map, layer + 1, NULL, GV_MTABLE); } if (ncnames > 0) { cat_col_name = param.cnames->answers[0]; } Vect_map_add_dblink(&Map, layer + 1, layer_names[layer], Fi->table, cat_col_name, Fi->database, Fi->driver); ncols = OGR_FD_GetFieldCount(Ogr_featuredefn); G_debug(2, "%d columns", ncols); /* Create table */ sprintf(buf, "create table %s (%s integer", Fi->table, cat_col_name); db_set_string(&sql, buf); for (i = 0; i < ncols; i++) { Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i); Ogr_ftype = OGR_Fld_GetType(Ogr_field); G_debug(3, "Ogr_ftype: %i", Ogr_ftype); /* look up below */ if (i < ncnames - 1) { Ogr_fieldname = G_store(param.cnames->answers[i + 1]); } else { /* Change column names to [A-Za-z][A-Za-z0-9_]* */ Ogr_fieldname = G_store(OGR_Fld_GetNameRef(Ogr_field)); G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname); G_str_to_sql(Ogr_fieldname); G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname); } /* avoid that we get the 'cat' column twice */ if (strcmp(Ogr_fieldname, GV_KEY_COLUMN) == 0) { sprintf(namebuf, "%s_", Ogr_fieldname); Ogr_fieldname = G_store(namebuf); } /* captial column names are a pain in SQL */ if (flag.tolower->answer) G_str_to_lower(Ogr_fieldname); if (strcmp(OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname) != 0) { G_warning(_("Column name changed: '%s' -> '%s'"), OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname); } /** Simple 32bit integer OFTInteger = 0 **/ /** List of 32bit integers OFTIntegerList = 1 **/ /** Double Precision floating point OFTReal = 2 **/ /** List of doubles OFTRealList = 3 **/ /** String of ASCII chars OFTString = 4 **/ /** Array of strings OFTStringList = 5 **/ /** Double byte string (unsupported) OFTWideString = 6 **/ /** List of wide strings (unsupported) OFTWideStringList = 7 **/ /** Raw Binary data (unsupported) OFTBinary = 8 **/ /** OFTDate = 9 **/ /** OFTTime = 10 **/ /** OFTDateTime = 11 **/ if (Ogr_ftype == OFTInteger) { sprintf(buf, ", %s integer", Ogr_fieldname); } else if (Ogr_ftype == OFTIntegerList) { /* hack: treat as string */ sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname, OFTIntegerListlength); G_warning(_("Writing column <%s> with fixed length %d chars (may be truncated)"), Ogr_fieldname, OFTIntegerListlength); } else if (Ogr_ftype == OFTReal) { sprintf(buf, ", %s double precision", Ogr_fieldname); #if GDAL_VERSION_NUM >= 1320 } else if (Ogr_ftype == OFTDate) { sprintf(buf, ", %s date", Ogr_fieldname); } else if (Ogr_ftype == OFTTime) { sprintf(buf, ", %s time", Ogr_fieldname); } else if (Ogr_ftype == OFTDateTime) { sprintf(buf, ", %s datetime", Ogr_fieldname); #endif } else if (Ogr_ftype == OFTString) { int fwidth; fwidth = OGR_Fld_GetWidth(Ogr_field); /* TODO: read all records first and find the longest string length */ if (fwidth == 0) { G_warning(_("Width for column %s set to 255 (was not specified by OGR), " "some strings may be truncated!"), Ogr_fieldname); fwidth = 255; } sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname, fwidth); } else if (Ogr_ftype == OFTStringList) { /* hack: treat as string */ sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname, OFTIntegerListlength); G_warning(_("Writing column %s with fixed length %d chars (may be truncated)"), Ogr_fieldname, OFTIntegerListlength); } else { G_warning(_("Column type not supported (%s)"), Ogr_fieldname); buf[0] = 0; } db_append_string(&sql, buf); G_free(Ogr_fieldname); } db_append_string(&sql, ")"); G_debug(3, db_get_string(&sql)); driver = db_start_driver_open_database(Fi->driver, Vect_subst_var(Fi->database, &Map)); if (driver == NULL) { G_fatal_error(_("Unable open database <%s> by driver <%s>"), Vect_subst_var(Fi->database, &Map), Fi->driver); } if (db_execute_immediate(driver, &sql) != DB_OK) { db_close_database(driver); db_shutdown_driver(driver); G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql)); } if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK) G_warning(_("Unable to create index for table <%s>, key <%s>"), Fi->table, cat_col_name); if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) G_fatal_error(_("Unable to grant privileges on table <%s>"), Fi->table); db_begin_transaction(driver); } /* Import feature */ cat = 1; nogeom = 0; OGR_L_ResetReading(Ogr_layer); n_features = feature_count = 0; n_features = OGR_L_GetFeatureCount(Ogr_layer, 1); G_important_message(_("Importing %d features (OGR layer <%s>)..."), n_features, layer_names[layer]); while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) { G_percent(feature_count++, n_features, 1); /* show something happens */ /* Geometry */ Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature); if (Ogr_geometry == NULL) { nogeom++; } else { dim = OGR_G_GetCoordinateDimension(Ogr_geometry); if (dim > 2) with_z = 1; geom(Ogr_geometry, Out, layer + 1, cat, min_area, type, flag.no_clean->answer); } /* Attributes */ if (!flag.notab->answer) { sprintf(buf, "insert into %s values ( %d", Fi->table, cat); db_set_string(&sql, buf); for (i = 0; i < ncols; i++) { Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i); Ogr_ftype = OGR_Fld_GetType(Ogr_field); if (OGR_F_IsFieldSet(Ogr_feature, i)) { if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) { sprintf(buf, ", %s", OGR_F_GetFieldAsString(Ogr_feature, i)); #if GDAL_VERSION_NUM >= 1320 /* should we use OGR_F_GetFieldAsDateTime() here ? */ } else if (Ogr_ftype == OFTDate || Ogr_ftype == OFTTime || Ogr_ftype == OFTDateTime) { char *newbuf; db_set_string(&strval, (char *) OGR_F_GetFieldAsString(Ogr_feature, i)); db_double_quote_string(&strval); sprintf(buf, ", '%s'", db_get_string(&strval)); newbuf = G_str_replace(buf, "/", "-"); /* fix 2001/10/21 to 2001-10-21 */ sprintf(buf, "%s", newbuf); #endif } else if (Ogr_ftype == OFTString || Ogr_ftype == OFTIntegerList) { db_set_string(&strval, (char *) OGR_F_GetFieldAsString(Ogr_feature, i)); db_double_quote_string(&strval); sprintf(buf, ", '%s'", db_get_string(&strval)); } } else { /* G_warning (_("Column value not set" )); */ if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) { sprintf(buf, ", NULL"); #if GDAL_VERSION_NUM >= 1320 } else if (Ogr_ftype == OFTString || Ogr_ftype == OFTIntegerList || Ogr_ftype == OFTDate) { #else } else if (Ogr_ftype == OFTString || Ogr_ftype == OFTIntegerList) { #endif sprintf(buf, ", ''"); } } db_append_string(&sql, buf); } db_append_string(&sql, " )"); G_debug(3, db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) { db_close_database(driver); db_shutdown_driver(driver); G_fatal_error(_("Cannot insert new row: %s"), db_get_string(&sql)); } } OGR_F_Destroy(Ogr_feature); cat++; } G_percent(1, 1, 1); /* finish it */ if (!flag.notab->answer) { db_commit_transaction(driver); db_close_database_shutdown_driver(driver); } if (nogeom > 0) G_warning(_("%d %s without geometry"), nogeom, nogeom == 1 ? "feature" : "features"); } separator = "-----------------------------------------------------"; G_message("%s", separator); if (use_tmp_vect) { /* TODO: is it necessary to build here? probably not, consumes time */ /* GV_BUILD_BASE is sufficient to toggle boundary cleaning */ Vect_build_partial(&Tmp, GV_BUILD_BASE); } if (use_tmp_vect && !flag.no_clean->answer && Vect_get_num_primitives(Out, GV_BOUNDARY) > 0) { int ret, centr, ncentr, otype, n_overlaps, n_nocat; CENTR *Centr; struct spatial_index si; double x, y, total_area, overlap_area, nocat_area; struct bound_box box; struct line_pnts *Points; int nmodif; Points = Vect_new_line_struct(); G_message("%s", separator); G_warning(_("Cleaning polygons, result is not guaranteed!")); if (snap >= 0) { G_message("%s", separator); G_message(_("Snapping boundaries (threshold = %.3e)..."), snap); Vect_snap_lines(&Tmp, GV_BOUNDARY, snap, NULL); } /* It is not to clean to snap centroids, but I have seen data with 2 duplicate polygons * (as far as decimal places were printed) and centroids were not identical */ /* Disabled, because overlapping polygons result in many duplicate centroids anyway */ /* fprintf ( stderr, separator ); fprintf ( stderr, "Snap centroids (threshold 0.000001):\n" ); Vect_snap_lines ( &Map, GV_CENTROID, 0.000001, NULL, stderr ); */ G_message("%s", separator); G_message(_("Breaking polygons...")); Vect_break_polygons(&Tmp, GV_BOUNDARY, NULL); /* It is important to remove also duplicate centroids in case of duplicate input polygons */ G_message("%s", separator); G_message(_("Removing duplicates...")); Vect_remove_duplicates(&Tmp, GV_BOUNDARY | GV_CENTROID, NULL); /* in non-pathological cases, the bulk of the cleaning is now done */ /* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections * are created. We must call Vect_break_lines(), Vect_remove_duplicates() * and Vect_clean_small_angles_at_nodes() until no more small angles are found */ do { G_message("%s", separator); G_message(_("Breaking boundaries...")); Vect_break_lines(&Tmp, GV_BOUNDARY, NULL); G_message("%s", separator); G_message(_("Removing duplicates...")); Vect_remove_duplicates(&Tmp, GV_BOUNDARY, NULL); G_message("%s", separator); G_message(_("Cleaning boundaries at nodes...")); nmodif = Vect_clean_small_angles_at_nodes(&Tmp, GV_BOUNDARY, NULL); } while (nmodif > 0); /* merge boundaries */ G_message("%s", separator); G_message(_("Merging boundaries...")); Vect_merge_lines(&Tmp, GV_BOUNDARY, NULL, NULL); G_message("%s", separator); if (type & GV_BOUNDARY) { /* that means lines were converted to boundaries */ G_message(_("Changing boundary dangles to lines...")); Vect_chtype_dangles(&Tmp, -1.0, NULL); } else { G_message(_("Removing dangles...")); Vect_remove_dangles(&Tmp, GV_BOUNDARY, -1.0, NULL); } G_message("%s", separator); if (type & GV_BOUNDARY) { G_message(_("Changing boundary bridges to lines...")); Vect_chtype_bridges(&Tmp, NULL); } else { G_message(_("Removing bridges...")); Vect_remove_bridges(&Tmp, NULL); } /* Boundaries are hopefully clean, build areas */ G_message("%s", separator); Vect_build_partial(&Tmp, GV_BUILD_ATTACH_ISLES); /* Calculate new centroids for all areas, centroids have the same id as area */ ncentr = Vect_get_num_areas(&Tmp); G_debug(3, "%d centroids/areas", ncentr); Centr = (CENTR *) G_calloc(ncentr + 1, sizeof(CENTR)); Vect_spatial_index_init(&si, 0); for (centr = 1; centr <= ncentr; centr++) { Centr[centr].valid = 0; Centr[centr].cats = Vect_new_cats_struct(); ret = Vect_get_point_in_area(&Tmp, centr, &x, &y); if (ret < 0) { G_warning(_("Unable to calculate area centroid")); continue; } Centr[centr].x = x; Centr[centr].y = y; Centr[centr].valid = 1; box.N = box.S = y; box.E = box.W = x; box.T = box.B = 0; Vect_spatial_index_add_item(&si, centr, &box); } /* Go through all layers and find centroids for each polygon */ for (layer = 0; layer < nlayers; layer++) { G_message("%s", separator); G_message(_("Finding centroids for OGR layer <%s>..."), layer_names[layer]); layer_id = layers[layer]; Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id); n_features = OGR_L_GetFeatureCount(Ogr_layer, 1); OGR_L_ResetReading(Ogr_layer); cat = 0; /* field = layer + 1 */ G_percent(cat, n_features, 2); while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) { cat++; G_percent(cat, n_features, 2); /* Geometry */ Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature); if (Ogr_geometry != NULL) { centroid(Ogr_geometry, Centr, &si, layer + 1, cat, min_area, type); } OGR_F_Destroy(Ogr_feature); } } /* Write centroids */ G_message("%s", separator); G_message(_("Writing centroids...")); n_overlaps = n_nocat = 0; total_area = overlap_area = nocat_area = 0.0; for (centr = 1; centr <= ncentr; centr++) { double area; G_percent(centr, ncentr, 2); area = Vect_get_area_area(&Tmp, centr); total_area += area; if (!(Centr[centr].valid)) { continue; } if (Centr[centr].cats->n_cats == 0) { nocat_area += area; n_nocat++; continue; } if (Centr[centr].cats->n_cats > 1) { Vect_cat_set(Centr[centr].cats, nlayers + 1, Centr[centr].cats->n_cats); overlap_area += area; n_overlaps++; } Vect_reset_line(Points); Vect_append_point(Points, Centr[centr].x, Centr[centr].y, 0.0); if (type & GV_POINT) otype = GV_POINT; else otype = GV_CENTROID; Vect_write_line(&Tmp, otype, Points, Centr[centr].cats); } if (Centr) G_free(Centr); Vect_spatial_index_destroy(&si); if (n_overlaps > 0) { G_warning(_("%d areas represent more (overlapping) features, because polygons overlap " "in input layer(s). Such areas are linked to more than 1 row in attribute table. " "The number of features for those areas is stored as category in layer %d"), n_overlaps, nlayers + 1); } G_message("%s", separator); Vect_hist_write(&Map, separator); Vect_hist_write(&Map, "\n"); sprintf(buf, _("%d input polygons\n"), n_polygons); G_message(_("%d input polygons"), n_polygons); Vect_hist_write(&Map, buf); sprintf(buf, _("Total area: %G (%d areas)\n"), total_area, ncentr); G_message(_("Total area: %G (%d areas)"), total_area, ncentr); Vect_hist_write(&Map, buf); sprintf(buf, _("Overlapping area: %G (%d areas)\n"), overlap_area, n_overlaps); G_message(_("Overlapping area: %G (%d areas)"), overlap_area, n_overlaps); Vect_hist_write(&Map, buf); sprintf(buf, _("Area without category: %G (%d areas)\n"), nocat_area, n_nocat); G_message(_("Area without category: %G (%d areas)"), nocat_area, n_nocat); Vect_hist_write(&Map, buf); G_message("%s", separator); } /* needed? * OGR_DS_Destroy( Ogr_ds ); */ if (use_tmp_vect) { /* Copy temporary vector to output vector */ Vect_copy_map_lines(&Tmp, &Map); /* release memory occupied by topo, we may need that memory for main output */ Vect_set_release_support(&Tmp); Vect_close(&Tmp); Vect_delete(tempvect); } Vect_build(&Map); Vect_close(&Map); /* -------------------------------------------------------------------- */ /* Extend current window based on dataset. */ /* -------------------------------------------------------------------- */ if (flag.extend->answer) { G_get_default_window(&loc_wind); loc_wind.north = MAX(loc_wind.north, cellhd.north); loc_wind.south = MIN(loc_wind.south, cellhd.south); loc_wind.west = MIN(loc_wind.west, cellhd.west); loc_wind.east = MAX(loc_wind.east, cellhd.east); loc_wind.rows = (int)ceil((loc_wind.north - loc_wind.south) / loc_wind.ns_res); loc_wind.south = loc_wind.north - loc_wind.rows * loc_wind.ns_res; loc_wind.cols = (int)ceil((loc_wind.east - loc_wind.west) / loc_wind.ew_res); loc_wind.east = loc_wind.west + loc_wind.cols * loc_wind.ew_res; G__put_window(&loc_wind, "../PERMANENT", "DEFAULT_WIND"); } if (with_z && !flag.z->answer) G_warning(_("Input data contains 3D features. Created vector is 2D only, " "use -z flag to import 3D vector.")); exit(EXIT_SUCCESS); }