Skip to content
Permalink
Browse files

Always create valid GeoJSON (both geometry and properties members

are required
  • Loading branch information
nyalldawson committed May 7, 2016
1 parent 3681e2c commit 55793a4534013b2137d26da09a968910e3b69808
Showing with 48 additions and 36 deletions.
  1. +33 −33 src/core/qgsjsonutils.cpp
  2. +15 −3 tests/src/python/test_qgsjsonutils.py
@@ -45,9 +45,34 @@ QgsVectorLayer *QgsJSONExporter::vectorLayer() const
QString QgsJSONExporter::exportFeature( const QgsFeature& feature, const QVariantMap& extraProperties,
const QVariant& id ) const
{
//first step is to build up the properties list
QString properties;
QString s = "{\n \"type\":\"Feature\",\n";

// ID
s += QString( " \"id\":%1,\n" ).arg( !id.isValid() ? QString::number( feature.id() ) : QgsJSONUtils::encodeValue( id ) );

const QgsGeometry* geom = feature.constGeometry();
if ( geom && !geom->isEmpty() && mIncludeGeometry )
{
QgsRectangle box = geom->boundingBox();

if ( QgsWKBTypes::flatType( geom->geometry()->wkbType() ) != QgsWKBTypes::Point )
{
s += QString( " \"bbox\":[%1, %2, %3, %4],\n" ).arg( qgsDoubleToString( box.xMinimum(), mPrecision ),
qgsDoubleToString( box.yMinimum(), mPrecision ),
qgsDoubleToString( box.xMaximum(), mPrecision ),
qgsDoubleToString( box.yMaximum(), mPrecision ) );
}
s += " \"geometry\":\n ";
s += geom->exportToGeoJSON( mPrecision );
s += ",\n";
}
else
{
s += " \"geometry\":null,\n";
}

// build up properties element
QString properties;
int attributeCounter = 0;
if ( mIncludeAttributes || !extraProperties.isEmpty() )
{
@@ -124,40 +149,15 @@ QString QgsJSONExporter::exportFeature( const QgsFeature& feature, const QVarian

bool hasProperties = attributeCounter > 0;

QString s = "{\n \"type\":\"Feature\",\n";

// ID
s += QString( " \"id\":%1" ).arg( !id.isValid() ? QString::number( feature.id() ) : QgsJSONUtils::encodeValue( id ) );

if ( hasProperties || mIncludeGeometry )
s += ",\n";
else
s += '\n';

const QgsGeometry* geom = feature.constGeometry();
if ( geom && !geom->isEmpty() && mIncludeGeometry )
{
QgsRectangle box = geom->boundingBox();

if ( QgsWKBTypes::flatType( geom->geometry()->wkbType() ) != QgsWKBTypes::Point )
{
s += QString( " \"bbox\":[%1, %2, %3, %4],\n" ).arg( qgsDoubleToString( box.xMinimum(), mPrecision ),
qgsDoubleToString( box.yMinimum(), mPrecision ),
qgsDoubleToString( box.xMaximum(), mPrecision ),
qgsDoubleToString( box.yMaximum(), mPrecision ) );
}
s += " \"geometry\":\n ";
s += geom->exportToGeoJSON( mPrecision );
if ( hasProperties )
s += ",\n";
else
s += '\n';
}

s += " \"properties\":";
if ( hasProperties )
{
//read all attribute values from the feature
s += " \"properties\":{\n" + properties + "\n }\n";
s += "{\n" + properties + "\n }\n";
}
else
{
s += "null\n";
}

s += '}';
@@ -256,7 +256,8 @@ def testJSONExporter(self):
"type":"Feature",
"id":5,
"geometry":
{"type": "Point", "coordinates": [5, 6]}
{"type": "Point", "coordinates": [5, 6]},
"properties":null
}"""
self.assertEqual(exporter.exportFeature(feature), expected)

@@ -286,6 +287,7 @@ def testJSONExporter(self):
expected = """{
"type":"Feature",
"id":5,
"geometry":null,
"properties":{
"name":"Valsier Peninsula",
"cost":6.8,
@@ -304,14 +306,17 @@ def testJSONExporter(self):
"type":"Feature",
"id":5,
"geometry":
{"type": "Point", "coordinates": [5, 6]}
{"type": "Point", "coordinates": [5, 6]},
"properties":null
}"""
self.assertEqual(exporter.exportFeature(feature), expected)

exporter.setIncludeGeometry(False)
expected = """{
"type":"Feature",
"id":5
"id":5,
"geometry":null,
"properties":null
}"""
self.assertEqual(exporter.exportFeature(feature), expected)
exporter.setIncludeAttributes(True)
@@ -320,6 +325,7 @@ def testJSONExporter(self):
expected = """{
"type":"Feature",
"id":29,
"geometry":null,
"properties":{
"name":"Valsier Peninsula",
"cost":6.8,
@@ -332,6 +338,7 @@ def testJSONExporter(self):
expected = """{
"type":"Feature",
"id":5,
"geometry":null,
"properties":{
"name":"Valsier Peninsula",
"cost":6.8,
@@ -346,6 +353,7 @@ def testJSONExporter(self):
expected = """{
"type":"Feature",
"id":5,
"geometry":null,
"properties":{
"extra":"val1",
"extra2":{"nested_map":5,
@@ -408,6 +416,7 @@ def testExportFeatureRelations(self):
expected = """{
"type":"Feature",
"id":0,
"geometry":null,
"properties":{
"fldtxt":"test1",
"fldint":67,
@@ -425,6 +434,7 @@ def testExportFeatureRelations(self):
expected = """{
"type":"Feature",
"id":0,
"geometry":null,
"properties":{
"fldtxt":"test2",
"fldint":68,
@@ -443,6 +453,7 @@ def testExportFeatureRelations(self):
expected = """{
"type":"Feature",
"id":0,
"geometry":null,
"properties":{
"fldtxt":"test2",
"fldint":68,
@@ -458,6 +469,7 @@ def testExportFeatureRelations(self):
expected = """{
"type":"Feature",
"id":0,
"geometry":null,
"properties":{
"fldtxt":"test2",
"fldint":68,

0 comments on commit 55793a4

Please sign in to comment.
You can’t perform that action at this time.