| 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 <cassert>
|
|---|
| 45 | #include <vector>
|
|---|
| 46 | #include <typeinfo>
|
|---|
| 47 | #include <cmath>
|
|---|
| 48 |
|
|---|
| 49 | #ifndef GEOS_DEBUG
|
|---|
| 50 | #define GEOS_DEBUG 0
|
|---|
| 51 | #endif
|
|---|
| 52 |
|
|---|
| 53 | #if GEOS_DEBUG
|
|---|
| 54 | #include <iostream>
|
|---|
| 55 | #endif
|
|---|
| 56 |
|
|---|
| 57 | namespace geos {
|
|---|
| 58 | namespace geom { // geos::geom
|
|---|
| 59 |
|
|---|
| 60 | namespace {
|
|---|
| 61 |
|
|---|
| 62 | class gfCoordinateOperation: public util::CoordinateOperation {
|
|---|
| 63 | using CoordinateOperation::edit;
|
|---|
| 64 | public:
|
|---|
| 65 | std::unique_ptr<CoordinateSequence>
|
|---|
| 66 | edit(const CoordinateSequence* coordSeq,
|
|---|
| 67 | const Geometry*) override
|
|---|
| 68 | {
|
|---|
| 69 | return detail::make_unique<CoordinateSequence>(*coordSeq);
|
|---|
| 70 | }
|
|---|
| 71 | };
|
|---|
| 72 |
|
|---|
| 73 | } // anonymous namespace
|
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 |
|
|---|
| 77 | /*protected*/
|
|---|
| 78 | GeometryFactory::GeometryFactory()
|
|---|
| 79 | :
|
|---|
| 80 | SRID(0)
|
|---|
| 81 | , _refCount(0), _autoDestroy(false)
|
|---|
| 82 | {
|
|---|
| 83 | #if GEOS_DEBUG
|
|---|
| 84 | std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::GeometryFactory()" << std::endl;
|
|---|
| 85 | std::cerr << "\tcreate PrecisionModel[" << &precisionModel << "]" << std::endl;
|
|---|
| 86 | #endif
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | /*public static*/
|
|---|
| 90 | GeometryFactory::Ptr
|
|---|
| 91 | GeometryFactory::create()
|
|---|
| 92 | {
|
|---|
| 93 | return GeometryFactory::Ptr(new GeometryFactory());
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 | /*protected*/
|
|---|
| 97 | GeometryFactory::GeometryFactory(const PrecisionModel* pm)
|
|---|
| 98 | :
|
|---|
| 99 | SRID(0)
|
|---|
| 100 | , _refCount(0), _autoDestroy(false)
|
|---|
| 101 | {
|
|---|
| 102 | #if GEOS_DEBUG
|
|---|
| 103 | std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::GeometryFactory(PrecisionModel[" << pm << "])" << std::endl;
|
|---|
| 104 | #endif
|
|---|
| 105 | if(pm) {
|
|---|
| 106 | precisionModel = *pm;
|
|---|
| 107 | }
|
|---|
| 108 | }
|
|---|
| 109 |
|
|---|
| 110 | /*public static*/
|
|---|
| 111 | GeometryFactory::Ptr
|
|---|
| 112 | GeometryFactory::create(const PrecisionModel* pm)
|
|---|
| 113 | {
|
|---|
| 114 | return GeometryFactory::Ptr(
|
|---|
| 115 | new GeometryFactory(pm)
|
|---|
| 116 | );
|
|---|
| 117 | }
|
|---|
| 118 |
|
|---|
| 119 | /*protected*/
|
|---|
| 120 | GeometryFactory::GeometryFactory(const PrecisionModel* pm, int newSRID)
|
|---|
| 121 | : SRID(newSRID)
|
|---|
| 122 | , _refCount(0)
|
|---|
| 123 | , _autoDestroy(false)
|
|---|
| 124 | {
|
|---|
| 125 | #if GEOS_DEBUG
|
|---|
| 126 | std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::GeometryFactory(PrecisionModel[" << pm << "], SRID)" <<
|
|---|
| 127 | std::endl;
|
|---|
| 128 | #endif
|
|---|
| 129 | if(pm) {
|
|---|
| 130 | precisionModel = *pm;
|
|---|
| 131 | }
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| 134 | /*public static*/
|
|---|
| 135 | GeometryFactory::Ptr
|
|---|
| 136 | GeometryFactory::create(const PrecisionModel* pm, int newSRID)
|
|---|
| 137 | {
|
|---|
| 138 | return GeometryFactory::Ptr(
|
|---|
| 139 | new GeometryFactory(pm, newSRID)
|
|---|
| 140 | );
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | /*protected*/
|
|---|
| 144 | GeometryFactory::GeometryFactory(const GeometryFactory& gf)
|
|---|
| 145 | : precisionModel(gf.precisionModel)
|
|---|
| 146 | , SRID(gf.SRID)
|
|---|
| 147 | , _refCount(0)
|
|---|
| 148 | , _autoDestroy(false)
|
|---|
| 149 | {}
|
|---|
| 150 |
|
|---|
| 151 | /*public static*/
|
|---|
| 152 | GeometryFactory::Ptr
|
|---|
| 153 | GeometryFactory::create(const GeometryFactory& gf)
|
|---|
| 154 | {
|
|---|
| 155 | return GeometryFactory::Ptr(
|
|---|
| 156 | new GeometryFactory(gf)
|
|---|
| 157 | );
|
|---|
| 158 | }
|
|---|
| 159 |
|
|---|
| 160 | /*public virtual*/
|
|---|
| 161 | GeometryFactory::~GeometryFactory()
|
|---|
| 162 | {
|
|---|
| 163 | #if GEOS_DEBUG
|
|---|
| 164 | std::cerr << "GEOS_DEBUG: GeometryFactory[" << this << "]::~GeometryFactory()" << std::endl;
|
|---|
| 165 | #endif
|
|---|
| 166 | }
|
|---|
| 167 |
|
|---|
| 168 | /*public*/
|
|---|
| 169 | std::unique_ptr<Point>
|
|---|
| 170 | GeometryFactory::createPointFromInternalCoord(const Coordinate* coord,
|
|---|
| 171 | const Geometry* exemplar)
|
|---|
| 172 | {
|
|---|
| 173 | assert(coord);
|
|---|
| 174 | Coordinate newcoord = *coord;
|
|---|
| 175 | exemplar->getPrecisionModel()->makePrecise(&newcoord);
|
|---|
| 176 | return exemplar->getFactory()->createPoint(newcoord);
|
|---|
| 177 | }
|
|---|
| 178 |
|
|---|
| 179 |
|
|---|
| 180 | /*public*/
|
|---|
| 181 | std::unique_ptr<Geometry>
|
|---|
| 182 | GeometryFactory::toGeometry(const Envelope* envelope) const
|
|---|
| 183 | {
|
|---|
| 184 | CoordinateXY coord;
|
|---|
| 185 |
|
|---|
| 186 | if(envelope->isNull()) {
|
|---|
| 187 | return createPoint();
|
|---|
| 188 | }
|
|---|
| 189 | if(envelope->getMinX() == envelope->getMaxX() && envelope->getMinY() == envelope->getMaxY()) {
|
|---|
| 190 | coord.x = envelope->getMinX();
|
|---|
| 191 | coord.y = envelope->getMinY();
|
|---|
| 192 | return std::unique_ptr<Geometry>(createPoint(coord));
|
|---|
| 193 | }
|
|---|
| 194 |
|
|---|
| 195 | auto cl = detail::make_unique<CoordinateSequence>(5u, false, false, false);
|
|---|
| 196 |
|
|---|
| 197 | coord.x = envelope->getMinX();
|
|---|
| 198 | coord.y = envelope->getMinY();
|
|---|
| 199 | cl->setAt(coord, 0);
|
|---|
| 200 |
|
|---|
| 201 | coord.x = envelope->getMaxX();
|
|---|
| 202 | coord.y = envelope->getMinY();
|
|---|
| 203 | cl->setAt(coord, 1);
|
|---|
| 204 |
|
|---|
| 205 | coord.x = envelope->getMaxX();
|
|---|
| 206 | coord.y = envelope->getMaxY();
|
|---|
| 207 | cl->setAt(coord, 2);
|
|---|
| 208 |
|
|---|
| 209 | coord.x = envelope->getMinX();
|
|---|
| 210 | coord.y = envelope->getMaxY();
|
|---|
| 211 | cl->setAt(coord, 3);
|
|---|
| 212 |
|
|---|
| 213 | coord.x = envelope->getMinX();
|
|---|
| 214 | coord.y = envelope->getMinY();
|
|---|
| 215 | cl->setAt(coord, 4);
|
|---|
| 216 |
|
|---|
| 217 | return createPolygon(createLinearRing(std::move(cl)));
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | /*public*/
|
|---|
| 221 | std::unique_ptr<Point>
|
|---|
| 222 | GeometryFactory::createPoint(std::size_t coordinateDimension) const
|
|---|
| 223 | {
|
|---|
| 224 | CoordinateSequence seq(0u, coordinateDimension);
|
|---|
| 225 | return std::unique_ptr<Point>(new Point(std::move(seq), this));
|
|---|
| 226 | }
|
|---|
| 227 |
|
|---|
| 228 | /*public*/
|
|---|
| 229 | std::unique_ptr<Point>
|
|---|
| 230 | GeometryFactory::createPoint(bool hasZ, bool hasM) const
|
|---|
| 231 | {
|
|---|
| 232 | CoordinateSequence seq(0u, hasZ, hasM);
|
|---|
| 233 | return std::unique_ptr<Point>(new Point(std::move(seq), this));
|
|---|
| 234 | }
|
|---|
| 235 |
|
|---|
| 236 | /*public*/
|
|---|
| 237 | std::unique_ptr<Point>
|
|---|
| 238 | GeometryFactory::createPoint(std::unique_ptr<CoordinateSequence>&& coords) const
|
|---|
| 239 | {
|
|---|
| 240 | if (!coords) {
|
|---|
| 241 | return createPoint();
|
|---|
| 242 | }
|
|---|
| 243 | return std::unique_ptr<Point>(new Point(std::move(*coords), this));
|
|---|
| 244 | }
|
|---|
| 245 |
|
|---|
| 246 | std::unique_ptr<Point>
|
|---|
| 247 | GeometryFactory::createPoint(const CoordinateXY& coordinate) const
|
|---|
| 248 | {
|
|---|
| 249 | return std::unique_ptr<Point>(new Point(coordinate, this));
|
|---|
| 250 | }
|
|---|
| 251 |
|
|---|
| 252 | /*public*/
|
|---|
| 253 | std::unique_ptr<Point>
|
|---|
| 254 | GeometryFactory::createPoint(const Coordinate& coordinate) const
|
|---|
| 255 | {
|
|---|
| 256 | return std::unique_ptr<Point>(new Point(coordinate, this));
|
|---|
| 257 | }
|
|---|
| 258 |
|
|---|
| 259 | std::unique_ptr<Point>
|
|---|
| 260 | GeometryFactory::createPoint(const CoordinateXYM& coordinate) const
|
|---|
| 261 | {
|
|---|
| 262 | return std::unique_ptr<Point>(new Point(coordinate, this));
|
|---|
| 263 | }
|
|---|
| 264 |
|
|---|
| 265 | std::unique_ptr<Point>
|
|---|
| 266 | GeometryFactory::createPoint(const CoordinateXYZM& coordinate) const
|
|---|
| 267 | {
|
|---|
| 268 | return std::unique_ptr<Point>(new Point(coordinate, this));
|
|---|
| 269 | }
|
|---|
| 270 |
|
|---|
| 271 | /*public*/
|
|---|
| 272 | std::unique_ptr<Point>
|
|---|
| 273 | GeometryFactory::createPoint(const CoordinateSequence& fromCoords) const
|
|---|
| 274 | {
|
|---|
| 275 | CoordinateSequence newCoords(fromCoords);
|
|---|
| 276 | return std::unique_ptr<Point>(new Point(std::move(newCoords), this));
|
|---|
| 277 |
|
|---|
| 278 | }
|
|---|
| 279 |
|
|---|
| 280 | /*public*/
|
|---|
| 281 | std::unique_ptr<MultiLineString>
|
|---|
| 282 | GeometryFactory::createMultiLineString() const
|
|---|
| 283 | {
|
|---|
| 284 | return createMultiLineString(std::vector<std::unique_ptr<Geometry>>());
|
|---|
| 285 | }
|
|---|
| 286 |
|
|---|
| 287 | /*public*/
|
|---|
| 288 | std::unique_ptr<MultiLineString>
|
|---|
| 289 | GeometryFactory::createMultiLineString(const std::vector<const Geometry*>& fromLines)
|
|---|
| 290 | const
|
|---|
| 291 | {
|
|---|
| 292 | std::vector<std::unique_ptr<Geometry>> newGeoms(fromLines.size());
|
|---|
| 293 |
|
|---|
| 294 | for(std::size_t i = 0; i < fromLines.size(); i++) {
|
|---|
| 295 | auto line = dynamic_cast<const LineString*>(fromLines[i]);
|
|---|
| 296 |
|
|---|
| 297 | if(!line) {
|
|---|
| 298 | throw geos::util::IllegalArgumentException("createMultiLineString called with a vector containing non-LineStrings");
|
|---|
| 299 | }
|
|---|
| 300 |
|
|---|
| 301 | newGeoms[i].reset(new LineString(*line));
|
|---|
| 302 | }
|
|---|
| 303 |
|
|---|
| 304 | return createMultiLineString(std::move(newGeoms));
|
|---|
| 305 | }
|
|---|
| 306 |
|
|---|
| 307 | std::unique_ptr<MultiLineString>
|
|---|
| 308 | GeometryFactory::createMultiLineString(std::vector<std::unique_ptr<LineString>> && fromLines) const {
|
|---|
| 309 | // Can't use make_unique because constructor is protected
|
|---|
| 310 | return std::unique_ptr<MultiLineString>(new MultiLineString(std::move(fromLines), *this));
|
|---|
| 311 | }
|
|---|
| 312 |
|
|---|
| 313 | std::unique_ptr<MultiLineString>
|
|---|
| 314 | GeometryFactory::createMultiLineString(std::vector<std::unique_ptr<Geometry>> && fromLines) const {
|
|---|
| 315 | // Can't use make_unique because constructor is protected
|
|---|
| 316 | return std::unique_ptr<MultiLineString>(new MultiLineString(std::move(fromLines), *this));
|
|---|
| 317 | }
|
|---|
| 318 |
|
|---|
| 319 | std::unique_ptr<MultiCurve>
|
|---|
| 320 | GeometryFactory::createMultiCurve() const {
|
|---|
| 321 | return createMultiCurve(std::vector<std::unique_ptr<Curve>>());
|
|---|
| 322 | }
|
|---|
| 323 |
|
|---|
| 324 | std::unique_ptr<MultiCurve>
|
|---|
| 325 | GeometryFactory::createMultiCurve(std::vector<std::unique_ptr<Curve>> && fromCurves) const {
|
|---|
| 326 | // Can't use make_unique because constructor is protected
|
|---|
| 327 | return std::unique_ptr<MultiCurve>(new MultiCurve(std::move(fromCurves), *this));
|
|---|
| 328 | }
|
|---|
| 329 |
|
|---|
| 330 | std::unique_ptr<MultiCurve>
|
|---|
| 331 | GeometryFactory::createMultiCurve(std::vector<std::unique_ptr<Geometry>> && fromCurves) const {
|
|---|
| 332 | // Can't use make_unique because constructor is protected
|
|---|
| 333 | return std::unique_ptr<MultiCurve>(new MultiCurve(std::move(fromCurves), *this));
|
|---|
| 334 | }
|
|---|
| 335 |
|
|---|
| 336 | /*public*/
|
|---|
| 337 | std::unique_ptr<GeometryCollection>
|
|---|
| 338 | GeometryFactory::createGeometryCollection() const
|
|---|
| 339 | {
|
|---|
| 340 | return createGeometryCollection(std::vector<std::unique_ptr<Geometry>>());
|
|---|
| 341 | }
|
|---|
| 342 |
|
|---|
| 343 | /*public*/
|
|---|
| 344 | std::unique_ptr<Geometry>
|
|---|
| 345 | GeometryFactory::createEmptyGeometry(GeometryTypeId type, bool hasZ, bool hasM) const
|
|---|
| 346 | {
|
|---|
| 347 | switch (type) {
|
|---|
| 348 | case GEOS_POINT: return createPoint(hasZ, hasM);
|
|---|
| 349 | case GEOS_LINESTRING: return createLineString(hasZ, hasM);
|
|---|
| 350 | case GEOS_LINEARRING: return createLinearRing(hasZ, hasM);
|
|---|
| 351 | case GEOS_POLYGON: return createPolygon(hasZ, hasM);
|
|---|
| 352 | case GEOS_MULTIPOINT: return createMultiPoint();
|
|---|
| 353 | case GEOS_MULTILINESTRING: return createMultiLineString();
|
|---|
| 354 | case GEOS_MULTIPOLYGON: return createMultiPolygon();
|
|---|
| 355 | case GEOS_GEOMETRYCOLLECTION: return createGeometryCollection();
|
|---|
| 356 | case GEOS_CIRCULARSTRING: return createCircularString(hasZ, hasM);
|
|---|
| 357 | case GEOS_COMPOUNDCURVE: return createCompoundCurve();
|
|---|
| 358 | case GEOS_CURVEPOLYGON: return createCurvePolygon(hasZ, hasM);
|
|---|
| 359 | case GEOS_MULTICURVE: return createMultiCurve();
|
|---|
| 360 | case GEOS_MULTISURFACE: return createMultiSurface();
|
|---|
| 361 | default:
|
|---|
| 362 | throw geos::util::IllegalArgumentException("Unexpected GeometryTypeId");
|
|---|
| 363 |
|
|---|
| 364 | }
|
|---|
| 365 | }
|
|---|
| 366 |
|
|---|
| 367 | /*public*/
|
|---|
| 368 | std::unique_ptr<GeometryCollection>
|
|---|
| 369 | GeometryFactory::createGeometryCollection(const std::vector<const Geometry*>& fromGeoms) const
|
|---|
| 370 | {
|
|---|
| 371 | std::vector<std::unique_ptr<Geometry>> newGeoms(fromGeoms.size());
|
|---|
| 372 |
|
|---|
| 373 | for(std::size_t i = 0; i < fromGeoms.size(); i++) {
|
|---|
| 374 | newGeoms[i] = fromGeoms[i]->clone();
|
|---|
| 375 | }
|
|---|
| 376 |
|
|---|
| 377 | return createGeometryCollection(std::move(newGeoms));
|
|---|
| 378 | }
|
|---|
| 379 |
|
|---|
| 380 | /*public*/
|
|---|
| 381 | std::unique_ptr<MultiPolygon>
|
|---|
| 382 | GeometryFactory::createMultiPolygon() const
|
|---|
| 383 | {
|
|---|
| 384 | return createMultiPolygon(std::vector<std::unique_ptr<Polygon>>());
|
|---|
| 385 | }
|
|---|
| 386 |
|
|---|
| 387 | /*public*/
|
|---|
| 388 | std::unique_ptr<MultiPolygon>
|
|---|
| 389 | GeometryFactory::createMultiPolygon(std::vector<std::unique_ptr<Polygon>> && newPolys) const
|
|---|
| 390 | {
|
|---|
| 391 | // Can't use make_unique because constructor is protected
|
|---|
| 392 | return std::unique_ptr<MultiPolygon>(new MultiPolygon(std::move(newPolys), *this));
|
|---|
| 393 | }
|
|---|
| 394 |
|
|---|
| 395 | std::unique_ptr<MultiPolygon>
|
|---|
| 396 | GeometryFactory::createMultiPolygon(std::vector<std::unique_ptr<Geometry>> && newPolys) const
|
|---|
| 397 | {
|
|---|
| 398 | // Can't use make_unique because constructor is protected
|
|---|
| 399 | return std::unique_ptr<MultiPolygon>(new MultiPolygon(std::move(newPolys), *this));
|
|---|
| 400 | }
|
|---|
| 401 |
|
|---|
| 402 | /*public*/
|
|---|
| 403 | std::unique_ptr<MultiPolygon>
|
|---|
| 404 | GeometryFactory::createMultiPolygon(const std::vector<const Geometry*>& fromPolys) const
|
|---|
| 405 | {
|
|---|
| 406 | std::vector<std::unique_ptr<Geometry>> newGeoms(fromPolys.size());
|
|---|
| 407 |
|
|---|
| 408 | for(std::size_t i = 0; i < fromPolys.size(); i++) {
|
|---|
| 409 | newGeoms[i] = fromPolys[i]->clone();
|
|---|
| 410 | }
|
|---|
| 411 |
|
|---|
| 412 | return createMultiPolygon(std::move(newGeoms));
|
|---|
| 413 | }
|
|---|
| 414 |
|
|---|
| 415 | std::unique_ptr<MultiSurface>
|
|---|
| 416 | GeometryFactory::createMultiSurface() const
|
|---|
| 417 | {
|
|---|
| 418 | // Can't use make_unique because constructor is protected
|
|---|
| 419 | return std::unique_ptr<MultiSurface>(new MultiSurface(std::vector<std::unique_ptr<Surface>>(), *this));
|
|---|
| 420 | }
|
|---|
| 421 |
|
|---|
| 422 | std::unique_ptr<MultiSurface>
|
|---|
| 423 | GeometryFactory::createMultiSurface(std::vector<std::unique_ptr<Geometry>> && newSurfaces) const
|
|---|
| 424 | {
|
|---|
| 425 | // Can't use make_unique because constructor is protected
|
|---|
| 426 | return std::unique_ptr<MultiSurface>(new MultiSurface(std::move(newSurfaces), *this));
|
|---|
| 427 | }
|
|---|
| 428 |
|
|---|
| 429 | std::unique_ptr<MultiSurface>
|
|---|
| 430 | GeometryFactory::createMultiSurface(std::vector<std::unique_ptr<Surface>> && newSurfaces) const
|
|---|
| 431 | {
|
|---|
| 432 | // Can't use make_unique because constructor is protected
|
|---|
| 433 | return std::unique_ptr<MultiSurface>(new MultiSurface(std::move(newSurfaces), *this));
|
|---|
| 434 | }
|
|---|
| 435 |
|
|---|
| 436 | /*public*/
|
|---|
| 437 | std::unique_ptr<LinearRing>
|
|---|
| 438 | GeometryFactory::createLinearRing(std::size_t coordinateDimension) const
|
|---|
| 439 | {
|
|---|
| 440 | // Can't use make_unique with protected constructor
|
|---|
| 441 | auto cs = detail::make_unique<CoordinateSequence>(0u, coordinateDimension);
|
|---|
| 442 | return std::unique_ptr<LinearRing>(new LinearRing(std::move(cs), *this));
|
|---|
| 443 | }
|
|---|
| 444 |
|
|---|
| 445 | /*public*/
|
|---|
| 446 | std::unique_ptr<LinearRing>
|
|---|
| 447 | GeometryFactory::createLinearRing(bool hasZ, bool hasM) const
|
|---|
| 448 | {
|
|---|
| 449 | // Can't use make_unique with protected constructor
|
|---|
| 450 | auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
|
|---|
| 451 | return std::unique_ptr<LinearRing>(new LinearRing(std::move(cs), *this));
|
|---|
| 452 | }
|
|---|
| 453 |
|
|---|
| 454 | std::unique_ptr<LinearRing>
|
|---|
| 455 | GeometryFactory::createLinearRing(CoordinateSequence::Ptr && newCoords) const
|
|---|
| 456 | {
|
|---|
| 457 | // Can't use make_unique with protected constructor
|
|---|
| 458 | return std::unique_ptr<LinearRing>(new LinearRing(std::move(newCoords), *this));
|
|---|
| 459 | }
|
|---|
| 460 |
|
|---|
| 461 | /*public*/
|
|---|
| 462 | std::unique_ptr<LinearRing>
|
|---|
| 463 | GeometryFactory::createLinearRing(const CoordinateSequence& fromCoords) const
|
|---|
| 464 | {
|
|---|
| 465 | return createLinearRing(fromCoords.clone());
|
|---|
| 466 | }
|
|---|
| 467 |
|
|---|
| 468 | /*public*/
|
|---|
| 469 | std::unique_ptr<MultiPoint>
|
|---|
| 470 | GeometryFactory::createMultiPoint(std::vector<std::unique_ptr<Point>> && newPoints) const
|
|---|
| 471 | {
|
|---|
| 472 | return std::unique_ptr<MultiPoint>(new MultiPoint(std::move(newPoints), *this));
|
|---|
| 473 | }
|
|---|
| 474 |
|
|---|
| 475 | std::unique_ptr<MultiPoint>
|
|---|
| 476 | GeometryFactory::createMultiPoint(std::vector<std::unique_ptr<Geometry>> && newPoints) const
|
|---|
| 477 | {
|
|---|
| 478 | return std::unique_ptr<MultiPoint>(new MultiPoint(std::move(newPoints), *this));
|
|---|
| 479 | }
|
|---|
| 480 |
|
|---|
| 481 | /*public*/
|
|---|
| 482 | std::unique_ptr<MultiPoint>
|
|---|
| 483 | GeometryFactory::createMultiPoint(const std::vector<const Geometry*>& fromPoints) const
|
|---|
| 484 | {
|
|---|
| 485 | std::vector<std::unique_ptr<Geometry>> newGeoms(fromPoints.size());
|
|---|
| 486 | for(std::size_t i = 0; i < fromPoints.size(); i++) {
|
|---|
| 487 | newGeoms[i] = fromPoints[i]->clone();
|
|---|
| 488 | }
|
|---|
| 489 |
|
|---|
| 490 | return createMultiPoint(std::move(newGeoms));
|
|---|
| 491 | }
|
|---|
| 492 |
|
|---|
| 493 | /*public*/
|
|---|
| 494 | std::unique_ptr<MultiPoint>
|
|---|
| 495 | GeometryFactory::createMultiPoint() const
|
|---|
| 496 | {
|
|---|
| 497 | return std::unique_ptr<MultiPoint>(new MultiPoint(std::vector<std::unique_ptr<Geometry>>(), *this));
|
|---|
| 498 | }
|
|---|
| 499 |
|
|---|
| 500 | /*public*/
|
|---|
| 501 | std::unique_ptr<MultiPoint>
|
|---|
| 502 | GeometryFactory::createMultiPoint(const CoordinateSequence& fromCoords) const
|
|---|
| 503 | {
|
|---|
| 504 | std::size_t npts = fromCoords.getSize();
|
|---|
| 505 | std::vector<std::unique_ptr<Geometry>> pts;
|
|---|
| 506 | pts.reserve(npts);
|
|---|
| 507 |
|
|---|
| 508 | fromCoords.forEach([&pts, this](const auto& coord) -> void {
|
|---|
| 509 | pts.push_back(this->createPoint(coord));
|
|---|
| 510 | });
|
|---|
| 511 |
|
|---|
| 512 | return createMultiPoint(std::move(pts));
|
|---|
| 513 | }
|
|---|
| 514 |
|
|---|
| 515 | /*public*/
|
|---|
| 516 | std::unique_ptr<Polygon>
|
|---|
| 517 | GeometryFactory::createPolygon(std::size_t coordinateDimension) const
|
|---|
| 518 | {
|
|---|
| 519 | auto cs = detail::make_unique<CoordinateSequence>(0u, coordinateDimension);
|
|---|
| 520 | auto lr = createLinearRing(std::move(cs));
|
|---|
| 521 | return createPolygon(std::move(lr));
|
|---|
| 522 | }
|
|---|
| 523 |
|
|---|
| 524 | /*public*/
|
|---|
| 525 | std::unique_ptr<Polygon>
|
|---|
| 526 | GeometryFactory::createPolygon(bool hasZ, bool hasM) const
|
|---|
| 527 | {
|
|---|
| 528 | auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
|
|---|
| 529 | auto lr = createLinearRing(std::move(cs));
|
|---|
| 530 | return createPolygon(std::move(lr));
|
|---|
| 531 | }
|
|---|
| 532 |
|
|---|
| 533 | std::unique_ptr<Polygon>
|
|---|
| 534 | GeometryFactory::createPolygon(std::unique_ptr<LinearRing> && shell)
|
|---|
| 535 | const
|
|---|
| 536 | {
|
|---|
| 537 | // Can't use make_unique with protected constructor
|
|---|
| 538 | return std::unique_ptr<Polygon>(new Polygon(std::move(shell), *this));
|
|---|
| 539 | }
|
|---|
| 540 |
|
|---|
| 541 | /*public*/
|
|---|
| 542 | std::unique_ptr<Polygon>
|
|---|
| 543 | GeometryFactory::createPolygon(CoordinateSequence && coords)
|
|---|
| 544 | const
|
|---|
| 545 | {
|
|---|
| 546 | auto cs = detail::make_unique<CoordinateSequence>(std::move(coords));
|
|---|
| 547 | std::unique_ptr<geom::LinearRing> lr = createLinearRing(std::move(cs));
|
|---|
| 548 | std::unique_ptr<geom::Polygon> ply = createPolygon(std::move(lr));
|
|---|
| 549 | return ply;
|
|---|
| 550 | }
|
|---|
| 551 |
|
|---|
| 552 |
|
|---|
| 553 | std::unique_ptr<Polygon>
|
|---|
| 554 | GeometryFactory::createPolygon(std::unique_ptr<LinearRing> && shell, std::vector<std::unique_ptr<LinearRing>> && holes)
|
|---|
| 555 | const
|
|---|
| 556 | {
|
|---|
| 557 | // Can't use make_unique with protected constructor
|
|---|
| 558 | return std::unique_ptr<Polygon>(new Polygon(std::move(shell), std::move(holes), *this));
|
|---|
| 559 | }
|
|---|
| 560 |
|
|---|
| 561 | /*public*/
|
|---|
| 562 | Polygon*
|
|---|
| 563 | GeometryFactory::createPolygon(const LinearRing& shell, const std::vector<LinearRing*>& holes)
|
|---|
| 564 | const
|
|---|
| 565 | {
|
|---|
| 566 | std::unique_ptr<LinearRing> newRing(new LinearRing(shell));
|
|---|
| 567 |
|
|---|
| 568 | std::vector<std::unique_ptr<LinearRing>> newHoles(holes.size());
|
|---|
| 569 |
|
|---|
| 570 | for(std::size_t i = 0; i < holes.size(); i++) {
|
|---|
| 571 | newHoles[i].reset(new LinearRing(*holes[i]));
|
|---|
| 572 | }
|
|---|
| 573 |
|
|---|
| 574 | return new Polygon(std::move(newRing), std::move(newHoles), *this);
|
|---|
| 575 | }
|
|---|
| 576 |
|
|---|
| 577 | /* public */
|
|---|
| 578 | std::unique_ptr<CurvePolygon>
|
|---|
| 579 | GeometryFactory::createCurvePolygon(bool hasZ, bool hasM)
|
|---|
| 580 | const
|
|---|
| 581 | {
|
|---|
| 582 | // Can't use make_unique with protected constructor
|
|---|
| 583 | return std::unique_ptr<CurvePolygon>(new CurvePolygon(createLinearRing(hasZ, hasM), *this));
|
|---|
| 584 | }
|
|---|
| 585 |
|
|---|
| 586 | /* public */
|
|---|
| 587 | std::unique_ptr<CurvePolygon>
|
|---|
| 588 | GeometryFactory::createCurvePolygon(std::unique_ptr<Curve> && shell)
|
|---|
| 589 | const
|
|---|
| 590 | {
|
|---|
| 591 | // Can't use make_unique with protected constructor
|
|---|
| 592 | return std::unique_ptr<CurvePolygon>(new CurvePolygon(std::move(shell), *this));
|
|---|
| 593 | }
|
|---|
| 594 |
|
|---|
| 595 | /* public */
|
|---|
| 596 | std::unique_ptr<CurvePolygon>
|
|---|
| 597 | GeometryFactory::createCurvePolygon(std::unique_ptr<Curve> && shell, std::vector<std::unique_ptr<Curve>> && holes)
|
|---|
| 598 | const
|
|---|
| 599 | {
|
|---|
| 600 | // Can't use make_unique with protected constructor
|
|---|
| 601 | return std::unique_ptr<CurvePolygon>(new CurvePolygon(std::move(shell), std::move(holes), *this));
|
|---|
| 602 | }
|
|---|
| 603 |
|
|---|
| 604 | /*public*/
|
|---|
| 605 | std::unique_ptr<LineString>
|
|---|
| 606 | GeometryFactory::createLineString(std::size_t coordinateDimension) const
|
|---|
| 607 | {
|
|---|
| 608 | auto cs = detail::make_unique<CoordinateSequence>(0u, coordinateDimension);
|
|---|
| 609 | return createLineString(std::move(cs));
|
|---|
| 610 | }
|
|---|
| 611 |
|
|---|
| 612 | /*public*/
|
|---|
| 613 | std::unique_ptr<LineString>
|
|---|
| 614 | GeometryFactory::createLineString(bool hasZ, bool hasM) const
|
|---|
| 615 | {
|
|---|
| 616 | auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
|
|---|
| 617 | return createLineString(std::move(cs));
|
|---|
| 618 | }
|
|---|
| 619 |
|
|---|
| 620 | /*public*/
|
|---|
| 621 | std::unique_ptr<CircularString>
|
|---|
| 622 | GeometryFactory::createCircularString(bool hasZ, bool hasM) const
|
|---|
| 623 | {
|
|---|
| 624 | auto cs = detail::make_unique<CoordinateSequence>(0u, hasZ, hasM);
|
|---|
| 625 | return createCircularString(std::move(cs));
|
|---|
| 626 | }
|
|---|
| 627 |
|
|---|
| 628 | /*public*/
|
|---|
| 629 | std::unique_ptr<LineString>
|
|---|
| 630 | GeometryFactory::createLineString(const LineString& ls) const
|
|---|
| 631 | {
|
|---|
| 632 | // Can't use make_unique with protected constructor
|
|---|
| 633 | return std::unique_ptr<LineString>(new LineString(ls));
|
|---|
| 634 | }
|
|---|
| 635 |
|
|---|
| 636 | /*public*/
|
|---|
| 637 | std::unique_ptr<CircularString>
|
|---|
| 638 | GeometryFactory::createCircularString(const CircularString& ls) const
|
|---|
| 639 | {
|
|---|
| 640 | // Can't use make_unique with protected constructor
|
|---|
| 641 | return std::unique_ptr<CircularString>(new CircularString(ls));
|
|---|
| 642 | }
|
|---|
| 643 |
|
|---|
| 644 | /*public*/
|
|---|
| 645 | std::unique_ptr<LineString>
|
|---|
| 646 | GeometryFactory::createLineString(CoordinateSequence::Ptr && newCoords)
|
|---|
| 647 | const
|
|---|
| 648 | {
|
|---|
| 649 | if (!newCoords)
|
|---|
| 650 | return createLineString();
|
|---|
| 651 | // Can't use make_unique with protected constructor
|
|---|
| 652 | return std::unique_ptr<LineString>(new LineString(std::move(newCoords), *this));
|
|---|
| 653 | }
|
|---|
| 654 |
|
|---|
| 655 | /*public*/
|
|---|
| 656 | std::unique_ptr<CircularString>
|
|---|
| 657 | GeometryFactory::createCircularString(CoordinateSequence::Ptr && newCoords)
|
|---|
| 658 | const
|
|---|
| 659 | {
|
|---|
| 660 | if (!newCoords)
|
|---|
| 661 | return createCircularString(false, false);
|
|---|
| 662 | // Can't use make_unique with protected constructor
|
|---|
| 663 | return std::unique_ptr<CircularString>(new CircularString(std::move(newCoords), *this));
|
|---|
| 664 | }
|
|---|
| 665 |
|
|---|
| 666 | /*public*/
|
|---|
| 667 | std::unique_ptr<CompoundCurve>
|
|---|
| 668 | GeometryFactory::createCompoundCurve()
|
|---|
| 669 | const
|
|---|
| 670 | {
|
|---|
| 671 | std::vector<std::unique_ptr<SimpleCurve>> curves;
|
|---|
| 672 | return createCompoundCurve(std::move(curves));
|
|---|
| 673 | }
|
|---|
| 674 |
|
|---|
| 675 | /*public*/
|
|---|
| 676 | std::unique_ptr<CompoundCurve>
|
|---|
| 677 | GeometryFactory::createCompoundCurve(std::vector<std::unique_ptr<SimpleCurve>>&& curves)
|
|---|
| 678 | const
|
|---|
| 679 | {
|
|---|
| 680 | return std::unique_ptr<CompoundCurve>(new CompoundCurve(std::move(curves), *this));
|
|---|
| 681 | }
|
|---|
| 682 |
|
|---|
| 683 | /*public*/
|
|---|
| 684 | std::unique_ptr<LineString>
|
|---|
| 685 | GeometryFactory::createLineString(const CoordinateSequence& fromCoords)
|
|---|
| 686 | const
|
|---|
| 687 | {
|
|---|
| 688 | // Can't use make_unique with protected constructor
|
|---|
| 689 | return std::unique_ptr<LineString>(new LineString(fromCoords.clone(), *this));
|
|---|
| 690 | }
|
|---|
| 691 |
|
|---|
| 692 | /*public*/
|
|---|
| 693 | std::unique_ptr<CircularString>
|
|---|
| 694 | GeometryFactory::createCircularString(const CoordinateSequence& fromCoords)
|
|---|
| 695 | const
|
|---|
| 696 | {
|
|---|
| 697 | // Can't use make_unique with protected constructor
|
|---|
| 698 | return std::unique_ptr<CircularString>(new CircularString(fromCoords.clone(), *this));
|
|---|
| 699 | }
|
|---|
| 700 |
|
|---|
| 701 | /*public*/
|
|---|
| 702 | std::unique_ptr<Geometry>
|
|---|
| 703 | GeometryFactory::createEmpty(int dimension) const
|
|---|
| 704 | {
|
|---|
| 705 | switch (dimension) {
|
|---|
| 706 | case -1: return createGeometryCollection();
|
|---|
| 707 | case 0: return createPoint();
|
|---|
| 708 | case 1: return createLineString();
|
|---|
| 709 | case 2: return createPolygon();
|
|---|
| 710 | default:
|
|---|
| 711 | throw geos::util::IllegalArgumentException("Invalid dimension");
|
|---|
| 712 | }
|
|---|
| 713 | }
|
|---|
| 714 |
|
|---|
| 715 | /*public*/
|
|---|
| 716 | std::unique_ptr<Geometry>
|
|---|
| 717 | GeometryFactory::createEmpty(GeometryTypeId typeId) const
|
|---|
| 718 | {
|
|---|
| 719 | switch (typeId) {
|
|---|
| 720 | case GEOS_POINT: return createPoint();
|
|---|
| 721 | case GEOS_LINESTRING: return createLineString();
|
|---|
| 722 | case GEOS_POLYGON: return createPolygon();
|
|---|
| 723 | case GEOS_MULTIPOINT: return createMultiPoint();
|
|---|
| 724 | case GEOS_MULTILINESTRING: return createMultiLineString();
|
|---|
| 725 | case GEOS_MULTIPOLYGON: return createMultiPolygon();
|
|---|
| 726 | case GEOS_GEOMETRYCOLLECTION: return createGeometryCollection();
|
|---|
| 727 | default:
|
|---|
| 728 | throw geos::util::IllegalArgumentException("Invalid GeometryTypeId");
|
|---|
| 729 | }
|
|---|
| 730 | }
|
|---|
| 731 |
|
|---|
| 732 | /*public*/
|
|---|
| 733 | std::unique_ptr<Geometry>
|
|---|
| 734 | GeometryFactory::createMulti(std::unique_ptr<Geometry> && geom) const
|
|---|
| 735 | {
|
|---|
| 736 | GeometryTypeId typeId = geom->getGeometryTypeId();
|
|---|
| 737 |
|
|---|
| 738 | // Already a collection? Done!
|
|---|
| 739 | if (geom->isCollection())
|
|---|
| 740 | return std::move(geom);
|
|---|
| 741 |
|
|---|
| 742 | if (geom->isEmpty()) {
|
|---|
| 743 | return geom->getFactory()->createEmpty(Geometry::multiTypeId(typeId));
|
|---|
| 744 | }
|
|---|
| 745 |
|
|---|
| 746 | std::vector<std::unique_ptr<Geometry>> subgeoms;
|
|---|
| 747 | const GeometryFactory* gf = geom->getFactory();
|
|---|
| 748 | subgeoms.push_back(std::move(geom));
|
|---|
| 749 | switch (typeId) {
|
|---|
| 750 | case GEOS_POINT:
|
|---|
| 751 | return gf->createMultiPoint(std::move(subgeoms));
|
|---|
| 752 | case GEOS_LINESTRING:
|
|---|
| 753 | return gf->createMultiLineString(std::move(subgeoms));
|
|---|
| 754 | case GEOS_POLYGON:
|
|---|
| 755 | return gf->createMultiPolygon(std::move(subgeoms));
|
|---|
| 756 | default:
|
|---|
| 757 | throw geos::util::IllegalArgumentException("Unsupported GeometryTypeId");
|
|---|
| 758 | }
|
|---|
| 759 | }
|
|---|
| 760 |
|
|---|
| 761 | template<typename T>
|
|---|
| 762 | GeometryTypeId commonType(const T& geoms) {
|
|---|
| 763 | if (geoms.empty()) {
|
|---|
| 764 | return GEOS_GEOMETRYCOLLECTION;
|
|---|
| 765 | }
|
|---|
| 766 |
|
|---|
| 767 | if (geoms.size() == 1) {
|
|---|
| 768 | return geoms[0]->getGeometryTypeId();
|
|---|
| 769 | }
|
|---|
| 770 |
|
|---|
| 771 | GeometryTypeId type = geoms[0]->getGeometryTypeId();
|
|---|
| 772 | for (std::size_t i = 1; i < geoms.size(); i++) {
|
|---|
| 773 | if (geoms[i]->getGeometryTypeId() != type) {
|
|---|
| 774 | return GEOS_GEOMETRYCOLLECTION;
|
|---|
| 775 | }
|
|---|
| 776 | }
|
|---|
| 777 |
|
|---|
| 778 | switch(geoms[0]->getGeometryTypeId()) {
|
|---|
| 779 | case GEOS_POINT: return GEOS_MULTIPOINT;
|
|---|
| 780 | case GEOS_LINEARRING:
|
|---|
| 781 | case GEOS_LINESTRING: return GEOS_MULTILINESTRING;
|
|---|
| 782 | case GEOS_POLYGON: return GEOS_MULTIPOLYGON;
|
|---|
| 783 | default: return GEOS_GEOMETRYCOLLECTION;
|
|---|
| 784 | }
|
|---|
| 785 | }
|
|---|
| 786 |
|
|---|
| 787 | std::unique_ptr<Geometry>
|
|---|
| 788 | GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Geometry>> && geoms) const
|
|---|
| 789 | {
|
|---|
| 790 | if (geoms.empty()) {
|
|---|
| 791 | return createGeometryCollection();
|
|---|
| 792 | }
|
|---|
| 793 |
|
|---|
| 794 | if (geoms.size() == 1) {
|
|---|
| 795 | return std::move(geoms[0]);
|
|---|
| 796 | }
|
|---|
| 797 |
|
|---|
| 798 | auto resultType = commonType(geoms);
|
|---|
| 799 |
|
|---|
| 800 | switch(resultType) {
|
|---|
| 801 | case GEOS_MULTIPOINT: return createMultiPoint(std::move(geoms));
|
|---|
| 802 | case GEOS_MULTILINESTRING: return createMultiLineString(std::move(geoms));
|
|---|
| 803 | case GEOS_MULTIPOLYGON: return createMultiPolygon(std::move(geoms));
|
|---|
| 804 | default: return createGeometryCollection(std::move(geoms));
|
|---|
| 805 | }
|
|---|
| 806 | }
|
|---|
| 807 |
|
|---|
| 808 | std::unique_ptr<Geometry>
|
|---|
| 809 | GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Point>> && geoms) const
|
|---|
| 810 | {
|
|---|
| 811 | if (geoms.empty()) {
|
|---|
| 812 | return createGeometryCollection();
|
|---|
| 813 | }
|
|---|
| 814 |
|
|---|
| 815 | if (geoms.size() == 1) {
|
|---|
| 816 | return std::move(geoms[0]);
|
|---|
| 817 | }
|
|---|
| 818 |
|
|---|
| 819 | return createMultiPoint(std::move(geoms));
|
|---|
| 820 | }
|
|---|
| 821 |
|
|---|
| 822 | std::unique_ptr<Geometry>
|
|---|
| 823 | GeometryFactory::buildGeometry(std::vector<std::unique_ptr<LineString>> && geoms) const
|
|---|
| 824 | {
|
|---|
| 825 | if (geoms.empty()) {
|
|---|
| 826 | return createGeometryCollection();
|
|---|
| 827 | }
|
|---|
| 828 |
|
|---|
| 829 | if (geoms.size() == 1) {
|
|---|
| 830 | return std::move(geoms[0]);
|
|---|
| 831 | }
|
|---|
| 832 |
|
|---|
| 833 | return createMultiLineString(std::move(geoms));
|
|---|
| 834 | }
|
|---|
| 835 |
|
|---|
| 836 | std::unique_ptr<Geometry>
|
|---|
| 837 | GeometryFactory::buildGeometry(std::vector<std::unique_ptr<Polygon>> && geoms) const
|
|---|
| 838 | {
|
|---|
| 839 | if (geoms.empty()) {
|
|---|
| 840 | return createGeometryCollection();
|
|---|
| 841 | }
|
|---|
| 842 |
|
|---|
| 843 | if (geoms.size() == 1) {
|
|---|
| 844 | return std::move(geoms[0]);
|
|---|
| 845 | }
|
|---|
| 846 |
|
|---|
| 847 | return createMultiPolygon(std::move(geoms));
|
|---|
| 848 | }
|
|---|
| 849 |
|
|---|
| 850 | /*public*/
|
|---|
| 851 | std::unique_ptr<Geometry>
|
|---|
| 852 | GeometryFactory::buildGeometry(const std::vector<const Geometry*>& fromGeoms) const
|
|---|
| 853 | {
|
|---|
| 854 | if(fromGeoms.empty()) {
|
|---|
| 855 | return createGeometryCollection();
|
|---|
| 856 | }
|
|---|
| 857 |
|
|---|
| 858 | if(fromGeoms.size() == 1) {
|
|---|
| 859 | return fromGeoms[0]->clone();
|
|---|
| 860 | }
|
|---|
| 861 |
|
|---|
| 862 | auto resultType = commonType(fromGeoms);
|
|---|
| 863 |
|
|---|
| 864 | switch(resultType) {
|
|---|
| 865 | case GEOS_MULTIPOINT: return createMultiPoint(fromGeoms);
|
|---|
| 866 | case GEOS_MULTILINESTRING: return createMultiLineString(fromGeoms);
|
|---|
| 867 | case GEOS_MULTIPOLYGON: return createMultiPolygon(fromGeoms);
|
|---|
| 868 | default: return createGeometryCollection(fromGeoms);
|
|---|
| 869 | }
|
|---|
| 870 | }
|
|---|
| 871 |
|
|---|
| 872 | /*public*/
|
|---|
| 873 | std::unique_ptr<Geometry>
|
|---|
| 874 | GeometryFactory::createGeometry(const Geometry* g) const
|
|---|
| 875 | {
|
|---|
| 876 | // could this be cached to make this more efficient? Or maybe it isn't enough overhead to bother
|
|---|
| 877 | //return g->clone(); <-- a simple clone() wouldn't change the factory to `this`
|
|---|
| 878 | util::GeometryEditor editor(this);
|
|---|
| 879 | gfCoordinateOperation coordOp;
|
|---|
| 880 | return editor.edit(g, &coordOp);
|
|---|
| 881 | }
|
|---|
| 882 |
|
|---|
| 883 | /*public*/
|
|---|
| 884 | void
|
|---|
| 885 | GeometryFactory::destroyGeometry(Geometry* g) const
|
|---|
| 886 | {
|
|---|
| 887 | delete g;
|
|---|
| 888 | }
|
|---|
| 889 |
|
|---|
| 890 | /*public static*/
|
|---|
| 891 | const GeometryFactory*
|
|---|
| 892 | GeometryFactory::getDefaultInstance()
|
|---|
| 893 | {
|
|---|
| 894 | static GeometryFactory defInstance;
|
|---|
| 895 | return &defInstance;
|
|---|
| 896 | }
|
|---|
| 897 |
|
|---|
| 898 | /*private*/
|
|---|
| 899 | void
|
|---|
| 900 | GeometryFactory::addRef() const
|
|---|
| 901 | {
|
|---|
| 902 | ++_refCount;
|
|---|
| 903 | }
|
|---|
| 904 |
|
|---|
| 905 | /*private*/
|
|---|
| 906 | void
|
|---|
| 907 | GeometryFactory::dropRef() const
|
|---|
| 908 | {
|
|---|
| 909 | if(! --_refCount) {
|
|---|
| 910 | if(_autoDestroy) {
|
|---|
| 911 | delete this;
|
|---|
| 912 | }
|
|---|
| 913 | }
|
|---|
| 914 | }
|
|---|
| 915 |
|
|---|
| 916 | void
|
|---|
| 917 | GeometryFactory::destroy()
|
|---|
| 918 | {
|
|---|
| 919 | assert(!_autoDestroy); // don't call me twice !
|
|---|
| 920 | _autoDestroy = true;
|
|---|
| 921 | if(! _refCount) {
|
|---|
| 922 | delete this;
|
|---|
| 923 | }
|
|---|
| 924 | }
|
|---|
| 925 |
|
|---|
| 926 | } // namespace geos::geom
|
|---|
| 927 | } // namespace geos
|
|---|