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. */ /* -------------------------------------------------------------------- */ GDALDataset *poDstDS; OGRLayer *poDstLayer = NULL; poDstDS = (GDALDataset*) OGROpen( pszOutputName, TRUE, NULL ); /* -------------------------------------------------------------------- */ /* If that failed, find the driver so we can create the tile index.*/ /* -------------------------------------------------------------------- */ if( poDstDS == NULL ) { OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); GDALDriver *poDriver = NULL; int iDriver; for( iDriver = 0; iDriver < poR->GetDriverCount() && poDriver == NULL; iDriver++ ) { if( EQUAL(poR->GetDriver(iDriver)->GetDescription(),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)->GetDescription() ); } exit( 1 ); } if( !CSLTestBoolean( CSLFetchNameValueDef(poDriver->GetMetadata(), GDAL_DCAP_CREATE, "FALSE") ) ) { fprintf( stderr, "%s driver does not support data source creation.\n", pszFormat ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Now create it. */ /* -------------------------------------------------------------------- */ poDstDS = poDriver->Create( pszOutputName, 0, 0, 0, GDT_Unknown, 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) { GDALDataset* poDS = (GDALDataset*) OGROpen(papszArgv[nFirstSourceDataset], FALSE, NULL); 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; } } GDALClose( (GDALDatasetH)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) { GDALDataset *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 = (GDALDataset*) OGROpen(filename, FALSE, NULL); 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(); } GDALClose( (GDALDatasetH)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; GDALDataset *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 = (GDALDataset*) OGROpen( papszArgv[nFirstSourceDataset], FALSE, NULL ); 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." ); GDALClose( (GDALDatasetH) poDstDS ); exit( 1 ); } } /* -------------------------------------------------------------------- */ /* Cleanup this data source. */ /* -------------------------------------------------------------------- */ CPLFree(fileNameToWrite); GDALClose( (GDALDatasetH)poDS ); } /* -------------------------------------------------------------------- */ /* Close tile index and clear buffers. */ /* -------------------------------------------------------------------- */ GDALClose( (GDALDatasetH) 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); } OGRCleanupAll(); return 0; }
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; } }
CPLErr GDALRasterizeLayersBuf(void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nPixelSpace, int nLineSpace, int nLayerCount, OGRLayerH *pahLayers, const char *pszDstProjection, double *padfDstGeoTransform, GDALTransformerFunc pfnTransformer, void *pTransformArg, double dfBurnValue, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressArg) { #ifndef OGR_ENABLED CPLError(CE_Failure, CPLE_NotSupported, "GDALRasterizeLayersBuf() unimplemented in a non OGR build"); return CE_Failure; #else /* -------------------------------------------------------------------- */ /* If pixel and line spaceing are defaulted assign reasonable */ /* value assuming a packed buffer. */ /* -------------------------------------------------------------------- */ if (nPixelSpace == 0) nPixelSpace = GDALGetDataTypeSize(eBufType) / 8; if (nLineSpace == 0) nLineSpace = nPixelSpace * nBufXSize; if (pfnProgress == NULL) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Do some rudimentary arg checking. */ /* -------------------------------------------------------------------- */ if (nLayerCount == 0) return CE_None; int bAllTouched = CSLFetchBoolean(papszOptions, "ALL_TOUCHED", FALSE); const char *pszOpt = CSLFetchNameValue(papszOptions, "BURN_VALUE_FROM"); GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue; if (pszOpt) { if (EQUAL(pszOpt, "Z")) eBurnValueSource = GBV_Z; /*else if( EQUAL(pszOpt,"M")) eBurnValueSource = GBV_M;*/ } /* ==================================================================== */ /* Read thes pecified layers transfoming and rasterizing */ /* geometries. */ /* ==================================================================== */ CPLErr eErr = CE_None; int iLayer; const char *pszBurnAttribute = CSLFetchNameValue(papszOptions, "ATTRIBUTE"); pfnProgress(0.0, NULL, pProgressArg); for (iLayer = 0; iLayer < nLayerCount; iLayer++) { int iBurnField = -1; OGRLayer *poLayer = (OGRLayer*) pahLayers[iLayer]; if (!poLayer) { CPLError(CE_Warning, CPLE_AppDefined, "Layer element number %d is NULL, skipping.\n", iLayer); continue; } /* -------------------------------------------------------------------- */ /* If the layer does not contain any features just skip it. */ /* Do not force the feature count, so if driver doesn't know */ /* exact number of features, go down the normal way. */ /* -------------------------------------------------------------------- */ if (poLayer->GetFeatureCount(FALSE) == 0) continue; if (pszBurnAttribute) { iBurnField = poLayer->GetLayerDefn()->GetFieldIndex(pszBurnAttribute); if (iBurnField == -1) { CPLError(CE_Warning, CPLE_AppDefined, "Failed to find field %s on layer %s, skipping.\n", pszBurnAttribute, poLayer->GetLayerDefn()->GetName()); continue; } } /* -------------------------------------------------------------------- */ /* If we have no transformer, create the one from input file */ /* projection. Note that each layer can be georefernced */ /* separately. */ /* -------------------------------------------------------------------- */ int bNeedToFreeTransformer = FALSE; if (pfnTransformer == NULL) { char *pszProjection = NULL; bNeedToFreeTransformer = TRUE; OGRSpatialReference *poSRS = poLayer->GetSpatialRef(); if (!poSRS) { CPLError(CE_Warning, CPLE_AppDefined, "Failed to fetch spatial reference on layer %s " "to build transformer, assuming matching coordinate systems.\n", poLayer->GetLayerDefn()->GetName()); } else poSRS->exportToWkt(&pszProjection); pTransformArg = GDALCreateGenImgProjTransformer3(pszProjection, NULL, pszDstProjection, padfDstGeoTransform); pfnTransformer = GDALGenImgProjTransform; CPLFree(pszProjection); } OGRFeature *poFeat; poLayer->ResetReading(); while ((poFeat = poLayer->GetNextFeature()) != NULL) { OGRGeometry *poGeom = poFeat->GetGeometryRef(); if (pszBurnAttribute) dfBurnValue = poFeat->GetFieldAsDouble(iBurnField); gv_rasterize_one_shape((unsigned char*) pData, 0, nBufXSize, nBufYSize, 1, eBufType, bAllTouched, poGeom, &dfBurnValue, eBurnValueSource, pfnTransformer, pTransformArg); delete poFeat; } poLayer->ResetReading(); if (!pfnProgress(1, "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); eErr = CE_Failure; } if (bNeedToFreeTransformer) { GDALDestroyTransformer(pTransformArg); pTransformArg = NULL; pfnTransformer = NULL; } } return eErr; #endif /* def OGR_ENABLED */ }
GDALDataset *HF2Dataset::Open( GDALOpenInfo * poOpenInfo ) { CPLString osOriginalFilename(poOpenInfo->pszFilename); if (!Identify(poOpenInfo)) return NULL; GDALOpenInfo* poOpenInfoToDelete = NULL; /* GZipped .hf2 files are common, so automagically open them */ /* if the /vsigzip/ has not been explicitely passed */ CPLString osFilename(poOpenInfo->pszFilename); if ((EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "hfz") || (strlen(poOpenInfo->pszFilename) > 6 && EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "hf2.gz"))) && !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) { osFilename = "/vsigzip/"; osFilename += poOpenInfo->pszFilename; poOpenInfo = poOpenInfoToDelete = new GDALOpenInfo(osFilename.c_str(), GA_ReadOnly, poOpenInfo->papszSiblingFiles); } /* -------------------------------------------------------------------- */ /* Parse header */ /* -------------------------------------------------------------------- */ int nXSize, nYSize; memcpy(&nXSize, poOpenInfo->pabyHeader + 6, 4); CPL_LSBPTR32(&nXSize); memcpy(&nYSize, poOpenInfo->pabyHeader + 10, 4); CPL_LSBPTR32(&nYSize); GUInt16 nTileSize; memcpy(&nTileSize, poOpenInfo->pabyHeader + 14, 2); CPL_LSBPTR16(&nTileSize); float fVertPres, fHorizScale; memcpy(&fVertPres, poOpenInfo->pabyHeader + 16, 4); CPL_LSBPTR32(&fVertPres); memcpy(&fHorizScale, poOpenInfo->pabyHeader + 20, 4); CPL_LSBPTR32(&fHorizScale); GUInt32 nExtendedHeaderLen; memcpy(&nExtendedHeaderLen, poOpenInfo->pabyHeader + 24, 4); CPL_LSBPTR32(&nExtendedHeaderLen); delete poOpenInfoToDelete; poOpenInfoToDelete = NULL; if (nTileSize < 8) return NULL; if (nXSize <= 0 || nXSize > INT_MAX - nTileSize || nYSize <= 0 || nYSize > INT_MAX - nTileSize) return NULL; /* To avoid later potential int overflows */ if (nExtendedHeaderLen > 1024 * 65536) return NULL; if (!GDALCheckDatasetDimensions(nXSize, nYSize)) { return NULL; } /* -------------------------------------------------------------------- */ /* Parse extended blocks */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb"); if (fp == NULL) return NULL; VSIFSeekL(fp, 28, SEEK_SET); int bHasExtent = FALSE; double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0; int bHasUTMZone = FALSE; GInt16 nUTMZone = 0; int bHasEPSGDatumCode = FALSE; GInt16 nEPSGDatumCode = 0; int bHasEPSGCode = FALSE; GInt16 nEPSGCode = 0; int bHasRelativePrecision = FALSE; float fRelativePrecision = 0; char szApplicationName[256]; szApplicationName[0] = 0; GUInt32 nExtendedHeaderOff = 0; while(nExtendedHeaderOff < nExtendedHeaderLen) { char pabyBlockHeader[24]; VSIFReadL(pabyBlockHeader, 24, 1, fp); char szBlockName[16 + 1]; memcpy(szBlockName, pabyBlockHeader + 4, 16); szBlockName[16] = 0; GUInt32 nBlockSize; memcpy(&nBlockSize, pabyBlockHeader + 20, 4); CPL_LSBPTR32(&nBlockSize); if (nBlockSize > 65536) break; nExtendedHeaderOff += 24 + nBlockSize; if (strcmp(szBlockName, "georef-extents") == 0 && nBlockSize == 34) { char pabyBlockData[34]; VSIFReadL(pabyBlockData, 34, 1, fp); memcpy(&dfMinX, pabyBlockData + 2, 8); CPL_LSBPTR64(&dfMinX); memcpy(&dfMaxX, pabyBlockData + 2 + 8, 8); CPL_LSBPTR64(&dfMaxX); memcpy(&dfMinY, pabyBlockData + 2 + 8 + 8, 8); CPL_LSBPTR64(&dfMinY); memcpy(&dfMaxY, pabyBlockData + 2 + 8 + 8 + 8, 8); CPL_LSBPTR64(&dfMaxY); bHasExtent = TRUE; } else if (strcmp(szBlockName, "georef-utm") == 0 && nBlockSize == 2) { VSIFReadL(&nUTMZone, 2, 1, fp); CPL_LSBPTR16(&nUTMZone); CPLDebug("HF2", "UTM Zone = %d", nUTMZone); bHasUTMZone = TRUE; } else if (strcmp(szBlockName, "georef-datum") == 0 && nBlockSize == 2) { VSIFReadL(&nEPSGDatumCode, 2, 1, fp); CPL_LSBPTR16(&nEPSGDatumCode); CPLDebug("HF2", "EPSG Datum Code = %d", nEPSGDatumCode); bHasEPSGDatumCode = TRUE; } else if (strcmp(szBlockName, "georef-epsg-prj") == 0 && nBlockSize == 2) { VSIFReadL(&nEPSGCode, 2, 1, fp); CPL_LSBPTR16(&nEPSGCode); CPLDebug("HF2", "EPSG Code = %d", nEPSGCode); bHasEPSGCode = TRUE; } else if (strcmp(szBlockName, "precis-rel") == 0 && nBlockSize == 4) { VSIFReadL(&fRelativePrecision, 4, 1, fp); CPL_LSBPTR32(&fRelativePrecision); bHasRelativePrecision = TRUE; } else if (strcmp(szBlockName, "app-name") == 0 && nBlockSize < 256) { VSIFReadL(szApplicationName, nBlockSize, 1, fp); szApplicationName[nBlockSize] = 0; } else { CPLDebug("HF2", "Skipping block %s", szBlockName); VSIFSeekL(fp, nBlockSize, SEEK_CUR); } } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ HF2Dataset *poDS; poDS = new HF2Dataset(); poDS->fp = fp; poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->nTileSize = nTileSize; CPLDebug("HF2", "nXSize = %d, nYSize = %d, nTileSize = %d", nXSize, nYSize, nTileSize); if (bHasExtent) { poDS->adfGeoTransform[0] = dfMinX; poDS->adfGeoTransform[3] = dfMaxY; poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nXSize; poDS->adfGeoTransform[5] = -(dfMaxY - dfMinY) / nYSize; } else { poDS->adfGeoTransform[1] = fHorizScale; poDS->adfGeoTransform[5] = fHorizScale; } if (bHasEPSGCode) { OGRSpatialReference oSRS; if (oSRS.importFromEPSG(nEPSGCode) == OGRERR_NONE) oSRS.exportToWkt(&poDS->pszWKT); } else { int bHasSRS = FALSE; OGRSpatialReference oSRS; oSRS.SetGeogCS("unknown", "unknown", "unknown", SRS_WGS84_SEMIMAJOR, SRS_WGS84_INVFLATTENING); if (bHasEPSGDatumCode) { if (nEPSGDatumCode == 23 || nEPSGDatumCode == 6326) { bHasSRS = TRUE; oSRS.SetWellKnownGeogCS("WGS84"); } else if (nEPSGDatumCode >= 6000) { char szName[32]; sprintf( szName, "EPSG:%d", nEPSGDatumCode-2000 ); oSRS.SetWellKnownGeogCS( szName ); bHasSRS = TRUE; } } if (bHasUTMZone && ABS(nUTMZone) >= 1 && ABS(nUTMZone) <= 60) { bHasSRS = TRUE; oSRS.SetUTM(ABS(nUTMZone), nUTMZone > 0); } if (bHasSRS) oSRS.exportToWkt(&poDS->pszWKT); } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; int i; for( i = 0; i < poDS->nBands; i++ ) { poDS->SetBand( i+1, new HF2RasterBand( poDS, i+1, GDT_Float32 ) ); poDS->GetRasterBand(i+1)->SetUnitType("m"); } if (szApplicationName[0] != '\0') poDS->SetMetadataItem("APPLICATION_NAME", szApplicationName); poDS->SetMetadataItem("VERTICAL_PRECISION", CPLString().Printf("%f", fVertPres)); if (bHasRelativePrecision) poDS->SetMetadataItem("RELATIVE_VERTICAL_PRECISION", CPLString().Printf("%f", fRelativePrecision)); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osOriginalFilename.c_str() ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, osOriginalFilename.c_str() ); return( poDS ); }
GDALDataset *CTGDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; if (!Identify(poOpenInfo)) return NULL; CPLString osFilename(poOpenInfo->pszFilename); /* GZipped grid_cell.gz files are common, so automagically open them */ /* if the /vsigzip/ has not been explicitly passed */ const char* pszFilename = CPLGetFilename(poOpenInfo->pszFilename); if ((EQUAL(pszFilename, "grid_cell.gz") || EQUAL(pszFilename, "grid_cell1.gz") || EQUAL(pszFilename, "grid_cell2.gz")) && !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) { osFilename = "/vsigzip/"; osFilename += poOpenInfo->pszFilename; } if (poOpenInfo->eAccess == GA_Update) { CPLError( CE_Failure, CPLE_NotSupported, "The CTG driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Find dataset characteristics */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb"); if (fp == NULL) return NULL; char szHeader[HEADER_LINE_COUNT * 80+1]; szHeader[HEADER_LINE_COUNT * 80] = 0; if (VSIFReadL(szHeader, 1, HEADER_LINE_COUNT * 80, fp) != HEADER_LINE_COUNT * 80) { VSIFCloseL(fp); return NULL; } for(i=HEADER_LINE_COUNT * 80 - 1;i>=0;i--) { if (szHeader[i] == ' ') szHeader[i] = 0; else break; } char szField[11]; int nRows = atoi(ExtractField(szField, szHeader, 0, 10)); int nCols = atoi(ExtractField(szField, szHeader, 20, 10)); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ CTGDataset *poDS; poDS = new CTGDataset(); poDS->fp = fp; fp = NULL; poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->SetMetadataItem("TITLE", szHeader + 4 * 80); poDS->nCellSize = atoi(ExtractField(szField, szHeader, 35, 5)); if (poDS->nCellSize <= 0 || poDS->nCellSize >= 10000) { delete poDS; return NULL; } poDS->nNWEasting = atoi(ExtractField(szField, szHeader + 3*80, 40, 10)); poDS->nNWNorthing = atoi(ExtractField(szField, szHeader + 3*80, 50, 10)); poDS->nUTMZone = atoi(ExtractField(szField, szHeader, 50, 5)); if (poDS->nUTMZone <= 0 || poDS->nUTMZone > 60) { delete poDS; return NULL; } OGRSpatialReference oSRS; oSRS.importFromEPSG(32600 + poDS->nUTMZone); oSRS.exportToWkt(&poDS->pszProjection); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Read the imagery */ /* -------------------------------------------------------------------- */ GByte* pabyImage = (GByte*)VSICalloc(nCols * nRows, 6 * sizeof(int)); if (pabyImage == NULL) { delete poDS; return NULL; } poDS->pabyImage = pabyImage; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 6; for( i = 0; i < poDS->nBands; i++ ) { poDS->SetBand( i+1, new CTGRasterBand( poDS, i+1 ) ); poDS->GetRasterBand(i+1)->SetDescription(apszBandDescription[i]); } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate, int bTestOpen ) { SHPHandle hSHP; DBFHandle hDBF; const char *pszExtension = CPLGetExtension( pszNewName ); (void) bTestOpen; if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx") && !EQUAL(pszExtension,"dbf") ) return FALSE; /* -------------------------------------------------------------------- */ /* SHPOpen() should include better (CPL based) error reporting, */ /* and we should be trying to distinquish at this point whether */ /* failure is a result of trying to open a non-shapefile, or */ /* whether it was a shapefile and we want to report the error */ /* up. */ /* */ /* Care is taken to suppress the error and only reissue it if */ /* we think it is appropriate. */ /* -------------------------------------------------------------------- */ CPLPushErrorHandler( CPLQuietErrorHandler ); if( bUpdate ) hSHP = SHPOpen( pszNewName, "r+" ); else hSHP = SHPOpen( pszNewName, "r" ); CPLPopErrorHandler(); if( hSHP == NULL && (!EQUAL(CPLGetExtension(pszNewName),"dbf") || strstr(CPLGetLastErrorMsg(),".shp") == NULL) ) { CPLString osMsg = CPLGetLastErrorMsg(); CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() ); return FALSE; } CPLErrorReset(); /* -------------------------------------------------------------------- */ /* Open the .dbf file, if it exists. To open a dbf file, the */ /* filename has to either refer to a successfully opened shp */ /* file or has to refer to the actual .dbf file. */ /* -------------------------------------------------------------------- */ if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") ) { if( bUpdate ) hDBF = DBFOpen( pszNewName, "r+" ); else hDBF = DBFOpen( pszNewName, "r" ); } else hDBF = NULL; if( hDBF == NULL && hSHP == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Is there an associated .prj file we can read? */ /* -------------------------------------------------------------------- */ OGRSpatialReference *poSRS = NULL; const char *pszPrjFile = CPLResetExtension( pszNewName, "prj" ); FILE *fp = NULL; fp = VSIFOpen( pszPrjFile, "r" ); #ifndef WIN32 if( NULL == fp ) { pszPrjFile = CPLResetExtension( pszNewName, "PRJ" ); fp = VSIFOpen( pszPrjFile, "r" ); } #endif if( fp != NULL ) { char **papszLines; VSIFClose( fp ); papszLines = CSLLoad( pszPrjFile ); poSRS = new OGRSpatialReference(); if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE ) { delete poSRS; poSRS = NULL; } CSLDestroy( papszLines ); } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRShapeLayer *poLayer; poLayer = new OGRShapeLayer( pszNewName, hSHP, hDBF, poSRS, bUpdate, wkbNone ); poLayer->InitializeIndexSupport( pszNewName ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRShapeLayer **) CPLRealloc( papoLayers, sizeof(OGRShapeLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return TRUE; }
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; }
bool QgsImageWarper::createDestinationDataset( const QString &outputName, GDALDatasetH hSrcDS, GDALDatasetH &hDstDS, uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans, const QString& compression, const QString &projection ) { // create the output file GDALDriverH driver = GDALGetDriverByName( "GTiff" ); if ( driver == NULL ) { return false; } char **papszOptions = NULL; papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toAscii() ); hDstDS = GDALCreate( driver, QFile::encodeName( outputName ).constData(), resX, resY, GDALGetRasterCount( hSrcDS ), GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ), papszOptions ); if ( hDstDS == NULL ) { return false; } if ( CE_None != GDALSetGeoTransform( hDstDS, adfGeoTransform ) ) { return false; } if ( !projection.isEmpty() ) { OGRSpatialReference oTargetSRS; if ( projection.startsWith( "EPSG", Qt::CaseInsensitive ) ) { QString epsg = projection.mid( projection.indexOf( ":" ) + 1 ); oTargetSRS.importFromEPSG( epsg.toInt() ); } else { oTargetSRS.importFromProj4( projection.toLatin1().data() ); } char *wkt = NULL; OGRErr err = oTargetSRS.exportToWkt( &wkt ); if ( err != CE_None || GDALSetProjection( hDstDS, wkt ) != CE_None ) { OGRFree( wkt ); return false; } OGRFree( wkt ); } for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i ) { GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 ); GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS, i + 1 ); GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand ); GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) ); if ( cTable ) { GDALSetRasterColorTable( hDstBand, cTable ); } int success; double noData = GDALGetRasterNoDataValue( hSrcBand, &success ); if ( success ) { GDALSetRasterNoDataValue( hDstBand, noData ); } else if ( useZeroAsTrans ) { GDALSetRasterNoDataValue( hDstBand, 0 ); } } return true; }
GDALDataset *LCPDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Verify that this is a FARSITE LCP file */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The LCP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ LCPDataset *poDS; VSILFILE *fpImage; fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fpImage == NULL) return NULL; poDS = new LCPDataset(); poDS->fpImage = fpImage; /* -------------------------------------------------------------------- */ /* Read the header and extract some information. */ /* -------------------------------------------------------------------- */ int bHaveCrownFuels, bHaveGroundFuels; int nBands, i; long nWidth = -1, nHeight = -1; int nTemp, nTemp2; char szTemp[32]; char* pszList; VSIFSeekL( poDS->fpImage, 0, SEEK_SET ); if (VSIFReadL( poDS->pachHeader, 1, LCP_HEADER_SIZE, poDS->fpImage ) != LCP_HEADER_SIZE) { CPLError(CE_Failure, CPLE_FileIO, "File too short"); delete poDS; return NULL; } nWidth = CPL_LSBINT32PTR (poDS->pachHeader + 4164); nHeight = CPL_LSBINT32PTR (poDS->pachHeader + 4168); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } // crown fuels = canopy height, canopy base height, canopy bulk density // 21 = have them, 20 = don't have them bHaveCrownFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 0) - 20 ); // ground fuels = duff loading, coarse woody bHaveGroundFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 4) - 20 ); if( bHaveCrownFuels ) { if( bHaveGroundFuels ) nBands = 10; else nBands = 8; } else { if( bHaveGroundFuels ) nBands = 7; else nBands = 5; } // add dataset-level metadata nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 8); sprintf(szTemp, "%d", nTemp); poDS->SetMetadataItem( "LATITUDE", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 4204); if ( nTemp == 0 ) poDS->SetMetadataItem( "LINEAR_UNIT", "Meters" ); if ( nTemp == 1 ) poDS->SetMetadataItem( "LINEAR_UNIT", "Feet" ); poDS->pachHeader[LCP_HEADER_SIZE-1] = '\0'; poDS->SetMetadataItem( "DESCRIPTION", poDS->pachHeader + 6804 ); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int iPixelSize; iPixelSize = nBands * 2; int bNativeOrder; if (nWidth > INT_MAX / iPixelSize) { CPLError( CE_Failure, CPLE_AppDefined, "Int overflow occured"); delete poDS; return NULL; } #ifdef CPL_LSB bNativeOrder = TRUE; #else bNativeOrder = FALSE; #endif pszList = (char*)CPLMalloc(2048); for( int iBand = 1; iBand <= nBands; iBand++ ) { GDALRasterBand *poBand = NULL; poBand = new RawRasterBand( poDS, iBand, poDS->fpImage, LCP_HEADER_SIZE + ((iBand-1)*2), iPixelSize, iPixelSize * nWidth, GDT_Int16, bNativeOrder, TRUE ); poDS->SetBand(iBand, poBand); switch ( iBand ) { case 1: poBand->SetDescription("Elevation"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4224); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Meters" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Feet" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 44); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 48); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 52); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ELEVATION_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4244 + 255) = '\0'; poBand->SetMetadataItem( "ELEVATION_FILE", poDS->pachHeader + 4244 ); break; case 2: poBand->SetDescription("Slope"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4226); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Degrees" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Percent" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 456); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 460); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 464); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "SLOPE_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4500 + 255) = '\0'; poBand->SetMetadataItem( "SLOPE_FILE", poDS->pachHeader + 4500 ); break; case 3: poBand->SetDescription("Aspect"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4228); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass categories" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass degrees" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Azimuth degrees" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 868); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 872); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 876); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "ASPECT_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 4756 + 255) = '\0'; poBand->SetMetadataItem( "ASPECT_FILE", poDS->pachHeader + 4756 ); break; case 4: int nMinFM, nMaxFM; poBand->SetDescription("Fuel models"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4230); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "FUEL_MODEL_OPTION", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models AND no conversion file needed" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models BUT no conversion file needed" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models BUT conversion file needed" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models AND conversion file needed" ); nMinFM = CPL_LSBINT32PTR (poDS->pachHeader + 1280); sprintf(szTemp, "%d", nMinFM); poBand->SetMetadataItem( "FUEL_MODEL_MIN", szTemp ); nMaxFM = CPL_LSBINT32PTR (poDS->pachHeader + 1284); sprintf(szTemp, "%d", nMaxFM); poBand->SetMetadataItem( "FUEL_MODEL_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1288); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "FUEL_MODEL_NUM_CLASSES", szTemp ); if (nTemp > 0 && nTemp <= 100) { strcpy(pszList, ""); for ( i = 0; i <= nTemp; i++ ) { nTemp2 = CPL_LSBINT32PTR (poDS->pachHeader + (1292+(i*4))) ; if ( nTemp2 >= nMinFM && nTemp2 <= nMaxFM ) { sprintf(szTemp, "%d", nTemp2); strcat(pszList, szTemp); if (i < (nTemp) ) strcat(pszList, ","); } } } poBand->SetMetadataItem( "FUEL_MODEL_VALUES", pszList ); *(poDS->pachHeader + 5012 + 255) = '\0'; poBand->SetMetadataItem( "FUEL_MODEL_FILE", poDS->pachHeader + 5012 ); break; case 5: poBand->SetDescription("Canopy cover"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4232); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_UNIT", szTemp ); if ( nTemp == 0 ) poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Categories (0-4)" ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Percent" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1692); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1696); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1700); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_COV_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5268 + 255) = '\0'; poBand->SetMetadataItem( "CANOPY_COV_FILE", poDS->pachHeader + 5268 ); break; case 6: if(bHaveCrownFuels) { poBand->SetDescription("Canopy height"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4234); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters x 10" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet x 10" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2104); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2108); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2112); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CANOPY_HT_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5524 + 255) = '\0'; poBand->SetMetadataItem( "CANOPY_HT_FILE", poDS->pachHeader + 5524 ); } else { poBand->SetDescription("Duff"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6292 + 255) = '\0'; poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 ); } break; case 7: if(bHaveCrownFuels) { poBand->SetDescription("Canopy base height"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4236); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters x 10" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet x 10" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2516); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2520); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2524); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBH_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 5780 + 255) = '\0'; poBand->SetMetadataItem( "CBH_FILE", poDS->pachHeader + 5780 ); } else { poBand->SetDescription("Coarse woody debris"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_OPTION", szTemp ); //if ( nTemp == 1 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); //if ( nTemp == 2 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6548 + 255) = '\0'; poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 ); } break; case 8: poBand->SetDescription("Canopy bulk density"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4238); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3" ); if ( nTemp == 3 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3 x 100" ); if ( nTemp == 4 ) poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3 x 1000" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2928); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2932); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2936); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CBD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6036 + 255) = '\0'; poBand->SetMetadataItem( "CBD_FILE", poDS->pachHeader + 6036 ); break; case 9: poBand->SetDescription("Duff"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_UNIT", szTemp ); if ( nTemp == 1 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" ); if ( nTemp == 2 ) poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6292 + 255) = '\0'; poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 ); break; case 10: poBand->SetDescription("Coarse woody debris"); nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_OPTION", szTemp ); //if ( nTemp == 1 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); //if ( nTemp == 2 ) // poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MIN", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_MAX", szTemp ); nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760); sprintf(szTemp, "%d", nTemp); poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp ); *(poDS->pachHeader + 6548 + 255) = '\0'; poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 ); break; } } /* -------------------------------------------------------------------- */ /* Try to read projection file. */ /* -------------------------------------------------------------------- */ char *pszDirname, *pszBasename; VSIStatBufL sStatBuf; pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "prj" ); int nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf ); if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename)) { poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "PRJ" ); nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf ); } if( nRet == 0 ) { OGRSpatialReference oSRS; char** papszPrj = CSLLoad( poDS->osPrjFilename ); CPLDebug( "LCP", "Loaded SRS from %s", poDS->osPrjFilename.c_str() ); if( oSRS.importFromESRI( papszPrj ) == OGRERR_NONE ) { oSRS.exportToWkt( &(poDS->pszProjection) ); } CSLDestroy(papszPrj); } CPLFree( pszDirname ); CPLFree( pszBasename ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); CPLFree(pszList); return( poDS ); }
void E00GRIDDataset::ReadMetadata() { if (bHasReadMetadata) return; bHasReadMetadata = TRUE; if (e00ReadPtr == NULL) { int nRoundedBlockXSize = ((nRasterXSize + VALS_PER_LINE - 1) / VALS_PER_LINE) * VALS_PER_LINE; vsi_l_offset nValsToSkip = (vsi_l_offset)nRasterYSize * nRoundedBlockXSize; vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE; int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + nBytesEOL; vsi_l_offset nPos = nDataStart + nLinesToSkip * nBytesPerLine; VSIFSeekL(fp, nPos, SEEK_SET); } else { nLastYOff = -1; const unsigned int BUFFER_SIZE = 65536; const unsigned int NEEDLE_SIZE = 3*5; const unsigned int nToRead = BUFFER_SIZE - NEEDLE_SIZE; char* pabyBuffer = (char*)CPLCalloc(1, BUFFER_SIZE+NEEDLE_SIZE); int nRead; int bEOGFound = FALSE; VSIFSeekL(fp, 0, SEEK_END); vsi_l_offset nEndPos = VSIFTellL(fp); if (nEndPos > BUFFER_SIZE) nEndPos -= BUFFER_SIZE; else nEndPos = 0; VSIFSeekL(fp, nEndPos, SEEK_SET); #define GOTO_NEXT_CHAR() \ i ++; \ if (pabyBuffer[i] == 13 || pabyBuffer[i] == 10) \ { \ i++; \ if (pabyBuffer[i] == 10) \ i++; \ } \ while ((nRead = VSIFReadL(pabyBuffer, 1, nToRead, fp)) != 0) { int i; for(i = 0; i < nRead; i++) { if (pabyBuffer[i] == 'E') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == 'O') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == 'G') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == '~') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == '}') { bEOGFound = TRUE; break; } } } } } } if (bEOGFound) { VSIFSeekL(fp, VSIFTellL(fp) - nRead + i + 1, SEEK_SET); e00ReadPtr->iInBufPtr = 0; e00ReadPtr->szInBuf[0] = '\0'; break; } if (nEndPos == 0) break; if ((unsigned int)nRead == nToRead) { memmove(pabyBuffer + nToRead, pabyBuffer, NEEDLE_SIZE); if (nEndPos >= (vsi_l_offset)nToRead) nEndPos -= nToRead; else nEndPos = 0; VSIFSeekL(fp, nEndPos, SEEK_SET); } else break; } CPLFree(pabyBuffer); if (!bEOGFound) return; } const char* pszLine; int bPRJFound = FALSE; int bStatsFound = FALSE; while((pszLine = ReadLine()) != NULL) { if (EQUALN(pszLine, "PRJ 2", 6)) { bPRJFound = TRUE; while((pszLine = ReadLine()) != NULL) { if (EQUAL(pszLine, "EOP")) { break; } papszPrj = CSLAddString(papszPrj, pszLine); } OGRSpatialReference oSRS; if( oSRS.importFromESRI( papszPrj ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to parse PRJ section, ignoring." ); } else { char* pszWKT = NULL; if (oSRS.exportToWkt(&pszWKT) == OGRERR_NONE && pszWKT != NULL) osProjection = pszWKT; CPLFree(pszWKT); } if (bStatsFound) break; } else if (strcmp(pszLine, "STDV 8-1 254-1 15 3 60-1 -1 -1-1 4-") == 0) { bStatsFound = TRUE; pszLine = ReadLine(); if (pszLine) { CPLString osStats = pszLine; pszLine = ReadLine(); if (pszLine) { osStats += pszLine; char** papszTokens = CSLTokenizeString(osStats); if (CSLCount(papszTokens) == 4) { dfMin = CPLAtof(papszTokens[0]); dfMax = CPLAtof(papszTokens[1]); dfMean = CPLAtof(papszTokens[2]); dfStddev = CPLAtof(papszTokens[3]); bHasStats = TRUE; } CSLDestroy(papszTokens); } } if (bPRJFound) break; } } }
static int OGR2GML3GeometryAppend( OGRGeometry *poGeometry, const OGRSpatialReference* poParentSRS, char **ppszText, int *pnLength, int *pnMaxLength, int bIsSubGeometry, int bLongSRS, int bLineStringAsCurve, const char* pszGMLId, int nSRSDimensionLocFlags ) { /* -------------------------------------------------------------------- */ /* Check for Spatial Reference System attached to given geometry */ /* -------------------------------------------------------------------- */ // Buffer for srsName, srsDimension and gml:id attributes (srsName="..." gml:id="...") char szAttributes[256]; int nAttrsLength = 0; szAttributes[0] = 0; const OGRSpatialReference* poSRS = NULL; if (poParentSRS) poSRS = poParentSRS; else poParentSRS = poSRS = poGeometry->getSpatialReference(); int bCoordSwap = FALSE; if( NULL != poSRS ) { const char* pszAuthName = NULL; const char* pszAuthCode = NULL; const char* pszTarget = NULL; if (poSRS->IsProjected()) pszTarget = "PROJCS"; else pszTarget = "GEOGCS"; pszAuthName = poSRS->GetAuthorityName( pszTarget ); if( NULL != pszAuthName ) { if( EQUAL( pszAuthName, "EPSG" ) ) { pszAuthCode = poSRS->GetAuthorityCode( pszTarget ); if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 ) { if (bLongSRS && !(((OGRSpatialReference*)poSRS)->EPSGTreatsAsLatLong() || ((OGRSpatialReference*)poSRS)->EPSGTreatsAsNorthingEasting())) { OGRSpatialReference oSRS; if (oSRS.importFromEPSGA(atoi(pszAuthCode)) == OGRERR_NONE) { if (oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting()) bCoordSwap = TRUE; } } if (!bIsSubGeometry) { if (bLongSRS) { snprintf( szAttributes, sizeof(szAttributes), " srsName=\"urn:ogc:def:crs:%s::%s\"", pszAuthName, pszAuthCode ); } else { snprintf( szAttributes, sizeof(szAttributes), " srsName=\"%s:%s\"", pszAuthName, pszAuthCode ); } nAttrsLength = strlen(szAttributes); } } } } } if( (nSRSDimensionLocFlags & SRSDIM_LOC_GEOMETRY) != 0 && (poGeometry->getGeometryType() & wkb25DBit) != 0 ) { strcat(szAttributes, " srsDimension=\"3\""); nAttrsLength = strlen(szAttributes); nSRSDimensionLocFlags &= ~SRSDIM_LOC_GEOMETRY; } if (pszGMLId != NULL && nAttrsLength + 9 + strlen(pszGMLId) + 1 < sizeof(szAttributes)) { strcat(szAttributes, " gml:id=\""); strcat(szAttributes, pszGMLId); strcat(szAttributes, "\""); nAttrsLength = strlen(szAttributes); } /* -------------------------------------------------------------------- */ /* 2D Point */ /* -------------------------------------------------------------------- */ if( poGeometry->getGeometryType() == wkbPoint ) { char szCoordinate[256]; OGRPoint *poPoint = (OGRPoint *) poGeometry; if (bCoordSwap) OGRMakeWktCoordinate( szCoordinate, poPoint->getY(), poPoint->getX(), 0.0, 2 ); else OGRMakeWktCoordinate( szCoordinate, poPoint->getX(), poPoint->getY(), 0.0, 2 ); _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nAttrsLength, ppszText, pnMaxLength ); sprintf( *ppszText + *pnLength, "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>", szAttributes, szCoordinate ); *pnLength += strlen( *ppszText + *pnLength ); } /* -------------------------------------------------------------------- */ /* 3D Point */ /* -------------------------------------------------------------------- */ else if( poGeometry->getGeometryType() == wkbPoint25D ) { char szCoordinate[256]; OGRPoint *poPoint = (OGRPoint *) poGeometry; if (bCoordSwap) OGRMakeWktCoordinate( szCoordinate, poPoint->getY(), poPoint->getX(), poPoint->getZ(), 3 ); else OGRMakeWktCoordinate( szCoordinate, poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3 ); _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nAttrsLength, ppszText, pnMaxLength ); sprintf( *ppszText + *pnLength, "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>", szAttributes, szCoordinate ); *pnLength += strlen( *ppszText + *pnLength ); } /* -------------------------------------------------------------------- */ /* LineString and LinearRing */ /* -------------------------------------------------------------------- */ else if( poGeometry->getGeometryType() == wkbLineString || poGeometry->getGeometryType() == wkbLineString25D ) { int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING"); if (!bRing && bLineStringAsCurve) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:Curve" ); AppendString( ppszText, pnLength, pnMaxLength, szAttributes ); AppendString( ppszText, pnLength, pnMaxLength, "><gml:segments><gml:LineStringSegment>" ); AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap, ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags ); AppendString( ppszText, pnLength, pnMaxLength, "</gml:LineStringSegment></gml:segments></gml:Curve>" ); } else { // Buffer for tag name + srsName attribute if set const size_t nLineTagLength = 16; char* pszLineTagName = NULL; pszLineTagName = (char *) CPLMalloc( nLineTagLength + nAttrsLength + 1 ); if( bRing ) { /* LinearRing isn't supposed to have srsName attribute according to GML3 SF-0 */ AppendString( ppszText, pnLength, pnMaxLength, "<gml:LinearRing>" ); } else { sprintf( pszLineTagName, "<gml:LineString%s>", szAttributes ); AppendString( ppszText, pnLength, pnMaxLength, pszLineTagName ); } // FREE TAG BUFFER CPLFree( pszLineTagName ); AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap, ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags ); if( bRing ) AppendString( ppszText, pnLength, pnMaxLength, "</gml:LinearRing>" ); else AppendString( ppszText, pnLength, pnMaxLength, "</gml:LineString>" ); } } /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ else if( poGeometry->getGeometryType() == wkbPolygon || poGeometry->getGeometryType() == wkbPolygon25D ) { OGRPolygon *poPolygon = (OGRPolygon *) poGeometry; // Buffer for polygon tag name + srsName attribute if set const size_t nPolyTagLength = 13; char* pszPolyTagName = NULL; pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nAttrsLength + 1 ); // Compose Polygon tag with or without srsName attribute sprintf( pszPolyTagName, "<gml:Polygon%s>", szAttributes ); AppendString( ppszText, pnLength, pnMaxLength, pszPolyTagName ); // FREE TAG BUFFER CPLFree( pszPolyTagName ); // Don't add srsName to polygon rings if( poPolygon->getExteriorRing() != NULL ) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:exterior>" ); if( !OGR2GML3GeometryAppend( poPolygon->getExteriorRing(), poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, NULL, nSRSDimensionLocFlags) ) { return FALSE; } AppendString( ppszText, pnLength, pnMaxLength, "</gml:exterior>" ); } for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ ) { OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing); AppendString( ppszText, pnLength, pnMaxLength, "<gml:interior>" ); if( !OGR2GML3GeometryAppend( poRing, poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, NULL, nSRSDimensionLocFlags) ) return FALSE; AppendString( ppszText, pnLength, pnMaxLength, "</gml:interior>" ); } AppendString( ppszText, pnLength, pnMaxLength, "</gml:Polygon>" ); } /* -------------------------------------------------------------------- */ /* MultiPolygon, MultiLineString, MultiPoint, MultiGeometry */ /* -------------------------------------------------------------------- */ else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry; int iMember; const char *pszElemClose = NULL; const char *pszMemberElem = NULL; // Buffer for opening tag + srsName attribute char* pszElemOpen = NULL; if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon ) { pszElemOpen = (char *) CPLMalloc( 13 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiSurface%s>", szAttributes ); pszElemClose = "MultiSurface>"; pszMemberElem = "surfaceMember>"; } else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString ) { pszElemOpen = (char *) CPLMalloc( 16 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiCurve%s>", szAttributes ); pszElemClose = "MultiCurve>"; pszMemberElem = "curveMember>"; } else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint ) { pszElemOpen = (char *) CPLMalloc( 11 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiPoint%s>", szAttributes ); pszElemClose = "MultiPoint>"; pszMemberElem = "pointMember>"; } else { pszElemOpen = (char *) CPLMalloc( 19 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiGeometry%s>", szAttributes ); pszElemClose = "MultiGeometry>"; pszMemberElem = "geometryMember>"; } AppendString( ppszText, pnLength, pnMaxLength, "<gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen ); for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++) { OGRGeometry *poMember = poGC->getGeometryRef( iMember ); AppendString( ppszText, pnLength, pnMaxLength, "<gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem ); char* pszGMLIdSub = NULL; if (pszGMLId != NULL) pszGMLIdSub = CPLStrdup(CPLSPrintf("%s.%d", pszGMLId, iMember)); if( !OGR2GML3GeometryAppend( poMember, poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, pszGMLIdSub, nSRSDimensionLocFlags ) ) { CPLFree(pszGMLIdSub); return FALSE; } CPLFree(pszGMLIdSub); AppendString( ppszText, pnLength, pnMaxLength, "</gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem ); } AppendString( ppszText, pnLength, pnMaxLength, "</gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszElemClose ); // FREE TAG BUFFER CPLFree( pszElemOpen ); } else { return FALSE; } return TRUE; }
void LevelTerrainCallback::loaded(osgTerrain::TerrainTile *tile, const osgDB::ReaderWriter::Options *options) const { //Change TerrainTechnique tile->setTerrainTechnique(new DecoratedGeometryTechnique(voidBoundingAreaVector, treeStateSet.get(), buildingStateSet.get(), shapeFileVector)); std::stringstream nameStream; nameStream << "tile_L" << tile->getTileID().level << "_X" << tile->getTileID().x << "_Y" << tile->getTileID().y; tile->setName(nameStream.str()); /*tile->setName("TerrainTile"); osg::Vec3d model; tile->getLocator()->convertLocalToModel(osg::Vec3d(0.0,0.0,0.0), model); char name[1000]; sprintf(name,"X%f_Y%f_Z%f", model.x(), model.y(), model.z()); tile->setName(name);*/ //MTRand mt(10101); osgTerrain::HeightFieldLayer *hflayer = dynamic_cast<osgTerrain::HeightFieldLayer *>(tile->getElevationLayer()); osg::HeightField *field = NULL; if (hflayer) { field = hflayer->getHeightField(); } else { return; } double tileXInterval = field->getXInterval(); double tileYInterval = field->getYInterval(); double tileElementArea = tileXInterval * tileYInterval; double tileXMin = offset.x() + field->getOrigin().x(); double tileXMax = tileXMin + tileXInterval * (double)field->getNumColumns(); double tileYMin = offset.y() + field->getOrigin().y(); double tileYMax = tileYMin + tileYInterval * (double)field->getNumRows(); //osg::BoundingBox tileBB(tileXMin, tileYMin, -10.000, tileXMax, tileYMax, 10.000); if (tileXInterval > 10.0 && tileYInterval > 10.0) { return; } for (int i = 0; i < RoadSystem::Instance()->getNumRoads(); ++i) { Road *road = RoadSystem::Instance()->getRoad(i); double roadLength = road->getLength(); const osg::BoundingBox &roadBB = road->getRoadGeode()->getBoundingBox(); //if(roadBB.intersects(tileBB)) { if (((roadBB.xMax() >= tileXMin && roadBB.xMax() <= tileXMax) || (roadBB.xMin() >= tileXMin && roadBB.xMin() <= tileXMax) || (roadBB.xMin() <= tileXMin && roadBB.xMax() >= tileXMax)) && (roadBB.yMax() >= tileYMin && roadBB.yMin() <= tileYMax)) { //double h = sqrt(tileXInterval*tileXInterval + tileYInterval*tileYInterval); double h = 20.0; std::deque<RoadPoint> pointDeque(4); double widthRight, widthLeft; road->getRoadSideWidths(0.0, widthRight, widthLeft); pointDeque.pop_front(); pointDeque.pop_front(); pointDeque.push_back(road->getRoadPoint(0.0, widthLeft + 10.0)); pointDeque.push_back(road->getRoadPoint(0.0, widthRight - 10.0)); std::map<std::pair<int, int>, double> coordHeightMap; for (double s_ = h; s_ < roadLength + h; s_ = s_ + h) { double s = s_; if (s > roadLength) s = roadLength; road->getRoadSideWidths(s, widthRight, widthLeft); pointDeque.pop_front(); pointDeque.pop_front(); pointDeque.push_back(road->getRoadPoint(s, widthLeft + 10.0)); pointDeque.push_back(road->getRoadPoint(s, widthRight - 10.0)); //Bresenham // y x z std::map<int, std::map<int, double> > fillBorderMap; //iteration over four lines for (int i = 0; i < 4; ++i) { int j; switch (i) { case 0: j = 1; break; case 1: j = 3; break; case 2: j = 0; break; case 3: j = 2; break; } double fx0 = (pointDeque[i].x() - tileXMin) / tileXInterval; double fy0 = (pointDeque[i].y() - tileYMin) / tileYInterval; double fx1 = (pointDeque[j].x() - tileXMin) / tileXInterval; double fy1 = (pointDeque[j].y() - tileYMin) / tileYInterval; double dir_x = (fx0 - fx1) < 0.0 ? -1.0 : 1.0; double dir_y = (fy0 - fy1) < 0.0 ? -1.0 : 1.0; int x0 = (int)floor(fx0 + dir_x + 0.5); //if(x0<0) x0=0; else if(x0>=field->getNumColumns()) x0=field->getNumColumns()-1; int y0 = (int)floor(fy0 + dir_y + 0.5); //if(y0<0) y0=0; else if(y0>=field->getNumRows()) y0=field->getNumRows()-1; int x1 = (int)floor(fx1 - dir_x + 0.5); //if(x1<0) x1=0; else if(x1>=field->getNumColumns()) x1=field->getNumColumns()-1; int y1 = (int)floor(fy1 - dir_y + 0.5); //if(y1<0) y1=0; else if(y1>=field->getNumRows()) y1=field->getNumRows()-1; double z = 0.5 * (pointDeque[i].z() + pointDeque[j].z()); //wikipedia implementation int dx = abs(x1 - x0); int sx = x0 < x1 ? 1 : -1; int dy = -abs(y1 - y0); int sy = y0 < y1 ? 1 : -1; int err = dx + dy; int e2; /* error value e_xy */ do { /* loop */ //setPixel(x0,y0); fillBorderMap[y0][x0] = z; //fillBorderMap[y0][x0] = 0.5; //if (x0==x1 && y0==y1) break; e2 = 2 * err; if (e2 >= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ } while (!(x0 == x1 && y0 == y1)); } for (std::map<int, std::map<int, double> >::iterator yScanlineIt = fillBorderMap.begin(); yScanlineIt != fillBorderMap.end(); ++yScanlineIt) { int x0 = (yScanlineIt->second.begin())->first; double z0 = (yScanlineIt->second.begin())->second; int x1 = (--(yScanlineIt->second.end()))->first; double z1 = (--(yScanlineIt->second.end()))->second; unsigned int y = yScanlineIt->first; //if(y==field->getNumRows()-1) continue; for (int x = x0; x <= x1; ++x) { if (x >= 0 && x < (int)field->getNumColumns() && y >= 0 && y < field->getNumRows()) { //field->setHeight(x,y,0.5*(z0+z1)-0.5); //double z = field->getHeight(x,y); double rl_x = 0.5 * (pointDeque[0].x() + pointDeque[1].x()); double rl_y = 0.5 * (pointDeque[0].y() + pointDeque[1].y()); double ru_x = 0.5 * (pointDeque[2].x() + pointDeque[3].x()); double ru_y = 0.5 * (pointDeque[2].y() + pointDeque[3].y()); double t_x = ru_x - rl_x; double t_y = ru_y - rl_y; double mag_t = sqrt(t_x * t_x + t_y * t_y); if (mag_t != mag_t) continue; t_x /= mag_t; t_y /= mag_t; double rp_x = tileXInterval * ((double)(x)) + tileXMin - rl_x; double rp_y = tileYInterval * ((double)(y)) + tileYMin - rl_y; double d_x = -t_y * t_x * rp_y + t_y * t_y * rp_x; double d_y = t_x * t_x * rp_y - t_x * t_y * rp_x; double d = sqrt(d_x * d_x + d_y * d_y); //double mag_d = sqrt(d_x*d_x + d_y*d_y); //double d = 0.0; //if(mag_d==mag_d) { // d = (d_x*d_x+d_y*d_y)/mag_d; //} double s_x = rp_x - d_x; double s_y = rp_y - d_y; double s = sqrt(s_x * s_x + s_y * s_y); double wl = sqrt(pow(pointDeque[0].x() - pointDeque[1].x(), 2) + pow(pointDeque[0].y() - pointDeque[1].y(), 2)); double wu = sqrt(pow(pointDeque[2].x() - pointDeque[3].x(), 2) + pow(pointDeque[2].y() - pointDeque[3].y(), 2)); double l = sqrt(pow(0.5 * (pointDeque[0].x() - pointDeque[2].x() + pointDeque[1].x() - pointDeque[3].x()), 2) + pow(0.5 * (pointDeque[0].y() - pointDeque[2].y() + pointDeque[1].y() - pointDeque[3].y()), 2)); double zt; std::map<std::pair<int, int>, double>::iterator coordHeightMapIt = coordHeightMap.find(std::make_pair(x, y)); if (coordHeightMapIt == coordHeightMap.end()) { zt = (double)field->getHeight(x, y); coordHeightMap[std::make_pair(x, y)] = zt; } else { zt = coordHeightMapIt->second; } double zf0 = 7.0; double zf = 0.5 * (z0 + z1) - zf0; double kt0 = 50.0; double kt = (d / (0.5 * (wl + (wu - wl) * s / l))) * kt0; double kf0 = 10.0; double kf = (1.0 - d / (0.5 * (wl + (wu - wl) * s / l))) * kf0; double zl = (zt * kt + zf * kf) / (kt + kf); double z_field = field->getHeight(x, y); if (z_field > zl) { field->setHeight(x, y, zl); } //std::cout << "(x,y): (" << x << "," << y << "), zt: " << zt << ", zf: " << zf << ", kt: " << kt << ", kf: " << kf << std::endl; //field->setHeight(x,y, std::min(zf, 0.5*(z0+z1) - 1.0*(1.0- d/(wl+(wu-wl)*s/l)) ) ); //std::cout << "(x,y): (" << x << "," << y << "), z0: " << z0 << ", z1: " << z1 << ", d: " << d << ", wl: " << wl << ", wu: " << wu << ", s: " << s << ", l: " << l << std::endl; } } } /*Vector3D roadCenterPoint = road->getCenterLinePoint(s); int x = floor((roadCenterPoint.x() - tileXMin)/tileXInterval + 0.5); int y = floor((roadCenterPoint.y() - tileYMin)/tileYInterval + 0.5); if(x>=0 && x<field->getNumColumns() && y>=0 && y<field->getNumRows()) { field->setHeight(x,y,0.0); }*/ } } } #if 0 //osg::Group* treeGroup = new osg::Group(); //tile->addChild(treeGroup); //treeGroup->setName("TreeGroup"); osg::PositionAttitudeTransform* treeGeodeTransform = new osg::PositionAttitudeTransform; tile->addChild(treeGeodeTransform); treeGeodeTransform->setName("TreeGeodeTransform"); osg::Vec3 tileMin(tileXMin, tileYMin, 0.0); treeGeodeTransform->setPosition(-offset + tileMin); osg::Geode* treeGeode = new osg::Geode(); //tile->addChild(treeGeode); treeGeodeTransform->addChild(treeGeode); treeGeode->setName("TreeGeode"); treeGeode->setStateSet(treeStateSet); #endif #if 0 for(int layerIt = 0; layerIt < layers.size(); ++layerIt) { OGRLayer* layer = layers[layerIt]; layer->ResetReading(); OGRFeature* poFeature = NULL; while((poFeature = layer->GetNextFeature()) != NULL) { OGRGeometry *poGeometry = poFeature->GetGeometryRef(); if(poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon) { OGRPolygon *poPolygon = dynamic_cast<OGRPolygon*>(poGeometry); //std::cout << "Geometry name: " << poPolygon->getGeometryName() << std::endl; //std::cout << "Polgon area: " << poPolygon->get_Area() << std::endl; OGRSpatialReference *poSource = layer->GetSpatialRef(); OGRSpatialReference *poTarget = new OGRSpatialReference(); poTarget->importFromProj4("+proj=utm +zone=32"); OGRCoordinateTransformation* poCoordTrans = OGRCreateCoordinateTransformation(poSource, poTarget); poPolygon->transform(poCoordTrans); OGRLinearRing* poRing = poPolygon->getExteriorRing(); /*for(int pointIt = 0; pointIt<poRing->getNumPoints(); ++pointIt) { std::cout << "Point " << pointIt << ": (" << poRing->getX(pointIt) + offset.x() << ", " << poRing->getY(pointIt) + offset.y() << ", " << poRing->getZ(pointIt) << ")" << std::endl; }*/ /*double interval = 10.0*sqrt(tileXInterval*tileXInterval + tileYInterval*tileYInterval); OGRPoint point; poRing->Value(0, &point); OGRPoint point_next; for(double s = 0; s<poRing->get_Length(); s += interval*mt()) { double s_next = s+interval; if(s_next>poRing->get_Length()) s_next = poRing->get_Length(); poRing->Value(s_next, &point_next); double ccw = poRing->isClockwise() ? -1.0 : 1.0; double t_x = point_next.getX() - point.getX(); double t_y = point_next.getY() - point.getY(); double n_x = -t_y*ccw; double n_y = t_x*ccw; double mag_n = sqrt(n_x*n_x+n_y*n_y); if(mag_n>1e-3) { n_x /= mag_n; n_y /= mag_n; } double n_mt = mt(); double x = point.getX()+offset.x() + 0.5*t_x + 10.0*n_mt*n_x; double y = point.getY()+offset.y() + 0.5*t_y + 10.0*n_mt*n_y; //std::cout << "t_x: " << t_x << ", t_y: " << t_y << ", n_x: " << 10.0*n_mt*n_x << ", n_y: " << 10.0*n_mt*n_y << std::endl; std::cout << "x: " << x << ", y: " << y << std::endl; point = point_next; //std::cout << "Boundary trace: s: " << s << ", x: " << x << ", y:" << y << ", tile min: (" << tileXMin << ", " << tileYMin << "), max: (" << tileXMax << ", " << tileYMax << ")" << std::endl; osg::BoundingBox tileBB(tileXMin, tileYMin, -1.0, tileXMax, tileYMax, 1.0); if(tileBB.contains(osg::Vec3(x,y,0.0))) { osg::PositionAttitudeTransform* treeTrans = new osg::PositionAttitudeTransform(); treeGroup->addChild(treeTrans); //hflayer->getInterpolatedValue(x,y,z); int x_int = floor((x-tileXMin)/tileXInterval+0.5); if(x_int<0) x_int=0; else if(x_int>=field->getNumColumns()) x_int=field->getNumColumns()-1; int y_int = floor((y-tileYMin)/tileYInterval+0.5); if(y_int<0) y_int=0; else if(y_int>=field->getNumRows()) y_int=field->getNumRows()-1; double z = field->getHeight(x_int,y_int); //osg::Vec3 treePos(x,y,z); osg::Vec3 treePos(point.getX(),point.getY(),z); treeTrans->setPosition(treePos); int treeIt = (int)floor(mt()*(double)treeNodeVector.size()); treeTrans->addChild(treeNodeVector[treeIt].get()); treeTrans->setName("TreeTransform"); } }*/ OGREnvelope psEnvelope; poPolygon->getEnvelope(&psEnvelope); int nTrees = (int)((psEnvelope.MaxX-psEnvelope.MinX)*(psEnvelope.MaxY-psEnvelope.MinY)*1e-5/tileElementArea); for(int i = 0; i<nTrees; ++i) { OGRPoint point; //point.setX(mt()*(psEnvelope.MaxX-psEnvelope.MinX) + psEnvelope.MinX); //point.setY(mt()*(psEnvelope.MaxY-psEnvelope.MinY) + psEnvelope.MinY); point.setX(mt()*(tileXMax-tileXMin) + tileXMin); point.setY(mt()*(tileYMax-tileYMin) + tileYMin); //if(poPolygon->Contains(&point)) { osg::PositionAttitudeTransform* treeTrans = new osg::PositionAttitudeTransform(); treeGroup->addChild(treeTrans); //hflayer->getInterpolatedValue(x,y,z); double x = point.getX() + offset.x(); double y = point.getY() + offset.y(); int x_int = floor((x-tileXMin)/tileXInterval+0.5); if(x_int<0) x_int=0; else if(x_int>=field->getNumColumns()) x_int=field->getNumColumns()-1; int y_int = floor((y-tileYMin)/tileYInterval+0.5); if(y_int<0) y_int=0; else if(y_int>=field->getNumRows()) y_int=field->getNumRows()-1; double z = field->getHeight(x_int,y_int); std::cout << "int x: " << x_int << ", x: " << x-tileXMin << ", y: " << y_int << ", y: " << y-tileYMin << std::endl; //osg::Vec3 treePos(x,y,z); osg::Vec3 treePos(x,y,z); treeTrans->setPosition(treePos); int treeIt = (int)floor(mt()*(double)treeNodeVector.size()); treeTrans->addChild(treeNodeVector[treeIt].get()); treeTrans->setName("TreeTransform"); //} } } } } #endif #if 0 typedef gaalet::algebra< gaalet::signature<3,0> > em; typedef em::mv<1, 2, 4>::type Vector; typedef em::mv<3, 5, 6>::type Bivector; typedef em::mv<0, 3, 5, 6>::type Rotor; static const em::mv<0>::type one(1.0); static const em::mv<1>::type e1(1.0); static const em::mv<2>::type e2(1.0); static const em::mv<4>::type e3(1.0); static const em::mv<7>::type e123(1.0); osgTerrain::Layer* colorLayer = tile->getColorLayer(0); if(colorLayer) { osg::Image* inputImage = colorLayer->getImage(); /*static int tileLoadCounter = 0; osg::Image* outputImage = NULL; if(tileLoadCounter==0) { outputImage = new osg::Image(); outputImage->allocateImage(inputImage->s(), inputImage->t(), 1, 0x1907, 0x1401); } tileLoadCounter += 1;*/ em::mv<0,6>::type *fftwImag1 = (em::mv<0,6>::type*) fftw_malloc(sizeof(em::mv<0,6>::type)*inputImage->s()*inputImage->t()); em::mv<0,3>::type *fftwImag2 = (em::mv<0,3>::type*) fftw_malloc(sizeof(em::mv<0,3>::type)*inputImage->s()*inputImage->t()); em::mv<0,6>::type *fftwFreq1 = (em::mv<0,6>::type*) fftw_malloc(sizeof(em::mv<0,6>::type)*inputImage->s()*inputImage->t()); em::mv<0,3>::type *fftwFreq2 = (em::mv<0,3>::type*) fftw_malloc(sizeof(em::mv<0,3>::type)*inputImage->s()*inputImage->t()); fftw_plan fftwForward1 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwImag1), reinterpret_cast<fftw_complex*>(fftwFreq1), FFTW_FORWARD, FFTW_ESTIMATE); fftw_plan fftwForward2 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwImag2), reinterpret_cast<fftw_complex*>(fftwFreq2), FFTW_FORWARD, FFTW_ESTIMATE); fftw_plan fftwBackward1 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwFreq1), reinterpret_cast<fftw_complex*>(fftwImag1), FFTW_BACKWARD, FFTW_ESTIMATE); fftw_plan fftwBackward2 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwFreq2), reinterpret_cast<fftw_complex*>(fftwImag2), FFTW_BACKWARD, FFTW_ESTIMATE); for(int x=0; x<inputImage->s(); ++x) { for(int y=0; y<inputImage->t(); ++y) { if(inputImage->getPixelFormat()==0x83f0) { //COMPRESSED_RGB_S3TC_DXT1_EXT decompression unsigned int blocksize = 8; unsigned char* data = inputImage->data(); unsigned char* block = data + (blocksize*(unsigned int)(ceil(double(inputImage->s()/4.0)*floor(y/4.0) + floor(x/4.0)))); int rel_x = x % 4; int rel_y = y % 4; unsigned char& c0_lo = *(block+0); unsigned char& c0_hi = *(block+1); unsigned char& c1_lo = *(block+2); unsigned char& c1_hi = *(block+3); unsigned char& bits_0 = *(block+4); unsigned char& bits_1 = *(block+5); unsigned char& bits_2 = *(block+6); unsigned char& bits_3 = *(block+7); unsigned short color0 = c0_lo + c0_hi * 256; unsigned short color1 = c1_lo + c1_hi * 256; unsigned int bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * bits_3)); unsigned int code_bits_pos = 2*(4*rel_y+rel_x); unsigned int code = (bits>>code_bits_pos) & 0x03; unsigned char r0 = ((color0>>11) & 0x1f); unsigned char g0 = ((color0>>5) & 0x3f); unsigned char b0 = ((color0>>0) & 0x1f); unsigned char r1 = ((color1>>11) & 0x1f); unsigned char g1 = ((color1>>5) & 0x3f); unsigned char b1 = ((color1>>0) & 0x1f); unsigned char r = 0; unsigned char g = 0; unsigned char b = 0; if(color0>color1) { switch(code) { case 0: r = r0; g = g0; b = b0; break; case 1: r = r1; g = g1; b = b1; break; case 2: r = (2*r0+r1)/3; g = (2*g0+g1)/3; b = (2*b0+b1)/3; break; case 3: r = (r0+2*r1)/3; g = (g0+2*g1)/3; b = (b0+2*b1)/3; break; }; } else { switch(code) { case 0: r = r0; g = g0; b = b0; break; case 1: r = r1; g = g1; b = b1; break; case 2: r = (r0+r1)/2; g = (g0+g1)/2; b = (b0+b1)/2; break; case 3: r = 0; g = 0; b = 0; break; }; } (*(fftwImag1+inputImage->t()*x+y)) = (0.0*one)+((double)r*(double)0xff/(double)0x1f*e2*e3); (*(fftwImag2+inputImage->t()*x+y)) = ((double)g*(double)0xff/(double)0x3f*e3*e1)*e3*e1 + ((double)b*(double)0xff/(double)0x1f*e1*e2); /*if(outputImage) { *(outputImage->data(x,y)+0) = (unsigned int)((double)r*(double)0xff/(double)0x1f); *(outputImage->data(x,y)+1) = (unsigned int)((double)g*(double)0xff/(double)0x3f); *(outputImage->data(x,y)+2) = (unsigned int)((double)b*(double)0xff/(double)0x1f); }*/ } else { unsigned char& r = *(inputImage->data(x,y)+0); unsigned char& g = *(inputImage->data(x,y)+1); unsigned char& b = *(inputImage->data(x,y)+2); (*(fftwImag1+inputImage->t()*x+y)) = (0.0*one)+((double)r*e2*e3); (*(fftwImag2+inputImage->t()*x+y)) = ((double)g*e3*e1)*e3*e1 + ((double)b*e1*e2); //if(x==0 && y==0) std::cout << "(0,0): r: " << (int)r << ", g: " << (int)g << ", b: " << (int)b << std::endl; } } }
OGRErr PDFWritableVectorDataset::SyncToDisk() { if (nLayers == 0 || !bModified) return OGRERR_NONE; bModified = FALSE; OGREnvelope sGlobalExtent; int bHasExtent = FALSE; for(int i=0;i<nLayers;i++) { OGREnvelope sExtent; if (papoLayers[i]->GetExtent(&sExtent) == OGRERR_NONE) { bHasExtent = TRUE; sGlobalExtent.Merge(sExtent); } } if (!bHasExtent || sGlobalExtent.MinX == sGlobalExtent.MaxX || sGlobalExtent.MinY == sGlobalExtent.MaxY) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot compute spatial extent of features"); return OGRERR_FAILURE; } PDFCompressMethod eStreamCompressMethod = COMPRESS_DEFLATE; const char* pszStreamCompressMethod = CSLFetchNameValue(papszOptions, "STREAM_COMPRESS"); if (pszStreamCompressMethod) { if( EQUAL(pszStreamCompressMethod, "NONE") ) eStreamCompressMethod = COMPRESS_NONE; else if( EQUAL(pszStreamCompressMethod, "DEFLATE") ) eStreamCompressMethod = COMPRESS_DEFLATE; else { CPLError( CE_Warning, CPLE_NotSupported, "Unsupported value for STREAM_COMPRESS."); } } const char* pszGEO_ENCODING = CSLFetchNameValueDef(papszOptions, "GEO_ENCODING", "ISO32000"); double dfDPI = CPLAtof(CSLFetchNameValueDef(papszOptions, "DPI", "72")); if (dfDPI < 72.0) dfDPI = 72.0; const char* pszNEATLINE = CSLFetchNameValue(papszOptions, "NEATLINE"); int nMargin = atoi(CSLFetchNameValueDef(papszOptions, "MARGIN", "0")); PDFMargins sMargins; sMargins.nLeft = nMargin; sMargins.nRight = nMargin; sMargins.nTop = nMargin; sMargins.nBottom = nMargin; const char* pszLeftMargin = CSLFetchNameValue(papszOptions, "LEFT_MARGIN"); if (pszLeftMargin) sMargins.nLeft = atoi(pszLeftMargin); const char* pszRightMargin = CSLFetchNameValue(papszOptions, "RIGHT_MARGIN"); if (pszRightMargin) sMargins.nRight = atoi(pszRightMargin); const char* pszTopMargin = CSLFetchNameValue(papszOptions, "TOP_MARGIN"); if (pszTopMargin) sMargins.nTop = atoi(pszTopMargin); const char* pszBottomMargin = CSLFetchNameValue(papszOptions, "BOTTOM_MARGIN"); if (pszBottomMargin) sMargins.nBottom = atoi(pszBottomMargin); const char* pszExtraImages = CSLFetchNameValue(papszOptions, "EXTRA_IMAGES"); const char* pszExtraStream = CSLFetchNameValue(papszOptions, "EXTRA_STREAM"); const char* pszExtraLayerName = CSLFetchNameValue(papszOptions, "EXTRA_LAYER_NAME"); const char* pszOGRDisplayField = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_FIELD"); const char* pszOGRDisplayLayerNames = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_LAYER_NAMES"); int bWriteOGRAttributes = CSLFetchBoolean(papszOptions, "OGR_WRITE_ATTRIBUTES", TRUE); const char* pszOGRLinkField = CSLFetchNameValue(papszOptions, "OGR_LINK_FIELD"); const char* pszOffLayers = CSLFetchNameValue(papszOptions, "OFF_LAYERS"); const char* pszExclusiveLayers = CSLFetchNameValue(papszOptions, "EXCLUSIVE_LAYERS"); const char* pszJavascript = CSLFetchNameValue(papszOptions, "JAVASCRIPT"); const char* pszJavascriptFile = CSLFetchNameValue(papszOptions, "JAVASCRIPT_FILE"); /* -------------------------------------------------------------------- */ /* Create file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(GetDescription(), "wb"); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create PDF file %s.\n", GetDescription() ); return OGRERR_FAILURE; } GDALPDFWriter oWriter(fp); double dfRatio = (sGlobalExtent.MaxY - sGlobalExtent.MinY) / (sGlobalExtent.MaxX - sGlobalExtent.MinX); int nWidth, nHeight; if (dfRatio < 1) { nWidth = 1024; nHeight = nWidth * dfRatio; } else { nHeight = 1024; nWidth = nHeight / dfRatio; } GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, NULL ); double adfGeoTransform[6]; adfGeoTransform[0] = sGlobalExtent.MinX; adfGeoTransform[1] = (sGlobalExtent.MaxX - sGlobalExtent.MinX) / nWidth; adfGeoTransform[2] = 0; adfGeoTransform[3] = sGlobalExtent.MaxY; adfGeoTransform[4] = 0; adfGeoTransform[5] = - (sGlobalExtent.MaxY - sGlobalExtent.MinY) / nHeight; poSrcDS->SetGeoTransform(adfGeoTransform); OGRSpatialReference* poSRS = papoLayers[0]->GetSpatialRef(); if (poSRS) { char* pszWKT = NULL; poSRS->exportToWkt(&pszWKT); poSrcDS->SetProjection(pszWKT); CPLFree(pszWKT); } oWriter.SetInfo(poSrcDS, papszOptions); oWriter.StartPage(poSrcDS, dfDPI, pszGEO_ENCODING, pszNEATLINE, &sMargins, eStreamCompressMethod, bWriteOGRAttributes); int iObj = 0; char** papszLayerNames = CSLTokenizeString2(pszOGRDisplayLayerNames,",",0); for(int i=0;i<nLayers;i++) { CPLString osLayerName; if (CSLCount(papszLayerNames) < nLayers) osLayerName = papoLayers[i]->GetName(); else osLayerName = papszLayerNames[i]; oWriter.WriteOGRLayer((OGRDataSourceH)this, i, pszOGRDisplayField, pszOGRLinkField, osLayerName, bWriteOGRAttributes, iObj); } CSLDestroy(papszLayerNames); oWriter.EndPage(pszExtraImages, pszExtraStream, pszExtraLayerName, pszOffLayers, pszExclusiveLayers); if (pszJavascript) oWriter.WriteJavascript(pszJavascript); else if (pszJavascriptFile) oWriter.WriteJavascriptFile(pszJavascriptFile); oWriter.Close(); delete poSrcDS; return OGRERR_NONE; }
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] = atof(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] = atof(papszUL[2]); poDS->adfGeoTransform[1] = (atof(papszUR[2]) - atof(papszUL[2])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[2] = (atof(papszUR[3]) - atof(papszUL[3])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[3] = atof(papszUL[3]); poDS->adfGeoTransform[4] = (atof(papszLL[2]) - atof(papszUL[2])) / (poDS->nRasterYSize-1); poDS->adfGeoTransform[5] = (atof(papszLL[3]) - atof(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 ); }
/** * Captures Geolocation information from a COSMO-SKYMED * file. * The geoid will always be WGS84 * The projection type may be UTM or UPS, depending on the * latitude from the center of the image. * @param iProductType type of CSK subproduct, see HDF5CSKProduct */ void HDF5ImageDataset::CaptureCSKGeolocation(int iProductType) { // Set the ellipsoid to WGS84. oSRS.SetWellKnownGeogCS( "WGS84" ); if(iProductType == PROD_CSK_L1C||iProductType == PROD_CSK_L1D) { double *dfProjFalseEastNorth = NULL; double *dfProjScaleFactor = NULL; double *dfCenterCoord = NULL; // Check if all the metadata attributes are present. if(HDF5ReadDoubleAttr("Map Projection False East-North", &dfProjFalseEastNorth) == CE_Failure|| HDF5ReadDoubleAttr("Map Projection Scale Factor", &dfProjScaleFactor) == CE_Failure|| HDF5ReadDoubleAttr("Map Projection Centre", &dfCenterCoord) == CE_Failure|| GetMetadataItem("Projection_ID") == NULL) { pszProjection = CPLStrdup(""); pszGCPProjection = CPLStrdup(""); CPLError( CE_Failure, CPLE_OpenFailed, "The CSK hdf5 file geolocation information is " "malformed\n" ); } else { // Fetch projection Type. CPLString osProjectionID = GetMetadataItem("Projection_ID"); //If the projection is UTM if(EQUAL(osProjectionID,"UTM")) { // @TODO: use SetUTM oSRS.SetProjCS(SRS_PT_TRANSVERSE_MERCATOR); oSRS.SetTM(dfCenterCoord[0], dfCenterCoord[1], dfProjScaleFactor[0], dfProjFalseEastNorth[0], dfProjFalseEastNorth[1]); } else { //TODO Test! I didn't had any UPS projected files to test! //If the projection is UPS if(EQUAL(osProjectionID,"UPS")) { oSRS.SetProjCS(SRS_PT_POLAR_STEREOGRAPHIC); oSRS.SetPS(dfCenterCoord[0], dfCenterCoord[1], dfProjScaleFactor[0], dfProjFalseEastNorth[0], dfProjFalseEastNorth[1]); } } //Export Projection to Wkt. //In case of error then clean the projection if (oSRS.exportToWkt(&pszProjection) != OGRERR_NONE) pszProjection = CPLStrdup(""); CPLFree(dfCenterCoord); CPLFree(dfProjScaleFactor); CPLFree(dfProjFalseEastNorth); } } else { //Export GCPProjection to Wkt. //In case of error then clean the projection if(oSRS.exportToWkt(&pszGCPProjection) != OGRERR_NONE) pszGCPProjection = CPLStrdup(""); } }
GDALDataset *SDTSDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; /* -------------------------------------------------------------------- */ /* Before trying SDTSOpen() we first verify that the first */ /* record is in fact a SDTS file descriptor record. */ /* -------------------------------------------------------------------- */ char *pachLeader = (char *) poOpenInfo->pabyHeader; if( poOpenInfo->nHeaderBytes < 24 ) return NULL; if( pachLeader[5] != '1' && pachLeader[5] != '2' && pachLeader[5] != '3' ) return NULL; if( pachLeader[6] != 'L' ) return NULL; if( pachLeader[8] != '1' && pachLeader[8] != ' ' ) return NULL; /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ SDTSTransfer *poTransfer = new SDTSTransfer; if( !poTransfer->Open( poOpenInfo->pszFilename ) ) { delete poTransfer; return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poTransfer; CPLError( CE_Failure, CPLE_NotSupported, "The SDTS driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Find the first raster layer. If there are none, abort */ /* returning an error. */ /* -------------------------------------------------------------------- */ SDTSRasterReader *poRL = NULL; for( i = 0; i < poTransfer->GetLayerCount(); i++ ) { if( poTransfer->GetLayerType( i ) == SLTRaster ) { poRL = poTransfer->GetLayerRasterReader( i ); break; } } if( poRL == NULL ) { delete poTransfer; CPLError( CE_Warning, CPLE_AppDefined, "%s is an SDTS transfer, but has no raster cell layers.\n" "Perhaps it is a vector transfer?\n", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Initialize a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ SDTSDataset *poDS = new SDTSDataset(); poDS->poTransfer = poTransfer; poDS->poRL = poRL; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = poRL->GetXSize(); poDS->nRasterYSize = poRL->GetYSize(); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; poDS->papoBands = (GDALRasterBand **) VSICalloc(sizeof(GDALRasterBand *),poDS->nBands); for( i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new SDTSRasterBand( poDS, i+1, poRL ) ); /* -------------------------------------------------------------------- */ /* Try to establish the projection string. For now we only */ /* support UTM and GEO. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; SDTS_XREF *poXREF = poTransfer->GetXREF(); if( EQUAL(poXREF->pszSystemName,"UTM") ) { oSRS.SetUTM( poXREF->nZone ); } else if( EQUAL(poXREF->pszSystemName,"GEO") ) { /* we set datum later */ } else oSRS.SetLocalCS( poXREF->pszSystemName ); if( oSRS.IsLocal() ) /* don't try to set datum. */; else if( EQUAL(poXREF->pszDatum,"NAS") ) oSRS.SetWellKnownGeogCS( "NAD27" ); else if( EQUAL(poXREF->pszDatum, "NAX") ) oSRS.SetWellKnownGeogCS( "NAD83" ); else if( EQUAL(poXREF->pszDatum, "WGC") ) oSRS.SetWellKnownGeogCS( "WGS72" ); else if( EQUAL(poXREF->pszDatum, "WGE") ) oSRS.SetWellKnownGeogCS( "WGS84" ); else oSRS.SetWellKnownGeogCS( "WGS84" ); oSRS.Fixup(); poDS->pszProjection = NULL; if( oSRS.exportToWkt( &poDS->pszProjection ) != OGRERR_NONE ) poDS->pszProjection = CPLStrdup(""); /* -------------------------------------------------------------------- */ /* Get metadata from the IDEN file. */ /* -------------------------------------------------------------------- */ const char* pszIDENFilePath = poTransfer->GetCATD()->GetModuleFilePath("IDEN"); if (pszIDENFilePath) { DDFModule oIDENFile; if( oIDENFile.Open( pszIDENFilePath ) ) { DDFRecord* poRecord; while( (poRecord = oIDENFile.ReadRecord()) != NULL ) { if( poRecord->GetStringSubfield( "IDEN", 0, "MODN", 0 ) == NULL ) continue; static const char* fields[][2] = { { "TITL", "TITLE" }, { "DAID", "DATASET_ID" }, { "DAST", "DATA_STRUCTURE" }, { "MPDT", "MAP_DATE" }, { "DCDT", "DATASET_CREATION_DATE" } }; for (i = 0; i < (int)sizeof(fields) / (int)sizeof(fields[0]) ; i++) { const char* pszFieldValue = poRecord->GetStringSubfield( "IDEN", 0, fields[i][0], 0 ); if ( pszFieldValue ) poDS->SetMetadataItem(fields[i][1], pszFieldValue); } break; } } } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); return( poDS ); }
CPLErr HDF5ImageDataset::CreateProjections() { switch(iSubdatasetType) { case CSK_PRODUCT: { const char *osMissionLevel = NULL; int productType = PROD_UNKNOWN; if(GetMetadataItem("Product_Type")!=NULL) { //Get the format's level osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type"); if(STARTS_WITH_CI(osMissionLevel, "RAW")) productType = PROD_CSK_L0; if(STARTS_WITH_CI(osMissionLevel, "SSC")) productType = PROD_CSK_L1A; if(STARTS_WITH_CI(osMissionLevel, "DGM")) productType = PROD_CSK_L1B; if(STARTS_WITH_CI(osMissionLevel, "GEC")) productType = PROD_CSK_L1C; if(STARTS_WITH_CI(osMissionLevel, "GTC")) productType = PROD_CSK_L1D; } CaptureCSKGeoTransform(productType); CaptureCSKGeolocation(productType); CaptureCSKGCPs(productType); break; } case UNKNOWN_PRODUCT: { static const int NBGCPLAT = 100; static const int NBGCPLON = 30; const int nDeltaLat = nRasterYSize / NBGCPLAT; const int nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { if( GetMetadataItem("where_projdef") != NULL ) return CreateODIMH5Projection(); return CE_None; } /* -------------------------------------------------------------------- */ /* The Latitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ const hid_t LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); // LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); const hid_t LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); // LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { float * const Latitude = static_cast<float *>( CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) ); float * const Longitude = static_cast<float *>( CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon; pasGCPList = static_cast<GDAL_GCP *>( CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; const int nYLimit = (static_cast<int>(nRasterYSize)/nDeltaLat) * nDeltaLat; const int nXLimit = (static_cast<int>(nRasterXSize)/nDeltaLon) * nDeltaLon; for( int j = 0; j < nYLimit; j+=nDeltaLat ) { for( int i = 0; i < nXLimit; i+=nDeltaLon ) { const int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = static_cast<double>(Longitude[iGCP])+180.0; pasGCPList[k].dfGCPY = static_cast<double>(Latitude[iGCP]); pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } if( LatitudeDatasetID > 0 ) H5Dclose(LatitudeDatasetID); if( LongitudeDatasetID > 0 ) H5Dclose(LongitudeDatasetID); break; } } return CE_None; }
GDALDataset *BTDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Verify that this is some form of binterr file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 256) return NULL; if( strncmp( (const char *) poOpenInfo->pabyHeader, "binterr", 7 ) != 0 ) return NULL; /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ BTDataset *poDS; 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 = (int) (atof(szVersion) * 10); /* -------------------------------------------------------------------- */ /* Extract core header information, being careful about the */ /* version. */ /* -------------------------------------------------------------------- */ GInt32 nIntTemp; GInt16 nDataSize; GDALDataType eType; 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; } memcpy( &nDataSize, poDS->abyHeader+18, 2 ); nDataSize = CPL_LSBWORD16( nDataSize ); 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; fp = VSIFOpenL( pszPrjFile, "rt" ); if( fp != NULL ) { char *pszBuffer, *pszBufPtr; int nBufMax = 10000; int nBytes; pszBuffer = (char *) CPLMalloc(nBufMax); nBytes = VSIFReadL( pszBuffer, 1, nBufMax-1, fp ); VSIFCloseL( fp ); pszBuffer[nBytes] = '\0'; 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, nDatum, nHUnits; memcpy( &nUTMZone, poDS->abyHeader + 24, 2 ); nUTMZone = CPL_LSBWORD16( nUTMZone ); memcpy( &nDatum, poDS->abyHeader + 26, 2 ); nDatum = CPL_LSBWORD16( nDatum ); memcpy( &nHUnits, poDS->abyHeader + 22, 2 ); nHUnits = CPL_LSBWORD16( nHUnits ); if( nUTMZone != 0 ) oSRS.SetUTM( ABS(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, atof(SRS_UL_FOOT_CONV) ); else if( nHUnits == 3 ) oSRS.SetLinearUnits( SRS_UL_US_FOOT, atof(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]; sprintf( 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, dfRight, dfTop, dfBottom; memcpy( &dfLeft, poDS->abyHeader + 28, 8 ); CPL_LSBPTR64( &dfLeft ); memcpy( &dfRight, poDS->abyHeader + 36, 8 ); CPL_LSBPTR64( &dfRight ); memcpy( &dfBottom, poDS->abyHeader + 44, 8 ); CPL_LSBPTR64( &dfBottom ); 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 ); 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 *ISIS3Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE dataset? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS3Dataset *poDS; poDS = new ISIS3Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* Assume user is pointing to label (ie .lbl) file for detached option */ /* -------------------------------------------------------------------- */ // Image can be inline or detached and point to an image name // the Format can be Tiled or Raw // Object = Core // StartByte = 65537 // Format = Tile // TileSamples = 128 // TileLines = 128 //OR----- // Object = Core // StartByte = 1 // ^Core = r0200357_detatched.cub // Format = BandSequential //OR----- // Object = Core // StartByte = 1 // ^Core = r0200357_detached_tiled.cub // Format = Tile // TileSamples = 128 // TileLines = 128 /* -------------------------------------------------------------------- */ /* What file contains the actual data? */ /* -------------------------------------------------------------------- */ const char *pszCore = poDS->GetKeyword( "IsisCube.Core.^Core" ); CPLString osQubeFile; if( EQUAL(pszCore,"") ) osQubeFile = poOpenInfo->pszFilename; else { CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); osQubeFile = CPLFormFilename( osPath, pszCore, NULL ); poDS->osExternalCube = osQubeFile; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS3 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; int nRows = -1; int nCols = -1; int nBands = 1; int nSkipBytes = 0; int tileSizeX = 0; int tileSizeY = 0; double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double scaleFactor = 1.0; double dfNoData = 0.0; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB char szLayout[32] = "BandSequential"; //default to band seq. const char *target_name; //planet name //projection parameters const char *map_proj_name; int bProjectionSet = TRUE; char proj_target_name[200]; char geog_name[60]; char datum_name[60]; char sphere_name[60]; char bIsGeographic = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; double center_lat = 0.0; double center_lon = 0.0; double first_std_parallel = 0.0; double second_std_parallel = 0.0; double radLat, localRadius; VSILFILE *fp; /************* Skipbytes *****************************/ nSkipBytes = atoi(poDS->GetKeyword("IsisCube.Core.StartByte","")) - 1; /******* Grab format type (BandSequential, Tiled) *******/ const char *value; value = poDS->GetKeyword( "IsisCube.Core.Format", "" ); if (EQUAL(value,"Tile") ) { //Todo strcpy(szLayout,"Tiled"); /******* Get Tile Sizes *********/ tileSizeX = atoi(poDS->GetKeyword("IsisCube.Core.TileSamples","")); tileSizeY = atoi(poDS->GetKeyword("IsisCube.Core.TileLines","")); if (tileSizeX <= 0 || tileSizeY <= 0) { CPLError( CE_Failure, CPLE_OpenFailed, "Wrong tile dimensions : %d x %d", tileSizeX, tileSizeY); delete poDS; return NULL; } } else if (EQUAL(value,"BandSequential") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return NULL; } /*********** Grab samples lines band ************/ nCols = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Samples","")); nRows = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Lines","")); nBands = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Bands","")); /****** Grab format type - ISIS3 only supports 8,U16,S16,32 *****/ const char *itype; itype = poDS->GetKeyword( "IsisCube.Core.Pixels.Type" ); if (EQUAL(itype,"UnsignedByte") ) { eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; } else if (EQUAL(itype,"UnsignedWord") ) { eDataType = GDT_UInt16; dfNoData = NULL1; bNoDataSet = TRUE; } else if (EQUAL(itype,"SignedWord") ) { eDataType = GDT_Int16; dfNoData = NULL2; bNoDataSet = TRUE; } else if (EQUAL(itype,"Real") || EQUAL(value,"") ) { eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; } else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout type not supported. Abort\n\n", itype); delete poDS; return NULL; } /*********** Grab samples lines band ************/ value = poDS->GetKeyword( "IsisCube.Core.Pixels.ByteOrder"); if (EQUAL(value,"Lsb")) chByteOrder = 'I'; /*********** Grab Cellsize ************/ value = poDS->GetKeyword("IsisCube.Mapping.PixelResolution"); if (strlen(value) > 0 ) { dfXDim = CPLAtof(value); /* values are in meters */ dfYDim = -CPLAtof(value); } /*********** Grab UpperLeftCornerY ************/ value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerY"); if (strlen(value) > 0) { dfULYMap = CPLAtof(value); } /*********** Grab UpperLeftCornerX ************/ value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerX"); if( strlen(value) > 0 ) { dfULXMap = CPLAtof(value); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. Mars ***/ target_name = poDS->GetKeyword("IsisCube.Mapping.TargetName"); /*********** Grab MAP_PROJECTION_TYPE ************/ map_proj_name = poDS->GetKeyword( "IsisCube.Mapping.ProjectionName"); /*********** Grab SEMI-MAJOR ************/ semi_major = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.EquatorialRadius")); /*********** Grab semi-minor ************/ semi_minor = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.PolarRadius")); /*********** Grab CENTER_LAT ************/ center_lat = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.CenterLatitude")); /*********** Grab CENTER_LON ************/ center_lon = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.CenterLongitude")); /*********** Grab 1st std parallel ************/ first_std_parallel = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.FirstStandardParallel")); /*********** Grab 2nd std parallel ************/ second_std_parallel = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.SecondStandardParallel")); /*********** Grab scaleFactor ************/ scaleFactor = CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.scaleFactor", "1.0")); /*** grab LatitudeType = Planetographic ****/ // Need to further study how ocentric/ographic will effect the gdal library // So far we will use this fact to define a sphere or ellipse for some // projections // Frank - may need to talk this over value = poDS->GetKeyword("IsisCube.Mapping.LatitudeType"); if (EQUAL( value, "Planetocentric" )) bIsGeographic = FALSE; //Set oSRS projection and parameters //############################################################ //ISIS3 Projection types // Equirectangular // LambertConformal // Mercator // ObliqueCylindrical //Todo // Orthographic // PolarStereographic // SimpleCylindrical // Sinusoidal // TransverseMercator #ifdef DEBUG CPLDebug( "ISIS3", "using projection %s", map_proj_name); #endif if ((EQUAL( map_proj_name, "Equirectangular" )) || (EQUAL( map_proj_name, "SimpleCylindrical" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "Orthographic" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "Sinusoidal" )) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "Mercator" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "PolarStereographic" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "TransverseMercator" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "LambertConformal" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else { CPLDebug( "ISIS3", "Dataset projection %s is not supported. Continuing...", map_proj_name ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword strcpy(proj_target_name, map_proj_name); strcat(proj_target_name, " "); strcat(proj_target_name, target_name); oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System strcpy(geog_name, "GCS_"); strcat(geog_name, target_name); //The datum name will be the same basic name as the planet strcpy(datum_name, "D_"); strcat(datum_name, target_name); strcpy(sphere_name, target_name); //strcat(sphere_name, "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "Stereographic" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "PolarStereographic" )) ) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... strcat(sphere_name, "_polarRadius"); oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SimpleCylindrical" )) || (EQUAL( map_proj_name, "Orthographic" )) || (EQUAL( map_proj_name, "Stereographic" )) || (EQUAL( map_proj_name, "Sinusoidal" )) ) { //isis uses the sphereical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if (EQUAL( map_proj_name, "Equirectangular" )) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); radLat = center_lat * PI / 180; // in radians localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); strcat(sphere_name, "_localRadius"); oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS3 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Is the CUB detached - if so, reset name to binary file? */ /* -------------------------------------------------------------------- */ #ifdef notdef // Frank - is this correct? //The extension already added on so don't add another. But is this needed? char *pszPath = CPLStrdup( CPLGetPath( poOpenInfo->pszFilename ) ); char *pszName = CPLStrdup( CPLGetBasename( poOpenInfo->pszFilename ) ); if (bIsDetached) pszCUBFilename = CPLFormCIFilename( pszPath, detachedCub, "" ); #endif /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osQubeFile, "r" ); else poDS->fpImage = VSIFOpenL( osQubeFile, "r+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osQubeFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset=0, nPixelOffset=0, nBandOffset=0; if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* Tiled */ { } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; #ifdef CPL_LSB int bNativeOrder = !(chByteOrder == 'M'); #else int bNativeOrder = (chByteOrder == 'M'); #endif for( i = 0; i < nBands; i++ ) { GDALRasterBand *poBand; if( EQUAL(szLayout,"Tiled") ) { poBand = new ISISTiledBand( poDS, poDS->fpImage, i+1, eDataType, tileSizeX, tileSizeY, nSkipBytes, 0, 0, bNativeOrder ); } else { poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); } poDS->SetBand( i+1, poBand ); if( bNoDataSet ) ((GDALPamRasterBand *) poBand)->SetNoDataValue( dfNoData ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Base","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Multiplier","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For ISIS3 I would like to keep this in */ /* -------------------------------------------------------------------- */ CPLString osPath, osName; osPath = CPLGetPath( poOpenInfo->pszFilename ); osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFile, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFile ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
int main( int argc, char ** argv ) { int i; int bGotSRS = FALSE; int bPretty = FALSE; int bOutputAll = FALSE; int bValidate = FALSE; const char *pszInput = NULL; const char *pszOutputType = "all"; char *pszOutput = NULL; OGRSpatialReference oSRS; VSILFILE *fp = NULL; GDALDataset *poGDALDS = NULL; OGRDataSource *poOGRDS = NULL; OGRLayer *poLayer = NULL; char *pszProjection = NULL; int bDebug = FALSE; CPLErrorHandler oErrorHandler = NULL; int bIsFile = FALSE; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") ) { CPLSetConfigOption( argv[i+1], argv[i+2] ); i += 2; } } argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { CPLDebug( "gdalsrsinfo", "got arg #%d : [%s]", i, argv[i] ); if( EQUAL(argv[i], "--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( EQUAL(argv[i], "-h") ) Usage(); else if( EQUAL(argv[i], "-o") && i < argc - 1) pszOutputType = argv[++i]; else if( EQUAL(argv[i], "-p") ) bPretty = TRUE; else if( EQUAL(argv[i], "-V") ) bValidate = TRUE; else if( argv[i][0] == '-' ) { CSLDestroy( argv ); Usage(); } else pszInput = argv[i]; } if ( pszInput == NULL ) { CSLDestroy( argv ); Usage(); } /* Register drivers */ GDALAllRegister(); OGRRegisterAll(); /* Search for SRS */ /* temporarily supress error messages we may get from xOpen() */ bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF")); if ( ! bDebug ) oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler ); /* If argument is a file, try to open it with GDALOpen() and get the projection */ fp = VSIFOpenL( pszInput, "r" ); if ( fp ) { bIsFile = TRUE; VSIFCloseL( fp ); /* try to open with GDAL */ CPLDebug( "gdalsrsinfo", "trying to open with GDAL" ); poGDALDS = (GDALDataset *) GDALOpen( pszInput, GA_ReadOnly ); if ( poGDALDS != NULL && poGDALDS->GetProjectionRef( ) != NULL ) { pszProjection = (char *) poGDALDS->GetProjectionRef( ); if( oSRS.importFromWkt( &pszProjection ) == CE_None ) { CPLDebug( "gdalsrsinfo", "got SRS from GDAL" ); bGotSRS = TRUE; } GDALClose( (GDALDatasetH) poGDALDS ); } if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with GDAL" ); /* if unsuccessful, try to open with OGR */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to open with OGR" ); poOGRDS = OGRSFDriverRegistrar::Open( pszInput, FALSE, NULL ); if( poOGRDS != NULL ) { poLayer = poOGRDS->GetLayer( 0 ); if ( poLayer != NULL ) { OGRSpatialReference *poSRS = poLayer->GetSpatialRef( ); if ( poSRS != NULL ) { CPLDebug( "gdalsrsinfo", "got SRS from OGR" ); bGotSRS = TRUE; OGRSpatialReference* poSRSClone = poSRS->Clone(); oSRS = *poSRSClone; OGRSpatialReference::DestroySpatialReference( poSRSClone ); } } OGRDataSource::DestroyDataSource( poOGRDS ); poOGRDS = NULL; } if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with OGR" ); /* OGR_DS_Destroy( hOGRDS ); */ } } /* If didn't get the projection from the file, try OSRSetFromUserInput() */ /* File might not be a dataset, but contain projection info (e.g. .prf files) */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from user input [%s]", pszInput ); if( oSRS.SetFromUserInput( pszInput ) != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from user input" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from user input" ); bGotSRS = TRUE; } } /* restore error messages */ if ( ! bDebug ) CPLSetErrorHandler ( oErrorHandler ); CPLDebug( "gdalsrsinfo", "bGotSRS: %d bValidate: %d pszOutputType: %s bPretty: %d", bGotSRS, bValidate, pszOutputType, bPretty ); /* Make sure we got a SRS */ if ( ! bGotSRS ) { CPLError( CE_Failure, CPLE_AppDefined, "ERROR - failed to load SRS definition from %s", pszInput ); } else { /* Validate - not well tested!*/ if ( bValidate ) { OGRErr eErr = oSRS.Validate( ); if ( eErr != OGRERR_NONE ) { printf( "\nValidate Fails" ); if ( eErr == OGRERR_CORRUPT_DATA ) printf( " - SRS is not well formed"); else if ( eErr == OGRERR_UNSUPPORTED_SRS ) printf(" - contains non-standard PROJECTION[] values"); printf("\n"); } else printf( "\nValidate Succeeds\n" ); } /* Output */ if ( EQUAL("all", pszOutputType ) ) { bOutputAll = TRUE; bPretty = TRUE; } printf("\n"); if ( bOutputAll || EQUAL("proj4", pszOutputType ) ) { if ( bOutputAll ) printf("PROJ.4 : "); oSRS.exportToProj4( &pszOutput ); printf("\'%s\'\n\n",pszOutput); CPLFree( pszOutput ); } if ( bOutputAll || EQUAL("wkt", pszOutputType ) ) { if ( bOutputAll ) printf("OGC WKT :\n"); if ( bPretty ) oSRS.exportToPrettyWkt( &pszOutput, FALSE ); else oSRS.exportToWkt( &pszOutput ); printf("%s\n\n",pszOutput); CPLFree( pszOutput ); } if ( bOutputAll || EQUAL("wkt_simple", pszOutputType ) ) { if ( bOutputAll ) printf("OGC WKT (simple) :\n"); oSRS.exportToPrettyWkt( &pszOutput, TRUE ); printf("%s\n\n",pszOutput); CPLFree( pszOutput ); } if ( EQUAL("wkt_old", pszOutputType ) ) { if ( bOutputAll ) printf("OGC WKT (old) :\n"); oSRS.StripCTParms( ); if ( bPretty ) oSRS.exportToPrettyWkt( &pszOutput, FALSE ); else oSRS.exportToWkt( &pszOutput ); printf("%s\n\n",pszOutput); CPLFree( pszOutput ); } if ( bOutputAll || EQUAL("wkt_esri", pszOutputType ) ) { if ( bOutputAll ) printf("ESRI WKT :\n"); OGRSpatialReference *poSRS = oSRS.Clone(); poSRS->morphToESRI( ); if ( bPretty ) poSRS->exportToPrettyWkt( &pszOutput, FALSE ); else poSRS->exportToWkt( &pszOutput ); printf("%s\n\n",pszOutput); CPLFree( pszOutput ); OGRSpatialReference::DestroySpatialReference( poSRS ); } /* mapinfo and xml are not output with "all" */ if ( EQUAL("mapinfo", pszOutputType ) ) { if ( bOutputAll ) printf("MAPINFO : "); oSRS.exportToMICoordSys( &pszOutput ); printf("\'%s\'\n\n",pszOutput); CPLFree( pszOutput ); } if ( EQUAL("xml", pszOutputType ) ) { if ( bOutputAll ) printf("XML :\n"); oSRS.exportToXML( &pszOutput, NULL ); printf("%s\n\n",pszOutput); CPLFree( pszOutput ); } } /* cleanup anything left */ GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy( argv ); return 0; }
OGRLayer* OGRVRTDataSource::InstanciateUnionLayer( CPLXMLNode *psLTree, const char *pszVRTDirectory, int bUpdate, int nRecLevel) { CPLXMLNode *psSubNode; if( !EQUAL(psLTree->pszValue,"OGRVRTUnionLayer") ) return NULL; /* -------------------------------------------------------------------- */ /* Get layer name. */ /* -------------------------------------------------------------------- */ const char *pszLayerName = CPLGetXMLValue( psLTree, "name", NULL ); if( pszLayerName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing name attribute on OGRVRTUnionLayer" ); return FALSE; } /* -------------------------------------------------------------------- */ /* Do we have a fixed geometry type? If not derive from the */ /* source layer. */ /* -------------------------------------------------------------------- */ const char* pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL ); int bGlobalGeomTypeSet = FALSE; OGRwkbGeometryType eGlobalGeomType = wkbUnknown; if( pszGType != NULL ) { int bError; bGlobalGeomTypeSet = TRUE; eGlobalGeomType = OGRVRTGetGeometryType(pszGType, &bError); if( bError ) { CPLError( CE_Failure, CPLE_AppDefined, "GeometryType %s not recognised.", pszGType ); return NULL; } } /* -------------------------------------------------------------------- */ /* Apply a spatial reference system if provided */ /* -------------------------------------------------------------------- */ const char* pszLayerSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL ); OGRSpatialReference* poGlobalSRS = NULL; int bGlobalSRSSet = FALSE; if( pszLayerSRS != NULL ) { bGlobalSRSSet = TRUE; if( !EQUAL(pszLayerSRS,"NULL") ) { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszLayerSRS ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import LayerSRS `%s'.", pszLayerSRS ); return FALSE; } poGlobalSRS = oSRS.Clone(); } } /* -------------------------------------------------------------------- */ /* Find field declarations. */ /* -------------------------------------------------------------------- */ OGRFieldDefn** papoFields = NULL; int nFields = 0; OGRUnionLayerGeomFieldDefn** papoGeomFields = NULL; int nGeomFields = 0; for( psSubNode=psLTree->psChild; psSubNode != NULL; psSubNode=psSubNode->psNext ) { if( psSubNode->eType != CXT_Element ) continue; if( psSubNode->eType == CXT_Element && EQUAL(psSubNode->pszValue,"Field") ) { /* -------------------------------------------------------------------- */ /* Field name. */ /* -------------------------------------------------------------------- */ const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL ); if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify Field name." ); break; } OGRFieldDefn oFieldDefn( pszName, OFTString ); /* -------------------------------------------------------------------- */ /* Type */ /* -------------------------------------------------------------------- */ const char *pszArg = CPLGetXMLValue( psSubNode, "type", NULL ); if( pszArg != NULL ) { int iType; for( iType = 0; iType <= (int) OFTMaxType; iType++ ) { if( EQUAL(pszArg,OGRFieldDefn::GetFieldTypeName( (OGRFieldType)iType)) ) { oFieldDefn.SetType( (OGRFieldType) iType ); break; } } if( iType > (int) OFTMaxType ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify Field type '%s'.", pszArg ); break; } } /* -------------------------------------------------------------------- */ /* Width and precision. */ /* -------------------------------------------------------------------- */ int nWidth = atoi(CPLGetXMLValue( psSubNode, "width", "0" )); if (nWidth < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "Invalid width for field %s.", pszName ); break; } oFieldDefn.SetWidth(nWidth); int nPrecision = atoi(CPLGetXMLValue( psSubNode, "precision", "0" )); if (nPrecision < 0 || nPrecision > 1024) { CPLError( CE_Failure, CPLE_IllegalArg, "Invalid precision for field %s.", pszName ); break; } oFieldDefn.SetPrecision(nPrecision); papoFields = (OGRFieldDefn**) CPLRealloc(papoFields, sizeof(OGRFieldDefn*) * (nFields + 1)); papoFields[nFields] = new OGRFieldDefn(&oFieldDefn); nFields ++; } else if( psSubNode->eType == CXT_Element && EQUAL(psSubNode->pszValue,"GeometryField") ) { const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL ); if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify GeometryField name." ); break; } pszGType = CPLGetXMLValue( psSubNode, "GeometryType", NULL ); if( pszGType == NULL && nGeomFields == 0 ) pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL ); OGRwkbGeometryType eGeomType = wkbUnknown; int bGeomTypeSet = FALSE; if( pszGType != NULL ) { int bError; eGeomType = OGRVRTGetGeometryType(pszGType, &bError); bGeomTypeSet = TRUE; if( bError || eGeomType == wkbNone ) { CPLError( CE_Failure, CPLE_AppDefined, "GeometryType %s not recognised.", pszGType ); break; } } const char* pszSRS = CPLGetXMLValue( psSubNode, "SRS", NULL ); if( pszSRS == NULL && nGeomFields == 0 ) pszSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL ); OGRSpatialReference* poSRS = NULL; int bSRSSet = FALSE; if( pszSRS != NULL ) { bSRSSet = TRUE; if( !EQUAL(pszSRS,"NULL") ) { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszSRS ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import SRS `%s'.", pszSRS ); break; } poSRS = oSRS.Clone(); } } OGRUnionLayerGeomFieldDefn* poFieldDefn = new OGRUnionLayerGeomFieldDefn(pszName, eGeomType); if( poSRS != NULL ) { poFieldDefn->SetSpatialRef(poSRS); poSRS->Dereference(); } poFieldDefn->bGeomTypeSet = bGeomTypeSet; poFieldDefn->bSRSSet = bSRSSet; const char* pszExtentXMin = CPLGetXMLValue( psSubNode, "ExtentXMin", NULL ); const char* pszExtentYMin = CPLGetXMLValue( psSubNode, "ExtentYMin", NULL ); const char* pszExtentXMax = CPLGetXMLValue( psSubNode, "ExtentXMax", NULL ); const char* pszExtentYMax = CPLGetXMLValue( psSubNode, "ExtentYMax", NULL ); if( pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL ) { poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin); poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin); poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax); poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax); } papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields, sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1)); papoGeomFields[nGeomFields] = poFieldDefn; nGeomFields ++; } } /* -------------------------------------------------------------------- */ /* 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( eGlobalGeomType != wkbNone && nGeomFields == 0 && (bGlobalGeomTypeSet || bGlobalSRSSet || (pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL)) ) { OGRUnionLayerGeomFieldDefn* poFieldDefn = new OGRUnionLayerGeomFieldDefn("", eGlobalGeomType); if( poGlobalSRS != NULL ) { poFieldDefn->SetSpatialRef(poGlobalSRS); poGlobalSRS->Dereference(); poGlobalSRS = NULL; } poFieldDefn->bGeomTypeSet = bGlobalGeomTypeSet; poFieldDefn->bSRSSet = bGlobalSRSSet; if( pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL ) { poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin); poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin); poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax); poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax); } papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields, sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1)); papoGeomFields[nGeomFields] = poFieldDefn; nGeomFields ++; } else { delete poGlobalSRS; poGlobalSRS = NULL; } /* -------------------------------------------------------------------- */ /* Find source layers */ /* -------------------------------------------------------------------- */ int nSrcLayers = 0; OGRLayer** papoSrcLayers = NULL; for( psSubNode=psLTree->psChild; psSubNode != NULL; psSubNode=psSubNode->psNext ) { if( psSubNode->eType != CXT_Element ) continue; OGRLayer* poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory, bUpdate, nRecLevel + 1); if( poSrcLayer != NULL ) { papoSrcLayers = (OGRLayer**) CPLRealloc(papoSrcLayers, sizeof(OGRLayer*) * (nSrcLayers + 1)); papoSrcLayers[nSrcLayers] = poSrcLayer; nSrcLayers ++; } } if( nSrcLayers == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot find source layers" ); int iField; for(iField = 0; iField < nFields; iField++) delete papoFields[iField]; CPLFree(papoFields); for(iField = 0; iField < nGeomFields; iField++) delete papoGeomFields[iField]; CPLFree(papoGeomFields); return NULL; } /* -------------------------------------------------------------------- */ /* Build the OGRUnionLayer. */ /* -------------------------------------------------------------------- */ OGRUnionLayer* poLayer = new OGRUnionLayer( pszLayerName, nSrcLayers, papoSrcLayers, TRUE ); /* -------------------------------------------------------------------- */ /* Set the source layer field name attribute. */ /* -------------------------------------------------------------------- */ const char* pszSourceLayerFieldName = CPLGetXMLValue( psLTree, "SourceLayerFieldName", NULL ); poLayer->SetSourceLayerFieldName(pszSourceLayerFieldName); /* -------------------------------------------------------------------- */ /* Set the PreserveSrcFID attribute. */ /* -------------------------------------------------------------------- */ int bPreserveSrcFID = FALSE; const char* pszPreserveFID = CPLGetXMLValue( psLTree, "PreserveSrcFID", NULL ); if( pszPreserveFID != NULL ) bPreserveSrcFID = CSLTestBoolean(pszPreserveFID); poLayer->SetPreserveSrcFID(bPreserveSrcFID); /* -------------------------------------------------------------------- */ /* Set fields */ /* -------------------------------------------------------------------- */ FieldUnionStrategy eFieldStrategy = FIELD_UNION_ALL_LAYERS; const char* pszFieldStrategy = CPLGetXMLValue( psLTree, "FieldStrategy", NULL ); if( pszFieldStrategy != NULL ) { if( EQUAL(pszFieldStrategy, "FirstLayer") ) eFieldStrategy = FIELD_FROM_FIRST_LAYER; else if( EQUAL(pszFieldStrategy, "Union") ) eFieldStrategy = FIELD_UNION_ALL_LAYERS; else if( EQUAL(pszFieldStrategy, "Intersection") ) eFieldStrategy = FIELD_INTERSECTION_ALL_LAYERS; else { CPLError( CE_Warning, CPLE_AppDefined, "Unhandled value for FieldStrategy `%s'.", pszFieldStrategy ); } } if( nFields != 0 || nGeomFields > 1 ) { if( pszFieldStrategy != NULL ) CPLError( CE_Warning, CPLE_AppDefined, "Ignoring FieldStrategy value, because explicit Field or GeometryField is provided") ; eFieldStrategy = FIELD_SPECIFIED; } poLayer->SetFields(eFieldStrategy, nFields, papoFields, (nGeomFields == 0 && eGlobalGeomType == wkbNone) ? -1 : nGeomFields, papoGeomFields); int iField; for(iField = 0; iField < nFields; iField++) delete papoFields[iField]; CPLFree(papoFields); for(iField = 0; iField < nGeomFields; iField++) delete papoGeomFields[iField]; CPLFree(papoGeomFields); /* -------------------------------------------------------------------- */ /* Set FeatureCount if provided */ /* -------------------------------------------------------------------- */ const char* pszFeatureCount = CPLGetXMLValue( psLTree, "FeatureCount", NULL ); if( pszFeatureCount != NULL ) { poLayer->SetFeatureCount(atoi(pszFeatureCount)); } return poLayer; }
GDALDataset *ROIPACDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Confirm that the header is compatible with a ROIPAC dataset. */ /* -------------------------------------------------------------------- */ if ( !Identify(poOpenInfo) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Open the .rsc file */ /* -------------------------------------------------------------------- */ CPLString osRscFilename = getRscFilename( poOpenInfo ); if ( osRscFilename.empty() ) { return NULL; } VSILFILE *fpRsc; if ( poOpenInfo->eAccess == GA_Update ) { fpRsc = VSIFOpenL( osRscFilename, "r+" ); } else { fpRsc = VSIFOpenL( osRscFilename, "r" ); } if ( fpRsc == NULL ) { return NULL; } /* -------------------------------------------------------------------- */ /* Load the .rsc information. */ /* -------------------------------------------------------------------- */ char **papszRsc = NULL; while ( true ) { const char *pszLine; char **papszTokens; pszLine = CPLReadLineL( fpRsc ); if (pszLine == NULL) { break; } papszTokens = CSLTokenizeString2( pszLine, " \t", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES ); if ( papszTokens == NULL || papszTokens[0] == NULL || papszTokens[1] == NULL ) { CSLDestroy ( papszTokens ); break; } papszRsc = CSLSetNameValue( papszRsc, papszTokens[0], papszTokens[1] ); CSLDestroy ( papszTokens ); } /* -------------------------------------------------------------------- */ /* Fetch required fields. */ /* -------------------------------------------------------------------- */ int nWidth = 0, nFileLength = 0; if ( CSLFetchNameValue( papszRsc, "WIDTH" ) == NULL || CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) == NULL ) { CSLDestroy( papszRsc ); VSIFCloseL( fpRsc ); return NULL; } nWidth = atoi( CSLFetchNameValue( papszRsc, "WIDTH" ) ); nFileLength = atoi( CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ ROIPACDataset *poDS; poDS = new ROIPACDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nFileLength; poDS->eAccess = poOpenInfo->eAccess; poDS->fpRsc = fpRsc; poDS->pszRscFilename = CPLStrdup( osRscFilename.c_str() ); /* -------------------------------------------------------------------- */ /* Reopen file in update mode if necessary. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); } else { poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); } if( poDS->fpImage == NULL ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to re-open %s within ROI_PAC driver.\n", poOpenInfo->pszFilename ); CSLDestroy( papszRsc ); return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType; int nBands; enum Interleave { LINE, PIXEL } eInterleave; const char *pszExtension = CPLGetExtension(poOpenInfo->pszFilename); if ( strcmp( pszExtension, "raw" ) == 0 ) { /* ------------------------------------------------------------ */ /* TODO: ROI_PAC raw images are what would be GDT_CInt8 typed, */ /* but since that type do not exist, we will have to implement */ /* a specific case in the RasterBand to convert it to */ /* GDT_CInt16 for example */ /* ------------------------------------------------------------ */ #if 0 eDataType = GDT_CInt8; nBands = 1; eInterleave = PIXEL; #else CPLError( CE_Failure, CPLE_NotSupported, "Reading ROI_PAC raw files is not supported yet." ); delete poDS; CSLDestroy( papszRsc ); return NULL; #endif } else if ( strcmp( pszExtension, "int" ) == 0 || strcmp( pszExtension, "slc" ) == 0 ) { eDataType = GDT_CFloat32; nBands = 1; eInterleave = PIXEL; } else if ( strcmp( pszExtension, "amp" ) == 0 ) { eDataType = GDT_Float32; nBands = 2; eInterleave = PIXEL; } else if ( strcmp( pszExtension, "cor" ) == 0 || strcmp( pszExtension, "hgt" ) == 0 || strcmp( pszExtension, "unw" ) == 0 || strcmp( pszExtension, "msk" ) == 0 || strcmp( pszExtension, "trans" ) == 0 ) { eDataType = GDT_Float32; nBands = 2; eInterleave = LINE; } else if ( strcmp( pszExtension, "dem" ) == 0 ) { eDataType = GDT_Int16; nBands = 1; eInterleave = PIXEL; } else { /* Eeek */ delete poDS; CSLDestroy( papszRsc ); return NULL; } int nPixelOffset; int nLineOffset; int nBandOffset; if (eInterleave == LINE) { nPixelOffset = GDALGetDataTypeSize(eDataType)/8; nLineOffset = nPixelOffset * nWidth * nBands; nBandOffset = GDALGetDataTypeSize(eDataType)/8 * nWidth; } else { /* PIXEL */ nPixelOffset = GDALGetDataTypeSize(eDataType)/8 * nBands; nLineOffset = nPixelOffset * nWidth * nBands; nBandOffset = GDALGetDataTypeSize(eDataType)/8; } poDS->nBands = nBands; for (int b = 0; b < nBands; b++) { poDS->SetBand( b + 1, new ROIPACRasterBand( poDS, b + 1, poDS->fpImage, nBandOffset * b, nPixelOffset, nLineOffset, eDataType, TRUE, TRUE, FALSE ) ); } /* -------------------------------------------------------------------- */ /* Interpret georeferencing, if present. */ /* -------------------------------------------------------------------- */ if ( CSLFetchNameValue( papszRsc, "X_FIRST" ) != NULL && CSLFetchNameValue( papszRsc, "X_STEP" ) != NULL && CSLFetchNameValue( papszRsc, "Y_FIRST" ) != NULL && CSLFetchNameValue( papszRsc, "Y_STEP" ) != NULL ) { poDS->adfGeoTransform[0] = CPLAtof( CSLFetchNameValue( papszRsc, "X_FIRST" ) ); poDS->adfGeoTransform[1] = CPLAtof( CSLFetchNameValue( papszRsc, "X_STEP" ) ); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = CPLAtof( CSLFetchNameValue( papszRsc, "Y_FIRST" ) ); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = CPLAtof( CSLFetchNameValue( papszRsc, "Y_STEP" ) ); poDS->bValidGeoTransform = true; } if ( CSLFetchNameValue( papszRsc, "PROJECTION" ) != NULL ) { /* ------------------------------------------------------------ */ /* In ROI_PAC, images are georeferenced either with lat/long or */ /* UTM projection. However, using UTM projection is dangerous */ /* because there is no North/South field, or use of latitude */ /* bands! */ /* ------------------------------------------------------------ */ OGRSpatialReference oSRS; if ( strcmp( CSLFetchNameValue( papszRsc, "PROJECTION" ), "LL" ) == 0 ) { if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL ) { oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc, "DATUM" ) ); } else { oSRS.SetWellKnownGeogCS( "WGS84" ); } } else if( strncmp( CSLFetchNameValue( papszRsc, "PROJECTION" ), "UTM", 3 ) == 0 ) { const char *pszZone = CSLFetchNameValue( papszRsc, "PROJECTION" ) + 3; oSRS.SetUTM( atoi( pszZone ), TRUE ); /* FIXME: north/south? */ if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL ) { oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc, "DATUM" ) ); } else { oSRS.SetWellKnownGeogCS( "NAD27" ); } } oSRS.exportToWkt( &poDS->pszProjection ); } /* -------------------------------------------------------------------- */ /* Set all the other header metadata into the ROI_PAC domain */ /* -------------------------------------------------------------------- */ for (int i = 0; i < CSLCount( papszRsc ); i++) { char **papszTokens; papszTokens = CSLTokenizeString2( papszRsc[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if ( strcmp( papszTokens[0], "WIDTH" ) == 0 || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0 || strcmp( papszTokens[0], "X_FIRST" ) == 0 || strcmp( papszTokens[0], "X_STEP" ) == 0 || strcmp( papszTokens[0], "Y_FIRST" ) == 0 || strcmp( papszTokens[0], "Y_STEP" ) == 0 || strcmp( papszTokens[0], "PROJECTION" ) == 0 || strcmp( papszTokens[0], "DATUM" ) == 0 ) { CSLDestroy( papszTokens ); continue; } poDS->SetMetadataItem(papszTokens[0], papszTokens[1], "ROI_PAC"); CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Free papszRsc */ /* -------------------------------------------------------------------- */ CSLDestroy( papszRsc ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "HF2 driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Get source dataset info */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform(adfGeoTransform); int bHasGeoTransform = !(adfGeoTransform[0] == 0 && adfGeoTransform[1] == 1 && adfGeoTransform[2] == 0 && adfGeoTransform[3] == 0 && adfGeoTransform[4] == 0 && adfGeoTransform[5] == 1); if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n"); return NULL; } GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); GDALDataType eReqDT; float fVertPres = (float) 0.01; if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16) { fVertPres = 1; eReqDT = GDT_Int16; } else eReqDT = GDT_Float32; /* -------------------------------------------------------------------- */ /* Read creation options */ /* -------------------------------------------------------------------- */ const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS"); int bCompress = FALSE; if (pszCompressed) bCompress = CSLTestBoolean(pszCompressed); const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION"); if (pszVerticalPrecision) { fVertPres = (float) CPLAtofM(pszVerticalPrecision); if (fVertPres <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01"); fVertPres = (float) 0.01; } if (eReqDT == GDT_Int16 && fVertPres > 1) eReqDT = GDT_Float32; } const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE"); int nTileSize = 256; if (pszBlockSize) { nTileSize = atoi(pszBlockSize); if (nTileSize < 8 || nTileSize > 4096) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for BLOCKSIZE. Defaulting to 256"); nTileSize = 256; } } /* -------------------------------------------------------------------- */ /* Parse source dataset georeferencing info */ /* -------------------------------------------------------------------- */ int nExtendedHeaderLen = 0; if (bHasGeoTransform) nExtendedHeaderLen += 58; const char* pszProjectionRef = poSrcDS->GetProjectionRef(); int nDatumCode = -2; int nUTMZone = 0; int bNorth = FALSE; int nEPSGCode = 0; int nExtentUnits = 1; if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') { OGRSpatialReference oSRS; char* pszTemp = (char*) pszProjectionRef; if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE) { const char* pszValue = NULL; if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") ) nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" )); else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL) { if (strstr(pszValue, "WGS") && strstr(pszValue, "84")) nDatumCode = 6326; } nUTMZone = oSRS.GetUTMZone(&bNorth); } if( oSRS.GetAuthorityName( "PROJCS" ) != NULL && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") ) nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); if( oSRS.IsGeographic() ) { nExtentUnits = 0; } else { double dfLinear = oSRS.GetLinearUnits(); if( ABS(dfLinear - 0.3048) < 0.0000001 ) nExtentUnits = 2; else if( ABS(dfLinear - atof(SRS_UL_US_FOOT_CONV)) < 0.00000001 ) nExtentUnits = 3; else nExtentUnits = 1; } } if (nDatumCode != -2) nExtendedHeaderLen += 26; if (nUTMZone != 0) nExtendedHeaderLen += 26; if (nEPSGCode) nExtendedHeaderLen += 26; /* -------------------------------------------------------------------- */ /* Create target file */ /* -------------------------------------------------------------------- */ CPLString osFilename; if (bCompress) { osFilename = "/vsigzip/"; osFilename += pszFilename; } else osFilename = pszFilename; VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb"); if (fp == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Write header */ /* -------------------------------------------------------------------- */ VSIFWriteL("HF2\0", 4, 1, fp); WriteShort(fp, 0); WriteInt(fp, nXSize); WriteInt(fp, nYSize); WriteShort(fp, (GInt16) nTileSize); WriteFloat(fp, fVertPres); float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2); WriteFloat(fp, fHorizScale); WriteInt(fp, nExtendedHeaderLen); /* -------------------------------------------------------------------- */ /* Write extended header */ /* -------------------------------------------------------------------- */ char szBlockName[16 + 1]; if (bHasGeoTransform) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-extents"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 34); WriteShort(fp, (GInt16) nExtentUnits); WriteDouble(fp, adfGeoTransform[0]); WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]); WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]); WriteDouble(fp, adfGeoTransform[3]); } if (nUTMZone != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-utm"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone)); } if (nDatumCode != -2) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-datum"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nDatumCode); } if (nEPSGCode != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-epsg-prj"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nEPSGCode); } /* -------------------------------------------------------------------- */ /* Copy imagery */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nTileSize - 1) / nTileSize; int nYBlocks = (nYSize + nTileSize - 1) / nTileSize; void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8)); if (pTileBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); VSIFCloseL(fp); return NULL; } int i, j, k, l; CPLErr eErr = CE_None; for(j=0;j<nYBlocks && eErr == CE_None;j++) { for(i=0;i<nXBlocks && eErr == CE_None;i++) { int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize); int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize); eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read, i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize), nReqXSize, nReqYSize, pTileBuffer, nReqXSize, nReqYSize, eReqDT, 0, 0); if (eErr != CE_None) break; if (eReqDT == GDT_Int16) { WriteFloat(fp, 1); /* scale */ WriteFloat(fp, 0); /* offset */ for(k=0;k<nReqYSize;k++) { int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); char chDiff = (char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } else { float fMinVal = ((float*)pTileBuffer)[0]; float fMaxVal = fMinVal; for(k=1;k<nReqYSize*nReqXSize;k++) { float fVal = ((float*)pTileBuffer)[k]; if (fVal < fMinVal) fMinVal = fVal; if (fVal > fMaxVal) fMaxVal = fVal; } float fIntRange = (fMaxVal - fMinVal) / fVertPres; float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange; float fOffset = fMinVal; WriteFloat(fp, fScale); /* scale */ WriteFloat(fp, fOffset); /* offset */ for(k=0;k<nReqYSize;k++) { float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; float fIntLastVal = (fLastVal - fOffset) / fScale; CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f); int nLastVal = (int)fIntLastVal; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f); int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; fIntLastVal = (fLastVal - fOffset) / fScale; nLastVal = (int)fIntLastVal; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); char chDiff = (char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) ) { eErr = CE_Failure; break; } } } CPLFree(pTileBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly); }
void ROIPACDataset::FlushCache( void ) { RawDataset::FlushCache(); GDALRasterBand *band = (GetRasterCount() > 0) ? GetRasterBand(1) : NULL; if ( eAccess == GA_ReadOnly || band == NULL ) return; // If opening an existing file in Update mode (i.e. "r+") we need to make // sure any existing content is cleared, otherwise the file may contain // trailing content from the previous write. VSIFTruncateL( fpRsc, 0 ); VSIFSeekL( fpRsc, 0, SEEK_SET ); /* -------------------------------------------------------------------- */ /* Rewrite out the header. */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Raster dimensions. */ /* -------------------------------------------------------------------- */ VSIFPrintfL( fpRsc, "%-40s %d\n", "WIDTH", nRasterXSize ); VSIFPrintfL( fpRsc, "%-40s %d\n", "FILE_LENGTH", nRasterYSize ); /* -------------------------------------------------------------------- */ /* Georeferencing. */ /* -------------------------------------------------------------------- */ if ( pszProjection != NULL ) { char *pszProjectionTmp = pszProjection; OGRSpatialReference oSRS; if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) { int bNorth; int iUTMZone; iUTMZone = oSRS.GetUTMZone( &bNorth ); if ( iUTMZone != 0 ) { VSIFPrintfL( fpRsc, "%-40s %s%d\n", "PROJECTION", "UTM", iUTMZone ); } else if ( oSRS.IsGeographic() ) { VSIFPrintfL( fpRsc, "%-40s %s\n", "PROJECTION", "LL" ); } else { CPLError( CE_Warning, CPLE_AppDefined, "ROI_PAC format only support Latitude/Longitude and " "UTM projections, discarding projection."); } if ( oSRS.GetAttrValue( "DATUM" ) != NULL ) { if ( strcmp( oSRS.GetAttrValue( "DATUM" ), "WGS_1984" ) == 0 ) { VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", "WGS84" ); } else { CPLError( CE_Warning, CPLE_AppDefined, "Datum \"%s\" probably not supported in the " "ROI_PAC format, saving it anyway", oSRS.GetAttrValue( "DATUM" ) ); VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", oSRS.GetAttrValue( "DATUM" ) ); } } if ( oSRS.GetAttrValue( "UNIT" ) != NULL ) { VSIFPrintfL( fpRsc, "%-40s %s\n", "X_UNIT", oSRS.GetAttrValue( "UNIT" ) ); VSIFPrintfL( fpRsc, "%-40s %s\n", "Y_UNIT", oSRS.GetAttrValue( "UNIT" ) ); } } } if( bValidGeoTransform ) { if ( adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "ROI_PAC format do not support geotransform with " "rotation, discarding info."); } else { VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_FIRST", adfGeoTransform[0] ); VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_STEP", adfGeoTransform[1] ); VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_FIRST", adfGeoTransform[3] ); VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_STEP", adfGeoTransform[5] ); } } /* -------------------------------------------------------------------- */ /* Metadata stored in the ROI_PAC domain. */ /* -------------------------------------------------------------------- */ char** papszROIPACMetadata = GetMetadata( "ROI_PAC" ); for (int i = 0; i < CSLCount( papszROIPACMetadata ); i++) { char **papszTokens; /* Get the tokens from the metadata item */ papszTokens = CSLTokenizeString2( papszROIPACMetadata[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if ( CSLCount( papszTokens ) != 2 ) { CPLDebug("ROI_PAC", "Line of header file could not be split at = into two elements: %s", papszROIPACMetadata[i]); CSLDestroy( papszTokens ); continue; } /* Don't write it out if it is one of the bits of metadata that is * written out elsewhere in this routine */ if ( strcmp( papszTokens[0], "WIDTH" ) == 0 || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0 ) { CSLDestroy( papszTokens ); continue; } VSIFPrintfL( fpRsc, "%-40s %s\n", papszTokens[0], papszTokens[1] ); CSLDestroy( papszTokens ); } }
OGRSpatialReference *OGRMySQLDataSource::FetchSRS( int nId ) { char szCommand[1024]; char **papszRow; MYSQL_RES *hResult; 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]; } OGRSpatialReference *poSRS = NULL; // make sure to attempt to free any old results hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; sprintf( szCommand, "SELECT srtext FROM spatial_ref_sys WHERE srid = %d", nId ); if( !mysql_query( GetConn(), szCommand ) ) hResult = mysql_store_result( GetConn() ); char *pszWKT = NULL; papszRow = NULL; if( hResult != NULL ) papszRow = mysql_fetch_row( hResult ); if( papszRow != NULL && papszRow[0] != NULL ) { pszWKT = CPLStrdup(papszRow[0]); } if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; poSRS = new OGRSpatialReference(); char* pszWKTOri = pszWKT; if( pszWKT == NULL || poSRS->importFromWkt( &pszWKT ) != OGRERR_NONE ) { delete poSRS; CPLFree(pszWKTOri); poSRS = NULL; } CPLFree(pszWKTOri); /* -------------------------------------------------------------------- */ /* 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 *ARGDataset::Open( GDALOpenInfo * poOpenInfo ) { json_object * pJSONObject; const char * pszJSONStr; char * pszLayer; /***** items from the json metadata *****/ GDALDataType eType = GDT_Unknown; double fXmin = 0.0; double fYmin = 0.0; double fXmax = 0.0; double fYmax = 0.0; double fCellwidth = 1.0; double fCellheight = 1.0; double fXSkew = 0.0; double fYSkew = 0.0; int nRows = 0; int nCols = 0; int nSrs = 3857; /***** items from the json metadata *****/ int nPixelOffset = 0; double fNoDataValue = NAN; char * pszWKT = NULL; OGRSpatialReference oSRS; OGRErr nErr = OGRERR_NONE; if ( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Check metadata settings in JSON. */ /* -------------------------------------------------------------------- */ pJSONObject = GetJsonObject(poOpenInfo->pszFilename); if (pJSONObject == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Error parsing JSON."); return NULL; } // get the type (always 'arg') pszJSONStr = GetJsonValueStr(pJSONObject, "type"); if (pszJSONStr == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'type' is missing from the JSON file."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } else if (!EQUAL(pszJSONStr, "arg")) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'type' is not recognized: '%s'.", pszJSONStr); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the datatype pszJSONStr = GetJsonValueStr(pJSONObject, "datatype"); if (pszJSONStr == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'datatype' is missing from the JSON file."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } else if (EQUAL(pszJSONStr, "int8")) { CPLDebug("ARGDataset", "Open(): " "int8 data is not supported in GDAL -- mapped to uint8"); eType = GDT_Byte; nPixelOffset = 1; fNoDataValue = 128; } else if (EQUAL(pszJSONStr, "int16")) { eType = GDT_Int16; nPixelOffset = 2; fNoDataValue = -32767; } else if (EQUAL(pszJSONStr, "int32")) { eType = GDT_Int32; nPixelOffset = 4; fNoDataValue = -2e31; } else if (EQUAL(pszJSONStr, "uint8")) { eType = GDT_Byte; nPixelOffset = 1; fNoDataValue = 255; } else if (EQUAL(pszJSONStr, "uint16")) { eType = GDT_UInt16; nPixelOffset = 2; fNoDataValue = 65535; } else if (EQUAL(pszJSONStr, "uint32")) { eType = GDT_UInt32; nPixelOffset = 4; fNoDataValue = -2e31; } else if (EQUAL(pszJSONStr, "float32")) { eType = GDT_Float32; nPixelOffset = 4; fNoDataValue = NAN; } else if (EQUAL(pszJSONStr, "float64")) { eType = GDT_Float64; nPixelOffset = 8; fNoDataValue = NAN; } else { if (EQUAL(pszJSONStr, "int64") || EQUAL(pszJSONStr, "uint64")) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'datatype' is unsupported in GDAL: '%s'.", pszJSONStr); } else { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'datatype' is unknown: '%s'.", pszJSONStr); } json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the xmin of the bounding box fXmin = GetJsonValueDbl(pJSONObject, "xmin"); if (CPLIsNan(fXmin)) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'xmin' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the ymin of the bounding box fYmin = GetJsonValueDbl(pJSONObject, "ymin"); if (CPLIsNan(fYmin)) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'ymin' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the xmax of the bounding box fXmax = GetJsonValueDbl(pJSONObject, "xmax"); if (CPLIsNan(fXmax)) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'xmax' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the ymax of the bounding box fYmax = GetJsonValueDbl(pJSONObject, "ymax"); if (CPLIsNan(fYmax)) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'ymax' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the cell width fCellwidth = GetJsonValueDbl(pJSONObject, "cellwidth"); if (CPLIsNan(fCellwidth)) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'cellwidth' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the cell height fCellheight = GetJsonValueDbl(pJSONObject, "cellheight"); if (CPLIsNan(fCellheight)) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'cellheight' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } fXSkew = GetJsonValueDbl(pJSONObject, "xskew"); if (CPLIsNan(fXSkew)) { // not an error -- default to 0.0 fXSkew = 0.0f; } fYSkew = GetJsonValueDbl(pJSONObject, "yskew"); if (CPLIsNan(fYSkew)) { // not an error -- default to 0.0 fYSkew = 0.0f; } // get the rows nRows = GetJsonValueInt(pJSONObject, "rows"); if (nRows < 0) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'rows' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the columns nCols = GetJsonValueInt(pJSONObject, "cols"); if (nCols < 0) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'cols' is missing or invalid."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } nSrs = GetJsonValueInt(pJSONObject, "epsg"); if (nSrs < 0) { // not an error -- default to web mercator nSrs = 3857; } nErr = oSRS.importFromEPSG(nSrs); if (nErr != OGRERR_NONE) { nErr = oSRS.importFromEPSG(3857); if (nErr == OGRERR_NONE) { CPLDebug("ARGDataset", "Open(): " "The EPSG provided did not import cleanly. Defaulting to EPSG:3857"); } else { CPLError(CE_Failure, CPLE_AppDefined, "The 'epsg' value did not transate to a known spatial reference." " Please check the 'epsg' value and try again."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } } nErr = oSRS.exportToWkt(&pszWKT); if (nErr != OGRERR_NONE) { CPLError(CE_Failure, CPLE_AppDefined, "The spatial reference is known, but could not be set on the " "dataset. Please check the 'epsg' value and try again."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } // get the layer (always the file basename) pszJSONStr = GetJsonValueStr(pJSONObject, "layer"); if (pszJSONStr == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "The ARG 'layer' is missing from the JSON file."); json_object_put(pJSONObject); pJSONObject = NULL; return NULL; } pszLayer = CPLStrdup(pszJSONStr); // done with the json object now json_object_put(pJSONObject); pJSONObject = NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ ARGDataset *poDS; poDS = new ARGDataset(); poDS->pszFilename = CPLStrdup(poOpenInfo->pszFilename); poDS->SetMetadataItem("LAYER",pszLayer,NULL); poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->SetProjection( pszWKT ); // done with the projection string CPLFree(pszWKT); CPLFree(pszLayer); /* -------------------------------------------------------------------- */ /* Assume ownership of the file handled from the GDALOpenInfo. */ /* -------------------------------------------------------------------- */ poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (poDS->fpImage == NULL) { delete poDS; CPLError(CE_Failure, CPLE_AppDefined, "Could not open dataset '%s'", poOpenInfo->pszFilename); return NULL; } poDS->adfGeoTransform[0] = fXmin; poDS->adfGeoTransform[1] = fCellwidth; poDS->adfGeoTransform[2] = fXSkew; poDS->adfGeoTransform[3] = fYmax; poDS->adfGeoTransform[4] = fYSkew; poDS->adfGeoTransform[5] = -fCellheight; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ RawRasterBand *poBand; #ifdef CPL_LSB int bNative = FALSE; #else int bNative = TRUE; #endif poBand = new RawRasterBand( poDS, 1, poDS->fpImage, 0, nPixelOffset, nPixelOffset * nCols, eType, bNative, TRUE ); poDS->SetBand( 1, poBand ); poBand->SetNoDataValue( fNoDataValue ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
CPLErr IDADataset::SetProjection( const char *pszWKTIn ) { OGRSpatialReference oSRS; oSRS.importFromWkt( (char **) &pszWKTIn ); if( !oSRS.IsGeographic() && !oSRS.IsProjected() ) GDALPamDataset::SetProjection( pszWKTIn ); /* -------------------------------------------------------------------- */ /* Clear projection parameters. */ /* -------------------------------------------------------------------- */ dfParallel1 = 0.0; dfParallel2 = 0.0; dfLatCenter = 0.0; dfLongCenter = 0.0; /* -------------------------------------------------------------------- */ /* Geographic. */ /* -------------------------------------------------------------------- */ if( oSRS.IsGeographic() ) { // If no change, just return. if( nProjection == 3 ) return CE_None; nProjection = 3; } /* -------------------------------------------------------------------- */ /* Verify we don't have a false easting or northing as these */ /* will be ignored for the projections we do support. */ /* -------------------------------------------------------------------- */ if( oSRS.GetProjParm( SRS_PP_FALSE_EASTING ) != 0.0 || oSRS.GetProjParm( SRS_PP_FALSE_NORTHING ) != 0.0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to set a projection on an IDA file with a non-zero\n" "false easting and/or northing. This is not supported." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Lambert Conformal Conic. Note that we don't support false */ /* eastings or nothings. */ /* -------------------------------------------------------------------- */ const char *pszProjection = oSRS.GetAttrValue( "PROJECTION" ); if( pszProjection == NULL ) { /* do nothing - presumably geographic */; } else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) ) { nProjection = 4; dfParallel1 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0); dfParallel2 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0); dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0); dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0); } else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) ) { nProjection = 6; dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0); dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0); } else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) ) { nProjection = 8; dfParallel1 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0); dfParallel2 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0); dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0); dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0); } else if( EQUAL(pszProjection,SRS_PT_GOODE_HOMOLOSINE) ) { nProjection = 9; dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0); } else { return GDALPamDataset::SetProjection( pszWKTIn ); } /* -------------------------------------------------------------------- */ /* Update header and mark it as dirty. */ /* -------------------------------------------------------------------- */ bHeaderDirty = TRUE; abyHeader[23] = (GByte) nProjection; c2tp( dfLatCenter, abyHeader + 120 ); c2tp( dfLongCenter, abyHeader + 126 ); c2tp( dfParallel1, abyHeader + 156 ); c2tp( dfParallel2, abyHeader + 162 ); return CE_None; }
GDALDataset * ARGDataset::CreateCopy( const char * pszFilename, GDALDataset * poSrcDS, CPL_UNUSED int bStrict, CPL_UNUSED char ** papszOptions, CPL_UNUSED GDALProgressFunc pfnProgress, CPL_UNUSED void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); int nXBlockSize, nYBlockSize, nPixelOffset = 0; GDALDataType eType; CPLString osJSONFilename; CPLString pszDataType; json_object * poJSONObject = NULL; double adfTransform[6]; GDALRasterBand * poSrcBand = NULL; RawRasterBand * poDstBand = NULL; VSILFILE * fpImage = NULL; void * pabyData; OGRSpatialReference oSRS; char * pszWKT = NULL; char ** pszTokens = NULL; const char * pszLayer = NULL; int nSrs = 0; OGRErr nErr = OGRERR_NONE; CPLErr eErr; if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support %d bands. Must be 1 band.", nBands ); return NULL; } eType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eType == GDT_Unknown || eType == GDT_CInt16 || eType == GDT_CInt32 || eType == GDT_CFloat32 || eType == GDT_CFloat64 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support data type %s.", GDALGetDataTypeName(eType) ); return NULL; } else if (eType == GDT_Int16) { pszDataType = "int16"; nPixelOffset = 2; } else if (eType == GDT_Int32) { pszDataType = "int32"; nPixelOffset = 4; } else if (eType == GDT_Byte) { pszDataType = "uint8"; nPixelOffset = 1; } else if (eType == GDT_UInt16) { pszDataType = "uint16"; nPixelOffset = 2; } else if (eType == GDT_UInt32) { pszDataType = "uint32"; nPixelOffset = 4; } else if (eType == GDT_Float32) { pszDataType = "float32"; nPixelOffset = 4; } else if (eType == GDT_Float64) { pszDataType = "float64"; nPixelOffset = 8; } poSrcDS->GetGeoTransform( adfTransform ); pszWKT = (char *)poSrcDS->GetProjectionRef(); nErr = oSRS.importFromWkt(&pszWKT); if (nErr != OGRERR_NONE) { CPLError( CE_Failure, CPLE_NotSupported, "Cannot import spatial reference WKT from source dataset."); return NULL; } if (oSRS.GetAuthorityCode("PROJCS") != NULL) { nSrs = atoi(oSRS.GetAuthorityCode("PROJCS")); } else if (oSRS.GetAuthorityCode("GEOGCS") != NULL) { nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS")); } else { // could not determine projected or geographic code // default to EPSG:3857 if no code could be found nSrs = 3857; } /********************************************************************/ /* Create JSON companion file. */ /********************************************************************/ osJSONFilename = GetJsonFilename(pszFilename); poJSONObject = json_object_new_object(); pszTokens = poSrcDS->GetMetadata(); pszLayer = CSLFetchNameValue(pszTokens, "LAYER"); if ( pszLayer == NULL) { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( CPLGetBasename(osJSONFilename) )); } else { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( pszLayer )); } // Set the type json_object_object_add(poJSONObject, "type", json_object_new_string("arg")); // Set the datatype json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType)); // Set the number of rows json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize)); // Set the number of columns json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize)); // Set the xmin json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0])); // Set the ymax json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3])); // Set the cellwidth json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1])); // Set the cellheight json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5])); // Set the xmax json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1])); // Set the ymin json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5])); // Set the xskew json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2])); // Set the yskew json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4])); if (nSrs > 0) { // Set the epsg json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs)); } if (json_object_to_file((char *)osJSONFilename.c_str(), poJSONObject) < 0) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't write companion file."); json_object_put(poJSONObject); poJSONObject = NULL; return NULL; } json_object_put(poJSONObject); poJSONObject = NULL; fpImage = VSIFOpenL(pszFilename, "wb"); if (fpImage == NULL) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't create data file %s.", pszFilename); // remove JSON file VSIUnlink( osJSONFilename.c_str() ); return NULL; } // only 1 raster band poSrcBand = poSrcDS->GetRasterBand( 1 ); #ifdef CPL_LSB int bNative = FALSE; #else int bNative = TRUE; #endif poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset, nPixelOffset * nXSize, eType, bNative, nXSize, nYSize, TRUE, FALSE); poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize); pabyData = CPLMalloc(nXBlockSize * nPixelOffset); // convert any blocks into scanlines for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) { for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) { if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) { continue; } for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) { int nXValid; if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() ) nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize; else nXValid = nXBlockSize; eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, NULL); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error reading."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return NULL; } eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, NULL); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error writing."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return NULL; } } } } CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return (GDALDataset *)GDALOpen( pszFilename, GA_ReadOnly ); }
CPLErr GDALRasterizeLayers(GDALDatasetH hDS, int nBandCount, int *panBandList, int nLayerCount, OGRLayerH *pahLayers, GDALTransformerFunc pfnTransformer, void *pTransformArg, double *padfLayerBurnValues, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressArg) { #ifndef OGR_ENABLED CPLError(CE_Failure, CPLE_NotSupported, "GDALRasterizeLayers() unimplemented in a non OGR build"); return CE_Failure; #else GDALDataType eType; unsigned char *pabyChunkBuf; GDALDataset *poDS = (GDALDataset*) hDS; if (pfnProgress == NULL) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Do some rudimentary arg checking. */ /* -------------------------------------------------------------------- */ if (nBandCount == 0 || nLayerCount == 0) return CE_None; // prototype band. GDALRasterBand *poBand = poDS->GetRasterBand(panBandList[0]); if (poBand == NULL) return CE_Failure; int bAllTouched = CSLFetchBoolean(papszOptions, "ALL_TOUCHED", FALSE); const char *pszOpt = CSLFetchNameValue(papszOptions, "BURN_VALUE_FROM"); GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue; if (pszOpt) { if (EQUAL(pszOpt, "Z")) eBurnValueSource = GBV_Z; /*else if( EQUAL(pszOpt,"M")) eBurnValueSource = GBV_M;*/ } /* -------------------------------------------------------------------- */ /* Establish a chunksize to operate on. The larger the chunk */ /* size the less times we need to make a pass through all the */ /* shapes. */ /* -------------------------------------------------------------------- */ int nYChunkSize, nScanlineBytes; const char *pszYChunkSize = CSLFetchNameValue(papszOptions, "CHUNKYSIZE"); if (poBand->GetRasterDataType() == GDT_Byte) eType = GDT_Byte; else eType = GDT_Float32; nScanlineBytes = nBandCount * poDS->GetRasterXSize() * (GDALGetDataTypeSize(eType) / 8); if (pszYChunkSize && ((nYChunkSize = atoi(pszYChunkSize))) != 0) ; else { GIntBig nYChunkSize64 = GDALGetCacheMax64() / nScanlineBytes; if (nYChunkSize64 > INT_MAX) nYChunkSize = INT_MAX; else nYChunkSize = (int)nYChunkSize64; } if (nYChunkSize < 1) nYChunkSize = 1; if (nYChunkSize > poDS->GetRasterYSize()) nYChunkSize = poDS->GetRasterYSize(); pabyChunkBuf = (unsigned char*) VSIMalloc(nYChunkSize * nScanlineBytes); if (pabyChunkBuf == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Unable to allocate rasterization buffer."); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Read the image once for all layers if user requested to render */ /* the whole raster in single chunk. */ /* -------------------------------------------------------------------- */ if (nYChunkSize == poDS->GetRasterYSize()) { if (poDS->RasterIO(GF_Read, 0, 0, poDS->GetRasterXSize(), nYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nYChunkSize, eType, nBandCount, panBandList, 0, 0, 0) != CE_None) { CPLError(CE_Failure, CPLE_OutOfMemory, "Unable to read buffer."); CPLFree(pabyChunkBuf); return CE_Failure; } } /* ==================================================================== */ /* Read the specified layers transfoming and rasterizing */ /* geometries. */ /* ==================================================================== */ CPLErr eErr = CE_None; int iLayer; const char *pszBurnAttribute = CSLFetchNameValue(papszOptions, "ATTRIBUTE"); pfnProgress(0.0, NULL, pProgressArg); for (iLayer = 0; iLayer < nLayerCount; iLayer++) { int iBurnField = -1; double *padfBurnValues = NULL; OGRLayer *poLayer = (OGRLayer*) pahLayers[iLayer]; if (!poLayer) { CPLError(CE_Warning, CPLE_AppDefined, "Layer element number %d is NULL, skipping.\n", iLayer); continue; } /* -------------------------------------------------------------------- */ /* If the layer does not contain any features just skip it. */ /* Do not force the feature count, so if driver doesn't know */ /* exact number of features, go down the normal way. */ /* -------------------------------------------------------------------- */ if (poLayer->GetFeatureCount(FALSE) == 0) continue; if (pszBurnAttribute) { iBurnField = poLayer->GetLayerDefn()->GetFieldIndex(pszBurnAttribute); if (iBurnField == -1) { CPLError(CE_Warning, CPLE_AppDefined, "Failed to find field %s on layer %s, skipping.\n", pszBurnAttribute, poLayer->GetLayerDefn()->GetName()); continue; } } else padfBurnValues = padfLayerBurnValues + iLayer * nBandCount; /* -------------------------------------------------------------------- */ /* If we have no transformer, create the one from input file */ /* projection. Note that each layer can be georefernced */ /* separately. */ /* -------------------------------------------------------------------- */ int bNeedToFreeTransformer = FALSE; if (pfnTransformer == NULL) { char *pszProjection = NULL; bNeedToFreeTransformer = TRUE; OGRSpatialReference *poSRS = poLayer->GetSpatialRef(); if (!poSRS) { CPLError(CE_Warning, CPLE_AppDefined, "Failed to fetch spatial reference on layer %s " "to build transformer, assuming matching coordinate systems.\n", poLayer->GetLayerDefn()->GetName()); } else poSRS->exportToWkt(&pszProjection); pTransformArg = GDALCreateGenImgProjTransformer(NULL, pszProjection, hDS, NULL, FALSE, 0.0, 0); pfnTransformer = GDALGenImgProjTransform; CPLFree(pszProjection); } OGRFeature *poFeat; poLayer->ResetReading(); /* -------------------------------------------------------------------- */ /* Loop over image in designated chunks. */ /* -------------------------------------------------------------------- */ int iY; for (iY = 0; iY < poDS->GetRasterYSize() && eErr == CE_None; iY += nYChunkSize) { int nThisYChunkSize; nThisYChunkSize = nYChunkSize; if (nThisYChunkSize + iY > poDS->GetRasterYSize()) nThisYChunkSize = poDS->GetRasterYSize() - iY; // Only re-read image if not a single chunk is being rendered if (nYChunkSize < poDS->GetRasterYSize()) { eErr = poDS->RasterIO(GF_Read, 0, iY, poDS->GetRasterXSize(), nThisYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nThisYChunkSize, eType, nBandCount, panBandList, 0, 0, 0); if (eErr != CE_None) break; } double *padfAttrValues = (double*) VSIMalloc(sizeof(double) * nBandCount); while ((poFeat = poLayer->GetNextFeature()) != NULL) { OGRGeometry *poGeom = poFeat->GetGeometryRef(); if (pszBurnAttribute) { int iBand; double dfAttrValue; dfAttrValue = poFeat->GetFieldAsDouble(iBurnField); for (iBand = 0; iBand < nBandCount; iBand++) padfAttrValues[iBand] = dfAttrValue; padfBurnValues = padfAttrValues; } gv_rasterize_one_shape(pabyChunkBuf, iY, poDS->GetRasterXSize(), nThisYChunkSize, nBandCount, eType, bAllTouched, poGeom, padfBurnValues, eBurnValueSource, pfnTransformer, pTransformArg); delete poFeat; } VSIFree(padfAttrValues); // Only write image if not a single chunk is being rendered if (nYChunkSize < poDS->GetRasterYSize()) { eErr = poDS->RasterIO(GF_Write, 0, iY, poDS->GetRasterXSize(), nThisYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nThisYChunkSize, eType, nBandCount, panBandList, 0, 0, 0); } poLayer->ResetReading(); if (!pfnProgress((iY + nThisYChunkSize) / ((double)poDS->GetRasterYSize()), "", pProgressArg)) { CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated"); eErr = CE_Failure; } } if (bNeedToFreeTransformer) { GDALDestroyTransformer(pTransformArg); pTransformArg = NULL; pfnTransformer = NULL; } } /* -------------------------------------------------------------------- */ /* Write out the image once for all layers if user requested */ /* to render the whole raster in single chunk. */ /* -------------------------------------------------------------------- */ if (nYChunkSize == poDS->GetRasterYSize()) { poDS->RasterIO(GF_Write, 0, 0, poDS->GetRasterXSize(), nYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nYChunkSize, eType, nBandCount, panBandList, 0, 0, 0); } /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ VSIFree(pabyChunkBuf); return eErr; #endif /* def OGR_ENABLED */ }
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE or an IMAGE Primary Data Object? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr ) return nullptr; VSILFILE *fpQube = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; ISIS2Dataset *poDS = new ISIS2Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return nullptr; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the label (i.e. .lab) file. */ /* -------------------------------------------------------------------- */ // QUBE can be inline or detached and point to an image name // ^QUBE = 76 // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image // ^QUBE = "ui31s015.img" - which implies no label or skip value const char *pszQube = poDS->GetKeyword( "^QUBE" ); GUIntBig nQube = 0; int bByteLocation = FALSE; CPLString osTargetFile = poOpenInfo->pszFilename; if( pszQube[0] == '"' ) { const CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = pszQube; poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, nullptr ); poDS->osExternalCube = osTargetFile; } else if( pszQube[0] == '(' ) { const CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,""); poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, nullptr ); poDS->osExternalCube = osTargetFile; nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1")); if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != nullptr ) bByteLocation = true; } else { nQube = atoi(pszQube); if( strstr(pszQube,"<BYTES>") != nullptr ) bByteLocation = true; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS2 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Checks to see if this is valid ISIS2 cube */ /* SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes */ /* -------------------------------------------------------------------- */ const int s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 )); const int s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 )); const int s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 )); if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n" "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n" "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz ); delete poDS; return nullptr; } /**************** end SUFFIX_ITEM check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /***********************************************************/ char szLayout[10] = "BSQ"; //default to band seq. const char *value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) strcpy(szLayout,"BSQ"); else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) strcpy(szLayout,"BIP"); else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return nullptr; } /*********** Grab samples lines band ************/ const int nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1)); const int nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2)); const int nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3)); /*********** Grab Qube record bytes **********/ const int record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES")); GUIntBig nSkipBytes = 0; if (nQube > 0 && bByteLocation ) nSkipBytes = (nQube - 1); else if( nQube > 0 ) nSkipBytes = (nQube - 1) * record_bytes; else nSkipBytes = 0; /*********** Grab samples lines band ************/ char chByteOrder = 'M'; //default to MSB CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" ); if( (EQUAL(osCoreItemType,"PC_INTEGER")) || (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) || (EQUAL(osCoreItemType,"PC_REAL")) ) { chByteOrder = 'I'; } /******** Grab format type - isis2 only supports 8,16,32 *******/ GDALDataType eDataType = GDT_Byte; bool bNoDataSet = false; double dfNoData = 0.0; int itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES","")); switch(itype) { case 1 : eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = true; break; case 2 : if( strstr(osCoreItemType,"UNSIGNED") != nullptr ) { dfNoData = 0; eDataType = GDT_UInt16; } else { dfNoData = NULL2; eDataType = GDT_Int16; } bNoDataSet = true; break; case 4 : eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = true; break; case 8 : eDataType = GDT_Float64; dfNoData = NULL3; bNoDataSet = true; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Itype of %d is not supported in ISIS 2.", itype); delete poDS; return nullptr; } /*********** Grab Cellsize ************/ double dfXDim = 1.0; double dfYDim = 1.0; value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE"); if (strlen(value) > 0 ) { // Convert km to m dfXDim = static_cast<float>( CPLAtof(value) * 1000.0 ); dfYDim = static_cast<float>( CPLAtof(value) * 1000.0 * -1 ); } /*********** Grab LINE_PROJECTION_OFFSET ************/ double dfULYMap = 0.5; double yulcenter = 0.0; value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = static_cast<float>( CPLAtof(value) ); yulcenter = ((yulcenter) * dfYDim); dfULYMap = yulcenter - (dfYDim/2); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ double dfULXMap = 0.5; double xulcenter = 0.0; value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter= static_cast<float>( CPLAtof(value) ); xulcenter = ((xulcenter) * dfXDim); dfULXMap = xulcenter - (dfXDim/2); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME"); /*********** Grab MAP_PROJECTION_TYPE ************/ CPLString map_proj_name = poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE"); poDS->CleanString( map_proj_name ); /*********** Grab SEMI-MAJOR ************/ const double semi_major = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0; /*********** Grab semi-minor ************/ const double semi_minor = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ const double center_lat = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ const double center_lon = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE")); /*********** Grab 1st std parallel ************/ const double first_std_parallel = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL")); /*********** Grab 2nd std parallel ************/ const double second_std_parallel = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over bool bIsGeographic = true; value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE"); if (EQUAL( value, "\"PLANETOCENTRIC\"" )) bIsGeographic = false; CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() ); OGRSpatialReference oSRS; bool bProjectionSet = true; //Set oSRS projection and parameters if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "") ) { /* no projection */ bProjectionSet = false; } else { CPLDebug( "ISIS2", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = false; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword const CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System const CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet const CPLString datum_name = "D_" + target_name; // Might not be IAU defined so don't add. CPLString sphere_name = target_name; // + "_IAU_IAG"); //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) double iflattening = 0.0; if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { // ISIS uses the spherical equation for these projections so force // a sphere. oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); if (center_lon == 0) { //No need to calculate local radius oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { const double radLat = center_lat * M_PI / 180; // in radians const double localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); CPLDebug( "ISIS2", "local radius: %f", localRadius); } } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = nullptr; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS2 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( !GDALCheckDatasetDimensions(nCols, nRows) || !GDALCheckBandCount(nBands, false) ) { delete poDS; return nullptr; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osTargetFile, "rb" ); else poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" ); if( poDS->fpImage == nullptr ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); delete poDS; return nullptr; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSizeBytes(eDataType); int nLineOffset, nPixelOffset; vsi_l_offset nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; if( nPixelOffset > INT_MAX / nBands ) { delete poDS; return nullptr; } nLineOffset = nPixelOffset * nCols; nBandOffset = nItemSize; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; if( nPixelOffset > INT_MAX / nCols ) { delete poDS; return nullptr; } nLineOffset = nPixelOffset * nCols; nBandOffset = static_cast<vsi_l_offset>(nLineOffset) * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; if( nPixelOffset > INT_MAX / nBands || nPixelOffset * nBands > INT_MAX / nCols ) { delete poDS; return nullptr; } nLineOffset = nItemSize * nBands * nCols; nBandOffset = static_cast<vsi_l_offset>(nItemSize) * nCols; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = nBands; for( int i = 0; i < poDS->nBands; i++ ) { RawRasterBand *poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( bNoDataSet ) poBand->SetNoDataValue( dfNoData ); poDS->SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For isis2 I would like to keep this in */ /* -------------------------------------------------------------------- */ const CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); const CPLString osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); VSILFILE *fp = VSIFOpenL( pszPrjFile, "r" ); if( fp != nullptr ) { VSIFCloseL( fp ); char **papszLines = CSLLoad( pszPrjFile ); OGRSpatialReference oSRS2; if( oSRS2.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = nullptr; oSRS2.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULXMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }