11 #include <netinet/in.h> 
   22   QDomElement geometryTypeElement = geometryNode.toElement();
 
   23   QString geomType = geometryTypeElement.tagName();
 
   25   if ( !( geomType == 
"Point" || geomType == 
"LineString" || geomType == 
"Polygon" ||
 
   26           geomType == 
"MultiPoint" || geomType == 
"MultiLineString" || geomType == 
"MultiPolygon" ||
 
   27           geomType == 
"Box" || geomType == 
"Envelope" ) )
 
   29     QDomNode geometryChild = geometryNode.firstChild();
 
   30     if ( geometryChild.isNull() )
 
   34     geometryTypeElement = geometryChild.toElement();
 
   35     geomType = geometryTypeElement.tagName();
 
   38   if ( !( geomType == 
"Point" || geomType == 
"LineString" || geomType == 
"Polygon" ||
 
   39           geomType == 
"MultiPoint" || geomType == 
"MultiLineString" || geomType == 
"MultiPolygon" ||
 
   40           geomType == 
"Box" || geomType == 
"Envelope" ) )
 
   43   if ( geomType == 
"Point" )
 
   45     return geometryFromGMLPoint( geometryTypeElement );
 
   47   else if ( geomType == 
"LineString" )
 
   49     return geometryFromGMLLineString( geometryTypeElement );
 
   51   else if ( geomType == 
"Polygon" )
 
   53     return geometryFromGMLPolygon( geometryTypeElement );
 
   55   else if ( geomType == 
"MultiPoint" )
 
   57     return geometryFromGMLMultiPoint( geometryTypeElement );
 
   59   else if ( geomType == 
"MultiLineString" )
 
   61     return geometryFromGMLMultiLineString( geometryTypeElement );
 
   63   else if ( geomType == 
"MultiPolygon" )
 
   65     return geometryFromGMLMultiPolygon( geometryTypeElement );
 
   67   else if ( geomType == 
"Box" )
 
   71   else if ( geomType == 
"Envelope" )
 
   84   QString xml = QString( 
"<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>" ).arg( 
GML_NAMESPACE ).arg( xmlString );
 
   86   if ( !doc.setContent( xml, 
true ) )
 
   93 QgsGeometry* QgsOgcUtils::geometryFromGMLPoint( 
const QDomElement& geometryElement )
 
   97   QDomNodeList coordList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
   98   if ( coordList.size() > 0 )
 
  100     QDomElement coordElement = coordList.at( 0 ).toElement();
 
  101     if ( readGMLCoordinates( pointCoordinate, coordElement ) != 0 )
 
  108     QDomNodeList posList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"pos" );
 
  109     if ( posList.size() < 1 )
 
  113     QDomElement posElement = posList.at( 0 ).toElement();
 
  114     if ( readGMLPositions( pointCoordinate, posElement ) != 0 )
 
  120   if ( pointCoordinate.size() < 1 )
 
  125   QgsPolyline::const_iterator point_it = pointCoordinate.begin();
 
  126   char e = htonl( 1 ) != 1;
 
  127   double x = point_it->x();
 
  128   double y = point_it->y();
 
  129   int size = 1 + 
sizeof( int ) + 2 * 
sizeof( 
double );
 
  132   unsigned char* wkb = 
new unsigned char[
size];
 
  135   memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  137   memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  138   wkbPosition += 
sizeof( int );
 
  139   memcpy( &( wkb )[wkbPosition], &x, 
sizeof( 
double ) );
 
  140   wkbPosition += 
sizeof( double );
 
  141   memcpy( &( wkb )[wkbPosition], &y, 
sizeof( 
double ) );
 
  148 QgsGeometry* QgsOgcUtils::geometryFromGMLLineString( 
const QDomElement& geometryElement )
 
  152   QDomNodeList coordList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
  153   if ( coordList.size() > 0 )
 
  155     QDomElement coordElement = coordList.at( 0 ).toElement();
 
  156     if ( readGMLCoordinates( lineCoordinates, coordElement ) != 0 )
 
  163     QDomNodeList posList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"posList" );
 
  164     if ( posList.size() < 1 )
 
  168     QDomElement posElement = posList.at( 0 ).toElement();
 
  169     if ( readGMLPositions( lineCoordinates, posElement ) != 0 )
 
  175   char e = htonl( 1 ) != 1;
 
  176   int size = 1 + 2 * 
sizeof( int ) + lineCoordinates.size() * 2 * 
sizeof( double );
 
  179   unsigned char* wkb = 
new unsigned char[
size];
 
  183   int nPoints = lineCoordinates.size();
 
  186   memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  188   memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  189   wkbPosition += 
sizeof( int );
 
  190   memcpy( &( wkb )[wkbPosition], &nPoints, 
sizeof( 
int ) );
 
  191   wkbPosition += 
sizeof( int );
 
  193   QgsPolyline::const_iterator iter;
 
  194   for ( iter = lineCoordinates.begin(); iter != lineCoordinates.end(); ++iter )
 
  198     memcpy( &( wkb )[wkbPosition], &x, 
sizeof( 
double ) );
 
  199     wkbPosition += 
sizeof( double );
 
  200     memcpy( &( wkb )[wkbPosition], &y, 
sizeof( 
double ) );
 
  201     wkbPosition += 
sizeof( double );
 
  209 QgsGeometry* QgsOgcUtils::geometryFromGMLPolygon( 
const QDomElement& geometryElement )
 
  216   QDomNodeList outerBoundaryList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"outerBoundaryIs" );
 
  217   if ( outerBoundaryList.size() > 0 ) 
 
  219     QDomElement coordinatesElement = outerBoundaryList.at( 0 ).firstChild().firstChild().toElement();
 
  220     if ( coordinatesElement.isNull() )
 
  224     if ( readGMLCoordinates( exteriorPointList, coordinatesElement ) != 0 )
 
  228     ringCoordinates.push_back( exteriorPointList );
 
  231     QDomNodeList innerBoundaryList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"innerBoundaryIs" );
 
  232     for ( 
int i = 0; i < innerBoundaryList.size(); ++i )
 
  235       coordinatesElement = innerBoundaryList.at( i ).firstChild().firstChild().toElement();
 
  236       if ( coordinatesElement.isNull() )
 
  240       if ( readGMLCoordinates( interiorPointList, coordinatesElement ) != 0 )
 
  244       ringCoordinates.push_back( interiorPointList );
 
  250     QDomNodeList exteriorList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"exterior" );
 
  251     if ( exteriorList.size() < 1 ) 
 
  255     QDomElement posElement = exteriorList.at( 0 ).firstChild().firstChild().toElement();
 
  256     if ( posElement.isNull() )
 
  260     if ( readGMLPositions( exteriorPointList, posElement ) != 0 )
 
  264     ringCoordinates.push_back( exteriorPointList );
 
  267     QDomNodeList interiorList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"interior" );
 
  268     for ( 
int i = 0; i < interiorList.size(); ++i )
 
  271       QDomElement posElement = interiorList.at( i ).firstChild().firstChild().toElement();
 
  272       if ( posElement.isNull() )
 
  276       if ( readGMLPositions( interiorPointList, posElement ) != 0 )
 
  280       ringCoordinates.push_back( interiorPointList );
 
  285   int nrings = ringCoordinates.size();
 
  290   for ( QgsMultiPolyline::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it )
 
  292     npoints += it->size();
 
  294   int size = 1 + 2 * 
sizeof( int ) + nrings * 
sizeof( 
int ) + 2 * npoints * 
sizeof( double );
 
  297   unsigned char* wkb = 
new unsigned char[
size];
 
  300   char e = htonl( 1 ) != 1;
 
  302   int nPointsInRing = 0;
 
  306   memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  308   memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  309   wkbPosition += 
sizeof( int );
 
  310   memcpy( &( wkb )[wkbPosition], &nrings, 
sizeof( 
int ) );
 
  311   wkbPosition += 
sizeof( int );
 
  312   for ( QgsMultiPolyline::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it )
 
  314     nPointsInRing = it->size();
 
  315     memcpy( &( wkb )[wkbPosition], &nPointsInRing, 
sizeof( 
int ) );
 
  316     wkbPosition += 
sizeof( int );
 
  318     QgsPolyline::const_iterator iter;
 
  319     for ( iter = it->begin(); iter != it->end(); ++iter )
 
  324       memcpy( &( wkb )[wkbPosition], &x, 
sizeof( 
double ) );
 
  325       wkbPosition += 
sizeof( double );
 
  326       memcpy( &( wkb )[wkbPosition], &y, 
sizeof( 
double ) );
 
  327       wkbPosition += 
sizeof( double );
 
  336 QgsGeometry* QgsOgcUtils::geometryFromGMLMultiPoint( 
const QDomElement& geometryElement )
 
  340   QDomNodeList pointMemberList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"pointMember" );
 
  341   if ( pointMemberList.size() < 1 )
 
  345   QDomNodeList pointNodeList;
 
  347   QDomNodeList coordinatesList;
 
  348   QDomNodeList posList;
 
  349   for ( 
int i = 0; i < pointMemberList.size(); ++i )
 
  352     pointNodeList = pointMemberList.at( i ).toElement().elementsByTagNameNS( 
GML_NAMESPACE, 
"Point" );
 
  353     if ( pointNodeList.size() < 1 )
 
  358     coordinatesList = pointNodeList.at( 0 ).toElement().elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
  359     if ( coordinatesList.size() > 0 )
 
  361       currentPoint.clear();
 
  362       if ( readGMLCoordinates( currentPoint, coordinatesList.at( 0 ).toElement() ) != 0 )
 
  366       if ( currentPoint.size() < 1 )
 
  370       pointList.push_back(( *currentPoint.begin() ) );
 
  376       posList = pointNodeList.at( 0 ).toElement().elementsByTagNameNS( 
GML_NAMESPACE, 
"pos" );
 
  377       if ( posList.size() < 1 )
 
  381       currentPoint.clear();
 
  382       if ( readGMLPositions( currentPoint, posList.at( 0 ).toElement() ) != 0 )
 
  386       if ( currentPoint.size() < 1 )
 
  390       pointList.push_back(( *currentPoint.begin() ) );
 
  394   int nPoints = pointList.size(); 
 
  399   int size = 1 + 2 * 
sizeof( int ) + pointList.size() * ( 2 * 
sizeof( double ) + 1 + 
sizeof( 
int ) );
 
  402   unsigned char* wkb = 
new unsigned char[
size];
 
  405   char e = htonl( 1 ) != 1;
 
  408   memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  410   memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  411   wkbPosition += 
sizeof( int );
 
  412   memcpy( &( wkb )[wkbPosition], &nPoints, 
sizeof( 
int ) );
 
  413   wkbPosition += 
sizeof( int );
 
  415   for ( QgsPolyline::const_iterator it = pointList.begin(); it != pointList.end(); ++it )
 
  417     memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  419     memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  420     wkbPosition += 
sizeof( int );
 
  422     memcpy( &( wkb )[wkbPosition], &x, 
sizeof( 
double ) );
 
  423     wkbPosition += 
sizeof( double );
 
  425     memcpy( &( wkb )[wkbPosition], &y, 
sizeof( 
double ) );
 
  426     wkbPosition += 
sizeof( double );
 
  434 QgsGeometry* QgsOgcUtils::geometryFromGMLMultiLineString( 
const QDomElement& geometryElement )
 
  445   QList< QgsPolyline > lineCoordinates; 
 
  446   QDomElement currentLineStringElement;
 
  447   QDomNodeList currentCoordList;
 
  448   QDomNodeList currentPosList;
 
  450   QDomNodeList lineStringMemberList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"lineStringMember" );
 
  451   if ( lineStringMemberList.size() > 0 ) 
 
  453     for ( 
int i = 0; i < lineStringMemberList.size(); ++i )
 
  455       QDomNodeList lineStringNodeList = lineStringMemberList.at( i ).toElement().elementsByTagNameNS( 
GML_NAMESPACE, 
"LineString" );
 
  456       if ( lineStringNodeList.size() < 1 )
 
  460       currentLineStringElement = lineStringNodeList.at( 0 ).toElement();
 
  461       currentCoordList = currentLineStringElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
  462       if ( currentCoordList.size() > 0 )
 
  465         if ( readGMLCoordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
 
  469         lineCoordinates.push_back( currentPointList );
 
  473         currentPosList = currentLineStringElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"posList" );
 
  474         if ( currentPosList.size() < 1 )
 
  479         if ( readGMLPositions( currentPointList, currentPosList.at( 0 ).toElement() ) != 0 )
 
  483         lineCoordinates.push_back( currentPointList );
 
  489     QDomNodeList lineStringList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"LineString" );
 
  490     if ( lineStringList.size() > 0 ) 
 
  492       for ( 
int i = 0; i < lineStringList.size(); ++i )
 
  494         currentLineStringElement = lineStringList.at( i ).toElement();
 
  495         currentCoordList = currentLineStringElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
  496         if ( currentCoordList.size() > 0 )
 
  499           if ( readGMLCoordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
 
  503           lineCoordinates.push_back( currentPointList );
 
  508           currentPosList = currentLineStringElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"posList" );
 
  509           if ( currentPosList.size() < 1 )
 
  514           if ( readGMLPositions( currentPointList, currentPosList.at( 0 ).toElement() ) != 0 )
 
  518           lineCoordinates.push_back( currentPointList );
 
  528   int nLines = lineCoordinates.size();
 
  533   int size = ( lineCoordinates.size() + 1 ) * ( 1 + 2 * 
sizeof( 
int ) );
 
  534   for ( QList< QgsPolyline >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it )
 
  536     size += it->size() * 2 * 
sizeof( double );
 
  540   unsigned char* wkb = 
new unsigned char[
size];
 
  543   char e = htonl( 1 ) != 1;
 
  547   memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  549   memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  550   wkbPosition += 
sizeof( int );
 
  551   memcpy( &( wkb )[wkbPosition], &nLines, 
sizeof( 
int ) );
 
  552   wkbPosition += 
sizeof( int );
 
  554   for ( QList< QgsPolyline >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it )
 
  556     memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  558     memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  559     wkbPosition += 
sizeof( int );
 
  560     nPoints = it->size();
 
  561     memcpy( &( wkb )[wkbPosition], &nPoints, 
sizeof( 
int ) );
 
  562     wkbPosition += 
sizeof( int );
 
  563     for ( QgsPolyline::const_iterator iter = it->begin(); iter != it->end(); ++iter )
 
  568       memcpy( &( wkb )[wkbPosition], &x, 
sizeof( 
double ) );
 
  569       wkbPosition += 
sizeof( double );
 
  570       memcpy( &( wkb )[wkbPosition], &y, 
sizeof( 
double ) );
 
  571       wkbPosition += 
sizeof( double );
 
  580 QgsGeometry* QgsOgcUtils::geometryFromGMLMultiPolygon( 
const QDomElement& geometryElement )
 
  584   QDomElement currentPolygonMemberElement;
 
  585   QDomNodeList polygonList;
 
  586   QDomElement currentPolygonElement;
 
  588   QDomNodeList outerBoundaryList;
 
  589   QDomElement currentOuterBoundaryElement;
 
  590   QDomNodeList innerBoundaryList;
 
  591   QDomElement currentInnerBoundaryElement;
 
  593   QDomNodeList exteriorList;
 
  594   QDomElement currentExteriorElement;
 
  595   QDomElement currentInteriorElement;
 
  596   QDomNodeList interiorList;
 
  598   QDomNodeList linearRingNodeList;
 
  599   QDomElement currentLinearRingElement;
 
  601   QDomNodeList currentCoordinateList;
 
  602   QDomNodeList currentPosList;
 
  604   QDomNodeList polygonMemberList = geometryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"polygonMember" );
 
  605   for ( 
int i = 0; i < polygonMemberList.size(); ++i )
 
  608     currentPolygonMemberElement = polygonMemberList.at( i ).toElement();
 
  609     polygonList = currentPolygonMemberElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"Polygon" );
 
  610     if ( polygonList.size() < 1 )
 
  614     currentPolygonElement = polygonList.at( 0 ).toElement();
 
  617     outerBoundaryList = currentPolygonElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"outerBoundaryIs" );
 
  618     if ( outerBoundaryList.size() > 0 )
 
  620       currentOuterBoundaryElement = outerBoundaryList.at( 0 ).toElement();
 
  623       linearRingNodeList = currentOuterBoundaryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"LinearRing" );
 
  624       if ( linearRingNodeList.size() < 1 )
 
  628       currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
 
  629       currentCoordinateList = currentLinearRingElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
  630       if ( currentCoordinateList.size() < 1 )
 
  634       if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
 
  638       currentPolygonList.push_back( ringCoordinates );
 
  641       QDomNodeList innerBoundaryList = currentPolygonElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"innerBoundaryIs" );
 
  642       for ( 
int j = 0; j < innerBoundaryList.size(); ++j )
 
  645         currentInnerBoundaryElement = innerBoundaryList.at( j ).toElement();
 
  646         linearRingNodeList = currentInnerBoundaryElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"LinearRing" );
 
  647         if ( linearRingNodeList.size() < 1 )
 
  651         currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
 
  652         currentCoordinateList = currentLinearRingElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"coordinates" );
 
  653         if ( currentCoordinateList.size() < 1 )
 
  657         if ( readGMLCoordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
 
  661         currentPolygonList.push_back( ringCoordinates );
 
  667       exteriorList = currentPolygonElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"exterior" );
 
  668       if ( exteriorList.size() < 1 )
 
  673       currentExteriorElement = exteriorList.at( 0 ).toElement();
 
  676       linearRingNodeList = currentExteriorElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"LinearRing" );
 
  677       if ( linearRingNodeList.size() < 1 )
 
  681       currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
 
  682       currentPosList = currentLinearRingElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"posList" );
 
  683       if ( currentPosList.size() < 1 )
 
  687       if ( readGMLPositions( ringPositions, currentPosList.at( 0 ).toElement() ) != 0 )
 
  691       currentPolygonList.push_back( ringPositions );
 
  694       QDomNodeList interiorList = currentPolygonElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"interior" );
 
  695       for ( 
int j = 0; j < interiorList.size(); ++j )
 
  698         currentInteriorElement = interiorList.at( j ).toElement();
 
  699         linearRingNodeList = currentInteriorElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"LinearRing" );
 
  700         if ( linearRingNodeList.size() < 1 )
 
  704         currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
 
  705         currentPosList = currentLinearRingElement.elementsByTagNameNS( 
GML_NAMESPACE, 
"posList" );
 
  706         if ( currentPosList.size() < 1 )
 
  710         if ( readGMLPositions( ringPositions, currentPosList.at( 0 ).toElement() ) != 0 )
 
  714         currentPolygonList.push_back( ringPositions );
 
  717     multiPolygonPoints.push_back( currentPolygonList );
 
  720   int nPolygons = multiPolygonPoints.size();
 
  724   int size = 1 + 2 * 
sizeof( int );
 
  726   for ( QgsMultiPolygon::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it )
 
  728     size += 1 + 2 * 
sizeof( int );
 
  729     for ( QgsPolygon::const_iterator iter = it->begin(); iter != it->end(); ++iter )
 
  731       size += 
sizeof( int ) + 2 * iter->size() * 
sizeof( double );
 
  736   unsigned char* wkb = 
new unsigned char[
size];
 
  738   char e = htonl( 1 ) != 1;
 
  745   memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  747   memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  748   wkbPosition += 
sizeof( int );
 
  749   memcpy( &( wkb )[wkbPosition], &nPolygons, 
sizeof( 
int ) );
 
  750   wkbPosition += 
sizeof( int );
 
  754   for ( QgsMultiPolygon::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it )
 
  756     memcpy( &( wkb )[wkbPosition], &e, 1 );
 
  758     memcpy( &( wkb )[wkbPosition], &type, 
sizeof( 
int ) );
 
  759     wkbPosition += 
sizeof( int );
 
  761     memcpy( &( wkb )[wkbPosition], &nRings, 
sizeof( 
int ) );
 
  762     wkbPosition += 
sizeof( int );
 
  763     for ( QgsPolygon::const_iterator iter = it->begin(); iter != it->end(); ++iter )
 
  765       nPointsInRing = iter->size();
 
  766       memcpy( &( wkb )[wkbPosition], &nPointsInRing, 
sizeof( 
int ) );
 
  767       wkbPosition += 
sizeof( int );
 
  768       for ( QgsPolyline::const_iterator iterator = iter->begin(); iterator != iter->end(); ++iterator )
 
  772         memcpy( &( wkb )[wkbPosition], &x, 
sizeof( 
double ) );
 
  773         wkbPosition += 
sizeof( double );
 
  774         memcpy( &( wkb )[wkbPosition], &y, 
sizeof( 
double ) );
 
  775         wkbPosition += 
sizeof( double );
 
  785 bool QgsOgcUtils::readGMLCoordinates( 
QgsPolyline &coords, 
const QDomElement &elem )
 
  787   QString coordSeparator = 
",";
 
  788   QString tupelSeparator = 
" ";
 
  793   if ( elem.hasAttribute( 
"cs" ) )
 
  795     coordSeparator = elem.attribute( 
"cs" );
 
  797   if ( elem.hasAttribute( 
"ts" ) )
 
  799     tupelSeparator = elem.attribute( 
"ts" );
 
  802   QStringList tupels = elem.text().split( tupelSeparator, QString::SkipEmptyParts );
 
  803   QStringList tupel_coords;
 
  805   bool conversionSuccess;
 
  807   QStringList::const_iterator it;
 
  808   for ( it = tupels.constBegin(); it != tupels.constEnd(); ++it )
 
  810     tupel_coords = ( *it ).split( coordSeparator, QString::SkipEmptyParts );
 
  811     if ( tupel_coords.size() < 2 )
 
  815     x = tupel_coords.at( 0 ).toDouble( &conversionSuccess );
 
  816     if ( !conversionSuccess )
 
  820     y = tupel_coords.at( 1 ).toDouble( &conversionSuccess );
 
  821     if ( !conversionSuccess )
 
  825     coords.push_back( 
QgsPoint( x, y ) );
 
  834   QDomElement boxElem = boxNode.toElement();
 
  835   if ( boxElem.tagName() != 
"Box" )
 
  838   QDomElement bElem = boxElem.firstChild().toElement();
 
  839   QString coordSeparator = 
",";
 
  840   QString tupelSeparator = 
" ";
 
  841   if ( bElem.hasAttribute( 
"cs" ) )
 
  843     coordSeparator = bElem.attribute( 
"cs" );
 
  845   if ( bElem.hasAttribute( 
"ts" ) )
 
  847     tupelSeparator = bElem.attribute( 
"ts" );
 
  850   QString bString = bElem.text();
 
  851   bool ok1, ok2, ok3, ok4;
 
  852   double xmin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 0, 0 ).toDouble( &ok1 );
 
  853   double ymin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 1, 1 ).toDouble( &ok2 );
 
  854   double xmax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 0, 0 ).toDouble( &ok3 );
 
  855   double ymax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 1, 1 ).toDouble( &ok4 );
 
  857   if ( ok1 && ok2 && ok3 && ok4 )
 
  866 bool QgsOgcUtils::readGMLPositions( 
QgsPolyline &coords, 
const QDomElement &elem )
 
  869   QString coordSeparator = 
" ";
 
  870   QString tupelSeparator = 
" ";
 
  876   QStringList pos = elem.text().split( 
" ", QString::SkipEmptyParts );
 
  878   bool conversionSuccess;
 
  879   int posSize = pos.size();
 
  881   int srsDimension = 2;
 
  882   if ( elem.hasAttribute( 
"srsDimension" ) )
 
  884     srsDimension = elem.attribute( 
"srsDimension" ).toInt( &conversionSuccess );
 
  885     if ( !conversionSuccess )
 
  890   else if ( elem.hasAttribute( 
"dimension" ) )
 
  892     srsDimension = elem.attribute( 
"dimension" ).toInt( &conversionSuccess );
 
  893     if ( !conversionSuccess )
 
  899   for ( 
int i = 0; i < posSize / srsDimension; i++ )
 
  901     x = pos.at( i * srsDimension ).toDouble( &conversionSuccess );
 
  902     if ( !conversionSuccess )
 
  906     y = pos.at( i * srsDimension + 1 ).toDouble( &conversionSuccess );
 
  907     if ( !conversionSuccess )
 
  911     coords.push_back( 
QgsPoint( x, y ) );
 
  921   QDomElement envelopeElem = envelopeNode.toElement();
 
  922   if ( envelopeElem.tagName() != 
"Envelope" )
 
  925   QDomNodeList lowerCornerList = envelopeElem.elementsByTagNameNS( 
GML_NAMESPACE, 
"lowerCorner" );
 
  926   if ( lowerCornerList.size() < 1 )
 
  929   QDomNodeList upperCornerList = envelopeElem.elementsByTagNameNS( 
GML_NAMESPACE, 
"upperCorner" );
 
  930   if ( upperCornerList.size() < 1 )
 
  933   bool conversionSuccess;
 
  934   int srsDimension = 2;
 
  936   QDomElement elem = lowerCornerList.at( 0 ).toElement();
 
  937   if ( elem.hasAttribute( 
"srsDimension" ) )
 
  939     srsDimension = elem.attribute( 
"srsDimension" ).toInt( &conversionSuccess );
 
  940     if ( !conversionSuccess )
 
  945   else if ( elem.hasAttribute( 
"dimension" ) )
 
  947     srsDimension = elem.attribute( 
"dimension" ).toInt( &conversionSuccess );
 
  948     if ( !conversionSuccess )
 
  953   QString bString = elem.text();
 
  955   double xmin = bString.section( 
" ", 0, 0 ).toDouble( &conversionSuccess );
 
  956   if ( !conversionSuccess )
 
  958   double ymin = bString.section( 
" ", 1, 1 ).toDouble( &conversionSuccess );
 
  959   if ( !conversionSuccess )
 
  962   elem = upperCornerList.at( 0 ).toElement();
 
  963   if ( elem.hasAttribute( 
"srsDimension" ) )
 
  965     srsDimension = elem.attribute( 
"srsDimension" ).toInt( &conversionSuccess );
 
  966     if ( !conversionSuccess )
 
  971   else if ( elem.hasAttribute( 
"dimension" ) )
 
  973     srsDimension = elem.attribute( 
"dimension" ).toInt( &conversionSuccess );
 
  974     if ( !conversionSuccess )
 
  980   Q_UNUSED( srsDimension );
 
  982   bString = elem.text();
 
  983   double xmax = bString.section( 
" ", 0, 0 ).toDouble( &conversionSuccess );
 
  984   if ( !conversionSuccess )
 
  986   double ymax = bString.section( 
" ", 1, 1 ).toDouble( &conversionSuccess );
 
  987   if ( !conversionSuccess )
 
 1000     return QDomElement();
 
 1003   QDomElement boxElem = doc.createElement( 
"gml:Box" );
 
 1004   QDomElement coordElem = doc.createElement( 
"gml:coordinates" );
 
 1005   coordElem.setAttribute( 
"cs", 
"," );
 
 1006   coordElem.setAttribute( 
"ts", 
" " );
 
 1008   QString coordString;
 
 1017   QDomText coordText = doc.createTextNode( coordString );
 
 1018   coordElem.appendChild( coordText );
 
 1019   boxElem.appendChild( coordElem );
 
 1028     return QDomElement();
 
 1031   QDomElement envElem = doc.createElement( 
"gml:Envelope" );
 
 1034   QDomElement lowerCornerElem = doc.createElement( 
"gml:lowerCorner" );
 
 1038   QDomText lowerCornerText = doc.createTextNode( posList );
 
 1039   lowerCornerElem.appendChild( lowerCornerText );
 
 1040   envElem.appendChild( lowerCornerElem );
 
 1042   QDomElement upperCornerElem = doc.createElement( 
"gml:upperCorner" );
 
 1046   QDomText upperCornerText = doc.createTextNode( posList );
 
 1047   upperCornerElem.appendChild( upperCornerText );
 
 1048   envElem.appendChild( upperCornerElem );
 
 1055   if ( !geometry || !geometry->
asWkb() )
 
 1056     return QDomElement();
 
 1063   QDomElement baseCoordElem;
 
 1065   bool hasZValue = 
false;
 
 1069   if ( format == 
"GML3" )
 
 1071     switch ( geometry->
wkbType() )
 
 1077         baseCoordElem = doc.createElement( 
"gml:pos" );;
 
 1080         baseCoordElem = doc.createElement( 
"gml:posList" );;
 
 1083     baseCoordElem.setAttribute( 
"srsDimension", 
"2" );
 
 1088     baseCoordElem = doc.createElement( 
"gml:coordinates" );;
 
 1089     baseCoordElem.setAttribute( 
"cs", cs );
 
 1090     baseCoordElem.setAttribute( 
"ts", ts );
 
 1093   switch ( geometry->
wkbType() )
 
 1098       QDomElement pointElem = doc.createElement( 
"gml:Point" );
 
 1099       QDomElement coordElem = baseCoordElem.cloneNode().toElement();
 
 1105       coordElem.appendChild( coordText );
 
 1106       pointElem.appendChild( coordElem );
 
 1114       QDomElement multiPointElem = doc.createElement( 
"gml:MultiPoint" );
 
 1119       for ( 
int idx = 0; idx < nPoints; ++idx )
 
 1121         wkbPtr += 1 + 
sizeof( int );
 
 1122         QDomElement pointMemberElem = doc.createElement( 
"gml:pointMember" );
 
 1123         QDomElement pointElem = doc.createElement( 
"gml:Point" );
 
 1124         QDomElement coordElem = baseCoordElem.cloneNode().toElement();
 
 1130         coordElem.appendChild( coordText );
 
 1131         pointElem.appendChild( coordElem );
 
 1135           wkbPtr += 
sizeof( double );
 
 1137         pointMemberElem.appendChild( pointElem );
 
 1138         multiPointElem.appendChild( pointMemberElem );
 
 1140       return multiPointElem;
 
 1147       QDomElement lineStringElem = doc.createElement( 
"gml:LineString" );
 
 1153       QDomElement coordElem = baseCoordElem.cloneNode().toElement();
 
 1154       QString coordString;
 
 1155       for ( 
int idx = 0; idx < nPoints; ++idx )
 
 1168           wkbPtr += 
sizeof( double );
 
 1171       QDomText coordText = doc.createTextNode( coordString );
 
 1172       coordElem.appendChild( coordText );
 
 1173       lineStringElem.appendChild( coordElem );
 
 1174       return lineStringElem;
 
 1181       QDomElement multiLineStringElem = doc.createElement( 
"gml:MultiLineString" );
 
 1186       for ( 
int jdx = 0; jdx < nLines; jdx++ )
 
 1188         QDomElement lineStringMemberElem = doc.createElement( 
"gml:lineStringMember" );
 
 1189         QDomElement lineStringElem = doc.createElement( 
"gml:LineString" );
 
 1190         wkbPtr += 1 + 
sizeof( int ); 
 
 1195         QDomElement coordElem = baseCoordElem.cloneNode().toElement();
 
 1196         QString coordString;
 
 1197         for ( 
int idx = 0; idx < nPoints; idx++ )
 
 1211             wkbPtr += 
sizeof( double );
 
 1214         QDomText coordText = doc.createTextNode( coordString );
 
 1215         coordElem.appendChild( coordText );
 
 1216         lineStringElem.appendChild( coordElem );
 
 1217         lineStringMemberElem.appendChild( lineStringElem );
 
 1218         multiLineStringElem.appendChild( lineStringMemberElem );
 
 1220       return multiLineStringElem;
 
 1227       QDomElement polygonElem = doc.createElement( 
"gml:Polygon" );
 
 1233       if ( numRings == 0 ) 
 
 1234         return QDomElement();
 
 1236       int *ringNumPoints = 
new int[numRings]; 
 
 1238       for ( 
int idx = 0; idx < numRings; idx++ )
 
 1240         QString boundaryName = 
"gml:outerBoundaryIs";
 
 1243           boundaryName = 
"gml:innerBoundaryIs";
 
 1245         QDomElement boundaryElem = doc.createElement( boundaryName );
 
 1246         QDomElement ringElem = doc.createElement( 
"gml:LinearRing" );
 
 1250         ringNumPoints[idx] = nPoints;
 
 1252         QDomElement coordElem = baseCoordElem.cloneNode().toElement();
 
 1253         QString coordString;
 
 1254         for ( 
int jdx = 0; jdx < nPoints; jdx++ )
 
 1267             wkbPtr += 
sizeof( double );
 
 1270         QDomText coordText = doc.createTextNode( coordString );
 
 1271         coordElem.appendChild( coordText );
 
 1272         ringElem.appendChild( coordElem );
 
 1273         boundaryElem.appendChild( ringElem );
 
 1274         polygonElem.appendChild( boundaryElem );
 
 1276       delete [] ringNumPoints;
 
 1284       QDomElement multiPolygonElem = doc.createElement( 
"gml:MultiPolygon" );
 
 1287       wkbPtr >> numPolygons;
 
 1289       for ( 
int kdx = 0; kdx < numPolygons; kdx++ )
 
 1291         QDomElement polygonMemberElem = doc.createElement( 
"gml:polygonMember" );
 
 1292         QDomElement polygonElem = doc.createElement( 
"gml:Polygon" );
 
 1294         wkbPtr += 1 + 
sizeof( int );
 
 1299         for ( 
int idx = 0; idx < numRings; idx++ )
 
 1301           QString boundaryName = 
"gml:outerBoundaryIs";
 
 1304             boundaryName = 
"gml:innerBoundaryIs";
 
 1306           QDomElement boundaryElem = doc.createElement( boundaryName );
 
 1307           QDomElement ringElem = doc.createElement( 
"gml:LinearRing" );
 
 1312           QDomElement coordElem = baseCoordElem.cloneNode().toElement();
 
 1313           QString coordString;
 
 1314           for ( 
int jdx = 0; jdx < nPoints; jdx++ )
 
 1328               wkbPtr += 
sizeof( double );
 
 1331           QDomText coordText = doc.createTextNode( coordString );
 
 1332           coordElem.appendChild( coordText );
 
 1333           ringElem.appendChild( coordElem );
 
 1334           boundaryElem.appendChild( ringElem );
 
 1335           polygonElem.appendChild( boundaryElem );
 
 1336           polygonMemberElem.appendChild( polygonElem );
 
 1337           multiPolygonElem.appendChild( polygonMemberElem );
 
 1340       return multiPolygonElem;
 
 1343       return QDomElement();
 
 1352 QDomElement QgsOgcUtils::createGMLCoordinates( 
const QgsPolyline &points, QDomDocument &doc )
 
 1354   QDomElement coordElem = doc.createElement( 
"gml:coordinates" );
 
 1355   coordElem.setAttribute( 
"cs", 
"," );
 
 1356   coordElem.setAttribute( 
"ts", 
" " );
 
 1358   QString coordString;
 
 1359   QVector<QgsPoint>::const_iterator pointIt = points.constBegin();
 
 1360   for ( ; pointIt != points.constEnd(); ++pointIt )
 
 1362     if ( pointIt != points.constBegin() )
 
 1371   QDomText coordText = doc.createTextNode( coordString );
 
 1372   coordElem.appendChild( coordText );
 
 1376 QDomElement QgsOgcUtils::createGMLPositions( 
const QgsPolyline &points, QDomDocument& doc )
 
 1378   QDomElement posElem = doc.createElement( 
"gml:pos" );
 
 1379   if ( points.size() > 1 )
 
 1380     posElem = doc.createElement( 
"gml:posList" );
 
 1381   posElem.setAttribute( 
"srsDimension", 
"2" );
 
 1383   QString coordString;
 
 1384   QVector<QgsPoint>::const_iterator pointIt = points.constBegin();
 
 1385   for ( ; pointIt != points.constEnd(); ++pointIt )
 
 1387     if ( pointIt != points.constBegin() )
 
 1396   QDomText coordText = doc.createTextNode( coordString );
 
 1397   posElem.appendChild( coordText );
 
 1407   if ( fillElement.isNull() || !fillElement.hasChildNodes() )
 
 1415   QDomElement cssElem = fillElement.firstChildElement( 
"CssParameter" );
 
 1416   while ( !cssElem.isNull() )
 
 1418     cssName = cssElem.attribute( 
"name", 
"not_found" );
 
 1419     if ( cssName != 
"not_found" )
 
 1421       elemText = cssElem.text();
 
 1422       if ( cssName == 
"fill" )
 
 1424         color.setNamedColor( elemText );
 
 1426       else if ( cssName == 
"fill-opacity" )
 
 1429         double opacity = elemText.toDouble( &ok );
 
 1432           color.setAlphaF( opacity );
 
 1437     cssElem = cssElem.nextSiblingElement( 
"CssParameter" );
 
 1446   if ( element.isNull() || !element.hasChildNodes() )
 
 1451   QDomElement childElem = element.firstChildElement();
 
 1452   while ( !childElem.isNull() )
 
 1473     childElem = childElem.nextSiblingElement();
 
 1485   static QMap<QString, int> binOps;
 
 1486   if ( binOps.isEmpty() )
 
 1527   static QStringList spatialOps;
 
 1528   if ( spatialOps.isEmpty() )
 
 1530     spatialOps << 
"BBOX" << 
"Intersects" << 
"Contians" << 
"Crosses" << 
"Equals" 
 1531     << 
"Disjoint" << 
"Overlaps" << 
"Touches" << 
"Within";
 
 1534   return spatialOps.contains( tagName );
 
 1539 QgsExpression::Node* QgsOgcUtils::nodeFromOgcFilter( QDomElement &element, QString &errorMessage )
 
 1541   if ( element.isNull() )
 
 1547     return nodeBinaryOperatorFromOgcFilter( element, errorMessage );
 
 1553     return nodeSpatialOperatorFromOgcFilter( element, errorMessage );
 
 1558   if ( element.tagName() == 
"Not" )
 
 1560     return nodeNotFromOgcFilter( element, errorMessage );
 
 1562   else if ( element.tagName() == 
"PropertyIsNull" )
 
 1564     return nodePropertyIsNullFromOgcFilter( element, errorMessage );
 
 1566   else if ( element.tagName() == 
"Literal" )
 
 1568     return nodeLiteralFromOgcFilter( element, errorMessage );
 
 1570   else if ( element.tagName() == 
"Function" )
 
 1572     return nodeFunctionFromOgcFilter( element, errorMessage );
 
 1574   else if ( element.tagName() == 
"PropertyName" )
 
 1576     return nodeColumnRefFromOgcFilter( element, errorMessage );
 
 1578   else if ( element.tagName() == 
"PropertyIsBetween" )
 
 1580     return nodeIsBetweenFromOgcFilter( element, errorMessage );
 
 1583   errorMessage += QString( 
"unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).arg( element.tagName() );
 
 1591   if ( element.isNull() )
 
 1597     if ( errorMessage.isEmpty() )
 
 1598       errorMessage = QString( 
"'%1' binary operator not supported." ).arg( element.tagName() );
 
 1602   QDomElement operandElem = element.firstChildElement();
 
 1603   QgsExpression::Node *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
 
 1606     if ( errorMessage.isEmpty() )
 
 1607       errorMessage = QString( 
"invalid left operand for '%1' binary operator" ).arg( element.tagName() );
 
 1611   for ( operandElem = operandElem.nextSiblingElement(); !operandElem.isNull(); operandElem = operandElem.nextSiblingElement() )
 
 1616       if ( errorMessage.isEmpty() )
 
 1617         errorMessage = QString( 
"invalid right operand for '%1' binary operator" ).arg( element.tagName() );
 
 1625   if ( expr == leftOp )
 
 1627     if ( errorMessage.isEmpty() )
 
 1628       errorMessage = QString( 
"only one operand for '%1' binary operator" ).arg( element.tagName() );
 
 1647   QDomElement childElem = element.firstChildElement();
 
 1649   while ( !childElem.isNull() && gml2Str.isEmpty() )
 
 1651     if ( childElem.tagName() != 
"PropertyName" )
 
 1653       QTextStream gml2Stream( &gml2Str );
 
 1654       childElem.save( gml2Stream, 0 );
 
 1656     childElem = childElem.nextSiblingElement();
 
 1658   if ( !gml2Str.isEmpty() )
 
 1664     errorMessage = 
"No OGC Geometry found";
 
 1679   if ( element.tagName() != 
"Not" )
 
 1682   QDomElement operandElem = element.firstChildElement();
 
 1686     if ( errorMessage.isEmpty() )
 
 1687       errorMessage = QString( 
"invalid operand for '%1' unary operator" ).arg( element.tagName() );
 
 1697   if ( element.isNull() || element.tagName() != 
"Function" )
 
 1699     errorMessage = QString( 
"ogc:Function expected, got %1" ).arg( element.tagName() );
 
 1707     if ( element.attribute( 
"name" ) != funcDef->
name() )
 
 1712     QDomElement operandElem = element.firstChildElement();
 
 1713     while ( !operandElem.isNull() )
 
 1723       operandElem = operandElem.nextSiblingElement();
 
 1734 QgsExpression::Node* QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element, QString &errorMessage )
 
 1736   if ( element.isNull() || element.tagName() != 
"Literal" )
 
 1738     errorMessage = QString( 
"ogc:Literal expected, got %1" ).arg( element.tagName() );
 
 1745   QDomNode childNode = element.firstChild();
 
 1746   while ( !childNode.isNull() )
 
 1750     if ( childNode.nodeType() == QDomNode::ElementNode )
 
 1753       QDomElement operandElem = childNode.toElement();
 
 1754       operand = nodeFromOgcFilter( operandElem, errorMessage );
 
 1760         errorMessage = QString( 
"'%1' is an invalid or not supported content for ogc:Literal" ).arg( operandElem.tagName() );
 
 1767       QVariant value = childNode.nodeValue();
 
 1772       double d = value.toDouble( &ok );
 
 1791     childNode = childNode.nextSibling();
 
 1803   if ( element.isNull() || element.tagName() != 
"PropertyName" )
 
 1805     errorMessage = QString( 
"ogc:PropertyName expected, got %1" ).arg( element.tagName() );
 
 1813 QgsExpression::Node* QgsOgcUtils::nodeIsBetweenFromOgcFilter( QDomElement& element, QString& errorMessage )
 
 1819   QDomElement operandElem = element.firstChildElement();
 
 1820   while ( !operandElem.isNull() )
 
 1822     if ( operandElem.tagName() == 
"LowerBoundary" )
 
 1824       QDomElement lowerBoundElem = operandElem.firstChildElement();
 
 1825       lowerBound = nodeFromOgcFilter( lowerBoundElem, errorMessage );
 
 1827     else if ( operandElem.tagName() ==  
"UpperBoundary" )
 
 1829       QDomElement upperBoundElem = operandElem.firstChildElement();
 
 1830       upperBound = nodeFromOgcFilter( upperBoundElem, errorMessage );
 
 1837       operand = nodeFromOgcFilter( operandElem, errorMessage );
 
 1838       operand2 = nodeFromOgcFilter( operandElem, errorMessage );
 
 1841     if ( operand && lowerBound && operand2 && upperBound )
 
 1844     operandElem = operandElem.nextSiblingElement();
 
 1847   if ( !operand || !lowerBound || !operand2 || !upperBound )
 
 1858     errorMessage = 
"missing some required sub-elements in ogc:PropertyIsBetween";
 
 1871   if ( element.tagName() != 
"PropertyIsNull" )
 
 1876   QDomElement operandElem = element.firstChildElement();
 
 1892     return QDomElement();
 
 1894   QString localErrorMessage; 
 
 1895   QString& refErrorMessage = ( errorMessage ? *errorMessage : localErrorMessage );
 
 1896   refErrorMessage.clear();
 
 1898   QDomElement exprRootElem = expressionNodeToOgcFilter( exp.
rootNode(), doc, refErrorMessage );
 
 1899   if ( exprRootElem.isNull() )
 
 1900     return QDomElement();
 
 1902   QDomElement filterElem = doc.createElementNS( 
OGC_NAMESPACE, 
"ogc:Filter" );
 
 1903   filterElem.appendChild( exprRootElem );
 
 1908 QDomElement QgsOgcUtils::expressionNodeToOgcFilter( 
const QgsExpression::Node* node, QDomDocument& doc, QString& errorMessage )
 
 1913       return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeUnaryOperator*>( node ), doc, errorMessage );
 
 1915       return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeBinaryOperator*>( node ), doc, errorMessage );
 
 1917       return expressionInOperatorToOgcFilter( static_cast<const QgsExpression::NodeInOperator*>( node ), doc, errorMessage );
 
 1919       return expressionFunctionToOgcFilter( static_cast<const QgsExpression::NodeFunction*>( node ), doc, errorMessage );
 
 1921       return expressionLiteralToOgcFilter( static_cast<const QgsExpression::NodeLiteral*>( node ), doc, errorMessage );
 
 1923       return expressionColumnRefToOgcFilter( static_cast<const QgsExpression::NodeColumnRef*>( node ), doc, errorMessage );
 
 1926       errorMessage = QString( 
"Node type not supported: %1" ).arg( node->
nodeType() );
 
 1927       return QDomElement();
 
 1935   switch ( node->
op() )
 
 1938       uoElem = doc.createElement( 
"ogc:Literal" );
 
 1939       uoElem.appendChild( doc.createTextNode( 
"-" ) );
 
 1942       uoElem = doc.createElement( 
"ogc:Not" );
 
 1947       return QDomElement();
 
 1950   QDomElement operandElem = expressionNodeToOgcFilter( node->
operand(), doc, errorMessage );
 
 1951   if ( !errorMessage.isEmpty() )
 
 1952     return QDomElement();
 
 1954   uoElem.appendChild( operandElem );
 
 1961   QDomElement leftElem = expressionNodeToOgcFilter( node->
opLeft(), doc, errorMessage );
 
 1962   if ( !errorMessage.isEmpty() )
 
 1963     return QDomElement();
 
 1973       if ( rightLit->
value().isNull() )
 
 1976         QDomElement elem = doc.createElement( 
"ogc:PropertyIsNull" );
 
 1977         elem.appendChild( leftElem );
 
 1981           QDomElement notElem = doc.createElement( 
"ogc:Not" );
 
 1982           notElem.appendChild( elem );
 
 1995   QDomElement rightElem = expressionNodeToOgcFilter( node->
opRight(), doc, errorMessage );
 
 1996   if ( !errorMessage.isEmpty() )
 
 1997     return QDomElement();
 
 2001   if ( opText.isEmpty() )
 
 2006     return QDomElement();
 
 2009   QDomElement boElem = doc.createElement( 
"ogc:" + opText );
 
 2014       boElem.setAttribute( 
"matchCase", 
"false" );
 
 2017     boElem.setAttribute( 
"wildCard", 
"%" );
 
 2018     boElem.setAttribute( 
"singleChar", 
"?" );
 
 2019     boElem.setAttribute( 
"escapeChar", 
"!" );
 
 2022   boElem.appendChild( leftElem );
 
 2023   boElem.appendChild( rightElem );
 
 2028 QDomElement QgsOgcUtils::expressionLiteralToOgcFilter( 
const QgsExpression::NodeLiteral* node, QDomDocument& doc, QString& errorMessage )
 
 2031   switch ( node->
value().type() )
 
 2034       value = QString::number( node->
value().toInt() );
 
 2036     case QVariant::Double:
 
 2037       value = QString::number( node->
value().toDouble() );
 
 2039     case QVariant::String:
 
 2040       value = node->
value().toString();
 
 2044       errorMessage = QString( 
"Literal type not supported: %1" ).arg( node->
value().type() );
 
 2045       return QDomElement();
 
 2048   QDomElement litElem = doc.createElement( 
"ogc:Literal" );
 
 2049   litElem.appendChild( doc.createTextNode( value ) );
 
 2056   QDomElement propElem = doc.createElement( 
"ogc:PropertyName" );
 
 2057   propElem.appendChild( doc.createTextNode( node->
name() ) );
 
 2063 QDomElement QgsOgcUtils::expressionInOperatorToOgcFilter( 
const QgsExpression::NodeInOperator* node, QDomDocument& doc, QString& errorMessage )
 
 2065   if ( node->
list()->
list().size() == 1 )
 
 2066     return expressionNodeToOgcFilter( node->
list()->
list()[0], doc, errorMessage );
 
 2068   QDomElement orElem = doc.createElement( 
"ogc:Or" );
 
 2069   QDomElement leftNode = expressionNodeToOgcFilter( node->
node(), doc, errorMessage );
 
 2073     QDomElement listNode = expressionNodeToOgcFilter( n, doc, errorMessage );
 
 2074     if ( !errorMessage.isEmpty() )
 
 2075       return QDomElement();
 
 2077     QDomElement eqElem = doc.createElement( 
"ogc:PropertyIsEqualTo" );
 
 2078     eqElem.appendChild( leftNode.cloneNode() );
 
 2079     eqElem.appendChild( listNode );
 
 2081     orElem.appendChild( eqElem );
 
 2088   static QMap<QString, QString> binSpatialOps;
 
 2089   if ( binSpatialOps.isEmpty() )
 
 2091     binSpatialOps.insert( 
"disjoint", 
"Disjoint" );
 
 2092     binSpatialOps.insert( 
"intersects", 
"Intersects" );
 
 2093     binSpatialOps.insert( 
"touches", 
"Touches" );
 
 2094     binSpatialOps.insert( 
"crosses", 
"Crosses" );
 
 2095     binSpatialOps.insert( 
"contains", 
"Contains" );
 
 2096     binSpatialOps.insert( 
"overlaps", 
"Overlaps" );
 
 2097     binSpatialOps.insert( 
"within", 
"Within" );
 
 2099   return binSpatialOps;
 
 2119   return fd->
name() == 
"$geometry";
 
 2131     if ( fnDef->
name() == 
"geomFromWKT" )
 
 2133       const QList<QgsExpression::Node*>& args = fnNode->
args()->
list();
 
 2145 QDomElement QgsOgcUtils::expressionFunctionToOgcFilter( 
const QgsExpression::NodeFunction* node, QDomDocument& doc, QString& errorMessage )
 
 2149   if ( fd->
name() == 
"bbox" )
 
 2151     QList<QgsExpression::Node*> argNodes = node->
args()->
list();
 
 2152     Q_ASSERT( argNodes.count() == 2 ); 
 
 2162       QDomElement geomProperty = doc.createElement( 
"ogc:PropertyName" );
 
 2163       geomProperty.appendChild( doc.createTextNode( 
"geometry" ) );
 
 2165       QDomElement funcElem = doc.createElement( 
"ogr:BBOX" );
 
 2166       funcElem.appendChild( geomProperty );
 
 2167       funcElem.appendChild( elemBox );
 
 2174       errorMessage = QString( 
"<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('...'))" );
 
 2175       return QDomElement();
 
 2181     QList<QgsExpression::Node*> argNodes = node->
args()->
list();
 
 2182     Q_ASSERT( argNodes.count() == 2 ); 
 
 2186       otherNode = argNodes[1];
 
 2188       otherNode = argNodes[0];
 
 2191       errorMessage = QString( 
"Unable to translate spatial operator: at least one must refer to geometry." );
 
 2192       return QDomElement();
 
 2195     QDomElement otherGeomElem;
 
 2200       errorMessage = 
"spatial operator: the other operator must be a geometry constructor function";
 
 2201       return QDomElement();
 
 2206     if ( otherFnDef->
name() == 
"geomFromWKT" )
 
 2211         errorMessage = 
"geomFromWKT: argument must be string literal";
 
 2212         return QDomElement();
 
 2219     else if ( otherFnDef->
name() == 
"geomFromGML" )
 
 2224         errorMessage = 
"geomFromGML: argument must be string literal";
 
 2225         return QDomElement();
 
 2228       QDomDocument geomDoc;
 
 2230       if ( !geomDoc.setContent( gml, 
true ) )
 
 2232         errorMessage = 
"geomFromGML: unable to parse XML";
 
 2233         return QDomElement();
 
 2236       QDomNode geomNode = doc.importNode( geomDoc.documentElement(), true );
 
 2237       otherGeomElem = geomNode.toElement();
 
 2241       errorMessage = 
"spatial operator: unknown geometry constructor function";
 
 2242       return QDomElement();
 
 2246     QDomElement geomProperty = doc.createElement( 
"ogc:PropertyName" );
 
 2247     geomProperty.appendChild( doc.createTextNode( 
"geometry" ) );
 
 2248     funcElem.appendChild( geomProperty );
 
 2249     funcElem.appendChild( otherGeomElem );
 
 2255     errorMessage = QString( 
"Special columns / constants are not supported." );
 
 2256     return QDomElement();
 
 2260   QDomElement funcElem = doc.createElement( 
"ogc:Function" );
 
 2261   funcElem.setAttribute( 
"name", fd->
name() );
 
 2264     QDomElement childElem = expressionNodeToOgcFilter( n, doc, errorMessage );
 
 2265     if ( !errorMessage.isEmpty() )
 
 2266       return QDomElement();
 
 2268     funcElem.appendChild( childElem );