OGRSpatialReference* OGRGetGeomediaSRS(OGRFeature* poFeature) { if (poFeature == NULL) return NULL; int nGeodeticDatum = poFeature->GetFieldAsInteger("GeodeticDatum"); int nEllipsoid = poFeature->GetFieldAsInteger("Ellipsoid"); int nProjAlgorithm = poFeature->GetFieldAsInteger("ProjAlgorithm"); if (nGeodeticDatum == 17 && nEllipsoid == 22) { if (nProjAlgorithm == 12) { OGRSpatialReference* poSRS = new OGRSpatialReference(); const char* pszDescription = poFeature->GetFieldAsString("Description"); if (pszDescription && pszDescription[0] != 0) poSRS->SetNode( "PROJCS", pszDescription ); poSRS->SetWellKnownGeogCS("WGS84"); double dfStdP1 = poFeature->GetFieldAsDouble("StandPar1"); double dfStdP2 = poFeature->GetFieldAsDouble("StandPar2"); double dfCenterLat = poFeature->GetFieldAsDouble("LatOfOrigin"); double dfCenterLong = poFeature->GetFieldAsDouble("LonOfOrigin"); double dfFalseEasting = poFeature->GetFieldAsDouble("FalseX"); double dfFalseNorthing = poFeature->GetFieldAsDouble("FalseY"); poSRS->SetACEA( dfStdP1, dfStdP2, dfCenterLat, dfCenterLong, dfFalseEasting, dfFalseNorthing ); return poSRS; } } return NULL; }
int USGSDEMDataset::LoadFromFile(VSILFILE *InDem) { // check for version of DEM format CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 864, 0)); // Read DEM into matrix const int nRow = ReadInt(InDem); const int nColumn = ReadInt(InDem); const bool bNewFormat = VSIFTellL(InDem) >= 1024 || nRow != 1 || nColumn != 1; if (bNewFormat) { CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 1024, 0)); // New Format int i = ReadInt(InDem); int j = ReadInt(InDem); if ( i != 1 || ( j != 1 && j != 0 ) ) // File OK? { CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 893, 0)); // Undocumented Format (39109h1.dem) i = ReadInt(InDem); j = ReadInt(InDem); if ( i != 1 || j != 1 ) // File OK? { CPLError( CE_Failure, CPLE_AppDefined, "Does not appear to be a USGS DEM file." ); return FALSE; } else nDataStartOffset = 893; } else nDataStartOffset = 1024; } else nDataStartOffset = 864; CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 156, 0)); const int nCoordSystem = ReadInt(InDem); const int iUTMZone = ReadInt(InDem); CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 528, 0)); const int nGUnit = ReadInt(InDem); const int nVUnit = ReadInt(InDem); // Vertical Units in meters if (nVUnit==1) pszUnits = "ft"; else pszUnits = "m"; CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 816, 0)); const double dxdelta = DConvert(InDem, 12); const double dydelta = DConvert(InDem, 12); if( dydelta == 0 ) return FALSE; fVRes = DConvert(InDem, 12); /* -------------------------------------------------------------------- */ /* Should we treat this as floating point, or GInt16. */ /* -------------------------------------------------------------------- */ if (nVUnit==1 || fVRes < 1.0) eNaturalDataFormat = GDT_Float32; else eNaturalDataFormat = GDT_Int16; /* -------------------------------------------------------------------- */ /* Read four corner coordinates. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 546, 0)); DPoint2 corners[4]; // SW, NW, NE, SE for (int i = 0; i < 4; i++) { corners[i].x = DConvert(InDem, 24); corners[i].y = DConvert(InDem, 24); } // find absolute extents of raw vales DPoint2 extent_min, extent_max; extent_min.x = std::min(corners[0].x, corners[1].x); extent_max.x = std::max(corners[2].x, corners[3].x); extent_min.y = std::min(corners[0].y, corners[3].y); extent_max.y = std::max(corners[1].y, corners[2].y); /* dElevMin = */ DConvert(InDem, 48); /* dElevMax = */ DConvert(InDem, 48); CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 858, 0)); const int nProfiles = ReadInt(InDem); /* -------------------------------------------------------------------- */ /* Collect the spatial reference system. */ /* -------------------------------------------------------------------- */ OGRSpatialReference sr; bool bNAD83 = true; // OLD format header ends at byte 864 if (bNewFormat) { // year of data compilation CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 876, 0)); char szDateBuffer[5]; CPL_IGNORE_RET_VAL(VSIFReadL(szDateBuffer, 4, 1, InDem)); /* szDateBuffer[4] = 0; */ // Horizontal datum // 1=North American Datum 1927 (NAD 27) // 2=World Geodetic System 1972 (WGS 72) // 3=WGS 84 // 4=NAD 83 // 5=Old Hawaii Datum // 6=Puerto Rico Datum CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 890, 0)); char szHorzDatum[3]; CPL_IGNORE_RET_VAL(VSIFReadL( szHorzDatum, 1, 2, InDem )); szHorzDatum[2] = '\0'; const int datum = atoi(szHorzDatum); switch (datum) { case 1: sr.SetWellKnownGeogCS( "NAD27" ); bNAD83 = false; break; case 2: sr.SetWellKnownGeogCS( "WGS72" ); break; case 3: sr.SetWellKnownGeogCS( "WGS84" ); break; case 4: sr.SetWellKnownGeogCS( "NAD83" ); break; case -9: break; default: sr.SetWellKnownGeogCS( "NAD27" ); break; } } else { sr.SetWellKnownGeogCS( "NAD27" ); bNAD83 = false; } if (nCoordSystem == 1) // UTM { if( iUTMZone >= -60 && iUTMZone <= 60 ) { sr.SetUTM( abs(iUTMZone), iUTMZone >= 0 ); if( nGUnit == 1 ) { sr.SetLinearUnitsAndUpdateParameters( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) ); char szUTMName[128]; snprintf( szUTMName, sizeof(szUTMName), "UTM Zone %d, Northern Hemisphere, us-ft", iUTMZone ); sr.SetNode( "PROJCS", szUTMName ); } } } else if (nCoordSystem == 2) // state plane { if( nGUnit == 1 ) sr.SetStatePlane( iUTMZone, bNAD83, "Foot", CPLAtof(SRS_UL_US_FOOT_CONV) ); else sr.SetStatePlane( iUTMZone, bNAD83 ); } sr.exportToWkt( &pszProjection ); /* -------------------------------------------------------------------- */ /* For UTM we use the extents (really the UTM coordinates of */ /* the lat/long corners of the quad) to determine the size in */ /* pixels and lines, but we have to make the anchors be modulus */ /* the pixel size which what really gets used. */ /* -------------------------------------------------------------------- */ if (nCoordSystem == 1 // UTM || nCoordSystem == 2 // State Plane || nCoordSystem == -9999 ) // unknown { // expand extents modulus the pixel size. extent_min.y = floor(extent_min.y/dydelta) * dydelta; extent_max.y = ceil(extent_max.y/dydelta) * dydelta; // Forcibly compute X extents based on first profile and pixelsize. CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, nDataStartOffset, 0)); /* njunk = */ ReadInt(InDem); /* njunk = */ ReadInt(InDem); /* njunk = */ ReadInt(InDem); /* njunk = */ ReadInt(InDem); const double dxStart = DConvert(InDem, 24); nRasterYSize = static_cast<int>( ( extent_max.y - extent_min.y ) / dydelta + 1.5 ); nRasterXSize = nProfiles; adfGeoTransform[0] = dxStart - dxdelta/2.0; adfGeoTransform[1] = dxdelta; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = extent_max.y + dydelta/2.0; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dydelta; } /* -------------------------------------------------------------------- */ /* Geographic -- use corners directly. */ /* -------------------------------------------------------------------- */ else { nRasterYSize = static_cast<int>( ( extent_max.y - extent_min.y ) / dydelta + 1.5 ); nRasterXSize = nProfiles; // Translate extents from arc-seconds to decimal degrees. adfGeoTransform[0] = (extent_min.x - dxdelta/2.0) / 3600.0; adfGeoTransform[1] = dxdelta / 3600.0; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = (extent_max.y + dydelta/2.0) / 3600.0; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (-dydelta) / 3600.0; } if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize)) { return FALSE; } return TRUE; }