void QgsMapToolCircularStringRadius::recalculateTempRubberBand( const QgsPointXY &mousePosition )
{
  QgsPointSequence rubberBandPoints;
  if ( !( mPoints.size() % 2 ) )
  {
    //recalculate midpoint on circle segment
    QgsPoint midPoint;
    if ( !QgsGeometryUtils::segmentMidPoint( mPoints.at( mPoints.size() - 2 ), mTemporaryEndPoint, midPoint, mRadius,
         QgsPoint( mousePosition ) ) )
    {
      return;
    }
    mPoints.replace( mPoints.size() - 1, midPoint );
    rubberBandPoints.append( mPoints.at( mPoints.size() - 2 ) );
    rubberBandPoints.append( mPoints.last() );
    rubberBandPoints.append( mTemporaryEndPoint );
  }
  else
  {
    rubberBandPoints.append( mPoints.last() );
    rubberBandPoints.append( mapPoint( mousePosition ) );
  }
  QgsCircularString *cString = new QgsCircularString();
  cString->setPoints( rubberBandPoints );
  delete mTempRubberBand;
  mTempRubberBand = createGeometryRubberBand( mLayerType, true );
  mTempRubberBand->setGeometry( cString );
  mTempRubberBand->show();
}
void QgsMapToolCircularStringCurvePoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
  QgsPointV2 mapPoint( e->mapPoint() );

  if ( e->button() == Qt::LeftButton )
  {
    mPoints.append( mapPoint );
    if ( !mCenterPointRubberBand && mShowCenterPointRubberBand )
    {
      createCenterPointRubberBand();
    }

    if ( !mPoints.isEmpty() )
    {
      if ( !mTempRubberBand )
      {
        mTempRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true );
        mTempRubberBand->show();
      }

      QgsCircularString *c = new QgsCircularString();
      QgsPointSequence rubberBandPoints = mPoints.mid( mPoints.size() - 1 - ( mPoints.size() + 1 ) % 2 );
      rubberBandPoints.append( mapPoint );
      c->setPoints( rubberBandPoints );
      mTempRubberBand->setGeometry( c );
    }
    if ( mPoints.size() > 1 && mPoints.size() % 2 )
    {
      if ( !mRubberBand )
      {
        mRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
        mRubberBand->show();
      }

      QgsCircularString *c = new QgsCircularString();
      QgsPointSequence rubberBandPoints = mPoints;
      rubberBandPoints.append( mapPoint );
      c->setPoints( rubberBandPoints );
      mRubberBand->setGeometry( c );
      removeCenterPointRubberBand();
    }
  }
  else if ( e->button() == Qt::RightButton )
  {
    deactivate();
    if ( mParentTool )
    {
      mParentTool->canvasReleaseEvent( e );
    }
  }
}
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 QgsCompoundCurve *compoundCurve = mParentTool->captureCurve();
      if ( compoundCurve && compoundCurve->nCurves() > 0 )
      {
        const QgsCurve *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 ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true );
            mTempRubberBand->show();
          }
          QgsCircularString *c = new QgsCircularString();
          QgsPointSequence rubberBandPoints = mPoints;
          rubberBandPoints.append( QgsPointV2( mapPoint ) );
          c->setPoints( rubberBandPoints );
          mTempRubberBand->setGeometry( c );
        }
      }
    }
  }
  QgsMapToolCapture::activate();
}
void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPointV2 &pt )
{
  if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 )
  {
    return;
  }

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

  //create circular string
  QgsCircularString *cs = new QgsCircularString();
  QgsPointSequence 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() );

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

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

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

  QgsCurvePolygon *cp = new QgsCurvePolygon();
  cp->setExteriorRing( cc );
  mCenterPointRubberBand->setGeometry( cp );
  mCenterPointRubberBand->show();
}
示例#5
0
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, const QgsFeatureIds& targetFeatureIds, QgsFeatureId* modifiedFeatureId )
{
  QgsLineString* ringLine = new QgsLineString();
  QgsPointSequence ringPoints;
  QList<QgsPoint>::const_iterator ringIt = ring.constBegin();
  for ( ; ringIt != ring.constEnd(); ++ringIt )
  {
    ringPoints.append( QgsPointV2( ringIt->x(), ringIt->y() ) );
  }
  ringLine->setPoints( ringPoints );
  return addRing( ringLine, targetFeatureIds,  modifiedFeatureId );
}
示例#6
0
void QgsCompoundCurve::points( QgsPointSequence &pts ) const
{
  pts.clear();
  if ( mCurves.empty() )
  {
    return;
  }

  mCurves[0]->points( pts );
  for ( int i = 1; i < mCurves.size(); ++i )
  {
    QgsPointSequence pList;
    mCurves[i]->points( pList );
    pList.removeFirst(); //first vertex already added in previous line
    pts.append( pList );
  }
}
示例#7
0
文件: qgscircle.cpp 项目: ndavid/QGIS
QgsCircularString *QgsCircle::toCircularString( bool oriented ) const
{
  std::unique_ptr<QgsCircularString> circString( new QgsCircularString() );
  QgsPointSequence points;
  QVector<QgsPoint> quad;
  if ( oriented )
  {
    quad = quadrant();
  }
  else
  {
    quad = northQuadrant();
  }
  quad.append( quad.at( 0 ) );
  for ( QVector<QgsPoint>::const_iterator it = quad.constBegin(); it != quad.constEnd(); ++it )
  {
    points.append( *it );
  }
  circString->setPoints( points );

  return circString.release();
}
示例#8
0
void QgsCircularString::segmentize( const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &p3, QgsPointSequence &points, double tolerance, SegmentationToleranceType toleranceType ) const
{
  bool clockwise = false;
  int segSide = segmentSide( p1, p3, p2 );
  if ( segSide == -1 )
  {
    clockwise = true;
  }

  QgsPointV2 circlePoint1 = clockwise ? p3 : p1;
  QgsPointV2 circlePoint2 = p2;
  QgsPointV2 circlePoint3 = clockwise ? p1 : p3 ;

  //adapted code from postgis
  double radius = 0;
  double centerX = 0;
  double centerY = 0;
  QgsGeometryUtils::circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );


  if ( circlePoint1 != circlePoint3 && ( radius < 0 || qgsDoubleNear( segSide, 0.0 ) ) ) //points are colinear
  {
    points.append( p1 );
    points.append( p2 );
    points.append( p3 );
    return;
  }

  double increment = tolerance; //one segment per degree
  if ( toleranceType == QgsAbstractGeometry::MaximumDifference )
  {
    double halfAngle = acos( -tolerance / radius + 1 );
    increment = 2 * halfAngle;
  }

  //angles of pt1, pt2, pt3
  double a1 = atan2( circlePoint1.y() - centerY, circlePoint1.x() - centerX );
  double a2 = atan2( circlePoint2.y() - centerY, circlePoint2.x() - centerX );
  double a3 = atan2( circlePoint3.y() - centerY, circlePoint3.x() - centerX );

  /* Adjust a3 up so we can increment from a1 to a3 cleanly */
  if ( a3 <= a1 )
    a3 += 2.0 * M_PI;
  if ( a2 < a1 )
    a2 += 2.0 * M_PI;

  bool hasZ = is3D();
  bool hasM = isMeasure();

  double x, y;
  double z = 0;
  double m = 0;

  QList<QgsPointV2> stringPoints;
  stringPoints.insert( clockwise ? 0 : stringPoints.size(), circlePoint1 );
  if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) //draw straight line segment if two points have the same position
  {
    QgsWkbTypes::Type pointWkbType = QgsWkbTypes::Point;
    if ( hasZ )
      pointWkbType = QgsWkbTypes::addZ( pointWkbType );
    if ( hasM )
      pointWkbType = QgsWkbTypes::addM( pointWkbType );

    //make sure the curve point p2 is part of the segmentized vertices. But only if p1 != p3
    bool addP2 = true;
    if ( qgsDoubleNear( circlePoint1.x(), circlePoint3.x() ) && qgsDoubleNear( circlePoint1.y(), circlePoint3.y() ) )
    {
      addP2 = false;
    }

    for ( double angle = a1 + increment; angle < a3; angle += increment )
    {
      if ( ( addP2 && angle > a2 ) )
      {
        stringPoints.insert( clockwise ? 0 : stringPoints.size(), circlePoint2 );
        addP2 = false;
      }

      x = centerX + radius * cos( angle );
      y = centerY + radius * sin( angle );

      if ( !hasZ && !hasM )
      {
        stringPoints.insert( clockwise ? 0 : stringPoints.size(), QgsPointV2( x, y ) );
        continue;
      }

      if ( hasZ )
      {
        z = interpolateArc( angle, a1, a2, a3, circlePoint1.z(), circlePoint2.z(), circlePoint3.z() );
      }
      if ( hasM )
      {
        m = interpolateArc( angle, a1, a2, a3, circlePoint1.m(), circlePoint2.m(), circlePoint3.m() );
      }

      stringPoints.insert( clockwise ? 0 : stringPoints.size(), QgsPointV2( pointWkbType, x, y, z, m ) );
    }
  }
  stringPoints.insert( clockwise ? 0 : stringPoints.size(), circlePoint3 );
  points.append( stringPoints );
}
示例#9
0
QgsPointSequence QgsCircularString::compassPointsOnSegment( double p1Angle, double p2Angle, double p3Angle, double centerX, double centerY, double radius )
{
  QgsPointSequence pointList;

  QgsPointV2 nPoint( centerX, centerY + radius );
  QgsPointV2 ePoint( centerX + radius, centerY );
  QgsPointV2 sPoint( centerX, centerY - radius );
  QgsPointV2 wPoint( centerX - radius, centerY );

  if ( p3Angle >= p1Angle )
  {
    if ( p2Angle > p1Angle && p2Angle < p3Angle )
    {
      if ( p1Angle <= 90 && p3Angle >= 90 )
      {
        pointList.append( nPoint );
      }
      if ( p1Angle <= 180 && p3Angle >= 180 )
      {
        pointList.append( wPoint );
      }
      if ( p1Angle <= 270 && p3Angle >= 270 )
      {
        pointList.append( sPoint );
      }
    }
    else
    {
      pointList.append( ePoint );
      if ( p1Angle >= 90 || p3Angle <= 90 )
      {
        pointList.append( nPoint );
      }
      if ( p1Angle >= 180 || p3Angle <= 180 )
      {
        pointList.append( wPoint );
      }
      if ( p1Angle >= 270 || p3Angle <= 270 )
      {
        pointList.append( sPoint );
      }
    }
  }
  else
  {
    if ( p2Angle < p1Angle && p2Angle > p3Angle )
    {
      if ( p1Angle >= 270 && p3Angle <= 270 )
      {
        pointList.append( sPoint );
      }
      if ( p1Angle >= 180 && p3Angle <= 180 )
      {
        pointList.append( wPoint );
      }
      if ( p1Angle >= 90 && p3Angle <= 90 )
      {
        pointList.append( nPoint );
      }
    }
    else
    {
      pointList.append( ePoint );
      if ( p1Angle <= 270 || p3Angle >= 270 )
      {
        pointList.append( sPoint );
      }
      if ( p1Angle <= 180 || p3Angle >= 180 )
      {
        pointList.append( wPoint );
      }
      if ( p1Angle <= 90 || p3Angle >= 90 )
      {
        pointList.append( nPoint );
      }
    }
  }
  return pointList;
}