void IDADataset::ProcessGeoref() { OGRSpatialReference oSRS; if( nProjection == 3 ) { oSRS.SetWellKnownGeogCS( "WGS84" ); } else if( nProjection == 4 ) { oSRS.SetLCC( dfParallel1, dfParallel2, dfLatCenter, dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Clarke 1866", "Clarke 1866", "Clarke 1866", 6378206.4, 293.97869821389662 ); } else if( nProjection == 6 ) { oSRS.SetLAEA( dfLatCenter, dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Sphere", "Sphere", "Sphere", 6370997.0, 0.0 ); } else if( nProjection == 8 ) { oSRS.SetACEA( dfParallel1, dfParallel2, dfLatCenter, dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Clarke 1866", "Clarke 1866", "Clarke 1866", 6378206.4, 293.97869821389662 ); } else if( nProjection == 9 ) { oSRS.SetGH( dfLongCenter, 0.0, 0.0 ); oSRS.SetGeogCS( "Sphere", "Sphere", "Sphere", 6370997.0, 0.0 ); } if( oSRS.GetRoot() != NULL ) { CPLFree( pszProjection ); pszProjection = NULL; oSRS.exportToWkt( &pszProjection ); } adfGeoTransform[0] = 0 - dfDX * dfXCenter; adfGeoTransform[1] = dfDX; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = dfDY * dfYCenter; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dfDY; if( nProjection == 3 ) { adfGeoTransform[0] += dfLongCenter; adfGeoTransform[3] += dfLatCenter; } }
OGRSpatialReference *OGROCIDataSource::FetchSRS( int nId ) { if( nId < 0 ) return NULL; /* -------------------------------------------------------------------- */ /* First, we look through our SRID cache, is it there? */ /* -------------------------------------------------------------------- */ int i; for( i = 0; i < nKnownSRID; i++ ) { if( panSRID[i] == nId ) return papoSRS[i]; } /* -------------------------------------------------------------------- */ /* Try looking up in MDSYS.CS_SRS table. */ /* -------------------------------------------------------------------- */ OGROCIStatement oStatement( GetSession() ); char szSelect[200], **papszResult; snprintf( szSelect, sizeof(szSelect), "SELECT WKTEXT, AUTH_SRID, AUTH_NAME FROM MDSYS.CS_SRS " "WHERE SRID = %d AND WKTEXT IS NOT NULL", nId ); if( oStatement.Execute( szSelect ) != CE_None ) return NULL; papszResult = oStatement.SimpleFetchRow(); if( CSLCount(papszResult) < 1 ) return NULL; /* -------------------------------------------------------------------- */ /* Turn into a spatial reference. */ /* -------------------------------------------------------------------- */ char *pszWKT = papszResult[0]; OGRSpatialReference *poSRS = NULL; poSRS = new OGRSpatialReference(); if( poSRS->importFromWkt( &pszWKT ) != OGRERR_NONE ) { delete poSRS; poSRS = NULL; } /* -------------------------------------------------------------------- */ /* If we have a corresponding EPSG code for this SRID, use that */ /* authority. */ /* -------------------------------------------------------------------- */ int bGotEPSGMapping = FALSE; for( i = 0; anEPSGOracleMapping[i] != 0; i += 2 ) { if( anEPSGOracleMapping[i] == nId ) { poSRS->SetAuthority( poSRS->GetRoot()->GetValue(), "EPSG", anEPSGOracleMapping[i+1] ); bGotEPSGMapping = TRUE; break; } } /* -------------------------------------------------------------------- */ /* Insert authority information, if it is available. */ /* -------------------------------------------------------------------- */ if( papszResult[1] != NULL && atoi(papszResult[1]) != 0 && papszResult[2] != NULL && strlen(papszResult[1]) != 0 && poSRS->GetRoot() != NULL && !bGotEPSGMapping ) { poSRS->SetAuthority( poSRS->GetRoot()->GetValue(), papszResult[2], atoi(papszResult[1]) ); } /* -------------------------------------------------------------------- */ /* Add to the cache. */ /* -------------------------------------------------------------------- */ panSRID = (int *) CPLRealloc(panSRID,sizeof(int) * (nKnownSRID+1) ); papoSRS = (OGRSpatialReference **) CPLRealloc(papoSRS, sizeof(void*) * (nKnownSRID + 1) ); panSRID[nKnownSRID] = nId; papoSRS[nKnownSRID] = poSRS; nKnownSRID++; return poSRS; }
GDALDataset *BTDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Verify that this is some form of binterr file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 256) return NULL; if( !STARTS_WITH((const char *) poOpenInfo->pabyHeader, "binterr") ) return NULL; /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ BTDataset *poDS = new BTDataset(); memcpy( poDS->abyHeader, poOpenInfo->pabyHeader, 256 ); /* -------------------------------------------------------------------- */ /* Get the version. */ /* -------------------------------------------------------------------- */ char szVersion[4] = {}; strncpy( szVersion, (char *) (poDS->abyHeader + 7), 3 ); szVersion[3] = '\0'; poDS->nVersionCode = static_cast<int>(CPLAtof(szVersion) * 10); /* -------------------------------------------------------------------- */ /* Extract core header information, being careful about the */ /* version. */ /* -------------------------------------------------------------------- */ GInt32 nIntTemp = 0; memcpy( &nIntTemp, poDS->abyHeader + 10, 4 ); poDS->nRasterXSize = CPL_LSBWORD32( nIntTemp ); memcpy( &nIntTemp, poDS->abyHeader + 14, 4 ); poDS->nRasterYSize = CPL_LSBWORD32( nIntTemp ); if( !GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ) { delete poDS; return NULL; } GInt16 nDataSize = 0; memcpy( &nDataSize, poDS->abyHeader+18, 2 ); nDataSize = CPL_LSBWORD16( nDataSize ); GDALDataType eType = GDT_Unknown; if( poDS->abyHeader[20] != 0 && nDataSize == 4 ) eType = GDT_Float32; else if( poDS->abyHeader[20] == 0 && nDataSize == 4 ) eType = GDT_Int32; else if( poDS->abyHeader[20] == 0 && nDataSize == 2 ) eType = GDT_Int16; else { CPLError( CE_Failure, CPLE_AppDefined, ".bt file data type unknown, got datasize=%d.", nDataSize ); delete poDS; return NULL; } /* rcg, apr 7/06: read offset 62 for vert. units. If zero, assume 1.0 as per spec. */ memcpy( &poDS->m_fVscale, poDS->abyHeader + 62, 4 ); CPL_LSBPTR32(&poDS->m_fVscale); if(poDS->m_fVscale == 0.0f) poDS->m_fVscale = 1.0f; /* -------------------------------------------------------------------- */ /* Try to read a .prj file if it is indicated. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; if( poDS->nVersionCode >= 12 && poDS->abyHeader[60] != 0 ) { const char *pszPrjFile = CPLResetExtension( poOpenInfo->pszFilename, "prj" ); VSILFILE *fp = VSIFOpenL( pszPrjFile, "rt" ); if( fp != NULL ) { const int nBufMax = 10000; char *pszBuffer = static_cast<char *>(CPLMalloc(nBufMax)); const int nBytes = static_cast<int>(VSIFReadL( pszBuffer, 1, nBufMax-1, fp )); CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); pszBuffer[nBytes] = '\0'; char *pszBufPtr = pszBuffer; if( oSRS.importFromWkt( &pszBufPtr ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Unable to parse .prj file, " "coordinate system missing." ); } CPLFree( pszBuffer ); } } /* -------------------------------------------------------------------- */ /* If we didn't find a .prj file, try to use internal info. */ /* -------------------------------------------------------------------- */ if( oSRS.GetRoot() == NULL ) { GInt16 nUTMZone = 0; memcpy( &nUTMZone, poDS->abyHeader + 24, 2 ); nUTMZone = CPL_LSBWORD16( nUTMZone ); GInt16 nDatum = 0; memcpy( &nDatum, poDS->abyHeader + 26, 2 ); nDatum = CPL_LSBWORD16( nDatum ); GInt16 nHUnits = 0; memcpy( &nHUnits, poDS->abyHeader + 22, 2 ); nHUnits = CPL_LSBWORD16( nHUnits ); if( nUTMZone != 0 ) oSRS.SetUTM( std::abs(static_cast<int>(nUTMZone)), nUTMZone > 0 ); else if( nHUnits != 0 ) oSRS.SetLocalCS( "Unknown" ); if( nHUnits == 1 ) oSRS.SetLinearUnits( SRS_UL_METER, 1.0 ); else if( nHUnits == 2 ) oSRS.SetLinearUnits( SRS_UL_FOOT, CPLAtof(SRS_UL_FOOT_CONV) ); else if( nHUnits == 3 ) oSRS.SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) ); // Translate some of the more obvious old USGS datum codes if( nDatum == 0 ) nDatum = 6201; else if( nDatum == 1 ) nDatum = 6209; else if( nDatum == 2 ) nDatum = 6210; else if( nDatum == 3 ) nDatum = 6202; else if( nDatum == 4 ) nDatum = 6203; else if( nDatum == 6 ) nDatum = 6222; else if( nDatum == 7 ) nDatum = 6230; else if( nDatum == 13 ) nDatum = 6267; else if( nDatum == 14 ) nDatum = 6269; else if( nDatum == 17 ) nDatum = 6277; else if( nDatum == 19 ) nDatum = 6284; else if( nDatum == 21 ) nDatum = 6301; else if( nDatum == 22 ) nDatum = 6322; else if( nDatum == 23 ) nDatum = 6326; if( !oSRS.IsLocal() ) { if( nDatum >= 6000 ) { char szName[32]; snprintf( szName, sizeof(szName), "EPSG:%d", nDatum-2000 ); oSRS.SetWellKnownGeogCS( szName ); } else oSRS.SetWellKnownGeogCS( "WGS84" ); } } /* -------------------------------------------------------------------- */ /* Convert coordinate system back to WKT. */ /* -------------------------------------------------------------------- */ if( oSRS.GetRoot() != NULL ) oSRS.exportToWkt( &poDS->pszProjection ); /* -------------------------------------------------------------------- */ /* Get georeferencing bounds. */ /* -------------------------------------------------------------------- */ if( poDS->nVersionCode >= 11 ) { double dfLeft = 0.0; memcpy( &dfLeft, poDS->abyHeader + 28, 8 ); CPL_LSBPTR64( &dfLeft ); double dfRight = 0.0; memcpy( &dfRight, poDS->abyHeader + 36, 8 ); CPL_LSBPTR64( &dfRight ); double dfBottom = 0.0; memcpy( &dfBottom, poDS->abyHeader + 44, 8 ); CPL_LSBPTR64( &dfBottom ); double dfTop = 0.0; memcpy( &dfTop, poDS->abyHeader + 52, 8 ); CPL_LSBPTR64( &dfTop ); poDS->adfGeoTransform[0] = dfLeft; poDS->adfGeoTransform[1] = (dfRight - dfLeft) / poDS->nRasterXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfTop; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (dfBottom - dfTop) / poDS->nRasterYSize; poDS->bGeoTransformValid = TRUE; } /* -------------------------------------------------------------------- */ /* Re-open the file with the desired access. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to re-open %s within BT driver.\n", poOpenInfo->pszFilename ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Create band information objects */ /* -------------------------------------------------------------------- */ poDS->SetBand( 1, new BTRasterBand( poDS, poDS->fpImage, eType ) ); #ifdef notdef poDS->bGeoTransformValid = GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", poDS->adfGeoTransform ); #endif /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
GDALDataset *NDFDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* The user must select the header file (ie. .H1). */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 50 ) return NULL; if( !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=2",14) && !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=0",14) ) return NULL; /* -------------------------------------------------------------------- */ /* Read and process the header into a local name/value */ /* stringlist. We just take off the trailing semicolon. The */ /* keyword is already seperated from the value by an equal */ /* sign. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fp == NULL) return NULL; const char *pszLine; const int nHeaderMax = 1000; int nHeaderLines = 0; char **papszHeader = (char **) CPLMalloc(sizeof(char *) * (nHeaderMax+1)); while( nHeaderLines < nHeaderMax && (pszLine = CPLReadLineL( fp )) != NULL && !EQUAL(pszLine,"END_OF_HDR;") ) { char *pszFixed; if( strstr(pszLine,"=") == NULL ) break; pszFixed = CPLStrdup( pszLine ); if( pszFixed[strlen(pszFixed)-1] == ';' ) pszFixed[strlen(pszFixed)-1] = '\0'; papszHeader[nHeaderLines++] = pszFixed; papszHeader[nHeaderLines] = NULL; } VSIFCloseL(fp); fp = NULL; if( CSLFetchNameValue( papszHeader, "PIXELS_PER_LINE" ) == NULL || CSLFetchNameValue( papszHeader, "LINES_PER_DATA_FILE" ) == NULL || CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL" ) == NULL || CSLFetchNameValue( papszHeader, "PIXEL_FORMAT" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Dataset appears to be NDF but is missing a required field."); CSLDestroy( papszHeader ); return NULL; } if( !EQUAL(CSLFetchNameValue( papszHeader, "PIXEL_FORMAT"), "BYTE" ) || !EQUAL(CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL"),"8") ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently NDF driver supports only 8bit BYTE format." ); CSLDestroy( papszHeader ); return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CSLDestroy( papszHeader ); CPLError( CE_Failure, CPLE_NotSupported, "The NDF driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ NDFDataset *poDS; poDS = new NDFDataset(); poDS->papszHeader = papszHeader; poDS->nRasterXSize = atoi(poDS->Get("PIXELS_PER_LINE","")); poDS->nRasterYSize = atoi(poDS->Get("LINES_PER_DATA_FILE","")); /* -------------------------------------------------------------------- */ /* Create a raw raster band for each file. */ /* -------------------------------------------------------------------- */ int iBand; const char* pszBand = CSLFetchNameValue(papszHeader, "NUMBER_OF_BANDS_IN_VOLUME"); if (pszBand == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find band count"); delete poDS; return NULL; } int nBands = atoi(pszBand); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBands, FALSE)) { delete poDS; return NULL; } for( iBand = 0; iBand < nBands; iBand++ ) { char szKey[100]; CPLString osFilename; sprintf( szKey, "BAND%d_FILENAME", iBand+1 ); osFilename = poDS->Get(szKey,""); // NDF1 file do not include the band filenames. if( osFilename.size() == 0 ) { char szBandExtension[15]; sprintf( szBandExtension, "I%d", iBand+1 ); osFilename = CPLResetExtension( poOpenInfo->pszFilename, szBandExtension ); } else { CPLString osBasePath = CPLGetPath(poOpenInfo->pszFilename); osFilename = CPLFormFilename( osBasePath, osFilename, NULL); } VSILFILE *fpRaw = VSIFOpenL( osFilename, "rb" ); if( fpRaw == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to open band file: %s", osFilename.c_str() ); delete poDS; return NULL; } poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, osFilename ); RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, fpRaw, 0, 1, poDS->nRasterXSize, GDT_Byte, TRUE, TRUE ); sprintf( szKey, "BAND%d_NAME", iBand+1 ); poBand->SetDescription( poDS->Get(szKey, "") ); sprintf( szKey, "BAND%d_WAVELENGTHS", iBand+1 ); poBand->SetMetadataItem( "WAVELENGTHS", poDS->Get(szKey,"") ); sprintf( szKey, "BAND%d_RADIOMETRIC_GAINS/BIAS", iBand+1 ); poBand->SetMetadataItem( "RADIOMETRIC_GAINS_BIAS", poDS->Get(szKey,"") ); poDS->SetBand( iBand+1, poBand ); } /* -------------------------------------------------------------------- */ /* Fetch and parse USGS projection parameters. */ /* -------------------------------------------------------------------- */ double adfUSGSParms[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char **papszParmTokens = CSLTokenizeStringComplex( poDS->Get( "USGS_PROJECTION_NUMBER", "" ), ",", FALSE, TRUE ); if( CSLCount( papszParmTokens ) >= 15 ) { int i; for( i = 0; i < 15; i++ ) adfUSGSParms[i] = CPLAtof(papszParmTokens[i]); } CSLDestroy(papszParmTokens); papszParmTokens = NULL; /* -------------------------------------------------------------------- */ /* Minimal georef support ... should add full USGS style */ /* support at some point. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; int nUSGSProjection = atoi(poDS->Get( "USGS_PROJECTION_NUMBER", "" )); int nZone = atoi(poDS->Get("USGS_MAP_ZONE","0")); oSRS.importFromUSGS( nUSGSProjection, nZone, adfUSGSParms, 12 ); CPLString osDatum = poDS->Get( "HORIZONTAL_DATUM", "" ); if( EQUAL(osDatum,"WGS84") || EQUAL(osDatum,"NAD83") || EQUAL(osDatum,"NAD27") ) { oSRS.SetWellKnownGeogCS( osDatum ); } else if( EQUALN(osDatum,"NAD27",5) ) { oSRS.SetWellKnownGeogCS( "NAD27" ); } else { CPLError( CE_Warning, CPLE_AppDefined, "Unrecognised datum name in NLAPS/NDF file:%s, assuming WGS84.", osDatum.c_str() ); oSRS.SetWellKnownGeogCS( "WGS84" ); } if( oSRS.GetRoot() != NULL ) { CPLFree( poDS->pszProjection ); poDS->pszProjection = NULL; oSRS.exportToWkt( &(poDS->pszProjection) ); } /* -------------------------------------------------------------------- */ /* Get geotransform. */ /* -------------------------------------------------------------------- */ char **papszUL = CSLTokenizeString2( poDS->Get("UPPER_LEFT_CORNER",""), ",", 0 ); char **papszUR = CSLTokenizeString2( poDS->Get("UPPER_RIGHT_CORNER",""), ",", 0 ); char **papszLL = CSLTokenizeString2( poDS->Get("LOWER_LEFT_CORNER",""), ",", 0 ); if( CSLCount(papszUL) == 4 && CSLCount(papszUR) == 4 && CSLCount(papszLL) == 4 ) { poDS->adfGeoTransform[0] = CPLAtof(papszUL[2]); poDS->adfGeoTransform[1] = (CPLAtof(papszUR[2]) - CPLAtof(papszUL[2])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[2] = (CPLAtof(papszUR[3]) - CPLAtof(papszUL[3])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[3] = CPLAtof(papszUL[3]); poDS->adfGeoTransform[4] = (CPLAtof(papszLL[2]) - CPLAtof(papszUL[2])) / (poDS->nRasterYSize-1); poDS->adfGeoTransform[5] = (CPLAtof(papszLL[3]) - CPLAtof(papszUL[3])) / (poDS->nRasterYSize-1); // Move origin up-left half a pixel. poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5; poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[4] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[2] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5; } CSLDestroy( papszUL ); CSLDestroy( papszLL ); CSLDestroy( papszUR ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
void BExtractorDoc::OnImportimage2(LPCTSTR szPathName) { VTLOG("OnImportimage2 %s\n", szPathName); m_picLoaded = false; m_pImage = new CBImage; if (1) { CProgressDlg prog(CG_IDS_PROGRESS_CAPTION3); prog.Create(NULL); // top level CDC *pDC = GetView()->GetDC(); bool success = m_pImage->LoadFromFile(szPathName, pDC, m_hdd); GetView()->ReleaseDC(pDC); if (!success) { VTLOG("LoadFromFile failed\n"); return; } } // we don't know projection unless we have read a geotiff OGRSpatialReference *srs = m_pImage->m_pSpatialReference; if (srs == NULL || (srs != NULL && srs->GetRoot() == NULL)) { VTLOG("no SRS, opening Projection dialog.\n"); // Assume that I have loaded from a world file // and need some more info // get utm zone from a dialog CProjectionDlg dlg; dlg.m_iZone = 1; if (dlg.DoModal() != IDOK) return; m_proj.SetWellKnownGeogCS( "WGS84" ); switch (dlg.m_iProjection) { case 0: // UTM m_proj.SetUTMZone(dlg.m_iZone); m_Buildings.m_proj.SetUTMZone(dlg.m_iZone); m_Links.GetProjection().SetUTMZone(dlg.m_iZone); break; case 1: // OSGB m_proj.SetProjectionSimple(false, -1, 6277); // OSGB 1936 m_Buildings.m_proj.SetProjectionSimple(false, -1, 6277); m_Links.GetProjection().SetProjectionSimple(false, -1, 6277); break; default: // default to UTM m_proj.SetUTMZone(dlg.m_iZone); m_Buildings.m_proj.SetUTMZone(dlg.m_iZone); m_Links.GetProjection().SetUTMZone(dlg.m_iZone); break; } } else { // Loaded from a GDAL dataset (Geotiff etc.) // I should have a valid projection m_proj.SetSpatialReference(m_pImage->m_pSpatialReference); m_Buildings.m_proj.SetSpatialReference(m_pImage->m_pSpatialReference); m_Links.GetProjection().SetSpatialReference(m_pImage->m_pSpatialReference); } // is image >50 million pixels? if (m_pImage->m_PixelSize.x * m_pImage->m_PixelSize.y > 45000000) { CString str; str.Format("Warning! That image is really large (%d * %d)\n" "You can save memory by disabling color display.\n" "Do you want to do this?", m_pImage->m_PixelSize.x, m_pImage->m_PixelSize.y); int result = AfxMessageBox(str, MB_YESNO); if (result == IDYES) { if (NULL != m_pImage->m_pSourceDIB) { delete m_pImage->m_pSourceDIB; m_pImage->m_pSourceDIB = NULL; } } } m_picLoaded = true; // Tell the view to zoom to the freshly loaded bitmap m_Buildings.Empty(); //clear out any old buildings we have lying around m_Links.DeleteElements(); GetView()->ZoomToImage(m_pImage); VTLOG("OnImportimage2 finished\n"); }
/** Apply a vertical shift grid to a source (DEM typically) dataset. * * hGridDataset will typically use WGS84 as horizontal datum (but this is * not a requirement) and its values are the values to add to go from geoid * elevations to WGS84 ellipsoidal heights. * * hGridDataset will be on-the-fly reprojected and resampled to the projection * and resolution of hSrcDataset, using bilinear resampling by default. * * Both hSrcDataset and hGridDataset must be single band datasets, and have * a valid geotransform and projection. * * On success, a reference will be taken on hSrcDataset and hGridDataset. * Reference counting semantics on the source and grid datasets should be * honoured. That is, don't just GDALClose() it, unless it was opened with * GDALOpenShared(), but rather use GDALReleaseDataset() if wanting to * immediately release the reference(s) and make the returned dataset the * owner of them. * * Valid use cases: * * \code * hSrcDataset = GDALOpen(...) * hGridDataset = GDALOpen(...) * hDstDataset = GDALApplyVerticalShiftGrid(hSrcDataset, hGridDataset, ...) * GDALReleaseDataset(hSrcDataset); * GDALReleaseDataset(hGridDataset); * if( hDstDataset ) * { * // Do things with hDstDataset * GDALClose(hDstDataset) // will close hSrcDataset and hGridDataset * } * \endcode * * @param hSrcDataset source (DEM) dataset. Must not be NULL. * @param hGridDataset vertical grid shift dataset. Must not be NULL. * @param bInverse if set to FALSE, hGridDataset values will be added to * hSrcDataset. If set to TRUE, they will be subtracted. * @param dfSrcUnitToMeter the factor to convert values from hSrcDataset to * meters (1.0 if source values are in meter). * @param dfDstUnitToMeter the factor to convert shifted values from meter * (1.0 if output values must be in meter). * @param papszOptions list of options, or NULL. Supported options are: * <ul> * <li>RESAMPLING=NEAREST/BILINEAR/CUBIC. Defaults to BILINEAR.</li> * <li>MAX_ERROR=val. Maximum error measured in input pixels that is allowed in * approximating the transformation (0.0 for exact calculations). Defaults * to 0.125</li> * <li>DATATYPE=Byte/UInt16/Int16/Float32/Float64. Output data type. If not * specified will be the same as the one of hSrcDataset. * <li>ERROR_ON_MISSING_VERT_SHIFT=YES/NO. Whether a missing/nodata value in * hGridDataset should cause I/O requests to fail. Default is NO (in which case * 0 will be used) * <li>SRC_SRS=srs_def. Override projection on hSrcDataset; * </ul> * * @return a new dataset corresponding to hSrcDataset adjusted with * hGridDataset, or NULL. If not NULL, it must be closed with GDALClose(). * * @since GDAL 2.2 */ GDALDatasetH GDALApplyVerticalShiftGrid( GDALDatasetH hSrcDataset, GDALDatasetH hGridDataset, int bInverse, double dfSrcUnitToMeter, double dfDstUnitToMeter, const char* const* papszOptions ) { VALIDATE_POINTER1( hSrcDataset, "GDALApplyVerticalShiftGrid", nullptr ); VALIDATE_POINTER1( hGridDataset, "GDALApplyVerticalShiftGrid", nullptr ); double adfSrcGT[6]; if( GDALGetGeoTransform(hSrcDataset, adfSrcGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no geotransform."); return nullptr; } const char* pszSrcProjection = CSLFetchNameValueDef(papszOptions, "SRC_SRS", GDALGetProjectionRef(hSrcDataset)); if( pszSrcProjection == nullptr || pszSrcProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hSrcDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band source dataset is supported."); return nullptr; } double adfGridGT[6]; if( GDALGetGeoTransform(hGridDataset, adfGridGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no geotransform."); return nullptr; } const char* pszGridProjection = GDALGetProjectionRef(hGridDataset); if( pszGridProjection == nullptr || pszGridProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hGridDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band grid dataset is supported."); return nullptr; } GDALDataType eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDataset,1)); const char* pszDataType = CSLFetchNameValue(papszOptions, "DATATYPE"); if( pszDataType ) eDT = GDALGetDataTypeByName(pszDataType); if( eDT == GDT_Unknown ) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid DATATYPE=%s", pszDataType); return nullptr; } const int nSrcXSize = GDALGetRasterXSize(hSrcDataset); const int nSrcYSize = GDALGetRasterYSize(hSrcDataset); OGRSpatialReference oSRS; CPLString osSrcProjection(pszSrcProjection); oSRS.SetFromUserInput(osSrcProjection); if( oSRS.IsCompound() ) { OGR_SRSNode* poNode = oSRS.GetRoot()->GetChild(1); if( poNode != nullptr ) { char* pszWKT = nullptr; poNode->exportToWkt(&pszWKT); osSrcProjection = pszWKT; CPLFree(pszWKT); } } void* hTransform = GDALCreateGenImgProjTransformer3( pszGridProjection, adfGridGT, osSrcProjection, adfSrcGT ); if( hTransform == nullptr ) return nullptr; GDALWarpOptions* psWO = GDALCreateWarpOptions(); psWO->hSrcDS = hGridDataset; psWO->eResampleAlg = GRA_Bilinear; const char* pszResampling = CSLFetchNameValue(papszOptions, "RESAMPLING"); if( pszResampling ) { if( EQUAL(pszResampling, "NEAREST") ) psWO->eResampleAlg = GRA_NearestNeighbour; else if( EQUAL(pszResampling, "BILINEAR") ) psWO->eResampleAlg = GRA_Bilinear; else if( EQUAL(pszResampling, "CUBIC") ) psWO->eResampleAlg = GRA_Cubic; } psWO->eWorkingDataType = GDT_Float32; int bHasNoData = FALSE; const double dfSrcNoData = GDALGetRasterNoDataValue( GDALGetRasterBand(hGridDataset, 1), &bHasNoData ); if( bHasNoData ) { psWO->padfSrcNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); psWO->padfSrcNoDataReal[0] = dfSrcNoData; } psWO->padfDstNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); const bool bErrorOnMissingShift = CPLFetchBool( papszOptions, "ERROR_ON_MISSING_VERT_SHIFT", false ); psWO->padfDstNoDataReal[0] = (bErrorOnMissingShift) ? -std::numeric_limits<float>::infinity() : 0.0; psWO->papszWarpOptions = CSLSetNameValue(psWO->papszWarpOptions, "INIT_DEST", "NO_DATA"); psWO->pfnTransformer = GDALGenImgProjTransform; psWO->pTransformerArg = hTransform; const double dfMaxError = CPLAtof(CSLFetchNameValueDef(papszOptions, "MAX_ERROR", "0.125")); if( dfMaxError > 0.0 ) { psWO->pTransformerArg = GDALCreateApproxTransformer( psWO->pfnTransformer, psWO->pTransformerArg, dfMaxError ); psWO->pfnTransformer = GDALApproxTransform; GDALApproxTransformerOwnsSubtransformer(psWO->pTransformerArg, TRUE); } psWO->nBandCount = 1; psWO->panSrcBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panSrcBands[0] = 1; psWO->panDstBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panDstBands[0] = 1; VRTWarpedDataset* poReprojectedGrid = new VRTWarpedDataset(nSrcXSize, nSrcYSize); // This takes a reference on hGridDataset CPLErr eErr = poReprojectedGrid->Initialize(psWO); CPLAssert(eErr == CE_None); CPL_IGNORE_RET_VAL(eErr); GDALDestroyWarpOptions(psWO); poReprojectedGrid->SetGeoTransform(adfSrcGT); poReprojectedGrid->AddBand(GDT_Float32, nullptr); GDALApplyVSGDataset* poOutDS = new GDALApplyVSGDataset( reinterpret_cast<GDALDataset*>(hSrcDataset), poReprojectedGrid, eDT, CPL_TO_BOOL(bInverse), dfSrcUnitToMeter, dfDstUnitToMeter, // Undocumented option. For testing only atoi(CSLFetchNameValueDef(papszOptions, "BLOCKSIZE", "256")) ); poReprojectedGrid->ReleaseRef(); if( !poOutDS->IsInitOK() ) { delete poOutDS; return nullptr; } poOutDS->SetDescription( GDALGetDescription( hSrcDataset ) ); return reinterpret_cast<GDALDatasetH>(poOutDS); }
bool WriteTilesetHeader(const char *filename, int cols, int rows, int lod0size, const DRECT &area, const vtProjection &proj, float minheight, float maxheight, LODMap *lodmap, bool bJPEG) { FILE *fp = vtFileOpen(filename, "wb"); if (!fp) return false; fprintf(fp, "[TilesetDescription]\n"); fprintf(fp, "Columns=%d\n", cols); fprintf(fp, "Rows=%d\n", rows); fprintf(fp, "LOD0_Size=%d\n", lod0size); fprintf(fp, "Extent_Left=%.16lg\n", area.left); fprintf(fp, "Extent_Right=%.16lg\n", area.right); fprintf(fp, "Extent_Bottom=%.16lg\n", area.bottom); fprintf(fp, "Extent_Top=%.16lg\n", area.top); // write CRS, but pretty it up a bit OGRSpatialReference *poSimpleClone = proj.Clone(); poSimpleClone->GetRoot()->StripNodes( "AXIS" ); poSimpleClone->GetRoot()->StripNodes( "AUTHORITY" ); char *wkt; poSimpleClone->exportToWkt(&wkt); fprintf(fp, "CRS=%s\n", wkt); OGRFree(wkt); // Free CRS delete poSimpleClone; // For elevation tilesets, also write vertical extents if (minheight != INVALID_ELEVATION) { fprintf(fp, "Elevation_Min=%.f\n", minheight); fprintf(fp, "Elevation_Max=%.f\n", maxheight); } if (lodmap != NULL) { int mmin, mmax; for (int i = 0; i < rows; i++) { fprintf(fp, "RowLODs %2d:", i); for (int j = 0; j < cols; j++) { lodmap->get(j, i, mmin, mmax); fprintf(fp, " %d/%d", mmin, mmax); } fprintf(fp, "\n"); } } // create a transformation that will map from the current projection to Lat/Lon WGS84 vtProjection proj_llwgs84; proj_llwgs84.SetWellKnownGeogCS("WGS84"); OCT *LLWGS84transform=CreateCoordTransform(&proj,&proj_llwgs84); // write center point of the tileset in Lat/Lon WGS84 // this is helpful for libMini to compute an approximate translation double cx=(area.left+area.right)/2; double cy=(area.bottom+area.top)/2; if (LLWGS84transform->Transform(1,&cx,&cy)==1) fprintf(fp, "CenterPoint_LLWGS84=(%.16lg,%.16lg)\n",cx,cy); // write north point of the tileset in Lat/Lon WGS84 // this is helpful for libMini to compute an approximate rotation double nx=(area.left+area.right)/2; double ny=area.top; if (LLWGS84transform->Transform(1,&nx,&ny)==1) fprintf(fp, "NorthPoint_LLWGS84=(%.16lg,%.16lg)\n",nx,ny); // delete Lat/Lon WGS84 transformation delete LLWGS84transform; // write CRS info // this is helpful for libMini to easily identify the coordinate reference system // supported CRS are: Geographic, UTM, Mercator const int crs=mapCRS2MINI(proj); const int datum=mapEPSG2MINI(proj.GetDatum()); const int utmzone=proj.GetUTMZone(); fprintf(fp, "CoordSys=(%d,%d,%d)\n",crs,datum,utmzone); if (bJPEG) fprintf(fp, "Format=JPEG\n"); else fprintf(fp, "Format=DB\n"); fclose(fp); return true; }