@@ -26,7 +26,7 @@ email : morb at ozemail dot com dot au
26
26
#include " qgsrect.h"
27
27
28
28
// Set up static GEOS geometry factory
29
- GEOS_GEOM::GeometryFactory* QgsGeometry:: geosGeometryFactory = new GEOS_GEOM::GeometryFactory();
29
+ static GEOS_GEOM::GeometryFactory* geosGeometryFactory = new GEOS_GEOM::GeometryFactory();
30
30
31
31
32
32
QgsGeometry::QgsGeometry ()
@@ -69,7 +69,7 @@ mDirtyGeos( rhs.mDirtyGeos )
69
69
{
70
70
polygonVector.push_back ((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN (i)));
71
71
}
72
- mGeos = QgsGeometry:: geosGeometryFactory->createMultiPolygon (polygonVector);
72
+ mGeos = geosGeometryFactory->createMultiPolygon (polygonVector);
73
73
}
74
74
}
75
75
else
@@ -120,24 +120,47 @@ QgsGeometry* QgsGeometry::fromPolyline(const QgsPolyline& polyline)
120
120
return g;
121
121
}
122
122
123
- QgsGeometry* QgsGeometry::fromPolygon (const QgsPolygon& polygon )
123
+ static GEOS_GEOM::LinearRing* _createGeosLinearRing (const QgsPolyline& ring )
124
124
{
125
- const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance ();
126
- const QgsPolyline& ring0 = polygon [0 ];
125
+ // LinearRing in GEOS must have the first point the same as the last one
126
+ bool needRepeatLastPnt = (ring [0 ] != ring[ring. count ()- 1 ]) ;
127
127
128
- // outer ring
129
- GEOS_GEOM::CoordinateSequence* seq = seqFactory->create (ring0.count (), 2 );
128
+ const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance ();
129
+
130
+ GEOS_GEOM::CoordinateSequence* seq = seqFactory->create (ring.count () + (needRepeatLastPnt ? 1 : 0 ), 2 );
130
131
QgsPolyline::const_iterator it;
131
132
int i = 0 ;
132
- for (it = ring0 .begin (); it != ring0 .end (); ++it)
133
+ for (it = ring .begin (); it != ring .end (); ++it)
133
134
{
134
135
seq->setAt (GEOS_GEOM::Coordinate (it->x (), it->y ()), i++);
135
136
}
137
+
138
+ // add the first point to close the ring if needed
139
+ if (needRepeatLastPnt)
140
+ seq->setAt (GEOS_GEOM::Coordinate (ring[0 ].x (), ring[0 ].y ()), ring.count ());
141
+
136
142
// ring takes ownership of the sequence
137
- GEOS_GEOM::LinearRing* outerRing = geosGeometryFactory->createLinearRing (seq);
143
+ GEOS_GEOM::LinearRing* linRing = geosGeometryFactory->createLinearRing (seq);
144
+
145
+ return linRing;
146
+ }
138
147
139
- std::vector<GEOS_GEOM::Geometry*>* holes = new std::vector<GEOS_GEOM::Geometry*>;
140
- // TODO: holes
148
+ QgsGeometry* QgsGeometry::fromPolygon (const QgsPolygon& polygon)
149
+ {
150
+ if (polygon.count () == 0 )
151
+ return NULL ;
152
+
153
+ const QgsPolyline& ring0 = polygon[0 ];
154
+
155
+ // outer ring
156
+ GEOS_GEOM::LinearRing* outerRing = _createGeosLinearRing (ring0);
157
+
158
+ // holes
159
+ std::vector<GEOS_GEOM::Geometry*>* holes = new std::vector<GEOS_GEOM::Geometry*> (polygon.count ()-1 );
160
+ for (int i = 1 ; i < polygon.count (); i++)
161
+ {
162
+ (*holes)[i-1 ] = _createGeosLinearRing (polygon[i]);
163
+ }
141
164
142
165
// new geometry takes ownership of outerRing and vector of holes
143
166
GEOS_GEOM::Geometry* geom = geosGeometryFactory->createPolygon (outerRing, holes);
@@ -191,7 +214,7 @@ QgsGeometry & QgsGeometry::operator=( QgsGeometry const & rhs )
191
214
{
192
215
polygonVector.push_back ((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN (i)));
193
216
}
194
- mGeos = QgsGeometry:: geosGeometryFactory->createMultiPolygon (polygonVector);
217
+ mGeos = geosGeometryFactory->createMultiPolygon (polygonVector);
195
218
}
196
219
}
197
220
else
0 commit comments