1 : /******************************************************************************
2 : * $Id: ogrili1layer.cpp 24611 2012-06-25 15:21:48Z pka $
3 : *
4 : * Project: Interlis 1 Translator
5 : * Purpose: Implements OGRILI1Layer class.
6 : * Author: Pirmin Kalberer, 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_ili1.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 : #include "ogr_geos.h"
34 :
35 : CPL_CVSID("$Id: ogrili1layer.cpp 24611 2012-06-25 15:21:48Z pka $");
36 :
37 : /************************************************************************/
38 : /* OGRILI1Layer() */
39 : /************************************************************************/
40 :
41 43 : OGRILI1Layer::OGRILI1Layer( const char * pszName,
42 : OGRSpatialReference *poSRSIn, int bWriterIn,
43 : OGRwkbGeometryType eReqType,
44 43 : OGRILI1DataSource *poDSIn )
45 :
46 : {
47 43 : if( poSRSIn == NULL )
48 43 : poSRS = NULL;
49 : else
50 0 : poSRS = poSRSIn->Clone();
51 :
52 43 : poDS = poDSIn;
53 :
54 43 : poFeatureDefn = new OGRFeatureDefn( pszName );
55 43 : poFeatureDefn->Reference();
56 43 : poFeatureDefn->SetGeomType( eReqType );
57 :
58 43 : nFeatures = 0;
59 43 : papoFeatures = NULL;
60 43 : nFeatureIdx = 0;
61 :
62 43 : poSurfacePolyLayer = 0;
63 43 : poAreaLineLayer = 0;
64 :
65 43 : bWriter = bWriterIn;
66 43 : }
67 :
68 : /************************************************************************/
69 : /* ~OGRILI1Layer() */
70 : /************************************************************************/
71 :
72 43 : OGRILI1Layer::~OGRILI1Layer()
73 : {
74 : int i;
75 :
76 103 : for(i=0;i<nFeatures;i++)
77 : {
78 60 : delete papoFeatures[i];
79 : }
80 43 : CPLFree(papoFeatures);
81 :
82 43 : if( poFeatureDefn )
83 43 : poFeatureDefn->Release();
84 :
85 43 : if( poSRS != NULL )
86 0 : poSRS->Release();
87 43 : }
88 :
89 :
90 60 : OGRErr OGRILI1Layer::AddFeature (OGRFeature *poFeature)
91 : {
92 60 : nFeatures++;
93 :
94 : papoFeatures = (OGRFeature **)
95 60 : CPLRealloc( papoFeatures, sizeof(void*) * nFeatures );
96 :
97 60 : papoFeatures[nFeatures-1] = poFeature;
98 :
99 60 : return OGRERR_NONE;
100 : }
101 :
102 : /************************************************************************/
103 : /* ResetReading() */
104 : /************************************************************************/
105 :
106 76 : void OGRILI1Layer::ResetReading(){
107 76 : nFeatureIdx = 0;
108 76 : }
109 :
110 : /************************************************************************/
111 : /* GetNextFeature() */
112 : /************************************************************************/
113 :
114 210 : OGRFeature *OGRILI1Layer::GetNextFeature()
115 : {
116 : OGRFeature *poFeature;
117 :
118 210 : if (poSurfacePolyLayer != 0) JoinSurfaceLayer();
119 210 : if (poAreaLineLayer != 0) PolygonizeAreaLayer(); //TODO: polygonize only when polygon layer is reqested
120 :
121 420 : while(nFeatureIdx < nFeatures)
122 : {
123 135 : poFeature = GetNextFeatureRef();
124 135 : if (poFeature)
125 135 : return poFeature->Clone();
126 : }
127 75 : return NULL;
128 : }
129 :
130 135 : OGRFeature *OGRILI1Layer::GetNextFeatureRef() {
131 135 : OGRFeature *poFeature = NULL;
132 135 : if (nFeatureIdx < nFeatures)
133 : {
134 135 : poFeature = papoFeatures[nFeatureIdx++];
135 : //apply filters
136 135 : if( (m_poFilterGeom == NULL
137 : || FilterGeometry( poFeature->GetGeometryRef() ) )
138 : && (m_poAttrQuery == NULL
139 : || m_poAttrQuery->Evaluate( poFeature )) )
140 135 : return poFeature;
141 : }
142 0 : return NULL;
143 : }
144 :
145 : /************************************************************************/
146 : /* GetFeatureRef() */
147 : /************************************************************************/
148 :
149 0 : OGRFeature *OGRILI1Layer::GetFeatureRef( long nFID )
150 :
151 : {
152 : OGRFeature *poFeature;
153 :
154 0 : ResetReading();
155 0 : while( (poFeature = GetNextFeatureRef()) != NULL )
156 : {
157 0 : if( poFeature->GetFID() == nFID )
158 0 : return poFeature;
159 : }
160 :
161 0 : return NULL;
162 : }
163 :
164 : /************************************************************************/
165 : /* GetFeatureCount() */
166 : /************************************************************************/
167 :
168 6 : int OGRILI1Layer::GetFeatureCount( int bForce )
169 : {
170 6 : if (m_poFilterGeom == NULL && m_poAttrQuery == NULL &&
171 : poAreaLineLayer == NULL)
172 : {
173 6 : return nFeatures;
174 : }
175 : else
176 : {
177 0 : return OGRLayer::GetFeatureCount(bForce);
178 : }
179 : }
180 :
181 0 : static char* d2str(double val)
182 : {
183 : static char strbuf[255];
184 0 : if( val == (int) val )
185 0 : sprintf( strbuf, "%d", (int) val );
186 0 : else if( fabs(val) < 370 )
187 0 : sprintf( strbuf, "%.16g", val );
188 0 : else if( fabs(val) > 100000000.0 )
189 0 : sprintf( strbuf, "%.16g", val );
190 : else
191 0 : sprintf( strbuf, "%.3f", val );
192 0 : return strbuf;
193 : }
194 :
195 0 : static void AppendCoordinateList( OGRLineString *poLine, OGRILI1DataSource *poDS)
196 : {
197 0 : int b3D = (poLine->getGeometryType() & wkb25DBit);
198 :
199 0 : for( int iPoint = 0; iPoint < poLine->getNumPoints(); iPoint++ )
200 : {
201 0 : if (iPoint == 0) VSIFPrintf( poDS->GetTransferFile(), "STPT" );
202 0 : else VSIFPrintf( poDS->GetTransferFile(), "LIPT" );
203 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poLine->getX(iPoint)) );
204 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poLine->getY(iPoint)) );
205 0 : if (b3D) VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poLine->getZ(iPoint)) );
206 0 : VSIFPrintf( poDS->GetTransferFile(), "\n" );
207 : }
208 0 : VSIFPrintf( poDS->GetTransferFile(), "ELIN\n" );
209 0 : }
210 :
211 0 : int OGRILI1Layer::GeometryAppend( OGRGeometry *poGeometry )
212 : {
213 : /* -------------------------------------------------------------------- */
214 : /* 2D Point */
215 : /* -------------------------------------------------------------------- */
216 0 : if( poGeometry->getGeometryType() == wkbPoint )
217 : {
218 : /* embedded in from non-geometry fields */
219 : }
220 : /* -------------------------------------------------------------------- */
221 : /* 3D Point */
222 : /* -------------------------------------------------------------------- */
223 0 : else if( poGeometry->getGeometryType() == wkbPoint25D )
224 : {
225 : /* embedded in from non-geometry fields */
226 : }
227 :
228 : /* -------------------------------------------------------------------- */
229 : /* LineString and LinearRing */
230 : /* -------------------------------------------------------------------- */
231 0 : else if( poGeometry->getGeometryType() == wkbLineString
232 0 : || poGeometry->getGeometryType() == wkbLineString25D )
233 : {
234 0 : AppendCoordinateList( (OGRLineString *) poGeometry, poDS );
235 : }
236 :
237 : /* -------------------------------------------------------------------- */
238 : /* Polygon */
239 : /* -------------------------------------------------------------------- */
240 0 : else if( poGeometry->getGeometryType() == wkbPolygon
241 0 : || poGeometry->getGeometryType() == wkbPolygon25D )
242 : {
243 0 : OGRPolygon *poPolygon = (OGRPolygon *) poGeometry;
244 :
245 0 : if( poPolygon->getExteriorRing() != NULL )
246 : {
247 0 : if( !GeometryAppend( poPolygon->getExteriorRing() ) )
248 0 : return FALSE;
249 : }
250 :
251 0 : for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
252 : {
253 0 : OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);
254 :
255 0 : if( !GeometryAppend( poRing ) )
256 0 : return FALSE;
257 : }
258 : }
259 :
260 : /* -------------------------------------------------------------------- */
261 : /* MultiPolygon */
262 : /* -------------------------------------------------------------------- */
263 0 : else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
264 0 : || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
265 0 : || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
266 0 : || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
267 : {
268 0 : OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
269 : int iMember;
270 :
271 0 : if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
272 : {
273 : }
274 0 : else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
275 : {
276 : }
277 0 : else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
278 : {
279 : }
280 : else
281 : {
282 : }
283 :
284 0 : for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
285 : {
286 0 : OGRGeometry *poMember = poGC->getGeometryRef( iMember );
287 :
288 0 : if( !GeometryAppend( poMember ) )
289 0 : return FALSE;
290 : }
291 :
292 : }
293 :
294 : else
295 0 : return FALSE;
296 :
297 0 : return TRUE;
298 : }
299 :
300 : /************************************************************************/
301 : /* CreateFeature() */
302 : /************************************************************************/
303 :
304 3 : OGRErr OGRILI1Layer::CreateFeature( OGRFeature *poFeature ) {
305 : static long tid = -1; //system generated TID (must be unique within table)
306 3 : VSIFPrintf( poDS->GetTransferFile(), "OBJE" );
307 :
308 3 : if ( poFeatureDefn->GetFieldCount() && !EQUAL(poFeatureDefn->GetFieldDefn(0)->GetNameRef(), "TID") )
309 : {
310 : //Input is not generated from an Interlis 1 source
311 3 : if (poFeature->GetFID() != OGRNullFID)
312 0 : tid = poFeature->GetFID();
313 : else
314 3 : ++tid;
315 3 : VSIFPrintf( poDS->GetTransferFile(), " %ld", tid );
316 : //Embedded geometry
317 3 : if( poFeature->GetGeometryRef() != NULL )
318 : {
319 0 : OGRGeometry *poGeometry = poFeature->GetGeometryRef();
320 : // 2D Point
321 0 : if( poGeometry->getGeometryType() == wkbPoint )
322 : {
323 0 : OGRPoint *poPoint = (OGRPoint *) poGeometry;
324 :
325 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poPoint->getX()) );
326 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poPoint->getY()) );
327 : }
328 : // 3D Point
329 0 : else if( poGeometry->getGeometryType() == wkbPoint25D )
330 : {
331 0 : OGRPoint *poPoint = (OGRPoint *) poGeometry;
332 :
333 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poPoint->getX()) );
334 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poPoint->getY()) );
335 0 : VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poPoint->getZ()) );
336 : }
337 : }
338 : }
339 :
340 : // Write all fields.
341 18 : for(int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
342 : {
343 15 : if ( !EQUAL(poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), "ILI_Geometry") )
344 : {
345 15 : if ( poFeature->IsFieldSet( iField ) )
346 : {
347 12 : const char *pszRaw = poFeature->GetFieldAsString( iField );
348 12 : if (poFeatureDefn->GetFieldDefn( iField )->GetType() == OFTString) {
349 : //Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode from UTF-8
350 9 : char* pszString = CPLRecode(pszRaw, CPL_ENC_UTF8, CPL_ENC_ISO8859_1);
351 : //Replace spaces
352 38 : for(size_t i=0; i<strlen(pszString); i++ ) {
353 29 : if (pszString[i] == ' ') pszString[i] = '_';
354 : }
355 9 : VSIFPrintf( poDS->GetTransferFile(), " %s", pszString );
356 9 : CPLFree( pszString );
357 : } else {
358 3 : VSIFPrintf( poDS->GetTransferFile(), " %s", pszRaw );
359 : }
360 : }
361 : else
362 : {
363 3 : VSIFPrintf( poDS->GetTransferFile(), " @" );
364 : }
365 : }
366 : }
367 3 : VSIFPrintf( poDS->GetTransferFile(), "\n" );
368 :
369 : // Write out Geometry
370 3 : if( poFeature->GetGeometryRef() != NULL )
371 : {
372 0 : if (EQUAL(poFeatureDefn->GetFieldDefn(poFeatureDefn->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry"))
373 : {
374 : //Write original ILI geometry
375 0 : VSIFPrintf( poDS->GetTransferFile(), "%s", poFeature->GetFieldAsString( poFeatureDefn->GetFieldCount()-1 ) );
376 : }
377 : else
378 : {
379 : //Convert to ILI geometry
380 0 : GeometryAppend(poFeature->GetGeometryRef());
381 : }
382 : }
383 :
384 3 : return OGRERR_NONE;
385 : }
386 :
387 : /************************************************************************/
388 : /* TestCapability() */
389 : /************************************************************************/
390 :
391 1 : int OGRILI1Layer::TestCapability( const char * pszCap ) {
392 1 : return FALSE;
393 : }
394 :
395 : /************************************************************************/
396 : /* CreateField() */
397 : /************************************************************************/
398 :
399 35 : OGRErr OGRILI1Layer::CreateField( OGRFieldDefn *poField, int bApproxOK ) {
400 35 : poFeatureDefn->AddFieldDefn( poField );
401 :
402 35 : return OGRERR_NONE;
403 : }
404 :
405 : /************************************************************************/
406 : /* GetSpatialRef() */
407 : /************************************************************************/
408 :
409 1 : OGRSpatialReference *OGRILI1Layer::GetSpatialRef() {
410 1 : return poSRS;
411 : }
412 :
413 :
414 : /************************************************************************/
415 : /* Internal routines */
416 : /************************************************************************/
417 :
418 0 : void OGRILI1Layer::SetSurfacePolyLayer(OGRILI1Layer *poSurfacePolyLayerIn) {
419 0 : poSurfacePolyLayer = poSurfacePolyLayerIn;
420 0 : }
421 :
422 0 : void OGRILI1Layer::JoinSurfaceLayer()
423 : {
424 0 : if (poSurfacePolyLayer == 0) return;
425 :
426 0 : CPLDebug( "OGR_ILI", "Joining surface layer %s with geometries", GetLayerDefn()->GetName());
427 0 : GetLayerDefn()->SetGeomType(poSurfacePolyLayer->GetLayerDefn()->GetGeomType());
428 0 : ResetReading();
429 0 : while (OGRFeature *feature = GetNextFeatureRef())
430 : {
431 0 : OGRFeature *polyfeature = poSurfacePolyLayer->GetFeatureRef(feature->GetFID());
432 0 : if (polyfeature) {
433 0 : feature->SetGeometry(polyfeature->GetGeometryRef());
434 : }
435 : }
436 :
437 0 : ResetReading();
438 0 : poSurfacePolyLayer = 0;
439 : }
440 :
441 5 : void OGRILI1Layer::SetAreaLayers(OGRILI1Layer *poReferenceLayer, OGRILI1Layer *poAreaLineLayerIn) {
442 5 : poAreaReferenceLayer = poReferenceLayer;
443 5 : poAreaLineLayer = poAreaLineLayerIn;
444 5 : }
445 :
446 0 : OGRMultiPolygon* OGRILI1Layer::Polygonize( OGRGeometryCollection* poLines, bool fix_crossing_lines )
447 : {
448 0 : OGRMultiPolygon *poPolygon = new OGRMultiPolygon();
449 :
450 0 : if (poLines->getNumGeometries() == 0) return poPolygon;
451 :
452 : #if defined(HAVE_GEOS)
453 0 : GEOSGeom *ahInGeoms = NULL;
454 0 : int i = 0;
455 0 : OGRGeometryCollection *poNoncrossingLines = poLines;
456 0 : GEOSGeom hResultGeom = NULL;
457 0 : OGRGeometry *poMP = NULL;
458 :
459 0 : if (fix_crossing_lines && poLines->getNumGeometries() > 0)
460 : {
461 : #if (GEOS_VERSION_MAJOR >= 3)
462 0 : CPLDebug( "OGR_ILI", "Fixing crossing lines");
463 : //A union of the geometry collection with one line fixes invalid geometries
464 0 : poNoncrossingLines = (OGRGeometryCollection*)poLines->Union(poLines->getGeometryRef(0));
465 0 : CPLDebug( "OGR_ILI", "Fixed lines: %d", poNoncrossingLines->getNumGeometries()-poLines->getNumGeometries());
466 : #else
467 : #warning Interlis 1 AREA cleanup disabled. Needs GEOS >= 3.0
468 : #endif
469 : }
470 :
471 0 : ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),poNoncrossingLines->getNumGeometries());
472 0 : for( i = 0; i < poNoncrossingLines->getNumGeometries(); i++ )
473 0 : ahInGeoms[i] = poNoncrossingLines->getGeometryRef(i)->exportToGEOS();
474 :
475 : hResultGeom = GEOSPolygonize( ahInGeoms,
476 0 : poNoncrossingLines->getNumGeometries() );
477 :
478 0 : for( i = 0; i < poNoncrossingLines->getNumGeometries(); i++ )
479 0 : GEOSGeom_destroy( ahInGeoms[i] );
480 0 : CPLFree( ahInGeoms );
481 0 : if (poNoncrossingLines != poLines) delete poNoncrossingLines;
482 :
483 0 : if( hResultGeom == NULL )
484 0 : return NULL;
485 :
486 0 : poMP = OGRGeometryFactory::createFromGEOS( hResultGeom );
487 :
488 0 : GEOSGeom_destroy( hResultGeom );
489 :
490 0 : return (OGRMultiPolygon *) poMP;
491 :
492 : #endif
493 :
494 : return poPolygon;
495 : }
496 :
497 :
498 0 : void OGRILI1Layer::PolygonizeAreaLayer()
499 : {
500 0 : if (poAreaLineLayer == 0) return;
501 :
502 : //add all lines from poAreaLineLayer to collection
503 0 : OGRGeometryCollection *gc = new OGRGeometryCollection();
504 0 : poAreaLineLayer->ResetReading();
505 0 : while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef())
506 0 : gc->addGeometry(feature->GetGeometryRef());
507 :
508 : //polygonize lines
509 0 : CPLDebug( "OGR_ILI", "Polygonizing layer %s with %d multilines", poAreaLineLayer->GetLayerDefn()->GetName(), gc->getNumGeometries());
510 0 : poAreaLineLayer = 0;
511 0 : OGRMultiPolygon* polys = Polygonize( gc , false);
512 0 : CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries());
513 0 : if (polys->getNumGeometries() != poAreaReferenceLayer->GetFeatureCount())
514 : {
515 0 : CPLDebug( "OGR_ILI", "Feature count of layer %s: %d", poAreaReferenceLayer->GetLayerDefn()->GetName(), GetFeatureCount());
516 0 : CPLDebug( "OGR_ILI", "Polygonizing again with crossing line fix");
517 0 : delete polys;
518 0 : polys = Polygonize( gc, true ); //try again with crossing line fix
519 : }
520 0 : delete gc;
521 :
522 : //associate polygon feature with data row according to centroid
523 : #if defined(HAVE_GEOS)
524 : int i;
525 0 : OGRPolygon emptyPoly;
526 0 : GEOSGeom *ahInGeoms = NULL;
527 :
528 0 : CPLDebug( "OGR_ILI", "Associating layer %s with area polygons", GetLayerDefn()->GetName());
529 0 : ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),polys->getNumGeometries());
530 0 : for( i = 0; i < polys->getNumGeometries(); i++ )
531 : {
532 0 : ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS();
533 0 : if (!GEOSisValid(ahInGeoms[i])) ahInGeoms[i] = NULL;
534 : }
535 0 : poAreaReferenceLayer->ResetReading();
536 0 : while (OGRFeature *feature = poAreaReferenceLayer->GetNextFeatureRef())
537 : {
538 0 : OGRGeometry* geomRef = feature->GetGeometryRef();
539 0 : if( !geomRef )
540 : {
541 0 : continue;
542 : }
543 0 : GEOSGeom point = (GEOSGeom)(geomRef->exportToGEOS());
544 0 : for (i = 0; i < polys->getNumGeometries(); i++ )
545 : {
546 0 : if (ahInGeoms[i] && GEOSWithin(point, ahInGeoms[i]))
547 : {
548 0 : OGRFeature* areaFeature = new OGRFeature(poFeatureDefn);
549 0 : areaFeature->SetFrom(feature);
550 0 : areaFeature->SetGeometry( polys->getGeometryRef(i) );
551 0 : AddFeature(areaFeature);
552 0 : break;
553 : }
554 : }
555 0 : if (i == polys->getNumGeometries())
556 : {
557 0 : CPLDebug( "OGR_ILI", "Association between area and point failed.");
558 0 : feature->SetGeometry( &emptyPoly );
559 : }
560 0 : GEOSGeom_destroy( point );
561 : }
562 0 : for( i = 0; i < polys->getNumGeometries(); i++ )
563 0 : GEOSGeom_destroy( ahInGeoms[i] );
564 0 : CPLFree( ahInGeoms );
565 : #endif
566 0 : poAreaLineLayer = 0;
567 0 : delete polys;
568 : }
|