49 , mPreparedGeom( nullptr )
68 , mPreparedGeom( nullptr )
91 , mPreparedGeom( nullptr )
114 , mPreparedGeom( nullptr )
121 memcpy(
x, ps.
x,
sizeof(
double )*
nbPoints );
122 memcpy(
y, ps.
y,
sizeof(
double )* nbPoints );
154 bool needClose =
false;
160 GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt,
nbPoints + ( needClose ? 1 : 0 ), 2 );
161 for (
int i = 0; i <
nbPoints; ++i )
163 GEOSCoordSeq_setX_r( geosctxt, coord, i,
x[i] );
164 GEOSCoordSeq_setY_r( geosctxt, coord, i,
y[i] );
170 GEOSCoordSeq_setX_r( geosctxt, coord, nbPoints,
x[0] );
171 GEOSCoordSeq_setY_r( geosctxt, coord, nbPoints,
y[0] );
177 mGeos = GEOSGeom_createPolygon_r( geosctxt, GEOSGeom_createLinearRing_r( geosctxt, coord ),
nullptr, 0 );
180 case GEOS_LINESTRING:
181 mGeos = GEOSGeom_createLineString_r( geosctxt, coord );
185 mGeos = GEOSGeom_createPoint_r( geosctxt, coord );
197 if ( !mPreparedGeom )
201 return mPreparedGeom;
208 GEOSGeom_destroy_r( geosctxt,
mGeos );
209 GEOSPreparedGeom_destroy_r( geosctxt, mPreparedGeom );
212 mPreparedGeom =
nullptr;
221 GEOSGeom_destroy_r( geosctxt,
mGeos );
224 GEOSPreparedGeom_destroy_r( geosctxt, mPreparedGeom );
246 newShape->
type = GEOS_POLYGON;
248 newShape->
x =
new double[newShape->
nbPoints];
249 newShape->
y =
new double[newShape->
nbPoints];
252 for ( j = 0, i = imin; i != ( imax + 1 ) %
nbPoints; i = ( i + 1 ) %
nbPoints, j++ )
254 newShape->
x[j] =
x[i];
255 newShape->
y[j] =
y[i];
261 newShape->
x[j] = fptx;
262 newShape->
y[j] = fpty;
273 GEOSCoordSequence* seq = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
274 GEOSCoordSeq_setX_r( geosctxt, seq, 0, x );
275 GEOSCoordSeq_setY_r( geosctxt, seq, 0, y );
276 GEOSGeometry* point = GEOSGeom_createPoint_r( geosctxt, seq );
277 bool result = ( GEOSPreparedContainsProperly_r( geosctxt,
preparedGeom(), point ) == 1 );
278 GEOSGeom_destroy_r( geosctxt, point );
282 catch ( GEOSException &e )
297 double xrm,
double yrm )
332 double labelArea = xrm * yrm;
336 while ( !shapes_toProcess.
isEmpty() )
345 for ( i = 0; i < nbp; i++ )
353 cHull = shape->
cHull;
363 ihn = ( ihs + 1 ) % cHullSize;
366 ipn = ( ips + 1 ) % nbp;
367 if ( ipn != cHull[ihn] )
372 for ( i = ips; i != cHull[ihn]; i = ( i + 1 ) % nbp )
375 x[cHull[ihn]], y[cHull[ihn]],
388 x[cHull[ihn]], y[cHull[ihn]] );
396 s = ( base + b + c ) / 2;
397 area = s * ( s - base ) * ( s - b ) * ( s - c );
402 if ( area - bestArea >
EPSILON )
419 bestArea = sqrt( bestArea );
420 double cx, cy, dx, dy, ex, ey, fx, fy, seg_length, ptx = 0, pty = 0, fptx = 0, fpty = 0;
421 int ps = -1, pe = -1, fps = -1, fpe = -1;
422 if ( retainedPt >= 0 && bestArea > labelArea )
429 for ( i = ( cHull[holeE] + 1 ) % nbp; i != ( cHull[holeS] - 1 + nbp ) % nbp; i = j )
437 cx = ( x[i] + x[j] ) / 2.0;
438 cy = ( y[i] + y[j] ) / 2.0;
476 double pointX, pointY;
488 for ( k = cHull[holeS]; k != cHull[holeE]; k = ( k + 1 ) % nbp )
499 if ( isValid && b < c )
510 int imin = retainedPt;
511 int imax = ((( fps < retainedPt && fpe < retainedPt ) || ( fps > retainedPt && fpe > retainedPt ) ) ? qMin( fps, fpe ) : qMax( fps, fpe ) );
513 int nbPtSh1, nbPtSh2;
515 nbPtSh1 = imax - imin + 1 + ( fpe != fps );
517 nbPtSh1 = imax + nbp - imin + 1 + ( fpe != fps );
519 if (( imax == fps ? fpe : fps ) < imin )
520 nbPtSh2 = imin - ( imax == fps ? fpe : fps ) + 1 + ( fpe != fps );
522 nbPtSh2 = imin + nbp - ( imax == fps ? fpe : fps ) + 1 + ( fpe != fps );
524 if ( retainedPt == -1 || fps == -1 || fpe == -1 )
530 else if ( imax == imin || nbPtSh1 <= 2 || nbPtSh2 <= 2 || nbPtSh1 == nbp || nbPtSh2 == nbp )
532 shapes_final.
append( shape );
544 shapes_toProcess.
append( newShape );
551 newShape = shape->
extractShape( nbPtSh2, imax, imin, fps, fpe, fptx, fpty );
558 shapes_toProcess.
append( newShape );
566 shapes_final.
append( shape );
591 double distNearestPoint;
597 double best_area = DBL_MAX;
598 double best_alpha = -1;
600 double best_length = 0;
601 double best_width = 0;
611 if (
x[
cHull[i]] < bbox[0] )
614 if (
x[cHull[i]] > bbox[2] )
615 bbox[2] =
x[cHull[i]];
617 if (
y[cHull[i]] < bbox[1] )
618 bbox[1] =
y[cHull[i]];
620 if (
y[cHull[i]] > bbox[3] )
621 bbox[3] =
y[cHull[i]];
625 dref = bbox[2] - bbox[0];
627 for ( alpha_d = 0; alpha_d < 90; alpha_d++ )
629 alpha = alpha_d *
M_PI / 180.0;
630 d1 = cos( alpha ) * dref;
631 d2 = sin( alpha ) * dref;
652 bb[14] = bb[12] + d2;
653 bb[15] = bb[13] - d1;
656 for ( i = 0; i < 16; i += 4 )
659 alpha_seg = (( i / 4 > 0 ? ( i / 4 ) - 1 : 3 ) ) *
M_PI / 2 + alpha;
671 distNearestPoint = best_cp / dref;
673 d1 = cos( alpha_seg ) * distNearestPoint;
674 d2 = sin( alpha_seg ) * distNearestPoint;
692 if ( best_area - area >
EPSILON )
698 memcpy( best_bb, bb,
sizeof(
double ) *16 );
706 for ( i = 0; i < 16; i = i + 4 )
709 best_bb[( i+4 ) %16], best_bb[( i+5 ) %16], best_bb[( i+6 ) %16], best_bb[( i+7 ) %16],
710 &finalBb->
x[int ( i/4 )], &finalBb->
y[int ( i/4 )] );
713 finalBb->
alpha = best_alpha;
714 finalBb->
width = best_width;
715 finalBb->
length = best_length;
731 GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
732 GEOSCoordSeq_setX_r( geosctxt, coord, 0, px );
733 GEOSCoordSeq_setY_r( geosctxt, coord, 0, py );
734 GEOSGeometry* geosPt = GEOSGeom_createPoint_r( geosctxt, coord );
736 int type = GEOSGeomTypeId_r( geosctxt,
mGeos );
737 const GEOSGeometry* extRing =
nullptr;
738 if ( type != GEOS_POLYGON )
745 extRing = GEOSGetExteriorRing_r( geosctxt,
mGeos );
747 GEOSCoordSequence *nearestCoord = GEOSNearestPoints_r( geosctxt, extRing, geosPt );
750 ( void )GEOSCoordSeq_getX_r( geosctxt, nearestCoord, 0, &nx );
751 ( void )GEOSCoordSeq_getY_r( geosctxt, nearestCoord, 0, &ny );
752 GEOSCoordSeq_destroy_r( geosctxt, nearestCoord );
753 GEOSGeom_destroy_r( geosctxt, geosPt );
762 catch ( GEOSException &e )
780 GEOSGeometry *centroidGeom = GEOSGetCentroid_r( geosctxt,
mGeos );
783 const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, centroidGeom );
784 GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
785 GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
791 GEOSGeometry *pointGeom = GEOSPointOnSurface_r( geosctxt,
mGeos );
795 const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom );
796 GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
797 GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
798 GEOSGeom_destroy_r( geosctxt, pointGeom );
802 GEOSGeom_destroy_r( geosctxt, centroidGeom );
804 catch ( GEOSException &e )
820 while ( i <
nbPoints && ad[i] <= dl ) i++;
830 di = sqrt( dx * dx + dy * dy );
840 *px =
x[i] + dx * distr / di;
841 *py =
y[i] + dy * distr / di;
871 ( void )GEOSLength_r( geosctxt,
mGeos, &len );
874 catch ( GEOSException &e )
bool containsPoint(double x, double y) const
Tests whether point set contains a specified point.
static bool computeLineIntersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *x, double *y)
Compute the point where two lines intersect.
PointSet * extractShape(int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty)
void createGeosGeom() const
static bool isSegIntersects(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
Returns true if the two segments intersect.
struct pal::_cHullBox CHullBox
QString tr(const char *sourceText, const char *disambiguation, int n)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
static double cross_product(double x1, double y1, double x2, double y2, double x3, double y3)
static bool containsCandidate(const GEOSPreparedGeometry *geom, double x, double y, double width, double height, double alpha)
Returns true if a GEOS prepared geometry totally contains a label candidate.
void getPointByDistance(double *d, double *ad, double dl, double *px, double *py)
Get a point a set distance along a line geometry.
static int convexHullId(int *id, const double *const x, const double *const y, int n, int *&cHull)
Compute the convex hull in O(n·log(n))
static void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
static double dist_euc2d(double x1, double y1, double x2, double y2)
GEOSContextHandle_t geosContext()
Get GEOS context handle to be used in all GEOS library calls with reentrant API.
CHullBox * compute_chull_bbox()
double length() const
Returns length of line geometry.
const GEOSPreparedGeometry * preparedGeom() const
static double dist_euc2d_sq(double x1, double y1, double x2, double y2)
void getCentroid(double &px, double &py, bool forceInside=false) const
static void splitPolygons(QLinkedList< PointSet *> &shapes_toProcess, QLinkedList< PointSet *> &shapes_final, double xrm, double yrm)
Split a concave shape into several convex shapes.
const GEOSGeometry * geos() const
Returns the point set's GEOS geometry.
double minDistanceToPoint(double px, double py, double *rx=nullptr, double *ry=nullptr) const
Returns the squared minimum distance between the point set geometry and the point (px...
void append(const T &value)
bool containsLabelCandidate(double x, double y, double width, double height, double alpha=0) const
Tests whether a possible label candidate will fit completely within the shape.