Skip to content

Commit

Permalink
Fix some handling of wkb types which is broken for z/m type geometries
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 27, 2017
1 parent 060a36b commit d1e83b5
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 124 deletions.
4 changes: 2 additions & 2 deletions src/app/qgsmaptooldeletepart.cpp
Expand Up @@ -136,13 +136,13 @@ QgsGeometry QgsMapToolDeletePart::partUnderPoint( QPoint point, QgsFeatureId &fi
fid = match.featureId();
return QgsGeometry::fromPointXY( match.point() );
}
if ( g.wkbType() == QgsWkbTypes::MultiPoint || g.wkbType() == QgsWkbTypes::MultiPoint25D )
else if ( QgsWkbTypes::geometryType( g.wkbType() ) == QgsWkbTypes::PointGeometry )
{
fid = match.featureId();
partNum = snapVertex;
return QgsGeometry::fromPointXY( match.point() );
}
if ( g.wkbType() == QgsWkbTypes::MultiLineString || g.wkbType() == QgsWkbTypes::MultiLineString25D )
else if ( QgsWkbTypes::geometryType( g.wkbType() ) == QgsWkbTypes::LineGeometry )
{
QgsMultiPolylineXY mline = g.asMultiPolyline();
for ( int part = 0; part < mline.count(); part++ )
Expand Down
14 changes: 8 additions & 6 deletions src/app/qgsmaptooldeletering.cpp
Expand Up @@ -133,9 +133,10 @@ QgsGeometry QgsMapToolDeleteRing::ringUnderPoint( const QgsPointXY &p, QgsFeatur
while ( fit.nextFeature( f ) )
{
g = f.geometry();
if ( g.isNull() )
if ( g.isNull() || QgsWkbTypes::geometryType( g.wkbType() ) != QgsWkbTypes::PolygonGeometry )
continue;
if ( g.wkbType() == QgsWkbTypes::Polygon || g.wkbType() == QgsWkbTypes::Polygon25D )

if ( !QgsWkbTypes::isMultiType( g.wkbType() ) )
{
pol = QgsMultiPolygonXY() << g.asPolygon();
}
Expand Down Expand Up @@ -178,16 +179,17 @@ void QgsMapToolDeleteRing::deleteRing( QgsFeatureId fId, int beforeVertexNr, Qgs
QgsWkbTypes::Type wkbtype = g.wkbType();
int ringNum, partNum = 0;

if ( wkbtype == QgsWkbTypes::Polygon || wkbtype == QgsWkbTypes::Polygon25D )
if ( QgsWkbTypes::geometryType( wkbtype ) != QgsWkbTypes::PolygonGeometry )
return;

if ( !QgsWkbTypes::isMultiType( wkbtype ) )
{
ringNum = ringNumInPolygon( g, beforeVertexNr );
}
else if ( wkbtype == QgsWkbTypes::MultiPolygon || wkbtype == QgsWkbTypes::MultiPolygon25D )
else
{
ringNum = ringNumInMultiPolygon( g, beforeVertexNr, partNum );
}
else
return;

QgsGeometry editableGeom = f.geometry();
if ( editableGeom.deleteRing( ringNum, partNum ) )
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsmaptoolfillring.cpp
Expand Up @@ -198,11 +198,11 @@ QgsGeometry QgsMapToolFillRing::ringUnderPoint( const QgsPointXY &p, QgsFeatureI
while ( fit.nextFeature( f ) )
{
QgsGeometry g = f.geometry();
if ( g.isNull() )
if ( g.isNull() || QgsWkbTypes::geometryType( g.wkbType() ) != QgsWkbTypes::PolygonGeometry )
continue;

QgsMultiPolygonXY pol;
if ( g.wkbType() == QgsWkbTypes::Polygon || g.wkbType() == QgsWkbTypes::Polygon25D )
if ( !QgsWkbTypes::isMultiType( g.wkbType() ) )
{
pol = QgsMultiPolygonXY() << g.asPolygon();
}
Expand Down
104 changes: 51 additions & 53 deletions src/core/qgsvectorlayereditutils.cpp
Expand Up @@ -513,81 +513,53 @@ int QgsVectorLayerEditUtils::addTopologicalPoints( const QgsGeometry &geom )

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

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

//multiline
case QgsWkbTypes::MultiLineString25D:
case QgsWkbTypes::MultiLineString:
{
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 )
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;
}
}
}
break;
}

//polygon
case QgsWkbTypes::Polygon25D:
case QgsWkbTypes::Polygon:
{
QgsPolygonXY polygon = geom.asPolygon();
QgsPolylineXY currentRing;

for ( int i = 0; i < polygon.size(); ++i )
else
{
currentRing = polygon.at( i );
QgsPolylineXY::const_iterator line_it = currentRing.constBegin();
for ( ; line_it != currentRing.constEnd(); ++line_it )
QgsMultiPolylineXY multiLine = geom.asMultiPolyline();
QgsPolylineXY currentPolyline;

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

//multipolygon
case QgsWkbTypes::MultiPolygon25D:
case QgsWkbTypes::MultiPolygon:
case QgsWkbTypes::PolygonGeometry:
{
QgsMultiPolygonXY multiPolygon = geom.asMultiPolygon();
QgsPolygonXY currentPolygon;
QgsPolylineXY currentRing;

for ( int i = 0; i < multiPolygon.size(); ++i )
if ( !QgsWkbTypes::isMultiType( wkbType ) )
{
currentPolygon = multiPolygon.at( i );
for ( int j = 0; j < currentPolygon.size(); ++j )
QgsPolygonXY polygon = geom.asPolygon();
QgsPolylineXY currentRing;

for ( int i = 0; i < polygon.size(); ++i )
{
currentRing = currentPolygon.at( j );
currentRing = polygon.at( i );
QgsPolylineXY::const_iterator line_it = currentRing.constBegin();
for ( ; line_it != currentRing.constEnd(); ++line_it )
{
Expand All @@ -598,9 +570,35 @@ int QgsVectorLayerEditUtils::addTopologicalPoints( const QgsGeometry &geom )
}
}
}
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;
}
default:

case QgsWkbTypes::PointGeometry:
case QgsWkbTypes::UnknownGeometry:
case QgsWkbTypes::NullGeometry:
break;
}
return returnVal;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/symbology/qgspointdisplacementrendererwidget.cpp
Expand Up @@ -40,7 +40,7 @@ QgsPointDisplacementRendererWidget::QgsPointDisplacementRendererWidget( QgsVecto
}

//the renderer only applies to point vector layers
if ( layer->wkbType() != QgsWkbTypes::Point && layer->wkbType() != QgsWkbTypes::Point25D )
if ( QgsWkbTypes::geometryType( layer->wkbType() ) != QgsWkbTypes::PointGeometry || QgsWkbTypes::isMultiType( layer->wkbType() ) )
{
//setup blank dialog
mRenderer = nullptr;
Expand Down
128 changes: 68 additions & 60 deletions src/plugins/topology/topolTest.cpp
Expand Up @@ -1006,96 +1006,73 @@ ErrorList topolTest::checkSegmentLength( double tolerance, QgsVectorLayer *layer


// switching by type here, because layer can contain both single and multi version geometries
switch ( g1.wkbType() )
switch ( QgsWkbTypes::geometryType( g1.wkbType() ) )
{
case QgsWkbTypes::LineString:
case QgsWkbTypes::LineString25D:
ls = g1.asPolyline();


for ( int i = 1; i < ls.size(); ++i )
case QgsWkbTypes::LineGeometry:
{
if ( !QgsWkbTypes::isMultiType( g1.wkbType() ) )
{
distance = std::sqrt( ls[i - 1].sqrDist( ls[i] ) );
if ( distance < tolerance )
{
fls.clear();
fls << *it << *it;
segm.clear();
segm << ls[i - 1] << ls[i];
QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
//err = new TopolErrorShort(g1->boundingBox(), QgsGeometry::fromPolyline(segm), fls);
errorList << err;
//break on getting the first error
break;
}
}
break;
ls = g1.asPolyline();

case QgsWkbTypes::Polygon:
case QgsWkbTypes::Polygon25D:
pol = g1.asPolygon();

for ( int i = 0; i < pol.size(); ++i )
{
for ( int j = 1; j < pol[i].size(); ++j )
for ( int i = 1; i < ls.size(); ++i )
{
distance = std::sqrt( pol[i][j - 1].sqrDist( pol[i][j] ) );
distance = std::sqrt( ls[i - 1].sqrDist( ls[i] ) );
if ( distance < tolerance )
{
fls.clear();
fls << *it << *it;
segm.clear();
segm << pol[i][j - 1] << pol[i][j];
segm << ls[i - 1] << ls[i];
QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
//err = new TopolErrorShort(g1->boundingBox(), QgsGeometry::fromPolyline(segm), fls);
errorList << err;
//break on getting the first error
break;
}
}
}

break;

case QgsWkbTypes::MultiLineString:
case QgsWkbTypes::MultiLineString25D:
mls = g1.asMultiPolyline();

for ( int k = 0; k < mls.size(); ++k )
else
{
QgsPolylineXY &ls = mls[k];
for ( int i = 1; i < ls.size(); ++i )
mls = g1.asMultiPolyline();

for ( int k = 0; k < mls.size(); ++k )
{
distance = std::sqrt( ls[i - 1].sqrDist( ls[i] ) );
if ( distance < tolerance )
QgsPolylineXY &ls = mls[k];
for ( int i = 1; i < ls.size(); ++i )
{
fls.clear();
fls << *it << *it;
segm.clear();
segm << ls[i - 1] << ls[i];
QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
errorList << err;
//break on getting the first error
break;
distance = std::sqrt( ls[i - 1].sqrDist( ls[i] ) );
if ( distance < tolerance )
{
fls.clear();
fls << *it << *it;
segm.clear();
segm << ls[i - 1] << ls[i];
QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
errorList << err;
//break on getting the first error
break;
}
}
}
}
break;
}

case QgsWkbTypes::MultiPolygon:
case QgsWkbTypes::MultiPolygon25D:
mpol = g1.asMultiPolygon();

for ( int k = 0; k < mpol.size(); ++k )
case QgsWkbTypes::PolygonGeometry:
{
if ( !QgsWkbTypes::isMultiType( g1.wkbType() ) )
{
QgsPolygonXY &pol = mpol[k];

pol = g1.asPolygon();

for ( int i = 0; i < pol.size(); ++i )
{
for ( int j = 1; j < pol[i].size(); ++j )
{
distance = pol[i][j - 1].sqrDist( pol[i][j] );
distance = std::sqrt( pol[i][j - 1].sqrDist( pol[i][j] ) );
if ( distance < tolerance )
{
fls.clear();
Expand All @@ -1111,9 +1088,40 @@ ErrorList topolTest::checkSegmentLength( double tolerance, QgsVectorLayer *layer
}
}
}
else
{
mpol = g1.asMultiPolygon();

for ( int k = 0; k < mpol.size(); ++k )
{
QgsPolygonXY &pol = mpol[k];
for ( int i = 0; i < pol.size(); ++i )
{
for ( int j = 1; j < pol[i].size(); ++j )
{
distance = pol[i][j - 1].sqrDist( pol[i][j] );
if ( distance < tolerance )
{
fls.clear();
fls << *it << *it;
segm.clear();
segm << pol[i][j - 1] << pol[i][j];
QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
errorList << err;
//break on getting the first error
break;
}
}
}
}
}
break;
}

default:
case QgsWkbTypes::PointGeometry:
case QgsWkbTypes::UnknownGeometry:
case QgsWkbTypes::NullGeometry:
continue;
}
}
Expand Down

0 comments on commit d1e83b5

Please sign in to comment.