wfs-server-1_7-V3.patch
| src/core/qgsgeometry.cpp | ||
|---|---|---|
| 4101 | 4101 |
} |
| 4102 | 4102 |
} |
| 4103 | 4103 | |
| 4104 |
QString QgsGeometry::exportToGeoJSON() |
|
| 4105 |
{
|
|
| 4106 |
QgsDebugMsg( "entered." ); |
|
| 4107 | ||
| 4108 |
// TODO: implement with GEOS |
|
| 4109 |
if ( mDirtyWkb ) |
|
| 4110 |
{
|
|
| 4111 |
exportGeosToWkb(); |
|
| 4112 |
} |
|
| 4113 | ||
| 4114 |
if ( !mGeometry ) |
|
| 4115 |
{
|
|
| 4116 |
QgsDebugMsg( "WKB geometry not available!" ); |
|
| 4117 |
return QString::null; |
|
| 4118 |
} |
|
| 4119 | ||
| 4120 |
QGis::WkbType wkbType; |
|
| 4121 |
bool hasZValue = false; |
|
| 4122 |
double *x, *y; |
|
| 4123 | ||
| 4124 |
QString mWkt; // TODO: rename |
|
| 4125 | ||
| 4126 |
// Will this really work when mGeometry[0] == 0 ???? I (gavin) think not. |
|
| 4127 |
//wkbType = (mGeometry[0] == 1) ? mGeometry[1] : mGeometry[4]; |
|
| 4128 |
memcpy( &wkbType, &( mGeometry[1] ), sizeof( int ) ); |
|
| 4129 | ||
| 4130 |
switch ( wkbType ) |
|
| 4131 |
{
|
|
| 4132 |
case QGis::WKBPoint25D: |
|
| 4133 |
case QGis::WKBPoint: |
|
| 4134 |
{
|
|
| 4135 |
mWkt += "{ \"type\": \"Point\", \"coordinates\": [";
|
|
| 4136 |
x = ( double * )( mGeometry + 5 ); |
|
| 4137 |
mWkt += QString::number( *x, 'f', 6 ); |
|
| 4138 |
mWkt += ", "; |
|
| 4139 |
y = ( double * )( mGeometry + 5 + sizeof( double ) ); |
|
| 4140 |
mWkt += QString::number( *y, 'f', 6 ); |
|
| 4141 |
mWkt += "] }"; |
|
| 4142 |
return mWkt; |
|
| 4143 |
} |
|
| 4144 | ||
| 4145 |
case QGis::WKBLineString25D: |
|
| 4146 |
hasZValue = true; |
|
| 4147 |
case QGis::WKBLineString: |
|
| 4148 |
{
|
|
| 4149 |
QgsDebugMsg( "LINESTRING found" ); |
|
| 4150 |
unsigned char *ptr; |
|
| 4151 |
int *nPoints; |
|
| 4152 |
int idx; |
|
| 4153 | ||
| 4154 |
mWkt += "{ \"type\": \"LineString\", \"coordinates\": [ ";
|
|
| 4155 |
// get number of points in the line |
|
| 4156 |
ptr = mGeometry + 5; |
|
| 4157 |
nPoints = ( int * ) ptr; |
|
| 4158 |
ptr = mGeometry + 1 + 2 * sizeof( int ); |
|
| 4159 |
for ( idx = 0; idx < *nPoints; ++idx ) |
|
| 4160 |
{
|
|
| 4161 |
if ( idx != 0 ) |
|
| 4162 |
{
|
|
| 4163 |
mWkt += ", "; |
|
| 4164 |
} |
|
| 4165 |
mWkt += "["; |
|
| 4166 |
x = ( double * ) ptr; |
|
| 4167 |
mWkt += QString::number( *x, 'f', 6 ); |
|
| 4168 |
mWkt += ", "; |
|
| 4169 |
ptr += sizeof( double ); |
|
| 4170 |
y = ( double * ) ptr; |
|
| 4171 |
mWkt += QString::number( *y, 'f', 6 ); |
|
| 4172 |
ptr += sizeof( double ); |
|
| 4173 |
if ( hasZValue ) |
|
| 4174 |
{
|
|
| 4175 |
ptr += sizeof( double ); |
|
| 4176 |
} |
|
| 4177 |
mWkt += "]"; |
|
| 4178 |
} |
|
| 4179 |
mWkt += " ] }"; |
|
| 4180 |
return mWkt; |
|
| 4181 |
} |
|
| 4182 | ||
| 4183 |
case QGis::WKBPolygon25D: |
|
| 4184 |
hasZValue = true; |
|
| 4185 |
case QGis::WKBPolygon: |
|
| 4186 |
{
|
|
| 4187 |
QgsDebugMsg( "POLYGON found" ); |
|
| 4188 |
unsigned char *ptr; |
|
| 4189 |
int idx, jdx; |
|
| 4190 |
int *numRings, *nPoints; |
|
| 4191 | ||
| 4192 |
mWkt += "{ \"type\": \"Polygon\", \"coordinates\": [ ";
|
|
| 4193 |
// get number of rings in the polygon |
|
| 4194 |
numRings = ( int * )( mGeometry + 1 + sizeof( int ) ); |
|
| 4195 |
if ( !( *numRings ) ) // sanity check for zero rings in polygon |
|
| 4196 |
{
|
|
| 4197 |
return QString(); |
|
| 4198 |
} |
|
| 4199 |
int *ringStart; // index of first point for each ring |
|
| 4200 |
int *ringNumPoints; // number of points in each ring |
|
| 4201 |
ringStart = new int[*numRings]; |
|
| 4202 |
ringNumPoints = new int[*numRings]; |
|
| 4203 |
ptr = mGeometry + 1 + 2 * sizeof( int ); // set pointer to the first ring |
|
| 4204 |
for ( idx = 0; idx < *numRings; idx++ ) |
|
| 4205 |
{
|
|
| 4206 |
if ( idx != 0 ) |
|
| 4207 |
{
|
|
| 4208 |
mWkt += ", "; |
|
| 4209 |
} |
|
| 4210 |
mWkt += "[ "; |
|
| 4211 |
// get number of points in the ring |
|
| 4212 |
nPoints = ( int * ) ptr; |
|
| 4213 |
ringNumPoints[idx] = *nPoints; |
|
| 4214 |
ptr += 4; |
|
| 4215 | ||
| 4216 |
for ( jdx = 0; jdx < *nPoints; jdx++ ) |
|
| 4217 |
{
|
|
| 4218 |
if ( jdx != 0 ) |
|
| 4219 |
{
|
|
| 4220 |
mWkt += ", "; |
|
| 4221 |
} |
|
| 4222 |
mWkt += "["; |
|
| 4223 |
x = ( double * ) ptr; |
|
| 4224 |
mWkt += QString::number( *x, 'f', 6 ); |
|
| 4225 |
mWkt += ", "; |
|
| 4226 |
ptr += sizeof( double ); |
|
| 4227 |
y = ( double * ) ptr; |
|
| 4228 |
mWkt += QString::number( *y, 'f', 6 ); |
|
| 4229 |
ptr += sizeof( double ); |
|
| 4230 |
if ( hasZValue ) |
|
| 4231 |
{
|
|
| 4232 |
ptr += sizeof( double ); |
|
| 4233 |
} |
|
| 4234 |
mWkt += "]"; |
|
| 4235 |
} |
|
| 4236 |
mWkt += " ]"; |
|
| 4237 |
} |
|
| 4238 |
mWkt += " ] }"; |
|
| 4239 |
delete [] ringStart; |
|
| 4240 |
delete [] ringNumPoints; |
|
| 4241 |
return mWkt; |
|
| 4242 |
} |
|
| 4243 | ||
| 4244 |
case QGis::WKBMultiPoint25D: |
|
| 4245 |
hasZValue = true; |
|
| 4246 |
case QGis::WKBMultiPoint: |
|
| 4247 |
{
|
|
| 4248 |
unsigned char *ptr; |
|
| 4249 |
int idx; |
|
| 4250 |
int *nPoints; |
|
| 4251 | ||
| 4252 |
mWkt += "{ \"type\": \"MultiPoint\", \"coordinates\": [ ";
|
|
| 4253 |
nPoints = ( int* )( mGeometry + 5 ); |
|
| 4254 |
ptr = mGeometry + 5 + sizeof( int ); |
|
| 4255 |
for ( idx = 0; idx < *nPoints; ++idx ) |
|
| 4256 |
{
|
|
| 4257 |
ptr += ( 1 + sizeof( int ) ); |
|
| 4258 |
if ( idx != 0 ) |
|
| 4259 |
{
|
|
| 4260 |
mWkt += ", "; |
|
| 4261 |
} |
|
| 4262 |
mWkt += "["; |
|
| 4263 |
x = ( double * )( ptr ); |
|
| 4264 |
mWkt += QString::number( *x, 'f', 6 ); |
|
| 4265 |
mWkt += ", "; |
|
| 4266 |
ptr += sizeof( double ); |
|
| 4267 |
y = ( double * )( ptr ); |
|
| 4268 |
mWkt += QString::number( *y, 'f', 6 ); |
|
| 4269 |
ptr += sizeof( double ); |
|
| 4270 |
if ( hasZValue ) |
|
| 4271 |
{
|
|
| 4272 |
ptr += sizeof( double ); |
|
| 4273 |
} |
|
| 4274 |
mWkt += "]"; |
|
| 4275 |
} |
|
| 4276 |
mWkt += " ] }"; |
|
| 4277 |
return mWkt; |
|
| 4278 |
} |
|
| 4279 | ||
| 4280 |
case QGis::WKBMultiLineString25D: |
|
| 4281 |
hasZValue = true; |
|
| 4282 |
case QGis::WKBMultiLineString: |
|
| 4283 |
{
|
|
| 4284 |
QgsDebugMsg( "MULTILINESTRING found" ); |
|
| 4285 |
unsigned char *ptr; |
|
| 4286 |
int idx, jdx, numLineStrings; |
|
| 4287 |
int *nPoints; |
|
| 4288 | ||
| 4289 |
mWkt += "{ \"type\": \"MultiLineString\", \"coordinates\": [ ";
|
|
| 4290 |
numLineStrings = ( int )( mGeometry[5] ); |
|
| 4291 |
ptr = mGeometry + 9; |
|
| 4292 |
for ( jdx = 0; jdx < numLineStrings; jdx++ ) |
|
| 4293 |
{
|
|
| 4294 |
if ( jdx != 0 ) |
|
| 4295 |
{
|
|
| 4296 |
mWkt += ", "; |
|
| 4297 |
} |
|
| 4298 |
mWkt += "[ "; |
|
| 4299 |
ptr += 5; // skip type since we know its 2 |
|
| 4300 |
nPoints = ( int * ) ptr; |
|
| 4301 |
ptr += sizeof( int ); |
|
| 4302 |
for ( idx = 0; idx < *nPoints; idx++ ) |
|
| 4303 |
{
|
|
| 4304 |
if ( idx != 0 ) |
|
| 4305 |
{
|
|
| 4306 |
mWkt += ", "; |
|
| 4307 |
} |
|
| 4308 |
mWkt += "["; |
|
| 4309 |
x = ( double * ) ptr; |
|
| 4310 |
mWkt += QString::number( *x, 'f', 6 ); |
|
| 4311 |
ptr += sizeof( double ); |
|
| 4312 |
mWkt += ", "; |
|
| 4313 |
y = ( double * ) ptr; |
|
| 4314 |
mWkt += QString::number( *y, 'f', 6 ); |
|
| 4315 |
ptr += sizeof( double ); |
|
| 4316 |
if ( hasZValue ) |
|
| 4317 |
{
|
|
| 4318 |
ptr += sizeof( double ); |
|
| 4319 |
} |
|
| 4320 |
mWkt += "]"; |
|
| 4321 |
} |
|
| 4322 |
mWkt += " ]"; |
|
| 4323 |
} |
|
| 4324 |
mWkt += " ] }"; |
|
| 4325 |
return mWkt; |
|
| 4326 |
} |
|
| 4327 | ||
| 4328 |
case QGis::WKBMultiPolygon25D: |
|
| 4329 |
hasZValue = true; |
|
| 4330 |
case QGis::WKBMultiPolygon: |
|
| 4331 |
{
|
|
| 4332 |
QgsDebugMsg( "MULTIPOLYGON found" ); |
|
| 4333 |
unsigned char *ptr; |
|
| 4334 |
int idx, jdx, kdx; |
|
| 4335 |
int *numPolygons, *numRings, *nPoints; |
|
| 4336 | ||
| 4337 |
mWkt += "{ \"type\": \"MultiPolygon\", \"coordinates\": [ ";
|
|
| 4338 |
ptr = mGeometry + 5; |
|
| 4339 |
numPolygons = ( int * ) ptr; |
|
| 4340 |
ptr = mGeometry + 9; |
|
| 4341 |
for ( kdx = 0; kdx < *numPolygons; kdx++ ) |
|
| 4342 |
{
|
|
| 4343 |
if ( kdx != 0 ) |
|
| 4344 |
{
|
|
| 4345 |
mWkt += ", "; |
|
| 4346 |
} |
|
| 4347 |
mWkt += "[ "; |
|
| 4348 |
ptr += 5; |
|
| 4349 |
numRings = ( int * ) ptr; |
|
| 4350 |
ptr += 4; |
|
| 4351 |
for ( idx = 0; idx < *numRings; idx++ ) |
|
| 4352 |
{
|
|
| 4353 |
if ( idx != 0 ) |
|
| 4354 |
{
|
|
| 4355 |
mWkt += ", "; |
|
| 4356 |
} |
|
| 4357 |
mWkt += "[ "; |
|
| 4358 |
nPoints = ( int * ) ptr; |
|
| 4359 |
ptr += 4; |
|
| 4360 |
for ( jdx = 0; jdx < *nPoints; jdx++ ) |
|
| 4361 |
{
|
|
| 4362 |
if ( jdx != 0 ) |
|
| 4363 |
{
|
|
| 4364 |
mWkt += ", "; |
|
| 4365 |
} |
|
| 4366 |
mWkt += "["; |
|
| 4367 |
x = ( double * ) ptr; |
|
| 4368 |
mWkt += QString::number( *x, 'f', 6 ); |
|
| 4369 |
ptr += sizeof( double ); |
|
| 4370 |
mWkt += ", "; |
|
| 4371 |
y = ( double * ) ptr; |
|
| 4372 |
mWkt += QString::number( *y, 'f', 6 ); |
|
| 4373 |
ptr += sizeof( double ); |
|
| 4374 |
if ( hasZValue ) |
|
| 4375 |
{
|
|
| 4376 |
ptr += sizeof( double ); |
|
| 4377 |
} |
|
| 4378 |
mWkt += "]"; |
|
| 4379 |
} |
|
| 4380 |
mWkt += " ]"; |
|
| 4381 |
} |
|
| 4382 |
mWkt += " ]"; |
|
| 4383 |
} |
|
| 4384 |
mWkt += " ] }"; |
|
| 4385 |
return mWkt; |
|
| 4386 |
} |
|
| 4387 | ||
| 4388 |
default: |
|
| 4389 |
QgsDebugMsg( "error: mGeometry type not recognized" ); |
|
| 4390 |
return QString::null; |
|
| 4391 |
} |
|
| 4392 |
} |
|
| 4393 | ||
| 4104 | 4394 |
bool QgsGeometry::exportWkbToGeos() |
| 4105 | 4395 |
{
|
| 4106 | 4396 |
QgsDebugMsgLevel( "entered.", 3 ); |
| src/core/qgsgeometry.h | ||
|---|---|---|
| 360 | 360 |
*/ |
| 361 | 361 |
QString exportToWkt(); |
| 362 | 362 | |
| 363 |
/** Exports the geometry to mGeoJSON |
|
| 364 |
@return true in case of success and false else |
|
| 365 |
*/ |
|
| 366 |
QString exportToGeoJSON(); |
|
| 367 | ||
| 363 | 368 |
/* Accessor functions for getting geometry data */ |
| 364 | 369 | |
| 365 | 370 |
/** return contents of the geometry as a point |
| src/mapserver/CMakeLists.txt | ||
|---|---|---|
| 27 | 27 |
qgssldparser.cpp |
| 28 | 28 |
qgssldrenderer.cpp |
| 29 | 29 |
qgswmsserver.cpp |
| 30 |
qgswfsserver.cpp |
|
| 30 | 31 |
qgsmapserviceexception.cpp |
| 31 | 32 |
qgsmapserverlogger.cpp |
| 32 | 33 |
qgsmslayercache.cpp |
| src/mapserver/qgis_map_serv.cpp | ||
|---|---|---|
| 28 | 28 |
#include "qgsmapserviceexception.h" |
| 29 | 29 |
#include "qgsprojectparser.h" |
| 30 | 30 |
#include "qgssldparser.h" |
| 31 |
#include "qgswfsserver.h" |
|
| 31 | 32 |
#include <QDomDocument> |
| 32 | 33 |
#include <QImage> |
| 33 | 34 |
#include <QSettings> |
| ... | ... | |
| 264 | 265 |
} |
| 265 | 266 | |
| 266 | 267 |
QgsWMSServer* theServer = 0; |
| 268 |
if ( serviceIt->second == "WFS" ) |
|
| 269 |
{
|
|
| 270 |
delete theServer; |
|
| 271 |
QgsWFSServer* theServer = 0; |
|
| 272 |
try |
|
| 273 |
{
|
|
| 274 |
theServer = new QgsWFSServer( parameterMap ); |
|
| 275 |
} |
|
| 276 |
catch ( QgsMapServiceException e ) //admin.sld may be invalid |
|
| 277 |
{
|
|
| 278 |
theRequestHandler->sendServiceException( e ); |
|
| 279 |
continue; |
|
| 280 |
} |
|
| 281 | ||
| 282 |
theServer->setAdminConfigParser( adminConfigParser ); |
|
| 283 | ||
| 284 | ||
| 285 |
//request type |
|
| 286 |
std::map<QString, QString>::const_iterator requestIt = parameterMap.find( "REQUEST" ); |
|
| 287 |
if ( requestIt == parameterMap.end() ) |
|
| 288 |
{
|
|
| 289 |
//do some error handling |
|
| 290 |
QgsMSDebugMsg( "unable to find 'REQUEST' parameter, exiting..." ); |
|
| 291 |
theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQUEST parameter" ) ); |
|
| 292 |
delete theRequestHandler; |
|
| 293 |
delete theServer; |
|
| 294 |
continue; |
|
| 295 |
} |
|
| 296 | ||
| 297 |
if ( requestIt->second == "GetCapabilities" ) |
|
| 298 |
{
|
|
| 299 |
QDomDocument capabilitiesDocument; |
|
| 300 |
try |
|
| 301 |
{
|
|
| 302 |
capabilitiesDocument = theServer->getCapabilities(); |
|
| 303 |
} |
|
| 304 |
catch ( QgsMapServiceException& ex ) |
|
| 305 |
{
|
|
| 306 |
theRequestHandler->sendServiceException( ex ); |
|
| 307 |
delete theRequestHandler; |
|
| 308 |
delete theServer; |
|
| 309 |
continue; |
|
| 310 |
} |
|
| 311 |
QgsMSDebugMsg( "sending GetCapabilities response" ); |
|
| 312 |
theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument ); |
|
| 313 |
delete theRequestHandler; |
|
| 314 |
delete theServer; |
|
| 315 |
continue; |
|
| 316 |
} |
|
| 317 |
else if ( requestIt->second == "DescribeFeatureType" ) |
|
| 318 |
{
|
|
| 319 |
QDomDocument describeDocument; |
|
| 320 |
try |
|
| 321 |
{
|
|
| 322 |
describeDocument = theServer->describeFeatureType(); |
|
| 323 |
} |
|
| 324 |
catch ( QgsMapServiceException& ex ) |
|
| 325 |
{
|
|
| 326 |
theRequestHandler->sendServiceException( ex ); |
|
| 327 |
delete theRequestHandler; |
|
| 328 |
delete theServer; |
|
| 329 |
continue; |
|
| 330 |
} |
|
| 331 |
QgsMSDebugMsg( "sending GetCapabilities response" ); |
|
| 332 |
theRequestHandler->sendGetCapabilitiesResponse( describeDocument ); |
|
| 333 |
delete theRequestHandler; |
|
| 334 |
delete theServer; |
|
| 335 |
continue; |
|
| 336 |
} |
|
| 337 |
else if ( requestIt->second == "GetFeature" ) |
|
| 338 |
{
|
|
| 339 |
//output format for GetFeature |
|
| 340 |
QString outputFormat; |
|
| 341 |
std::map<QString, QString>::const_iterator p_it = parameterMap.find( "OUTPUTFORMAT" ); |
|
| 342 |
if ( p_it != parameterMap.end() ) |
|
| 343 |
{
|
|
| 344 |
outputFormat = p_it->second; |
|
| 345 |
} |
|
| 346 | ||
| 347 |
try |
|
| 348 |
{
|
|
| 349 |
if ( theServer->getFeature( *theRequestHandler, outputFormat ) != 0 ) |
|
| 350 |
{
|
|
| 351 |
delete theRequestHandler; |
|
| 352 |
delete theServer; |
|
| 353 |
continue; |
|
| 354 |
} else {
|
|
| 355 |
delete theRequestHandler; |
|
| 356 |
delete theServer; |
|
| 357 |
continue; |
|
| 358 |
} |
|
| 359 |
} |
|
| 360 |
catch ( QgsMapServiceException& ex ) |
|
| 361 |
{
|
|
| 362 |
theRequestHandler->sendServiceException( ex ); |
|
| 363 |
delete theRequestHandler; |
|
| 364 |
delete theServer; |
|
| 365 |
continue; |
|
| 366 |
} |
|
| 367 |
} |
|
| 368 | ||
| 369 |
return 0; |
|
| 370 |
} |
|
| 371 |
else |
|
| 372 |
{
|
|
| 267 | 373 |
try |
| 268 | 374 |
{
|
| 269 | 375 |
theServer = new QgsWMSServer( parameterMap, theMapRenderer ); |
| ... | ... | |
| 273 | 379 |
theRequestHandler->sendServiceException( e ); |
| 274 | 380 |
continue; |
| 275 | 381 |
} |
| 382 |
} |
|
| 276 | 383 | |
| 277 | 384 |
theServer->setAdminConfigParser( adminConfigParser ); |
| 278 | 385 | |
| src/mapserver/qgsconfigparser.h | ||
|---|---|---|
| 40 | 40 |
/**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ |
| 41 | 41 |
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0; |
| 42 | 42 | |
| 43 |
virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const = 0; |
|
| 44 | ||
| 43 | 45 |
/**Returns one or possibly several maplayers for a given layer name and style. If there are several layers, the layers should be drawn in inverse list order. |
| 44 | 46 |
If no layers/style are found, an empty list is returned*/ |
| 45 | 47 |
virtual QList<QgsMapLayer*> mapLayerFromStyle( const QString& layerName, const QString& styleName, bool allowCaching = true ) const = 0; |
| src/mapserver/qgsgetrequesthandler.cpp | ||
|---|---|---|
| 11 | 11 |
#include <QImage> |
| 12 | 12 |
#include <QStringList> |
| 13 | 13 |
#include <QUrl> |
| 14 |
#include <fcgi_stdio.h> |
|
| 14 | 15 | |
| 15 | 16 |
QgsGetRequestHandler::QgsGetRequestHandler(): QgsHttpRequestHandler() |
| 16 | 17 |
{
|
| ... | ... | |
| 306 | 307 |
{
|
| 307 | 308 |
sendHttpResponse( ba, formatToMimeType( mFormat ) ); |
| 308 | 309 |
} |
| 310 | ||
| 311 |
bool QgsGetRequestHandler::startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) const |
|
| 312 |
{
|
|
| 313 |
if ( !ba ) |
|
| 314 |
{
|
|
| 315 |
return false; |
|
| 316 |
} |
|
| 317 | ||
| 318 |
if ( ba->size() < 1 ) |
|
| 319 |
{
|
|
| 320 |
return false; |
|
| 321 |
} |
|
| 322 | ||
| 323 |
QString format; |
|
| 324 |
if (infoFormat == "GeoJSON") |
|
| 325 |
format = "text/plain"; |
|
| 326 |
else |
|
| 327 |
format = "text/xml"; |
|
| 328 | ||
| 329 |
printf( "Content-Type: " ); |
|
| 330 |
printf( format.toLocal8Bit() ); |
|
| 331 |
printf( "\n" ); |
|
| 332 |
printf( "\n" ); |
|
| 333 |
fwrite( ba->data(), ba->size(), 1, FCGI_stdout ); |
|
| 334 |
return true; |
|
| 335 |
} |
|
| 336 | ||
| 337 |
void QgsGetRequestHandler::sendGetFeatureResponse( QByteArray* ba ) const |
|
| 338 |
{
|
|
| 339 |
if ( !ba ) |
|
| 340 |
{
|
|
| 341 |
return; |
|
| 342 |
} |
|
| 343 | ||
| 344 |
if ( ba->size() < 1 ) |
|
| 345 |
{
|
|
| 346 |
return; |
|
| 347 |
} |
|
| 348 |
fwrite( ba->data(), ba->size(), 1, FCGI_stdout ); |
|
| 349 |
} |
|
| 350 | ||
| 351 |
void QgsGetRequestHandler::endGetFeatureResponse( QByteArray* ba ) const |
|
| 352 |
{
|
|
| 353 |
if ( !ba ) |
|
| 354 |
{
|
|
| 355 |
return; |
|
| 356 |
} |
|
| 357 | ||
| 358 |
fwrite( ba->data(), ba->size(), 1, FCGI_stdout ); |
|
| 359 |
} |
|
| src/mapserver/qgsgetrequesthandler.h | ||
|---|---|---|
| 30 | 30 |
void sendServiceException( const QgsMapServiceException& ex ) const; |
| 31 | 31 |
void sendGetStyleResponse( const QDomDocument& doc ) const; |
| 32 | 32 |
void sendGetPrintResponse( QByteArray* ba ) const; |
| 33 |
bool startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) const; |
|
| 34 |
void sendGetFeatureResponse( QByteArray* ba ) const; |
|
| 35 |
void endGetFeatureResponse( QByteArray* ba ) const; |
|
| 33 | 36 |
}; |
| src/mapserver/qgsprojectparser.cpp | ||
|---|---|---|
| 115 | 115 |
parentElement.appendChild( layerParentElem ); |
| 116 | 116 |
} |
| 117 | 117 | |
| 118 |
void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const |
|
| 119 |
{
|
|
| 120 |
QList<QDomElement> layerElems = projectLayerElements(); |
|
| 121 | ||
| 122 |
QStringList nonIdentifiableLayers = identifyDisabledLayers(); |
|
| 123 | ||
| 124 |
if ( layerElems.size() < 1 ) |
|
| 125 |
{
|
|
| 126 |
return; |
|
| 127 |
} |
|
| 128 | ||
| 129 |
QMap<QString, QgsMapLayer *> layerMap; |
|
| 130 | ||
| 131 |
QList<QDomElement>::const_iterator layerIt = layerElems.constBegin(); |
|
| 132 |
for ( ; layerIt != layerElems.constEnd(); ++layerIt ) |
|
| 133 |
{
|
|
| 134 |
QDomElement elem = *layerIt; |
|
| 135 |
QString type = elem.attribute( "type" ); |
|
| 136 |
if ( type == "vector" ) |
|
| 137 |
{
|
|
| 138 |
QgsMapLayer *layer = createLayerFromElement( *layerIt ); |
|
| 139 |
if ( layer ) |
|
| 140 |
{
|
|
| 141 |
QgsMSDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) ); |
|
| 142 |
layerMap.insert( layer->id(), layer ); |
|
| 143 | ||
| 144 |
QDomElement layerElem = doc.createElement( "FeatureType" ); |
|
| 145 |
QDomElement nameElem = doc.createElement( "Name" ); |
|
| 146 |
//We use the layer name even though it might not be unique. |
|
| 147 |
//Because the id sometimes contains user/pw information and the name is more descriptive |
|
| 148 |
QDomText nameText = doc.createTextNode( layer->name() ); |
|
| 149 |
nameElem.appendChild( nameText ); |
|
| 150 |
layerElem.appendChild( nameElem ); |
|
| 151 | ||
| 152 |
QDomElement titleElem = doc.createElement( "Title" ); |
|
| 153 |
QDomText titleText = doc.createTextNode( layer->name() ); |
|
| 154 |
titleElem.appendChild( titleText ); |
|
| 155 |
layerElem.appendChild( titleElem ); |
|
| 156 | ||
| 157 |
//appendExGeographicBoundingBox( layerElem, doc, layer->extent(), layer->crs() ); |
|
| 158 | ||
| 159 |
QDomElement srsElem = doc.createElement( "SRS" ); |
|
| 160 |
QDomText srsText = doc.createTextNode( layer->crs().authid() ); |
|
| 161 |
srsElem.appendChild( srsText ); |
|
| 162 |
layerElem.appendChild( srsElem ); |
|
| 163 | ||
| 164 |
QgsRectangle layerExtent = layer->extent(); |
|
| 165 |
QDomElement bBoxElement = doc.createElement( "LatLongBoundingBox" ); |
|
| 166 |
bBoxElement.setAttribute( "minx", QString::number( layerExtent.xMinimum() ) ); |
|
| 167 |
bBoxElement.setAttribute( "miny", QString::number( layerExtent.yMinimum() ) ); |
|
| 168 |
bBoxElement.setAttribute( "maxx", QString::number( layerExtent.xMaximum() ) ); |
|
| 169 |
bBoxElement.setAttribute( "maxy", QString::number( layerExtent.yMaximum() ) ); |
|
| 170 |
layerElem.appendChild( bBoxElement ); |
|
| 171 | ||
| 172 |
parentElement.appendChild(layerElem); |
|
| 173 |
} |
|
| 174 |
#if QGSMSDEBUG |
|
| 175 |
else |
|
| 176 |
{
|
|
| 177 |
QString buf; |
|
| 178 |
QTextStream s( &buf ); |
|
| 179 |
layerIt->save( s, 0 ); |
|
| 180 |
QgsMSDebugMsg( QString( "layer %1 not found" ).arg( buf ) ); |
|
| 181 |
} |
|
| 182 |
#endif |
|
| 183 |
} |
|
| 184 |
} |
|
| 185 |
return; |
|
| 186 |
} |
|
| 187 | ||
| 118 | 188 |
void QgsProjectParser::addLayers( QDomDocument &doc, |
| 119 | 189 |
QDomElement &parentElem, |
| 120 | 190 |
const QDomElement &legendElem, |
| src/mapserver/qgsprojectparser.h | ||
|---|---|---|
| 38 | 38 |
/**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ |
| 39 | 39 |
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const; |
| 40 | 40 | |
| 41 |
virtual void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const; |
|
| 42 | ||
| 41 | 43 |
int numberOfLayers() const; |
| 42 | 44 | |
| 43 | 45 |
/**Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/ |
| src/mapserver/qgsrequesthandler.h | ||
|---|---|---|
| 41 | 41 |
virtual void sendServiceException( const QgsMapServiceException& ex ) const = 0; |
| 42 | 42 |
virtual void sendGetStyleResponse( const QDomDocument& doc ) const = 0; |
| 43 | 43 |
virtual void sendGetPrintResponse( QByteArray* ba ) const = 0; |
| 44 |
virtual void sendGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) const = 0; |
|
| 44 | 45 |
QString format() const { return mFormat; }
|
| 45 | 46 |
protected: |
| 46 | 47 |
/**This is set by the parseInput methods of the subclasses (parameter FORMAT, e.g. 'FORMAT=PNG')*/ |
| src/mapserver/qgssldparser.h | ||
|---|---|---|
| 57 | 57 |
/**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ |
| 58 | 58 |
void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const; |
| 59 | 59 | |
| 60 |
void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const {};
|
|
| 61 | ||
| 60 | 62 |
/**Returns number of layers in configuration*/ |
| 61 | 63 |
int numberOfLayers() const; |
| 62 | 64 | |
| src/mapserver/qgssoaprequesthandler.h | ||
|---|---|---|
| 35 | 35 |
void sendServiceException( const QgsMapServiceException& ex ) const; |
| 36 | 36 |
void sendGetStyleResponse( const QDomDocument& doc ) const; |
| 37 | 37 |
void sendGetPrintResponse( QByteArray* ba ) const; |
| 38 |
bool startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) const { return false; };
|
|
| 39 |
void sendGetFeatureResponse( QByteArray* ba ) const {};
|
|
| 40 |
void endGetFeatureResponse( QByteArray* ba ) const {};
|
|
| 38 | 41 |
private: |
| 39 | 42 |
/**Parses the xml of a getMap request and fills the parameters into the map. Returns 0 in case of success*/ |
| 40 | 43 |
int parseGetMapElement( std::map<QString, QString>& parameterMap, const QDomElement& getMapElement ) const; |
| src/mapserver/qgswfsserver.cpp | ||
|---|---|---|
| 1 |
#include "qgswfsserver.h" |
|
| 2 |
#include "qgsconfigparser.h" |
|
| 3 |
#include "qgsepsgcache.h" |
|
| 4 |
#include "qgsfield.h" |
|
| 5 |
#include "qgsgeometry.h" |
|
| 6 |
#include "qgsmaplayer.h" |
|
| 7 |
#include "qgsmaplayerregistry.h" |
|
| 8 |
#include "qgsmaprenderer.h" |
|
| 9 |
#include "qgsmaptopixel.h" |
|
| 10 |
#include "qgspallabeling.h" |
|
| 11 |
#include "qgsproject.h" |
|
| 12 |
#include "qgsrasterlayer.h" |
|
| 13 |
#include "qgsscalecalculator.h" |
|
| 14 |
#include "qgscoordinatereferencesystem.h" |
|
| 15 |
#include "qgsvectordataprovider.h" |
|
| 16 |
#include "qgsvectorlayer.h" |
|
| 17 |
#include "qgsfilter.h" |
|
| 18 |
#include "qgsmapserverlogger.h" |
|
| 19 |
#include "qgsmapserviceexception.h" |
|
| 20 |
#include "qgssldparser.h" |
|
| 21 |
#include "qgssymbol.h" |
|
| 22 |
#include "qgssymbolv2.h" |
|
| 23 |
#include "qgsrenderer.h" |
|
| 24 |
#include "qgslegendmodel.h" |
|
| 25 |
#include "qgscomposerlegenditem.h" |
|
| 26 |
#include "qgslogger.h" |
|
| 27 |
#include "qgsrequesthandler.h" |
|
| 28 |
#include <QImage> |
|
| 29 |
#include <QPainter> |
|
| 30 |
#include <QStringList> |
|
| 31 |
#include <QTextStream> |
|
| 32 |
#include <QDir> |
|
| 33 | ||
| 34 |
//for printing |
|
| 35 |
#include "qgscomposition.h" |
|
| 36 |
#include <QBuffer> |
|
| 37 |
#include <QPrinter> |
|
| 38 |
#include <QSvgGenerator> |
|
| 39 |
#include <QUrl> |
|
| 40 |
#include <QPaintEngine> |
|
| 41 | ||
| 42 |
QgsWFSServer::QgsWFSServer( std::map<QString, QString> parameters ) |
|
| 43 |
: mParameterMap( parameters ) |
|
| 44 |
, mConfigParser( 0 ) |
|
| 45 |
{
|
|
| 46 |
} |
|
| 47 | ||
| 48 |
QgsWFSServer::~QgsWFSServer() |
|
| 49 |
{
|
|
| 50 |
} |
|
| 51 | ||
| 52 |
QgsWFSServer::QgsWFSServer() |
|
| 53 |
{
|
|
| 54 |
} |
|
| 55 | ||
| 56 |
QDomDocument QgsWFSServer::getCapabilities() |
|
| 57 |
{
|
|
| 58 |
QgsMSDebugMsg( "Entering." ); |
|
| 59 |
QDomDocument doc; |
|
| 60 |
//wfs:WFS_Capabilities element |
|
| 61 |
QDomElement wfsCapabilitiesElement = doc.createElement( "WFS_Capabilities"/*wms:WFS_Capabilities*/ ); |
|
| 62 |
wfsCapabilitiesElement.setAttribute( "xmlns", "http://www.opengis.net/wfs" ); |
|
| 63 |
wfsCapabilitiesElement.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" ); |
|
| 64 |
wfsCapabilitiesElement.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd" ); |
|
| 65 |
wfsCapabilitiesElement.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" ); |
|
| 66 |
wfsCapabilitiesElement.setAttribute( "xmlns:gml", "http://www.opengis.net/gml" ); |
|
| 67 |
wfsCapabilitiesElement.setAttribute( "xmlns:ows", "http://www.opengis.net/ows" ); |
|
| 68 |
wfsCapabilitiesElement.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); |
|
| 69 |
wfsCapabilitiesElement.setAttribute( "version", "1.0.0" ); |
|
| 70 |
wfsCapabilitiesElement.setAttribute( "updateSequence", "0" ); |
|
| 71 |
doc.appendChild( wfsCapabilitiesElement ); |
|
| 72 | ||
| 73 |
if ( mConfigParser ) |
|
| 74 |
{
|
|
| 75 |
mConfigParser->serviceCapabilities( wfsCapabilitiesElement, doc ); |
|
| 76 |
} |
|
| 77 | ||
| 78 |
//wfs:Capability element |
|
| 79 |
QDomElement capabilityElement = doc.createElement( "Capability"/*wfs:Capability*/ ); |
|
| 80 |
wfsCapabilitiesElement.appendChild( capabilityElement ); |
|
| 81 |
|
|
| 82 |
//wfs:Request element |
|
| 83 |
QDomElement requestElement = doc.createElement( "Request"/*wfs:Request*/ ); |
|
| 84 |
capabilityElement.appendChild( requestElement ); |
|
| 85 |
//wfs:GetCapabilities |
|
| 86 |
QDomElement getCapabilitiesElement = doc.createElement( "GetCapabilities"/*wfs:GetCapabilities*/ ); |
|
| 87 |
requestElement.appendChild( getCapabilitiesElement ); |
|
| 88 |
QDomElement capabilitiesFormatElement = doc.createElement( "Format" );/*wfs:Format*/ |
|
| 89 |
getCapabilitiesElement.appendChild( capabilitiesFormatElement ); |
|
| 90 |
QDomText capabilitiesFormatText = doc.createTextNode( "text/xml" ); |
|
| 91 |
capabilitiesFormatElement.appendChild( capabilitiesFormatText ); |
|
| 92 | ||
| 93 |
QDomElement dcpTypeElement = doc.createElement( "DCPType"/*wfs:DCPType*/ ); |
|
| 94 |
getCapabilitiesElement.appendChild( dcpTypeElement ); |
|
| 95 |
QDomElement httpElement = doc.createElement( "HTTP"/*wfs:HTTP*/ ); |
|
| 96 |
dcpTypeElement.appendChild( httpElement ); |
|
| 97 | ||
| 98 |
//Prepare url |
|
| 99 |
//Some client requests already have http://<SERVER_NAME> in the REQUEST_URI variable |
|
| 100 |
QString hrefString; |
|
| 101 |
QString requestUrl = getenv( "REQUEST_URI" ); |
|
| 102 |
QUrl mapUrl( requestUrl ); |
|
| 103 |
mapUrl.setHost( QString( getenv( "SERVER_NAME" ) ) ); |
|
| 104 |
mapUrl.removeQueryItem( "REQUEST" ); |
|
| 105 |
mapUrl.removeQueryItem( "VERSION" ); |
|
| 106 |
mapUrl.removeQueryItem( "SERVICE" ); |
|
| 107 |
hrefString = mapUrl.toString(); |
|
| 108 | ||
| 109 |
//only Get supported for the moment |
|
| 110 |
QDomElement getElement = doc.createElement( "Get"/*wfs:Get*/ ); |
|
| 111 |
httpElement.appendChild( getElement ); |
|
| 112 |
QDomElement olResourceElement = doc.createElement( "OnlineResource"/*wfs:OnlineResource*/ ); |
|
| 113 |
olResourceElement.setAttribute( "xlink:type", "simple" ); |
|
| 114 |
requestUrl.truncate( requestUrl.indexOf( "?" ) + 1 ); |
|
| 115 |
olResourceElement.setAttribute( "xlink:href", hrefString ); |
|
| 116 |
getElement.appendChild( olResourceElement ); |
|
| 117 | ||
| 118 |
//wfs:DescribeFeatureType |
|
| 119 |
QDomElement describeFeatureTypeElement = doc.createElement( "DescribeFeatureType"/*wfs:DescribeFeatureType*/ ); |
|
| 120 |
requestElement.appendChild( describeFeatureTypeElement ); |
|
| 121 |
QDomElement schemaDescriptionLanguageElement = doc.createElement( "SchemaDescriptionLanguage"/*wfs:SchemaDescriptionLanguage*/ ); |
|
| 122 |
describeFeatureTypeElement.appendChild( schemaDescriptionLanguageElement ); |
|
| 123 |
QDomElement xmlSchemaElement = doc.createElement( "XMLSCHEMA"/*wfs:XMLSCHEMA*/ ); |
|
| 124 |
schemaDescriptionLanguageElement.appendChild( xmlSchemaElement ); |
|
| 125 |
QDomElement describeFeatureTypeDhcTypeElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities' |
|
| 126 |
describeFeatureTypeElement.appendChild( describeFeatureTypeDhcTypeElement ); |
|
| 127 | ||
| 128 |
//wfs:GetFeature |
|
| 129 |
QDomElement getFeatureElement = doc.createElement( "GetFeature"/*wfs:GetFeature*/ ); |
|
| 130 |
requestElement.appendChild( getFeatureElement ); |
|
| 131 |
QDomElement getFeatureFormatElement = doc.createElement( "ResultFormat" );/*wfs:ResultFormat*/ |
|
| 132 |
getFeatureElement.appendChild( getFeatureFormatElement ); |
|
| 133 |
QDomElement gmlFormatElement = doc.createElement( "GML2" );/*wfs:GML2*/ |
|
| 134 |
getFeatureFormatElement.appendChild( gmlFormatElement ); |
|
| 135 |
QDomElement geojsonFormatElement = doc.createElement( "GeoJSON" );/*wfs:GeoJSON*/ |
|
| 136 |
getFeatureFormatElement.appendChild( geojsonFormatElement ); |
|
| 137 |
QDomElement getFeatureDhcTypeElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities' |
|
| 138 |
getFeatureElement.appendChild( getFeatureDhcTypeElement ); |
|
| 139 | ||
| 140 |
//wfs:FeatureTypeList element |
|
| 141 |
QDomElement featureTypeListElement = doc.createElement( "FeatureTypeList"/*wfs:FeatureTypeList*/ ); |
|
| 142 |
capabilityElement.appendChild( featureTypeListElement ); |
|
| 143 |
//wfs:Operations element |
|
| 144 |
QDomElement operationsElement = doc.createElement( "Operations"/*wfs:Operations*/ ); |
|
| 145 |
featureTypeListElement.appendChild( operationsElement ); |
|
| 146 |
//wfs:Query element |
|
| 147 |
QDomElement queryElement = doc.createElement( "Query"/*wfs:Query*/ ); |
|
| 148 |
operationsElement.appendChild( queryElement ); |
|
| 149 |
/* |
|
| 150 |
* Adding layer liste in featureTypeListElement |
|
| 151 |
*/ |
|
| 152 |
if ( mConfigParser ) |
|
| 153 |
{
|
|
| 154 |
mConfigParser->featureTypeList( featureTypeListElement, doc ); |
|
| 155 |
} |
|
| 156 | ||
| 157 |
/* |
|
| 158 |
* Adding ogc:Filter_Capabilities in capabilityElement |
|
| 159 |
*/ |
|
| 160 |
//ogc:Filter_Capabilities element |
|
| 161 |
QDomElement filterCapabilitiesElement = doc.createElement( "ogc:Filter_Capabilities"/*ogc:Filter_Capabilities*/ ); |
|
| 162 |
capabilityElement.appendChild( filterCapabilitiesElement ); |
|
| 163 |
QDomElement spatialCapabilitiesElement = doc.createElement( "ogc:Spatial_Capabilities"/*ogc:Spatial_Capabilities*/ ); |
|
| 164 |
filterCapabilitiesElement.appendChild( spatialCapabilitiesElement ); |
|
| 165 |
QDomElement spatialOperatorsElement = doc.createElement( "ogc:Spatial_Operators"/*ogc:Spatial_Operators*/ ); |
|
| 166 |
spatialCapabilitiesElement.appendChild( spatialOperatorsElement ); |
|
| 167 |
QDomElement ogcBboxElement = doc.createElement( "ogc:BBOX"/*ogc:BBOX*/ ); |
|
| 168 |
spatialOperatorsElement.appendChild( ogcBboxElement ); |
|
| 169 |
QDomElement scalarCapabilitiesElement = doc.createElement( "ogc:Scalar_Capabilities"/*ogc:Scalar_Capabilities*/ ); |
|
| 170 |
filterCapabilitiesElement.appendChild( scalarCapabilitiesElement ); |
|
| 171 |
QDomElement comparisonOperatorsElement = doc.createElement( "ogc:Comparison_Operators"/*ogc:Comparison_Operators*/ ); |
|
| 172 |
scalarCapabilitiesElement.appendChild( comparisonOperatorsElement ); |
|
| 173 |
QDomElement simpleComparisonsElement = doc.createElement( "ogc:Simple_Comparisons"/*ogc:Simple_Comparisons*/ ); |
|
| 174 |
comparisonOperatorsElement.appendChild( simpleComparisonsElement ); |
|
| 175 |
return doc; |
|
| 176 |
} |
|
| 177 | ||
| 178 |
QDomDocument QgsWFSServer::describeFeatureType() |
|
| 179 |
{
|
|
| 180 |
QgsMSDebugMsg( "Entering." ); |
|
| 181 |
QDomDocument doc; |
|
| 182 |
//xsd:schema |
|
| 183 |
QDomElement schemaElement = doc.createElement( "schema"/*xsd:schema*/ ); |
|
| 184 |
schemaElement.setAttribute( "xmlns", "http://www.w3.org/2001/XMLSchema" ); |
|
| 185 |
schemaElement.setAttribute( "xmlns:xsd", "http://www.w3.org/2001/XMLSchema" ); |
|
| 186 |
schemaElement.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" ); |
|
| 187 |
schemaElement.setAttribute( "xmlns:gml", "http://www.opengis.net/gml" ); |
|
| 188 |
schemaElement.setAttribute( "xmlns:qgs", "http://www.qgis.org/gml" ); |
|
| 189 |
schemaElement.setAttribute( "targetNamespace", "http://www.qgis.org/gml" ); |
|
| 190 |
doc.appendChild( schemaElement ); |
|
| 191 | ||
| 192 |
//xsd:import |
|
| 193 |
QDomElement importElement = doc.createElement( "import"/*xsd:import*/ ); |
|
| 194 |
importElement.setAttribute( "namespace", "http://www.opengis.net/gml" ); |
|
| 195 |
importElement.setAttribute( "schemaLocation", "http://schemas.opengis.net/gml/2.1.2/feature.xsd" ); |
|
| 196 |
schemaElement.appendChild( importElement ); |
|
| 197 | ||
| 198 |
//read TYPENAME |
|
| 199 |
QString typeName; |
|
| 200 |
std::map<QString, QString>::const_iterator type_name_it = mParameterMap.find( "TYPENAME" ); |
|
| 201 |
if ( type_name_it != mParameterMap.end() ) |
|
| 202 |
{
|
|
| 203 |
typeName = type_name_it->second; |
|
| 204 |
} |
|
| 205 |
else |
|
| 206 |
{
|
|
| 207 |
return doc; |
|
| 208 |
} |
|
| 209 | ||
| 210 |
QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers(); |
|
| 211 |
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo(); |
|
| 212 |
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes(); |
|
| 213 |
|
|
| 214 |
QList<QgsMapLayer*> layerList; |
|
| 215 |
QgsMapLayer* currentLayer = 0; |
|
| 216 | ||
| 217 |
layerList = mConfigParser->mapLayerFromStyle( typeName, "" ); |
|
| 218 |
currentLayer = layerList.at( 0 ); |
|
| 219 |
|
|
| 220 |
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( currentLayer ); |
|
| 221 |
if ( layer ) |
|
| 222 |
{
|
|
| 223 |
//is there alias info for this vector layer? |
|
| 224 |
QMap< int, QString > layerAliasInfo; |
|
| 225 |
QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() ); |
|
| 226 |
if ( aliasIt != aliasInfo.constEnd() ) |
|
| 227 |
{
|
|
| 228 |
layerAliasInfo = aliasIt.value(); |
|
| 229 |
} |
|
| 230 | ||
| 231 |
//hidden attributes for this layer |
|
| 232 |
QSet<QString> layerHiddenAttributes; |
|
| 233 |
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() ); |
|
| 234 |
if ( hiddenIt != hiddenAttributes.constEnd() ) |
|
| 235 |
{
|
|
| 236 |
layerHiddenAttributes = hiddenIt.value(); |
|
| 237 |
} |
|
| 238 |
|
|
| 239 |
//do a select with searchRect and go through all the features |
|
| 240 |
QgsVectorDataProvider* provider = layer->dataProvider(); |
|
| 241 |
if ( !provider ) |
|
| 242 |
{
|
|
| 243 |
return doc; |
|
| 244 |
} |
|
| 245 | ||
| 246 |
typeName = typeName.replace( QString(" "), QString("_") );
|
|
| 247 |
|
|
| 248 |
//xsd:element |
|
| 249 |
QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ ); |
|
| 250 |
elementElem.setAttribute( "name", typeName ); |
|
| 251 |
elementElem.setAttribute( "type", "qgs:" + typeName + "Type" ); |
|
| 252 |
elementElem.setAttribute( "substitutionGroup", "gml:_Feature" ); |
|
| 253 |
schemaElement.appendChild( elementElem ); |
|
| 254 | ||
| 255 |
//xsd:complexType |
|
| 256 |
QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ ); |
|
| 257 |
complexTypeElem.setAttribute( "name", typeName + "Type" ); |
|
| 258 |
schemaElement.appendChild( complexTypeElem ); |
|
| 259 | ||
| 260 |
//xsd:complexType |
|
| 261 |
QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ ); |
|
| 262 |
complexTypeElem.appendChild( complexContentElem ); |
|
| 263 | ||
| 264 |
//xsd:extension |
|
| 265 |
QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ ); |
|
| 266 |
extensionElem.setAttribute( "base", "gml:AbstractFeatureType" ); |
|
| 267 |
complexContentElem.appendChild( extensionElem ); |
|
| 268 | ||
| 269 |
//xsd:sequence |
|
| 270 |
QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ ); |
|
| 271 |
extensionElem.appendChild( sequenceElem ); |
|
| 272 | ||
| 273 |
//xsd:element |
|
| 274 |
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); |
|
| 275 |
geomElem.setAttribute( "name", "geometry" ); |
|
| 276 |
geomElem.setAttribute( "type", "gml:GeometryPropertyType" ); |
|
| 277 |
geomElem.setAttribute( "minOccurs", "0" ); |
|
| 278 |
geomElem.setAttribute( "maxOccurs", "1" ); |
|
| 279 |
sequenceElem.appendChild( geomElem ); |
|
| 280 | ||
| 281 |
const QgsFieldMap& fields = provider->fields(); |
|
| 282 |
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it ) |
|
| 283 |
{
|
|
| 284 | ||
| 285 |
QString attributeName = it.value().name(); |
|
| 286 |
//skip attribute if it has edit type 'hidden' |
|
| 287 |
if ( layerHiddenAttributes.contains( attributeName ) ) |
|
| 288 |
{
|
|
| 289 |
continue; |
|
| 290 |
} |
|
| 291 | ||
| 292 |
//check if the attribute name should be replaced with an alias |
|
| 293 |
QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() ); |
|
| 294 |
if ( aliasIt != layerAliasInfo.constEnd() ) |
|
| 295 |
{
|
|
| 296 |
attributeName = aliasIt.value(); |
|
| 297 |
} |
|
| 298 | ||
| 299 |
//xsd:element |
|
| 300 |
QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); |
|
| 301 |
geomElem.setAttribute( "name", attributeName ); |
|
| 302 |
if ( it.value().type() == 2 ) |
|
| 303 |
geomElem.setAttribute( "type", "integer" ); |
|
| 304 |
else if ( it.value().type() == 6 ) |
|
| 305 |
geomElem.setAttribute( "type", "double" ); |
|
| 306 |
else |
|
| 307 |
geomElem.setAttribute( "type", "string" ); |
|
| 308 | ||
| 309 |
sequenceElem.appendChild( geomElem ); |
|
| 310 | ||
| 311 |
} |
|
| 312 |
} |
|
| 313 | ||
| 314 |
return doc; |
|
| 315 |
} |
|
| 316 | ||
| 317 |
int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format ) |
|
| 318 |
{
|
|
| 319 |
QByteArray result; |
|
| 320 |
QgsMSDebugMsg( "Info format is:" + infoFormat ); |
|
| 321 | ||
| 322 |
//read TYPENAME |
|
| 323 |
QString typeName; |
|
| 324 |
std::map<QString, QString>::const_iterator type_name_it = mParameterMap.find( "TYPENAME" ); |
|
| 325 |
if ( type_name_it != mParameterMap.end() ) |
|
| 326 |
{
|
|
| 327 |
typeName = type_name_it->second; |
|
| 328 |
} |
|
| 329 |
else |
|
| 330 |
{
|
|
| 331 |
return 1; |
|
| 332 |
} |
|
| 333 | ||
| 334 |
QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers(); |
|
| 335 |
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo(); |
|
| 336 |
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes(); |
|
| 337 |
|
|
| 338 |
QList<QgsMapLayer*> layerList; |
|
| 339 |
QgsMapLayer* currentLayer = 0; |
|
| 340 | ||
| 341 |
layerList = mConfigParser->mapLayerFromStyle( typeName, "" ); |
|
| 342 |
currentLayer = layerList.at( 0 ); |
|
| 343 |
|
|
| 344 |
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( currentLayer ); |
|
| 345 |
if ( layer ) |
|
| 346 |
{
|
|
| 347 |
//is there alias info for this vector layer? |
|
| 348 |
QMap< int, QString > layerAliasInfo; |
|
| 349 |
QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() ); |
|
| 350 |
if ( aliasIt != aliasInfo.constEnd() ) |
|
| 351 |
{
|
|
| 352 |
layerAliasInfo = aliasIt.value(); |
|
| 353 |
} |
|
| 354 | ||
| 355 |
//hidden attributes for this layer |
|
| 356 |
QSet<QString> layerHiddenAttributes; |
|
| 357 |
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() ); |
|
| 358 |
if ( hiddenIt != hiddenAttributes.constEnd() ) |
|
| 359 |
{
|
|
| 360 |
layerHiddenAttributes = hiddenIt.value(); |
|
| 361 |
} |
|
| 362 |
|
|
| 363 |
//do a select with searchRect and go through all the features |
|
| 364 |
QgsVectorDataProvider* provider = layer->dataProvider(); |
|
| 365 |
if ( !provider ) |
|
| 366 |
{
|
|
| 367 |
return 2; |
|
| 368 |
} |
|
| 369 | ||
| 370 |
QgsFeature feature; |
|
| 371 |
QgsAttributeMap featureAttributes; |
|
| 372 |
const QgsFieldMap& fields = provider->fields(); |
|
| 373 | ||
| 374 |
//map extent |
|
| 375 |
QgsRectangle searchRect = layer->extent(); |
|
| 376 | ||
| 377 |
//read FEATUREDID |
|
| 378 |
bool fidOk = false; |
|
| 379 |
QString fid; |
|
| 380 |
std::map<QString, QString>::const_iterator fidIt = mParameterMap.find( "FEATUREID" ); |
|
| 381 |
if ( fidIt != mParameterMap.end() ) {
|
|
| 382 |
fidOk = true; |
|
| 383 |
fid = fidIt->second; |
|
| 384 |
} |
|
| 385 | ||
| 386 |
//read FILTER |
|
| 387 |
bool filterOk = false; |
|
| 388 |
QDomDocument filter; |
|
| 389 |
std::map<QString, QString>::const_iterator filterIt = mParameterMap.find( "FILTER" ); |
|
| 390 |
if ( filterIt != mParameterMap.end() ) {
|
|
| 391 |
try {
|
|
| 392 |
QString errorMsg; |
|
| 393 |
if ( !filter.setContent( filterIt->second, true, &errorMsg ) ) |
|
| 394 |
{
|
|
| 395 |
QgsMSDebugMsg( "soap request parse error" ); |
|
| 396 |
QgsMSDebugMsg( "error message: " + errorMsg ); |
|
| 397 |
QgsMSDebugMsg( "the xml string was:" ); |
|
| 398 |
QgsMSDebugMsg( filterIt->second ); |
|
| 399 |
} |
|
| 400 |
else |
|
| 401 |
{
|
|
| 402 |
filterOk = true; |
|
| 403 |
} |
|
| 404 |
} catch(QgsMapServiceException& e ) {
|
|
| 405 |
filterOk = false; |
|
| 406 |
} |
|
| 407 |
} |
|
| 408 | ||
| 409 |
//read BBOX |
|
| 410 |
bool conversionSuccess; |
|
| 411 |
double minx, miny, maxx, maxy; |
|
| 412 |
bool bboxOk = false; |
|
| 413 |
std::map<QString, QString>::const_iterator bbIt = mParameterMap.find( "BBOX" ); |
|
| 414 |
if ( bbIt == mParameterMap.end() ) |
|
| 415 |
{
|
|
| 416 |
minx = 0; miny = 0; maxx = 0; maxy = 0; |
|
| 417 |
} |
|
| 418 |
else |
|
| 419 |
{
|
|
| 420 |
bboxOk = true; |
|
| 421 |
QString bbString = bbIt->second; |
|
| 422 |
minx = bbString.section( ",", 0, 0 ).toDouble( &conversionSuccess ); |
|
| 423 |
if ( !conversionSuccess ) {bboxOk = false;}
|
|
| 424 |
miny = bbString.section( ",", 1, 1 ).toDouble( &conversionSuccess ); |
|
| 425 |
if ( !conversionSuccess ) {bboxOk = false;}
|
|
| 426 |
maxx = bbString.section( ",", 2, 2 ).toDouble( &conversionSuccess ); |
|
| 427 |
if ( !conversionSuccess ) {bboxOk = false;}
|
|
| 428 |
maxy = bbString.section( ",", 3, 3 ).toDouble( &conversionSuccess ); |
|
| 429 |
if ( !conversionSuccess ) {bboxOk = false;}
|
|
| 430 |
} |
|
| 431 | ||
| 432 |
//read MAXFEATURES |
|
| 433 |
long maxFeat = layer->featureCount(); |
|
| 434 |
long featureCounter = 0; |
|
| 435 |
std::map<QString, QString>::const_iterator mfIt = mParameterMap.find( "MAXFEATURES" ); |
|
| 436 |
if ( mfIt != mParameterMap.end() ) |
|
| 437 |
{
|
|
| 438 |
QString mfString = mfIt->second; |
|
| 439 |
bool mfOk; |
|
| 440 |
maxFeat = mfString.toLong(&mfOk, 10); |
|
| 441 |
if ( !mfOk ) { maxFeat = layer->featureCount(); }
|
|
| 442 |
} |
|
| 443 | ||
| 444 |
//read PROPERTYNAME |
|
| 445 |
bool withGeom = true; |
|
| 446 |
QgsAttributeList attrIndexes = provider->attributeIndexes(); |
|
| 447 |
std::map<QString, QString>::const_iterator pnIt = mParameterMap.find( "PROPERTYNAME" ); |
|
| 448 |
if ( pnIt != mParameterMap.end() ) |
|
| 449 |
{
|
|
| 450 |
QStringList attrList = pnIt->second.split( "," ); |
|
| 451 |
if ( attrList.size() > 0 ) |
|
| 452 |
{
|
|
| 453 |
withGeom = false; |
|
| 454 |
QStringList::const_iterator alstIt; |
|
| 455 |
QList<int> idxList; |
|
| 456 |
QMap<QString, int> fieldMap = provider->fieldNameMap(); |
|
| 457 |
QMap<QString, int>::const_iterator fieldIt; |
|
| 458 |
QString fieldName; |
|
| 459 |
for ( alstIt = attrList.begin(); alstIt != attrList.end(); ++alstIt ) |
|
| 460 |
{
|
|
| 461 |
fieldName = *alstIt; |
|
| 462 |
fieldIt = fieldMap.find( fieldName ); |
|
| 463 |
if ( fieldIt != fieldMap.end() ) |
|
| 464 |
{
|
|
| 465 |
idxList.append( fieldIt.value() ); |
|
| 466 |
} |
|
| 467 |
else if ( fieldName == "geometry" ) |
|
| 468 |
{
|
|
| 469 |
withGeom = true; |
|
| 470 |
} |
|
| 471 |
} |
|
| 472 |
if ( idxList.size() > 0 || withGeom) |
|
| 473 |
{
|
|
| 474 |
attrIndexes = idxList; |
|
| 475 |
} |
|
| 476 |
else |
|
| 477 |
{
|
|
| 478 |
withGeom = true; |
|
| 479 |
} |
|
| 480 |
} |
|
| 481 |
} |
|
| 482 | ||
| 483 |
QList<QgsFeature> featureList; |
|
| 484 |
if ( fidOk ) |
|
| 485 |
{
|
|
| 486 |
provider->featureAtId( fid.toInt(), feature, withGeom, attrIndexes ); |
|
| 487 |
featureList.append(feature); |
|
| 488 |
} |
|
| 489 |
else if ( filterOk ) |
|
| 490 |
{
|
|
| 491 |
provider->select( attrIndexes, searchRect, withGeom, true ); |
|
| 492 |
try {
|
|
| 493 |
QgsFilter* mFilter = QgsFilter::createFilterFromXml( filter.firstChild().toElement().firstChild().toElement(), layer ); |
|
| 494 |
while ( provider->nextFeature( feature ) && featureCounter < maxFeat) |
|
| 495 |
{
|
|
| 496 |
if ( mFilter ) |
|
| 497 |
{
|
|
| 498 |
if ( mFilter->evaluate( feature ) ) |
|
| 499 |
{
|
|
| 500 |
featureList.append(feature); |
|
| 501 |
++featureCounter; |
|
| 502 |
} |
|
| 503 |
} |
|
| 504 |
else |
|
| 505 |
{
|
|
| 506 |
featureList.append(feature); |
|
| 507 |
++featureCounter; |
|
| 508 |
} |
|
| 509 |
} |
|
| 510 |
delete mFilter; |
|
| 511 |
} catch(QgsMapServiceException& e ) {
|
|
| 512 |
while ( provider->nextFeature( feature ) && featureCounter < maxFeat) |
|
| 513 |
{
|
|
| 514 |
featureList.append(feature); |
|
| 515 |
++featureCounter; |
|
| 516 |
} |
|
| 517 |
} |
|
| 518 |
} |
|
| 519 |
else |
|
| 520 |
{
|
|
| 521 |
if ( bboxOk ) |
|
| 522 |
searchRect.set( minx, miny, maxx, maxy ); |
|
| 523 |
provider->select( attrIndexes, searchRect, withGeom, true ); |
|
| 524 |
while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) |
|
| 525 |
{
|
|
| 526 |
featureList.append(feature); |
|
| 527 |
++featureCounter; |
|
| 528 |
} |
|
| 529 |
} |
|
| 530 |
QList<QgsFeature>::const_iterator featureIt = featureList.constBegin(); |
|
| 531 | ||
| 532 |
QString fcString; |
|
| 533 |
if ( format == "GeoJSON" ) |
|
| 534 |
{
|
|
| 535 |
featureCounter = 0; |
|
| 536 | ||
| 537 |
fcString = "{\"type\": \"FeatureCollection\",\n";
|
|
| 538 |
fcString += " \"features\": [\n"; |
|
| 539 |
result = fcString.toUtf8(); |
|
| 540 |
request.startGetFeatureResponse(&result, format); |
|
| 541 |
fcString = ""; |
|
| 542 | ||
| 543 |
for ( ; featureIt != featureList.constEnd(); ++featureIt ) |
|
| 544 |
{
|
|
| 545 |
feature = *featureIt; |
|
| 546 |
if (featureCounter == 0) |
|
| 547 |
fcString += " {\"type\": \"Feature\",\n";
|
|
| 548 |
else |
|
| 549 |
fcString += " ,{\"type\": \"Feature\",\n";
|
|
| 550 | ||
| 551 |
fcString += " \"id\": "; |
|
| 552 |
fcString += QString::number( feature.id() ); |
|
| 553 |
fcString += ",\n"; |
|
| 554 | ||
| 555 |
QgsGeometry* geom = feature.geometry(); |
|
| 556 |
if ( geom && withGeom ) |
|
| 557 |
{
|
|
| 558 |
fcString += " \"geometry\": "; |
|
| 559 |
fcString += geom->exportToGeoJSON(); |
|
| 560 |
fcString += ",\n"; |
|
| 561 |
} |
|
| 562 | ||
| 563 |
fcString += " \"properties\": {\n";
|
|
| 564 | ||
| 565 |
//read all attribute values from the feature |
|
| 566 |
featureAttributes = feature.attributeMap(); |
|
| 567 |
int attributeCounter = 0; |
|
| 568 |
for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it ) |
|
| 569 |
{
|
|
| 570 | ||
| 571 |
QString attributeName = fields[it.key()].name(); |
|
| 572 |
//skip attribute if it has edit type 'hidden' |
|
| 573 |
if ( layerHiddenAttributes.contains( attributeName ) ) |
|
| 574 |
{
|
|
| 575 |
continue; |
|
| 576 |
} |
|
| 577 | ||
| 578 |
//check if the attribute name should be replaced with an alias |
|
| 579 |
QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() ); |
|
| 580 |
if ( aliasIt != layerAliasInfo.constEnd() ) |
|
| 581 |
{
|
|
| 582 |
attributeName = aliasIt.value(); |
|
| 583 |
} |
|
| 584 | ||
| 585 |
if (attributeCounter == 0) |
|
| 586 |
fcString += " \""; |
|
| 587 |
else |
|
| 588 |
fcString += " ,\""; |
|
| 589 |
fcString += attributeName; |
|
| 590 |
fcString += "\": "; |
|
| 591 |
if (it->type() == 6 || it->type() == 2) |
|
| 592 |
{
|
|
| 593 |
fcString += it->toString(); |
|
| 594 |
} |
|
| 595 |
else |
|
| 596 |
{
|
|
| 597 |
fcString += "\""; |
|
| 598 |
fcString += it->toString().replace( QString( "\"" ), QString( "\\\"" ) ); |
|
| 599 |
fcString += "\""; |
|
| 600 |
} |
|
| 601 |
fcString += "\n"; |
|
| 602 |
++attributeCounter; |
|
| 603 |
} |
|
| 604 | ||
| 605 |
fcString += " }\n"; |
|
| 606 | ||
| 607 |
fcString += " }"; |
|
| 608 |
fcString += "\n"; |
|
| 609 | ||
| 610 |
result = fcString.toUtf8(); |
|
| 611 |
request.sendGetFeatureResponse( &result ); |
|
| 612 |
fcString = ""; |
|
| 613 | ||
| 614 |
++featureCounter; |
|
| 615 |
} |
|
| 616 |
fcString = ""; |
|
| 617 |
fcString += " ]\n"; |
|
| 618 |
fcString += "}"; |
|
| 619 | ||
| 620 |
result = fcString.toUtf8(); |
|
| 621 |
request.endGetFeatureResponse( &result ); |
|
| 622 |
fcString = ""; |
|
| 623 |
} |
|
| 624 |
else |
|
| 625 |
{
|
|
| 626 |
QDomDocument gmlDoc; |
|
| 627 |
//wfs:FeatureCollection |
|
| 628 |
fcString = "<wfs:FeatureCollection"; |
|
| 629 |
fcString += " xmlns=\"http://www.opengis.net/wfs\""; |
|
| 630 |
fcString += " xmlns:wfs=\"http://www.opengis.net/wfs\""; |
|
| 631 |
fcString += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""; |
|
| 632 |
fcString += " xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd\""; |
|
| 633 |
fcString += " xmlns:ogc=\"http://www.opengis.net/ogc\""; |
|
| 634 |
fcString += " xmlns:gml=\"http://www.opengis.net/gml\""; |
|
| 635 |
fcString += " xmlns:ows=\"http://www.opengis.net/ows\""; |
|
| 636 |
fcString += " xmlns:xlink=\"http://www.w3.org/1999/xlink\""; |
|
| 637 |
fcString += " xmlns:qgs=\"http://www.qgis.org/gml\""; |
|
| 638 |
fcString += ">"; |
|
| 639 |
result = fcString.toUtf8(); |
|
| 640 |
request.startGetFeatureResponse(&result, format); |
|
| 641 |
fcString = ""; |
|
| 642 | ||
| 643 |
for ( ; featureIt != featureList.constEnd(); ++featureIt ) |
|
| 644 |
{
|
|
| 645 |
feature = *featureIt; |
|
| 646 |
//gml:FeatureMember |
|
| 647 |
QDomElement featureElement = gmlDoc.createElement( "gml:featureMember"/*wfs:FeatureMember*/ ); |
|
| 648 |
gmlDoc.appendChild(featureElement); |
|
| 649 | ||
| 650 |
//qgs:%TYPENAME% |
|
| 651 |
QDomElement typeNameElement = gmlDoc.createElement( "qgs:"+typeName.replace( QString(" "), QString("_") )/*qgs:%TYPENAME%*/ );
|
|
| 652 |
typeNameElement.setAttribute( "fid", QString::number( feature.id() ) ); |
|
| 653 |
featureElement.appendChild(typeNameElement); |
|
| 654 | ||
| 655 |
if ( withGeom ) |
|
| 656 |
{
|
|
| 657 |
//add geometry column (as gml) |
|
| 658 |
QDomElement geomElem = gmlDoc.createElement( "qgs:geometry" ); |
|
| 659 |
QDomElement gmlElem = createGeometryElem( feature.geometry(), gmlDoc ); |
|
| 660 |
if ( !gmlElem.isNull() ) |
|
| 661 |
{
|
|
| 662 |
QgsCoordinateReferenceSystem layerCrs = layer->crs(); |
|
| 663 |
if ( layerCrs.isValid() ) |
|
| 664 |
{
|
|
| 665 |
gmlElem.setAttribute( "srsName", layerCrs.authid() ); |
|
| 666 |
} |
|
| 667 |
geomElem.appendChild( gmlElem ); |
|
| 668 |
typeNameElement.appendChild( geomElem ); |
|
| 669 |
} |
|
| 670 |
} |
|
| 671 | ||
| 672 |
//read all attribute values from the feature |
|
| 673 |
featureAttributes = feature.attributeMap(); |
|
| 674 |
for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it ) |
|
| 675 |
{
|
|
| 676 | ||
| 677 |
QString attributeName = fields[it.key()].name(); |
|
| 678 |
//skip attribute if it has edit type 'hidden' |
|
| 679 |
if ( layerHiddenAttributes.contains( attributeName ) ) |
|
| 680 |
{
|
|
| 681 |
continue; |
|
| 682 |
} |
|
| 683 | ||
| 684 |
//check if the attribute name should be replaced with an alias |
|
| 685 |
QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() ); |
|
| 686 |
if ( aliasIt != layerAliasInfo.constEnd() ) |
|
| 687 |
{
|
|
| 688 |
attributeName = aliasIt.value(); |
|
| 689 |
} |
|
| 690 |
|
|
| 691 |
QDomElement fieldElem = gmlDoc.createElement( "qgs:"+attributeName ); |
|
| 692 |
QDomText fieldText = gmlDoc.createTextNode( it->toString() ); |
|
| 693 |
fieldElem.appendChild( fieldText ); |
|
| 694 |
typeNameElement.appendChild( fieldElem ); |
|
| 695 |
} |
|
| 696 |
result = gmlDoc.toByteArray(); |
|
| 697 |
request.sendGetFeatureResponse( &result ); |
|
| 698 |
gmlDoc.removeChild(featureElement); |
|
| 699 |
} |
|
| 700 | ||
| 701 |
fcString = "</wfs:FeatureCollection>"; |
|
| 702 |
result = fcString.toUtf8(); |
|
| 703 |
request.endGetFeatureResponse( &result ); |
|
| 704 |
fcString = ""; |
|
| 705 |
} |
|
| 706 | ||
| 707 |
} |
|
| 708 |
else |
|
| 709 |
{
|
|
| 710 |
return 2; |
|
| 711 |
} |
|
| 712 |
return 0; |
|
| 713 |
} |
|
| 714 | ||
| 715 |
QDomElement QgsWFSServer::createGeometryElem( QgsGeometry* geom, QDomDocument& doc ) /*const*/ |
|
| 716 |
{
|
|
| 717 |
if ( !geom ) |
|
| 718 |
{
|
|
| 719 |
return QDomElement(); |
|
| 720 |
} |
|
| 721 | ||
| 722 | ||
| 723 |
QDomElement geomElement; |
|
| 724 |
QString geomTypeName; |
|
| 725 |
QGis::WkbType wkbType = geom->wkbType(); |
|
| 726 |
switch ( wkbType ) |
|
| 727 |
{
|
|
| 728 |
case QGis::WKBPoint: |
|
| 729 |
case QGis::WKBPoint25D: |
|
| 730 |
geomElement = createPointElem( geom, doc ); |
|
| 731 |
break; |
|
| 732 |
case QGis::WKBMultiPoint: |
|
| 733 |
case QGis::WKBMultiPoint25D: |
|
| 734 |
geomElement = createMultiPointElem( geom, doc ); |
|
| 735 |
break; |
|
| 736 |
case QGis::WKBLineString: |
|
| 737 |
case QGis::WKBLineString25D: |
|
| 738 |
geomElement = createLineStringElem( geom, doc ); |
|
| 739 |
break; |
|
| 740 |
case QGis::WKBMultiLineString: |
|
| 741 |
case QGis::WKBMultiLineString25D: |
|
| 742 |
geomElement = createMultiLineStringElem( geom, doc ); |
|
| 743 |
break; |
|
| 744 |
case QGis::WKBPolygon: |
|
| 745 |
case QGis::WKBPolygon25D: |
|
| 746 |
geomElement = createPolygonElem( geom, doc ); |
|
| 747 |
break; |
|
| 748 |
case QGis::WKBMultiPolygon: |
|
| 749 |
case QGis::WKBMultiPolygon25D: |
|
| 750 |
geomElement = createMultiPolygonElem( geom, doc ); |
|
| 751 |
break; |
|
| 752 |
default: |
|
| 753 |
return QDomElement(); |
|
| 754 |
} |
|
| 755 |
return geomElement; |
|
| 756 |
} |
|
| 757 | ||
| 758 |
QDomElement QgsWFSServer::createLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const |
|
| 759 |
{
|
|
| 760 |
if ( !geom ) |
|
| 761 |
{
|
|
| 762 |
return QDomElement(); |
|
| 763 |
} |
|
| 764 | ||
| 765 |
QDomElement lineStringElem = doc.createElement( "gml:LineString" ); |
|
| 766 |
QDomElement coordElem = createCoordinateElem( geom->asPolyline(), doc ); |
|
| 767 |
lineStringElem.appendChild( coordElem ); |
|
| 768 |
return lineStringElem; |
|
| 769 |
} |
|
| 770 | ||
| 771 |
QDomElement QgsWFSServer::createMultiLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const |
|
| 772 |
{
|
|
| 773 |
if ( !geom ) |
|
| 774 |
{
|
|
| 775 |
return QDomElement(); |
|
| 776 |
} |
|
| 777 | ||
| 778 |
QDomElement multiLineStringElem = doc.createElement( "gml:MultiLineString" ); |
|
| 779 |
QgsMultiPolyline multiline = geom->asMultiPolyline(); |
|
| 780 | ||
| 781 |
QgsMultiPolyline::const_iterator multiLineIt = multiline.constBegin(); |
|
| 782 |
for ( ; multiLineIt != multiline.constEnd(); ++multiLineIt ) |
|
| 783 |
{
|
|
| 784 |
QgsGeometry* lineGeom = QgsGeometry::fromPolyline( *multiLineIt ); |
|
| 785 |
if ( lineGeom ) |
|
| 786 |
{
|
|