21 #include <QProgressDialog> 31 const QString& outputLineLayer,
const QString& usedBaselineLayer,
double minTransectLength,
32 double baselineBufferDistance,
double baselineSimplificationTolerance )
33 : mStrataLayer( strataLayer )
34 , mStrataIdAttribute( strataIdAttribute )
35 , mMinDistanceAttribute( minDistanceAttribute )
36 , mNPointsAttribute( nPointsAttribute )
37 , mBaselineLayer( baselineLayer )
38 , mShareBaseline( shareBaseline )
39 , mBaselineStrataId( baselineStrataId )
40 , mOutputPointLayer( outputPointLayer )
41 , mOutputLineLayer( outputLineLayer )
42 , mUsedBaselineLayer( usedBaselineLayer )
43 , mMinDistanceUnits( minDistUnits )
44 , mMinTransectLength( minTransectLength )
45 , mBaselineBufferDistance( baselineBufferDistance )
46 , mBaselineSimplificationTolerance( baselineSimplificationTolerance )
51 : mStrataLayer(
nullptr )
52 , mBaselineLayer(
nullptr )
53 , mShareBaseline(
false )
54 , mMinDistanceUnits(
Meters )
55 , mMinTransectLength( 0.0 )
56 , mBaselineBufferDistance( -1.0 )
57 , mBaselineSimplificationTolerance( -1.0 )
65 if ( !mStrataLayer || !mStrataLayer->
isValid() )
70 if ( !mBaselineLayer || !mBaselineLayer->
isValid() )
76 QVariant::Type stratumIdType = QVariant::Int;
77 if ( !mStrataIdAttribute.
isEmpty() )
79 stratumIdType = mStrataLayer->
fields().
field( mStrataIdAttribute ).
type();
85 outputPointFields.
append(
QgsField(
"station_id", QVariant::Int ) );
86 outputPointFields.
append(
QgsField(
"stratum_id", stratumIdType ) );
87 outputPointFields.
append(
QgsField(
"station_code", QVariant::String ) );
88 outputPointFields.
append(
QgsField(
"start_lat", QVariant::Double ) );
89 outputPointFields.
append(
QgsField(
"start_long", QVariant::Double ) );
92 &( mStrataLayer->
crs() ) );
98 outputPointFields.
append(
QgsField(
"bearing", QVariant::Double ) );
100 &( mStrataLayer->
crs() ) );
107 usedBaselineFields.
append(
QgsField(
"stratum_id", stratumIdType ) );
110 &( mStrataLayer->
crs() ) );
117 QFileInfo outputPointInfo( mOutputPointLayer );
118 QString bufferClipLineOutput = outputPointInfo.
absolutePath() +
"/out_buffer_clip_line.shp";
126 if ( mMinDistanceUnits ==
Meters )
146 int nTotalTransects = 0;
173 QgsGeometry* baselineGeom = findBaselineGeometry( strataId.
isValid() ? strataId : -1 );
180 double minDistanceLayerUnits = minDistance;
182 double bufferDist = bufferDistance( minDistance );
185 minDistanceLayerUnits = minDistance / 111319.9;
191 delete clippedBaseline;
194 QgsGeometry* bufferLineClipped = clipBufferLine( strataGeom, clippedBaseline, bufferDist );
195 if ( !bufferLineClipped )
197 delete clippedBaseline;
210 int nCreatedTransects = 0;
212 int nMaxIterations = nTransects * 50;
217 while ( nCreatedTransects < nTransects && nIterations < nMaxIterations )
227 QgsPoint latLongSamplePoint = toLatLongTransform.transform( sampleQgsPoint );
229 QgsFeature samplePointFeature( outputPointFields );
231 samplePointFeature.
setAttribute(
"id", nTotalTransects + 1 );
232 samplePointFeature.
setAttribute(
"station_id", nCreatedTransects + 1 );
233 samplePointFeature.
setAttribute(
"stratum_id", strataId );
235 samplePointFeature.
setAttribute(
"start_lat", latLongSamplePoint.
y() );
236 samplePointFeature.
setAttribute(
"start_long", latLongSamplePoint.
x() );
248 double bearing = distanceArea.
bearing( sampleQgsPoint, minDistPoint ) /
M_PI * 180.0;
251 QgsPoint ptFarAway( sampleQgsPoint.
x() + ( minDistPoint.
x() - sampleQgsPoint.
x() ) * 1000000,
252 sampleQgsPoint.
y() + ( minDistPoint.
y() - sampleQgsPoint.
y() ) * 1000000 );
254 lineFarAway << sampleQgsPoint << ptFarAway;
257 if ( !lineClipStratum )
259 delete lineFarAwayGeom;
260 delete lineClipStratum;
265 if ( lineClipStratum->
distance( *samplePoint ) > 0.000001 )
267 delete lineFarAwayGeom;
268 delete lineClipStratum;
276 QgsGeometry* singleLine = closestMultilineElement( sampleQgsPoint, lineClipStratum );
279 delete lineClipStratum;
280 lineClipStratum = singleLine;
285 double transectLength = distanceArea.
measureLength( lineClipStratum );
286 if ( transectLength < mMinTransectLength )
288 delete lineFarAwayGeom;
289 delete lineClipStratum;
294 if ( otherTransectWithinDistance( lineClipStratum, minDistanceLayerUnits, minDistance, sIndex, lineFeatureMap, distanceArea ) )
296 delete lineFarAwayGeom;
297 delete lineClipStratum;
302 QgsFeature sampleLineFeature( outputPointFields, fid );
304 sampleLineFeature.
setAttribute(
"id", nTotalTransects + 1 );
305 sampleLineFeature.
setAttribute(
"station_id", nCreatedTransects + 1 );
306 sampleLineFeature.
setAttribute(
"stratum_id", strataId );
308 sampleLineFeature.
setAttribute(
"start_lat", latLongSamplePoint.
y() );
309 sampleLineFeature.
setAttribute(
"start_long", latLongSamplePoint.
x() );
311 outputLineWriter.
addFeature( sampleLineFeature );
315 outputPointWriter.
addFeature( samplePointFeature );
322 delete lineFarAwayGeom;
326 delete clippedBaseline;
329 bufferClipFeature.
setGeometry( bufferLineClipped );
331 bufferClipLineWriter.
addFeature( bufferClipFeature );
336 for ( ; featureMapIt != lineFeatureMap.
end(); ++featureMapIt )
338 delete( featureMapIt.
value() );
340 lineFeatureMap.
clear();
356 if ( !mBaselineLayer )
366 if ( strataId == fet.
attribute( mBaselineStrataId ) || mShareBaseline )
376 bool QgsTransectSample::otherTransectWithinDistance(
QgsGeometry* geom,
double minDistLayerUnit,
double minDistance,
QgsSpatialIndex& sIndex,
393 for ( ; lineIdIt != lineIdList.
constEnd(); ++lineIdIt )
396 if ( idMapIt != lineFeatureMap.
constEnd() )
400 closestSegmentPoints( *geom, *( idMapIt.
value() ), dist, pt1, pt2 );
403 if ( dist < minDistance )
432 if ( pl1.
size() < 2 || pl2.
size() < 2 )
442 double p1x = p11.
x();
443 double p1y = p11.
y();
444 double v1x = p12.
x() - p11.
x();
445 double v1y = p12.
y() - p11.
y();
446 double p2x = p21.
x();
447 double p2y = p21.
y();
448 double v2x = p22.
x() - p21.
x();
449 double v2y = p22.
y() - p21.
y();
451 double denominatorU = v2x * v1y - v2y * v1x;
452 double denominatorT = v1x * v2y - v1y * v2x;
467 if ( d1 <= d2 && d1 <= d3 && d1 <= d4 )
474 else if ( d2 <= d1 && d2 <= d3 && d2 <= d4 )
481 else if ( d3 <= d1 && d3 <= d2 && d3 <= d4 )
497 double u = ( p1x * v1y - p1y * v1x - p2x * v1y + p2y * v1x ) / denominatorU;
498 double t = ( p2x * v2y - p2y * v2x - p1x * v2y + p1y * v2x ) / denominatorT;
500 if ( u >= 0 && u <= 1.0 && t >= 0 && t <= 1.0 )
503 pt1.
setX( p2x + u * v2x );
504 pt1.
setY( p2y + u * v2y );
530 if ( t >= 0.0 && t <= 1.0 )
535 if ( u >= 0.0 && u <= 1.0 )
541 dist = sqrt( pt1.
sqrDist( pt2 ) );
553 double minDist = DBL_MAX;
554 double currentDist = 0;
561 for ( ; it != multiPolyline.
constEnd(); ++it )
564 currentDist = pointGeom->
distance( *currentLine );
565 if ( currentDist < minDist )
567 minDist = currentDist;
568 closestLine.
reset( currentLine );
577 return closestLine.
take();
588 if ( mBaselineSimplificationTolerance >= 0 )
591 usedBaseline = clippedBaseline->
simplify( mBaselineSimplificationTolerance );
604 double currentBufferDist = tolerance;
607 for (
int i = 0; i < maxLoops; ++i )
611 if ( !clipBaselineBuffer )
613 delete clipBaselineBuffer;
624 if ( bufferMultiPolygon.
size() < 1 )
626 delete clipBaselineBuffer;
630 for (
int j = 0; j < bufferMultiPolygon.
size(); ++j )
632 int size = bufferMultiPolygon.
at( j ).size();
633 for (
int k = 0; k < size; ++k )
635 mpl.
append( bufferMultiPolygon.
at( j ).at( k ) );
643 if ( bufferPolygon.
size() < 1 )
645 delete clipBaselineBuffer;
649 int size = bufferPolygon.
size();
651 for (
int j = 0; j < size; ++j )
653 mpl.
append( bufferPolygon[j] );
657 bufferLineClipped = bufferLine->
intersection( stratumGeom );
660 if ( bufferLineClipped && bufferLineClipped->
type() ==
QGis::Line )
663 bool bufferLineClippedIntersectsStratum =
true;
668 for ( ; multiIt != multiPoly.
constEnd(); ++multiIt )
673 bufferLineClippedIntersectsStratum =
false;
681 if ( bufferLineClippedIntersectsStratum )
683 delete clipBaselineBuffer;
684 if ( mBaselineSimplificationTolerance >= 0 )
688 return bufferLineClipped;
692 delete bufferLineClipped;
693 delete clipBaselineBuffer;
694 currentBufferDist /= 2;
697 if ( mBaselineSimplificationTolerance >= 0 )
704 double QgsTransectSample::bufferDistance(
double minDistanceFromAttribute )
const 706 double bufferDist = minDistanceFromAttribute;
707 if ( mBaselineBufferDistance >= 0 )
709 bufferDist = mBaselineBufferDistance;
714 bufferDist /= 111319.9;
QgsPolygon asPolygon() const
Return contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list...
Wrapper for iterator of features from vector data provider or vector layer.
QgsMultiPolyline asMultiPolyline() const
Return contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
A rectangle specified with double values.
int createSample(QProgressDialog *pd)
QgsTransectSample(QgsVectorLayer *strataLayer, const QString &strataIdAttribute, const QString &minDistanceAttribute, const QString &nPointsAttribute, DistanceUnits minDistUnits, QgsVectorLayer *baselineLayer, bool shareBaseline, const QString &baselineStrataId, const QString &outputPointLayer, const QString &outputLineLayer, const QString &usedBaselineLayer, double minTransectLength=0.0, double baselineBufferDistance=-1.0, double baselineSimplificationTolerance=-1.0)
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
bool intersects(const QgsRectangle &r) const
Test for intersection with a rectangle (uses GEOS)
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry, using GEOS.
void append(const T &value)
void setMaximum(int maximum)
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QList< QgsFeatureId > intersects(const QgsRectangle &rect) const
Returns features that intersect the specified rectangle.
const_iterator constEnd() const
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
#define Q_NOWARN_DEPRECATED_PUSH
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
bool addFeature(QgsFeature &feature, QgsFeatureRendererV2 *renderer=nullptr, QGis::UnitType outputUnit=QGis::Meters)
Add feature to the currently opened data source.
WkbType
Used for symbology operations.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
A convenience class for writing vector files to disk.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
QgsPolyline asPolyline() const
Return contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list...
double y() const
Get the y value of the point.
QgsFields fields() const
Returns the list of fields of this layer.
long featureCount(QgsSymbolV2 *symbol)
Number of features rendered with specified symbol.
void setValue(int progress)
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
QString number(int n, int base)
int toInt(bool *ok) const
double sqrDistToSegment(double x1, double y1, double x2, double y2, QgsPoint &minDistPoint, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Returns the minimum distance between this point and a segment.
QgsGeometry * buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
const_iterator constEnd() const
QGis::UnitType mapUnits() const
Returns the units for the projection used by the CRS.
double bearing(const QgsPoint &p1, const QgsPoint &p2) const
compute bearing - in radians
QgsGeometry * interpolate(double distance) const
Return interpolated point on line at distance.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void mt_srand(unsigned value)
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
double measureLine(const QList< QgsPoint > &points) const
Measures the length of a line with multiple segments.
Encapsulate a field in an attribute table or data source.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
bool isValid()
Return the status of the layer.
A class to represent a point.
static QgsGeometry * fromPoint(const QgsPoint &point)
Creates a new geometry from a QgsPoint object.
double length() const
Returns the length of geometry using GEOS.
QgsGeometry * simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
void setX(double x)
Sets the x value of the point.
void setY(double y)
Sets the y value of the point.
static QgsGeometry * fromMultiPolyline(const QgsMultiPolyline &multiline)
Creates a new geometry from a QgsMultiPolyline object.
#define Q_NOWARN_DEPRECATED_POP
General purpose distance and area calculator.
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=nullptr, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
const T & at(int i) const
const_iterator constBegin() const
bool insertFeature(const QgsFeature &f)
Add feature to index.
WriterError hasError()
Checks whether there were any errors in constructor.
QgsMultiPolygon asMultiPolygon() const
Return contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty ...
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
Class for storing a coordinate reference system (CRS)
QgsGeometry * intersection(const QgsGeometry *geometry) const
Returns a geometry representing the points shared by this geometry and other.
static QgsGeometry * fromPolyline(const QgsPolyline &polyline)
Creates a new geometry from a QgsPolyline object.
double measureLength(const QgsGeometry *geometry) const
Measures the length of a geometry.
double toDouble(bool *ok) const
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
iterator insert(const Key &key, const T &value)
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
static QgsGeometry * fromPolygon(const QgsPolygon &polygon)
Creates a new geometry from a QgsPolygon.
const_iterator constEnd() const
bool nextFeature(QgsFeature &f)
const_iterator constBegin() const
long srsid() const
Returns the SrsId, if available.
QString absolutePath() const
Q_DECL_DEPRECATED QgsGeometry * geometryAndOwnership()
Get the geometry object associated with this feature, and transfer ownership of the geometry to the c...
Represents a vector layer which manages a vector based data sets.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
iterator find(const Key &key)
double x() const
Get the x value of the point.
void setEllipsoidalMode(bool flag)
Sets whether coordinates must be projected to ellipsoid before measuring.