7 #include <QProgressDialog>
16 QgsVectorLayer* baselineLayer,
bool shareBaseline, QString baselineStrataId,
const QString& outputPointLayer,
17 const QString& outputLineLayer,
const QString& usedBaselineLayer,
double minTransectLength ): mStrataLayer( strataLayer ),
18 mStrataIdAttribute( strataIdAttribute ), mMinDistanceAttribute( minDistanceAttribute ), mNPointsAttribute( nPointsAttribute ), mBaselineLayer( baselineLayer ), mShareBaseline( shareBaseline ),
19 mBaselineStrataId( baselineStrataId ), mOutputPointLayer( outputPointLayer ), mOutputLineLayer( outputLineLayer ), mUsedBaselineLayer( usedBaselineLayer ),
20 mMinDistanceUnits( minDistUnits ), mMinTransectLength( minTransectLength )
47 QVariant::Type stratumIdType = QVariant::Int;
56 outputPointFields.
append(
QgsField(
"station_id", QVariant::Int ) );
57 outputPointFields.
append(
QgsField(
"stratum_id", stratumIdType ) );
58 outputPointFields.
append(
QgsField(
"station_code", QVariant::String ) );
59 outputPointFields.
append(
QgsField(
"start_lat", QVariant::Double ) );
60 outputPointFields.
append(
QgsField(
"start_long", QVariant::Double ) );
69 outputPointFields.
append(
QgsField(
"bearing", QVariant::Double ) );
78 usedBaselineFields.
append(
QgsField(
"stratum_id", stratumIdType ) );
89 QString bufferClipLineOutput = outputPointInfo.absolutePath() +
"/out_buffer_clip_line.shp";
110 mt_srand( QTime::currentTime().msec() );
117 int nTotalTransects = 0;
129 pd->setValue( nFeatures );
131 if ( pd && pd->wasCanceled() )
144 bool strataIdOk =
true;
153 double minDistanceLayerUnits = minDistance;
155 double bufferDist = minDistance;
158 bufferDist = minDistance / 111319.9;
159 minDistanceLayerUnits = bufferDist;
165 delete clippedBaseline;
169 if ( !bufferLineClipped )
171 delete clippedBaseline;
184 int nCreatedTransects = 0;
186 int nMaxIterations = nTransects * 50;
189 QMap< QgsFeatureId, QgsGeometry* > lineFeatureMap;
191 while ( nCreatedTransects < nTransects && nIterations < nMaxIterations )
201 QgsPoint latLongSamplePoint = toLatLongTransform.transform( sampleQgsPoint );
205 samplePointFeature.
setAttribute(
"id", nTotalTransects + 1 );
206 samplePointFeature.
setAttribute(
"station_id", nCreatedTransects + 1 );
207 samplePointFeature.
setAttribute(
"stratum_id", strataId );
208 samplePointFeature.
setAttribute(
"station_code", strataId.toString() +
"_" + QString::number( nCreatedTransects + 1 ) );
209 samplePointFeature.
setAttribute(
"start_lat", latLongSamplePoint.
y() );
210 samplePointFeature.
setAttribute(
"start_long", latLongSamplePoint.
x() );
222 double bearing = distanceArea.
bearing( sampleQgsPoint, minDistPoint ) /
M_PI * 180.0;
225 QgsPoint ptFarAway( sampleQgsPoint.
x() + ( minDistPoint.
x() - sampleQgsPoint.
x() ) * 1000000,
226 sampleQgsPoint.
y() + ( minDistPoint.
y() - sampleQgsPoint.
y() ) * 1000000 );
228 lineFarAway << sampleQgsPoint << ptFarAway;
231 if ( !lineClipStratum )
233 delete lineFarAwayGeom;
delete lineClipStratum;
238 if ( lineClipStratum->
distance( *samplePoint ) > 0.000001 )
240 delete lineFarAwayGeom;
delete lineClipStratum;
251 delete lineClipStratum;
252 lineClipStratum = singleLine;
257 double transectLength = distanceArea.
measure( lineClipStratum );
260 delete lineFarAwayGeom;
delete lineClipStratum;
267 delete lineFarAwayGeom;
delete lineClipStratum;
274 sampleLineFeature.
setAttribute(
"id", nTotalTransects + 1 );
275 sampleLineFeature.
setAttribute(
"station_id", nCreatedTransects + 1 );
276 sampleLineFeature.
setAttribute(
"stratum_id", strataId );
277 sampleLineFeature.
setAttribute(
"station_code", strataId.toString() +
"_" + QString::number( nCreatedTransects + 1 ) );
278 sampleLineFeature.
setAttribute(
"start_lat", latLongSamplePoint.
y() );
279 sampleLineFeature.
setAttribute(
"start_long", latLongSamplePoint.
x() );
281 outputLineWriter.
addFeature( sampleLineFeature );
285 outputPointWriter.
addFeature( samplePointFeature );
290 delete lineFarAwayGeom;
294 delete clippedBaseline;
297 bufferClipFeature.
setGeometry( bufferLineClipped );
299 bufferClipLineWriter.
addFeature( bufferClipFeature );
303 QMap< QgsFeatureId, QgsGeometry* >::iterator featureMapIt = lineFeatureMap.begin();
304 for ( ; featureMapIt != lineFeatureMap.end(); ++featureMapIt )
306 delete( featureMapIt.value() );
308 lineFeatureMap.clear();
343 const QMap< QgsFeatureId, QgsGeometry* >& lineFeatureMap,
QgsDistanceArea& da )
356 QList<QgsFeatureId> lineIdList = sIndex.
intersects( rect );
358 QList<QgsFeatureId>::const_iterator lineIdIt = lineIdList.constBegin();
359 for ( ; lineIdIt != lineIdList.constEnd(); ++lineIdIt )
361 const QMap< QgsFeatureId, QgsGeometry* >::const_iterator idMapIt = lineFeatureMap.find( *lineIdIt );
362 if ( idMapIt != lineFeatureMap.constEnd() )
369 if ( dist < minDistance )
398 if ( pl1.size() < 2 || pl2.size() < 2 )
408 double p1x = p11.
x();
409 double p1y = p11.
y();
410 double v1x = p12.
x() - p11.
x();
411 double v1y = p12.
y() - p11.
y();
412 double p2x = p21.
x();
413 double p2y = p21.
y();
414 double v2x = p22.
x() - p21.
x();
415 double v2y = p22.
y() - p21.
y();
417 double denominatorU = v2x * v1y - v2y * v1x;
418 double denominatorT = v1x * v2y - v1y * v2x;
433 if ( d1 <= d2 && d1 <= d3 && d1 <= d4 )
435 dist = sqrt( d1 ); pt1 = p11; pt2 = minDistPoint1;
438 else if ( d2 <= d1 && d2 <= d3 && d2 <= d4 )
440 dist = sqrt( d2 ); pt1 = p12; pt2 = minDistPoint2;
443 else if ( d3 <= d1 && d3 <= d2 && d3 <= d4 )
445 dist = sqrt( d3 ); pt1 = p21; pt2 = minDistPoint3;
450 dist = sqrt( d4 ); pt1 = p21; pt2 = minDistPoint4;
455 double u = ( p1x * v1y - p1y * v1x - p2x * v1y + p2y * v1x ) / denominatorU;
456 double t = ( p2x * v2y - p2y * v2x - p1x * v2y + p1y * v2x ) / denominatorT;
458 if ( u >= 0 && u <= 1.0 && t >= 0 && t <= 1.0 )
461 pt1.
setX( p2x + u * v2x );
462 pt1.
setY( p2y + u * v2y );
488 if ( t >= 0.0 && t <= 1.0 )
493 if ( u >= 0.0 && u <= 1.0 )
499 dist = sqrt( pt1.
sqrDist( pt2 ) );
511 double minDist = DBL_MAX;
512 double currentDist = 0;
518 QgsMultiPolyline::const_iterator it = multiPolyline.constBegin();
519 for ( ; it != multiPolyline.constEnd(); ++it )
522 currentDist = pointGeom->
distance( *currentLine );
523 if ( currentDist < minDist )
525 minDist = currentDist;
526 closestLine = currentLine;
545 double currentBufferDist = tolerance;
548 for (
int i = 0; i < maxLoops; ++i )
551 QgsGeometry* clipBaselineBuffer = clippedBaseline->
buffer( currentBufferDist, 8 );
552 if ( !clipBaselineBuffer )
554 delete clipBaselineBuffer;
565 if ( bufferMultiPolygon.size() < 1 )
567 delete clipBaselineBuffer;
571 for (
int j = 0; j < bufferMultiPolygon.size(); ++j )
573 int size = bufferMultiPolygon.at( j ).size();
574 for (
int k = 0; k <
size; ++k )
576 mpl.append( bufferMultiPolygon.at( j ).at( k ) );
584 if ( bufferPolygon.size() < 1 )
586 delete clipBaselineBuffer;
590 int size = bufferPolygon.size();
591 for (
int j = 0; j <
size; ++j )
593 mpl.append( bufferPolygon[j] );
597 bufferLineClipped = bufferLine->
intersection( stratumGeom );
599 if ( bufferLineClipped && bufferLineClipped->
type() ==
QGis::Line )
602 bool bufferLineClippedIntersectsStratum =
true;
606 QVector<QgsPolygon>::const_iterator multiIt = multiPoly.constBegin();
607 for ( ; multiIt != multiPoly.constEnd(); ++multiIt )
612 bufferLineClippedIntersectsStratum =
false;
620 if ( bufferLineClippedIntersectsStratum )
622 return bufferLineClipped;
626 delete bufferLineClipped;
delete clipBaselineBuffer;
delete bufferLine;
627 currentBufferDist /= 2;