Example #1
0
static QgsPointLocator::Match _findClosestSegmentIntersection( const QgsPoint& pt, const QgsPointLocator::MatchList& segments )
{
  if ( segments.isEmpty() )
    return QgsPointLocator::Match();

  QSet<QgsPoint> endpoints;

  // make a geometry
  QList<QgsGeometry*> geoms;
  Q_FOREACH ( const QgsPointLocator::Match& m, segments )
  {
    if ( m.hasEdge() )
    {
      QgsPolyline pl( 2 );
      m.edgePoints( pl[0], pl[1] );
      geoms << QgsGeometry::fromPolyline( pl );
      endpoints << pl[0] << pl[1];
    }
  }

  QgsGeometry* g = QgsGeometry::unaryUnion( geoms );
  qDeleteAll( geoms );

  // get intersection points
  QList<QgsPoint> newPoints;
  if ( g->wkbType() == QGis::WKBLineString )
  {
    Q_FOREACH ( const QgsPoint& p, g->asPolyline() )
    {
      if ( !endpoints.contains( p ) )
        newPoints << p;
    }
  }
Example #2
0
static QgsPointLocator::Match _findClosestSegmentIntersection( const QgsPointXY &pt, const QgsPointLocator::MatchList &segments )
{
  if ( segments.isEmpty() )
    return QgsPointLocator::Match();

  QSet<QgsPointXY> endpoints;

  // make a geometry
  QVector<QgsGeometry> geoms;
  Q_FOREACH ( const QgsPointLocator::Match &m, segments )
  {
    if ( m.hasEdge() )
    {
      QgsPolylineXY pl( 2 );
      m.edgePoints( pl[0], pl[1] );
      geoms << QgsGeometry::fromPolylineXY( pl );
      endpoints << pl[0] << pl[1];
    }
  }

  QgsGeometry g = QgsGeometry::unaryUnion( geoms );

  // get intersection points
  QList<QgsPointXY> newPoints;
  if ( g.wkbType() == QgsWkbTypes::LineString )
  {
    Q_FOREACH ( const QgsPointXY &p, g.asPolyline() )
    {
      if ( !endpoints.contains( p ) )
        newPoints << p;
    }
  }
Example #3
0
bool QgsMapToolReshape::isBindingLine( QgsVectorLayer *vlayer, const QgsRectangle &bbox ) const
{
  if ( vlayer->geometryType() != QgsWkbTypes::LineGeometry )
    return false;

  bool begin = false;
  bool end = false;
  const QgsPointXY beginPoint = points().first();
  const QgsPointXY endPoint = points().last();

  QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) );
  QgsFeature f;

  // check that extremities of the new line are contained by features
  while ( fit.nextFeature( f ) )
  {
    const QgsGeometry geom = f.geometry();
    if ( !geom.isNull() )
    {
      const QgsPolylineXY line = geom.asPolyline();

      if ( line.contains( beginPoint ) )
        begin = true;
      else if ( line.contains( endPoint ) )
        end = true;
    }
  }

  return end && begin;
}
bool QgsSimplifyFeature::simplifyLine( QgsFeature& lineFeature,  double tolerance )
{
  QgsGeometry* line = lineFeature.geometry();
  if ( line->type() != QGis::Line )
  {
    return false;
  }

  QVector<QgsPoint> resultPoints = simplifyPoints( line->asPolyline(), tolerance );
  lineFeature.setGeometry( QgsGeometry::fromPolyline( resultPoints ) );
  return true;
}
QVector<QgsPoint> QgsMapToolSimplify::getPointList( QgsFeature& f )
{
  QgsGeometry* line = f.geometry();
  if (( line->type() != QGis::Line && line->type() != QGis::Polygon ) || line->isMultipart() )
  {
    return QVector<QgsPoint>();
  }
  if (( line->type() == QGis::Line ) )
  {
    return line->asPolyline();
  }
  else
  {
    if ( line->asPolygon().size() > 1 )
    {
      return QVector<QgsPoint>();
    }
    return line->asPolygon()[0];
  }
}
Example #6
0
bool TopolError::fixSnap()
{
  bool ok;
  QgsFeature f1, f2;
  FeatureLayer fl = mFeaturePairs.at( 1 );
  ok = fl.layer->getFeatures( ( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ) ).nextFeature( f2 );
  fl = mFeaturePairs.first();
  ok = ok && fl.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ).nextFeature( f1 );

  if ( !ok )
    return false;

  QgsGeometry ge = f1.geometry();

  QgsPolylineXY line = ge.asPolyline();
  QgsPolylineXY conflictLine = mConflict.asPolyline();
  line.last() = conflictLine.last();

  QgsGeometry newG = QgsGeometry::fromPolylineXY( line );
  bool ret = fl.layer->changeGeometry( f1.id(), newG );

  return ret;
}
Example #7
0
void QgsRubberBand::addGeometry( const QgsGeometry& geom, QgsVectorLayer* layer )
{
  if ( geom.isEmpty() )
  {
    return;
  }

  //maprender object of canvas
  const QgsMapSettings& ms = mMapCanvas->mapSettings();

  int idx = mPoints.size();

  switch ( geom.wkbType() )
  {

    case QgsWkbTypes::Point:
    case QgsWkbTypes::Point25D:
    {
      QgsPoint pt;
      if ( layer )
      {
        pt = ms.layerToMapCoordinates( layer, geom.asPoint() );
      }
      else
      {
        pt = geom.asPoint();
      }
      addPoint( pt, false, idx );
      removeLastPoint( idx, false );
    }
    break;

    case QgsWkbTypes::MultiPoint:
    case QgsWkbTypes::MultiPoint25D:
    {
      QgsMultiPoint mpt = geom.asMultiPoint();
      for ( int i = 0; i < mpt.size(); ++i, ++idx )
      {
        QgsPoint pt = mpt[i];
        if ( layer )
        {
          addPoint( ms.layerToMapCoordinates( layer, pt ), false, idx );
          removeLastPoint( idx, false );
        }
        else
        {
          addPoint( pt, false, idx );
          removeLastPoint( idx, false );
        }
      }
    }
    break;

    case QgsWkbTypes::LineString:
    case QgsWkbTypes::LineString25D:
    {
      QgsPolyline line = geom.asPolyline();
      for ( int i = 0; i < line.count(); i++ )
      {
        if ( layer )
        {
          addPoint( ms.layerToMapCoordinates( layer, line[i] ), false, idx );
        }
        else
        {
          addPoint( line[i], false, idx );
        }
      }
    }
    break;

    case QgsWkbTypes::MultiLineString:
    case QgsWkbTypes::MultiLineString25D:
    {

      QgsMultiPolyline mline = geom.asMultiPolyline();
      for ( int i = 0; i < mline.size(); ++i, ++idx )
      {
        QgsPolyline line = mline[i];

        if ( line.isEmpty() )
        {
          --idx;
        }

        for ( int j = 0; j < line.size(); ++j )
        {
          if ( layer )
          {
            addPoint( ms.layerToMapCoordinates( layer, line[j] ), false, idx );
          }
          else
          {
            addPoint( line[j], false, idx );
          }
        }
      }
    }
    break;

    case QgsWkbTypes::Polygon:
    case QgsWkbTypes::Polygon25D:
    {
      QgsPolygon poly = geom.asPolygon();
      QgsPolyline line = poly[0];
      for ( int i = 0; i < line.count(); i++ )
      {
        if ( layer )
        {
          addPoint( ms.layerToMapCoordinates( layer, line[i] ), false, idx );
        }
        else
        {
          addPoint( line[i], false, idx );
        }
      }
    }
    break;

    case QgsWkbTypes::MultiPolygon:
    case QgsWkbTypes::MultiPolygon25D:
    {

      QgsMultiPolygon multipoly = geom.asMultiPolygon();
      for ( int i = 0; i < multipoly.size(); ++i, ++idx )
      {
        QgsPolygon poly = multipoly[i];
        QgsPolyline line = poly[0];
        for ( int j = 0; j < line.count(); ++j )
        {
          if ( layer )
          {
            addPoint( ms.layerToMapCoordinates( layer, line[j] ), false, idx );
          }
          else
          {
            addPoint( line[j], false, idx );
          }
        }
      }
    }
    break;

    case QgsWkbTypes::Unknown:
    default:
      return;
  }

  setVisible( true );
  updateRect();
  update();
}
Example #8
0
void QgsMapToolReshape::reshape( QgsVectorLayer *vlayer )
{
  QgsPointXY firstPoint = points().at( 0 );
  QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() );
  for ( int i = 1; i < size(); ++i )
  {
    bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() );
  }

  QgsLineString reshapeLineString( points() );
  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) )
    reshapeLineString.addZValue( defaultZValue() );

  //query all the features that intersect bounding box of capture line
  QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) );
  QgsFeature f;
  int reshapeReturn;
  bool reshapeDone = false;
  bool isBinding = isBindingLine( vlayer, bbox );

  vlayer->beginEditCommand( tr( "Reshape" ) );
  while ( fit.nextFeature( f ) )
  {
    //query geometry
    //call geometry->reshape(mCaptureList)
    //register changed geometry in vector layer
    QgsGeometry geom = f.geometry();
    if ( !geom.isNull() )
    {
      // in case of a binding line, we just want to update the line from
      // the starting point and not both side
      if ( isBinding && !geom.asPolyline().contains( points().first() ) )
        continue;

      reshapeReturn = geom.reshapeGeometry( reshapeLineString );
      if ( reshapeReturn == 0 )
      {
        //avoid intersections on polygon layers
        if ( vlayer->geometryType() == QgsWkbTypes::PolygonGeometry )
        {
          //ignore all current layer features as they should be reshaped too
          QHash<QgsVectorLayer *, QSet<QgsFeatureId> > ignoreFeatures;
          ignoreFeatures.insert( vlayer, vlayer->allFeatureIds() );

          if ( geom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers(), ignoreFeatures ) != 0 )
          {
            emit messageEmitted( tr( "An error was reported during intersection removal" ), Qgis::Critical );
            vlayer->destroyEditCommand();
            stopCapturing();
            return;
          }

          if ( geom.isEmpty() ) //intersection removal might have removed the whole geometry
          {
            emit messageEmitted( tr( "The feature cannot be reshaped because the resulting geometry is empty" ), Qgis::Critical );
            vlayer->destroyEditCommand();
            return;
          }
        }

        vlayer->changeGeometry( f.id(), geom );
        reshapeDone = true;
      }
    }
  }

  if ( reshapeDone )
  {
    vlayer->endEditCommand();
  }
  else
  {
    vlayer->destroyEditCommand();
  }
}
Example #9
0
bool QgsTransectSample::closestSegmentPoints( const QgsGeometry& g1, const QgsGeometry& g2, double& dist, QgsPoint& pt1, QgsPoint& pt2 )
{
  QgsWkbTypes::Type t1 = g1.wkbType();
  if ( t1 != QgsWkbTypes::LineString && t1 != QgsWkbTypes::LineString25D )
  {
    return false;
  }

  QgsWkbTypes::Type t2 = g2.wkbType();
  if ( t2 != QgsWkbTypes::LineString && t2 != QgsWkbTypes::LineString25D )
  {
    return false;
  }

  QgsPolyline pl1 = g1.asPolyline();
  QgsPolyline pl2 = g2.asPolyline();

  if ( pl1.size() < 2 || pl2.size() < 2 )
  {
    return false;
  }

  QgsPoint p11 = pl1.at( 0 );
  QgsPoint p12 = pl1.at( 1 );
  QgsPoint p21 = pl2.at( 0 );
  QgsPoint p22 = pl2.at( 1 );

  double p1x = p11.x();
  double p1y = p11.y();
  double v1x = p12.x() - p11.x();
  double v1y = p12.y() - p11.y();
  double p2x = p21.x();
  double p2y = p21.y();
  double v2x = p22.x() - p21.x();
  double v2y = p22.y() - p21.y();

  double denominatorU = v2x * v1y - v2y * v1x;
  double denominatorT = v1x * v2y - v1y * v2x;

  if ( qgsDoubleNear( denominatorU, 0 ) || qgsDoubleNear( denominatorT, 0 ) )
  {
    //lines are parallel
    //project all points on the other segment and take the one with the smallest distance
    QgsPoint minDistPoint1;
    double d1 = p11.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), minDistPoint1 );
    QgsPoint minDistPoint2;
    double d2 = p12.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), minDistPoint2 );
    QgsPoint minDistPoint3;
    double d3 = p21.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), minDistPoint3 );
    QgsPoint minDistPoint4;
    double d4 = p22.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), minDistPoint4 );

    if ( d1 <= d2 && d1 <= d3 && d1 <= d4 )
    {
      dist = sqrt( d1 );
      pt1 = p11;
      pt2 = minDistPoint1;
      return true;
    }
    else if ( d2 <= d1 && d2 <= d3 && d2 <= d4 )
    {
      dist = sqrt( d2 );
      pt1 = p12;
      pt2 = minDistPoint2;
      return true;
    }
    else if ( d3 <= d1 && d3 <= d2 && d3 <= d4 )
    {
      dist = sqrt( d3 );
      pt1 = p21;
      pt2 = minDistPoint3;
      return true;
    }
    else
    {
      dist = sqrt( d4 );
      pt1 = p21;
      pt2 = minDistPoint4;
      return true;
    }
  }

  double u = ( p1x * v1y - p1y * v1x - p2x * v1y + p2y * v1x ) / denominatorU;
  double t = ( p2x * v2y - p2y * v2x - p1x * v2y + p1y * v2x ) / denominatorT;

  if ( u >= 0 && u <= 1.0 && t >= 0 && t <= 1.0 )
  {
    dist = 0;
    pt1.setX( p2x + u * v2x );
    pt1.setY( p2y + u * v2y );
    pt2 = pt1;
    dist = 0;
    return true;
  }

  if ( t > 1.0 )
  {
    pt1.setX( p12.x() );
    pt1.setY( p12.y() );
  }
  else if ( t < 0.0 )
  {
    pt1.setX( p11.x() );
    pt1.setY( p11.y() );
  }
  if ( u > 1.0 )
  {
    pt2.setX( p22.x() );
    pt2.setY( p22.y() );
  }
  if ( u < 0.0 )
  {
    pt2.setX( p21.x() );
    pt2.setY( p21.y() );
  }
  if ( t >= 0.0 && t <= 1.0 )
  {
    //project pt2 onto g1
    pt2.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), pt1 );
  }
  if ( u >= 0.0 && u <= 1.0 )
  {
    //project pt1 onto g2
    pt1.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), pt2 );
  }

  dist = sqrt( pt1.sqrDist( pt2 ) );
  return true;
}
Example #10
0
void QgsDxfExport::addFeature( const QgsSymbolV2RenderContext& ctx, const QString& layer, const QgsSymbolLayerV2* symbolLayer, const QgsSymbolV2* symbol )
{
  const QgsFeature* fet = ctx.feature();
  if ( !fet )
  {
    return;
  }

  QgsGeometry* geom = fet->geometry();
  if ( geom )
  {
    int c = 0;
    if ( mSymbologyExport != NoSymbology )
    {
      c = colorFromSymbolLayer( symbolLayer, ctx );
    }
    double width = -1;
    if ( mSymbologyExport != NoSymbology && symbolLayer )
    {
      width = symbolLayer->dxfWidth( *this, ctx );
    }
    QString lineStyleName = "CONTINUOUS";
    if ( mSymbologyExport != NoSymbology )
    {
      lineStyleName = lineStyleFromSymbolLayer( symbolLayer );
    }
    QGis::WkbType geometryType = geom->wkbType();

    //single point
    if ( geometryType == QGis::WKBPoint || geometryType == QGis::WKBPoint25D )
    {
      writePoint( geom->asPoint(), layer, c, fet, symbolLayer, symbol );
    }

    //multipoint
    if ( geometryType == QGis::WKBMultiPoint || geometryType == QGis::WKBMultiPoint25D )
    {
      QgsMultiPoint multiPoint = geom->asMultiPoint();
      QgsMultiPoint::const_iterator it = multiPoint.constBegin();
      for ( ; it != multiPoint.constEnd(); ++it )
      {
        writePoint( *it, layer, c, fet, symbolLayer, symbol );
      }
    }

    //single line
    if ( geometryType == QGis::WKBLineString || geometryType == QGis::WKBLineString25D )
    {
      writePolyline( geom->asPolyline(), layer, lineStyleName, c, width, false );
    }

    //multiline
    if ( geometryType == QGis::WKBMultiLineString || geometryType == QGis::WKBMultiLineString25D )
    {
      QgsMultiPolyline multiLine = geom->asMultiPolyline();
      QgsMultiPolyline::const_iterator lIt = multiLine.constBegin();
      for ( ; lIt != multiLine.constEnd(); ++lIt )
      {
        writePolyline( *lIt, layer, lineStyleName, c, width, false );
      }
    }

    //polygon
    if ( geometryType == QGis::WKBPolygon || geometryType == QGis::WKBPolygon25D )
    {
      QgsPolygon polygon = geom->asPolygon();
      QgsPolygon::const_iterator polyIt = polygon.constBegin();
      for ( ; polyIt != polygon.constEnd(); ++polyIt ) //iterate over rings
      {
        writePolyline( *polyIt, layer, lineStyleName, c, width, true );
      }
    }

    //multipolygon or polygon
    if ( geometryType == QGis::WKBMultiPolygon || geometryType == QGis::WKBMultiPolygon25D )
    {
      QgsMultiPolygon mp = geom->asMultiPolygon();
      QgsMultiPolygon::const_iterator mpIt = mp.constBegin();
      for ( ; mpIt != mp.constEnd(); ++mpIt )
      {
        QgsPolygon::const_iterator polyIt = mpIt->constBegin();
        for ( ; polyIt != mpIt->constEnd(); ++polyIt )
        {
          writePolyline( *polyIt, layer, lineStyleName, c, width, true );
        }
      }
    }
  }
}
Example #11
0
int QgsVectorLayerEditUtils::addTopologicalPoints( const QgsGeometry& geom )
{
  if ( !L->hasGeometryType() )
    return 1;

  if ( geom.isEmpty() )
  {
    return 1;
  }

  int returnVal = 0;

  QgsWkbTypes::Type wkbType = geom.wkbType();

  switch ( wkbType )
  {
      //line
    case QgsWkbTypes::LineString25D:
    case QgsWkbTypes::LineString:
    {
      QgsPolyline theLine = geom.asPolyline();
      QgsPolyline::const_iterator line_it = theLine.constBegin();
      for ( ; line_it != theLine.constEnd(); ++line_it )
      {
        if ( addTopologicalPoints( *line_it ) != 0 )
        {
          returnVal = 2;
        }
      }
      break;
    }

    //multiline
    case QgsWkbTypes::MultiLineString25D:
    case QgsWkbTypes::MultiLineString:
    {
      QgsMultiPolyline theMultiLine = geom.asMultiPolyline();
      QgsPolyline currentPolyline;

      for ( int i = 0; i < theMultiLine.size(); ++i )
      {
        QgsPolyline::const_iterator line_it = currentPolyline.constBegin();
        for ( ; line_it != currentPolyline.constEnd(); ++line_it )
        {
          if ( addTopologicalPoints( *line_it ) != 0 )
          {
            returnVal = 2;
          }
        }
      }
      break;
    }

    //polygon
    case QgsWkbTypes::Polygon25D:
    case QgsWkbTypes::Polygon:
    {
      QgsPolygon thePolygon = geom.asPolygon();
      QgsPolyline currentRing;

      for ( int i = 0; i < thePolygon.size(); ++i )
      {
        currentRing = thePolygon.at( i );
        QgsPolyline::const_iterator line_it = currentRing.constBegin();
        for ( ; line_it != currentRing.constEnd(); ++line_it )
        {
          if ( addTopologicalPoints( *line_it ) != 0 )
          {
            returnVal = 2;
          }
        }
      }
      break;
    }

    //multipolygon
    case QgsWkbTypes::MultiPolygon25D:
    case QgsWkbTypes::MultiPolygon:
    {
      QgsMultiPolygon theMultiPolygon = geom.asMultiPolygon();
      QgsPolygon currentPolygon;
      QgsPolyline currentRing;

      for ( int i = 0; i < theMultiPolygon.size(); ++i )
      {
        currentPolygon = theMultiPolygon.at( i );
        for ( int j = 0; j < currentPolygon.size(); ++j )
        {
          currentRing = currentPolygon.at( j );
          QgsPolyline::const_iterator line_it = currentRing.constBegin();
          for ( ; line_it != currentRing.constEnd(); ++line_it )
          {
            if ( addTopologicalPoints( *line_it ) != 0 )
            {
              returnVal = 2;
            }
          }
        }
      }
      break;
    }
    default:
      break;
  }
  return returnVal;
}
Example #12
0
int QgsVectorLayerEditUtils::addTopologicalPoints( const QgsGeometry &geom )
{
  if ( !mLayer->isSpatial() )
    return 1;

  if ( geom.isNull() )
  {
    return 1;
  }

  int returnVal = 0;

  QgsWkbTypes::Type wkbType = geom.wkbType();

  switch ( QgsWkbTypes::geometryType( wkbType ) )
  {
    //line
    case QgsWkbTypes::LineGeometry:
    {
      if ( !QgsWkbTypes::isMultiType( wkbType ) )
      {
        QgsPolylineXY line = geom.asPolyline();
        QgsPolylineXY::const_iterator line_it = line.constBegin();
        for ( ; line_it != line.constEnd(); ++line_it )
        {
          if ( addTopologicalPoints( *line_it ) != 0 )
          {
            returnVal = 2;
          }
        }
      }
      else
      {
        QgsMultiPolylineXY multiLine = geom.asMultiPolyline();
        QgsPolylineXY currentPolyline;

        for ( int i = 0; i < multiLine.size(); ++i )
        {
          QgsPolylineXY::const_iterator line_it = currentPolyline.constBegin();
          for ( ; line_it != currentPolyline.constEnd(); ++line_it )
          {
            if ( addTopologicalPoints( *line_it ) != 0 )
            {
              returnVal = 2;
            }
          }
        }
      }
      break;
    }

    case QgsWkbTypes::PolygonGeometry:
    {
      if ( !QgsWkbTypes::isMultiType( wkbType ) )
      {
        QgsPolygonXY polygon = geom.asPolygon();
        QgsPolylineXY currentRing;

        for ( int i = 0; i < polygon.size(); ++i )
        {
          currentRing = polygon.at( i );
          QgsPolylineXY::const_iterator line_it = currentRing.constBegin();
          for ( ; line_it != currentRing.constEnd(); ++line_it )
          {
            if ( addTopologicalPoints( *line_it ) != 0 )
            {
              returnVal = 2;
            }
          }
        }
      }
      else
      {
        QgsMultiPolygonXY multiPolygon = geom.asMultiPolygon();
        QgsPolygonXY currentPolygon;
        QgsPolylineXY currentRing;

        for ( int i = 0; i < multiPolygon.size(); ++i )
        {
          currentPolygon = multiPolygon.at( i );
          for ( int j = 0; j < currentPolygon.size(); ++j )
          {
            currentRing = currentPolygon.at( j );
            QgsPolylineXY::const_iterator line_it = currentRing.constBegin();
            for ( ; line_it != currentRing.constEnd(); ++line_it )
            {
              if ( addTopologicalPoints( *line_it ) != 0 )
              {
                returnVal = 2;
              }
            }
          }
        }
      }
      break;
    }

    case QgsWkbTypes::PointGeometry:
    case QgsWkbTypes::UnknownGeometry:
    case QgsWkbTypes::NullGeometry:
      break;
  }
  return returnVal;
}