23 #include <QStringList> 24 #include <QTextStream> 27 #include <netinet/in.h> 41 if ( !( geomType ==
"Point" || geomType ==
"LineString" || geomType ==
"Polygon" ||
42 geomType ==
"MultiPoint" || geomType ==
"MultiLineString" || geomType ==
"MultiPolygon" ||
43 geomType ==
"Box" || geomType ==
"Envelope" ) )
46 if ( geometryChild.
isNull() )
50 geometryTypeElement = geometryChild.
toElement();
51 geomType = geometryTypeElement.
tagName();
54 if ( !( geomType ==
"Point" || geomType ==
"LineString" || geomType ==
"Polygon" ||
55 geomType ==
"MultiPoint" || geomType ==
"MultiLineString" || geomType ==
"MultiPolygon" ||
56 geomType ==
"Box" || geomType ==
"Envelope" ) )
59 if ( geomType ==
"Point" )
61 return geometryFromGMLPoint( geometryTypeElement );
63 else if ( geomType ==
"LineString" )
65 return geometryFromGMLLineString( geometryTypeElement );
67 else if ( geomType ==
"Polygon" )
69 return geometryFromGMLPolygon( geometryTypeElement );
71 else if ( geomType ==
"MultiPoint" )
73 return geometryFromGMLMultiPoint( geometryTypeElement );
75 else if ( geomType ==
"MultiLineString" )
77 return geometryFromGMLMultiLineString( geometryTypeElement );
79 else if ( geomType ==
"MultiPolygon" )
81 return geometryFromGMLMultiPolygon( geometryTypeElement );
83 else if ( geomType ==
"Box" )
87 else if ( geomType ==
"Envelope" )
100 QString xml =
QString(
"<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>" ).
arg( GML_NAMESPACE, xmlString );
117 if ( readGMLCoordinates( pointCoordinate, coordElement ) != 0 )
125 if ( posList.
size() < 1 )
130 if ( readGMLPositions( pointCoordinate, posElement ) != 0 )
136 if ( pointCoordinate.
size() < 1 )
142 char e = htonl( 1 ) != 1;
143 double x = point_it->x();
144 double y = point_it->y();
145 int size = 1 +
sizeof( int ) + 2 *
sizeof(
double );
148 unsigned char* wkb =
new unsigned char[size];
151 memcpy( &( wkb )[wkbPosition], &e, 1 );
153 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
154 wkbPosition +=
sizeof( int );
155 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
156 wkbPosition +=
sizeof( double );
157 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
172 if ( readGMLCoordinates( lineCoordinates, coordElement ) != 0 )
180 if ( posList.
size() < 1 )
185 if ( readGMLPositions( lineCoordinates, posElement ) != 0 )
191 char e = htonl( 1 ) != 1;
192 int size = 1 + 2 *
sizeof( int ) + lineCoordinates.
size() * 2 *
sizeof( double );
195 unsigned char* wkb =
new unsigned char[size];
199 int nPoints = lineCoordinates.
size();
202 memcpy( &( wkb )[wkbPosition], &e, 1 );
204 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
205 wkbPosition +=
sizeof( int );
206 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
207 wkbPosition +=
sizeof( int );
210 for ( iter = lineCoordinates.
begin(); iter != lineCoordinates.
end(); ++iter )
214 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
215 wkbPosition +=
sizeof( double );
216 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
217 wkbPosition +=
sizeof( double );
233 if ( !outerBoundaryList.
isEmpty() )
236 if ( coordinatesElement.
isNull() )
240 if ( readGMLCoordinates( exteriorPointList, coordinatesElement ) != 0 )
244 ringCoordinates.
push_back( exteriorPointList );
248 for (
int i = 0; i < innerBoundaryList.
size(); ++i )
252 if ( coordinatesElement.
isNull() )
256 if ( readGMLCoordinates( interiorPointList, coordinatesElement ) != 0 )
260 ringCoordinates.
push_back( interiorPointList );
267 if ( exteriorList.
size() < 1 )
272 if ( posElement.
isNull() )
276 if ( readGMLPositions( exteriorPointList, posElement ) != 0 )
280 ringCoordinates.
push_back( exteriorPointList );
284 for (
int i = 0; i < interiorList.
size(); ++i )
288 if ( posElement.
isNull() )
292 if ( readGMLPositions( interiorPointList, posElement ) != 0 )
296 ringCoordinates.
push_back( interiorPointList );
301 int nrings = ringCoordinates.
size();
308 npoints += it->size();
310 int size = 1 + 2 *
sizeof( int ) + nrings *
sizeof(
int ) + 2 * npoints *
sizeof( double );
313 unsigned char* wkb =
new unsigned char[size];
316 char e = htonl( 1 ) != 1;
318 int nPointsInRing = 0;
322 memcpy( &( wkb )[wkbPosition], &e, 1 );
324 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
325 wkbPosition +=
sizeof( int );
326 memcpy( &( wkb )[wkbPosition], &nrings,
sizeof(
int ) );
327 wkbPosition +=
sizeof( int );
330 nPointsInRing = it->size();
331 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
332 wkbPosition +=
sizeof( int );
335 for ( iter = it->begin(); iter != it->end(); ++iter )
340 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
341 wkbPosition +=
sizeof( double );
342 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
343 wkbPosition +=
sizeof( double );
357 if ( pointMemberList.
size() < 1 )
365 for (
int i = 0; i < pointMemberList.
size(); ++i )
369 if ( pointNodeList.
size() < 1 )
375 if ( !coordinatesList.
isEmpty() )
377 currentPoint.
clear();
378 if ( readGMLCoordinates( currentPoint, coordinatesList.
at( 0 ).
toElement() ) != 0 )
382 if ( currentPoint.
size() < 1 )
393 if ( posList.
size() < 1 )
397 currentPoint.
clear();
398 if ( readGMLPositions( currentPoint, posList.
at( 0 ).
toElement() ) != 0 )
402 if ( currentPoint.
size() < 1 )
410 int nPoints = pointList.
size();
415 int size = 1 + 2 *
sizeof( int ) + pointList.
size() * ( 2 *
sizeof( double ) + 1 +
sizeof(
int ) );
418 unsigned char* wkb =
new unsigned char[size];
421 char e = htonl( 1 ) != 1;
424 memcpy( &( wkb )[wkbPosition], &e, 1 );
426 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
427 wkbPosition +=
sizeof( int );
428 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
429 wkbPosition +=
sizeof( int );
433 memcpy( &( wkb )[wkbPosition], &e, 1 );
435 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
436 wkbPosition +=
sizeof( int );
438 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
439 wkbPosition +=
sizeof( double );
441 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
442 wkbPosition +=
sizeof( double );
467 if ( !lineStringMemberList.
isEmpty() )
469 for (
int i = 0; i < lineStringMemberList.
size(); ++i )
472 if ( lineStringNodeList.
size() < 1 )
476 currentLineStringElement = lineStringNodeList.
at( 0 ).
toElement();
477 currentCoordList = currentLineStringElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
478 if ( !currentCoordList.
isEmpty() )
481 if ( readGMLCoordinates( currentPointList, currentCoordList.
at( 0 ).
toElement() ) != 0 )
485 lineCoordinates.
push_back( currentPointList );
490 if ( currentPosList.
size() < 1 )
495 if ( readGMLPositions( currentPointList, currentPosList.
at( 0 ).
toElement() ) != 0 )
499 lineCoordinates.
push_back( currentPointList );
506 if ( !lineStringList.
isEmpty() )
508 for (
int i = 0; i < lineStringList.
size(); ++i )
510 currentLineStringElement = lineStringList.
at( i ).
toElement();
511 currentCoordList = currentLineStringElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
512 if ( !currentCoordList.
isEmpty() )
515 if ( readGMLCoordinates( currentPointList, currentCoordList.
at( 0 ).
toElement() ) != 0 )
519 lineCoordinates.
push_back( currentPointList );
525 if ( currentPosList.
size() < 1 )
530 if ( readGMLPositions( currentPointList, currentPosList.
at( 0 ).
toElement() ) != 0 )
534 lineCoordinates.
push_back( currentPointList );
544 int nLines = lineCoordinates.
size();
549 int size = ( lineCoordinates.
size() + 1 ) * ( 1 + 2 *
sizeof(
int ) );
552 size += it->size() * 2 *
sizeof( double );
556 unsigned char* wkb =
new unsigned char[size];
559 char e = htonl( 1 ) != 1;
563 memcpy( &( wkb )[wkbPosition], &e, 1 );
565 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
566 wkbPosition +=
sizeof( int );
567 memcpy( &( wkb )[wkbPosition], &nLines,
sizeof(
int ) );
568 wkbPosition +=
sizeof( int );
572 memcpy( &( wkb )[wkbPosition], &e, 1 );
574 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
575 wkbPosition +=
sizeof( int );
576 nPoints = it->size();
577 memcpy( &( wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
578 wkbPosition +=
sizeof( int );
584 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
585 wkbPosition +=
sizeof( double );
586 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
587 wkbPosition +=
sizeof( double );
621 for (
int i = 0; i < polygonMemberList.
size(); ++i )
624 currentPolygonMemberElement = polygonMemberList.
at( i ).
toElement();
626 if ( polygonList.
size() < 1 )
630 currentPolygonElement = polygonList.
at( 0 ).
toElement();
633 outerBoundaryList = currentPolygonElement.
elementsByTagNameNS( GML_NAMESPACE,
"outerBoundaryIs" );
634 if ( !outerBoundaryList.
isEmpty() )
636 currentOuterBoundaryElement = outerBoundaryList.
at( 0 ).
toElement();
639 linearRingNodeList = currentOuterBoundaryElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
640 if ( linearRingNodeList.
size() < 1 )
644 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
645 currentCoordinateList = currentLinearRingElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
646 if ( currentCoordinateList.
size() < 1 )
650 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.
at( 0 ).
toElement() ) != 0 )
654 currentPolygonList.
push_back( ringCoordinates );
658 for (
int j = 0; j < innerBoundaryList.
size(); ++j )
661 currentInnerBoundaryElement = innerBoundaryList.
at( j ).
toElement();
662 linearRingNodeList = currentInnerBoundaryElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
663 if ( linearRingNodeList.
size() < 1 )
667 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
668 currentCoordinateList = currentLinearRingElement.
elementsByTagNameNS( GML_NAMESPACE,
"coordinates" );
669 if ( currentCoordinateList.
size() < 1 )
673 if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.
at( 0 ).
toElement() ) != 0 )
677 currentPolygonList.
push_back( ringCoordinates );
684 if ( exteriorList.
size() < 1 )
689 currentExteriorElement = exteriorList.
at( 0 ).
toElement();
692 linearRingNodeList = currentExteriorElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
693 if ( linearRingNodeList.
size() < 1 )
697 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
699 if ( currentPosList.
size() < 1 )
703 if ( readGMLPositions( ringPositions, currentPosList.
at( 0 ).
toElement() ) != 0 )
707 currentPolygonList.
push_back( ringPositions );
711 for (
int j = 0; j < interiorList.
size(); ++j )
714 currentInteriorElement = interiorList.
at( j ).
toElement();
715 linearRingNodeList = currentInteriorElement.
elementsByTagNameNS( GML_NAMESPACE,
"LinearRing" );
716 if ( linearRingNodeList.
size() < 1 )
720 currentLinearRingElement = linearRingNodeList.
at( 0 ).
toElement();
722 if ( currentPosList.
size() < 1 )
726 if ( readGMLPositions( ringPositions, currentPosList.
at( 0 ).
toElement() ) != 0 )
730 currentPolygonList.
push_back( ringPositions );
733 multiPolygonPoints.
push_back( currentPolygonList );
736 int nPolygons = multiPolygonPoints.
size();
740 int size = 1 + 2 *
sizeof( int );
744 size += 1 + 2 *
sizeof( int );
747 size +=
sizeof( int ) + 2 * iter->size() *
sizeof( double );
752 unsigned char* wkb =
new unsigned char[size];
754 char e = htonl( 1 ) != 1;
761 memcpy( &( wkb )[wkbPosition], &e, 1 );
763 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
764 wkbPosition +=
sizeof( int );
765 memcpy( &( wkb )[wkbPosition], &nPolygons,
sizeof(
int ) );
766 wkbPosition +=
sizeof( int );
772 memcpy( &( wkb )[wkbPosition], &e, 1 );
774 memcpy( &( wkb )[wkbPosition], &type,
sizeof(
int ) );
775 wkbPosition +=
sizeof( int );
777 memcpy( &( wkb )[wkbPosition], &nRings,
sizeof(
int ) );
778 wkbPosition +=
sizeof( int );
781 nPointsInRing = iter->size();
782 memcpy( &( wkb )[wkbPosition], &nPointsInRing,
sizeof(
int ) );
783 wkbPosition +=
sizeof( int );
788 memcpy( &( wkb )[wkbPosition], &x,
sizeof(
double ) );
789 wkbPosition +=
sizeof( double );
790 memcpy( &( wkb )[wkbPosition], &y,
sizeof(
double ) );
791 wkbPosition +=
sizeof( double );
821 bool conversionSuccess;
826 tupel_coords = ( *it ).
split( coordSeparator, QString::SkipEmptyParts );
827 if ( tupel_coords.
size() < 2 )
831 x = tupel_coords.
at( 0 ).toDouble( &conversionSuccess );
832 if ( !conversionSuccess )
836 y = tupel_coords.
at( 1 ).toDouble( &conversionSuccess );
837 if ( !conversionSuccess )
851 if ( boxElem.
tagName() !=
"Box" )
859 coordSeparator = bElem.
attribute(
"cs" );
863 tupelSeparator = bElem.
attribute(
"ts" );
867 bool ok1, ok2, ok3, ok4;
873 if ( ok1 && ok2 && ok3 && ok4 )
894 bool conversionSuccess;
895 int posSize = pos.
size();
897 int srsDimension = 2;
900 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
901 if ( !conversionSuccess )
908 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
909 if ( !conversionSuccess )
915 for (
int i = 0; i < posSize / srsDimension; i++ )
917 x = pos.
at( i * srsDimension ).toDouble( &conversionSuccess );
918 if ( !conversionSuccess )
922 y = pos.
at( i * srsDimension + 1 ).toDouble( &conversionSuccess );
923 if ( !conversionSuccess )
938 if ( envelopeElem.
tagName() !=
"Envelope" )
942 if ( lowerCornerList.
size() < 1 )
946 if ( upperCornerList.
size() < 1 )
949 bool conversionSuccess;
950 int srsDimension = 2;
955 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
956 if ( !conversionSuccess )
963 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
964 if ( !conversionSuccess )
971 double xmin = bString.
section(
' ', 0, 0 ).
toDouble( &conversionSuccess );
972 if ( !conversionSuccess )
974 double ymin = bString.
section(
' ', 1, 1 ).
toDouble( &conversionSuccess );
975 if ( !conversionSuccess )
981 srsDimension = elem.
attribute(
"srsDimension" ).
toInt( &conversionSuccess );
982 if ( !conversionSuccess )
989 srsDimension = elem.
attribute(
"dimension" ).
toInt( &conversionSuccess );
990 if ( !conversionSuccess )
996 Q_UNUSED( srsDimension );
998 bString = elem.
text();
999 double xmax = bString.
section(
' ', 0, 0 ).
toDouble( &conversionSuccess );
1000 if ( !conversionSuccess )
1002 double ymax = bString.
section(
' ', 1, 1 ).
toDouble( &conversionSuccess );
1003 if ( !conversionSuccess )
1071 if ( !geometry || !geometry->
asWkb() )
1081 bool hasZValue =
false;
1086 if ( format ==
"GML3" )
1088 switch ( geometry->
wkbType() )
1110 switch ( geometry->
wkbType() )
1137 for (
int idx = 0; idx < nPoints; ++idx )
1143 wkbPtr.readHeader();
1154 wkbPtr +=
sizeof( double );
1159 return multiPointElem;
1175 for (
int idx = 0; idx < nPoints; ++idx )
1188 wkbPtr +=
sizeof( double );
1194 return lineStringElem;
1207 for (
int jdx = 0; jdx < nLines; jdx++ )
1212 wkbPtr.readHeader();
1219 for (
int idx = 0; idx < nPoints; idx++ )
1233 wkbPtr +=
sizeof( double );
1239 lineStringMemberElem.
appendChild( lineStringElem );
1240 multiLineStringElem.
appendChild( lineStringMemberElem );
1242 return multiLineStringElem;
1256 if ( numRings == 0 )
1259 int *ringNumPoints =
new int[numRings];
1261 for (
int idx = 0; idx < numRings; idx++ )
1263 QString boundaryName =
"gml:outerBoundaryIs";
1266 boundaryName =
"gml:innerBoundaryIs";
1273 ringNumPoints[idx] = nPoints;
1277 for (
int jdx = 0; jdx < nPoints; jdx++ )
1290 wkbPtr +=
sizeof( double );
1299 delete [] ringNumPoints;
1311 wkbPtr >> numPolygons;
1313 for (
int kdx = 0; kdx < numPolygons; kdx++ )
1318 wkbPtr.readHeader();
1323 for (
int idx = 0; idx < numRings; idx++ )
1325 QString boundaryName =
"gml:outerBoundaryIs";
1328 boundaryName =
"gml:innerBoundaryIs";
1338 for (
int jdx = 0; jdx < nPoints; jdx++ )
1352 wkbPtr +=
sizeof( double );
1361 multiPolygonElem.
appendChild( polygonMemberElem );
1364 return multiPolygonElem;
1384 for ( ; pointIt != points.
constEnd(); ++pointIt )
1403 if ( points.
size() > 1 )
1409 for ( ; pointIt != points.
constEnd(); ++pointIt )
1440 while ( !cssElem.
isNull() )
1442 cssName = cssElem.
attribute(
"name",
"not_found" );
1443 if ( cssName !=
"not_found" )
1445 elemText = cssElem.
text();
1446 if ( cssName ==
"fill" )
1450 else if ( cssName ==
"fill-opacity" )
1453 double opacity = elemText.
toDouble( &ok );
1476 while ( !childElem.
isNull() )
1483 expr->
d->mParserErrorString = errorMsg;
1488 if ( !expr->
d->mRootNode )
1490 expr->
d->mRootNode = node;
1501 expr->
d->mExp = expr->
dump();
1554 spatialOps <<
"BBOX" <<
"Intersects" <<
"Contians" <<
"Crosses" <<
"Equals" 1555 <<
"Disjoint" <<
"Overlaps" <<
"Touches" <<
"Within";
1558 return spatialOps.
contains( tagName );
1571 return nodeBinaryOperatorFromOgcFilter( element, errorMessage );
1577 return nodeSpatialOperatorFromOgcFilter( element, errorMessage );
1582 if ( element.
tagName() ==
"Not" )
1584 return nodeNotFromOgcFilter( element, errorMessage );
1586 else if ( element.
tagName() ==
"PropertyIsNull" )
1588 return nodePropertyIsNullFromOgcFilter( element, errorMessage );
1590 else if ( element.
tagName() ==
"Literal" )
1592 return nodeLiteralFromOgcFilter( element, errorMessage );
1594 else if ( element.
tagName() ==
"Function" )
1596 return nodeFunctionFromOgcFilter( element, errorMessage );
1598 else if ( element.
tagName() ==
"PropertyName" )
1600 return nodeColumnRefFromOgcFilter( element, errorMessage );
1602 else if ( element.
tagName() ==
"PropertyIsBetween" )
1604 return nodeIsBetweenFromOgcFilter( element, errorMessage );
1607 errorMessage +=
QString(
"unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).
arg( element.
tagName() );
1622 errorMessage =
QString(
"'%1' binary operator not supported." ).
arg( element.
tagName() );
1627 QgsExpression::Node *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
1631 errorMessage =
QString(
"invalid left operand for '%1' binary operator" ).
arg( element.
tagName() );
1641 errorMessage =
QString(
"invalid right operand for '%1' binary operator" ).
arg( element.
tagName() );
1649 if ( expr == leftOp )
1652 errorMessage =
QString(
"only one operand for '%1' binary operator" ).
arg( element.
tagName() );
1675 if ( childElem.
tagName() !=
"PropertyName" )
1678 childElem.
save( gml2Stream, 0 );
1688 errorMessage =
"No OGC Geometry found";
1703 if ( element.
tagName() !=
"Not" )
1711 errorMessage =
QString(
"invalid operand for '%1' unary operator" ).
arg( element.
tagName() );
1723 errorMessage =
QString(
"ogc:Function expected, got %1" ).
arg( element.
tagName() );
1737 while ( !operandElem.
isNull() )
1762 errorMessage =
QString(
"ogc:Literal expected, got %1" ).
arg( element.
tagName() );
1770 while ( !childNode.
isNull() )
1774 if ( childNode.
nodeType() == QDomNode::ElementNode )
1778 operand = nodeFromOgcFilter( operandElem, errorMessage );
1784 errorMessage =
QString(
"'%1' is an invalid or not supported content for ogc:Literal" ).
arg( operandElem.
tagName() );
1827 if ( element.
isNull() || element.
tagName() !=
"PropertyName" )
1829 errorMessage =
QString(
"ogc:PropertyName expected, got %1" ).
arg( element.
tagName() );
1844 while ( !operandElem.
isNull() )
1846 if ( operandElem.
tagName() ==
"LowerBoundary" )
1849 lowerBound = nodeFromOgcFilter( lowerBoundElem, errorMessage );
1851 else if ( operandElem.
tagName() ==
"UpperBoundary" )
1854 upperBound = nodeFromOgcFilter( upperBoundElem, errorMessage );
1861 operand = nodeFromOgcFilter( operandElem, errorMessage );
1862 operand2 = nodeFromOgcFilter( operandElem, errorMessage );
1865 if ( operand && lowerBound && operand2 && upperBound )
1871 if ( !operand || !lowerBound || !operand2 || !upperBound )
1882 errorMessage =
"missing some required sub-elements in ogc:PropertyIsBetween";
1895 if ( element.
tagName() !=
"PropertyIsNull" )
1919 QString& refErrorMessage = ( errorMessage ? *errorMessage : localErrorMessage );
1920 refErrorMessage.
clear();
1922 QDomElement exprRootElem = expressionNodeToOgcFilter( exp.
rootNode(), doc, refErrorMessage );
1923 if ( exprRootElem.
isNull() )
1937 return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeUnaryOperator*>( node ), doc, errorMessage );
1939 return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeBinaryOperator*>( node ), doc, errorMessage );
1941 return expressionInOperatorToOgcFilter( static_cast<const QgsExpression::NodeInOperator*>( node ), doc, errorMessage );
1943 return expressionFunctionToOgcFilter( static_cast<const QgsExpression::NodeFunction*>( node ), doc, errorMessage );
1945 return expressionLiteralToOgcFilter( static_cast<const QgsExpression::NodeLiteral*>( node ), doc, errorMessage );
1947 return expressionColumnRefToOgcFilter( static_cast<const QgsExpression::NodeColumnRef*>( node ), doc, errorMessage );
1959 QDomElement operandElem = expressionNodeToOgcFilter( node->
operand(), doc, errorMessage );
1960 if ( !errorMessage.
isEmpty() )
1964 switch ( node->
op() )
1977 errorMessage =
QString(
"This use of unary operator not implemented yet" );
1997 QDomElement leftElem = expressionNodeToOgcFilter( node->
opLeft(), doc, errorMessage );
1998 if ( !errorMessage.
isEmpty() )
2031 QDomElement rightElem = expressionNodeToOgcFilter( node->
opRight(), doc, errorMessage );
2032 if ( !errorMessage.
isEmpty() )
2072 case QVariant::Double:
2075 case QVariant::String:
2101 if ( node->
list()->
list().size() == 1 )
2102 return expressionNodeToOgcFilter( node->
list()->
list()[0], doc, errorMessage );
2105 QDomElement leftNode = expressionNodeToOgcFilter( node->
node(), doc, errorMessage );
2109 QDomElement listNode = expressionNodeToOgcFilter( n, doc, errorMessage );
2110 if ( !errorMessage.
isEmpty() )
2125 if ( binSpatialOps.
isEmpty() )
2127 binSpatialOps.
insert(
"disjoint",
"Disjoint" );
2128 binSpatialOps.
insert(
"intersects",
"Intersects" );
2129 binSpatialOps.
insert(
"touches",
"Touches" );
2130 binSpatialOps.
insert(
"crosses",
"Crosses" );
2131 binSpatialOps.
insert(
"contains",
"Contains" );
2132 binSpatialOps.
insert(
"overlaps",
"Overlaps" );
2133 binSpatialOps.
insert(
"within",
"Within" );
2135 return binSpatialOps;
2155 return fd->
name() ==
"$geometry";
2167 if ( fnDef->
name() ==
"geom_from_wkt" )
2185 if ( fd->
name() ==
"intersects_bbox" )
2188 Q_ASSERT( argNodes.
count() == 2 );
2210 errorMessage =
QString(
"<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('...'))" );
2218 Q_ASSERT( argNodes.
count() == 2 );
2222 otherNode = argNodes[1];
2224 otherNode = argNodes[0];
2227 errorMessage =
QString(
"Unable to translate spatial operator: at least one must refer to geometry." );
2236 errorMessage =
"spatial operator: the other operator must be a geometry constructor function";
2242 if ( otherFnDef->
name() ==
"geom_from_wkt" )
2247 errorMessage =
"geom_from_wkt: argument must be string literal";
2255 else if ( otherFnDef->
name() ==
"geom_from_gml" )
2260 errorMessage =
"geom_from_gml: argument must be string literal";
2268 errorMessage =
"geom_from_gml: unable to parse XML";
2277 errorMessage =
"spatial operator: unknown geometry constructor function";
2291 errorMessage =
QString(
"Special columns / constants are not supported." );
2300 QDomElement childElem = expressionNodeToOgcFilter( n, doc, errorMessage );
2301 if ( !errorMessage.
isEmpty() )
Class for parsing and evaluation of expressions (formerly called "search strings").
virtual NodeType nodeType() const =0
Abstract virtual that returns the type of this node.
A rectangle specified with double values.
QDomNodeList elementsByTagNameNS(const QString &nsURI, const QString &localName) const
bool contains(const Key &key) const
QDomNode appendChild(const QDomNode &newChild)
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
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 geometryToGML(const QgsGeometry *geometry, QDomDocument &doc, const QString &format, int precision=17)
Exports the geometry to GML2 or GML3.
WkbType
Used for symbology operations.
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.
NodeType nodeType() const
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
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)
QString number(int n, int base)
int count(const T &value) const
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)
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()
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)
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
QDomNode cloneNode(bool deep) const
static QDomElement expressionToOgcFilter(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates OGC filter XML element.
int params()
The number of parameters this function takes.
QDomElement firstChildElement(const QString &tagName) const
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 GML2 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)
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[]