Navigation Menu

Skip to content

Commit

Permalink
Adds a few magic to make the parser more tolerant of typos and allows…
Browse files Browse the repository at this point in the history
… the creation of empty geometry using empty parentheses like 'LineString ( )'.
  • Loading branch information
lbartoletti committed Aug 24, 2020
1 parent 7212fec commit d349fc4
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 27 deletions.
9 changes: 5 additions & 4 deletions src/core/geometry/qgscircularstring.cpp
Expand Up @@ -314,12 +314,13 @@ bool QgsCircularString::fromWkt( const QString &wkt )
return false;
mWkbType = parts.first;

if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
parts.second = parts.second.remove( '(' ).remove( ')' );
QString secondWithoutParentheses = parts.second;
secondWithoutParentheses = secondWithoutParentheses.simplified().remove( ' ' );
if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
secondWithoutParentheses.isEmpty() )
return true;

if ( parts.second.compare( QLatin1String( "NULL" ), Qt::CaseInsensitive ) == 0 )
return false;

QgsPointSequence points = QgsGeometryUtils::pointsFromWKT( parts.second, is3D(), isMeasure() );
if ( points.isEmpty() )
return false;
Expand Down
8 changes: 4 additions & 4 deletions src/core/geometry/qgscompoundcurve.cpp
Expand Up @@ -179,12 +179,12 @@ bool QgsCompoundCurve::fromWkt( const QString &wkt )
return false;
mWkbType = parts.first;

if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
QString secondWithoutParentheses = parts.second;
secondWithoutParentheses = secondWithoutParentheses.remove( '(' ).remove( ')' ).simplified().remove( ' ' );
if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
secondWithoutParentheses.isEmpty() )
return true;

if ( parts.second.compare( QLatin1String( "NULL" ), Qt::CaseInsensitive ) == 0 )
return false;

QString defaultChildWkbType = QStringLiteral( "LineString%1%2" ).arg( is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );

const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType );
Expand Down
8 changes: 4 additions & 4 deletions src/core/geometry/qgscurvepolygon.cpp
Expand Up @@ -215,12 +215,12 @@ bool QgsCurvePolygon::fromWkt( const QString &wkt )

mWkbType = parts.first;

if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
QString secondWithoutParentheses = parts.second;
secondWithoutParentheses = secondWithoutParentheses.remove( '(' ).remove( ')' ).simplified().remove( ' ' );
if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
secondWithoutParentheses.isEmpty() )
return true;

if ( parts.second.compare( QLatin1String( "NULL" ), Qt::CaseInsensitive ) == 0 )
return false;

QString defaultChildWkbType = QStringLiteral( "LineString%1%2" ).arg( is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );

const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType );
Expand Down
8 changes: 4 additions & 4 deletions src/core/geometry/qgsgeometrycollection.cpp
Expand Up @@ -698,12 +698,12 @@ bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector
}
mWkbType = parts.first;

if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
QString secondWithoutParentheses = parts.second;
secondWithoutParentheses = secondWithoutParentheses.remove( '(' ).remove( ')' ).simplified().remove( ' ' );
if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
secondWithoutParentheses.isEmpty() )
return true;

if ( parts.second.compare( QLatin1String( "NULL" ), Qt::CaseInsensitive ) == 0 )
return false;

QString defChildWkbType = QStringLiteral( "%1%2%3 " ).arg( defaultChildWkbType, is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );

const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defChildWkbType );
Expand Down
13 changes: 10 additions & 3 deletions src/core/geometry/qgsgeometryutils.cpp
Expand Up @@ -1100,6 +1100,7 @@ QgsPointSequence QgsGeometryUtils::pointsFromWKT( const QString &wktCoordinateLi
{
int dim = 2 + is3D + isMeasure;
QgsPointSequence points;

const QStringList coordList = wktCoordinateList.split( ',', QString::SkipEmptyParts );

//first scan through for extra unexpected dimensions
Expand Down Expand Up @@ -1306,9 +1307,7 @@ QPair<QgsWkbTypes::Type, QString> QgsGeometryUtils::wktReadBlock( const QString
{
QString wktParsed = wkt;
QString contents;
if ( wktParsed.count( '(' ) != wktParsed.count( ')' ) ) // if unbalanced parenthesis will returns false
contents = QStringLiteral( "NULL" );
else if ( wkt.contains( QString( "EMPTY" ), Qt::CaseInsensitive ) )
if ( wkt.contains( QString( "EMPTY" ), Qt::CaseInsensitive ) )
{
QRegularExpression wktRegEx( QStringLiteral( "^\\s*(\\w+)\\s+(\\w+)\\s*$" ) );
wktRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
Expand All @@ -1321,6 +1320,14 @@ QPair<QgsWkbTypes::Type, QString> QgsGeometryUtils::wktReadBlock( const QString
}
else
{
const int openedParenthesisCount = wktParsed.count( '(' );
const int closedParenthesisCount = wktParsed.count( ')' );
// closes missing parentheses
for ( int i = 0 ; i < openedParenthesisCount - closedParenthesisCount; ++i )
wktParsed.push_back( ')' );
// removes extra parentheses
wktParsed.truncate( wktParsed.size() - ( closedParenthesisCount - openedParenthesisCount ) );

QRegularExpression cooRegEx( QStringLiteral( "^[^\\(]*\\((.*)\\)[^\\)]*$" ) );
cooRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
QRegularExpressionMatch match = cooRegEx.match( wktParsed );
Expand Down
11 changes: 7 additions & 4 deletions src/core/geometry/qgslinestring.cpp
Expand Up @@ -434,13 +434,16 @@ bool QgsLineString::fromWkt( const QString &wkt )
return false;
mWkbType = parts.first;

if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
QString secondWithoutParentheses = parts.second;
secondWithoutParentheses = secondWithoutParentheses.remove( '(' ).remove( ')' ).simplified().remove( ' ' );
parts.second = parts.second.remove( '(' ).remove( ')' );
if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
secondWithoutParentheses.isEmpty() )
return true;

if ( parts.second.compare( QLatin1String( "NULL" ), Qt::CaseInsensitive ) == 0 )
return false;

QgsPointSequence points = QgsGeometryUtils::pointsFromWKT( parts.second, is3D(), isMeasure() );
// There is a non number in the coordinates sequence
// LineString ( A b, 1 2)
if ( points.isEmpty() )
return false;

Expand Down
9 changes: 5 additions & 4 deletions src/core/geometry/qgspoint.cpp
Expand Up @@ -169,12 +169,13 @@ bool QgsPoint::fromWkt( const QString &wkt )
return false;
mWkbType = parts.first;

if ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 )
QString secondWithoutParentheses = parts.second;
secondWithoutParentheses = secondWithoutParentheses.remove( '(' ).remove( ')' ).simplified().remove( ' ' );
parts.second = parts.second.remove( '(' ).remove( ')' );
if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
secondWithoutParentheses.isEmpty() )
return true;

if ( parts.second.compare( QLatin1String( "NULL" ), Qt::CaseInsensitive ) == 0 )
return false;

QRegularExpression rx( QStringLiteral( "\\s" ) );
QStringList coordinates = parts.second.split( rx, QString::SkipEmptyParts );

Expand Down

0 comments on commit d349fc4

Please sign in to comment.