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;
 
  567      const GEOSGeometry *longestPart = 
nullptr;
 
  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 );
 
  599      newGeos = std::move( reversed );
 
  602    const int newNbPoints = GEOSGeomGetNumPoints_r( geosctxt, newGeos.get() );
 
  603    const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, newGeos.get() );
 
  604    std::vector< double > newX;
 
  605    std::vector< double > newY;
 
  606    newX.resize( newNbPoints );
 
  607    newY.resize( newNbPoints );
 
  608    for ( 
int i = 0; i < newNbPoints; i++ )
 
  610      GEOSCoordSeq_getX_r( geosctxt, coordSeq, i, &newX[i] );
 
  611      GEOSCoordSeq_getY_r( geosctxt, coordSeq, i, &newY[i] );
 
  617  catch ( GEOSException &e )
 
  619    qWarning( 
"GEOS exception: %s", e.what() );
 
  625  mGeos = newGeos.release();
 
  636  if ( startDistance > 0 )
 
  642    double distanceConsumed = 0;
 
  645    for ( 
int i = 1; i < 
nbPoints; ++i )
 
  647      const double thisX = 
x[i];
 
  648      const double thisY = 
y[i];
 
  649      const double thisSegmentLength = std::sqrt( ( thisX - lastX ) * ( thisX - lastX ) + ( thisY - lastY ) * ( thisY - lastY ) );
 
  650      distanceConsumed += thisSegmentLength;
 
  651      if ( distanceConsumed >= smoothDistance )
 
  653        const double c = ( distanceConsumed - smoothDistance ) / thisSegmentLength;
 
  654        x1 = lastX + 
c * ( thisX - lastX );
 
  655        y1 = lastY + 
c * ( thisY - lastY );
 
  662    const double distance = std::sqrt( ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ) );
 
  663    const double extensionFactor = ( startDistance + distance ) / distance;
 
  670  if ( endDistance > 0 )
 
  678    double distanceConsumed = 0;
 
  681    for ( 
int i = 
nbPoints - 2; i >= 0; --i )
 
  683      const double thisX = 
x[i];
 
  684      const double thisY = 
y[i];
 
  685      const double thisSegmentLength = std::sqrt( ( thisX - lastX ) * ( thisX - lastX ) + ( thisY - lastY ) * ( thisY - lastY ) );
 
  686      distanceConsumed += thisSegmentLength;
 
  687      if ( distanceConsumed >= smoothDistance )
 
  689        const double c = ( distanceConsumed - smoothDistance ) / thisSegmentLength;
 
  690        xend1 = lastX + 
c * ( thisX - lastX );
 
  691        yend1 = lastY + 
c * ( thisY - lastY );
 
  698    const double distance = std::sqrt( ( xend1 - xend0 ) * ( xend1 - xend0 ) + ( yend1 - yend0 ) * ( yend1 - yend0 ) );
 
  699    const double extensionFactor = ( endDistance + distance ) / distance;
 
  701    x.emplace_back( newEnd.
x() );
 
  702    y.emplace_back( newEnd.
y() );
 
  706  if ( startDistance > 0 )
 
  708    x.insert( 
x.begin(), x0 );
 
  709    y.insert( 
y.begin(), y0 );
 
  730  double best_area = std::numeric_limits<double>::max();
 
  731  double best_alpha = -1;
 
  733  double best_length = 0;
 
  734  double best_width = 0;
 
  737  bbox[0] = std::numeric_limits<double>::max();
 
  738  bbox[1] = std::numeric_limits<double>::max();
 
  739  bbox[2] = std::numeric_limits<double>::lowest();
 
  740  bbox[3] = std::numeric_limits<double>::lowest();
 
  742  for ( std::size_t i = 0; i < 
convexHull.size(); i++ )
 
  759  const double dref = bbox[2] - bbox[0];
 
  766  for ( alpha_d = 0; alpha_d < 90; alpha_d++ )
 
  768    alpha = alpha_d *  M_PI / 180.0;
 
  769    d1 = std::cos( alpha ) * dref;
 
  770    d2 = std::sin( alpha ) * dref;
 
  791    bb[14] = bb[12] + d2;
 
  792    bb[15] = bb[13] - d1; 
 
  795    for ( 
int  i = 0; i < 16; i += 4 )
 
  798      alpha_seg = ( ( i / 4 > 0 ? ( i / 4 ) - 1 : 3 ) ) * M_PI_2 + alpha;
 
  800      double best_cp = std::numeric_limits<double>::max();
 
  802      for ( std::size_t j = 0; j < 
convexHull.size(); j++ )
 
  811      const double distNearestPoint = best_cp / dref;
 
  813      d1 = std::cos( alpha_seg ) * distNearestPoint;
 
  814      d2 = std::sin( alpha_seg ) * distNearestPoint;
 
  838      memcpy( best_bb, bb, 
sizeof( 
double ) * 16 );
 
  843  for ( 
int i = 0; i < 16; i = i + 4 )
 
  846                                           best_bb[( i + 4 ) % 16], best_bb[( i + 5 ) % 16], best_bb[( i + 6 ) % 16], best_bb[( i + 7 ) % 16],
 
  847                                           &finalBb.
x[int ( i / 4 )], &finalBb.
y[int ( i / 4 )] );
 
  850  finalBb.
alpha = best_alpha;
 
  851  finalBb.
width = best_width;
 
  852  finalBb.
length = best_length;
 
  869    geos::unique_ptr geosPt( GEOSGeom_createPointFromXY_r( geosctxt, px, py ) );
 
  870    const int type = GEOSGeomTypeId_r( geosctxt, 
mGeos );
 
  871    const GEOSGeometry *extRing = 
nullptr;
 
  872    const GEOSPreparedGeometry *preparedExtRing = 
nullptr;
 
  874    if ( 
type != GEOS_POLYGON )
 
  882      extRing = GEOSGetExteriorRing_r( geosctxt, 
mGeos );
 
  883      if ( ! mGeosPreparedBoundary )
 
  885        mGeosPreparedBoundary = GEOSPrepare_r( geosctxt, extRing );
 
  887      preparedExtRing = mGeosPreparedBoundary;
 
  893    unsigned int nPoints = 0;
 
  894    GEOSCoordSeq_getSize_r( geosctxt, nearestCoord.get(), &nPoints );
 
  898    ( void )GEOSCoordSeq_getXY_r( geosctxt, nearestCoord.get(), 0, &nx, &ny );
 
  907  catch ( GEOSException &e )
 
  909    qWarning( 
"GEOS exception: %s", e.what() );
 
  929      const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, centroidGeom.get() );
 
  930      unsigned int nPoints = 0;
 
  931      GEOSCoordSeq_getSize_r( geosctxt, coordSeq, &nPoints );
 
  934      GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
 
  944        const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom.get() );
 
  945        unsigned int nPoints = 0;
 
  946        GEOSCoordSeq_getSize_r( geosctxt, coordSeq, &nPoints );
 
  950        GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
 
  954  catch ( GEOSException &e )
 
  956    qWarning( 
"GEOS exception: %s", e.what() );
 
  982    while ( i < 
nbPoints && ad[i] <= dl ) i++;
 
  992      di = std::sqrt( dx * dx + dy * dy );
 
  996      dx = 
x[i + 1] - 
x[i];
 
  997      dy = 
y[i + 1] - 
y[i];
 
 1002    *px = 
x[i] + dx * distr / di;
 
 1003    *py = 
y[i] + dy * distr / di;
 
 1014  const GEOSGeometry *thisGeos = 
geos();
 
 1023  catch ( GEOSException &e )
 
 1025    qWarning( 
"GEOS exception: %s", e.what() );
 
 1032  const GEOSGeometry *thisGeos = 
geos();
 
 1036  double distance = -1;
 
 1041  catch ( GEOSException &e )
 
 1043    qWarning( 
"GEOS exception: %s", e.what() );
 
 1076  catch ( GEOSException &e )
 
 1078    qWarning( 
"GEOS exception: %s", e.what() );
 
 1099    ( void )GEOSArea_r( geosctxt, 
mGeos, &
mArea );
 
 1103  catch ( GEOSException &e )
 
 1105    qWarning( 
"GEOS exception: %s", e.what() );
 
 1125    GEOSWKTWriter *writer = GEOSWKTWriter_create_r( geosctxt );
 
 1127    char *wkt = GEOSWKTWriter_write_r( geosctxt, writer, 
mGeos );
 
 1128    const QString res( wkt );
 
 1130    GEOSFree_r( geosctxt, wkt );
 
 1132    GEOSWKTWriter_destroy_r( geosctxt, writer );
 
 1137  catch ( GEOSException &e )
 
 1139    qWarning( 
"GEOS exception: %s", e.what() );
 
 1147  std::vector< double > distances( 
nbPoints );
 
 1148  double totalDistance = 0;
 
 1149  double oldX = -1.0, oldY = -1.0;
 
 1150  for ( 
int i = 0; i < 
nbPoints; i++ )
 
 1155      distances[i] = std::sqrt( std::pow( oldX - 
x[i], 2 ) + std::pow( oldY - 
y[i], 2 ) );
 
 1159    totalDistance += distances[i];
 
 1161  return std::make_tuple( std::move( distances ), totalDistance );
 
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction) SIP_HOLDGIL
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.