Skip to content

Commit cb249c3

Browse files
committed
[pal] Move storage of GEOS geometry from Feature up to PointSet. Use
GEOS to calculate feature centroids rather than custom code.
1 parent 9a23cec commit cb249c3

File tree

4 files changed

+79
-80
lines changed

4 files changed

+79
-80
lines changed

src/core/pal/feature.cpp

+14-5
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,6 @@ namespace pal
116116
qDeleteAll( mHoles );
117117
mHoles.clear();
118118

119-
if ( mOwnsGeom )
120-
{
121-
GEOSGeom_destroy_r( geosContext(), mGeos );
122-
mGeos = NULL;
123-
}
124119
}
125120

126121
void FeaturePart::extractCoords( const GEOSGeometry* geom )
@@ -1298,6 +1293,9 @@ namespace pal
12981293

12991294
void FeaturePart::addSizePenalty( int nbp, LabelPosition** lPos, double bbx[4], double bby[4] )
13001295
{
1296+
if ( !mGeos )
1297+
createGeosGeom();
1298+
13011299
GEOSContextHandle_t ctxt = geosContext();
13021300
int geomType = GEOSGeomTypeId_r( ctxt, mGeos );
13031301

@@ -1338,11 +1336,22 @@ namespace pal
13381336

13391337
bool FeaturePart::isConnected( FeaturePart* p2 )
13401338
{
1339+
if ( !mGeos )
1340+
createGeosGeom();
1341+
1342+
if ( !p2->mGeos )
1343+
p2->createGeosGeom();
1344+
13411345
return ( GEOSTouches_r( geosContext(), mGeos, p2->mGeos ) == 1 );
13421346
}
13431347

13441348
bool FeaturePart::mergeWithFeaturePart( FeaturePart* other )
13451349
{
1350+
if ( !mGeos )
1351+
createGeosGeom();
1352+
if ( !other->mGeos )
1353+
other->createGeosGeom();
1354+
13461355
GEOSContextHandle_t ctxt = geosContext();
13471356
GEOSGeometry* g1 = GEOSGeom_clone_r( ctxt, mGeos );
13481357
GEOSGeometry* g2 = GEOSGeom_clone_r( ctxt, other->mGeos );

src/core/pal/feature.h

-6
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,6 @@ namespace pal
230230
*/
231231
Feature* getFeature() { return mFeature; }
232232

233-
/** Returns the part's GEOS geometry.
234-
*/
235-
const GEOSGeometry* getGeometry() const { return mGeos; }
236-
237233
/** Returns the layer that feature belongs to.
238234
*/
239235
Layer* layer();
@@ -292,8 +288,6 @@ namespace pal
292288

293289
Feature* mFeature;
294290
QList<FeaturePart*> mHoles;
295-
GEOSGeometry *mGeos;
296-
bool mOwnsGeom;
297291

298292
/** \brief read coordinates from a GEOS geom */
299293
void extractCoords( const GEOSGeometry* geom );

src/core/pal/pointset.cpp

+52-53
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ namespace pal
4545

4646

4747
PointSet::PointSet()
48-
: holeOf( NULL )
48+
: mGeos( 0 )
49+
, mOwnsGeom( false )
50+
, holeOf( NULL )
4951
, parent( NULL )
5052
, xmin( DBL_MAX )
5153
, xmax( -DBL_MAX )
@@ -60,7 +62,9 @@ namespace pal
6062
}
6163

6264
PointSet::PointSet( int nbPoints, double *x, double *y )
63-
: cHullSize( 0 )
65+
: mGeos( 0 )
66+
, mOwnsGeom( false )
67+
, cHullSize( 0 )
6468
, holeOf( NULL )
6569
, parent( NULL )
6670
, xmin( DBL_MAX )
@@ -83,8 +87,12 @@ namespace pal
8387
}
8488

8589
PointSet::PointSet( double aX, double aY )
86-
: xmin( aX ), xmax( aY )
87-
, ymin( aX ), ymax( aY )
90+
: mGeos( 0 )
91+
, mOwnsGeom( false )
92+
, xmin( aX )
93+
, xmax( aY )
94+
, ymin( aX )
95+
, ymax( aY )
8896
{
8997
nbPoints = cHullSize = 1;
9098
x = new double[1];
@@ -100,7 +108,9 @@ namespace pal
100108
}
101109

102110
PointSet::PointSet( PointSet &ps )
103-
: parent( 0 )
111+
: mGeos( 0 )
112+
, mOwnsGeom( false )
113+
, parent( 0 )
104114
, xmin( DBL_MAX )
105115
, xmax( -DBL_MAX )
106116
, ymin( DBL_MAX )
@@ -138,8 +148,27 @@ namespace pal
138148
holeOf = ps.holeOf;
139149
}
140150

151+
void PointSet::createGeosGeom()
152+
{
153+
GEOSContextHandle_t geosctxt = geosContext();
154+
GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, nbPoints, 2 );
155+
for ( int i = 0; i < nbPoints; ++i )
156+
{
157+
GEOSCoordSeq_setX_r( geosctxt, coord, i, x[i] );
158+
GEOSCoordSeq_setY_r( geosctxt, coord, i, y[i] );
159+
}
160+
mGeos = GEOSGeom_createPolygon_r( geosctxt, GEOSGeom_createLinearRing_r( geosctxt, coord ), 0, 0 );
161+
mOwnsGeom = true;
162+
}
163+
141164
PointSet::~PointSet()
142165
{
166+
if ( mOwnsGeom )
167+
{
168+
GEOSGeom_destroy_r( geosContext(), mGeos );
169+
mGeos = NULL;
170+
}
171+
143172
deleteCoords();
144173

145174
if ( cHull )
@@ -156,9 +185,6 @@ namespace pal
156185
y = NULL;
157186
}
158187

159-
160-
161-
162188
PointSet* PointSet::extractShape( int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty )
163189
{
164190

@@ -842,65 +868,38 @@ namespace pal
842868
}
843869

844870

845-
846871
void PointSet::getCentroid( double &px, double &py, bool forceInside )
847872
{
848-
// for explanation see this page:
849-
// http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
873+
if ( !mGeos )
874+
createGeosGeom();
850875

851-
int i, j;
852-
double cx = 0, cy = 0, A = 0, tmp, sumx = 0, sumy = 0;
853-
for ( i = 0; i < nbPoints; i++ )
854-
{
855-
j = i + 1; if ( j == nbPoints ) j = 0;
856-
tmp = (( x[i] - x[0] ) * ( y[j] - y[0] ) - ( x[j] - x[0] ) * ( y[i] - y[0] ) );
857-
cx += ( x[i] + x[j] - 2 * x[0] ) * tmp;
858-
cy += ( y[i] + y[j] - 2 * y[0] ) * tmp;
859-
A += tmp;
860-
sumx += x[i];
861-
sumy += y[i];
862-
}
876+
if ( !mGeos )
877+
return;
863878

864-
if ( A == 0 )
879+
GEOSContextHandle_t geosctxt = geosContext();
880+
GEOSGeometry *centroidGeom = GEOSGetCentroid_r( geosctxt, mGeos );
881+
if ( centroidGeom )
865882
{
866-
px = sumx / nbPoints;
867-
py = sumy / nbPoints;
868-
}
869-
else
870-
{
871-
px = cx / ( 3 * A ) + x[0];
872-
py = cy / ( 3 * A ) + y[0];
883+
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, centroidGeom );
884+
GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
885+
GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
873886
}
874887

875888
// check if centroid inside in polygon
876889
if ( forceInside && !isPointInPolygon( nbPoints, x, y, px, py ) )
877890
{
878-
GEOSContextHandle_t geosctxt = geosContext();
879-
GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, nbPoints, 2 );
880-
881-
for ( int i = 0; i < nbPoints; ++i )
882-
{
883-
GEOSCoordSeq_setX_r( geosctxt, coord, i, x[i] );
884-
GEOSCoordSeq_setY_r( geosctxt, coord, i, y[i] );
885-
}
886-
887-
GEOSGeometry *geom = GEOSGeom_createPolygon_r( geosctxt, GEOSGeom_createLinearRing_r( geosctxt, coord ), 0, 0 );
891+
GEOSGeometry *pointGeom = GEOSPointOnSurface_r( geosctxt, mGeos );
888892

889-
if ( geom )
893+
if ( pointGeom )
890894
{
891-
GEOSGeometry *pointGeom = GEOSPointOnSurface_r( geosctxt, geom );
892-
893-
if ( pointGeom )
894-
{
895-
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom );
896-
GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
897-
GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
898-
899-
GEOSGeom_destroy_r( geosctxt, pointGeom );
900-
}
901-
GEOSGeom_destroy_r( geosctxt, geom );
895+
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom );
896+
GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
897+
GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
898+
GEOSGeom_destroy_r( geosctxt, pointGeom );
902899
}
903900
}
901+
902+
GEOSGeom_destroy_r( geosctxt, centroidGeom );
904903
}
905904

906905
} // end namespace

src/core/pal/pointset.h

+13-16
Original file line numberDiff line numberDiff line change
@@ -95,43 +95,36 @@ namespace pal
9595
PointSet( int nbPoints, double *x, double *y );
9696
virtual ~PointSet();
9797

98+
/** Returns the point set's GEOS geometry.
99+
*/
100+
const GEOSGeometry* getGeometry() const { return mGeos; }
101+
98102
PointSet* extractShape( int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty );
99103

100104
PointSet* createProblemSpecificPointSet( double bbmin[2], double bbmax[2], bool *inside );
101105

102106
CHullBox * compute_chull_bbox();
103107

104108

105-
/*
106-
* split a concave shape into several convex shapes
107-
*
109+
/** Split a concave shape into several convex shapes.
108110
*/
109111
static void splitPolygons( QLinkedList<PointSet *> &shapes_toProcess,
110112
QLinkedList<PointSet *> &shapes_final,
111113
double xrm, double yrm, const QString &uid );
112114

113115

114116

115-
/**
116-
* \brief return the minimum distance bw this and the point (px,py)
117-
*
118-
* compute the minimum distance bw the point (px,py) and this.
119-
* Optionnaly, store the nearest point in (rx,ry)
120-
*
117+
/** Return the minimum distance bw this and the point (px,py). Optionally, store the nearest point in (rx,ry).
121118
* @param px x coordinate of the point
122119
* @param py y coordinate of the points
123120
* @param rx pointer to x coorinates of the nearest point (can be NULL)
124121
* @param ry pointer to y coorinates of the nearest point (can be NULL)
122+
* @returns minimum distance
125123
*/
126124
double getDist( double px, double py, double *rx, double *ry );
127125

128-
129-
130-
//double getDistInside(double px, double py);
131-
132126
void getCentroid( double &px, double &py, bool forceInside = false );
133127

134-
135128
int getGeosType() const { return type; }
136129

137130
void getBoundingBox( double min[2], double max[2] ) const
@@ -145,8 +138,7 @@ namespace pal
145138

146139
int getNumPoints() const { return nbPoints; }
147140

148-
/*
149-
* Iterate on line by real step of dl on x,y points
141+
/** Iterate on line by real step of dl on x,y points.
150142
* @param nbPoint # point in line
151143
* @param x x coord
152144
* @param y y coord
@@ -197,6 +189,9 @@ namespace pal
197189
}
198190

199191
protected:
192+
GEOSGeometry *mGeos;
193+
bool mOwnsGeom;
194+
200195
int nbPoints;
201196
double *x;
202197
double *y; // points order is counterclockwise
@@ -214,11 +209,13 @@ namespace pal
214209
PointSet( PointSet &ps );
215210

216211
void deleteCoords();
212+
void createGeosGeom();
217213

218214
double xmin;
219215
double xmax;
220216
double ymin;
221217
double ymax;
218+
222219
};
223220

224221
} // namespace pal

0 commit comments

Comments
 (0)