24 #include <QStringList>
25 #include <QTextStream>
28 #include <netinet/in.h>
44 bool honourAxisOrientation,
45 bool invertAxisOrientation )
48 , mGMLVersion( gmlVersion )
49 , mFilterVersion( filterVersion )
50 , mGeometryName( geometryName )
52 , mInvertAxisOrientation( invertAxisOrientation )
53 , mFilterPrefix(( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"fes" :
"ogc" )
54 , mPropertyName(( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"ValueReference" :
"PropertyName" )
63 mInvertAxisOrientation = !mInvertAxisOrientation;
73 if ( !( geomType ==
"Point" || geomType ==
"LineString" || geomType ==
"Polygon" ||
74 geomType ==
"MultiPoint" || geomType ==
"MultiLineString" || geomType ==
"MultiPolygon" ||
75 geomType ==
"Box" || geomType ==
"Envelope" ) )
78 if ( geometryChild.
isNull() )
82 geometryTypeElement = geometryChild.
toElement();
83 geomType = geometryTypeElement.
tagName();
86 if ( !( geomType ==
"Point" || geomType ==
"LineString" || geomType ==
"Polygon" ||
87 geomType ==
"MultiPoint" || geomType ==
"MultiLineString" || geomType ==
"MultiPolygon" ||
88 geomType ==
"Box" || geomType ==
"Envelope" ) )
91 if ( geomType ==
"Point" )
93 return geometryFromGMLPoint( geometryTypeElement );
95 else if ( geomType ==
"LineString" )
97 return geometryFromGMLLineString( geometryTypeElement );
99 else if ( geomType ==
"Polygon" )
101 return geometryFromGMLPolygon( geometryTypeElement );
103 else if ( geomType ==
"MultiPoint" )
105 return geometryFromGMLMultiPoint( geometryTypeElement );
107 else if ( geomType ==
"MultiLineString" )
109 return geometryFromGMLMultiLineString( geometryTypeElement );
111 else if ( geomType ==
"MultiPolygon" )
113 return geometryFromGMLMultiPolygon( geometryTypeElement );
115 else if ( geomType ==
"Box" )
119 else if ( geomType ==
"Envelope" )
132 QString xml =
QString(
"<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>" ).
arg( GML_NAMESPACE, xmlString );
149 if ( readGMLCoordinates( pointCoordinate, coordElement ) != 0 )
157 if ( posList.
size() < 1 )
162 if ( readGMLPositions( pointCoordinate, posElement ) != 0 )
168 if ( pointCoordinate.
size() < 1 )
174 char e = htonl( 1 ) != 1;
175 double x = point_it->x();
176 double y = point_it->y();
177 int size = 1 +
sizeof( int ) + 2 *
sizeof(
double );
180 unsigned char* wkb =
new unsigned char[size];
183 memcpy( &( wkb )[wkbPosition], &e, 1 );
185 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
186 wkbPosition +=
sizeof( int );
187 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
188 wkbPosition +=
sizeof( double );
189 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
204 if ( readGMLCoordinates( lineCoordinates, coordElement ) != 0 )
212 if ( posList.
size() < 1 )
217 if ( readGMLPositions( lineCoordinates, posElement ) != 0 )
223 char e = htonl( 1 ) != 1;
224 int size = 1 + 2 *
sizeof( int ) + lineCoordinates.
size() * 2 *
sizeof( double );
227 unsigned char* wkb =
new unsigned char[size];
231 int nPoints = lineCoordinates.
size();
234 memcpy( &( wkb )[wkbPosition], &e, 1 );
236 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
237 wkbPosition +=
sizeof( int );
238 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
239 wkbPosition +=
sizeof( int );
242 for ( iter = lineCoordinates.
begin(); iter != lineCoordinates.
end(); ++iter )
246 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
247 wkbPosition +=
sizeof( double );
248 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
249 wkbPosition +=
sizeof( double );
265 if ( !outerBoundaryList.
isEmpty() )
268 if ( coordinatesElement.
isNull() )
272 if ( readGMLCoordinates( exteriorPointList, coordinatesElement ) != 0 )
276 ringCoordinates.
push_back( exteriorPointList );
280 for (
int i = 0; i < innerBoundaryList.
size(); ++i )
284 if ( coordinatesElement.
isNull() )
288 if ( readGMLCoordinates( interiorPointList, coordinatesElement ) != 0 )
292 ringCoordinates.
push_back( interiorPointList );
299 if ( exteriorList.
size() < 1 )
304 if ( posElement.
isNull() )
308 if ( readGMLPositions( exteriorPointList, posElement ) != 0 )
312 ringCoordinates.
push_back( exteriorPointList );
316 for (
int i = 0; i < interiorList.
size(); ++i )
320 if ( posElement.
isNull() )
324 if ( readGMLPositions( interiorPointList, posElement ) != 0 )
328 ringCoordinates.
push_back( interiorPointList );
333 int nrings = ringCoordinates.
size();
340 npoints += it->size();
342 int size = 1 + 2 *
sizeof( int ) + nrings *
sizeof(
int ) + 2 * npoints *
sizeof( double );
345 unsigned char* wkb =
new unsigned char[size];
348 char e = htonl( 1 ) != 1;
350 int nPointsInRing = 0;
354 memcpy( &( wkb )[wkbPosition], &e, 1 );
356 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
357 wkbPosition +=
sizeof( int );
358 memcpy( &( wkb )[wkbPosition], &nrings,
sizeof(
int ) );
359 wkbPosition +=
sizeof( int );
362 nPointsInRing = it->size();
363 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
364 wkbPosition +=
sizeof( int );
367 for ( iter = it->begin(); iter != it->end(); ++iter )
372 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
373 wkbPosition +=
sizeof( double );
374 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
375 wkbPosition +=
sizeof( double );
389 if ( pointMemberList.
size() < 1 )
397 for (
int i = 0; i < pointMemberList.
size(); ++i )
401 if ( pointNodeList.
size() < 1 )
407 if ( !coordinatesList.
isEmpty() )
409 currentPoint.
clear();
410 if ( readGMLCoordinates( currentPoint, coordinatesList.
at( 0 ).
toElement() ) != 0 )
414 if ( currentPoint.
size() < 1 )
425 if ( posList.
size() < 1 )
429 currentPoint.
clear();
430 if ( readGMLPositions( currentPoint, posList.
at( 0 ).
toElement() ) != 0 )
434 if ( currentPoint.
size() < 1 )
442 int nPoints = pointList.
size();
447 int size = 1 + 2 *
sizeof( int ) + pointList.
size() * ( 2 *
sizeof( double ) + 1 +
sizeof(
int ) );
450 unsigned char* wkb =
new unsigned char[size];
453 char e = htonl( 1 ) != 1;
456 memcpy( &( wkb )[wkbPosition], &e, 1 );
458 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
459 wkbPosition +=
sizeof( int );
460 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
461 wkbPosition +=
sizeof( int );
465 memcpy( &( wkb )[wkbPosition], &e, 1 );
467 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
468 wkbPosition +=
sizeof( int );
470 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
471 wkbPosition +=
sizeof( double );
473 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
474 wkbPosition +=
sizeof( double );
499 if ( !lineStringMemberList.
isEmpty() )
501 for (
int i = 0; i < lineStringMemberList.
size(); ++i )
504 if ( lineStringNodeList.
size() < 1 )
508 currentLineStringElement = lineStringNodeList.
at( 0 ).
toElement();
509 currentCoordList = currentLineStringElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
510 if ( !currentCoordList.
isEmpty() )
513 if ( readGMLCoordinates( currentPointList, currentCoordList.
at( 0 ).
toElement() ) != 0 )
517 lineCoordinates.
push_back( currentPointList );
522 if ( currentPosList.
size() < 1 )
527 if ( readGMLPositions( currentPointList, currentPosList.
at( 0 ).
toElement() ) != 0 )
531 lineCoordinates.
push_back( currentPointList );
538 if ( !lineStringList.
isEmpty() )
540 for (
int i = 0; i < lineStringList.
size(); ++i )
542 currentLineStringElement = lineStringList.
at( i ).
toElement();
543 currentCoordList = currentLineStringElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
544 if ( !currentCoordList.
isEmpty() )
547 if ( readGMLCoordinates( currentPointList, currentCoordList.
at( 0 ).
toElement() ) != 0 )
551 lineCoordinates.
push_back( currentPointList );
557 if ( currentPosList.
size() < 1 )
562 if ( readGMLPositions( currentPointList, currentPosList.
at( 0 ).
toElement() ) != 0 )
566 lineCoordinates.
push_back( currentPointList );
576 int nLines = lineCoordinates.
size();
581 int size = ( lineCoordinates.
size() + 1 ) * ( 1 + 2 *
sizeof(
int ) );
584 size += it->size() * 2 *
sizeof( double );
588 unsigned char* wkb =
new unsigned char[size];
591 char e = htonl( 1 ) != 1;
595 memcpy( &( wkb )[wkbPosition], &e, 1 );
597 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
598 wkbPosition +=
sizeof( int );
599 memcpy( &( wkb )[wkbPosition], &nLines,
sizeof(
int ) );
600 wkbPosition +=
sizeof( int );
604 memcpy( &( wkb )[wkbPosition], &e, 1 );
606 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
607 wkbPosition +=
sizeof( int );
608 nPoints = it->size();
609 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
610 wkbPosition +=
sizeof( int );
616 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
617 wkbPosition +=
sizeof( double );
618 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
619 wkbPosition +=
sizeof( double );
653 for (
int i = 0; i < polygonMemberList.
size(); ++i )
656 currentPolygonMemberElement = polygonMemberList.
at( i ).
toElement();
658 if ( polygonList.
size() < 1 )
662 currentPolygonElement = polygonList.
at( 0 ).
toElement();
665 outerBoundaryList = currentPolygonElement.
elementsByTagNameNS( GML_NAMESPACE,
"outerBoundaryIs" );
666 if ( !outerBoundaryList.
isEmpty() )
668 currentOuterBoundaryElement = outerBoundaryList.
at( 0 ).
toElement();
671 linearRingNodeList = currentOuterBoundaryElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
672 if ( linearRingNodeList.
size() < 1 )
676 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
677 currentCoordinateList = currentLinearRingElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
678 if ( currentCoordinateList.
size() < 1 )
682 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.
at( 0 ).
toElement() ) != 0 )
686 currentPolygonList.
push_back( ringCoordinates );
690 for (
int j = 0; j < innerBoundaryList.
size(); ++j )
693 currentInnerBoundaryElement = innerBoundaryList.
at( j ).
toElement();
694 linearRingNodeList = currentInnerBoundaryElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
695 if ( linearRingNodeList.
size() < 1 )
699 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
700 currentCoordinateList = currentLinearRingElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
701 if ( currentCoordinateList.
size() < 1 )
705 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.
at( 0 ).
toElement() ) != 0 )
709 currentPolygonList.
push_back( ringCoordinates );
716 if ( exteriorList.
size() < 1 )
721 currentExteriorElement = exteriorList.
at( 0 ).
toElement();
724 linearRingNodeList = currentExteriorElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
725 if ( linearRingNodeList.
size() < 1 )
729 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
731 if ( currentPosList.
size() < 1 )
735 if ( readGMLPositions( ringPositions, currentPosList.
at( 0 ).
toElement() ) != 0 )
739 currentPolygonList.
push_back( ringPositions );
743 for (
int j = 0; j < interiorList.
size(); ++j )
746 currentInteriorElement = interiorList.
at( j ).
toElement();
747 linearRingNodeList = currentInteriorElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
748 if ( linearRingNodeList.
size() < 1 )
752 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
754 if ( currentPosList.
size() < 1 )
758 if ( readGMLPositions( ringPositions, currentPosList.
at( 0 ).
toElement() ) != 0 )
762 currentPolygonList.
push_back( ringPositions );
765 multiPolygonPoints.
push_back( currentPolygonList );
768 int nPolygons = multiPolygonPoints.
size();
772 int size = 1 + 2 *
sizeof( int );
776 size += 1 + 2 *
sizeof( int );
779 size +=
sizeof( int ) + 2 * iter->size() *
sizeof( double );
784 unsigned char* wkb =
new unsigned char[size];
786 char e = htonl( 1 ) != 1;
793 memcpy( &( wkb )[wkbPosition], &e, 1 );
795 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
796 wkbPosition +=
sizeof( int );
797 memcpy( &( wkb )[wkbPosition], &nPolygons,
sizeof(
int ) );
798 wkbPosition +=
sizeof( int );
804 memcpy( &( wkb )[wkbPosition], &e, 1 );
806 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
807 wkbPosition +=
sizeof( int );
809 memcpy( &( wkb )[wkbPosition], &nRings,
sizeof(
int ) );
810 wkbPosition +=
sizeof( int );
813 nPointsInRing = iter->size();
814 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
815 wkbPosition +=
sizeof( int );
820 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
821 wkbPosition +=
sizeof( double );
822 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
823 wkbPosition +=
sizeof( double );
853 bool conversionSuccess;
858 tupel_coords = ( *it ).
split( coordSeparator, QString::SkipEmptyParts );
859 if ( tupel_coords.
size() < 2 )
863 x = tupel_coords.
at( 0 ).toDouble( &conversionSuccess );
864 if ( !conversionSuccess )
868 y = tupel_coords.
at( 1 ).toDouble( &conversionSuccess );
869 if ( !conversionSuccess )
883 if ( boxElem.
tagName() !=
"Box" )
891 coordSeparator = bElem.
attribute(
"cs" );
895 tupelSeparator = bElem.
attribute(
"ts" );
899 bool ok1, ok2, ok3, ok4;
905 if ( ok1 && ok2 && ok3 && ok4 )
926 bool conversionSuccess;
927 int posSize = pos.
size();
929 int srsDimension = 2;
932 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
933 if ( !conversionSuccess )
940 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
941 if ( !conversionSuccess )
947 for (
int i = 0; i < posSize / srsDimension; i++ )
949 x = pos.
at( i * srsDimension ).toDouble( &conversionSuccess );
950 if ( !conversionSuccess )
954 y = pos.
at( i * srsDimension + 1 ).toDouble( &conversionSuccess );
955 if ( !conversionSuccess )
970 if ( envelopeElem.
tagName() !=
"Envelope" )
974 if ( lowerCornerList.
size() < 1 )
978 if ( upperCornerList.
size() < 1 )
981 bool conversionSuccess;
982 int srsDimension = 2;
987 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
988 if ( !conversionSuccess )
995 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
996 if ( !conversionSuccess )
1003 double xmin = bString.
section(
' ', 0, 0 ).
toDouble( &conversionSuccess );
1004 if ( !conversionSuccess )
1006 double ymin = bString.
section(
' ', 1, 1 ).
toDouble( &conversionSuccess );
1007 if ( !conversionSuccess )
1013 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
1014 if ( !conversionSuccess )
1021 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
1022 if ( !conversionSuccess )
1028 Q_UNUSED( srsDimension );
1030 bString = elem.
text();
1031 double xmax = bString.
section(
' ', 0, 0 ).
toDouble( &conversionSuccess );
1032 if ( !conversionSuccess )
1034 double ymax = bString.
section(
' ', 1, 1 ).
toDouble( &conversionSuccess );
1035 if ( !conversionSuccess )
1051 bool invertAxisOrientation,
1091 bool invertAxisOrientation,
1133 bool invertAxisOrientation,
1137 if ( !geometry || !geometry->
asWkb() )
1147 bool hasZValue =
false;
1154 switch ( geometry->
wkbType() )
1176 switch ( geometry->
wkbType() )
1189 if ( invertAxisOrientation )
1214 for (
int idx = 0; idx < nPoints; ++idx )
1222 wkbPtr.readHeader();
1225 if ( invertAxisOrientation )
1236 wkbPtr +=
sizeof( double );
1241 return multiPointElem;
1261 for (
int idx = 0; idx < nPoints; ++idx )
1269 if ( invertAxisOrientation )
1277 wkbPtr +=
sizeof( double );
1283 return lineStringElem;
1293 multiLineStringElem.
setAttribute(
"gml:id", gmlIdBase );
1295 multiLineStringElem.
setAttribute(
"srsName", srsName );
1300 for (
int jdx = 0; jdx < nLines; jdx++ )
1307 wkbPtr.readHeader();
1314 for (
int idx = 0; idx < nPoints; idx++ )
1322 if ( invertAxisOrientation )
1331 wkbPtr +=
sizeof( double );
1337 lineStringMemberElem.
appendChild( lineStringElem );
1338 multiLineStringElem.
appendChild( lineStringMemberElem );
1340 return multiLineStringElem;
1358 if ( numRings == 0 )
1361 int *ringNumPoints =
new int[numRings];
1363 for (
int idx = 0; idx < numRings; idx++ )
1365 QString boundaryName = ( gmlVersion ==
GML_2_1_2 ) ?
"gml:outerBoundaryIs" :
"gml:exterior";
1368 boundaryName = ( gmlVersion ==
GML_2_1_2 ) ?
"gml:innerBoundaryIs" :
"gml:interior";
1375 ringNumPoints[idx] = nPoints;
1379 for (
int jdx = 0; jdx < nPoints; jdx++ )
1387 if ( invertAxisOrientation )
1395 wkbPtr +=
sizeof( double );
1404 delete [] ringNumPoints;
1420 wkbPtr >> numPolygons;
1422 for (
int kdx = 0; kdx < numPolygons; kdx++ )
1429 wkbPtr.readHeader();
1434 for (
int idx = 0; idx < numRings; idx++ )
1436 QString boundaryName = ( gmlVersion ==
GML_2_1_2 ) ?
"gml:outerBoundaryIs" :
"gml:exterior";
1439 boundaryName = ( gmlVersion ==
GML_2_1_2 ) ?
"gml:innerBoundaryIs" :
"gml:interior";
1449 for (
int jdx = 0; jdx < nPoints; jdx++ )
1457 if ( invertAxisOrientation )
1466 wkbPtr +=
sizeof( double );
1475 multiPolygonElem.
appendChild( polygonMemberElem );
1478 return multiPolygonElem;
1498 for ( ; pointIt != points.
constEnd(); ++pointIt )
1517 if ( points.
size() > 1 )
1523 for ( ; pointIt != points.
constEnd(); ++pointIt )
1554 while ( !cssElem.
isNull() )
1556 cssName = cssElem.
attribute(
"name",
"not_found" );
1557 if ( cssName !=
"not_found" )
1559 elemText = cssElem.
text();
1560 if ( cssName ==
"fill" )
1564 else if ( cssName ==
"fill-opacity" )
1567 double opacity = elemText.
toDouble( &ok );
1590 while ( !childElem.
isNull() )
1597 expr->
d->mParserErrorString = errorMsg;
1602 if ( !expr->
d->mRootNode )
1604 expr->
d->mRootNode = node;
1615 expr->
d->mExp = expr->
dump();
1656 return "PropertyIsLike";
1672 spatialOps <<
"BBOX" <<
"Intersects" <<
"Contains" <<
"Crosses" <<
"Equals"
1673 <<
"Disjoint" <<
"Overlaps" <<
"Touches" <<
"Within";
1676 return spatialOps.
contains( tagName );
1689 return nodeBinaryOperatorFromOgcFilter( element, errorMessage );
1695 return nodeSpatialOperatorFromOgcFilter( element, errorMessage );
1700 if ( element.
tagName() ==
"Not" )
1702 return nodeNotFromOgcFilter( element, errorMessage );
1704 else if ( element.
tagName() ==
"PropertyIsNull" )
1706 return nodePropertyIsNullFromOgcFilter( element, errorMessage );
1708 else if ( element.
tagName() ==
"Literal" )
1710 return nodeLiteralFromOgcFilter( element, errorMessage );
1712 else if ( element.
tagName() ==
"Function" )
1714 return nodeFunctionFromOgcFilter( element, errorMessage );
1716 else if ( element.
tagName() ==
"PropertyName" )
1718 return nodeColumnRefFromOgcFilter( element, errorMessage );
1720 else if ( element.
tagName() ==
"PropertyIsBetween" )
1722 return nodeIsBetweenFromOgcFilter( element, errorMessage );
1725 errorMessage +=
QString(
"unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).
arg( element.
tagName() );
1740 errorMessage =
QString(
"'%1' binary operator not supported." ).
arg( element.
tagName() );
1750 QgsExpression::Node *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
1754 errorMessage =
QString(
"invalid left operand for '%1' binary operator" ).
arg( element.
tagName() );
1764 errorMessage =
QString(
"invalid right operand for '%1' binary operator" ).
arg( element.
tagName() );
1774 wildCard = element.
attribute(
"wildCard" );
1779 singleChar = element.
attribute(
"singleChar" );
1788 if ( !wildCard.
isEmpty() && wildCard !=
"%" )
1790 oprValue.
replace(
'%',
"\\%" );
1793 oprValue.
replace( 0, 1,
"%" );
1797 while (( pos = rx.indexIn( oprValue, pos ) ) != -1 )
1799 oprValue.
replace( pos + 1, 1,
"%" );
1802 oprValue.
replace( escape + wildCard, wildCard );
1804 if ( !singleChar.
isEmpty() && singleChar !=
"_" )
1806 oprValue.
replace(
'_',
"\\_" );
1809 oprValue.
replace( 0, 1,
"_" );
1813 while (( pos = rx.indexIn( oprValue, pos ) ) != -1 )
1815 oprValue.
replace( pos + 1, 1,
"_" );
1818 oprValue.
replace( escape + singleChar, singleChar );
1820 if ( !escape.
isEmpty() && escape !=
"\\" )
1822 oprValue.
replace( escape + escape, escape );
1830 if ( expr == leftOp )
1833 errorMessage =
QString(
"only one operand for '%1' binary operator" ).
arg( element.
tagName() );
1856 if ( childElem.
tagName() !=
"PropertyName" )
1859 childElem.
save( gml2Stream, 0 );
1869 errorMessage =
"No OGC Geometry found";
1884 if ( element.
tagName() !=
"Not" )
1892 errorMessage =
QString(
"invalid operand for '%1' unary operator" ).
arg( element.
tagName() );
1904 errorMessage =
QString(
"ogc:Function expected, got %1" ).
arg( element.
tagName() );
1918 while ( !operandElem.
isNull() )
1943 errorMessage =
QString(
"ogc:Literal expected, got %1" ).
arg( element.
tagName() );
1951 while ( !childNode.
isNull() )
1955 if ( childNode.
nodeType() == QDomNode::ElementNode )
1959 operand = nodeFromOgcFilter( operandElem, errorMessage );
1965 errorMessage =
QString(
"'%1' is an invalid or not supported content for ogc:Literal" ).
arg( operandElem.
tagName() );
2008 if ( element.
isNull() || element.
tagName() !=
"PropertyName" )
2010 errorMessage =
QString(
"ogc:PropertyName expected, got %1" ).
arg( element.
tagName() );
2025 while ( !operandElem.
isNull() )
2027 if ( operandElem.
tagName() ==
"LowerBoundary" )
2030 lowerBound = nodeFromOgcFilter( lowerBoundElem, errorMessage );
2032 else if ( operandElem.
tagName() ==
"UpperBoundary" )
2035 upperBound = nodeFromOgcFilter( upperBoundElem, errorMessage );
2042 operand = nodeFromOgcFilter( operandElem, errorMessage );
2043 operand2 = nodeFromOgcFilter( operandElem, errorMessage );
2046 if ( operand && lowerBound && operand2 && upperBound )
2052 if ( !operand || !lowerBound || !operand2 || !upperBound )
2063 errorMessage =
"missing some required sub-elements in ogc:PropertyIsBetween";
2076 if ( element.
tagName() !=
"PropertyIsNull" )
2097 "geometry",
QString(),
false,
false, errorMessage );
2103 "geometry",
QString(),
false,
false, errorMessage );
2112 bool honourAxisOrientation,
2113 bool invertAxisOrientation,
2119 QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
2123 if ( exprRootElem.
isNull() )
2149 bool honourAxisOrientation,
2150 bool invertAxisOrientation,
2163 QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
2169 if ( !exprRootElem.
isNull() )
2171 return exprRootElem;
2176 *errorMessage =
QObject::tr(
"Node type not supported in expression translation: %1" ).
arg( node->
nodeType() );
2187 return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeUnaryOperator*>( node ) );
2189 return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeBinaryOperator*>( node ) );
2191 return expressionInOperatorToOgcFilter( static_cast<const QgsExpression::NodeInOperator*>( node ) );
2193 return expressionFunctionToOgcFilter( static_cast<const QgsExpression::NodeFunction*>( node ) );
2195 return expressionLiteralToOgcFilter( static_cast<const QgsExpression::NodeLiteral*>( node ) );
2197 return expressionColumnRefToOgcFilter( static_cast<const QgsExpression::NodeColumnRef*>( node ) );
2210 if ( !mErrorMessage.
isEmpty() )
2214 switch ( node->
op() )
2227 mErrorMessage =
QObject::tr(
"This use of unary operator not implemented yet" );
2248 if ( !mErrorMessage.
isEmpty() )
2282 if ( !mErrorMessage.
isEmpty() )
2325 case QVariant::Double:
2328 case QVariant::String:
2354 if ( node->
list()->
list().size() == 1 )
2363 if ( !mErrorMessage.
isEmpty() )
2378 if ( binSpatialOps.
isEmpty() )
2380 binSpatialOps.
insert(
"disjoint",
"Disjoint" );
2381 binSpatialOps.
insert(
"intersects",
"Intersects" );
2382 binSpatialOps.
insert(
"touches",
"Touches" );
2383 binSpatialOps.
insert(
"crosses",
"Crosses" );
2384 binSpatialOps.
insert(
"contains",
"Contains" );
2385 binSpatialOps.
insert(
"overlaps",
"Overlaps" );
2386 binSpatialOps.
insert(
"within",
"Within" );
2388 return binSpatialOps;
2408 return fd->
name() ==
"$geometry";
2420 if ( fnDef->
name() ==
"geom_from_wkt" )
2438 if ( fd->
name() ==
"intersects_bbox" )
2441 Q_ASSERT( argNodes.
count() == 2 );
2467 mErrorMessage =
QObject::tr(
"<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('...'))" );
2475 Q_ASSERT( argNodes.
count() == 2 );
2479 otherNode = argNodes[1];
2481 otherNode = argNodes[0];
2484 mErrorMessage =
QObject::tr(
"Unable to translate spatial operator: at least one must refer to geometry." );
2493 mErrorMessage =
QObject::tr(
"spatial operator: the other operator must be a geometry constructor function" );
2499 if ( otherFnDef->
name() ==
"geom_from_wkt" )
2504 mErrorMessage =
QObject::tr(
"geom_from_wkt: argument must be string literal" );
2510 QString(
"qgis_id_geom_%1" ).arg( mGeomId ) );
2514 else if ( otherFnDef->
name() ==
"geom_from_gml" )
2519 mErrorMessage =
QObject::tr(
"geom_from_gml: argument must be string literal" );
2527 mErrorMessage =
QObject::tr(
"geom_from_gml: unable to parse XML" );
2536 mErrorMessage =
QObject::tr(
"spatial operator: unknown geometry constructor function" );
2552 mErrorMessage =
QObject::tr(
"Special columns/constants are not supported." );
2562 if ( !mErrorMessage.
isEmpty() )
QDomAttr createAttribute(const QString &name)
Class for parsing and evaluation of expressions (formerly called "search strings").
static const QString GML32_NAMESPACE
virtual NodeType nodeType() const =0
Abstract virtual that returns the type of this node.
A rectangle specified with double values.
Internal use by QgsOgcUtils.
QDomNodeList elementsByTagNameNS(const QString &nsURI, const QString &localName) const
void setValue(const QString &v)
bool contains(const Key &key) const
QDomNode appendChild(const QDomNode &newChild)
QgsOgcUtilsExprToFilter(QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, QgsOgcUtils::FilterVersion filterVersion, const QString &geometryName, const QString &srsName, bool honourAxisOrientation, bool invertAxisOrientation)
Constructor.
static const QString FES_NAMESPACE
void push_back(const T &value)
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
QString attribute(const QString &name, const QString &defValue) const
A abstract base class for defining QgsExpression functions.
QString nodeValue() const
double yMaximum() const
Get the y maximum value (top side of rectangle)
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QString escape(const QString &str)
const_iterator constEnd() const
const T & at(int i) const
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QDomElement nextSiblingElement(const QString &tagName) const
static bool isGeometryColumn(const QgsExpression::Node *node)
A geometry is the spatial representation of a feature.
static QDomElement rectangleToGMLBox(QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
QDomElement documentElement() const
QString dump() const
Return an expression string, constructed from the internal abstract syntax tree.
bool axisInverted() const
Returns whether axis is inverted (eg.
NodeType nodeType() const
WkbType
Used for symbology operations.
QString & remove(int position, int n)
QDomElement createElementNS(const QString &nsURI, const QString &qName)
QVariant value() const
The value of the literal.
void setNamedColor(const QString &name)
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
const Node * rootNode() const
Returns root node of the expression. Root node is null is parsing has failed.
static QMap< QString, QString > binarySpatialOpsMap()
static QgsRectangle rectangleFromGMLBox(const QDomNode &boxNode)
Read rectangle from GML2 Box.
QDomNode nextSibling() const
QDomNode importNode(const QDomNode &importedNode, bool deep)
static QgsRectangle rectangleFromGMLEnvelope(const QDomNode &envelopeNode)
Read rectangle from GML3 Envelope.
QDomElement toElement() const
static const QList< Function * > & Functions()
static int binaryOperatorFromTagName(const QString &tagName)
QgsWKBTypes::Type readHeader() const
static bool isBinaryOperator(const QString &tagName)
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
QString number(int n, int base)
int count(const T &value) const
const QString & errorMessage() const
Return the error message.
static const QString GML_NAMESPACE
int toInt(bool *ok) const
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
static int functionIndex(const QString &name)
return index of the function in Functions array
bool hasAttribute(const QString &name) const
double xMaximum() const
Get the x maximum value (right side of rectangle)
QString name() const
The name of the column.
void setAttribute(const QString &name, const QString &value)
static QgsGeometry * geometryFromGML(const QString &xmlString)
Static method that creates geometry from GML.
int toInt(bool *ok, int base) const
QString qgsDoubleToString(double a, int precision=17)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
static bool isBinarySpatialOperator(const QString &fnName)
QString name()
The name of the function.
static QString tagNameForSpatialOperator(const QString &fnName)
A class to represent a point.
bool hasChildNodes() const
static const QMap< QString, int > & binaryOperatorsTagNamesMap()
FilterVersion
OGC filter version.
QDomText createTextNode(const QString &value)
BinaryOperator op() const
QDomNode removeChild(const QDomNode &oldChild)
static const QString OGC_NAMESPACE
const Key key(const T &value) const
static bool isSpatialOperator(const QString &tagName)
QString & replace(int position, int n, QChar after)
const_iterator constBegin() const
void save(QTextStream &str, int indent) const
QDomNode firstChild() const
int wkbSize() const
Returns the size of the WKB in asWkb().
static const char * UnaryOperatorText[]
BinaryOperator
list of binary operators
QDomElement expressionNodeToOgcFilter(const QgsExpression::Node *node)
Convert an expression to a OGC filter.
QDomNode cloneNode(bool deep) const
QString escape(const QString &plain)
static QDomElement expressionToOgcFilter(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates OGC filter XML element.
static QDomElement expressionToOgcExpression(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates an OGC expression XML element.
QDomAttr setAttributeNode(const QDomAttr &newAttr)
int params()
The number of parameters this function takes.
QDomElement firstChildElement(const QString &tagName) const
Class for storing a coordinate reference system (CRS)
static QgsExpression * expressionFromOgcFilter(const QDomElement &element)
Parse XML with OGC filter into QGIS expression.
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QDomElement rectangleToGMLEnvelope(QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static QgsGeometry * geometryFromConstExpr(const QgsExpression::Node *node)
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
static QString binaryOperatorToTagName(QgsExpression::BinaryOperator op)
static QColor colorFromOgcFill(const QDomElement &fillElement)
Parse XML with OGC fill into QColor.
void push_back(const T &value)
void setAlphaF(qreal alpha)
double toDouble(bool *ok) const
iterator insert(const Key &key, const T &value)
void append(Node *node)
Takes ownership of the provided node.
static QgsGeometry * fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
void normalize()
Normalize the rectangle so it has non-negative width/height.
const_iterator constEnd() const
QDomElement createElement(const QString &tagName)
const_iterator constBegin() const
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
double xMinimum() const
Get the x minimum value (left side of rectangle)
The QgsOgcUtils class provides various utility functions for conversion between OGC (Open Geospatial ...
bool GMLNamespaceUsed() const
Return whether the gml: namespace is used.
static QDomElement geometryToGML(const QgsGeometry *geometry, QDomDocument &doc, GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
QDomNode at(int index) const
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
const T value(const Key &key) const
static const char * BinaryOperatorText[]