bool SpatialReference::equals(const SpatialReference& input) const { OGRSpatialReferenceH current = OSRNewSpatialReference(getWKT(eCompoundOK, false).c_str()); OGRSpatialReferenceH other = OSRNewSpatialReference(input.getWKT(eCompoundOK, false).c_str()); int output = OSRIsSame(current, other); OSRDestroySpatialReference(current); OSRDestroySpatialReference(other); return (output == 1); }
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; }
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 ); }
int main(int argc, char *argv[]) { const char *index_filename = NULL; const char *tile_index = "location"; int i_arg, ti_field; OGRDataSourceH hTileIndexDS; OGRLayerH hLayer = NULL; OGRFeatureDefnH hFDefn; int write_absolute_path = FALSE; char* current_path = NULL; int i; int nExistingFiles; int skip_different_projection = FALSE; char** existingFilesTab = NULL; int alreadyExistingProjectionRefValid = FALSE; char* alreadyExistingProjectionRef = NULL; char* index_filename_mod; int bExists; VSIStatBuf sStatBuf; const char *pszTargetSRS = ""; int bSetTargetSRS = FALSE; OGRSpatialReferenceH hTargetSRS = NULL; /* 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. */ /* -------------------------------------------------------------------- */ for( i_arg = 1; i_arg < argc; i_arg++ ) { if( EQUAL(argv[i_arg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( strcmp(argv[i_arg],"-tileindex") == 0 ) { tile_index = argv[++i_arg]; } else if( strcmp(argv[i_arg],"-t_srs") == 0 ) { pszTargetSRS = argv[++i_arg]; bSetTargetSRS = TRUE; } else if ( strcmp(argv[i_arg],"-write_absolute_path") == 0 ) { write_absolute_path = TRUE; } else if ( strcmp(argv[i_arg],"-skip_different_projection") == 0 ) { skip_different_projection = TRUE; } else if( argv[i_arg][0] == '-' ) Usage(); else if( index_filename == NULL ) { index_filename = argv[i_arg]; i_arg++; break; } } if( index_filename == NULL || i_arg == argc ) Usage(); /* -------------------------------------------------------------------- */ /* Create and validate target SRS if given. */ /* -------------------------------------------------------------------- */ if( bSetTargetSRS ) { if ( skip_different_projection ) { fprintf( stderr, "Warning : -skip_different_projection does not apply " "when -t_srs is requested.\n" ); } hTargetSRS = OSRNewSpatialReference(""); if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None ) { OSRDestroySpatialReference( hTargetSRS ); fprintf( stderr, "Invalid target SRS `%s'.\n", pszTargetSRS ); exit(1); } } /* -------------------------------------------------------------------- */ /* Open or create the target shapefile and DBF file. */ /* -------------------------------------------------------------------- */ index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); if (!bExists) { CPLFree(index_filename_mod); index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); } CPLFree(index_filename_mod); if (bExists) { hTileIndexDS = OGROpen( index_filename, TRUE, NULL ); if (hTileIndexDS != NULL) { hLayer = OGR_DS_GetLayer(hTileIndexDS, 0); } } else { OGRSFDriverH hDriver; const char* pszDriverName = "ESRI Shapefile"; printf( "Creating new index file...\n" ); hDriver = OGRGetDriverByName( pszDriverName ); if( hDriver == NULL ) { printf( "%s driver not available.\n", pszDriverName ); exit( 1 ); } hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL ); if (hTileIndexDS) { char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); /* get spatial reference for output file from target SRS (if set) */ /* or from first input file */ OGRSpatialReferenceH hSpatialRef = NULL; if( bSetTargetSRS ) { hSpatialRef = OSRClone( hTargetSRS ); } else { GDALDatasetH hDS = GDALOpen( argv[i_arg], GA_ReadOnly ); if (hDS) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != NULL && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } } hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL ); CPLFree(pszLayerName); if (hSpatialRef) OSRRelease(hSpatialRef); if (hLayer) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); OGR_Fld_SetWidth( hFieldDefn, 255); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == NULL || hLayer == NULL ) { fprintf( stderr, "Unable to open/create shapefile `%s'.\n", index_filename ); exit(2); } hFDefn = OGR_L_GetLayerDefn(hLayer); for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ ) { OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field ); if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 ) break; } if( ti_field == OGR_FD_GetFieldCount(hFDefn) ) { fprintf( stderr, "Unable to find field `%s' in DBF file `%s'.\n", tile_index, index_filename ); exit(2); } /* Load in memory existing file names in SHP */ nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE); if (nExistingFiles) { OGRFeatureH hFeature; existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*)); for(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 == NULL) { 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( ; i_arg < argc; i_arg++ ) { GDALDatasetH hDS; double adfGeoTransform[6]; double adfX[5], adfY[5]; int nXSize, nYSize; char* fileNameToWrite; const char* projectionRef; VSIStatBuf sStatBuf; int k; OGRFeatureH hFeature; OGRGeometryH hPoly, hRing; /* Make sure it is a file before building absolute path name */ if (write_absolute_path && CPLIsFilenameRelative( argv[i_arg] ) && VSIStat( argv[i_arg], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[i_arg])); } else { fileNameToWrite = CPLStrdup(argv[i_arg]); } /* Checks that file is not already in tileindex */ for(i=0;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; } hDS = GDALOpen( argv[i_arg], GA_ReadOnly ); if( hDS == NULL ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv[i_arg] ); CPLFree(fileNameToWrite); continue; } GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && ABS(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv[i_arg] ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } 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[i_arg], (skip_different_projection) ? "Skipping this file." : ""); if (skip_different_projection) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } } nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); 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]; /* if set target srs, do the forward transformation of all points */ if( bSetTargetSRS ) { OGRSpatialReferenceH hSourceSRS = NULL; OGRCoordinateTransformationH hCT = NULL; hSourceSRS = OSRNewSpatialReference( projectionRef ); if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) ) { hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS ); if( hCT == NULL || !OCTTransform( hCT, 5, adfX, adfY, NULL ) ) { 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 ); } if ( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); } hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); hPoly = OGR_G_CreateGeometry(wkbPolygon); hRing = OGR_G_CreateGeometry(wkbLinearRing); for(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(i=0;i<nExistingFiles;i++) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); if ( hTargetSRS ) OSRDestroySpatialReference( hTargetSRS ); OGR_DS_Destroy( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy(argv); exit( 0 ); }