Created
January 27, 2014 16:45
-
-
Save 3nids/8652202 to your computer and use it in GitHub Desktop.
convert geometry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool QgsVectorLayer::convertToLayerGeometry( QgsGeometry &geometry ) | |
{ | |
QGis::GeometryType layerGeomType = geometryType(); | |
QGis::GeometryType geomType = geometry.type(); | |
switch ( geomType ) | |
{ | |
// geometry type is point | |
case QGis::Point: | |
{ | |
if ( layerGeomType == QGis::Point ) | |
{ | |
if ( (mIsMultiPart && geometry.isMultipart()) || | |
(!mIsMultiPart && ! geometry.isMultipart()) ) | |
{ | |
// keep the same geom | |
return true; | |
} | |
if ( mIsMultiPart ) | |
{ | |
// layer is multipart => makes a multipoint with a single point | |
geometry = *QgsGeometry::fromMultiPoint( QgsMultiPoint() << geometry.asPoint() ); | |
} | |
else | |
{ | |
// layer is singlepart => make a point if geometry contains only one, return false otherwise | |
QgsMultiPoint multiPoint = geometry.asMultiPoint(); | |
if ( multiPoint.count() != 1 ) | |
{ | |
return false; | |
} | |
else | |
{ | |
geometry = *QgsGeometry::fromPoint( multiPoint[0] ); | |
} | |
} | |
} | |
else | |
{ | |
// cannot change point in any other type, | |
// even for multipoints since there is no ordering | |
return false; | |
} | |
} | |
// geometry type is line | |
case QGis::Line: | |
{ | |
QgsMultiPolyline multiLine; | |
QgsPolyline line; | |
if ( geometry.isMultipart() ) | |
{ | |
multiLine = geometry.asMultiPolyline(); | |
if ( multiLine.isEmpty() ) | |
return false; | |
} | |
else | |
{ | |
line = geometry.asPolyline(); | |
if ( line.isEmpty() ) | |
return false; | |
} | |
switch ( layerGeomType ) | |
{ | |
// line geometry for point layer => make a multipoint | |
case QGis::Point: | |
{ | |
// if layer is not multi part: cannot transform | |
if ( !mIsMultiPart ) | |
return false; | |
// input geometry is multipart | |
if ( geometry.isMultipart() ) | |
{ | |
QgsMultiPoint multiPoint; | |
for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt ) | |
for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt ) | |
multiPoint << *lineIt; | |
geometry = *QgsGeometry::fromMultiPoint( multiPoint ); | |
return true; | |
} | |
// input geometry is not multipart | |
else | |
{ | |
geometry = *QgsGeometry::fromMultiPoint( line ); | |
return true; | |
} | |
break; | |
} | |
case QGis::Line: | |
{ | |
if ( (mIsMultiPart && geometry.isMultipart()) || | |
(!mIsMultiPart && ! geometry.isMultipart()) ) | |
{ | |
// keep the same geom | |
return true; | |
} | |
if ( mIsMultiPart ) | |
{ | |
// layer is multipart => makes a multipoint with a single line | |
geometry = *QgsGeometry::fromMultiPolyline( QgsMultiPolyline() << line ); | |
} | |
else | |
{ | |
// layer is singlepart => make a point if geometry contains only one, return false otherwise | |
if ( multiLine.count() != 1 ) | |
{ | |
return false; | |
} | |
else | |
{ | |
geometry = *QgsGeometry::fromPolyline( multiLine[0] ); | |
} | |
} | |
} | |
// line geometry for polygon layer => create polygon by closing the line(s) | |
case QGis::Polygon: | |
{ | |
// input geometry is multipart | |
if ( geometry.isMultipart() ) | |
{ | |
QgsMultiPolygon multiPolygon; | |
for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt ) | |
{ | |
// do not create polygon for a 2 segment line | |
if (( *multiLineIt ).count() < 3 ) | |
continue; | |
// add closing node | |
if (( *multiLineIt ).first() != ( *multiLineIt ).last() ) | |
*multiLineIt << ( *multiLineIt ).first(); | |
multiPolygon << ( QgsPolygon() << *multiLineIt ); | |
} | |
// no polygons were added | |
if ( multiPolygon.isEmpty() ) | |
return false; | |
if ( mIsMultiPart ) | |
{ | |
geometry = *QgsGeometry::fromMultiPolygon( multiPolygon ); | |
return true; | |
} | |
else | |
{ | |
if ( multiPolygon.count() > 1 ) | |
{ | |
// cannot fit a multipolygon in a polygon layer | |
return false; | |
} | |
else | |
{ | |
// since the geometry contains only one polygon, make it single part geometry | |
geometry = *QgsGeometry::fromPolygon( multiPolygon[0] ); | |
return true; | |
} | |
} | |
} | |
// input geometry is not multipart | |
else | |
{ | |
// do not create polygon for a 2 segment line | |
if ( line.count() < 3 ) | |
return false; | |
// add closing node | |
if ( line.first() != line.last() ) | |
line << line.first(); | |
// layer is multipart | |
if ( mIsMultiPart ) | |
{ | |
geometry = *QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << line ) ); | |
return true; | |
} | |
else | |
{ | |
geometry = *QgsGeometry::fromPolygon( QgsPolygon() << line ); | |
return true; | |
} | |
} | |
break; | |
} | |
default: | |
return false; | |
} | |
} | |
// geometry type is polygon | |
case QGis::Polygon: | |
{ | |
QgsMultiPolygon multiPolygon; | |
QgsPolygon polygon; | |
if ( geometry.isMultipart() ) | |
{ | |
multiPolygon = geometry.asMultiPolygon(); | |
if ( multiPolygon.isEmpty() ) | |
return false; | |
} | |
else | |
{ | |
polygon = geometry.asPolygon(); | |
if ( polygon.isEmpty() ) | |
return false; | |
} | |
switch ( layerGeomType ) | |
{ | |
// feature: polygon & layer point => make a multipoint | |
case QGis::Point: | |
{ | |
// if layer is not multi part: cannot transform | |
if ( !mIsMultiPart ) | |
return false; | |
// input geometry is multipart | |
if ( geometry.isMultipart() ) | |
{ | |
QgsMultiPoint multiPoint; | |
for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt ) | |
for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt ) | |
for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt ) | |
multiPoint << *lineIt; | |
geometry = *QgsGeometry::fromMultiPoint( multiPoint ); | |
return true; | |
} | |
// input geometry is not multipart | |
else | |
{ | |
QgsMultiPoint multiPoint; | |
for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt ) | |
for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt ) | |
multiPoint << *lineIt; | |
geometry = *QgsGeometry::fromMultiPoint( multiPoint ); | |
return true; | |
} | |
break; | |
} | |
// feature: polygon & layer: line => polygon to line | |
// convert multipolygon and rings to multilines | |
case QGis::Line: | |
{ | |
if ( geometry.isMultipart() ) | |
{ | |
QgsMultiPolyline multiLine; | |
for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt ) | |
for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt ) | |
multiLine << *multiLineIt; | |
// layer is multipart | |
if ( mIsMultiPart ) | |
{ | |
geometry = *QgsGeometry::fromMultiPolyline( multiLine ); | |
return true; | |
} | |
else | |
{ | |
if ( multiLine.count() > 1 ) | |
{ | |
// cannot fit a multiline in a line layer | |
return false; | |
} | |
else | |
{ | |
// since the geometry contains only one polygon without ring, make it single part geometry | |
geometry = *QgsGeometry::fromPolyline( multiLine[0] ); | |
return true; | |
} | |
} | |
} | |
// not multipart | |
else | |
{ | |
// if polygon has rings | |
if ( polygon.count() > 1 ) | |
{ | |
// cannot fit a polygon with rings in a single line layer | |
// TODO: would it be better to remove rings? | |
if ( !mIsMultiPart ) | |
return false; | |
QgsMultiPolyline multiLine; | |
for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt ) | |
multiLine << *multiLineIt; | |
geometry = *QgsGeometry::fromMultiPolyline( multiLine ); | |
} | |
// no rings | |
else | |
{ | |
if ( mIsMultiPart ) | |
{ | |
geometry = *QgsGeometry::fromMultiPolyline( polygon ); | |
return true; | |
} | |
else | |
{ | |
geometry = *QgsGeometry::fromPolyline( polygon[0] ); | |
return true; | |
} | |
} | |
} | |
} | |
case QGis::Polygon: | |
{ | |
if ( (mIsMultiPart && geometry.isMultipart()) || | |
(!mIsMultiPart && ! geometry.isMultipart()) ) | |
{ | |
// keep the same geom | |
return true; | |
} | |
if ( mIsMultiPart ) | |
{ | |
// layer is multipart => makes a multipoint with a single polygon | |
geometry = *QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << polygon ); | |
} | |
else | |
{ | |
// layer is singlepart => make a point if geometry contains only one, return false otherwise | |
if ( multiPolygon.count() != 1 ) | |
{ | |
return false; | |
} | |
else | |
{ | |
geometry = *QgsGeometry::fromPolygon( multiPolygon[0] ); | |
} | |
} | |
} | |
default: | |
return false; | |
} | |
} | |
default: | |
return false; | |
} | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment