示例#1
0
bool QgsGeometryEditUtils::deleteRing( QgsAbstractGeometry *geom, int ringNum, int partNum )
{
  if ( !geom || partNum < 0 )
  {
    return false;
  }

  if ( ringNum < 1 ) //cannot remove exterior ring
  {
    return false;
  }

  QgsAbstractGeometry *g = geom;
  QgsGeometryCollection *c = qgsgeometry_cast<QgsGeometryCollection *>( geom );
  if ( c )
  {
    g = c->geometryN( partNum );
  }
  else if ( partNum > 0 )
  {
    //part num specified, but not a multi part geometry type
    return false;
  }

  QgsCurvePolygon *cpoly = qgsgeometry_cast<QgsCurvePolygon *>( g );
  if ( !cpoly )
  {
    return false;
  }

  return cpoly->removeInteriorRing( ringNum - 1 );
}
示例#2
0
static bool lwcollection_make_geos_friendly( QgsGeometryCollection &g )
{
  for ( int i = 0; i < g.numGeometries(); i++ )
  {
    if ( !lwgeom_make_geos_friendly( *g.geometryN( i ) ) )
      return false;
  }

  return true;
}
示例#3
0
QgsGeometry::OperationResult QgsGeometryEditUtils::addRing( QgsAbstractGeometry *geom, std::unique_ptr<QgsCurve> ring )
{
  if ( !ring )
  {
    return QgsGeometry::InvalidInput;
  }

  QList< QgsCurvePolygon * > polygonList;
  QgsCurvePolygon *curvePoly = qgsgeometry_cast< QgsCurvePolygon * >( geom );
  QgsGeometryCollection *multiGeom = qgsgeometry_cast< QgsGeometryCollection * >( geom );
  if ( curvePoly )
  {
    polygonList.append( curvePoly );
  }
  else if ( multiGeom )
  {
    polygonList.reserve( multiGeom->numGeometries() );
    for ( int i = 0; i < multiGeom->numGeometries(); ++i )
    {
      polygonList.append( qgsgeometry_cast< QgsCurvePolygon * >( multiGeom->geometryN( i ) ) );
    }
  }
  else
  {
    return QgsGeometry::InvalidInput; //not polygon / multipolygon;
  }

  //ring must be closed
  if ( !ring->isClosed() )
  {
    return QgsGeometry::AddRingNotClosed;
  }
  else if ( !ring->isRing() )
  {
    return QgsGeometry::AddRingNotValid;
  }

  std::unique_ptr<QgsGeometryEngine> ringGeom( QgsGeometry::createGeometryEngine( ring.get() ) );
  ringGeom->prepareGeometry();

  //for each polygon, test if inside outer ring and no intersection with other interior ring
  QList< QgsCurvePolygon * >::const_iterator polyIter = polygonList.constBegin();
  for ( ; polyIter != polygonList.constEnd(); ++polyIter )
  {
    if ( ringGeom->within( *polyIter ) )
    {
      //check if disjoint with other interior rings
      int nInnerRings = ( *polyIter )->numInteriorRings();
      for ( int i = 0; i < nInnerRings; ++i )
      {
        if ( !ringGeom->disjoint( ( *polyIter )->interiorRing( i ) ) )
        {
          return QgsGeometry::AddRingCrossesExistingRings;
        }
      }

      //make sure dimensionality of ring matches geometry
      if ( QgsWkbTypes::hasZ( geom->wkbType() ) )
        ring->addZValue( 0 );
      if ( QgsWkbTypes::hasM( geom->wkbType() ) )
        ring->addMValue( 0 );

      ( *polyIter )->addInteriorRing( ring.release() );
      return QgsGeometry::Success; //success
    }
  }
  return QgsGeometry::AddRingNotInExistingFeature; //not contained in any outer ring
}