1 : /******************************************************************************
2 : * $Id: ogrili2layer.cpp 23895 2012-02-04 11:21:18Z rouault $
3 : *
4 : * Project: Interlis 2 Translator
5 : * Purpose: Implements OGRILI2Layer class.
6 : * Author: Markus Schnider, Sourcepole AG
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
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 "ogr_ili2.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ogrili2layer.cpp 23895 2012-02-04 11:21:18Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRILI2Layer() */
38 : /************************************************************************/
39 :
40 13 : OGRILI2Layer::OGRILI2Layer( const char * pszName,
41 : OGRSpatialReference *poSRSIn, int bWriterIn,
42 : OGRwkbGeometryType eReqType,
43 13 : OGRILI2DataSource *poDSIn )
44 :
45 : {
46 13 : if( poSRSIn == NULL )
47 13 : poSRS = NULL;
48 : else
49 0 : poSRS = poSRSIn->Clone();
50 :
51 13 : poDS = poDSIn;
52 :
53 13 : poFeatureDefn = new OGRFeatureDefn( pszName );
54 13 : poFeatureDefn->Reference();
55 13 : poFeatureDefn->SetGeomType( eReqType );
56 :
57 13 : bWriter = bWriterIn;
58 :
59 13 : listFeatureIt = listFeature.begin();
60 13 : }
61 :
62 : /************************************************************************/
63 : /* ~OGRILI2Layer() */
64 : /************************************************************************/
65 :
66 13 : OGRILI2Layer::~OGRILI2Layer()
67 :
68 : {
69 13 : if( poFeatureDefn )
70 13 : poFeatureDefn->Release();
71 :
72 13 : if( poSRS != NULL )
73 0 : poSRS->Release();
74 :
75 13 : listFeatureIt = listFeature.begin();
76 88 : while(listFeatureIt != listFeature.end())
77 : {
78 62 : OGRFeature *poFeature = *(listFeatureIt++);
79 62 : delete poFeature;
80 : }
81 13 : }
82 :
83 :
84 : /************************************************************************/
85 : /* SetFeature() */
86 : /************************************************************************/
87 :
88 62 : OGRErr OGRILI2Layer::SetFeature (OGRFeature *poFeature) {
89 62 : listFeature.push_back(poFeature);
90 62 : return OGRERR_NONE;
91 : }
92 :
93 : /************************************************************************/
94 : /* ResetReading() */
95 : /************************************************************************/
96 :
97 13 : void OGRILI2Layer::ResetReading(){
98 13 : listFeatureIt = listFeature.begin();
99 13 : }
100 :
101 : /************************************************************************/
102 : /* GetNextFeature() */
103 : /************************************************************************/
104 :
105 1 : OGRFeature *OGRILI2Layer::GetNextFeature() {
106 1 : OGRFeature *poFeature = NULL;
107 2 : while (listFeatureIt != listFeature.end())
108 : {
109 1 : poFeature = *(listFeatureIt++);
110 : //apply filters
111 1 : if( (m_poFilterGeom == NULL
112 : || FilterGeometry( poFeature->GetGeometryRef() ) )
113 : && (m_poAttrQuery == NULL
114 : || m_poAttrQuery->Evaluate( poFeature )) )
115 1 : return poFeature->Clone();
116 : }
117 0 : return NULL;
118 : }
119 :
120 : /************************************************************************/
121 : /* GetFeatureCount() */
122 : /************************************************************************/
123 :
124 1 : int OGRILI2Layer::GetFeatureCount( int bForce )
125 : {
126 1 : if (m_poFilterGeom == NULL && m_poAttrQuery == NULL)
127 : {
128 1 : return listFeature.size();
129 : }
130 : else
131 : {
132 0 : return OGRLayer::GetFeatureCount(bForce);
133 : }
134 : }
135 :
136 0 : static char* d2str(double val)
137 : {
138 : static char strbuf[255];
139 0 : if( val == (int) val )
140 0 : sprintf( strbuf, "%d", (int) val );
141 0 : else if( fabs(val) < 370 )
142 0 : sprintf( strbuf, "%.16g", val );
143 0 : else if( fabs(val) > 100000000.0 )
144 0 : sprintf( strbuf, "%.16g", val );
145 : else
146 0 : sprintf( strbuf, "%.3f", val );
147 0 : return strbuf;
148 : }
149 :
150 0 : static void AppendCoordinateList( OGRLineString *poLine, IOM_OBJECT sequence)
151 : {
152 : IOM_OBJECT coordValue;
153 0 : int b3D = (poLine->getGeometryType() & wkb25DBit);
154 :
155 0 : for( int iPoint = 0; iPoint < poLine->getNumPoints(); iPoint++ )
156 : {
157 0 : coordValue=iom_addattrobj(sequence,"segment","COORD");
158 0 : iom_setattrvalue(coordValue,"C1", d2str(poLine->getX(iPoint)));
159 0 : iom_setattrvalue(coordValue,"C2", d2str(poLine->getY(iPoint)));
160 0 : if (b3D) iom_setattrvalue(coordValue,"C3", d2str(poLine->getZ(iPoint)));
161 0 : iom_releaseobject(coordValue);
162 : }
163 0 : }
164 :
165 0 : static int OGR2ILIGeometryAppend( OGRGeometry *poGeometry, IOM_OBJECT obj, const char *attrname )
166 : {
167 : IOM_OBJECT polylineValue;
168 : IOM_OBJECT sequence;
169 : IOM_OBJECT coordValue;
170 : IOM_OBJECT multisurface;
171 : IOM_OBJECT surface;
172 : IOM_OBJECT boundary;
173 :
174 : /* -------------------------------------------------------------------- */
175 : /* 2D Point */
176 : /* -------------------------------------------------------------------- */
177 0 : if( poGeometry->getGeometryType() == wkbPoint )
178 : {
179 0 : OGRPoint *poPoint = (OGRPoint *) poGeometry;
180 :
181 0 : coordValue=iom_changeattrobj(obj,attrname,0,"COORD");
182 0 : iom_setattrvalue(coordValue,"C1", d2str(poPoint->getX()));
183 0 : iom_setattrvalue(coordValue,"C2", d2str(poPoint->getY()));
184 0 : iom_releaseobject(coordValue);
185 : }
186 : /* -------------------------------------------------------------------- */
187 : /* 3D Point */
188 : /* -------------------------------------------------------------------- */
189 0 : else if( poGeometry->getGeometryType() == wkbPoint25D )
190 : {
191 0 : OGRPoint *poPoint = (OGRPoint *) poGeometry;
192 :
193 0 : coordValue=iom_changeattrobj(obj,attrname,0,"COORD");
194 0 : iom_setattrvalue(coordValue,"C1", d2str(poPoint->getX()));
195 0 : iom_setattrvalue(coordValue,"C2", d2str(poPoint->getY()));
196 0 : iom_setattrvalue(coordValue,"C3", d2str(poPoint->getZ()));
197 0 : iom_releaseobject(coordValue);
198 : }
199 :
200 : /* -------------------------------------------------------------------- */
201 : /* LineString and LinearRing */
202 : /* -------------------------------------------------------------------- */
203 0 : else if( poGeometry->getGeometryType() == wkbLineString
204 0 : || poGeometry->getGeometryType() == wkbLineString25D )
205 : {
206 : //int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING");
207 0 : if (attrname) polylineValue=iom_changeattrobj(obj,attrname,0,"POLYLINE");
208 0 : else polylineValue=iom_addattrobj(obj,"polyline","POLYLINE");
209 : // unclipped polyline, add one sequence
210 0 : sequence=iom_changeattrobj(polylineValue,"sequence",0,"SEGMENTS");
211 0 : AppendCoordinateList( (OGRLineString *) poGeometry, sequence );
212 0 : iom_releaseobject(sequence);
213 0 : iom_releaseobject(polylineValue);
214 : }
215 :
216 : /* -------------------------------------------------------------------- */
217 : /* Polygon */
218 : /* -------------------------------------------------------------------- */
219 0 : else if( poGeometry->getGeometryType() == wkbPolygon
220 0 : || poGeometry->getGeometryType() == wkbPolygon25D )
221 : {
222 0 : OGRPolygon *poPolygon = (OGRPolygon *) poGeometry;
223 :
224 0 : multisurface=iom_changeattrobj(obj,attrname,0,"MULTISURFACE");
225 0 : surface=iom_changeattrobj(multisurface,"surface",0,"SURFACE");
226 0 : boundary=iom_changeattrobj(surface,"boundary",0,"BOUNDARY");
227 :
228 0 : if( poPolygon->getExteriorRing() != NULL )
229 : {
230 0 : if( !OGR2ILIGeometryAppend( poPolygon->getExteriorRing(), boundary, NULL ) )
231 0 : return FALSE;
232 : }
233 :
234 0 : for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
235 : {
236 0 : OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);
237 :
238 0 : if( !OGR2ILIGeometryAppend( poRing, boundary, NULL ) )
239 0 : return FALSE;
240 : }
241 0 : iom_releaseobject(boundary);
242 0 : iom_releaseobject(surface);
243 0 : iom_releaseobject(multisurface);
244 : }
245 :
246 : /* -------------------------------------------------------------------- */
247 : /* MultiPolygon */
248 : /* -------------------------------------------------------------------- */
249 0 : else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
250 0 : || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
251 0 : || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
252 0 : || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
253 : {
254 0 : OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
255 : int iMember;
256 :
257 0 : if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
258 : {
259 : }
260 0 : else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
261 : {
262 : }
263 0 : else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
264 : {
265 : }
266 : else
267 : {
268 : }
269 :
270 0 : for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
271 : {
272 0 : OGRGeometry *poMember = poGC->getGeometryRef( iMember );
273 :
274 0 : if( !OGR2ILIGeometryAppend( poMember, obj, NULL ) )
275 0 : return FALSE;
276 : }
277 :
278 : }
279 :
280 : else
281 0 : return FALSE;
282 :
283 0 : return TRUE;
284 : }
285 :
286 : /************************************************************************/
287 : /* CreateFeature() */
288 : /************************************************************************/
289 :
290 0 : OGRErr OGRILI2Layer::CreateFeature( OGRFeature *poFeature ) {
291 : static char szTempBuffer[80];
292 : const char* tid;
293 0 : int iField = 0;
294 0 : if (poFeatureDefn->GetFieldCount() && EQUAL(poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), "TID"))
295 : {
296 0 : tid = poFeature->GetFieldAsString(0);
297 0 : ++iField;
298 : }
299 : else
300 : {
301 0 : sprintf( szTempBuffer, "%ld", poFeature->GetFID() );
302 0 : tid = szTempBuffer;
303 : }
304 : // create new object
305 : IOM_OBJECT obj;
306 0 : obj=iom_newobject(poDS->GetBasket(), poFeatureDefn->GetName(), tid);
307 :
308 : // Write out Geometry
309 0 : if( poFeature->GetGeometryRef() != NULL )
310 : {
311 0 : OGR2ILIGeometryAppend(poFeature->GetGeometryRef(), obj, "Geometry");
312 : }
313 : // Write all "set" fields.
314 0 : for( ; iField < poFeatureDefn->GetFieldCount(); iField++ )
315 : {
316 :
317 0 : OGRFieldDefn *poField = poFeatureDefn->GetFieldDefn( iField );
318 :
319 0 : if( poFeature->IsFieldSet( iField ) )
320 : {
321 0 : const char *pszRaw = poFeature->GetFieldAsString( iField );
322 :
323 : //while( *pszRaw == ' ' )
324 : // pszRaw++;
325 :
326 : //char *pszEscaped = CPLEscapeString( pszRaw, -1, CPLES_XML );
327 :
328 0 : iom_setattrvalue(obj, poField->GetNameRef(), pszRaw);
329 : //CPLFree( pszEscaped );
330 : }
331 : }
332 :
333 0 : iom_releaseobject(obj);
334 0 : return OGRERR_NONE;
335 : }
336 :
337 : /************************************************************************/
338 : /* TestCapability() */
339 : /************************************************************************/
340 :
341 0 : int OGRILI2Layer::TestCapability( const char * pszCap ) {
342 0 : return FALSE;
343 : }
344 :
345 : /************************************************************************/
346 : /* CreateField() */
347 : /************************************************************************/
348 :
349 0 : OGRErr OGRILI2Layer::CreateField( OGRFieldDefn *poField, int bApproxOK ) {
350 0 : poFeatureDefn->AddFieldDefn( poField );
351 0 : return OGRERR_NONE;
352 : }
353 :
354 : /************************************************************************/
355 : /* GetSpatialRef() */
356 : /************************************************************************/
357 :
358 0 : OGRSpatialReference *OGRILI2Layer::GetSpatialRef() {
359 0 : return poSRS;
360 : }
|