Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
In addition to indicate the geometry type in the DescribeFeatureType …
…request, this patch adds boundedBy to FeatureCollection and Feature element.
  • Loading branch information
rldhont committed Sep 20, 2012
1 parent 8173484 commit 593da45
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 26 deletions.
24 changes: 12 additions & 12 deletions src/core/qgsgeometry.cpp
Expand Up @@ -4226,10 +4226,10 @@ QString QgsGeometry::exportToGeoJSON()
{
mWkt += "{ \"type\": \"Point\", \"coordinates\": [";
x = ( double * )( mGeometry + 5 );
mWkt += QString::number( *x, 'f', 6 );
mWkt += QString::number( *x, 'f' );
mWkt += ", ";
y = ( double * )( mGeometry + 5 + sizeof( double ) );
mWkt += QString::number( *y, 'f', 6 );
mWkt += QString::number( *y, 'f' );
mWkt += "] }";
return mWkt;
}
Expand All @@ -4256,11 +4256,11 @@ QString QgsGeometry::exportToGeoJSON()
}
mWkt += "[";
x = ( double * ) ptr;
mWkt += QString::number( *x, 'f', 6 );
mWkt += QString::number( *x, 'f' );
mWkt += ", ";
ptr += sizeof( double );
y = ( double * ) ptr;
mWkt += QString::number( *y, 'f', 6 );
mWkt += QString::number( *y, 'f' );
ptr += sizeof( double );
if ( hasZValue )
{
Expand Down Expand Up @@ -4313,11 +4313,11 @@ QString QgsGeometry::exportToGeoJSON()
}
mWkt += "[";
x = ( double * ) ptr;
mWkt += QString::number( *x, 'f', 6 );
mWkt += QString::number( *x, 'f' );
mWkt += ", ";
ptr += sizeof( double );
y = ( double * ) ptr;
mWkt += QString::number( *y, 'f', 6 );
mWkt += QString::number( *y, 'f' );
ptr += sizeof( double );
if ( hasZValue )
{
Expand Down Expand Up @@ -4353,11 +4353,11 @@ QString QgsGeometry::exportToGeoJSON()
}
mWkt += "[";
x = ( double * )( ptr );
mWkt += QString::number( *x, 'f', 6 );
mWkt += QString::number( *x, 'f' );
mWkt += ", ";
ptr += sizeof( double );
y = ( double * )( ptr );
mWkt += QString::number( *y, 'f', 6 );
mWkt += QString::number( *y, 'f' );
ptr += sizeof( double );
if ( hasZValue )
{
Expand Down Expand Up @@ -4399,11 +4399,11 @@ QString QgsGeometry::exportToGeoJSON()
}
mWkt += "[";
x = ( double * ) ptr;
mWkt += QString::number( *x, 'f', 6 );
mWkt += QString::number( *x, 'f' );
ptr += sizeof( double );
mWkt += ", ";
y = ( double * ) ptr;
mWkt += QString::number( *y, 'f', 6 );
mWkt += QString::number( *y, 'f' );
ptr += sizeof( double );
if ( hasZValue )
{
Expand Down Expand Up @@ -4457,11 +4457,11 @@ QString QgsGeometry::exportToGeoJSON()
}
mWkt += "[";
x = ( double * ) ptr;
mWkt += QString::number( *x, 'f', 6 );
mWkt += QString::number( *x, 'f' );
ptr += sizeof( double );
mWkt += ", ";
y = ( double * ) ptr;
mWkt += QString::number( *y, 'f', 6 );
mWkt += QString::number( *y, 'f' );
ptr += sizeof( double );
if ( hasZValue )
{
Expand Down
184 changes: 171 additions & 13 deletions src/mapserver/qgswfsserver.cpp
Expand Up @@ -331,7 +331,37 @@ QDomDocument QgsWFSServer::describeFeatureType()
//xsd:element
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ );
geomElem.setAttribute( "name", "geometry" );
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
QGis::WkbType wkbType = layer->wkbType();
switch ( wkbType )
{
case QGis::WKBPoint25D:
case QGis::WKBPoint:
geomElem.setAttribute( "type", "gml:PointPropertyType" );
break;
case QGis::WKBLineString25D:
case QGis::WKBLineString:
geomElem.setAttribute( "type", "gml:LineStringPropertyType" );
break;
case QGis::WKBPolygon25D:
case QGis::WKBPolygon:
geomElem.setAttribute( "type", "gml:PolygonPropertyType" );
break;
case QGis::WKBMultiPoint25D:
case QGis::WKBMultiPoint:
geomElem.setAttribute( "type", "gml:MultiPointPropertyType" );
break;
case QGis::WKBMultiLineString25D:
case QGis::WKBMultiLineString:
geomElem.setAttribute( "type", "gml:MultiLineStringPropertyType" );
break;
case QGis::WKBMultiPolygon25D:
case QGis::WKBMultiPolygon:
geomElem.setAttribute( "type", "gml:MultiPolygonPropertyType" );
break;
default:
geomElem.setAttribute( "type", "gml:GeometryPropertyType" );
break;
}
geomElem.setAttribute( "minOccurs", "0" );
geomElem.setAttribute( "maxOccurs", "1" );
sequenceElem.appendChild( geomElem );
Expand Down Expand Up @@ -543,9 +573,11 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
}
}

if ( bboxOk )
searchRect.set( minx, miny, maxx, maxy );
QgsCoordinateReferenceSystem layerCrs = layer->crs();

startGetFeature( request, format );
startGetFeature( request, format, layerCrs, &searchRect );

if ( fidOk )
{
Expand Down Expand Up @@ -589,8 +621,6 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
}
else
{
if ( bboxOk )
searchRect.set( minx, miny, maxx, maxy );
provider->select( attrIndexes, searchRect, mWithGeom, true );
while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
{
Expand All @@ -608,25 +638,102 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
return 0;
}

void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& format )
void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect )
{
QByteArray result;
QString fcString;
if ( format == "GeoJSON" )
{
fcString = "{\"type\": \"FeatureCollection\",\n";
fcString += " \"bbox\": [ "+ QString::number( rect->xMinimum(), 'f' ) +", "+ QString::number( rect->yMinimum(), 'f' ) +", "+ QString::number( rect->xMaximum(), 'f' ) +", "+ QString::number( rect->yMaximum(), 'f' ) +"],\n";
fcString += " \"features\": [\n";
result = fcString.toUtf8();
request.startGetFeatureResponse( &result, format );
}
else
{
//Prepare url
//Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable
QString hrefString;
QString requestUrl = getenv( "REQUEST_URI" );
QUrl mapUrl( requestUrl );
mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) );

//Add non-default ports to url
QString portString = getenv( "SERVER_PORT" );
if ( !portString.isEmpty() )
{
bool portOk;
int portNumber = portString.toInt( &portOk );
if ( portOk )
{
if ( portNumber != 80 )
{
mapUrl.setPort( portNumber );
}
}
}

if ( QString( getenv( "HTTPS" ) ).compare( "on", Qt::CaseInsensitive ) == 0 )
{
mapUrl.setScheme( "https" );
}
else
{
mapUrl.setScheme( "http" );
}

QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
{
if ( queryIt->first.compare( "REQUEST", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
mapUrl.addQueryItem( queryIt->first, "DescribeFeatureType" );
}
else if ( queryIt->first.compare( "FORMAT", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "OUTPUTFORMAT", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "BBOX", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "FEATUREID", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "FILTER", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "MAXFEATURES", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "PROPERTYNAME", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
else if ( queryIt->first.compare( "_DC", Qt::CaseInsensitive ) == 0 )
{
mapUrl.removeQueryItem( queryIt->first );
}
}
mapUrl.addQueryItem( "OUTPUTFORMAT", "XMLSCHEMA" );
hrefString = mapUrl.toString();

//wfs:FeatureCollection
fcString = "<wfs:FeatureCollection";
fcString += " xmlns=\"http://www.opengis.net/wfs\"";
fcString += " xmlns:wfs=\"http://www.opengis.net/wfs\"";
fcString += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
fcString += " xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd\"";
fcString += " xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.opengis.net/gml "+ hrefString.replace( "&", "&amp;" ) +"\"";
fcString += " xmlns:ogc=\"http://www.opengis.net/ogc\"";
fcString += " xmlns:gml=\"http://www.opengis.net/gml\"";
fcString += " xmlns:ows=\"http://www.opengis.net/ows\"";
Expand All @@ -635,6 +742,21 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
fcString += ">";
result = fcString.toUtf8();
request.startGetFeatureResponse( &result, format );

QDomDocument doc;
QDomElement bbElem = doc.createElement( "gml:boundedBy" );
QDomElement boxElem = createBoxElem( rect, doc );
if ( !boxElem.isNull() )
{
if ( crs.isValid() )
{
boxElem.setAttribute( "srsName", crs.authid() );
}
bbElem.appendChild( boxElem );
doc.appendChild( bbElem );
}
result = doc.toByteArray();
request.sendGetFeatureResponse( &result );
}
fcString = "";
}
Expand Down Expand Up @@ -701,6 +823,10 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateRefer
QgsGeometry* geom = feat->geometry();
if ( geom && mWithGeom )
{
QgsRectangle box = geom->boundingBox();

fStr += " \"bbox\": [ "+ QString::number( box.xMinimum(), 'f' ) +", "+ QString::number( box.yMinimum(), 'f' ) +", "+ QString::number( box.xMaximum(), 'f' ) +", "+ QString::number( box.yMaximum(), 'f' ) +"],\n";

fStr += " \"geometry\": ";
fStr += geom->exportToGeoJSON();
fStr += ",\n";
Expand Down Expand Up @@ -759,14 +885,25 @@ QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc
if ( mWithGeom )
{
//add geometry column (as gml)
QgsGeometry* geom = feat->geometry();

QDomElement geomElem = doc.createElement( "qgs:geometry" );
QDomElement gmlElem = createGeometryElem( feat->geometry(), doc );
QDomElement gmlElem = createGeometryElem( geom, doc );
if ( !gmlElem.isNull() )
{
QgsRectangle box = geom->boundingBox();
QDomElement bbElem = doc.createElement( "gml:boundedBy" );
QDomElement boxElem = createBoxElem( &box, doc );

if ( crs.isValid() )
{
boxElem.setAttribute( "srsName", crs.authid() );
gmlElem.setAttribute( "srsName", crs.authid() );
}

bbElem.appendChild( boxElem );
typeNameElement.appendChild( bbElem );

geomElem.appendChild( gmlElem );
typeNameElement.appendChild( geomElem );
}
Expand All @@ -793,6 +930,27 @@ QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc
return featureElement;
}

QDomElement QgsWFSServer::createBoxElem( QgsRectangle* box, QDomDocument& doc ) /*const*/
{
if ( !box )
{
return QDomElement();
}

QDomElement boxElem = doc.createElement( "gml:Box" );
QVector<QgsPoint> v;
QgsPoint p1;
p1.set( box->xMinimum(), box->yMinimum() );
v.append( p1 );
QgsPoint p2;
p2.set( box->xMaximum(), box->yMaximum() );
v.append( p2 );
QDomElement coordElem = createCoordinateElem( v, doc );
boxElem.appendChild( coordElem );

return boxElem;
}

QDomElement QgsWFSServer::createGeometryElem( QgsGeometry* geom, QDomDocument& doc ) /*const*/
{
if ( !geom )
Expand Down Expand Up @@ -931,13 +1089,13 @@ QDomElement QgsWFSServer::createPolygonElem( QgsGeometry* geom, QDomDocument& do
QString boundaryName;
if ( i == 0 )
{
boundaryName = "outerBoundaryIs";
boundaryName = "gml:outerBoundaryIs";
}
else
{
boundaryName = "innerBoundaryIs";
boundaryName = "gml:innerBoundaryIs";
}
QDomElement boundaryElem = doc.createElementNS( "http://www.opengis.net/gml", boundaryName );
QDomElement boundaryElem = doc.createElement( boundaryName );
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
QDomElement coordElem = createCoordinateElem( poly.at( i ), doc );
ringElem.appendChild( coordElem );
Expand Down Expand Up @@ -979,7 +1137,7 @@ QDomElement QgsWFSServer::createCoordinateElem( const QVector<QgsPoint> points,
coordElem.setAttribute( "ts", " " );

//precision 4 for meters / feet, precision 8 for degrees
int precision = 8;
int precision = 6;
/*
if ( mSourceCRS.mapUnits() == QGis::Meters
|| mSourceCRS.mapUnits() == QGis::Feet )
Expand All @@ -996,9 +1154,9 @@ QDomElement QgsWFSServer::createCoordinateElem( const QVector<QgsPoint> points,
{
coordString += " ";
}
coordString += QString::number( pointIt->x(), 'f', precision );
coordString += QString::number( pointIt->x(), 'f');
coordString += ",";
coordString += QString::number( pointIt->y(), 'f', precision );
coordString += QString::number( pointIt->y(), 'f' );
}

QDomText coordText = doc.createTextNode( coordString );
Expand Down
4 changes: 3 additions & 1 deletion src/mapserver/qgswfsserver.h
Expand Up @@ -36,6 +36,7 @@ class QgsVectorLayer;
class QgsCoordinateReferenceSystem;
class QgsField;
class QgsFeature;
class QgsRectangle;
class QgsGeometry;
class QgsSymbol;
class QgsRequestHandler;
Expand Down Expand Up @@ -80,7 +81,7 @@ class QgsWFSServer

protected:

void startGetFeature( QgsRequestHandler& request, const QString& format );
void startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect );
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes );
void endGetFeature( QgsRequestHandler& request, const QString& format );

Expand All @@ -90,6 +91,7 @@ class QgsWFSServer
//methods to write GML2
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;

QDomElement createBoxElem( QgsRectangle* box, QDomDocument& doc ) /* const */;
QDomElement createGeometryElem( QgsGeometry* g, QDomDocument& doc ) /*const*/;
QDomElement createLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createMultiLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
Expand Down

0 comments on commit 593da45

Please sign in to comment.