1 : /**********************************************************************
2 : * $Id: gmlfeature.cpp 25579 2013-01-29 18:53:52Z rouault $
3 : *
4 : * Project: GML Reader
5 : * Purpose: Implementation of GMLFeature.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : **********************************************************************
9 : * Copyright (c) 2002, Frank Warmerdam
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 OR
22 : * 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 "gmlreader.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : /************************************************************************/
35 : /* GMLFeature() */
36 : /************************************************************************/
37 :
38 10769 : GMLFeature::GMLFeature( GMLFeatureClass *poClass )
39 :
40 : {
41 10769 : m_poClass = poClass;
42 10769 : m_pszFID = NULL;
43 :
44 10769 : m_nPropertyCount = 0;
45 10769 : m_pasProperties = NULL;
46 :
47 10769 : m_nGeometryCount = 0;
48 10769 : m_papsGeometry = m_apsGeometry;
49 10769 : m_apsGeometry[0] = NULL;
50 10769 : m_apsGeometry[1] = NULL;
51 :
52 10769 : m_papszOBProperties = NULL;
53 10769 : }
54 :
55 : /************************************************************************/
56 : /* ~GMLFeature() */
57 : /************************************************************************/
58 :
59 10769 : GMLFeature::~GMLFeature()
60 :
61 : {
62 10769 : CPLFree( m_pszFID );
63 :
64 : int i;
65 74967 : for( i = 0; i < m_nPropertyCount; i++ )
66 : {
67 64198 : int nSubProperties = m_pasProperties[i].nSubProperties;
68 64198 : if (nSubProperties == 1)
69 51283 : CPLFree( m_pasProperties[i].aszSubProperties[0] );
70 12915 : else if (nSubProperties > 1)
71 : {
72 690 : for( int j = 0; j < nSubProperties; j++)
73 494 : CPLFree( m_pasProperties[i].papszSubProperties[j] );
74 196 : CPLFree( m_pasProperties[i].papszSubProperties );
75 : }
76 : }
77 :
78 10769 : if (m_nGeometryCount == 1)
79 : {
80 8698 : CPLDestroyXMLNode(m_apsGeometry[0]);
81 : }
82 2071 : else if (m_nGeometryCount > 1)
83 : {
84 0 : for(i=0;i<m_nGeometryCount;i++)
85 0 : CPLDestroyXMLNode(m_papsGeometry[i]);
86 0 : CPLFree(m_papsGeometry);
87 : }
88 :
89 10769 : CPLFree( m_pasProperties );
90 10769 : CSLDestroy( m_papszOBProperties );
91 10769 : }
92 :
93 : /************************************************************************/
94 : /* SetFID() */
95 : /************************************************************************/
96 :
97 1118 : void GMLFeature::SetFID( const char *pszFID )
98 :
99 : {
100 1118 : CPLFree( m_pszFID );
101 1118 : if( pszFID != NULL )
102 1118 : m_pszFID = CPLStrdup( pszFID );
103 : else
104 0 : m_pszFID = NULL;
105 1118 : }
106 :
107 : /************************************************************************/
108 : /* SetPropertyDirectly() */
109 : /************************************************************************/
110 :
111 51777 : void GMLFeature::SetPropertyDirectly( int iIndex, char *pszValue )
112 :
113 : {
114 51777 : CPLAssert(pszValue);
115 51777 : if( iIndex >= m_nPropertyCount )
116 : {
117 10568 : int nClassPropertyCount = m_poClass->GetPropertyCount();
118 : m_pasProperties = (GMLProperty*)
119 : CPLRealloc( m_pasProperties,
120 10568 : sizeof(GMLProperty) * nClassPropertyCount );
121 : int i;
122 10974 : for( i = 0; i < m_nPropertyCount; i ++ )
123 : {
124 : /* Make sure papszSubProperties point to the right address in case */
125 : /* m_pasProperties has been relocated */
126 406 : if (m_pasProperties[i].nSubProperties <= 1)
127 406 : m_pasProperties[i].papszSubProperties = m_pasProperties[i].aszSubProperties;
128 : }
129 74766 : for( i = m_nPropertyCount; i < nClassPropertyCount; i++ )
130 : {
131 64198 : m_pasProperties[i].nSubProperties = 0;
132 64198 : m_pasProperties[i].papszSubProperties = m_pasProperties[i].aszSubProperties;
133 64198 : m_pasProperties[i].aszSubProperties[0] = NULL;
134 64198 : m_pasProperties[i].aszSubProperties[1] = NULL;
135 : }
136 10568 : m_nPropertyCount = nClassPropertyCount;
137 : }
138 :
139 51777 : GMLProperty* psProperty = &m_pasProperties[iIndex];
140 51777 : int nSubProperties = psProperty->nSubProperties;
141 51777 : if (nSubProperties == 0)
142 51479 : psProperty->aszSubProperties[0] = pszValue;
143 298 : else if (nSubProperties == 1)
144 : {
145 : psProperty->papszSubProperties = (char**) CPLMalloc(
146 196 : sizeof(char*) * (nSubProperties + 2) );
147 196 : psProperty->papszSubProperties[0] = psProperty->aszSubProperties[0];
148 196 : psProperty->aszSubProperties[0] = NULL;
149 196 : psProperty->papszSubProperties[nSubProperties] = pszValue;
150 196 : psProperty->papszSubProperties[nSubProperties + 1] = NULL;
151 : }
152 : else
153 : {
154 : psProperty->papszSubProperties = (char**) CPLRealloc(
155 : psProperty->papszSubProperties,
156 102 : sizeof(char*) * (nSubProperties + 2) );
157 102 : psProperty->papszSubProperties[nSubProperties] = pszValue;
158 102 : psProperty->papszSubProperties[nSubProperties + 1] = NULL;
159 : }
160 51777 : psProperty->nSubProperties ++;
161 51777 : }
162 :
163 : /************************************************************************/
164 : /* Dump() */
165 : /************************************************************************/
166 :
167 0 : void GMLFeature::Dump( FILE * fp )
168 :
169 : {
170 0 : printf( "GMLFeature(%s):\n", m_poClass->GetName() );
171 :
172 0 : if( m_pszFID != NULL )
173 0 : printf( " FID = %s\n", m_pszFID );
174 :
175 : int i;
176 0 : for( i = 0; i < m_nPropertyCount; i++ )
177 : {
178 0 : const GMLProperty * psGMLProperty = GetProperty( i );
179 0 : printf( " %s = ", m_poClass->GetProperty( i )->GetName());
180 0 : for ( int j = 0; j < psGMLProperty->nSubProperties; j ++)
181 : {
182 0 : if (j > 0) printf(", ");
183 0 : printf("%s", psGMLProperty->papszSubProperties[j]);
184 : }
185 0 : printf("\n");
186 : }
187 :
188 0 : for(i=0;i<m_nGeometryCount;i++)
189 : {
190 0 : char* pszXML = CPLSerializeXMLTree(m_papsGeometry[i]);
191 0 : printf( " %s\n", pszXML );
192 0 : CPLFree(pszXML);
193 : }
194 0 : }
195 :
196 : /************************************************************************/
197 : /* SetGeometryDirectly() */
198 : /************************************************************************/
199 :
200 8698 : void GMLFeature::SetGeometryDirectly( CPLXMLNode* psGeom )
201 :
202 : {
203 8698 : if (m_apsGeometry[0] != NULL)
204 0 : CPLDestroyXMLNode(m_apsGeometry[0]);
205 8698 : m_nGeometryCount = 1;
206 8698 : m_apsGeometry[0] = psGeom;
207 8698 : }
208 :
209 : /************************************************************************/
210 : /* AddGeometry() */
211 : /************************************************************************/
212 :
213 0 : void GMLFeature::AddGeometry( CPLXMLNode* psGeom )
214 :
215 : {
216 0 : if (m_nGeometryCount == 0)
217 : {
218 0 : m_apsGeometry[0] = psGeom;
219 : }
220 0 : else if (m_nGeometryCount == 1)
221 : {
222 : m_papsGeometry = (CPLXMLNode **) CPLMalloc(
223 0 : (m_nGeometryCount + 2) * sizeof(CPLXMLNode *));
224 0 : m_papsGeometry[0] = m_apsGeometry[0];
225 0 : m_apsGeometry[0] = NULL;
226 0 : m_papsGeometry[m_nGeometryCount] = psGeom;
227 0 : m_papsGeometry[m_nGeometryCount + 1] = NULL;
228 : }
229 : else
230 : {
231 : m_papsGeometry = (CPLXMLNode **) CPLRealloc(m_papsGeometry,
232 0 : (m_nGeometryCount + 2) * sizeof(CPLXMLNode *));
233 0 : m_papsGeometry[m_nGeometryCount] = psGeom;
234 0 : m_papsGeometry[m_nGeometryCount + 1] = NULL;
235 : }
236 0 : m_nGeometryCount ++;
237 0 : }
238 :
239 : /************************************************************************/
240 : /* AddOBProperty() */
241 : /************************************************************************/
242 :
243 2508 : void GMLFeature::AddOBProperty( const char *pszName, const char *pszValue )
244 :
245 : {
246 : m_papszOBProperties =
247 2508 : CSLAddNameValue( m_papszOBProperties, pszName, pszValue );
248 2508 : }
249 :
250 : /************************************************************************/
251 : /* GetOBProperty() */
252 : /************************************************************************/
253 :
254 0 : const char *GMLFeature::GetOBProperty( const char *pszName )
255 :
256 : {
257 0 : return CSLFetchNameValue( m_papszOBProperties, pszName );
258 : }
259 :
260 : /************************************************************************/
261 : /* GetOBProperties() */
262 : /************************************************************************/
263 :
264 8392 : char **GMLFeature::GetOBProperties()
265 :
266 : {
267 8392 : return m_papszOBProperties;
268 : }
|