47  : nbPoints( nbPoints )
 
   48  , type( GEOS_POLYGON )
 
 
  103  bool needClose = 
false;
 
  109  GEOSCoordSequence *coord = 
nullptr;
 
  110#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=10 ) 
  114    coord = GEOSCoordSeq_copyFromArrays_r( geosctxt, 
x.data(), 
y.data(), 
nullptr, 
nullptr, 
nbPoints );
 
  123    coord = GEOSCoordSeq_create_r( geosctxt, 
nbPoints + ( needClose ? 1 : 0 ), 2 );
 
  124    for ( 
int i = 0; i < 
nbPoints; ++i )
 
  126      GEOSCoordSeq_setXY_r( geosctxt, coord, i, 
x[i], 
y[i] );
 
  132      GEOSCoordSeq_setXY_r( geosctxt, coord, 
nbPoints, 
x[0], 
y[0] );
 
  139      mGeos = GEOSGeom_createPolygon_r( geosctxt, GEOSGeom_createLinearRing_r( geosctxt, coord ), 
nullptr, 0 );
 
  142    case GEOS_LINESTRING:
 
  143      mGeos = GEOSGeom_createLineString_r( geosctxt, coord );
 
  147      mGeos = GEOSGeom_createPoint_r( geosctxt, coord );
 
 
  159  if ( !mPreparedGeom )
 
  163  return mPreparedGeom;
 
 
  170    GEOSGeom_destroy_r( geosctxt, 
mGeos );
 
  176    GEOSPreparedGeom_destroy_r( geosctxt, mPreparedGeom );
 
  177    mPreparedGeom = 
nullptr;
 
  180  if ( mGeosPreparedBoundary )
 
  182    GEOSPreparedGeom_destroy_r( geosctxt, mGeosPreparedBoundary );
 
  183    mGeosPreparedBoundary = 
nullptr;
 
  186  if ( mMultipartPreparedGeos )
 
  188    GEOSPreparedGeom_destroy_r( geosctxt, mMultipartPreparedGeos );
 
  189    mMultipartPreparedGeos = 
nullptr;
 
  191  if ( mMultipartGeos )
 
  193    GEOSGeom_destroy_r( geosctxt, mMultipartGeos );
 
  194    mMultipartGeos = 
nullptr;
 
 
  207    GEOSGeom_destroy_r( geosctxt, 
mGeos );
 
  210  GEOSPreparedGeom_destroy_r( geosctxt, mPreparedGeom );
 
  212  if ( mGeosPreparedBoundary )
 
  214    GEOSPreparedGeom_destroy_r( geosctxt, mGeosPreparedBoundary );
 
  215    mGeosPreparedBoundary = 
nullptr;
 
  218  if ( mMultipartPreparedGeos )
 
  220    GEOSPreparedGeom_destroy_r( geosctxt, mMultipartPreparedGeos );
 
  221    mMultipartPreparedGeos = 
nullptr;
 
  223  if ( mMultipartGeos )
 
  225    GEOSGeom_destroy_r( geosctxt, mMultipartGeos );
 
  226    mMultipartGeos = 
nullptr;
 
 
  238std::unique_ptr<PointSet> 
PointSet::extractShape( 
int nbPtSh, 
int imin, 
int imax, 
int fps, 
int fpe, 
double fptx, 
double fpty )
 
  242  std::unique_ptr<PointSet> newShape = std::make_unique< PointSet >();
 
  243  newShape->type = GEOS_POLYGON;
 
  244  newShape->nbPoints = nbPtSh;
 
  245  newShape->x.resize( newShape->nbPoints );
 
  246  newShape->y.resize( newShape->nbPoints );
 
  249  for ( j = 0, i = imin; i != ( imax + 1 ) % 
nbPoints; i = ( i + 1 ) % 
nbPoints, j++ )
 
  251    newShape->x[j] = 
x[i];
 
  252    newShape->y[j] = 
y[i];
 
  258    newShape->x[j] = fptx;
 
  259    newShape->y[j] = fpty;
 
 
  267  return std::unique_ptr< PointSet>( 
new PointSet( *
this ) );
 
 
  276    const bool result = ( GEOSPreparedContainsProperly_r( geosctxt, 
preparedGeom(), point.get() ) == 1 );
 
  280  catch ( GEOSException &e )
 
  282    qWarning( 
"GEOS exception: %s", e.what() );
 
 
  307  const double labelArea = labelWidth * labelHeight;
 
  309  QLinkedList<PointSet *> inputShapes;
 
  310  inputShapes.push_back( inputShape );
 
  311  QLinkedList<PointSet *> outputShapes;
 
  313  while ( !inputShapes.isEmpty() )
 
  315    PointSet *shape = inputShapes.takeFirst();
 
  317    const std::vector< double > &
x = shape->
x;
 
  318    const std::vector< double > &
y = shape->
y;
 
  320    std::vector< int > pts( nbp );
 
  321    for ( 
int i = 0; i < nbp; i++ )
 
  333    for ( std::size_t ihs = 0; ihs < shape->
convexHull.size(); ihs++ )
 
  336      const std::size_t ihn = ( ihs + 1 ) % shape->
convexHull.size();
 
  339      const int ipn = ( ips + 1 ) % nbp;
 
  345        for ( 
int i = ips; i != shape->
convexHull[ihn]; i = ( i + 1 ) % nbp )
 
  369          const double s = ( base + b + 
c ) / 2; 
 
  370          double area = s * ( s - base ) * ( s - b ) * ( s - 
c );
 
  392    bestArea = std::sqrt( bestArea );
 
  393    double cx, cy, dx, dy, ex, ey, fx, fy, seg_length, ptx = 0, pty = 0, fptx = 0, fpty = 0;
 
  394    int ps = -1, pe = -1, fps = -1, fpe = -1;
 
  395    if ( retainedPt >= 0 && bestArea > labelArea ) 
 
  397      double c = std::numeric_limits<double>::max();
 
  402      for ( 
int i = ( shape->
convexHull[holeE] + 1 ) % nbp; i != ( shape->
convexHull[holeS] - 1 + nbp ) % nbp; i = j )
 
  410        cx = ( 
x[i] + 
x[j] ) / 2.0;
 
  411        cy = ( 
y[i] + 
y[j] ) / 2.0;
 
  449        double pointX, pointY;
 
  472        if ( isValid && b < 
c )
 
  483      const int imin = retainedPt;
 
  484      int imax = ( ( ( fps < retainedPt && fpe < retainedPt ) || ( fps > retainedPt && fpe > retainedPt ) ) ? std::min( fps, fpe ) : std::max( fps, fpe ) );
 
  486      int nbPtSh1, nbPtSh2; 
 
  488        nbPtSh1 = imax - imin + 1 + ( fpe != fps );
 
  490        nbPtSh1 = imax + nbp - imin + 1 + ( fpe != fps );
 
  492      if ( ( imax == fps ? fpe : fps ) < imin )
 
  493        nbPtSh2 = imin - ( imax == fps ? fpe : fps ) + 1 + ( fpe != fps );
 
  495        nbPtSh2 = imin + nbp - ( imax == fps ? fpe : fps ) + 1 + ( fpe != fps );
 
  497      if ( retainedPt == -1 || fps == -1 || fpe == -1 )
 
  503      else if ( imax == imin || nbPtSh1 <= 2 || nbPtSh2 <= 2 || nbPtSh1 == nbp  || nbPtSh2 == nbp )
 
  505        outputShapes.append( shape );
 
  510        PointSet *newShape = shape->
extractShape( nbPtSh1, imin, imax, fps, fpe, fptx, fpty ).release();
 
  517        inputShapes.append( newShape );
 
  524        newShape = shape->
extractShape( nbPtSh2, imax, imin, fps, fpe, fptx, fpty ).release();
 
  531        inputShapes.append( newShape );
 
  539      outputShapes.append( shape );
 
 
  557    newGeos.reset( GEOSOffsetCurve_r( geosctxt, 
mGeos, distance, 0, GEOSBUF_JOIN_MITRE, 2 ) );
 
  562    if ( GEOSGeomTypeId_r( geosctxt, newGeos.get() ) == GEOS_MULTILINESTRING )
 
  565      const int nParts = GEOSGetNumGeometries_r( geosctxt, newGeos.get() );
 
  566      double maximumLength = -1;
 
  568      for ( 
int i = 0; i < nParts; ++i )
 
  570        const GEOSGeometry *part = GEOSGetGeometryN_r( geosctxt, newGeos.get(), i );
 
  571        double partLength = -1;
 
  572        if ( GEOSLength_r( geosctxt, part, &partLength ) == 1 )
 
  574          if ( partLength > maximumLength )
 
  576            maximumLength = partLength;
 
  588      geos::unique_ptr longestPartClone( GEOSGeom_clone_r( geosctxt, longestPart ) );
 
  589      newGeos = std::move( longestPartClone );
 
  592#if GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR<11 
  600      newGeos = std::move( reversed );
 
  604    const int newNbPoints = GEOSGeomGetNumPoints_r( geosctxt, newGeos.get() );
 
  605    const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, newGeos.get() );
 
  606    std::vector< double > newX;
 
  607    std::vector< double > newY;
 
  608    newX.resize( newNbPoints );
 
  609    newY.resize( newNbPoints );
 
  610    for ( 
int i = 0; i < newNbPoints; i++ )
 
  612      GEOSCoordSeq_getX_r( geosctxt, coordSeq, i, &newX[i] );
 
  613      GEOSCoordSeq_getY_r( geosctxt, coordSeq, i, &newY[i] );
 
  619  catch ( GEOSException &e )
 
  621    qWarning( 
"GEOS exception: %s", e.what() );
 
  627  mGeos = newGeos.release();
 
 
  638  if ( startDistance > 0 )
 
  644    double distanceConsumed = 0;
 
  647    for ( 
int i = 1; i < 
nbPoints; ++i )
 
  649      const double thisX = 
x[i];
 
  650      const double thisY = 
y[i];
 
  651      const double thisSegmentLength = std::sqrt( ( thisX - lastX ) * ( thisX - lastX ) + ( thisY - lastY ) * ( thisY - lastY ) );
 
  652      distanceConsumed += thisSegmentLength;
 
  653      if ( distanceConsumed >= smoothDistance )
 
  655        const double c = ( distanceConsumed - smoothDistance ) / thisSegmentLength;
 
  656        x1 = lastX + 
c * ( thisX - lastX );
 
  657        y1 = lastY + 
c * ( thisY - lastY );
 
  664    const double distance = std::sqrt( ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ) );
 
  665    const double extensionFactor = ( startDistance + distance ) / distance;
 
  672  if ( endDistance > 0 )
 
  680    double distanceConsumed = 0;
 
  683    for ( 
int i = 
nbPoints - 2; i >= 0; --i )
 
  685      const double thisX = 
x[i];
 
  686      const double thisY = 
y[i];
 
  687      const double thisSegmentLength = std::sqrt( ( thisX - lastX ) * ( thisX - lastX ) + ( thisY - lastY ) * ( thisY - lastY ) );
 
  688      distanceConsumed += thisSegmentLength;
 
  689      if ( distanceConsumed >= smoothDistance )
 
  691        const double c = ( distanceConsumed - smoothDistance ) / thisSegmentLength;
 
  692        xend1 = lastX + 
c * ( thisX - lastX );
 
  693        yend1 = lastY + 
c * ( thisY - lastY );
 
  700    const double distance = std::sqrt( ( xend1 - xend0 ) * ( xend1 - xend0 ) + ( yend1 - yend0 ) * ( yend1 - yend0 ) );
 
  701    const double extensionFactor = ( endDistance + distance ) / distance;
 
  703    x.emplace_back( newEnd.
x() );
 
  704    y.emplace_back( newEnd.
y() );
 
  708  if ( startDistance > 0 )
 
  710    x.insert( 
x.begin(), x0 );
 
  711    y.insert( 
y.begin(), y0 );
 
 
  732  double best_area = std::numeric_limits<double>::max();
 
  733  double best_alpha = -1;
 
  735  double best_length = 0;
 
  736  double best_width = 0;
 
  739  bbox[0] = std::numeric_limits<double>::max();
 
  740  bbox[1] = std::numeric_limits<double>::max();
 
  741  bbox[2] = std::numeric_limits<double>::lowest();
 
  742  bbox[3] = std::numeric_limits<double>::lowest();
 
  744  for ( std::size_t i = 0; i < 
convexHull.size(); i++ )
 
  761  const double dref = bbox[2] - bbox[0];
 
  768  for ( alpha_d = 0; alpha_d < 90; alpha_d++ )
 
  770    alpha = alpha_d *  M_PI / 180.0;
 
  771    d1 = std::cos( alpha ) * dref;
 
  772    d2 = std::sin( alpha ) * dref;
 
  793    bb[14] = bb[12] + d2;
 
  794    bb[15] = bb[13] - d1; 
 
  797    for ( 
int  i = 0; i < 16; i += 4 )
 
  800      alpha_seg = ( ( i / 4 > 0 ? ( i / 4 ) - 1 : 3 ) ) * M_PI_2 + alpha;
 
  802      double best_cp = std::numeric_limits<double>::max();
 
  804      for ( std::size_t j = 0; j < 
convexHull.size(); j++ )
 
  813      const double distNearestPoint = best_cp / dref;
 
  815      d1 = std::cos( alpha_seg ) * distNearestPoint;
 
  816      d2 = std::sin( alpha_seg ) * distNearestPoint;
 
  840      memcpy( best_bb, bb, 
sizeof( 
double ) * 16 );
 
  845  for ( 
int i = 0; i < 16; i = i + 4 )
 
  848                                           best_bb[( i + 4 ) % 16], best_bb[( i + 5 ) % 16], best_bb[( i + 6 ) % 16], best_bb[( i + 7 ) % 16],
 
  849                                           &finalBb.
x[int ( i / 4 )], &finalBb.
y[int ( i / 4 )] );
 
  852  finalBb.
alpha = best_alpha;
 
  853  finalBb.
width = best_width;
 
  854  finalBb.
length = best_length;
 
 
  871    geos::unique_ptr geosPt( GEOSGeom_createPointFromXY_r( geosctxt, px, py ) );
 
  872    const int type = GEOSGeomTypeId_r( geosctxt, 
mGeos );
 
  874    const GEOSPreparedGeometry *preparedExtRing = 
nullptr;
 
  876    if ( 
type != GEOS_POLYGON )
 
  884      extRing = GEOSGetExteriorRing_r( geosctxt, 
mGeos );
 
  885      if ( ! mGeosPreparedBoundary )
 
  887        mGeosPreparedBoundary = GEOSPrepare_r( geosctxt, extRing );
 
  889      preparedExtRing = mGeosPreparedBoundary;
 
  895    unsigned int nPoints = 0;
 
  896    GEOSCoordSeq_getSize_r( geosctxt, nearestCoord.get(), &nPoints );
 
  900    ( void )GEOSCoordSeq_getXY_r( geosctxt, nearestCoord.get(), 0, &nx, &ny );
 
  909  catch ( GEOSException &e )
 
  911    qWarning( 
"GEOS exception: %s", e.what() );
 
 
  931      const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, centroidGeom.get() );
 
  932      unsigned int nPoints = 0;
 
  933      GEOSCoordSeq_getSize_r( geosctxt, coordSeq, &nPoints );
 
  936      GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
 
  946        const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom.get() );
 
  947        unsigned int nPoints = 0;
 
  948        GEOSCoordSeq_getSize_r( geosctxt, coordSeq, &nPoints );
 
  952        GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
 
  956  catch ( GEOSException &e )
 
  958    qWarning( 
"GEOS exception: %s", e.what() );
 
 
  984    while ( i < 
nbPoints && ad[i] <= dl ) i++;
 
  994      di = std::sqrt( dx * dx + dy * dy );
 
  998      dx = 
x[i + 1] - 
x[i];
 
  999      dy = 
y[i + 1] - 
y[i];
 
 1004    *px = 
x[i] + dx * distr / di;
 
 1005    *py = 
y[i] + dy * distr / di;
 
 
 1025  catch ( GEOSException &e )
 
 1027    qWarning( 
"GEOS exception: %s", e.what() );
 
 
 1038  double distance = -1;
 
 1043  catch ( GEOSException &e )
 
 1045    qWarning( 
"GEOS exception: %s", e.what() );
 
 
 1078  catch ( GEOSException &e )
 
 1080    qWarning( 
"GEOS exception: %s", e.what() );
 
 
 1101    ( void )GEOSArea_r( geosctxt, 
mGeos, &
mArea );
 
 1105  catch ( GEOSException &e )
 
 1107    qWarning( 
"GEOS exception: %s", e.what() );
 
 
 1127    GEOSWKTWriter *writer = GEOSWKTWriter_create_r( geosctxt );
 
 1129    char *wkt = GEOSWKTWriter_write_r( geosctxt, writer, 
mGeos );
 
 1130    const QString res( wkt );
 
 1132    GEOSFree_r( geosctxt, wkt );
 
 1134    GEOSWKTWriter_destroy_r( geosctxt, writer );
 
 1139  catch ( GEOSException &e )
 
 1141    qWarning( 
"GEOS exception: %s", e.what() );
 
 
 1149  std::vector< double > distances( 
nbPoints );
 
 1150  double totalDistance = 0;
 
 1151  double oldX = -1.0, oldY = -1.0;
 
 1152  for ( 
int i = 0; i < 
nbPoints; i++ )
 
 1157      distances[i] = std::sqrt( std::pow( oldX - 
x[i], 2 ) + std::pow( oldY - 
y[i], 2 ) );
 
 1161    totalDistance += distances[i];
 
 1163  return std::make_tuple( std::move( distances ), totalDistance );
 
 
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction)
Interpolates the position of a point a fraction of the way along the line from (x1,...
 
static GEOSContextHandle_t getGEOSHandler()
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
 
A class to represent a 2D point.
 
static double dist_euc2d(double x1, double y1, double x2, double y2)
 
static std::vector< int > convexHullId(std::vector< int > &id, const std::vector< double > &x, const std::vector< double > &y)
Compute the convex hull in O(n·log(n))
 
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.
 
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.
 
static double cross_product(double x1, double y1, double x2, double y2, double x3, double y3)
 
static double dist_euc2d_sq(double x1, double y1, double x2, double y2)
 
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.
 
The underlying raw pal geometry class.
 
geos::unique_ptr interpolatePoint(double distance) const
Returns a GEOS geometry representing the point interpolated on the shape by distance.
 
std::unique_ptr< PointSet > clone() const
Returns a copy of the point set.
 
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.
 
double lineLocatePoint(const GEOSGeometry *point) const
Returns the distance along the geometry closest to the specified GEOS point.
 
OrientedConvexHullBoundingBox computeConvexHullOrientedBoundingBox(bool &ok)
Computes an oriented bounding box for the shape's convex hull.
 
double length() const
Returns length of line geometry.
 
void extendLineByDistance(double startDistance, double endDistance, double smoothDistance)
Extends linestrings by the specified amount at the start and end of the line, by extending the existi...
 
double area() const
Returns area of polygon geometry.
 
bool isClosed() const
Returns true if pointset is closed.
 
void createGeosGeom() const
 
void getPointByDistance(double *d, double *ad, double dl, double *px, double *py) const
Gets a point a set distance along a line geometry.
 
bool boundingBoxIntersects(const PointSet *other) const
Returns true if the bounding box of this pointset intersects the bounding box of another pointset.
 
void getCentroid(double &px, double &py, bool forceInside=false) const
 
void offsetCurveByDistance(double distance)
Offsets linestrings by the specified distance.
 
std::vector< int > convexHull
 
const GEOSPreparedGeometry * preparedGeom() const
 
QString toWkt() const
Returns a WKT representation of the point set.
 
const GEOSGeometry * geos() const
Returns the point set's GEOS geometry.
 
void invalidateGeos() const
 
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,...
 
std::unique_ptr< PointSet > extractShape(int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty)
Does... something completely inscrutable.
 
bool containsPoint(double x, double y) const
Tests whether point set contains a specified point.
 
std::tuple< std::vector< double >, double > edgeDistances() const
Returns a vector of edge distances as well as its total length.
 
static QLinkedList< PointSet * > splitPolygons(PointSet *inputShape, double labelWidth, double labelHeight)
Split a polygon using some random logic into some other polygons.
 
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
 
std::unique_ptr< GEOSCoordSequence, GeosDeleter > coord_sequence_unique_ptr
Scoped GEOS coordinate sequence pointer.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
Represents the minimum area, oriented bounding box surrounding a convex hull.
 
struct GEOSGeom_t GEOSGeometry