Пример #1
0
bool QgsCircularString::insertVertex( QgsVertexId position, const QgsPointV2 &vertex )
{
  if ( position.vertex > mX.size() || position.vertex < 1 )
  {
    return false;
  }

  mX.insert( position.vertex, vertex.x() );
  mY.insert( position.vertex, vertex.y() );
  if ( is3D() )
  {
    mZ.insert( position.vertex, vertex.z() );
  }
  if ( isMeasure() )
  {
    mM.insert( position.vertex, vertex.m() );
  }

  bool vertexNrEven = ( position.vertex % 2 == 0 );
  if ( vertexNrEven )
  {
    insertVertexBetween( position.vertex - 2, position.vertex - 1, position.vertex );
  }
  else
  {
    insertVertexBetween( position.vertex, position.vertex + 1, position.vertex - 1 );
  }
  clearCache(); //set bounding box invalid
  return true;
}
Пример #2
0
void QgsMapToolAddCircularString::activate()
{
  if ( mParentTool )
  {
    mParentTool->deleteTempRubberBand();
    if ( mPoints.isEmpty() )
    {
      // if the parent tool has a curve, use its last point as the first point in this curve
      const QgsCompoundCurveV2* compoundCurve = mParentTool->captureCurve();
      if ( compoundCurve && compoundCurve->nCurves() > 0 )
      {
        const QgsCurveV2* curve = compoundCurve->curveAt( compoundCurve->nCurves() - 1 );
        if ( curve )
        {
          //mParentTool->captureCurve() is in layer coordinates, but we need map coordinates
          QgsPointV2 endPointLayerCoord = curve->endPoint();
          QgsPoint mapPoint = toMapCoordinates( mCanvas->currentLayer(), QgsPoint( endPointLayerCoord.x(), endPointLayerCoord.y() ) );
          mPoints.append( QgsPointV2( mapPoint ) );
          if ( !mTempRubberBand )
          {
            mTempRubberBand = createGeometryRubberBand(( mode() == CapturePolygon ) ? Qgis::Polygon : Qgis::Line, true );
            mTempRubberBand->show();
          }
          QgsCircularStringV2* c = new QgsCircularStringV2();
          QgsPointSequenceV2 rubberBandPoints = mPoints;
          rubberBandPoints.append( QgsPointV2( mapPoint ) );
          c->setPoints( rubberBandPoints );
          mTempRubberBand->setGeometry( c );
        }
      }
    }
  }
  QgsMapToolCapture::activate();
}
Пример #3
0
void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometry& geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString >& derivedAttributes )
{
  QString str = QLocale::system().toString( vId.vertex + 1 );
  derivedAttributes.insert( tr( "Closest vertex number" ), str );

  QgsPointV2 closestPoint = geometry.vertexAt( vId );

  QgsPoint closestPointMapCoords = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( closestPoint.x(), closestPoint.y() ) );
  derivedAttributes.insert( "Closest vertex X", formatXCoordinate( closestPointMapCoords ) );
  derivedAttributes.insert( "Closest vertex Y", formatYCoordinate( closestPointMapCoords ) );

  if ( closestPoint.is3D() )
  {
    str = QLocale::system().toString( closestPoint.z(), 'g', 10 );
    derivedAttributes.insert( "Closest vertex Z", str );
  }
  if ( closestPoint.isMeasure() )
  {
    str = QLocale::system().toString( closestPoint.m(), 'g', 10 );
    derivedAttributes.insert( "Closest vertex M", str );
  }

  if ( vId.type == QgsVertexId::CurveVertex )
  {
    double radius, centerX, centerY;
    QgsVertexId vIdBefore = vId;
    --vIdBefore.vertex;
    QgsVertexId vIdAfter = vId;
    ++vIdAfter.vertex;
    QgsGeometryUtils::circleCenterRadius( geometry.vertexAt( vIdBefore ), geometry.vertexAt( vId ),
                                          geometry.vertexAt( vIdAfter ), radius, centerX, centerY );
    derivedAttributes.insert( "Closest vertex radius", QLocale::system().toString( radius ) );
  }
}
Пример #4
0
void QgsCircularString::insertVertexBetween( int after, int before, int pointOnCircle )
{
  double xAfter = mX.at( after );
  double yAfter = mY.at( after );
  double xBefore = mX.at( before );
  double yBefore = mY.at( before );
  double xOnCircle = mX.at( pointOnCircle );
  double yOnCircle = mY.at( pointOnCircle );

  double radius, centerX, centerY;
  QgsGeometryUtils::circleCenterRadius( QgsPointV2( xAfter, yAfter ), QgsPointV2( xBefore, yBefore ), QgsPointV2( xOnCircle, yOnCircle ), radius, centerX, centerY );

  double x = ( xAfter + xBefore ) / 2.0;
  double y = ( yAfter + yBefore ) / 2.0;

  QgsPointV2 newVertex = QgsGeometryUtils::pointOnLineWithDistance( QgsPointV2( centerX, centerY ), QgsPointV2( x, y ), radius );
  mX.insert( before, newVertex.x() );
  mY.insert( before, newVertex.y() );

  if ( is3D() )
  {
    mZ.insert( before, ( mZ[after] + mZ[before] ) / 2.0 );
  }
  if ( isMeasure() )
  {
    mM.insert( before, ( mM[after] + mM[before] ) / 2.0 );
  }
  clearCache();
}
Пример #5
0
void QgsMapToolCapture::canvasMapMoveEvent( QgsMapMouseEvent * e )
{
  bool snapped = e->isSnapped();
  QgsPoint point = e->mapPoint();

  if ( !snapped )
  {
    delete mSnappingMarker;
    mSnappingMarker = 0;
  }
  else
  {
    if ( !mSnappingMarker )
    {
      mSnappingMarker = new QgsVertexMarker( mCanvas );
      mSnappingMarker->setIconType( QgsVertexMarker::ICON_CROSS );
      mSnappingMarker->setColor( Qt::magenta );
      mSnappingMarker->setPenWidth( 3 );
    }
    mSnappingMarker->setCenter( point );
  }

  if ( !mTempRubberBand && mCaptureCurve.numPoints() > 0 )
  {
    mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true );
    QgsPointV2 pt = mCaptureCurve.endPoint();
    mTempRubberBand->addPoint( QgsPoint( pt.x(), pt.y() ) );
    mTempRubberBand->addPoint( point );
  }

  if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
  {
    mTempRubberBand->movePoint( point );
  }
} // mouseMoveEvent
Пример #6
0
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex )
{
  if ( position.vertex < 0 || position.vertex > mX.size() )
  {
    return false;
  }

  if ( mWkbType == QgsWKBTypes::Unknown || mX.isEmpty() )
  {
    setZMTypeFromSubGeometry( &vertex, QgsWKBTypes::LineString );
  }

  mX.insert( position.vertex, vertex.x() );
  mY.insert( position.vertex, vertex.y() );
  if ( is3D() )
  {
    mZ.insert( position.vertex, vertex.z() );
  }
  if ( isMeasure() )
  {
    mM.insert( position.vertex, vertex.m() );
  }
  mBoundingBox = QgsRectangle(); //set bounding box invalid
  return true;
}
Пример #7
0
QgsRectangle QgsAbstractGeometry::calculateBoundingBox() const
{
  double xmin = std::numeric_limits<double>::max();
  double ymin = std::numeric_limits<double>::max();
  double xmax = -std::numeric_limits<double>::max();
  double ymax = -std::numeric_limits<double>::max();

  QgsVertexId id;
  QgsPointV2 vertex;
  double x, y;
  while ( nextVertex( id, vertex ) )
  {
    x = vertex.x();
    y = vertex.y();
    if ( x < xmin )
      xmin = x;
    if ( x > xmax )
      xmax = x;
    if ( y < ymin )
      ymin = y;
    if ( y > ymax )
      ymax = y;
  }

  return QgsRectangle( xmin, ymin, xmax, ymax );
}
Пример #8
0
double QgsLineStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt,  QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
  double sqrDist = std::numeric_limits<double>::max();
  double testDist = 0;
  double segmentPtX, segmentPtY;

  int size = mCoords.size();
  for ( int i = 1; i < size; ++i )
  {
    const QPointF& prev = mCoords.at( i - 1 );
    const QPointF& currentPt = mCoords.at( i );
    testDist = QgsGeometryUtils::sqrDistToLine( pt.x(), pt.y(), prev.x(), prev.y(), currentPt.x(), currentPt.y(), segmentPtX, segmentPtY, epsilon );
    if ( testDist < sqrDist )
    {
      sqrDist = testDist;
      segmentPt.setX( segmentPtX );
      segmentPt.setY( segmentPtY );
      if ( leftOf )
      {
        *leftOf = ( QgsGeometryUtils::leftOfLine( segmentPtX, segmentPtY, prev.x(), prev.y(), pt.x(), pt.y() ) < 0 );
      }
      vertexAfter.part = 0; vertexAfter.ring = 0; vertexAfter.vertex = i;
    }
  }
  return sqrDist;
}
Пример #9
0
void QgsSelectedFeature::moveSelectedVertexes( QgsVector v )
{
  int nUpdates = 0;
  Q_FOREACH ( QgsVertexEntry *entry, mVertexMap )
  {
    if ( entry->isSelected() )
      nUpdates++;
  }

  if ( nUpdates == 0 )
    return;

  mVlayer->beginEditCommand( QObject::tr( "Moved vertices" ) );
  int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );

  beginGeometryChange();

  QMultiMap<double, QgsSnappingResult> currentResultList;
  for ( int i = mVertexMap.size() - 1; i > -1 && nUpdates > 0; i-- )
  {
    QgsVertexEntry *entry = mVertexMap.value( i, nullptr );
    if ( !entry || !entry->isSelected() )
      continue;

    if ( topologicalEditing )
    {
      // snap from current vertex
      currentResultList.clear();
      mVlayer->snapWithContext( entry->pointV1(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
    }

    // only last update should trigger the geometry update
    // as vertex selection gets lost on the update
    if ( --nUpdates == 0 )
      endGeometryChange();

    QgsPointV2 p = entry->point();
    p.setX( p.x() + v.x() );
    p.setY( p.y() + v.y() );
    mVlayer->moveVertex( p, mFeatureId, i );

    if ( topologicalEditing )
    {
      QMultiMap<double, QgsSnappingResult>::iterator resultIt =  currentResultList.begin();

      for ( ; resultIt != currentResultList.end(); ++resultIt )
      {
        // move all other
        if ( mFeatureId !=  resultIt.value().snappedAtGeometry )
          mVlayer->moveVertex( p, resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
      }
    }
  }

  if ( nUpdates > 0 )
    endGeometryChange();

  mVlayer->endEditCommand();
}
Пример #10
0
bool QgsSnapIndex::SegmentSnapItem::getProjection( const QgsPointV2 &p, QgsPointV2 &pProj )
{
    const QgsPointV2& s1 = idxFrom->point();
    const QgsPointV2& s2 = idxTo->point();
    double nx = s2.y() - s1.y();
    double ny = -( s2.x() - s1.x() );
    double t = ( p.x() * ny - p.y() * nx - s1.x() * ny + s1.y() * nx ) / (( s2.x() - s1.x() ) * ny - ( s2.y() - s1.y() ) * nx );
    if ( t < 0. || t > 1. )
    {
        return false;
    }
    pProj = QgsPointV2( s1.x() + ( s2.x() - s1.x() ) * t, s1.y() + ( s2.y() - s1.y() ) * t );
    return true;
}
Пример #11
0
void QgsLineStringV2::addVertex( const QgsPointV2& pt )
{
  if ( mWkbType == QgsWKBTypes::Unknown )
  {
    setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString );
  }

  mCoords.append( QPointF( pt.x(), pt.y() ) );
  if ( is3D() )
  {
    mZ.append( pt.z() );
  }
  if ( isMeasure() )
  {
    mM.append( pt.m() );
  }
}
Пример #12
0
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex )
{
  if ( position.vertex < 0 || position.vertex > mCoords.size() )
  {
    return false;
  }
  mCoords.insert( position.vertex, QPointF( vertex.x(), vertex.y() ) );
  if ( is3D() )
  {
    mZ.insert( position.vertex, vertex.z() );
  }
  if ( isMeasure() )
  {
    mM.insert( position.vertex, vertex.m() );
  }
  return true;
}
Пример #13
0
bool QgsNodeEditorModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
  if ( !index.isValid() || role != Qt::EditRole )
  {
    return false;
  }
  if ( index.row() >= mSelectedFeature->vertexMap().count() )
  {
    return false;
  }

  double x = ( index.column() == 0 ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().x() );
  double y = ( index.column() == 1 ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().y() );

  if ( index.column() == mRCol ) // radius modified
  {
    if ( index.row() == 0 || index.row() >= mSelectedFeature->vertexMap().count() - 1 )
      return false;

    double r = value.toDouble();
    double x1 = mSelectedFeature->vertexMap().at( index.row() - 1 )->point().x();
    double y1 = mSelectedFeature->vertexMap().at( index.row() - 1 )->point().y();
    double x2 = x;
    double y2 = y;
    double x3 = mSelectedFeature->vertexMap().at( index.row() + 1 )->point().x();
    double y3 = mSelectedFeature->vertexMap().at( index.row() + 1 )->point().y();

    QgsPointV2 result;
    if ( QgsGeometryUtils::segmentMidPoint( QgsPointV2( x1, y1 ), QgsPointV2( x3, y3 ), result, r, QgsPointV2( x2, y2 ) ) )
    {
      x = result.x();
      y = result.y();
    }
  }
  double z = ( index.column() == mZCol ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().z() );
  double m = ( index.column() == mMCol ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().m() );
  QgsPointV2 p( QgsWkbTypes::PointZM, x, y, z, m );

  mLayer->beginEditCommand( QObject::tr( "Moved vertices" ) );
  mLayer->moveVertex( p, mSelectedFeature->featureId(), index.row() );
  mLayer->endEditCommand();
  mLayer->triggerRepaint();

  return false;
}
Пример #14
0
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex )
{
  if ( position.vertex < 0 || position.vertex >= mCoords.size() )
  {
    return false;
  }
  mCoords.insert( position.vertex, QPointF( vertex.x(), vertex.y() ) );
  if ( is3D() )
  {
    mZ.insert( position.vertex, vertex.z() );
  }
  if ( isMeasure() )
  {
    mM.insert( position.vertex, vertex.m() );
  }
  mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time
  return true;
}
Пример #15
0
void QgsLineStringV2::addVertex( const QgsPointV2& pt )
{
  if ( mWkbType == QgsWKBTypes::Unknown )
  {
    setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString );
  }

  mCoords.append( QPointF( pt.x(), pt.y() ) );
  if ( is3D() )
  {
    mZ.append( pt.z() );
  }
  if ( isMeasure() )
  {
    mM.append( pt.m() );
  }
  mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time
}
Пример #16
0
int QgsMapToolCapture::addCurve( QgsCurveV2* c )
{
  if ( !c )
  {
    return 1;
  }

  if ( !mRubberBand )
  {
    mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
  }

  QgsLineStringV2* lineString = c->curveToLine();
  QList<QgsPointV2> linePoints;
  lineString->points( linePoints );
  delete lineString;
  QList<QgsPointV2>::const_iterator ptIt = linePoints.constBegin();
  for ( ; ptIt != linePoints.constEnd(); ++ptIt )
  {
    mRubberBand->addPoint( QgsPoint( ptIt->x(), ptIt->y() ) );
  }

  if ( !mTempRubberBand )
  {
    mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true );
  }
  else
  {
    mTempRubberBand->reset();
  }
  QgsPointV2 endPt = c->endPoint();
  mTempRubberBand->addPoint( QgsPoint( endPt.x(), endPt.y() ) ); //add last point of c

  //transform back to layer CRS in case map CRS and layer CRS are different
  QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
  const QgsCoordinateTransform* ct =  mCanvas->mapSettings().layerTransform( vlayer );
  if ( ct )
  {
    c->transform( *ct, QgsCoordinateTransform::ReverseTransform );
  }
  mCaptureCurve.addCurve( c );

  return 0;
}
Пример #17
0
bool QgsCurve::isClosed() const
{
  if ( numPoints() == 0 )
    return false;

  //don't consider M-coordinates when testing closedness
  QgsPointV2 start = startPoint();
  QgsPointV2 end = endPoint();
  return ( qgsDoubleNear( start.x(), end.x(), 1E-8 ) &&
           qgsDoubleNear( start.y(), end.y(), 1E-8 ) &&
           qgsDoubleNear( start.z(), end.z(), 1E-8 ) );
}
Пример #18
0
void QgsLineStringV2::addVertex( const QgsPointV2& pt )
{
  if ( mWkbType == QgsWKBTypes::Unknown || mX.isEmpty() )
  {
    setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString );
  }

  mX.append( pt.x() );
  mY.append( pt.y() );
  if ( is3D() )
  {
    mZ.append( pt.z() );
  }
  if ( isMeasure() )
  {
    mM.append( pt.m() );
  }
  mBoundingBox = QgsRectangle(); //set bounding box invalid
}
Пример #19
0
void TestQgsGeometryUtils::testSegmentMidPoint()
{
    QFETCH( double, pt1x );
    QFETCH( double, pt1y );
    QFETCH( double, pt2x );
    QFETCH( double, pt2y );
    QFETCH( double, radius );
    QFETCH( bool, left );
    QFETCH( double, expectedX );
    QFETCH( double, expectedY );

    QgsPointV2 midPoint;
    bool ok = QgsGeometryUtils::segmentMidPoint( QgsPointV2( pt1x, pt1y ), QgsPointV2( pt2x, pt2y ),
              midPoint, radius, left );

    QVERIFY( ok );
    QVERIFY( qgsDoubleNear( midPoint.x(), expectedX ) );
    QVERIFY( qgsDoubleNear( midPoint.y(), expectedY ) );
}
Пример #20
0
double QgsGeometryUtils::circleTangentDirection( const QgsPointV2& tangentPoint, const QgsPointV2& cp1,
    const QgsPointV2& cp2, const QgsPointV2& cp3 )
{
  //calculate circle midpoint
  double mX, mY, radius;
  circleCenterRadius( cp1, cp2, cp3, radius, mX, mY );

  double p1Angle = QgsGeometryUtils::ccwAngle( cp1.y() - mY, cp1.x() - mX );
  double p2Angle = QgsGeometryUtils::ccwAngle( cp2.y() - mY, cp2.x() - mX );
  double p3Angle = QgsGeometryUtils::ccwAngle( cp3.y() - mY, cp3.x() - mX );
  if ( circleClockwise( p1Angle, p2Angle, p3Angle ) )
  {
    return lineAngle( tangentPoint.x(), tangentPoint.y(), mX, mY );
  }
  else
  {
    return lineAngle( mX, mY, tangentPoint.x(), tangentPoint.y() );
  }
}
Пример #21
0
double QgsLineString::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt,  QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
  double sqrDist = std::numeric_limits<double>::max();
  double testDist = 0;
  double segmentPtX, segmentPtY;

  int size = mX.size();
  if ( size == 0 || size == 1 )
  {
    vertexAfter = QgsVertexId( 0, 0, 0 );
    return -1;
  }
  for ( int i = 1; i < size; ++i )
  {
    double prevX = mX.at( i - 1 );
    double prevY = mY.at( i - 1 );
    double currentX = mX.at( i );
    double currentY = mY.at( i );
    testDist = QgsGeometryUtils::sqrDistToLine( pt.x(), pt.y(), prevX, prevY, currentX, currentY, segmentPtX, segmentPtY, epsilon );
    if ( testDist < sqrDist )
    {
      sqrDist = testDist;
      segmentPt.setX( segmentPtX );
      segmentPt.setY( segmentPtY );
      if ( leftOf )
      {
        *leftOf = ( QgsGeometryUtils::leftOfLine( pt.x(), pt.y(), prevX, prevY, currentX, currentY ) < 0 );
      }
      vertexAfter.part = 0;
      vertexAfter.ring = 0;
      vertexAfter.vertex = i;
    }
  }
  return sqrDist;
}
Пример #22
0
/**
 * Calculate the area of a triangle in 3d space
 */
static double triarea3d( const QgsPointV2 &P1, const QgsPointV2 &P2, const QgsPointV2 &P3 )
{
    //LWDEBUG( 2, "Entered  triarea3d" );
    double ax, bx, ay, by, az, bz, cx, cy, cz, area;

    ax = P1.x() - P2.x();
    bx = P3.x() - P2.x();
    ay = P1.y() - P2.y();
    by = P3.y() - P2.y();
    az = P1.z() - P2.z();
    bz = P3.z() - P2.z();

    cx = ay * bz - az * by;
    cy = az * bx - ax * bz;
    cz = ax * by - ay * bx;

    area = qAbs( 0.5 * ( sqrt( cx * cx + cy * cy + cz * cz ) ) );
    return area;
}
void QgsGeometrySegmentLengthCheck::collectErrors( QList<QgsGeometryCheckError*>& errors, QStringList &/*messages*/, QAtomicInt* progressCounter , const QgsFeatureIds &ids ) const
{
  const QgsFeatureIds& featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids;
  Q_FOREACH ( QgsFeatureId featureid, featureIds )
  {
    if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
    QgsFeature feature;
    if ( !mFeaturePool->get( featureid, feature ) )
    {
      continue;
    }
    QgsGeometry featureGeom = feature.geometry();
    QgsAbstractGeometry* geom = featureGeom.geometry();

    for ( int iPart = 0, nParts = geom->partCount(); iPart < nParts; ++iPart )
    {
      for ( int iRing = 0, nRings = geom->ringCount( iPart ); iRing < nRings; ++iRing )
      {
        int nVerts = QgsGeometryCheckerUtils::polyLineSize( geom, iPart, iRing );
        if ( nVerts < 2 )
        {
          continue;
        }
        for ( int iVert = 0, jVert = nVerts - 1; iVert < nVerts; jVert = iVert++ )
        {
          QgsPointV2 pi = geom->vertexAt( QgsVertexId( iPart, iRing, iVert ) );
          QgsPointV2 pj = geom->vertexAt( QgsVertexId( iPart, iRing, jVert ) );
          double dist = qSqrt( QgsGeometryUtils::sqrDistance2D( pi, pj ) );
          if ( dist < mMinLength )
          {
            errors.append( new QgsGeometryCheckError( this, featureid, QgsPointV2( 0.5 * ( pi.x() + pj.x() ), 0.5 * ( pi.y() + pj.y() ) ), QgsVertexId( iPart, iRing, iVert ), dist, QgsGeometryCheckError::ValueLength ) );
          }
        }
      }
    }
  }
}
Пример #24
0
void QgsGeometryRubberBand::paint( QPainter* painter )
{
  if ( !mGeometry || !painter )
  {
    return;
  }

  painter->save();
  painter->translate( -pos() );

  if ( mGeometryType == QGis::Polygon )
  {
    painter->setBrush( mBrush );
  }
  else
  {
    painter->setBrush( Qt::NoBrush );
  }
  painter->setPen( mPen );


  QgsAbstractGeometryV2* paintGeom = mGeometry->clone();

  paintGeom->transform( mMapCanvas->getCoordinateTransform()->transform() );
  paintGeom->draw( *painter );

  //draw vertices
  QgsVertexId vertexId;
  QgsPointV2 vertex;
  while ( paintGeom->nextVertex( vertexId, vertex ) )
  {
    drawVertex( painter, vertex.x(), vertex.y() );
  }

  delete paintGeom;
  painter->restore();
}
Пример #25
0
void QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometryV2& geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString >& derivedAttributes )
{
  QString str = QLocale::system().toString( vId.vertex + 1 );
  derivedAttributes.insert( tr( "Closest vertex number" ), str );

  QgsPointV2 closestPoint = geometry.vertexAt( vId );

  QgsPoint closestPointMapCoords = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( closestPoint.x(), closestPoint.y() ) );
  str = QLocale::system().toString( closestPointMapCoords.x(), 'g', 10 );
  derivedAttributes.insert( "Closest vertex X", str );
  str = QLocale::system().toString( closestPointMapCoords.y(), 'g', 10 );
  derivedAttributes.insert( "Closest vertex Y", str );

  if ( closestPoint.is3D() )
  {
    str = QLocale::system().toString( closestPoint.z(), 'g', 10 );
    derivedAttributes.insert( "Closest vertex Z", str );
  }
  if ( closestPoint.isMeasure() )
  {
    str = QLocale::system().toString( closestPoint.m(), 'g', 10 );
    derivedAttributes.insert( "Closest vertex M", str );
  }
}
Пример #26
0
QgsPointV2 QgsGeometryUtils::pointOnLineWithDistance( const QgsPointV2& startPoint, const QgsPointV2& directionPoint, double distance )
{
  double dx = directionPoint.x() - startPoint.x();
  double dy = directionPoint.y() - startPoint.y();
  double length = sqrt( dx * dx + dy * dy );

  if ( qgsDoubleNear( length, 0.0 ) )
  {
    return startPoint;
  }

  double scaleFactor = distance / length;
  return QgsPointV2( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
}
Пример #27
0
void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPointV2& pt )
{
  if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 )
  {
    return;
  }

  if (( mPoints.size() ) % 2 != 0 )
  {
    return;
  }

  //create circular string
  QgsCircularStringV2* cs = new QgsCircularStringV2();
  QgsPointSequenceV2 csPoints;
  csPoints.append( mPoints.at( mPoints.size() - 2 ) );
  csPoints.append( mPoints.at( mPoints.size() - 1 ) );
  csPoints.append( pt );
  cs->setPoints( csPoints );

  QgsPointV2 center;
  double radius;
  QgsGeometryUtils::circleCenterRadius( csPoints.at( 0 ), csPoints.at( 1 ), csPoints.at( 2 ), radius, center.rx(), center.ry() );

  QgsLineStringV2* segment1 = new QgsLineStringV2();
  segment1->addVertex( center );
  segment1->addVertex( csPoints.at( 0 ) );

  QgsLineStringV2* segment2 = new QgsLineStringV2();
  segment2->addVertex( csPoints.at( 2 ) );
  segment2->addVertex( center );

  QgsCompoundCurveV2* cc = new QgsCompoundCurveV2();
  cc->addCurve( segment1 );
  cc->addCurve( cs );
  cc->addCurve( segment2 );

  QgsCurvePolygonV2* cp = new QgsCurvePolygonV2();
  cp->setExteriorRing( cc );
  mCenterPointRubberBand->setGeometry( cp );
  mCenterPointRubberBand->show();
}
Пример #28
0
bool QgsGeometryUtils::lineIntersection( const QgsPointV2& p1, const QgsVector& v, const QgsPointV2& q1, const QgsVector& w, QgsPointV2& inter )
{
  double d = v.y() * w.x() - v.x() * w.y();

  if ( d == 0 )
    return false;

  double dx = q1.x() - p1.x();
  double dy = q1.y() - p1.y();
  double k = ( dy * w.x() - dx * w.y() ) / d;

  inter = QgsPointV2( p1.x() + v.x() * k, p1.y() + v.y() * k );

  return true;
}
Пример #29
0
double QgsCircularString::closestPointOnArc( double x1, double y1, double x2, double y2, double x3, double y3,
    const QgsPointV2 &pt, QgsPointV2 &segmentPt,  QgsVertexId &vertexAfter, bool *leftOf, double epsilon )
{
  double radius, centerX, centerY;
  QgsPointV2 pt1( x1, y1 );
  QgsPointV2 pt2( x2, y2 );
  QgsPointV2 pt3( x3, y3 );

  QgsGeometryUtils::circleCenterRadius( pt1, pt2, pt3, radius, centerX, centerY );
  double angle = QgsGeometryUtils::ccwAngle( pt.y() - centerY, pt.x() - centerX );
  double angle1 = QgsGeometryUtils::ccwAngle( pt1.y() - centerY, pt1.x() - centerX );
  double angle2 = QgsGeometryUtils::ccwAngle( pt2.y() - centerY, pt2.x() - centerX );
  double angle3 = QgsGeometryUtils::ccwAngle( pt3.y() - centerY, pt3.x() - centerX );

  bool clockwise = QgsGeometryUtils::circleClockwise( angle1, angle2, angle3 );

  if ( QgsGeometryUtils::angleOnCircle( angle, angle1, angle2, angle3 ) )
  {
    //get point on line center -> pt with distance radius
    segmentPt = QgsGeometryUtils::pointOnLineWithDistance( QgsPointV2( centerX, centerY ), pt, radius );

    //vertexAfter
    vertexAfter.vertex = QgsGeometryUtils::circleAngleBetween( angle, angle1, angle2, clockwise ) ? 1 : 2;
  }
  else
  {
    double distPtPt1 = QgsGeometryUtils::sqrDistance2D( pt, pt1 );
    double distPtPt3 = QgsGeometryUtils::sqrDistance2D( pt, pt3 );
    segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3;
    vertexAfter.vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2;
  }

  double sqrDistance = QgsGeometryUtils::sqrDistance2D( segmentPt, pt );
  //prevent rounding errors if the point is directly on the segment
  if ( qgsDoubleNear( sqrDistance, 0.0, epsilon ) )
  {
    segmentPt.setX( pt.x() );
    segmentPt.setY( pt.y() );
    sqrDistance = 0.0;
  }

  if ( leftOf )
  {
    *leftOf = clockwise ? sqrDistance > radius : sqrDistance < radius;
  }

  return sqrDistance;
}
Пример #30
0
QgsTriangle::QgsTriangle( const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &p3 )
{
  mWkbType = QgsWkbTypes::Triangle;

  if ( !validateGeom( p1, p2, p3 ) )
  {
    return;
  }
  QVector< double > x;
  x << p1.x() << p2.x() << p3.x();
  QVector< double > y;
  y << p1.y() << p2.y() << p3.y();
  QgsLineString *ext = new QgsLineString( x, y );
  setExteriorRing( ext );

}