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 )
1046 return rectangleToGMLBox( box, doc,
QString(),
false, precision );
1051 bool invertAxisOrientation,
1086 return rectangleToGMLEnvelope( env, doc,
QString(),
false, precision );
1091 bool invertAxisOrientation,
1127 return geometryToGML( geometry, doc, ( format ==
"GML2" ) ? GML_2_1_2 : GML_3_2_1,
QString(),
false,
QString(), precision );
1133 bool invertAxisOrientation,
1137 if ( !geometry || !geometry->
asWkb() )
1147 bool hasZValue =
false;
1152 if ( gmlVersion != GML_2_1_2 )
1154 switch ( geometry->
wkbType() )
1176 switch ( geometry->
wkbType() )
1182 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1189 if ( invertAxisOrientation )
1206 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1214 for (
int idx = 0; idx < nPoints; ++idx )
1218 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1222 wkbPtr.readHeader();
1225 if ( invertAxisOrientation )
1236 wkbPtr +=
sizeof( double );
1241 return multiPointElem;
1250 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1261 for (
int idx = 0; idx < nPoints; ++idx )
1269 if ( invertAxisOrientation )
1277 wkbPtr +=
sizeof( double );
1283 return lineStringElem;
1292 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1293 multiLineStringElem.
setAttribute(
"gml:id", gmlIdBase );
1295 multiLineStringElem.
setAttribute(
"srsName", srsName );
1300 for (
int jdx = 0; jdx < nLines; jdx++ )
1304 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
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;
1349 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
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;
1414 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
1420 wkbPtr >> numPolygons;
1422 for (
int kdx = 0; kdx < numPolygons; kdx++ )
1426 if ( gmlVersion == GML_3_2_1 && !gmlIdBase.
isEmpty() )
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;
1487 return geometryToGML( geometry, doc,
"GML2", precision );
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" )
2096 return expressionToOgcFilter( exp, doc, GML_2_1_2, FILTER_OGC_1_0,
2097 "geometry",
QString(),
false,
false, errorMessage );
2102 return expressionToOgcExpression( exp, doc, GML_2_1_2, FILTER_OGC_1_0,
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() )
2127 ( filterVersion == FILTER_FES_2_0 ) ?
2133 if ( gmlVersion == GML_3_2_1 )
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.
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[]