bool LevellerDataset::make_local_coordsys(const char* pszName, const char* pszUnits) { OGRSpatialReference sr; sr.SetLocalCS(pszName); double d; return ( this->convert_measure(1.0, d, pszUnits) && OGRERR_NONE == sr.SetLinearUnits(pszUnits, d) && OGRERR_NONE == sr.exportToWkt(&m_pszProjection) ); }
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 ); }
int TerragenDataset::LoadFromFile() { GUInt16 nSize, xpts=0, ypts=0; m_dSCAL = 30.0; m_nDataOffset = 0; if(0 != VSIFSeekL(m_fp, 16, SEEK_SET)) return 0; char szTag[4]; if(!this->read_next_tag(szTag) || !tag_is(szTag, "SIZE")) return 0; if(!this->get(nSize) || !this->skip(2)) return 0; // Set dimensions to SIZE chunk. If we don't // encounter XPTS/YPTS chunks, we can assume // the terrain to be square. xpts = ypts = nSize+1; while(this->read_next_tag(szTag)) { if(this->tag_is(szTag, "XPTS")) { this->get(xpts); if(xpts < nSize || !this->skip(2)) return 0; continue; } if(this->tag_is(szTag, "YPTS")) { this->get(ypts); if(ypts < nSize || !this->skip(2)) return 0; continue; } if(this->tag_is(szTag, "SCAL")) { float sc[3]; this->get(sc[0]); this->get(sc[1]); this->get(sc[2]); m_dSCAL = sc[1]; continue; } if(this->tag_is(szTag, "CRAD")) { if(!this->skip(sizeof(float))) return 0; continue; } if(this->tag_is(szTag, "CRVM")) { if(!this->skip(sizeof(GUInt32))) return 0; continue; } if(this->tag_is(szTag, "ALTW")) { this->get(m_nHeightScale); this->get(m_nBaseHeight); m_nDataOffset = VSIFTellL(m_fp); if(!this->skip(xpts * ypts * sizeof(GInt16))) return 0; continue; } if(this->tag_is(szTag, "EOF ")) { break; } } if(xpts == 0 || ypts == 0 || m_nDataOffset == 0) return 0; nRasterXSize = xpts; nRasterYSize = ypts; // todo: sanity check: do we have enough pixels? // Cache realworld scaling and offset. m_dScale = m_dSCAL / 65536 * m_nHeightScale; m_dOffset = m_dSCAL * m_nBaseHeight; strcpy(m_szUnits, "m"); // Make our projection to have origin at the // NW corner, and groundscale to match elev scale // (i.e., uniform voxels). m_adfTransform[0] = 0.0; m_adfTransform[1] = m_dSCAL; m_adfTransform[2] = 0.0; m_adfTransform[3] = 0.0; m_adfTransform[4] = 0.0; m_adfTransform[5] = m_dSCAL; /* -------------------------------------------------------------------- */ /* Set projection. */ /* -------------------------------------------------------------------- */ // Terragen files as of Apr 2006 are partially georeferenced, // we can declare a local coordsys that uses meters. OGRSpatialReference sr; sr.SetLocalCS("Terragen world space"); if(OGRERR_NONE != sr.SetLinearUnits("m", 1.0)) return 0; if(OGRERR_NONE != sr.exportToWkt(&m_pszProjection)) return 0; return TRUE; }
GDALDataset *BTDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Verify that this is some form of binterr file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 256) return NULL; if( !STARTS_WITH((const char *) poOpenInfo->pabyHeader, "binterr") ) return NULL; /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ BTDataset *poDS = new BTDataset(); memcpy( poDS->abyHeader, poOpenInfo->pabyHeader, 256 ); /* -------------------------------------------------------------------- */ /* Get the version. */ /* -------------------------------------------------------------------- */ char szVersion[4] = {}; strncpy( szVersion, (char *) (poDS->abyHeader + 7), 3 ); szVersion[3] = '\0'; poDS->nVersionCode = static_cast<int>(CPLAtof(szVersion) * 10); /* -------------------------------------------------------------------- */ /* Extract core header information, being careful about the */ /* version. */ /* -------------------------------------------------------------------- */ GInt32 nIntTemp = 0; memcpy( &nIntTemp, poDS->abyHeader + 10, 4 ); poDS->nRasterXSize = CPL_LSBWORD32( nIntTemp ); memcpy( &nIntTemp, poDS->abyHeader + 14, 4 ); poDS->nRasterYSize = CPL_LSBWORD32( nIntTemp ); if( !GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ) { delete poDS; return NULL; } GInt16 nDataSize = 0; memcpy( &nDataSize, poDS->abyHeader+18, 2 ); nDataSize = CPL_LSBWORD16( nDataSize ); GDALDataType eType = GDT_Unknown; if( poDS->abyHeader[20] != 0 && nDataSize == 4 ) eType = GDT_Float32; else if( poDS->abyHeader[20] == 0 && nDataSize == 4 ) eType = GDT_Int32; else if( poDS->abyHeader[20] == 0 && nDataSize == 2 ) eType = GDT_Int16; else { CPLError( CE_Failure, CPLE_AppDefined, ".bt file data type unknown, got datasize=%d.", nDataSize ); delete poDS; return NULL; } /* rcg, apr 7/06: read offset 62 for vert. units. If zero, assume 1.0 as per spec. */ memcpy( &poDS->m_fVscale, poDS->abyHeader + 62, 4 ); CPL_LSBPTR32(&poDS->m_fVscale); if(poDS->m_fVscale == 0.0f) poDS->m_fVscale = 1.0f; /* -------------------------------------------------------------------- */ /* Try to read a .prj file if it is indicated. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; if( poDS->nVersionCode >= 12 && poDS->abyHeader[60] != 0 ) { const char *pszPrjFile = CPLResetExtension( poOpenInfo->pszFilename, "prj" ); VSILFILE *fp = VSIFOpenL( pszPrjFile, "rt" ); if( fp != NULL ) { const int nBufMax = 10000; char *pszBuffer = static_cast<char *>(CPLMalloc(nBufMax)); const int nBytes = static_cast<int>(VSIFReadL( pszBuffer, 1, nBufMax-1, fp )); CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); pszBuffer[nBytes] = '\0'; char *pszBufPtr = pszBuffer; if( oSRS.importFromWkt( &pszBufPtr ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Unable to parse .prj file, " "coordinate system missing." ); } CPLFree( pszBuffer ); } } /* -------------------------------------------------------------------- */ /* If we didn't find a .prj file, try to use internal info. */ /* -------------------------------------------------------------------- */ if( oSRS.GetRoot() == NULL ) { GInt16 nUTMZone = 0; memcpy( &nUTMZone, poDS->abyHeader + 24, 2 ); nUTMZone = CPL_LSBWORD16( nUTMZone ); GInt16 nDatum = 0; memcpy( &nDatum, poDS->abyHeader + 26, 2 ); nDatum = CPL_LSBWORD16( nDatum ); GInt16 nHUnits = 0; memcpy( &nHUnits, poDS->abyHeader + 22, 2 ); nHUnits = CPL_LSBWORD16( nHUnits ); if( nUTMZone != 0 ) oSRS.SetUTM( std::abs(static_cast<int>(nUTMZone)), nUTMZone > 0 ); else if( nHUnits != 0 ) oSRS.SetLocalCS( "Unknown" ); if( nHUnits == 1 ) oSRS.SetLinearUnits( SRS_UL_METER, 1.0 ); else if( nHUnits == 2 ) oSRS.SetLinearUnits( SRS_UL_FOOT, CPLAtof(SRS_UL_FOOT_CONV) ); else if( nHUnits == 3 ) oSRS.SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) ); // Translate some of the more obvious old USGS datum codes if( nDatum == 0 ) nDatum = 6201; else if( nDatum == 1 ) nDatum = 6209; else if( nDatum == 2 ) nDatum = 6210; else if( nDatum == 3 ) nDatum = 6202; else if( nDatum == 4 ) nDatum = 6203; else if( nDatum == 6 ) nDatum = 6222; else if( nDatum == 7 ) nDatum = 6230; else if( nDatum == 13 ) nDatum = 6267; else if( nDatum == 14 ) nDatum = 6269; else if( nDatum == 17 ) nDatum = 6277; else if( nDatum == 19 ) nDatum = 6284; else if( nDatum == 21 ) nDatum = 6301; else if( nDatum == 22 ) nDatum = 6322; else if( nDatum == 23 ) nDatum = 6326; if( !oSRS.IsLocal() ) { if( nDatum >= 6000 ) { char szName[32]; snprintf( szName, sizeof(szName), "EPSG:%d", nDatum-2000 ); oSRS.SetWellKnownGeogCS( szName ); } else oSRS.SetWellKnownGeogCS( "WGS84" ); } } /* -------------------------------------------------------------------- */ /* Convert coordinate system back to WKT. */ /* -------------------------------------------------------------------- */ if( oSRS.GetRoot() != NULL ) oSRS.exportToWkt( &poDS->pszProjection ); /* -------------------------------------------------------------------- */ /* Get georeferencing bounds. */ /* -------------------------------------------------------------------- */ if( poDS->nVersionCode >= 11 ) { double dfLeft = 0.0; memcpy( &dfLeft, poDS->abyHeader + 28, 8 ); CPL_LSBPTR64( &dfLeft ); double dfRight = 0.0; memcpy( &dfRight, poDS->abyHeader + 36, 8 ); CPL_LSBPTR64( &dfRight ); double dfBottom = 0.0; memcpy( &dfBottom, poDS->abyHeader + 44, 8 ); CPL_LSBPTR64( &dfBottom ); double dfTop = 0.0; memcpy( &dfTop, poDS->abyHeader + 52, 8 ); CPL_LSBPTR64( &dfTop ); poDS->adfGeoTransform[0] = dfLeft; poDS->adfGeoTransform[1] = (dfRight - dfLeft) / poDS->nRasterXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfTop; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = (dfBottom - dfTop) / poDS->nRasterYSize; poDS->bGeoTransformValid = TRUE; } /* -------------------------------------------------------------------- */ /* Re-open the file with the desired access. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to re-open %s within BT driver.\n", poOpenInfo->pszFilename ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Create band information objects */ /* -------------------------------------------------------------------- */ poDS->SetBand( 1, new BTRasterBand( poDS, poDS->fpImage, eType ) ); #ifdef notdef poDS->bGeoTransformValid = GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", poDS->adfGeoTransform ); #endif /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
static OGRErr importGeogCSFromXML(OGRSpatialReference *poSRS, CPLXMLNode *psCRS) { const char *pszGeogName, *pszDatumName, *pszEllipsoidName, *pszPMName; double dfSemiMajor, dfInvFlattening, dfPMOffset = 0.0; /* -------------------------------------------------------------------- */ /* Set the GEOGCS name from the srsName. */ /* -------------------------------------------------------------------- */ pszGeogName = CPLGetXMLValue(psCRS, "srsName", "Unnamed GeogCS"); /* -------------------------------------------------------------------- */ /* If we don't seem to have a detailed coordinate system */ /* definition, check if we can define based on an EPSG code. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDatum; psDatum = CPLGetXMLNode(psCRS, "usesGeodeticDatum.GeodeticDatum"); if (psDatum == NULL) { OGRSpatialReference oIdSRS; oIdSRS.SetLocalCS("dummy"); importXMLAuthority(psCRS, &oIdSRS, "srsID", "LOCAL_CS"); if (oIdSRS.GetAuthorityCode("LOCAL_CS") != NULL && oIdSRS.GetAuthorityName("LOCAL_CS") != NULL && EQUAL(oIdSRS.GetAuthorityName("LOCAL_CS"), "EPSG")) { return poSRS->importFromEPSG( atoi(oIdSRS.GetAuthorityCode("LOCAL_CS"))); } } /* -------------------------------------------------------------------- */ /* Get datum name. */ /* -------------------------------------------------------------------- */ pszDatumName = CPLGetXMLValue(psDatum, "datumName", "Unnamed Datum"); /* -------------------------------------------------------------------- */ /* Get ellipsoid information. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psE; psE = CPLGetXMLNode(psDatum, "usesEllipsoid.Ellipsoid"); pszEllipsoidName = CPLGetXMLValue(psE, "ellipsoidName", "Unnamed Ellipsoid"); dfSemiMajor = getNormalizedValue(psE, "semiMajorAxis", "Linear", SRS_WGS84_SEMIMAJOR); dfInvFlattening = getNormalizedValue(psE, "secondDefiningParameter.inverseFlattening", "Unitless", 0.0); if (dfInvFlattening == 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Ellipsoid inverseFlattening corrupt or missing."); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* Get the prime meridian. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psPM; psPM = CPLGetXMLNode(psDatum, "usesPrimeMeridian.PrimeMeridian"); if (psPM == NULL) { pszPMName = "Greenwich"; dfPMOffset = 0.0; } else { pszPMName = CPLGetXMLValue(psPM, "meridianName", "Unnamed Prime Meridian"); dfPMOffset = getNormalizedValue(psPM, "greenwichLongitude.angle", "Angular", 0.0); } /* -------------------------------------------------------------------- */ /* Set the geographic definition. */ /* -------------------------------------------------------------------- */ poSRS->SetGeogCS(pszGeogName, pszDatumName, pszEllipsoidName, dfSemiMajor, dfInvFlattening, pszPMName, dfPMOffset); /* -------------------------------------------------------------------- */ /* Look for angular units. We don't check that all axes match */ /* at this time. */ /* -------------------------------------------------------------------- */ #ifdef notdef CPLXMLNode *psAxis; psAxis = CPLGetXMLNode(psGeo2DCRS, "EllipsoidalCoordinateSystem.CoordinateAxis"); importXMLUnits(psAxis, "AngularUnit", poSRS, "GEOGCS"); #endif /* -------------------------------------------------------------------- */ /* Can we set authorities for any of the levels? */ /* -------------------------------------------------------------------- */ importXMLAuthority(psCRS, poSRS, "srsID", "GEOGCS"); importXMLAuthority(psDatum, poSRS, "datumID", "GEOGCS|DATUM"); importXMLAuthority(psE, poSRS, "ellipsoidID", "GEOGCS|DATUM|SPHEROID"); importXMLAuthority(psDatum, poSRS, "usesPrimeMeridian.PrimeMeridian.meridianID", "GEOGCS|PRIMEM"); poSRS->Fixup(); return OGRERR_NONE; }