49 : nbPoints( nbPoints )
50 , type( GEOS_POLYGON )
121 bool needClose =
false;
127 GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt,
nbPoints + ( needClose ? 1 : 0 ), 2 );
128 for (
int i = 0; i <
nbPoints; ++i )
130 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
131 GEOSCoordSeq_setXY_r( geosctxt, coord, i,
x[i],
y[i] );
133 GEOSCoordSeq_setX_r( geosctxt, coord, i,
x[i] );
134 GEOSCoordSeq_setY_r( geosctxt, coord, i,
y[i] );
141 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
142 GEOSCoordSeq_setXY_r( geosctxt, coord,
nbPoints,
x[0],
y[0] );
144 GEOSCoordSeq_setX_r( geosctxt, coord,
nbPoints,
x[0] );
145 GEOSCoordSeq_setY_r( geosctxt, coord,
nbPoints,
y[0] );
152 mGeos = GEOSGeom_createPolygon_r( geosctxt, GEOSGeom_createLinearRing_r( geosctxt, coord ),
nullptr, 0 );
155 case GEOS_LINESTRING:
156 mGeos = GEOSGeom_createLineString_r( geosctxt, coord );
160 mGeos = GEOSGeom_createPoint_r( geosctxt, coord );
172 if ( !mPreparedGeom )
176 return mPreparedGeom;
183 GEOSGeom_destroy_r( geosctxt,
mGeos );
184 GEOSPreparedGeom_destroy_r( geosctxt, mPreparedGeom );
187 mPreparedGeom =
nullptr;
198 GEOSGeom_destroy_r( geosctxt,
mGeos );
201 GEOSPreparedGeom_destroy_r( geosctxt, mPreparedGeom );
214 std::unique_ptr<PointSet>
PointSet::extractShape(
int nbPtSh,
int imin,
int imax,
int fps,
int fpe,
double fptx,
double fpty )
218 std::unique_ptr<PointSet> newShape = qgis::make_unique< PointSet >();
219 newShape->type = GEOS_POLYGON;
220 newShape->nbPoints = nbPtSh;
221 newShape->x.resize( newShape->nbPoints );
222 newShape->y.resize( newShape->nbPoints );
225 for ( j = 0, i = imin; i != ( imax + 1 ) %
nbPoints; i = ( i + 1 ) %
nbPoints, j++ )
227 newShape->x[j] =
x[i];
228 newShape->y[j] =
y[i];
234 newShape->x[j] = fptx;
235 newShape->y[j] = fpty;
243 return std::unique_ptr< PointSet>(
new PointSet( *
this ) );
251 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
254 GEOSCoordSequence *seq = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
255 GEOSCoordSeq_setX_r( geosctxt, seq, 0,
x );
256 GEOSCoordSeq_setY_r( geosctxt, seq, 0,
y );
259 bool result = ( GEOSPreparedContainsProperly_r( geosctxt,
preparedGeom(), point.get() ) == 1 );
263 catch ( GEOSException &e )
265 qWarning(
"GEOS exception: %s", e.what() );
278 QLinkedList<PointSet *> &outputShapes,
279 double xrm,
double yrm )
284 std::vector< double >
x;
285 std::vector< double >
y;
289 int *
cHull =
nullptr;
314 double labelArea = xrm * yrm;
318 while ( !inputShapes.isEmpty() )
320 shape = inputShapes.takeFirst();
327 for ( i = 0; i < nbp; i++ )
348 ipn = ( ips + 1 ) % nbp;
349 if ( ipn !=
cHull[ihn] )
354 for ( i = ips; i !=
cHull[ihn]; i = ( i + 1 ) % nbp )
378 s = ( base + b +
c ) / 2;
379 area = s * ( s - base ) * ( s - b ) * ( s -
c );
401 bestArea = std::sqrt( bestArea );
402 double cx, cy, dx, dy, ex, ey, fx, fy, seg_length, ptx = 0, pty = 0, fptx = 0, fpty = 0;
403 int ps = -1, pe = -1, fps = -1, fpe = -1;
404 if ( retainedPt >= 0 && bestArea > labelArea )
406 c = std::numeric_limits<double>::max();
411 for ( i = (
cHull[holeE] + 1 ) % nbp; i != (
cHull[holeS] - 1 + nbp ) % nbp; i = j )
419 cx = (
x[i] +
x[j] ) / 2.0;
420 cy = (
y[i] +
y[j] ) / 2.0;
458 double pointX, pointY;
470 for ( k =
cHull[holeS]; k !=
cHull[holeE]; k = ( k + 1 ) % nbp )
481 if ( isValid && b <
c )
492 int imin = retainedPt;
493 int imax = ( ( ( fps < retainedPt && fpe < retainedPt ) || ( fps > retainedPt && fpe > retainedPt ) ) ? std::min( fps, fpe ) : std::max( fps, fpe ) );
495 int nbPtSh1, nbPtSh2;
497 nbPtSh1 = imax - imin + 1 + ( fpe != fps );
499 nbPtSh1 = imax + nbp - imin + 1 + ( fpe != fps );
501 if ( ( imax == fps ? fpe : fps ) < imin )
502 nbPtSh2 = imin - ( imax == fps ? fpe : fps ) + 1 + ( fpe != fps );
504 nbPtSh2 = imin + nbp - ( imax == fps ? fpe : fps ) + 1 + ( fpe != fps );
506 if ( retainedPt == -1 || fps == -1 || fpe == -1 )
512 else if ( imax == imin || nbPtSh1 <= 2 || nbPtSh2 <= 2 || nbPtSh1 == nbp || nbPtSh2 == nbp )
514 outputShapes.append( shape );
519 PointSet *newShape = shape->
extractShape( nbPtSh1, imin, imax, fps, fpe, fptx, fpty ).release();
526 inputShapes.append( newShape );
533 newShape = shape->
extractShape( nbPtSh2, imax, imin, fps, fpe, fptx, fpty ).release();
540 inputShapes.append( newShape );
548 outputShapes.append( shape );
561 if ( startDistance > 0 )
567 double distanceConsumed = 0;
570 for (
int i = 1; i <
nbPoints; ++i )
574 const double thisSegmentLength = std::sqrt( ( thisX - lastX ) * ( thisX - lastX ) + ( thisY - lastY ) * ( thisY - lastY ) );
575 distanceConsumed += thisSegmentLength;
576 if ( distanceConsumed >= smoothDistance )
578 double c = ( distanceConsumed - smoothDistance ) / thisSegmentLength;
579 x1 = lastX +
c * ( thisX - lastX );
580 y1 = lastY +
c * ( thisY - lastY );
587 const double distance = std::sqrt( ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ) );
588 const double extensionFactor = ( startDistance + distance ) / distance;
595 if ( endDistance > 0 )
603 double distanceConsumed = 0;
606 for (
int i =
nbPoints - 2; i >= 0; --i )
610 const double thisSegmentLength = std::sqrt( ( thisX - lastX ) * ( thisX - lastX ) + ( thisY - lastY ) * ( thisY - lastY ) );
611 distanceConsumed += thisSegmentLength;
612 if ( distanceConsumed >= smoothDistance )
614 double c = ( distanceConsumed - smoothDistance ) / thisSegmentLength;
615 xend1 = lastX +
c * ( thisX - lastX );
616 yend1 = lastY +
c * ( thisY - lastY );
623 const double distance = std::sqrt( ( xend1 - xend0 ) * ( xend1 - xend0 ) + ( yend1 - yend0 ) * ( yend1 - yend0 ) );
624 const double extensionFactor = ( endDistance + distance ) / distance;
626 x.emplace_back( newEnd.
x() );
627 y.emplace_back( newEnd.
y() );
631 if ( startDistance > 0 )
633 x.insert(
x.begin(), x0 );
634 y.insert(
y.begin(), y0 );
660 double distNearestPoint;
666 double best_area = std::numeric_limits<double>::max();
667 double best_alpha = -1;
669 double best_length = 0;
670 double best_width = 0;
673 bbox[0] = std::numeric_limits<double>::max();
674 bbox[1] = std::numeric_limits<double>::max();
675 bbox[2] = std::numeric_limits<double>::lowest();
676 bbox[3] = std::numeric_limits<double>::lowest();
680 if (
x[
cHull[i]] < bbox[0] )
683 if (
x[
cHull[i]] > bbox[2] )
686 if (
y[
cHull[i]] < bbox[1] )
689 if (
y[
cHull[i]] > bbox[3] )
694 dref = bbox[2] - bbox[0];
696 for ( alpha_d = 0; alpha_d < 90; alpha_d++ )
698 alpha = alpha_d * M_PI / 180.0;
699 d1 = std::cos( alpha ) * dref;
700 d2 = std::sin( alpha ) * dref;
721 bb[14] = bb[12] + d2;
722 bb[15] = bb[13] - d1;
725 for ( i = 0; i < 16; i += 4 )
728 alpha_seg = ( ( i / 4 > 0 ? ( i / 4 ) - 1 : 3 ) ) * M_PI_2 + alpha;
730 best_cp = std::numeric_limits<double>::max();
740 distNearestPoint = best_cp / dref;
742 d1 = std::cos( alpha_seg ) * distNearestPoint;
743 d2 = std::sin( alpha_seg ) * distNearestPoint;
767 memcpy( best_bb, bb,
sizeof(
double ) * 16 );
775 for ( i = 0; i < 16; i = i + 4 )
778 best_bb[( i + 4 ) % 16], best_bb[( i + 5 ) % 16], best_bb[( i + 6 ) % 16], best_bb[( i + 7 ) % 16],
779 &finalBb.
x[int ( i / 4 )], &finalBb.
y[int ( i / 4 )] );
782 finalBb.
alpha = best_alpha;
783 finalBb.
width = best_width;
784 finalBb.
length = best_length;
800 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
801 geos::unique_ptr geosPt( GEOSGeom_createPointFromXY_r( geosctxt, px, py ) );
803 GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
804 GEOSCoordSeq_setX_r( geosctxt, coord, 0, px );
805 GEOSCoordSeq_setY_r( geosctxt, coord, 0, py );
808 int type = GEOSGeomTypeId_r( geosctxt,
mGeos );
809 const GEOSGeometry *extRing =
nullptr;
810 if (
type != GEOS_POLYGON )
817 extRing = GEOSGetExteriorRing_r( geosctxt,
mGeos );
822 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
823 unsigned int nPoints = 0;
824 GEOSCoordSeq_getSize_r( geosctxt, nearestCoord.get(), &nPoints );
828 ( void )GEOSCoordSeq_getXY_r( geosctxt, nearestCoord.get(), 0, &nx, &ny );
830 ( void )GEOSCoordSeq_getX_r( geosctxt, nearestCoord.get(), 0, &nx );
831 ( void )GEOSCoordSeq_getY_r( geosctxt, nearestCoord.get(), 0, &ny );
841 catch ( GEOSException &e )
843 qWarning(
"GEOS exception: %s", e.what() );
863 const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, centroidGeom.get() );
864 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
865 unsigned int nPoints = 0;
866 GEOSCoordSeq_getSize_r( geosctxt, coordSeq, &nPoints );
869 GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
871 GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
872 GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
883 const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom.get() );
884 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
885 unsigned int nPoints = 0;
886 GEOSCoordSeq_getSize_r( geosctxt, coordSeq, &nPoints );
890 GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
892 GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
893 GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
898 catch ( GEOSException &e )
900 qWarning(
"GEOS exception: %s", e.what() );
926 while ( i <
nbPoints && ad[i] <= dl ) i++;
936 di = std::sqrt( dx * dx + dy * dy );
940 dx =
x[i + 1] -
x[i];
941 dy =
y[i + 1] -
y[i];
946 *px =
x[i] + dx * distr / di;
947 *py =
y[i] + dy * distr / di;
982 catch ( GEOSException &e )
984 qWarning(
"GEOS exception: %s", e.what() );
1005 ( void )GEOSArea_r( geosctxt,
mGeos, &
mArea );
1009 catch ( GEOSException &e )
1011 qWarning(
"GEOS exception: %s", e.what() );