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