GEOS  3.6.2
GeometryFactory.h
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