Skip to content

Commit eb4cee1

Browse files
author
wonder
committed
Fixed QgsGeometry::fromPolygon:
- fixed creation of outer ring, added creation of holes - fixed Python binding for QgsPolygon type git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@6974 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 550b681 commit eb4cee1

File tree

3 files changed

+42
-22
lines changed

3 files changed

+42
-22
lines changed

python/core/qgsgeometry.sip

+7-5
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,21 @@ template <TYPE>
5050
%End
5151

5252
%ConvertToTypeCode
53+
const sipMappedType* qvector_qgspoint = sipFindMappedType("QVector<QgsPoint>");
54+
5355
// Check the type if that is all that is required.
5456
if (sipIsErr == NULL)
5557
{
5658
if (!PyList_Check(sipPy))
5759
return 0;
5860

5961
for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
60-
if (!sipCanConvertToInstance(PyList_GET_ITEM(sipPy, i), sipClass_TYPE, SIP_NOT_NONE))
62+
if (!sipCanConvertToMappedType(PyList_GET_ITEM(sipPy, i), qvector_qgspoint, SIP_NOT_NONE))
6163
return 0;
6264

6365
return 1;
6466
}
6567

66-
const sipMappedType* qvector_qgspoint = sipFindMappedType("QVector<QgsPoint>");
6768

6869
QVector< QVector<TYPE> > *ql = new QVector< QVector<TYPE> >;
6970

@@ -124,21 +125,22 @@ template <TYPE>
124125
%End
125126

126127
%ConvertToTypeCode
128+
129+
const sipMappedType* qvector_qgspoint = sipFindMappedType("QVector<QVector<QgsPoint> >");
130+
127131
// Check the type if that is all that is required.
128132
if (sipIsErr == NULL)
129133
{
130134
if (!PyList_Check(sipPy))
131135
return 0;
132136

133-
// TODO: this is not correct!
134137
for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
135-
if (!sipCanConvertToInstance(PyList_GET_ITEM(sipPy, i), sipClass_TYPE, SIP_NOT_NONE))
138+
if (!sipCanConvertToMappedType(PyList_GET_ITEM(sipPy, i), qvector_qgspoint, SIP_NOT_NONE))
136139
return 0;
137140

138141
return 1;
139142
}
140143

141-
const sipMappedType* qvector_qgspoint = sipFindMappedType("QVector<QVector<QgsPoint> >");
142144

143145
QVector< QVector< QVector<TYPE> > > *ql = new QVector< QVector< QVector<TYPE> > >;
144146

src/core/qgsgeometry.cpp

+35-12
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ email : morb at ozemail dot com dot au
2626
#include "qgsrect.h"
2727

2828
// 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();
3030

3131

3232
QgsGeometry::QgsGeometry()
@@ -69,7 +69,7 @@ mDirtyGeos( rhs.mDirtyGeos )
6969
{
7070
polygonVector.push_back((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN(i)));
7171
}
72-
mGeos = QgsGeometry::geosGeometryFactory->createMultiPolygon(polygonVector);
72+
mGeos = geosGeometryFactory->createMultiPolygon(polygonVector);
7373
}
7474
}
7575
else
@@ -120,24 +120,47 @@ QgsGeometry* QgsGeometry::fromPolyline(const QgsPolyline& polyline)
120120
return g;
121121
}
122122

123-
QgsGeometry* QgsGeometry::fromPolygon(const QgsPolygon& polygon)
123+
static GEOS_GEOM::LinearRing* _createGeosLinearRing(const QgsPolyline& ring)
124124
{
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]);
127127

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);
130131
QgsPolyline::const_iterator it;
131132
int i = 0;
132-
for (it = ring0.begin(); it != ring0.end(); ++it)
133+
for (it = ring.begin(); it != ring.end(); ++it)
133134
{
134135
seq->setAt(GEOS_GEOM::Coordinate(it->x(), it->y()), i++);
135136
}
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+
136142
// 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+
}
138147

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+
}
141164

142165
// new geometry takes ownership of outerRing and vector of holes
143166
GEOS_GEOM::Geometry* geom = geosGeometryFactory->createPolygon(outerRing, holes);
@@ -191,7 +214,7 @@ QgsGeometry & QgsGeometry::operator=( QgsGeometry const & rhs )
191214
{
192215
polygonVector.push_back((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN(i)));
193216
}
194-
mGeos = QgsGeometry::geosGeometryFactory->createMultiPolygon(polygonVector);
217+
mGeos = geosGeometryFactory->createMultiPolygon(polygonVector);
195218
}
196219
}
197220
else

src/core/qgsgeometry.h

-5
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,6 @@ not disjoint with existing polygons of the feature*/
291291

292292
private:
293293

294-
// Private static members
295-
296-
//! This is used to create new GEOS variables.
297-
static GEOS_GEOM::GeometryFactory* geosGeometryFactory;
298-
299294

300295
// Private variables
301296

0 commit comments

Comments
 (0)