Coverage Report

Created: 2026-07-16 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/geom/GeometryFactory.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
7
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
8
 * Copyright (C) 2005 Refractions Research Inc.
9
 *
10
 * This is free software; you can redistribute and/or modify it under
11
 * the terms of the GNU Lesser General Public Licence as published
12
 * by the Free Software Foundation.
13
 * See the COPYING file for more information.
14
 *
15
 **********************************************************************
16
 *
17
 * Last port: geom/GeometryFactory.java r320 (JTS-1.12)
18
 *
19
 **********************************************************************/
20
21
#include <geos/geom/Coordinate.h>
22
#include <geos/geom/CoordinateSequence.h>
23
#include <geos/geom/CircularString.h>
24
#include <geos/geom/CurvePolygon.h>
25
#include <geos/geom/CompoundCurve.h>
26
#include <geos/geom/GeometryFactory.h>
27
#include <geos/geom/Point.h>
28
#include <geos/geom/LineString.h>
29
#include <geos/geom/LinearRing.h>
30
#include <geos/geom/Polygon.h>
31
#include <geos/geom/MultiCurve.h>
32
#include <geos/geom/MultiPoint.h>
33
#include <geos/geom/MultiLineString.h>
34
#include <geos/geom/MultiPolygon.h>
35
#include <geos/geom/MultiSurface.h>
36
#include <geos/geom/GeometryCollection.h>
37
#include <geos/geom/PrecisionModel.h>
38
#include <geos/geom/Envelope.h>
39
#include <geos/geom/util/CoordinateOperation.h>
40
#include <geos/geom/util/GeometryEditor.h>
41
#include <geos/util/IllegalArgumentException.h>
42
#include <geos/util.h>
43
44
#include <algorithm>
45
#include <cassert>
46
#include <vector>
47
#include <typeinfo>
48
#include <cmath>
49
50
#ifndef GEOS_DEBUG
51
#define GEOS_DEBUG 0
52
#endif
53
54
#if GEOS_DEBUG
55
#include <iostream>
56
#endif
57
58
namespace geos {
59
namespace geom { // geos::geom
60
61
namespace {
62
63
class gfCoordinateOperation: public util::CoordinateOperation {
64
    using CoordinateOperation::edit;
65
public:
66
    std::unique_ptr<CoordinateSequence>
67
    edit(const CoordinateSequence* coordSeq,
68
         const Geometry*) override
69
0
    {
70
0
        return detail::make_unique<CoordinateSequence>(*coordSeq);
71
0
    }
72
};
73
74
} // anonymous namespace
75
76
77
78
/*protected*/
79
GeometryFactory::GeometryFactory()
80
    :
81
313
    SRID(0)
82
313
    , _refCount(0), _autoDestroy(false)
83
313
{
84
#if GEOS_DEBUG
85
    std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::GeometryFactory()" << std::endl;
86
    std::cerr << "\tcreate PrecisionModel[" << &precisionModel << "]" << std::endl;
87
#endif
88
313
}
89
90
/*public static*/
91
GeometryFactory::Ptr
92
GeometryFactory::create()
93
309
{
94
309
    return GeometryFactory::Ptr(new GeometryFactory());
95
309
}
96
97
/*protected*/
98
GeometryFactory::GeometryFactory(const PrecisionModel* pm)
99
    :
100
0
    SRID(0)
101
0
    , _refCount(0), _autoDestroy(false)
102
0
{
103
#if GEOS_DEBUG
104
    std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::GeometryFactory(PrecisionModel[" << pm << "])" << std::endl;
105
#endif
106
0
    if(pm) {
107
0
        precisionModel = *pm;
108
0
    }
109
0
}
110
111
/*public static*/
112
GeometryFactory::Ptr
113
GeometryFactory::create(const PrecisionModel* pm)
114
0
{
115
0
    return GeometryFactory::Ptr(
116
0
               new GeometryFactory(pm)
117
0
           );
118
0
}
119
120
/*protected*/
121
GeometryFactory::GeometryFactory(const PrecisionModel* pm, int newSRID)
122
0
    : SRID(newSRID)
123
0
    , _refCount(0)
124
0
    , _autoDestroy(false)
125
0
{
126
#if GEOS_DEBUG
127
    std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::GeometryFactory(PrecisionModel[" << pm << "], SRID)" <<
128
              std::endl;
129
#endif
130
0
    if(pm) {
131
0
        precisionModel = *pm;
132
0
    }
133
0
}
134
135
/*public static*/
136
GeometryFactory::Ptr
137
GeometryFactory::create(const PrecisionModel* pm, int newSRID)
138
0
{
139
0
    return GeometryFactory::Ptr(
140
0
               new GeometryFactory(pm, newSRID)
141
0
           );
142
0
}
143
144
/*protected*/
145
GeometryFactory::GeometryFactory(const GeometryFactory& gf)
146
0
    : precisionModel(gf.precisionModel)
147
0
    , SRID(gf.SRID)
148
0
    , _refCount(0)
149
0
    , _autoDestroy(false)
150
0
{}
151
152
/*public static*/
153
GeometryFactory::Ptr
154
GeometryFactory::create(const GeometryFactory& gf)
155
0
{
156
0
    return GeometryFactory::Ptr(
157
0
               new GeometryFactory(gf)
158
0
           );
159
0
}
160
161
/*public virtual*/
162
GeometryFactory::~GeometryFactory()
163
313
{
164
#if GEOS_DEBUG
165
    std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::~GeometryFactory()" << std::endl;
166
#endif
167
313
}
168
169
/*public*/
170
std::unique_ptr<Point>
171
GeometryFactory::createPointFromInternalCoord(const Coordinate* coord,
172
        const Geometry* exemplar)
173
9.46k
{
174
9.46k
    assert(coord);
175
9.46k
    Coordinate newcoord = *coord;
176
9.46k
    exemplar->getPrecisionModel()->makePrecise(&newcoord);
177
9.46k
    return exemplar->getFactory()->createPoint(newcoord);
178
9.46k
}
179
180
181
/*public*/
182
std::unique_ptr<Geometry>
183
GeometryFactory::toGeometry(const Envelope* envelope) const
184
3.55k
{
185
3.55k
    CoordinateXY coord;
186
187
3.55k
    if(envelope->isNull()) {
188
0
        return createPoint();
189
0
    }
190
3.55k
    if(envelope->getMinX() == envelope->getMaxX() && envelope->getMinY() == envelope->getMaxY()) {
191
0
        coord.x = envelope->getMinX();
192
0
        coord.y = envelope->getMinY();
193
0
        return std::unique_ptr<Geometry>(createPoint(coord));
194
0
    }
195
196
3.55k
    auto cl = detail::make_unique<CoordinateSequence>(5u, false, false, false);
197
198
3.55k
    coord.x = envelope->getMinX();
199
3.55k
    coord.y = envelope->getMinY();
200
3.55k
    cl->setAt(coord, 0);
201
202
3.55k
    coord.x = envelope->getMaxX();
203
3.55k
    coord.y = envelope->getMinY();
204
3.55k
    cl->setAt(coord, 1);
205
206
3.55k
    coord.x = envelope->getMaxX();
207
3.55k
    coord.y = envelope->getMaxY();
208
3.55k
    cl->setAt(coord, 2);
209
210
3.55k
    coord.x = envelope->getMinX();
211
3.55k
    coord.y = envelope->getMaxY();
212
3.55k
    cl->setAt(coord, 3);
213
214
3.55k
    coord.x = envelope->getMinX();
215
3.55k
    coord.y = envelope->getMinY();
216
3.55k
    cl->setAt(coord, 4);
217
218
3.55k
    return createPolygon(createLinearRing(std::move(cl)));
219
3.55k
}
220
221
/*public*/
222
std::unique_ptr<Point>
223
GeometryFactory::createPoint(std::size_t coordinateDimension) const
224
13.4k
{
225
13.4k
    CoordinateSequence seq(0u, coordinateDimension);
226
13.4k
    return std::unique_ptr<Point>(new Point(std::move(seq), this));
227
13.4k
}
228
229
/*public*/
230
std::unique_ptr<Point>
231
GeometryFactory::createPoint(bool hasZ, bool hasM) const
232
0
{
233
0
    CoordinateSequence seq(0u, hasZ, hasM);
234
0
    return std::unique_ptr<Point>(new Point(std::move(seq), this));
235
0
}
236
237
/*public*/
238
std::unique_ptr<Point>
239
GeometryFactory::createPoint(std::unique_ptr<CoordinateSequence>&& coords) const
240
13.8k
{
241
13.8k
    if (!coords) {
242
0
        return createPoint();
243
0
    }
244
13.8k
    return std::unique_ptr<Point>(new Point(std::move(*coords), this));
245
13.8k
}
246
247
std::unique_ptr<Point>
248
GeometryFactory::createPoint(const CoordinateXY& coordinate) const
249
442
{
250
442
    return std::unique_ptr<Point>(new Point(coordinate, this));
251
442
}
252
253
/*public*/
254
std::unique_ptr<Point>
255
GeometryFactory::createPoint(const Coordinate& coordinate) const
256
5.19M
{
257
5.19M
    return std::unique_ptr<Point>(new Point(coordinate, this));
258
5.19M
}
259
260
std::unique_ptr<Point>
261
GeometryFactory::createPoint(const CoordinateXYM& coordinate) const
262
0
{
263
0
    return std::unique_ptr<Point>(new Point(coordinate, this));
264
0
}
265
266
std::unique_ptr<Point>
267
GeometryFactory::createPoint(const CoordinateXYZM& coordinate) const
268
562k
{
269
562k
    return std::unique_ptr<Point>(new Point(coordinate, this));
270
562k
}
271
272
/*public*/
273
std::unique_ptr<Point>
274
GeometryFactory::createPoint(const CoordinateSequence& fromCoords) const
275
0
{
276
0
    CoordinateSequence newCoords(fromCoords);
277
0
    return std::unique_ptr<Point>(new Point(std::move(newCoords), this));
278
279
0
}
280
281
/*public*/
282
std::unique_ptr<MultiLineString>
283
GeometryFactory::createMultiLineString() const
284
601
{
285
601
    return createMultiLineString(std::vector<std::unique_ptr<Geometry>>());
286
601
}
287
288
/*public*/
289
std::unique_ptr<MultiLineString>
290
GeometryFactory::createMultiLineString(const std::vector<const Geometry*>& fromLines)
291
const
292
13.9k
{
293
13.9k
    std::vector<std::unique_ptr<Geometry>> newGeoms(fromLines.size());
294
295
448k
    for(std::size_t i = 0; i < fromLines.size(); i++) {
296
434k
        auto line = dynamic_cast<const LineString*>(fromLines[i]);
297
298
434k
        if(!line) {
299
0
            throw geos::util::IllegalArgumentException("createMultiLineString called with a vector containing non-LineStrings");
300
0
        }
301
302
434k
        newGeoms[i].reset(new LineString(*line));
303
434k
    }
304
305
13.9k
    return createMultiLineString(std::move(newGeoms));
306
13.9k
}
307
308
std::unique_ptr<MultiLineString>
309
2.64k
GeometryFactory::createMultiLineString(std::vector<std::unique_ptr<LineString>> && fromLines) const {
310
    // Can't use make_unique because constructor is protected
311
2.64k
    return std::unique_ptr<MultiLineString>(new MultiLineString(std::move(fromLines), *this));
312
2.64k
}
313
314
std::unique_ptr<MultiLineString>
315
0
GeometryFactory::createMultiLineString(std::vector<std::unique_ptr<Curve>> && fromLines) const {
316
    // Can't use make_unique because constructor is protected
317
0
    return std::unique_ptr<MultiLineString>(new MultiLineString(std::move(fromLines), *this));
318
0
}
319
320
std::unique_ptr<MultiLineString>
321
59.8k
GeometryFactory::createMultiLineString(std::vector<std::unique_ptr<Geometry>> && fromLines) const {
322
    // Can't use make_unique because constructor is protected
323
59.8k
    return std::unique_ptr<MultiLineString>(new MultiLineString(std::move(fromLines), *this));
324
59.8k
}
325
326
std::unique_ptr<MultiCurve>
327
9
GeometryFactory::createMultiCurve() const {
328
9
    return createMultiCurve(std::vector<std::unique_ptr<Curve>>());
329
9
}
330
331
/*public*/
332
std::unique_ptr<MultiCurve>
333
GeometryFactory::createMultiCurve(const std::vector<const Geometry*>& fromCurves)
334
const
335
0
{
336
0
    std::vector<std::unique_ptr<Geometry>> newGeoms(fromCurves.size());
337
338
0
    for(std::size_t i = 0; i < fromCurves.size(); i++) {
339
0
        newGeoms[i]= fromCurves[i]->clone(); // MultiCurve constructor will check that it's actually a Curve
340
0
    }
341
342
0
    return createMultiCurve(std::move(newGeoms));
343
0
}
344
345
std::unique_ptr<MultiCurve>
346
292
GeometryFactory::createMultiCurve(std::vector<std::unique_ptr<Curve>> && fromCurves) const {
347
    // Can't use make_unique because constructor is protected
348
292
    return std::unique_ptr<MultiCurve>(new MultiCurve(std::move(fromCurves), *this));
349
292
}
350
351
std::unique_ptr<MultiCurve>
352
1.95k
GeometryFactory::createMultiCurve(std::vector<std::unique_ptr<Geometry>> && fromCurves) const {
353
    // Can't use make_unique because constructor is protected
354
1.95k
    return std::unique_ptr<MultiCurve>(new MultiCurve(std::move(fromCurves), *this));
355
1.95k
}
356
357
/*public*/
358
std::unique_ptr<GeometryCollection>
359
GeometryFactory::createGeometryCollection() const
360
73.8k
{
361
73.8k
    return createGeometryCollection(std::vector<std::unique_ptr<Geometry>>());
362
73.8k
}
363
364
/*public*/
365
std::unique_ptr<Geometry>
366
GeometryFactory::createEmptyGeometry(GeometryTypeId type, bool hasZ, bool hasM) const
367
32.4k
{
368
32.4k
    switch (type) {
369
0
        case GEOS_POINT: return createPoint(hasZ, hasM);
370
1.73k
        case GEOS_LINESTRING: return createLineString(hasZ, hasM);
371
0
        case GEOS_LINEARRING: return createLinearRing(hasZ, hasM);
372
927
        case GEOS_POLYGON: return createPolygon(hasZ, hasM);
373
0
        case GEOS_MULTIPOINT: return createMultiPoint();
374
0
        case GEOS_MULTILINESTRING: return createMultiLineString();
375
0
        case GEOS_MULTIPOLYGON: return createMultiPolygon();
376
29.8k
        case GEOS_GEOMETRYCOLLECTION: return createGeometryCollection();
377
0
        case GEOS_CIRCULARSTRING: return createCircularString(hasZ, hasM);
378
0
        case GEOS_COMPOUNDCURVE: return createCompoundCurve();
379
0
        case GEOS_CURVEPOLYGON: return createCurvePolygon(hasZ, hasM);
380
0
        case GEOS_MULTICURVE: return createMultiCurve();
381
0
        case GEOS_MULTISURFACE: return createMultiSurface();
382
0
        default:
383
0
            throw geos::util::IllegalArgumentException("Unexpected GeometryTypeId");
384
385
32.4k
    }
386
32.4k
}
387
388
/*public*/
389
std::unique_ptr<GeometryCollection>
390
GeometryFactory::createGeometryCollection(const std::vector<const Geometry*>& fromGeoms) const
391
0
{
392
0
    std::vector<std::unique_ptr<Geometry>> newGeoms(fromGeoms.size());
393
394
0
    for(std::size_t i = 0; i < fromGeoms.size(); i++) {
395
0
        newGeoms[i] = fromGeoms[i]->clone();
396
0
    }
397
398
0
    return createGeometryCollection(std::move(newGeoms));
399
0
}
400
401
/*public*/
402
std::unique_ptr<MultiPolygon>
403
GeometryFactory::createMultiPolygon() const
404
3.19k
{
405
3.19k
    return createMultiPolygon(std::vector<std::unique_ptr<Polygon>>());
406
3.19k
}
407
408
/*public*/
409
std::unique_ptr<MultiPolygon>
410
GeometryFactory::createMultiPolygon(std::vector<std::unique_ptr<Polygon>> && newPolys) const
411
5.87k
{
412
    // Can't use make_unique because constructor is protected
413
5.87k
    return std::unique_ptr<MultiPolygon>(new MultiPolygon(std::move(newPolys), *this));
414
5.87k
}
415
416
std::unique_ptr<MultiPolygon>
417
GeometryFactory::createMultiPolygon(std::vector<std::unique_ptr<Geometry>> && newPolys) const
418
15.8k
{
419
    // Can't use make_unique because constructor is protected
420
15.8k
    return std::unique_ptr<MultiPolygon>(new MultiPolygon(std::move(newPolys), *this));
421
15.8k
}
422
423
/*public*/
424
std::unique_ptr<MultiPolygon>
425
GeometryFactory::createMultiPolygon(const std::vector<const Geometry*>& fromPolys) const
426
13.9k
{
427
13.9k
    std::vector<std::unique_ptr<Geometry>> newGeoms(fromPolys.size());
428
429
14.6k
    for(std::size_t i = 0; i < fromPolys.size(); i++) {
430
760
        newGeoms[i] = fromPolys[i]->clone();
431
760
    }
432
433
13.9k
    return createMultiPolygon(std::move(newGeoms));
434
13.9k
}
435
436
std::unique_ptr<MultiSurface>
437
GeometryFactory::createMultiSurface() const
438
5
{
439
    // Can't use make_unique because constructor is protected
440
5
    return std::unique_ptr<MultiSurface>(new MultiSurface(std::vector<std::unique_ptr<Surface>>(), *this));
441
5
}
442
443
std::unique_ptr<MultiSurface>
444
GeometryFactory::createMultiSurface(std::vector<std::unique_ptr<Geometry>> && newSurfaces) const
445
100
{
446
    // Can't use make_unique because constructor is protected
447
100
    return std::unique_ptr<MultiSurface>(new MultiSurface(std::move(newSurfaces), *this));
448
100
}
449
450
std::unique_ptr<MultiSurface>
451
GeometryFactory::createMultiSurface(std::vector<std::unique_ptr<Surface>> && newSurfaces) const
452
25
{
453
    // Can't use make_unique because constructor is protected
454
25
    return std::unique_ptr<MultiSurface>(new MultiSurface(std::move(newSurfaces), *this));
455
25
}
456
457
/*public*/
458
std::unique_ptr<MultiSurface>
459
GeometryFactory::createMultiSurface(const std::vector<const Geometry*>& from) const
460
0
{
461
0
    std::vector<std::unique_ptr<Geometry>> newGeoms(from.size());
462
463
0
    for(std::size_t i = 0; i < from.size(); i++) {
464
0
        newGeoms[i] = from[i]->clone(); // MultiSurface constructor will check that it's actually a Surface
465
0
    }
466
467
0
    return createMultiSurface(std::move(newGeoms));
468
0
}
469
470
/*public*/
471
std::unique_ptr<LinearRing>
472
GeometryFactory::createLinearRing(std::size_t coordinateDimension) const
473
0
{
474
    // Can't use make_unique with protected constructor
475
0
    auto cs = detail::make_unique<CoordinateSequence>(0u, coordinateDimension);
476
0
    return std::unique_ptr<LinearRing>(new LinearRing(std::move(cs), *this));
477
0
}
478
479
/*public*/
480
std::unique_ptr<LinearRing>
481
GeometryFactory::createLinearRing(bool hasZ, bool hasM) const
482
736
{
483
    // Can't use make_unique with protected constructor
484
736
    auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
485
736
    return std::unique_ptr<LinearRing>(new LinearRing(std::move(cs), *this));
486
736
}
487
488
std::unique_ptr<LinearRing>
489
GeometryFactory::createLinearRing(CoordinateSequence::Ptr && newCoords) const
490
991k
{
491
    // Can't use make_unique with protected constructor
492
991k
    return std::unique_ptr<LinearRing>(new LinearRing(std::move(newCoords), *this));
493
991k
}
494
495
std::unique_ptr<LinearRing>
496
GeometryFactory::createLinearRing(const std::shared_ptr<const CoordinateSequence>& newCoords) const
497
0
{
498
    // Can't use make_unique with protected constructor
499
0
    return std::unique_ptr<LinearRing>(new LinearRing(newCoords, *this));
500
0
}
501
502
/*public*/
503
std::unique_ptr<LinearRing>
504
GeometryFactory::createLinearRing(const CoordinateSequence& fromCoords) const
505
0
{
506
0
    return createLinearRing(fromCoords.clone());
507
0
}
508
509
/*public*/
510
std::unique_ptr<MultiPoint>
511
GeometryFactory::createMultiPoint(std::vector<std::unique_ptr<Point>> && newPoints) const
512
24.7k
{
513
24.7k
    return std::unique_ptr<MultiPoint>(new MultiPoint(std::move(newPoints), *this));
514
24.7k
}
515
516
std::unique_ptr<MultiPoint>
517
GeometryFactory::createMultiPoint(std::vector<std::unique_ptr<Geometry>> && newPoints) const
518
45.3k
{
519
45.3k
    return std::unique_ptr<MultiPoint>(new MultiPoint(std::move(newPoints), *this));
520
45.3k
}
521
522
/*public*/
523
std::unique_ptr<MultiPoint>
524
GeometryFactory::createMultiPoint(const std::vector<const Geometry*>& fromPoints) const
525
13.9k
{
526
13.9k
    std::vector<std::unique_ptr<Geometry>> newGeoms(fromPoints.size());
527
2.20M
    for(std::size_t i = 0; i < fromPoints.size(); i++) {
528
2.18M
        newGeoms[i] = fromPoints[i]->clone();
529
2.18M
    }
530
531
13.9k
    return createMultiPoint(std::move(newGeoms));
532
13.9k
}
533
534
/*public*/
535
std::unique_ptr<MultiPoint>
536
GeometryFactory::createMultiPoint() const
537
2.23k
{
538
2.23k
    return std::unique_ptr<MultiPoint>(new MultiPoint(std::vector<std::unique_ptr<Geometry>>(), *this));
539
2.23k
}
540
541
/*public*/
542
std::unique_ptr<MultiPoint>
543
GeometryFactory::createMultiPoint(const CoordinateSequence& fromCoords) const
544
15.3k
{
545
15.3k
    std::size_t npts = fromCoords.getSize();
546
15.3k
    std::vector<std::unique_ptr<Geometry>> pts;
547
15.3k
    pts.reserve(npts);
548
549
3.75M
    fromCoords.forEach([&pts, this](const auto& coord) -> void {
550
3.75M
        pts.push_back(this->createPoint(coord));
551
3.75M
    });
Unexecuted instantiation: GeometryFactory.cpp:void geos::geom::GeometryFactory::createMultiPoint(geos::geom::CoordinateSequence const&) const::$_0::operator()<geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&) const
GeometryFactory.cpp:void geos::geom::GeometryFactory::createMultiPoint(geos::geom::CoordinateSequence const&) const::$_0::operator()<geos::geom::Coordinate>(geos::geom::Coordinate const&) const
Line
Count
Source
549
3.74M
    fromCoords.forEach([&pts, this](const auto& coord) -> void {
550
3.74M
        pts.push_back(this->createPoint(coord));
551
3.74M
    });
Unexecuted instantiation: GeometryFactory.cpp:void geos::geom::GeometryFactory::createMultiPoint(geos::geom::CoordinateSequence const&) const::$_0::operator()<geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&) const
GeometryFactory.cpp:void geos::geom::GeometryFactory::createMultiPoint(geos::geom::CoordinateSequence const&) const::$_0::operator()<geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&) const
Line
Count
Source
549
1.69k
    fromCoords.forEach([&pts, this](const auto& coord) -> void {
550
1.69k
        pts.push_back(this->createPoint(coord));
551
1.69k
    });
552
553
15.3k
    return createMultiPoint(std::move(pts));
554
15.3k
}
555
556
/*public*/
557
std::unique_ptr<Polygon>
558
GeometryFactory::createPolygon(std::size_t coordinateDimension) const
559
38.2k
{
560
38.2k
    auto cs = detail::make_unique<CoordinateSequence>(0u, coordinateDimension);
561
38.2k
    auto lr = createLinearRing(std::move(cs));
562
38.2k
    return createPolygon(std::move(lr));
563
38.2k
}
564
565
/*public*/
566
std::unique_ptr<Polygon>
567
GeometryFactory::createPolygon(bool hasZ, bool hasM) const
568
927
{
569
927
    auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
570
927
    auto lr = createLinearRing(std::move(cs));
571
927
    return createPolygon(std::move(lr));
572
927
}
573
574
std::unique_ptr<Polygon>
575
GeometryFactory::createPolygon(std::unique_ptr<LinearRing> && shell)
576
const
577
149k
{
578
    // Can't use make_unique with protected constructor
579
149k
    return std::unique_ptr<Polygon>(new Polygon(std::move(shell), *this));
580
149k
}
581
582
/*public*/
583
std::unique_ptr<Polygon>
584
GeometryFactory::createPolygon(CoordinateSequence && coords)
585
const
586
4.44k
{
587
4.44k
    auto cs = detail::make_unique<CoordinateSequence>(std::move(coords));
588
4.44k
    std::unique_ptr<geom::LinearRing> lr = createLinearRing(std::move(cs));
589
4.44k
    std::unique_ptr<geom::Polygon> ply = createPolygon(std::move(lr));
590
4.44k
    return ply;
591
4.44k
}
592
593
594
std::unique_ptr<Polygon>
595
GeometryFactory::createPolygon(std::unique_ptr<LinearRing> && shell, std::vector<std::unique_ptr<LinearRing>> && holes)
596
const
597
310k
{
598
    // Can't use make_unique with protected constructor
599
310k
    return std::unique_ptr<Polygon>(new Polygon(std::move(shell), std::move(holes), *this));
600
310k
}
601
602
/*public*/
603
Polygon*
604
GeometryFactory::createPolygon(const LinearRing& shell, const std::vector<LinearRing*>& holes)
605
const
606
0
{
607
0
    std::unique_ptr<LinearRing> newRing(new LinearRing(shell));
608
609
0
    std::vector<std::unique_ptr<LinearRing>> newHoles(holes.size());
610
611
0
    for(std::size_t i = 0; i < holes.size(); i++) {
612
0
        newHoles[i].reset(new LinearRing(*holes[i]));
613
0
    }
614
615
0
    return new Polygon(std::move(newRing), std::move(newHoles), *this);
616
0
}
617
618
/* public */
619
std::unique_ptr<CurvePolygon>
620
GeometryFactory::createCurvePolygon(bool hasZ, bool hasM)
621
const
622
736
{
623
    // Can't use make_unique with protected constructor
624
736
    return std::unique_ptr<CurvePolygon>(new CurvePolygon(createLinearRing(hasZ, hasM), *this));
625
736
}
626
627
/* public */
628
std::unique_ptr<CurvePolygon>
629
GeometryFactory::createCurvePolygon(std::unique_ptr<Curve> && shell)
630
const
631
66
{
632
    // Can't use make_unique with protected constructor
633
66
    return std::unique_ptr<CurvePolygon>(new CurvePolygon(std::move(shell), *this));
634
66
}
635
636
/* public */
637
std::unique_ptr<CurvePolygon>
638
GeometryFactory::createCurvePolygon(std::unique_ptr<Curve> && shell, std::vector<std::unique_ptr<Curve>> && holes)
639
const
640
323
{
641
    // Can't use make_unique with protected constructor
642
323
    return std::unique_ptr<CurvePolygon>(new CurvePolygon(std::move(shell), std::move(holes), *this));
643
323
}
644
645
static std::unique_ptr<LineString>
646
linearRingToLineString(std::unique_ptr<Curve> linearRing)
647
0
{
648
0
    const std::shared_ptr<const CoordinateSequence> pts = detail::down_cast<const SimpleCurve*>(linearRing.get())->getSharedCoordinates();
649
0
    return linearRing->getFactory()->createLineString(pts);
650
0
}
651
652
/* public */
653
std::unique_ptr<Surface>
654
GeometryFactory::createSurface(std::unique_ptr<Curve> && shell)
655
const
656
34.2k
{
657
34.2k
    if (shell->getGeometryTypeId() == GEOS_LINEARRING) {
658
34.2k
        std::unique_ptr<LinearRing> shellLR(detail::down_cast<LinearRing*>(shell.release()));
659
34.2k
        return createPolygon(std::move(shellLR));
660
34.2k
    }
661
662
7
    if (shell->getGeometryTypeId() == GEOS_LINEARRING) {
663
0
        shell = linearRingToLineString(std::move(shell));
664
0
    }
665
666
7
    return createCurvePolygon(std::move(shell));
667
34.2k
}
668
669
/* public */
670
std::unique_ptr<Surface>
671
GeometryFactory::createSurface(std::unique_ptr<Curve> && shell, std::vector<std::unique_ptr<Curve>> && holes)
672
const
673
1.00k
{
674
1.06k
    const bool returnPolygon = shell->getGeometryTypeId() == GEOS_LINEARRING && std::all_of(holes.begin(), holes.end(), [](const auto& hole) {
675
1.06k
        return hole->getGeometryTypeId() == GEOS_LINEARRING;
676
1.06k
    });
677
678
1.00k
    if (returnPolygon) {
679
1.00k
        std::unique_ptr<LinearRing> shellLR(detail::down_cast<LinearRing*>(shell.release()));
680
681
1.00k
        std::vector<std::unique_ptr<LinearRing>> holesLR(holes.size());
682
2.06k
        for (std::size_t i = 0; i < holes.size(); i++) {
683
1.06k
            holesLR[i].reset(detail::down_cast<LinearRing*>(holes[i].release()));
684
1.06k
        }
685
686
1.00k
        return createPolygon(std::move(shellLR), std::move(holesLR));
687
1.00k
    }
688
689
    // Purge LinearRings
690
0
    if (shell->getGeometryTypeId() == GEOS_LINEARRING) {
691
0
        shell = linearRingToLineString(std::move(shell));
692
0
    }
693
694
0
    for (std::size_t i = 0; i < holes.size(); i++) {
695
0
        if (holes[i]->getGeometryTypeId() == GEOS_LINEARRING) {
696
0
            holes[i] = linearRingToLineString(std::move(holes[i]));
697
0
        }
698
0
    }
699
700
0
    return createCurvePolygon(std::move(shell), std::move(holes));
701
1.00k
}
702
703
/*public*/
704
std::unique_ptr<LineString>
705
GeometryFactory::createLineString(std::size_t coordinateDimension) const
706
9.33k
{
707
9.33k
    auto cs = detail::make_unique<CoordinateSequence>(0u, coordinateDimension);
708
9.33k
    return createLineString(std::move(cs));
709
9.33k
}
710
711
/*public*/
712
std::unique_ptr<LineString>
713
GeometryFactory::createLineString(bool hasZ, bool hasM) const
714
1.73k
{
715
1.73k
    auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
716
1.73k
    return createLineString(std::move(cs));
717
1.73k
}
718
719
/*public*/
720
std::unique_ptr<CircularString>
721
GeometryFactory::createCircularString(bool hasZ, bool hasM) const
722
0
{
723
0
    auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
724
0
    return createCircularString(std::move(cs));
725
0
}
726
727
/*public*/
728
std::unique_ptr<LineString>
729
GeometryFactory::createLineString(const LineString& ls) const
730
22.3k
{
731
    // Can't use make_unique with protected constructor
732
22.3k
    return std::unique_ptr<LineString>(new LineString(ls));
733
22.3k
}
734
735
/*public*/
736
std::unique_ptr<CircularString>
737
GeometryFactory::createCircularString(const CircularString& ls) const
738
0
{
739
    // Can't use make_unique with protected constructor
740
0
    return std::unique_ptr<CircularString>(new CircularString(ls));
741
0
}
742
743
/*public*/
744
std::unique_ptr<LineString>
745
GeometryFactory::createLineString(const std::shared_ptr<const CoordinateSequence>& newCoords) const
746
61.3k
{
747
61.3k
    if (!newCoords)
748
0
        return createLineString();
749
    // Can't use make_unique with protected constructor
750
61.3k
    return std::unique_ptr<LineString>(new LineString(newCoords, *this));
751
61.3k
}
752
753
/*public*/
754
std::unique_ptr<LineString>
755
GeometryFactory::createLineString(CoordinateSequence::Ptr && newCoords)
756
const
757
2.93M
{
758
2.93M
    if (!newCoords)
759
0
        return createLineString();
760
    // Can't use make_unique with protected constructor
761
2.93M
    return std::unique_ptr<LineString>(new LineString(std::move(newCoords), *this));
762
2.93M
}
763
764
/*public*/
765
std::unique_ptr<CircularString>
766
GeometryFactory::createCircularString(CoordinateSequence::Ptr && newCoords)
767
const
768
125k
{
769
125k
    if (!newCoords)
770
0
        return createCircularString(false, false);
771
    // Can't use make_unique with protected constructor
772
125k
    return std::unique_ptr<CircularString>(new CircularString(std::move(newCoords), *this));
773
125k
}
774
775
std::unique_ptr<CircularString>
776
GeometryFactory::createCircularString(const std::shared_ptr<const CoordinateSequence>& newCoords)
777
const
778
67.8k
{
779
67.8k
    if (!newCoords)
780
0
        return createCircularString(false, false);
781
    // Can't use make_unique with protected constructor
782
67.8k
    return std::unique_ptr<CircularString>(new CircularString(newCoords, *this));
783
67.8k
}
784
785
/*public*/
786
std::unique_ptr<CompoundCurve>
787
GeometryFactory::createCompoundCurve()
788
const
789
105
{
790
105
    std::vector<std::unique_ptr<SimpleCurve>> curves;
791
105
    return createCompoundCurve(std::move(curves));
792
105
}
793
794
/*public*/
795
std::unique_ptr<CompoundCurve>
796
GeometryFactory::createCompoundCurve(std::vector<std::unique_ptr<SimpleCurve>>&& curves)
797
const
798
1.96k
{
799
1.96k
    return std::unique_ptr<CompoundCurve>(new CompoundCurve(std::move(curves), *this));
800
1.96k
}
801
802
/*public*/
803
std::unique_ptr<LineString>
804
GeometryFactory::createLineString(const CoordinateSequence& fromCoords)
805
const
806
1.10k
{
807
    // Can't use make_unique with protected constructor
808
1.10k
    return std::unique_ptr<LineString>(new LineString(fromCoords.clone(), *this));
809
1.10k
}
810
811
/*public*/
812
std::unique_ptr<CircularString>
813
GeometryFactory::createCircularString(const CoordinateSequence& fromCoords)
814
const
815
0
{
816
    // Can't use make_unique with protected constructor
817
0
    return std::unique_ptr<CircularString>(new CircularString(fromCoords.clone(), *this));
818
0
}
819
820
/*public*/
821
std::unique_ptr<Geometry>
822
GeometryFactory::createEmpty(int dimension) const
823
3.60k
{
824
3.60k
    switch (dimension) {
825
0
        case -1: return createGeometryCollection();
826
2.28k
        case 0: return createPoint();
827
1.31k
        case 1: return createLineString();
828
0
        case 2: return createPolygon();
829
0
        default:
830
0
            throw geos::util::IllegalArgumentException("Invalid dimension");
831
3.60k
    }
832
3.60k
}
833
834
/*public*/
835
std::unique_ptr<Geometry>
836
GeometryFactory::createEmpty(GeometryTypeId typeId) const
837
0
{
838
0
    switch (typeId) {
839
0
        case GEOS_POINT: return createPoint();
840
0
        case GEOS_LINESTRING: return createLineString();
841
0
        case GEOS_POLYGON: return createPolygon();
842
0
        case GEOS_CIRCULARSTRING: return createCircularString(false, false);
843
0
        case GEOS_COMPOUNDCURVE: return createCompoundCurve();
844
0
        case GEOS_CURVEPOLYGON: return createCurvePolygon(false, false);
845
0
        case GEOS_MULTIPOINT: return createMultiPoint();
846
0
        case GEOS_MULTILINESTRING: return createMultiLineString();
847
0
        case GEOS_MULTIPOLYGON: return createMultiPolygon();
848
0
        case GEOS_MULTICURVE: return createMultiCurve();
849
0
        case GEOS_MULTISURFACE: return createMultiSurface();
850
0
        case GEOS_GEOMETRYCOLLECTION: return createGeometryCollection();
851
0
        default:
852
0
            throw geos::util::IllegalArgumentException("Invalid GeometryTypeId");
853
0
    }
854
0
}
855
856
/*public*/
857
std::unique_ptr<Geometry>
858
GeometryFactory::createMulti(std::unique_ptr<Geometry> && geom) const
859
0
{
860
0
    GeometryTypeId typeId = geom->getGeometryTypeId();
861
862
    // Already a collection? Done!
863
0
    if (geom->isCollection())
864
0
        return std::move(geom);
865
866
0
    if (geom->isEmpty()) {
867
0
        return geom->getFactory()->createEmpty(Geometry::multiTypeId(typeId));
868
0
    }
869
870
0
    std::vector<std::unique_ptr<Geometry>> subgeoms;
871
0
    const GeometryFactory* gf = geom->getFactory();
872
0
    subgeoms.push_back(std::move(geom));
873
0
    switch (typeId) {
874
0
        case GEOS_POINT:
875
0
            return gf->createMultiPoint(std::move(subgeoms));
876
0
        case GEOS_LINESTRING:
877
0
            return gf->createMultiLineString(std::move(subgeoms));
878
0
        case GEOS_POLYGON:
879
0
            return gf->createMultiPolygon(std::move(subgeoms));
880
0
        case GEOS_CIRCULARSTRING:
881
0
        case GEOS_COMPOUNDCURVE:
882
0
            return gf->createMultiCurve(std::move(subgeoms));
883
0
        case GEOS_CURVEPOLYGON:
884
0
            return gf->createMultiSurface(std::move(subgeoms));
885
0
        default:
886
0
            throw geos::util::IllegalArgumentException("Unsupported GeometryTypeId");
887
0
    }
888
0
}
889
890
template<typename T>
891
48.2k
GeometryTypeId commonType(const T& geoms) {
892
48.2k
    if (geoms.empty()) {
893
0
        return GEOS_GEOMETRYCOLLECTION;
894
0
    }
895
896
48.2k
    if (geoms.size() == 1) {
897
0
        return geoms[0]->getGeometryTypeId();
898
0
    }
899
900
48.2k
    bool hasCurvedComponents = geoms[0]->hasCurvedComponents();
901
902
48.2k
    const Dimension::DimensionType dim = geoms[0]->getDimension();
903
3.89M
    for (std::size_t i = 1; i < geoms.size(); i++) {
904
3.85M
        hasCurvedComponents |= geoms[i]->hasCurvedComponents();
905
906
3.85M
        if (geoms[i]->getDimension() != dim) {
907
8.39k
            return GEOS_GEOMETRYCOLLECTION;
908
8.39k
        }
909
3.85M
    }
910
911
39.8k
    switch(geoms[0]->getGeometryTypeId()) {
912
8.34k
        case GEOS_POINT: return GEOS_MULTIPOINT;
913
22
        case GEOS_COMPOUNDCURVE:
914
1.02k
        case GEOS_CIRCULARSTRING: return GEOS_MULTICURVE;
915
1
        case GEOS_LINEARRING:
916
28.6k
        case GEOS_LINESTRING: return hasCurvedComponents ? GEOS_MULTICURVE : GEOS_MULTILINESTRING;
917
0
        case GEOS_CURVEPOLYGON: return GEOS_MULTISURFACE;
918
1.84k
        case GEOS_POLYGON: return hasCurvedComponents ? GEOS_MULTISURFACE : GEOS_MULTIPOLYGON;
919
0
        default: return GEOS_GEOMETRYCOLLECTION;
920
39.8k
    }
921
39.8k
}
geos::geom::GeometryTypeId geos::geom::commonType<std::__1::vector<std::__1::unique_ptr<geos::geom::Geometry, std::__1::default_delete<geos::geom::Geometry> >, std::__1::allocator<std::__1::unique_ptr<geos::geom::Geometry, std::__1::default_delete<geos::geom::Geometry> > > > >(std::__1::vector<std::__1::unique_ptr<geos::geom::Geometry, std::__1::default_delete<geos::geom::Geometry> >, std::__1::allocator<std::__1::unique_ptr<geos::geom::Geometry, std::__1::default_delete<geos::geom::Geometry> > > > const&)
Line
Count
Source
891
48.2k
GeometryTypeId commonType(const T& geoms) {
892
48.2k
    if (geoms.empty()) {
893
0
        return GEOS_GEOMETRYCOLLECTION;
894
0
    }
895
896
48.2k
    if (geoms.size() == 1) {
897
0
        return geoms[0]->getGeometryTypeId();
898
0
    }
899
900
48.2k
    bool hasCurvedComponents = geoms[0]->hasCurvedComponents();
901
902
48.2k
    const Dimension::DimensionType dim = geoms[0]->getDimension();
903
3.89M
    for (std::size_t i = 1; i < geoms.size(); i++) {
904
3.85M
        hasCurvedComponents |= geoms[i]->hasCurvedComponents();
905
906
3.85M
        if (geoms[i]->getDimension() != dim) {
907
8.39k
            return GEOS_GEOMETRYCOLLECTION;
908
8.39k
        }
909
3.85M
    }
910
911
39.8k
    switch(geoms[0]->getGeometryTypeId()) {
912
8.34k
        case GEOS_POINT: return GEOS_MULTIPOINT;
913
22
        case GEOS_COMPOUNDCURVE:
914
1.02k
        case GEOS_CIRCULARSTRING: return GEOS_MULTICURVE;
915
1
        case GEOS_LINEARRING:
916
28.6k
        case GEOS_LINESTRING: return hasCurvedComponents ? GEOS_MULTICURVE : GEOS_MULTILINESTRING;
917
0
        case GEOS_CURVEPOLYGON: return GEOS_MULTISURFACE;
918
1.84k
        case GEOS_POLYGON: return hasCurvedComponents ? GEOS_MULTISURFACE : GEOS_MULTIPOLYGON;
919
0
        default: return GEOS_GEOMETRYCOLLECTION;
920
39.8k
    }
921
39.8k
}
Unexecuted instantiation: geos::geom::GeometryTypeId geos::geom::commonType<std::__1::vector<geos::geom::Geometry const*, std::__1::allocator<geos::geom::Geometry const*> > >(std::__1::vector<geos::geom::Geometry const*, std::__1::allocator<geos::geom::Geometry const*> > const&)
922
923
std::unique_ptr<Geometry>
924
GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Geometry>> && geoms) const
925
110k
{
926
110k
    if (geoms.empty()) {
927
255
        return createGeometryCollection();
928
255
    }
929
930
110k
    if (geoms.size() == 1) {
931
61.8k
        return std::move(geoms[0]);
932
61.8k
    }
933
934
48.2k
    auto resultType = commonType(geoms);
935
936
48.2k
    switch(resultType) {
937
8.34k
        case GEOS_MULTIPOINT: return createMultiPoint(std::move(geoms));
938
1.33k
        case GEOS_MULTICURVE: return createMultiCurve(std::move(geoms));
939
28.3k
        case GEOS_MULTILINESTRING: return createMultiLineString(std::move(geoms));
940
1.84k
        case GEOS_MULTIPOLYGON: return createMultiPolygon(std::move(geoms));
941
0
        case GEOS_MULTISURFACE: return createMultiSurface(std::move(geoms));
942
8.39k
        default: return createGeometryCollection(std::move(geoms));
943
48.2k
    }
944
48.2k
}
945
946
std::unique_ptr<Geometry>
947
GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Point>> && geoms) const
948
1.79k
{
949
1.79k
    if (geoms.empty()) {
950
0
        return createGeometryCollection();
951
0
    }
952
953
1.79k
    if (geoms.size() == 1) {
954
83
        return std::move(geoms[0]);
955
83
    }
956
957
1.71k
    return createMultiPoint(std::move(geoms));
958
1.79k
}
959
960
std::unique_ptr<Geometry>
961
GeometryFactory::buildGeometry(std::vector<std::unique_ptr<LineString>> && geoms) const
962
0
{
963
0
    if (geoms.empty()) {
964
0
        return createGeometryCollection();
965
0
    }
966
967
0
    if (geoms.size() == 1) {
968
0
        return std::move(geoms[0]);
969
0
    }
970
971
0
    return createMultiLineString(std::move(geoms));
972
0
}
973
974
std::unique_ptr<Geometry>
975
GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Polygon>> && geoms) const
976
2.14k
{
977
2.14k
    if (geoms.empty()) {
978
0
        return createGeometryCollection();
979
0
    }
980
981
2.14k
    if (geoms.size() == 1) {
982
381
        return std::move(geoms[0]);
983
381
    }
984
985
1.76k
    return createMultiPolygon(std::move(geoms));
986
2.14k
}
987
988
std::unique_ptr<Geometry>
989
GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Curve>> && geoms) const
990
0
{
991
0
    if (geoms.empty()) {
992
0
        return createGeometryCollection();
993
0
    }
994
995
0
    if (geoms.size() == 1) {
996
0
        return std::move(geoms[0]);
997
0
    }
998
999
0
    const bool hasCurves = std::any_of(geoms.begin(), geoms.end(), [](const auto& geom) {
1000
0
        const auto typeId = geom->getGeometryTypeId();
1001
0
        return typeId == GEOS_COMPOUNDCURVE || typeId == GEOS_CIRCULARSTRING;
1002
0
    });
1003
1004
0
    if (hasCurves) {
1005
0
        return createMultiCurve(std::move(geoms));
1006
0
    } else {
1007
0
        return createMultiLineString(std::move(geoms));
1008
0
    }
1009
0
}
1010
1011
/*public*/
1012
std::unique_ptr<Geometry>
1013
GeometryFactory::buildGeometry(const std::vector<const Geometry*>& fromGeoms) const
1014
0
{
1015
0
    if(fromGeoms.empty()) {
1016
0
        return createGeometryCollection();
1017
0
    }
1018
1019
0
    if(fromGeoms.size() == 1) {
1020
0
        return fromGeoms[0]->clone();
1021
0
    }
1022
1023
0
    auto resultType = commonType(fromGeoms);
1024
1025
0
    switch(resultType) {
1026
0
        case GEOS_MULTIPOINT: return createMultiPoint(fromGeoms);
1027
0
        case GEOS_MULTICURVE: return createMultiCurve(fromGeoms);
1028
0
        case GEOS_MULTILINESTRING: return createMultiLineString(fromGeoms);
1029
0
        case GEOS_MULTIPOLYGON: return createMultiPolygon(fromGeoms);
1030
0
        case GEOS_MULTISURFACE: return createMultiSurface(fromGeoms);
1031
0
        default: return createGeometryCollection(fromGeoms);
1032
0
    }
1033
0
}
1034
1035
/*public*/
1036
std::unique_ptr<Geometry>
1037
GeometryFactory::createGeometry(const Geometry* g) const
1038
0
{
1039
    // could this be cached to make this more efficient? Or maybe it isn't enough overhead to bother
1040
    //return g->clone(); <-- a simple clone() wouldn't change the factory to `this`
1041
0
    util::GeometryEditor editor(this);
1042
0
    gfCoordinateOperation coordOp;
1043
0
    return editor.edit(g, &coordOp);
1044
0
}
1045
1046
/*public*/
1047
void
1048
GeometryFactory::destroyGeometry(Geometry* g) const
1049
0
{
1050
0
    delete g;
1051
0
}
1052
1053
/*public static*/
1054
const GeometryFactory*
1055
GeometryFactory::getDefaultInstance()
1056
4
{
1057
4
    static GeometryFactory defInstance;
1058
4
    return &defInstance;
1059
4
}
1060
1061
/*private*/
1062
void
1063
GeometryFactory::addRef() const
1064
17.6M
{
1065
17.6M
    ++_refCount;
1066
17.6M
}
1067
1068
/*private*/
1069
void
1070
GeometryFactory::dropRef() const
1071
17.6M
{
1072
17.6M
    if(! --_refCount) {
1073
309
        if(_autoDestroy) {
1074
309
            delete this;
1075
309
        }
1076
309
    }
1077
17.6M
}
1078
1079
void
1080
GeometryFactory::destroy()
1081
309
{
1082
309
    assert(!_autoDestroy); // don't call me twice !
1083
309
    _autoDestroy = true;
1084
309
    if(! _refCount) {
1085
0
        delete this;
1086
0
    }
1087
309
}
1088
1089
} // namespace geos::geom
1090
} // namespace geos