Coverage Report

Created: 2025-11-15 08:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrsf_frmts/ili/ogrili1layer.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  Interlis 1 Translator
4
 * Purpose:  Implements OGRILI1Layer class.
5
 * Author:   Pirmin Kalberer, Sourcepole AG
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
9
 * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#include "cpl_conv.h"
15
#include "cpl_string.h"
16
#include "ogr_geos.h"
17
#include "ogr_ili1.h"
18
19
#include <map>
20
#include <vector>
21
22
/************************************************************************/
23
/*                           OGRILI1Layer()                              */
24
/************************************************************************/
25
26
OGRILI1Layer::OGRILI1Layer(OGRFeatureDefn *poFeatureDefnIn,
27
                           const GeomFieldInfos &oGeomFieldInfosIn,
28
                           OGRILI1DataSource *poDSIn)
29
10.4k
    : poFeatureDefn(poFeatureDefnIn), oGeomFieldInfos(oGeomFieldInfosIn),
30
10.4k
      nFeatures(0), papoFeatures(nullptr), nFeatureIdx(0), bGeomsJoined(FALSE),
31
10.4k
      poDS(poDSIn)
32
10.4k
{
33
10.4k
    SetDescription(poFeatureDefn->GetName());
34
10.4k
    poFeatureDefn->Reference();
35
10.4k
}
36
37
/************************************************************************/
38
/*                           ~OGRILI1Layer()                           */
39
/************************************************************************/
40
41
OGRILI1Layer::~OGRILI1Layer()
42
10.4k
{
43
115k
    for (int i = 0; i < nFeatures; i++)
44
105k
    {
45
105k
        delete papoFeatures[i];
46
105k
    }
47
10.4k
    CPLFree(papoFeatures);
48
49
10.4k
    if (poFeatureDefn)
50
10.4k
        poFeatureDefn->Release();
51
10.4k
}
52
53
OGRErr OGRILI1Layer::AddFeature(OGRFeature *poFeature)
54
105k
{
55
105k
    nFeatures++;
56
57
105k
    papoFeatures = static_cast<OGRFeature **>(
58
105k
        CPLRealloc(papoFeatures, sizeof(void *) * nFeatures));
59
60
105k
    papoFeatures[nFeatures - 1] = poFeature;
61
62
105k
    return OGRERR_NONE;
63
105k
}
64
65
/************************************************************************/
66
/*                            ResetReading()                            */
67
/************************************************************************/
68
69
void OGRILI1Layer::ResetReading()
70
0
{
71
0
    nFeatureIdx = 0;
72
0
}
73
74
/************************************************************************/
75
/*                           GetNextFeature()                           */
76
/************************************************************************/
77
78
OGRFeature *OGRILI1Layer::GetNextFeature()
79
54.7k
{
80
54.7k
    if (!bGeomsJoined)
81
4.38k
        JoinGeomLayers();
82
83
54.7k
    while (nFeatureIdx < nFeatures)
84
50.3k
    {
85
50.3k
        OGRFeature *poFeature = GetNextFeatureRef();
86
50.3k
        if (poFeature)
87
50.3k
            return poFeature->Clone();
88
50.3k
    }
89
4.38k
    return nullptr;
90
54.7k
}
91
92
OGRFeature *OGRILI1Layer::GetNextFeatureRef()
93
50.3k
{
94
50.3k
    OGRFeature *poFeature = nullptr;
95
50.3k
    if (nFeatureIdx < nFeatures)
96
50.3k
    {
97
50.3k
        poFeature = papoFeatures[nFeatureIdx++];
98
        // apply filters
99
50.3k
        if ((m_poFilterGeom == nullptr ||
100
0
             FilterGeometry(poFeature->GetGeometryRef())) &&
101
50.3k
            (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
102
50.3k
            return poFeature;
103
50.3k
    }
104
0
    return nullptr;
105
50.3k
}
106
107
/************************************************************************/
108
/*                             GetFeatureRef()                          */
109
/************************************************************************/
110
111
OGRFeature *OGRILI1Layer::GetFeatureRef(GIntBig nFID)
112
113
0
{
114
0
    ResetReading();
115
116
0
    OGRFeature *poFeature = nullptr;
117
0
    while ((poFeature = GetNextFeatureRef()) != nullptr)
118
0
    {
119
0
        if (poFeature->GetFID() == nFID)
120
0
            return poFeature;
121
0
    }
122
123
0
    return nullptr;
124
0
}
125
126
OGRFeature *OGRILI1Layer::GetFeatureRef(const char *fid)
127
128
0
{
129
0
    ResetReading();
130
131
0
    OGRFeature *poFeature = nullptr;
132
0
    while ((poFeature = GetNextFeatureRef()) != nullptr)
133
0
    {
134
0
        if (!strcmp(poFeature->GetFieldAsString(0), fid))
135
0
            return poFeature;
136
0
    }
137
138
0
    return nullptr;
139
0
}
140
141
/************************************************************************/
142
/*                          GetFeatureCount()                           */
143
/************************************************************************/
144
145
GIntBig OGRILI1Layer::GetFeatureCount(int bForce)
146
68.6k
{
147
68.6k
    if (m_poFilterGeom == nullptr && m_poAttrQuery == nullptr
148
68.6k
        /* && poAreaLineLayer == NULL*/)
149
68.6k
    {
150
68.6k
        return nFeatures;
151
68.6k
    }
152
0
    else
153
0
    {
154
0
        return OGRLayer::GetFeatureCount(bForce);
155
0
    }
156
68.6k
}
157
158
/************************************************************************/
159
/*                           TestCapability()                           */
160
/************************************************************************/
161
162
int OGRILI1Layer::TestCapability(const char *pszCap) const
163
0
{
164
0
    if (EQUAL(pszCap, OLCCurveGeometries))
165
0
        return TRUE;
166
0
    if (EQUAL(pszCap, OLCZGeometries))
167
0
        return TRUE;
168
169
0
    return FALSE;
170
0
}
171
172
/************************************************************************/
173
/*                         Internal routines                            */
174
/************************************************************************/
175
176
void OGRILI1Layer::JoinGeomLayers()
177
4.38k
{
178
4.38k
    bGeomsJoined = true;
179
180
4.38k
    CPLConfigOptionSetter oSetter("OGR_ARC_STEPSIZE", "0.96",
181
4.38k
                                  /* bSetOnlyIfUndefined = */ true);
182
183
4.38k
    for (GeomFieldInfos::const_iterator it = oGeomFieldInfos.begin();
184
4.38k
         it != oGeomFieldInfos.end(); ++it)
185
0
    {
186
0
        OGRFeatureDefn *geomFeatureDefn = it->second.GetGeomTableDefnRef();
187
0
        if (geomFeatureDefn)
188
0
        {
189
0
            CPLDebug("OGR_ILI", "Join geometry table %s of field '%s'",
190
0
                     geomFeatureDefn->GetName(), it->first.c_str());
191
0
            OGRILI1Layer *poGeomLayer =
192
0
                poDS->GetLayerByName(geomFeatureDefn->GetName());
193
0
            const int nGeomFieldIndex =
194
0
                GetLayerDefn()->GetGeomFieldIndex(it->first.c_str());
195
0
            if (it->second.iliGeomType == "Surface")
196
0
            {
197
0
                JoinSurfaceLayer(poGeomLayer, nGeomFieldIndex);
198
0
            }
199
0
            else if (it->second.iliGeomType == "Area")
200
0
            {
201
0
                CPLString pointField = it->first + "__Point";
202
0
                const int nPointFieldIndex =
203
0
                    GetLayerDefn()->GetGeomFieldIndex(pointField.c_str());
204
0
                PolygonizeAreaLayer(poGeomLayer, nGeomFieldIndex,
205
0
                                    nPointFieldIndex);
206
0
            }
207
0
        }
208
0
    }
209
4.38k
}
210
211
void OGRILI1Layer::JoinSurfaceLayer(OGRILI1Layer *poSurfaceLineLayer,
212
                                    int nSurfaceFieldIndex)
213
0
{
214
0
    CPLDebug("OGR_ILI", "Joining surface layer %s with geometries",
215
0
             GetLayerDefn()->GetName());
216
0
    OGRwkbGeometryType geomType =
217
0
        GetLayerDefn()->GetGeomFieldDefn(nSurfaceFieldIndex)->GetType();
218
219
0
    std::map<OGRFeature *, std::vector<OGRCurve *>> oMapFeatureToGeomSet;
220
221
0
    poSurfaceLineLayer->ResetReading();
222
223
    // First map: for each target curvepolygon, find all belonging curves
224
0
    while (OGRFeature *linefeature = poSurfaceLineLayer->GetNextFeatureRef())
225
0
    {
226
        // OBJE entries with same _RefTID are polygon rings of same feature
227
0
        OGRFeature *feature = nullptr;
228
0
        if (poFeatureDefn->GetFieldDefn(0)->GetType() == OFTString)
229
0
        {
230
0
            feature = GetFeatureRef(linefeature->GetFieldAsString(1));
231
0
        }
232
0
        else
233
0
        {
234
0
            GIntBig reftid = linefeature->GetFieldAsInteger64(1);
235
0
            feature = GetFeatureRef(reftid);
236
0
        }
237
0
        if (feature)
238
0
        {
239
0
            OGRGeometry *poGeom = linefeature->GetGeomFieldRef(0);
240
0
            OGRMultiCurve *curves = dynamic_cast<OGRMultiCurve *>(poGeom);
241
0
            if (curves)
242
0
            {
243
0
                for (auto &&curve : curves)
244
0
                {
245
0
                    if (!curve->IsEmpty())
246
0
                        oMapFeatureToGeomSet[feature].push_back(curve);
247
0
                }
248
0
            }
249
0
        }
250
0
        else
251
0
        {
252
0
            CPLError(CE_Warning, CPLE_AppDefined,
253
0
                     "Couldn't join feature FID " CPL_FRMT_GIB,
254
0
                     linefeature->GetFieldAsInteger64(1));
255
0
        }
256
0
    }
257
258
    // Now for each target polygon, assemble the curves together.
259
0
    std::map<OGRFeature *, std::vector<OGRCurve *>>::const_iterator oIter =
260
0
        oMapFeatureToGeomSet.begin();
261
0
    for (; oIter != oMapFeatureToGeomSet.end(); ++oIter)
262
0
    {
263
0
        OGRFeature *feature = oIter->first;
264
0
        std::vector<OGRCurve *> oCurves = oIter->second;
265
266
0
        std::vector<OGRCurve *> oSetDestCurves;
267
0
        double dfLargestArea = 0.0;
268
0
        OGRCurve *poLargestCurve = nullptr;
269
0
        while (true)
270
0
        {
271
0
            std::vector<OGRCurve *>::iterator oIterCurves = oCurves.begin();
272
0
            if (oIterCurves == oCurves.end())
273
0
                break;
274
275
0
            OGRPoint endPointCC;
276
0
            OGRCompoundCurve *poCC = new OGRCompoundCurve();
277
278
0
            bool bFirst = true;
279
0
            while (true)
280
0
            {
281
0
                bool bNewCurveAdded = false;
282
0
                const double dfEps = 1e-14;
283
0
                for (oIterCurves = oCurves.begin();
284
0
                     oIterCurves != oCurves.end(); ++oIterCurves)
285
0
                {
286
0
                    OGRCurve *curve = *oIterCurves;
287
0
                    OGRPoint startPoint;
288
0
                    OGRPoint endPoint;
289
0
                    curve->StartPoint(&startPoint);
290
0
                    curve->EndPoint(&endPoint);
291
0
                    if (bFirst ||
292
0
                        (fabs(startPoint.getX() - endPointCC.getX()) < dfEps &&
293
0
                         fabs(startPoint.getY() - endPointCC.getY()) < dfEps))
294
0
                    {
295
0
                        bFirst = false;
296
297
0
                        curve->EndPoint(&endPointCC);
298
299
0
                        const OGRwkbGeometryType eCurveType =
300
0
                            wkbFlatten(curve->getGeometryType());
301
0
                        if (eCurveType == wkbCompoundCurve)
302
0
                        {
303
0
                            OGRCompoundCurve *poCCSub =
304
0
                                curve->toCompoundCurve();
305
0
                            for (auto &&subCurve : poCCSub)
306
0
                            {
307
0
                                poCC->addCurve(subCurve);
308
0
                            }
309
0
                        }
310
0
                        else
311
0
                        {
312
0
                            poCC->addCurve(curve);
313
0
                        }
314
0
                        oCurves.erase(oIterCurves);
315
0
                        bNewCurveAdded = true;
316
0
                        break;
317
0
                    }
318
0
                    else if (fabs(endPoint.getX() - endPointCC.getX()) <
319
0
                                 dfEps &&
320
0
                             fabs(endPoint.getY() - endPointCC.getY()) < dfEps)
321
0
                    {
322
0
                        curve->StartPoint(&endPointCC);
323
324
0
                        const OGRwkbGeometryType eCurveType =
325
0
                            wkbFlatten(curve->getGeometryType());
326
0
                        if (eCurveType == wkbLineString ||
327
0
                            eCurveType == wkbCircularString)
328
0
                        {
329
0
                            OGRSimpleCurve *poSC =
330
0
                                curve->toSimpleCurve()->clone();
331
0
                            poSC->reversePoints();
332
0
                            poCC->addCurveDirectly(poSC);
333
0
                        }
334
0
                        else if (eCurveType == wkbCompoundCurve)
335
0
                        {
336
                            // Reverse the order of the elements of the
337
                            // compound curve
338
0
                            OGRCompoundCurve *poCCSub =
339
0
                                curve->toCompoundCurve();
340
0
                            for (int i = poCCSub->getNumCurves() - 1; i >= 0;
341
0
                                 --i)
342
0
                            {
343
0
                                OGRSimpleCurve *poSC = poCCSub->getCurve(i)
344
0
                                                           ->toSimpleCurve()
345
0
                                                           ->clone();
346
0
                                poSC->reversePoints();
347
0
                                poCC->addCurveDirectly(poSC);
348
0
                            }
349
0
                        }
350
351
0
                        oCurves.erase(oIterCurves);
352
0
                        bNewCurveAdded = true;
353
0
                        break;
354
0
                    }
355
0
                }
356
0
                if (!bNewCurveAdded || oCurves.empty() || poCC->get_IsClosed())
357
0
                    break;
358
0
            }
359
360
0
            if (!poCC->get_IsClosed())
361
0
            {
362
0
                char *pszJSon = poCC->exportToJson();
363
0
                CPLError(CE_Warning, CPLE_AppDefined,
364
0
                         "A ring %s for feature " CPL_FRMT_GIB " in layer %s "
365
0
                         "was not closed. Dropping it",
366
0
                         pszJSon, feature->GetFID(), GetName());
367
0
                delete poCC;
368
0
                CPLFree(pszJSon);
369
0
            }
370
0
            else
371
0
            {
372
0
                double dfArea = poCC->get_Area();
373
0
                if (dfArea >= dfLargestArea)
374
0
                {
375
0
                    dfLargestArea = dfArea;
376
0
                    poLargestCurve = poCC;
377
0
                }
378
0
                oSetDestCurves.push_back(poCC);
379
0
            }
380
0
        }
381
382
        // Now build the final polygon by first inserting the largest ring.
383
0
        OGRCurvePolygon *poPoly =
384
0
            (geomType == wkbPolygon) ? new OGRPolygon() : new OGRCurvePolygon();
385
0
        if (poLargestCurve)
386
0
        {
387
0
            std::vector<OGRCurve *>::iterator oIterCurves =
388
0
                oSetDestCurves.begin();
389
0
            for (; oIterCurves != oSetDestCurves.end(); ++oIterCurves)
390
0
            {
391
0
                OGRCurve *poCurve = *oIterCurves;
392
0
                if (poCurve == poLargestCurve)
393
0
                {
394
0
                    oSetDestCurves.erase(oIterCurves);
395
0
                    break;
396
0
                }
397
0
            }
398
399
0
            if (geomType == wkbPolygon)
400
0
            {
401
0
                poLargestCurve = OGRCurve::CastToLinearRing(poLargestCurve);
402
0
            }
403
0
            OGRErr error = poPoly->addRingDirectly(poLargestCurve);
404
0
            if (error != OGRERR_NONE)
405
0
            {
406
0
                char *pszJSon = poLargestCurve->exportToJson();
407
0
                CPLError(CE_Warning, CPLE_AppDefined,
408
0
                         "Cannot add ring %s to feature " CPL_FRMT_GIB
409
0
                         " in layer %s",
410
0
                         pszJSon, feature->GetFID(), GetName());
411
0
                CPLFree(pszJSon);
412
0
            }
413
414
0
            oIterCurves = oSetDestCurves.begin();
415
0
            for (; oIterCurves != oSetDestCurves.end(); ++oIterCurves)
416
0
            {
417
0
                OGRCurve *poCurve = *oIterCurves;
418
0
                if (geomType == wkbPolygon)
419
0
                {
420
0
                    poCurve = OGRCurve::CastToLinearRing(poCurve);
421
0
                }
422
0
                error = poPoly->addRingDirectly(poCurve);
423
0
                if (error != OGRERR_NONE)
424
0
                {
425
0
                    char *pszJSon = poCurve->exportToJson();
426
0
                    CPLError(CE_Warning, CPLE_AppDefined,
427
0
                             "Cannot add ring %s to feature " CPL_FRMT_GIB
428
0
                             " in layer %s",
429
0
                             pszJSon, feature->GetFID(), GetName());
430
0
                    CPLFree(pszJSon);
431
0
                }
432
0
            }
433
0
        }
434
435
0
        feature->SetGeomFieldDirectly(nSurfaceFieldIndex, poPoly);
436
0
    }
437
438
0
    ResetReading();
439
0
}
440
441
OGRMultiPolygon *OGRILI1Layer::Polygonize(OGRGeometryCollection *poLines,
442
                                          bool
443
#if defined(HAVE_GEOS)
444
                                              fix_crossing_lines
445
#endif
446
)
447
0
{
448
0
    if (poLines->getNumGeometries() == 0)
449
0
    {
450
0
        return new OGRMultiPolygon();
451
0
    }
452
453
#if defined(HAVE_GEOS)
454
    GEOSGeom *ahInGeoms = nullptr;
455
    OGRGeometryCollection *poNoncrossingLines = poLines;
456
    GEOSGeom hResultGeom = nullptr;
457
    OGRGeometry *poMP = nullptr;
458
459
    if (fix_crossing_lines && poLines->getNumGeometries() > 0)
460
    {
461
        CPLDebug("OGR_ILI", "Fixing crossing lines");
462
        // A union of the geometry collection with one line fixes
463
        // invalid geometries.
464
        OGRGeometry *poUnion = poLines->Union(poLines->getGeometryRef(0));
465
        if (poUnion != nullptr)
466
        {
467
            if (wkbFlatten(poUnion->getGeometryType()) ==
468
                    wkbGeometryCollection ||
469
                wkbFlatten(poUnion->getGeometryType()) == wkbMultiLineString)
470
            {
471
                poNoncrossingLines =
472
                    dynamic_cast<OGRGeometryCollection *>(poUnion);
473
                CPLDebug("OGR_ILI", "Fixed lines: %d",
474
                         poNoncrossingLines->getNumGeometries() -
475
                             poLines->getNumGeometries());
476
            }
477
            else
478
            {
479
                delete poUnion;
480
            }
481
        }
482
    }
483
484
    GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext();
485
486
    ahInGeoms = static_cast<GEOSGeom *>(
487
        CPLCalloc(sizeof(void *), poNoncrossingLines->getNumGeometries()));
488
    for (int i = 0; i < poNoncrossingLines->getNumGeometries(); i++)
489
        ahInGeoms[i] =
490
            poNoncrossingLines->getGeometryRef(i)->exportToGEOS(hGEOSCtxt);
491
492
    hResultGeom = GEOSPolygonize_r(hGEOSCtxt, ahInGeoms,
493
                                   poNoncrossingLines->getNumGeometries());
494
495
    for (int i = 0; i < poNoncrossingLines->getNumGeometries(); i++)
496
        GEOSGeom_destroy_r(hGEOSCtxt, ahInGeoms[i]);
497
    CPLFree(ahInGeoms);
498
    if (poNoncrossingLines != poLines)
499
        delete poNoncrossingLines;
500
501
    if (hResultGeom == nullptr)
502
    {
503
        OGRGeometry::freeGEOSContext(hGEOSCtxt);
504
        return new OGRMultiPolygon();
505
    }
506
507
    poMP = OGRGeometryFactory::createFromGEOS(hGEOSCtxt, hResultGeom);
508
509
    GEOSGeom_destroy_r(hGEOSCtxt, hResultGeom);
510
    OGRGeometry::freeGEOSContext(hGEOSCtxt);
511
512
    poMP = OGRGeometryFactory::forceToMultiPolygon(poMP);
513
    if (poMP && wkbFlatten(poMP->getGeometryType()) == wkbMultiPolygon)
514
        return dynamic_cast<OGRMultiPolygon *>(poMP);
515
516
    delete poMP;
517
    return new OGRMultiPolygon();
518
519
#else
520
0
    return new OGRMultiPolygon();
521
0
#endif
522
0
}
523
524
void OGRILI1Layer::PolygonizeAreaLayer(OGRILI1Layer *poAreaLineLayer,
525
                                       int
526
#if defined(HAVE_GEOS)
527
                                           nAreaFieldIndex
528
#endif
529
                                       ,
530
                                       int
531
#if defined(HAVE_GEOS)
532
                                           nPointFieldIndex
533
#endif
534
)
535
0
{
536
    // add all lines from poAreaLineLayer to collection
537
0
    OGRGeometryCollection *gc = new OGRGeometryCollection();
538
0
    poAreaLineLayer->ResetReading();
539
0
    while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef())
540
0
        gc->addGeometry(feature->GetGeometryRef());
541
542
    // polygonize lines
543
0
    CPLDebug("OGR_ILI", "Polygonizing layer %s with %d multilines",
544
0
             poAreaLineLayer->GetLayerDefn()->GetName(),
545
0
             gc->getNumGeometries());
546
0
    poAreaLineLayer = nullptr;
547
0
    OGRMultiPolygon *polys = Polygonize(gc, false);
548
0
    CPLDebug("OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries());
549
0
    if (polys->getNumGeometries() != GetFeatureCount())
550
0
    {
551
0
        CPLDebug("OGR_ILI", "Feature count of layer %s: " CPL_FRMT_GIB,
552
0
                 GetLayerDefn()->GetName(), GetFeatureCount());
553
0
        CPLDebug("OGR_ILI", "Polygonizing again with crossing line fix");
554
0
        delete polys;
555
0
        polys = Polygonize(gc, true);  // try again with crossing line fix
556
0
        CPLDebug("OGR_ILI", "Resulting polygons: %d",
557
0
                 polys->getNumGeometries());
558
0
    }
559
0
    delete gc;
560
561
    // associate polygon feature with data row according to centroid
562
#if defined(HAVE_GEOS)
563
    OGRPolygon emptyPoly;
564
565
    CPLDebug("OGR_ILI", "Associating layer %s with area polygons",
566
             GetLayerDefn()->GetName());
567
    GEOSGeom *ahInGeoms = static_cast<GEOSGeom *>(
568
        CPLCalloc(sizeof(void *), polys->getNumGeometries()));
569
    GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext();
570
    for (int i = 0; i < polys->getNumGeometries(); i++)
571
    {
572
        ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS(hGEOSCtxt);
573
        if (!GEOSisValid_r(hGEOSCtxt, ahInGeoms[i]))
574
            ahInGeoms[i] = nullptr;
575
    }
576
    for (int nFidx = 0; nFidx < nFeatures; nFidx++)
577
    {
578
        OGRFeature *feature = papoFeatures[nFidx];
579
        OGRGeometry *geomRef = feature->GetGeomFieldRef(nPointFieldIndex);
580
        if (!geomRef)
581
        {
582
            continue;
583
        }
584
        GEOSGeom point =
585
            reinterpret_cast<GEOSGeom>(geomRef->exportToGEOS(hGEOSCtxt));
586
587
        int i = 0;
588
        for (; i < polys->getNumGeometries(); i++)
589
        {
590
            if (ahInGeoms[i] && GEOSWithin_r(hGEOSCtxt, point, ahInGeoms[i]))
591
            {
592
                feature->SetGeomField(nAreaFieldIndex,
593
                                      polys->getGeometryRef(i));
594
                break;
595
            }
596
        }
597
        if (i == polys->getNumGeometries())
598
        {
599
            CPLDebug("OGR_ILI", "Association between area and point failed.");
600
            feature->SetGeometry(&emptyPoly);
601
        }
602
        GEOSGeom_destroy_r(hGEOSCtxt, point);
603
    }
604
    for (int i = 0; i < polys->getNumGeometries(); i++)
605
        GEOSGeom_destroy_r(hGEOSCtxt, ahInGeoms[i]);
606
    CPLFree(ahInGeoms);
607
    OGRGeometry::freeGEOSContext(hGEOSCtxt);
608
#endif
609
0
    delete polys;
610
0
}
611
612
/************************************************************************/
613
/*                             GetDataset()                             */
614
/************************************************************************/
615
616
GDALDataset *OGRILI1Layer::GetDataset()
617
0
{
618
0
    return poDS;
619
0
}