29 #include <QStringList> 30 #include <QTextStream> 34 #include <netinet/in.h> 40 static const QString
GML_NAMESPACE = QStringLiteral(
"http://www.opengis.net/gml" );
41 static const QString GML32_NAMESPACE = QStringLiteral(
"http://www.opengis.net/gml/3.2" );
42 static const QString OGC_NAMESPACE = QStringLiteral(
"http://www.opengis.net/ogc" );
43 static const QString FES_NAMESPACE = QStringLiteral(
"http://www.opengis.net/fes/2.0" );
49 const QString &srsName,
50 bool honourAxisOrientation,
51 bool invertAxisOrientation )
54 , mGMLVersion( gmlVersion )
55 , mFilterVersion( filterVersion )
56 , mGeometryName( geometryName )
58 , mInvertAxisOrientation( invertAxisOrientation )
59 , mFilterPrefix( ( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"fes" :
"ogc" )
60 , mPropertyName( ( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"ValueReference" :
"PropertyName" )
64 if ( !mSrsName.isEmpty() )
70 mInvertAxisOrientation = !mInvertAxisOrientation;
77 QDomElement geometryTypeElement = geometryNode.toElement();
78 QString geomType = geometryTypeElement.tagName();
80 if ( !( geomType == QLatin1String(
"Point" ) || geomType == QLatin1String(
"LineString" ) || geomType == QLatin1String(
"Polygon" ) ||
81 geomType == QLatin1String(
"MultiPoint" ) || geomType == QLatin1String(
"MultiLineString" ) || geomType == QLatin1String(
"MultiPolygon" ) ||
82 geomType == QLatin1String(
"Box" ) || geomType == QLatin1String(
"Envelope" ) ) )
84 QDomNode geometryChild = geometryNode.firstChild();
85 if ( geometryChild.isNull() )
89 geometryTypeElement = geometryChild.toElement();
90 geomType = geometryTypeElement.tagName();
93 if ( !( geomType == QLatin1String(
"Point" ) || geomType == QLatin1String(
"LineString" ) || geomType == QLatin1String(
"Polygon" ) ||
94 geomType == QLatin1String(
"MultiPoint" ) || geomType == QLatin1String(
"MultiLineString" ) || geomType == QLatin1String(
"MultiPolygon" ) ||
95 geomType == QLatin1String(
"Box" ) || geomType == QLatin1String(
"Envelope" ) ) )
98 if ( geomType == QLatin1String(
"Point" ) )
100 return geometryFromGMLPoint( geometryTypeElement );
102 else if ( geomType == QLatin1String(
"LineString" ) )
104 return geometryFromGMLLineString( geometryTypeElement );
106 else if ( geomType == QLatin1String(
"Polygon" ) )
108 return geometryFromGMLPolygon( geometryTypeElement );
110 else if ( geomType == QLatin1String(
"MultiPoint" ) )
112 return geometryFromGMLMultiPoint( geometryTypeElement );
114 else if ( geomType == QLatin1String(
"MultiLineString" ) )
116 return geometryFromGMLMultiLineString( geometryTypeElement );
118 else if ( geomType == QLatin1String(
"MultiPolygon" ) )
120 return geometryFromGMLMultiPolygon( geometryTypeElement );
122 else if ( geomType == QLatin1String(
"Box" ) )
126 else if ( geomType == QLatin1String(
"Envelope" ) )
139 QString xml = QStringLiteral(
"<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>" ).arg(
GML_NAMESPACE, xmlString );
141 if ( !doc.setContent( xml,
true ) )
144 return geometryFromGML( doc.documentElement().firstChildElement() );
148 QgsGeometry QgsOgcUtils::geometryFromGMLPoint(
const QDomElement &geometryElement )
152 QDomNodeList coordList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
153 if ( !coordList.isEmpty() )
155 QDomElement coordElement = coordList.at( 0 ).toElement();
156 if ( readGMLCoordinates( pointCoordinate, coordElement ) != 0 )
163 QDomNodeList posList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"pos" ) );
164 if ( posList.size() < 1 )
168 QDomElement posElement = posList.at( 0 ).toElement();
169 if ( readGMLPositions( pointCoordinate, posElement ) != 0 )
175 if ( pointCoordinate.empty() )
180 QgsPolylineXY::const_iterator point_it = pointCoordinate.constBegin();
181 char e = htonl( 1 ) != 1;
182 double x = point_it->x();
183 double y = point_it->y();
184 int size = 1 +
sizeof( int ) + 2 *
sizeof(
double );
187 unsigned char *wkb =
new unsigned char[size];
190 memcpy( &( wkb )[wkbPosition], &e, 1 );
192 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
193 wkbPosition +=
sizeof( int );
194 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
195 wkbPosition +=
sizeof( double );
196 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
203 QgsGeometry QgsOgcUtils::geometryFromGMLLineString(
const QDomElement &geometryElement )
207 QDomNodeList coordList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
208 if ( !coordList.isEmpty() )
210 QDomElement coordElement = coordList.at( 0 ).toElement();
211 if ( readGMLCoordinates( lineCoordinates, coordElement ) != 0 )
218 QDomNodeList posList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"posList" ) );
219 if ( posList.size() < 1 )
223 QDomElement posElement = posList.at( 0 ).toElement();
224 if ( readGMLPositions( lineCoordinates, posElement ) != 0 )
230 char e = htonl( 1 ) != 1;
231 int size = 1 + 2 *
sizeof( int ) + lineCoordinates.size() * 2 *
sizeof( double );
234 unsigned char *wkb =
new unsigned char[size];
238 int nPoints = lineCoordinates.size();
241 memcpy( &( wkb )[wkbPosition], &e, 1 );
243 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
244 wkbPosition +=
sizeof( int );
245 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
246 wkbPosition +=
sizeof( int );
248 QgsPolylineXY::const_iterator iter;
249 for ( iter = lineCoordinates.constBegin(); iter != lineCoordinates.constEnd(); ++iter )
253 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
254 wkbPosition +=
sizeof( double );
255 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
256 wkbPosition +=
sizeof( double );
264 QgsGeometry QgsOgcUtils::geometryFromGMLPolygon(
const QDomElement &geometryElement )
271 QDomNodeList outerBoundaryList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"outerBoundaryIs" ) );
272 if ( !outerBoundaryList.isEmpty() )
274 QDomElement coordinatesElement = outerBoundaryList.at( 0 ).firstChild().firstChild().toElement();
275 if ( coordinatesElement.isNull() )
279 if ( readGMLCoordinates( exteriorPointList, coordinatesElement ) != 0 )
283 ringCoordinates.push_back( exteriorPointList );
286 QDomNodeList innerBoundaryList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"innerBoundaryIs" ) );
287 for (
int i = 0; i < innerBoundaryList.size(); ++i )
290 coordinatesElement = innerBoundaryList.at( i ).firstChild().firstChild().toElement();
291 if ( coordinatesElement.isNull() )
295 if ( readGMLCoordinates( interiorPointList, coordinatesElement ) != 0 )
299 ringCoordinates.push_back( interiorPointList );
305 QDomNodeList exteriorList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"exterior" ) );
306 if ( exteriorList.size() < 1 )
310 QDomElement posElement = exteriorList.at( 0 ).firstChild().firstChild().toElement();
311 if ( posElement.isNull() )
315 if ( readGMLPositions( exteriorPointList, posElement ) != 0 )
319 ringCoordinates.push_back( exteriorPointList );
322 QDomNodeList interiorList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"interior" ) );
323 for (
int i = 0; i < interiorList.size(); ++i )
326 QDomElement posElement = interiorList.at( i ).firstChild().firstChild().toElement();
327 if ( posElement.isNull() )
331 if ( readGMLPositions( interiorPointList, posElement ) != 0 )
335 ringCoordinates.push_back( interiorPointList );
340 int nrings = ringCoordinates.size();
345 for ( QgsMultiPolylineXY::const_iterator it = ringCoordinates.constBegin(); it != ringCoordinates.constEnd(); ++it )
347 npoints += it->size();
349 int size = 1 + 2 *
sizeof( int ) + nrings *
sizeof(
int ) + 2 * npoints *
sizeof( double );
352 unsigned char *wkb =
new unsigned char[size];
355 char e = htonl( 1 ) != 1;
357 int nPointsInRing = 0;
361 memcpy( &( wkb )[wkbPosition], &e, 1 );
363 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
364 wkbPosition +=
sizeof( int );
365 memcpy( &( wkb )[wkbPosition], &nrings,
sizeof(
int ) );
366 wkbPosition +=
sizeof( int );
367 for ( QgsMultiPolylineXY::const_iterator it = ringCoordinates.constBegin(); it != ringCoordinates.constEnd(); ++it )
369 nPointsInRing = it->size();
370 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
371 wkbPosition +=
sizeof( int );
373 QgsPolylineXY::const_iterator iter;
374 for ( iter = it->begin(); iter != it->end(); ++iter )
379 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
380 wkbPosition +=
sizeof( double );
381 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
382 wkbPosition +=
sizeof( double );
391 QgsGeometry QgsOgcUtils::geometryFromGMLMultiPoint(
const QDomElement &geometryElement )
395 QDomNodeList pointMemberList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"pointMember" ) );
396 if ( pointMemberList.size() < 1 )
400 QDomNodeList pointNodeList;
402 QDomNodeList coordinatesList;
403 QDomNodeList posList;
404 for (
int i = 0; i < pointMemberList.size(); ++i )
407 pointNodeList = pointMemberList.at( i ).toElement().elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"Point" ) );
408 if ( pointNodeList.size() < 1 )
413 coordinatesList = pointNodeList.at( 0 ).toElement().elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
414 if ( !coordinatesList.isEmpty() )
416 currentPoint.clear();
417 if ( readGMLCoordinates( currentPoint, coordinatesList.at( 0 ).toElement() ) != 0 )
421 if ( currentPoint.empty() )
425 pointList.push_back( ( *currentPoint.begin() ) );
431 posList = pointNodeList.at( 0 ).toElement().elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"pos" ) );
432 if ( posList.size() < 1 )
436 currentPoint.clear();
437 if ( readGMLPositions( currentPoint, posList.at( 0 ).toElement() ) != 0 )
441 if ( currentPoint.empty() )
445 pointList.push_back( ( *currentPoint.begin() ) );
449 int nPoints = pointList.size();
454 int size = 1 + 2 *
sizeof( int ) + pointList.size() * ( 2 *
sizeof( double ) + 1 +
sizeof(
int ) );
457 unsigned char *wkb =
new unsigned char[size];
460 char e = htonl( 1 ) != 1;
463 memcpy( &( wkb )[wkbPosition], &e, 1 );
465 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
466 wkbPosition +=
sizeof( int );
467 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
468 wkbPosition +=
sizeof( int );
470 for ( QgsPolylineXY::const_iterator it = pointList.constBegin(); it != pointList.constEnd(); ++it )
472 memcpy( &( wkb )[wkbPosition], &e, 1 );
474 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
475 wkbPosition +=
sizeof( int );
477 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
478 wkbPosition +=
sizeof( double );
480 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
481 wkbPosition +=
sizeof( double );
489 QgsGeometry QgsOgcUtils::geometryFromGMLMultiLineString(
const QDomElement &geometryElement )
500 QList< QgsPolylineXY > lineCoordinates;
501 QDomElement currentLineStringElement;
502 QDomNodeList currentCoordList;
503 QDomNodeList currentPosList;
505 QDomNodeList lineStringMemberList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"lineStringMember" ) );
506 if ( !lineStringMemberList.isEmpty() )
508 for (
int i = 0; i < lineStringMemberList.size(); ++i )
510 QDomNodeList lineStringNodeList = lineStringMemberList.at( i ).toElement().elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"LineString" ) );
511 if ( lineStringNodeList.size() < 1 )
515 currentLineStringElement = lineStringNodeList.at( 0 ).toElement();
516 currentCoordList = currentLineStringElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
517 if ( !currentCoordList.isEmpty() )
520 if ( readGMLCoordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
524 lineCoordinates.push_back( currentPointList );
528 currentPosList = currentLineStringElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"posList" ) );
529 if ( currentPosList.size() < 1 )
534 if ( readGMLPositions( currentPointList, currentPosList.at( 0 ).toElement() ) != 0 )
538 lineCoordinates.push_back( currentPointList );
544 QDomNodeList lineStringList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"LineString" ) );
545 if ( !lineStringList.isEmpty() )
547 for (
int i = 0; i < lineStringList.size(); ++i )
549 currentLineStringElement = lineStringList.at( i ).toElement();
550 currentCoordList = currentLineStringElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
551 if ( !currentCoordList.isEmpty() )
554 if ( readGMLCoordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
558 lineCoordinates.push_back( currentPointList );
563 currentPosList = currentLineStringElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"posList" ) );
564 if ( currentPosList.size() < 1 )
569 if ( readGMLPositions( currentPointList, currentPosList.at( 0 ).toElement() ) != 0 )
573 lineCoordinates.push_back( currentPointList );
583 int nLines = lineCoordinates.size();
588 int size = ( lineCoordinates.size() + 1 ) * ( 1 + 2 *
sizeof(
int ) );
589 for ( QList< QgsPolylineXY >::const_iterator it = lineCoordinates.constBegin(); it != lineCoordinates.constEnd(); ++it )
591 size += it->size() * 2 *
sizeof( double );
595 unsigned char *wkb =
new unsigned char[size];
598 char e = htonl( 1 ) != 1;
602 memcpy( &( wkb )[wkbPosition], &e, 1 );
604 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
605 wkbPosition +=
sizeof( int );
606 memcpy( &( wkb )[wkbPosition], &nLines,
sizeof(
int ) );
607 wkbPosition +=
sizeof( int );
609 for ( QList< QgsPolylineXY >::const_iterator it = lineCoordinates.constBegin(); it != lineCoordinates.constEnd(); ++it )
611 memcpy( &( wkb )[wkbPosition], &e, 1 );
613 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
614 wkbPosition +=
sizeof( int );
615 nPoints = it->size();
616 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
617 wkbPosition +=
sizeof( int );
618 for ( QgsPolylineXY::const_iterator iter = it->begin(); iter != it->end(); ++iter )
623 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
624 wkbPosition +=
sizeof( double );
625 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
626 wkbPosition +=
sizeof( double );
635 QgsGeometry QgsOgcUtils::geometryFromGMLMultiPolygon(
const QDomElement &geometryElement )
639 QDomElement currentPolygonMemberElement;
640 QDomNodeList polygonList;
641 QDomElement currentPolygonElement;
643 QDomNodeList outerBoundaryList;
644 QDomElement currentOuterBoundaryElement;
645 QDomNodeList innerBoundaryList;
646 QDomElement currentInnerBoundaryElement;
648 QDomNodeList exteriorList;
649 QDomElement currentExteriorElement;
650 QDomElement currentInteriorElement;
651 QDomNodeList interiorList;
653 QDomNodeList linearRingNodeList;
654 QDomElement currentLinearRingElement;
656 QDomNodeList currentCoordinateList;
657 QDomNodeList currentPosList;
659 QDomNodeList polygonMemberList = geometryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"polygonMember" ) );
661 for (
int i = 0; i < polygonMemberList.size(); ++i )
663 currentPolygonList.resize( 0 );
664 currentPolygonMemberElement = polygonMemberList.at( i ).toElement();
665 polygonList = currentPolygonMemberElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"Polygon" ) );
666 if ( polygonList.size() < 1 )
670 currentPolygonElement = polygonList.at( 0 ).toElement();
673 outerBoundaryList = currentPolygonElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"outerBoundaryIs" ) );
674 if ( !outerBoundaryList.isEmpty() )
676 currentOuterBoundaryElement = outerBoundaryList.at( 0 ).toElement();
679 linearRingNodeList = currentOuterBoundaryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"LinearRing" ) );
680 if ( linearRingNodeList.size() < 1 )
684 currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
685 currentCoordinateList = currentLinearRingElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
686 if ( currentCoordinateList.size() < 1 )
690 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
694 currentPolygonList.push_back( ringCoordinates );
697 QDomNodeList innerBoundaryList = currentPolygonElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"innerBoundaryIs" ) );
698 for (
int j = 0; j < innerBoundaryList.size(); ++j )
701 currentInnerBoundaryElement = innerBoundaryList.at( j ).toElement();
702 linearRingNodeList = currentInnerBoundaryElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"LinearRing" ) );
703 if ( linearRingNodeList.size() < 1 )
707 currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
708 currentCoordinateList = currentLinearRingElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"coordinates" ) );
709 if ( currentCoordinateList.size() < 1 )
713 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
717 currentPolygonList.push_back( ringCoordinates );
723 exteriorList = currentPolygonElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"exterior" ) );
724 if ( exteriorList.size() < 1 )
729 currentExteriorElement = exteriorList.at( 0 ).toElement();
732 linearRingNodeList = currentExteriorElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"LinearRing" ) );
733 if ( linearRingNodeList.size() < 1 )
737 currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
738 currentPosList = currentLinearRingElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"posList" ) );
739 if ( currentPosList.size() < 1 )
743 if ( readGMLPositions( ringPositions, currentPosList.at( 0 ).toElement() ) != 0 )
747 currentPolygonList.push_back( ringPositions );
750 QDomNodeList interiorList = currentPolygonElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"interior" ) );
751 for (
int j = 0; j < interiorList.size(); ++j )
754 currentInteriorElement = interiorList.at( j ).toElement();
755 linearRingNodeList = currentInteriorElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"LinearRing" ) );
756 if ( linearRingNodeList.size() < 1 )
760 currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
761 currentPosList = currentLinearRingElement.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"posList" ) );
762 if ( currentPosList.size() < 1 )
766 if ( readGMLPositions( ringPositions, currentPosList.at( 0 ).toElement() ) != 0 )
770 currentPolygonList.push_back( ringPositions );
773 multiPolygonPoints.push_back( currentPolygonList );
776 int nPolygons = multiPolygonPoints.size();
780 int size = 1 + 2 *
sizeof( int );
782 for ( QgsMultiPolygonXY::const_iterator it = multiPolygonPoints.constBegin(); it != multiPolygonPoints.constEnd(); ++it )
784 size += 1 + 2 *
sizeof( int );
785 for ( QgsPolygonXY::const_iterator iter = it->begin(); iter != it->end(); ++iter )
787 size +=
sizeof( int ) + 2 * iter->size() *
sizeof( double );
792 unsigned char *wkb =
new unsigned char[size];
794 char e = htonl( 1 ) != 1;
801 memcpy( &( wkb )[wkbPosition], &e, 1 );
803 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
804 wkbPosition +=
sizeof( int );
805 memcpy( &( wkb )[wkbPosition], &nPolygons,
sizeof(
int ) );
806 wkbPosition +=
sizeof( int );
810 for ( QgsMultiPolygonXY::const_iterator it = multiPolygonPoints.constBegin(); it != multiPolygonPoints.constEnd(); ++it )
812 memcpy( &( wkb )[wkbPosition], &e, 1 );
814 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
815 wkbPosition +=
sizeof( int );
817 memcpy( &( wkb )[wkbPosition], &nRings,
sizeof(
int ) );
818 wkbPosition +=
sizeof( int );
819 for ( QgsPolygonXY::const_iterator iter = it->begin(); iter != it->end(); ++iter )
821 nPointsInRing = iter->size();
822 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
823 wkbPosition +=
sizeof( int );
824 for ( QgsPolylineXY::const_iterator iterator = iter->begin(); iterator != iter->end(); ++iterator )
828 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
829 wkbPosition +=
sizeof( double );
830 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
831 wkbPosition +=
sizeof( double );
841 bool QgsOgcUtils::readGMLCoordinates(
QgsPolylineXY &coords,
const QDomElement &elem )
843 QString coordSeparator = QStringLiteral(
"," );
844 QString tupelSeparator = QStringLiteral(
" " );
849 if ( elem.hasAttribute( QStringLiteral(
"cs" ) ) )
851 coordSeparator = elem.attribute( QStringLiteral(
"cs" ) );
853 if ( elem.hasAttribute( QStringLiteral(
"ts" ) ) )
855 tupelSeparator = elem.attribute( QStringLiteral(
"ts" ) );
858 QStringList tupels = elem.text().split( tupelSeparator, QString::SkipEmptyParts );
859 QStringList tupel_coords;
861 bool conversionSuccess;
863 QStringList::const_iterator it;
864 for ( it = tupels.constBegin(); it != tupels.constEnd(); ++it )
866 tupel_coords = ( *it ).split( coordSeparator, QString::SkipEmptyParts );
867 if ( tupel_coords.size() < 2 )
871 x = tupel_coords.at( 0 ).toDouble( &conversionSuccess );
872 if ( !conversionSuccess )
876 y = tupel_coords.at( 1 ).toDouble( &conversionSuccess );
877 if ( !conversionSuccess )
890 QDomElement boxElem = boxNode.toElement();
891 if ( boxElem.tagName() != QLatin1String(
"Box" ) )
894 QDomElement bElem = boxElem.firstChild().toElement();
895 QString coordSeparator = QStringLiteral(
"," );
896 QString tupelSeparator = QStringLiteral(
" " );
897 if ( bElem.hasAttribute( QStringLiteral(
"cs" ) ) )
899 coordSeparator = bElem.attribute( QStringLiteral(
"cs" ) );
901 if ( bElem.hasAttribute( QStringLiteral(
"ts" ) ) )
903 tupelSeparator = bElem.attribute( QStringLiteral(
"ts" ) );
906 QString bString = bElem.text();
907 bool ok1, ok2, ok3, ok4;
908 double xmin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 0, 0 ).toDouble( &ok1 );
909 double ymin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 1, 1 ).toDouble( &ok2 );
910 double xmax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 0, 0 ).toDouble( &ok3 );
911 double ymax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 1, 1 ).toDouble( &ok4 );
913 if ( ok1 && ok2 && ok3 && ok4 )
922 bool QgsOgcUtils::readGMLPositions(
QgsPolylineXY &coords,
const QDomElement &elem )
926 QStringList pos = elem.text().split(
' ', QString::SkipEmptyParts );
928 bool conversionSuccess;
929 int posSize = pos.size();
931 int srsDimension = 2;
932 if ( elem.hasAttribute( QStringLiteral(
"srsDimension" ) ) )
934 srsDimension = elem.attribute( QStringLiteral(
"srsDimension" ) ).toInt( &conversionSuccess );
935 if ( !conversionSuccess )
940 else if ( elem.hasAttribute( QStringLiteral(
"dimension" ) ) )
942 srsDimension = elem.attribute( QStringLiteral(
"dimension" ) ).toInt( &conversionSuccess );
943 if ( !conversionSuccess )
949 for (
int i = 0; i < posSize / srsDimension; i++ )
951 x = pos.at( i * srsDimension ).toDouble( &conversionSuccess );
952 if ( !conversionSuccess )
956 y = pos.at( i * srsDimension + 1 ).toDouble( &conversionSuccess );
957 if ( !conversionSuccess )
971 QDomElement envelopeElem = envelopeNode.toElement();
972 if ( envelopeElem.tagName() != QLatin1String(
"Envelope" ) )
975 QDomNodeList lowerCornerList = envelopeElem.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"lowerCorner" ) );
976 if ( lowerCornerList.size() < 1 )
979 QDomNodeList upperCornerList = envelopeElem.elementsByTagNameNS(
GML_NAMESPACE, QStringLiteral(
"upperCorner" ) );
980 if ( upperCornerList.size() < 1 )
983 bool conversionSuccess;
984 int srsDimension = 2;
986 QDomElement elem = lowerCornerList.at( 0 ).toElement();
987 if ( elem.hasAttribute( QStringLiteral(
"srsDimension" ) ) )
989 srsDimension = elem.attribute( QStringLiteral(
"srsDimension" ) ).toInt( &conversionSuccess );
990 if ( !conversionSuccess )
995 else if ( elem.hasAttribute( QStringLiteral(
"dimension" ) ) )
997 srsDimension = elem.attribute( QStringLiteral(
"dimension" ) ).toInt( &conversionSuccess );
998 if ( !conversionSuccess )
1003 QString bString = elem.text();
1005 double xmin = bString.section(
' ', 0, 0 ).toDouble( &conversionSuccess );
1006 if ( !conversionSuccess )
1008 double ymin = bString.section(
' ', 1, 1 ).toDouble( &conversionSuccess );
1009 if ( !conversionSuccess )
1012 elem = upperCornerList.at( 0 ).toElement();
1013 if ( elem.hasAttribute( QStringLiteral(
"srsDimension" ) ) )
1015 srsDimension = elem.attribute( QStringLiteral(
"srsDimension" ) ).toInt( &conversionSuccess );
1016 if ( !conversionSuccess )
1021 else if ( elem.hasAttribute( QStringLiteral(
"dimension" ) ) )
1023 srsDimension = elem.attribute( QStringLiteral(
"dimension" ) ).toInt( &conversionSuccess );
1024 if ( !conversionSuccess )
1030 Q_UNUSED( srsDimension );
1032 bString = elem.text();
1033 double xmax = bString.section(
' ', 0, 0 ).toDouble( &conversionSuccess );
1034 if ( !conversionSuccess )
1036 double ymax = bString.section(
' ', 1, 1 ).toDouble( &conversionSuccess );
1037 if ( !conversionSuccess )
1048 return rectangleToGMLBox( box, doc, QString(),
false, precision );
1052 const QString &srsName,
1053 bool invertAxisOrientation,
1058 return QDomElement();
1061 QDomElement boxElem = doc.createElement( QStringLiteral(
"gml:Box" ) );
1062 if ( !srsName.isEmpty() )
1064 boxElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1066 QDomElement coordElem = doc.createElement( QStringLiteral(
"gml:coordinates" ) );
1067 coordElem.setAttribute( QStringLiteral(
"cs" ), QStringLiteral(
"," ) );
1068 coordElem.setAttribute( QStringLiteral(
"ts" ), QStringLiteral(
" " ) );
1070 QString coordString;
1079 QDomText coordText = doc.createTextNode( coordString );
1080 coordElem.appendChild( coordText );
1081 boxElem.appendChild( coordElem );
1088 return rectangleToGMLEnvelope( env, doc, QString(),
false, precision );
1092 const QString &srsName,
1093 bool invertAxisOrientation,
1098 return QDomElement();
1101 QDomElement envElem = doc.createElement( QStringLiteral(
"gml:Envelope" ) );
1102 if ( !srsName.isEmpty() )
1104 envElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1108 QDomElement lowerCornerElem = doc.createElement( QStringLiteral(
"gml:lowerCorner" ) );
1112 QDomText lowerCornerText = doc.createTextNode( posList );
1113 lowerCornerElem.appendChild( lowerCornerText );
1114 envElem.appendChild( lowerCornerElem );
1116 QDomElement upperCornerElem = doc.createElement( QStringLiteral(
"gml:upperCorner" ) );
1120 QDomText upperCornerText = doc.createTextNode( posList );
1121 upperCornerElem.appendChild( upperCornerText );
1122 envElem.appendChild( upperCornerElem );
1129 return geometryToGML( geometry, doc, ( format == QLatin1String(
"GML2" ) ) ? GML_2_1_2 : GML_3_2_1, QString(),
false, QString(), precision );
1134 const QString &srsName,
1135 bool invertAxisOrientation,
1136 const QString &gmlIdBase,
1140 return QDomElement();
1143 QString cs = QStringLiteral(
"," );
1145 QString ts = QStringLiteral(
" " );
1147 QDomElement baseCoordElem;
1149 bool hasZValue =
false;
1151 QByteArray wkb( geometry.
asWkb() );
1155 wkbPtr.readHeader();
1161 return QDomElement();
1164 if ( gmlVersion != GML_2_1_2 )
1172 baseCoordElem = doc.createElement( QStringLiteral(
"gml:pos" ) );
1175 baseCoordElem = doc.createElement( QStringLiteral(
"gml:posList" ) );
1178 baseCoordElem.setAttribute( QStringLiteral(
"srsDimension" ), QStringLiteral(
"2" ) );
1183 baseCoordElem = doc.createElement( QStringLiteral(
"gml:coordinates" ) );
1184 baseCoordElem.setAttribute( QStringLiteral(
"cs" ), cs );
1185 baseCoordElem.setAttribute( QStringLiteral(
"ts" ), ts );
1195 QDomElement pointElem = doc.createElement( QStringLiteral(
"gml:Point" ) );
1196 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1197 pointElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase );
1198 if ( !srsName.isEmpty() )
1199 pointElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1200 QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1204 if ( invertAxisOrientation )
1210 coordElem.appendChild( coordText );
1211 pointElem.appendChild( coordElem );
1220 QDomElement multiPointElem = doc.createElement( QStringLiteral(
"gml:MultiPoint" ) );
1221 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1222 multiPointElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase );
1223 if ( !srsName.isEmpty() )
1224 multiPointElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1229 for (
int idx = 0; idx < nPoints; ++idx )
1231 QDomElement pointMemberElem = doc.createElement( QStringLiteral(
"gml:pointMember" ) );
1232 QDomElement pointElem = doc.createElement( QStringLiteral(
"gml:Point" ) );
1233 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1234 pointElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase + QStringLiteral(
".%1" ).arg( idx + 1 ) );
1235 QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1237 wkbPtr.readHeader();
1240 if ( invertAxisOrientation )
1246 coordElem.appendChild( coordText );
1247 pointElem.appendChild( coordElem );
1251 wkbPtr +=
sizeof( double );
1253 pointMemberElem.appendChild( pointElem );
1254 multiPointElem.appendChild( pointMemberElem );
1256 return multiPointElem;
1264 QDomElement lineStringElem = doc.createElement( QStringLiteral(
"gml:LineString" ) );
1265 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1266 lineStringElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase );
1267 if ( !srsName.isEmpty() )
1268 lineStringElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1274 QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1275 QString coordString;
1276 for (
int idx = 0; idx < nPoints; ++idx )
1284 if ( invertAxisOrientation )
1292 wkbPtr +=
sizeof( double );
1295 QDomText coordText = doc.createTextNode( coordString );
1296 coordElem.appendChild( coordText );
1297 lineStringElem.appendChild( coordElem );
1298 return lineStringElem;
1306 QDomElement multiLineStringElem = doc.createElement( QStringLiteral(
"gml:MultiLineString" ) );
1307 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1308 multiLineStringElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase );
1309 if ( !srsName.isEmpty() )
1310 multiLineStringElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1315 for (
int jdx = 0; jdx < nLines; jdx++ )
1317 QDomElement lineStringMemberElem = doc.createElement( QStringLiteral(
"gml:lineStringMember" ) );
1318 QDomElement lineStringElem = doc.createElement( QStringLiteral(
"gml:LineString" ) );
1319 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1320 lineStringElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase + QStringLiteral(
".%1" ).arg( jdx + 1 ) );
1322 wkbPtr.readHeader();
1327 QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1328 QString coordString;
1329 for (
int idx = 0; idx < nPoints; idx++ )
1337 if ( invertAxisOrientation )
1346 wkbPtr +=
sizeof( double );
1349 QDomText coordText = doc.createTextNode( coordString );
1350 coordElem.appendChild( coordText );
1351 lineStringElem.appendChild( coordElem );
1352 lineStringMemberElem.appendChild( lineStringElem );
1353 multiLineStringElem.appendChild( lineStringMemberElem );
1355 return multiLineStringElem;
1363 QDomElement polygonElem = doc.createElement( QStringLiteral(
"gml:Polygon" ) );
1364 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1365 polygonElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase );
1366 if ( !srsName.isEmpty() )
1367 polygonElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1373 if ( numRings == 0 )
1374 return QDomElement();
1376 int *ringNumPoints =
new int[numRings];
1378 for (
int idx = 0; idx < numRings; idx++ )
1380 QString boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:outerBoundaryIs" :
"gml:exterior";
1383 boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:innerBoundaryIs" :
"gml:interior";
1385 QDomElement boundaryElem = doc.createElement( boundaryName );
1386 QDomElement ringElem = doc.createElement( QStringLiteral(
"gml:LinearRing" ) );
1390 ringNumPoints[idx] = nPoints;
1392 QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1393 QString coordString;
1394 for (
int jdx = 0; jdx < nPoints; jdx++ )
1402 if ( invertAxisOrientation )
1410 wkbPtr +=
sizeof( double );
1413 QDomText coordText = doc.createTextNode( coordString );
1414 coordElem.appendChild( coordText );
1415 ringElem.appendChild( coordElem );
1416 boundaryElem.appendChild( ringElem );
1417 polygonElem.appendChild( boundaryElem );
1419 delete [] ringNumPoints;
1428 QDomElement multiPolygonElem = doc.createElement( QStringLiteral(
"gml:MultiPolygon" ) );
1429 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1430 multiPolygonElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase );
1431 if ( !srsName.isEmpty() )
1432 multiPolygonElem.setAttribute( QStringLiteral(
"srsName" ), srsName );
1435 wkbPtr >> numPolygons;
1437 for (
int kdx = 0; kdx < numPolygons; kdx++ )
1439 QDomElement polygonMemberElem = doc.createElement( QStringLiteral(
"gml:polygonMember" ) );
1440 QDomElement polygonElem = doc.createElement( QStringLiteral(
"gml:Polygon" ) );
1441 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.isEmpty() )
1442 polygonElem.setAttribute( QStringLiteral(
"gml:id" ), gmlIdBase + QStringLiteral(
".%1" ).arg( kdx + 1 ) );
1444 wkbPtr.readHeader();
1449 for (
int idx = 0; idx < numRings; idx++ )
1451 QString boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:outerBoundaryIs" :
"gml:exterior";
1454 boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:innerBoundaryIs" :
"gml:interior";
1456 QDomElement boundaryElem = doc.createElement( boundaryName );
1457 QDomElement ringElem = doc.createElement( QStringLiteral(
"gml:LinearRing" ) );
1462 QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1463 QString coordString;
1464 for (
int jdx = 0; jdx < nPoints; jdx++ )
1472 if ( invertAxisOrientation )
1481 wkbPtr +=
sizeof( double );
1484 QDomText coordText = doc.createTextNode( coordString );
1485 coordElem.appendChild( coordText );
1486 ringElem.appendChild( coordElem );
1487 boundaryElem.appendChild( ringElem );
1488 polygonElem.appendChild( boundaryElem );
1489 polygonMemberElem.appendChild( polygonElem );
1490 multiPolygonElem.appendChild( polygonMemberElem );
1493 return multiPolygonElem;
1496 return QDomElement();
1502 return QDomElement();
1508 return geometryToGML( geometry, doc, QStringLiteral(
"GML2" ), precision );
1511 QDomElement QgsOgcUtils::createGMLCoordinates(
const QgsPolylineXY &points, QDomDocument &doc )
1513 QDomElement coordElem = doc.createElement( QStringLiteral(
"gml:coordinates" ) );
1514 coordElem.setAttribute( QStringLiteral(
"cs" ), QStringLiteral(
"," ) );
1515 coordElem.setAttribute( QStringLiteral(
"ts" ), QStringLiteral(
" " ) );
1517 QString coordString;
1518 QVector<QgsPointXY>::const_iterator pointIt = points.constBegin();
1519 for ( ; pointIt != points.constEnd(); ++pointIt )
1521 if ( pointIt != points.constBegin() )
1530 QDomText coordText = doc.createTextNode( coordString );
1531 coordElem.appendChild( coordText );
1535 QDomElement QgsOgcUtils::createGMLPositions(
const QgsPolylineXY &points, QDomDocument &doc )
1537 QDomElement posElem = doc.createElement( QStringLiteral(
"gml:pos" ) );
1538 if ( points.size() > 1 )
1539 posElem = doc.createElement( QStringLiteral(
"gml:posList" ) );
1540 posElem.setAttribute( QStringLiteral(
"srsDimension" ), QStringLiteral(
"2" ) );
1542 QString coordString;
1543 QVector<QgsPointXY>::const_iterator pointIt = points.constBegin();
1544 for ( ; pointIt != points.constEnd(); ++pointIt )
1546 if ( pointIt != points.constBegin() )
1555 QDomText coordText = doc.createTextNode( coordString );
1556 posElem.appendChild( coordText );
1566 if ( fillElement.isNull() || !fillElement.hasChildNodes() )
1574 QDomElement cssElem = fillElement.firstChildElement( QStringLiteral(
"CssParameter" ) );
1575 while ( !cssElem.isNull() )
1577 cssName = cssElem.attribute( QStringLiteral(
"name" ), QStringLiteral(
"not_found" ) );
1578 if ( cssName != QLatin1String(
"not_found" ) )
1580 elemText = cssElem.text();
1581 if ( cssName == QLatin1String(
"fill" ) )
1583 color.setNamedColor( elemText );
1585 else if ( cssName == QLatin1String(
"fill-opacity" ) )
1588 double opacity = elemText.toDouble( &ok );
1591 color.setAlphaF( opacity );
1596 cssElem = cssElem.nextSiblingElement( QStringLiteral(
"CssParameter" ) );
1610 if ( element.isNull() || !element.hasChildNodes() )
1617 if ( element.firstChild().nodeType() == QDomNode::TextNode )
1627 QDomElement childElem = element.firstChildElement();
1628 while ( !childElem.isNull() )
1640 if ( !expr->d->mRootNode )
1642 expr->d->mRootNode = node;
1649 childElem = childElem.nextSiblingElement();
1653 expr->d->mExp = expr->
dump();
1658 static const QMap<QString, int> BINARY_OPERATORS_TAG_NAMES_MAP
1678 static int binaryOperatorFromTagName(
const QString &tagName )
1681 return BINARY_OPERATORS_TAG_NAMES_MAP.value( tagName, -1 );
1688 return QStringLiteral(
"PropertyIsLike" );
1690 return BINARY_OPERATORS_TAG_NAMES_MAP.key( op, QString() );
1693 static bool isBinaryOperator(
const QString &tagName )
1695 return binaryOperatorFromTagName( tagName ) >= 0;
1699 static bool isSpatialOperator(
const QString &tagName )
1701 static QStringList spatialOps;
1702 if ( spatialOps.isEmpty() )
1704 spatialOps << QStringLiteral(
"BBOX" ) << QStringLiteral(
"Intersects" ) << QStringLiteral(
"Contains" ) << QStringLiteral(
"Crosses" ) << QStringLiteral(
"Equals" )
1705 << QStringLiteral(
"Disjoint" ) << QStringLiteral(
"Overlaps" ) << QStringLiteral(
"Touches" ) << QStringLiteral(
"Within" );
1708 return spatialOps.contains( tagName );
1789 return expressionToOgcFilter( exp, doc, GML_2_1_2, FILTER_OGC_1_0,
1790 QStringLiteral(
"geometry" ), QString(),
false,
false, errorMessage );
1795 return expressionToOgcExpression( exp, doc, GML_2_1_2, FILTER_OGC_1_0,
1796 QStringLiteral(
"geometry" ), QString(),
false,
false, errorMessage );
1804 const QString &srsName,
1805 bool honourAxisOrientation,
1806 bool invertAxisOrientation,
1810 return QDomElement();
1816 QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
1820 if ( exprRootElem.isNull() )
1821 return QDomElement();
1823 QDomElement filterElem =
1824 ( filterVersion == FILTER_FES_2_0 ) ?
1825 doc.createElementNS( FES_NAMESPACE, QStringLiteral(
"fes:Filter" ) ) :
1826 doc.createElementNS( OGC_NAMESPACE, QStringLiteral(
"ogc:Filter" ) );
1829 QDomAttr attr = doc.createAttribute( QStringLiteral(
"xmlns:gml" ) );
1830 if ( gmlVersion == GML_3_2_1 )
1831 attr.setValue( GML32_NAMESPACE );
1834 filterElem.setAttributeNode( attr );
1836 filterElem.appendChild( exprRootElem );
1845 const QString &srsName,
1846 bool honourAxisOrientation,
1847 bool invertAxisOrientation,
1857 return QDomElement();
1865 QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
1871 if ( !exprRootElem.isNull() )
1873 return exprRootElem;
1880 *errorMessage = QObject::tr(
"Node type not supported in expression translation: %1" ).arg( node->
nodeType() );
1884 return QDomElement();
1891 const QList<LayerProperties> &layerProperties,
1892 bool honourAxisOrientation,
1893 bool invertAxisOrientation,
1894 const QMap< QString, QString> &mapUnprefixedTypenameToPrefixedTypename,
1898 return QDomElement();
1901 layerProperties, honourAxisOrientation, invertAxisOrientation,
1902 mapUnprefixedTypenameToPrefixedTypename );
1906 if ( exprRootElem.isNull() )
1907 return QDomElement();
1909 QDomElement filterElem =
1910 ( filterVersion == FILTER_FES_2_0 ) ?
1911 doc.createElementNS( FES_NAMESPACE, QStringLiteral(
"fes:Filter" ) ) :
1912 doc.createElementNS( OGC_NAMESPACE, QStringLiteral(
"ogc:Filter" ) );
1915 QDomAttr attr = doc.createAttribute( QStringLiteral(
"xmlns:gml" ) );
1916 if ( gmlVersion == GML_3_2_1 )
1917 attr.setValue( GML32_NAMESPACE );
1920 filterElem.setAttributeNode( attr );
1922 filterElem.appendChild( exprRootElem );
1934 return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeUnaryOperator *>( node ), expression, context );
1936 return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeBinaryOperator *>( node ), expression, context );
1938 return expressionInOperatorToOgcFilter( static_cast<const QgsExpressionNodeInOperator *>( node ), expression, context );
1940 return expressionFunctionToOgcFilter( static_cast<const QgsExpressionNodeFunction *>( node ), expression, context );
1942 return expressionLiteralToOgcFilter( static_cast<const QgsExpressionNodeLiteral *>( node ), expression, context );
1944 return expressionColumnRefToOgcFilter( static_cast<const QgsExpressionNodeColumnRef *>( node ), expression, context );
1947 mErrorMessage = QObject::tr(
"Node type not supported: %1" ).arg( node->
nodeType() );
1948 return QDomElement();
1955 if ( !mErrorMessage.isEmpty() )
1956 return QDomElement();
1959 switch ( node->
op() )
1962 uoElem = mDoc.createElement( mFilterPrefix +
":Literal" );
1967 uoElem.appendChild( mDoc.createTextNode(
"-" + operandElem.text() ) );
1968 mDoc.removeChild( operandElem );
1972 mErrorMessage = QObject::tr(
"This use of unary operator not implemented yet" );
1973 return QDomElement();
1977 uoElem = mDoc.createElement( mFilterPrefix +
":Not" );
1978 uoElem.appendChild( operandElem );
1982 mErrorMessage = QObject::tr(
"Unary operator '%1' not implemented yet" ).arg( node->
text() );
1983 return QDomElement();
1993 if ( !mErrorMessage.isEmpty() )
1994 return QDomElement();
2004 if ( rightLit->
value().isNull() )
2007 QDomElement elem = mDoc.createElement( mFilterPrefix +
":PropertyIsNull" );
2008 elem.appendChild( leftElem );
2012 QDomElement notElem = mDoc.createElement( mFilterPrefix +
":Not" );
2013 notElem.appendChild( elem );
2027 if ( !mErrorMessage.isEmpty() )
2028 return QDomElement();
2031 QString opText = binaryOperatorToTagName( op );
2032 if ( opText.isEmpty() )
2036 mErrorMessage = QObject::tr(
"Binary operator %1 not implemented yet" ).arg( node->
text() );
2037 return QDomElement();
2040 QDomElement boElem = mDoc.createElement( mFilterPrefix +
":" + opText );
2045 boElem.setAttribute( QStringLiteral(
"matchCase" ), QStringLiteral(
"false" ) );
2048 boElem.setAttribute( QStringLiteral(
"wildCard" ), QStringLiteral(
"%" ) );
2049 boElem.setAttribute( QStringLiteral(
"singleChar" ), QStringLiteral(
"_" ) );
2051 boElem.setAttribute( QStringLiteral(
"escape" ), QStringLiteral(
"\\" ) );
2053 boElem.setAttribute( QStringLiteral(
"escapeChar" ), QStringLiteral(
"\\" ) );
2056 boElem.appendChild( leftElem );
2057 boElem.appendChild( rightElem );
2064 Q_UNUSED( expression )
2067 switch ( node->
value().type() )
2070 value = QString::number( node->
value().toInt() );
2072 case QVariant::Double:
2075 case QVariant::String:
2076 value = node->
value().toString();
2078 case QVariant::Date:
2079 value = node->
value().toDate().toString( Qt::ISODate );
2081 case QVariant::DateTime:
2082 value = node->
value().toDateTime().toString( Qt::ISODate );
2086 mErrorMessage = QObject::tr(
"Literal type not supported: %1" ).arg( node->
value().type() );
2087 return QDomElement();
2090 QDomElement litElem = mDoc.createElement( mFilterPrefix +
":Literal" );
2091 litElem.appendChild( mDoc.createTextNode( value ) );
2098 Q_UNUSED( expression )
2100 QDomElement propElem = mDoc.createElement( mFilterPrefix +
":" + mPropertyName );
2101 propElem.appendChild( mDoc.createTextNode( node->
name() ) );
2109 if ( node->
list()->
list().size() == 1 )
2112 QDomElement orElem = mDoc.createElement( mFilterPrefix +
":Or" );
2118 if ( !mErrorMessage.isEmpty() )
2119 return QDomElement();
2121 QDomElement eqElem = mDoc.createElement( mFilterPrefix +
":PropertyIsEqualTo" );
2122 eqElem.appendChild( leftNode.cloneNode() );
2123 eqElem.appendChild( listNode );
2125 orElem.appendChild( eqElem );
2130 QDomElement notElem = mDoc.createElement( mFilterPrefix +
":Not" );
2131 notElem.appendChild( orElem );
2138 static const QMap<QString, QString> BINARY_SPATIAL_OPS_MAP
2140 { QStringLiteral(
"disjoint" ), QStringLiteral(
"Disjoint" ) },
2141 { QStringLiteral(
"intersects" ), QStringLiteral(
"Intersects" )},
2142 { QStringLiteral(
"touches" ), QStringLiteral(
"Touches" ) },
2143 { QStringLiteral(
"crosses" ), QStringLiteral(
"Crosses" ) },
2144 { QStringLiteral(
"contains" ), QStringLiteral(
"Contains" ) },
2145 { QStringLiteral(
"overlaps" ), QStringLiteral(
"Overlaps" ) },
2146 { QStringLiteral(
"within" ), QStringLiteral(
"Within" ) }
2149 static bool isBinarySpatialOperator(
const QString &fnName )
2151 return BINARY_SPATIAL_OPS_MAP.contains( fnName );
2154 static QString tagNameForSpatialOperator(
const QString &fnName )
2156 return BINARY_SPATIAL_OPS_MAP.value( fnName );
2166 return fd->
name() == QLatin1String(
"$geometry" );
2178 if ( fnDef->
name() == QLatin1String(
"geom_from_wkt" ) )
2180 const QList<QgsExpressionNode *> &args = fnNode->
args()->
list();
2196 if ( fd->
name() == QLatin1String(
"intersects_bbox" ) )
2198 QList<QgsExpressionNode *> argNodes = node->
args()->
list();
2199 Q_ASSERT( argNodes.count() == 2 );
2201 QgsGeometry geom = geometryFromConstExpr( argNodes[1] );
2202 if ( !geom.isNull() && isGeometryColumn( argNodes[0] ) )
2212 QDomElement geomProperty = mDoc.createElement( mFilterPrefix +
":" + mPropertyName );
2213 geomProperty.appendChild( mDoc.createTextNode( mGeometryName ) );
2215 QDomElement funcElem = mDoc.createElement( mFilterPrefix +
":BBOX" );
2216 funcElem.appendChild( geomProperty );
2217 funcElem.appendChild( elemBox );
2222 mErrorMessage = QObject::tr(
"<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('…'))" );
2223 return QDomElement();
2227 if ( isBinarySpatialOperator( fd->
name() ) )
2229 QList<QgsExpressionNode *> argNodes = node->
args()->
list();
2230 Q_ASSERT( argNodes.count() == 2 );
2233 if ( isGeometryColumn( argNodes[0] ) )
2234 otherNode = argNodes[1];
2235 else if ( isGeometryColumn( argNodes[1] ) )
2236 otherNode = argNodes[0];
2239 mErrorMessage = QObject::tr(
"Unable to translate spatial operator: at least one must refer to geometry." );
2240 return QDomElement();
2243 QDomElement otherGeomElem;
2248 mErrorMessage = QObject::tr(
"spatial operator: the other operator must be a geometry constructor function" );
2249 return QDomElement();
2254 if ( otherFnDef->
name() == QLatin1String(
"geom_from_wkt" ) )
2259 mErrorMessage = QObject::tr(
"geom_from_wkt: argument must be string literal" );
2260 return QDomElement();
2265 QStringLiteral(
"qgis_id_geom_%1" ).arg( mGeomId ) );
2268 else if ( otherFnDef->
name() == QLatin1String(
"geom_from_gml" ) )
2273 mErrorMessage = QObject::tr(
"geom_from_gml: argument must be string literal" );
2274 return QDomElement();
2277 QDomDocument geomDoc;
2279 if ( !geomDoc.setContent( gml,
true ) )
2281 mErrorMessage = QObject::tr(
"geom_from_gml: unable to parse XML" );
2282 return QDomElement();
2285 QDomNode geomNode = mDoc.importNode( geomDoc.documentElement(), true );
2286 otherGeomElem = geomNode.toElement();
2290 mErrorMessage = QObject::tr(
"spatial operator: unknown geometry constructor function" );
2291 return QDomElement();
2296 QDomElement funcElem = mDoc.createElement( mFilterPrefix +
":" + tagNameForSpatialOperator( fd->
name() ) );
2297 QDomElement geomProperty = mDoc.createElement( mFilterPrefix +
":" + mPropertyName );
2298 geomProperty.appendChild( mDoc.createTextNode( mGeometryName ) );
2299 funcElem.appendChild( geomProperty );
2300 funcElem.appendChild( otherGeomElem );
2304 if ( fd->
isStatic( node, expression, context ) )
2306 QVariant result = fd->
run( node->
args(), context, expression, node );
2308 return expressionLiteralToOgcFilter( &literal, expression, context );
2313 mErrorMessage = QObject::tr(
"Special columns/constants are not supported." );
2314 return QDomElement();
2318 QDomElement funcElem = mDoc.createElement( mFilterPrefix +
":Function" );
2319 funcElem.setAttribute( QStringLiteral(
"name" ), fd->
name() );
2323 if ( !mErrorMessage.isEmpty() )
2324 return QDomElement();
2326 funcElem.appendChild( childElem );
2337 const QList<QgsOgcUtils::LayerProperties> &layerProperties,
2338 bool honourAxisOrientation,
2339 bool invertAxisOrientation,
2340 const QMap< QString, QString> &mapUnprefixedTypenameToPrefixedTypename )
2343 , mGMLVersion( gmlVersion )
2344 , mFilterVersion( filterVersion )
2345 , mLayerProperties( layerProperties )
2346 , mHonourAxisOrientation( honourAxisOrientation )
2347 , mInvertAxisOrientation( invertAxisOrientation )
2348 , mFilterPrefix( ( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"fes" :
"ogc" )
2349 , mPropertyName( ( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"ValueReference" :
"PropertyName" )
2351 , mMapUnprefixedTypenameToPrefixedTypename( mapUnprefixedTypenameToPrefixedTypename )
2360 return toOgcFilter( static_cast<const QgsSQLStatement::NodeUnaryOperator *>( node ) );
2362 return toOgcFilter( static_cast<const QgsSQLStatement::NodeBinaryOperator *>( node ) );
2364 return toOgcFilter( static_cast<const QgsSQLStatement::NodeInOperator *>( node ) );
2366 return toOgcFilter( static_cast<const QgsSQLStatement::NodeBetweenOperator *>( node ) );
2368 return toOgcFilter( static_cast<const QgsSQLStatement::NodeFunction *>( node ) );
2370 return toOgcFilter( static_cast<const QgsSQLStatement::NodeLiteral *>( node ) );
2372 return toOgcFilter( static_cast<const QgsSQLStatement::NodeColumnRef *>( node ) );
2374 return toOgcFilter( static_cast<const QgsSQLStatement::NodeSelect *>( node ) );
2377 mErrorMessage = QObject::tr(
"Node type not supported: %1" ).arg( node->
nodeType() );
2378 return QDomElement();
2387 if ( !mErrorMessage.isEmpty() )
2388 return QDomElement();
2391 switch ( node->
op() )
2394 uoElem = mDoc.createElement( mFilterPrefix +
":Literal" );
2399 uoElem.appendChild( mDoc.createTextNode(
"-" + operandElem.text() ) );
2400 mDoc.removeChild( operandElem );
2404 mErrorMessage = QObject::tr(
"This use of unary operator not implemented yet" );
2405 return QDomElement();
2409 uoElem = mDoc.createElement( mFilterPrefix +
":Not" );
2410 uoElem.appendChild( operandElem );
2415 return QDomElement();
2425 if ( !mErrorMessage.isEmpty() )
2426 return QDomElement();
2436 if ( rightLit->
value().isNull() )
2439 QDomElement elem = mDoc.createElement( mFilterPrefix +
":PropertyIsNull" );
2440 elem.appendChild( leftElem );
2444 QDomElement notElem = mDoc.createElement( mFilterPrefix +
":Not" );
2445 notElem.appendChild( elem );
2459 if ( !mErrorMessage.isEmpty() )
2460 return QDomElement();
2465 opText = QStringLiteral(
"Or" );
2467 opText = QStringLiteral(
"And" );
2469 opText = QStringLiteral(
"PropertyIsEqualTo" );
2471 opText = QStringLiteral(
"PropertyIsNotEqualTo" );
2473 opText = QStringLiteral(
"PropertyIsLessThanOrEqualTo" );
2475 opText = QStringLiteral(
"PropertyIsGreaterThanOrEqualTo" );
2477 opText = QStringLiteral(
"PropertyIsLessThan" );
2479 opText = QStringLiteral(
"PropertyIsGreaterThan" );
2481 opText = QStringLiteral(
"PropertyIsLike" );
2483 opText = QStringLiteral(
"PropertyIsLike" );
2485 if ( opText.isEmpty() )
2489 return QDomElement();
2492 QDomElement boElem = mDoc.createElement( mFilterPrefix +
":" + opText );
2497 boElem.setAttribute( QStringLiteral(
"matchCase" ), QStringLiteral(
"false" ) );
2500 boElem.setAttribute( QStringLiteral(
"wildCard" ), QStringLiteral(
"%" ) );
2501 boElem.setAttribute( QStringLiteral(
"singleChar" ), QStringLiteral(
"_" ) );
2503 boElem.setAttribute( QStringLiteral(
"escape" ), QStringLiteral(
"\\" ) );
2505 boElem.setAttribute( QStringLiteral(
"escapeChar" ), QStringLiteral(
"\\" ) );
2508 boElem.appendChild( leftElem );
2509 boElem.appendChild( rightElem );
2517 switch ( node->
value().type() )
2520 value = QString::number( node->
value().toInt() );
2522 case QVariant::LongLong:
2523 value = QString::number( node->
value().toLongLong() );
2525 case QVariant::Double:
2528 case QVariant::String:
2529 value = node->
value().toString();
2533 mErrorMessage = QObject::tr(
"Literal type not supported: %1" ).arg( node->
value().type() );
2534 return QDomElement();
2537 QDomElement litElem = mDoc.createElement( mFilterPrefix +
":Literal" );
2538 litElem.appendChild( mDoc.createTextNode( value ) );
2545 QDomElement propElem = mDoc.createElement( mFilterPrefix +
":" + mPropertyName );
2546 if ( node->
tableName().isEmpty() || mLayerProperties.size() == 1 )
2547 propElem.appendChild( mDoc.createTextNode( node->
name() ) );
2550 QString tableName( mMapTableAliasToNames[node->
tableName()] );
2551 if ( mMapUnprefixedTypenameToPrefixedTypename.contains( tableName ) )
2552 tableName = mMapUnprefixedTypenameToPrefixedTypename[tableName];
2553 propElem.appendChild( mDoc.createTextNode( tableName +
"/" + node->
name() ) );
2560 if ( node->
list()->
list().size() == 1 )
2563 QDomElement orElem = mDoc.createElement( mFilterPrefix +
":Or" );
2569 if ( !mErrorMessage.isEmpty() )
2570 return QDomElement();
2572 QDomElement eqElem = mDoc.createElement( mFilterPrefix +
":PropertyIsEqualTo" );
2573 eqElem.appendChild( leftNode.cloneNode() );
2574 eqElem.appendChild( listNode );
2576 orElem.appendChild( eqElem );
2581 QDomElement notElem = mDoc.createElement( mFilterPrefix +
":Not" );
2582 notElem.appendChild( orElem );
2591 QDomElement elem = mDoc.createElement( mFilterPrefix +
":PropertyIsBetween" );
2593 QDomElement lowerBoundary = mDoc.createElement( mFilterPrefix +
":LowerBoundary" );
2595 elem.appendChild( lowerBoundary );
2596 QDomElement upperBoundary = mDoc.createElement( mFilterPrefix +
":UpperBoundary" );
2598 elem.appendChild( upperBoundary );
2602 QDomElement notElem = mDoc.createElement( mFilterPrefix +
":Not" );
2603 notElem.appendChild( elem );
2610 static QString mapBinarySpatialToOgc(
const QString &name )
2612 QString nameCompare( name );
2613 if ( name.size() > 3 && name.midRef( 0, 3 ).compare( QLatin1String(
"ST_" ), Qt::CaseInsensitive ) == 0 )
2614 nameCompare = name.mid( 3 );
2615 QStringList spatialOps;
2616 spatialOps << QStringLiteral(
"BBOX" ) << QStringLiteral(
"Intersects" ) << QStringLiteral(
"Contains" ) << QStringLiteral(
"Crosses" ) << QStringLiteral(
"Equals" )
2617 << QStringLiteral(
"Disjoint" ) << QStringLiteral(
"Overlaps" ) << QStringLiteral(
"Touches" ) << QStringLiteral(
"Within" );
2618 Q_FOREACH ( QString op, spatialOps )
2620 if ( nameCompare.compare( op, Qt::CaseInsensitive ) == 0 )
2626 static QString mapTernarySpatialToOgc(
const QString &name )
2628 QString nameCompare( name );
2629 if ( name.size() > 3 && name.midRef( 0, 3 ).compare( QLatin1String(
"ST_" ), Qt::CaseInsensitive ) == 0 )
2630 nameCompare = name.mid( 3 );
2631 if ( nameCompare.compare( QLatin1String(
"DWithin" ), Qt::CaseInsensitive ) == 0 )
2632 return QStringLiteral(
"DWithin" );
2633 if ( nameCompare.compare( QLatin1String(
"Beyond" ), Qt::CaseInsensitive ) == 0 )
2634 return QStringLiteral(
"Beyond" );
2638 QString QgsOgcUtilsSQLStatementToFilter::getGeometryColumnSRSName(
const QgsSQLStatement::Node *node )
2648 if ( prop.
mName.compare( mMapTableAliasToNames[col->
tableName()], Qt::CaseInsensitive ) == 0 &&
2655 if ( !mLayerProperties.empty() &&
2656 mLayerProperties.at( 0 ).mGeometryAttribute.compare( col->
name(), Qt::CaseInsensitive ) == 0 )
2658 return mLayerProperties.at( 0 ).mSRSName;
2664 QList<QgsSQLStatement::Node *> args,
2665 bool lastArgIsSRSName,
2667 bool &axisInversion )
2669 srsName = mCurrentSRSName;
2670 axisInversion = mInvertAxisOrientation;
2672 if ( lastArgIsSRSName )
2677 mErrorMessage = QObject::tr(
"%1: Last argument must be string or integer literal" ).arg( mainNode->
name() );
2681 if ( lit->
value().type() == QVariant::Int )
2685 srsName =
"EPSG:" + QString::number( lit->
value().toInt() );
2689 srsName =
"urn:ogc:def:crs:EPSG::" + QString::number( lit->
value().toInt() );
2694 srsName = lit->
value().toString();
2695 if ( srsName.startsWith( QLatin1String(
"EPSG:" ), Qt::CaseInsensitive ) )
2701 if ( !srsName.isEmpty() )
2707 axisInversion = !axisInversion;
2717 if ( node->
name().compare( QLatin1String(
"ST_GeometryFromText" ), Qt::CaseInsensitive ) == 0 )
2719 QList<QgsSQLStatement::Node *> args = node->
args()->
list();
2720 if ( args.size() != 1 && args.size() != 2 )
2722 mErrorMessage = QObject::tr(
"Function %1 should have 1 or 2 arguments" ).arg( node->
name() );
2723 return QDomElement();
2729 mErrorMessage = QObject::tr(
"%1: First argument must be string literal" ).arg( node->
name() );
2730 return QDomElement();
2735 if ( ! processSRSName( node, args, args.size() == 2, srsName, axisInversion ) )
2737 return QDomElement();
2743 QStringLiteral(
"qgis_id_geom_%1" ).arg( mGeomId ) );
2745 if ( geomElem.isNull() )
2747 mErrorMessage = QObject::tr(
"%1: invalid WKT" ).arg( node->
name() );
2748 return QDomElement();
2755 if ( node->
name().compare( QLatin1String(
"ST_MakeEnvelope" ), Qt::CaseInsensitive ) == 0 )
2757 QList<QgsSQLStatement::Node *> args = node->
args()->
list();
2758 if ( args.size() != 4 && args.size() != 5 )
2760 mErrorMessage = QObject::tr(
"Function %1 should have 4 or 5 arguments" ).arg( node->
name() );
2761 return QDomElement();
2766 for (
int i = 0; i < 4; i++ )
2771 mErrorMessage = QObject::tr(
"%1: Argument %2 must be numeric literal" ).arg( node->
name() ).arg( i + 1 );
2772 return QDomElement();
2776 if ( lit->
value().type() == QVariant::Int )
2777 val = lit->
value().toInt();
2778 else if ( lit->
value().type() == QVariant::LongLong )
2779 val = lit->
value().toLongLong();
2780 else if ( lit->
value().type() == QVariant::Double )
2781 val = lit->
value().toDouble();
2784 mErrorMessage = QObject::tr(
"%1 Argument %2 must be numeric literal" ).arg( node->
name() ).arg( i + 1 );
2785 return QDomElement();
2799 if ( ! processSRSName( node, args, args.size() == 5, srsName, axisInversion ) )
2801 return QDomElement();
2812 if ( node->
name().compare( QLatin1String(
"ST_GeomFromGML" ), Qt::CaseInsensitive ) == 0 )
2814 QList<QgsSQLStatement::Node *> args = node->
args()->
list();
2815 if ( args.size() != 1 )
2817 mErrorMessage = QObject::tr(
"Function %1 should have 1 argument" ).arg( node->
name() );
2818 return QDomElement();
2824 mErrorMessage = QObject::tr(
"%1: Argument must be string literal" ).arg( node->
name() );
2825 return QDomElement();
2828 QDomDocument geomDoc;
2830 if ( !geomDoc.setContent( gml,
true ) )
2832 mErrorMessage = QObject::tr(
"ST_GeomFromGML: unable to parse XML" );
2833 return QDomElement();
2836 QDomNode geomNode = mDoc.importNode( geomDoc.documentElement(), true );
2838 return geomNode.toElement();
2842 QString ogcName( mapBinarySpatialToOgc( node->
name() ) );
2843 if ( !ogcName.isEmpty() )
2845 QList<QgsSQLStatement::Node *> args = node->
args()->
list();
2846 if ( args.size() != 2 )
2848 mErrorMessage = QObject::tr(
"Function %1 should have 2 arguments" ).arg( node->
name() );
2849 return QDomElement();
2852 for (
int i = 0; i < 2; i ++ )
2855 ( static_cast<const QgsSQLStatement::NodeFunction *>( args[i] )->name().compare( QLatin1String(
"ST_GeometryFromText" ), Qt::CaseInsensitive ) == 0 ||
2856 static_cast<const QgsSQLStatement::NodeFunction *>( args[i] )->name().compare( QLatin1String(
"ST_MakeEnvelope" ), Qt::CaseInsensitive ) == 0 ) )
2858 mCurrentSRSName = getGeometryColumnSRSName( args[1 - i] );
2865 QDomElement funcElem = mDoc.createElement( mFilterPrefix +
":" + ogcName );
2869 if ( !mErrorMessage.isEmpty() )
2871 mCurrentSRSName.clear();
2872 return QDomElement();
2875 funcElem.appendChild( childElem );
2878 mCurrentSRSName.clear();
2882 ogcName = mapTernarySpatialToOgc( node->
name() );
2883 if ( !ogcName.isEmpty() )
2885 QList<QgsSQLStatement::Node *> args = node->
args()->
list();
2886 if ( args.size() != 3 )
2888 mErrorMessage = QObject::tr(
"Function %1 should have 3 arguments" ).arg( node->
name() );
2889 return QDomElement();
2892 for (
int i = 0; i < 2; i ++ )
2895 ( static_cast<const QgsSQLStatement::NodeFunction *>( args[i] )->name().compare( QLatin1String(
"ST_GeometryFromText" ), Qt::CaseInsensitive ) == 0 ||
2896 static_cast<const QgsSQLStatement::NodeFunction *>( args[i] )->name().compare( QLatin1String(
"ST_MakeEnvelope" ), Qt::CaseInsensitive ) == 0 ) )
2898 mCurrentSRSName = getGeometryColumnSRSName( args[1 - i] );
2903 QDomElement funcElem = mDoc.createElement( mFilterPrefix +
":" + node->
name().mid( 3 ) );
2904 for (
int i = 0; i < 2; i++ )
2907 if ( !mErrorMessage.isEmpty() )
2909 mCurrentSRSName.clear();
2910 return QDomElement();
2913 funcElem.appendChild( childElem );
2915 mCurrentSRSName.clear();
2920 mErrorMessage = QObject::tr(
"Function %1 3rd argument should be a numeric value or a string made of a numeric value followed by a string" ).arg( node->
name() );
2921 return QDomElement();
2924 if ( lit->
value().isNull() )
2926 mErrorMessage = QObject::tr(
"Function %1 3rd argument should be a numeric value or a string made of a numeric value followed by a string" ).arg( node->
name() );
2927 return QDomElement();
2930 QString unit( QStringLiteral(
"m" ) );
2931 switch ( lit->
value().type() )
2934 distance = QString::number( lit->
value().toInt() );
2936 case QVariant::LongLong:
2937 distance = QString::number( lit->
value().toLongLong() );
2939 case QVariant::Double:
2942 case QVariant::String:
2944 distance = lit->
value().toString();
2945 for (
int i = 0; i < distance.size(); i++ )
2947 if ( !( ( distance[i] >=
'0' && distance[i] <=
'9' ) || distance[i] ==
'-' || distance[i] ==
'.' || distance[i] ==
'e' || distance[i] ==
'E' ) )
2949 unit = distance.mid( i ).trimmed();
2950 distance = distance.mid( 0, i );
2958 mErrorMessage = QObject::tr(
"Literal type not supported: %1" ).arg( lit->
value().type() );
2959 return QDomElement();
2962 QDomElement distanceElem = mDoc.createElement( mFilterPrefix +
":Distance" );
2964 distanceElem.setAttribute( QStringLiteral(
"uom" ), unit );
2966 distanceElem.setAttribute( QStringLiteral(
"unit" ), unit );
2967 distanceElem.appendChild( mDoc.createTextNode( distance ) );
2968 funcElem.appendChild( distanceElem );
2973 QDomElement funcElem = mDoc.createElement( mFilterPrefix +
":Function" );
2974 funcElem.setAttribute( QStringLiteral(
"name" ), node->
name() );
2978 if ( !mErrorMessage.isEmpty() )
2979 return QDomElement();
2981 funcElem.appendChild( childElem );
2987 const QString &leftTable )
2995 QList<QDomElement> listElem;
2996 Q_FOREACH (
const QString &columnName, node->
usingColumns() )
2998 QDomElement eqElem = mDoc.createElement( mFilterPrefix +
":PropertyIsEqualTo" );
2999 QDomElement propElem1 = mDoc.createElement( mFilterPrefix +
":" + mPropertyName );
3000 propElem1.appendChild( mDoc.createTextNode( leftTable +
"/" + columnName ) );
3001 eqElem.appendChild( propElem1 );
3002 QDomElement propElem2 = mDoc.createElement( mFilterPrefix +
":" + mPropertyName );
3003 propElem2.appendChild( mDoc.createTextNode( node->
tableDef()->
name() +
"/" + columnName ) );
3004 eqElem.appendChild( propElem2 );
3005 listElem.append( eqElem );
3008 if ( listElem.size() == 1 )
3012 else if ( listElem.size() > 1 )
3014 QDomElement andElem = mDoc.createElement( mFilterPrefix +
":And" );
3015 Q_FOREACH (
const QDomElement &elem, listElem )
3017 andElem.appendChild( elem );
3022 return QDomElement();
3027 if ( node->
alias().isEmpty() )
3029 mMapTableAliasToNames[ node->
name()] = node->
name();
3033 mMapTableAliasToNames[ node->
alias()] = node->
name();
3039 QList<QDomElement> listElem;
3042 ( node->
tables().size() != 1 || !node->
joins().empty() ) )
3044 mErrorMessage = QObject::tr(
"Joins are only supported with WFS 2.0" );
3045 return QDomElement();
3059 QList< QgsSQLStatement::NodeTableDef *> nodeTables = node->
tables();
3060 QString leftTable = nodeTables.at( nodeTables.length() - 1 )->name();
3063 QDomElement joinElem =
toOgcFilter( join, leftTable );
3064 if ( !mErrorMessage.isEmpty() )
3065 return QDomElement();
3066 listElem.append( joinElem );
3071 if ( node->
where() )
3074 if ( !mErrorMessage.isEmpty() )
3075 return QDomElement();
3076 listElem.append( whereElem );
3080 if ( listElem.size() == 1 )
3084 else if ( listElem.size() > 1 )
3086 QDomElement andElem = mDoc.createElement( mFilterPrefix +
":And" );
3087 Q_FOREACH (
const QDomElement &elem, listElem )
3089 andElem.appendChild( elem );
3094 return QDomElement();
3100 mPropertyName = QStringLiteral(
"PropertyName" );
3101 mPrefix = QStringLiteral(
"ogc" );
3105 mPropertyName = QStringLiteral(
"ValueReference" );
3106 mPrefix = QStringLiteral(
"fes" );
3112 if ( element.isNull() )
3116 if ( isBinaryOperator( element.tagName() ) )
3122 if ( isSpatialOperator( element.tagName() ) )
3128 if ( element.tagName() == QLatin1String(
"Not" ) )
3132 else if ( element.tagName() == QLatin1String(
"PropertyIsNull" ) )
3136 else if ( element.tagName() == QLatin1String(
"Literal" ) )
3140 else if ( element.tagName() == QLatin1String(
"Function" ) )
3144 else if ( element.tagName() == mPropertyName )
3148 else if ( element.tagName() == QLatin1String(
"PropertyIsBetween" ) )
3153 mErrorMessage += QObject::tr(
"unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).arg( element.tagName() );
3159 if ( element.isNull() )
3162 int op = binaryOperatorFromTagName( element.tagName() );
3165 mErrorMessage = QObject::tr(
"'%1' binary operator not supported." ).arg( element.tagName() );
3169 if ( op ==
QgsExpressionNodeBinaryOperator::boLike && element.hasAttribute( QStringLiteral(
"matchCase" ) ) && element.attribute( QStringLiteral(
"matchCase" ) ) == QLatin1String(
"false" ) )
3174 QDomElement operandElem = element.firstChildElement();
3179 mErrorMessage = QObject::tr(
"invalid left operand for '%1' binary operator" ).arg( element.tagName() );
3183 std::unique_ptr<QgsExpressionNode> leftOp( expr->clone() );
3184 for ( operandElem = operandElem.nextSiblingElement(); !operandElem.isNull(); operandElem = operandElem.nextSiblingElement() )
3189 mErrorMessage = QObject::tr(
"invalid right operand for '%1' binary operator" ).arg( element.tagName() );
3196 if ( element.hasAttribute( QStringLiteral(
"wildCard" ) ) )
3198 wildCard = element.attribute( QStringLiteral(
"wildCard" ) );
3201 if ( element.hasAttribute( QStringLiteral(
"singleChar" ) ) )
3203 singleChar = element.attribute( QStringLiteral(
"singleChar" ) );
3205 QString escape = QStringLiteral(
"\\" );
3206 if ( element.hasAttribute( QStringLiteral(
"escape" ) ) )
3208 escape = element.attribute( QStringLiteral(
"escape" ) );
3210 if ( element.hasAttribute( QStringLiteral(
"escapeChar" ) ) )
3212 escape = element.attribute( QStringLiteral(
"escapeChar" ) );
3216 if ( !wildCard.isEmpty() && wildCard != QLatin1String(
"%" ) )
3218 oprValue.replace(
'%', QLatin1String(
"\\%" ) );
3219 if ( oprValue.startsWith( wildCard ) )
3221 oprValue.replace( 0, 1, QStringLiteral(
"%" ) );
3223 QRegExp rx(
"[^" + QRegExp::escape( escape ) +
"](" + QRegExp::escape( wildCard ) +
")" );
3225 while ( ( pos = rx.indexIn( oprValue, pos ) ) != -1 )
3227 oprValue.replace( pos + 1, 1, QStringLiteral(
"%" ) );
3230 oprValue.replace( escape + wildCard, wildCard );
3232 if ( !singleChar.isEmpty() && singleChar != QLatin1String(
"_" ) )
3234 oprValue.replace(
'_', QLatin1String(
"\\_" ) );
3235 if ( oprValue.startsWith( singleChar ) )
3237 oprValue.replace( 0, 1, QStringLiteral(
"_" ) );
3239 QRegExp rx(
"[^" + QRegExp::escape( escape ) +
"](" + QRegExp::escape( singleChar ) +
")" );
3241 while ( ( pos = rx.indexIn( oprValue, pos ) ) != -1 )
3243 oprValue.replace( pos + 1, 1, QStringLiteral(
"_" ) );
3246 oprValue.replace( escape + singleChar, singleChar );
3248 if ( !escape.isEmpty() && escape != QLatin1String(
"\\" ) )
3250 oprValue.replace( escape + escape, escape );
3255 expr.reset(
new QgsExpressionNodeBinaryOperator( static_cast< QgsExpressionNodeBinaryOperator::BinaryOperator >( op ), expr.release(), opRight.release() ) );
3258 if ( expr == leftOp )
3260 mErrorMessage = QObject::tr(
"only one operand for '%1' binary operator" ).arg( element.tagName() );
3274 QDomElement childElem = element.firstChildElement();
3276 while ( !childElem.isNull() && gml2Str.isEmpty() )
3278 if ( childElem.tagName() != mPropertyName )
3280 QTextStream gml2Stream( &gml2Str );
3281 childElem.save( gml2Stream, 0 );
3283 childElem = childElem.nextSiblingElement();
3285 if ( !gml2Str.isEmpty() )
3291 mErrorMessage = QObject::tr(
"No OGC Geometry found" );
3304 if ( element.isNull() || element.tagName() != mPropertyName )
3306 mErrorMessage = QObject::tr(
"%1:PropertyName expected, got %2" ).arg( mPrefix, element.tagName() );
3315 if ( element.isNull() || element.tagName() != QLatin1String(
"Literal" ) )
3317 mErrorMessage = QObject::tr(
"%1:Literal expected, got %2" ).arg( mPrefix, element.tagName() );
3321 std::unique_ptr<QgsExpressionNode> root;
3324 QDomNode childNode = element.firstChild();
3325 while ( !childNode.isNull() )
3327 std::unique_ptr<QgsExpressionNode> operand;
3329 if ( childNode.nodeType() == QDomNode::ElementNode )
3332 const QDomElement operandElem = childNode.toElement();
3336 mErrorMessage = QObject::tr(
"'%1' is an invalid or not supported content for %2:Literal" ).arg( operandElem.tagName(), mPrefix );
3343 QVariant value = childNode.nodeValue();
3345 bool converted =
false;
3350 QDomElement propertyNameElement = element.previousSiblingElement( mPropertyName );
3351 if ( propertyNameElement.isNull() || propertyNameElement.tagName() != mPropertyName )
3353 propertyNameElement = element.nextSiblingElement( mPropertyName );
3355 if ( !propertyNameElement.isNull() || propertyNameElement.tagName() == mPropertyName )
3357 const int fieldIndex = mLayer->
fields().
indexOf( propertyNameElement.firstChild().nodeValue() );
3358 if ( fieldIndex != -1 )
3371 const double d = value.toDouble( &ok );
3384 root = std::move( operand );
3391 childNode = childNode.nextSibling();
3395 return root.release();
3402 if ( element.tagName() != QLatin1String(
"Not" ) )
3405 const QDomElement operandElem = element.firstChildElement();
3409 mErrorMessage = QObject::tr(
"invalid operand for '%1' unary operator" ).arg( element.tagName() );
3419 if ( element.tagName() != QLatin1String(
"PropertyIsNull" ) )
3424 const QDomElement operandElem = element.firstChildElement();
3435 if ( element.isNull() || element.tagName() != QLatin1String(
"Function" ) )
3437 mErrorMessage = QObject::tr(
"%1:Function expected, got %2" ).arg( mPrefix, element.tagName() );
3445 if ( element.attribute( QStringLiteral(
"name" ) ) != funcDef->
name() )
3450 QDomElement operandElem = element.firstChildElement();
3451 while ( !operandElem.isNull() )
3458 args->append( op.release() );
3460 operandElem = operandElem.nextSiblingElement();
3472 std::unique_ptr<QgsExpressionNode> operand;
3473 std::unique_ptr<QgsExpressionNode> lowerBound;
3474 std::unique_ptr<QgsExpressionNode> upperBound;
3476 QDomElement operandElem = element.firstChildElement();
3477 while ( !operandElem.isNull() )
3479 if ( operandElem.tagName() == QLatin1String(
"LowerBoundary" ) )
3481 QDomElement lowerBoundElem = operandElem.firstChildElement();
3484 else if ( operandElem.tagName() == QLatin1String(
"UpperBoundary" ) )
3486 QDomElement upperBoundElem = operandElem.firstChildElement();
3495 if ( operand && lowerBound && upperBound )
3498 operandElem = operandElem.nextSiblingElement();
3501 if ( !operand || !lowerBound || !upperBound )
3503 mErrorMessage = QObject::tr(
"missing some required sub-elements in %1:PropertyIsBetween" ).arg( mPrefix );
3514 return mErrorMessage;
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsSQLStatement::NodeList * list() const
Values list.
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
A rectangle specified with double values.
Internal use by QgsOgcUtils.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
QDomElement expressionNodeToOgcFilter(const QgsExpressionNode *node, QgsExpression *expression, const QgsExpressionContext *context)
Convert an expression to a OGC filter.
QgsExpressionNode * nodeLiteralFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with literal tag.
QgsSQLStatement::Node * onExpr() const
On expression. Will be nullptr if usingColumns() is not empty.
int params() const
The number of parameters this function takes.
void setXMaximum(double x)
Set the maximum x value.
Function with a name and arguments node.
QgsOgcUtilsExprToFilter(QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, QgsOgcUtils::FilterVersion filterVersion, const QString &geometryName, const QString &srsName, bool honourAxisOrientation, bool invertAxisOrientation)
Constructor.
void setExpression(const QString &expression)
Set the expression string, will reset the whole internal structure.
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
QgsExpressionNode * nodeFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document element.
QgsExpressionNode * opRight() const
Returns the node to the right of the operator.
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsExpressionNodeFunction * nodeFunctionFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with functions.
A class to represent a 2D point.
QgsSQLStatement::NodeTableDef * tableDef() const
Table definition.
QString dump() const
Returns an expression string, constructed from the internal abstract syntax tree. ...
QgsSQLStatement::Node * operand() const
Operand.
QgsSQLStatement::Node * where() const
Returns the where clause.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
static const char * BINARY_OPERATOR_TEXT[]
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
QString errorMessage() const
Returns the error message.
bool GMLNamespaceUsed() const
Returns whether the gml: namespace is used.
A geometry is the spatial representation of a feature.
QgsExpressionNode::NodeList * list() const
Returns the list of nodes to search for matching values within.
QgsExpressionNodeUnaryOperator * nodeNotFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with Not operator.
QgsExpressionNode * opLeft() const
Returns the node to the left of the operator.
static QDomElement rectangleToGMLBox(QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
QDomElement toOgcFilter(const QgsSQLStatement::Node *node)
Convert a SQL statement to a OGC filter.
const QgsCoordinateReferenceSystem & crs
Binary logical/arithmetical operator (AND, OR, =, +, ...)
QString name() const
The name of the column.
QString errorMessage() const
Returns the underlying error message, or an empty string in case of no error.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QString name() const
Returns function name.
QgsOgcUtilsSQLStatementToFilter(QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, QgsOgcUtils::FilterVersion filterVersion, const QList< QgsOgcUtils::LayerProperties > &layerProperties, bool honourAxisOrientation, bool invertAxisOrientation, const QMap< QString, QString > &mapUnprefixedTypenameToPrefixedTypename)
Constructor.
QgsExpressionNodeBinaryOperator * nodeBinaryOperatorFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with binary operators.
static QgsRectangle rectangleFromGMLBox(const QDomNode &boxNode)
Read rectangle from GML2 Box.
QgsSQLStatement::Node * node() const
Variable at the left of BETWEEN.
QList< QString > usingColumns() const
Columns referenced by USING.
const QString GML_NAMESPACE
static QgsRectangle rectangleFromGMLEnvelope(const QDomNode &envelopeNode)
Read rectangle from GML3 Envelope.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QgsSQLStatement::Node * minVal() const
Minimum bound.
bool GMLNamespaceUsed() const
Returns whether the gml: namespace is used.
Internal use by QgsOgcUtils.
bool isNotIn() const
Whether this is a NOT IN operator.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
QString text() const
Returns a the name of this operator without the operands.
Class for parsing SQL statements.
Type
The WKB type describes the number of dimensions a geometry has.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QString name() const
Table name.
QString alias() const
Table alias.
static int functionIndex(const QString &name)
Returns index of the function in Functions array.
const QString & geometryName
QgsExpressionNodeFunction * nodeSpatialOperatorFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with spatial operators.
QgsSQLStatement::NodeList * args() const
Returns arguments.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
void setYMinimum(double y)
Set the minimum y value.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
BinaryOperator
list of binary operators
An expression node for value IN or NOT IN clauses.
Literal value (integer, integer64, double, string)
QString errorMessage() const
Returns the error message.
QString name() const
The name of the column.
QList< QgsSQLStatement::NodeTableDef * > tables() const
Returns the list of tables.
Internal use by QgsOgcUtils.
An expression node which takes it value from a feature's field.
QgsExpressionNode * nodeIsBetweenFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with boudnaries operator...
Unary logicial/arithmetical operator ( NOT, - )
QgsSQLStatement::BinaryOperator op() const
Operator.
const QgsSQLStatement::Node * rootNode() const
Returns root node of the statement. Root node is null is parsing has failed.
static QDomElement SQLStatementToOgcFilter(const QgsSQLStatement &statement, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, FilterVersion filterVersion, const QList< LayerProperties > &layerProperties, bool honourAxisOrientation, bool invertAxisOrientation, const QMap< QString, QString > &mapUnprefixedTypenameToPrefixedTypename, QString *errorMessage=nullptr)
Creates OGC filter XML element from the WHERE and JOIN clauses of a SQL statement.
BinaryOperator
list of binary operators
virtual bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
Will be called during prepare to determine if the function is static.
QString mSRSName
SRS name.
Abstract base class for all nodes that can appear in an expression.
Encapsulate a field in an attribute table or data source.
An expression node for expression functions.
static const QList< QgsExpressionFunction * > & Functions()
QgsSQLStatement::Node * maxVal() const
Maximum bound.
bool isNotBetween() const
Whether this is a NOT BETWEEN operator.
FilterVersion
OGC filter version.
QByteArray asWkb() const
Export the geometry to WKB.
'X BETWEEN y and z' operator
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
QString name() const
The name of the function.
Custom exception class for Wkb related exceptions.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
QVariant value() const
The value of the literal.
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QList< QgsSQLStatement::NodeJoin * > joins() const
Returns the list of joins.
A abstract base class for defining QgsExpression functions.
A list of expression nodes.
static QgsGeometry geometryFromGML(const QString &xmlString)
Static method that creates geometry from GML.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
An expression node for literal values.
const QgsExpressionNode * rootNode() const
Returns root node of the expression. Root node is null is parsing has failed.
void setYMaximum(double y)
Set the maximum y value.
static QDomElement expressionToOgcFilter(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates OGC filter XML element.
QList< QgsSQLStatement::Node * > list()
Returns list.
A unary node is either negative as in boolean (not) or as in numbers (minus).
static QDomElement expressionToOgcExpression(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates an OGC expression XML element.
QgsExpressionNodeColumnRef * nodeColumnRefFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with column references.
A binary expression operator, which operates on two values.
bool hasAxisInverted() const
Returns whether axis is inverted (e.g., for WMS 1.3) for the CRS.
This class represents a coordinate reference system (CRS).
static QDomElement geometryToGML(const QgsGeometry &geometry, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
QString text() const
Returns a the name of this operator without the operands.
static QDomElement rectangleToGMLEnvelope(QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static const char * UNARY_OPERATOR_TEXT[]
double xMinimum() const
Returns the x minimum value (left side of rectangle).
QString mGeometryAttribute
Geometry attribute name.
static QColor colorFromOgcFill(const QDomElement &fillElement)
Parse XML with OGC fill into QColor.
QgsOgcUtilsExpressionFromFilter(QgsOgcUtils::FilterVersion version=QgsOgcUtils::FILTER_OGC_1_0, const QgsVectorLayer *layer=nullptr)
Constructor for QgsOgcUtilsExpressionFromFilter.
QString tableName() const
The name of the table. May be empty.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
void normalize()
Normalize the rectangle so it has non-negative width/height.
QgsSQLStatement::UnaryOperator op() const
Operator.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
QgsExpressionNode * node() const
Returns the expression node.
Represents a vector layer which manages a vector based data sets.
'x IN (y, z)' operator
bool isNotIn() const
Returns true if this node is a "NOT IN" operator, or false if the node is a normal "IN" operator...
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.
QgsExpressionNode * operand() const
Returns the node the operator will operate upon.
QgsSQLStatement::Node * node() const
Variable at the left of IN.
The QgsOgcUtils class provides various utility functions for conversion between OGC (Open Geospatial ...
QgsExpressionNodeBinaryOperator::BinaryOperator op() const
Returns the binary operator.
QgsSQLStatement::Node * opLeft() const
Left operand.
QgsField field(int fieldIdx) const
Gets field at particular index (must be in range 0..N-1)
QgsSQLStatement::Node * opRight() const
Right operand.
QgsExpressionNodeBinaryOperator * nodePropertyIsNullFromOgcFilter(const QDomElement &element)
Returns an expression node from a WFS filter embedded in a document with IsNull operator.
void setXMinimum(double x)
Set the minimum x value.
QVariant value() const
The value of the literal.
virtual QgsSQLStatement::NodeType nodeType() const =0
Abstract virtual that returns the type of this node.
int fnIndex() const
Returns the index of the node's function.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.