EVOLUTION-MANAGER
Edit File: gdalgmlcoverage.cpp
/****************************************************************************** * * Project: GDAL * Purpose: Generic support for GML Coverage descriptions. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2006, Frank Warmerdam <warmerdam@pobox.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "cpl_port.h" #include "gdal_priv.h" #include <cstdlib> #include <cstring> #include "cpl_conv.h" #include "cpl_error.h" #include "cpl_minixml.h" #include "cpl_string.h" #include "ogr_api.h" #include "ogr_core.h" #include "ogr_geometry.h" #include "ogr_spatialref.h" CPL_CVSID("$Id: gdalgmlcoverage.cpp 36523 2016-11-27 04:13:26Z goatbar $"); /************************************************************************/ /* ParseGMLCoverageDesc() */ /************************************************************************/ CPLErr GDALParseGMLCoverage( CPLXMLNode *psXML, int *pnXSize, int *pnYSize, double *padfGeoTransform, char **ppszProjection ) { CPLStripXMLNamespace( psXML, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* Isolate RectifiedGrid. Eventually we will need to support */ /* other georeferencing objects. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRG = CPLSearchXMLNode( psXML, "=RectifiedGrid" ); CPLXMLNode *psOriginPoint = NULL; const char *pszOffset1 = NULL; const char *pszOffset2 = NULL; if( psRG != NULL ) { psOriginPoint = CPLGetXMLNode( psRG, "origin.Point" ); if( psOriginPoint == NULL ) psOriginPoint = CPLGetXMLNode( psRG, "origin" ); CPLXMLNode *psOffset1 = CPLGetXMLNode( psRG, "offsetVector" ); if( psOffset1 != NULL ) { pszOffset1 = CPLGetXMLValue( psOffset1, "", NULL ); pszOffset2 = CPLGetXMLValue( psOffset1->psNext, "=offsetVector", NULL ); } } /* -------------------------------------------------------------------- */ /* If we are missing any of the origin or 2 offsets then give up. */ /* -------------------------------------------------------------------- */ if( psRG == NULL || psOriginPoint == NULL || pszOffset1 == NULL || pszOffset2 == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find GML RectifiedGrid, origin or offset vectors"); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Search for the GridEnvelope and derive the raster size. */ /* -------------------------------------------------------------------- */ char **papszLow = CSLTokenizeString( CPLGetXMLValue( psRG, "limits.GridEnvelope.low", "")); char **papszHigh = CSLTokenizeString( CPLGetXMLValue( psRG, "limits.GridEnvelope.high","")); if( CSLCount(papszLow) < 2 || CSLCount(papszHigh) < 2 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find or parse GridEnvelope.low/high." ); CSLDestroy( papszLow ); CSLDestroy( papszHigh ); return CE_Failure; } if( pnXSize != NULL ) *pnXSize = atoi(papszHigh[0]) - atoi(papszLow[0]) + 1; if( pnYSize != NULL ) *pnYSize = atoi(papszHigh[1]) - atoi(papszLow[1]) + 1; CSLDestroy( papszLow ); CSLDestroy( papszHigh ); /* -------------------------------------------------------------------- */ /* Extract origin location. */ /* -------------------------------------------------------------------- */ OGRPoint *poOriginGeometry = NULL; const char *pszSRSName = NULL; if( psOriginPoint != NULL ) { bool bOldWrap = false; // Old coverages (i.e. WCS) just have <pos> under <origin>, so we // may need to temporarily force <origin> to <Point>. if( psOriginPoint->eType == CXT_Element && EQUAL(psOriginPoint->pszValue, "origin") ) { strcpy( psOriginPoint->pszValue, "Point"); bOldWrap = true; } poOriginGeometry = reinterpret_cast<OGRPoint *>( OGR_G_CreateFromGMLTree( psOriginPoint ) ); if( poOriginGeometry != NULL && wkbFlatten(poOriginGeometry->getGeometryType()) != wkbPoint ) { delete poOriginGeometry; poOriginGeometry = NULL; } if( bOldWrap ) strcpy( psOriginPoint->pszValue, "origin"); // SRS? pszSRSName = CPLGetXMLValue( psOriginPoint, "srsName", NULL ); } /* -------------------------------------------------------------------- */ /* Extract offset(s) */ /* -------------------------------------------------------------------- */ char **papszOffset1Tokens = NULL; char **papszOffset2Tokens = NULL; bool bSuccess = false; papszOffset1Tokens = CSLTokenizeStringComplex( pszOffset1, " ,", FALSE, FALSE ); papszOffset2Tokens = CSLTokenizeStringComplex( pszOffset2, " ,", FALSE, FALSE ); if( CSLCount(papszOffset1Tokens) >= 2 && CSLCount(papszOffset2Tokens) >= 2 && poOriginGeometry != NULL ) { padfGeoTransform[0] = poOriginGeometry->getX(); padfGeoTransform[1] = CPLAtof(papszOffset1Tokens[0]); padfGeoTransform[2] = CPLAtof(papszOffset1Tokens[1]); padfGeoTransform[3] = poOriginGeometry->getY(); padfGeoTransform[4] = CPLAtof(papszOffset2Tokens[0]); padfGeoTransform[5] = CPLAtof(papszOffset2Tokens[1]); // offset from center of pixel. padfGeoTransform[0] -= padfGeoTransform[1]*0.5; padfGeoTransform[0] -= padfGeoTransform[2]*0.5; padfGeoTransform[3] -= padfGeoTransform[4]*0.5; padfGeoTransform[3] -= padfGeoTransform[5]*0.5; bSuccess = true; //bHaveGeoTransform = TRUE; } CSLDestroy( papszOffset1Tokens ); CSLDestroy( papszOffset2Tokens ); if( poOriginGeometry != NULL ) delete poOriginGeometry; /* -------------------------------------------------------------------- */ /* If we have gotten a geotransform, then try to interpret the */ /* srsName. */ /* -------------------------------------------------------------------- */ if( bSuccess && pszSRSName != NULL && (*ppszProjection == NULL || strlen(*ppszProjection) == 0) ) { if( STARTS_WITH_CI(pszSRSName, "epsg:") ) { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszSRSName ) == OGRERR_NONE ) oSRS.exportToWkt( ppszProjection ); } else if( STARTS_WITH_CI(pszSRSName, "urn:ogc:def:crs:") ) { OGRSpatialReference oSRS; if( oSRS.importFromURN( pszSRSName ) == OGRERR_NONE ) oSRS.exportToWkt( ppszProjection ); } else *ppszProjection = CPLStrdup(pszSRSName); } if( *ppszProjection ) CPLDebug( "GDALJP2Metadata", "Got projection from GML box: %s", *ppszProjection ); return CE_None; }