[PATCH 10/10] Initialise default styles just once; display an icon for points

John Zaitseff J.Zaitseff at zap.org.au
Tue Aug 27 11:55:12 BST 2019


Previously, default styles would be constructed for every placemark.  Now
create the default styles just once, then copy as required.

In addition, now display an icon for placemarks with points, but not for
lines or polygons.  Currently, the icon cannot be styled with the
Simplestyle properties "marker-size", "marker-symbol" or "marker-color":
this is yet to be implemented.
---
 src/plugins/runner/json/JsonParser.cpp | 543 +++++++++++++------------
 src/plugins/runner/json/JsonParser.h   |  13 +-
 2 files changed, 304 insertions(+), 252 deletions(-)

diff --git a/src/plugins/runner/json/JsonParser.cpp b/src/plugins/runner/json/JsonParser.cpp
index c89c592bf..12ec4461e 100644
--- a/src/plugins/runner/json/JsonParser.cpp
+++ b/src/plugins/runner/json/JsonParser.cpp
@@ -7,6 +7,9 @@
     ((https://github.com/mapbox/simplestyle-spec).  Attributes are also
     stored as OSM tags as required.
 
+    TODO: Handle the Simplestyle "marker-size", "marker-symbol" and
+    "marker-color" correctly.
+
     This program is free software licensed under the GNU LGPL. You can
     find a copy of this license in LICENSE.txt in the top directory of
     the source code.
@@ -22,6 +25,7 @@
 #include "GeoDataLinearRing.h"
 #include "GeoDataPoint.h"
 #include "GeoDataMultiGeometry.h"
+#include "MarbleDirs.h"
 #include "MarbleDebug.h"
 #include "StyleBuilder.h"
 #include "osm/OsmPlacemarkData.h"
@@ -30,26 +34,65 @@
 #include <QJsonDocument>
 #include <QJsonArray>
 #include <QJsonObject>
-#include <QApplication>
-#include <QPalette>
 #include <QColor>
 
 #include "GeoDataStyle.h"
 #include "GeoDataIconStyle.h"
-#include "GeoDataLabelStyle.h"
 #include "GeoDataLineStyle.h"
 #include "GeoDataPolyStyle.h"
+#include "GeoDataLabelStyle.h"
 
 
 namespace Marble {
 
 JsonParser::JsonParser() : m_document( nullptr )
 {
+    // Get the default styles set by Marble
+
+    GeoDataPlacemark placemark;
+    GeoDataStyle::Ptr style(new GeoDataStyle(*(placemark.style())));
+    m_iconStylePoints = new GeoDataIconStyle(style->iconStyle());
+    m_iconStyleOther = new GeoDataIconStyle(style->iconStyle());
+    m_lineStyle = new GeoDataLineStyle(style->lineStyle());
+    m_polyStyle = new GeoDataPolyStyle(style->polyStyle());
+    m_labelStyle = new GeoDataLabelStyle(style->labelStyle());
+
+    // Set default styles for GeoJSON objects using Simplestyle specification 1.1.0
+
+    // Set "marker-color": "#7e7e7e" and "marker-size": "medium"
+    m_iconStylePoints->setColor(QColor("#ff7e7e7e"));
+    m_iconStylePoints->setIconPath(MarbleDirs::path(QStringLiteral("svg/dot-circle-regular.svg")));
+    m_iconStylePoints->setSize(QSize(22,22), Qt::KeepAspectRatio);
+
+    m_iconStyleOther->setIconPath(nullptr);
+    m_iconStyleOther->setColor(QColor("#ff7e7e7e"));
+
+    // Set "stroke": "#555555", "stroke-opacity": 1.0 and "stroke-width": 2 (increased to 2.5 due
+    // to problems with antialiased lines disappearing on drawn maps
+    m_lineStyle->setColor(QColor("#ff555555"));
+    m_lineStyle->setWidth(2.5);
+
+    // Set "fill": "#555555" and "fill-opacity": 0.6
+    m_polyStyle->setColor(QColor("#99555555"));
+
+    // Set visual properties not part of the Simplestyle spec
+
+    m_labelStyle->setColor(QColor("#ff000000"));
+    m_labelStyle->setGlow(true);
+
+    m_polyStyle->setFill(true);
+    m_polyStyle->setOutline(true);
 }
 
 JsonParser::~JsonParser()
 {
     delete m_document;
+
+    delete m_iconStylePoints;
+    delete m_iconStyleOther;
+    delete m_lineStyle;
+    delete m_polyStyle;
+    delete m_labelStyle;
 }
 
 GeoDataDocument *JsonParser::releaseDocument()
@@ -125,9 +168,10 @@ bool JsonParser::parseGeoJsonTopLevel( const QJsonObject& jsonObject )
         // associated properties.  Note that only Feature objects can have recognised properties.
 
         QVector<GeoDataGeometry*> geometryList;     // Populated by parseGeoJsonSubLevel()
+        bool hasPoints = false;                     // Populated by parseGeoJsonSubLevel()
 
         if (! parseGeoJsonSubLevel( jsonObject.value(QStringLiteral("geometry")).toObject(),
-                geometryList )) {
+                geometryList, hasPoints )) {
             return false;
         }
 
@@ -153,183 +197,178 @@ bool JsonParser::parseGeoJsonTopLevel( const QJsonObject& jsonObject )
             placemark->setGeometry(geom);
         }
 
-	// Set default style properties using the Simplestyle specification 1.1.0
+        // Create copies of the default styles
 
-	GeoDataStyle::Ptr style(new GeoDataStyle(*(placemark->style())));
-	GeoDataIconStyle iconStyle = style->iconStyle();
-	GeoDataLabelStyle labelStyle = style->labelStyle();
-	GeoDataLineStyle lineStyle = style->lineStyle();
-	GeoDataPolyStyle polyStyle = style->polyStyle();
+        GeoDataStyle::Ptr style(new GeoDataStyle(*(placemark->style())));
+        GeoDataIconStyle iconStyle = hasPoints ? *m_iconStylePoints : *m_iconStyleOther;
+        GeoDataLineStyle lineStyle = *m_lineStyle;
+        GeoDataPolyStyle polyStyle = *m_polyStyle;
 
-	// TODO: Handle "marker-size": "medium" and "marker-symbol": ""
-	iconStyle.setColor(QColor("#ff7e7e7e"));  // "marker-color": "#7e7e7e"
+        // Parse any associated properties
+
+        const QJsonObject propertiesObject = jsonObject.value(QStringLiteral("properties")).toObject();
+        QJsonObject::ConstIterator iter = propertiesObject.begin();
+        const QJsonObject::ConstIterator end = propertiesObject.end();
+
+        OsmPlacemarkData osmData;
 
-	lineStyle.setColor(QColor("#ff555555"));  // "stroke": "#555555" and "stroke-opacity": 1.0
-	lineStyle.setWidth(2.5);		  // "stroke-width": 2 (increased to 2.5 due to
-						  // problems with antialiased lines disappearing
+        for ( ; iter != end; ++iter) {
+            // Pass the value through QVariant to also get booleans and numbers
+            const QString propertyValue = iter.value().toVariant().toString();
+            const QString propertyKey = iter.key();
 
-	polyStyle.setColor(QColor("#99555555"));  // "fill": "#555555" and "fill-opacity": 0.6
+            if (iter.value().isObject() || iter.value().isArray()) {
+                qDebug() << "Skipping unsupported JSON property containing an object or array:" << propertyKey;
+                continue;
+            }
 
-	// Set visual properties not part of the Simplestyle spec
+            if (propertyKey == QStringLiteral("name")) {
+                // The "name" property is not defined in the Simplestyle specification, but is used
+                // extensively in the wild.  Treat "name" and "title" essentially the same for the
+                // purposes of placemarks (although osmData tags will preserve the distinction).
+
+                placemark->setName(propertyValue);
+                osmData.addTag(propertyKey, propertyValue);
+
+            } else if (propertyKey == QStringLiteral("title")) {
+                placemark->setName(propertyValue);
+                osmData.addTag(propertyKey, propertyValue);
+
+            } else if (propertyKey == QStringLiteral("description")) {
+                placemark->setDescription(propertyValue);
+                osmData.addTag(propertyKey, propertyValue);
+
+            } else if (propertyKey == QStringLiteral("marker-size")) {
+                // TODO: Implement marker-size handling
+                if (propertyValue == QStringLiteral("")) {
+                    // Use the default value
+                    ;
+                } else {
+                    //qDebug() << "Ignoring unimplemented marker-size property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("marker-symbol")) {
+                // TODO: Implement marker-symbol handling
+                if (propertyValue == QStringLiteral("")) {
+                    // Use the default value
+                    ;
+                } else {
+                    //qDebug() << "Ignoring unimplemented marker-symbol property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("marker-color")) {
+                // Even though the Simplestyle spec allows colors to omit the leading "#", this
+                // implementation assumes it is always present, as this then allows named colors
+                // understood by QColor as an extension
+                QColor color = QColor(propertyValue);
+                if (color.isValid()) {
+                    iconStyle.setColor(color);  // Currently ignored by Marble
+                } else {
+                    qDebug() << "Ignoring invalid marker-color property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("stroke")) {
+                QColor color = QColor(propertyValue);   // Assume leading "#" is present
+                if (color.isValid()) {
+                    color.setAlpha(lineStyle.color().alpha());
+                    lineStyle.setColor(color);
+                } else {
+                    qDebug() << "Ignoring invalid stroke property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("stroke-opacity")) {
+                bool ok;
+                float opacity = propertyValue.toFloat(&ok);
+                if (ok && opacity >= 0.0 && opacity <= 1.0) {
+                    QColor color = lineStyle.color();
+                    color.setAlphaF(opacity);
+                    lineStyle.setColor(color);
+                } else {
+                    qDebug() << "Ignoring invalid stroke-opacity property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("stroke-width")) {
+                bool ok;
+                float width = propertyValue.toFloat(&ok);
+                if (ok && width >= 0.0) {
+                    lineStyle.setWidth(width);
+                } else {
+                    qDebug() << "Ignoring invalid stroke-width property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("fill")) {
+                QColor color = QColor(propertyValue);   // Assume leading "#" is present
+                if (color.isValid()) {
+                    color.setAlpha(polyStyle.color().alpha());
+                    polyStyle.setColor(color);
+                } else {
+                    qDebug() << "Ignoring invalid fill property:" << propertyValue;
+                }
+
+            } else if (propertyKey == QStringLiteral("fill-opacity")) {
+                bool ok;
+                float opacity = propertyValue.toFloat(&ok);
+                if (ok && opacity >= 0.0 && opacity <= 1.0) {
+                    QColor color = polyStyle.color();
+                    color.setAlphaF(opacity);
+                    polyStyle.setColor(color);
+                } else {
+                    qDebug() << "Ignoring invalid fill-opacity property:" << propertyValue;
+                }
+
+            } else {
+                // Property is not defined by the Simplestyle spec
+                osmData.addTag(propertyKey, propertyValue);
+            }
+        }
 
-	labelStyle.setColor(QApplication::palette().brightText().color());
-	labelStyle.setGlow(true);
+        style->setIconStyle(iconStyle);
+        style->setLineStyle(lineStyle);
+        style->setPolyStyle(polyStyle);
+        style->setLabelStyle(*m_labelStyle);
+        placemark->setStyle(style);
 
-	polyStyle.setFill(true);
-	polyStyle.setOutline(true);
+        placemark->setOsmData(osmData);
+        placemark->setVisible(true);
 
-        // Parse any associated properties
+        const GeoDataPlacemark::GeoDataVisualCategory category =
+            StyleBuilder::determineVisualCategory(osmData);
+        if (category != GeoDataPlacemark::None) {
+            placemark->setVisualCategory(category);
+        }
 
-        const QJsonObject propertiesObject = jsonObject.value(QStringLiteral("properties")).toObject();
-        QJsonObject::ConstIterator iter = propertiesObject.begin();
-	const QJsonObject::ConstIterator end = propertiesObject.end();
-
-	OsmPlacemarkData osmData;
-
-	for ( ; iter != end; ++iter) {
-	    // Pass the value through QVariant to also get booleans and numbers
-	    const QString propertyValue = iter.value().toVariant().toString();
-	    const QString propertyKey = iter.key();
-
-	    if (iter.value().isObject() || iter.value().isArray()) {
-		qDebug() << "Skipping unsupported JSON property containing an object or array:" << propertyKey;
-		continue;
-	    }
-
-	    if (propertyKey == QStringLiteral("name")) {
-		// The "name" property is not defined in the Simplestyle specification, but is used
-		// extensively in the wild.  Treat "name" and "title" essentially the same for the
-		// purposes of placemarks (although osmData tags will preserve the distinction).
-
-		placemark->setName(propertyValue);
-		osmData.addTag(propertyKey, propertyValue);
-
-	    } else if (propertyKey == QStringLiteral("title")) {
-		placemark->setName(propertyValue);
-		osmData.addTag(propertyKey, propertyValue);
-
-	    } else if (propertyKey == QStringLiteral("description")) {
-		placemark->setDescription(propertyValue);
-		osmData.addTag(propertyKey, propertyValue);
-
-	    } else if (propertyKey == QStringLiteral("marker-size")) {
-		// TODO: Implement marker-size handling
-
-	    } else if (propertyKey == QStringLiteral("marker-symbol")) {
-		// TODO: Implement marker-symbol handling
-
-	    } else if (propertyKey == QStringLiteral("marker-color")) {
-		// Even though the Simplestyle spec allows colors to omit the leading "#", this
-		// implementation assumes it is always present, as this then allows named colors
-		// understood by QColor as an extension
-		QColor color = QColor(propertyValue);
-		if (color.isValid()) {
-		    iconStyle.setColor(color);
-		} else {
-		    qDebug() << "Ignoring invalid marker-color property:" << propertyValue;
-		}
-
-	    } else if (propertyKey == QStringLiteral("stroke")) {
-		QColor color = QColor(propertyValue);	// Assume leading "#" is present
-		if (color.isValid()) {
-		    color.setAlpha(lineStyle.color().alpha());
-		    lineStyle.setColor(color);
-		} else {
-		    qDebug() << "Ignoring invalid stroke property:" << propertyValue;
-		}
-
-	    } else if (propertyKey == QStringLiteral("stroke-opacity")) {
-		bool ok;
-		float opacity = propertyValue.toFloat(&ok);
-		if (ok && opacity >= 0.0 && opacity <= 1.0) {
-		    QColor color = lineStyle.color();
-		    color.setAlphaF(opacity);
-		    lineStyle.setColor(color);
-		} else {
-		    qDebug() << "Ignoring invalid stroke-opacity property:" << propertyValue;
-		}
-
-	    } else if (propertyKey == QStringLiteral("stroke-width")) {
-		bool ok;
-		float width = propertyValue.toFloat(&ok);
-		if (ok && width >= 0.0) {
-		    lineStyle.setWidth(width);
-		} else {
-		    qDebug() << "Ignoring invalid stroke-width property:" << propertyValue;
-		}
-
-	    } else if (propertyKey == QStringLiteral("fill")) {
-		QColor color = QColor(propertyValue);	// Assume leading "#" is present
-		if (color.isValid()) {
-		    color.setAlpha(polyStyle.color().alpha());
-		    polyStyle.setColor(color);
-		} else {
-		    qDebug() << "Ignoring invalid fill property:" << propertyValue;
-		}
-
-	    } else if (propertyKey == QStringLiteral("fill-opacity")) {
-		bool ok;
-		float opacity = propertyValue.toFloat(&ok);
-		if (ok && opacity >= 0.0 && opacity <= 1.0) {
-		    QColor color = polyStyle.color();
-		    color.setAlphaF(opacity);
-		    polyStyle.setColor(color);
-		} else {
-		    qDebug() << "Ignoring invalid fill-opacity property:" << propertyValue;
-		}
-
-	    } else {
-		// Property is not defined by the Simplestyle spec
-		osmData.addTag(propertyKey, propertyValue);
-	    }
-	}
-
-	style->setIconStyle(iconStyle);
-	style->setLineStyle(lineStyle);
-	style->setPolyStyle(polyStyle);
-	placemark->setStyle(style);
-
-	placemark->setOsmData(osmData);
-	placemark->setVisible(true);
-
-	const GeoDataPlacemark::GeoDataVisualCategory category =
-	    StyleBuilder::determineVisualCategory(osmData);
-	if (category != GeoDataPlacemark::None) {
-	    placemark->setVisualCategory(category);
-	}
-
-	m_document->append(placemark);
-	return true;
+        m_document->append(placemark);
+        return true;
 
     } else {
-	qDebug() << "Missing FeatureCollection or Feature object in GeoJSON file";
-	return false;
+        qDebug() << "Missing FeatureCollection or Feature object in GeoJSON file";
+        return false;
     }
 }
 
 bool JsonParser::parseGeoJsonSubLevel( const QJsonObject& jsonObject,
-				       QVector<GeoDataGeometry*>& geometryList )
+                                       QVector<GeoDataGeometry*>& geometryList, bool& hasPoints )
 {
     // The GeoJSON object type
     const QString jsonObjectType = jsonObject.value(QStringLiteral("type")).toString();
 
     if (jsonObjectType == QStringLiteral("FeatureCollection")
-	|| jsonObjectType == QStringLiteral("Feature")) {
+        || jsonObjectType == QStringLiteral("Feature")) {
 
-	qDebug() << "Cannot have FeatureCollection or Feature objects at this level of the GeoJSON file";
-	return false;
+        qDebug() << "Cannot have FeatureCollection or Feature objects at this level of the GeoJSON file";
+        return false;
 
     } else if (jsonObjectType == QStringLiteral("GeometryCollection")) {
-	// Handle the GeometryCollection object, which may contain multiple geometry objects
+        // Handle the GeometryCollection object, which may contain multiple geometry objects
 
-	const QJsonArray geometryArray = jsonObject.value(QStringLiteral("geometries")).toArray();
-	for (int geometryIndex = 0; geometryIndex < geometryArray.size(); ++geometryIndex) {
-	    if (! parseGeoJsonSubLevel( geometryArray[geometryIndex].toObject(), geometryList )) {
-		return false;
-	    }
-	}
+        const QJsonArray geometryArray = jsonObject.value(QStringLiteral("geometries")).toArray();
+        for (int geometryIndex = 0; geometryIndex < geometryArray.size(); ++geometryIndex) {
+            if (! parseGeoJsonSubLevel( geometryArray[geometryIndex].toObject(), geometryList, hasPoints )) {
+                return false;
+            }
+        }
 
-	return true;
+        return true;
     }
 
     // Handle remaining GeoJSON objects, which each have a "coordinates" member (an array)
@@ -337,150 +376,152 @@ bool JsonParser::parseGeoJsonSubLevel( const QJsonObject& jsonObject,
     const QJsonArray coordinateArray = jsonObject.value(QStringLiteral("coordinates")).toArray();
 
     if (jsonObjectType == QStringLiteral("Point")) {
-	// A Point object has a single GeoJSON position: an array of at least two values
+        // A Point object has a single GeoJSON position: an array of at least two values
 
-	GeoDataPoint* geom = new GeoDataPoint();
-	const qreal lon = coordinateArray.at(0).toDouble();
-	const qreal lat = coordinateArray.at(1).toDouble();
-	const qreal alt = coordinateArray.at(2).toDouble();	// If missing, uses 0 as the default
+        GeoDataPoint* geom = new GeoDataPoint();
+        const qreal lon = coordinateArray.at(0).toDouble();
+        const qreal lat = coordinateArray.at(1).toDouble();
+        const qreal alt = coordinateArray.at(2).toDouble();     // If missing, uses 0 as the default
 
-	geom->setCoordinates( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
-	geometryList.append(geom);
+        geom->setCoordinates( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
+        geometryList.append(geom);
 
-	return true;
+        hasPoints = true;
+        return true;
 
     } else if (jsonObjectType == QStringLiteral("MultiPoint")) {
-	// A MultiPoint object has an array of GeoJSON positions (ie, a two-level array)
+        // A MultiPoint object has an array of GeoJSON positions (ie, a two-level array)
 
-	for (int positionIndex = 0; positionIndex < coordinateArray.size(); ++positionIndex) {
-	    const QJsonArray positionArray = coordinateArray[positionIndex].toArray();
+        for (int positionIndex = 0; positionIndex < coordinateArray.size(); ++positionIndex) {
+            const QJsonArray positionArray = coordinateArray[positionIndex].toArray();
 
-	    GeoDataPoint* geom = new GeoDataPoint();
-	    const qreal lon = positionArray.at(0).toDouble();
-	    const qreal lat = positionArray.at(1).toDouble();
-	    const qreal alt = positionArray.at(2).toDouble();
+            GeoDataPoint* geom = new GeoDataPoint();
+            const qreal lon = positionArray.at(0).toDouble();
+            const qreal lat = positionArray.at(1).toDouble();
+            const qreal alt = positionArray.at(2).toDouble();
 
-	    geom->setCoordinates( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
-	    geometryList.append(geom);
-	}
+            geom->setCoordinates( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
+            geometryList.append(geom);
+        }
 
-	return true;
+        hasPoints = true;
+        return true;
 
     } else if (jsonObjectType == QStringLiteral("LineString")) {
-	// A LineString object has an array of GeoJSON positions (ie, a two-level array)
+        // A LineString object has an array of GeoJSON positions (ie, a two-level array)
 
-	GeoDataLineString* geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );
+        GeoDataLineString* geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );
 
-	for (int positionIndex = 0; positionIndex < coordinateArray.size(); ++positionIndex) {
-	    const QJsonArray positionArray = coordinateArray[positionIndex].toArray();
+        for (int positionIndex = 0; positionIndex < coordinateArray.size(); ++positionIndex) {
+            const QJsonArray positionArray = coordinateArray[positionIndex].toArray();
 
-	    const qreal lon = positionArray.at(0).toDouble();
-	    const qreal lat = positionArray.at(1).toDouble();
-	    const qreal alt = positionArray.at(2).toDouble();
+            const qreal lon = positionArray.at(0).toDouble();
+            const qreal lat = positionArray.at(1).toDouble();
+            const qreal alt = positionArray.at(2).toDouble();
 
-	    geom->append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
-	}
-	geometryList.append(geom);
+            geom->append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
+        }
+        geometryList.append(geom);
 
-	return true;
+        return true;
 
     } else if (jsonObjectType == QStringLiteral("MultiLineString")) {
-	// A MultiLineString object has an array of arrays of GeoJSON positions (three-level)
+        // A MultiLineString object has an array of arrays of GeoJSON positions (three-level)
 
-	for (int lineStringIndex = 0; lineStringIndex < coordinateArray.size(); ++lineStringIndex) {
-	    const QJsonArray lineStringArray = coordinateArray[lineStringIndex].toArray();
+        for (int lineStringIndex = 0; lineStringIndex < coordinateArray.size(); ++lineStringIndex) {
+            const QJsonArray lineStringArray = coordinateArray[lineStringIndex].toArray();
 
-	    GeoDataLineString* geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );
+            GeoDataLineString* geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );
 
-	    for (int positionIndex = 0; positionIndex < lineStringArray.size(); ++positionIndex) {
-		const QJsonArray positionArray = lineStringArray[positionIndex].toArray();
+            for (int positionIndex = 0; positionIndex < lineStringArray.size(); ++positionIndex) {
+                const QJsonArray positionArray = lineStringArray[positionIndex].toArray();
 
-		const qreal lon = positionArray.at(0).toDouble();
-		const qreal lat = positionArray.at(1).toDouble();
-		const qreal alt = positionArray.at(2).toDouble();
+                const qreal lon = positionArray.at(0).toDouble();
+                const qreal lat = positionArray.at(1).toDouble();
+                const qreal alt = positionArray.at(2).toDouble();
 
-		geom->append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
-	    }
-	    geometryList.append(geom);
-	}
+                geom->append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
+            }
+            geometryList.append(geom);
+        }
 
-	return true;
+        return true;
 
     } else if (jsonObjectType == QStringLiteral("Polygon")) {
-	// A Polygon object has an array of arrays of GeoJSON positions: the first array within the
-	// top-level Polygon coordinates array is the outer boundary, following arrays are inner
-	// holes (if any)
+        // A Polygon object has an array of arrays of GeoJSON positions: the first array within the
+        // top-level Polygon coordinates array is the outer boundary, following arrays are inner
+        // holes (if any)
 
-	GeoDataPolygon* geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );
+        GeoDataPolygon* geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );
 
-	for (int ringIndex = 0; ringIndex < coordinateArray.size(); ++ringIndex) {
-	    const QJsonArray ringArray = coordinateArray[ringIndex].toArray();
+        for (int ringIndex = 0; ringIndex < coordinateArray.size(); ++ringIndex) {
+            const QJsonArray ringArray = coordinateArray[ringIndex].toArray();
 
-	    GeoDataLinearRing linearRing;
+            GeoDataLinearRing linearRing;
 
-	    for (int positionIndex = 0; positionIndex < ringArray.size(); ++positionIndex) {
-		const QJsonArray positionArray = ringArray[positionIndex].toArray();
+            for (int positionIndex = 0; positionIndex < ringArray.size(); ++positionIndex) {
+                const QJsonArray positionArray = ringArray[positionIndex].toArray();
 
-		const qreal lon = positionArray.at(0).toDouble();
-		const qreal lat = positionArray.at(1).toDouble();
-		const qreal alt = positionArray.at(2).toDouble();
+                const qreal lon = positionArray.at(0).toDouble();
+                const qreal lat = positionArray.at(1).toDouble();
+                const qreal alt = positionArray.at(2).toDouble();
 
-		linearRing.append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
-	    }
+                linearRing.append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
+            }
 
-	    if (ringIndex == 0) {
-		// Outer boundary of the polygon
-		geom->setOuterBoundary(linearRing);
-	    } else {
-		geom->appendInnerBoundary(linearRing);
-	    }
-	}
-	geometryList.append(geom);
+            if (ringIndex == 0) {
+                // Outer boundary of the polygon
+                geom->setOuterBoundary(linearRing);
+            } else {
+                geom->appendInnerBoundary(linearRing);
+            }
+        }
+        geometryList.append(geom);
 
-	return true;
+        return true;
 
     } else if (jsonObjectType == QStringLiteral("MultiPolygon")) {
-	// A MultiPolygon object has an array of Polygon arrays (ie, a four-level array)
+        // A MultiPolygon object has an array of Polygon arrays (ie, a four-level array)
 
-	for (int polygonIndex = 0; polygonIndex < coordinateArray.size(); ++polygonIndex) {
-	    const QJsonArray polygonArray = coordinateArray[polygonIndex].toArray();
+        for (int polygonIndex = 0; polygonIndex < coordinateArray.size(); ++polygonIndex) {
+            const QJsonArray polygonArray = coordinateArray[polygonIndex].toArray();
 
-	    GeoDataPolygon* geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );
+            GeoDataPolygon* geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );
 
-	    for (int ringIndex = 0; ringIndex < polygonArray.size(); ++ringIndex) {
-		const QJsonArray ringArray = polygonArray[ringIndex].toArray();
+            for (int ringIndex = 0; ringIndex < polygonArray.size(); ++ringIndex) {
+                const QJsonArray ringArray = polygonArray[ringIndex].toArray();
 
-		GeoDataLinearRing linearRing;
+                GeoDataLinearRing linearRing;
 
-		for (int positionIndex = 0; positionIndex < ringArray.size(); ++positionIndex) {
-		    const QJsonArray positionArray = ringArray[positionIndex].toArray();
+                for (int positionIndex = 0; positionIndex < ringArray.size(); ++positionIndex) {
+                    const QJsonArray positionArray = ringArray[positionIndex].toArray();
 
-		    const qreal lon = positionArray.at(0).toDouble();
-		    const qreal lat = positionArray.at(1).toDouble();
-		    const qreal alt = positionArray.at(2).toDouble();
+                    const qreal lon = positionArray.at(0).toDouble();
+                    const qreal lat = positionArray.at(1).toDouble();
+                    const qreal alt = positionArray.at(2).toDouble();
 
-		    linearRing.append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
-		}
+                    linearRing.append( GeoDataCoordinates( lon, lat, alt, GeoDataCoordinates::Degree ));
+                }
 
-		if (ringIndex == 0) {
-		    // Outer boundary of the polygon
-		    geom->setOuterBoundary(linearRing);
-		} else {
-		    geom->appendInnerBoundary(linearRing);
-		}
-	    }
-	    geometryList.append(geom);
-	}
+                if (ringIndex == 0) {
+                    // Outer boundary of the polygon
+                    geom->setOuterBoundary(linearRing);
+                } else {
+                    geom->appendInnerBoundary(linearRing);
+                }
+            }
+            geometryList.append(geom);
+        }
 
-	return true;
+        return true;
 
     } else if (jsonObjectType == QStringLiteral("")) {
-	// Unlocated Feature objects have a null value for "geometry" (RFC7946 section 3.2)
-	return true;
+        // Unlocated Feature objects have a null value for "geometry" (RFC7946 section 3.2)
+        return true;
 
     } else {
-	qDebug() << "Unknown GeoJSON object type" << jsonObjectType;
-	return false;
+        qDebug() << "Unknown GeoJSON object type" << jsonObjectType;
+        return false;
     }
 }
 
diff --git a/src/plugins/runner/json/JsonParser.h b/src/plugins/runner/json/JsonParser.h
index 69fda8c73..6a0b0de61 100644
--- a/src/plugins/runner/json/JsonParser.h
+++ b/src/plugins/runner/json/JsonParser.h
@@ -21,6 +21,10 @@ namespace Marble {
 
 class GeoDataDocument;
 class GeoDataGeometry;
+class GeoDataIconStyle;
+class GeoDataLineStyle;
+class GeoDataPolyStyle;
+class GeoDataLabelStyle;
 
 class JsonParser
 {
@@ -45,6 +49,12 @@ private:
 
     GeoDataDocument* m_document;
 
+    GeoDataIconStyle*  m_iconStylePoints;
+    GeoDataIconStyle*  m_iconStyleOther;
+    GeoDataLineStyle*  m_lineStyle;
+    GeoDataPolyStyle*  m_polyStyle;
+    GeoDataLabelStyle* m_labelStyle;
+
     /**
      * @brief parse a top-level GeoJSON object (FeatureCollection or Feature)
      * @param jsonObject  the object to parse
@@ -56,9 +66,10 @@ private:
       * @brief parse a sub-level GeoJSON object
       * @param jsonObject    the object to parse
       * @param geometryList  a list of geometries pass back to the caller
+      * @param hasPoints     a boolean passed back to the caller: true if Points exist in geometry
       * @return true if parsing of the object was successful
       */
-    bool parseGeoJsonSubLevel(const QJsonObject&, QVector<GeoDataGeometry*>&);
+    bool parseGeoJsonSubLevel(const QJsonObject&, QVector<GeoDataGeometry*>&, bool&);
 };
 
 }
-- 
2.20.1



More information about the Marble-devel mailing list