mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-19 00:04:52 -04:00
Moved GML import/export to a new class: QgsOgcUtils
This commit is contained in:
parent
290f8fd5b8
commit
969df016bc
@ -47,6 +47,7 @@
|
|||||||
%Include qgsmimedatautils.sip
|
%Include qgsmimedatautils.sip
|
||||||
%Include qgsnetworkaccessmanager.sip
|
%Include qgsnetworkaccessmanager.sip
|
||||||
%Include qgsofflineediting.sip
|
%Include qgsofflineediting.sip
|
||||||
|
%Include qgsogcutils.sip
|
||||||
%Include qgsoverlayobject.sip
|
%Include qgsoverlayobject.sip
|
||||||
%Include qgsowsconnection.sip
|
%Include qgsowsconnection.sip
|
||||||
%Include qgspaintenginehack.sip
|
%Include qgspaintenginehack.sip
|
||||||
|
@ -41,18 +41,6 @@ class QgsGeometry
|
|||||||
/** static method that creates geometry from Wkt */
|
/** static method that creates geometry from Wkt */
|
||||||
static QgsGeometry* fromWkt( QString wkt ) /Factory/;
|
static QgsGeometry* fromWkt( QString wkt ) /Factory/;
|
||||||
|
|
||||||
/** static method that creates geometry from GML2
|
|
||||||
@param XML representation of the geometry. GML elements are expected to be
|
|
||||||
in default namespace (<Point>...</Point>) or in "gml" namespace (<gml:Point>...</gml:Point>)
|
|
||||||
@note added in 1.9
|
|
||||||
*/
|
|
||||||
static QgsGeometry* fromGML2( const QString& xmlString ) /Factory/;
|
|
||||||
|
|
||||||
/** static method that creates geometry from GML2
|
|
||||||
@note added in 1.9
|
|
||||||
*/
|
|
||||||
static QgsGeometry* fromGML2( const QDomNode& geometryNode ) /Factory/;
|
|
||||||
|
|
||||||
/** construct geometry from a point */
|
/** construct geometry from a point */
|
||||||
static QgsGeometry* fromPoint( const QgsPoint& point ) /Factory/;
|
static QgsGeometry* fromPoint( const QgsPoint& point ) /Factory/;
|
||||||
/** construct geometry from a multipoint */
|
/** construct geometry from a multipoint */
|
||||||
|
32
python/core/qgsogcutils.sip
Normal file
32
python/core/qgsogcutils.sip
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class QgsOgcUtils
|
||||||
|
{
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include <qgsogcutils.h>
|
||||||
|
%End
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** static method that creates geometry from GML2
|
||||||
|
@param XML representation of the geometry. GML elements are expected to be
|
||||||
|
in default namespace (<Point>...</Point>) or in "gml" namespace (<gml:Point>...</gml:Point>)
|
||||||
|
@note added in 1.9
|
||||||
|
*/
|
||||||
|
static QgsGeometry* geometryFromGML2( const QString& xmlString ) /Factory/;
|
||||||
|
|
||||||
|
/** static method that creates geometry from GML2
|
||||||
|
@note added in 1.9
|
||||||
|
*/
|
||||||
|
static QgsGeometry* geometryFromGML2( const QDomNode& geometryNode ) /Factory/;
|
||||||
|
|
||||||
|
/** Exports the geometry to mGML2
|
||||||
|
@return true in case of success and false else
|
||||||
|
*/
|
||||||
|
static QDomElement geometryToGML2( QgsGeometry* geometry, QDomDocument& doc );
|
||||||
|
|
||||||
|
/** read rectangle from GML2 Box */
|
||||||
|
static QgsRectangle rectangleFromGMLBox( const QDomNode& boxNode );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -86,6 +86,7 @@ SET(QGIS_CORE_SRCS
|
|||||||
qgsnetworkreplyparser.cpp
|
qgsnetworkreplyparser.cpp
|
||||||
qgscredentials.cpp
|
qgscredentials.cpp
|
||||||
qgsofflineediting.cpp
|
qgsofflineediting.cpp
|
||||||
|
qgsogcutils.cpp
|
||||||
qgsoverlayobject.cpp
|
qgsoverlayobject.cpp
|
||||||
qgsowsconnection.cpp
|
qgsowsconnection.cpp
|
||||||
qgspalgeometry.cpp
|
qgspalgeometry.cpp
|
||||||
@ -404,6 +405,7 @@ SET(QGIS_CORE_HDRS
|
|||||||
qgsnetworkreplyparser.h
|
qgsnetworkreplyparser.h
|
||||||
qgscredentials.h
|
qgscredentials.h
|
||||||
qgsofflineediting.h
|
qgsofflineediting.h
|
||||||
|
qgsogcutils.h
|
||||||
qgsoverlayobjectpositionmanager.h
|
qgsoverlayobjectpositionmanager.h
|
||||||
qgsowsconnection.h
|
qgsowsconnection.h
|
||||||
qgspallabeling.h
|
qgspallabeling.h
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "qgsfeature.h"
|
#include "qgsfeature.h"
|
||||||
#include "qgsgeometry.h"
|
#include "qgsgeometry.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
|
#include "qgsogcutils.h"
|
||||||
|
|
||||||
// from parser
|
// from parser
|
||||||
extern QgsExpression::Node* parseExpression( const QString& str, QString& parserErrorMsg );
|
extern QgsExpression::Node* parseExpression( const QString& str, QString& parserErrorMsg );
|
||||||
@ -796,7 +797,7 @@ static QVariant fcnGeomFromWKT( const QVariantList& values, QgsFeature*, QgsExpr
|
|||||||
static QVariant fcnGeomFromGML2( const QVariantList& values, QgsFeature*, QgsExpression* parent )
|
static QVariant fcnGeomFromGML2( const QVariantList& values, QgsFeature*, QgsExpression* parent )
|
||||||
{
|
{
|
||||||
QString gml = getStringValue( values.at( 0 ), parent );
|
QString gml = getStringValue( values.at( 0 ), parent );
|
||||||
QgsGeometry* geom = QgsGeometry::fromGML2( gml );
|
QgsGeometry* geom = QgsOgcUtils::geometryFromGML2( gml );
|
||||||
|
|
||||||
if ( geom )
|
if ( geom )
|
||||||
return QVariant::fromValue( *geom );
|
return QVariant::fromValue( *geom );
|
||||||
@ -2268,11 +2269,10 @@ void QgsExpression::NodeFunction::toOgcFilter( QDomDocument &doc, QDomElement &e
|
|||||||
{
|
{
|
||||||
if ( childElem.attribute( "name" ) == "geomFromWKT" )
|
if ( childElem.attribute( "name" ) == "geomFromWKT" )
|
||||||
{
|
{
|
||||||
QgsGeometry* geom = 0;
|
QgsGeometry* geom = QgsGeometry::fromWkt( childElem.firstChildElement().text() );
|
||||||
geom = QgsGeometry::fromWkt( childElem.firstChildElement().text() );
|
|
||||||
if ( geom )
|
if ( geom )
|
||||||
funcElem.appendChild( geom->exportToGML2( doc ) );
|
funcElem.appendChild( QgsOgcUtils::geometryToGML2( geom, doc ) );
|
||||||
|
delete geom;
|
||||||
}
|
}
|
||||||
else if ( childElem.attribute( "name" ) == "geomFromGML2" )
|
else if ( childElem.attribute( "name" ) == "geomFromGML2" )
|
||||||
{
|
{
|
||||||
|
@ -533,625 +533,6 @@ QgsGeometry* QgsGeometry::fromRect( const QgsRectangle& rect )
|
|||||||
return fromPolygon( polygon );
|
return fromPolygon( polygon );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
|
|
||||||
QgsGeometry* QgsGeometry::fromGML2( const QDomNode& geometryNode )
|
|
||||||
{
|
|
||||||
QgsGeometry* g = new QgsGeometry();
|
|
||||||
QDomElement geometryTypeElement = geometryNode.toElement();
|
|
||||||
QString geomType = geometryTypeElement.tagName();
|
|
||||||
|
|
||||||
if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" || geomType == "Box" ) )
|
|
||||||
{
|
|
||||||
QDomNode geometryChild = geometryNode.firstChild();
|
|
||||||
if ( geometryChild.isNull() )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
geometryTypeElement = geometryChild.toElement();
|
|
||||||
geomType = geometryTypeElement.tagName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" || geomType == "Box" ) )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ( geomType == "Point" && g->setFromGML2Point( geometryTypeElement ) )
|
|
||||||
{
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
else if ( geomType == "LineString" && g->setFromGML2LineString( geometryTypeElement ) )
|
|
||||||
{
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
else if ( geomType == "Polygon" && g->setFromGML2Polygon( geometryTypeElement ) )
|
|
||||||
{
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
else if ( geomType == "MultiPoint" && g->setFromGML2MultiPoint( geometryTypeElement ) )
|
|
||||||
{
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
else if ( geomType == "MultiLineString" && g->setFromGML2MultiLineString( geometryTypeElement ) )
|
|
||||||
{
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
else if ( geomType == "MultiPolygon" && g->setFromGML2MultiPolygon( geometryTypeElement ) )
|
|
||||||
{
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
else if ( geomType == "Box" )
|
|
||||||
{
|
|
||||||
return QgsGeometry::fromRect( QgsRectangle( geometryTypeElement ) );
|
|
||||||
}
|
|
||||||
else //unknown type
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsGeometry* QgsGeometry::fromGML2( const QString& xmlString )
|
|
||||||
{
|
|
||||||
// wrap the string into a root tag to have "gml" namespace (and also as a default namespace)
|
|
||||||
QString xml = QString( "<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>").arg( GML_NAMESPACE ).arg( xmlString );
|
|
||||||
QDomDocument doc;
|
|
||||||
if ( !doc.setContent( xml, true ) )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return fromGML2( doc.documentElement().firstChildElement() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QgsGeometry::setFromGML2Point( const QDomElement& geometryElement )
|
|
||||||
{
|
|
||||||
QDomNodeList coordList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( coordList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QDomElement coordElement = coordList.at( 0 ).toElement();
|
|
||||||
std::list<QgsPoint> pointCoordinate;
|
|
||||||
if ( readGML2Coordinates( pointCoordinate, coordElement ) != 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( pointCoordinate.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<QgsPoint>::const_iterator point_it = pointCoordinate.begin();
|
|
||||||
//char e = QgsApplication::endian();
|
|
||||||
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
|
||||||
double x = point_it->x();
|
|
||||||
double y = point_it->y();
|
|
||||||
int size = 1 + sizeof( int ) + 2 * sizeof( double );
|
|
||||||
|
|
||||||
QGis::WkbType type = QGis::WKBPoint;
|
|
||||||
unsigned char* wkb = new unsigned char[size];
|
|
||||||
|
|
||||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
|
||||||
|
|
||||||
fromWkb( wkb, size );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::setFromGML2LineString( const QDomElement& geometryElement )
|
|
||||||
{
|
|
||||||
QDomNodeList coordinatesList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( coordinatesList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QDomElement coordinatesElement = coordinatesList.at( 0 ).toElement();
|
|
||||||
std::list<QgsPoint> lineCoordinates;
|
|
||||||
if ( readGML2Coordinates( lineCoordinates, coordinatesElement ) != 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//char e = QgsApplication::endian();
|
|
||||||
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
|
||||||
int size = 1 + 2 * sizeof( int ) + lineCoordinates.size() * 2 * sizeof( double );
|
|
||||||
|
|
||||||
QGis::WkbType type = QGis::WKBLineString;
|
|
||||||
unsigned char* wkb = new unsigned char[size];
|
|
||||||
|
|
||||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
|
||||||
double x, y;
|
|
||||||
int nPoints = lineCoordinates.size();
|
|
||||||
|
|
||||||
//fill the contents into *wkb
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
|
|
||||||
std::list<QgsPoint>::const_iterator iter;
|
|
||||||
for ( iter = lineCoordinates.begin(); iter != lineCoordinates.end(); ++iter )
|
|
||||||
{
|
|
||||||
x = iter->x();
|
|
||||||
y = iter->y();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
}
|
|
||||||
|
|
||||||
fromWkb( wkb, size );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::setFromGML2Polygon( const QDomElement& geometryElement )
|
|
||||||
{
|
|
||||||
//read all the coordinates (as QgsPoint) into memory. Each linear ring has an entry in the vector
|
|
||||||
std::vector<std::list<QgsPoint> > ringCoordinates;
|
|
||||||
|
|
||||||
//read coordinates for outer boundary
|
|
||||||
QDomNodeList outerBoundaryList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "outerBoundaryIs" );
|
|
||||||
if ( outerBoundaryList.size() < 1 ) //outer ring is necessary
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QDomElement coordinatesElement = outerBoundaryList.at( 0 ).firstChild().firstChild().toElement();
|
|
||||||
if ( coordinatesElement.isNull() )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::list<QgsPoint> exteriorPointList;
|
|
||||||
if ( readGML2Coordinates( exteriorPointList, coordinatesElement ) != 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ringCoordinates.push_back( exteriorPointList );
|
|
||||||
|
|
||||||
//read coordinates for inner boundary
|
|
||||||
QDomNodeList innerBoundaryList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "innerBoundaryIs" );
|
|
||||||
for ( int i = 0; i < innerBoundaryList.size(); ++i )
|
|
||||||
{
|
|
||||||
std::list<QgsPoint> interiorPointList;
|
|
||||||
QDomElement coordinatesElement = innerBoundaryList.at( i ).firstChild().firstChild().toElement();
|
|
||||||
if ( coordinatesElement.isNull() )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( readGML2Coordinates( interiorPointList, coordinatesElement ) != 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ringCoordinates.push_back( interiorPointList );
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate number of bytes to allocate
|
|
||||||
int nrings = ringCoordinates.size();
|
|
||||||
int npoints = 0;//total number of points
|
|
||||||
for ( std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it )
|
|
||||||
{
|
|
||||||
npoints += it->size();
|
|
||||||
}
|
|
||||||
int size = 1 + 2 * sizeof( int ) + nrings * sizeof( int ) + 2 * npoints * sizeof( double );
|
|
||||||
|
|
||||||
QGis::WkbType type = QGis::WKBPolygon;
|
|
||||||
unsigned char* wkb = new unsigned char[size];
|
|
||||||
|
|
||||||
//char e = QgsApplication::endian();
|
|
||||||
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
|
||||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
|
||||||
int nPointsInRing = 0;
|
|
||||||
double x, y;
|
|
||||||
|
|
||||||
//fill the contents into *wkb
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nrings, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
for ( std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it )
|
|
||||||
{
|
|
||||||
nPointsInRing = it->size();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nPointsInRing, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
//iterate through the string list converting the strings to x-/y- doubles
|
|
||||||
std::list<QgsPoint>::const_iterator iter;
|
|
||||||
for ( iter = it->begin(); iter != it->end(); ++iter )
|
|
||||||
{
|
|
||||||
x = iter->x();
|
|
||||||
y = iter->y();
|
|
||||||
//qWarning("currentCoordinate: " + QString::number(x) + " // " + QString::number(y));
|
|
||||||
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fromWkb( wkb, size );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::setFromGML2MultiPoint( const QDomElement& geometryElement )
|
|
||||||
{
|
|
||||||
std::list<QgsPoint> pointList;
|
|
||||||
std::list<QgsPoint> currentPoint;
|
|
||||||
QDomNodeList pointMemberList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "pointMember" );
|
|
||||||
if ( pointMemberList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QDomNodeList pointNodeList;
|
|
||||||
QDomNodeList coordinatesList;
|
|
||||||
for ( int i = 0; i < pointMemberList.size(); ++i )
|
|
||||||
{
|
|
||||||
//<Point> element
|
|
||||||
pointNodeList = pointMemberList.at( i ).toElement().elementsByTagNameNS( GML_NAMESPACE, "Point" );
|
|
||||||
if ( pointNodeList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//<coordinates> element
|
|
||||||
coordinatesList = pointNodeList.at( 0 ).toElement().elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( coordinatesList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
currentPoint.clear();
|
|
||||||
if ( readGML2Coordinates( currentPoint, coordinatesList.at( 0 ).toElement() ) != 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( currentPoint.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pointList.push_back(( *currentPoint.begin() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate the required wkb size
|
|
||||||
int size = 1 + 2 * sizeof( int ) + pointList.size() * ( 2 * sizeof( double ) + 1 + sizeof( int ) );
|
|
||||||
|
|
||||||
QGis::WkbType type = QGis::WKBMultiPoint;
|
|
||||||
unsigned char* wkb = new unsigned char[size];
|
|
||||||
|
|
||||||
//fill the wkb content
|
|
||||||
//char e = QgsApplication::endian();
|
|
||||||
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
|
||||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
|
||||||
int nPoints = pointList.size(); //number of points
|
|
||||||
double x, y;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
for ( std::list<QgsPoint>::const_iterator it = pointList.begin(); it != pointList.end(); ++it )
|
|
||||||
{
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
x = it->x();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
y = it->y();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
}
|
|
||||||
|
|
||||||
fromWkb( wkb, size );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::setFromGML2MultiLineString( const QDomElement& geometryElement )
|
|
||||||
{
|
|
||||||
//geoserver has
|
|
||||||
//<gml:MultiLineString>
|
|
||||||
//<gml:lineStringMember>
|
|
||||||
//<gml:LineString>
|
|
||||||
|
|
||||||
//mapserver has directly
|
|
||||||
//<gml:MultiLineString
|
|
||||||
//<gml:LineString
|
|
||||||
|
|
||||||
std::list<std::list<QgsPoint> > lineCoordinates; //first list: lines, second list: points of one line
|
|
||||||
QDomElement currentLineStringElement;
|
|
||||||
QDomNodeList currentCoordList;
|
|
||||||
|
|
||||||
QDomNodeList lineStringMemberList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "lineStringMember" );
|
|
||||||
if ( lineStringMemberList.size() > 0 ) //geoserver
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < lineStringMemberList.size(); ++i )
|
|
||||||
{
|
|
||||||
QDomNodeList lineStringNodeList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "LineString" );
|
|
||||||
if ( lineStringNodeList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
currentLineStringElement = lineStringNodeList.at( 0 ).toElement();
|
|
||||||
currentCoordList = currentLineStringElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( currentCoordList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::list<QgsPoint> currentPointList;
|
|
||||||
if ( readGML2Coordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
lineCoordinates.push_back( currentPointList );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QDomNodeList lineStringList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "LineString" );
|
|
||||||
if ( lineStringList.size() > 0 ) //mapserver
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < lineStringList.size(); ++i )
|
|
||||||
{
|
|
||||||
currentLineStringElement = lineStringList.at( i ).toElement();
|
|
||||||
currentCoordList = currentLineStringElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( currentCoordList.size() < 1 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::list<QgsPoint> currentPointList;
|
|
||||||
if ( readGML2Coordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
lineCoordinates.push_back( currentPointList );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//calculate the required wkb size
|
|
||||||
int size = ( lineCoordinates.size() + 1 ) * ( 1 + 2 * sizeof( int ) );
|
|
||||||
for ( std::list<std::list<QgsPoint> >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it )
|
|
||||||
{
|
|
||||||
size += it->size() * 2 * sizeof( double );
|
|
||||||
}
|
|
||||||
|
|
||||||
QGis::WkbType type = QGis::WKBMultiLineString;
|
|
||||||
unsigned char* wkb = new unsigned char[size];
|
|
||||||
|
|
||||||
//fill the wkb content
|
|
||||||
//char e = QgsApplication::endian();
|
|
||||||
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
|
||||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
|
||||||
int nLines = lineCoordinates.size();
|
|
||||||
int nPoints; //number of points in a line
|
|
||||||
double x, y;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nLines, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
for ( std::list<std::list<QgsPoint> >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it )
|
|
||||||
{
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
nPoints = it->size();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
for ( std::list<QgsPoint>::const_iterator iter = it->begin(); iter != it->end(); ++iter )
|
|
||||||
{
|
|
||||||
x = iter->x();
|
|
||||||
//qWarning("x is: " + QString::number(x));
|
|
||||||
y = iter->y();
|
|
||||||
//qWarning("y is: " + QString::number(y));
|
|
||||||
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fromWkb( wkb, size );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::setFromGML2MultiPolygon( const QDomElement& geometryElement )
|
|
||||||
{
|
|
||||||
//first list: different polygons, second list: different rings, third list: different points
|
|
||||||
std::list<std::list<std::list<QgsPoint> > > multiPolygonPoints;
|
|
||||||
QDomElement currentPolygonMemberElement;
|
|
||||||
QDomNodeList polygonList;
|
|
||||||
QDomElement currentPolygonElement;
|
|
||||||
QDomNodeList outerBoundaryList;
|
|
||||||
QDomElement currentOuterBoundaryElement;
|
|
||||||
QDomElement currentInnerBoundaryElement;
|
|
||||||
QDomNodeList innerBoundaryList;
|
|
||||||
QDomNodeList linearRingNodeList;
|
|
||||||
QDomElement currentLinearRingElement;
|
|
||||||
QDomNodeList currentCoordinateList;
|
|
||||||
|
|
||||||
QDomNodeList polygonMemberList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "polygonMember" );
|
|
||||||
for ( int i = 0; i < polygonMemberList.size(); ++i )
|
|
||||||
{
|
|
||||||
std::list<std::list<QgsPoint> > currentPolygonList;
|
|
||||||
currentPolygonMemberElement = polygonMemberList.at( i ).toElement();
|
|
||||||
polygonList = currentPolygonMemberElement.elementsByTagNameNS( GML_NAMESPACE, "Polygon" );
|
|
||||||
if ( polygonList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
currentPolygonElement = polygonList.at( 0 ).toElement();
|
|
||||||
|
|
||||||
//find exterior ring
|
|
||||||
outerBoundaryList = currentPolygonElement.elementsByTagNameNS( GML_NAMESPACE, "outerBoundaryIs" );
|
|
||||||
if ( outerBoundaryList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentOuterBoundaryElement = outerBoundaryList.at( 0 ).toElement();
|
|
||||||
std::list<QgsPoint> ringCoordinates;
|
|
||||||
|
|
||||||
linearRingNodeList = currentOuterBoundaryElement.elementsByTagNameNS( GML_NAMESPACE, "LinearRing" );
|
|
||||||
if ( linearRingNodeList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
|
|
||||||
currentCoordinateList = currentLinearRingElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( currentCoordinateList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( readGML2Coordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
currentPolygonList.push_back( ringCoordinates );
|
|
||||||
|
|
||||||
//find interior rings
|
|
||||||
QDomNodeList innerBoundaryList = currentPolygonElement.elementsByTagNameNS( GML_NAMESPACE, "innerBoundaryIs" );
|
|
||||||
for ( int j = 0; j < innerBoundaryList.size(); ++j )
|
|
||||||
{
|
|
||||||
std::list<QgsPoint> ringCoordinates;
|
|
||||||
currentInnerBoundaryElement = innerBoundaryList.at( j ).toElement();
|
|
||||||
linearRingNodeList = currentInnerBoundaryElement.elementsByTagNameNS( GML_NAMESPACE, "LinearRing" );
|
|
||||||
if ( linearRingNodeList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
|
|
||||||
currentCoordinateList = currentLinearRingElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
|
||||||
if ( currentCoordinateList.size() < 1 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( readGML2Coordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
currentPolygonList.push_back( ringCoordinates );
|
|
||||||
}
|
|
||||||
multiPolygonPoints.push_back( currentPolygonList );
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = 1 + 2 * sizeof( int );
|
|
||||||
//calculate the wkb size
|
|
||||||
for ( std::list<std::list<std::list<QgsPoint> > >::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it )
|
|
||||||
{
|
|
||||||
size += 1 + 2 * sizeof( int );
|
|
||||||
for ( std::list<std::list<QgsPoint> >::const_iterator iter = it->begin(); iter != it->end(); ++iter )
|
|
||||||
{
|
|
||||||
size += sizeof( int ) + 2 * iter->size() * sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QGis::WkbType type = QGis::WKBMultiPolygon;
|
|
||||||
unsigned char* wkb = new unsigned char[size];
|
|
||||||
|
|
||||||
int polygonType = QGis::WKBPolygon;
|
|
||||||
//char e = QgsApplication::endian();
|
|
||||||
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
|
||||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
|
||||||
double x, y;
|
|
||||||
int nPolygons = multiPolygonPoints.size();
|
|
||||||
int nRings;
|
|
||||||
int nPointsInRing;
|
|
||||||
|
|
||||||
//fill the contents into *wkb
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nPolygons, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
|
|
||||||
for ( std::list<std::list<std::list<QgsPoint> > >::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it )
|
|
||||||
{
|
|
||||||
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
|
||||||
wkbPosition += 1;
|
|
||||||
memcpy( &( wkb )[wkbPosition], &polygonType, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
nRings = it->size();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nRings, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
for ( std::list<std::list<QgsPoint> >::const_iterator iter = it->begin(); iter != it->end(); ++iter )
|
|
||||||
{
|
|
||||||
nPointsInRing = iter->size();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &nPointsInRing, sizeof( int ) );
|
|
||||||
wkbPosition += sizeof( int );
|
|
||||||
for ( std::list<QgsPoint>::const_iterator iterator = iter->begin(); iterator != iter->end(); ++iterator )
|
|
||||||
{
|
|
||||||
x = iterator->x();
|
|
||||||
y = iterator->y();
|
|
||||||
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
|
||||||
wkbPosition += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fromWkb( wkb, size );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::readGML2Coordinates( std::list<QgsPoint>& coords, const QDomElement elem ) const
|
|
||||||
{
|
|
||||||
QString coordSeparator = ",";
|
|
||||||
QString tupelSeparator = " ";
|
|
||||||
//"decimal" has to be "."
|
|
||||||
|
|
||||||
coords.clear();
|
|
||||||
|
|
||||||
if ( elem.hasAttribute( "cs" ) )
|
|
||||||
{
|
|
||||||
coordSeparator = elem.attribute( "cs" );
|
|
||||||
}
|
|
||||||
if ( elem.hasAttribute( "ts" ) )
|
|
||||||
{
|
|
||||||
tupelSeparator = elem.attribute( "ts" );
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList tupels = elem.text().split( tupelSeparator, QString::SkipEmptyParts );
|
|
||||||
QStringList tupel_coords;
|
|
||||||
double x, y;
|
|
||||||
bool conversionSuccess;
|
|
||||||
|
|
||||||
QStringList::const_iterator it;
|
|
||||||
for ( it = tupels.constBegin(); it != tupels.constEnd(); ++it )
|
|
||||||
{
|
|
||||||
tupel_coords = ( *it ).split( coordSeparator, QString::SkipEmptyParts );
|
|
||||||
if ( tupel_coords.size() < 2 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
x = tupel_coords.at( 0 ).toDouble( &conversionSuccess );
|
|
||||||
if ( !conversionSuccess )
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
y = tupel_coords.at( 1 ).toDouble( &conversionSuccess );
|
|
||||||
if ( !conversionSuccess )
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
coords.push_back( QgsPoint( x, y ) );
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsGeometry & QgsGeometry::operator=( QgsGeometry const & rhs )
|
QgsGeometry & QgsGeometry::operator=( QgsGeometry const & rhs )
|
||||||
{
|
{
|
||||||
@ -5145,316 +4526,6 @@ QString QgsGeometry::exportToGeoJSON()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDomElement QgsGeometry::exportToGML2( QDomDocument& doc )
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "entered." );
|
|
||||||
|
|
||||||
// TODO: implement with GEOS
|
|
||||||
if ( mDirtyWkb )
|
|
||||||
{
|
|
||||||
exportGeosToWkb();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !mGeometry )
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "WKB geometry not available!" );
|
|
||||||
return QDomElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
QGis::WkbType wkbType;
|
|
||||||
bool hasZValue = false;
|
|
||||||
double *x, *y;
|
|
||||||
|
|
||||||
QString mWkt; // TODO: rename
|
|
||||||
|
|
||||||
// Will this really work when mGeometry[0] == 0 ???? I (gavin) think not.
|
|
||||||
//wkbType = (mGeometry[0] == 1) ? mGeometry[1] : mGeometry[4];
|
|
||||||
memcpy( &wkbType, &( mGeometry[1] ), sizeof( int ) );
|
|
||||||
|
|
||||||
switch ( wkbType )
|
|
||||||
{
|
|
||||||
case QGis::WKBPoint25D:
|
|
||||||
case QGis::WKBPoint:
|
|
||||||
{
|
|
||||||
QDomElement pointElem = doc.createElement( "gml:Point" );
|
|
||||||
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
|
||||||
coordElem.setAttribute( "cs", "," );
|
|
||||||
coordElem.setAttribute( "ts", " " );
|
|
||||||
QString coordString;
|
|
||||||
x = ( double * )( mGeometry + 5 );
|
|
||||||
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
coordString += ",";
|
|
||||||
y = ( double * )( mGeometry + 5 + sizeof( double ) );
|
|
||||||
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
|
||||||
coordElem.appendChild( coordText );
|
|
||||||
pointElem.appendChild( coordElem );
|
|
||||||
return pointElem;
|
|
||||||
}
|
|
||||||
case QGis::WKBMultiPoint25D:
|
|
||||||
hasZValue = true;
|
|
||||||
case QGis::WKBMultiPoint:
|
|
||||||
{
|
|
||||||
unsigned char *ptr;
|
|
||||||
int idx;
|
|
||||||
int *nPoints;
|
|
||||||
|
|
||||||
QDomElement multiPointElem = doc.createElement( "gml:MultiPoint" );
|
|
||||||
nPoints = ( int* )( mGeometry + 5 );
|
|
||||||
ptr = mGeometry + 5 + sizeof( int );
|
|
||||||
for ( idx = 0; idx < *nPoints; ++idx )
|
|
||||||
{
|
|
||||||
ptr += ( 1 + sizeof( int ) );
|
|
||||||
QDomElement pointMemberElem = doc.createElement( "gml:pointMember" );
|
|
||||||
QDomElement pointElem = doc.createElement( "gml:Point" );
|
|
||||||
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
|
||||||
coordElem.setAttribute( "cs", "," );
|
|
||||||
coordElem.setAttribute( "ts", " " );
|
|
||||||
QString coordString;
|
|
||||||
x = ( double * )( ptr );
|
|
||||||
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
coordString += ",";
|
|
||||||
ptr += sizeof( double );
|
|
||||||
y = ( double * )( ptr );
|
|
||||||
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
|
||||||
coordElem.appendChild( coordText );
|
|
||||||
pointElem.appendChild( coordElem );
|
|
||||||
|
|
||||||
ptr += sizeof( double );
|
|
||||||
if ( hasZValue )
|
|
||||||
{
|
|
||||||
ptr += sizeof( double );
|
|
||||||
}
|
|
||||||
pointMemberElem.appendChild( pointElem );
|
|
||||||
multiPointElem.appendChild( pointMemberElem );
|
|
||||||
}
|
|
||||||
return multiPointElem;
|
|
||||||
}
|
|
||||||
case QGis::WKBLineString25D:
|
|
||||||
hasZValue = true;
|
|
||||||
case QGis::WKBLineString:
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "LINESTRING found" );
|
|
||||||
unsigned char *ptr;
|
|
||||||
int *nPoints;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
|
|
||||||
// get number of points in the line
|
|
||||||
ptr = mGeometry + 5;
|
|
||||||
nPoints = ( int * ) ptr;
|
|
||||||
ptr = mGeometry + 1 + 2 * sizeof( int );
|
|
||||||
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
|
||||||
coordElem.setAttribute( "cs", "," );
|
|
||||||
coordElem.setAttribute( "ts", " " );
|
|
||||||
QString coordString;
|
|
||||||
for ( idx = 0; idx < *nPoints; ++idx )
|
|
||||||
{
|
|
||||||
if ( idx != 0 )
|
|
||||||
{
|
|
||||||
coordString += " ";
|
|
||||||
}
|
|
||||||
x = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
coordString += ",";
|
|
||||||
ptr += sizeof( double );
|
|
||||||
y = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
ptr += sizeof( double );
|
|
||||||
if ( hasZValue )
|
|
||||||
{
|
|
||||||
ptr += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
|
||||||
coordElem.appendChild( coordText );
|
|
||||||
lineStringElem.appendChild( coordElem );
|
|
||||||
return lineStringElem;
|
|
||||||
}
|
|
||||||
case QGis::WKBMultiLineString25D:
|
|
||||||
hasZValue = true;
|
|
||||||
case QGis::WKBMultiLineString:
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "MULTILINESTRING found" );
|
|
||||||
unsigned char *ptr;
|
|
||||||
int idx, jdx, numLineStrings;
|
|
||||||
int *nPoints;
|
|
||||||
|
|
||||||
QDomElement multiLineStringElem = doc.createElement( "gml:MultiLineString" );
|
|
||||||
numLineStrings = ( int )( mGeometry[5] );
|
|
||||||
ptr = mGeometry + 9;
|
|
||||||
for ( jdx = 0; jdx < numLineStrings; jdx++ )
|
|
||||||
{
|
|
||||||
QDomElement lineStringMemberElem = doc.createElement( "gml:lineStringMember" );
|
|
||||||
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
|
|
||||||
ptr += 5; // skip type since we know its 2
|
|
||||||
nPoints = ( int * ) ptr;
|
|
||||||
ptr += sizeof( int );
|
|
||||||
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
|
||||||
coordElem.setAttribute( "cs", "," );
|
|
||||||
coordElem.setAttribute( "ts", " " );
|
|
||||||
QString coordString;
|
|
||||||
for ( idx = 0; idx < *nPoints; idx++ )
|
|
||||||
{
|
|
||||||
if ( idx != 0 )
|
|
||||||
{
|
|
||||||
coordString += " ";
|
|
||||||
}
|
|
||||||
x = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
ptr += sizeof( double );
|
|
||||||
coordString += ",";
|
|
||||||
y = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
ptr += sizeof( double );
|
|
||||||
if ( hasZValue )
|
|
||||||
{
|
|
||||||
ptr += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
|
||||||
coordElem.appendChild( coordText );
|
|
||||||
lineStringElem.appendChild( coordElem );
|
|
||||||
lineStringMemberElem.appendChild( lineStringElem );
|
|
||||||
multiLineStringElem.appendChild( lineStringMemberElem );
|
|
||||||
}
|
|
||||||
return multiLineStringElem;
|
|
||||||
}
|
|
||||||
case QGis::WKBPolygon25D:
|
|
||||||
hasZValue = true;
|
|
||||||
case QGis::WKBPolygon:
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "POLYGON found" );
|
|
||||||
unsigned char *ptr;
|
|
||||||
int idx, jdx;
|
|
||||||
int *numRings, *nPoints;
|
|
||||||
|
|
||||||
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
|
|
||||||
// get number of rings in the polygon
|
|
||||||
numRings = ( int * )( mGeometry + 1 + sizeof( int ) );
|
|
||||||
if ( !( *numRings ) ) // sanity check for zero rings in polygon
|
|
||||||
{
|
|
||||||
return QDomElement();
|
|
||||||
}
|
|
||||||
int *ringStart; // index of first point for each ring
|
|
||||||
int *ringNumPoints; // number of points in each ring
|
|
||||||
ringStart = new int[*numRings];
|
|
||||||
ringNumPoints = new int[*numRings];
|
|
||||||
ptr = mGeometry + 1 + 2 * sizeof( int ); // set pointer to the first ring
|
|
||||||
for ( idx = 0; idx < *numRings; idx++ )
|
|
||||||
{
|
|
||||||
QString boundaryName = "gml:outerBoundaryIs";
|
|
||||||
if ( idx != 0 )
|
|
||||||
{
|
|
||||||
boundaryName = "gml:innerBoundaryIs";
|
|
||||||
}
|
|
||||||
QDomElement boundaryElem = doc.createElement( boundaryName );
|
|
||||||
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
|
|
||||||
// get number of points in the ring
|
|
||||||
nPoints = ( int * ) ptr;
|
|
||||||
ringNumPoints[idx] = *nPoints;
|
|
||||||
ptr += 4;
|
|
||||||
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
|
||||||
coordElem.setAttribute( "cs", "," );
|
|
||||||
coordElem.setAttribute( "ts", " " );
|
|
||||||
QString coordString;
|
|
||||||
for ( jdx = 0; jdx < *nPoints; jdx++ )
|
|
||||||
{
|
|
||||||
if ( jdx != 0 )
|
|
||||||
{
|
|
||||||
coordString += " ";
|
|
||||||
}
|
|
||||||
x = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
coordString += ",";
|
|
||||||
ptr += sizeof( double );
|
|
||||||
y = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
ptr += sizeof( double );
|
|
||||||
if ( hasZValue )
|
|
||||||
{
|
|
||||||
ptr += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
|
||||||
coordElem.appendChild( coordText );
|
|
||||||
ringElem.appendChild( coordElem );
|
|
||||||
boundaryElem.appendChild( ringElem );
|
|
||||||
polygonElem.appendChild( boundaryElem );
|
|
||||||
}
|
|
||||||
delete [] ringStart;
|
|
||||||
delete [] ringNumPoints;
|
|
||||||
return polygonElem;
|
|
||||||
}
|
|
||||||
case QGis::WKBMultiPolygon25D:
|
|
||||||
hasZValue = true;
|
|
||||||
case QGis::WKBMultiPolygon:
|
|
||||||
{
|
|
||||||
QgsDebugMsg( "MULTIPOLYGON found" );
|
|
||||||
unsigned char *ptr;
|
|
||||||
int idx, jdx, kdx;
|
|
||||||
int *numPolygons, *numRings, *nPoints;
|
|
||||||
|
|
||||||
QDomElement multiPolygonElem = doc.createElement( "gml:MultiPolygon" );
|
|
||||||
ptr = mGeometry + 5;
|
|
||||||
numPolygons = ( int * ) ptr;
|
|
||||||
ptr = mGeometry + 9;
|
|
||||||
for ( kdx = 0; kdx < *numPolygons; kdx++ )
|
|
||||||
{
|
|
||||||
QDomElement polygonMemberElem = doc.createElement( "gml:polygonMember" );
|
|
||||||
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
|
|
||||||
ptr += 5;
|
|
||||||
numRings = ( int * ) ptr;
|
|
||||||
ptr += 4;
|
|
||||||
for ( idx = 0; idx < *numRings; idx++ )
|
|
||||||
{
|
|
||||||
QString boundaryName = "gml:outerBoundaryIs";
|
|
||||||
if ( idx != 0 )
|
|
||||||
{
|
|
||||||
boundaryName = "gml:innerBoundaryIs";
|
|
||||||
}
|
|
||||||
QDomElement boundaryElem = doc.createElement( boundaryName );
|
|
||||||
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
|
|
||||||
nPoints = ( int * ) ptr;
|
|
||||||
ptr += 4;
|
|
||||||
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
|
||||||
coordElem.setAttribute( "cs", "," );
|
|
||||||
coordElem.setAttribute( "ts", " " );
|
|
||||||
QString coordString;
|
|
||||||
for ( jdx = 0; jdx < *nPoints; jdx++ )
|
|
||||||
{
|
|
||||||
if ( jdx != 0 )
|
|
||||||
{
|
|
||||||
coordString += " ";
|
|
||||||
}
|
|
||||||
x = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
ptr += sizeof( double );
|
|
||||||
coordString += ",";
|
|
||||||
y = ( double * ) ptr;
|
|
||||||
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
|
||||||
ptr += sizeof( double );
|
|
||||||
if ( hasZValue )
|
|
||||||
{
|
|
||||||
ptr += sizeof( double );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QDomText coordText = doc.createTextNode( coordString );
|
|
||||||
coordElem.appendChild( coordText );
|
|
||||||
ringElem.appendChild( coordElem );
|
|
||||||
boundaryElem.appendChild( ringElem );
|
|
||||||
polygonElem.appendChild( boundaryElem );
|
|
||||||
polygonMemberElem.appendChild( polygonElem );
|
|
||||||
multiPolygonElem.appendChild( polygonMemberElem );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return multiPolygonElem;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return QDomElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsGeometry::exportWkbToGeos()
|
bool QgsGeometry::exportWkbToGeos()
|
||||||
{
|
{
|
||||||
|
@ -89,18 +89,6 @@ class CORE_EXPORT QgsGeometry
|
|||||||
/** static method that creates geometry from Wkt */
|
/** static method that creates geometry from Wkt */
|
||||||
static QgsGeometry* fromWkt( QString wkt );
|
static QgsGeometry* fromWkt( QString wkt );
|
||||||
|
|
||||||
/** static method that creates geometry from GML2
|
|
||||||
@param XML representation of the geometry. GML elements are expected to be
|
|
||||||
in default namespace (<Point>...</Point>) or in "gml" namespace (<gml:Point>...</gml:Point>)
|
|
||||||
@note added in 1.9
|
|
||||||
*/
|
|
||||||
static QgsGeometry* fromGML2( const QString& xmlString );
|
|
||||||
|
|
||||||
/** static method that creates geometry from GML2
|
|
||||||
@note added in 1.9
|
|
||||||
*/
|
|
||||||
static QgsGeometry* fromGML2( const QDomNode& geometryNode );
|
|
||||||
|
|
||||||
/** construct geometry from a point */
|
/** construct geometry from a point */
|
||||||
static QgsGeometry* fromPoint( const QgsPoint& point );
|
static QgsGeometry* fromPoint( const QgsPoint& point );
|
||||||
/** construct geometry from a multipoint */
|
/** construct geometry from a multipoint */
|
||||||
@ -395,12 +383,6 @@ class CORE_EXPORT QgsGeometry
|
|||||||
*/
|
*/
|
||||||
QString exportToGeoJSON();
|
QString exportToGeoJSON();
|
||||||
|
|
||||||
/** Exports the geometry to mGML2
|
|
||||||
@return true in case of success and false else
|
|
||||||
* @note added in 1.9
|
|
||||||
*/
|
|
||||||
QDomElement exportToGML2( QDomDocument& doc );
|
|
||||||
|
|
||||||
/* Accessor functions for getting geometry data */
|
/* Accessor functions for getting geometry data */
|
||||||
|
|
||||||
/** return contents of the geometry as a point
|
/** return contents of the geometry as a point
|
||||||
@ -506,24 +488,6 @@ class CORE_EXPORT QgsGeometry
|
|||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
|
|
||||||
/** static method that creates geometry from GML2 Point */
|
|
||||||
bool setFromGML2Point( const QDomElement& geometryElement );
|
|
||||||
/** static method that creates geometry from GML2 LineString */
|
|
||||||
bool setFromGML2LineString( const QDomElement& geometryElement );
|
|
||||||
/** static method that creates geometry from GML2 Polygon */
|
|
||||||
bool setFromGML2Polygon( const QDomElement& geometryElement );
|
|
||||||
/** static method that creates geometry from GML2 MultiPoint */
|
|
||||||
bool setFromGML2MultiPoint( const QDomElement& geometryElement );
|
|
||||||
/** static method that creates geometry from GML2 MultiLineString */
|
|
||||||
bool setFromGML2MultiLineString( const QDomElement& geometryElement );
|
|
||||||
/** static method that creates geometry from GML2 MultiPolygon */
|
|
||||||
bool setFromGML2MultiPolygon( const QDomElement& geometryElement );
|
|
||||||
/**Reads the <gml:coordinates> element and extracts the coordinates as points
|
|
||||||
@param coords list where the found coordinates are appended
|
|
||||||
@param elem the <gml:coordinates> element
|
|
||||||
@return boolean for success*/
|
|
||||||
bool readGML2Coordinates( std::list<QgsPoint>& coords, const QDomElement elem ) const;
|
|
||||||
|
|
||||||
/** Converts from the WKB geometry to the GEOS geometry.
|
/** Converts from the WKB geometry to the GEOS geometry.
|
||||||
@return true in case of success and false else
|
@return true in case of success and false else
|
||||||
*/
|
*/
|
||||||
|
969
src/core/qgsogcutils.cpp
Normal file
969
src/core/qgsogcutils.cpp
Normal file
@ -0,0 +1,969 @@
|
|||||||
|
#include "qgsogcutils.h"
|
||||||
|
|
||||||
|
#include "qgsgeometry.h"
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#ifndef Q_WS_WIN
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#else
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2( const QDomNode& geometryNode )
|
||||||
|
{
|
||||||
|
QDomElement geometryTypeElement = geometryNode.toElement();
|
||||||
|
QString geomType = geometryTypeElement.tagName();
|
||||||
|
|
||||||
|
if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" || geomType == "Box" ) )
|
||||||
|
{
|
||||||
|
QDomNode geometryChild = geometryNode.firstChild();
|
||||||
|
if ( geometryChild.isNull() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
geometryTypeElement = geometryChild.toElement();
|
||||||
|
geomType = geometryTypeElement.tagName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" || geomType == "Box" ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( geomType == "Point" )
|
||||||
|
{
|
||||||
|
return geometryFromGML2Point( geometryTypeElement );
|
||||||
|
}
|
||||||
|
else if ( geomType == "LineString" )
|
||||||
|
{
|
||||||
|
return geometryFromGML2LineString( geometryTypeElement );
|
||||||
|
}
|
||||||
|
else if ( geomType == "Polygon" )
|
||||||
|
{
|
||||||
|
return geometryFromGML2Polygon( geometryTypeElement );
|
||||||
|
}
|
||||||
|
else if ( geomType == "MultiPoint" )
|
||||||
|
{
|
||||||
|
return geometryFromGML2MultiPoint( geometryTypeElement );
|
||||||
|
}
|
||||||
|
else if ( geomType == "MultiLineString" )
|
||||||
|
{
|
||||||
|
return geometryFromGML2MultiLineString( geometryTypeElement );
|
||||||
|
}
|
||||||
|
else if ( geomType == "MultiPolygon" )
|
||||||
|
{
|
||||||
|
return geometryFromGML2MultiPolygon( geometryTypeElement );
|
||||||
|
}
|
||||||
|
else if ( geomType == "Box" )
|
||||||
|
{
|
||||||
|
return QgsGeometry::fromRect( rectangleFromGMLBox( geometryTypeElement ) );
|
||||||
|
}
|
||||||
|
else //unknown type
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2( const QString& xmlString )
|
||||||
|
{
|
||||||
|
// wrap the string into a root tag to have "gml" namespace (and also as a default namespace)
|
||||||
|
QString xml = QString( "<tmp xmlns=\"%1\" xmlns:gml=\"%1\">%2</tmp>").arg( GML_NAMESPACE ).arg( xmlString );
|
||||||
|
QDomDocument doc;
|
||||||
|
if ( !doc.setContent( xml, true ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return geometryFromGML2( doc.documentElement().firstChildElement() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2Point( const QDomElement& geometryElement )
|
||||||
|
{
|
||||||
|
QDomNodeList coordList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( coordList.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
QDomElement coordElement = coordList.at( 0 ).toElement();
|
||||||
|
std::list<QgsPoint> pointCoordinate;
|
||||||
|
if ( readGML2Coordinates( pointCoordinate, coordElement ) != 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pointCoordinate.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<QgsPoint>::const_iterator point_it = pointCoordinate.begin();
|
||||||
|
//char e = QgsApplication::endian();
|
||||||
|
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
||||||
|
double x = point_it->x();
|
||||||
|
double y = point_it->y();
|
||||||
|
int size = 1 + sizeof( int ) + 2 * sizeof( double );
|
||||||
|
|
||||||
|
QGis::WkbType type = QGis::WKBPoint;
|
||||||
|
unsigned char* wkb = new unsigned char[size];
|
||||||
|
|
||||||
|
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
||||||
|
|
||||||
|
QgsGeometry* g = new QgsGeometry();
|
||||||
|
g->fromWkb( wkb, size );
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2LineString( const QDomElement& geometryElement )
|
||||||
|
{
|
||||||
|
QDomNodeList coordinatesList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( coordinatesList.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
QDomElement coordinatesElement = coordinatesList.at( 0 ).toElement();
|
||||||
|
std::list<QgsPoint> lineCoordinates;
|
||||||
|
if ( readGML2Coordinates( lineCoordinates, coordinatesElement ) != 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//char e = QgsApplication::endian();
|
||||||
|
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
||||||
|
int size = 1 + 2 * sizeof( int ) + lineCoordinates.size() * 2 * sizeof( double );
|
||||||
|
|
||||||
|
QGis::WkbType type = QGis::WKBLineString;
|
||||||
|
unsigned char* wkb = new unsigned char[size];
|
||||||
|
|
||||||
|
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||||
|
double x, y;
|
||||||
|
int nPoints = lineCoordinates.size();
|
||||||
|
|
||||||
|
//fill the contents into *wkb
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
|
||||||
|
std::list<QgsPoint>::const_iterator iter;
|
||||||
|
for ( iter = lineCoordinates.begin(); iter != lineCoordinates.end(); ++iter )
|
||||||
|
{
|
||||||
|
x = iter->x();
|
||||||
|
y = iter->y();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* g = new QgsGeometry();
|
||||||
|
g->fromWkb( wkb, size );
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2Polygon( const QDomElement& geometryElement )
|
||||||
|
{
|
||||||
|
//read all the coordinates (as QgsPoint) into memory. Each linear ring has an entry in the vector
|
||||||
|
std::vector<std::list<QgsPoint> > ringCoordinates;
|
||||||
|
|
||||||
|
//read coordinates for outer boundary
|
||||||
|
QDomNodeList outerBoundaryList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "outerBoundaryIs" );
|
||||||
|
if ( outerBoundaryList.size() < 1 ) //outer ring is necessary
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
QDomElement coordinatesElement = outerBoundaryList.at( 0 ).firstChild().firstChild().toElement();
|
||||||
|
if ( coordinatesElement.isNull() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::list<QgsPoint> exteriorPointList;
|
||||||
|
if ( readGML2Coordinates( exteriorPointList, coordinatesElement ) != 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ringCoordinates.push_back( exteriorPointList );
|
||||||
|
|
||||||
|
//read coordinates for inner boundary
|
||||||
|
QDomNodeList innerBoundaryList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "innerBoundaryIs" );
|
||||||
|
for ( int i = 0; i < innerBoundaryList.size(); ++i )
|
||||||
|
{
|
||||||
|
std::list<QgsPoint> interiorPointList;
|
||||||
|
QDomElement coordinatesElement = innerBoundaryList.at( i ).firstChild().firstChild().toElement();
|
||||||
|
if ( coordinatesElement.isNull() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( readGML2Coordinates( interiorPointList, coordinatesElement ) != 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ringCoordinates.push_back( interiorPointList );
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate number of bytes to allocate
|
||||||
|
int nrings = ringCoordinates.size();
|
||||||
|
int npoints = 0;//total number of points
|
||||||
|
for ( std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it )
|
||||||
|
{
|
||||||
|
npoints += it->size();
|
||||||
|
}
|
||||||
|
int size = 1 + 2 * sizeof( int ) + nrings * sizeof( int ) + 2 * npoints * sizeof( double );
|
||||||
|
|
||||||
|
QGis::WkbType type = QGis::WKBPolygon;
|
||||||
|
unsigned char* wkb = new unsigned char[size];
|
||||||
|
|
||||||
|
//char e = QgsApplication::endian();
|
||||||
|
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
||||||
|
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||||
|
int nPointsInRing = 0;
|
||||||
|
double x, y;
|
||||||
|
|
||||||
|
//fill the contents into *wkb
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nrings, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
for ( std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it )
|
||||||
|
{
|
||||||
|
nPointsInRing = it->size();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nPointsInRing, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
//iterate through the string list converting the strings to x-/y- doubles
|
||||||
|
std::list<QgsPoint>::const_iterator iter;
|
||||||
|
for ( iter = it->begin(); iter != it->end(); ++iter )
|
||||||
|
{
|
||||||
|
x = iter->x();
|
||||||
|
y = iter->y();
|
||||||
|
//qWarning("currentCoordinate: " + QString::number(x) + " // " + QString::number(y));
|
||||||
|
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* g = new QgsGeometry();
|
||||||
|
g->fromWkb( wkb, size );
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2MultiPoint( const QDomElement& geometryElement )
|
||||||
|
{
|
||||||
|
std::list<QgsPoint> pointList;
|
||||||
|
std::list<QgsPoint> currentPoint;
|
||||||
|
QDomNodeList pointMemberList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "pointMember" );
|
||||||
|
if ( pointMemberList.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
QDomNodeList pointNodeList;
|
||||||
|
QDomNodeList coordinatesList;
|
||||||
|
for ( int i = 0; i < pointMemberList.size(); ++i )
|
||||||
|
{
|
||||||
|
//<Point> element
|
||||||
|
pointNodeList = pointMemberList.at( i ).toElement().elementsByTagNameNS( GML_NAMESPACE, "Point" );
|
||||||
|
if ( pointNodeList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//<coordinates> element
|
||||||
|
coordinatesList = pointNodeList.at( 0 ).toElement().elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( coordinatesList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentPoint.clear();
|
||||||
|
if ( readGML2Coordinates( currentPoint, coordinatesList.at( 0 ).toElement() ) != 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( currentPoint.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pointList.push_back(( *currentPoint.begin() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate the required wkb size
|
||||||
|
int size = 1 + 2 * sizeof( int ) + pointList.size() * ( 2 * sizeof( double ) + 1 + sizeof( int ) );
|
||||||
|
|
||||||
|
QGis::WkbType type = QGis::WKBMultiPoint;
|
||||||
|
unsigned char* wkb = new unsigned char[size];
|
||||||
|
|
||||||
|
//fill the wkb content
|
||||||
|
//char e = QgsApplication::endian();
|
||||||
|
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
||||||
|
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||||
|
int nPoints = pointList.size(); //number of points
|
||||||
|
double x, y;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
for ( std::list<QgsPoint>::const_iterator it = pointList.begin(); it != pointList.end(); ++it )
|
||||||
|
{
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
x = it->x();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
y = it->y();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* g = new QgsGeometry();
|
||||||
|
g->fromWkb( wkb, size );
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2MultiLineString( const QDomElement& geometryElement )
|
||||||
|
{
|
||||||
|
//geoserver has
|
||||||
|
//<gml:MultiLineString>
|
||||||
|
//<gml:lineStringMember>
|
||||||
|
//<gml:LineString>
|
||||||
|
|
||||||
|
//mapserver has directly
|
||||||
|
//<gml:MultiLineString
|
||||||
|
//<gml:LineString
|
||||||
|
|
||||||
|
std::list<std::list<QgsPoint> > lineCoordinates; //first list: lines, second list: points of one line
|
||||||
|
QDomElement currentLineStringElement;
|
||||||
|
QDomNodeList currentCoordList;
|
||||||
|
|
||||||
|
QDomNodeList lineStringMemberList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "lineStringMember" );
|
||||||
|
if ( lineStringMemberList.size() > 0 ) //geoserver
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < lineStringMemberList.size(); ++i )
|
||||||
|
{
|
||||||
|
QDomNodeList lineStringNodeList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "LineString" );
|
||||||
|
if ( lineStringNodeList.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
currentLineStringElement = lineStringNodeList.at( 0 ).toElement();
|
||||||
|
currentCoordList = currentLineStringElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( currentCoordList.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::list<QgsPoint> currentPointList;
|
||||||
|
if ( readGML2Coordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lineCoordinates.push_back( currentPointList );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QDomNodeList lineStringList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "LineString" );
|
||||||
|
if ( lineStringList.size() > 0 ) //mapserver
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < lineStringList.size(); ++i )
|
||||||
|
{
|
||||||
|
currentLineStringElement = lineStringList.at( i ).toElement();
|
||||||
|
currentCoordList = currentLineStringElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( currentCoordList.size() < 1 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::list<QgsPoint> currentPointList;
|
||||||
|
if ( readGML2Coordinates( currentPointList, currentCoordList.at( 0 ).toElement() ) != 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lineCoordinates.push_back( currentPointList );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//calculate the required wkb size
|
||||||
|
int size = ( lineCoordinates.size() + 1 ) * ( 1 + 2 * sizeof( int ) );
|
||||||
|
for ( std::list<std::list<QgsPoint> >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it )
|
||||||
|
{
|
||||||
|
size += it->size() * 2 * sizeof( double );
|
||||||
|
}
|
||||||
|
|
||||||
|
QGis::WkbType type = QGis::WKBMultiLineString;
|
||||||
|
unsigned char* wkb = new unsigned char[size];
|
||||||
|
|
||||||
|
//fill the wkb content
|
||||||
|
//char e = QgsApplication::endian();
|
||||||
|
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
||||||
|
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||||
|
int nLines = lineCoordinates.size();
|
||||||
|
int nPoints; //number of points in a line
|
||||||
|
double x, y;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nLines, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
for ( std::list<std::list<QgsPoint> >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it )
|
||||||
|
{
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
nPoints = it->size();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
for ( std::list<QgsPoint>::const_iterator iter = it->begin(); iter != it->end(); ++iter )
|
||||||
|
{
|
||||||
|
x = iter->x();
|
||||||
|
//qWarning("x is: " + QString::number(x));
|
||||||
|
y = iter->y();
|
||||||
|
//qWarning("y is: " + QString::number(y));
|
||||||
|
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* g = new QgsGeometry();
|
||||||
|
g->fromWkb( wkb, size );
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* QgsOgcUtils::geometryFromGML2MultiPolygon( const QDomElement& geometryElement )
|
||||||
|
{
|
||||||
|
//first list: different polygons, second list: different rings, third list: different points
|
||||||
|
std::list<std::list<std::list<QgsPoint> > > multiPolygonPoints;
|
||||||
|
QDomElement currentPolygonMemberElement;
|
||||||
|
QDomNodeList polygonList;
|
||||||
|
QDomElement currentPolygonElement;
|
||||||
|
QDomNodeList outerBoundaryList;
|
||||||
|
QDomElement currentOuterBoundaryElement;
|
||||||
|
QDomElement currentInnerBoundaryElement;
|
||||||
|
QDomNodeList innerBoundaryList;
|
||||||
|
QDomNodeList linearRingNodeList;
|
||||||
|
QDomElement currentLinearRingElement;
|
||||||
|
QDomNodeList currentCoordinateList;
|
||||||
|
|
||||||
|
QDomNodeList polygonMemberList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "polygonMember" );
|
||||||
|
for ( int i = 0; i < polygonMemberList.size(); ++i )
|
||||||
|
{
|
||||||
|
std::list<std::list<QgsPoint> > currentPolygonList;
|
||||||
|
currentPolygonMemberElement = polygonMemberList.at( i ).toElement();
|
||||||
|
polygonList = currentPolygonMemberElement.elementsByTagNameNS( GML_NAMESPACE, "Polygon" );
|
||||||
|
if ( polygonList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentPolygonElement = polygonList.at( 0 ).toElement();
|
||||||
|
|
||||||
|
//find exterior ring
|
||||||
|
outerBoundaryList = currentPolygonElement.elementsByTagNameNS( GML_NAMESPACE, "outerBoundaryIs" );
|
||||||
|
if ( outerBoundaryList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentOuterBoundaryElement = outerBoundaryList.at( 0 ).toElement();
|
||||||
|
std::list<QgsPoint> ringCoordinates;
|
||||||
|
|
||||||
|
linearRingNodeList = currentOuterBoundaryElement.elementsByTagNameNS( GML_NAMESPACE, "LinearRing" );
|
||||||
|
if ( linearRingNodeList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
|
||||||
|
currentCoordinateList = currentLinearRingElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( currentCoordinateList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( readGML2Coordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentPolygonList.push_back( ringCoordinates );
|
||||||
|
|
||||||
|
//find interior rings
|
||||||
|
QDomNodeList innerBoundaryList = currentPolygonElement.elementsByTagNameNS( GML_NAMESPACE, "innerBoundaryIs" );
|
||||||
|
for ( int j = 0; j < innerBoundaryList.size(); ++j )
|
||||||
|
{
|
||||||
|
std::list<QgsPoint> ringCoordinates;
|
||||||
|
currentInnerBoundaryElement = innerBoundaryList.at( j ).toElement();
|
||||||
|
linearRingNodeList = currentInnerBoundaryElement.elementsByTagNameNS( GML_NAMESPACE, "LinearRing" );
|
||||||
|
if ( linearRingNodeList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentLinearRingElement = linearRingNodeList.at( 0 ).toElement();
|
||||||
|
currentCoordinateList = currentLinearRingElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
|
||||||
|
if ( currentCoordinateList.size() < 1 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( readGML2Coordinates( ringCoordinates, currentCoordinateList.at( 0 ).toElement() ) != 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
currentPolygonList.push_back( ringCoordinates );
|
||||||
|
}
|
||||||
|
multiPolygonPoints.push_back( currentPolygonList );
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 1 + 2 * sizeof( int );
|
||||||
|
//calculate the wkb size
|
||||||
|
for ( std::list<std::list<std::list<QgsPoint> > >::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it )
|
||||||
|
{
|
||||||
|
size += 1 + 2 * sizeof( int );
|
||||||
|
for ( std::list<std::list<QgsPoint> >::const_iterator iter = it->begin(); iter != it->end(); ++iter )
|
||||||
|
{
|
||||||
|
size += sizeof( int ) + 2 * iter->size() * sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QGis::WkbType type = QGis::WKBMultiPolygon;
|
||||||
|
unsigned char* wkb = new unsigned char[size];
|
||||||
|
|
||||||
|
int polygonType = QGis::WKBPolygon;
|
||||||
|
//char e = QgsApplication::endian();
|
||||||
|
char e = ( htonl( 1 ) == 1 ) ? 0 : 1 ;
|
||||||
|
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||||
|
double x, y;
|
||||||
|
int nPolygons = multiPolygonPoints.size();
|
||||||
|
int nRings;
|
||||||
|
int nPointsInRing;
|
||||||
|
|
||||||
|
//fill the contents into *wkb
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &type, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nPolygons, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
|
||||||
|
for ( std::list<std::list<std::list<QgsPoint> > >::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it )
|
||||||
|
{
|
||||||
|
memcpy( &( wkb )[wkbPosition], &e, 1 );
|
||||||
|
wkbPosition += 1;
|
||||||
|
memcpy( &( wkb )[wkbPosition], &polygonType, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
nRings = it->size();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nRings, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
for ( std::list<std::list<QgsPoint> >::const_iterator iter = it->begin(); iter != it->end(); ++iter )
|
||||||
|
{
|
||||||
|
nPointsInRing = iter->size();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &nPointsInRing, sizeof( int ) );
|
||||||
|
wkbPosition += sizeof( int );
|
||||||
|
for ( std::list<QgsPoint>::const_iterator iterator = iter->begin(); iterator != iter->end(); ++iterator )
|
||||||
|
{
|
||||||
|
x = iterator->x();
|
||||||
|
y = iterator->y();
|
||||||
|
memcpy( &( wkb )[wkbPosition], &x, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
memcpy( &( wkb )[wkbPosition], &y, sizeof( double ) );
|
||||||
|
wkbPosition += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsGeometry* g = new QgsGeometry();
|
||||||
|
g->fromWkb( wkb, size );
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsOgcUtils::readGML2Coordinates( std::list<QgsPoint>& coords, const QDomElement elem )
|
||||||
|
{
|
||||||
|
QString coordSeparator = ",";
|
||||||
|
QString tupelSeparator = " ";
|
||||||
|
//"decimal" has to be "."
|
||||||
|
|
||||||
|
coords.clear();
|
||||||
|
|
||||||
|
if ( elem.hasAttribute( "cs" ) )
|
||||||
|
{
|
||||||
|
coordSeparator = elem.attribute( "cs" );
|
||||||
|
}
|
||||||
|
if ( elem.hasAttribute( "ts" ) )
|
||||||
|
{
|
||||||
|
tupelSeparator = elem.attribute( "ts" );
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList tupels = elem.text().split( tupelSeparator, QString::SkipEmptyParts );
|
||||||
|
QStringList tupel_coords;
|
||||||
|
double x, y;
|
||||||
|
bool conversionSuccess;
|
||||||
|
|
||||||
|
QStringList::const_iterator it;
|
||||||
|
for ( it = tupels.constBegin(); it != tupels.constEnd(); ++it )
|
||||||
|
{
|
||||||
|
tupel_coords = ( *it ).split( coordSeparator, QString::SkipEmptyParts );
|
||||||
|
if ( tupel_coords.size() < 2 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
x = tupel_coords.at( 0 ).toDouble( &conversionSuccess );
|
||||||
|
if ( !conversionSuccess )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
y = tupel_coords.at( 1 ).toDouble( &conversionSuccess );
|
||||||
|
if ( !conversionSuccess )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
coords.push_back( QgsPoint( x, y ) );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QDomElement QgsOgcUtils::geometryToGML2( QgsGeometry* geometry, QDomDocument& doc )
|
||||||
|
{
|
||||||
|
if ( !geometry || !geometry->asWkb() )
|
||||||
|
return QDomElement();
|
||||||
|
|
||||||
|
bool hasZValue = false;
|
||||||
|
double *x, *y;
|
||||||
|
unsigned char* wkb = geometry->asWkb();
|
||||||
|
|
||||||
|
switch ( geometry->wkbType() )
|
||||||
|
{
|
||||||
|
case QGis::WKBPoint25D:
|
||||||
|
case QGis::WKBPoint:
|
||||||
|
{
|
||||||
|
QDomElement pointElem = doc.createElement( "gml:Point" );
|
||||||
|
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
||||||
|
coordElem.setAttribute( "cs", "," );
|
||||||
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
QString coordString;
|
||||||
|
x = ( double * )( wkb + 5 );
|
||||||
|
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
coordString += ",";
|
||||||
|
y = ( double * )( wkb + 5 + sizeof( double ) );
|
||||||
|
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
coordElem.appendChild( coordText );
|
||||||
|
pointElem.appendChild( coordElem );
|
||||||
|
return pointElem;
|
||||||
|
}
|
||||||
|
case QGis::WKBMultiPoint25D:
|
||||||
|
hasZValue = true;
|
||||||
|
case QGis::WKBMultiPoint:
|
||||||
|
{
|
||||||
|
unsigned char *ptr;
|
||||||
|
int idx;
|
||||||
|
int *nPoints;
|
||||||
|
|
||||||
|
QDomElement multiPointElem = doc.createElement( "gml:MultiPoint" );
|
||||||
|
nPoints = ( int* )( wkb + 5 );
|
||||||
|
ptr = wkb + 5 + sizeof( int );
|
||||||
|
for ( idx = 0; idx < *nPoints; ++idx )
|
||||||
|
{
|
||||||
|
ptr += ( 1 + sizeof( int ) );
|
||||||
|
QDomElement pointMemberElem = doc.createElement( "gml:pointMember" );
|
||||||
|
QDomElement pointElem = doc.createElement( "gml:Point" );
|
||||||
|
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
||||||
|
coordElem.setAttribute( "cs", "," );
|
||||||
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
QString coordString;
|
||||||
|
x = ( double * )( ptr );
|
||||||
|
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
coordString += ",";
|
||||||
|
ptr += sizeof( double );
|
||||||
|
y = ( double * )( ptr );
|
||||||
|
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
coordElem.appendChild( coordText );
|
||||||
|
pointElem.appendChild( coordElem );
|
||||||
|
|
||||||
|
ptr += sizeof( double );
|
||||||
|
if ( hasZValue )
|
||||||
|
{
|
||||||
|
ptr += sizeof( double );
|
||||||
|
}
|
||||||
|
pointMemberElem.appendChild( pointElem );
|
||||||
|
multiPointElem.appendChild( pointMemberElem );
|
||||||
|
}
|
||||||
|
return multiPointElem;
|
||||||
|
}
|
||||||
|
case QGis::WKBLineString25D:
|
||||||
|
hasZValue = true;
|
||||||
|
case QGis::WKBLineString:
|
||||||
|
{
|
||||||
|
unsigned char *ptr;
|
||||||
|
int *nPoints;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
|
||||||
|
// get number of points in the line
|
||||||
|
ptr = wkb + 5;
|
||||||
|
nPoints = ( int * ) ptr;
|
||||||
|
ptr = wkb + 1 + 2 * sizeof( int );
|
||||||
|
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
||||||
|
coordElem.setAttribute( "cs", "," );
|
||||||
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
QString coordString;
|
||||||
|
for ( idx = 0; idx < *nPoints; ++idx )
|
||||||
|
{
|
||||||
|
if ( idx != 0 )
|
||||||
|
{
|
||||||
|
coordString += " ";
|
||||||
|
}
|
||||||
|
x = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
coordString += ",";
|
||||||
|
ptr += sizeof( double );
|
||||||
|
y = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
ptr += sizeof( double );
|
||||||
|
if ( hasZValue )
|
||||||
|
{
|
||||||
|
ptr += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
coordElem.appendChild( coordText );
|
||||||
|
lineStringElem.appendChild( coordElem );
|
||||||
|
return lineStringElem;
|
||||||
|
}
|
||||||
|
case QGis::WKBMultiLineString25D:
|
||||||
|
hasZValue = true;
|
||||||
|
case QGis::WKBMultiLineString:
|
||||||
|
{
|
||||||
|
unsigned char *ptr;
|
||||||
|
int idx, jdx, numLineStrings;
|
||||||
|
int *nPoints;
|
||||||
|
|
||||||
|
QDomElement multiLineStringElem = doc.createElement( "gml:MultiLineString" );
|
||||||
|
numLineStrings = ( int )( wkb[5] );
|
||||||
|
ptr = wkb + 9;
|
||||||
|
for ( jdx = 0; jdx < numLineStrings; jdx++ )
|
||||||
|
{
|
||||||
|
QDomElement lineStringMemberElem = doc.createElement( "gml:lineStringMember" );
|
||||||
|
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
|
||||||
|
ptr += 5; // skip type since we know its 2
|
||||||
|
nPoints = ( int * ) ptr;
|
||||||
|
ptr += sizeof( int );
|
||||||
|
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
||||||
|
coordElem.setAttribute( "cs", "," );
|
||||||
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
QString coordString;
|
||||||
|
for ( idx = 0; idx < *nPoints; idx++ )
|
||||||
|
{
|
||||||
|
if ( idx != 0 )
|
||||||
|
{
|
||||||
|
coordString += " ";
|
||||||
|
}
|
||||||
|
x = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
ptr += sizeof( double );
|
||||||
|
coordString += ",";
|
||||||
|
y = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
ptr += sizeof( double );
|
||||||
|
if ( hasZValue )
|
||||||
|
{
|
||||||
|
ptr += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
coordElem.appendChild( coordText );
|
||||||
|
lineStringElem.appendChild( coordElem );
|
||||||
|
lineStringMemberElem.appendChild( lineStringElem );
|
||||||
|
multiLineStringElem.appendChild( lineStringMemberElem );
|
||||||
|
}
|
||||||
|
return multiLineStringElem;
|
||||||
|
}
|
||||||
|
case QGis::WKBPolygon25D:
|
||||||
|
hasZValue = true;
|
||||||
|
case QGis::WKBPolygon:
|
||||||
|
{
|
||||||
|
unsigned char *ptr;
|
||||||
|
int idx, jdx;
|
||||||
|
int *numRings, *nPoints;
|
||||||
|
|
||||||
|
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
|
||||||
|
// get number of rings in the polygon
|
||||||
|
numRings = ( int * )( wkb + 1 + sizeof( int ) );
|
||||||
|
if ( !( *numRings ) ) // sanity check for zero rings in polygon
|
||||||
|
{
|
||||||
|
return QDomElement();
|
||||||
|
}
|
||||||
|
int *ringStart; // index of first point for each ring
|
||||||
|
int *ringNumPoints; // number of points in each ring
|
||||||
|
ringStart = new int[*numRings];
|
||||||
|
ringNumPoints = new int[*numRings];
|
||||||
|
ptr = wkb + 1 + 2 * sizeof( int ); // set pointer to the first ring
|
||||||
|
for ( idx = 0; idx < *numRings; idx++ )
|
||||||
|
{
|
||||||
|
QString boundaryName = "gml:outerBoundaryIs";
|
||||||
|
if ( idx != 0 )
|
||||||
|
{
|
||||||
|
boundaryName = "gml:innerBoundaryIs";
|
||||||
|
}
|
||||||
|
QDomElement boundaryElem = doc.createElement( boundaryName );
|
||||||
|
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
|
||||||
|
// get number of points in the ring
|
||||||
|
nPoints = ( int * ) ptr;
|
||||||
|
ringNumPoints[idx] = *nPoints;
|
||||||
|
ptr += 4;
|
||||||
|
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
||||||
|
coordElem.setAttribute( "cs", "," );
|
||||||
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
QString coordString;
|
||||||
|
for ( jdx = 0; jdx < *nPoints; jdx++ )
|
||||||
|
{
|
||||||
|
if ( jdx != 0 )
|
||||||
|
{
|
||||||
|
coordString += " ";
|
||||||
|
}
|
||||||
|
x = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
coordString += ",";
|
||||||
|
ptr += sizeof( double );
|
||||||
|
y = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
ptr += sizeof( double );
|
||||||
|
if ( hasZValue )
|
||||||
|
{
|
||||||
|
ptr += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
coordElem.appendChild( coordText );
|
||||||
|
ringElem.appendChild( coordElem );
|
||||||
|
boundaryElem.appendChild( ringElem );
|
||||||
|
polygonElem.appendChild( boundaryElem );
|
||||||
|
}
|
||||||
|
delete [] ringStart;
|
||||||
|
delete [] ringNumPoints;
|
||||||
|
return polygonElem;
|
||||||
|
}
|
||||||
|
case QGis::WKBMultiPolygon25D:
|
||||||
|
hasZValue = true;
|
||||||
|
case QGis::WKBMultiPolygon:
|
||||||
|
{
|
||||||
|
unsigned char *ptr;
|
||||||
|
int idx, jdx, kdx;
|
||||||
|
int *numPolygons, *numRings, *nPoints;
|
||||||
|
|
||||||
|
QDomElement multiPolygonElem = doc.createElement( "gml:MultiPolygon" );
|
||||||
|
ptr = wkb + 5;
|
||||||
|
numPolygons = ( int * ) ptr;
|
||||||
|
ptr = wkb + 9;
|
||||||
|
for ( kdx = 0; kdx < *numPolygons; kdx++ )
|
||||||
|
{
|
||||||
|
QDomElement polygonMemberElem = doc.createElement( "gml:polygonMember" );
|
||||||
|
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
|
||||||
|
ptr += 5;
|
||||||
|
numRings = ( int * ) ptr;
|
||||||
|
ptr += 4;
|
||||||
|
for ( idx = 0; idx < *numRings; idx++ )
|
||||||
|
{
|
||||||
|
QString boundaryName = "gml:outerBoundaryIs";
|
||||||
|
if ( idx != 0 )
|
||||||
|
{
|
||||||
|
boundaryName = "gml:innerBoundaryIs";
|
||||||
|
}
|
||||||
|
QDomElement boundaryElem = doc.createElement( boundaryName );
|
||||||
|
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
|
||||||
|
nPoints = ( int * ) ptr;
|
||||||
|
ptr += 4;
|
||||||
|
QDomElement coordElem = doc.createElement( "gml:coordinates" );
|
||||||
|
coordElem.setAttribute( "cs", "," );
|
||||||
|
coordElem.setAttribute( "ts", " " );
|
||||||
|
QString coordString;
|
||||||
|
for ( jdx = 0; jdx < *nPoints; jdx++ )
|
||||||
|
{
|
||||||
|
if ( jdx != 0 )
|
||||||
|
{
|
||||||
|
coordString += " ";
|
||||||
|
}
|
||||||
|
x = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *x, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
ptr += sizeof( double );
|
||||||
|
coordString += ",";
|
||||||
|
y = ( double * ) ptr;
|
||||||
|
coordString += QString::number( *y, 'f', 8 ).remove( QRegExp( "[0]{1,7}$" ) );
|
||||||
|
ptr += sizeof( double );
|
||||||
|
if ( hasZValue )
|
||||||
|
{
|
||||||
|
ptr += sizeof( double );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QDomText coordText = doc.createTextNode( coordString );
|
||||||
|
coordElem.appendChild( coordText );
|
||||||
|
ringElem.appendChild( coordElem );
|
||||||
|
boundaryElem.appendChild( ringElem );
|
||||||
|
polygonElem.appendChild( boundaryElem );
|
||||||
|
polygonMemberElem.appendChild( polygonElem );
|
||||||
|
multiPolygonElem.appendChild( polygonMemberElem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return multiPolygonElem;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QDomElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QgsRectangle QgsOgcUtils::rectangleFromGMLBox( const QDomNode& boxNode )
|
||||||
|
{
|
||||||
|
QgsRectangle rect;
|
||||||
|
|
||||||
|
QDomElement boxElem = boxNode.toElement();
|
||||||
|
if ( boxElem.tagName() != "Box" )
|
||||||
|
return rect;
|
||||||
|
|
||||||
|
QDomElement bElem = boxElem.firstChild().toElement();
|
||||||
|
QString coordSeparator = ",";
|
||||||
|
QString tupelSeparator = " ";
|
||||||
|
if ( bElem.hasAttribute( "cs" ) )
|
||||||
|
{
|
||||||
|
coordSeparator = bElem.attribute( "cs" );
|
||||||
|
}
|
||||||
|
if ( bElem.hasAttribute( "ts" ) )
|
||||||
|
{
|
||||||
|
tupelSeparator = bElem.attribute( "ts" );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString bString = bElem.text();
|
||||||
|
bool ok1, ok2, ok3, ok4;
|
||||||
|
double xmin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 0, 0 ).toDouble( &ok1 );
|
||||||
|
double ymin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 1, 1 ).toDouble( &ok2 );
|
||||||
|
double xmax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 0, 0 ).toDouble( &ok3 );
|
||||||
|
double ymax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 1, 1 ).toDouble( &ok4 );
|
||||||
|
|
||||||
|
if ( ok1 && ok2 && ok3 && ok4 )
|
||||||
|
{
|
||||||
|
rect = QgsRectangle( xmin, ymin, xmax, ymax );
|
||||||
|
rect.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
67
src/core/qgsogcutils.h
Normal file
67
src/core/qgsogcutils.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#ifndef QGSOGCUTILS_H
|
||||||
|
#define QGSOGCUTILS_H
|
||||||
|
|
||||||
|
class QDomNode;
|
||||||
|
class QDomElement;
|
||||||
|
class QDomDocument;
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class QgsGeometry;
|
||||||
|
class QgsPoint;
|
||||||
|
class QgsRectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The QgsOgcUtils class provides various utility functions for conversion between
|
||||||
|
* OGC (Open Geospatial Consortium) standards and QGIS internal representations.
|
||||||
|
*
|
||||||
|
* Currently supported standards:
|
||||||
|
* - GML2 - Geography Markup Language (import, export)
|
||||||
|
*
|
||||||
|
* @note added in 2.0
|
||||||
|
*/
|
||||||
|
class CORE_EXPORT QgsOgcUtils
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
/** static method that creates geometry from GML2
|
||||||
|
@param XML representation of the geometry. GML elements are expected to be
|
||||||
|
in default namespace (<Point>...</Point>) or in "gml" namespace (<gml:Point>...</gml:Point>)
|
||||||
|
*/
|
||||||
|
static QgsGeometry* geometryFromGML2( const QString& xmlString );
|
||||||
|
|
||||||
|
/** static method that creates geometry from GML2
|
||||||
|
*/
|
||||||
|
static QgsGeometry* geometryFromGML2( const QDomNode& geometryNode );
|
||||||
|
|
||||||
|
/** Exports the geometry to mGML2
|
||||||
|
@return true in case of success and false else
|
||||||
|
*/
|
||||||
|
static QDomElement geometryToGML2( QgsGeometry* geometry, QDomDocument& doc );
|
||||||
|
|
||||||
|
/** read rectangle from GML2 Box */
|
||||||
|
static QgsRectangle rectangleFromGMLBox( const QDomNode& boxNode );
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** static method that creates geometry from GML2 Point */
|
||||||
|
static QgsGeometry* geometryFromGML2Point( const QDomElement& geometryElement );
|
||||||
|
/** static method that creates geometry from GML2 LineString */
|
||||||
|
static QgsGeometry* geometryFromGML2LineString( const QDomElement& geometryElement );
|
||||||
|
/** static method that creates geometry from GML2 Polygon */
|
||||||
|
static QgsGeometry* geometryFromGML2Polygon( const QDomElement& geometryElement );
|
||||||
|
/** static method that creates geometry from GML2 MultiPoint */
|
||||||
|
static QgsGeometry* geometryFromGML2MultiPoint( const QDomElement& geometryElement );
|
||||||
|
/** static method that creates geometry from GML2 MultiLineString */
|
||||||
|
static QgsGeometry* geometryFromGML2MultiLineString( const QDomElement& geometryElement );
|
||||||
|
/** static method that creates geometry from GML2 MultiPolygon */
|
||||||
|
static QgsGeometry* geometryFromGML2MultiPolygon( const QDomElement& geometryElement );
|
||||||
|
/** Reads the <gml:coordinates> element and extracts the coordinates as points
|
||||||
|
@param coords list where the found coordinates are appended
|
||||||
|
@param elem the <gml:coordinates> element
|
||||||
|
@return boolean for success*/
|
||||||
|
static bool readGML2Coordinates( std::list<QgsPoint>& coords, const QDomElement elem );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSOGCUTILS_H
|
@ -55,32 +55,6 @@ QgsRectangle::QgsRectangle( const QgsRectangle &r )
|
|||||||
ymax = r.yMaximum();
|
ymax = r.yMaximum();
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsRectangle::QgsRectangle( const QDomNode& boxNode )
|
|
||||||
{
|
|
||||||
QDomElement boxElem = boxNode.toElement();
|
|
||||||
if ( boxElem.tagName() == "Box" )
|
|
||||||
{
|
|
||||||
QDomElement bElem = boxElem.firstChild().toElement();
|
|
||||||
QString coordSeparator = ",";
|
|
||||||
QString tupelSeparator = " ";
|
|
||||||
if ( bElem.hasAttribute( "cs" ) )
|
|
||||||
{
|
|
||||||
coordSeparator = bElem.attribute( "cs" );
|
|
||||||
}
|
|
||||||
if ( bElem.hasAttribute( "ts" ) )
|
|
||||||
{
|
|
||||||
tupelSeparator = bElem.attribute( "ts" );
|
|
||||||
}
|
|
||||||
|
|
||||||
QString bString = bElem.text();
|
|
||||||
bool conversionSuccess;
|
|
||||||
xmin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 0, 0 ).toDouble( &conversionSuccess );
|
|
||||||
ymin = bString.section( tupelSeparator, 0, 0 ).section( coordSeparator, 1, 1 ).toDouble( &conversionSuccess );
|
|
||||||
xmax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 0, 0 ).toDouble( &conversionSuccess );
|
|
||||||
ymax = bString.section( tupelSeparator, 1, 1 ).section( coordSeparator, 1, 1 ).toDouble( &conversionSuccess );
|
|
||||||
}
|
|
||||||
normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QgsRectangle::set( const QgsPoint& p1, const QgsPoint& p2 )
|
void QgsRectangle::set( const QgsPoint& p1, const QgsPoint& p2 )
|
||||||
{
|
{
|
||||||
|
@ -44,9 +44,6 @@ class CORE_EXPORT QgsRectangle
|
|||||||
QgsRectangle( const QRectF & qRectF );
|
QgsRectangle( const QRectF & qRectF );
|
||||||
//! Copy constructor
|
//! Copy constructor
|
||||||
QgsRectangle( const QgsRectangle &other );
|
QgsRectangle( const QgsRectangle &other );
|
||||||
//! GML2 constructor
|
|
||||||
//@note added in 1.9
|
|
||||||
QgsRectangle( const QDomNode& boxNode );
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
~QgsRectangle();
|
~QgsRectangle();
|
||||||
//! Set the rectangle from two QgsPoints. The rectangle is
|
//! Set the rectangle from two QgsPoints. The rectangle is
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "qgslogicalfilter.h"
|
#include "qgslogicalfilter.h"
|
||||||
#include "qgsspatialfilter.h"
|
#include "qgsspatialfilter.h"
|
||||||
#include "qgsvectordataprovider.h"
|
#include "qgsvectordataprovider.h"
|
||||||
|
#include "qgsogcutils.h"
|
||||||
|
|
||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
@ -129,7 +131,7 @@ QgsFilter* QgsFilter::createFilterFromXml( const QDomElement& filterElem, QgsVec
|
|||||||
if ( gNodes.size() > 0 )
|
if ( gNodes.size() > 0 )
|
||||||
{
|
{
|
||||||
QDomElement gElem = gNodes.at( 0 ).toElement();
|
QDomElement gElem = gNodes.at( 0 ).toElement();
|
||||||
geom = QgsGeometry::fromGML2( gElem );
|
geom = QgsOgcUtils::geometryFromGML2( gElem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +141,7 @@ QgsFilter* QgsFilter::createFilterFromXml( const QDomElement& filterElem, QgsVec
|
|||||||
if ( gNodes.size() > 0 )
|
if ( gNodes.size() > 0 )
|
||||||
{
|
{
|
||||||
QDomElement gElem = gNodes.at( 0 ).toElement();
|
QDomElement gElem = gNodes.at( 0 ).toElement();
|
||||||
geom = QgsGeometry::fromGML2( gElem );
|
geom = QgsOgcUtils::geometryFromGML2( gElem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +151,7 @@ QgsFilter* QgsFilter::createFilterFromXml( const QDomElement& filterElem, QgsVec
|
|||||||
if ( gNodes.size() > 0 )
|
if ( gNodes.size() > 0 )
|
||||||
{
|
{
|
||||||
QDomElement gElem = gNodes.at( 0 ).toElement();
|
QDomElement gElem = gNodes.at( 0 ).toElement();
|
||||||
geom = QgsGeometry::fromGML2( gElem );
|
geom = QgsOgcUtils::geometryFromGML2( gElem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +161,7 @@ QgsFilter* QgsFilter::createFilterFromXml( const QDomElement& filterElem, QgsVec
|
|||||||
if ( gNodes.size() > 0 )
|
if ( gNodes.size() > 0 )
|
||||||
{
|
{
|
||||||
QDomElement gElem = gNodes.at( 0 ).toElement();
|
QDomElement gElem = gNodes.at( 0 ).toElement();
|
||||||
geom = QgsGeometry::fromGML2( gElem );
|
geom = QgsOgcUtils::geometryFromGML2( gElem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +171,7 @@ QgsFilter* QgsFilter::createFilterFromXml( const QDomElement& filterElem, QgsVec
|
|||||||
if ( gNodes.size() > 0 )
|
if ( gNodes.size() > 0 )
|
||||||
{
|
{
|
||||||
QDomElement gElem = gNodes.at( 0 ).toElement();
|
QDomElement gElem = gNodes.at( 0 ).toElement();
|
||||||
geom = QgsGeometry::fromGML2( gElem );
|
geom = QgsOgcUtils::geometryFromGML2( gElem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +181,7 @@ QgsFilter* QgsFilter::createFilterFromXml( const QDomElement& filterElem, QgsVec
|
|||||||
if ( gNodes.size() > 0 )
|
if ( gNodes.size() > 0 )
|
||||||
{
|
{
|
||||||
QDomElement gElem = gNodes.at( 0 ).toElement();
|
QDomElement gElem = gNodes.at( 0 ).toElement();
|
||||||
geom = QgsGeometry::fromGML2( gElem );
|
geom = QgsOgcUtils::geometryFromGML2( gElem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#include "qgslegendmodel.h"
|
#include "qgslegendmodel.h"
|
||||||
#include "qgscomposerlegenditem.h"
|
#include "qgscomposerlegenditem.h"
|
||||||
#include "qgsrequesthandler.h"
|
#include "qgsrequesthandler.h"
|
||||||
|
#include "qgsogcutils.h"
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
@ -509,11 +511,11 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
|
|||||||
{
|
{
|
||||||
if ( childElem.tagName() == "Box" )
|
if ( childElem.tagName() == "Box" )
|
||||||
{
|
{
|
||||||
req.setFilterRect( QgsRectangle( childElem ) );
|
req.setFilterRect( QgsOgcUtils::rectangleFromGMLBox( childElem ) );
|
||||||
}
|
}
|
||||||
else if ( childElem.tagName() != "PropertyName" )
|
else if ( childElem.tagName() != "PropertyName" )
|
||||||
{
|
{
|
||||||
QgsGeometry *geom = QgsGeometry::fromGML2( childElem );
|
QgsGeometry *geom = QgsOgcUtils::geometryFromGML2( childElem );
|
||||||
req.setFilterRect( geom->boundingBox() );
|
req.setFilterRect( geom->boundingBox() );
|
||||||
delete geom;
|
delete geom;
|
||||||
}
|
}
|
||||||
@ -892,11 +894,11 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
|
|||||||
{
|
{
|
||||||
if ( childElem.tagName() == "Box" )
|
if ( childElem.tagName() == "Box" )
|
||||||
{
|
{
|
||||||
req.setFilterRect( QgsRectangle( childElem ) );
|
req.setFilterRect( QgsOgcUtils::rectangleFromGMLBox( childElem ) );
|
||||||
}
|
}
|
||||||
else if ( childElem.tagName() != "PropertyName" )
|
else if ( childElem.tagName() != "PropertyName" )
|
||||||
{
|
{
|
||||||
QgsGeometry* geom = QgsGeometry::fromGML2( childElem );
|
QgsGeometry* geom = QgsOgcUtils::geometryFromGML2( childElem );
|
||||||
req.setFilterRect( geom->boundingBox() );
|
req.setFilterRect( geom->boundingBox() );
|
||||||
delete geom;
|
delete geom;
|
||||||
}
|
}
|
||||||
@ -1335,7 +1337,7 @@ QDomDocument QgsWFSServer::transaction( const QString& requestBody )
|
|||||||
|
|
||||||
if ( !geometryElem.isNull() )
|
if ( !geometryElem.isNull() )
|
||||||
{
|
{
|
||||||
if ( !layer->changeGeometry( *fidIt, QgsGeometry::fromGML2( geometryElem ) ) )
|
if ( !layer->changeGeometry( *fidIt, QgsOgcUtils::geometryFromGML2( geometryElem ) ) )
|
||||||
throw QgsMapServiceException( "RequestNotWellFormed", "Error in change geometry" );
|
throw QgsMapServiceException( "RequestNotWellFormed", "Error in change geometry" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1451,7 +1453,7 @@ QDomDocument QgsWFSServer::transaction( const QString& requestBody )
|
|||||||
}
|
}
|
||||||
else //a geometry attribute
|
else //a geometry attribute
|
||||||
{
|
{
|
||||||
f->setGeometry( QgsGeometry::fromGML2( currentAttributeElement ) );
|
f->setGeometry( QgsOgcUtils::geometryFromGML2( currentAttributeElement ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentAttributeChild = currentAttributeChild.nextSibling();
|
currentAttributeChild = currentAttributeChild.nextSibling();
|
||||||
@ -1649,7 +1651,7 @@ QDomElement QgsWFSServer::createFeatureGML2( QgsFeature* feat, QDomDocument& doc
|
|||||||
QgsGeometry* geom = feat->geometry();
|
QgsGeometry* geom = feat->geometry();
|
||||||
|
|
||||||
QDomElement geomElem = doc.createElement( "qgs:geometry" );
|
QDomElement geomElem = doc.createElement( "qgs:geometry" );
|
||||||
QDomElement gmlElem = geom->exportToGML2( doc );
|
QDomElement gmlElem = QgsOgcUtils::geometryToGML2( geom, doc );
|
||||||
if ( !gmlElem.isNull() )
|
if ( !gmlElem.isNull() )
|
||||||
{
|
{
|
||||||
QgsRectangle box = geom->boundingBox();
|
QgsRectangle box = geom->boundingBox();
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "qgsspatialindex.h"
|
#include "qgsspatialindex.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
#include "qgsnetworkaccessmanager.h"
|
#include "qgsnetworkaccessmanager.h"
|
||||||
|
#include "qgsogcutils.h"
|
||||||
|
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDomNodeList>
|
#include <QDomNodeList>
|
||||||
@ -418,7 +420,7 @@ bool QgsWFSProvider::addFeatures( QgsFeatureList &flist )
|
|||||||
|
|
||||||
//add geometry column (as gml)
|
//add geometry column (as gml)
|
||||||
QDomElement geomElem = transactionDoc.createElementNS( mWfsNamespace, mGeometryAttribute );
|
QDomElement geomElem = transactionDoc.createElementNS( mWfsNamespace, mGeometryAttribute );
|
||||||
QDomElement gmlElem = featureIt->geometry()->exportToGML2( transactionDoc );
|
QDomElement gmlElem = QgsOgcUtils::geometryToGML2( featureIt->geometry(), transactionDoc );
|
||||||
if ( !gmlElem.isNull() )
|
if ( !gmlElem.isNull() )
|
||||||
{
|
{
|
||||||
geomElem.appendChild( gmlElem );
|
geomElem.appendChild( gmlElem );
|
||||||
@ -569,7 +571,7 @@ bool QgsWFSProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
|
|||||||
nameElem.appendChild( nameText );
|
nameElem.appendChild( nameText );
|
||||||
propertyElem.appendChild( nameElem );
|
propertyElem.appendChild( nameElem );
|
||||||
QDomElement valueElem = transactionDoc.createElementNS( "http://www.opengis.net/wfs", "Value" );
|
QDomElement valueElem = transactionDoc.createElementNS( "http://www.opengis.net/wfs", "Value" );
|
||||||
QDomElement gmlElem = ( &geomIt.value() )->exportToGML2( transactionDoc );
|
QDomElement gmlElem = QgsOgcUtils::geometryToGML2( &geomIt.value(), transactionDoc );
|
||||||
valueElem.appendChild( gmlElem );
|
valueElem.appendChild( gmlElem );
|
||||||
propertyElem.appendChild( valueElem );
|
propertyElem.appendChild( valueElem );
|
||||||
updateElem.appendChild( propertyElem );
|
updateElem.appendChild( propertyElem );
|
||||||
@ -1287,7 +1289,7 @@ int QgsWFSProvider::getFeaturesFromGML2( const QDomElement& wfsCollectionElement
|
|||||||
}
|
}
|
||||||
else //a geometry attribute
|
else //a geometry attribute
|
||||||
{
|
{
|
||||||
f->setGeometry( QgsGeometry::fromGML2( currentAttributeElement ) );
|
f->setGeometry( QgsOgcUtils::geometryFromGML2( currentAttributeElement ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentAttributeChild = currentAttributeChild.nextSibling();
|
currentAttributeChild = currentAttributeChild.nextSibling();
|
||||||
|
@ -109,3 +109,4 @@ ADD_QGIS_TEST(stylev2test testqgsstylev2.cpp)
|
|||||||
ADD_QGIS_TEST(composerhtmltest testqgscomposerhtml.cpp )
|
ADD_QGIS_TEST(composerhtmltest testqgscomposerhtml.cpp )
|
||||||
ADD_QGIS_TEST(rectangletest testqgsrectangle.cpp)
|
ADD_QGIS_TEST(rectangletest testqgsrectangle.cpp)
|
||||||
ADD_QGIS_TEST(composerscalebartest testqgscomposerscalebar.cpp )
|
ADD_QGIS_TEST(composerscalebartest testqgscomposerscalebar.cpp )
|
||||||
|
ADD_QGIS_TEST(ogcutilstest testqgsogcutils.cpp)
|
||||||
|
@ -56,8 +56,6 @@ class TestQgsGeometry: public QObject
|
|||||||
void differenceCheck2();
|
void differenceCheck2();
|
||||||
void bufferCheck();
|
void bufferCheck();
|
||||||
|
|
||||||
void gmlTest();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** A helper method to do a render check to see if the geometry op is as expected */
|
/** A helper method to do a render check to see if the geometry op is as expected */
|
||||||
bool renderCheck( QString theTestName, QString theComment = "" );
|
bool renderCheck( QString theTestName, QString theComment = "" );
|
||||||
@ -372,18 +370,6 @@ void TestQgsGeometry::dumpPolyline( QgsPolyline &thePolyline )
|
|||||||
mpPainter->drawPolyline( myPoints );
|
mpPainter->drawPolyline( myPoints );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestQgsGeometry::gmlTest()
|
|
||||||
{
|
|
||||||
QgsGeometry* geom = QgsGeometry::fromGML2( "<Point><coordinates>123,456</coordinates></Point>" );
|
|
||||||
QVERIFY( geom );
|
|
||||||
QVERIFY( geom->wkbType() == QGis::WKBPoint );
|
|
||||||
QVERIFY( geom->asPoint() == QgsPoint( 123, 456 ) );
|
|
||||||
|
|
||||||
QgsGeometry* geomBox = QgsGeometry::fromGML2( "<gml:Box srsName=\"foo\"><gml:coordinates>135.2239,34.4879 135.8578,34.8471</gml:coordinates></gml:Box>" );
|
|
||||||
QVERIFY( geomBox );
|
|
||||||
QVERIFY( geomBox->wkbType() == QGis::WKBPolygon );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QTEST_MAIN( TestQgsGeometry )
|
QTEST_MAIN( TestQgsGeometry )
|
||||||
#include "moc_testqgsgeometry.cxx"
|
#include "moc_testqgsgeometry.cxx"
|
||||||
|
67
tests/src/core/testqgsogcutils.cpp
Normal file
67
tests/src/core/testqgsogcutils.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
testqgsogcutils.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : March 2013
|
||||||
|
Copyright : (C) 2013 Martin Dobias
|
||||||
|
Email : wonder.sk at gmail dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
//qgis includes...
|
||||||
|
#include <qgsgeometry.h>
|
||||||
|
#include <qgsogcutils.h>
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup UnitTests
|
||||||
|
* This is a unit test for OGC utilities
|
||||||
|
*/
|
||||||
|
class TestQgsOgcUtils : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void testGeometryFromGML();
|
||||||
|
void testGeometryToGML();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void TestQgsOgcUtils::testGeometryFromGML()
|
||||||
|
{
|
||||||
|
QgsGeometry* geom = QgsOgcUtils::geometryFromGML2( "<Point><coordinates>123,456</coordinates></Point>" );
|
||||||
|
QVERIFY( geom );
|
||||||
|
QVERIFY( geom->wkbType() == QGis::WKBPoint );
|
||||||
|
QVERIFY( geom->asPoint() == QgsPoint( 123, 456 ) );
|
||||||
|
|
||||||
|
QgsGeometry* geomBox = QgsOgcUtils::geometryFromGML2( "<gml:Box srsName=\"foo\"><gml:coordinates>135.2239,34.4879 135.8578,34.8471</gml:coordinates></gml:Box>" );
|
||||||
|
QVERIFY( geomBox );
|
||||||
|
QVERIFY( geomBox->wkbType() == QGis::WKBPolygon );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQgsOgcUtils::testGeometryToGML()
|
||||||
|
{
|
||||||
|
QDomDocument doc;
|
||||||
|
|
||||||
|
QDomElement elemInvalid = QgsOgcUtils::geometryToGML2( 0, doc );
|
||||||
|
QVERIFY( elemInvalid.isNull() );
|
||||||
|
|
||||||
|
QgsGeometry* geomPoint = QgsGeometry::fromPoint( QgsPoint( 111, 222 ) );
|
||||||
|
QDomElement elemPoint = QgsOgcUtils::geometryToGML2( geomPoint, doc );
|
||||||
|
delete geomPoint;
|
||||||
|
QVERIFY( !elemPoint.isNull() );
|
||||||
|
|
||||||
|
doc.appendChild( elemPoint );
|
||||||
|
QCOMPARE( doc.toString( -1 ), QString( "<gml:Point><gml:coordinates cs=\",\" ts=\" \">111.0,222.0</gml:coordinates></gml:Point>" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTEST_MAIN( TestQgsOgcUtils )
|
||||||
|
#include "moc_testqgsogcutils.cxx"
|
Loading…
x
Reference in New Issue
Block a user