Skip to content

Commit

Permalink
Fixed QgsGeometry::fromPolygon:
Browse files Browse the repository at this point in the history
- fixed creation of outer ring, added creation of holes
- fixed Python binding for QgsPolygon type


git-svn-id: http://svn.osgeo.org/qgis/trunk@6974 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Jun 2, 2007
1 parent d894411 commit 05131b1
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 22 deletions.
12 changes: 7 additions & 5 deletions python/core/qgsgeometry.sip
Expand Up @@ -50,20 +50,21 @@ template <TYPE>
%End

%ConvertToTypeCode
const sipMappedType* qvector_qgspoint = sipFindMappedType("QVector<QgsPoint>");

// Check the type if that is all that is required.
if (sipIsErr == NULL)
{
if (!PyList_Check(sipPy))
return 0;

for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
if (!sipCanConvertToInstance(PyList_GET_ITEM(sipPy, i), sipClass_TYPE, SIP_NOT_NONE))
if (!sipCanConvertToMappedType(PyList_GET_ITEM(sipPy, i), qvector_qgspoint, SIP_NOT_NONE))
return 0;

return 1;
}

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

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

Expand Down Expand Up @@ -124,21 +125,22 @@ template <TYPE>
%End

%ConvertToTypeCode

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

// Check the type if that is all that is required.
if (sipIsErr == NULL)
{
if (!PyList_Check(sipPy))
return 0;

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

return 1;
}

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

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

Expand Down
47 changes: 35 additions & 12 deletions src/core/qgsgeometry.cpp
Expand Up @@ -26,7 +26,7 @@ email : morb at ozemail dot com dot au
#include "qgsrect.h"

// Set up static GEOS geometry factory
GEOS_GEOM::GeometryFactory* QgsGeometry::geosGeometryFactory = new GEOS_GEOM::GeometryFactory();
static GEOS_GEOM::GeometryFactory* geosGeometryFactory = new GEOS_GEOM::GeometryFactory();


QgsGeometry::QgsGeometry()
Expand Down Expand Up @@ -69,7 +69,7 @@ mDirtyGeos( rhs.mDirtyGeos )
{
polygonVector.push_back((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN(i)));
}
mGeos = QgsGeometry::geosGeometryFactory->createMultiPolygon(polygonVector);
mGeos = geosGeometryFactory->createMultiPolygon(polygonVector);
}
}
else
Expand Down Expand Up @@ -120,24 +120,47 @@ QgsGeometry* QgsGeometry::fromPolyline(const QgsPolyline& polyline)
return g;
}

QgsGeometry* QgsGeometry::fromPolygon(const QgsPolygon& polygon)
static GEOS_GEOM::LinearRing* _createGeosLinearRing(const QgsPolyline& ring)
{
const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance();
const QgsPolyline& ring0 = polygon[0];
// LinearRing in GEOS must have the first point the same as the last one
bool needRepeatLastPnt = (ring[0] != ring[ring.count()-1]);

// outer ring
GEOS_GEOM::CoordinateSequence* seq = seqFactory->create(ring0.count(), 2);
const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance();

GEOS_GEOM::CoordinateSequence* seq = seqFactory->create(ring.count() + (needRepeatLastPnt ? 1 : 0), 2);
QgsPolyline::const_iterator it;
int i = 0;
for (it = ring0.begin(); it != ring0.end(); ++it)
for (it = ring.begin(); it != ring.end(); ++it)
{
seq->setAt(GEOS_GEOM::Coordinate(it->x(), it->y()), i++);
}

// add the first point to close the ring if needed
if (needRepeatLastPnt)
seq->setAt(GEOS_GEOM::Coordinate(ring[0].x(), ring[0].y()), ring.count());

// ring takes ownership of the sequence
GEOS_GEOM::LinearRing* outerRing = geosGeometryFactory->createLinearRing(seq);
GEOS_GEOM::LinearRing* linRing = geosGeometryFactory->createLinearRing(seq);

return linRing;
}

std::vector<GEOS_GEOM::Geometry*>* holes = new std::vector<GEOS_GEOM::Geometry*>;
// TODO: holes
QgsGeometry* QgsGeometry::fromPolygon(const QgsPolygon& polygon)
{
if (polygon.count() == 0)
return NULL;

const QgsPolyline& ring0 = polygon[0];

// outer ring
GEOS_GEOM::LinearRing* outerRing = _createGeosLinearRing(ring0);

// holes
std::vector<GEOS_GEOM::Geometry*>* holes = new std::vector<GEOS_GEOM::Geometry*> (polygon.count()-1);
for (int i = 1; i < polygon.count(); i++)
{
(*holes)[i-1] = _createGeosLinearRing(polygon[i]);
}

// new geometry takes ownership of outerRing and vector of holes
GEOS_GEOM::Geometry* geom = geosGeometryFactory->createPolygon(outerRing, holes);
Expand Down Expand Up @@ -191,7 +214,7 @@ QgsGeometry & QgsGeometry::operator=( QgsGeometry const & rhs )
{
polygonVector.push_back((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN(i)));
}
mGeos = QgsGeometry::geosGeometryFactory->createMultiPolygon(polygonVector);
mGeos = geosGeometryFactory->createMultiPolygon(polygonVector);
}
}
else
Expand Down
5 changes: 0 additions & 5 deletions src/core/qgsgeometry.h
Expand Up @@ -291,11 +291,6 @@ not disjoint with existing polygons of the feature*/

private:

// Private static members

//! This is used to create new GEOS variables.
static GEOS_GEOM::GeometryFactory* geosGeometryFactory;


// Private variables

Expand Down

0 comments on commit 05131b1

Please sign in to comment.