void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer) { if( !pabCheckIfAutoWrap[iLayer] ) { pabCheckIfAutoWrap[iLayer] = TRUE; for(int i=0; i<GetLayerDefn()->GetGeomFieldCount();i++) { OGRSpatialReference* poSRS = GetLayerDefn()->GetGeomFieldDefn(i)->GetSpatialRef(); if( poSRS != NULL ) poSRS->Reference(); OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn(); int iSrcGeomField = poSrcFeatureDefn->GetGeomFieldIndex( GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef()); if( iSrcGeomField >= 0 ) { OGRSpatialReference* poSRS2 = poSrcFeatureDefn->GetGeomFieldDefn(iSrcGeomField)->GetSpatialRef(); if( (poSRS == NULL && poSRS2 != NULL) || (poSRS != NULL && poSRS2 == NULL) ) { CPLError(CE_Warning, CPLE_AppDefined, "SRS of geometry field '%s' layer %s not consistent with UnionLayer SRS", GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef(), papoSrcLayers[iLayer]->GetName()); } else if (poSRS != NULL && poSRS2 != NULL && poSRS != poSRS2 && !poSRS->IsSame(poSRS2)) { CPLDebug("VRT", "SRS of geometry field '%s' layer %s not consistent with UnionLayer SRS. " "Trying auto warping", GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef(), papoSrcLayers[iLayer]->GetName()); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation( poSRS2, poSRS ); OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ? OGRCreateCoordinateTransformation( poSRS, poSRS2 ) : NULL; if( poReversedCT != NULL ) papoSrcLayers[iLayer] = new OGRWarpedLayer( papoSrcLayers[iLayer], iSrcGeomField, TRUE, poCT, poReversedCT); else { CPLError(CE_Warning, CPLE_AppDefined, "AutoWarpLayerIfNecessary failed to create " "poCT or poReversedCT."); if ( poCT != NULL ) delete poCT; } } } if( poSRS != NULL ) poSRS->Release(); } } }
bool CSpatialReference::IsSame(const Geodatabase::CSpatialReference *pOther) const { if(m_Handle ==NULL || pOther->m_Handle==NULL) { return false; } OGRSpatialReference* psr = (OGRSpatialReference*)m_Handle; return psr->IsSame((OGRSpatialReference*)pOther->m_Handle); }
int OGRGeomFieldDefn::IsSame( OGRGeomFieldDefn * poOtherFieldDefn ) { if( !(strcmp(GetNameRef(), poOtherFieldDefn->GetNameRef()) == 0 && GetType() == poOtherFieldDefn->GetType() && IsNullable() == poOtherFieldDefn->IsNullable()) ) return FALSE; OGRSpatialReference* poMySRS = GetSpatialRef(); OGRSpatialReference* poOtherSRS = poOtherFieldDefn->GetSpatialRef(); return ((poMySRS == poOtherSRS) || (poMySRS != NULL && poOtherSRS != NULL && poMySRS->IsSame(poOtherSRS))); }
bool hasSourceSRS(const std::string& sourceURN) { if (m_transformation == nullptr) { return false; } OGRSpatialReference refSys; OGRErr err = refSys.SetFromUserInput(sourceURN.c_str()); if (err != OGRERR_NONE) { return false; } return refSys.IsSame(m_transformation->GetSourceCS()); }
void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer) { if( !pabCheckIfAutoWrap[iLayer] ) { pabCheckIfAutoWrap[iLayer] = TRUE; OGRSpatialReference* poSRS = GetSpatialRef(); if( poSRS != NULL ) poSRS->Reference(); OGRSpatialReference* poSRS2 = papoSrcLayers[iLayer]->GetSpatialRef(); if( (poSRS == NULL && poSRS2 != NULL) || (poSRS != NULL && poSRS2 == NULL) ) { CPLError(CE_Warning, CPLE_AppDefined, "SRS of layer %s not consistant with layer SRS", papoSrcLayers[iLayer]->GetName()); } else if (poSRS != NULL && poSRS2 != NULL && poSRS != poSRS2 && !poSRS->IsSame(poSRS2)) { CPLDebug("VRT", "SRS of layer %s not consistant with layer SRS. " "Trying auto warping", papoSrcLayers[iLayer]->GetName()); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation( poSRS2, poSRS ); OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ? OGRCreateCoordinateTransformation( poSRS, poSRS2 ) : NULL; if( poCT != NULL && poReversedCT != NULL ) papoSrcLayers[iLayer] = new OGRWarpedLayer( papoSrcLayers[iLayer], TRUE, poCT, poReversedCT); } if( poSRS != NULL ) poSRS->Release(); } }
int main( int nArgc, char ** papszArgv ) { int nFirstSourceDataset = -1, bLayersWildcarded = TRUE, iArg; const char *pszFormat = "ESRI Shapefile"; const char *pszTileIndexField = "LOCATION"; const char *pszOutputName = NULL; int write_absolute_path = FALSE; int skip_different_projection = FALSE; char* current_path = NULL; int accept_different_schemas = FALSE; int bFirstWarningForNonMatchingAttributes = TRUE; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(papszArgv[0])) exit(1); /* -------------------------------------------------------------------- */ /* Register format(s). */ /* -------------------------------------------------------------------- */ OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 ) { pszFormat = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-write_absolute_path")) { write_absolute_path = TRUE; } else if( EQUAL(papszArgv[iArg],"-skip_different_projection")) { skip_different_projection = TRUE; } else if( EQUAL(papszArgv[iArg],"-accept_different_schemas")) { accept_different_schemas = TRUE; } else if( EQUAL(papszArgv[iArg],"-tileindex") && iArg < nArgc-1 ) { pszTileIndexField = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-lnum") || EQUAL(papszArgv[iArg],"-lname") ) { iArg++; bLayersWildcarded = FALSE; } else if( papszArgv[iArg][0] == '-' ) Usage(); else if( pszOutputName == NULL ) pszOutputName = papszArgv[iArg]; else if( nFirstSourceDataset == -1 ) nFirstSourceDataset = iArg; } if( pszOutputName == NULL || nFirstSourceDataset == -1 ) Usage(); /* -------------------------------------------------------------------- */ /* Try to open as an existing dataset for update access. */ /* -------------------------------------------------------------------- */ OGRDataSource *poDstDS; OGRLayer *poDstLayer = NULL; poDstDS = OGRSFDriverRegistrar::Open( pszOutputName, TRUE ); /* -------------------------------------------------------------------- */ /* If that failed, find the driver so we can create the tile index.*/ /* -------------------------------------------------------------------- */ if( poDstDS == NULL ) { OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); OGRSFDriver *poDriver = NULL; int iDriver; for( iDriver = 0; iDriver < poR->GetDriverCount() && poDriver == NULL; iDriver++ ) { if( EQUAL(poR->GetDriver(iDriver)->GetName(),pszFormat) ) { poDriver = poR->GetDriver(iDriver); } } if( poDriver == NULL ) { fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat ); fprintf( stderr, "The following drivers are available:\n" ); for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ ) { fprintf( stderr, " -> `%s'\n", poR->GetDriver(iDriver)->GetName() ); } exit( 1 ); } if( !poDriver->TestCapability( ODrCCreateDataSource ) ) { fprintf( stderr, "%s driver does not support data source creation.\n", pszFormat ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Now create it. */ /* -------------------------------------------------------------------- */ poDstDS = poDriver->CreateDataSource( pszOutputName, NULL ); if( poDstDS == NULL ) { fprintf( stderr, "%s driver failed to create %s\n", pszFormat, pszOutputName ); exit( 1 ); } if( poDstDS->GetLayerCount() == 0 ) { OGRFieldDefn oLocation( pszTileIndexField, OFTString ); oLocation.SetWidth( 200 ); if( nFirstSourceDataset < nArgc && papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; } OGRSpatialReference* poSrcSpatialRef = NULL; /* Fetches the SRS of the first layer and use it when creating the tileindex layer */ if (nFirstSourceDataset < nArgc) { OGRDataSource* poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], FALSE ); if (poDS) { int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; if ( poLayer->GetSpatialRef() ) poSrcSpatialRef = poLayer->GetSpatialRef()->Clone(); break; } } OGRDataSource::DestroyDataSource( poDS ); } poDstLayer = poDstDS->CreateLayer( "tileindex", poSrcSpatialRef ); poDstLayer->CreateField( &oLocation, OFTString ); OGRSpatialReference::DestroySpatialReference( poSrcSpatialRef ); } } /* -------------------------------------------------------------------- */ /* Identify target layer and field. */ /* -------------------------------------------------------------------- */ int iTileIndexField; poDstLayer = poDstDS->GetLayer(0); if( poDstLayer == NULL ) { fprintf( stderr, "Can't find any layer in output tileindex!\n" ); exit( 1 ); } iTileIndexField = poDstLayer->GetLayerDefn()->GetFieldIndex( pszTileIndexField ); if( iTileIndexField == -1 ) { fprintf( stderr, "Can't find %s field in tile index dataset.\n", pszTileIndexField ); exit( 1 ); } OGRFeatureDefn* poFeatureDefn = NULL; /* Load in memory existing file names in SHP */ int nExistingLayers = 0; char** existingLayersTab = NULL; OGRSpatialReference* alreadyExistingSpatialRef = NULL; int alreadyExistingSpatialRefValid = FALSE; nExistingLayers = poDstLayer->GetFeatureCount(); if (nExistingLayers) { int i; existingLayersTab = (char**)CPLMalloc(nExistingLayers * sizeof(char*)); for(i=0;i<nExistingLayers;i++) { OGRFeature* feature = poDstLayer->GetNextFeature(); existingLayersTab[i] = CPLStrdup(feature->GetFieldAsString( iTileIndexField)); if (i == 0) { OGRDataSource *poDS; char* filename = CPLStrdup(existingLayersTab[i]); int j; for(j=strlen(filename)-1;j>=0;j--) { if (filename[j] == ',') break; } if (j >= 0) { int iLayer = atoi(filename + j + 1); filename[j] = 0; poDS = OGRSFDriverRegistrar::Open(filename, FALSE ); if (poDS) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if (poLayer) { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (poLayer->GetSpatialRef()) ? poLayer->GetSpatialRef()->Clone() : NULL; if (poFeatureDefn == NULL) poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } OGRDataSource::DestroyDataSource( poDS ); } } } } } 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; } } /* ==================================================================== */ /* Process each input datasource in turn. */ /* ==================================================================== */ for(; nFirstSourceDataset < nArgc; nFirstSourceDataset++ ) { int i; OGRDataSource *poDS; if( papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; continue; } char* fileNameToWrite; VSIStatBuf sStatBuf; if (write_absolute_path && CPLIsFilenameRelative( papszArgv[nFirstSourceDataset] ) && VSIStat( papszArgv[nFirstSourceDataset], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,papszArgv[nFirstSourceDataset])); } else { fileNameToWrite = CPLStrdup(papszArgv[nFirstSourceDataset]); } poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], FALSE ); if( poDS == NULL ) { fprintf( stderr, "Failed to open dataset %s, skipping.\n", papszArgv[nFirstSourceDataset] ); CPLFree(fileNameToWrite); continue; } /* -------------------------------------------------------------------- */ /* Check all layers, and see if they match requests. */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; /* Checks that the layer is not already in tileindex */ for(i=0;i<nExistingLayers;i++) { char szLocation[5000]; sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); if (EQUAL(szLocation, existingLayersTab[i])) { fprintf(stderr, "Layer %d of %s is already in tileindex. Skipping it.\n", iLayer, papszArgv[nFirstSourceDataset]); break; } } if (i != nExistingLayers) { continue; } OGRSpatialReference* spatialRef = poLayer->GetSpatialRef(); if (alreadyExistingSpatialRefValid) { if ((spatialRef != NULL && alreadyExistingSpatialRef != NULL && spatialRef->IsSame(alreadyExistingSpatialRef) == FALSE) || ((spatialRef != NULL) != (alreadyExistingSpatialRef != NULL))) { fprintf(stderr, "Warning : layer %d of %s is not using the same projection system as " "other files in the tileindex. This may cause problems when " "using it in MapServer for example.%s\n", iLayer, papszArgv[nFirstSourceDataset], (skip_different_projection) ? " Skipping it" : ""); if (skip_different_projection) { continue; } } } else { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (spatialRef) ? spatialRef->Clone() : NULL; } /* -------------------------------------------------------------------- */ /* Check if all layers in dataset have the same attributes schema. */ /* -------------------------------------------------------------------- */ if( poFeatureDefn == NULL ) { poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } else if ( !accept_different_schemas ) { OGRFeatureDefn* poFeatureDefnCur = poLayer->GetLayerDefn(); assert(NULL != poFeatureDefnCur); int fieldCount = poFeatureDefnCur->GetFieldCount(); if( fieldCount != poFeatureDefn->GetFieldCount()) { fprintf( stderr, "Number of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } continue; } int bSkip = FALSE; for( int fn = 0; fn < poFeatureDefnCur->GetFieldCount(); fn++ ) { OGRFieldDefn* poField = poFeatureDefn->GetFieldDefn(fn); OGRFieldDefn* poFieldCur = poFeatureDefnCur->GetFieldDefn(fn); /* XXX - Should those pointers be checked against NULL? */ assert(NULL != poField); assert(NULL != poFieldCur); if( poField->GetType() != poFieldCur->GetType() || poField->GetWidth() != poFieldCur->GetWidth() || poField->GetPrecision() != poFieldCur->GetPrecision() || !EQUAL( poField->GetNameRef(), poFieldCur->GetNameRef() ) ) { fprintf( stderr, "Schema of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } bSkip = TRUE; break; } } if (bSkip) continue; } /* -------------------------------------------------------------------- */ /* Get layer extents, and create a corresponding polygon */ /* geometry. */ /* -------------------------------------------------------------------- */ OGREnvelope sExtents; OGRPolygon oRegion; OGRLinearRing oRing; if( poLayer->GetExtent( &sExtents, TRUE ) != OGRERR_NONE ) { fprintf( stderr, "GetExtent() failed on layer %s of %s, skipping.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset] ); continue; } oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRegion.addRing( &oRing ); /* -------------------------------------------------------------------- */ /* Add layer to tileindex. */ /* -------------------------------------------------------------------- */ char szLocation[5000]; OGRFeature oTileFeat( poDstLayer->GetLayerDefn() ); sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); oTileFeat.SetGeometry( &oRegion ); oTileFeat.SetField( iTileIndexField, szLocation ); if( poDstLayer->CreateFeature( &oTileFeat ) != OGRERR_NONE ) { fprintf( stderr, "Failed to create feature on tile index ... terminating." ); OGRDataSource::DestroyDataSource( poDstDS ); exit( 1 ); } } /* -------------------------------------------------------------------- */ /* Cleanup this data source. */ /* -------------------------------------------------------------------- */ CPLFree(fileNameToWrite); OGRDataSource::DestroyDataSource( poDS ); } /* -------------------------------------------------------------------- */ /* Close tile index and clear buffers. */ /* -------------------------------------------------------------------- */ OGRDataSource::DestroyDataSource( poDstDS ); OGRFeatureDefn::DestroyFeatureDefn( poFeatureDefn ); if (alreadyExistingSpatialRef != NULL) OGRSpatialReference::DestroySpatialReference( alreadyExistingSpatialRef ); CPLFree(current_path); if (nExistingLayers) { int i; for(i=0;i<nExistingLayers;i++) { CPLFree(existingLayersTab[i]); } CPLFree(existingLayersTab); } return 0; }
bool ShpReader::SetupVectorProjection(OGRDataSource* OGRDataset, StudyControllerPtr studyController, OGRLayer* poLayer, VectorMapControllerPtr vectorMapController) { //If there exists a map layer, the vector file will be projected based on the projection of the map layer if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() > 0 ) { ProjectionToolPtr projTool = studyController->GetProjectionTool(); OGRSpatialReference* currentShpSR = poLayer->GetSpatialRef(); if (!studyController->IsProjectData() && !studyController->IsGeographic()) { needProjection=false; Log::Inst().Write("The projection information for this study is being ignored."); } else { if(currentShpSR != NULL) { if(currentShpSR->IsGeographic()) { Log::Inst().Write("Loading vector map with geographic coordinates."); studyController->SetProjectData(true); studyController->SetGeographic(true); needProjection=true; poTransform = studyController->GetProjectionTool(); } else if(currentShpSR->IsProjected()) { studyController->SetProjectData(true); studyController->SetGeographic(false); needProjection=true; Log::Inst().Write("Loading vector map with projected coordinates."); ProjectionToolPtr projTool = studyController->GetProjectionTool(); //OGRSpatialReference* currentLatLong = currentShpSR->CloneGeogCS(); OGRSpatialReference *targetCS= projTool->GetTargetCS (); if(targetCS != NULL && !currentShpSR->IsSame(targetCS)) poTransform.reset(OGRCreateCoordinateTransformation(currentShpSR, targetCS)); else needProjection=false; } else { // The user should probably be made aware of this warning. Log::Inst().Warning("(Warning) Unknown type of coordinate system."); return false; } } else { //studyController->SetProjectData(false); //studyController->SetGeographic(false); needProjection=false; Log::Inst().Write("Coordinate system information is not available for this map."); Log::Inst().Write("As a result, the projection information for this study is being ignored."); Log::Inst().Write(""); } return true; } } // App::Inst().GetLayerTreeController()->GetNumMapLayers() ==0 else { OGRSpatialReference* currentShpSR = poLayer->GetSpatialRef(); //OGRSpatialReference oSource; if(currentShpSR != NULL) { if(currentShpSR->IsGeographic()) { // lat/lon coordinates are using the geographic projection (aka, plate carrée) Log::Inst().Write("Loading vector map with lat/long coordinates."); studyController->SetProjectData(true); studyController->SetGeographic(true); needProjection=true; // determine centre of map VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel(); float vectorMinX= vectorMapModel->GetVectorBoundary_MinX(); float vectorMinY = vectorMapModel->GetVectorBoundary_MinY(); float vectorMaxX = vectorMapModel->GetVectorBoundary_MaxX(); float vectorMaxY = vectorMapModel->GetVectorBoundary_MaxY(); studyController->SetCentreLongitude(float(vectorMinX + fabs(vectorMinX - vectorMaxX) / 2.0)); studyController->SetCentreLatitude(float(vectorMinY + fabs(vectorMinY - vectorMaxY) / 2.0)); studyController->SetFirstStandardParallel(vectorMinY); studyController->SetSecondStandardParallel(vectorMaxY); studyController->CalculateProjectionTool(currentShpSR); poTransform = studyController->GetProjectionTool(); } else if(currentShpSR->IsProjected()) { studyController->SetProjectData(true); studyController->SetGeographic(false); Log::Inst().Write("Loading vector map with projected coordinates."); studyController->CalculateProjectionTool(currentShpSR); poTransform = studyController->GetProjectionTool(); needProjection=false; } else { // The user should probably be made aware of this warning. Log::Inst().Warning("(Warning) Unknown type of coordinate system."); return false; } } else { studyController->SetProjectData(false); studyController->SetGeographic(false); needProjection=false; Log::Inst().Write("Coordinate system information is not available for this map."); Log::Inst().Write("As a result, the projection information for this study is being ignored."); Log::Inst().Write("To overlaid a Vector map on top of this map, the vector map must be specified in the same coordinate system as this map"); Log::Inst().Write(""); } } return true; }
GDALTiler::GDALTiler(GDALDataset *poDataset, const Grid &grid, const TilerOptions &options): mGrid(grid), poDataset(poDataset), options(options) { // Transformed bounds can give slightly different results on different threads unless mutexed static std::mutex mutex; std::lock_guard<std::mutex> lock(mutex); // if the dataset is set we need to initialise the tile bounds and raster // resolution from it. if (poDataset != NULL) { // Get the bounds of the dataset double adfGeoTransform[6]; CRSBounds bounds; if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) { bounds = CRSBounds(adfGeoTransform[0], adfGeoTransform[3] + (poDataset->GetRasterYSize() * adfGeoTransform[5]), adfGeoTransform[0] + (poDataset->GetRasterXSize() * adfGeoTransform[1]), adfGeoTransform[3]); } else { throw CTBException("Could not get transformation information from source dataset"); } // Find out whether the dataset SRS matches that of the grid const char *srcWKT = poDataset->GetProjectionRef(); if (!strlen(srcWKT)) throw CTBException("The source dataset does not have a spatial reference system assigned"); OGRSpatialReference srcSRS = OGRSpatialReference(srcWKT); OGRSpatialReference gridSRS = mGrid.getSRS(); if (!srcSRS.IsSame(&gridSRS)) { // it doesn't match // Check the srs is valid switch(srcSRS.Validate()) { case OGRERR_NONE: break; case OGRERR_CORRUPT_DATA: throw CTBException("The source spatial reference system appears to be corrupted"); break; case OGRERR_UNSUPPORTED_SRS: throw CTBException("The source spatial reference system is not supported"); break; default: throw CTBException("There is an unhandled return value from `srcSRS.Validate()`"); } // We need to transform the bounds to the grid SRS double x[4] = { bounds.getMinX(), bounds.getMaxX(), bounds.getMaxX(), bounds.getMinX() }; double y[4] = { bounds.getMinY(), bounds.getMinY(), bounds.getMaxY(), bounds.getMaxY() }; OGRCoordinateTransformation *transformer = OGRCreateCoordinateTransformation(&srcSRS, &gridSRS); if (transformer == NULL) { throw CTBException("The source dataset to tile grid coordinate transformation could not be created"); } else if (transformer->Transform(4, x, y) != true) { delete transformer; throw CTBException("Could not transform dataset bounds to tile spatial reference system"); } delete transformer; // Get the min and max values of the transformed coordinates double minX = std::min(std::min(x[0], x[1]), std::min(x[2], x[3])), maxX = std::max(std::max(x[0], x[1]), std::max(x[2], x[3])), minY = std::min(std::min(y[0], y[1]), std::min(y[2], y[3])), maxY = std::max(std::max(y[0], y[1]), std::max(y[2], y[3])); mBounds = CRSBounds(minX, minY, maxX, maxY); // set the bounds mResolution = mBounds.getWidth() / poDataset->GetRasterXSize(); // set the resolution // cache the SRS string for use in reprojections later char *srsWKT = NULL; if (gridSRS.exportToWkt(&srsWKT) != OGRERR_NONE) { CPLFree(srsWKT); throw CTBException("Could not create grid WKT string"); } crsWKT = srsWKT; CPLFree(srsWKT); srsWKT = NULL; } else { // no reprojection is necessary mBounds = bounds; // use the existing dataset bounds mResolution = std::abs(adfGeoTransform[1]); // use the existing dataset resolution } poDataset->Reference(); // increase the refcount of the dataset } }
OGRLayer* OGRVRTDataSource::InstanciateWarpedLayer( CPLXMLNode *psLTree, const char *pszVRTDirectory, int bUpdate, int nRecLevel) { if( !EQUAL(psLTree->pszValue,"OGRVRTWarpedLayer") ) return NULL; CPLXMLNode *psSubNode; OGRLayer* poSrcLayer = NULL; for( psSubNode=psLTree->psChild; psSubNode != NULL; psSubNode=psSubNode->psNext ) { if( psSubNode->eType != CXT_Element ) continue; poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory, bUpdate, nRecLevel + 1); if( poSrcLayer != NULL ) break; } if( poSrcLayer == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot instanciate source layer" ); return NULL; } const char* pszTargetSRS = CPLGetXMLValue(psLTree, "TargetSRS", NULL); if( pszTargetSRS == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing TargetSRS element within OGRVRTWarpedLayer" ); delete poSrcLayer; return NULL; } const char* pszGeomFieldName = CPLGetXMLValue(psLTree, "WarpedGeomFieldName", NULL); int iGeomField = 0; if( pszGeomFieldName != NULL ) { iGeomField = poSrcLayer->GetLayerDefn()->GetGeomFieldIndex(pszGeomFieldName); if( iGeomField < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot find source geometry field '%s'", pszGeomFieldName ); delete poSrcLayer; return NULL; } } OGRSpatialReference* poSrcSRS; OGRSpatialReference* poTargetSRS; const char* pszSourceSRS = CPLGetXMLValue(psLTree, "SrcSRS", NULL); if( pszSourceSRS == NULL ) { poSrcSRS = poSrcLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetSpatialRef(); if( poSrcSRS != NULL) poSrcSRS = poSrcSRS->Clone(); } else { poSrcSRS = new OGRSpatialReference(); if( poSrcSRS->SetFromUserInput(pszSourceSRS) != OGRERR_NONE ) { delete poSrcSRS; poSrcSRS = NULL; } } if( poSrcSRS == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import source SRS" ); delete poSrcLayer; return NULL; } poTargetSRS = new OGRSpatialReference(); if( poTargetSRS->SetFromUserInput(pszTargetSRS) != OGRERR_NONE ) { delete poTargetSRS; poTargetSRS = NULL; } if( poTargetSRS == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import target SRS" ); delete poSrcSRS; delete poSrcLayer; return NULL; } if( pszSourceSRS == NULL && poSrcSRS->IsSame(poTargetSRS) ) { delete poSrcSRS; delete poTargetSRS; return poSrcLayer; } OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation( poSrcSRS, poTargetSRS ); OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ? OGRCreateCoordinateTransformation( poTargetSRS, poSrcSRS ) : NULL; delete poSrcSRS; delete poTargetSRS; if( poCT == NULL ) { delete poSrcLayer; return NULL; } /* -------------------------------------------------------------------- */ /* Build the OGRWarpedLayer. */ /* -------------------------------------------------------------------- */ OGRWarpedLayer* poLayer = new OGRWarpedLayer(poSrcLayer, iGeomField, TRUE, poCT, poReversedCT); /* -------------------------------------------------------------------- */ /* Set Extent if provided */ /* -------------------------------------------------------------------- */ const char* pszExtentXMin = CPLGetXMLValue( psLTree, "ExtentXMin", NULL ); const char* pszExtentYMin = CPLGetXMLValue( psLTree, "ExtentYMin", NULL ); const char* pszExtentXMax = CPLGetXMLValue( psLTree, "ExtentXMax", NULL ); const char* pszExtentYMax = CPLGetXMLValue( psLTree, "ExtentYMax", NULL ); if( pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL ) { poLayer->SetExtent( CPLAtof(pszExtentXMin), CPLAtof(pszExtentYMin), CPLAtof(pszExtentXMax), CPLAtof(pszExtentYMax) ); } return poLayer; }
int GDALRPCTransform( void *pTransformArg, int bDstToSrc, int nPointCount, double *padfX, double *padfY, double *padfZ, int *panSuccess ) { VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 ); GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg; GDALRPCInfo *psRPC = &(psTransform->sRPC); int i; if( psTransform->bReversed ) bDstToSrc = !bDstToSrc; int bands[1] = {1}; int nRasterXSize = 0, nRasterYSize = 0; /* -------------------------------------------------------------------- */ /* Lazy opening of the optionnal DEM file. */ /* -------------------------------------------------------------------- */ if(psTransform->pszDEMPath != NULL && psTransform->bHasTriedOpeningDS == FALSE) { int bIsValid = FALSE; psTransform->bHasTriedOpeningDS = TRUE; psTransform->poDS = (GDALDataset *) GDALOpen( psTransform->pszDEMPath, GA_ReadOnly ); if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1) { const char* pszSpatialRef = psTransform->poDS->GetProjectionRef(); if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0') { OGRSpatialReference* poWGSSpaRef = new OGRSpatialReference(SRS_WKT_WGS84); OGRSpatialReference* poDSSpaRef = new OGRSpatialReference(pszSpatialRef); if(!poWGSSpaRef->IsSame(poDSSpaRef)) psTransform->poCT =OGRCreateCoordinateTransformation( poWGSSpaRef, poDSSpaRef ); delete poWGSSpaRef; delete poDSSpaRef; } if (psTransform->poDS->GetGeoTransform( psTransform->adfGeoTransform) == CE_None && GDALInvGeoTransform( psTransform->adfGeoTransform, psTransform->adfReverseGeoTransform )) { bIsValid = TRUE; } } if (!bIsValid && psTransform->poDS != NULL) { GDALClose(psTransform->poDS); psTransform->poDS = NULL; } } if (psTransform->poDS) { nRasterXSize = psTransform->poDS->GetRasterXSize(); nRasterYSize = psTransform->poDS->GetRasterYSize(); } /* -------------------------------------------------------------------- */ /* The simple case is transforming from lat/long to pixel/line. */ /* Just apply the equations directly. */ /* -------------------------------------------------------------------- */ if( bDstToSrc ) { for( i = 0; i < nPointCount; i++ ) { if(psTransform->poDS) { double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfXOrig = padfX[i]; double dfYOrig = padfY[i]; double dfZOrig = padfZ[i]; if (!psTransform->poCT->Transform( 1, &dfXOrig, &dfYOrig, &dfZOrig)) { panSuccess[i] = FALSE; continue; } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfXOrig, dfYOrig, &dfX, &dfY ); } else GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, padfX[i], padfY[i], &dfX, &dfY ); int dX = int(dfX); int dY = int(dfY); if (!(dX >= 0 && dY >= 0 && dX+2 <= nRasterXSize && dY+2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //cubic interpolation int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adElevData, 4, 4, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfSumH(0); for ( int i = 0; i < 5; i++ ) { // Loop across the X axis for ( int j = 0; j < 5; j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = j - 1; int dKernIndY = i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight dfSumH += adElevData[j + i * 4] * dfPixelWeight; } } dfDEMH = dfSumH; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //bilinear interpolation int anElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &anElevData, 2, 2, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = anElevData[0] * dfDeltaX1 + anElevData[1] * dfDeltaX; double dfXZ2 = anElevData[2] * dfDeltaX1 + anElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } } RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, padfX + i, padfY + i ); } else RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, padfX + i, padfY + i ); panSuccess[i] = TRUE; } return TRUE; } /* -------------------------------------------------------------------- */ /* Compute the inverse (pixel/line/height to lat/long). This */ /* function uses an iterative method from an initial linear */ /* approximation. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPointCount; i++ ) { double dfResultX, dfResultY; if(psTransform->poDS) { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfZ = 0; if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ)) { panSuccess[i] = FALSE; continue; } } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfResultX, dfResultY, &dfX, &dfY ); int dX = int(dfX); int dY = int(dfY); double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //cubic interpolation int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adElevData, 4, 4, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfSumH(0); for ( int i = 0; i < 5; i++ ) { // Loop across the X axis for ( int j = 0; j < 5; j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = j - 1; int dKernIndY = i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight dfSumH += adElevData[j + i * 4] * dfPixelWeight; } } dfDEMH = dfSumH; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //bilinear interpolation int adElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &adElevData, 2, 2, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = adElevData[0] * dfDeltaX1 + adElevData[1] * dfDeltaX; double dfXZ2 = adElevData[2] * dfDeltaX1 + adElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } } RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } else { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } padfX[i] = dfResultX; padfY[i] = dfResultY; panSuccess[i] = TRUE; } return TRUE; }
void wxGISRasterRGBRenderer::Draw(wxGISDataset* pRasterDataset, wxGISEnumDrawPhase DrawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel) { wxGISRasterDataset* pRaster = dynamic_cast<wxGISRasterDataset*>(pRasterDataset); if(!pRaster) return; IDisplayTransformation* pDisplayTransformation = pDisplay->GetDisplayTransformation(); OGRSpatialReference* pDisplaySpatialReference = pDisplayTransformation->GetSpatialReference(); OGRSpatialReference* pRasterSpatialReference = pRaster->GetSpatialReference(); bool IsSpaRefSame(true); if(pDisplaySpatialReference && pDisplaySpatialReference) IsSpaRefSame = pDisplaySpatialReference->IsSame(pRasterSpatialReference); OGREnvelope VisibleBounds = pDisplayTransformation->GetVisibleBounds(); OGREnvelope* pRasterExtent = pRaster->GetEnvelope(); OGREnvelope RasterEnvelope, DisplayEnvelope; if(!IsSpaRefSame) { RasterEnvelope = TransformEnvelope(pRasterExtent, pRasterSpatialReference, pDisplaySpatialReference); } else { RasterEnvelope = *pRasterExtent; } bool IsZoomIn(false); //IsZoomIn = RasterEnvelope.Contains(VisibleBounds); IsZoomIn = RasterEnvelope.MaxX > VisibleBounds.MaxX || RasterEnvelope.MaxY > VisibleBounds.MaxY || RasterEnvelope.MinX < VisibleBounds.MinX || RasterEnvelope.MinY < VisibleBounds.MinY; if(IsZoomIn) { //intersect bounds OGREnvelope DrawBounds; DrawBounds.MinX = MAX(RasterEnvelope.MinX, VisibleBounds.MinX); DrawBounds.MinY = MAX(RasterEnvelope.MinY, VisibleBounds.MinY); DrawBounds.MaxX = MIN(RasterEnvelope.MaxX, VisibleBounds.MaxX); DrawBounds.MaxY = MIN(RasterEnvelope.MaxY, VisibleBounds.MaxY); OGRRawPoint OGRRawPoints[2]; OGRRawPoints[0].x = DrawBounds.MinX; OGRRawPoints[0].y = DrawBounds.MinY; OGRRawPoints[1].x = DrawBounds.MaxX; OGRRawPoints[1].y = DrawBounds.MaxY; wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2); if(!pDCPoints) { wxDELETEA(pDCPoints); return; } int nDCXOrig = pDCPoints[0].x; int nDCYOrig = pDCPoints[1].y; int nWidth = pDCPoints[1].x - pDCPoints[0].x; int nHeight = pDCPoints[0].y - pDCPoints[1].y; wxDELETEA(pDCPoints); if(nWidth <= 20 || nHeight <= 20) return; GDALDataset* pGDALDataset = pRaster->GetRaster(); int nBandCount = pGDALDataset->GetRasterCount(); //hack! int bands[3]; if(nBandCount < 3) { bands[0] = 1; bands[1] = 1; bands[2] = 1; } else { bands[0] = 1; bands[1] = 2; bands[2] = 3; } double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; double adfReverseGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; CPLErr err = pGDALDataset->GetGeoTransform(adfGeoTransform); bool bNoTransform(false); if(err != CE_None) { bNoTransform = true; } else { int nRes = GDALInvGeoTransform( adfGeoTransform, adfReverseGeoTransform ); } //2. get image data from raster - draw part of the raster if(IsSpaRefSame) { double rMinX, rMinY, rMaxX, rMaxY; int nXSize = pGDALDataset->GetRasterXSize(); int nYSize = pGDALDataset->GetRasterYSize(); if(bNoTransform) { rMinX = DrawBounds.MinX; rMaxX = DrawBounds.MaxX; rMaxY = nYSize - DrawBounds.MinY; rMinY = nYSize - DrawBounds.MaxY; } else { GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MinX, DrawBounds.MinY, &rMinX, &rMaxY ); GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MaxX, DrawBounds.MaxY, &rMaxX, &rMinY ); } //double rRealMinX, rRealMinY, rRealMaxX, rRealMaxY; //rRealMinX = MIN(rMinX, rMaxX); //rRealMinY = MIN(rMinY, rMaxY); //rRealMaxX = MAX(rMinX, rMaxX); //rRealMaxY = MAX(rMinY, rMaxY); double rImgWidth = rMaxX - rMinX; double rImgHeight = rMaxY - rMinY; int nImgWidth = ceil(rImgWidth) + 1; int nImgHeight = ceil(rImgHeight) + 1; //read in buffer int nMinX = floor(rMinX); int nMinY = floor(rMinY); if(nMinX < 0) nMinX = 0; if(nMinY < 0) nMinY = 0; if(nImgWidth > nXSize - nMinX) nImgWidth -= 1; if(nImgHeight > nYSize - nMinY) nImgHeight -= 1; //create buffer int nWidthOut = nWidth > nImgWidth ? nImgWidth : (double)nWidth + 1.0 /*/ 1.2 / 2 * 2/ 1.5 + 1) / 2*/; int nHeightOut = nHeight > nImgHeight ? nImgHeight : (double)nHeight + 1.0 /*/ 1.2 / 2 * 2 / 1.5 + 1) / 2*/; double rImgWidthOut = nWidth > nImgWidth ? rImgWidth : (double)nWidthOut * rImgWidth / nImgWidth; double rImgHeightOut = nHeight > nImgHeight ? rImgHeight : (double)nHeightOut * rImgHeight / nImgHeight; unsigned char* data = new unsigned char[nWidthOut * nHeightOut * 3]; err = pGDALDataset->AdviseRead(nMinX, nMinY, nImgWidth, nImgHeight, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, NULL); if(err != CE_None) { wxDELETEA(data);//delete[](data); return; } err = pGDALDataset->RasterIO(GF_Read, nMinX, nMinY, nImgWidth, nImgHeight, data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char)); if(err != CE_None) { wxDELETEA(data);//delete[](data); return; } //scale pTempData to data using interpolation methods pDisplay->DrawBitmap(Scale(data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, rImgWidthOut/*rImgWidth*/, rImgHeightOut/*rImgHeight*/, nWidth + 1 , nHeight + 1, rMinX - nMinX, rMinY - nMinY, /*enumGISQualityNearest*/enumGISQualityBilinear, pTrackCancel), nDCXOrig, nDCYOrig); wxDELETEA(data); } else { //void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1 ); //GDALDestroyGenImgProjTransformer( hTransformArg ); //// //get new envelope - it may rotate //// OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pDisplaySpatialReference, pRasterSpatialReference); ////// get real envelope ////// poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MaxY); ////// poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MinY); ////// poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MinY); ////// poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MaxY); //// OCTDestroyCoordinateTransformation(poCT); } } else { //1. convert newrasterenvelope to DC OGRRawPoint OGRRawPoints[2]; OGRRawPoints[0].x = RasterEnvelope.MinX; OGRRawPoints[0].y = RasterEnvelope.MinY; OGRRawPoints[1].x = RasterEnvelope.MaxX; OGRRawPoints[1].y = RasterEnvelope.MaxY; wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2); //2. get image data from raster - buffer size = DC_X and DC_Y - draw full raster if(!pDCPoints) { wxDELETEA(pDCPoints); return; } int nDCXOrig = pDCPoints[0].x; int nDCYOrig = pDCPoints[1].y; int nWidth = pDCPoints[1].x - pDCPoints[0].x; int nHeight = pDCPoints[0].y - pDCPoints[1].y; delete[](pDCPoints); GDALDataset* pGDALDataset = pRaster->GetRaster(); int nImgWidth = pGDALDataset->GetRasterXSize(); int nImgHeight = pGDALDataset->GetRasterYSize(); int nBandCount = pGDALDataset->GetRasterCount(); //hack! int bands[3]; if(nBandCount < 3) { bands[0] = 1; bands[1] = 1; bands[2] = 1; } else { bands[0] = 1; bands[1] = 2; bands[2] = 3; } //create buffer unsigned char* data = new unsigned char[nWidth * nHeight * 3]; if(IsSpaRefSame) { //read in buffer CPLErr err = pGDALDataset->RasterIO(GF_Read, 0, 0, nImgWidth, nImgHeight, data, nWidth, nHeight, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char)); if(err != CE_None) { wxDELETEA(data); return; } } else { //1. calc Width & Height of TempData with same aspect ratio of raster //2. create pTempData buffer unsigned char* pTempData; //3. fill data //4. for each pixel of data buffer get pixel from pTempData using OGRCreateCoordinateTransformation //delete[](data); } //3. draw //think about transparancy! wxImage ResultImage(nWidth, nHeight, data); pDisplay->DrawBitmap(ResultImage, nDCXOrig, nDCYOrig); //delete[](data); } }
int GDALRPCTransform( void *pTransformArg, int bDstToSrc, int nPointCount, double *padfX, double *padfY, double *padfZ, int *panSuccess ) { VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 ); GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg; GDALRPCInfo *psRPC = &(psTransform->sRPC); int i; if( psTransform->bReversed ) bDstToSrc = !bDstToSrc; /* -------------------------------------------------------------------- */ /* Lazy opening of the optionnal DEM file. */ /* -------------------------------------------------------------------- */ if(psTransform->pszDEMPath != NULL && psTransform->bHasTriedOpeningDS == FALSE) { int bIsValid = FALSE; psTransform->bHasTriedOpeningDS = TRUE; psTransform->poDS = (GDALDataset *) GDALOpen( psTransform->pszDEMPath, GA_ReadOnly ); if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1) { const char* pszSpatialRef = psTransform->poDS->GetProjectionRef(); if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0') { OGRSpatialReference* poWGSSpaRef = new OGRSpatialReference(SRS_WKT_WGS84); OGRSpatialReference* poDSSpaRef = new OGRSpatialReference(pszSpatialRef); if(!poWGSSpaRef->IsSame(poDSSpaRef)) psTransform->poCT =OGRCreateCoordinateTransformation( poWGSSpaRef, poDSSpaRef ); delete poWGSSpaRef; delete poDSSpaRef; } if (psTransform->poDS->GetGeoTransform( psTransform->adfGeoTransform) == CE_None && GDALInvGeoTransform( psTransform->adfGeoTransform, psTransform->adfReverseGeoTransform )) { bIsValid = TRUE; } } if (!bIsValid && psTransform->poDS != NULL) { GDALClose(psTransform->poDS); psTransform->poDS = NULL; } } /* -------------------------------------------------------------------- */ /* The simple case is transforming from lat/long to pixel/line. */ /* Just apply the equations directly. */ /* -------------------------------------------------------------------- */ if( bDstToSrc ) { for( i = 0; i < nPointCount; i++ ) { if(psTransform->poDS) { double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfXOrig = padfX[i]; double dfYOrig = padfY[i]; double dfZOrig = padfZ[i]; if (!psTransform->poCT->Transform( 1, &dfXOrig, &dfYOrig, &dfZOrig)) { panSuccess[i] = FALSE; continue; } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfXOrig, dfYOrig, &dfX, &dfY ); } else GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, padfX[i], padfY[i], &dfX, &dfY ); double dfDEMH(0); if( !GDALRPCGetDEMHeight( psTransform, dfX, dfY, &dfDEMH) ) { if( psTransform->bHasDEMMissingValue ) dfDEMH = psTransform->dfDEMMissingValue; else { panSuccess[i] = FALSE; continue; } } RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, padfX + i, padfY + i ); } else RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, padfX + i, padfY + i ); panSuccess[i] = TRUE; } return TRUE; } /* -------------------------------------------------------------------- */ /* Compute the inverse (pixel/line/height to lat/long). This */ /* function uses an iterative method from an initial linear */ /* approximation. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPointCount; i++ ) { double dfResultX, dfResultY; if(psTransform->poDS) { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfZ = 0; if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ)) { panSuccess[i] = FALSE; continue; } } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfResultX, dfResultY, &dfX, &dfY ); double dfDEMH(0); if( !GDALRPCGetDEMHeight( psTransform, dfX, dfY, &dfDEMH) ) { if( psTransform->bHasDEMMissingValue ) dfDEMH = psTransform->dfDEMMissingValue; else { panSuccess[i] = FALSE; continue; } } RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } else { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } padfX[i] = dfResultX; padfY[i] = dfResultY; panSuccess[i] = TRUE; } return TRUE; }