mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-12 00:06:43 -04:00
In addition to indicate the geometry type in the DescribeFeatureType request, this patch adds boundedBy to FeatureCollection and Feature element.
This commit is contained in:
parent
81734840cc
commit
593da45219
@ -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;
|
||||
}
|
||||
@ -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 )
|
||||
{
|
||||
@ -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 )
|
||||
{
|
||||
@ -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 )
|
||||
{
|
||||
@ -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 )
|
||||
{
|
||||
@ -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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
@ -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 )
|
||||
{
|
||||
@ -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 )
|
||||
{
|
||||
@ -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( "&", "&" ) +"\"";
|
||||
fcString += " xmlns:ogc=\"http://www.opengis.net/ogc\"";
|
||||
fcString += " xmlns:gml=\"http://www.opengis.net/gml\"";
|
||||
fcString += " xmlns:ows=\"http://www.opengis.net/ows\"";
|
||||
@ -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 = "";
|
||||
}
|
||||
@ -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";
|
||||
@ -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 );
|
||||
}
|
||||
@ -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 )
|
||||
@ -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 );
|
||||
@ -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 )
|
||||
@ -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 );
|
||||
|
@ -36,6 +36,7 @@ class QgsVectorLayer;
|
||||
class QgsCoordinateReferenceSystem;
|
||||
class QgsField;
|
||||
class QgsFeature;
|
||||
class QgsRectangle;
|
||||
class QgsGeometry;
|
||||
class QgsSymbol;
|
||||
class QgsRequestHandler;
|
||||
@ -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 );
|
||||
|
||||
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user