25 #include <QStringList> 26 #include <QTextStream> 29 #include <netinet/in.h> 45 bool honourAxisOrientation,
46 bool invertAxisOrientation )
49 , mGMLVersion( gmlVersion )
50 , mFilterVersion( filterVersion )
51 , mGeometryName( geometryName )
53 , mInvertAxisOrientation( invertAxisOrientation )
54 , mFilterPrefix(( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"fes" :
"ogc" )
55 , mPropertyName(( filterVersion ==
QgsOgcUtils::FILTER_FES_2_0 ) ?
"ValueReference" :
"PropertyName" )
64 mInvertAxisOrientation = !mInvertAxisOrientation;
74 if ( !( geomType ==
"Point" || geomType ==
"LineString" || geomType ==
"Polygon" ||
75 geomType ==
"MultiPoint" || geomType ==
"MultiLineString" || geomType ==
"MultiPolygon" ||
76 geomType ==
"Box" || geomType ==
"Envelope" ) )
79 if ( geometryChild.
isNull() )
83 geometryTypeElement = geometryChild.
toElement();
84 geomType = geometryTypeElement.
tagName();
87 if ( !( geomType ==
"Point" || geomType ==
"LineString" || geomType ==
"Polygon" ||
88 geomType ==
"MultiPoint" || geomType ==
"MultiLineString" || geomType ==
"MultiPolygon" ||
89 geomType ==
"Box" || geomType ==
"Envelope" ) )
92 if ( geomType ==
"Point" )
94 return geometryFromGMLPoint( geometryTypeElement );
96 else if ( geomType ==
"LineString" )
98 return geometryFromGMLLineString( geometryTypeElement );
100 else if ( geomType ==
"Polygon" )
102 return geometryFromGMLPolygon( geometryTypeElement );
104 else if ( geomType ==
"MultiPoint" )
106 return geometryFromGMLMultiPoint( geometryTypeElement );
108 else if ( geomType ==
"MultiLineString" )
110 return geometryFromGMLMultiLineString( geometryTypeElement );
112 else if ( geomType ==
"MultiPolygon" )
114 return geometryFromGMLMultiPolygon( geometryTypeElement );
116 else if ( geomType ==
"Box" )
120 else if ( geomType ==
"Envelope" )
133 QString xml =
QString(
"<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>" ).
arg( GML_NAMESPACE, xmlString );
150 if ( readGMLCoordinates( pointCoordinate, coordElement ) != 0 )
158 if ( posList.
size() < 1 )
163 if ( readGMLPositions( pointCoordinate, posElement ) != 0 )
169 if ( pointCoordinate.
size() < 1 )
175 char e = htonl( 1 ) != 1;
176 double x = point_it->x();
177 double y = point_it->y();
178 int size = 1 +
sizeof( int ) + 2 *
sizeof(
double );
181 unsigned char* wkb =
new unsigned char[size];
184 memcpy( &( wkb )[wkbPosition], &e, 1 );
186 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
187 wkbPosition +=
sizeof( int );
188 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
189 wkbPosition +=
sizeof( double );
190 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
205 if ( readGMLCoordinates( lineCoordinates, coordElement ) != 0 )
213 if ( posList.
size() < 1 )
218 if ( readGMLPositions( lineCoordinates, posElement ) != 0 )
224 char e = htonl( 1 ) != 1;
225 int size = 1 + 2 *
sizeof( int ) + lineCoordinates.
size() * 2 *
sizeof( double );
228 unsigned char* wkb =
new unsigned char[size];
232 int nPoints = lineCoordinates.
size();
235 memcpy( &( wkb )[wkbPosition], &e, 1 );
237 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
238 wkbPosition +=
sizeof( int );
239 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
240 wkbPosition +=
sizeof( int );
243 for ( iter = lineCoordinates.
begin(); iter != lineCoordinates.
end(); ++iter )
247 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
248 wkbPosition +=
sizeof( double );
249 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
250 wkbPosition +=
sizeof( double );
266 if ( !outerBoundaryList.
isEmpty() )
269 if ( coordinatesElement.
isNull() )
273 if ( readGMLCoordinates( exteriorPointList, coordinatesElement ) != 0 )
277 ringCoordinates.
push_back( exteriorPointList );
281 for (
int i = 0; i < innerBoundaryList.
size(); ++i )
285 if ( coordinatesElement.
isNull() )
289 if ( readGMLCoordinates( interiorPointList, coordinatesElement ) != 0 )
293 ringCoordinates.
push_back( interiorPointList );
300 if ( exteriorList.
size() < 1 )
305 if ( posElement.
isNull() )
309 if ( readGMLPositions( exteriorPointList, posElement ) != 0 )
313 ringCoordinates.
push_back( exteriorPointList );
317 for (
int i = 0; i < interiorList.
size(); ++i )
321 if ( posElement.
isNull() )
325 if ( readGMLPositions( interiorPointList, posElement ) != 0 )
329 ringCoordinates.
push_back( interiorPointList );
334 int nrings = ringCoordinates.
size();
341 npoints += it->size();
343 int size = 1 + 2 *
sizeof( int ) + nrings *
sizeof(
int ) + 2 * npoints *
sizeof( double );
346 unsigned char* wkb =
new unsigned char[size];
349 char e = htonl( 1 ) != 1;
351 int nPointsInRing = 0;
355 memcpy( &( wkb )[wkbPosition], &e, 1 );
357 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
358 wkbPosition +=
sizeof( int );
359 memcpy( &( wkb )[wkbPosition], &nrings,
sizeof(
int ) );
360 wkbPosition +=
sizeof( int );
363 nPointsInRing = it->size();
364 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
365 wkbPosition +=
sizeof( int );
368 for ( iter = it->begin(); iter != it->end(); ++iter )
373 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
374 wkbPosition +=
sizeof( double );
375 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
376 wkbPosition +=
sizeof( double );
390 if ( pointMemberList.
size() < 1 )
398 for (
int i = 0; i < pointMemberList.
size(); ++i )
402 if ( pointNodeList.
size() < 1 )
408 if ( !coordinatesList.
isEmpty() )
410 currentPoint.
clear();
411 if ( readGMLCoordinates( currentPoint, coordinatesList.
at( 0 ).
toElement() ) != 0 )
415 if ( currentPoint.
size() < 1 )
426 if ( posList.
size() < 1 )
430 currentPoint.
clear();
431 if ( readGMLPositions( currentPoint, posList.
at( 0 ).
toElement() ) != 0 )
435 if ( currentPoint.
size() < 1 )
443 int nPoints = pointList.
size();
448 int size = 1 + 2 *
sizeof( int ) + pointList.
size() * ( 2 *
sizeof( double ) + 1 +
sizeof(
int ) );
451 unsigned char* wkb =
new unsigned char[size];
454 char e = htonl( 1 ) != 1;
457 memcpy( &( wkb )[wkbPosition], &e, 1 );
459 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
460 wkbPosition +=
sizeof( int );
461 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
462 wkbPosition +=
sizeof( int );
466 memcpy( &( wkb )[wkbPosition], &e, 1 );
468 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
469 wkbPosition +=
sizeof( int );
471 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
472 wkbPosition +=
sizeof( double );
474 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
475 wkbPosition +=
sizeof( double );
500 if ( !lineStringMemberList.
isEmpty() )
502 for (
int i = 0; i < lineStringMemberList.
size(); ++i )
505 if ( lineStringNodeList.
size() < 1 )
509 currentLineStringElement = lineStringNodeList.
at( 0 ).
toElement();
510 currentCoordList = currentLineStringElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
511 if ( !currentCoordList.
isEmpty() )
514 if ( readGMLCoordinates( currentPointList, currentCoordList.
at( 0 ).
toElement() ) != 0 )
518 lineCoordinates.
push_back( currentPointList );
523 if ( currentPosList.
size() < 1 )
528 if ( readGMLPositions( currentPointList, currentPosList.
at( 0 ).
toElement() ) != 0 )
532 lineCoordinates.
push_back( currentPointList );
539 if ( !lineStringList.
isEmpty() )
541 for (
int i = 0; i < lineStringList.
size(); ++i )
543 currentLineStringElement = lineStringList.
at( i ).
toElement();
544 currentCoordList = currentLineStringElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
545 if ( !currentCoordList.
isEmpty() )
548 if ( readGMLCoordinates( currentPointList, currentCoordList.
at( 0 ).
toElement() ) != 0 )
552 lineCoordinates.
push_back( currentPointList );
558 if ( currentPosList.
size() < 1 )
563 if ( readGMLPositions( currentPointList, currentPosList.
at( 0 ).
toElement() ) != 0 )
567 lineCoordinates.
push_back( currentPointList );
577 int nLines = lineCoordinates.
size();
582 int size = ( lineCoordinates.
size() + 1 ) * ( 1 + 2 *
sizeof(
int ) );
585 size += it->size() * 2 *
sizeof( double );
589 unsigned char* wkb =
new unsigned char[size];
592 char e = htonl( 1 ) != 1;
596 memcpy( &( wkb )[wkbPosition], &e, 1 );
598 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
599 wkbPosition +=
sizeof( int );
600 memcpy( &( wkb )[wkbPosition], &nLines,
sizeof(
int ) );
601 wkbPosition +=
sizeof( int );
605 memcpy( &( wkb )[wkbPosition], &e, 1 );
607 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
608 wkbPosition +=
sizeof( int );
609 nPoints = it->size();
610 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
611 wkbPosition +=
sizeof( int );
617 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
618 wkbPosition +=
sizeof( double );
619 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
620 wkbPosition +=
sizeof( double );
654 for (
int i = 0; i < polygonMemberList.
size(); ++i )
657 currentPolygonMemberElement = polygonMemberList.
at( i ).
toElement();
659 if ( polygonList.
size() < 1 )
663 currentPolygonElement = polygonList.
at( 0 ).
toElement();
666 outerBoundaryList = currentPolygonElement.
elementsByTagNameNS( GML_NAMESPACE,
"outerBoundaryIs" );
667 if ( !outerBoundaryList.
isEmpty() )
669 currentOuterBoundaryElement = outerBoundaryList.
at( 0 ).
toElement();
672 linearRingNodeList = currentOuterBoundaryElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
673 if ( linearRingNodeList.
size() < 1 )
677 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
678 currentCoordinateList = currentLinearRingElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
679 if ( currentCoordinateList.
size() < 1 )
683 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.
at( 0 ).
toElement() ) != 0 )
687 currentPolygonList.
push_back( ringCoordinates );
691 for (
int j = 0; j < innerBoundaryList.
size(); ++j )
694 currentInnerBoundaryElement = innerBoundaryList.
at( j ).
toElement();
695 linearRingNodeList = currentInnerBoundaryElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
696 if ( linearRingNodeList.
size() < 1 )
700 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
701 currentCoordinateList = currentLinearRingElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
702 if ( currentCoordinateList.
size() < 1 )
706 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.
at( 0 ).
toElement() ) != 0 )
710 currentPolygonList.
push_back( ringCoordinates );
717 if ( exteriorList.
size() < 1 )
722 currentExteriorElement = exteriorList.
at( 0 ).
toElement();
725 linearRingNodeList = currentExteriorElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
726 if ( linearRingNodeList.
size() < 1 )
730 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
732 if ( currentPosList.
size() < 1 )
736 if ( readGMLPositions( ringPositions, currentPosList.
at( 0 ).
toElement() ) != 0 )
740 currentPolygonList.
push_back( ringPositions );
744 for (
int j = 0; j < interiorList.
size(); ++j )
747 currentInteriorElement = interiorList.
at( j ).
toElement();
748 linearRingNodeList = currentInteriorElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
749 if ( linearRingNodeList.
size() < 1 )
753 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
755 if ( currentPosList.
size() < 1 )
759 if ( readGMLPositions( ringPositions, currentPosList.
at( 0 ).
toElement() ) != 0 )
763 currentPolygonList.
push_back( ringPositions );
766 multiPolygonPoints.
push_back( currentPolygonList );
769 int nPolygons = multiPolygonPoints.
size();
773 int size = 1 + 2 *
sizeof( int );
777 size += 1 + 2 *
sizeof( int );
780 size +=
sizeof( int ) + 2 * iter->size() *
sizeof( double );
785 unsigned char* wkb =
new unsigned char[size];
787 char e = htonl( 1 ) != 1;
794 memcpy( &( wkb )[wkbPosition], &e, 1 );
796 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
797 wkbPosition +=
sizeof( int );
798 memcpy( &( wkb )[wkbPosition], &nPolygons,
sizeof(
int ) );
799 wkbPosition +=
sizeof( int );
805 memcpy( &( wkb )[wkbPosition], &e, 1 );
807 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
808 wkbPosition +=
sizeof( int );
810 memcpy( &( wkb )[wkbPosition], &nRings,
sizeof(
int ) );
811 wkbPosition +=
sizeof( int );
814 nPointsInRing = iter->size();
815 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
816 wkbPosition +=
sizeof( int );
821 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
822 wkbPosition +=
sizeof( double );
823 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
824 wkbPosition +=
sizeof( double );
854 bool conversionSuccess;
859 tupel_coords = ( *it ).
split( coordSeparator, QString::SkipEmptyParts );
860 if ( tupel_coords.
size() < 2 )
864 x = tupel_coords.
at( 0 ).toDouble( &conversionSuccess );
865 if ( !conversionSuccess )
869 y = tupel_coords.
at( 1 ).toDouble( &conversionSuccess );
870 if ( !conversionSuccess )
884 if ( boxElem.
tagName() !=
"Box" )
892 coordSeparator = bElem.
attribute(
"cs" );
896 tupelSeparator = bElem.
attribute(
"ts" );
900 bool ok1, ok2, ok3, ok4;
906 if ( ok1 && ok2 && ok3 && ok4 )
927 bool conversionSuccess;
928 int posSize = pos.
size();
930 int srsDimension = 2;
933 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
934 if ( !conversionSuccess )
941 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
942 if ( !conversionSuccess )
948 for (
int i = 0; i < posSize / srsDimension; i++ )
950 x = pos.
at( i * srsDimension ).toDouble( &conversionSuccess );
951 if ( !conversionSuccess )
955 y = pos.
at( i * srsDimension + 1 ).toDouble( &conversionSuccess );
956 if ( !conversionSuccess )
971 if ( envelopeElem.
tagName() !=
"Envelope" )
975 if ( lowerCornerList.
size() < 1 )
979 if ( upperCornerList.
size() < 1 )
982 bool conversionSuccess;
983 int srsDimension = 2;
988 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
989 if ( !conversionSuccess )
996 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
997 if ( !conversionSuccess )
1004 double xmin = bString.
section(
' ', 0, 0 ).
toDouble( &conversionSuccess );
1005 if ( !conversionSuccess )
1007 double ymin = bString.
section(
' ', 1, 1 ).
toDouble( &conversionSuccess );
1008 if ( !conversionSuccess )
1014 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
1015 if ( !conversionSuccess )
1022 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
1023 if ( !conversionSuccess )
1029 Q_UNUSED( srsDimension );
1031 bString = elem.
text();
1032 double xmax = bString.
section(
' ', 0, 0 ).
toDouble( &conversionSuccess );
1033 if ( !conversionSuccess )
1035 double ymax = bString.
section(
' ', 1, 1 ).
toDouble( &conversionSuccess );
1036 if ( !conversionSuccess )
1047 return rectangleToGMLBox( box, doc,
QString(),
false, precision );
1052 bool invertAxisOrientation,
1087 return rectangleToGMLEnvelope( env, doc,
QString(),
false, precision );
1092 bool invertAxisOrientation,
1128 return geometryToGML( geometry, doc, ( format ==
"GML2" ) ? GML_2_1_2 : GML_3_2_1,
QString(),
false,
QString(), precision );
1134 bool invertAxisOrientation,
1138 if ( !geometry || !geometry->
asWkb() )
1148 bool hasZValue =
false;
1153 if ( gmlVersion != GML_2_1_2 )
1155 switch ( geometry->
wkbType() )
1177 switch ( geometry->
wkbType() )
1183 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1190 if ( invertAxisOrientation )
1207 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1215 for (
int idx = 0; idx < nPoints; ++idx )
1219 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1223 wkbPtr.readHeader();
1226 if ( invertAxisOrientation )
1237 wkbPtr +=
sizeof( double );
1242 return multiPointElem;
1251 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1262 for (
int idx = 0; idx < nPoints; ++idx )
1270 if ( invertAxisOrientation )
1278 wkbPtr +=
sizeof( double );
1284 return lineStringElem;
1293 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1294 multiLineStringElem.
setAttribute(
"gml:id", gmlIdBase );
1296 multiLineStringElem.
setAttribute(
"srsName", srsName );
1301 for (
int jdx = 0; jdx < nLines; jdx++ )
1305 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1308 wkbPtr.readHeader();
1315 for (
int idx = 0; idx < nPoints; idx++ )
1323 if ( invertAxisOrientation )
1332 wkbPtr +=
sizeof( double );
1338 lineStringMemberElem.
appendChild( lineStringElem );
1339 multiLineStringElem.
appendChild( lineStringMemberElem );
1341 return multiLineStringElem;
1350 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1359 if ( numRings == 0 )
1362 int *ringNumPoints =
new int[numRings];
1364 for (
int idx = 0; idx < numRings; idx++ )
1366 QString boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:outerBoundaryIs" :
"gml:exterior";
1369 boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:innerBoundaryIs" :
"gml:interior";
1376 ringNumPoints[idx] = nPoints;
1380 for (
int jdx = 0; jdx < nPoints; jdx++ )
1388 if ( invertAxisOrientation )
1396 wkbPtr +=
sizeof( double );
1405 delete [] ringNumPoints;
1415 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1421 wkbPtr >> numPolygons;
1423 for (
int kdx = 0; kdx < numPolygons; kdx++ )
1427 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1430 wkbPtr.readHeader();
1435 for (
int idx = 0; idx < numRings; idx++ )
1437 QString boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:outerBoundaryIs" :
"gml:exterior";
1440 boundaryName = ( gmlVersion == GML_2_1_2 ) ?
"gml:innerBoundaryIs" :
"gml:interior";
1450 for (
int jdx = 0; jdx < nPoints; jdx++ )
1458 if ( invertAxisOrientation )
1467 wkbPtr +=
sizeof( double );
1476 multiPolygonElem.
appendChild( polygonMemberElem );
1479 return multiPolygonElem;
1488 return geometryToGML( geometry, doc,
"GML2", precision );
1499 for ( ; pointIt != points.
constEnd(); ++pointIt )
1518 if ( points.
size() > 1 )
1524 for ( ; pointIt != points.
constEnd(); ++pointIt )
1555 while ( !cssElem.
isNull() )
1557 cssName = cssElem.
attribute(
"name",
"not_found" );
1558 if ( cssName !=
"not_found" )
1560 elemText = cssElem.
text();
1561 if ( cssName ==
"fill" )
1565 else if ( cssName ==
"fill-opacity" )
1568 double opacity = elemText.
toDouble( &ok );
1592 expr->
d->mParserErrorString =
QString();
1601 while ( !childElem.
isNull() )
1608 expr->
d->mParserErrorString = errorMsg;
1613 if ( !expr->
d->mRootNode )
1615 expr->
d->mRootNode = node;
1626 expr->
d->mExp = expr->
dump();
1667 return "PropertyIsLike";
1683 spatialOps <<
"BBOX" <<
"Intersects" <<
"Contains" <<
"Crosses" <<
"Equals" 1684 <<
"Disjoint" <<
"Overlaps" <<
"Touches" <<
"Within";
1687 return spatialOps.
contains( tagName );
1700 return nodeBinaryOperatorFromOgcFilter( element, errorMessage );
1706 return nodeSpatialOperatorFromOgcFilter( element, errorMessage );
1711 if ( element.
tagName() ==
"Not" )
1713 return nodeNotFromOgcFilter( element, errorMessage );
1715 else if ( element.
tagName() ==
"PropertyIsNull" )
1717 return nodePropertyIsNullFromOgcFilter( element, errorMessage );
1719 else if ( element.
tagName() ==
"Literal" )
1721 return nodeLiteralFromOgcFilter( element, errorMessage );
1723 else if ( element.
tagName() ==
"Function" )
1725 return nodeFunctionFromOgcFilter( element, errorMessage );
1727 else if ( element.
tagName() ==
"PropertyName" )
1729 return nodeColumnRefFromOgcFilter( element, errorMessage );
1731 else if ( element.
tagName() ==
"PropertyIsBetween" )
1733 return nodeIsBetweenFromOgcFilter( element, errorMessage );
1736 errorMessage +=
QString(
"unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).
arg( element.
tagName() );
1751 errorMessage =
QString(
"'%1' binary operator not supported." ).
arg( element.
tagName() );
1761 QgsExpression::Node *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
1765 errorMessage =
QString(
"invalid left operand for '%1' binary operator" ).
arg( element.
tagName() );
1775 errorMessage =
QString(
"invalid right operand for '%1' binary operator" ).
arg( element.
tagName() );
1785 wildCard = element.
attribute(
"wildCard" );
1790 singleChar = element.
attribute(
"singleChar" );
1799 if ( !wildCard.
isEmpty() && wildCard !=
"%" )
1801 oprValue.
replace(
'%',
"\\%" );
1804 oprValue.
replace( 0, 1,
"%" );
1808 while (( pos = rx.
indexIn( oprValue, pos ) ) != -1 )
1810 oprValue.
replace( pos + 1, 1,
"%" );
1813 oprValue.
replace( escape + wildCard, wildCard );
1815 if ( !singleChar.
isEmpty() && singleChar !=
"_" )
1817 oprValue.
replace(
'_',
"\\_" );
1820 oprValue.
replace( 0, 1,
"_" );
1824 while (( pos = rx.
indexIn( oprValue, pos ) ) != -1 )
1826 oprValue.
replace( pos + 1, 1,
"_" );
1829 oprValue.
replace( escape + singleChar, singleChar );
1831 if ( !escape.
isEmpty() && escape !=
"\\" )
1833 oprValue.
replace( escape + escape, escape );
1841 if ( expr == leftOp )
1844 errorMessage =
QString(
"only one operand for '%1' binary operator" ).
arg( element.
tagName() );
1867 if ( childElem.
tagName() !=
"PropertyName" )
1870 childElem.
save( gml2Stream, 0 );
1880 errorMessage =
"No OGC Geometry found";
1895 if ( element.
tagName() !=
"Not" )
1903 errorMessage =
QString(
"invalid operand for '%1' unary operator" ).
arg( element.
tagName() );
1915 errorMessage =
QString(
"ogc:Function expected, got %1" ).
arg( element.
tagName() );
1929 while ( !operandElem.
isNull() )
1954 errorMessage =
QString(
"ogc:Literal expected, got %1" ).
arg( element.
tagName() );
1962 while ( !childNode.
isNull() )
1966 if ( childNode.
nodeType() == QDomNode::ElementNode )
1970 operand = nodeFromOgcFilter( operandElem, errorMessage );
1976 errorMessage =
QString(
"'%1' is an invalid or not supported content for ogc:Literal" ).
arg( operandElem.
tagName() );
2019 if ( element.
isNull() || element.
tagName() !=
"PropertyName" )
2021 errorMessage =
QString(
"ogc:PropertyName expected, got %1" ).
arg( element.
tagName() );
2036 while ( !operandElem.
isNull() )
2038 if ( operandElem.
tagName() ==
"LowerBoundary" )
2041 lowerBound = nodeFromOgcFilter( lowerBoundElem, errorMessage );
2043 else if ( operandElem.
tagName() ==
"UpperBoundary" )
2046 upperBound = nodeFromOgcFilter( upperBoundElem, errorMessage );
2053 operand = nodeFromOgcFilter( operandElem, errorMessage );
2054 operand2 = nodeFromOgcFilter( operandElem, errorMessage );
2057 if ( operand && lowerBound && operand2 && upperBound )
2063 if ( !operand || !lowerBound || !operand2 || !upperBound )
2074 errorMessage =
"missing some required sub-elements in ogc:PropertyIsBetween";
2087 if ( element.
tagName() !=
"PropertyIsNull" )
2107 return expressionToOgcFilter( exp, doc, GML_2_1_2, FILTER_OGC_1_0,
2108 "geometry",
QString(),
false,
false, errorMessage );
2113 return expressionToOgcExpression( exp, doc, GML_2_1_2, FILTER_OGC_1_0,
2114 "geometry",
QString(),
false,
false, errorMessage );
2123 bool honourAxisOrientation,
2124 bool invertAxisOrientation,
2130 QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
2134 if ( exprRootElem.
isNull() )
2138 ( filterVersion == FILTER_FES_2_0 ) ?
2144 if ( gmlVersion == GML_3_2_1 )
2160 bool honourAxisOrientation,
2161 bool invertAxisOrientation,
2174 QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
2180 if ( !exprRootElem.
isNull() )
2182 return exprRootElem;
2187 *errorMessage =
QObject::tr(
"Node type not supported in expression translation: %1" ).
arg( node->
nodeType() );
2198 return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeUnaryOperator*>( node ) );
2200 return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeBinaryOperator*>( node ) );
2202 return expressionInOperatorToOgcFilter( static_cast<const QgsExpression::NodeInOperator*>( node ) );
2204 return expressionFunctionToOgcFilter( static_cast<const QgsExpression::NodeFunction*>( node ) );
2206 return expressionLiteralToOgcFilter( static_cast<const QgsExpression::NodeLiteral*>( node ) );
2208 return expressionColumnRefToOgcFilter( static_cast<const QgsExpression::NodeColumnRef*>( node ) );
2221 if ( !mErrorMessage.
isEmpty() )
2225 switch ( node->
op() )
2238 mErrorMessage =
QObject::tr(
"This use of unary operator not implemented yet" );
2259 if ( !mErrorMessage.
isEmpty() )
2293 if ( !mErrorMessage.
isEmpty() )
2336 case QVariant::Double:
2339 case QVariant::String:
2365 if ( node->
list()->
list().size() == 1 )
2374 if ( !mErrorMessage.
isEmpty() )
2389 if ( binSpatialOps.
isEmpty() )
2391 binSpatialOps.
insert(
"disjoint",
"Disjoint" );
2392 binSpatialOps.
insert(
"intersects",
"Intersects" );
2393 binSpatialOps.
insert(
"touches",
"Touches" );
2394 binSpatialOps.
insert(
"crosses",
"Crosses" );
2395 binSpatialOps.
insert(
"contains",
"Contains" );
2396 binSpatialOps.
insert(
"overlaps",
"Overlaps" );
2397 binSpatialOps.
insert(
"within",
"Within" );
2399 return binSpatialOps;
2419 return fd->
name() ==
"$geometry";
2431 if ( fnDef->
name() ==
"geom_from_wkt" )
2449 if ( fd->
name() ==
"intersects_bbox" )
2452 Q_ASSERT( argNodes.
count() == 2 );
2478 mErrorMessage =
QObject::tr(
"<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('...'))" );
2486 Q_ASSERT( argNodes.
count() == 2 );
2490 otherNode = argNodes[1];
2492 otherNode = argNodes[0];
2495 mErrorMessage =
QObject::tr(
"Unable to translate spatial operator: at least one must refer to geometry." );
2504 mErrorMessage =
QObject::tr(
"spatial operator: the other operator must be a geometry constructor function" );
2510 if ( otherFnDef->
name() ==
"geom_from_wkt" )
2515 mErrorMessage =
QObject::tr(
"geom_from_wkt: argument must be string literal" );
2521 QString(
"qgis_id_geom_%1" ).arg( mGeomId ) );
2525 else if ( otherFnDef->
name() ==
"geom_from_gml" )
2530 mErrorMessage =
QObject::tr(
"geom_from_gml: argument must be string literal" );
2538 mErrorMessage =
QObject::tr(
"geom_from_gml: unable to parse XML" );
2547 mErrorMessage =
QObject::tr(
"spatial operator: unknown geometry constructor function" );
2563 mErrorMessage =
QObject::tr(
"Special columns/constants are not supported." );
2573 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.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
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
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QString dump() const
Return an expression string, constructed from the internal abstract syntax tree.
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.
WkbType
Used for symbology operations.
static QDomElement rectangleToGMLBox(QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
QDomElement documentElement() const
NodeType nodeType() const
QString & remove(int position, int n)
QDomElement createElementNS(const QString &nsURI, const QString &qName)
void setNamedColor(const QString &name)
double toDouble(bool *ok) const
int wkbSize() const
Returns the size of the WKB in asWkb().
QString tr(const char *sourceText, const char *disambiguation, int n)
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.
const Node * rootNode() const
Returns root node of the expression. Root node is null is parsing has failed.
QDomElement toElement() const
bool GMLNamespaceUsed() const
Return whether the gml: namespace is used.
static const QList< Function * > & Functions()
static int binaryOperatorFromTagName(const QString &tagName)
int indexIn(const QString &str, int offset, CaretMode caretMode) 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
static const QString GML_NAMESPACE
int toInt(bool *ok) const
static int functionIndex(const QString &name)
return index of the function in Functions array
bool hasAttribute(const QString &name) const
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
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
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()
BinaryOperator op() const
FilterVersion
OGC filter version.
QDomText createTextNode(const QString &value)
QDomNode removeChild(const QDomNode &oldChild)
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
static const QString OGC_NAMESPACE
const QString & errorMessage() const
Return the error message.
const Key key(const T &value) const
static bool isSpatialOperator(const QString &tagName)
QString & replace(int position, int n, QChar after)
QString name() const
The name of the column.
const_iterator constBegin() const
void save(QTextStream &str, int indent) const
QDomNode firstChild() const
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
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.
QVariant value() const
The value of the literal.
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.
double xMinimum() const
Get the x minimum value (left side of rectangle)
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 yMaximum() const
Get the y maximum value (top side of rectangle)
double toDouble(bool *ok) const
iterator insert(const Key &key, const T &value)
void append(Node *node)
Takes ownership of the provided node.
QgsWKBTypes::Type readHeader() const
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
The QgsOgcUtils class provides various utility functions for conversion between OGC (Open Geospatial ...
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)
bool axisInverted() const
Returns whether axis is inverted (eg.
const T value(const Key &key) const
static const char * BinaryOperatorText[]