1 : /******************************************************************************
2 : * $Id: gdalgmlcoverage.cpp 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: GDAL
5 : * Purpose: Generic support for GML Coverage descriptions.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2006, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gdal_priv.h"
31 : #include "cpl_string.h"
32 : #include "cpl_minixml.h"
33 : #include "ogr_spatialref.h"
34 : #include "ogr_geometry.h"
35 : #include "ogr_api.h"
36 :
37 : CPL_CVSID("$Id: gdalgmlcoverage.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
38 :
39 : /************************************************************************/
40 : /* ParseGMLCoverageDesc() */
41 : /************************************************************************/
42 :
43 0 : CPLErr GDALParseGMLCoverage( CPLXMLNode *psXML,
44 : int *pnXSize, int *pnYSize,
45 : double *padfGeoTransform,
46 : char **ppszProjection )
47 :
48 : {
49 0 : CPLStripXMLNamespace( psXML, NULL, TRUE );
50 :
51 : /* -------------------------------------------------------------------- */
52 : /* Isolate RectifiedGrid. Eventually we will need to support */
53 : /* other georeferencing objects. */
54 : /* -------------------------------------------------------------------- */
55 0 : CPLXMLNode *psRG = CPLSearchXMLNode( psXML, "=RectifiedGrid" );
56 0 : CPLXMLNode *psOriginPoint = NULL;
57 0 : const char *pszOffset1=NULL, *pszOffset2=NULL;
58 :
59 0 : if( psRG != NULL )
60 : {
61 0 : psOriginPoint = CPLGetXMLNode( psRG, "origin.Point" );
62 0 : if( psOriginPoint == NULL )
63 0 : psOriginPoint = CPLGetXMLNode( psRG, "origin" );
64 :
65 0 : CPLXMLNode *psOffset1 = CPLGetXMLNode( psRG, "offsetVector" );
66 0 : if( psOffset1 != NULL )
67 : {
68 0 : pszOffset1 = CPLGetXMLValue( psOffset1, "", NULL );
69 : pszOffset2 = CPLGetXMLValue( psOffset1->psNext, "=offsetVector",
70 0 : NULL );
71 : }
72 : }
73 :
74 : /* -------------------------------------------------------------------- */
75 : /* If we are missing any of the origin or 2 offsets then give up. */
76 : /* -------------------------------------------------------------------- */
77 0 : if( psRG == NULL || psOriginPoint == NULL
78 : || pszOffset1 == NULL || pszOffset2 == NULL )
79 : {
80 : CPLError( CE_Failure, CPLE_AppDefined,
81 0 : "Unable to find GML RectifiedGrid, origin or offset vectors");
82 0 : return CE_Failure;
83 : }
84 :
85 : /* -------------------------------------------------------------------- */
86 : /* Search for the GridEnvelope and derive the raster size. */
87 : /* -------------------------------------------------------------------- */
88 : char **papszLow = CSLTokenizeString(
89 0 : CPLGetXMLValue( psRG, "limits.GridEnvelope.low", ""));
90 : char **papszHigh = CSLTokenizeString(
91 0 : CPLGetXMLValue( psRG, "limits.GridEnvelope.high",""));
92 :
93 0 : if( CSLCount(papszLow) < 2 || CSLCount(papszHigh) < 2 )
94 : {
95 : CPLError( CE_Failure, CPLE_AppDefined,
96 0 : "Unable to find or parse GridEnvelope.low/high." );
97 0 : return CE_Failure;
98 : }
99 :
100 0 : if( pnXSize != NULL )
101 0 : *pnXSize = atoi(papszHigh[0]) - atoi(papszLow[0]) + 1;
102 0 : if( pnYSize != NULL )
103 0 : *pnYSize = atoi(papszHigh[1]) - atoi(papszLow[1]) + 1;
104 :
105 0 : CSLDestroy( papszLow );
106 0 : CSLDestroy( papszHigh );
107 :
108 : /* -------------------------------------------------------------------- */
109 : /* Extract origin location. */
110 : /* -------------------------------------------------------------------- */
111 0 : OGRPoint *poOriginGeometry = NULL;
112 0 : const char *pszSRSName = NULL;
113 :
114 0 : if( psOriginPoint != NULL )
115 : {
116 0 : int bOldWrap = FALSE;
117 :
118 : // old coverages (ie. WCS) just have <pos> under <origin> so we
119 : // may need to temporarily force <origin> to <Point>
120 0 : if( psOriginPoint->eType == CXT_Element
121 : && EQUAL(psOriginPoint->pszValue,"origin") )
122 : {
123 0 : strcpy( psOriginPoint->pszValue, "Point");
124 0 : bOldWrap = TRUE;
125 : }
126 : poOriginGeometry = (OGRPoint *)
127 0 : OGR_G_CreateFromGMLTree( psOriginPoint );
128 :
129 0 : if( poOriginGeometry != NULL
130 0 : && wkbFlatten(poOriginGeometry->getGeometryType()) != wkbPoint )
131 : {
132 0 : delete poOriginGeometry;
133 0 : poOriginGeometry = NULL;
134 : }
135 :
136 0 : if( bOldWrap )
137 0 : strcpy( psOriginPoint->pszValue, "origin");
138 :
139 : // SRS?
140 0 : pszSRSName = CPLGetXMLValue( psOriginPoint, "srsName", NULL );
141 : }
142 :
143 : /* -------------------------------------------------------------------- */
144 : /* Extract offset(s) */
145 : /* -------------------------------------------------------------------- */
146 0 : char **papszOffset1Tokens = NULL;
147 0 : char **papszOffset2Tokens = NULL;
148 0 : int bSuccess = FALSE;
149 :
150 : papszOffset1Tokens =
151 0 : CSLTokenizeStringComplex( pszOffset1, " ,", FALSE, FALSE );
152 : papszOffset2Tokens =
153 0 : CSLTokenizeStringComplex( pszOffset2, " ,", FALSE, FALSE );
154 :
155 0 : if( CSLCount(papszOffset1Tokens) >= 2
156 : && CSLCount(papszOffset2Tokens) >= 2
157 : && poOriginGeometry != NULL )
158 : {
159 0 : padfGeoTransform[0] = poOriginGeometry->getX();
160 0 : padfGeoTransform[1] = atof(papszOffset1Tokens[0]);
161 0 : padfGeoTransform[2] = atof(papszOffset1Tokens[1]);
162 0 : padfGeoTransform[3] = poOriginGeometry->getY();
163 0 : padfGeoTransform[4] = atof(papszOffset2Tokens[0]);
164 0 : padfGeoTransform[5] = atof(papszOffset2Tokens[1]);
165 :
166 : // offset from center of pixel.
167 0 : padfGeoTransform[0] -= padfGeoTransform[1]*0.5;
168 0 : padfGeoTransform[0] -= padfGeoTransform[2]*0.5;
169 0 : padfGeoTransform[3] -= padfGeoTransform[4]*0.5;
170 0 : padfGeoTransform[3] -= padfGeoTransform[5]*0.5;
171 :
172 0 : bSuccess = TRUE;
173 : //bHaveGeoTransform = TRUE;
174 : }
175 :
176 0 : CSLDestroy( papszOffset1Tokens );
177 0 : CSLDestroy( papszOffset2Tokens );
178 :
179 0 : if( poOriginGeometry != NULL )
180 0 : delete poOriginGeometry;
181 :
182 : /* -------------------------------------------------------------------- */
183 : /* If we have gotten a geotransform, then try to interprete the */
184 : /* srsName. */
185 : /* -------------------------------------------------------------------- */
186 0 : if( bSuccess && pszSRSName != NULL
187 : && (*ppszProjection == NULL || strlen(*ppszProjection) == 0) )
188 : {
189 0 : if( EQUALN(pszSRSName,"epsg:",5) )
190 : {
191 0 : OGRSpatialReference oSRS;
192 0 : if( oSRS.SetFromUserInput( pszSRSName ) == OGRERR_NONE )
193 0 : oSRS.exportToWkt( ppszProjection );
194 : }
195 0 : else if( EQUALN(pszSRSName,"urn:ogc:def:crs:",16) )
196 : {
197 0 : OGRSpatialReference oSRS;
198 0 : if( oSRS.importFromURN( pszSRSName ) == OGRERR_NONE )
199 0 : oSRS.exportToWkt( ppszProjection );
200 : }
201 : else
202 0 : *ppszProjection = CPLStrdup(pszSRSName);
203 : }
204 :
205 0 : if( *ppszProjection )
206 : CPLDebug( "GDALJP2Metadata",
207 : "Got projection from GML box: %s",
208 0 : *ppszProjection );
209 :
210 0 : return CE_None;
211 : }
212 :
|