GEOS
3.6.2
|
00001 /********************************************************************** 00002 * 00003 * GEOS - Geometry Engine Open Source 00004 * http://geos.osgeo.org 00005 * 00006 * Copyright (C) 2011 Sandro Santilli <strk@keybit.net> 00007 * Copyright (C) 2006 Refractions Research Inc. 00008 * 00009 * This is free software; you can redistribute and/or modify it under 00010 * the terms of the GNU Lesser General Public Licence as published 00011 * by the Free Software Foundation. 00012 * See the COPYING file for more information. 00013 * 00014 ********************************************************************** 00015 * 00016 * Last port: geom/GeometryFactory.java r320 (JTS-1.12) 00017 * 00018 **********************************************************************/ 00019 00020 #ifndef GEOS_GEOM_GEOMETRYFACTORY_H 00021 #define GEOS_GEOM_GEOMETRYFACTORY_H 00022 00023 #include <geos/geom/Geometry.h> 00024 #include <geos/geom/GeometryCollection.h> 00025 #include <geos/geom/MultiPoint.h> 00026 #include <geos/geom/MultiLineString.h> 00027 #include <geos/geom/MultiPolygon.h> 00028 #include <geos/export.h> 00029 #include <geos/inline.h> 00030 00031 #include <vector> 00032 #include <memory> 00033 #include <cassert> 00034 00035 namespace geos { 00036 namespace geom { 00037 class CoordinateSequenceFactory; 00038 class Coordinate; 00039 class CoordinateSequence; 00040 class Envelope; 00041 class Geometry; 00042 class GeometryCollection; 00043 class LineString; 00044 class LinearRing; 00045 class MultiLineString; 00046 class MultiPoint; 00047 class MultiPolygon; 00048 class Point; 00049 class Polygon; 00050 class PrecisionModel; 00051 } 00052 } 00053 00054 namespace geos { 00055 namespace geom { // geos::geom 00056 00067 class GEOS_DLL GeometryFactory { 00068 public: 00069 00070 // TODO: typedef std::unique_ptr<GeometryFactory,destroy> 00071 class unique_ptr { 00072 mutable GeometryFactory *_f; 00073 public: 00074 // Copying an auto_unique_ptr transfers ownership 00075 unique_ptr(const unique_ptr& o): _f(o.release()) {}; 00076 GeometryFactory* release() const { GeometryFactory *f = _f; _f=0; return f; } 00077 void reset(GeometryFactory* f) { if ( _f ) _f->destroy(); _f = f; } 00078 // assigning an auto_unique_ptr transfers ownership 00079 unique_ptr& operator=(const unique_ptr& o) { 00080 reset( o.release() ); 00081 return *this; 00082 } 00083 GeometryFactory* get() const { return _f; } 00084 GeometryFactory* operator->() const { return _f; } 00085 GeometryFactory& operator*() { return *_f; }; 00086 unique_ptr(): _f(0) {} 00087 unique_ptr(GeometryFactory* f): _f(f) {} 00088 ~unique_ptr() { reset(0); } 00089 }; 00090 00096 static GeometryFactory::unique_ptr create(); 00097 00110 static GeometryFactory::unique_ptr create(const PrecisionModel *pm, int newSRID, 00111 CoordinateSequenceFactory *nCoordinateSequenceFactory); 00112 00119 static GeometryFactory::unique_ptr create(CoordinateSequenceFactory *nCoordinateSequenceFactory); 00120 00129 static GeometryFactory::unique_ptr create(const PrecisionModel *pm); 00130 00140 static GeometryFactory::unique_ptr create(const PrecisionModel* pm, int newSRID); 00141 00147 static GeometryFactory::unique_ptr create(const GeometryFactory &gf); 00148 00155 static const GeometryFactory* 00156 getDefaultInstance(); 00157 00158 //Skipped a lot of list to array convertors 00159 00160 Point* createPointFromInternalCoord(const Coordinate* coord, 00161 const Geometry *exemplar) const; 00162 00164 // 00167 Geometry* toGeometry(const Envelope* envelope) const; 00168 00172 const PrecisionModel* getPrecisionModel() const; 00173 00175 Point* createPoint() const; 00176 00178 Point* createPoint(const Coordinate& coordinate) const; 00179 00181 Point* createPoint(CoordinateSequence *coordinates) const; 00182 00184 Point* createPoint(const CoordinateSequence &coordinates) const; 00185 00187 GeometryCollection* createGeometryCollection() const; 00188 00190 Geometry* createEmptyGeometry() const; 00191 00193 GeometryCollection* createGeometryCollection( 00194 std::vector<Geometry *> *newGeoms) const; 00195 00197 GeometryCollection* createGeometryCollection( 00198 const std::vector<Geometry *> &newGeoms) const; 00199 00201 MultiLineString* createMultiLineString() const; 00202 00204 MultiLineString* createMultiLineString( 00205 std::vector<Geometry *> *newLines) const; 00206 00208 MultiLineString* createMultiLineString( 00209 const std::vector<Geometry *> &fromLines) const; 00210 00212 MultiPolygon* createMultiPolygon() const; 00213 00215 MultiPolygon* createMultiPolygon(std::vector<Geometry *> *newPolys) const; 00216 00218 MultiPolygon* createMultiPolygon( 00219 const std::vector<Geometry *> &fromPolys) const; 00220 00222 LinearRing* createLinearRing() const; 00223 00225 LinearRing* createLinearRing(CoordinateSequence* newCoords) const; 00226 00227 std::auto_ptr<Geometry> createLinearRing( 00228 std::auto_ptr<CoordinateSequence> newCoords) const; 00229 00231 LinearRing* createLinearRing( 00232 const CoordinateSequence& coordinates) const; 00233 00235 MultiPoint* createMultiPoint() const; 00236 00238 MultiPoint* createMultiPoint(std::vector<Geometry *> *newPoints) const; 00239 00241 MultiPoint* createMultiPoint( 00242 const std::vector<Geometry *> &fromPoints) const; 00243 00247 MultiPoint* createMultiPoint( 00248 const CoordinateSequence &fromCoords) const; 00249 00253 MultiPoint* createMultiPoint( 00254 const std::vector<Coordinate> &fromCoords) const; 00255 00257 Polygon* createPolygon() const; 00258 00260 Polygon* createPolygon(LinearRing *shell, 00261 std::vector<Geometry *> *holes) const; 00262 00264 Polygon* createPolygon(const LinearRing &shell, 00265 const std::vector<Geometry *> &holes) const; 00266 00268 LineString* createLineString() const; 00269 00271 std::auto_ptr<LineString> createLineString(const LineString& ls) const; 00272 00274 LineString* createLineString(CoordinateSequence* coordinates) const; 00275 00276 std::auto_ptr<Geometry> createLineString( 00277 std::auto_ptr<CoordinateSequence> coordinates) const; 00278 00280 LineString* createLineString( 00281 const CoordinateSequence& coordinates) const; 00282 00314 Geometry* buildGeometry(std::vector<Geometry *> *geoms) const; 00315 00317 // 00324 template <class T> 00325 std::auto_ptr<Geometry> buildGeometry(T from, T toofar) const 00326 { 00327 bool isHeterogeneous = false; 00328 size_t count = 0; 00329 int geomClass = -1; 00330 for (T i=from; i != toofar; ++i) 00331 { 00332 ++count; 00333 const Geometry* g = *i; 00334 if ( geomClass < 0 ) { 00335 geomClass = g->getClassSortIndex(); 00336 } 00337 else if ( geomClass != g->getClassSortIndex() ) { 00338 isHeterogeneous = true; 00339 } 00340 } 00341 00342 // for the empty geometry, return an empty GeometryCollection 00343 if ( count == 0 ) { 00344 return std::auto_ptr<Geometry>( createGeometryCollection() ); 00345 } 00346 00347 // for the single geometry, return a clone 00348 if ( count == 1 ) { 00349 return std::auto_ptr<Geometry>( (*from)->clone() ); 00350 } 00351 00352 // Now we know it is a collection 00353 00354 // FIXME: 00355 // Until we tweak all the createMulti* interfaces 00356 // to support taking iterators we'll have to build 00357 // a custom vector here. 00358 std::vector<Geometry*> fromGeoms; 00359 for (T i=from; i != toofar; ++i) { 00360 const Geometry* g = *i; 00361 fromGeoms.push_back(const_cast<Geometry*>(g)); 00362 } 00363 00364 00365 // for an heterogeneous ... 00366 if ( isHeterogeneous ) { 00367 return std::auto_ptr<Geometry>( createGeometryCollection(fromGeoms) ); 00368 } 00369 00370 // At this point we know the collection is not hetereogenous. 00371 if ( dynamic_cast<const Polygon*>(*from) ) { 00372 return std::auto_ptr<Geometry>( createMultiPolygon(fromGeoms) ); 00373 } else if ( dynamic_cast<const LineString*>(*from) ) { 00374 return std::auto_ptr<Geometry>( createMultiLineString(fromGeoms) ); 00375 } else if ( dynamic_cast<const Point*>(*from) ) { 00376 return std::auto_ptr<Geometry>( createMultiPoint(fromGeoms) ); 00377 } 00378 // FIXME: Why not to throw an exception? --mloskot 00379 assert(0); // buildGeomtry encountered an unkwnon geometry type 00380 return std::auto_ptr<Geometry>(); // nullptr 00381 } 00382 00390 Geometry* buildGeometry(const std::vector<Geometry *> &geoms) const; 00391 00392 int getSRID() const; 00393 00397 const CoordinateSequenceFactory* getCoordinateSequenceFactory() const; 00398 00400 Geometry* createGeometry(const Geometry *g) const; 00401 00403 void destroyGeometry(Geometry *g) const; 00404 00406 // 00411 void destroy(); 00412 00413 protected: 00414 00420 GeometryFactory(); 00421 00434 GeometryFactory(const PrecisionModel *pm, int newSRID, 00435 CoordinateSequenceFactory *nCoordinateSequenceFactory); 00436 00443 GeometryFactory(CoordinateSequenceFactory *nCoordinateSequenceFactory); 00444 00453 GeometryFactory(const PrecisionModel *pm); 00454 00464 GeometryFactory(const PrecisionModel* pm, int newSRID); 00465 00471 GeometryFactory(const GeometryFactory &gf); 00472 00474 virtual ~GeometryFactory(); 00475 00476 private: 00477 00478 const PrecisionModel* precisionModel; 00479 int SRID; 00480 const CoordinateSequenceFactory *coordinateListFactory; 00481 00482 mutable int _refCount; 00483 bool _autoDestroy; 00484 00485 friend class Geometry; 00486 00487 void addRef() const; 00488 void dropRef() const; 00489 00490 }; 00491 00492 } // namespace geos::geom 00493 } // namespace geos 00494 00495 #ifdef GEOS_INLINE 00496 # include "geos/geom/GeometryFactory.inl" 00497 #endif 00498 00499 #endif // ndef GEOS_GEOM_GEOMETRYFACTORY_H