7 #include <QProgressDialog> 17 const QString& outputLineLayer,
const QString& usedBaselineLayer,
double minTransectLength,
18 double baselineBufferDistance,
double baselineSimplificationTolerance ): mStrataLayer( strataLayer ),
19 mStrataIdAttribute( strataIdAttribute ), mMinDistanceAttribute( minDistanceAttribute ), mNPointsAttribute( nPointsAttribute ), mBaselineLayer( baselineLayer ), mShareBaseline( shareBaseline ),
20 mBaselineStrataId( baselineStrataId ), mOutputPointLayer( outputPointLayer ), mOutputLineLayer( outputLineLayer ), mUsedBaselineLayer( usedBaselineLayer ),
21 mMinDistanceUnits( minDistUnits ), mMinTransectLength( minTransectLength ), mBaselineBufferDistance( baselineBufferDistance ), mBaselineSimplificationTolerance( baselineSimplificationTolerance )
26 : mStrataLayer(
nullptr )
27 , mBaselineLayer(
nullptr )
28 , mShareBaseline(
false )
29 , mMinDistanceUnits(
Meters )
30 , mMinTransectLength( 0.0 )
31 , mBaselineBufferDistance( -1.0 )
32 , mBaselineSimplificationTolerance( -1.0 )
40 if ( !mStrataLayer || !mStrataLayer->
isValid() )
45 if ( !mBaselineLayer || !mBaselineLayer->
isValid() )
51 QVariant::Type stratumIdType = QVariant::Int;
52 if ( !mStrataIdAttribute.
isEmpty() )
54 stratumIdType = mStrataLayer->
fields().
field( mStrataIdAttribute ).
type();
60 outputPointFields.
append(
QgsField(
"station_id", QVariant::Int ) );
61 outputPointFields.
append(
QgsField(
"stratum_id", stratumIdType ) );
62 outputPointFields.
append(
QgsField(
"station_code", QVariant::String ) );
63 outputPointFields.
append(
QgsField(
"start_lat", QVariant::Double ) );
64 outputPointFields.
append(
QgsField(
"start_long", QVariant::Double ) );
67 &( mStrataLayer->
crs() ) );
73 outputPointFields.
append(
QgsField(
"bearing", QVariant::Double ) );
75 &( mStrataLayer->
crs() ) );
82 usedBaselineFields.
append(
QgsField(
"stratum_id", stratumIdType ) );
85 &( mStrataLayer->
crs() ) );
92 QFileInfo outputPointInfo( mOutputPointLayer );
93 QString bufferClipLineOutput = outputPointInfo.
absolutePath() +
"/out_buffer_clip_line.shp";
101 if ( mMinDistanceUnits ==
Meters )
121 int nTotalTransects = 0;
148 QgsGeometry* baselineGeom = findBaselineGeometry( strataId.
isValid() ? strataId : -1 );
155 double minDistanceLayerUnits = minDistance;
157 double bufferDist = bufferDistance( minDistance );
160 minDistanceLayerUnits = minDistance / 111319.9;
166 delete clippedBaseline;
169 QgsGeometry* bufferLineClipped = clipBufferLine( strataGeom, clippedBaseline, bufferDist );
170 if ( !bufferLineClipped )
172 delete clippedBaseline;
185 int nCreatedTransects = 0;
187 int nMaxIterations = nTransects * 50;
192 while ( nCreatedTransects < nTransects && nIterations < nMaxIterations )
202 QgsPoint latLongSamplePoint = toLatLongTransform.transform( sampleQgsPoint );
204 QgsFeature samplePointFeature( outputPointFields );
206 samplePointFeature.
setAttribute(
"id", nTotalTransects + 1 );
207 samplePointFeature.
setAttribute(
"station_id", nCreatedTransects + 1 );
208 samplePointFeature.
setAttribute(
"stratum_id", strataId );
210 samplePointFeature.
setAttribute(
"start_lat", latLongSamplePoint.
y() );
211 samplePointFeature.
setAttribute(
"start_long", latLongSamplePoint.
x() );
223 double bearing = distanceArea.
bearing( sampleQgsPoint, minDistPoint ) /
M_PI * 180.0;
226 QgsPoint ptFarAway( sampleQgsPoint.
x() + ( minDistPoint.
x() - sampleQgsPoint.
x() ) * 1000000,
227 sampleQgsPoint.
y() + ( minDistPoint.
y() - sampleQgsPoint.
y() ) * 1000000 );
229 lineFarAway << sampleQgsPoint << ptFarAway;
232 if ( !lineClipStratum )
234 delete lineFarAwayGeom;
235 delete lineClipStratum;
240 if ( lineClipStratum->
distance( *samplePoint ) > 0.000001 )
242 delete lineFarAwayGeom;
243 delete lineClipStratum;
251 QgsGeometry* singleLine = closestMultilineElement( sampleQgsPoint, lineClipStratum );
254 delete lineClipStratum;
255 lineClipStratum = singleLine;
260 double transectLength = distanceArea.
measureLength( lineClipStratum );
261 if ( transectLength < mMinTransectLength )
263 delete lineFarAwayGeom;
264 delete lineClipStratum;
269 if ( otherTransectWithinDistance( lineClipStratum, minDistanceLayerUnits, minDistance, sIndex, lineFeatureMap, distanceArea ) )
271 delete lineFarAwayGeom;
272 delete lineClipStratum;
277 QgsFeature sampleLineFeature( outputPointFields, fid );
279 sampleLineFeature.
setAttribute(
"id", nTotalTransects + 1 );
280 sampleLineFeature.
setAttribute(
"station_id", nCreatedTransects + 1 );
281 sampleLineFeature.
setAttribute(
"stratum_id", strataId );
283 sampleLineFeature.
setAttribute(
"start_lat", latLongSamplePoint.
y() );
284 sampleLineFeature.
setAttribute(
"start_long", latLongSamplePoint.
x() );
286 outputLineWriter.
addFeature( sampleLineFeature );
290 outputPointWriter.
addFeature( samplePointFeature );
297 delete lineFarAwayGeom;
301 delete clippedBaseline;
304 bufferClipFeature.
setGeometry( bufferLineClipped );
306 bufferClipLineWriter.
addFeature( bufferClipFeature );
311 for ( ; featureMapIt != lineFeatureMap.
end(); ++featureMapIt )
313 delete( featureMapIt.
value() );
315 lineFeatureMap.
clear();
331 if ( !mBaselineLayer )
341 if ( strataId == fet.
attribute( mBaselineStrataId ) || mShareBaseline )
351 bool QgsTransectSample::otherTransectWithinDistance(
QgsGeometry* geom,
double minDistLayerUnit,
double minDistance,
QgsSpatialIndex& sIndex,
368 for ( ; lineIdIt != lineIdList.
constEnd(); ++lineIdIt )
371 if ( idMapIt != lineFeatureMap.
constEnd() )
375 closestSegmentPoints( *geom, *( idMapIt.
value() ), dist, pt1, pt2 );
378 if ( dist < minDistance )
407 if ( pl1.
size() < 2 || pl2.
size() < 2 )
417 double p1x = p11.
x();
418 double p1y = p11.
y();
419 double v1x = p12.
x() - p11.
x();
420 double v1y = p12.
y() - p11.
y();
421 double p2x = p21.
x();
422 double p2y = p21.
y();
423 double v2x = p22.
x() - p21.
x();
424 double v2y = p22.
y() - p21.
y();
426 double denominatorU = v2x * v1y - v2y * v1x;
427 double denominatorT = v1x * v2y - v1y * v2x;
442 if ( d1 <= d2 && d1 <= d3 && d1 <= d4 )
449 else if ( d2 <= d1 && d2 <= d3 && d2 <= d4 )
456 else if ( d3 <= d1 && d3 <= d2 && d3 <= d4 )
472 double u = ( p1x * v1y - p1y * v1x - p2x * v1y + p2y * v1x ) / denominatorU;
473 double t = ( p2x * v2y - p2y * v2x - p1x * v2y + p1y * v2x ) / denominatorT;
475 if ( u >= 0 && u <= 1.0 && t >= 0 && t <= 1.0 )
478 pt1.
setX( p2x + u * v2x );
479 pt1.
setY( p2y + u * v2y );
505 if ( t >= 0.0 && t <= 1.0 )
510 if ( u >= 0.0 && u <= 1.0 )
516 dist = sqrt( pt1.
sqrDist( pt2 ) );
528 double minDist = DBL_MAX;
529 double currentDist = 0;
536 for ( ; it != multiPolyline.
constEnd(); ++it )
539 currentDist = pointGeom->
distance( *currentLine );
540 if ( currentDist < minDist )
542 minDist = currentDist;
543 closestLine.
reset( currentLine );
552 return closestLine.
take();
563 if ( mBaselineSimplificationTolerance >= 0 )
566 usedBaseline = clippedBaseline->
simplify( mBaselineSimplificationTolerance );
579 double currentBufferDist = tolerance;
582 for (
int i = 0; i < maxLoops; ++i )
586 if ( !clipBaselineBuffer )
588 delete clipBaselineBuffer;
599 if ( bufferMultiPolygon.
size() < 1 )
601 delete clipBaselineBuffer;
605 for (
int j = 0; j < bufferMultiPolygon.
size(); ++j )
607 int size = bufferMultiPolygon.
at( j ).size();
608 for (
int k = 0; k < size; ++k )
610 mpl.
append( bufferMultiPolygon.
at( j ).at( k ) );
618 if ( bufferPolygon.
size() < 1 )
620 delete clipBaselineBuffer;
624 int size = bufferPolygon.
size();
626 for (
int j = 0; j < size; ++j )
628 mpl.
append( bufferPolygon[j] );
632 bufferLineClipped = bufferLine->
intersection( stratumGeom );
635 if ( bufferLineClipped && bufferLineClipped->
type() ==
QGis::Line )
638 bool bufferLineClippedIntersectsStratum =
true;
643 for ( ; multiIt != multiPoly.
constEnd(); ++multiIt )
648 bufferLineClippedIntersectsStratum =
false;
656 if ( bufferLineClippedIntersectsStratum )
658 delete clipBaselineBuffer;
659 if ( mBaselineSimplificationTolerance >= 0 )
663 return bufferLineClipped;
667 delete bufferLineClipped;
668 delete clipBaselineBuffer;
669 currentBufferDist /= 2;
672 if ( mBaselineSimplificationTolerance >= 0 )
679 double QgsTransectSample::bufferDistance(
double minDistanceFromAttribute )
const 681 double bufferDist = minDistanceFromAttribute;
682 if ( mBaselineBufferDistance >= 0 )
684 bufferDist = mBaselineBufferDistance;
689 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)
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 and x,y.
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.