From 8105ad1fe53fd0c897c7b0c108c0ec25358ab93b Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Wed, 25 Mar 2020 13:27:11 +0100 Subject: [PATCH 01/27] Initial work on vector tile layer support --- CMakeLists.txt | 5 + python/CMakeLists.txt | 1 + python/core/core_auto.sip | 1 + scripts/astyle.sh | 2 +- src/core/CMakeLists.txt | 25 + .../wms => core}/qgsmbtilesreader.cpp | 0 .../wms => core}/qgsmbtilesreader.h | 3 +- .../vectortile/qgsvectortilebasicrenderer.cpp | 259 ++ .../vectortile/qgsvectortilebasicrenderer.h | 156 + src/core/vectortile/qgsvectortilelayer.cpp | 176 ++ src/core/vectortile/qgsvectortilelayer.h | 148 + .../vectortile/qgsvectortilelayerrenderer.cpp | 184 ++ .../vectortile/qgsvectortilelayerrenderer.h | 83 + src/core/vectortile/qgsvectortileloader.cpp | 265 ++ src/core/vectortile/qgsvectortileloader.h | 100 + .../vectortile/qgsvectortilemvtdecoder.cpp | 322 +++ src/core/vectortile/qgsvectortilemvtdecoder.h | 56 + src/core/vectortile/qgsvectortilerenderer.h | 90 + src/core/vectortile/qgsvectortileutils.cpp | 171 ++ src/core/vectortile/qgsvectortileutils.h | 62 + src/core/vectortile/vector_tile.pb.cc | 2527 +++++++++++++++++ src/core/vectortile/vector_tile.pb.h | 1260 ++++++++ src/providers/wms/CMakeLists.txt | 1 - 23 files changed, 5894 insertions(+), 3 deletions(-) rename src/{providers/wms => core}/qgsmbtilesreader.cpp (100%) rename src/{providers/wms => core}/qgsmbtilesreader.h (96%) create mode 100644 src/core/vectortile/qgsvectortilebasicrenderer.cpp create mode 100644 src/core/vectortile/qgsvectortilebasicrenderer.h create mode 100644 src/core/vectortile/qgsvectortilelayer.cpp create mode 100644 src/core/vectortile/qgsvectortilelayer.h create mode 100644 src/core/vectortile/qgsvectortilelayerrenderer.cpp create mode 100644 src/core/vectortile/qgsvectortilelayerrenderer.h create mode 100644 src/core/vectortile/qgsvectortileloader.cpp create mode 100644 src/core/vectortile/qgsvectortileloader.h create mode 100644 src/core/vectortile/qgsvectortilemvtdecoder.cpp create mode 100644 src/core/vectortile/qgsvectortilemvtdecoder.h create mode 100644 src/core/vectortile/qgsvectortilerenderer.h create mode 100644 src/core/vectortile/qgsvectortileutils.cpp create mode 100644 src/core/vectortile/qgsvectortileutils.h create mode 100644 src/core/vectortile/vector_tile.pb.cc create mode 100644 src/core/vectortile/vector_tile.pb.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c7f145d52578..2a17a6503f1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,11 @@ IF(WITH_CORE) MESSAGE (SEND_ERROR "sqlite3 dependency was not found!") ENDIF (NOT SQLITE3_FOUND) + FIND_PACKAGE(Protobuf REQUIRED) # for decoding of vector tiles in MVT format + MESSAGE(STATUS "Found Protobuf: ${Protobuf_LIBRARIES}") + FIND_PACKAGE(ZLIB REQUIRED) # for decompression of vector tiles in MBTiles file + MESSAGE(STATUS "Found zlib: ${ZLIB_LIBRARIES}") + # optional IF (WITH_POSTGRESQL) FIND_PACKAGE(Postgres) # PostgreSQL provider diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index e87ac9aad67a..101a12d656fd 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -123,6 +123,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/core/symbology ${CMAKE_SOURCE_DIR}/src/core/classification ${CMAKE_SOURCE_DIR}/src/core/validity + ${CMAKE_SOURCE_DIR}/src/core/vectortile ${CMAKE_SOURCE_DIR}/src/plugins ${CMAKE_SOURCE_DIR}/external ${CMAKE_SOURCE_DIR}/external/nlohmann diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index 542b47c86979..0ab8ae964435 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -534,3 +534,4 @@ %Include auto_generated/gps/qgsgpsconnectionregistry.sip %Include auto_generated/symbology/qgsmasksymbollayer.sip %Include auto_generated/qgsuserprofile.sip +%Include auto_generated/vectortile/qgsvectortilelayer.sip diff --git a/scripts/astyle.sh b/scripts/astyle.sh index 7217f9acee60..b1a44bd19a7d 100755 --- a/scripts/astyle.sh +++ b/scripts/astyle.sh @@ -105,7 +105,7 @@ astyleit() { for f in "$@"; do case "$f" in - src/plugins/grass/qtermwidget/*|external/o2/*|external/qt-unix-signals/*|external/rtree/*|external/astyle/*|external/kdbush/*|external/poly2tri/*|external/wintoast/*|external/qt3dextra-headers/*|external/meshOptimizer/*|python/ext-libs/*|ui_*.py|*.astyle|tests/testdata/*|editors/*) + src/plugins/grass/qtermwidget/*|external/o2/*|external/qt-unix-signals/*|external/rtree/*|external/astyle/*|external/kdbush/*|external/poly2tri/*|external/wintoast/*|external/qt3dextra-headers/*|external/meshOptimizer/*|python/ext-libs/*|ui_*.py|*.astyle|tests/testdata/*|editors/*|src/core/vectortile/*.pb.*) echo -ne "$f skipped $elcr" continue ;; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5b8b552b1daa..128c3d1ea022 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -312,6 +312,7 @@ SET(QGIS_CORE_SRCS qgsmapunitscale.cpp qgsmargins.cpp qgsmaskidprovider.cpp + qgsmbtilesreader.cpp qgsmessagelog.cpp qgsmessageoutput.cpp qgsmimedatautils.cpp @@ -395,6 +396,7 @@ SET(QGIS_CORE_SRCS qgstessellator.cpp qgstextrenderer.cpp qgstilecache.cpp + qgstiles.cpp qgstolerance.cpp qgstracer.cpp qgstranslationcontext.cpp @@ -635,6 +637,14 @@ SET(QGIS_CORE_SRCS validity/qgsvaliditycheckcontext.cpp validity/qgsvaliditycheckregistry.cpp + vectortile/qgsvectortilebasicrenderer.cpp + vectortile/qgsvectortilelayer.cpp + vectortile/qgsvectortilelayerrenderer.cpp + vectortile/qgsvectortileloader.cpp + vectortile/qgsvectortilemvtdecoder.cpp + vectortile/qgsvectortileutils.cpp + vectortile/vector_tile.pb.cc + ${CMAKE_CURRENT_BINARY_DIR}/qgsexpression_texts.cpp qgsuserprofile.cpp @@ -833,6 +843,7 @@ SET(QGIS_CORE_HDRS qgsmapunitscale.h qgsmargins.h qgsmaskidprovider.h + qgsmbtilesreader.h qgsmessagelog.h qgsmessageoutput.h qgsmimedatautils.h @@ -924,6 +935,7 @@ SET(QGIS_CORE_HDRS qgstextrenderer.h qgsthreadingutils.h qgstilecache.h + qgstiles.h qgstolerance.h qgstracer.h qgstrackedvectorlayertools.h @@ -1319,6 +1331,14 @@ SET(QGIS_CORE_HDRS validity/qgsabstractvaliditycheck.h validity/qgsvaliditycheckcontext.h validity/qgsvaliditycheckregistry.h + + vectortile/qgsvectortilebasicrenderer.h + vectortile/qgsvectortilelayer.h + vectortile/qgsvectortilelayerrenderer.h + vectortile/qgsvectortileloader.h + vectortile/qgsvectortilemvtdecoder.h + vectortile/qgsvectortilerenderer.h + vectortile/qgsvectortileutils.h ) SET(QGIS_CORE_PRIVATE_HDRS @@ -1408,6 +1428,7 @@ INCLUDE_DIRECTORIES( symbology mesh validity + vectortile ${CMAKE_SOURCE_DIR}/external ${CMAKE_SOURCE_DIR}/external/nlohmann ${CMAKE_SOURCE_DIR}/external/kdbush/include @@ -1429,6 +1450,8 @@ INCLUDE_DIRECTORIES(SYSTEM ${QCA_INCLUDE_DIR} ${QTKEYCHAIN_INCLUDE_DIR} ${Qt5SerialPort_INCLUDE_DIRS} + ${Protobuf_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIRS} ) @@ -1563,6 +1586,8 @@ TARGET_LINK_LIBRARIES(qgis_core ${SQLITE3_LIBRARY} ${SPATIALITE_LIBRARY} ${LIBZIP_LIBRARY} + ${Protobuf_LIBRARIES} + ${ZLIB_LIBRARIES} ) IF (FORCE_STATIC_PROVIDERS) diff --git a/src/providers/wms/qgsmbtilesreader.cpp b/src/core/qgsmbtilesreader.cpp similarity index 100% rename from src/providers/wms/qgsmbtilesreader.cpp rename to src/core/qgsmbtilesreader.cpp diff --git a/src/providers/wms/qgsmbtilesreader.h b/src/core/qgsmbtilesreader.h similarity index 96% rename from src/providers/wms/qgsmbtilesreader.h rename to src/core/qgsmbtilesreader.h index 279e89a6e3e9..7944c066dc2e 100644 --- a/src/providers/wms/qgsmbtilesreader.h +++ b/src/core/qgsmbtilesreader.h @@ -16,6 +16,7 @@ #ifndef QGSMBTILESREADER_H #define QGSMBTILESREADER_H +#include "qgis_core.h" #include "sqlite3.h" #include "qgssqliteutils.h" @@ -23,7 +24,7 @@ class QImage; class QgsRectangle; -class QgsMBTilesReader +class CORE_EXPORT QgsMBTilesReader { public: explicit QgsMBTilesReader( const QString &filename ); diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.cpp b/src/core/vectortile/qgsvectortilebasicrenderer.cpp new file mode 100644 index 000000000000..31130657a7e7 --- /dev/null +++ b/src/core/vectortile/qgsvectortilebasicrenderer.cpp @@ -0,0 +1,259 @@ +/*************************************************************************** + qgsvectortilebasicrenderer.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsvectortilebasicrenderer.h" + +#include "qgslinesymbollayer.h" +#include "qgssymbollayerutils.h" +#include "qgsvectortileutils.h" + + +QgsVectorTileBasicRendererStyle::QgsVectorTileBasicRendererStyle( const QString &stName, const QString &laName, QgsWkbTypes::GeometryType geomType ) + : mStyleName( stName ) + , mLayerName( laName ) + , mGeometryType( geomType ) +{ +} + +QgsVectorTileBasicRendererStyle::QgsVectorTileBasicRendererStyle( const QgsVectorTileBasicRendererStyle &other ) +{ + operator=( other ); +} + +QgsVectorTileBasicRendererStyle &QgsVectorTileBasicRendererStyle::operator=( const QgsVectorTileBasicRendererStyle &other ) +{ + mStyleName = other.mStyleName; + mLayerName = other.mLayerName; + mGeometryType = other.mGeometryType; + mSymbol.reset( other.mSymbol ? other.mSymbol->clone() : nullptr ); + mEnabled = other.mEnabled; + mExpression = other.mExpression; + mMinZoomLevel = other.mMinZoomLevel; + mMaxZoomLevel = other.mMaxZoomLevel; + return *this; +} + +void QgsVectorTileBasicRendererStyle::setSymbol( QgsSymbol *sym ) +{ + mSymbol.reset( sym ); +} + +void QgsVectorTileBasicRendererStyle::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const +{ + elem.setAttribute( "name", mStyleName ); + elem.setAttribute( "layer", mLayerName ); + elem.setAttribute( "geometry", mGeometryType ); + elem.setAttribute( "enabled", mEnabled ? "1" : "0" ); + elem.setAttribute( "expression", mExpression ); + elem.setAttribute( "min-zoom", mMinZoomLevel ); + elem.setAttribute( "max-zoom", mMaxZoomLevel ); + + QDomDocument doc = elem.ownerDocument(); + QgsSymbolMap symbols; + symbols[QStringLiteral( "0" )] = mSymbol.get(); + QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context ); + elem.appendChild( symbolsElem ); +} + +void QgsVectorTileBasicRendererStyle::readXml( const QDomElement &elem, const QgsReadWriteContext &context ) +{ + mStyleName = elem.attribute( "name" ); + mLayerName = elem.attribute( "layer" ); + mGeometryType = static_cast( elem.attribute( "geometry" ).toInt() ); + mEnabled = elem.attribute( "enabled" ).toInt(); + mExpression = elem.attribute( "expression" ); + mMinZoomLevel = elem.attribute( "min-zoom" ).toInt(); + mMaxZoomLevel = elem.attribute( "max-zoom" ).toInt(); + + mSymbol.reset(); + QDomElement symbolsElem = elem.firstChildElement( QStringLiteral( "symbols" ) ); + if ( !symbolsElem.isNull() ) + { + QgsSymbolMap symbolMap = QgsSymbolLayerUtils::loadSymbols( symbolsElem, context ); + if ( !symbolMap.contains( QStringLiteral( "0" ) ) ) + { + mSymbol.reset( symbolMap.take( QStringLiteral( "0" ) ) ); + } + } +} + +//////// + + +QgsVectorTileBasicRenderer::QgsVectorTileBasicRenderer() +{ + setDefaultStyle(); +} + +QString QgsVectorTileBasicRenderer::type() const +{ + return "basic"; +} + +QgsVectorTileBasicRenderer *QgsVectorTileBasicRenderer::clone() const +{ + QgsVectorTileBasicRenderer *r = new QgsVectorTileBasicRenderer; + r->mStyles = mStyles; + r->mStyles.detach(); // make a deep copy to make sure symbols get cloned + return r; +} + +void QgsVectorTileBasicRenderer::startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ) +{ + Q_UNUSED( context ) + Q_UNUSED( tileRange ) + // figure out required fields for different layers + for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) ) + { + if ( layerStyle.isActive( tileZoom ) && !layerStyle.filterExpression().isEmpty() ) + { + QgsExpression expr( layerStyle.filterExpression() ); + mRequiredFields[layerStyle.layerName()].unite( expr.referencedColumns() ); + } + } +} + +QMap > QgsVectorTileBasicRenderer::usedAttributes( const QgsRenderContext & ) +{ + return mRequiredFields; +} + +void QgsVectorTileBasicRenderer::stopRender( QgsRenderContext &context ) +{ + Q_UNUSED( context ) +} + +void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ) +{ + const QgsVectorTileFeatures tileData = tile.features; + int zoomLevel = tile.id.zoomLevel(); + + for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) ) + { + if ( !layerStyle.isActive( zoomLevel ) ) + continue; + + QgsFields fields = QgsVectorTileUtils::makeQgisFields( mRequiredFields[layerStyle.layerName()] ); + + QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) ); + scope->setFields( fields ); + context.expressionContext().appendScope( scope ); + + QgsExpression filterExpression( layerStyle.filterExpression() ); + filterExpression.prepare( &context.expressionContext() ); + + QgsSymbol *sym = layerStyle.symbol(); + sym->startRender( context, QgsFields() ); + if ( layerStyle.layerName().isEmpty() ) + { + // matching all layers + for ( QString layerName : tileData.keys() ) + { + for ( const QgsFeature &f : tileData[layerName] ) + { + scope->setFeature( f ); + if ( filterExpression.isValid() && !filterExpression.evaluate( &context.expressionContext() ).toBool() ) + continue; + + if ( QgsWkbTypes::geometryType( f.geometry().wkbType() ) == layerStyle.geometryType() ) + sym->renderFeature( f, context ); + } + } + } + else if ( tileData.contains( layerStyle.layerName() ) ) + { + // matching one particular layer + for ( const QgsFeature &f : tileData[layerStyle.layerName()] ) + { + scope->setFeature( f ); + if ( filterExpression.isValid() && !filterExpression.evaluate( &context.expressionContext() ).toBool() ) + continue; + + if ( QgsWkbTypes::geometryType( f.geometry().wkbType() ) == layerStyle.geometryType() ) + sym->renderFeature( f, context ); + } + } + sym->stopRender( context ); + + delete context.expressionContext().popScope(); + } +} + +void QgsVectorTileBasicRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const +{ + QDomDocument doc = elem.ownerDocument(); + QDomElement elemStyles = doc.createElement( "styles" ); + for ( const QgsVectorTileBasicRendererStyle &layerStyle : mStyles ) + { + QDomElement elemStyle = doc.createElement( "style" ); + layerStyle.writeXml( elemStyle, context ); + elemStyles.appendChild( elemStyle ); + } + elem.appendChild( elemStyles ); +} + +void QgsVectorTileBasicRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context ) +{ + mStyles.clear(); + + QDomElement elemStyles = elem.firstChildElement( "styles" ); + QDomElement elemStyle = elemStyles.firstChildElement( "style" ); + while ( !elemStyle.isNull() ) + { + QgsVectorTileBasicRendererStyle layerStyle; + layerStyle.readXml( elemStyle, context ); + mStyles.append( layerStyle ); + } +} + +void QgsVectorTileBasicRenderer::setStyles( const QList &styles ) +{ + mStyles = styles; +} + +QList QgsVectorTileBasicRenderer::styles() const +{ + return mStyles; +} + +void QgsVectorTileBasicRenderer::setDefaultStyle() +{ + QColor color = Qt::blue; + QColor polygonColor = color; + polygonColor.setAlpha( 100 ); + QColor pointColor = Qt::red; + + QgsFillSymbol *polygonSymbol = static_cast( QgsLineSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ); + polygonSymbol->setColor( polygonColor ); + + QgsLineSymbol *lineSymbol = static_cast( QgsLineSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ); + lineSymbol->setColor( color ); + + QgsMarkerSymbol *pointSymbol = static_cast( QgsLineSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) ); + pointSymbol->setColor( pointColor ); + + QgsVectorTileBasicRendererStyle st1( "polygons", QString(), QgsWkbTypes::PolygonGeometry ); + st1.setSymbol( polygonSymbol ); + + QgsVectorTileBasicRendererStyle st2( "lines", QString(), QgsWkbTypes::LineGeometry ); + st2.setSymbol( lineSymbol ); + + QgsVectorTileBasicRendererStyle st3( "points", QString(), QgsWkbTypes::PointGeometry ); + st3.setSymbol( pointSymbol ); + + QList lst; + lst << st1 << st2 << st3; + setStyles( lst ); +} diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.h b/src/core/vectortile/qgsvectortilebasicrenderer.h new file mode 100644 index 000000000000..e938877cecc1 --- /dev/null +++ b/src/core/vectortile/qgsvectortilebasicrenderer.h @@ -0,0 +1,156 @@ +/*************************************************************************** + qgsvectortilebasicrenderer.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILEBASICRENDERER_H +#define QGSVECTORTILEBASICRENDERER_H + +#include "qgsvectortilerenderer.h" + +class QgsLineSymbol; +class QgsFillSymbol; +class QgsMarkerSymbol; + +class QgsSymbol; + +/** + * \ingroup core + * Definition of map rendering of a subset of vector tile data. The subset of data is defined by: + * 1. sub-layer name + * 2. geometry type (a single sub-layer may have multiple geometry types) + * 3. filter expression + * + * Renering is determined by the associated symbol (QgsSymbol). Symbol has to be of the same + * type as the chosen geometryType() - i.e. QgsMarkerSymbol for points, QgsLineSymbol for linestrings + * and QgsFillSymbol for polygons. + * + * It is possible to further constrain when this style is applied by setting a range of allowed + * zoom levels, or by disabling it. + * + * \since QGIS 3.14 + */ +struct QgsVectorTileBasicRendererStyle +{ + public: + //! Constructs a style object + QgsVectorTileBasicRendererStyle( const QString &stName = QString(), const QString &laName = QString(), QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ); + + QgsVectorTileBasicRendererStyle( const QgsVectorTileBasicRendererStyle &other ); + QgsVectorTileBasicRendererStyle &operator=( const QgsVectorTileBasicRendererStyle &other ); + + //! Sets human readable name of this style + void setStyleName( const QString &name ) { mStyleName = name; } + //! Returns human readable name of this style + QString styleName() const { return mStyleName; } + + //! Sets name of the sub-layer to render (empty layer means that all layers match) + void setLayerName( const QString &name ) { mLayerName = name; } + //! Returns name of the sub-layer to render (empty layer means that all layers match) + QString layerName() const { return mLayerName; } + + //! Sets type of the geometry that will be used (point / line / polygon) + void setGeometryType( QgsWkbTypes::GeometryType geomType ) { mGeometryType = geomType; } + //! Returns type of the geometry that will be used (point / line / polygon) + QgsWkbTypes::GeometryType geometryType() const { return mGeometryType; } + + //! Sets filter expression (empty filter means that all features match) + void setFilterExpression( const QString &expr ) { mExpression = expr; } + //! Returns filter expression (empty filter means that all features match) + QString filterExpression() const { return mExpression; } + + //! Sets symbol for rendering. Takes ownership of the symbol. + void setSymbol( QgsSymbol *sym ); + //! Returns symbol for rendering + QgsSymbol *symbol() const { return mSymbol.get(); } + + //! Sets whether this style is enabled (used for rendering) + void setEnabled( bool enabled ) { mEnabled = enabled; } + //! Returns whether this style is enabled (used for rendering) + bool isEnabled() const { return mEnabled; } + + //! Sets minimum zoom level index (negative number means no limit) + void setMinZoomLevel( int minZoom ) { mMinZoomLevel = minZoom; } + //! Returns minimum zoom level index (negative number means no limit) + int minZoomLevel() const { return mMinZoomLevel; } + + //! Sets maximum zoom level index (negative number means no limit) + void setMaxZoomLevel( int maxZoom ) { mMaxZoomLevel = maxZoom; } + //! Returns maxnimum zoom level index (negative number means no limit) + int maxZoomLevel() const { return mMaxZoomLevel; } + + //! Returns whether the style is active at given zoom level (also checks "enabled" flag) + bool isActive( int zoomLevel ) const + { + return mEnabled && ( mMinZoomLevel == -1 || zoomLevel >= mMinZoomLevel ) && ( mMaxZoomLevel == -1 || zoomLevel <= mMaxZoomLevel ); + } + + //! Writes object content to given DOM element + void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const; + //! Reads object content from given DOM element + void readXml( const QDomElement &elem, const QgsReadWriteContext &context ); + + private: + QString mStyleName; + QString mLayerName; + QgsWkbTypes::GeometryType mGeometryType; + std::unique_ptr mSymbol; + bool mEnabled = true; + QString mExpression; + int mMinZoomLevel = -1; + int mMaxZoomLevel = -1; +}; + + +/** + * \ingroup core + * The default vector tile renderer implementation. It has an ordered list of "styles", + * each defines a rendering rule. + * + * \since QGIS 3.14 + */ +class QgsVectorTileBasicRenderer : public QgsVectorTileRenderer +{ + public: + //! Constructs renderer with some default styles + QgsVectorTileBasicRenderer(); + + QString type() const override; + QgsVectorTileBasicRenderer *clone() const override; + void startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ) override; + QMap > usedAttributes( const QgsRenderContext & ) override; + void stopRender( QgsRenderContext &context ) override; + void renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ) override; + void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override; + void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override; + + //! Sets list of styles of the renderer + void setStyles( const QList &styles ); + //! Returns list of styles of the renderer + QList styles() const; + + private: + void setDefaultStyle(); + + private: + //! List of rendering styles + QList mStyles; + + // temporary bits + + //! Names of required fields for each sub-layer (only valid between startRender/stopRender calls) + QMap > mRequiredFields; + +}; + +#endif // QGSVECTORTILEBASICRENDERER_H diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp new file mode 100644 index 000000000000..b035fde77b9b --- /dev/null +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -0,0 +1,176 @@ +/*************************************************************************** + qgsvectortilelayer.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsvectortilelayer.h" + +#include "qgsvectortilelayerrenderer.h" +#include "qgsmbtilesreader.h" +#include "qgsvectortilebasicrenderer.h" +#include "qgsvectortileloader.h" + +#include "qgsdatasourceuri.h" + +QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseName ) + : QgsPluginLayer( "vector-tile", baseName ) +{ + mDataSource = uri; + + QgsDataSourceUri dsUri; + dsUri.setEncodedUri( uri ); + + mSourceType = dsUri.param( "type" ); + mSourcePath = dsUri.param( "url" ); + if ( mSourceType == "xyz" ) + { + // online tiles + mSourceMinZoom = 0; + mSourceMaxZoom = 14; + + setExtent( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) ); + } + else if ( mSourceType == "mbtiles" ) + { + QgsMBTilesReader reader( mSourcePath ); + if ( !reader.open() ) + { + qDebug() << "failed to open MBTiles file:" << mSourcePath; + return; + } + + qDebug() << "name:" << reader.metadataValue( "name" ); + bool minZoomOk, maxZoomOk; + int minZoom = reader.metadataValue( "minzoom" ).toInt( &minZoomOk ); + int maxZoom = reader.metadataValue( "maxzoom" ).toInt( &maxZoomOk ); + if ( minZoomOk ) + mSourceMinZoom = minZoom; + if ( maxZoomOk ) + mSourceMaxZoom = maxZoom; + qDebug() << "zoom range:" << mSourceMinZoom << mSourceMaxZoom; + + QgsRectangle r = reader.extent(); + // TODO: reproject to EPSG:3857 + setExtent( r ); + } + else + { + // TODO: report error - unknown type + return; + } + + setCrs( QgsCoordinateReferenceSystem( "EPSG:3857" ) ); + setValid( true ); + + // set a default renderer + setRenderer( new QgsVectorTileBasicRenderer ); +} + +QgsVectorTileLayer::~QgsVectorTileLayer() = default; + + +QgsPluginLayer *QgsVectorTileLayer::clone() const +{ + QgsVectorTileLayer *layer = new QgsVectorTileLayer( source(), name() ); + layer->setRenderer( renderer() ? renderer()->clone() : nullptr ); + return layer; +} + +QgsMapLayerRenderer *QgsVectorTileLayer::createMapRenderer( QgsRenderContext &rendererContext ) +{ + return new QgsVectorTileLayerRenderer( this, rendererContext ); +} + +bool QgsVectorTileLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) +{ + QString errorMsg; + return readSymbology( layerNode, errorMsg, context ); +} + +bool QgsVectorTileLayer::writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const +{ + QDomElement mapLayerNode = layerNode.toElement(); + mapLayerNode.setAttribute( "type", "vector-tile" ); + + QString errorMsg; + return writeSymbology( layerNode, doc, errorMsg, context ); +} + +bool QgsVectorTileLayer::readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) +{ + QDomElement elem = node.toElement(); + + readCommonStyle( elem, context, categories ); + + QDomElement elemRenderer = elem.firstChildElement( "renderer" ); + if ( elemRenderer.isNull() ) + { + errorMessage = "Missing tag"; + return false; + } + QString rendererType = elemRenderer.attribute( "type" ); + QgsVectorTileRenderer *r = nullptr; + if ( rendererType == "basic" ) + r = new QgsVectorTileBasicRenderer; + //else if ( rendererType == "mapbox-gl" ) + // r = new MapboxGLStyleRenderer; + else + { + errorMessage = "Unknown renderer type: " + rendererType; + return false; + } + + r->readXml( elemRenderer, context ); + return true; +} + +bool QgsVectorTileLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const +{ + Q_UNUSED( errorMessage ) + QDomElement elem = node.toElement(); + + writeCommonStyle( elem, doc, context, categories ); + + if ( mRenderer ) + { + QDomElement elemRenderer = doc.createElement( "renderer" ); + elemRenderer.setAttribute( "type", mRenderer->type() ); + mRenderer->writeXml( elemRenderer, context ); + elem.appendChild( elemRenderer ); + } + return true; +} + +void QgsVectorTileLayer::setTransformContext( const QgsCoordinateTransformContext &transformContext ) +{ + Q_UNUSED( transformContext ) +} + +QByteArray QgsVectorTileLayer::getRawTile( QgsTileXYZ tileID ) +{ + QgsTileRange tileRange( tileID.column(), tileID.column(), tileID.row(), tileID.row() ); + QList rawTiles = QgsVectorTileLoader::blockingFetchTileRawData( mSourceType, mSourcePath, tileID.zoomLevel(), QPointF(), tileRange ); + if ( rawTiles.isEmpty() ) + return QByteArray(); + return rawTiles.first().data; +} + +void QgsVectorTileLayer::setRenderer( QgsVectorTileRenderer *r ) +{ + mRenderer.reset( r ); +} + +QgsVectorTileRenderer *QgsVectorTileLayer::renderer() const +{ + return mRenderer.get(); +} diff --git a/src/core/vectortile/qgsvectortilelayer.h b/src/core/vectortile/qgsvectortilelayer.h new file mode 100644 index 000000000000..675b97044c26 --- /dev/null +++ b/src/core/vectortile/qgsvectortilelayer.h @@ -0,0 +1,148 @@ +/*************************************************************************** + qgsvectortilelayer.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILELAYER_H +#define QGSVECTORTILELAYER_H + +#include "qgis_core.h" +#include "qgis_sip.h" + +#include "qgspluginlayer.h" + +class QgsVectorTileRenderer; + +struct QgsTileXYZ; + +/** + * \ingroup core + * Implements a map layer that is dedicated to rendering of vector tiles. + * Vector tiles compared to "ordinary" vector layers are pre-processed data + * optimized for fast rendering. A dataset is provided with a series of zoom levels + * for different map scales. Each zoom level has a matrix of tiles that contain + * actual data. A single vector tile may be a a file stored on a local drive, + * requested over HTTP request or retrieved from a database. + * + * Content of a vector tile is divided into one or more named sub-layers. Each such + * sub-layer may contain many features which consist of geometry and attributes. + * Contrary to traditional vector layers, these sub-layers do not need to have a rigid + * schema where geometry type and attributes are the same for all features. A single + * sub-layer may have multiple geometry types in a single tile or have some attributes + * defined only at particular zoom levels. + * + * Vector tile layer currently does not use the concept of data providers that other + * layer types use. The process of rendering of vector tiles looks like this: + * + * +--------+ +------+ +---------+ + * | DATA | | RAW | | DECODED | + * | | --> LOADER --> | | --> DECODER --> | | --> RENDERER + * | SOURCE | | TILE | | TILE | + * +--------+ +------+ +---------+ + * + * Data source is a place from where tiles are fetched from (URL for HTTP access, local + * files, MBTiles file, GeoPackage file or others. Loader (QgsVectorTileLoader) class + * takes care of loading data from the data source. The "raw tile" data is just a blob + * (QByteArray) that is encoded in some way. There are multiple ways how vector tiles + * are encoded just like there are different formats how to store images. For example, + * tiles can be encoded using Mapbox Vector Tiles (MVT) format or in GeoJSON. Decoder + * (QgsVectorTileDecoder) takes care of decoding raw tile data into QgsFeature objects. + * A decoded tile is essentially an array of vector features for each sub-layer found + * in the tile - this is what vector tile renderer (QgsVectorTileRenderer) expects + * and does the map rendering. + * + * To construct a vector tile layer, it is best to use QgsDataSourceUri class and set + * the following parameters to get a valid encoded URI: + * - "type" - what kind of data source will be used + * - "url" - URL or path of the data source (specific to each data source type, see below) + * + * Currently supported data source types: + * - "xyz" - the "url" should be a template like http://example.com/{z}/{x}/{y}.pbf where + * {x},{y},{z} will be replaced by tile coordinates + * - "mbtiles" - tiles read from a MBTiles file (a SQLite database) + * + * Currently supported decoders: + * - MVT - following Mapbox Vector Tiles specification + * + * \since QGIS 3.14 + */ +class CORE_EXPORT QgsVectorTileLayer : public QgsPluginLayer +{ + public: + //! Constructs a new vector tile layer + explicit QgsVectorTileLayer( const QString &path = QString(), const QString &baseName = QString() ); + ~QgsVectorTileLayer(); + + // implementation of virtual functions from QgsMapLayer + + QgsPluginLayer *clone() const override; + + virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override; + + virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) override; + + virtual bool writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const override; + + virtual bool readSymbology( const QDomNode &node, QString &errorMessage, + QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) override; + + virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, + StyleCategories categories = AllStyleCategories ) const override; + + virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override; + + // new methods + + //! Returns type of the data source + QString sourceType() const { return mSourceType; } + //! Returns URL/path of the data source (syntax different to each data source type) + QString sourcePath() const { return mSourcePath; } + + //! Returns minimum zoom level at which source has any valid tiles (negative = unconstrained) + int sourceMinZoom() const { return mSourceMinZoom; } + //! Returns maximum zoom level at which source has any valid tiles (negative = unconstrained) + int sourceMaxZoom() const { return mSourceMaxZoom; } + + /** + * Fetches raw tile data for the give tile coordinates. If failed to fetch tile data, + * it will return an empty byte array. + * + * \note This call may issue a network request (depending on the source type) and will block + * the caller until the request is finished. + */ + QByteArray getRawTile( QgsTileXYZ tileID ) SIP_SKIP; + + /** + * Sets renderer for the map layer. + * \note Takes ownership of the passed renderer + */ + void setRenderer( QgsVectorTileRenderer *r ) SIP_SKIP; + //! Returns currently assigned renderer + QgsVectorTileRenderer *renderer() const SIP_SKIP; + + private: + //! Type of the data source + QString mSourceType; + //! URL/Path of the data source + QString mSourcePath; + //! Minimum zoom level at which source has any valid tiles (negative = unconstrained) + int mSourceMinZoom = -1; + //! Maximum zoom level at which source has any valid tiles (negative = unconstrained) + int mSourceMaxZoom = -1; + + //! Renderer assigned to the layer to draw map + std::unique_ptr mRenderer; +}; + + +#endif // QGSVECTORTILELAYER_H diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp new file mode 100644 index 000000000000..47733c2d6391 --- /dev/null +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + qgsvectortilelayerrenderer.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsvectortilelayerrenderer.h" + +#include + +#include "qgsexpressioncontextutils.h" +#include "qgsfeedback.h" + +#include "qgsvectortilemvtdecoder.h" +#include "qgsvectortilelayer.h" +#include "qgsvectortileloader.h" +#include "qgsvectortileutils.h" + + +QgsVectorTileLayerRenderer::QgsVectorTileLayerRenderer( QgsVectorTileLayer *layer, QgsRenderContext &context ) + : QgsMapLayerRenderer( layer->id(), &context ) + , mSourceType( layer->sourceType() ) + , mSourcePath( layer->sourcePath() ) + , mSourceMinZoom( layer->sourceMinZoom() ) + , mSourceMaxZoom( layer->sourceMaxZoom() ) + , mRenderer( layer->renderer()->clone() ) + , mFeedback( new QgsFeedback ) +{ +} + +bool QgsVectorTileLayerRenderer::render() +{ + QgsRenderContext &ctx = *renderContext(); + + if ( ctx.renderingStopped() ) + return false; + + QElapsedTimer tTotal; + tTotal.start(); + + qDebug() << "MVT rend" << ctx.extent().toString( -1 ); + + mTileZoom = QgsVectorTileUtils::scaleToZoomLevel( ctx.rendererScale(), mSourceMinZoom, mSourceMaxZoom ); + qDebug() << "MVT zoom level" << mTileZoom; + + mTileMatrix = QgsTileMatrix::fromWebMercator( mTileZoom ); + + mTileRange = mTileMatrix.tileRangeFromExtent( ctx.extent() ); + qDebug() << "MVT tile range" << mTileRange.startColumn() << mTileRange.endColumn() << " | " << mTileRange.startRow() << mTileRange.endRow(); + + // view center is used to sort the order of tiles for fetching and rendering + QPointF viewCenter = mTileMatrix.mapToTileCoordinates( ctx.extent().center() ); + + if ( !mTileRange.isValid() ) + { + qDebug() << "outside of range"; + return true; // nothing to do + } + + bool isAsync = ( mSourceType == "xyz" ); + + std::unique_ptr asyncLoader; + QList rawTiles; + if ( !isAsync ) + { + QElapsedTimer tFetch; + tFetch.start(); + rawTiles = QgsVectorTileLoader::blockingFetchTileRawData( mSourceType, mSourcePath, mTileZoom, viewCenter, mTileRange ); + qDebug() << "FETCH TIME" << tFetch.elapsed() / 1000.; + qDebug() << "fetched tiles:" << rawTiles.count(); + } + else + { + asyncLoader.reset( new QgsVectorTileLoader( mSourcePath, mTileZoom, mTileRange, viewCenter, mFeedback.get() ) ); + QObject::connect( asyncLoader.get(), &QgsVectorTileLoader::tileRequestFinished, [this]( const QgsVectorTileRawData & rawTile ) + { + qDebug() << "got async tile" << rawTile.id.column() << rawTile.id.row() << rawTile.id.zoomLevel(); + if ( !rawTile.data.isEmpty() ) + decodeAndDrawTile( rawTile ); + } ); + } + + if ( ctx.renderingStopped() ) + return false; + + mRenderer->startRender( *renderContext(), mTileZoom, mTileRange ); + + QMap > requiredFields = mRenderer->usedAttributes( *renderContext() ); + + QMap perLayerFields; + for ( QString layerName : requiredFields.keys() ) + mPerLayerFields[layerName] = QgsVectorTileUtils::makeQgisFields( requiredFields[layerName] ); + + if ( !isAsync ) + { + for ( QgsVectorTileRawData &rawTile : rawTiles ) + { + if ( ctx.renderingStopped() ) + break; + + decodeAndDrawTile( rawTile ); + } + } + else + { + // Block until tiles are fetched and rendered. If the rendering gets cancelled at some point, + // the async loader will catch the signal, abort requests and return from downloadBlocking() + asyncLoader->downloadBlocking(); + } + + mRenderer->stopRender( ctx ); + + ctx.painter()->setClipping( false ); + + qDebug() << "DECODE TIME" << mTotalDecodeTime / 1000.; + qDebug() << "DRAW TIME" << mTotalDrawTime / 1000.; + qDebug() << "TOTAL TIME" << tTotal.elapsed() / 1000.; + + return !ctx.renderingStopped(); +} + +void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData &rawTile ) +{ + QgsRenderContext &ctx = *renderContext(); + + qDebug() << "decoding tile " << rawTile.id.zoomLevel() << rawTile.id.column() << rawTile.id.row(); + + QElapsedTimer tLoad; + tLoad.start(); + + // currently only MVT encoding supported + QgsVectorTileMVTDecoder decoder; + if ( !decoder.decode( rawTile.id, rawTile.data ) ) + { + qDebug() << "Failed to parse raw tile data!"; + return; + } + + if ( ctx.renderingStopped() ) + return; + + QgsVectorTileRendererData tile; + tile.id = rawTile.id; + tile.features = decoder.layerFeatures( mPerLayerFields ); + + mTotalDecodeTime += tLoad.elapsed(); + + // calculate tile polygon in screen coordinates + tile.tilePolygon = QgsVectorTileUtils::tilePolygon( rawTile.id, mTileMatrix, ctx.mapToPixel() ); + + if ( ctx.renderingStopped() ) + return; + + // set up clipping so that rendering does not go behind tile's extent + + ctx.painter()->setClipRegion( QRegion( tile.tilePolygon ) ); + + qDebug() << "drawing tile" << tile.id.zoomLevel() << tile.id.column() << tile.id.row(); + + QElapsedTimer tDraw; + tDraw.start(); + + mRenderer->renderTile( tile, ctx ); + mTotalDrawTime += tDraw.elapsed(); + + if ( mDrawTileBoundaries ) + { + ctx.painter()->setClipping( false ); + + QPen pen( Qt::red ); + pen.setWidth( 3 ); + ctx.painter()->setPen( pen ); + ctx.painter()->drawPolygon( tile.tilePolygon ); + } +} diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.h b/src/core/vectortile/qgsvectortilelayerrenderer.h new file mode 100644 index 000000000000..e6b87ee83955 --- /dev/null +++ b/src/core/vectortile/qgsvectortilelayerrenderer.h @@ -0,0 +1,83 @@ +/*************************************************************************** + qgsvectortilelayerrenderer.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILELAYERRENDERER_H +#define QGSVECTORTILELAYERRENDERER_H + +#include "qgsmaplayerrenderer.h" + +class QgsVectorTileLayer; +class QgsVectorTileRawData; + +#include "qgsvectortilerenderer.h" + +/** + * \ingroup core + * This class provides map rendering functionality for vector tile layers. + * In render() function (assumed to be run in a worker thread) it will: + * 1. fetch vector tiles using QgsVectorTileLoader + * 2. decode raw tiles into QgsFeature objects using QgsVectorTileDecoder + * 3. render tiles using a class derived from QgsVectorTileRenderer + * + * \since QGIS 3.14 + */ +class QgsVectorTileLayerRenderer : public QgsMapLayerRenderer +{ + public: + //! Creates the renderer. Always called from main thread, should copy whatever necessary from the layer + QgsVectorTileLayerRenderer( QgsVectorTileLayer *layer, QgsRenderContext &context ); + + virtual bool render() override; + virtual QgsFeedback *feedback() const override { return mFeedback.get(); } + + private: + void decodeAndDrawTile( const QgsVectorTileRawData &rawTile ); + + // data coming from the vector tile layer + + //! Type of the source from which we will be loading tiles (e.g. "xyz" or "mbtiles") + QString mSourceType; + //! Path/URL of the source. Format depends on source type + QString mSourcePath; + //! Minimum zoom level at which source has any valid tiles (negative = unconstrained) + int mSourceMinZoom = -1; + //! Maximum zoom level at which source has any valid tiles (negative = unconstrained) + int mSourceMaxZoom = -1; + //! Tile renderer object to do rendering of individual tiles + std::unique_ptr mRenderer; + + //! Whether to draw boundaries of tiles (useful for debugging) + bool mDrawTileBoundaries = true; + + // temporary data used during rendering process + + //! Feedback object that may be used by the caller to cancel the rendering + std::unique_ptr mFeedback; + //! Zoom level at which we will be rendering + int mTileZoom = 0; + //! Definition of the tile matrix for our zoom level + QgsTileMatrix mTileMatrix; + //!< Block of tiles we will be rendering in that zoom level + QgsTileRange mTileRange; + //! Cached QgsFields object for each sub-layer that will be rendered + QMap mPerLayerFields; + //! Counter of total elapsed time to decode tiles (ms) + int mTotalDecodeTime = 0; + //! Counter of total elapsed time to render tiles (ms) + int mTotalDrawTime = 0; +}; + + +#endif // QGSVECTORTILELAYERRENDERER_H diff --git a/src/core/vectortile/qgsvectortileloader.cpp b/src/core/vectortile/qgsvectortileloader.cpp new file mode 100644 index 000000000000..e6e22d7fcfc2 --- /dev/null +++ b/src/core/vectortile/qgsvectortileloader.cpp @@ -0,0 +1,265 @@ +/*************************************************************************** + qgsvectortileloader.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsvectortileloader.h" + +#include +#include + +#include + +#include "qgsblockingnetworkrequest.h" +#include "qgsmbtilesreader.h" +#include "qgsnetworkaccessmanager.h" +#include "qgsvectortileutils.h" + +QgsVectorTileLoader::QgsVectorTileLoader( const QString &uri, int zoomLevel, const QgsTileRange &range, const QPointF &viewCenter, QgsFeedback *feedback ) + : mEventLoop( new QEventLoop ) + , mFeedback( feedback ) +{ + if ( feedback ) + { + connect( feedback, &QgsFeedback::canceled, this, &QgsVectorTileLoader::canceled, Qt::QueuedConnection ); + + // rendering could have been canceled before we started to listen to canceled() signal + // so let's check before doing the download and maybe quit prematurely + if ( feedback->isCanceled() ) + return; + } + + qDebug() << "starting loader"; + QVector tiles = QgsVectorTileUtils::tilesInRange( range, zoomLevel ); + QgsVectorTileUtils::sortTilesByDistanceFromCenter( tiles, viewCenter ); + for ( QgsTileXYZ id : qgis::as_const( tiles ) ) + { + loadFromNetworkAsync( id, uri ); + } +} + +QgsVectorTileLoader::~QgsVectorTileLoader() +{ + qDebug() << "terminating loader"; + + if ( !mReplies.isEmpty() ) + { + // this can happen when the loader is terminated without getting requests finalized + // (e.g. downloadBlocking() was not called) + canceled(); + } +} + +void QgsVectorTileLoader::downloadBlocking() +{ + qDebug() << "starting event loop" << mReplies.count() << "requests"; + + if ( mFeedback && mFeedback->isCanceled() ) + { + qDebug() << "actually not - we were cancelled"; + return; // nothing to do + } + + mEventLoop->exec( QEventLoop::ExcludeUserInputEvents ); + + qDebug() << "download blocking finished"; + + Q_ASSERT( mReplies.isEmpty() ); +} + +void QgsVectorTileLoader::loadFromNetworkAsync( const QgsTileXYZ &id, const QString &requestUrl ) +{ + QString url = QgsVectorTileUtils::formatXYZUrlTemplate( requestUrl, id ); + QNetworkRequest request( url ); + // TODO: some extra headers? QgsSetRequestInitiatorClass / auth / "Accept" header + request.setAttribute( static_cast( QNetworkRequest::User + 1 ), id.column() ); + request.setAttribute( static_cast( QNetworkRequest::User + 2 ), id.row() ); + request.setAttribute( static_cast( QNetworkRequest::User + 3 ), id.zoomLevel() ); + + request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache ); + request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); + + QNetworkReply *reply = QgsNetworkAccessManager::instance()->get( request ); + connect( reply, &QNetworkReply::finished, this, &QgsVectorTileLoader::tileReplyFinished ); + + mReplies << reply; +} + +void QgsVectorTileLoader::tileReplyFinished() +{ + QNetworkReply *reply = qobject_cast( sender() ); + + int reqX = reply->request().attribute( static_cast( QNetworkRequest::User + 1 ) ).toInt(); + int reqY = reply->request().attribute( static_cast( QNetworkRequest::User + 2 ) ).toInt(); + int reqZ = reply->request().attribute( static_cast( QNetworkRequest::User + 3 ) ).toInt(); + QgsTileXYZ tileID( reqX, reqY, reqZ ); + + if ( reply->error() == QNetworkReply::NoError ) + { + // TODO: handle redirections? + + qDebug() << "tile reply - all good!"; + QByteArray rawData = reply->readAll(); + mReplies.removeOne( reply ); + reply->deleteLater(); + + emit tileRequestFinished( QgsVectorTileRawData( tileID, rawData ) ); + } + else + { + qDebug() << "tile reply - error! " << reply->errorString(); + mReplies.removeOne( reply ); + reply->deleteLater(); + + emit tileRequestFinished( QgsVectorTileRawData( tileID, QByteArray() ) ); + } + + if ( mReplies.isEmpty() ) + { + // exist the event loop + QMetaObject::invokeMethod( mEventLoop.get(), "quit", Qt::QueuedConnection ); + } +} + +void QgsVectorTileLoader::canceled() +{ + qDebug() << "cancelling pending requests"; + const QList replies = mReplies; + for ( QNetworkReply *reply : replies ) + { + qDebug() << "aborting request"; + reply->abort(); + } +} + +////// + +QList QgsVectorTileLoader::blockingFetchTileRawData( const QString &sourceType, const QString &sourcePath, int zoomLevel, const QPointF &viewCenter, const QgsTileRange &range ) +{ + QList rawTiles; + + QgsMBTilesReader mbReader( sourcePath ); + bool isUrl = ( sourceType == "xyz" ); + if ( !isUrl ) + { + bool res = mbReader.open(); + Q_ASSERT( res ); + } + + QVector tiles = QgsVectorTileUtils::tilesInRange( range, zoomLevel ); + QgsVectorTileUtils::sortTilesByDistanceFromCenter( tiles, viewCenter ); + for ( QgsTileXYZ id : qgis::as_const( tiles ) ) + { + QByteArray rawData = isUrl ? loadFromNetwork( id, sourcePath ) : loadFromMBTiles( id, mbReader ); + if ( !rawData.isEmpty() ) + { + rawTiles.append( QgsVectorTileRawData( id, rawData ) ); + } + } + return rawTiles; +} + +QByteArray QgsVectorTileLoader::loadFromNetwork( const QgsTileXYZ &id, const QString &requestUrl ) +{ + QString url = QgsVectorTileUtils::formatXYZUrlTemplate( requestUrl, id ); + QNetworkRequest nr; + nr.setUrl( QUrl( url ) ); + QgsBlockingNetworkRequest req; + qDebug() << "requestiong" << url; + QgsBlockingNetworkRequest::ErrorCode errCode = req.get( nr ); + qDebug() << "get" << errCode; + QgsNetworkReplyContent reply = req.reply(); + qDebug() << "content size" << reply.content().size(); + return reply.content(); +} + + +QByteArray QgsVectorTileLoader::loadFromMBTiles( const QgsTileXYZ &id, QgsMBTilesReader &mbTileReader ) +{ + // MBTiles uses TMS specs with Y starting at the bottom while XYZ uses Y starting at the top + int rowTMS = pow( 2, id.zoomLevel() ) - id.row() - 1; + QByteArray gzippedTileData = mbTileReader.tileData( id.zoomLevel(), id.column(), rowTMS ); + if ( gzippedTileData.isEmpty() ) + { + qDebug() << "Failed to get tile" << id.zoomLevel() << id.column() << id.row(); + return QByteArray(); + } + + // TODO: check format is "pbf" + + QByteArray data; + if ( !decodeGzip( gzippedTileData, data ) ) + { + qDebug() << "failed to decompress tile" << id.zoomLevel() << id.column() << id.row(); + return QByteArray(); + } + + qDebug() << "tile blob size" << gzippedTileData.size() << " -> uncompressed size" << data.size(); + return data; +} + + +bool QgsVectorTileLoader::decodeGzip( const QByteArray &bytesIn, QByteArray &bytesOut ) +{ + unsigned char *bytesInPtr = reinterpret_cast( const_cast( bytesIn.constData() ) ); + uint bytesInLeft = static_cast( bytesIn.count() ); + + const uint CHUNK = 16384; + unsigned char out[CHUNK]; + const int DEC_MAGIC_NUM_FOR_GZIP = 16; + + // allocate inflate state + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + int ret = inflateInit2( &strm, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP ); + if ( ret != Z_OK ) + return false; + + while ( ret != Z_STREAM_END ) // done when inflate() says it's done + { + // prepare next chunk + uint bytesToProcess = std::min( CHUNK, bytesInLeft ); + strm.next_in = bytesInPtr; + strm.avail_in = bytesToProcess; + bytesInPtr += bytesToProcess; + bytesInLeft -= bytesToProcess; + + if ( bytesToProcess == 0 ) + break; // we end with an error - no more data but inflate() wants more data + + // run inflate() on input until output buffer not full + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate( &strm, Z_NO_FLUSH ); + Q_ASSERT( ret != Z_STREAM_ERROR ); // state not clobbered + if ( ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR ) + { + inflateEnd( &strm ); + return false; + } + unsigned have = CHUNK - strm.avail_out; + bytesOut.append( QByteArray::fromRawData( reinterpret_cast( out ), static_cast( have ) ) ); + } + while ( strm.avail_out == 0 ); + } + + inflateEnd( &strm ); + return ret == Z_STREAM_END; +} diff --git a/src/core/vectortile/qgsvectortileloader.h b/src/core/vectortile/qgsvectortileloader.h new file mode 100644 index 000000000000..e1ca631b1e2a --- /dev/null +++ b/src/core/vectortile/qgsvectortileloader.h @@ -0,0 +1,100 @@ +/*************************************************************************** + qgsvectortileloader.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILELOADER_H +#define QGSVECTORTILELOADER_H + +class QByteArray; + +#include "qgsvectortilerenderer.h" + +/** + * \ingroup core + * Keeps track of raw tile data that need to be decoded + * + * \since QGIS 3.14 + */ +class QgsVectorTileRawData +{ + public: + QgsVectorTileRawData( QgsTileXYZ tileID = QgsTileXYZ(), const QByteArray &raw = QByteArray() ) + : id( tileID ), data( raw ) {} + + //! Tile position in tile matrix set + QgsTileXYZ id; + //! Raw tile data + QByteArray data; +}; + + +class QNetworkReply; +class QEventLoop; + +class QgsMBTilesReader; + +/** + * \ingroup core + * The loader class takes care of loading raw vector tile data from a tile source. + * + * \since QGIS 3.14 + */ +class QgsVectorTileLoader : public QObject +{ + Q_OBJECT + public: + + //! Returns raw tile data for the specified range of tiles. Blocks the caller until all tiles are fetched. + static QList blockingFetchTileRawData( const QString &sourceType, const QString &sourcePath, int zoomLevel, const QPointF &viewCenter, const QgsTileRange &range ); + + //! Returns raw tile data for a single tile, doing a HTTP request. Block the caller until tile data are downloaded. + static QByteArray loadFromNetwork( const QgsTileXYZ &id, const QString &requestUrl ); + //! Returns raw tile data for a signle tile loaded from MBTiles file + static QByteArray loadFromMBTiles( const QgsTileXYZ &id, QgsMBTilesReader &mbTileReader ); + //! Decodes gzip byte stream, returns true on success + static bool decodeGzip( const QByteArray &bytesIn, QByteArray &bytesOut ); + + // + // non-static stuff + // + + //! Constructs tile loader for doing asynchronous requests and starts network requests + QgsVectorTileLoader( const QString &uri, int zoomLevel, const QgsTileRange &range, const QPointF &viewCenter, QgsFeedback *feedback ); + ~QgsVectorTileLoader(); + + //! Blocks the caller until all asynchronous requests are finished (with a success or a failure) + void downloadBlocking(); + + private: + void loadFromNetworkAsync( const QgsTileXYZ &id, const QString &requestUrl ); + + private slots: + void tileReplyFinished(); + void canceled(); + + signals: + //! Emitted when a tile request has finished. If a tile request has failed, the returned raw tile byte array is empty. + void tileRequestFinished( const QgsVectorTileRawData &rawTile ); + + private: + //! Event loop used for blocking download + std::unique_ptr mEventLoop; + //! Feedback object that allows cancellation of pending requests + QgsFeedback *mFeedback; + //! Running tile requests + QList mReplies; + +}; + +#endif // QGSVECTORTILELOADER_H diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.cpp b/src/core/vectortile/qgsvectortilemvtdecoder.cpp new file mode 100644 index 000000000000..67f862cf0456 --- /dev/null +++ b/src/core/vectortile/qgsvectortilemvtdecoder.cpp @@ -0,0 +1,322 @@ +/*************************************************************************** + qgsvectortilemvtdecoder.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include + +#include "qgsvectortilemvtdecoder.h" + +#include "qgsvectortilelayerrenderer.h" +#include "qgsvectortileutils.h" + +#include "qgsmultipoint.h" +#include "qgslinestring.h" +#include "qgsmultilinestring.h" +#include "qgsmultipolygon.h" +#include "qgspolygon.h" + + +inline bool _isExteriorRing( const QVector &pts ) +{ + // Exterior rings have POSITIVE area while interior rings have NEGATIVE area + // when calculated with https://en.wikipedia.org/wiki/Shoelace_formula + // The orientation of axes is that X grows to the right and Y grows to the bottom. + // the input data are expected to form a closed ring, i.e. first pt == last pt. + + double total = 0.0; + const QgsPoint *ptsPtr = pts.constData(); + int count = pts.count(); + for ( int i = 0; i < count - 1; i++ ) + { + double val = ( pts[i + 1].x() - ptsPtr[i].x() ) * ( ptsPtr[i + 1].y() + pts[i].y() ); + //double val = ptsPtr[i].x() * (-ptsPtr[i+1].y()) - ptsPtr[i+1].x() * (-ptsPtr[i].y()); // gives the same result + total += val; + } + return total >= 0; +} + + +bool QgsVectorTileMVTDecoder::decode( QgsTileXYZ tileID, const QByteArray &rawTileData ) +{ + if ( !tile.ParseFromArray( rawTileData.constData(), rawTileData.count() ) ) + return false; + + mTileID = tileID; + + mLayerNameToIndex.clear(); + for ( int layerNum = 0; layerNum < tile.layers_size(); layerNum++ ) + { + const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum ); + QString layerName = layer.name().c_str(); + mLayerNameToIndex[layerName] = layerNum; + } + return true; +} + +QStringList QgsVectorTileMVTDecoder::layers() const +{ + QStringList layerNames; + for ( int layerNum = 0; layerNum < tile.layers_size(); layerNum++ ) + { + const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum ); + QString layerName = layer.name().c_str(); + layerNames << layerName; + } + return layerNames; +} + +QStringList QgsVectorTileMVTDecoder::layerFieldNames( const QString &layerName ) const +{ + if ( !mLayerNameToIndex.contains( layerName ) ) + return QStringList(); + + const ::vector_tile::Tile_Layer &layer = tile.layers( mLayerNameToIndex[layerName] ); + QStringList fieldNames; + for ( int i = 0; i < layer.keys_size(); ++i ) + { + QString fieldName = layer.keys( i ).c_str(); + fieldNames << fieldName; + } + return fieldNames; +} + +QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap &perLayerFields ) const +{ + QgsVectorTileFeatures features; + + int numTiles = static_cast( pow( 2, mTileID.zoomLevel() ) ); // assuming we won't ever go over 30 zoom levels + double z0xMin = -20037508.3427892, z0yMin = -20037508.3427892; + double z0xMax = 20037508.3427892, z0yMax = 20037508.3427892; + double tileDX = ( z0xMax - z0xMin ) / numTiles; + double tileDY = ( z0yMax - z0yMin ) / numTiles; + double tileXMin = z0xMin + mTileID.column() * tileDX; + double tileYMax = z0yMax - mTileID.row() * tileDY; + + for ( int layerNum = 0; layerNum < tile.layers_size(); layerNum++ ) + { + const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum ); + + QString layerName = layer.name().c_str(); + QVector layerFeatures; + QgsFields layerFields = perLayerFields[layerName]; + + // figure out how field indexes in MVT encoding map to field indexes in QgsFields (we may not use all available fields) + QHash tagKeyIndexToFieldIndex; + for ( int i = 0; i < layer.keys_size(); ++i ) + { + int fieldIndex = layerFields.indexOf( layer.keys( i ).c_str() ); + if ( fieldIndex != -1 ) + tagKeyIndexToFieldIndex.insert( i, fieldIndex ); + } + + // go through features of a layer + for ( int featureNum = 0; featureNum < layer.features_size(); featureNum++ ) + { + const ::vector_tile::Tile_Feature &feature = layer.features( featureNum ); + + QgsFeature f( layerFields, static_cast( feature.id() ) ); + + // initialize all fields to empty string. + // TODO: this should not be necessary, but some rules don't like NULL + for ( int i = 0; i < layerFields.count(); ++i ) + f.setAttribute( i, QStringLiteral( "" ) ); + + // + // parse attributes + // + + for ( int tagNum = 0; tagNum < feature.tags_size(); tagNum += 2 ) + { + int keyIndex = static_cast( feature.tags( tagNum ) ); + int fieldIndex = tagKeyIndexToFieldIndex.value( keyIndex, -1 ); + if ( fieldIndex == -1 ) + continue; + + int valueIndex = static_cast( feature.tags( tagNum + 1 ) ); + const ::vector_tile::Tile_Value &value = layer.values( valueIndex ); + + if ( value.has_string_value() ) + f.setAttribute( fieldIndex, QString::fromStdString( value.string_value() ) ); + else if ( value.has_float_value() ) + f.setAttribute( fieldIndex, static_cast( value.float_value() ) ); + else if ( value.has_double_value() ) + f.setAttribute( fieldIndex, value.double_value() ); + else if ( value.has_int_value() ) + f.setAttribute( fieldIndex, static_cast( value.int_value() ) ); + else if ( value.has_uint_value() ) + f.setAttribute( fieldIndex, static_cast( value.uint_value() ) ); + else if ( value.has_sint_value() ) + f.setAttribute( fieldIndex, static_cast( value.sint_value() ) ); + else if ( value.has_bool_value() ) + f.setAttribute( fieldIndex, static_cast( value.bool_value() ) ); // or keep it bool? (do we have good support for that?) + else + { + // TODO: report - should not happen + Q_ASSERT( false ); + } + } + + // + // parse geometry + // + + int extent = static_cast( layer.extent() ); + int cursorx = 0, cursory = 0; + + QVector outputPoints; // for point/multi-point + QVector outputLinestrings; // for linestring/multi-linestring + QVector outputPolygons; + QVector tmpPoints; + + for ( int i = 0; i < feature.geometry_size(); i ++ ) + { + unsigned g = feature.geometry( i ); + unsigned cmdId = g & 0x7; + unsigned cmdCount = g >> 3; + if ( cmdId == 1 ) // MoveTo + { + for ( unsigned j = 0; j < cmdCount; j++ ) + { + unsigned v = feature.geometry( i + 1 ); + unsigned w = feature.geometry( i + 2 ); + int dx = ( ( v >> 1 ) ^ ( -( v & 1 ) ) ); + int dy = ( ( w >> 1 ) ^ ( -( w & 1 ) ) ); + cursorx += dx; + cursory += dy; + double px = tileXMin + tileDX * double( cursorx ) / double( extent ); + double py = tileYMax - tileDY * double( cursory ) / double( extent ); + + if ( feature.type() == vector_tile::Tile_GeomType_POINT ) + { + outputPoints.append( new QgsPoint( px, py ) ); + } + else if ( feature.type() == vector_tile::Tile_GeomType_LINESTRING ) + { + if ( tmpPoints.size() > 0 ) + { + outputLinestrings.append( new QgsLineString( tmpPoints ) ); + tmpPoints.clear(); + } + tmpPoints.append( QgsPoint( px, py ) ); + } + else if ( feature.type() == vector_tile::Tile_GeomType_POLYGON ) + { + tmpPoints.append( QgsPoint( px, py ) ); + } + i += 2; + } + } + else if ( cmdId == 2 ) // LineTo + { + for ( unsigned j = 0; j < cmdCount; j++ ) + { + unsigned v = feature.geometry( i + 1 ); + unsigned w = feature.geometry( i + 2 ); + int dx = ( ( v >> 1 ) ^ ( -( v & 1 ) ) ); + int dy = ( ( w >> 1 ) ^ ( -( w & 1 ) ) ); + cursorx += dx; + cursory += dy; + double px = tileXMin + tileDX * double( cursorx ) / double( extent ); + double py = tileYMax - tileDY * double( cursory ) / double( extent ); + + tmpPoints.push_back( QgsPoint( px, py ) ); + i += 2; + } + } + else if ( cmdId == 7 ) // ClosePath + { + if ( feature.type() == vector_tile::Tile_GeomType_POLYGON ) + { + tmpPoints.append( tmpPoints.first() ); // close the ring + + if ( _isExteriorRing( tmpPoints ) ) + { + // start a new polygon + QgsPolygon *p = new QgsPolygon; + p->setExteriorRing( new QgsLineString( tmpPoints ) ); + outputPolygons.append( p ); + tmpPoints.clear(); + } + else + { + // interior ring (hole) + Q_ASSERT( outputPolygons.count() != 0 ); // TODO: better error handling + outputPolygons[outputPolygons.count() - 1]->addInteriorRing( new QgsLineString( tmpPoints ) ); + tmpPoints.clear(); + } + } + + } + else + { + qDebug() << "huh?"; // TODO: handle properly + } + } + + QString geomType; + if ( feature.type() == vector_tile::Tile_GeomType_POINT ) + { + geomType = QStringLiteral( "Point" ); + if ( outputPoints.count() == 1 ) + f.setGeometry( QgsGeometry( outputPoints[0] ) ); + else + { + QgsMultiPoint *mp = new QgsMultiPoint; + for ( int k = 0; k < outputPoints.count(); ++k ) + mp->addGeometry( outputPoints[k] ); + f.setGeometry( QgsGeometry( mp ) ); + } + } + else if ( feature.type() == vector_tile::Tile_GeomType_LINESTRING ) + { + geomType = QStringLiteral( "LineString" ); + + // finish the linestring we have started + outputLinestrings.append( new QgsLineString( tmpPoints ) ); + + if ( outputLinestrings.count() == 1 ) + f.setGeometry( QgsGeometry( outputLinestrings[0] ) ); + else + { + QgsMultiLineString *mls = new QgsMultiLineString; + for ( int k = 0; k < outputLinestrings.count(); ++k ) + mls->addGeometry( outputLinestrings[k] ); + f.setGeometry( QgsGeometry( mls ) ); + } + } + else if ( feature.type() == vector_tile::Tile_GeomType_POLYGON ) + { + geomType = QStringLiteral( "Polygon" ); + + if ( outputPolygons.count() == 1 ) + f.setGeometry( QgsGeometry( outputPolygons[0] ) ); + else + { + QgsMultiPolygon *mpl = new QgsMultiPolygon; + for ( int k = 0; k < outputPolygons.count(); ++k ) + mpl->addGeometry( outputPolygons[k] ); + f.setGeometry( QgsGeometry( mpl ) ); + } + } + + f.setAttribute( "ty_pe", geomType ); + + layerFeatures.append( f ); + } + + features[layerName] = layerFeatures; + } + return features; +} diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.h b/src/core/vectortile/qgsvectortilemvtdecoder.h new file mode 100644 index 000000000000..a0e8d10be9ad --- /dev/null +++ b/src/core/vectortile/qgsvectortilemvtdecoder.h @@ -0,0 +1,56 @@ +/*************************************************************************** + qgsvectortilemvtdecoder.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILEMVTDECODER_H +#define QGSVECTORTILEMVTDECODER_H + +class QgsFeature; + +#include +#include + +#include "vector_tile.pb.h" + +#include "qgsvectortilerenderer.h" + +/** + * \ingroup core + * This class is responsible for decoding raw tile data written with Mapbox Vector Tiles encoding. + * + * \since QGIS 3.14 + */ +class QgsVectorTileMVTDecoder +{ + public: + + //! Tries to decode raw tile data, returns true on success + bool decode( QgsTileXYZ tileID, const QByteArray &rawTileData ); + + //! Returns a list of sub-layer names in a tile. It can only be called after a successful decode() + QStringList layers() const; + + //! Returns a list of all field names in a tile. It can only be called after a successful decode() + QStringList layerFieldNames( const QString &layerName ) const; + + //! Returns decoded features grouped by sub-layers. It can only be called after a successful decode() + QgsVectorTileFeatures layerFeatures( const QMap &perLayerFields ) const; + + private: + vector_tile::Tile tile; + QgsTileXYZ mTileID; + QMap mLayerNameToIndex; +}; + +#endif // QGSVECTORTILEMVTDECODER_H diff --git a/src/core/vectortile/qgsvectortilerenderer.h b/src/core/vectortile/qgsvectortilerenderer.h new file mode 100644 index 000000000000..97f4a31286e2 --- /dev/null +++ b/src/core/vectortile/qgsvectortilerenderer.h @@ -0,0 +1,90 @@ +/*************************************************************************** + qgsvectortilerenderer.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILERENDERER_H +#define QGSVECTORTILERENDERER_H + +#include "qgis_core.h" + +#include "qgsfeature.h" + +#include "qgstiles.h" + +class QgsRenderContext; + +//! Features of a vector tile, grouped by sub-layer names (key of the map) +typedef QMap > QgsVectorTileFeatures; + +/** + * \ingroup core + * Contains decoded features of a single vector tile and any other data necessary + * for rendering of it. + * + * \since QGIS 3.14 + */ +struct QgsVectorTileRendererData +{ + //! Position of the tile in the tile matrix set + QgsTileXYZ id; + //! Features of the tile grouped into sub-layers + QgsVectorTileFeatures features; + //! Polygon (made out of four corners of the tile) in screen coordinates calculated from render context + QPolygon tilePolygon; +}; + +/** + * \ingroup core + * Abstract base class for all vector tile renderer implementations. + * + * For rendering it is expected that client code calls: + * 1. startRender() to prepare renderer + * 2. renderTile() for each tile + * 3. stopRender() to clean up renderer and free resources + * + * \since QGIS 3.14 + */ +class CORE_EXPORT QgsVectorTileRenderer +{ + public: + virtual ~QgsVectorTileRenderer() = default; + + //! Returns unique type name of the renderer implementation + virtual QString type() const = 0; + + //! Returns a clone of the renderer + virtual QgsVectorTileRenderer *clone() const = 0; + + //! Initializes rendering. It should be paired with a stopRender() call. + virtual void startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ) = 0; + + //! Returns field names of sub-layers that will be used for rendering. Must be called between startRender/stopRender. + virtual QMap > usedAttributes( const QgsRenderContext & ) = 0; + + //! Finishes rendering and cleans up any resources + virtual void stopRender( QgsRenderContext &context ) = 0; + + //! Renders given vector tile. Must be called between startRender/stopRender. + virtual void renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ) = 0; + + //! Writes renderer's properties to given XML element + virtual void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const = 0; + //! Reads renderer's properties from given XML element + virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) = 0; + //! Resolves references to other objects - second phase of loading - after readXml() + virtual void resolveReferences( const QgsProject &project ) { Q_UNUSED( project ) } + +}; + +#endif // QGSVECTORTILERENDERER_H diff --git a/src/core/vectortile/qgsvectortileutils.cpp b/src/core/vectortile/qgsvectortileutils.cpp new file mode 100644 index 000000000000..85a27a7504ff --- /dev/null +++ b/src/core/vectortile/qgsvectortileutils.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + qgsvectortileutils.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsvectortileutils.h" + +#include + +#include +#include + +#include "qgscoordinatetransform.h" +#include "qgsgeometrycollection.h" +#include "qgsfields.h" +#include "qgsmaptopixel.h" +#include "qgsrectangle.h" +#include "qgsvectorlayer.h" + +#include "qgsvectortilemvtdecoder.h" +#include "qgsvectortilelayer.h" +#include "qgsvectortilerenderer.h" + + + +QPolygon QgsVectorTileUtils::tilePolygon( QgsTileXYZ id, const QgsTileMatrix &tm, const QgsMapToPixel &mtp ) +{ + QgsRectangle r = tm.tileExtent( id ); + QgsPointXY p00a = mtp.transform( r.xMinimum(), r.yMinimum() ); + QgsPointXY p11a = mtp.transform( r.xMaximum(), r.yMaximum() ); + QgsPointXY p01a = mtp.transform( r.xMinimum(), r.yMaximum() ); + QgsPointXY p10a = mtp.transform( r.xMaximum(), r.yMinimum() ); + QPolygon path; + path << p00a.toQPointF().toPoint(); + path << p01a.toQPointF().toPoint(); + path << p11a.toQPointF().toPoint(); + path << p10a.toQPointF().toPoint(); + return path; +} + +QgsFields QgsVectorTileUtils::makeQgisFields( QSet flds ) +{ + QgsFields fields; + for ( QString fieldName : flds ) + { + fields.append( QgsField( fieldName, QVariant::String ) ); + } + return fields; +} + + +int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom ) +{ + qDebug() << "MVT map scale 1 :" << mapScale; + + double s0 = 559082264.0287178; // scale denominator at zoom level 0 of GoogleCRS84Quad + double tileZoom2 = log( s0 / mapScale ) / log( 2 ); + tileZoom2 -= 1; // TODO: it seems that map scale is double (is that because of high-dpi screen?) + int tileZoom = static_cast( round( tileZoom2 ) ); + + if ( tileZoom < sourceMinZoom ) + tileZoom = sourceMinZoom; + if ( tileZoom > sourceMaxZoom ) + tileZoom = sourceMaxZoom; + + return tileZoom; +} + +QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer *mvt, QgsTileXYZ tileID, const QString &layerName ) +{ + QgsVectorTileMVTDecoder decoder; + decoder.decode( tileID, mvt->getRawTile( tileID ) ); + qDebug() << decoder.layers(); + QSet fieldNames = QSet::fromList( decoder.layerFieldNames( layerName ) ); + fieldNames << "ty_pe"; // geom. type + QMap perLayerFields; + QgsFields fields = QgsVectorTileUtils::makeQgisFields( fieldNames ); + perLayerFields[layerName] = fields; + QgsVectorTileFeatures data = decoder.layerFeatures( perLayerFields ); + QgsFeatureList featuresList = data[layerName].toList(); + + // turn all geometries to geom. collections (otherwise they won't be accepted by memory provider) + for ( int i = 0; i < featuresList.count(); ++i ) + { + QgsGeometry g = featuresList[i].geometry(); + QgsGeometryCollection *gc = new QgsGeometryCollection; + const QgsAbstractGeometry *gg = g.constGet(); + if ( const QgsGeometryCollection *ggc = qgsgeometry_cast( gg ) ) + { + for ( int k = 0; k < ggc->numGeometries(); ++k ) + gc->addGeometry( ggc->geometryN( k )->clone() ); + } + else + gc->addGeometry( gg->clone() ); + featuresList[i].setGeometry( QgsGeometry( gc ) ); + } + + QgsVectorLayer *vl = new QgsVectorLayer( "GeometryCollection", layerName, "memory" ); + vl->dataProvider()->addAttributes( fields.toList() ); + vl->updateFields(); + bool res = vl->dataProvider()->addFeatures( featuresList ); + Q_ASSERT( res ); + Q_ASSERT( featuresList.count() == vl->featureCount() ); + vl->updateExtents(); + qDebug() << "layer" << layerName << "features" << vl->featureCount(); + return vl; +} + + +QString QgsVectorTileUtils::formatXYZUrlTemplate( const QString &url, QgsTileXYZ tile ) +{ + QString turl( url ); + + turl.replace( QLatin1String( "{x}" ), QString::number( tile.column() ), Qt::CaseInsensitive ); + // TODO: inverted Y axis +// if ( turl.contains( QLatin1String( "{-y}" ) ) ) +// { +// turl.replace( QLatin1String( "{-y}" ), QString::number( tm.matrixHeight - tile.tileRow - 1 ), Qt::CaseInsensitive ); +// } +// else + { + turl.replace( QLatin1String( "{y}" ), QString::number( tile.row() ), Qt::CaseInsensitive ); + } + turl.replace( QLatin1String( "{z}" ), QString::number( tile.zoomLevel() ), Qt::CaseInsensitive ); + return turl; +} + +//! a helper class for ordering tile requests according to the distance from view center +struct LessThanTileRequest +{ + QPointF center; //!< Center in tile matrix (!) coordinates + bool operator()( const QgsTileXYZ &req1, const QgsTileXYZ &req2 ) + { + QPointF p1( req1.column() + 0.5, req1.row() + 0.5 ); + QPointF p2( req2.column() + 0.5, req2.row() + 0.5 ); + // using chessboard distance (loading order more natural than euclidean/manhattan distance) + double d1 = std::max( std::fabs( center.x() - p1.x() ), std::fabs( center.y() - p1.y() ) ); + double d2 = std::max( std::fabs( center.x() - p2.x() ), std::fabs( center.y() - p2.y() ) ); + return d1 < d2; + } +}; + +QVector QgsVectorTileUtils::tilesInRange( const QgsTileRange &range, int zoomLevel ) +{ + QVector tiles; + for ( int tileRow = range.startRow(); tileRow <= range.endRow(); ++tileRow ) + { + for ( int tileColumn = range.startColumn(); tileColumn <= range.endColumn(); ++tileColumn ) + { + tiles.append( QgsTileXYZ( tileColumn, tileRow, zoomLevel ) ); + } + } + return tiles; +} + +void QgsVectorTileUtils::sortTilesByDistanceFromCenter( QVector &tiles, const QPointF ¢er ) +{ + LessThanTileRequest cmp; + cmp.center = center; + std::sort( tiles.begin(), tiles.end(), cmp ); +} diff --git a/src/core/vectortile/qgsvectortileutils.h b/src/core/vectortile/qgsvectortileutils.h new file mode 100644 index 000000000000..1d484f20c306 --- /dev/null +++ b/src/core/vectortile/qgsvectortileutils.h @@ -0,0 +1,62 @@ +/*************************************************************************** + qgsvectortileutils.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSVECTORTILEUTILS_H +#define QGSVECTORTILEUTILS_H + +#include + +class QPointF; +class QPolygon; + +class QgsCoordinateTransform; +class QgsFields; +class QgsMapToPixel; +class QgsRectangle; +class QgsVectorLayer; + +class QgsTileMatrix; +class QgsTileRange; +struct QgsTileXYZ; +class QgsVectorTileLayer; + +/** + * \ingroup core + * Random utility functions for working with vector tiles + * + * \since QGIS 3.14 + */ +class QgsVectorTileUtils +{ + public: + + //! Returns a list of tiles in the given tile range + static QVector tilesInRange( const QgsTileRange &range, int zoomLevel ); + //! Orders tile requests according to the distance from view center (given in tile matrix coords) + static void sortTilesByDistanceFromCenter( QVector &tiles, const QPointF ¢er ); + + //! Returns polygon (made by four corners of the tile) in screen coordinates + static QPolygon tilePolygon( QgsTileXYZ id, const QgsTileMatrix &tm, const QgsMapToPixel &mtp ); + //! Returns QgsFields instance based on the set of field names + static QgsFields makeQgisFields( QSet flds ); + //! Finds best fitting zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator and allowed zoom level range + static int scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom ); + //! Returns a temporary vector layer for given sub-layer of tile in vector tile layer + static QgsVectorLayer *makeVectorLayerForTile( QgsVectorTileLayer *mvt, QgsTileXYZ tileID, const QString &layerName ); + //! Returns formatted tile URL string replacing {x}, {y}, {z} placeholders + static QString formatXYZUrlTemplate( const QString &url, QgsTileXYZ tile ); +}; + +#endif // QGSVECTORTILEUTILS_H diff --git a/src/core/vectortile/vector_tile.pb.cc b/src/core/vectortile/vector_tile.pb.cc new file mode 100644 index 000000000000..3f66c597f2ce --- /dev/null +++ b/src/core/vectortile/vector_tile.pb.cc @@ -0,0 +1,2527 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: vector_tile.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "vector_tile.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace vector_tile { + +namespace { + +const ::google::protobuf::Descriptor* Tile_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Tile_reflection_ = NULL; +const ::google::protobuf::Descriptor* Tile_Value_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Tile_Value_reflection_ = NULL; +const ::google::protobuf::Descriptor* Tile_Feature_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Tile_Feature_reflection_ = NULL; +const ::google::protobuf::Descriptor* Tile_Layer_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Tile_Layer_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* Tile_GeomType_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_vector_5ftile_2eproto() GOOGLE_ATTRIBUTE_COLD; +void protobuf_AssignDesc_vector_5ftile_2eproto() { + protobuf_AddDesc_vector_5ftile_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "vector_tile.proto"); + GOOGLE_CHECK(file != NULL); + Tile_descriptor_ = file->message_type(0); + static const int Tile_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, layers_), + }; + Tile_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Tile_descriptor_, + Tile::default_instance_, + Tile_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, _has_bits_[0]), + -1, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, _extensions_), + sizeof(Tile), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, _internal_metadata_), + -1); + Tile_Value_descriptor_ = Tile_descriptor_->nested_type(0); + static const int Tile_Value_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, string_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, float_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, double_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, int_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, uint_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, sint_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, bool_value_), + }; + Tile_Value_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Tile_Value_descriptor_, + Tile_Value::default_instance_, + Tile_Value_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, _has_bits_[0]), + -1, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, _extensions_), + sizeof(Tile_Value), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, _internal_metadata_), + -1); + Tile_Feature_descriptor_ = Tile_descriptor_->nested_type(1); + static const int Tile_Feature_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, tags_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, geometry_), + }; + Tile_Feature_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Tile_Feature_descriptor_, + Tile_Feature::default_instance_, + Tile_Feature_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, _has_bits_[0]), + -1, + -1, + sizeof(Tile_Feature), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, _internal_metadata_), + -1); + Tile_Layer_descriptor_ = Tile_descriptor_->nested_type(2); + static const int Tile_Layer_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, features_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, keys_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, values_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, extent_), + }; + Tile_Layer_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Tile_Layer_descriptor_, + Tile_Layer::default_instance_, + Tile_Layer_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, _has_bits_[0]), + -1, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, _extensions_), + sizeof(Tile_Layer), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, _internal_metadata_), + -1); + Tile_GeomType_descriptor_ = Tile_descriptor_->enum_type(0); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_vector_5ftile_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Tile_descriptor_, &Tile::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Tile_Value_descriptor_, &Tile_Value::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Tile_Feature_descriptor_, &Tile_Feature::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Tile_Layer_descriptor_, &Tile_Layer::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_vector_5ftile_2eproto() { + delete Tile::default_instance_; + delete Tile_reflection_; + delete Tile_Value::default_instance_; + delete Tile_Value_reflection_; + delete Tile_Feature::default_instance_; + delete Tile_Feature_reflection_; + delete Tile_Layer::default_instance_; + delete Tile_Layer_reflection_; +} + +void protobuf_AddDesc_vector_5ftile_2eproto() GOOGLE_ATTRIBUTE_COLD; +void protobuf_AddDesc_vector_5ftile_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\021vector_tile.proto\022\013vector_tile\"\300\004\n\004Til" + "e\022\'\n\006layers\030\003 \003(\0132\027.vector_tile.Tile.Lay" + "er\032\241\001\n\005Value\022\024\n\014string_value\030\001 \001(\t\022\023\n\013fl" + "oat_value\030\002 \001(\002\022\024\n\014double_value\030\003 \001(\001\022\021\n" + "\tint_value\030\004 \001(\003\022\022\n\nuint_value\030\005 \001(\004\022\022\n\n" + "sint_value\030\006 \001(\022\022\022\n\nbool_value\030\007 \001(\010*\010\010\010" + "\020\200\200\200\200\002\032s\n\007Feature\022\r\n\002id\030\001 \001(\004:\0010\022\020\n\004tags" + "\030\002 \003(\rB\002\020\001\0221\n\004type\030\003 \001(\0162\032.vector_tile.T" + "ile.GeomType:\007UNKNOWN\022\024\n\010geometry\030\004 \003(\rB" + "\002\020\001\032\255\001\n\005Layer\022\022\n\007version\030\017 \002(\r:\0011\022\014\n\004nam" + "e\030\001 \002(\t\022+\n\010features\030\002 \003(\0132\031.vector_tile." + "Tile.Feature\022\014\n\004keys\030\003 \003(\t\022\'\n\006values\030\004 \003" + "(\0132\027.vector_tile.Tile.Value\022\024\n\006extent\030\005 " + "\001(\r:\0044096*\010\010\020\020\200\200\200\200\002\"\?\n\010GeomType\022\013\n\007UNKNO" + "WN\020\000\022\t\n\005POINT\020\001\022\016\n\nLINESTRING\020\002\022\013\n\007POLYG" + "ON\020\003*\005\010\020\020\200@", 611); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "vector_tile.proto", &protobuf_RegisterTypes); + Tile::default_instance_ = new Tile(); + Tile_Value::default_instance_ = new Tile_Value(); + Tile_Feature::default_instance_ = new Tile_Feature(); + Tile_Layer::default_instance_ = new Tile_Layer(); + Tile::default_instance_->InitAsDefaultInstance(); + Tile_Value::default_instance_->InitAsDefaultInstance(); + Tile_Feature::default_instance_->InitAsDefaultInstance(); + Tile_Layer::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_vector_5ftile_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_vector_5ftile_2eproto { + StaticDescriptorInitializer_vector_5ftile_2eproto() { + protobuf_AddDesc_vector_5ftile_2eproto(); + } +} static_descriptor_initializer_vector_5ftile_2eproto_; + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* Tile_GeomType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Tile_GeomType_descriptor_; +} +bool Tile_GeomType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const Tile_GeomType Tile::UNKNOWN; +const Tile_GeomType Tile::POINT; +const Tile_GeomType Tile::LINESTRING; +const Tile_GeomType Tile::POLYGON; +const Tile_GeomType Tile::GeomType_MIN; +const Tile_GeomType Tile::GeomType_MAX; +const int Tile::GeomType_ARRAYSIZE; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int Tile_Value::kStringValueFieldNumber; +const int Tile_Value::kFloatValueFieldNumber; +const int Tile_Value::kDoubleValueFieldNumber; +const int Tile_Value::kIntValueFieldNumber; +const int Tile_Value::kUintValueFieldNumber; +const int Tile_Value::kSintValueFieldNumber; +const int Tile_Value::kBoolValueFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +Tile_Value::Tile_Value() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:vector_tile.Tile.Value) +} + +void Tile_Value::InitAsDefaultInstance() { +} + +Tile_Value::Tile_Value(const Tile_Value& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:vector_tile.Tile.Value) +} + +void Tile_Value::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + float_value_ = 0; + double_value_ = 0; + int_value_ = GOOGLE_LONGLONG(0); + uint_value_ = GOOGLE_ULONGLONG(0); + sint_value_ = GOOGLE_LONGLONG(0); + bool_value_ = false; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Tile_Value::~Tile_Value() { + // @@protoc_insertion_point(destructor:vector_tile.Tile.Value) + SharedDtor(); +} + +void Tile_Value::SharedDtor() { + string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void Tile_Value::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Tile_Value::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Tile_Value_descriptor_; +} + +const Tile_Value& Tile_Value::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); + return *default_instance_; +} + +Tile_Value* Tile_Value::default_instance_ = NULL; + +Tile_Value* Tile_Value::New(::google::protobuf::Arena* arena) const { + Tile_Value* n = new Tile_Value; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Tile_Value::Clear() { +// @@protoc_insertion_point(message_clear_start:vector_tile.Tile.Value) + _extensions_.Clear(); +#if defined(__clang__) +#define ZR_HELPER_(f) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ + __builtin_offsetof(Tile_Value, f) \ + _Pragma("clang diagnostic pop") +#else +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) +#endif + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + if (_has_bits_[0 / 32] & 127u) { + ZR_(double_value_, sint_value_); + if (has_string_value()) { + string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + } + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool Tile_Value::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:vector_tile.Tile.Value) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string string_value = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_string_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->string_value().data(), this->string_value().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "vector_tile.Tile.Value.string_value"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(21)) goto parse_float_value; + break; + } + + // optional float float_value = 2; + case 2: { + if (tag == 21) { + parse_float_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &float_value_))); + set_has_float_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(25)) goto parse_double_value; + break; + } + + // optional double double_value = 3; + case 3: { + if (tag == 25) { + parse_double_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &double_value_))); + set_has_double_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_int_value; + break; + } + + // optional int64 int_value = 4; + case 4: { + if (tag == 32) { + parse_int_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &int_value_))); + set_has_int_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_uint_value; + break; + } + + // optional uint64 uint_value = 5; + case 5: { + if (tag == 40) { + parse_uint_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &uint_value_))); + set_has_uint_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_sint_value; + break; + } + + // optional sint64 sint_value = 6; + case 6: { + if (tag == 48) { + parse_sint_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_SINT64>( + input, &sint_value_))); + set_has_sint_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_bool_value; + break; + } + + // optional bool bool_value = 7; + case 7: { + if (tag == 56) { + parse_bool_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &bool_value_))); + set_has_bool_value(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + if ((64u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:vector_tile.Tile.Value) + return true; +failure: + // @@protoc_insertion_point(parse_failure:vector_tile.Tile.Value) + return false; +#undef DO_ +} + +void Tile_Value::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:vector_tile.Tile.Value) + // optional string string_value = 1; + if (has_string_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->string_value().data(), this->string_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "vector_tile.Tile.Value.string_value"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->string_value(), output); + } + + // optional float float_value = 2; + if (has_float_value()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->float_value(), output); + } + + // optional double double_value = 3; + if (has_double_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->double_value(), output); + } + + // optional int64 int_value = 4; + if (has_int_value()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->int_value(), output); + } + + // optional uint64 uint_value = 5; + if (has_uint_value()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(5, this->uint_value(), output); + } + + // optional sint64 sint_value = 6; + if (has_sint_value()) { + ::google::protobuf::internal::WireFormatLite::WriteSInt64(6, this->sint_value(), output); + } + + // optional bool bool_value = 7; + if (has_bool_value()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->bool_value(), output); + } + + // Extension range [8, 536870912) + _extensions_.SerializeWithCachedSizes( + 8, 536870912, output); + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:vector_tile.Tile.Value) +} + +::google::protobuf::uint8* Tile_Value::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile.Value) + // optional string string_value = 1; + if (has_string_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->string_value().data(), this->string_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "vector_tile.Tile.Value.string_value"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->string_value(), target); + } + + // optional float float_value = 2; + if (has_float_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(2, this->float_value(), target); + } + + // optional double double_value = 3; + if (has_double_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->double_value(), target); + } + + // optional int64 int_value = 4; + if (has_int_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->int_value(), target); + } + + // optional uint64 uint_value = 5; + if (has_uint_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(5, this->uint_value(), target); + } + + // optional sint64 sint_value = 6; + if (has_sint_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteSInt64ToArray(6, this->sint_value(), target); + } + + // optional bool bool_value = 7; + if (has_bool_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->bool_value(), target); + } + + // Extension range [8, 536870912) + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 8, 536870912, false, target); + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile.Value) + return target; +} + +int Tile_Value::ByteSize() const { +// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile.Value) + int total_size = 0; + + if (_has_bits_[0 / 32] & 127u) { + // optional string string_value = 1; + if (has_string_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->string_value()); + } + + // optional float float_value = 2; + if (has_float_value()) { + total_size += 1 + 4; + } + + // optional double double_value = 3; + if (has_double_value()) { + total_size += 1 + 8; + } + + // optional int64 int_value = 4; + if (has_int_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->int_value()); + } + + // optional uint64 uint_value = 5; + if (has_uint_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->uint_value()); + } + + // optional sint64 sint_value = 6; + if (has_sint_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::SInt64Size( + this->sint_value()); + } + + // optional bool bool_value = 7; + if (has_bool_value()) { + total_size += 1 + 1; + } + + } + total_size += _extensions_.ByteSize(); + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Tile_Value::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile.Value) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + const Tile_Value* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile.Value) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile.Value) + MergeFrom(*source); + } +} + +void Tile_Value::MergeFrom(const Tile_Value& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile.Value) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_string_value()) { + set_has_string_value(); + string_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.string_value_); + } + if (from.has_float_value()) { + set_float_value(from.float_value()); + } + if (from.has_double_value()) { + set_double_value(from.double_value()); + } + if (from.has_int_value()) { + set_int_value(from.int_value()); + } + if (from.has_uint_value()) { + set_uint_value(from.uint_value()); + } + if (from.has_sint_value()) { + set_sint_value(from.sint_value()); + } + if (from.has_bool_value()) { + set_bool_value(from.bool_value()); + } + } + _extensions_.MergeFrom(from._extensions_); + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void Tile_Value::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile.Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Tile_Value::CopyFrom(const Tile_Value& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile.Value) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Tile_Value::IsInitialized() const { + + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void Tile_Value::Swap(Tile_Value* other) { + if (other == this) return; + InternalSwap(other); +} +void Tile_Value::InternalSwap(Tile_Value* other) { + string_value_.Swap(&other->string_value_); + std::swap(float_value_, other->float_value_); + std::swap(double_value_, other->double_value_); + std::swap(int_value_, other->int_value_); + std::swap(uint_value_, other->uint_value_); + std::swap(sint_value_, other->sint_value_); + std::swap(bool_value_, other->bool_value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); +} + +::google::protobuf::Metadata Tile_Value::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Tile_Value_descriptor_; + metadata.reflection = Tile_Value_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int Tile_Feature::kIdFieldNumber; +const int Tile_Feature::kTagsFieldNumber; +const int Tile_Feature::kTypeFieldNumber; +const int Tile_Feature::kGeometryFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +Tile_Feature::Tile_Feature() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:vector_tile.Tile.Feature) +} + +void Tile_Feature::InitAsDefaultInstance() { +} + +Tile_Feature::Tile_Feature(const Tile_Feature& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:vector_tile.Tile.Feature) +} + +void Tile_Feature::SharedCtor() { + _cached_size_ = 0; + id_ = GOOGLE_ULONGLONG(0); + type_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Tile_Feature::~Tile_Feature() { + // @@protoc_insertion_point(destructor:vector_tile.Tile.Feature) + SharedDtor(); +} + +void Tile_Feature::SharedDtor() { + if (this != default_instance_) { + } +} + +void Tile_Feature::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Tile_Feature::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Tile_Feature_descriptor_; +} + +const Tile_Feature& Tile_Feature::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); + return *default_instance_; +} + +Tile_Feature* Tile_Feature::default_instance_ = NULL; + +Tile_Feature* Tile_Feature::New(::google::protobuf::Arena* arena) const { + Tile_Feature* n = new Tile_Feature; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Tile_Feature::Clear() { +// @@protoc_insertion_point(message_clear_start:vector_tile.Tile.Feature) + if (_has_bits_[0 / 32] & 5u) { + id_ = GOOGLE_ULONGLONG(0); + type_ = 0; + } + tags_.Clear(); + geometry_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool Tile_Feature::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:vector_tile.Tile.Feature) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional uint64 id = 1 [default = 0]; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &id_))); + set_has_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_tags; + break; + } + + // repeated uint32 tags = 2 [packed = true]; + case 2: { + if (tag == 18) { + parse_tags: + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, this->mutable_tags()))); + } else if (tag == 16) { + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + 1, 18, input, this->mutable_tags()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_type; + break; + } + + // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; + case 3: { + if (tag == 24) { + parse_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::vector_tile::Tile_GeomType_IsValid(value)) { + set_type(static_cast< ::vector_tile::Tile_GeomType >(value)); + } else { + mutable_unknown_fields()->AddVarint(3, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_geometry; + break; + } + + // repeated uint32 geometry = 4 [packed = true]; + case 4: { + if (tag == 34) { + parse_geometry: + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, this->mutable_geometry()))); + } else if (tag == 32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + 1, 34, input, this->mutable_geometry()))); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:vector_tile.Tile.Feature) + return true; +failure: + // @@protoc_insertion_point(parse_failure:vector_tile.Tile.Feature) + return false; +#undef DO_ +} + +void Tile_Feature::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:vector_tile.Tile.Feature) + // optional uint64 id = 1 [default = 0]; + if (has_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->id(), output); + } + + // repeated uint32 tags = 2 [packed = true]; + if (this->tags_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(_tags_cached_byte_size_); + } + for (int i = 0; i < this->tags_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag( + this->tags(i), output); + } + + // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->type(), output); + } + + // repeated uint32 geometry = 4 [packed = true]; + if (this->geometry_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(_geometry_cached_byte_size_); + } + for (int i = 0; i < this->geometry_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag( + this->geometry(i), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:vector_tile.Tile.Feature) +} + +::google::protobuf::uint8* Tile_Feature::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile.Feature) + // optional uint64 id = 1 [default = 0]; + if (has_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->id(), target); + } + + // repeated uint32 tags = 2 [packed = true]; + if (this->tags_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 2, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( + _tags_cached_byte_size_, target); + } + for (int i = 0; i < this->tags_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteUInt32NoTagToArray(this->tags(i), target); + } + + // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 3, this->type(), target); + } + + // repeated uint32 geometry = 4 [packed = true]; + if (this->geometry_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 4, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( + _geometry_cached_byte_size_, target); + } + for (int i = 0; i < this->geometry_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteUInt32NoTagToArray(this->geometry(i), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile.Feature) + return target; +} + +int Tile_Feature::ByteSize() const { +// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile.Feature) + int total_size = 0; + + if (_has_bits_[0 / 32] & 5u) { + // optional uint64 id = 1 [default = 0]; + if (has_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->id()); + } + + // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + } + // repeated uint32 tags = 2 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->tags_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + UInt32Size(this->tags(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _tags_cached_byte_size_ = data_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + total_size += data_size; + } + + // repeated uint32 geometry = 4 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->geometry_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + UInt32Size(this->geometry(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _geometry_cached_byte_size_ = data_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + total_size += data_size; + } + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Tile_Feature::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile.Feature) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + const Tile_Feature* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile.Feature) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile.Feature) + MergeFrom(*source); + } +} + +void Tile_Feature::MergeFrom(const Tile_Feature& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile.Feature) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + tags_.MergeFrom(from.tags_); + geometry_.MergeFrom(from.geometry_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_id()) { + set_id(from.id()); + } + if (from.has_type()) { + set_type(from.type()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void Tile_Feature::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile.Feature) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Tile_Feature::CopyFrom(const Tile_Feature& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile.Feature) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Tile_Feature::IsInitialized() const { + + return true; +} + +void Tile_Feature::Swap(Tile_Feature* other) { + if (other == this) return; + InternalSwap(other); +} +void Tile_Feature::InternalSwap(Tile_Feature* other) { + std::swap(id_, other->id_); + tags_.UnsafeArenaSwap(&other->tags_); + std::swap(type_, other->type_); + geometry_.UnsafeArenaSwap(&other->geometry_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Tile_Feature::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Tile_Feature_descriptor_; + metadata.reflection = Tile_Feature_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int Tile_Layer::kVersionFieldNumber; +const int Tile_Layer::kNameFieldNumber; +const int Tile_Layer::kFeaturesFieldNumber; +const int Tile_Layer::kKeysFieldNumber; +const int Tile_Layer::kValuesFieldNumber; +const int Tile_Layer::kExtentFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +Tile_Layer::Tile_Layer() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:vector_tile.Tile.Layer) +} + +void Tile_Layer::InitAsDefaultInstance() { +} + +Tile_Layer::Tile_Layer(const Tile_Layer& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:vector_tile.Tile.Layer) +} + +void Tile_Layer::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + version_ = 1u; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + extent_ = 4096u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Tile_Layer::~Tile_Layer() { + // @@protoc_insertion_point(destructor:vector_tile.Tile.Layer) + SharedDtor(); +} + +void Tile_Layer::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void Tile_Layer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Tile_Layer::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Tile_Layer_descriptor_; +} + +const Tile_Layer& Tile_Layer::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); + return *default_instance_; +} + +Tile_Layer* Tile_Layer::default_instance_ = NULL; + +Tile_Layer* Tile_Layer::New(::google::protobuf::Arena* arena) const { + Tile_Layer* n = new Tile_Layer; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Tile_Layer::Clear() { +// @@protoc_insertion_point(message_clear_start:vector_tile.Tile.Layer) + _extensions_.Clear(); + if (_has_bits_[0 / 32] & 35u) { + version_ = 1u; + if (has_name()) { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + extent_ = 4096u; + } + features_.Clear(); + keys_.Clear(); + values_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool Tile_Layer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:vector_tile.Tile.Layer) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "vector_tile.Tile.Layer.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_features; + break; + } + + // repeated .vector_tile.Tile.Feature features = 2; + case 2: { + if (tag == 18) { + parse_features: + DO_(input->IncrementRecursionDepth()); + parse_loop_features: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_features())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_loop_features; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(26)) goto parse_keys; + break; + } + + // repeated string keys = 3; + case 3: { + if (tag == 26) { + parse_keys: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_keys())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->keys(this->keys_size() - 1).data(), + this->keys(this->keys_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "vector_tile.Tile.Layer.keys"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_keys; + if (input->ExpectTag(34)) goto parse_values; + break; + } + + // repeated .vector_tile.Tile.Value values = 4; + case 4: { + if (tag == 34) { + parse_values: + DO_(input->IncrementRecursionDepth()); + parse_loop_values: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_values())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_loop_values; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(40)) goto parse_extent; + break; + } + + // optional uint32 extent = 5 [default = 4096]; + case 5: { + if (tag == 40) { + parse_extent: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &extent_))); + set_has_extent(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(120)) goto parse_version; + break; + } + + // required uint32 version = 15 [default = 1]; + case 15: { + if (tag == 120) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &version_))); + set_has_version(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + if ((128u <= tag)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:vector_tile.Tile.Layer) + return true; +failure: + // @@protoc_insertion_point(parse_failure:vector_tile.Tile.Layer) + return false; +#undef DO_ +} + +void Tile_Layer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:vector_tile.Tile.Layer) + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "vector_tile.Tile.Layer.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // repeated .vector_tile.Tile.Feature features = 2; + for (unsigned int i = 0, n = this->features_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->features(i), output); + } + + // repeated string keys = 3; + for (int i = 0; i < this->keys_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->keys(i).data(), this->keys(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "vector_tile.Tile.Layer.keys"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->keys(i), output); + } + + // repeated .vector_tile.Tile.Value values = 4; + for (unsigned int i = 0, n = this->values_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->values(i), output); + } + + // optional uint32 extent = 5 [default = 4096]; + if (has_extent()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->extent(), output); + } + + // required uint32 version = 15 [default = 1]; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(15, this->version(), output); + } + + // Extension range [16, 536870912) + _extensions_.SerializeWithCachedSizes( + 16, 536870912, output); + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:vector_tile.Tile.Layer) +} + +::google::protobuf::uint8* Tile_Layer::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile.Layer) + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "vector_tile.Tile.Layer.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .vector_tile.Tile.Feature features = 2; + for (unsigned int i = 0, n = this->features_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 2, this->features(i), false, target); + } + + // repeated string keys = 3; + for (int i = 0; i < this->keys_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->keys(i).data(), this->keys(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "vector_tile.Tile.Layer.keys"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->keys(i), target); + } + + // repeated .vector_tile.Tile.Value values = 4; + for (unsigned int i = 0, n = this->values_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 4, this->values(i), false, target); + } + + // optional uint32 extent = 5 [default = 4096]; + if (has_extent()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->extent(), target); + } + + // required uint32 version = 15 [default = 1]; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(15, this->version(), target); + } + + // Extension range [16, 536870912) + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 16, 536870912, false, target); + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile.Layer) + return target; +} + +int Tile_Layer::RequiredFieldsByteSizeFallback() const { +// @@protoc_insertion_point(required_fields_byte_size_fallback_start:vector_tile.Tile.Layer) + int total_size = 0; + + if (has_version()) { + // required uint32 version = 15 [default = 1]; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->version()); + } + + if (has_name()) { + // required string name = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + return total_size; +} +int Tile_Layer::ByteSize() const { +// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile.Layer) + int total_size = 0; + + if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present. + // required uint32 version = 15 [default = 1]; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->version()); + + // required string name = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + // optional uint32 extent = 5 [default = 4096]; + if (has_extent()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->extent()); + } + + // repeated .vector_tile.Tile.Feature features = 2; + total_size += 1 * this->features_size(); + for (int i = 0; i < this->features_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->features(i)); + } + + // repeated string keys = 3; + total_size += 1 * this->keys_size(); + for (int i = 0; i < this->keys_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->keys(i)); + } + + // repeated .vector_tile.Tile.Value values = 4; + total_size += 1 * this->values_size(); + for (int i = 0; i < this->values_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->values(i)); + } + + total_size += _extensions_.ByteSize(); + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Tile_Layer::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile.Layer) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + const Tile_Layer* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile.Layer) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile.Layer) + MergeFrom(*source); + } +} + +void Tile_Layer::MergeFrom(const Tile_Layer& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile.Layer) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + features_.MergeFrom(from.features_); + keys_.MergeFrom(from.keys_); + values_.MergeFrom(from.values_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_name()) { + set_has_name(); + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.has_extent()) { + set_extent(from.extent()); + } + } + _extensions_.MergeFrom(from._extensions_); + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void Tile_Layer::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile.Layer) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Tile_Layer::CopyFrom(const Tile_Layer& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile.Layer) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Tile_Layer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->values())) return false; + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void Tile_Layer::Swap(Tile_Layer* other) { + if (other == this) return; + InternalSwap(other); +} +void Tile_Layer::InternalSwap(Tile_Layer* other) { + std::swap(version_, other->version_); + name_.Swap(&other->name_); + features_.UnsafeArenaSwap(&other->features_); + keys_.UnsafeArenaSwap(&other->keys_); + values_.UnsafeArenaSwap(&other->values_); + std::swap(extent_, other->extent_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); +} + +::google::protobuf::Metadata Tile_Layer::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Tile_Layer_descriptor_; + metadata.reflection = Tile_Layer_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int Tile::kLayersFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +Tile::Tile() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:vector_tile.Tile) +} + +void Tile::InitAsDefaultInstance() { +} + +Tile::Tile(const Tile& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:vector_tile.Tile) +} + +void Tile::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Tile::~Tile() { + // @@protoc_insertion_point(destructor:vector_tile.Tile) + SharedDtor(); +} + +void Tile::SharedDtor() { + if (this != default_instance_) { + } +} + +void Tile::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Tile::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Tile_descriptor_; +} + +const Tile& Tile::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); + return *default_instance_; +} + +Tile* Tile::default_instance_ = NULL; + +Tile* Tile::New(::google::protobuf::Arena* arena) const { + Tile* n = new Tile; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Tile::Clear() { +// @@protoc_insertion_point(message_clear_start:vector_tile.Tile) + _extensions_.Clear(); + layers_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool Tile::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:vector_tile.Tile) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .vector_tile.Tile.Layer layers = 3; + case 3: { + if (tag == 26) { + DO_(input->IncrementRecursionDepth()); + parse_loop_layers: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_layers())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_loop_layers; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + if ((128u <= tag && tag < 65536u)) { + DO_(_extensions_.ParseField(tag, input, default_instance_, + mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:vector_tile.Tile) + return true; +failure: + // @@protoc_insertion_point(parse_failure:vector_tile.Tile) + return false; +#undef DO_ +} + +void Tile::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:vector_tile.Tile) + // repeated .vector_tile.Tile.Layer layers = 3; + for (unsigned int i = 0, n = this->layers_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->layers(i), output); + } + + // Extension range [16, 8192) + _extensions_.SerializeWithCachedSizes( + 16, 8192, output); + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:vector_tile.Tile) +} + +::google::protobuf::uint8* Tile::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile) + // repeated .vector_tile.Tile.Layer layers = 3; + for (unsigned int i = 0, n = this->layers_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 3, this->layers(i), false, target); + } + + // Extension range [16, 8192) + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 16, 8192, false, target); + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile) + return target; +} + +int Tile::ByteSize() const { +// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile) + int total_size = 0; + + // repeated .vector_tile.Tile.Layer layers = 3; + total_size += 1 * this->layers_size(); + for (int i = 0; i < this->layers_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->layers(i)); + } + + total_size += _extensions_.ByteSize(); + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Tile::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + const Tile* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile) + MergeFrom(*source); + } +} + +void Tile::MergeFrom(const Tile& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile) + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } + layers_.MergeFrom(from.layers_); + _extensions_.MergeFrom(from._extensions_); + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void Tile::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Tile::CopyFrom(const Tile& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Tile::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->layers())) return false; + + if (!_extensions_.IsInitialized()) return false; return true; +} + +void Tile::Swap(Tile* other) { + if (other == this) return; + InternalSwap(other); +} +void Tile::InternalSwap(Tile* other) { + layers_.UnsafeArenaSwap(&other->layers_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); +} + +::google::protobuf::Metadata Tile::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Tile_descriptor_; + metadata.reflection = Tile_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Tile_Value + +// optional string string_value = 1; +bool Tile_Value::has_string_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void Tile_Value::set_has_string_value() { + _has_bits_[0] |= 0x00000001u; +} +void Tile_Value::clear_has_string_value() { + _has_bits_[0] &= ~0x00000001u; +} +void Tile_Value::clear_string_value() { + string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_string_value(); +} + const ::std::string& Tile_Value::string_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.string_value) + return string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Tile_Value::set_string_value(const ::std::string& value) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.string_value) +} + void Tile_Value::set_string_value(const char* value) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Value.string_value) +} + void Tile_Value::set_string_value(const char* value, size_t size) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Value.string_value) +} + ::std::string* Tile_Value::mutable_string_value() { + set_has_string_value(); + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Value.string_value) + return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Tile_Value::release_string_value() { + // @@protoc_insertion_point(field_release:vector_tile.Tile.Value.string_value) + clear_has_string_value(); + return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Tile_Value::set_allocated_string_value(::std::string* string_value) { + if (string_value != NULL) { + set_has_string_value(); + } else { + clear_has_string_value(); + } + string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value); + // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Value.string_value) +} + +// optional float float_value = 2; +bool Tile_Value::has_float_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void Tile_Value::set_has_float_value() { + _has_bits_[0] |= 0x00000002u; +} +void Tile_Value::clear_has_float_value() { + _has_bits_[0] &= ~0x00000002u; +} +void Tile_Value::clear_float_value() { + float_value_ = 0; + clear_has_float_value(); +} + float Tile_Value::float_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.float_value) + return float_value_; +} + void Tile_Value::set_float_value(float value) { + set_has_float_value(); + float_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.float_value) +} + +// optional double double_value = 3; +bool Tile_Value::has_double_value() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void Tile_Value::set_has_double_value() { + _has_bits_[0] |= 0x00000004u; +} +void Tile_Value::clear_has_double_value() { + _has_bits_[0] &= ~0x00000004u; +} +void Tile_Value::clear_double_value() { + double_value_ = 0; + clear_has_double_value(); +} + double Tile_Value::double_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.double_value) + return double_value_; +} + void Tile_Value::set_double_value(double value) { + set_has_double_value(); + double_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.double_value) +} + +// optional int64 int_value = 4; +bool Tile_Value::has_int_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void Tile_Value::set_has_int_value() { + _has_bits_[0] |= 0x00000008u; +} +void Tile_Value::clear_has_int_value() { + _has_bits_[0] &= ~0x00000008u; +} +void Tile_Value::clear_int_value() { + int_value_ = GOOGLE_LONGLONG(0); + clear_has_int_value(); +} + ::google::protobuf::int64 Tile_Value::int_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.int_value) + return int_value_; +} + void Tile_Value::set_int_value(::google::protobuf::int64 value) { + set_has_int_value(); + int_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.int_value) +} + +// optional uint64 uint_value = 5; +bool Tile_Value::has_uint_value() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +void Tile_Value::set_has_uint_value() { + _has_bits_[0] |= 0x00000010u; +} +void Tile_Value::clear_has_uint_value() { + _has_bits_[0] &= ~0x00000010u; +} +void Tile_Value::clear_uint_value() { + uint_value_ = GOOGLE_ULONGLONG(0); + clear_has_uint_value(); +} + ::google::protobuf::uint64 Tile_Value::uint_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.uint_value) + return uint_value_; +} + void Tile_Value::set_uint_value(::google::protobuf::uint64 value) { + set_has_uint_value(); + uint_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.uint_value) +} + +// optional sint64 sint_value = 6; +bool Tile_Value::has_sint_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +void Tile_Value::set_has_sint_value() { + _has_bits_[0] |= 0x00000020u; +} +void Tile_Value::clear_has_sint_value() { + _has_bits_[0] &= ~0x00000020u; +} +void Tile_Value::clear_sint_value() { + sint_value_ = GOOGLE_LONGLONG(0); + clear_has_sint_value(); +} + ::google::protobuf::int64 Tile_Value::sint_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.sint_value) + return sint_value_; +} + void Tile_Value::set_sint_value(::google::protobuf::int64 value) { + set_has_sint_value(); + sint_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.sint_value) +} + +// optional bool bool_value = 7; +bool Tile_Value::has_bool_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +void Tile_Value::set_has_bool_value() { + _has_bits_[0] |= 0x00000040u; +} +void Tile_Value::clear_has_bool_value() { + _has_bits_[0] &= ~0x00000040u; +} +void Tile_Value::clear_bool_value() { + bool_value_ = false; + clear_has_bool_value(); +} + bool Tile_Value::bool_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.bool_value) + return bool_value_; +} + void Tile_Value::set_bool_value(bool value) { + set_has_bool_value(); + bool_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.bool_value) +} + +// ------------------------------------------------------------------- + +// Tile_Feature + +// optional uint64 id = 1 [default = 0]; +bool Tile_Feature::has_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void Tile_Feature::set_has_id() { + _has_bits_[0] |= 0x00000001u; +} +void Tile_Feature::clear_has_id() { + _has_bits_[0] &= ~0x00000001u; +} +void Tile_Feature::clear_id() { + id_ = GOOGLE_ULONGLONG(0); + clear_has_id(); +} + ::google::protobuf::uint64 Tile_Feature::id() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.id) + return id_; +} + void Tile_Feature::set_id(::google::protobuf::uint64 value) { + set_has_id(); + id_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.id) +} + +// repeated uint32 tags = 2 [packed = true]; +int Tile_Feature::tags_size() const { + return tags_.size(); +} +void Tile_Feature::clear_tags() { + tags_.Clear(); +} + ::google::protobuf::uint32 Tile_Feature::tags(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.tags) + return tags_.Get(index); +} + void Tile_Feature::set_tags(int index, ::google::protobuf::uint32 value) { + tags_.Set(index, value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.tags) +} + void Tile_Feature::add_tags(::google::protobuf::uint32 value) { + tags_.Add(value); + // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.tags) +} + const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& +Tile_Feature::tags() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.tags) + return tags_; +} + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* +Tile_Feature::mutable_tags() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.tags) + return &tags_; +} + +// optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; +bool Tile_Feature::has_type() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void Tile_Feature::set_has_type() { + _has_bits_[0] |= 0x00000004u; +} +void Tile_Feature::clear_has_type() { + _has_bits_[0] &= ~0x00000004u; +} +void Tile_Feature::clear_type() { + type_ = 0; + clear_has_type(); +} + ::vector_tile::Tile_GeomType Tile_Feature::type() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.type) + return static_cast< ::vector_tile::Tile_GeomType >(type_); +} + void Tile_Feature::set_type(::vector_tile::Tile_GeomType value) { + assert(::vector_tile::Tile_GeomType_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.type) +} + +// repeated uint32 geometry = 4 [packed = true]; +int Tile_Feature::geometry_size() const { + return geometry_.size(); +} +void Tile_Feature::clear_geometry() { + geometry_.Clear(); +} + ::google::protobuf::uint32 Tile_Feature::geometry(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.geometry) + return geometry_.Get(index); +} + void Tile_Feature::set_geometry(int index, ::google::protobuf::uint32 value) { + geometry_.Set(index, value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.geometry) +} + void Tile_Feature::add_geometry(::google::protobuf::uint32 value) { + geometry_.Add(value); + // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.geometry) +} + const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& +Tile_Feature::geometry() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.geometry) + return geometry_; +} + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* +Tile_Feature::mutable_geometry() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.geometry) + return &geometry_; +} + +// ------------------------------------------------------------------- + +// Tile_Layer + +// required uint32 version = 15 [default = 1]; +bool Tile_Layer::has_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void Tile_Layer::set_has_version() { + _has_bits_[0] |= 0x00000001u; +} +void Tile_Layer::clear_has_version() { + _has_bits_[0] &= ~0x00000001u; +} +void Tile_Layer::clear_version() { + version_ = 1u; + clear_has_version(); +} + ::google::protobuf::uint32 Tile_Layer::version() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.version) + return version_; +} + void Tile_Layer::set_version(::google::protobuf::uint32 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.version) +} + +// required string name = 1; +bool Tile_Layer::has_name() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void Tile_Layer::set_has_name() { + _has_bits_[0] |= 0x00000002u; +} +void Tile_Layer::clear_has_name() { + _has_bits_[0] &= ~0x00000002u; +} +void Tile_Layer::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} + const ::std::string& Tile_Layer::name() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Tile_Layer::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.name) +} + void Tile_Layer::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.name) +} + void Tile_Layer::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.name) +} + ::std::string* Tile_Layer::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Tile_Layer::release_name() { + // @@protoc_insertion_point(field_release:vector_tile.Tile.Layer.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Tile_Layer::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Layer.name) +} + +// repeated .vector_tile.Tile.Feature features = 2; +int Tile_Layer::features_size() const { + return features_.size(); +} +void Tile_Layer::clear_features() { + features_.Clear(); +} +const ::vector_tile::Tile_Feature& Tile_Layer::features(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.features) + return features_.Get(index); +} +::vector_tile::Tile_Feature* Tile_Layer::mutable_features(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.features) + return features_.Mutable(index); +} +::vector_tile::Tile_Feature* Tile_Layer::add_features() { + // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.features) + return features_.Add(); +} +::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >* +Tile_Layer::mutable_features() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.features) + return &features_; +} +const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >& +Tile_Layer::features() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.features) + return features_; +} + +// repeated string keys = 3; +int Tile_Layer::keys_size() const { + return keys_.size(); +} +void Tile_Layer::clear_keys() { + keys_.Clear(); +} + const ::std::string& Tile_Layer::keys(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.keys) + return keys_.Get(index); +} + ::std::string* Tile_Layer::mutable_keys(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.keys) + return keys_.Mutable(index); +} + void Tile_Layer::set_keys(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.keys) + keys_.Mutable(index)->assign(value); +} + void Tile_Layer::set_keys(int index, const char* value) { + keys_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.keys) +} + void Tile_Layer::set_keys(int index, const char* value, size_t size) { + keys_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.keys) +} + ::std::string* Tile_Layer::add_keys() { + // @@protoc_insertion_point(field_add_mutable:vector_tile.Tile.Layer.keys) + return keys_.Add(); +} + void Tile_Layer::add_keys(const ::std::string& value) { + keys_.Add()->assign(value); + // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.keys) +} + void Tile_Layer::add_keys(const char* value) { + keys_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:vector_tile.Tile.Layer.keys) +} + void Tile_Layer::add_keys(const char* value, size_t size) { + keys_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:vector_tile.Tile.Layer.keys) +} + const ::google::protobuf::RepeatedPtrField< ::std::string>& +Tile_Layer::keys() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.keys) + return keys_; +} + ::google::protobuf::RepeatedPtrField< ::std::string>* +Tile_Layer::mutable_keys() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.keys) + return &keys_; +} + +// repeated .vector_tile.Tile.Value values = 4; +int Tile_Layer::values_size() const { + return values_.size(); +} +void Tile_Layer::clear_values() { + values_.Clear(); +} +const ::vector_tile::Tile_Value& Tile_Layer::values(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.values) + return values_.Get(index); +} +::vector_tile::Tile_Value* Tile_Layer::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.values) + return values_.Mutable(index); +} +::vector_tile::Tile_Value* Tile_Layer::add_values() { + // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.values) + return values_.Add(); +} +::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >* +Tile_Layer::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.values) + return &values_; +} +const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >& +Tile_Layer::values() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.values) + return values_; +} + +// optional uint32 extent = 5 [default = 4096]; +bool Tile_Layer::has_extent() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +void Tile_Layer::set_has_extent() { + _has_bits_[0] |= 0x00000020u; +} +void Tile_Layer::clear_has_extent() { + _has_bits_[0] &= ~0x00000020u; +} +void Tile_Layer::clear_extent() { + extent_ = 4096u; + clear_has_extent(); +} + ::google::protobuf::uint32 Tile_Layer::extent() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.extent) + return extent_; +} + void Tile_Layer::set_extent(::google::protobuf::uint32 value) { + set_has_extent(); + extent_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.extent) +} + +// ------------------------------------------------------------------- + +// Tile + +// repeated .vector_tile.Tile.Layer layers = 3; +int Tile::layers_size() const { + return layers_.size(); +} +void Tile::clear_layers() { + layers_.Clear(); +} +const ::vector_tile::Tile_Layer& Tile::layers(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.layers) + return layers_.Get(index); +} +::vector_tile::Tile_Layer* Tile::mutable_layers(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.layers) + return layers_.Mutable(index); +} +::vector_tile::Tile_Layer* Tile::add_layers() { + // @@protoc_insertion_point(field_add:vector_tile.Tile.layers) + return layers_.Add(); +} +::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >* +Tile::mutable_layers() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.layers) + return &layers_; +} +const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >& +Tile::layers() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.layers) + return layers_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace vector_tile + +// @@protoc_insertion_point(global_scope) diff --git a/src/core/vectortile/vector_tile.pb.h b/src/core/vectortile/vector_tile.pb.h new file mode 100644 index 000000000000..876720072a39 --- /dev/null +++ b/src/core/vectortile/vector_tile.pb.h @@ -0,0 +1,1260 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: vector_tile.proto + +#ifndef PROTOBUF_vector_5ftile_2eproto__INCLUDED +#define PROTOBUF_vector_5ftile_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace vector_tile { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_vector_5ftile_2eproto(); +void protobuf_AssignDesc_vector_5ftile_2eproto(); +void protobuf_ShutdownFile_vector_5ftile_2eproto(); + +class Tile; +class Tile_Feature; +class Tile_Layer; +class Tile_Value; + +enum Tile_GeomType { + Tile_GeomType_UNKNOWN = 0, + Tile_GeomType_POINT = 1, + Tile_GeomType_LINESTRING = 2, + Tile_GeomType_POLYGON = 3 +}; +bool Tile_GeomType_IsValid(int value); +const Tile_GeomType Tile_GeomType_GeomType_MIN = Tile_GeomType_UNKNOWN; +const Tile_GeomType Tile_GeomType_GeomType_MAX = Tile_GeomType_POLYGON; +const int Tile_GeomType_GeomType_ARRAYSIZE = Tile_GeomType_GeomType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* Tile_GeomType_descriptor(); +inline const ::std::string& Tile_GeomType_Name(Tile_GeomType value) { + return ::google::protobuf::internal::NameOfEnum( + Tile_GeomType_descriptor(), value); +} +inline bool Tile_GeomType_Parse( + const ::std::string& name, Tile_GeomType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Tile_GeomType_descriptor(), name, value); +} +// =================================================================== + +class Tile_Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile.Value) */ { + public: + Tile_Value(); + virtual ~Tile_Value(); + + Tile_Value(const Tile_Value& from); + + inline Tile_Value& operator=(const Tile_Value& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Tile_Value& default_instance(); + + void Swap(Tile_Value* other); + + // implements Message ---------------------------------------------- + + inline Tile_Value* New() const { return New(NULL); } + + Tile_Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Tile_Value& from); + void MergeFrom(const Tile_Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Tile_Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string string_value = 1; + bool has_string_value() const; + void clear_string_value(); + static const int kStringValueFieldNumber = 1; + const ::std::string& string_value() const; + void set_string_value(const ::std::string& value); + void set_string_value(const char* value); + void set_string_value(const char* value, size_t size); + ::std::string* mutable_string_value(); + ::std::string* release_string_value(); + void set_allocated_string_value(::std::string* string_value); + + // optional float float_value = 2; + bool has_float_value() const; + void clear_float_value(); + static const int kFloatValueFieldNumber = 2; + float float_value() const; + void set_float_value(float value); + + // optional double double_value = 3; + bool has_double_value() const; + void clear_double_value(); + static const int kDoubleValueFieldNumber = 3; + double double_value() const; + void set_double_value(double value); + + // optional int64 int_value = 4; + bool has_int_value() const; + void clear_int_value(); + static const int kIntValueFieldNumber = 4; + ::google::protobuf::int64 int_value() const; + void set_int_value(::google::protobuf::int64 value); + + // optional uint64 uint_value = 5; + bool has_uint_value() const; + void clear_uint_value(); + static const int kUintValueFieldNumber = 5; + ::google::protobuf::uint64 uint_value() const; + void set_uint_value(::google::protobuf::uint64 value); + + // optional sint64 sint_value = 6; + bool has_sint_value() const; + void clear_sint_value(); + static const int kSintValueFieldNumber = 6; + ::google::protobuf::int64 sint_value() const; + void set_sint_value(::google::protobuf::int64 value); + + // optional bool bool_value = 7; + bool has_bool_value() const; + void clear_bool_value(); + static const int kBoolValueFieldNumber = 7; + bool bool_value() const; + void set_bool_value(bool value); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(Tile_Value) + // @@protoc_insertion_point(class_scope:vector_tile.Tile.Value) + private: + inline void set_has_string_value(); + inline void clear_has_string_value(); + inline void set_has_float_value(); + inline void clear_has_float_value(); + inline void set_has_double_value(); + inline void clear_has_double_value(); + inline void set_has_int_value(); + inline void clear_has_int_value(); + inline void set_has_uint_value(); + inline void clear_has_uint_value(); + inline void set_has_sint_value(); + inline void clear_has_sint_value(); + inline void set_has_bool_value(); + inline void clear_has_bool_value(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr string_value_; + double double_value_; + ::google::protobuf::int64 int_value_; + float float_value_; + bool bool_value_; + ::google::protobuf::uint64 uint_value_; + ::google::protobuf::int64 sint_value_; + friend void protobuf_AddDesc_vector_5ftile_2eproto(); + friend void protobuf_AssignDesc_vector_5ftile_2eproto(); + friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); + + void InitAsDefaultInstance(); + static Tile_Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class Tile_Feature : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile.Feature) */ { + public: + Tile_Feature(); + virtual ~Tile_Feature(); + + Tile_Feature(const Tile_Feature& from); + + inline Tile_Feature& operator=(const Tile_Feature& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Tile_Feature& default_instance(); + + void Swap(Tile_Feature* other); + + // implements Message ---------------------------------------------- + + inline Tile_Feature* New() const { return New(NULL); } + + Tile_Feature* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Tile_Feature& from); + void MergeFrom(const Tile_Feature& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Tile_Feature* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional uint64 id = 1 [default = 0]; + bool has_id() const; + void clear_id(); + static const int kIdFieldNumber = 1; + ::google::protobuf::uint64 id() const; + void set_id(::google::protobuf::uint64 value); + + // repeated uint32 tags = 2 [packed = true]; + int tags_size() const; + void clear_tags(); + static const int kTagsFieldNumber = 2; + ::google::protobuf::uint32 tags(int index) const; + void set_tags(int index, ::google::protobuf::uint32 value); + void add_tags(::google::protobuf::uint32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& + tags() const; + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* + mutable_tags(); + + // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; + bool has_type() const; + void clear_type(); + static const int kTypeFieldNumber = 3; + ::vector_tile::Tile_GeomType type() const; + void set_type(::vector_tile::Tile_GeomType value); + + // repeated uint32 geometry = 4 [packed = true]; + int geometry_size() const; + void clear_geometry(); + static const int kGeometryFieldNumber = 4; + ::google::protobuf::uint32 geometry(int index) const; + void set_geometry(int index, ::google::protobuf::uint32 value); + void add_geometry(::google::protobuf::uint32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& + geometry() const; + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* + mutable_geometry(); + + // @@protoc_insertion_point(class_scope:vector_tile.Tile.Feature) + private: + inline void set_has_id(); + inline void clear_has_id(); + inline void set_has_type(); + inline void clear_has_type(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 id_; + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > tags_; + mutable int _tags_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > geometry_; + mutable int _geometry_cached_byte_size_; + int type_; + friend void protobuf_AddDesc_vector_5ftile_2eproto(); + friend void protobuf_AssignDesc_vector_5ftile_2eproto(); + friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); + + void InitAsDefaultInstance(); + static Tile_Feature* default_instance_; +}; +// ------------------------------------------------------------------- + +class Tile_Layer : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile.Layer) */ { + public: + Tile_Layer(); + virtual ~Tile_Layer(); + + Tile_Layer(const Tile_Layer& from); + + inline Tile_Layer& operator=(const Tile_Layer& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Tile_Layer& default_instance(); + + void Swap(Tile_Layer* other); + + // implements Message ---------------------------------------------- + + inline Tile_Layer* New() const { return New(NULL); } + + Tile_Layer* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Tile_Layer& from); + void MergeFrom(const Tile_Layer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Tile_Layer* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint32 version = 15 [default = 1]; + bool has_version() const; + void clear_version(); + static const int kVersionFieldNumber = 15; + ::google::protobuf::uint32 version() const; + void set_version(::google::protobuf::uint32 value); + + // required string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .vector_tile.Tile.Feature features = 2; + int features_size() const; + void clear_features(); + static const int kFeaturesFieldNumber = 2; + const ::vector_tile::Tile_Feature& features(int index) const; + ::vector_tile::Tile_Feature* mutable_features(int index); + ::vector_tile::Tile_Feature* add_features(); + ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >* + mutable_features(); + const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >& + features() const; + + // repeated string keys = 3; + int keys_size() const; + void clear_keys(); + static const int kKeysFieldNumber = 3; + const ::std::string& keys(int index) const; + ::std::string* mutable_keys(int index); + void set_keys(int index, const ::std::string& value); + void set_keys(int index, const char* value); + void set_keys(int index, const char* value, size_t size); + ::std::string* add_keys(); + void add_keys(const ::std::string& value); + void add_keys(const char* value); + void add_keys(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& keys() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_keys(); + + // repeated .vector_tile.Tile.Value values = 4; + int values_size() const; + void clear_values(); + static const int kValuesFieldNumber = 4; + const ::vector_tile::Tile_Value& values(int index) const; + ::vector_tile::Tile_Value* mutable_values(int index); + ::vector_tile::Tile_Value* add_values(); + ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >* + mutable_values(); + const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >& + values() const; + + // optional uint32 extent = 5 [default = 4096]; + bool has_extent() const; + void clear_extent(); + static const int kExtentFieldNumber = 5; + ::google::protobuf::uint32 extent() const; + void set_extent(::google::protobuf::uint32 value); + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(Tile_Layer) + // @@protoc_insertion_point(class_scope:vector_tile.Tile.Layer) + private: + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_extent(); + inline void clear_has_extent(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature > features_; + ::google::protobuf::uint32 version_; + ::google::protobuf::uint32 extent_; + ::google::protobuf::RepeatedPtrField< ::std::string> keys_; + ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value > values_; + friend void protobuf_AddDesc_vector_5ftile_2eproto(); + friend void protobuf_AssignDesc_vector_5ftile_2eproto(); + friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); + + void InitAsDefaultInstance(); + static Tile_Layer* default_instance_; +}; +// ------------------------------------------------------------------- + +class Tile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile) */ { + public: + Tile(); + virtual ~Tile(); + + Tile(const Tile& from); + + inline Tile& operator=(const Tile& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Tile& default_instance(); + + void Swap(Tile* other); + + // implements Message ---------------------------------------------- + + inline Tile* New() const { return New(NULL); } + + Tile* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Tile& from); + void MergeFrom(const Tile& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Tile* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef Tile_Value Value; + typedef Tile_Feature Feature; + typedef Tile_Layer Layer; + + typedef Tile_GeomType GeomType; + static const GeomType UNKNOWN = + Tile_GeomType_UNKNOWN; + static const GeomType POINT = + Tile_GeomType_POINT; + static const GeomType LINESTRING = + Tile_GeomType_LINESTRING; + static const GeomType POLYGON = + Tile_GeomType_POLYGON; + static inline bool GeomType_IsValid(int value) { + return Tile_GeomType_IsValid(value); + } + static const GeomType GeomType_MIN = + Tile_GeomType_GeomType_MIN; + static const GeomType GeomType_MAX = + Tile_GeomType_GeomType_MAX; + static const int GeomType_ARRAYSIZE = + Tile_GeomType_GeomType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + GeomType_descriptor() { + return Tile_GeomType_descriptor(); + } + static inline const ::std::string& GeomType_Name(GeomType value) { + return Tile_GeomType_Name(value); + } + static inline bool GeomType_Parse(const ::std::string& name, + GeomType* value) { + return Tile_GeomType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // repeated .vector_tile.Tile.Layer layers = 3; + int layers_size() const; + void clear_layers(); + static const int kLayersFieldNumber = 3; + const ::vector_tile::Tile_Layer& layers(int index) const; + ::vector_tile::Tile_Layer* mutable_layers(int index); + ::vector_tile::Tile_Layer* add_layers(); + ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >* + mutable_layers(); + const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >& + layers() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(Tile) + // @@protoc_insertion_point(class_scope:vector_tile.Tile) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer > layers_; + friend void protobuf_AddDesc_vector_5ftile_2eproto(); + friend void protobuf_AssignDesc_vector_5ftile_2eproto(); + friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); + + void InitAsDefaultInstance(); + static Tile* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Tile_Value + +// optional string string_value = 1; +inline bool Tile_Value::has_string_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Tile_Value::set_has_string_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void Tile_Value::clear_has_string_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Tile_Value::clear_string_value() { + string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_string_value(); +} +inline const ::std::string& Tile_Value::string_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.string_value) + return string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Tile_Value::set_string_value(const ::std::string& value) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.string_value) +} +inline void Tile_Value::set_string_value(const char* value) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Value.string_value) +} +inline void Tile_Value::set_string_value(const char* value, size_t size) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Value.string_value) +} +inline ::std::string* Tile_Value::mutable_string_value() { + set_has_string_value(); + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Value.string_value) + return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Tile_Value::release_string_value() { + // @@protoc_insertion_point(field_release:vector_tile.Tile.Value.string_value) + clear_has_string_value(); + return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Tile_Value::set_allocated_string_value(::std::string* string_value) { + if (string_value != NULL) { + set_has_string_value(); + } else { + clear_has_string_value(); + } + string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value); + // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Value.string_value) +} + +// optional float float_value = 2; +inline bool Tile_Value::has_float_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Tile_Value::set_has_float_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void Tile_Value::clear_has_float_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Tile_Value::clear_float_value() { + float_value_ = 0; + clear_has_float_value(); +} +inline float Tile_Value::float_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.float_value) + return float_value_; +} +inline void Tile_Value::set_float_value(float value) { + set_has_float_value(); + float_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.float_value) +} + +// optional double double_value = 3; +inline bool Tile_Value::has_double_value() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Tile_Value::set_has_double_value() { + _has_bits_[0] |= 0x00000004u; +} +inline void Tile_Value::clear_has_double_value() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Tile_Value::clear_double_value() { + double_value_ = 0; + clear_has_double_value(); +} +inline double Tile_Value::double_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.double_value) + return double_value_; +} +inline void Tile_Value::set_double_value(double value) { + set_has_double_value(); + double_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.double_value) +} + +// optional int64 int_value = 4; +inline bool Tile_Value::has_int_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Tile_Value::set_has_int_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void Tile_Value::clear_has_int_value() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Tile_Value::clear_int_value() { + int_value_ = GOOGLE_LONGLONG(0); + clear_has_int_value(); +} +inline ::google::protobuf::int64 Tile_Value::int_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.int_value) + return int_value_; +} +inline void Tile_Value::set_int_value(::google::protobuf::int64 value) { + set_has_int_value(); + int_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.int_value) +} + +// optional uint64 uint_value = 5; +inline bool Tile_Value::has_uint_value() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void Tile_Value::set_has_uint_value() { + _has_bits_[0] |= 0x00000010u; +} +inline void Tile_Value::clear_has_uint_value() { + _has_bits_[0] &= ~0x00000010u; +} +inline void Tile_Value::clear_uint_value() { + uint_value_ = GOOGLE_ULONGLONG(0); + clear_has_uint_value(); +} +inline ::google::protobuf::uint64 Tile_Value::uint_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.uint_value) + return uint_value_; +} +inline void Tile_Value::set_uint_value(::google::protobuf::uint64 value) { + set_has_uint_value(); + uint_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.uint_value) +} + +// optional sint64 sint_value = 6; +inline bool Tile_Value::has_sint_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void Tile_Value::set_has_sint_value() { + _has_bits_[0] |= 0x00000020u; +} +inline void Tile_Value::clear_has_sint_value() { + _has_bits_[0] &= ~0x00000020u; +} +inline void Tile_Value::clear_sint_value() { + sint_value_ = GOOGLE_LONGLONG(0); + clear_has_sint_value(); +} +inline ::google::protobuf::int64 Tile_Value::sint_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.sint_value) + return sint_value_; +} +inline void Tile_Value::set_sint_value(::google::protobuf::int64 value) { + set_has_sint_value(); + sint_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.sint_value) +} + +// optional bool bool_value = 7; +inline bool Tile_Value::has_bool_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void Tile_Value::set_has_bool_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void Tile_Value::clear_has_bool_value() { + _has_bits_[0] &= ~0x00000040u; +} +inline void Tile_Value::clear_bool_value() { + bool_value_ = false; + clear_has_bool_value(); +} +inline bool Tile_Value::bool_value() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.bool_value) + return bool_value_; +} +inline void Tile_Value::set_bool_value(bool value) { + set_has_bool_value(); + bool_value_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.bool_value) +} + +// ------------------------------------------------------------------- + +// Tile_Feature + +// optional uint64 id = 1 [default = 0]; +inline bool Tile_Feature::has_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Tile_Feature::set_has_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void Tile_Feature::clear_has_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Tile_Feature::clear_id() { + id_ = GOOGLE_ULONGLONG(0); + clear_has_id(); +} +inline ::google::protobuf::uint64 Tile_Feature::id() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.id) + return id_; +} +inline void Tile_Feature::set_id(::google::protobuf::uint64 value) { + set_has_id(); + id_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.id) +} + +// repeated uint32 tags = 2 [packed = true]; +inline int Tile_Feature::tags_size() const { + return tags_.size(); +} +inline void Tile_Feature::clear_tags() { + tags_.Clear(); +} +inline ::google::protobuf::uint32 Tile_Feature::tags(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.tags) + return tags_.Get(index); +} +inline void Tile_Feature::set_tags(int index, ::google::protobuf::uint32 value) { + tags_.Set(index, value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.tags) +} +inline void Tile_Feature::add_tags(::google::protobuf::uint32 value) { + tags_.Add(value); + // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.tags) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& +Tile_Feature::tags() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.tags) + return tags_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* +Tile_Feature::mutable_tags() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.tags) + return &tags_; +} + +// optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; +inline bool Tile_Feature::has_type() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Tile_Feature::set_has_type() { + _has_bits_[0] |= 0x00000004u; +} +inline void Tile_Feature::clear_has_type() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Tile_Feature::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::vector_tile::Tile_GeomType Tile_Feature::type() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.type) + return static_cast< ::vector_tile::Tile_GeomType >(type_); +} +inline void Tile_Feature::set_type(::vector_tile::Tile_GeomType value) { + assert(::vector_tile::Tile_GeomType_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.type) +} + +// repeated uint32 geometry = 4 [packed = true]; +inline int Tile_Feature::geometry_size() const { + return geometry_.size(); +} +inline void Tile_Feature::clear_geometry() { + geometry_.Clear(); +} +inline ::google::protobuf::uint32 Tile_Feature::geometry(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.geometry) + return geometry_.Get(index); +} +inline void Tile_Feature::set_geometry(int index, ::google::protobuf::uint32 value) { + geometry_.Set(index, value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.geometry) +} +inline void Tile_Feature::add_geometry(::google::protobuf::uint32 value) { + geometry_.Add(value); + // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.geometry) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& +Tile_Feature::geometry() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.geometry) + return geometry_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* +Tile_Feature::mutable_geometry() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.geometry) + return &geometry_; +} + +// ------------------------------------------------------------------- + +// Tile_Layer + +// required uint32 version = 15 [default = 1]; +inline bool Tile_Layer::has_version() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Tile_Layer::set_has_version() { + _has_bits_[0] |= 0x00000001u; +} +inline void Tile_Layer::clear_has_version() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Tile_Layer::clear_version() { + version_ = 1u; + clear_has_version(); +} +inline ::google::protobuf::uint32 Tile_Layer::version() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.version) + return version_; +} +inline void Tile_Layer::set_version(::google::protobuf::uint32 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.version) +} + +// required string name = 1; +inline bool Tile_Layer::has_name() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Tile_Layer::set_has_name() { + _has_bits_[0] |= 0x00000002u; +} +inline void Tile_Layer::clear_has_name() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Tile_Layer::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& Tile_Layer::name() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Tile_Layer::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.name) +} +inline void Tile_Layer::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.name) +} +inline void Tile_Layer::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.name) +} +inline ::std::string* Tile_Layer::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Tile_Layer::release_name() { + // @@protoc_insertion_point(field_release:vector_tile.Tile.Layer.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Tile_Layer::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Layer.name) +} + +// repeated .vector_tile.Tile.Feature features = 2; +inline int Tile_Layer::features_size() const { + return features_.size(); +} +inline void Tile_Layer::clear_features() { + features_.Clear(); +} +inline const ::vector_tile::Tile_Feature& Tile_Layer::features(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.features) + return features_.Get(index); +} +inline ::vector_tile::Tile_Feature* Tile_Layer::mutable_features(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.features) + return features_.Mutable(index); +} +inline ::vector_tile::Tile_Feature* Tile_Layer::add_features() { + // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.features) + return features_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >* +Tile_Layer::mutable_features() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.features) + return &features_; +} +inline const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >& +Tile_Layer::features() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.features) + return features_; +} + +// repeated string keys = 3; +inline int Tile_Layer::keys_size() const { + return keys_.size(); +} +inline void Tile_Layer::clear_keys() { + keys_.Clear(); +} +inline const ::std::string& Tile_Layer::keys(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.keys) + return keys_.Get(index); +} +inline ::std::string* Tile_Layer::mutable_keys(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.keys) + return keys_.Mutable(index); +} +inline void Tile_Layer::set_keys(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.keys) + keys_.Mutable(index)->assign(value); +} +inline void Tile_Layer::set_keys(int index, const char* value) { + keys_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.keys) +} +inline void Tile_Layer::set_keys(int index, const char* value, size_t size) { + keys_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.keys) +} +inline ::std::string* Tile_Layer::add_keys() { + // @@protoc_insertion_point(field_add_mutable:vector_tile.Tile.Layer.keys) + return keys_.Add(); +} +inline void Tile_Layer::add_keys(const ::std::string& value) { + keys_.Add()->assign(value); + // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.keys) +} +inline void Tile_Layer::add_keys(const char* value) { + keys_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:vector_tile.Tile.Layer.keys) +} +inline void Tile_Layer::add_keys(const char* value, size_t size) { + keys_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:vector_tile.Tile.Layer.keys) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +Tile_Layer::keys() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.keys) + return keys_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +Tile_Layer::mutable_keys() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.keys) + return &keys_; +} + +// repeated .vector_tile.Tile.Value values = 4; +inline int Tile_Layer::values_size() const { + return values_.size(); +} +inline void Tile_Layer::clear_values() { + values_.Clear(); +} +inline const ::vector_tile::Tile_Value& Tile_Layer::values(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.values) + return values_.Get(index); +} +inline ::vector_tile::Tile_Value* Tile_Layer::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.values) + return values_.Mutable(index); +} +inline ::vector_tile::Tile_Value* Tile_Layer::add_values() { + // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.values) + return values_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >* +Tile_Layer::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.values) + return &values_; +} +inline const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >& +Tile_Layer::values() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.values) + return values_; +} + +// optional uint32 extent = 5 [default = 4096]; +inline bool Tile_Layer::has_extent() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void Tile_Layer::set_has_extent() { + _has_bits_[0] |= 0x00000020u; +} +inline void Tile_Layer::clear_has_extent() { + _has_bits_[0] &= ~0x00000020u; +} +inline void Tile_Layer::clear_extent() { + extent_ = 4096u; + clear_has_extent(); +} +inline ::google::protobuf::uint32 Tile_Layer::extent() const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.extent) + return extent_; +} +inline void Tile_Layer::set_extent(::google::protobuf::uint32 value) { + set_has_extent(); + extent_ = value; + // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.extent) +} + +// ------------------------------------------------------------------- + +// Tile + +// repeated .vector_tile.Tile.Layer layers = 3; +inline int Tile::layers_size() const { + return layers_.size(); +} +inline void Tile::clear_layers() { + layers_.Clear(); +} +inline const ::vector_tile::Tile_Layer& Tile::layers(int index) const { + // @@protoc_insertion_point(field_get:vector_tile.Tile.layers) + return layers_.Get(index); +} +inline ::vector_tile::Tile_Layer* Tile::mutable_layers(int index) { + // @@protoc_insertion_point(field_mutable:vector_tile.Tile.layers) + return layers_.Mutable(index); +} +inline ::vector_tile::Tile_Layer* Tile::add_layers() { + // @@protoc_insertion_point(field_add:vector_tile.Tile.layers) + return layers_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >* +Tile::mutable_layers() { + // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.layers) + return &layers_; +} +inline const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >& +Tile::layers() const { + // @@protoc_insertion_point(field_list:vector_tile.Tile.layers) + return layers_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace vector_tile + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::vector_tile::Tile_GeomType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::vector_tile::Tile_GeomType>() { + return ::vector_tile::Tile_GeomType_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_vector_5ftile_2eproto__INCLUDED diff --git a/src/providers/wms/CMakeLists.txt b/src/providers/wms/CMakeLists.txt index 834bef7dd077..331f7c982c51 100644 --- a/src/providers/wms/CMakeLists.txt +++ b/src/providers/wms/CMakeLists.txt @@ -1,5 +1,4 @@ SET (WMS_SRCS - qgsmbtilesreader.cpp qgswmscapabilities.cpp qgswmsprovider.cpp qgswmsconnection.cpp From da57d93c77435bb921cd85bc6a34ed5908a7cda1 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 26 Mar 2020 19:27:49 +0100 Subject: [PATCH 02/27] Added two new forgotten files with QgsTileXYZ, QgsTileMatrx, QgsTileRange --- src/core/qgstiles.cpp | 81 ++++++++++++++++++++++++++ src/core/qgstiles.h | 131 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 src/core/qgstiles.cpp create mode 100644 src/core/qgstiles.h diff --git a/src/core/qgstiles.cpp b/src/core/qgstiles.cpp new file mode 100644 index 000000000000..82d662f5ad18 --- /dev/null +++ b/src/core/qgstiles.cpp @@ -0,0 +1,81 @@ + +#include "qgstiles.h" + +#include + +QgsTileMatrix QgsTileMatrix::fromWebMercator( int zoomLevel ) +{ + int numTiles = static_cast( pow( 2, zoomLevel ) ); // assuming we won't ever go over 30 zoom levels + double z0xMin = -20037508.3427892, z0yMin = -20037508.3427892; + double z0xMax = 20037508.3427892, z0yMax = 20037508.3427892; + double s0 = 559082264.0287178; // scale denominator at zoom level 0 of GoogleCRS84Quad + + QgsTileMatrix tm; + tm.mZoomLevel = zoomLevel; + tm.mMatrixWidth = numTiles; + tm.mMatrixHeight = numTiles; + tm.mTileXSpan = ( z0xMax - z0xMin ) / tm.mMatrixWidth; + tm.mTileYSpan = ( z0yMax - z0yMin ) / tm.mMatrixHeight; + tm.mExtent = QgsRectangle( z0xMin, z0yMin, z0xMax, z0yMax ); + tm.mScaleDenom = s0 / pow( 2, zoomLevel ); + return tm; +} + +QgsRectangle QgsTileMatrix::tileExtent( QgsTileXYZ id ) const +{ + double xMin = mExtent.xMinimum() + mTileXSpan * id.column(); + double xMax = xMin + mTileXSpan; + double yMax = mExtent.yMaximum() - mTileYSpan * id.row(); + double yMin = yMax - mTileYSpan; + return QgsRectangle( xMin, yMin, xMax, yMax ); +} + +QgsPointXY QgsTileMatrix::tileCenter( QgsTileXYZ id ) const +{ + double x = mExtent.xMinimum() + mTileXSpan / 2 * id.column(); + double y = mExtent.yMaximum() - mTileYSpan / 2 * id.row(); + return QgsPointXY( x, y ); +} + +inline double clampDouble( double lo, double v, double hi ) +{ + return ( v < lo ) ? lo : ( hi < v ) ? hi : v; +} + +static int clampTile( int tile, int nTiles ) +{ + if ( tile < 0 ) return 0; + if ( tile >= nTiles ) return nTiles - 1; + return tile; +} + +QgsTileRange QgsTileMatrix::tileRangeFromExtent( const QgsRectangle &r ) +{ + double x0 = clampDouble( mExtent.xMinimum(), r.xMinimum(), mExtent.xMaximum() ); + double y0 = clampDouble( mExtent.yMinimum(), r.yMinimum(), mExtent.yMaximum() ); + double x1 = clampDouble( mExtent.xMinimum(), r.xMaximum(), mExtent.xMaximum() ); + double y1 = clampDouble( mExtent.yMinimum(), r.yMaximum(), mExtent.yMaximum() ); + if ( x0 >= x1 || y0 >= y1 ) + return QgsTileRange(); // nothing to display + + double tileX1 = ( x0 - mExtent.xMinimum() ) / mTileXSpan; + double tileX2 = ( x1 - mExtent.xMinimum() ) / mTileXSpan; + double tileY1 = ( mExtent.yMaximum() - y1 ) / mTileYSpan; + double tileY2 = ( mExtent.yMaximum() - y0 ) / mTileYSpan; + + qDebug() << "tile range of edges" << tileX1 << tileY1 << tileX2 << tileY2; + + // figure out tile range from zoom + int startColumn = clampTile( static_cast( floor( tileX1 ) ), mMatrixWidth ); + int endColumn = clampTile( static_cast( floor( tileX2 ) ), mMatrixWidth ); + int startRow = clampTile( static_cast( floor( tileY1 ) ), mMatrixHeight ); + int endRow = clampTile( static_cast( floor( tileY2 ) ), mMatrixHeight ); + return QgsTileRange( startColumn, endColumn, startRow, endRow ); +} + +QPointF QgsTileMatrix::mapToTileCoordinates( const QgsPointXY &mapPoint ) const +{ + double dx = mapPoint.x() - mExtent.xMinimum(); + double dy = mExtent.yMaximum() - mapPoint.y(); + return QPointF( dx / mTileXSpan, dy / mTileYSpan ); +} diff --git a/src/core/qgstiles.h b/src/core/qgstiles.h new file mode 100644 index 000000000000..d316bc241b8a --- /dev/null +++ b/src/core/qgstiles.h @@ -0,0 +1,131 @@ +/*************************************************************************** + qgstiles.h + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSTILES_H +#define QGSTILES_H + +#include "qgis_core.h" +#include "qgis_sip.h" + +#include "qgsrectangle.h" + +/** + * \ingroup core + * Stores coordinates of a tile in a tile matrix set. Tile matrix is identified + * by the zoomLevel(), and the position within tile matrix is given by column() + * and row(). + * + * \since QGIS 3.14 + */ +class CORE_EXPORT QgsTileXYZ +{ + public: + //! Constructs a tile identifier from given column, row and zoom level indices + QgsTileXYZ( int tc = -1, int tr = -1, int tz = -1 ) + : mColumn( tc ), mRow( tr ), mZoomLevel( tz ) + { + } + + //! Returns tile's column index (X) + int column() const { return mColumn; } + //! Returns tile's row index (Y) + int row() const { return mRow; } + //! Returns tile's zoom level (Z) + int zoomLevel() const { return mZoomLevel; } + + private: + int mColumn; + int mRow; + int mZoomLevel; +}; + + +/** + * \ingroup core + * Range of tiles in a tile matrix to be rendered. The selection is rectangular, + * given by start/end row and column numbers. + * + * \since QGIS 3.14 + */ +class CORE_EXPORT QgsTileRange +{ + public: + //! Constructs a range of tiles from given span of columns and rows + QgsTileRange( int c1 = -1, int c2 = -1, int r1 = -1, int r2 = -1 ) + : mStartColumn( c1 ), mEndColumn( c2 ), mStartRow( r1 ), mEndRow( r2 ) {} + + //! Returns whether the range is valid (when all row/column numbers are not negative) + bool isValid() const { return mStartColumn >= 0 && mEndColumn >= 0 && mStartRow >= 0 && mEndRow >= 0; } + + int startColumn() const { return mStartColumn; } + int endColumn() const { return mEndColumn; } + int startRow() const { return mStartRow; } + int endRow() const { return mEndRow; } + + private: + int mStartColumn; + int mEndColumn; + int mStartRow; + int mEndRow; +}; + + +/** + * \ingroup core + * Defines a matrix of tiles for a single zoom level: it is defined by its size (width * height) + * and map extent that it covers. + * + * Please note that we follow the XYZ convention of X/Y axes, i.e. top-left tile has [0,0] coordinate + * (which is different from TMS convention where bottom-left tile has [0,0] coordinate). + * + * \since QGIS 3.14 + */ +struct CORE_EXPORT QgsTileMatrix +{ + public: + + //! Returns a tile matrix for the usual web mercator + static QgsTileMatrix fromWebMercator( int mZoomLevel ); + + //! Returns extent of the given tile in this matrix + QgsRectangle tileExtent( QgsTileXYZ id ) const; + + //! Returns center of the given tile in this matrix + QgsPointXY tileCenter( QgsTileXYZ id ) const; + + //! Returns tile range that fully covers the given extent + QgsTileRange tileRangeFromExtent( const QgsRectangle &mExtent ); + + //! Returns row/column coordinates (floating point number) from the given point in map coordinates + QPointF mapToTileCoordinates( const QgsPointXY &mapPoint ) const; + + private: + //! Zoom level index associated with the tile matrix + int mZoomLevel; + //! Number of columns of the tile matrix + int mMatrixWidth; + //! Number of rows of the tile matrix + int mMatrixHeight; + //! Matrix extent in map units in the CRS of tile matrix set + QgsRectangle mExtent; + //! Scale denominator of the map scale associated with the tile matrix + double mScaleDenom; + //! Width of a single tile in map units (derived from extent and matrix size) + double mTileXSpan; + //! Height of a single tile in map units (derived from extent and matrix size) + double mTileYSpan; +}; + +#endif // QGSTILES_H From bbc6af5deddfd28470c878cf16afb9f1228b45f8 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 26 Mar 2020 19:31:00 +0100 Subject: [PATCH 03/27] Fixes to python bindings + some bits from code review --- doc/CMakeLists.txt | 1 + python/core/auto_generated/qgstiles.sip.in | 114 +++++++++++ .../qgsvectortilebasicrenderer.sip.in | 182 ++++++++++++++++++ .../vectortile/qgsvectortilelayer.sip.in | 137 +++++++++++++ .../vectortile/qgsvectortilerenderer.sip.in | 133 +++++++++++++ python/core/core_auto.sip | 3 + .../vectortile/qgsvectortilebasicrenderer.cpp | 11 +- .../vectortile/qgsvectortilebasicrenderer.h | 13 +- src/core/vectortile/qgsvectortilelayer.h | 8 +- .../vectortile/qgsvectortilelayerrenderer.cpp | 13 +- .../vectortile/qgsvectortilemvtdecoder.cpp | 5 - src/core/vectortile/qgsvectortilerenderer.h | 55 +++++- 12 files changed, 638 insertions(+), 37 deletions(-) create mode 100644 python/core/auto_generated/qgstiles.sip.in create mode 100644 python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in create mode 100644 python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in create mode 100644 python/core/auto_generated/vectortile/qgsvectortilerenderer.sip.in diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 78ab8d1d2be1..5513bd8d3448 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -99,6 +99,7 @@ IF(WITH_APIDOC) ${CMAKE_SOURCE_DIR}/src/core/scalebar ${CMAKE_SOURCE_DIR}/src/core/symbology ${CMAKE_SOURCE_DIR}/src/core/validity + ${CMAKE_SOURCE_DIR}/src/core/vectortile ${CMAKE_SOURCE_DIR}/src/gui ${CMAKE_SOURCE_DIR}/src/gui/auth ${CMAKE_SOURCE_DIR}/src/gui/attributetable diff --git a/python/core/auto_generated/qgstiles.sip.in b/python/core/auto_generated/qgstiles.sip.in new file mode 100644 index 000000000000..732f4ff030dd --- /dev/null +++ b/python/core/auto_generated/qgstiles.sip.in @@ -0,0 +1,114 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/qgstiles.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + +class QgsTileXYZ +{ +%Docstring +Stores coordinates of a tile in a tile matrix set. Tile matrix is identified +by the zoomLevel(), and the position within tile matrix is given by column() +and row(). + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgstiles.h" +%End + public: + QgsTileXYZ( int tc = -1, int tr = -1, int tz = -1 ); +%Docstring +Constructs a tile identifier from given column, row and zoom level indices +%End + + int column() const; +%Docstring +Returns tile's column index (X) +%End + int row() const; +%Docstring +Returns tile's row index (Y) +%End + int zoomLevel() const; +%Docstring +Returns tile's zoom level (Z) +%End + +}; + + +class QgsTileRange +{ +%Docstring +Range of tiles in a tile matrix to be rendered. The selection is rectangular, +given by start/end row and column numbers. + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgstiles.h" +%End + public: + QgsTileRange( int c1 = -1, int c2 = -1, int r1 = -1, int r2 = -1 ); +%Docstring +Constructs a range of tiles from given span of columns and rows +%End + bool isValid() const; +%Docstring +Returns whether the range is valid (when all row/column numbers are not negative) +%End + + int startColumn() const; + int endColumn() const; + int startRow() const; + int endRow() const; + +}; + + +struct QgsTileMatrix +{ + public: + + static QgsTileMatrix fromWebMercator( int mZoomLevel ); +%Docstring +Returns a tile matrix for the usual web mercator +%End + + QgsRectangle tileExtent( QgsTileXYZ id ) const; +%Docstring +Returns extent of the given tile in this matrix +%End + + QgsPointXY tileCenter( QgsTileXYZ id ) const; +%Docstring +Returns center of the given tile in this matrix +%End + + QgsTileRange tileRangeFromExtent( const QgsRectangle &mExtent ); +%Docstring +Returns tile range that fully covers the given extent +%End + + QPointF mapToTileCoordinates( const QgsPointXY &mapPoint ) const; +%Docstring +Returns row/column coordinates (floating point number) from the given point in map coordinates +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/qgstiles.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in new file mode 100644 index 000000000000..dbac17f4bef3 --- /dev/null +++ b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in @@ -0,0 +1,182 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vectortile/qgsvectortilebasicrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + +class QgsVectorTileBasicRendererStyle +{ +%Docstring +Definition of map rendering of a subset of vector tile data. The subset of data is defined by: +1. sub-layer name +2. geometry type (a single sub-layer may have multiple geometry types) +3. filter expression + +Renering is determined by the associated symbol (QgsSymbol). Symbol has to be of the same +type as the chosen geometryType() - i.e. QgsMarkerSymbol for points, QgsLineSymbol for linestrings +and QgsFillSymbol for polygons. + +It is possible to further constrain when this style is applied by setting a range of allowed +zoom levels, or by disabling it. + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgsvectortilebasicrenderer.h" +%End + public: + QgsVectorTileBasicRendererStyle( const QString &stName = QString(), const QString &laName = QString(), QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ); +%Docstring +Constructs a style object +%End + + QgsVectorTileBasicRendererStyle( const QgsVectorTileBasicRendererStyle &other ); + + void setStyleName( const QString &name ); +%Docstring +Sets human readable name of this style +%End + QString styleName() const; +%Docstring +Returns human readable name of this style +%End + + void setLayerName( const QString &name ); +%Docstring +Sets name of the sub-layer to render (empty layer means that all layers match) +%End + QString layerName() const; +%Docstring +Returns name of the sub-layer to render (empty layer means that all layers match) +%End + + void setGeometryType( QgsWkbTypes::GeometryType geomType ); +%Docstring +Sets type of the geometry that will be used (point / line / polygon) +%End + QgsWkbTypes::GeometryType geometryType() const; +%Docstring +Returns type of the geometry that will be used (point / line / polygon) +%End + + void setFilterExpression( const QString &expr ); +%Docstring +Sets filter expression (empty filter means that all features match) +%End + QString filterExpression() const; +%Docstring +Returns filter expression (empty filter means that all features match) +%End + + void setSymbol( QgsSymbol *sym /Transfer/ ); +%Docstring +Sets symbol for rendering. Takes ownership of the symbol. +%End + QgsSymbol *symbol() const; +%Docstring +Returns symbol for rendering +%End + + void setEnabled( bool enabled ); +%Docstring +Sets whether this style is enabled (used for rendering) +%End + bool isEnabled() const; +%Docstring +Returns whether this style is enabled (used for rendering) +%End + + void setMinZoomLevel( int minZoom ); +%Docstring +Sets minimum zoom level index (negative number means no limit) +%End + int minZoomLevel() const; +%Docstring +Returns minimum zoom level index (negative number means no limit) +%End + + void setMaxZoomLevel( int maxZoom ); +%Docstring +Sets maximum zoom level index (negative number means no limit) +%End + int maxZoomLevel() const; +%Docstring +Returns maxnimum zoom level index (negative number means no limit) +%End + + bool isActive( int zoomLevel ) const; +%Docstring +Returns whether the style is active at given zoom level (also checks "enabled" flag) +%End + + void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const; +%Docstring +Writes object content to given DOM element +%End + void readXml( const QDomElement &elem, const QgsReadWriteContext &context ); +%Docstring +Reads object content from given DOM element +%End + +}; + + +class QgsVectorTileBasicRenderer : QgsVectorTileRenderer +{ +%Docstring +The default vector tile renderer implementation. It has an ordered list of "styles", +each defines a rendering rule. + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgsvectortilebasicrenderer.h" +%End + public: + QgsVectorTileBasicRenderer(); +%Docstring +Constructs renderer with some default styles +%End + + virtual QString type() const; + + virtual QgsVectorTileBasicRenderer *clone() const /Factory/; + + virtual void startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ); + + virtual void stopRender( QgsRenderContext &context ); + + virtual void renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ); + + virtual void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const; + + virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context ); + + + void setStyles( const QList &styles ); +%Docstring +Sets list of styles of the renderer +%End + QList styles() const; +%Docstring +Returns list of styles of the renderer +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vectortile/qgsvectortilebasicrenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in new file mode 100644 index 000000000000..ea62e989f05d --- /dev/null +++ b/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in @@ -0,0 +1,137 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vectortile/qgsvectortilelayer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + +class QgsVectorTileLayer : QgsPluginLayer +{ +%Docstring +Implements a map layer that is dedicated to rendering of vector tiles. +Vector tiles compared to "ordinary" vector layers are pre-processed data +optimized for fast rendering. A dataset is provided with a series of zoom levels +for different map scales. Each zoom level has a matrix of tiles that contain +actual data. A single vector tile may be a a file stored on a local drive, +requested over HTTP request or retrieved from a database. + +Content of a vector tile is divided into one or more named sub-layers. Each such +sub-layer may contain many features which consist of geometry and attributes. +Contrary to traditional vector layers, these sub-layers do not need to have a rigid +schema where geometry type and attributes are the same for all features. A single +sub-layer may have multiple geometry types in a single tile or have some attributes +defined only at particular zoom levels. + +Vector tile layer currently does not use the concept of data providers that other +layer types use. The process of rendering of vector tiles looks like this: + ++--------+ +------+ +---------+ +| DATA | | RAW | | DECODED | +| | --> LOADER --> | | --> DECODER --> | | --> RENDERER +| SOURCE | | TILE | | TILE | ++--------+ +------+ +---------+ + +Data source is a place from where tiles are fetched from (URL for HTTP access, local +files, MBTiles file, GeoPackage file or others. Loader (QgsVectorTileLoader) class +takes care of loading data from the data source. The "raw tile" data is just a blob +(QByteArray) that is encoded in some way. There are multiple ways how vector tiles +are encoded just like there are different formats how to store images. For example, +tiles can be encoded using Mapbox Vector Tiles (MVT) format or in GeoJSON. Decoder +(QgsVectorTileDecoder) takes care of decoding raw tile data into QgsFeature objects. +A decoded tile is essentially an array of vector features for each sub-layer found +in the tile - this is what vector tile renderer (QgsVectorTileRenderer) expects +and does the map rendering. + +To construct a vector tile layer, it is best to use QgsDataSourceUri class and set +the following parameters to get a valid encoded URI: +- "type" - what kind of data source will be used +- "url" - URL or path of the data source (specific to each data source type, see below) + +Currently supported data source types: +- "xyz" - the "url" should be a template like http://example.com/{z}/{x}/{y}.pbf where +{x},{y},{z} will be replaced by tile coordinates +- "mbtiles" - tiles read from a MBTiles file (a SQLite database) + +Currently supported decoders: +- MVT - following Mapbox Vector Tiles specification + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgsvectortilelayer.h" +%End + public: + explicit QgsVectorTileLayer( const QString &path = QString(), const QString &baseName = QString() ); +%Docstring +Constructs a new vector tile layer +%End + ~QgsVectorTileLayer(); + + + virtual QgsPluginLayer *clone() const /Factory/; + + + virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/; + + virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ); + + virtual bool writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const; + + virtual bool readSymbology( const QDomNode &node, QString &errorMessage, + QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ); + + virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, + StyleCategories categories = AllStyleCategories ) const; + + virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext ); + + + QString sourceType() const; +%Docstring +Returns type of the data source +%End + QString sourcePath() const; +%Docstring +Returns URL/path of the data source (syntax different to each data source type) +%End + + int sourceMinZoom() const; +%Docstring +Returns minimum zoom level at which source has any valid tiles (negative = unconstrained) +%End + int sourceMaxZoom() const; +%Docstring +Returns maximum zoom level at which source has any valid tiles (negative = unconstrained) +%End + + + void setRenderer( QgsVectorTileRenderer *r /Transfer/ ); +%Docstring +Sets renderer for the map layer. + +.. note:: + + Takes ownership of the passed renderer +%End + QgsVectorTileRenderer *renderer() const; +%Docstring +Returns currently assigned renderer +%End + +}; + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vectortile/qgsvectortilelayer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/auto_generated/vectortile/qgsvectortilerenderer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilerenderer.sip.in new file mode 100644 index 000000000000..de0b552eca55 --- /dev/null +++ b/python/core/auto_generated/vectortile/qgsvectortilerenderer.sip.in @@ -0,0 +1,133 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vectortile/qgsvectortilerenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + + +class QgsVectorTileRendererData +{ +%Docstring +Contains decoded features of a single vector tile and any other data necessary +for rendering of it. + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgsvectortilerenderer.h" +%End + public: + explicit QgsVectorTileRendererData( QgsTileXYZ id ); +%Docstring +Constructs the object +%End + + QgsTileXYZ id() const; +%Docstring +Returns coordinates of the tile +%End + + void setTilePolygon( QPolygon polygon ); +%Docstring +Sets polygon of the tile +%End + QPolygon tilePolygon() const; +%Docstring +Returns polygon (made out of four corners of the tile) in screen coordinates calculated from render context +%End + + QStringList layers() const; +%Docstring +Returns list of layer names present in the tile +%End + QVector layerFeatures( const QString &layerName ) const; +%Docstring +Returns list of all features within a single sub-layer +%End + +}; + +class QgsVectorTileRenderer +{ +%Docstring +Abstract base class for all vector tile renderer implementations. + +For rendering it is expected that client code calls: +1. startRender() to prepare renderer +2. renderTile() for each tile +3. stopRender() to clean up renderer and free resources + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgsvectortilerenderer.h" +%End +%ConvertToSubClassCode + + const QString type = sipCpp->type(); + + if ( type == QStringLiteral( "basic" ) ) + sipType = sipType_QgsVectorTileBasicRenderer; + else + sipType = 0; +%End + public: + virtual ~QgsVectorTileRenderer(); + + virtual QString type() const = 0; +%Docstring +Returns unique type name of the renderer implementation +%End + + virtual QgsVectorTileRenderer *clone() const = 0 /Factory/; +%Docstring +Returns a clone of the renderer +%End + + virtual void startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ) = 0; +%Docstring +Initializes rendering. It should be paired with a stopRender() call. +%End + + + virtual void stopRender( QgsRenderContext &context ) = 0; +%Docstring +Finishes rendering and cleans up any resources +%End + + virtual void renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ) = 0; +%Docstring +Renders given vector tile. Must be called between startRender/stopRender. +%End + + virtual void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const = 0; +%Docstring +Writes renderer's properties to given XML element +%End + virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) = 0; +%Docstring +Reads renderer's properties from given XML element +%End + virtual void resolveReferences( const QgsProject &project ); +%Docstring +Resolves references to other objects - second phase of loading - after readXml() +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/vectortile/qgsvectortilerenderer.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index 0ab8ae964435..27af8bb5eec2 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -205,6 +205,7 @@ %Include auto_generated/qgstessellator.sip %Include auto_generated/qgstestutils.sip %Include auto_generated/qgstextrenderer.sip +%Include auto_generated/qgstiles.sip %Include auto_generated/qgstolerance.sip %Include auto_generated/qgstracer.sip %Include auto_generated/qgstrackedvectorlayertools.sip @@ -534,4 +535,6 @@ %Include auto_generated/gps/qgsgpsconnectionregistry.sip %Include auto_generated/symbology/qgsmasksymbollayer.sip %Include auto_generated/qgsuserprofile.sip +%Include auto_generated/vectortile/qgsvectortilebasicrenderer.sip %Include auto_generated/vectortile/qgsvectortilelayer.sip +%Include auto_generated/vectortile/qgsvectortilerenderer.sip diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.cpp b/src/core/vectortile/qgsvectortilebasicrenderer.cpp index 31130657a7e7..4ee5086660d4 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.cpp +++ b/src/core/vectortile/qgsvectortilebasicrenderer.cpp @@ -15,6 +15,7 @@ #include "qgsvectortilebasicrenderer.h" +#include "qgsexpressioncontextutils.h" #include "qgslinesymbollayer.h" #include "qgssymbollayerutils.h" #include "qgsvectortileutils.h" @@ -137,8 +138,8 @@ void QgsVectorTileBasicRenderer::stopRender( QgsRenderContext &context ) void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ) { - const QgsVectorTileFeatures tileData = tile.features; - int zoomLevel = tile.id.zoomLevel(); + const QgsVectorTileFeatures tileData = tile.features(); + int zoomLevel = tile.id().zoomLevel(); for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) ) { @@ -147,9 +148,9 @@ void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &ti QgsFields fields = QgsVectorTileUtils::makeQgisFields( mRequiredFields[layerStyle.layerName()] ); - QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) ); + QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) ); // will be deleted by popper scope->setFields( fields ); - context.expressionContext().appendScope( scope ); + QgsExpressionContextScopePopper popper( context.expressionContext(), scope ); QgsExpression filterExpression( layerStyle.filterExpression() ); filterExpression.prepare( &context.expressionContext() ); @@ -186,8 +187,6 @@ void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &ti } } sym->stopRender( context ); - - delete context.expressionContext().popScope(); } } diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.h b/src/core/vectortile/qgsvectortilebasicrenderer.h index e938877cecc1..ad95713a3637 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.h +++ b/src/core/vectortile/qgsvectortilebasicrenderer.h @@ -16,6 +16,9 @@ #ifndef QGSVECTORTILEBASICRENDERER_H #define QGSVECTORTILEBASICRENDERER_H +#include "qgis_core.h" +#include "qgis_sip.h" + #include "qgsvectortilerenderer.h" class QgsLineSymbol; @@ -40,7 +43,7 @@ class QgsSymbol; * * \since QGIS 3.14 */ -struct QgsVectorTileBasicRendererStyle +class CORE_EXPORT QgsVectorTileBasicRendererStyle { public: //! Constructs a style object @@ -70,7 +73,7 @@ struct QgsVectorTileBasicRendererStyle QString filterExpression() const { return mExpression; } //! Sets symbol for rendering. Takes ownership of the symbol. - void setSymbol( QgsSymbol *sym ); + void setSymbol( QgsSymbol *sym SIP_TRANSFER ); //! Returns symbol for rendering QgsSymbol *symbol() const { return mSymbol.get(); } @@ -119,16 +122,16 @@ struct QgsVectorTileBasicRendererStyle * * \since QGIS 3.14 */ -class QgsVectorTileBasicRenderer : public QgsVectorTileRenderer +class CORE_EXPORT QgsVectorTileBasicRenderer : public QgsVectorTileRenderer { public: //! Constructs renderer with some default styles QgsVectorTileBasicRenderer(); QString type() const override; - QgsVectorTileBasicRenderer *clone() const override; + QgsVectorTileBasicRenderer *clone() const override SIP_FACTORY; void startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ) override; - QMap > usedAttributes( const QgsRenderContext & ) override; + QMap > usedAttributes( const QgsRenderContext & ) override SIP_SKIP; void stopRender( QgsRenderContext &context ) override; void renderTile( const QgsVectorTileRendererData &tile, QgsRenderContext &context ) override; void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const override; diff --git a/src/core/vectortile/qgsvectortilelayer.h b/src/core/vectortile/qgsvectortilelayer.h index 675b97044c26..32450aa7d9fe 100644 --- a/src/core/vectortile/qgsvectortilelayer.h +++ b/src/core/vectortile/qgsvectortilelayer.h @@ -85,9 +85,9 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsPluginLayer // implementation of virtual functions from QgsMapLayer - QgsPluginLayer *clone() const override; + QgsPluginLayer *clone() const override SIP_FACTORY; - virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override; + virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY; virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context ) override; @@ -126,9 +126,9 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsPluginLayer * Sets renderer for the map layer. * \note Takes ownership of the passed renderer */ - void setRenderer( QgsVectorTileRenderer *r ) SIP_SKIP; + void setRenderer( QgsVectorTileRenderer *r SIP_TRANSFER ); //! Returns currently assigned renderer - QgsVectorTileRenderer *renderer() const SIP_SKIP; + QgsVectorTileRenderer *renderer() const; private: //! Type of the data source diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index 47733c2d6391..e52b7906429d 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -148,23 +148,22 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & if ( ctx.renderingStopped() ) return; - QgsVectorTileRendererData tile; - tile.id = rawTile.id; - tile.features = decoder.layerFeatures( mPerLayerFields ); + QgsVectorTileRendererData tile( rawTile.id ); + tile.setFeatures( decoder.layerFeatures( mPerLayerFields ) ); + tile.setTilePolygon( QgsVectorTileUtils::tilePolygon( rawTile.id, mTileMatrix, ctx.mapToPixel() ) ); mTotalDecodeTime += tLoad.elapsed(); // calculate tile polygon in screen coordinates - tile.tilePolygon = QgsVectorTileUtils::tilePolygon( rawTile.id, mTileMatrix, ctx.mapToPixel() ); if ( ctx.renderingStopped() ) return; // set up clipping so that rendering does not go behind tile's extent - ctx.painter()->setClipRegion( QRegion( tile.tilePolygon ) ); + ctx.painter()->setClipRegion( QRegion( tile.tilePolygon() ) ); - qDebug() << "drawing tile" << tile.id.zoomLevel() << tile.id.column() << tile.id.row(); + qDebug() << "drawing tile" << tile.id().zoomLevel() << tile.id().column() << tile.id().row(); QElapsedTimer tDraw; tDraw.start(); @@ -179,6 +178,6 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & QPen pen( Qt::red ); pen.setWidth( 3 ); ctx.painter()->setPen( pen ); - ctx.painter()->drawPolygon( tile.tilePolygon ); + ctx.painter()->drawPolygon( tile.tilePolygon() ); } } diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.cpp b/src/core/vectortile/qgsvectortilemvtdecoder.cpp index 67f862cf0456..2b710292df70 100644 --- a/src/core/vectortile/qgsvectortilemvtdecoder.cpp +++ b/src/core/vectortile/qgsvectortilemvtdecoder.cpp @@ -128,11 +128,6 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap( feature.id() ) ); - // initialize all fields to empty string. - // TODO: this should not be necessary, but some rules don't like NULL - for ( int i = 0; i < layerFields.count(); ++i ) - f.setAttribute( i, QStringLiteral( "" ) ); - // // parse attributes // diff --git a/src/core/vectortile/qgsvectortilerenderer.h b/src/core/vectortile/qgsvectortilerenderer.h index 97f4a31286e2..2b42704a938e 100644 --- a/src/core/vectortile/qgsvectortilerenderer.h +++ b/src/core/vectortile/qgsvectortilerenderer.h @@ -25,7 +25,7 @@ class QgsRenderContext; //! Features of a vector tile, grouped by sub-layer names (key of the map) -typedef QMap > QgsVectorTileFeatures; +typedef QMap > QgsVectorTileFeatures SIP_SKIP; /** * \ingroup core @@ -34,14 +34,36 @@ typedef QMap > QgsVectorTileFeatures; * * \since QGIS 3.14 */ -struct QgsVectorTileRendererData +class CORE_EXPORT QgsVectorTileRendererData { - //! Position of the tile in the tile matrix set - QgsTileXYZ id; - //! Features of the tile grouped into sub-layers - QgsVectorTileFeatures features; - //! Polygon (made out of four corners of the tile) in screen coordinates calculated from render context - QPolygon tilePolygon; + public: + //! Constructs the object + explicit QgsVectorTileRendererData( QgsTileXYZ id ): mId( id ) {} + + //! Returns coordinates of the tile + QgsTileXYZ id() const { return mId; } + + //! Sets polygon of the tile + void setTilePolygon( QPolygon polygon ) { mTilePolygon = polygon; } + //! Returns polygon (made out of four corners of the tile) in screen coordinates calculated from render context + QPolygon tilePolygon() const { return mTilePolygon; } + + //! Sets features of the tile + void setFeatures( const QgsVectorTileFeatures &features ) SIP_SKIP { mFeatures = features; } + //! Returns features of the tile grouped by sub-layer names + QgsVectorTileFeatures features() const SIP_SKIP { return mFeatures; } + //! Returns list of layer names present in the tile + QStringList layers() const { return mFeatures.keys(); } + //! Returns list of all features within a single sub-layer + QVector layerFeatures( const QString &layerName ) const { return mFeatures[layerName]; } + + private: + //! Position of the tile in the tile matrix set + QgsTileXYZ mId; + //! Features of the tile grouped into sub-layers + QgsVectorTileFeatures mFeatures; + //! Polygon (made out of four corners of the tile) in screen coordinates calculated from render context + QPolygon mTilePolygon; }; /** @@ -57,6 +79,19 @@ struct QgsVectorTileRendererData */ class CORE_EXPORT QgsVectorTileRenderer { + +#ifdef SIP_RUN + SIP_CONVERT_TO_SUBCLASS_CODE + + const QString type = sipCpp->type(); + + if ( type == QStringLiteral( "basic" ) ) + sipType = sipType_QgsVectorTileBasicRenderer; + else + sipType = 0; + SIP_END +#endif + public: virtual ~QgsVectorTileRenderer() = default; @@ -64,13 +99,13 @@ class CORE_EXPORT QgsVectorTileRenderer virtual QString type() const = 0; //! Returns a clone of the renderer - virtual QgsVectorTileRenderer *clone() const = 0; + virtual QgsVectorTileRenderer *clone() const = 0 SIP_FACTORY; //! Initializes rendering. It should be paired with a stopRender() call. virtual void startRender( QgsRenderContext &context, int tileZoom, const QgsTileRange &tileRange ) = 0; //! Returns field names of sub-layers that will be used for rendering. Must be called between startRender/stopRender. - virtual QMap > usedAttributes( const QgsRenderContext & ) = 0; + virtual QMap > usedAttributes( const QgsRenderContext & ) SIP_SKIP { return QMap >(); } //! Finishes rendering and cleans up any resources virtual void stopRender( QgsRenderContext &context ) = 0; From 617db5919a90bc4b63a787082ac0586932603b27 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 26 Mar 2020 21:08:01 +0100 Subject: [PATCH 04/27] Doxygen, spelling, sip fixes --- python/core/auto_generated/qgstiles.sip.in | 12 ++++++++++++ .../vectortile/qgsvectortilebasicrenderer.sip.in | 4 +++- src/core/qgsmbtilesreader.h | 14 +++++++++++++- src/core/qgstiles.cpp | 14 ++++++++++++++ src/core/qgstiles.h | 4 ++++ src/core/vectortile/qgsvectortilebasicrenderer.h | 2 +- src/core/vectortile/qgsvectortilelayerrenderer.cpp | 2 +- src/core/vectortile/qgsvectortilelayerrenderer.h | 2 ++ src/core/vectortile/qgsvectortileloader.cpp | 8 +++++--- src/core/vectortile/qgsvectortileloader.h | 5 ++++- src/core/vectortile/qgsvectortilemvtdecoder.cpp | 2 +- src/core/vectortile/qgsvectortilemvtdecoder.h | 2 ++ src/core/vectortile/qgsvectortileutils.cpp | 2 +- src/core/vectortile/qgsvectortileutils.h | 2 ++ 14 files changed, 65 insertions(+), 10 deletions(-) diff --git a/python/core/auto_generated/qgstiles.sip.in b/python/core/auto_generated/qgstiles.sip.in index 732f4ff030dd..67be19cd963c 100644 --- a/python/core/auto_generated/qgstiles.sip.in +++ b/python/core/auto_generated/qgstiles.sip.in @@ -67,9 +67,21 @@ Returns whether the range is valid (when all row/column numbers are not negative %End int startColumn() const; +%Docstring +Returns index of the first column in the range +%End int endColumn() const; +%Docstring +Returns index of the last column in the range +%End int startRow() const; +%Docstring +Returns index of the first row in the range +%End int endRow() const; +%Docstring +Returns index of the last row in the range +%End }; diff --git a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in index dbac17f4bef3..9f44f528ec36 100644 --- a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in +++ b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in @@ -37,8 +37,10 @@ zoom levels, or by disabling it. %Docstring Constructs a style object %End - QgsVectorTileBasicRendererStyle( const QgsVectorTileBasicRendererStyle &other ); +%Docstring +Constructs a style object as a copy of another style +%End void setStyleName( const QString &name ); %Docstring diff --git a/src/core/qgsmbtilesreader.h b/src/core/qgsmbtilesreader.h index 7944c066dc2e..801aeba0c557 100644 --- a/src/core/qgsmbtilesreader.h +++ b/src/core/qgsmbtilesreader.h @@ -24,22 +24,34 @@ class QImage; class QgsRectangle; +/** + * \ingroup core + * Utility class for reading MBTiles files (which are SQLite3 databases). + * + * \since QGIS 3.14 + */ class CORE_EXPORT QgsMBTilesReader { public: + //! Contructs MBTiles reader (but it does not open the file yet) explicit QgsMBTilesReader( const QString &filename ); + //! Tries to open the file, returns true on success bool open(); + //! Returns whether the MBTiles file is currently opened bool isOpen() const; + //! Requests metadata value for the given key QString metadataValue( const QString &key ); - //! given in WGS 84 (if available) + //! Returns bounding box from metadata, given in WGS 84 (if available) QgsRectangle extent(); + //! Returns raw tile data for given tile QByteArray tileData( int z, int x, int y ); + //! Returns tile decoded as a raster image (if stored in a known format like JPG or PNG) QImage tileDataAsImage( int z, int x, int y ); private: diff --git a/src/core/qgstiles.cpp b/src/core/qgstiles.cpp index 82d662f5ad18..fa79e39d746e 100644 --- a/src/core/qgstiles.cpp +++ b/src/core/qgstiles.cpp @@ -1,3 +1,17 @@ +/*************************************************************************** + qgstiles.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ #include "qgstiles.h" diff --git a/src/core/qgstiles.h b/src/core/qgstiles.h index d316bc241b8a..7c29d22d10e7 100644 --- a/src/core/qgstiles.h +++ b/src/core/qgstiles.h @@ -69,9 +69,13 @@ class CORE_EXPORT QgsTileRange //! Returns whether the range is valid (when all row/column numbers are not negative) bool isValid() const { return mStartColumn >= 0 && mEndColumn >= 0 && mStartRow >= 0 && mEndRow >= 0; } + //! Returns index of the first column in the range int startColumn() const { return mStartColumn; } + //! Returns index of the last column in the range int endColumn() const { return mEndColumn; } + //! Returns index of the first row in the range int startRow() const { return mStartRow; } + //! Returns index of the last row in the range int endRow() const { return mEndRow; } private: diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.h b/src/core/vectortile/qgsvectortilebasicrenderer.h index ad95713a3637..ecc47fe0aae5 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.h +++ b/src/core/vectortile/qgsvectortilebasicrenderer.h @@ -48,7 +48,7 @@ class CORE_EXPORT QgsVectorTileBasicRendererStyle public: //! Constructs a style object QgsVectorTileBasicRendererStyle( const QString &stName = QString(), const QString &laName = QString(), QgsWkbTypes::GeometryType geomType = QgsWkbTypes::UnknownGeometry ); - + //! Constructs a style object as a copy of another style QgsVectorTileBasicRendererStyle( const QgsVectorTileBasicRendererStyle &other ); QgsVectorTileBasicRendererStyle &operator=( const QgsVectorTileBasicRendererStyle &other ); diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index e52b7906429d..8976b0ffa46b 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -112,7 +112,7 @@ bool QgsVectorTileLayerRenderer::render() } else { - // Block until tiles are fetched and rendered. If the rendering gets cancelled at some point, + // Block until tiles are fetched and rendered. If the rendering gets canceled at some point, // the async loader will catch the signal, abort requests and return from downloadBlocking() asyncLoader->downloadBlocking(); } diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.h b/src/core/vectortile/qgsvectortilelayerrenderer.h index e6b87ee83955..ae90629bcdf7 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.h +++ b/src/core/vectortile/qgsvectortilelayerrenderer.h @@ -16,6 +16,8 @@ #ifndef QGSVECTORTILELAYERRENDERER_H #define QGSVECTORTILELAYERRENDERER_H +#define SIP_NO_FILE + #include "qgsmaplayerrenderer.h" class QgsVectorTileLayer; diff --git a/src/core/vectortile/qgsvectortileloader.cpp b/src/core/vectortile/qgsvectortileloader.cpp index e6e22d7fcfc2..dbd423a9bd3d 100644 --- a/src/core/vectortile/qgsvectortileloader.cpp +++ b/src/core/vectortile/qgsvectortileloader.cpp @@ -66,7 +66,7 @@ void QgsVectorTileLoader::downloadBlocking() if ( mFeedback && mFeedback->isCanceled() ) { - qDebug() << "actually not - we were cancelled"; + qDebug() << "actually not - we were canceled"; return; // nothing to do } @@ -81,7 +81,9 @@ void QgsVectorTileLoader::loadFromNetworkAsync( const QgsTileXYZ &id, const QStr { QString url = QgsVectorTileUtils::formatXYZUrlTemplate( requestUrl, id ); QNetworkRequest request( url ); - // TODO: some extra headers? QgsSetRequestInitiatorClass / auth / "Accept" header + QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLoader" ) ); + QgsSetRequestInitiatorId( request, QStringLiteral( "X=%1 Y=%2 Z=%3" ).arg( id.column() ).arg( id.row() ).arg( id.zoomLevel() ) ); + request.setAttribute( static_cast( QNetworkRequest::User + 1 ), id.column() ); request.setAttribute( static_cast( QNetworkRequest::User + 2 ), id.row() ); request.setAttribute( static_cast( QNetworkRequest::User + 3 ), id.zoomLevel() ); @@ -133,7 +135,7 @@ void QgsVectorTileLoader::tileReplyFinished() void QgsVectorTileLoader::canceled() { - qDebug() << "cancelling pending requests"; + qDebug() << "canceling pending requests"; const QList replies = mReplies; for ( QNetworkReply *reply : replies ) { diff --git a/src/core/vectortile/qgsvectortileloader.h b/src/core/vectortile/qgsvectortileloader.h index e1ca631b1e2a..e4b0b78a330c 100644 --- a/src/core/vectortile/qgsvectortileloader.h +++ b/src/core/vectortile/qgsvectortileloader.h @@ -16,6 +16,8 @@ #ifndef QGSVECTORTILELOADER_H #define QGSVECTORTILELOADER_H +#define SIP_NO_FILE + class QByteArray; #include "qgsvectortilerenderer.h" @@ -29,6 +31,7 @@ class QByteArray; class QgsVectorTileRawData { public: + //! Constructs a raw tile object QgsVectorTileRawData( QgsTileXYZ tileID = QgsTileXYZ(), const QByteArray &raw = QByteArray() ) : id( tileID ), data( raw ) {} @@ -60,7 +63,7 @@ class QgsVectorTileLoader : public QObject //! Returns raw tile data for a single tile, doing a HTTP request. Block the caller until tile data are downloaded. static QByteArray loadFromNetwork( const QgsTileXYZ &id, const QString &requestUrl ); - //! Returns raw tile data for a signle tile loaded from MBTiles file + //! Returns raw tile data for a single tile loaded from MBTiles file static QByteArray loadFromMBTiles( const QgsTileXYZ &id, QgsMBTilesReader &mbTileReader ); //! Decodes gzip byte stream, returns true on success static bool decodeGzip( const QByteArray &bytesIn, QByteArray &bytesOut ); diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.cpp b/src/core/vectortile/qgsvectortilemvtdecoder.cpp index 2b710292df70..6b2114add4c0 100644 --- a/src/core/vectortile/qgsvectortilemvtdecoder.cpp +++ b/src/core/vectortile/qgsvectortilemvtdecoder.cpp @@ -306,7 +306,7 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap diff --git a/src/core/vectortile/qgsvectortileutils.cpp b/src/core/vectortile/qgsvectortileutils.cpp index 85a27a7504ff..1cfa1e43b093 100644 --- a/src/core/vectortile/qgsvectortileutils.cpp +++ b/src/core/vectortile/qgsvectortileutils.cpp @@ -82,7 +82,7 @@ QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer * decoder.decode( tileID, mvt->getRawTile( tileID ) ); qDebug() << decoder.layers(); QSet fieldNames = QSet::fromList( decoder.layerFieldNames( layerName ) ); - fieldNames << "ty_pe"; // geom. type + fieldNames << "_geom_type"; QMap perLayerFields; QgsFields fields = QgsVectorTileUtils::makeQgisFields( fieldNames ); perLayerFields[layerName] = fields; diff --git a/src/core/vectortile/qgsvectortileutils.h b/src/core/vectortile/qgsvectortileutils.h index 1d484f20c306..03eb51340d02 100644 --- a/src/core/vectortile/qgsvectortileutils.h +++ b/src/core/vectortile/qgsvectortileutils.h @@ -16,6 +16,8 @@ #ifndef QGSVECTORTILEUTILS_H #define QGSVECTORTILEUTILS_H +#define SIP_NO_FILE + #include class QPointF; From f43bd8c09bfdf8499f0eec2974d59a1f4529b354 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 26 Mar 2020 21:23:51 +0100 Subject: [PATCH 05/27] Move the generated code for MVT to a directory in external/ --- external/mapbox-vector-tile/README.md | 15 +++++++++++++++ .../mapbox-vector-tile}/vector_tile.pb.cc | 0 .../mapbox-vector-tile}/vector_tile.pb.h | 0 scripts/astyle.sh | 2 +- src/core/CMakeLists.txt | 4 +++- 5 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 external/mapbox-vector-tile/README.md rename {src/core/vectortile => external/mapbox-vector-tile}/vector_tile.pb.cc (100%) rename {src/core/vectortile => external/mapbox-vector-tile}/vector_tile.pb.h (100%) diff --git a/external/mapbox-vector-tile/README.md b/external/mapbox-vector-tile/README.md new file mode 100644 index 000000000000..b6921a544e23 --- /dev/null +++ b/external/mapbox-vector-tile/README.md @@ -0,0 +1,15 @@ + +The .pb.cc and .pb.h are generated by 'protoc' tool and got copied here from https://github.com/TimSC/mbtiles-cpp + + +Update pbf files +---------------- + +To update the protobuf files, get vector_tile.proto from https://github.com/mapbox/vector-tile-spec, remove the line "option optimize_for = LITE_RUNTIME;", then + + mkdir vector_tile21 + + protoc vector_tile.proto --cpp_out vector_tile21 + +protobuf lite is avoided because it doesn't contain SerializeToOstream functionality. + diff --git a/src/core/vectortile/vector_tile.pb.cc b/external/mapbox-vector-tile/vector_tile.pb.cc similarity index 100% rename from src/core/vectortile/vector_tile.pb.cc rename to external/mapbox-vector-tile/vector_tile.pb.cc diff --git a/src/core/vectortile/vector_tile.pb.h b/external/mapbox-vector-tile/vector_tile.pb.h similarity index 100% rename from src/core/vectortile/vector_tile.pb.h rename to external/mapbox-vector-tile/vector_tile.pb.h diff --git a/scripts/astyle.sh b/scripts/astyle.sh index b1a44bd19a7d..7217f9acee60 100755 --- a/scripts/astyle.sh +++ b/scripts/astyle.sh @@ -105,7 +105,7 @@ astyleit() { for f in "$@"; do case "$f" in - src/plugins/grass/qtermwidget/*|external/o2/*|external/qt-unix-signals/*|external/rtree/*|external/astyle/*|external/kdbush/*|external/poly2tri/*|external/wintoast/*|external/qt3dextra-headers/*|external/meshOptimizer/*|python/ext-libs/*|ui_*.py|*.astyle|tests/testdata/*|editors/*|src/core/vectortile/*.pb.*) + src/plugins/grass/qtermwidget/*|external/o2/*|external/qt-unix-signals/*|external/rtree/*|external/astyle/*|external/kdbush/*|external/poly2tri/*|external/wintoast/*|external/qt3dextra-headers/*|external/meshOptimizer/*|python/ext-libs/*|ui_*.py|*.astyle|tests/testdata/*|editors/*) echo -ne "$f skipped $elcr" continue ;; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 128c3d1ea022..f13980fd21cf 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -18,6 +18,8 @@ SET(QGIS_CORE_SRCS ${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep.cc ${CMAKE_SOURCE_DIR}/external/meshOptimizer/simplifier.cpp + ${CMAKE_SOURCE_DIR}/external/mapbox-vector-tile/vector_tile.pb.cc + callouts/qgscallout.cpp callouts/qgscalloutsregistry.cpp @@ -643,7 +645,6 @@ SET(QGIS_CORE_SRCS vectortile/qgsvectortileloader.cpp vectortile/qgsvectortilemvtdecoder.cpp vectortile/qgsvectortileutils.cpp - vectortile/vector_tile.pb.cc ${CMAKE_CURRENT_BINARY_DIR}/qgsexpression_texts.cpp @@ -1436,6 +1437,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/external/poly2tri ${CMAKE_SOURCE_DIR}/external/rtree/include ${CMAKE_SOURCE_DIR}/external/meshOptimizer + ${CMAKE_SOURCE_DIR}/external/mapbox-vector-tile ) INCLUDE_DIRECTORIES(SYSTEM From 976c0e0ddb9a0f4637bd633f24a81a9fe7c9258f Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 26 Mar 2020 21:26:06 +0100 Subject: [PATCH 06/27] Do not mix class and struct --- python/core/auto_generated/qgstiles.sip.in | 15 ++++++++++++++- src/core/qgstiles.h | 2 +- src/core/vectortile/qgsvectortilelayer.h | 2 +- src/core/vectortile/qgsvectortileutils.h | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/python/core/auto_generated/qgstiles.sip.in b/python/core/auto_generated/qgstiles.sip.in index 67be19cd963c..b39c62bd6609 100644 --- a/python/core/auto_generated/qgstiles.sip.in +++ b/python/core/auto_generated/qgstiles.sip.in @@ -86,8 +86,21 @@ Returns index of the last row in the range }; -struct QgsTileMatrix +class QgsTileMatrix { +%Docstring +Defines a matrix of tiles for a single zoom level: it is defined by its size (width * height) +and map extent that it covers. + +Please note that we follow the XYZ convention of X/Y axes, i.e. top-left tile has [0,0] coordinate +(which is different from TMS convention where bottom-left tile has [0,0] coordinate). + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgstiles.h" +%End public: static QgsTileMatrix fromWebMercator( int mZoomLevel ); diff --git a/src/core/qgstiles.h b/src/core/qgstiles.h index 7c29d22d10e7..d7e7f73b76a2 100644 --- a/src/core/qgstiles.h +++ b/src/core/qgstiles.h @@ -96,7 +96,7 @@ class CORE_EXPORT QgsTileRange * * \since QGIS 3.14 */ -struct CORE_EXPORT QgsTileMatrix +class CORE_EXPORT QgsTileMatrix { public: diff --git a/src/core/vectortile/qgsvectortilelayer.h b/src/core/vectortile/qgsvectortilelayer.h index 32450aa7d9fe..496ba4d71a3e 100644 --- a/src/core/vectortile/qgsvectortilelayer.h +++ b/src/core/vectortile/qgsvectortilelayer.h @@ -23,7 +23,7 @@ class QgsVectorTileRenderer; -struct QgsTileXYZ; +class QgsTileXYZ; /** * \ingroup core diff --git a/src/core/vectortile/qgsvectortileutils.h b/src/core/vectortile/qgsvectortileutils.h index 03eb51340d02..6d045b9bf255 100644 --- a/src/core/vectortile/qgsvectortileutils.h +++ b/src/core/vectortile/qgsvectortileutils.h @@ -31,7 +31,7 @@ class QgsVectorLayer; class QgsTileMatrix; class QgsTileRange; -struct QgsTileXYZ; +class QgsTileXYZ; class QgsVectorTileLayer; /** From 4b362b3a5b4dc50642b67ee18a69571dfe4a7a87 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 26 Mar 2020 21:57:18 +0100 Subject: [PATCH 07/27] Silence warning, avoid indentation on generated MVT files --- scripts/astyle.sh | 2 +- src/core/CMakeLists.txt | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/astyle.sh b/scripts/astyle.sh index 7217f9acee60..29565ee2eff5 100755 --- a/scripts/astyle.sh +++ b/scripts/astyle.sh @@ -105,7 +105,7 @@ astyleit() { for f in "$@"; do case "$f" in - src/plugins/grass/qtermwidget/*|external/o2/*|external/qt-unix-signals/*|external/rtree/*|external/astyle/*|external/kdbush/*|external/poly2tri/*|external/wintoast/*|external/qt3dextra-headers/*|external/meshOptimizer/*|python/ext-libs/*|ui_*.py|*.astyle|tests/testdata/*|editors/*) + src/plugins/grass/qtermwidget/*|external/o2/*|external/qt-unix-signals/*|external/rtree/*|external/astyle/*|external/kdbush/*|external/poly2tri/*|external/wintoast/*|external/qt3dextra-headers/*|external/meshOptimizer/*|external/mapbox-vector-tile/*|python/ext-libs/*|ui_*.py|*.astyle|tests/testdata/*|editors/*) echo -ne "$f skipped $elcr" continue ;; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f13980fd21cf..ffcfff73da51 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -680,6 +680,11 @@ IF (CMAKE_CXX_COMPILER_ID MATCHES "Clang") SET_SOURCE_FILES_PROPERTIES(qgsspatialindex.cpp PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual) ENDIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang") +IF (NOT MSVC) + # automatically generated file produces warnings (unused-parameter, unused-variable, misleading-indentation) + SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/external/mapbox-vector-tile/vector_tile.pb.cc PROPERTIES COMPILE_FLAGS -w) +ENDIF (NOT MSVC) + IF (QT_MOBILITY_LOCATION_FOUND OR Qt5Positioning_FOUND) SET(QGIS_CORE_SRCS ${QGIS_CORE_SRCS} gps/qgsqtlocationconnection.cpp From 5ec1890643af969b99a51040ba4e8adbd70c77a5 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 27 Mar 2020 12:08:40 +0100 Subject: [PATCH 08/27] Moved to proper QgsMapLayer subclass + icon + optional tile borders --- images/images.qrc | 1 + python/core/auto_additions/qgsmaplayer.py | 4 +++- python/core/auto_generated/qgsdataitem.sip.in | 7 ++++++- python/core/auto_generated/qgsmaplayer.sip.in | 8 ++++++-- .../auto_generated/qgsmaplayerproxymodel.sip.in | 1 + .../vectortile/qgsvectortilelayer.sip.in | 13 +++++++++++-- python/plugins/db_manager/db_manager_plugin.py | 2 +- .../processing/qgsalgorithmfilterbygeometry.cpp | 1 + src/analysis/processing/qgsalgorithmpackage.cpp | 6 ++++++ src/app/CMakeLists.txt | 1 + src/app/browser/qgsinbuiltdataitemproviders.cpp | 1 + src/app/qgisapp.cpp | 11 +++++++++++ src/app/qgsidentifyresultsdialog.cpp | 4 ++++ src/app/qgslayerstylingwidget.cpp | 15 +++++++++++++++ src/app/qgslayertreeviewtemporalindicator.cpp | 1 + src/core/expression/qgsexpressionfunction.cpp | 2 ++ src/core/layertree/qgslayertreemodel.cpp | 3 +++ src/core/processing/qgsprocessingutils.cpp | 8 ++++++++ src/core/processing/qgsprocessingutils.h | 2 ++ src/core/qgsdataitem.cpp | 14 ++++++++++++++ src/core/qgsdataitem.h | 5 ++++- src/core/qgsmaplayer.h | 8 ++++++-- src/core/qgsmaplayermodel.cpp | 5 +++++ src/core/qgsmaplayerproxymodel.cpp | 1 + src/core/qgsmaplayerproxymodel.h | 3 ++- src/core/qgsmaprendererjob.cpp | 1 + src/core/qgsmbtilesreader.h | 2 ++ src/core/qgsmimedatautils.cpp | 6 ++++++ src/core/qgsproject.cpp | 5 +++++ src/core/vectortile/qgsvectortilelayer.cpp | 4 ++-- src/core/vectortile/qgsvectortilelayer.h | 17 +++++++++++++---- .../vectortile/qgsvectortilelayerrenderer.cpp | 1 + .../vectortile/qgsvectortilelayerrenderer.h | 2 +- src/gui/CMakeLists.txt | 1 + .../qgslayertreeembeddedwidgetsimpl.cpp | 3 +++ src/gui/qgsbrowserdockwidget_p.cpp | 8 ++++++++ src/gui/qgsidentifymenu.cpp | 4 ++++ 37 files changed, 163 insertions(+), 18 deletions(-) diff --git a/images/images.qrc b/images/images.qrc index 06a9872019bb..1fe5dee12ebd 100644 --- a/images/images.qrc +++ b/images/images.qrc @@ -513,6 +513,7 @@ themes/default/mIconTimerPause.svg themes/default/mIconTreeView.svg themes/default/mIconVector.svg + themes/default/mIconVectorTileLayer.svg themes/default/mIconVirtualLayer.svg themes/default/mIconWcs.svg themes/default/mIconWfs.svg diff --git a/python/core/auto_additions/qgsmaplayer.py b/python/core/auto_additions/qgsmaplayer.py index 4535f58d3d3d..fde3f16868da 100644 --- a/python/core/auto_additions/qgsmaplayer.py +++ b/python/core/auto_additions/qgsmaplayer.py @@ -9,7 +9,9 @@ QgsMapLayer.PluginLayer.__doc__ = "" QgsMapLayer.MeshLayer = QgsMapLayerType.MeshLayer QgsMapLayer.MeshLayer.__doc__ = "Added in 3.2" -QgsMapLayerType.__doc__ = 'Types of layers that can be added to a map\n\n.. versionadded:: 3.8\n\n' + '* ``VectorLayer``: ' + QgsMapLayerType.VectorLayer.__doc__ + '\n' + '* ``RasterLayer``: ' + QgsMapLayerType.RasterLayer.__doc__ + '\n' + '* ``PluginLayer``: ' + QgsMapLayerType.PluginLayer.__doc__ + '\n' + '* ``MeshLayer``: ' + QgsMapLayerType.MeshLayer.__doc__ +QgsMapLayer.VectorTileLayer = QgsMapLayerType.VectorTileLayer +QgsMapLayer.VectorTileLayer.__doc__ = "Added in 3.14" +QgsMapLayerType.__doc__ = 'Types of layers that can be added to a map\n\n.. versionadded:: 3.8\n\n' + '* ``VectorLayer``: ' + QgsMapLayerType.VectorLayer.__doc__ + '\n' + '* ``RasterLayer``: ' + QgsMapLayerType.RasterLayer.__doc__ + '\n' + '* ``PluginLayer``: ' + QgsMapLayerType.PluginLayer.__doc__ + '\n' + '* ``MeshLayer``: ' + QgsMapLayerType.MeshLayer.__doc__ + '\n' + '* ``VectorTileLayer``: ' + QgsMapLayerType.VectorTileLayer.__doc__ # -- QgsMapLayer.LayerFlag.baseClass = QgsMapLayer QgsMapLayer.LayerFlags.baseClass = QgsMapLayer diff --git a/python/core/auto_generated/qgsdataitem.sip.in b/python/core/auto_generated/qgsdataitem.sip.in index 4edac4ac530a..c44ca229b69e 100644 --- a/python/core/auto_generated/qgsdataitem.sip.in +++ b/python/core/auto_generated/qgsdataitem.sip.in @@ -479,7 +479,8 @@ Item that represents a layer that can be opened with one of the providers Database, Table, Plugin, - Mesh + Mesh, + VectorTile }; @@ -573,6 +574,10 @@ Use QgsDataItemGuiProvider.deleteLayer instead static QIcon iconMesh(); %Docstring Returns icon for mesh layer type +%End + static QIcon iconVectorTile(); +%Docstring +Returns icon for vector tile layer %End virtual QString layerName() const; diff --git a/python/core/auto_generated/qgsmaplayer.sip.in b/python/core/auto_generated/qgsmaplayer.sip.in index 480915b632e3..5185517f8242 100644 --- a/python/core/auto_generated/qgsmaplayer.sip.in +++ b/python/core/auto_generated/qgsmaplayer.sip.in @@ -19,7 +19,8 @@ enum class QgsMapLayerType VectorLayer, RasterLayer, PluginLayer, - MeshLayer + MeshLayer, + VectorTileLayer }; class QgsMapLayer : QObject @@ -53,6 +54,9 @@ This is the base class for all map layer types (vector, raster). case QgsMapLayerType::MeshLayer: sipType = sipType_QgsMeshLayer; break; + case QgsMapLayerType::VectorTileLayer: + sipType = sipType_QgsVectorTileLayer; + break; default: sipType = nullptr; break; @@ -1419,7 +1423,7 @@ Sets the coordinate transform context to ``transformContext`` SIP_PYOBJECT __repr__(); %MethodCode - QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider()->name() ); + QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QString() ); sipRes = PyUnicode_FromString( str.toUtf8().constData() ); %End diff --git a/python/core/auto_generated/qgsmaplayerproxymodel.sip.in b/python/core/auto_generated/qgsmaplayerproxymodel.sip.in index 6f07901d899a..cd78381587d9 100644 --- a/python/core/auto_generated/qgsmaplayerproxymodel.sip.in +++ b/python/core/auto_generated/qgsmaplayerproxymodel.sip.in @@ -34,6 +34,7 @@ The QgsMapLayerProxyModel class provides an easy to use model to display the lis PluginLayer, WritableLayer, MeshLayer, + VectorTileLayer, All }; typedef QFlags Filters; diff --git a/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in index ea62e989f05d..196d732ff912 100644 --- a/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in +++ b/python/core/auto_generated/vectortile/qgsvectortilelayer.sip.in @@ -11,7 +11,7 @@ -class QgsVectorTileLayer : QgsPluginLayer +class QgsVectorTileLayer : QgsMapLayer { %Docstring Implements a map layer that is dedicated to rendering of vector tiles. @@ -75,7 +75,7 @@ Constructs a new vector tile layer ~QgsVectorTileLayer(); - virtual QgsPluginLayer *clone() const /Factory/; + virtual QgsVectorTileLayer *clone() const /Factory/; virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/; @@ -123,6 +123,15 @@ Sets renderer for the map layer. QgsVectorTileRenderer *renderer() const; %Docstring Returns currently assigned renderer +%End + + void setTileBorderRenderingEnabled( bool enabled ); +%Docstring +Sets whether to render also borders of tiles (useful for debugging) +%End + bool isTileBorderRenderingEnabled() const; +%Docstring +Returns whether to render also borders of tiles (useful for debugging) %End }; diff --git a/python/plugins/db_manager/db_manager_plugin.py b/python/plugins/db_manager/db_manager_plugin.py index 049d4a77e854..5e137a6d7a01 100644 --- a/python/plugins/db_manager/db_manager_plugin.py +++ b/python/plugins/db_manager/db_manager_plugin.py @@ -85,7 +85,7 @@ def unload(self): def onLayerWasAdded(self, aMapLayer): # Be able to update every Db layer from Postgres, Spatialite and Oracle - if hasattr(aMapLayer, 'dataProvider') and aMapLayer.dataProvider().name() in ['postgres', 'spatialite', 'oracle']: + if hasattr(aMapLayer, 'dataProvider') and aMapLayer.dataProvider() and aMapLayer.dataProvider().name() in ['postgres', 'spatialite', 'oracle']: self.iface.addCustomActionForLayer(self.layerAction, aMapLayer) # virtual has QUrl source # url = QUrl(QUrl.fromPercentEncoding(l.source())) diff --git a/src/analysis/processing/qgsalgorithmfilterbygeometry.cpp b/src/analysis/processing/qgsalgorithmfilterbygeometry.cpp index 0bfc7f286c1e..52e8f101ea30 100644 --- a/src/analysis/processing/qgsalgorithmfilterbygeometry.cpp +++ b/src/analysis/processing/qgsalgorithmfilterbygeometry.cpp @@ -303,6 +303,7 @@ QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap & case QgsMapLayerType::PluginLayer: case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: break; } diff --git a/src/analysis/processing/qgsalgorithmpackage.cpp b/src/analysis/processing/qgsalgorithmpackage.cpp index f7d214385b4a..1461a494dde8 100644 --- a/src/analysis/processing/qgsalgorithmpackage.cpp +++ b/src/analysis/processing/qgsalgorithmpackage.cpp @@ -177,6 +177,12 @@ QVariantMap QgsPackageAlgorithm::processAlgorithm( const QVariantMap ¶meters feedback->pushDebugInfo( QObject::tr( "Packaging mesh layers is not supported." ) ); errored = true; break; + + case QgsMapLayerType::VectorTileLayer: + //not supported + feedback->pushDebugInfo( QObject::tr( "Packaging vector tile layers is not supported." ) ); + errored = true; + break; } } diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 4796088b48d1..af5ca1a46dbe 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -404,6 +404,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/core/symbology ${CMAKE_SOURCE_DIR}/src/core/effects ${CMAKE_SOURCE_DIR}/src/core/validity + ${CMAKE_SOURCE_DIR}/src/core/vectortile ${CMAKE_SOURCE_DIR}/src/gui ${CMAKE_SOURCE_DIR}/src/gui/attributeformconfig ${CMAKE_SOURCE_DIR}/src/gui/symbology diff --git a/src/app/browser/qgsinbuiltdataitemproviders.cpp b/src/app/browser/qgsinbuiltdataitemproviders.cpp index de79dfaa8d47..6d6898a26f9c 100644 --- a/src/app/browser/qgsinbuiltdataitemproviders.cpp +++ b/src/app/browser/qgsinbuiltdataitemproviders.cpp @@ -447,6 +447,7 @@ void QgsLayerItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *men case QgsMapLayerType::PluginLayer: case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: break; } } ); diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 8a0bbc4afb12..65f3b6f3afb7 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -8325,6 +8325,7 @@ QString QgisApp::saveAsFile( QgsMapLayer *layer, const bool onlySelected, const return saveAsVectorFileGeneral( qobject_cast( layer ), true, onlySelected, defaultToAddToMap ); case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: return QString(); } @@ -14006,6 +14007,10 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionIdentify->setEnabled( true ); break; + case QgsMapLayerType::VectorTileLayer: + // TODO + break; + case QgsMapLayerType::PluginLayer: break; @@ -14958,6 +14963,12 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page ) break; } + case QgsMapLayerType::VectorTileLayer: + { + // TODO + break; + } + case QgsMapLayerType::PluginLayer: { QgsPluginLayer *pl = qobject_cast( mapLayer ); diff --git a/src/app/qgsidentifyresultsdialog.cpp b/src/app/qgsidentifyresultsdialog.cpp index 617219d98f7f..1449961c5271 100644 --- a/src/app/qgsidentifyresultsdialog.cpp +++ b/src/app/qgsidentifyresultsdialog.cpp @@ -497,6 +497,10 @@ void QgsIdentifyResultsDialog::addFeature( const QgsMapToolIdentify::IdentifyRes addFeature( qobject_cast( result.mLayer ), result.mLabel, result.mAttributes, result.mDerivedAttributes ); break; + case QgsMapLayerType::VectorTileLayer: + // TODO + break; + case QgsMapLayerType::PluginLayer: break; } diff --git a/src/app/qgslayerstylingwidget.cpp b/src/app/qgslayerstylingwidget.cpp index 1ab0b863bbb1..0653dc46234a 100644 --- a/src/app/qgslayerstylingwidget.cpp +++ b/src/app/qgslayerstylingwidget.cpp @@ -225,6 +225,12 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer ) break; } + case QgsMapLayerType::VectorTileLayer: + { + // TODO + break; + } + case QgsMapLayerType::PluginLayer: break; } @@ -600,6 +606,12 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer() break; } + case QgsMapLayerType::VectorTileLayer: + { + // TODO + break; + } + case QgsMapLayerType::PluginLayer: { mStackedWidget->setCurrentIndex( mNotSupportedPage ); @@ -724,6 +736,9 @@ bool QgsLayerStyleManagerWidgetFactory::supportsLayer( QgsMapLayer *layer ) cons case QgsMapLayerType::MeshLayer: return true; + case QgsMapLayerType::VectorTileLayer: + return false; // TODO + case QgsMapLayerType::PluginLayer: return false; } diff --git a/src/app/qgslayertreeviewtemporalindicator.cpp b/src/app/qgslayertreeviewtemporalindicator.cpp index b616de741661..3b975fe40917 100644 --- a/src/app/qgslayertreeviewtemporalindicator.cpp +++ b/src/app/qgslayertreeviewtemporalindicator.cpp @@ -56,6 +56,7 @@ void QgsLayerTreeViewTemporalIndicatorProvider::onIndicatorClicked( const QModel case QgsMapLayerType::VectorLayer: case QgsMapLayerType::MeshLayer: case QgsMapLayerType::PluginLayer: + case QgsMapLayerType::VectorTileLayer: break; } } diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 49f044d9237a..6930b3bdef1e 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -4697,6 +4697,8 @@ static QVariant fcnGetLayerProperty( const QVariantList &values, const QgsExpres return QCoreApplication::translate( "expressions", "Raster" ); case QgsMapLayerType::MeshLayer: return QCoreApplication::translate( "expressions", "Mesh" ); + case QgsMapLayerType::VectorTileLayer: + return QCoreApplication::translate( "expressions", "Vector Tile" ); case QgsMapLayerType::PluginLayer: return QCoreApplication::translate( "expressions", "Plugin" ); } diff --git a/src/core/layertree/qgslayertreemodel.cpp b/src/core/layertree/qgslayertreemodel.cpp index 84dfaeb122af..909078f1f116 100644 --- a/src/core/layertree/qgslayertreemodel.cpp +++ b/src/core/layertree/qgslayertreemodel.cpp @@ -203,6 +203,9 @@ QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const case QgsMapLayerType::MeshLayer: return QgsLayerItem::iconMesh(); + case QgsMapLayerType::VectorTileLayer: + return QgsLayerItem::iconVectorTile(); + case QgsMapLayerType::VectorLayer: case QgsMapLayerType::PluginLayer: break; diff --git a/src/core/processing/qgsprocessingutils.cpp b/src/core/processing/qgsprocessingutils.cpp index fe7056ad88c0..53b5ada59908 100644 --- a/src/core/processing/qgsprocessingutils.cpp +++ b/src/core/processing/qgsprocessingutils.cpp @@ -33,6 +33,7 @@ #include "qgsmeshlayer.h" #include "qgsreferencedgeometry.h" #include "qgsrasterfilewriter.h" +#include "qgsvectortilelayer.h" QList QgsProcessingUtils::compatibleRasterLayers( QgsProject *project, bool sort ) { @@ -152,6 +153,8 @@ QgsMapLayer *QgsProcessingUtils::mapLayerFromStore( const QString &string, QgsMa return true; case QgsMapLayerType::MeshLayer: return !canUseLayer( qobject_cast< QgsMeshLayer * >( layer ) ); + case QgsMapLayerType::VectorTileLayer: + return !canUseLayer( qobject_cast< QgsVectorTileLayer * >( layer ) ); } return true; } ), layers.end() ); @@ -404,6 +407,11 @@ bool QgsProcessingUtils::canUseLayer( const QgsMeshLayer *layer ) return layer && layer->dataProvider(); } +bool QgsProcessingUtils::canUseLayer( const QgsVectorTileLayer *layer ) +{ + return layer && layer->isValid(); +} + bool QgsProcessingUtils::canUseLayer( const QgsRasterLayer *layer ) { return layer && layer->isValid(); diff --git a/src/core/processing/qgsprocessingutils.h b/src/core/processing/qgsprocessingutils.h index e8eb2a09a81c..f1ac1d8406cf 100644 --- a/src/core/processing/qgsprocessingutils.h +++ b/src/core/processing/qgsprocessingutils.h @@ -34,6 +34,7 @@ class QgsMapLayerStore; class QgsProcessingFeedback; class QgsProcessingFeatureSource; class QgsProcessingAlgorithm; +class QgsVectorTileLayer; #include #include @@ -383,6 +384,7 @@ class CORE_EXPORT QgsProcessingUtils private: static bool canUseLayer( const QgsRasterLayer *layer ); static bool canUseLayer( const QgsMeshLayer *layer ); + static bool canUseLayer( const QgsVectorTileLayer *layer ); static bool canUseLayer( const QgsVectorLayer *layer, const QList< int > &sourceTypes = QList< int >() ); diff --git a/src/core/qgsdataitem.cpp b/src/core/qgsdataitem.cpp index 8e4b80c5f3b4..85d3de6394a9 100644 --- a/src/core/qgsdataitem.cpp +++ b/src/core/qgsdataitem.cpp @@ -80,6 +80,11 @@ QIcon QgsLayerItem::iconMesh() return QgsApplication::getThemeIcon( QStringLiteral( "/mIconMeshLayer.svg" ) ); } +QIcon QgsLayerItem::iconVectorTile() +{ + return QgsApplication::getThemeIcon( QStringLiteral( "/mIconVectorTileLayer.svg" ) ); +} + QIcon QgsLayerItem::iconDefault() { return QgsApplication::getThemeIcon( QStringLiteral( "/mIconLayer.png" ) ); @@ -643,6 +648,9 @@ QgsMapLayerType QgsLayerItem::mapLayerType() const case QgsLayerItem::Mesh: return QgsMapLayerType::MeshLayer; + case QgsLayerItem::VectorTile: + return QgsMapLayerType::VectorTileLayer; + case QgsLayerItem::Plugin: return QgsMapLayerType::PluginLayer; @@ -693,6 +701,8 @@ QgsLayerItem::LayerType QgsLayerItem::typeFromMapLayer( QgsMapLayer *layer ) return Plugin; case QgsMapLayerType::MeshLayer: return Mesh; + case QgsMapLayerType::VectorTileLayer: + return VectorTile; } return Vector; // no warnings } @@ -778,6 +788,7 @@ QgsMimeDataUtils::Uri QgsLayerItem::mimeUri() const case Raster: case Plugin: case Mesh: + case VectorTile: break; } break; @@ -787,6 +798,9 @@ QgsMimeDataUtils::Uri QgsLayerItem::mimeUri() const case QgsMapLayerType::MeshLayer: u.layerType = QStringLiteral( "mesh" ); break; + case QgsMapLayerType::VectorTileLayer: + u.layerType = QStringLiteral( "vector-tile" ); + break; case QgsMapLayerType::PluginLayer: u.layerType = QStringLiteral( "plugin" ); break; diff --git a/src/core/qgsdataitem.h b/src/core/qgsdataitem.h index 637f8d3cb1c3..e697ecfdf151 100644 --- a/src/core/qgsdataitem.h +++ b/src/core/qgsdataitem.h @@ -506,7 +506,8 @@ class CORE_EXPORT QgsLayerItem : public QgsDataItem Database, Table, Plugin, //!< Added in 2.10 - Mesh //!< Added in 3.2 + Mesh, //!< Added in 3.2 + VectorTile //!< Added in 3.14 }; Q_ENUM( LayerType ) @@ -595,6 +596,8 @@ class CORE_EXPORT QgsLayerItem : public QgsDataItem static QIcon iconDefault(); //! Returns icon for mesh layer type static QIcon iconMesh(); + //! Returns icon for vector tile layer + static QIcon iconVectorTile(); //! \returns the layer name virtual QString layerName() const { return name(); } diff --git a/src/core/qgsmaplayer.h b/src/core/qgsmaplayer.h index 90f65cc83e0d..d1986c72881b 100644 --- a/src/core/qgsmaplayer.h +++ b/src/core/qgsmaplayer.h @@ -69,7 +69,8 @@ enum class QgsMapLayerType SIP_MONKEYPATCH_SCOPEENUM_UNNEST( QgsMapLayer, LayerT VectorLayer, RasterLayer, PluginLayer, - MeshLayer //!< Added in 3.2 + MeshLayer, //!< Added in 3.2 + VectorTileLayer //!< Added in 3.14 }; /** @@ -108,6 +109,9 @@ class CORE_EXPORT QgsMapLayer : public QObject case QgsMapLayerType::MeshLayer: sipType = sipType_QgsMeshLayer; break; + case QgsMapLayerType::VectorTileLayer: + sipType = sipType_QgsVectorTileLayer; + break; default: sipType = nullptr; break; @@ -1273,7 +1277,7 @@ class CORE_EXPORT QgsMapLayer : public QObject #ifdef SIP_RUN SIP_PYOBJECT __repr__(); % MethodCode - QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider()->name() ); + QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QString() ); sipRes = PyUnicode_FromString( str.toUtf8().constData() ); % End #endif diff --git a/src/core/qgsmaplayermodel.cpp b/src/core/qgsmaplayermodel.cpp index a4e2c5a78f07..fc51b44514ef 100644 --- a/src/core/qgsmaplayermodel.cpp +++ b/src/core/qgsmaplayermodel.cpp @@ -367,6 +367,11 @@ QIcon QgsMapLayerModel::iconForLayer( QgsMapLayer *layer ) return QgsLayerItem::iconMesh(); } + case QgsMapLayerType::VectorTileLayer: + { + return QgsLayerItem::iconVectorTile(); + } + case QgsMapLayerType::VectorLayer: { QgsVectorLayer *vl = qobject_cast( layer ); diff --git a/src/core/qgsmaplayerproxymodel.cpp b/src/core/qgsmaplayerproxymodel.cpp index 4dd20727fa97..485f61695d9f 100644 --- a/src/core/qgsmaplayerproxymodel.cpp +++ b/src/core/qgsmaplayerproxymodel.cpp @@ -116,6 +116,7 @@ bool QgsMapLayerProxyModel::acceptsLayer( QgsMapLayer *layer ) const if ( ( mFilters.testFlag( RasterLayer ) && layer->type() == QgsMapLayerType::RasterLayer ) || ( mFilters.testFlag( VectorLayer ) && layer->type() == QgsMapLayerType::VectorLayer ) || ( mFilters.testFlag( MeshLayer ) && layer->type() == QgsMapLayerType::MeshLayer ) || + ( mFilters.testFlag( VectorTileLayer ) && layer->type() == QgsMapLayerType::VectorTileLayer ) || ( mFilters.testFlag( PluginLayer ) && layer->type() == QgsMapLayerType::PluginLayer ) ) return true; diff --git a/src/core/qgsmaplayerproxymodel.h b/src/core/qgsmaplayerproxymodel.h index 2383bd9a94f0..8261dc911f02 100644 --- a/src/core/qgsmaplayerproxymodel.h +++ b/src/core/qgsmaplayerproxymodel.h @@ -51,7 +51,8 @@ class CORE_EXPORT QgsMapLayerProxyModel : public QSortFilterProxyModel PluginLayer = 32, WritableLayer = 64, MeshLayer = 128, //!< QgsMeshLayer \since QGIS 3.6 - All = RasterLayer | VectorLayer | PluginLayer | MeshLayer + VectorTileLayer = 256, //!< QgsVectorTileLayer \since QGIS 3.14 + All = RasterLayer | VectorLayer | PluginLayer | MeshLayer | VectorTileLayer }; Q_DECLARE_FLAGS( Filters, Filter ) Q_FLAG( Filters ) diff --git a/src/core/qgsmaprendererjob.cpp b/src/core/qgsmaprendererjob.cpp index 68c951a3beed..05969df628ae 100644 --- a/src/core/qgsmaprendererjob.cpp +++ b/src/core/qgsmaprendererjob.cpp @@ -906,6 +906,7 @@ bool QgsMapRendererJob::needTemporaryImage( QgsMapLayer *ml ) } case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: break; } diff --git a/src/core/qgsmbtilesreader.h b/src/core/qgsmbtilesreader.h index 801aeba0c557..a08ded825d9c 100644 --- a/src/core/qgsmbtilesreader.h +++ b/src/core/qgsmbtilesreader.h @@ -21,6 +21,8 @@ #include "sqlite3.h" #include "qgssqliteutils.h" +#define SIP_NO_FILE + class QImage; class QgsRectangle; diff --git a/src/core/qgsmimedatautils.cpp b/src/core/qgsmimedatautils.cpp index 58fea21faebd..08fba7866d2f 100644 --- a/src/core/qgsmimedatautils.cpp +++ b/src/core/qgsmimedatautils.cpp @@ -91,6 +91,12 @@ QgsMimeDataUtils::Uri::Uri( QgsMapLayer *layer ) break; } + case QgsMapLayerType::VectorTileLayer: + { + layerType = QStringLiteral( "vector-tile" ); + break; + } + case QgsMapLayerType::PluginLayer: { // plugin layers do not have a standard way of storing their URI... diff --git a/src/core/qgsproject.cpp b/src/core/qgsproject.cpp index 99d10c5b336c..415319c89e80 100644 --- a/src/core/qgsproject.cpp +++ b/src/core/qgsproject.cpp @@ -60,6 +60,7 @@ #include "qgsprojectviewsettings.h" #include "qgsprojectdisplaysettings.h" #include "qgsprojecttimesettings.h" +#include "qgsvectortilelayer.h" #include #include @@ -1062,6 +1063,10 @@ bool QgsProject::addLayer( const QDomElement &layerElem, QList &broken { mapLayer = qgis::make_unique(); } + else if ( type == QLatin1String( "vector-tile" ) ) + { + mapLayer = qgis::make_unique(); + } else if ( type == QLatin1String( "plugin" ) ) { QString typeName = layerElem.attribute( QStringLiteral( "name" ) ); diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index b035fde77b9b..f30690f07d51 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -23,7 +23,7 @@ #include "qgsdatasourceuri.h" QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseName ) - : QgsPluginLayer( "vector-tile", baseName ) + : QgsMapLayer( QgsMapLayerType::VectorTileLayer, baseName ) { mDataSource = uri; @@ -79,7 +79,7 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN QgsVectorTileLayer::~QgsVectorTileLayer() = default; -QgsPluginLayer *QgsVectorTileLayer::clone() const +QgsVectorTileLayer *QgsVectorTileLayer::clone() const { QgsVectorTileLayer *layer = new QgsVectorTileLayer( source(), name() ); layer->setRenderer( renderer() ? renderer()->clone() : nullptr ); diff --git a/src/core/vectortile/qgsvectortilelayer.h b/src/core/vectortile/qgsvectortilelayer.h index 496ba4d71a3e..82e6601e13be 100644 --- a/src/core/vectortile/qgsvectortilelayer.h +++ b/src/core/vectortile/qgsvectortilelayer.h @@ -19,7 +19,7 @@ #include "qgis_core.h" #include "qgis_sip.h" -#include "qgspluginlayer.h" +#include "qgsmaplayer.h" class QgsVectorTileRenderer; @@ -76,16 +76,18 @@ class QgsTileXYZ; * * \since QGIS 3.14 */ -class CORE_EXPORT QgsVectorTileLayer : public QgsPluginLayer +class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer { + Q_OBJECT + public: //! Constructs a new vector tile layer explicit QgsVectorTileLayer( const QString &path = QString(), const QString &baseName = QString() ); - ~QgsVectorTileLayer(); + ~QgsVectorTileLayer() override; // implementation of virtual functions from QgsMapLayer - QgsPluginLayer *clone() const override SIP_FACTORY; + QgsVectorTileLayer *clone() const override SIP_FACTORY; virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY; @@ -130,6 +132,11 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsPluginLayer //! Returns currently assigned renderer QgsVectorTileRenderer *renderer() const; + //! Sets whether to render also borders of tiles (useful for debugging) + void setTileBorderRenderingEnabled( bool enabled ) { mTileBorderRendering = enabled; } + //! Returns whether to render also borders of tiles (useful for debugging) + bool isTileBorderRenderingEnabled() const { return mTileBorderRendering; } + private: //! Type of the data source QString mSourceType; @@ -142,6 +149,8 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsPluginLayer //! Renderer assigned to the layer to draw map std::unique_ptr mRenderer; + //! Whether we draw borders of tiles + bool mTileBorderRendering = false; }; diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index 8976b0ffa46b..697ce32020db 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -33,6 +33,7 @@ QgsVectorTileLayerRenderer::QgsVectorTileLayerRenderer( QgsVectorTileLayer *laye , mSourceMinZoom( layer->sourceMinZoom() ) , mSourceMaxZoom( layer->sourceMaxZoom() ) , mRenderer( layer->renderer()->clone() ) + , mDrawTileBoundaries( layer->isTileBorderRenderingEnabled() ) , mFeedback( new QgsFeedback ) { } diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.h b/src/core/vectortile/qgsvectortilelayerrenderer.h index ae90629bcdf7..68bbb29d75e3 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.h +++ b/src/core/vectortile/qgsvectortilelayerrenderer.h @@ -61,7 +61,7 @@ class QgsVectorTileLayerRenderer : public QgsMapLayerRenderer std::unique_ptr mRenderer; //! Whether to draw boundaries of tiles (useful for debugging) - bool mDrawTileBoundaries = true; + bool mDrawTileBoundaries = false; // temporary data used during rendering process diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 3e1efdd206b1..74995087087b 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1197,6 +1197,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/core/metadata ${CMAKE_SOURCE_DIR}/src/core/expression ${CMAKE_SOURCE_DIR}/src/core/validity + ${CMAKE_SOURCE_DIR}/src/core/vectortile ${CMAKE_SOURCE_DIR}/src/native ${CMAKE_SOURCE_DIR}/external ${CMAKE_SOURCE_DIR}/external/nlohmann diff --git a/src/gui/layertree/qgslayertreeembeddedwidgetsimpl.cpp b/src/gui/layertree/qgslayertreeembeddedwidgetsimpl.cpp index f4c0f754fde6..08b73551505a 100644 --- a/src/gui/layertree/qgslayertreeembeddedwidgetsimpl.cpp +++ b/src/gui/layertree/qgslayertreeembeddedwidgetsimpl.cpp @@ -73,6 +73,7 @@ QgsLayerTreeOpacityWidget::QgsLayerTreeOpacityWidget( QgsMapLayer *layer ) case QgsMapLayerType::PluginLayer: case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: break; } @@ -112,6 +113,7 @@ void QgsLayerTreeOpacityWidget::updateOpacityFromSlider() case QgsMapLayerType::PluginLayer: case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: break; } @@ -152,6 +154,7 @@ bool QgsLayerTreeOpacityWidget::Provider::supportsLayer( QgsMapLayer *layer ) return true; case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: return false; } diff --git a/src/gui/qgsbrowserdockwidget_p.cpp b/src/gui/qgsbrowserdockwidget_p.cpp index 2fd1931766ad..5cea88a4ad52 100644 --- a/src/gui/qgsbrowserdockwidget_p.cpp +++ b/src/gui/qgsbrowserdockwidget_p.cpp @@ -44,6 +44,7 @@ #include "qgsnative.h" #include "qgsmaptoolpan.h" #include "qgsvectorlayercache.h" +#include "qgsvectortilelayer.h" #include "qgsattributetablemodel.h" #include "qgsattributetablefiltermodel.h" #include "qgsapplication.h" @@ -208,6 +209,13 @@ void QgsBrowserLayerProperties::setItem( QgsDataItem *item ) break; } + case QgsMapLayerType::VectorTileLayer: + { + QgsDebugMsg( QStringLiteral( "creating vector tile layer" ) ); + mLayer = qgis::make_unique< QgsVectorTileLayer >( layerItem->uri(), layerItem->name() ); + break; + } + case QgsMapLayerType::PluginLayer: { // TODO: support display of properties for plugin layers diff --git a/src/gui/qgsidentifymenu.cpp b/src/gui/qgsidentifymenu.cpp index cd973bd07546..f387c00d8278 100644 --- a/src/gui/qgsidentifymenu.cpp +++ b/src/gui/qgsidentifymenu.cpp @@ -126,6 +126,10 @@ QList QgsIdentifyMenu::exec( const QList Date: Fri, 27 Mar 2020 13:14:41 +0100 Subject: [PATCH 09/27] Added forgotten icon for vector tile layer --- .../themes/default/mIconVectorTileLayer.svg | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 images/themes/default/mIconVectorTileLayer.svg diff --git a/images/themes/default/mIconVectorTileLayer.svg b/images/themes/default/mIconVectorTileLayer.svg new file mode 100644 index 000000000000..fa10e503b7d5 --- /dev/null +++ b/images/themes/default/mIconVectorTileLayer.svg @@ -0,0 +1,195 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8d24e1744b02530eefe840b3a1076f117e8df12b Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 27 Mar 2020 14:02:13 +0100 Subject: [PATCH 10/27] Added zmin/zmax parameters to limit usable zoom levels --- python/core/auto_generated/qgsmaplayer.sip.in | 2 +- src/core/qgsmaplayer.h | 2 +- src/core/vectortile/qgsvectortilelayer.cpp | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/python/core/auto_generated/qgsmaplayer.sip.in b/python/core/auto_generated/qgsmaplayer.sip.in index 5185517f8242..fa8de3a8987d 100644 --- a/python/core/auto_generated/qgsmaplayer.sip.in +++ b/python/core/auto_generated/qgsmaplayer.sip.in @@ -1423,7 +1423,7 @@ Sets the coordinate transform context to ``transformContext`` SIP_PYOBJECT __repr__(); %MethodCode - QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QString() ); + QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QStringLiteral( "Invalid" ) ); sipRes = PyUnicode_FromString( str.toUtf8().constData() ); %End diff --git a/src/core/qgsmaplayer.h b/src/core/qgsmaplayer.h index d1986c72881b..b19cab3a817f 100644 --- a/src/core/qgsmaplayer.h +++ b/src/core/qgsmaplayer.h @@ -1277,7 +1277,7 @@ class CORE_EXPORT QgsMapLayer : public QObject #ifdef SIP_RUN SIP_PYOBJECT __repr__(); % MethodCode - QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QString() ); + QString str = QStringLiteral( "" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QStringLiteral( "Invalid" ) ); sipRes = PyUnicode_FromString( str.toUtf8().constData() ); % End #endif diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index f30690f07d51..80c26948fbc4 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -38,6 +38,11 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN mSourceMinZoom = 0; mSourceMaxZoom = 14; + if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) ) + mSourceMinZoom = dsUri.param( QStringLiteral( "zmin" ) ).toInt(); + if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) ) + mSourceMaxZoom = dsUri.param( QStringLiteral( "zmax" ) ).toInt(); + setExtent( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) ); } else if ( mSourceType == "mbtiles" ) From 6a107c804edebef568a72d72462e24aff67a6726 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 27 Mar 2020 14:36:44 +0100 Subject: [PATCH 11/27] Added initial unit test + test data --- tests/src/core/CMakeLists.txt | 2 + tests/src/core/testqgsvectortilelayer.cpp | 88 ++++++++++++++++++++++ tests/testdata/vector_tile/0-0-0.pbf | Bin 0 -> 64822 bytes tests/testdata/vector_tile/1-0-0.pbf | Bin 0 -> 155777 bytes tests/testdata/vector_tile/1-0-1.pbf | Bin 0 -> 147305 bytes tests/testdata/vector_tile/1-1-0.pbf | Bin 0 -> 165124 bytes tests/testdata/vector_tile/1-1-1.pbf | Bin 0 -> 146886 bytes tests/testdata/vector_tile/README.md | 15 ++++ 8 files changed, 105 insertions(+) create mode 100644 tests/src/core/testqgsvectortilelayer.cpp create mode 100644 tests/testdata/vector_tile/0-0-0.pbf create mode 100644 tests/testdata/vector_tile/1-0-0.pbf create mode 100644 tests/testdata/vector_tile/1-0-1.pbf create mode 100644 tests/testdata/vector_tile/1-1-0.pbf create mode 100644 tests/testdata/vector_tile/1-1-1.pbf create mode 100644 tests/testdata/vector_tile/README.md diff --git a/tests/src/core/CMakeLists.txt b/tests/src/core/CMakeLists.txt index be74141a7b23..d717b457a47e 100644 --- a/tests/src/core/CMakeLists.txt +++ b/tests/src/core/CMakeLists.txt @@ -31,6 +31,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src/core/symbology ${CMAKE_SOURCE_DIR}/src/core/classification ${CMAKE_SOURCE_DIR}/src/core/mesh + ${CMAKE_SOURCE_DIR}/src/core/vectortile ${CMAKE_SOURCE_DIR}/src/test ${CMAKE_BINARY_DIR}/src/core @@ -237,6 +238,7 @@ SET(TESTS testqgsvectorlayerjoinbuffer.cpp testqgsvectorlayer.cpp testqgsvectorlayerutils.cpp + testqgsvectortilelayer.cpp testqgsziputils.cpp testziplayer.cpp testqgslayerdefinition.cpp diff --git a/tests/src/core/testqgsvectortilelayer.cpp b/tests/src/core/testqgsvectortilelayer.cpp new file mode 100644 index 000000000000..1c132e3d434c --- /dev/null +++ b/tests/src/core/testqgsvectortilelayer.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + testqgsvectortilelayer.cpp + -------------------------------------- + Date : March 2020 + Copyright : (C) 2020 by Martin Dobias + Email : wonder dot sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgstest.h" +#include +#include + +//qgis includes... +#include "qgsapplication.h" +#include "qgsproject.h" +#include "qgstiles.h" +#include "qgsvectortilelayer.h" + +/** + * \ingroup UnitTests + * This is a unit test for a vector tile layer + */ +class TestQgsVectorTileLayer : public QObject +{ + Q_OBJECT + + public: + TestQgsVectorTileLayer() = default; + + private: + QString mDataDir; + QgsVectorTileLayer *mLayer = nullptr; + + private slots: + void initTestCase();// will be called before the first testfunction is executed. + void cleanupTestCase();// will be called after the last testfunction was executed. + void init() {} // will be called before each testfunction is executed. + void cleanup() {} // will be called after every testfunction. + + void test_basic(); +}; + + +void TestQgsVectorTileLayer::initTestCase() +{ + // init QGIS's paths - true means that all path will be inited from prefix + QgsApplication::init(); + QgsApplication::initQgis(); + QgsApplication::showSettings(); + mDataDir = QString( TEST_DATA_DIR ); //defined in CmakeLists.txt + mDataDir += "/vector_tile"; + + QgsDataSourceUri ds; + ds.setParam( "type", "xyz" ); + ds.setParam( "url", QString( "file://%1/{z}-{x}-{y}.pbf" ).arg( mDataDir ) ); + ds.setParam( "zmax", "1" ); + mLayer = new QgsVectorTileLayer( ds.encodedUri(), "Vector Tiles Test" ); + QVERIFY( mLayer->isValid() ); + + QgsProject::instance()->addMapLayer( mLayer ); + +} + +void TestQgsVectorTileLayer::cleanupTestCase() +{ + QgsApplication::exitQgis(); +} + +void TestQgsVectorTileLayer::test_basic() +{ + // tile fetch test + QByteArray tile0rawData = mLayer->getRawTile( QgsTileXYZ( 0, 0, 0 ) ); + QCOMPARE( tile0rawData.length(), 64822 ); + + QByteArray invalidTileRawData = mLayer->getRawTile( QgsTileXYZ( 0, 0, 99 ) ); + QCOMPARE( invalidTileRawData.length(), 0 ); +} + + +QGSTEST_MAIN( TestQgsVectorTileLayer ) +#include "testqgsvectortilelayer.moc" diff --git a/tests/testdata/vector_tile/0-0-0.pbf b/tests/testdata/vector_tile/0-0-0.pbf new file mode 100644 index 0000000000000000000000000000000000000000..3a2e0450500eb6495c39322b780b647b8b7ddc49 GIT binary patch literal 64822 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/vector_tile/1-0-1.pbf b/tests/testdata/vector_tile/1-0-1.pbf new file mode 100644 index 0000000000000000000000000000000000000000..3c4f544d98741c5dd17fe97dfb070e6dba0ec94c GIT binary patch literal 147305 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 afkDF8}vZf)|BQ4=0X*R@W2ra785!jwTZPJ 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� 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 BvK9aU literal 0 HcmV?d00001 diff --git a/tests/testdata/vector_tile/1-1-1.pbf b/tests/testdata/vector_tile/1-1-1.pbf new file mode 100644 index 0000000000000000000000000000000000000000..896ef86722a63133af95ddb1b0538288b370f4ea GIT binary patch literal 146886 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 D7gKQm literal 0 HcmV?d00001 diff --git a/tests/testdata/vector_tile/README.md b/tests/testdata/vector_tile/README.md new file mode 100644 index 000000000000..81c38e58dcbe --- /dev/null +++ b/tests/testdata/vector_tile/README.md @@ -0,0 +1,15 @@ + +# Vector Tiles Test Data + +Downloaded from https://api.maptiler.com/tiles/v3/{z}/{x}/{y}.pbf?key=XXX +(where XXX stands for a key that can be obtained when registered at MapTiler: https://www.maptiler.com/) + +## License + +These tiles are coming from OpenMapTiles project, under the "Free data" terms of use: https://openmaptiles.com/terms/ + +The FREE tiles are legally usable for: + +- open-source and open-data community project websites +- non-commercial personal projects +- evaluation and education purposes From 3c33bf7863dad110e4eb5c767aa0a1936fdb675c Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 27 Mar 2020 16:36:19 +0100 Subject: [PATCH 12/27] Added a basic rendering test --- .../qgsvectortilebasicrenderer.sip.in | 8 +++ .../vectortile/qgsvectortilebasicrenderer.cpp | 58 +++++++++++++----- .../vectortile/qgsvectortilebasicrenderer.h | 6 ++ tests/src/core/testqgsvectortilelayer.cpp | 31 ++++++++++ .../expected_render_test_basic.png | Bin 0 -> 160537 bytes 5 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 tests/testdata/control_images/vector_tile/expected_render_test_basic/expected_render_test_basic.png diff --git a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in index 9f44f528ec36..30156922914b 100644 --- a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in +++ b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in @@ -171,6 +171,14 @@ Sets list of styles of the renderer QList styles() const; %Docstring Returns list of styles of the renderer +%End + + static QList simpleStyle( + const QColor &polygonFillColor, const QColor &polygonStrokeColor, double polygonStrokeWidth, + const QColor &lineStrokeColor, double lineStrokeWidth, + const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize ); +%Docstring +Sets a default style to render all layers with the given fill/stroke colors, stroke widths and marker sizes %End }; diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.cpp b/src/core/vectortile/qgsvectortilebasicrenderer.cpp index 4ee5086660d4..bc6ba9036d33 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.cpp +++ b/src/core/vectortile/qgsvectortilebasicrenderer.cpp @@ -16,7 +16,9 @@ #include "qgsvectortilebasicrenderer.h" #include "qgsexpressioncontextutils.h" +#include "qgsfillsymbollayer.h" #include "qgslinesymbollayer.h" +#include "qgsmarkersymbollayer.h" #include "qgssymbollayerutils.h" #include "qgsvectortileutils.h" @@ -229,30 +231,56 @@ QList QgsVectorTileBasicRenderer::styles() cons void QgsVectorTileBasicRenderer::setDefaultStyle() { - QColor color = Qt::blue; - QColor polygonColor = color; - polygonColor.setAlpha( 100 ); - QColor pointColor = Qt::red; - - QgsFillSymbol *polygonSymbol = static_cast( QgsLineSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ); - polygonSymbol->setColor( polygonColor ); - - QgsLineSymbol *lineSymbol = static_cast( QgsLineSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ); - lineSymbol->setColor( color ); + QColor polygonFillColor = Qt::blue; + QColor polygonStrokeColor = polygonFillColor; + polygonFillColor.setAlpha( 100 ); + double polygonStrokeWidth = DEFAULT_LINE_WIDTH; + + QColor lineStrokeColor = Qt::blue; + double lineStrokeWidth = DEFAULT_LINE_WIDTH; + + QColor pointFillColor = Qt::red; + QColor pointStrokeColor = pointFillColor; + pointFillColor.setAlpha( 100 ); + double pointSize = DEFAULT_POINT_SIZE; + + setStyles( simpleStyle( polygonFillColor, polygonStrokeColor, polygonStrokeWidth, + lineStrokeColor, lineStrokeWidth, + pointFillColor, pointStrokeColor, pointSize ) ); +} - QgsMarkerSymbol *pointSymbol = static_cast( QgsLineSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) ); - pointSymbol->setColor( pointColor ); +QList QgsVectorTileBasicRenderer::simpleStyle( + const QColor &polygonFillColor, const QColor &polygonStrokeColor, double polygonStrokeWidth, + const QColor &lineStrokeColor, double lineStrokeWidth, + const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize ) +{ + QgsSimpleFillSymbolLayer *fillSymbolLayer = new QgsSimpleFillSymbolLayer(); + fillSymbolLayer->setFillColor( polygonFillColor ); + fillSymbolLayer->setStrokeColor( polygonStrokeColor ); + fillSymbolLayer->setStrokeWidth( polygonStrokeWidth ); + QgsFillSymbol *fillSymbol = new QgsFillSymbol( QgsSymbolLayerList() << fillSymbolLayer ); + + QgsSimpleLineSymbolLayer *lineSymbolLayer = new QgsSimpleLineSymbolLayer; + lineSymbolLayer->setColor( lineStrokeColor ); + lineSymbolLayer->setWidth( lineStrokeWidth ); + QgsLineSymbol *lineSymbol = new QgsLineSymbol( QgsSymbolLayerList() << lineSymbolLayer ); + + QgsSimpleMarkerSymbolLayer *markerSymbolLayer = new QgsSimpleMarkerSymbolLayer; + markerSymbolLayer->setFillColor( pointFillColor ); + markerSymbolLayer->setStrokeColor( pointStrokeColor ); + markerSymbolLayer->setSize( pointSize ); + QgsMarkerSymbol *markerSymbol = new QgsMarkerSymbol( QgsSymbolLayerList() << markerSymbolLayer ); QgsVectorTileBasicRendererStyle st1( "polygons", QString(), QgsWkbTypes::PolygonGeometry ); - st1.setSymbol( polygonSymbol ); + st1.setSymbol( fillSymbol ); QgsVectorTileBasicRendererStyle st2( "lines", QString(), QgsWkbTypes::LineGeometry ); st2.setSymbol( lineSymbol ); QgsVectorTileBasicRendererStyle st3( "points", QString(), QgsWkbTypes::PointGeometry ); - st3.setSymbol( pointSymbol ); + st3.setSymbol( markerSymbol ); QList lst; lst << st1 << st2 << st3; - setStyles( lst ); + return lst; } diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.h b/src/core/vectortile/qgsvectortilebasicrenderer.h index ecc47fe0aae5..7dd25e8d5720 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.h +++ b/src/core/vectortile/qgsvectortilebasicrenderer.h @@ -142,6 +142,12 @@ class CORE_EXPORT QgsVectorTileBasicRenderer : public QgsVectorTileRenderer //! Returns list of styles of the renderer QList styles() const; + //! Sets a default style to render all layers with the given fill/stroke colors, stroke widths and marker sizes + static QList simpleStyle( + const QColor &polygonFillColor, const QColor &polygonStrokeColor, double polygonStrokeWidth, + const QColor &lineStrokeColor, double lineStrokeWidth, + const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize ); + private: void setDefaultStyle(); diff --git a/tests/src/core/testqgsvectortilelayer.cpp b/tests/src/core/testqgsvectortilelayer.cpp index 1c132e3d434c..468cf1b0fe06 100644 --- a/tests/src/core/testqgsvectortilelayer.cpp +++ b/tests/src/core/testqgsvectortilelayer.cpp @@ -20,6 +20,7 @@ //qgis includes... #include "qgsapplication.h" #include "qgsproject.h" +#include "qgsrenderchecker.h" #include "qgstiles.h" #include "qgsvectortilelayer.h" @@ -37,6 +38,10 @@ class TestQgsVectorTileLayer : public QObject private: QString mDataDir; QgsVectorTileLayer *mLayer = nullptr; + QString mReport; + QgsMapSettings *mMapSettings = nullptr; + + bool imageCheck( const QString &testType, QgsVectorTileLayer *layer, QgsRectangle extent ); private slots: void initTestCase();// will be called before the first testfunction is executed. @@ -45,6 +50,7 @@ class TestQgsVectorTileLayer : public QObject void cleanup() {} // will be called after every testfunction. void test_basic(); + void test_render(); }; @@ -66,6 +72,9 @@ void TestQgsVectorTileLayer::initTestCase() QgsProject::instance()->addMapLayer( mLayer ); + mMapSettings = new QgsMapSettings(); + mMapSettings->setLayers( QList() << mLayer ); + } void TestQgsVectorTileLayer::cleanupTestCase() @@ -84,5 +93,27 @@ void TestQgsVectorTileLayer::test_basic() } +bool TestQgsVectorTileLayer::imageCheck( const QString &testType, QgsVectorTileLayer *layer, QgsRectangle extent ) +{ + mReport += "

" + testType + "

\n"; + mMapSettings->setExtent( extent ); + mMapSettings->setDestinationCrs( layer->crs() ); + mMapSettings->setOutputDpi( 96 ); + QgsRenderChecker myChecker; + myChecker.setControlPathPrefix( QStringLiteral( "vector_tile" ) ); + myChecker.setControlName( "expected_" + testType ); + myChecker.setMapSettings( *mMapSettings ); + myChecker.setColorTolerance( 15 ); + bool myResultFlag = myChecker.runTest( testType, 0 ); + mReport += myChecker.report(); + return myResultFlag; +} + +void TestQgsVectorTileLayer::test_render() +{ + QVERIFY( imageCheck( "render_test_basic", mLayer, mLayer->extent() ) ); +} + + QGSTEST_MAIN( TestQgsVectorTileLayer ) #include "testqgsvectortilelayer.moc" diff --git a/tests/testdata/control_images/vector_tile/expected_render_test_basic/expected_render_test_basic.png b/tests/testdata/control_images/vector_tile/expected_render_test_basic/expected_render_test_basic.png new file mode 100644 index 0000000000000000000000000000000000000000..45096375f9d3b78fac3e081ff84bf75d89b54b4d GIT binary patch literal 160537 zcmeF41)P-C_r}k}(k&f=gwm14?N$bObxR-cKlJD&blRF$M^l}u0Yj#(O8xJV%m1E?7ahf z??C(=ST-kMVJ1hjPSNZ+%J%xnPurXtt>ZV_`(Ae-8ZlckGhl0%2dqdjMcVg?x&KR)-FtifOLt(~1YvSq z`q{NMv~4$w21D)|gBk^$Ke@_YKCR#0Ns{o?N53DklI3F7@|dX2|08JgCI@ZBe6!6P z0(L@=h?OX_H@B2<%l?&rZkr%zj`+#J)i6eCxpKt6@&Y%m(RD-vR;*;q zrvDPOa+P9MxpvG_is$}vQa78;`7LOh)|%~8Gp0!qu!^HU+h2I}}&faFghJ=JXF zJ0TnXR>)?J57?)Vhpo{eQTuyAz`hx%Mc_?+{%g=;xfstMKNfZxr1U;!7v7U@sha~9 zOUSo|Q_Ok{Ot%G7gSLEbAo&yCyJexg1KYGop**{tJgLp=%|^c)vI`$bw+3xu8pviv z{?Q(Xo$rn48RG)>(}y7&p$XLS+=yvS$X3RD9J0$EPPdlFM(x#`!gl|uDOR;^)K)Ia z{AV}3m1Yl|mSW)|QL9ir7qc+)-R=E!H{AiJO%_ybW;o~gABhrxK`QEPod)P8&= zXmfrKSlg2#&i5#pje~yKqv6;!UR2iv#w{XF*%1s8yLt z(n=o$ooQCRLChu(4cQ4-N37NHoCv(yx2M6uf zZ-Z7%6Kc-yLBl*-yCPr*pBlA4Mg*+g=}{Z6eIMO5Vv~mj72b{6tcgK8`__mZc$7Ce zRxb_MlNX0={VE|rQ({)FeoO%Zvuc`16>G&Tu-6qy=1~;7Z6*&5T80VYpP}!Z{~OFI zqDw!%60*~8idehTyaDT9M^3L_JS#_iLeR=oj9F2Y5U@}*>JYV!YXkPsnPKbpRJxTY zXZG9oLHqovkkxG&v)aw0woi?i{qkwZO^}0i%<@%Z_N^TMP3z2>92&Dh*N2oJF&7Xx z`!;XF&KwuCm0EZ9J5Uj|I>~9boX&sm_XT?gvYa3Vd)WNl`+`5c#9j9na;G`oe;{Nt zG-w-ljM^M&gkEoMH!V3sFVA82PT#OSGda~hek5dLKMmU97kLwcZN7XiWTliBIjT$4 zX&gR77EY7jp(xt7140%?Ob${?$<|%%K#Ois3Zp zMp)??z#CVaqD(PcBM`v`y>{aVC~9L*G&YE|~z zF(Bga_rLbKer3QR4*reT^{<^EsawoB%q3+4m9Aj+%jZEm=;Y)~tP*9+7W^4>A=~j^ zhHR_Czy8pH(B+p9!M=sGLnk%5*pg3myZSL{8+lRJw?gGYNilz{%8^whhM)5>6%0K z!^k!`$a4$uMQUPiwkv^t86U2u209eHWQE_pEBzE%z< z87W)QZ2yB|*6O&3ZP^%503vVal+`iQ(*oA%;_ds!cLV10ZNZ zeq@UM{zE`u#;6r5kvEfO(vLx#JS6Bs&1+<~{q;VObUhmgiFcIb z{src8$XOBVcuv$9*ks$Q>fCl#W-4S{K|T@Kv6Awmx++(*Mw$NSx`o}K15NPe?I9Pw zPUaXSF~Op79}7|ldJvLF$_iawp@!M|zYFq+`M>W_)w*}}EzI$GP%vXYQf@)e5F%H; z00#W=)sSsi6A)t88+;7~Ir-#?uqKb3Y&oL7+}t6>{v06_=fa2{l=tZ*t;W$vz{*xO zt1ob4K?oBCbnl|Sg4X_wo!3tDr=W$*&buq(f)W*~n|!T+&7BmK*%ENjd=>=~m4!*7 zx@0tcqmJJF{q*sWCU#II1es&y3e&lBESWu9KnqW(31zhOyQaQE1%k&|_QjkJewX{s4yuwWOmA^!^ zDn3H@`O_g)GkQ*YL0&^%_s!z8uTas1*$FSVI67uGzME!$jtaQNFR%MA=-(H*34$gd z8HXbd;+8>ys$M)jXl3;|e{bCsaE^9ymAf)r?D3rOhJG67kj zR?IVd`0NyC4rW%8P}r`c&`b~p5s-`p8dTWV)PXM-XDU$^qD$@1h}cZU>>1$o+X~*U z6=;KE`G=etvC8{Jt;yk0D=tUl;1dzCnJbt_Ud=4-1q%ZiY9=4#6kIPQz-Y((m*EFqa+I0ZBf#4` zH8_6QHb0K{-HRc6XjGb%dcaXDvCnuvD?g5rpZnPDdYZ&t=f~6S*RKN(4nmHjytD&0 z_K$*7Fu>zw)Vo24$0Db3sFHJE_meO3okEF9q_xp!OdL!x9_;ydN1RFKPZs4*Gf?LHOv0dW}5imq4Fwqnrm^;Bq8MMPjn_@K?%{n5$^;Q zO$#_wKwgeRbQ0eQJQ$`fffa%-gn@}vQjAs@CDTHxU3H>3*{p~TD#hNa4TntjPEszW`$ zPHe>%}}QQ63jFG)GKJCV3nN6()*b?(CmKVSUBPan(TRz-D+aRpE%*$DI)^5WxZEg zi&;XQ0omjuFN-={&)ldg-{{ime3sz{Q3xe+3FlF!kGZchE*P04Q!hPG6<1lHsgEljO;!W zOJjw>4s8#i-72~m%p^j(K-L2qrNLlKS|jFc-}taEWwYgkr2>|M8gF|_L{2&QB$)<^ z?5vV`RlUB7cXU%49Hj8D257Q^IY)i@$vxARlS%eh8Mh;$2P6hFkMpZkJ0?0)1rWrq zRhWe^c-xbrE@uJA5D0&6Wuj_TI$f4-O%F@{x2qKO>#J2C(u=GjnAx2N5itCveWj@h z=n%qZLU29g(u#_8W@m*7vU_qOTBXT`!z_XdUn*yfJP4|o_&!;6D)LAIMs)+$YEt05 z5ecD6ZnLxu)qjvl|D*^Ah~7hCO_W2w|G_bpx{8iRzol4*90L1EM%WI%D{eab%&l;K zBL|0U@{e9r?eZtmRoH|LAIX;}R&LKH+3kt?6)hpsJVls(|3SnPs@_ai7?cE02y>Gd zjOl(;{h6##yamLFXV1dI!iUr1JL^!$QVNX|PV_5Lf(o(_jKSZlCLhwD5KI*Imlq)& zv3n+n&KjGOP$f8>hC=2Zr0Tm*pA0*msYxzfu5Bj|3AyAOlWCf?&&8^T zIJ#@pz$leeWCSx|{c0hBRp~cZ+*eGFb#nf=v6(sRncX~AdvX|!JLZ0Zpy^me9~_Zt zbz8?Ag%HSOCT(FB%v%u8*zM7BCz z5^?0?)8%(UoEyCtw}=$ zVaubpuQd0aoT8iJ5yRnJPt#y02G6RD`4ml$DeG?T;bF6q_+!O-|9(9nO|Vo=xQ;5& zS*AS4onNIHQLcqr)qu87SE3EmCmA8?0_=sGvok_6@9#xkbPeEQL4zZA<{aaHL-Yqz z7w4SBYo;gzJp%?W{9@#r&=`K;fyiRrmQm|)cGQ~x&qFW7??0LMXot%lNw>T7+)le8 zV!hu=7uOhcN?}*m-{+k)>+?>!*e|uxWwO@5YPoSOV*-BWoqKLsoo7Z6Q&wB$^XEi( zP^mcCNWZJZR=Cpao*&cfCnW-FG&CEbDnPQ*FdlAPtM`JLK!QMm@Q|~#?TIN$63RwI zjq08NMvctNEQJ;s4q-v`nS-xg+=wJ!@8bo=3xPT{z&L>om<6yO=N>P6PNq@ z%<}d4zF*xHB#58cG|lo?`S1luyc!z)2)sVTZ;26-_3NY%*8cLgD5)cDOpF%?1Mi#J zF-CWR*#(Y--?b1=D9ak&KX$|MS9#tsfqde}eZNh!TRu#8fURWI1lh-WvX{tW&iySD zBO{yZCr(P!kyCoBfL@`j3W_=UMJd_*Y`1=eopR3Y5pNbqrDrDCGawIf@>qE&dBpBL zsYg_ffM*wH_PhM}%ujIe%s0#SX10(F!9+k6GLukoRI6RCtnz(B((H~e(_JX>JJDk1 zRYDEg+}U@@ED!gQ)6U4sVZe@(r%dM>mdeZw)tvT2Oc1`DX+H&A@dwOnPc`CI#6D4r0h_DnBd|vr8U{XyAw4xlGYbqO8qV9R%X3w8A0bGvdkAtwPX? zahsL!03hovUQ)J&sH&&<{-hU4*r0)h>}-fEt8+~JoZ4J$O;X}yLvw?3 zA%qBfH@F?_Dsb!ZvSouAOEVc;$d2hW#ALztB5B3*AsklFf?Wm_;%AkfGHF&XA(RD` zik`bN#4KvQ>SkM_K2`Lb$16k37yxrb$dmA?Kk2eNXH*$wo}p;8Z(o2!IZ>6v$FqEX zz=e$P&X~opLR0ayc3Dsd_R^WyJn?bb#FN;fRR}yuWd-3Et46VDfi5Qr|Gc^M5Zc$8RhF1|lfVAqw^c{5gs)|}cqVn-=?MfeiOw&~&9 zCrA8mE7$fAu9HOB&od|^x|fOHhFoO8t+??UC%or5PSRKmlPzM#WhaD-%4<+|mn!y! zRfN?XLvY??a}S0Uo{D{P|MV;H!wX($$y=#dQ<)&7JQ;kf=p+y73*I~F2am)GuvFWV z{Ud1wR!HmKA*uH8SspfFye38U`rh|6^k8KJ!1bCs;H;F#Oi&*>4+alf;O6(zwk-f> z2~$Bv5{w0_UuFUc?^XTNjI0!1ZL*T8Z3)t&k#V|M*}1lY5ZJv5`SI*-ke7>b{;4z< z+IXoP2qsLjf~IZQKHXKVd8@OR=Ek`zQk)6oX~GiXZ6%CCY_*`SE2ner_Ka4AILRy) z9QU;y)j8_^_dk2|Tsr zdxF=;7f_7+o&Y)U(7zW1?Zj&$F2l%Y1kfp9uO{9d$e@@I#FL?2M=P=-e)nS7otM8) z5&-Ys3#qO&XC}e(&5Hdlo)L6f1Pnt`^|Ts0WWhE{i)@yCOqlKDUg_H=rhn}Gc;!K2 zIUXbvozlJ1E=oKexSRbY4xKNjj$3aQNlt# zEg%DWmOxW2j`k)P1Xncl*eq5wdKo;^Iqbq&Xb}q2Z~h?7-oGy-v&$SJksEQjs1G64 zMaYhQqZB%&idp#=IIlDkVGt5m%ubk$1n~(ta188S!YlIm9m)cZl#^b#sg!jirWRGoK_4l=0fL;<^u zE#CR@+)WODKj1*FcsAWGl&y;R55)i8pB(&+D(~`Sx;;83)eUsC4^AL0pt=cvO{%?? zXiTcs74?Z`KG`EC5V1!thzZzHfqCdfYRYkAV)34W3e3C`8oV#}4!eoL@qpYGF9oaI zj@QliMDoS?}tT%AsFzF7o5e>&_O`?ZQ@0+&ALj&zq`fUS-R^VCE! zcI!Jba%JV;ffEV|7nGaHvCp*0#{Y#y{K>)jVCDQzk<**sPs=bl`0fgsb73M7m?VV6 z$N&)qLA4MG0ebu7#VJ~m)7{PDN4b@poPYL*osWiMz%zIm;I&oM3=$4I5xbMBBv{}8 zJu#`@y(gq%5pVJxAQ#FR)0Sv{?Wgp99y zC0&km$Wbr4D2!)jyUSyh#jL`-O5Gawh5I(+Kb-4Ag**=uNQ}ryK?=SgXh`nKr4M^C z+1bB&xDk$v>G{;9VLRXuuXeyc7cy_K=TX>C(KwR>O#uS*i3z&t5*8ev*1mzD)bVor zXKBu-!lWg5K@eb_d`;hmkKZ=_eU;zFTKoHNwBjoj1(0msr?QQ{^GRFLtabcmh2niy zffTKGv`>l}%m;+~%4?N4SR_n-sE}+OO)#jN%x@u@H1v(2a3TRaQ6@B7Cq?vlTq)=CjSSO2>k{teLyxA zb-PE1WY)iC0tm37VKx=f>YSM{G0?pD8!pV4Fgb|k5hP$=1SyDY&HF=$I!)%C6@n3% zKfqvp!KU7zOe}(rMzscj7DO z59LZ_X?v>Pl9?PG`}VY{=XKfElbmj{huzV`M%?>+p`0X%*UaC+CoT*-2c_q$X-dvT ztlM*GE`&>o9Dcz*`zl!{r*)`u5BVu?+!nI_N~tpdi5$@KDZB7+PRHiAzED!y4-suv1> z{QR)-j2F)o{6G;dZgN)zOaAYZG?$o7JnyXjCJ?}}>$WmGON|_J5;RBrrSvH0I+_MT%BpGSk@clk0*n)pv8RN>nh@|p@GE{(eCGS2wmQ=l2q1QK|P zoQL$Povt1c8`mnAA@e%7!eYel-L>WLV|))xEG9>yM74sIShmQ@&zx$j>o-dLx={V? zFhoQ^h-l%wE}0p1(T-C4cn_ZPGgdhr7N>vq!ZsfOzEZL}3Dy5HgMs za;?VO%jF==WwQP6^6jQd;%~V}<)men%o5|a60*LG{fyjF?iU^!w1e;ic|e1AU&!4M z$e^LfC2ADU;Ki zTK~6a(jjEly;fc=E>3f4g^g)8LW|opB|@Q# zr#RimbSLhZFf_?Iw16)_UTJnncr_UzZ$Ywcg(5*0C_J0n$-#m}WR6%pn(M4vWrk{k zO#eCHd@fk70es>>`*N9*t^`6BP4mE>M6=?3Eq}X$ejRp<(E$5PW)-U+xq*TfSH&dHWq)aohl*Wc z#Vdqdu7u;pJ9?kIJ8avjU|SCq^*bgasvqqEpOC}eh;Dq^Pa*q5t1s7r55Qof@gM__ zGC86+(4u4|dppVG^__hf&m4&$kP@tlVU zn6B_Ed5d_V(LA}VWiqWEyCCd(E8tV^YFW{|jf-62oa1vK8>`l|;Scn;zniq&)u-c* zNA3!ZOClHu6WFyI-rhce*@%SiKy_ZKQio2hnM@EiVn884jca9M0(swhb+Q2E&buq! z{*(iX8M8CONk4RE*qX&AS+($Tt92j_X~s#JnREBO5@nAWHF^Z00NAjBq&vPAIT)eZ-lmnHpV+>5cdoHgXsaB`s@C}rxZ(f=uZDT|Mj*` zMO-ER)0d~XS_)RL1OFFs$*3vAJa~h@ZFa8=Y8sF)cuv{wk+BQ|Bdg!xJAr5=ftZz$ zfLu05|LZ!u27X>b@wJ;nZe<3GgPN_?DC>z$lMa%XULkeCb>&IC267i9@_fPU^e$ukpAuUh=rx{6rQZw_BD!NYTtvpj))XU%3u72HJ6N819u?0%wBbnC6 zUoC%B_&^pCN=jQEo9=>8Up}Ya-ii?Zq?{nlA>$>>34+OjCaG9kh2&2V|M!^2$gEP1 zH|Y8lmk|3}&gZ^bX{q8TVnXPaRSonks9g|~#L#o9^2g?{^hjfiob5SxD;9@UgA#Q1 zGZ&WV+yS8=pb+ms$6uKLp290Xdc|jy)@|A7UG}dEMleAxxF_og!f*VQ9C|-6P`g67 zE|Q!oA)_74j>#yKmpD;_8}o}ya57EBD@_`29dEnF9$wtlYBUQw zNKDg%wm9eR$G-h-O-s*y-I4BIMYl|dx0SH^pp zR_Cm0QR9DC5bvF{`1&7KQOU^?XEfb*2o@V)Gr)1?D40N~J#C8|_5l%lQ8qHHcytuP zpCb3uRk*hQJG_WJ`KxZo9w?7rAS*`eUbXsBN5PpUxDg0)z_a_*Ah8>9+)VV=CcVJe z%*ZUb<4wyoX%+*Hm^(HbMd#E9v{RHOD`D`G$RdjkSd55DGD5T}(YYIRo%^9 zk?$k1uWK3?u>)1(0l!dY!m-gHGy;ql1{S^u*K}h$&s2>6epkG&zhJDL_EsOOkh{w2hoQ)s95o9{w4`gS5$q9s>iQ%3+H9QC7_2MFRBJkCMB` zyW;wG)iG$hOS05QFK2dK7I^|6w+cuds`JW*6aOf@BEuX0~JhGfb=RUkW)Y zie^&ZgnVf)l$|h;$s%K3fe~_)71{mZpYMF zS$Ro=9^`R$6NP zYqqg6>z3R2KdM^w1%i=pU1nc@Tg_<~zlsw(n^1XMK}_De*Q+wbEJkxDhJy2QO_T)S zUxHgp2L8^oEAjVo+g!0qj)(pDQMET#^e(>iI>#UVvjKQKdidppuEuc(@_$@+ZzjTZ z07*!l19x;2;*X7%&eCD`H>79@yO@J_!F^{6M->!62SlVG2@eEuCy-HY~TujBswX{%CTVs{&=`v5-w;#22H1|MD&=^z&;;e&$ zrq4Ff#QJUWb_F1Yp}WK{S}EVMgTm;KoflStTvXMe>cA?qkK}25z9*+=mv}}Xt?BX# zJ}|dJB<~lU1ITc~+C(pxD{@&~+BQ+JK>TuIuvS0ITy5}=HIcY&;@>%H5RkGYopM8l zn|P4v!WB){4QC|}$g0VT|C1XGbo#GzF0&q;?*f$DD+mM~AbZa}2u)lB{;jX}_6$UsjW&#n10s?3@m+ z2?j+^MCclqo^6Nx_KqtQ`=##5R%YQG8(rpTt6y@Vjc9yptfmYyEU{i`1#^ zSVo|lr=qgwYw6A>ft2j$k6D#fYoqr&Bb3|HM*@Entqt=v_tG)J3<-#L)k{p0k0KI@ zBc%YrJ(oCFP$qd&4UY{!WQCLiGsxKAGQTDm4~!{0eUr%Cc0+g)tP znq-(xSqTr88&0?vRhq0|=3vTEn_rN!plUN)U8J)8Jx5K^Nlq!2K=b$GSG;TEiydO? z!{x31lp*$e<-@E}effYLI@oc`23ymkM1xqbiyi*R4a#*0F)Xd#NenKf744#?pAb9p zyEGA`w(K`2fgdc<2Viocb>Sa?X2+K{%C}r_Z^Z8TA6fgKa6g{_g~WOnyrFzs%h$k-o>9KV?Tx9Ax#H2*{_^GWy423$0ma2d^JyV>Y$0 zGJ*BBVV!8?wL-^2%7?65W5t&)u@y_UL&rHPNC8$yin<;?D{Q^n6mf&Pgfi;`uFl?q zCb39O&CMNB9N``uq+bcvPZJj)J(-D*3?>wP`i<%K)Fml4 zfBi<3o@XSnYQ+6G`#Tu7VSc?Oeowu|gQtZRe#^b>$$1>ErXi3OutE|N%}h|E7u_$g zpwPpa33e!rL;hYU$6T6*)ds0p*;$2M_uh&53-X zMu9H~&5V5xh|&k1G9hVj4!bxjIM~83Gyu6*>vUgvt(gtdz}q{OoLl`Dox=U+Mi_ZIsaS} z<~{7*AxrG+GRp(-@JV_CHTRhMdIIkpXB`SX=fj1U+sITjrl6Y z^{{9y-vu8fwlUSJzd6{x{bJZQ1Oy8tT}vV5An{9pf#?_->7El(9C=;Wr_(bme)w7M z-y3!u2GB)eruobyZ{I0a7gbwwtwh>YrdC^#a>yO6On zp0I14?_m>;>1+{3uOuXUq|LW4+b0hUu#4+u)Hpm)NYq~G6Z!}B>NNuCEsPhn9hnIg ze*I;7!0k)d9#F7MFo1%DpGOF)K!bN^IFlhP$m|%o`3#M4;;+xzkRz_Kmix}PCSSj8 zODc4*wFkGg@?*wY{e{2SmL(NQKQQ~ANpEQ@OnK= zp^m#fO*5A5t1PSdT&=L}g)j33c1+AqGzSBXpo#AzvW-7c{OuE8Gn+tfob;3(^GFY~ z<2u`nNkv@7-$C6!dBui5(|_CKU|)5Fy7uMTm%M^JG(PN(^;&r_OhWbXzDcnXVtITp z-TLX-{V_7+N&zkv%)go7BuqGdRkEDg5Ffw&I{jnh<#m^95dUO7ZYR-m3rAGD>Gm6z zSw@{YgRJ1vgrNI%4~v#m2|$7UXs3&srj~_)o+yu=E6RCI238-EnIAsnasEQiK!+KK z7yg#RM>r73e?gmDgnX}m^GtiZ#I4rsaG_1h&9VAlyk{wE)>zv5h?SP96^YS9PE8TD zp3Mq3u*)MaTeY4oogW6fCGhyF3ZK7udsys~8u0shwCC%!0DaRB=uXTY9O>1S`1j+7 zmxIo4VIiTZ%Z=i{LV$kb==!U(zrFv8|8(z3DUR8aL}q9C5q}90OV8&sn~k$Re_n4T z}3pB1_Ki!q}v-9^E|4KFIxBV4hh>C1Nu=K>q%5$L%;Mp!I_Qd#9`$7H;IS!(g zFkRA@f;>=u$ZpXf{)yv!!r~r3Irz@csAmS3&a504`xF8>LZvsgFXEgvqA+j%U&zJk zyT9OR9YTggQp%{TmPU!MioSI9Vi6;2asoqOrG+UZ(m-14FaZQL5VD#a3~GdER9=Mr zG@bdQg`=qsv&KNHd0B0nc%>>UmoKq-?=7)Ym%e7d9M#!Ygsa+D-`23AA)R~iE3NxW z{cTg_Ho}&P$>g8h(zP#^?xXeD@dDtGLWNYhZp8kQ6OFbgQo5O)-Uo)4jA!lgQwom* z?dN}dyH{oUO!&&fg*`sbn>-nRW%i=7*ie>U)juNVSok(2X$clU-dDA53;V=8*!zn; z!$Kpd-78U)+D**{-y_wd z)fpZxjIw$yrCAQ&QS&687f_K4zr4Z9Z1loC>q=I(*H7M#sY={FtH0S#myfTs$}47C zQ1RA~*p!!PGJI6&a%*yp3~I>|(fD-w@Il+WDP-?7zuA%D;b`O7R;ih0$1ixxx*a;w zv8#Y8pqdi&!~e?vY!7YdZADkCa06_8sY=#;>$7&?lP$L)tub}s2cx`q$qZ4?s*;g* zwo`vnR$nVJX7Krabxs=m(jP~oqxCJS@q~}_JJGG&H-~i8RUk4Jz2f(R&A25MLwC< zt9~*no@OR94kic-V0vyRHXB6RqHxQ-+k_HXqDJ0`3$ zyJ0?#YG~VT+v=}54{%g3pVn_1@G!IA#(&0suK1v{1vYH4QT5M~>JrXs!{63o(T{fS z%0c$ot6go%n%dSNWsa3!zr;SM)<=U@q!7n?z5{Tdnd6IC)tDGVW=z$@Y3v9%xbBvl z#@K^t*VxF8-E7S&EdrYT<@Sl#OQWx}3$GYxuas@0#lUOROXLUQi{h z|4Nkd9Ql#&cr2G_<;x!jQ5;htQrKx45Zpq1OHI8Dj;myfzpyHx&B^kJ$HDP0zg?JUbGK#`s^ z2710Px>8td^awT&6ftAj7s9(VqX|zm$4EK&M-QXa=in4M)gJR@naPu^;buAZi<-L$ z0+5sLn}o)Rc#$1HP9gF?RIgI3v?5hH0IeCa3TVV1-+!O1sZ7c7>k1Z7Z$D^mZ+pL1 zH(NGVEjOl;H_;793E8kVUF_m7dfDAqjBsWdrPee=Y9doQzh$>g5US+hsiJ)HSP{x) zCi%s?6xF<_b5LeSNbWNtS2*OE@jr!S+pI2AJxA@qk=W0wGBurvRjg>#RxkHR?x?{@ z+mLR>(#zV03RP_A+$NSbO_}M`gKS*s0d~*)>#fH8MJB~#^J6vboh}2c*nTan-YE6= z5GOEM`VEzu+tTzZmMYCTe|n0mo%u_p!)5l-O1&ag(D|Bn>DdRmK~06-8DdZT`j`oJ z!-Ku8{FdbwyG6;8&#FJS{Byh#TkhLi~$=1zM?rQykF64{P zm#pN3+wxg#sK3WY+3@}ps}x;s6>6!Ha=nNtWNs5Ypzy6oaZhWPnKspi&uii$Xzz=E zIzJrq#Ouj)g5+07Gx1=Ff5WRwvzx3Y2-}knIqc4B9PcX_AH?Tff?6gSso$3HU-Az# zvwgCfU;gRUZuP>fLYN#!jDN`nojx$LpJe(O`|19{W!84xaQnIJVH$jDHM=C;I;4-Z z&7qQZcg<(jLs3zw>Vm^4(>#1e8|&O|q%{luVI^d$Ob<7I?-*)GCyY{!<%08}ezQSt3pnG5Vtj((4+HM@2 zvsTWHsmx8obQ|`A5DyxiB@~L^M-!2}4G0MQnKbd3F;RY(57h87(K~4&$SQ}E=|jlH zhZ!bFeuXiUJw7TLpWv25Qye-o5i-Gk^2)pPmTKxTO|lC!CUd?NGZC#qwc~RjtIF1J zlVfi6mdWhGZNq;0o&B11{ivHAyW#_jErEZWc>Ib@I>*^fMnr%?&(&R6;cqiJrb zCRSJ3=zTHX^{)OecQ^;J=W`m z{n{;IJM?FdfV#F|E43BbLV)}Hb>8Ln;3L=DqgMW1=al2wR(kTA^GWFq@6HMX|C9V|E(%Vy?oN*&Hj&uW%%P5uYuERm9iHv=fm) zd`cJIXO>9h^Q?rhBqhL2rK$2$aLAFIobv3BiMg=yoxkjs+o#+5+I8)dUz)fUXnn;c z?90l9;Dy{Cy>AQWGX*NmbRcdC{mrixbx7j5d zDG?ZOxU;Ly{>^>=t~zw}pL2#y>3Ng;JMo|W?|aC;=>Mrj4{7A0h<}}Nu}vHzhrWiU zu1@dIQSwPTZ?RI34Ypg)A8BX*U(Q-2t7s(FK!eW)Z;M9y=K@TA+W$?o=Tf^nt*ydY znRS}P!g-xI{bjqU#*4Oa-FjhZGOFGh+>fdi;wYh5TZ7|LzHY7b7xKtM-oUp z$W?9(Did3j0YGg2Jhca-*d;sOrDbzfo2?a>qAJuc{Vs^B=lA5``tmX{{QE=Qe(#SP z*!*%0?3?}}*WQ6^MiX$}2p~MjGDxH`amX^iCtEuf3Ao0qTlF{J&%bZH-MP7!RShXR zBw1awvh^zRjQweCt)xP_o!kCo*M4$?Rr+|j&;z1oRkCBt-}0Tbcu<6tD1>|gfgV|5 zvK3pg+`bu9#Gwva93{=BbNlHd1q@Q;=Y$to&ATJ^*dppRc?QvB6#_`2*#iLw)e;P{Yvc( zCHWQC+_vYPctaiRDxvX8$`A(!eUHf*9;QgW71e_7`op6?A+C6ZdKEHIU>=mQG4OD?sjQ#fYqsTKIL`)7$?7_DJ%ebdweTYtBM6oYLpC&4cfC85PE zWmc6ck!nSLo2gbKXTYSP?^LIFK1K%0|t&snN4vrVng+9jQQH9jTMI7^gj;<5AN zZ#O~mV@LV1k3)rVrqYIt;VfaBE7kUviJQ(JZ3o_Xqm@(!AniO=**BL{D>WSWk>}Y@{CufS(C4{tiRRYD%~v=-lUm@rc|;Tb=6l|Xv*Ot94IfF zxJAWTR=?kSR&32`ySr!~yC(RE4ch#)J$+dl=Q7PvT>?!Ii7V4ijLxecJ`9>NdCpRj zW~;PN?%&qC%f1>fpWu{v-xl1z?#|~|Tr)pTvs48S*YLdgqjY z*c?{OjN0Q{ue7(z`PrlGnu4k*5)2^ufd4`=Oc8TV6p;CG?m6v)$uUACyR@Mluaz|# zp-;s2bI-V_U0mLp`s!+8 zF_(2}8~c{FD}yguvB#yNw8}4t*0lE?86fOI3#+d4B85Nv)+g+khp(}L(XJvKQ)N`K z+1B9GxAlAR6Lsrt>#NtYB}!WK_~I%XyJ3LMtJPYZwz2}`dBZ43J@0~PUZ){ysPX!< zvz`5mqXjP=PN|XJoua^!C&VN1(7{sp;>R^X==U-`W*JTos#mU9TFL3cRbeC zdNwcO$j;~~aqTVbt^cw8?9`QS+F|cJXw6@K+M)usOqVCm&WEJtiN4m=k|@T@R2lu=Y(;`(cGP~O?T&4Tr)o|<^(~0Y1MmT z`g85zp8f2##ljomv*=E!8kT%s79UJbx! z8SHP}Dd3X;ORp;y3k)_YbS8hmgeX%2{G)s@V1|oiDHMCVduD6P&am)5!mo2r` zmX+C0lpQLgeA%p1=k4F|4qqcux4Ny_(#SqnOtqR&g)PcQ-O7LDr822B;b@tRJoUms z_Ex>ocH_Yx+Bt)J39H}7`y%dNl2#?v51~o$Pa9FZsiRAwbygFF6f4#CF!r!AkS*pO zF!<@b8ecI*BS_dZXur$kMhp4p5O=6u`gYp{;izz9629^sBH!-YrDvpr;Q$^YN{`~J z<(R9#@fel<(a+5nQpsVV^LzoB2%a7%9lDd*6V%pL&i=%2f{y)e;WPyznt1#5f0NhO z++Vz-=z_$VL4NL? z5r-;WwJ7X3n+R3HKtV>g@nJD{4y5Wi2U6=m2I41AR);L;&ofLA|6tio3{>`5pt+ZB zAF%%K^79oEtG^ZCUstNKMYd!-7Kwlbzot3N$HIz@><4L^R5`f z3QhbjXprH4{#4jG@uZbmfx(f-ndV8K`p#rmF&6BxKgpb z8w!5Be7@kcoU5WkcYNWQy~lJDCPUg3KjQhRsUr9a+4&b9VuzOPZ!eYaX%#jua=WFY z&FDLneGUf6Vyz z3m^T}23P5B(=WK(@%``}lcUW2uUfz32HJ*pEw*iriG(&fO3!4D`e)Fi0v^)#!7+CG zqTW_LMNvsj78b$xFL)|LkX5; z!{29jU3tl_f&fIDfv|(J9`l1JQ9zR#s*ZR;n?PpUICYYl%tIyuQtqd*_RWf$tnS_7 zE0NGqbItKjNfUa|%=qXKaN2hF-DoFFTj7dh(xR2@>Z#A#yxOfT^#ie3NDGrwS@5UX zgJ%@6_wEllb`2&=b~3w0TYK~Desm2MkyL+lsxXP3BomGYGUz4VG?|! z`+IEnjYchQY-@&Vpw~3LbpK!pZe1---3ZQ?oOYmt-m{ z=|=G%(H06GP3Zrayd(=@p#WVu?9HI#`^3~ay28))X;}fRu3YZSKqkV}bGulj`}*6w zE4tX)ikejt;KnCE)Wgb5v8Zae2g^igve;I=o<2u4(B? z`$)9@ETZ2dFH>=d?j^omPC{v?Ug)Vp3W`V$u^SaL~2{eH*$iU|wCl020wB3G^O z*-!Ve&s%o0Ex!PoBcjIy*b%}}yrdjbOx!j<|3-UZKD;GjE)tuBF?*|X z5d)7<=wOvsLPQH?%gX1**@G*3*nmw}*p@V{!aC;?Ya@2k|MjxxQ?9e{I8_uWuYj-` ze^a`PT{rG}$E4t&b9-r#u}5{aEwj~6yMo6AH|fWa_4}=>UHU?AJABY+N6Jj))CoP( zGgO`V`^f6GzE=469|#Ma6>+(Z3G0j4xz(jovJf;l&ua3}unj(Zs-3JhN9#(2owi34 zQAZ2wV5#yMtI|r8(KW_`Hcoh*^(%K@PAikilEsx4(vMrn#^-ZbL>0a9 zqbUw1I%(5^VwR>2mE!iooRb0~`wsg9gDES?Yhsl`?Ny645Xxb0#azv6P0`I$`nX`4 zN2Q1Z{@J|VHlWlMR;g;pj#hJf8eSA%wAg~Hi`luG-m@2G-@NSMo~PyJyrVb+Jgm*N0xr>iIgfpzWOKU1tq>LNR?)f5}GxQRoLR;?e%v|pL~Q6~SO zAt-wP>HVO~aS&3+WXwrwC`YwXwDM@tWpe?DsX9uNgJ2${bIfEKh&O^cBZ|x_6!@H z-rfd0Gscy(@o+#&&Q@VG9c@-=mCsJ{l31nrJA;XiFic4LPS9S8OfxmeMBI+3{<|y8 zE>|;T)&6nRnLrFC5$Id#v^7>eAeAXuI90Ug$|2O07NE}fdyx-ctuXME5z?j_U`(DG z2WW-XiexYC%d74h+qllfb&YP}O880nO~x@9(wB-CJ1W%d5IBJsssI5NQE(RK9xF zr$Jfa+#0Q1C!7|4ePs>jj(#nmn1)^Uk_jAWrX&R(z*0E6R zg~u+nW+UITA)7lo<^=yt<}NO0mDTXEWXcx%IlZ0z@>3b7iK;cwN?b100+Z)i>YFz> zt=QsPf z$J<9HEP0&O@}FF%9BIQqHtP!}Fxqfki{{p2{yjFoY75)1jTeRV(HpOv`hrbgS>0(C z+L_TXbAc8D{K>h$g)-!d{CiW7uSs>4kY=9!jgxcE7Do5+V87~9zS8Taz9YlCrVxutF2Fn*i41Y zOKUO~*9y5v<`tTtoYsfmW6kXFNM+lyHtLw#(1_3tqT$N7JHw9rsh`F6t7u1wX9wb2 zLaog{d&SD=M{ekwQbYaU$D0?>Tj*ZgM`qf z2R~?Mq`ab4kW)pJAFCo*PgZ6Y&w(bA_$~k@U;Or9D{^XoyGDLf`Ju8oB~+yiJb9q~ zRl22(?gw{jKvXDRR1Zwu6os|-lW(~@WT$c>c|Fm*)h%x+3|d( zFaR9-)`Rxx^PkzE51P6G2xSVUOl=`FY91mZ#cqE-}=6l53F$*snvn<_V$*u?dame?d#8nsrPr-VZ-tY z41@*|Qz$DTAo0bsVQ0#gm+4zZT7e=Uy7$DRH{gba(gailrZ15!x&|SH=?NcW%4IbX zvpRlWKHuq_NL~)gZ}XB{$j!02p*Vz{F3LE-sXYM-vQb%UIQHQZqKODeP3gHKw%6)q|KO8%t}AF+*VYqYoFD<$vU=N5hPCavf4-n*vzr`TH;y=r;*^uJFwwCTP$RrQTT3-kU%8;mo1}`@ zhsB8`>73tS98?o@h00l+JZzopH-(5nTVy45w}mrH?>xBs5hx;A9W;cZLRef^O#M)w97VF zJNc0#`u4C%CHgq57mhf1wM|v4S+(QkFT5-khej$z92KxmYB9Aen^iyYeDeA?<)jRJ zqF?xUEJneQLfi_h&?u3G2vZDD>;(O`bqdMG&mEdx=K;OuPqTG8c-|bVSX_e z=T?yB`YxX!dA-@m{vK$|=tH~OW21W7`ag#K32_Lq3X%|OfM2NxOu>8(Hps?xHm7q=?0tGy^9qk z=K7CN|1tjP&UV~W&)bYZ6(^S#_xszkMSHov3;yIt+&4u@{EyuWd)mz(h<@;{h*~Xq z8F3;}bavSlLOlhYWF9`Nh-=Xl96rUW2A5mWa@!||e;$*5Dk_@wMfP%~>+PE21FgwH zsjeLrrO6Oy!4354iBJ2R=js*B@0&2W`eEG0oi2^q)0d>E|3SL?Ik4!6XWk$XKxJDsmxP)UQ~0l+rERpJ&Hi1`Bf)mYej2n}#60)TK3CY7FH;;+ z04R}9v~ceGy=|n5)rcDItn3yIl3xT=@fThD;^W`U3JY-2*M02ulHIIMST!QIiz!+? z2$s$Y+L#GqQQOepez9}ocjev#-JrC!_{!z(Z=fHe?-Yk-v(^R=5C0=LsZgr`OeDmd zn4okU<>NmP9doQ{8Z0&TMe}9!ulz%irA9iv+|d3?ea?=*?*==w^dejRx)8kLE_vg^ z0X9DuTt@6GKTR2OKkd(o+5@MhxI7TODu`4atmG)Z2c{)-@>T0mL?`AvF;o1aicC19 z2r~oKVc&PQKW)O7jjhq4 zJ4X$_TP90E7j3cXRS7J&8VdFLZBW;isb-^o4cQ6TM6CYv3vI^CsToQ_eOyycbn^@v z%q?0X5vqma{EVB_oKGfAK?$`Jqu&d-2tRj!OrM{0pCYpj|B_t0-@fOd37(#>`@>%xR zz{l(*&_e59=wRsWM<%{STsvF7ANNJT&Jg@&^S2@?o}mr&S#5z=OO(|j__6mJf-(oI z`QohNQTySgke#N6D!G;2GC?@Wc&C)Veasc_^F!#5z^XJ&s9zu@BoY~DPIUhgC0P#5 z_}|gMgHm58=t~sf1mT#F=u+>3`S)C(r|s&;ueLxFs1{R{o6sOr&f|!2uh=Q!m+a5O zQrrY?DpW1V-!=6@rg4*NDX7RJ6`)64tbr@ihou_aBpr(=b3S!c*i8f)PnMI3dt8bu_pMMfMx|7RsK_^j{+;0=gf}XA3#Uxpms!>)}yZDq=& z8qE*sMO{>NMCYw}$$CVd^*3|QK7Rmz`BK%J^m$80cAExC=H&9Sjqmd;sn%86Lj_n` ziH;((eDoGQ9^HF3oGjTii=g&Hh$J>A^` zT!rg{;t{DJQXS#eZyWPaf>csNnbNrn9t{!3cp7FVzTI4J1ch4~UJ=97or#eGwa^RQ` z8ri|VEOxr3tXyRW-*>Z>oi}USp|R^5zW0iaQY0&0u$dF91LMChi1&n;Pw$;kTcI&< zWZRz}b=8yjB7e`51N)`W!b);dG)6Bp#C0{*#9>7SaEQrSMj31V&PwuvWX@`zx&0iU zVYYmg({%0B09`8Pms8*DW51oE<|@hqtzP2oF(QWUX z`Oj*Q_zT|LqLCG=q#n~(2gOvV+(?*t9+%LWi)loi^4u7^`ON)b>*||M&%AXR~K@j=mPoEA@R=`_Jj~RqBU8 zz0WNlq^cm!Tnpri(*z8$fzo}D6#N{W`Qo?zF-kSBkvItgbT*TrD4e^5d>^nFOq;KL{xX7H#s)T`Nc-xRA)aMkn*sd zudbUvKK^P3vxl-8O-5_(w!d@QC#B$1)gZIJMf^L-M+--MA_i0G~H zpEj`)?uGj^5)Ih@1o|Txn40cIcD@;)9%QmZ=|ow)Vu}@6D@0>9GVBeHFd~~x^8G84 zg%lM*)kFRF;nD~(`Jc3ry+v97+dogUf!BEb+?LPrni75_#zYua{KjWaQ5+)#wp5VdItntD`B)^22y2oe`{{|2WtgMXg z2Ju9FtuFV(*P9;+x2$Rr)@tP)A^cVrISuUj`DzPGRH&rNX!9=fkDs8`D!04(xpuh|&=E4@HG3g46 zz>q?5*C{=tj;4rfO%y+GRdVq{wMBm0mbB?$bS&bPkaue7vaaXCe#(83Goj%+xVp@= z3j1%VL?q!~Ow_DokDDxzOjo+8iTypKvUR#3O?{SwsxlO{&@vA%R6&({v%ars^D8tm zAsw8ok@|k&%CHp?41#1919W!?s8}-jt&TItBywz}pY5DWdOOWXC0~QhRqVT-PuWAS z9OO zubhuMeby9XdxtYp?XtJ8vJY1bv_9=xTYL5TfK<;H>}xt3J#%@AD-iQPFD$Q=BPT2C zYt(i;!X<^bLk{?0NB{An2O_Qlv-CcgPTTK8{4p}?Iu!r?9yLM86{K!eS*z6R(xPhm z(&c&UAaGv^WzAdZu1s51%dS_4%+9>I5t;kx(9ZVs%$|0{meG#jJN{wwzOCwD(4zTcE++1M=l>>gNT~sN z8ePT?;*)tN=4dunuIBuZ#JrWi13-_^q_#OJ^9kZ_m(}YYH9=?sSVMK%Xp4&<5XJ(XIr?;CTM>O-WXJMNh+#48F#(bjox0y^1|K4TY`z`Z+Z~Tsg zXqpzqos~Umf<)5ADxwVS83+8Vj+UP7&W-aS?rSvop1&e&*S(|?+2Yvw9$h~0AKSr-+SlTPwHsG7?7EXQ#Lfd}cR&cYj8mci$RM+cWQ6WuMpWVp}6A zj+|n}v^2XSG{^>tTIb&=8{`}LyCJPC=TrnUF-Hd8HRfDWf zbdmkg`7c{qy|J3|i2GNVr@|;C`^Nlvke#<;fIYeNdaJl;kz*!YSGk4_I%Qx|Ss?^Yl&`}% zDoFch{oJD_$g+8A`l8~R1_$kUGg-M{<=_?Gs!Fw!y{)@`JJ><+i_+6t+M_AMGw@FB z`m@QuBbJqRpwA<`%kiDKGCKm#s*`dU_+1}77_u7&XEcRr21RErwnLJx5dYY*Qa7`X>vGq1+f^KH%{mKOS;s*!%Z~9RmBs>r!^A(BzdVDvFP|%x`YbcFoeDoq4myLtXt+hSx6PD9umW zjND$Zzx`Zs^e>+qbU66CdyaJ(!{UnDXI-8wFk`+jT)%%G{>!i6Z|KxR z%Q3uopai)Q91^msuyIpoz@l2ioYjb=!<2y@YsIyVCI$3dsWtaL>a z9g85r|CBEm=maTf+Kk-XfD%%dkSfvK+?QuA4+|>mu_*hW<>zZ*y8isUuEM-8`d`B% z)J#c~WJF10*Bj%kTOz70fN48p%jW`}AjzEIuGoh1F>K0qg1b_RhCHmyV6#pc;jg>m zT=pKL;O_vq{_I#9;?H2nt06m8=+B|5kZW?NGLx#HikAYNAn~*r@dxF7eiHU3?mO{s zR4#El$ZRQ0X4RnMO(ac~Q^_qfiMved@4|BZNuBH-x)HU>6!Di)qJ=8CL@Ce-!odmy zZ3e~1loS>%>GAagA#L12w(49(@(TD46o%_heCRv#HxZuyqLfoD1Z9_gSD(ad+$CY& z{T5BIMA{4nPBIMu6Hj<&{)Qkn99G)Ac)%{Y*UK7S*Sv^&9;X-h1mS#l_x110J&XSh z4bXr7Af!Iq5l4v_|J{H2J*}vA$prClVtj8d|Fd23O6YI3qF6+*x;~YzLWH0}lU}^+ z_M@*^DoXdwflRB8wr`cUcf0HQ^LEzWuPN3C50YI0M}8cqK=$$5q_WTC5eu-(`?lpb zS#Pp8mO^dFkcf7?{(oU%ssq+Q?N%FzWe$NcZoI%b6o^1Bn;C30*<)q5-R`>n?9M6K z@9L_b!Ja4uY>gL=TMAqht{7Sz0m`Cd%YrG}FTI2kMRi)xjJ)6`N8z{=d(R@bcc8$t z>bX6kg4mu;lZ1CaQ2Qf6ZLE=;^`&#vB;T|qDX>{=Vzwp)gV z?|Er_SQzf>9^-=)hMWCgK8OD*f_d)*`7e*!U36{#Wd!ry39^d@(cZ)SJMX}5oFFTQ z)xSB9Sb%@$J^xRi^?w=7yc;J=AsjP%16@1)Q2r}u=ENJYH=-4HM`)JbQIP0li*Vw8 zy2roW-Axb+>H+Lhly5;@L|*qx!}2el79>U7pMV(?No4c7|2^&Z|7J9E{IlBS$lmya z7nb+G|45fi8kf_%EoO~Xj=5Lzb_f2=2U_n<;8WK>0^Pt-H zsz-uq$MoW2hQ1zB7tXip0xO}$o8oAY~6{8v$1xhSBfjH>BTV|bc2maRgIsi9+ z)1<~{>&Ac`uSrfng}llxFU8I43Fp`ES&c>x4vK+MRfcV2*8G3TGxO!wIqa_eEcinv zjx=Vv%980d!0H??42nte%UT>0wHf0AuJW>kN|rl`WQ{tSM49+)NUW8x8;W;KBy7!( ziWotUMbpGq_>Tp&WR^;t>!_7*RZ;M_-F`e;^8SB&X96Teb;j{G(*sCA5td6q1fsBl zrGf|Sidf->AP9@#Ri$O3=F%i4CMIe`a+X%2xlN*#q=H(4Km=3*XbA{GYe7^*MHF1b zcyKL;Tyy0A>)Cep=s9<1w`b_D3U;@9`t|EK{k`|S@A&^apH{y`2;hy%5-d|THDbep zHvB~5$j4ial)-!s3i$R*LG!wpd8YkHOG_i=xK$9A{VmPq^J!v*T}K-+~r$U zZp;f?n=AQ0f3fU>u^~$P@6n&W~UIXKff_c9R*?TeQ$I_W# z$B%+&qQxW9w!NrjWkT%R8AlU@_9&)vA8*YsZdUy-kJ;FgUapeMb>wvsvqx-}yxeW& z0a~qNa9o$mwBd`z=0`c)XnKhYv=WR_P+sfO@~9a&yrCjAMmgv=)Dl&qrR_H~CS^2c z%I%rY!1bTICI4oOE|g2Tg95~>6$6SK!)X&IPn_^g_h%|7moNVCFAf65J^NvPUZ%z; z+X6DB!sf*%;%-GYpm<#t|5iLAXBhe8-3KZAyQRM3eJ%HEWWTpQAtrJ{DTW}5P**rG zpuL3wY4}ym)0fmejh}t)@0PuCIZ&>nZtzauGU;IWpYT|TNjP9pf>Cu zXa>Wz_{!3dmiCx!ix0oL;cV$P7+W_4w0ZPY!M_hT z2MiOzsISyjel0rQ7hJR(SH>f$^!A_-56bi|d>;YjX>Zx!e8DRf&Fw4* zeP--Vr^cThlMAJ34teGemd&pR+W4gkl!5Yyav)w*4*E6j>k-qYZOm5c_MJFVd_rK7 z_*i{Oyk+&z9uIV0&`#^Y>MtYw~x)29FIJNbE@>vGeb< zY)=*K?fuw@2RLYZe)xOv_^2TkaDrY)_8TLv4=ei18F^;3=_Q3B-$E`C&*HXE$oIV) z+y1aCqj|+PZfyS=bNwD+H}n0wx&B*ZlTPGwlQx}Q6=_95T8o(R%nOZjc_K<`v&@B; z)m`Rzc({Sd%fTJXER1UwK(FX-bN<^P9*Yr?l8 zQVJt7?f4^|J2L+BoRNA+rI5V0KB&N!R*7r13D=7Aj8+*|D6)6mWS`I%OO#BPPw9F( zCSHpy*!g^{f^YkIB}N`qUe~xJ0o1&DvB>h=DF#|d6FYQ?8Q4bK2~`~`UR-YY?lE&h zt>X6W=9hzZ`ZP z`IaUH;s?zy13S(drU}K2AN8ea&42eoxFZ$~lXivp4Bf=e(VG38YaVF2B}Fsxn{w0e zMlR>UY+Q%?`D;ILg5>pxF^OE5u1ZC2)bkI7;DRmL&=Y1`Kmo`FLxY|BpkQ z^>)mSP19boJ5#X*(f9N_edS0tMlErCOJzKF-g(!O^`XfWWWRi|LoW|2=_%Q*ayvd` za^eMs5xyw|w;Eh-qXi3(O_vY(R6b_baNKd%)NsY+<34_yxsAZ~O>!~TOwy@ZXc7fs zN6f!N`&kcCFIlNNldp56yHbjF_&`uO6morSG3F|TQS%|VMjL#@X!&csnAMU z-!u2}!l0obyW)<`qcCaO z_QdJ+QVOb(Vv&Fuor6o4X9tFnT$KeX)tjLe(-Cr}cPK5ivC2`56i&_mRrDY~3~8{V`|X%Q{L)F^4%-C|RRUuIN~22Ub6yqP((hajnT{WWBp&!iijHzu`{C8KYY{PP9($E$#N zR+OgvibTUt{xYPQ)tCV;#nLT3Heh9vQJG3eGbV59in|ieMDYMc`m!f}wx zY&=Xg&wVy5Pqg7&m+WUTQ#d7i=9WIb=R@^C-&O58i&TBe{M$^?3bweVoc6sc+wz)_ zEIInduz6Y)SY!n_0sz%QB{pLo5znxcIUKLjHRfd{OY%&VC^`ZvGnhis17em$L_{<)q<|JYkN#De#G9G zk&1GGoDiTpyt2eH?N!KvP=46G7CayOEMERE-{QV3lWp)SD~B$>JWITsVx@5M;(I`! z04?Ysb2wAUT0w{|SF1cPti-$>n}foDjF=bxCD_8760w3zZ{D1rWB*VgjDP|6F8i zkMqr}n^&4*p>WD&44Ug2VCn(?%2cvekV?(8;M=oNr%-D1OCfXirBPGTGt*nP?B@vj zVOAZLf)BVPA}BsmX|xYf4X;y^8&XO%jtO$kaC5VdsV%@5R%=fK5y=1*%n#Cv)D%)o z6i!Vs9{FgaUzzHZ@GIX~A^NJ-z#|%SiHgJ^xbUU0M&NN}qQm=;F7-WUR5@&V_`S}&C}LxL7S`~@ zdkePzf9F{?{St|d?K(7kiipfE_!RJPfl6`ljIgMX0(SPUqc9Dx@{f3Z1Wpoo!n^WZ zc0VKi%AeJ|KWD=0v+L&q44V-VQZ#&9SvBRkF)UNg8I)8Dq!4cMxNwF>eKl;R-X69S zHkbWPilg!M6~%3|3g;MDKqRMTB00a|cm=?9EOg;zA37y!=4c~dTORvK$c#~`Zbwlb zfzJu=0JZbOuSq`x)o#cC-FqW2NJJx~OW}}7CpjyK4eVM2VVLeFUO!KQVkf~cuBoAi zMOi?>AbGRC02}X1;g0~7pm4*blbjUa*t@Q$YqjM-Veh0t%m zkGYKi0bwdb@noiw)Mry%89pkvuQsv8BE8O5a;BDDHs>%-`cnKOfRaGkm`YNgO>reb zw$_3MFBTzcP8z$LSye30=s!o@5rC!_uD(>JR?Z4S<|}T{ViHoJ(;@H`)ARbz5-+ej zqzrEOvfae}sM{y&9b*sDMnN}U{1GVh5g@+qmif(dxhhB|K4RD;!RGbFAAv$20Wu^q zRuIy`VT1w1A(cQ{jpt|C!|7dRsoL?+`6JNMBS4}m7SY-T4JUl7`jeS6L7!VYFKFIZ zIW2*+?tPSyC@idW$z3JlJR@cNoJJ6J=YMb>z50cf%G&*(&k>OSu`Z4~oF(%4HS-~# z37B=NIt9Q4?B(DQ0W-iriNfrx5>t&3Aco52Nx}Q!T4kqh!$1NbspAwG`Qnd2p^v~R zstww-Dqt5{QC^N%q1H2JVm7t!Xlx$ib4Rj$QNfAG|F*0nQ8Be!m-DYJw?r~1MO!QG z5Gh=@KB=#S}10F*xFCYAk_k( zwS$7n0sVaPZDG6i!eh_xcgG)rtVV#MyI|iz$!B|5DqozF8SX8pA{S4On3$R?rf7Rs zBkF&+s77Fb_9Y>Bl#_UV?T77A8Z}S Date: Fri, 27 Mar 2020 19:41:18 +0100 Subject: [PATCH 13/27] Use random colors, fix sip includes, fix warnings in server --- .../qgsvectortilebasicrenderer.sip.in | 10 ++++++++-- python/core/core_auto.sip | 6 +++--- .../vectortile/qgsvectortilebasicrenderer.cpp | 19 +++++++++++-------- .../vectortile/qgsvectortilebasicrenderer.h | 8 ++++++-- src/core/vectortile/qgsvectortilelayer.cpp | 4 +++- src/server/services/wms/qgslayerrestorer.cpp | 2 ++ .../services/wms/qgswmsdescribelayer.cpp | 1 + .../services/wms/qgswmsgetcapabilities.cpp | 1 + src/server/services/wms/qgswmsrenderer.cpp | 1 + tests/src/core/testqgsvectortilelayer.cpp | 19 +++++++++++++++++++ 10 files changed, 55 insertions(+), 16 deletions(-) diff --git a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in index 30156922914b..30b7a0883cc8 100644 --- a/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in +++ b/python/core/auto_generated/vectortile/qgsvectortilebasicrenderer.sip.in @@ -41,6 +41,7 @@ Constructs a style object %Docstring Constructs a style object as a copy of another style %End + ~QgsVectorTileBasicRendererStyle(); void setStyleName( const QString &name ); %Docstring @@ -146,7 +147,7 @@ each defines a rendering rule. public: QgsVectorTileBasicRenderer(); %Docstring -Constructs renderer with some default styles +Constructs renderer with no styles %End virtual QString type() const; @@ -178,7 +179,12 @@ Returns list of styles of the renderer const QColor &lineStrokeColor, double lineStrokeWidth, const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize ); %Docstring -Sets a default style to render all layers with the given fill/stroke colors, stroke widths and marker sizes +Returns a list of styles to render all layers with the given fill/stroke colors, stroke widths and marker sizes +%End + + static QList simpleStyleWithRandomColors(); +%Docstring +Returns a list of styles to render all layers, using random colors %End }; diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index 27af8bb5eec2..8191000c84c8 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -531,10 +531,10 @@ %Include auto_generated/validity/qgsabstractvaliditycheck.sip %Include auto_generated/validity/qgsvaliditycheckcontext.sip %Include auto_generated/validity/qgsvaliditycheckregistry.sip +%Include auto_generated/vectortile/qgsvectortilebasicrenderer.sip +%Include auto_generated/vectortile/qgsvectortilelayer.sip +%Include auto_generated/vectortile/qgsvectortilerenderer.sip %Include auto_generated/gps/qgsqtlocationconnection.sip %Include auto_generated/gps/qgsgpsconnectionregistry.sip %Include auto_generated/symbology/qgsmasksymbollayer.sip %Include auto_generated/qgsuserprofile.sip -%Include auto_generated/vectortile/qgsvectortilebasicrenderer.sip -%Include auto_generated/vectortile/qgsvectortilelayer.sip -%Include auto_generated/vectortile/qgsvectortilerenderer.sip diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.cpp b/src/core/vectortile/qgsvectortilebasicrenderer.cpp index bc6ba9036d33..bbd09f202ad5 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.cpp +++ b/src/core/vectortile/qgsvectortilebasicrenderer.cpp @@ -15,6 +15,8 @@ #include "qgsvectortilebasicrenderer.h" +#include "qgsapplication.h" +#include "qgscolorschemeregistry.h" #include "qgsexpressioncontextutils.h" #include "qgsfillsymbollayer.h" #include "qgslinesymbollayer.h" @@ -48,6 +50,8 @@ QgsVectorTileBasicRendererStyle &QgsVectorTileBasicRendererStyle::operator=( con return *this; } +QgsVectorTileBasicRendererStyle::~QgsVectorTileBasicRendererStyle() = default; + void QgsVectorTileBasicRendererStyle::setSymbol( QgsSymbol *sym ) { mSymbol.reset( sym ); @@ -97,7 +101,6 @@ void QgsVectorTileBasicRendererStyle::readXml( const QDomElement &elem, const Qg QgsVectorTileBasicRenderer::QgsVectorTileBasicRenderer() { - setDefaultStyle(); } QString QgsVectorTileBasicRenderer::type() const @@ -229,24 +232,24 @@ QList QgsVectorTileBasicRenderer::styles() cons return mStyles; } -void QgsVectorTileBasicRenderer::setDefaultStyle() +QList QgsVectorTileBasicRenderer::simpleStyleWithRandomColors() { - QColor polygonFillColor = Qt::blue; + QColor polygonFillColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor(); QColor polygonStrokeColor = polygonFillColor; polygonFillColor.setAlpha( 100 ); double polygonStrokeWidth = DEFAULT_LINE_WIDTH; - QColor lineStrokeColor = Qt::blue; + QColor lineStrokeColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor(); double lineStrokeWidth = DEFAULT_LINE_WIDTH; - QColor pointFillColor = Qt::red; + QColor pointFillColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor(); QColor pointStrokeColor = pointFillColor; pointFillColor.setAlpha( 100 ); double pointSize = DEFAULT_POINT_SIZE; - setStyles( simpleStyle( polygonFillColor, polygonStrokeColor, polygonStrokeWidth, - lineStrokeColor, lineStrokeWidth, - pointFillColor, pointStrokeColor, pointSize ) ); + return simpleStyle( polygonFillColor, polygonStrokeColor, polygonStrokeWidth, + lineStrokeColor, lineStrokeWidth, + pointFillColor, pointStrokeColor, pointSize ); } QList QgsVectorTileBasicRenderer::simpleStyle( diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.h b/src/core/vectortile/qgsvectortilebasicrenderer.h index 7dd25e8d5720..1062551e5013 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.h +++ b/src/core/vectortile/qgsvectortilebasicrenderer.h @@ -51,6 +51,7 @@ class CORE_EXPORT QgsVectorTileBasicRendererStyle //! Constructs a style object as a copy of another style QgsVectorTileBasicRendererStyle( const QgsVectorTileBasicRendererStyle &other ); QgsVectorTileBasicRendererStyle &operator=( const QgsVectorTileBasicRendererStyle &other ); + ~QgsVectorTileBasicRendererStyle(); //! Sets human readable name of this style void setStyleName( const QString &name ) { mStyleName = name; } @@ -125,7 +126,7 @@ class CORE_EXPORT QgsVectorTileBasicRendererStyle class CORE_EXPORT QgsVectorTileBasicRenderer : public QgsVectorTileRenderer { public: - //! Constructs renderer with some default styles + //! Constructs renderer with no styles QgsVectorTileBasicRenderer(); QString type() const override; @@ -142,12 +143,15 @@ class CORE_EXPORT QgsVectorTileBasicRenderer : public QgsVectorTileRenderer //! Returns list of styles of the renderer QList styles() const; - //! Sets a default style to render all layers with the given fill/stroke colors, stroke widths and marker sizes + //! Returns a list of styles to render all layers with the given fill/stroke colors, stroke widths and marker sizes static QList simpleStyle( const QColor &polygonFillColor, const QColor &polygonStrokeColor, double polygonStrokeWidth, const QColor &lineStrokeColor, double lineStrokeWidth, const QColor &pointFillColor, const QColor &pointStrokeColor, double pointSize ); + //! Returns a list of styles to render all layers, using random colors + static QList simpleStyleWithRandomColors(); + private: void setDefaultStyle(); diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index 80c26948fbc4..17f6224e7c6d 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -78,7 +78,9 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN setValid( true ); // set a default renderer - setRenderer( new QgsVectorTileBasicRenderer ); + QgsVectorTileBasicRenderer *renderer = new QgsVectorTileBasicRenderer; + renderer->setStyles( QgsVectorTileBasicRenderer::simpleStyleWithRandomColors() ); + setRenderer( renderer ); } QgsVectorTileLayer::~QgsVectorTileLayer() = default; diff --git a/src/server/services/wms/qgslayerrestorer.cpp b/src/server/services/wms/qgslayerrestorer.cpp index f144f6792507..3574a7e21466 100644 --- a/src/server/services/wms/qgslayerrestorer.cpp +++ b/src/server/services/wms/qgslayerrestorer.cpp @@ -73,6 +73,7 @@ QgsLayerRestorer::QgsLayerRestorer( const QList &layers ) } case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: break; } @@ -128,6 +129,7 @@ QgsLayerRestorer::~QgsLayerRestorer() } case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: break; } diff --git a/src/server/services/wms/qgswmsdescribelayer.cpp b/src/server/services/wms/qgswmsdescribelayer.cpp index eef78646bd3a..eb6944fbebb4 100644 --- a/src/server/services/wms/qgswmsdescribelayer.cpp +++ b/src/server/services/wms/qgswmsdescribelayer.cpp @@ -191,6 +191,7 @@ namespace QgsWms } case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: break; } diff --git a/src/server/services/wms/qgswmsgetcapabilities.cpp b/src/server/services/wms/qgswmsgetcapabilities.cpp index 9f365e6b7331..46ad89958173 100644 --- a/src/server/services/wms/qgswmsgetcapabilities.cpp +++ b/src/server/services/wms/qgswmsgetcapabilities.cpp @@ -1956,6 +1956,7 @@ namespace QgsWms } case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: break; } diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index 1d271edc39ea..b1446e6162a1 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -2725,6 +2725,7 @@ namespace QgsWms } case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::PluginLayer: break; } diff --git a/tests/src/core/testqgsvectortilelayer.cpp b/tests/src/core/testqgsvectortilelayer.cpp index 468cf1b0fe06..8341efc9b04a 100644 --- a/tests/src/core/testqgsvectortilelayer.cpp +++ b/tests/src/core/testqgsvectortilelayer.cpp @@ -22,6 +22,7 @@ #include "qgsproject.h" #include "qgsrenderchecker.h" #include "qgstiles.h" +#include "qgsvectortilebasicrenderer.h" #include "qgsvectortilelayer.h" /** @@ -75,6 +76,24 @@ void TestQgsVectorTileLayer::initTestCase() mMapSettings = new QgsMapSettings(); mMapSettings->setLayers( QList() << mLayer ); + // let's have some standard style config for the layer + QColor polygonFillColor = Qt::blue; + QColor polygonStrokeColor = polygonFillColor; + polygonFillColor.setAlpha( 100 ); + double polygonStrokeWidth = DEFAULT_LINE_WIDTH; + QColor lineStrokeColor = Qt::blue; + double lineStrokeWidth = DEFAULT_LINE_WIDTH; + QColor pointFillColor = Qt::red; + QColor pointStrokeColor = pointFillColor; + pointFillColor.setAlpha( 100 ); + double pointSize = DEFAULT_POINT_SIZE; + + QgsVectorTileBasicRenderer *rend = new QgsVectorTileBasicRenderer; + rend->setStyles( QgsVectorTileBasicRenderer::simpleStyle( + polygonFillColor, polygonStrokeColor, polygonStrokeWidth, + lineStrokeColor, lineStrokeWidth, + pointFillColor, pointStrokeColor, pointSize ) ); + mLayer->setRenderer( rend ); // takes ownership } void TestQgsVectorTileLayer::cleanupTestCase() From 474477761ab1fef0a2dd548848e55d0e984d560e Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 27 Mar 2020 20:57:35 +0100 Subject: [PATCH 14/27] Handle on-the-fly reprojection correctly --- src/core/vectortile/qgsvectortilelayerrenderer.cpp | 6 ++++-- src/core/vectortile/qgsvectortilemvtdecoder.cpp | 3 ++- src/core/vectortile/qgsvectortilemvtdecoder.h | 2 +- src/core/vectortile/qgsvectortileutils.cpp | 12 ++++++------ src/core/vectortile/qgsvectortileutils.h | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index 697ce32020db..7b45197b2c66 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -149,9 +149,11 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & if ( ctx.renderingStopped() ) return; + QgsCoordinateTransform ct = ctx.coordinateTransform(); + QgsVectorTileRendererData tile( rawTile.id ); - tile.setFeatures( decoder.layerFeatures( mPerLayerFields ) ); - tile.setTilePolygon( QgsVectorTileUtils::tilePolygon( rawTile.id, mTileMatrix, ctx.mapToPixel() ) ); + tile.setFeatures( decoder.layerFeatures( mPerLayerFields, ct ) ); + tile.setTilePolygon( QgsVectorTileUtils::tilePolygon( rawTile.id, ct, mTileMatrix, ctx.mapToPixel() ) ); mTotalDecodeTime += tLoad.elapsed(); diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.cpp b/src/core/vectortile/qgsvectortilemvtdecoder.cpp index 6b2114add4c0..d2f7edccc778 100644 --- a/src/core/vectortile/qgsvectortilemvtdecoder.cpp +++ b/src/core/vectortile/qgsvectortilemvtdecoder.cpp @@ -92,7 +92,7 @@ QStringList QgsVectorTileMVTDecoder::layerFieldNames( const QString &layerName ) return fieldNames; } -QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap &perLayerFields ) const +QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap &perLayerFields, const QgsCoordinateTransform &ct ) const { QgsVectorTileFeatures features; @@ -307,6 +307,7 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap &perLayerFields ) const; + QgsVectorTileFeatures layerFeatures( const QMap &perLayerFields, const QgsCoordinateTransform &ct ) const; private: vector_tile::Tile tile; diff --git a/src/core/vectortile/qgsvectortileutils.cpp b/src/core/vectortile/qgsvectortileutils.cpp index 1cfa1e43b093..5424ee6fce3d 100644 --- a/src/core/vectortile/qgsvectortileutils.cpp +++ b/src/core/vectortile/qgsvectortileutils.cpp @@ -33,13 +33,13 @@ -QPolygon QgsVectorTileUtils::tilePolygon( QgsTileXYZ id, const QgsTileMatrix &tm, const QgsMapToPixel &mtp ) +QPolygon QgsVectorTileUtils::tilePolygon( QgsTileXYZ id, const QgsCoordinateTransform &ct, const QgsTileMatrix &tm, const QgsMapToPixel &mtp ) { QgsRectangle r = tm.tileExtent( id ); - QgsPointXY p00a = mtp.transform( r.xMinimum(), r.yMinimum() ); - QgsPointXY p11a = mtp.transform( r.xMaximum(), r.yMaximum() ); - QgsPointXY p01a = mtp.transform( r.xMinimum(), r.yMaximum() ); - QgsPointXY p10a = mtp.transform( r.xMaximum(), r.yMinimum() ); + QgsPointXY p00a = mtp.transform( ct.transform( r.xMinimum(), r.yMinimum() ) ); + QgsPointXY p11a = mtp.transform( ct.transform( r.xMaximum(), r.yMaximum() ) ); + QgsPointXY p01a = mtp.transform( ct.transform( r.xMinimum(), r.yMaximum() ) ); + QgsPointXY p10a = mtp.transform( ct.transform( r.xMaximum(), r.yMinimum() ) ); QPolygon path; path << p00a.toQPointF().toPoint(); path << p01a.toQPointF().toPoint(); @@ -86,7 +86,7 @@ QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer * QMap perLayerFields; QgsFields fields = QgsVectorTileUtils::makeQgisFields( fieldNames ); perLayerFields[layerName] = fields; - QgsVectorTileFeatures data = decoder.layerFeatures( perLayerFields ); + QgsVectorTileFeatures data = decoder.layerFeatures( perLayerFields, QgsCoordinateTransform() ); QgsFeatureList featuresList = data[layerName].toList(); // turn all geometries to geom. collections (otherwise they won't be accepted by memory provider) diff --git a/src/core/vectortile/qgsvectortileutils.h b/src/core/vectortile/qgsvectortileutils.h index 6d045b9bf255..4ceb86dbbdfa 100644 --- a/src/core/vectortile/qgsvectortileutils.h +++ b/src/core/vectortile/qgsvectortileutils.h @@ -50,7 +50,7 @@ class QgsVectorTileUtils static void sortTilesByDistanceFromCenter( QVector &tiles, const QPointF ¢er ); //! Returns polygon (made by four corners of the tile) in screen coordinates - static QPolygon tilePolygon( QgsTileXYZ id, const QgsTileMatrix &tm, const QgsMapToPixel &mtp ); + static QPolygon tilePolygon( QgsTileXYZ id, const QgsCoordinateTransform &ct, const QgsTileMatrix &tm, const QgsMapToPixel &mtp ); //! Returns QgsFields instance based on the set of field names static QgsFields makeQgisFields( QSet flds ); //! Finds best fitting zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator and allowed zoom level range From 804ac87030f97dd8230720e1f28e4d4deb57701a Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 27 Mar 2020 21:51:55 +0100 Subject: [PATCH 15/27] Get rid of qDebug(), wrap strings in QStringLiteral --- python/core/auto_generated/qgstiles.sip.in | 5 +++ src/core/qgstiles.h | 3 ++ .../vectortile/qgsvectortilebasicrenderer.cpp | 44 +++++++++---------- src/core/vectortile/qgsvectortilelayer.cpp | 41 +++++++++-------- .../vectortile/qgsvectortilelayerrenderer.cpp | 32 +++++++------- src/core/vectortile/qgsvectortileloader.cpp | 36 +++++++-------- .../vectortile/qgsvectortilemvtdecoder.cpp | 6 +-- src/core/vectortile/qgsvectortileutils.cpp | 11 ++--- 8 files changed, 91 insertions(+), 87 deletions(-) diff --git a/python/core/auto_generated/qgstiles.sip.in b/python/core/auto_generated/qgstiles.sip.in index b39c62bd6609..befad4c77ee3 100644 --- a/python/core/auto_generated/qgstiles.sip.in +++ b/python/core/auto_generated/qgstiles.sip.in @@ -39,6 +39,11 @@ Returns tile's row index (Y) int zoomLevel() const; %Docstring Returns tile's zoom level (Z) +%End + + QString toString() const; +%Docstring +Returns tile coordinates in a formatted string %End }; diff --git a/src/core/qgstiles.h b/src/core/qgstiles.h index d7e7f73b76a2..86641487ad38 100644 --- a/src/core/qgstiles.h +++ b/src/core/qgstiles.h @@ -45,6 +45,9 @@ class CORE_EXPORT QgsTileXYZ //! Returns tile's zoom level (Z) int zoomLevel() const { return mZoomLevel; } + //! Returns tile coordinates in a formatted string + QString toString() const { return QStringLiteral( "X=%1 Y=%2 Z=%3" ).arg( mColumn ).arg( mRow ).arg( mZoomLevel ); } + private: int mColumn; int mRow; diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.cpp b/src/core/vectortile/qgsvectortilebasicrenderer.cpp index bbd09f202ad5..14bc8d7851d1 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.cpp +++ b/src/core/vectortile/qgsvectortilebasicrenderer.cpp @@ -59,13 +59,13 @@ void QgsVectorTileBasicRendererStyle::setSymbol( QgsSymbol *sym ) void QgsVectorTileBasicRendererStyle::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const { - elem.setAttribute( "name", mStyleName ); - elem.setAttribute( "layer", mLayerName ); - elem.setAttribute( "geometry", mGeometryType ); - elem.setAttribute( "enabled", mEnabled ? "1" : "0" ); - elem.setAttribute( "expression", mExpression ); - elem.setAttribute( "min-zoom", mMinZoomLevel ); - elem.setAttribute( "max-zoom", mMaxZoomLevel ); + elem.setAttribute( QStringLiteral( "name" ), mStyleName ); + elem.setAttribute( QStringLiteral( "layer" ), mLayerName ); + elem.setAttribute( QStringLiteral( "geometry" ), mGeometryType ); + elem.setAttribute( QStringLiteral( "enabled" ), mEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ); + elem.setAttribute( QStringLiteral( "expression" ), mExpression ); + elem.setAttribute( QStringLiteral( "min-zoom" ), mMinZoomLevel ); + elem.setAttribute( QStringLiteral( "max-zoom" ), mMaxZoomLevel ); QDomDocument doc = elem.ownerDocument(); QgsSymbolMap symbols; @@ -76,13 +76,13 @@ void QgsVectorTileBasicRendererStyle::writeXml( QDomElement &elem, const QgsRead void QgsVectorTileBasicRendererStyle::readXml( const QDomElement &elem, const QgsReadWriteContext &context ) { - mStyleName = elem.attribute( "name" ); - mLayerName = elem.attribute( "layer" ); - mGeometryType = static_cast( elem.attribute( "geometry" ).toInt() ); - mEnabled = elem.attribute( "enabled" ).toInt(); - mExpression = elem.attribute( "expression" ); - mMinZoomLevel = elem.attribute( "min-zoom" ).toInt(); - mMaxZoomLevel = elem.attribute( "max-zoom" ).toInt(); + mStyleName = elem.attribute( QStringLiteral( "name" ) ); + mLayerName = elem.attribute( QStringLiteral( "layer" ) ); + mGeometryType = static_cast( elem.attribute( QStringLiteral( "geometry" ) ).toInt() ); + mEnabled = elem.attribute( QStringLiteral( "enabled" ) ).toInt(); + mExpression = elem.attribute( QStringLiteral( "expression" ) ); + mMinZoomLevel = elem.attribute( QStringLiteral( "min-zoom" ) ).toInt(); + mMaxZoomLevel = elem.attribute( QStringLiteral( "max-zoom" ) ).toInt(); mSymbol.reset(); QDomElement symbolsElem = elem.firstChildElement( QStringLiteral( "symbols" ) ); @@ -105,7 +105,7 @@ QgsVectorTileBasicRenderer::QgsVectorTileBasicRenderer() QString QgsVectorTileBasicRenderer::type() const { - return "basic"; + return QStringLiteral( "basic" ); } QgsVectorTileBasicRenderer *QgsVectorTileBasicRenderer::clone() const @@ -198,10 +198,10 @@ void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &ti void QgsVectorTileBasicRenderer::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const { QDomDocument doc = elem.ownerDocument(); - QDomElement elemStyles = doc.createElement( "styles" ); + QDomElement elemStyles = doc.createElement( QStringLiteral( "styles" ) ); for ( const QgsVectorTileBasicRendererStyle &layerStyle : mStyles ) { - QDomElement elemStyle = doc.createElement( "style" ); + QDomElement elemStyle = doc.createElement( QStringLiteral( "style" ) ); layerStyle.writeXml( elemStyle, context ); elemStyles.appendChild( elemStyle ); } @@ -212,8 +212,8 @@ void QgsVectorTileBasicRenderer::readXml( const QDomElement &elem, const QgsRead { mStyles.clear(); - QDomElement elemStyles = elem.firstChildElement( "styles" ); - QDomElement elemStyle = elemStyles.firstChildElement( "style" ); + QDomElement elemStyles = elem.firstChildElement( QStringLiteral( "styles" ) ); + QDomElement elemStyle = elemStyles.firstChildElement( QStringLiteral( "style" ) ); while ( !elemStyle.isNull() ) { QgsVectorTileBasicRendererStyle layerStyle; @@ -274,13 +274,13 @@ QList QgsVectorTileBasicRenderer::simpleStyle( markerSymbolLayer->setSize( pointSize ); QgsMarkerSymbol *markerSymbol = new QgsMarkerSymbol( QgsSymbolLayerList() << markerSymbolLayer ); - QgsVectorTileBasicRendererStyle st1( "polygons", QString(), QgsWkbTypes::PolygonGeometry ); + QgsVectorTileBasicRendererStyle st1( QStringLiteral( "Polygons" ), QString(), QgsWkbTypes::PolygonGeometry ); st1.setSymbol( fillSymbol ); - QgsVectorTileBasicRendererStyle st2( "lines", QString(), QgsWkbTypes::LineGeometry ); + QgsVectorTileBasicRendererStyle st2( QStringLiteral( "Lines" ), QString(), QgsWkbTypes::LineGeometry ); st2.setSymbol( lineSymbol ); - QgsVectorTileBasicRendererStyle st3( "points", QString(), QgsWkbTypes::PointGeometry ); + QgsVectorTileBasicRendererStyle st3( QStringLiteral( "Points" ), QString(), QgsWkbTypes::PointGeometry ); st3.setSymbol( markerSymbol ); QList lst; diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index 17f6224e7c6d..9780b59190bc 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -15,6 +15,7 @@ #include "qgsvectortilelayer.h" +#include "qgslogger.h" #include "qgsvectortilelayerrenderer.h" #include "qgsmbtilesreader.h" #include "qgsvectortilebasicrenderer.h" @@ -30,9 +31,9 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN QgsDataSourceUri dsUri; dsUri.setEncodedUri( uri ); - mSourceType = dsUri.param( "type" ); - mSourcePath = dsUri.param( "url" ); - if ( mSourceType == "xyz" ) + mSourceType = dsUri.param( QStringLiteral( "type" ) ); + mSourcePath = dsUri.param( QStringLiteral( "url" ) ); + if ( mSourceType == QStringLiteral( "xyz" ) ) { // online tiles mSourceMinZoom = 0; @@ -45,24 +46,24 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN setExtent( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) ); } - else if ( mSourceType == "mbtiles" ) + else if ( mSourceType == QStringLiteral( "mbtiles" ) ) { QgsMBTilesReader reader( mSourcePath ); if ( !reader.open() ) { - qDebug() << "failed to open MBTiles file:" << mSourcePath; + QgsDebugMsg( QStringLiteral( "failed to open MBTiles file: " ) + mSourcePath ); return; } - qDebug() << "name:" << reader.metadataValue( "name" ); + QgsDebugMsg( QStringLiteral( "name: " ) + reader.metadataValue( QStringLiteral( "name" ) ) ); bool minZoomOk, maxZoomOk; - int minZoom = reader.metadataValue( "minzoom" ).toInt( &minZoomOk ); - int maxZoom = reader.metadataValue( "maxzoom" ).toInt( &maxZoomOk ); + int minZoom = reader.metadataValue( QStringLiteral( "minzoom" ) ).toInt( &minZoomOk ); + int maxZoom = reader.metadataValue( QStringLiteral( "maxzoom" ) ).toInt( &maxZoomOk ); if ( minZoomOk ) mSourceMinZoom = minZoom; if ( maxZoomOk ) mSourceMaxZoom = maxZoom; - qDebug() << "zoom range:" << mSourceMinZoom << mSourceMaxZoom; + QgsDebugMsg( QStringLiteral( "zoom range: %1 - %2" ).arg( mSourceMinZoom ).arg( mSourceMaxZoom ) ); QgsRectangle r = reader.extent(); // TODO: reproject to EPSG:3857 @@ -70,11 +71,11 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN } else { - // TODO: report error - unknown type + QgsDebugMsg( QStringLiteral( "Unknown source type: " ) + mSourceType ); return; } - setCrs( QgsCoordinateReferenceSystem( "EPSG:3857" ) ); + setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) ) ); setValid( true ); // set a default renderer @@ -107,7 +108,7 @@ bool QgsVectorTileLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext bool QgsVectorTileLayer::writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const { QDomElement mapLayerNode = layerNode.toElement(); - mapLayerNode.setAttribute( "type", "vector-tile" ); + mapLayerNode.setAttribute( QStringLiteral( "type" ), QStringLiteral( "vector-tile" ) ); QString errorMsg; return writeSymbology( layerNode, doc, errorMsg, context ); @@ -119,21 +120,19 @@ bool QgsVectorTileLayer::readSymbology( const QDomNode &node, QString &errorMess readCommonStyle( elem, context, categories ); - QDomElement elemRenderer = elem.firstChildElement( "renderer" ); + QDomElement elemRenderer = elem.firstChildElement( QStringLiteral( "renderer" ) ); if ( elemRenderer.isNull() ) { - errorMessage = "Missing tag"; + errorMessage = tr( "Missing tag" ); return false; } - QString rendererType = elemRenderer.attribute( "type" ); + QString rendererType = elemRenderer.attribute( QStringLiteral( "type" ) ); QgsVectorTileRenderer *r = nullptr; - if ( rendererType == "basic" ) + if ( rendererType == QStringLiteral( "basic" ) ) r = new QgsVectorTileBasicRenderer; - //else if ( rendererType == "mapbox-gl" ) - // r = new MapboxGLStyleRenderer; else { - errorMessage = "Unknown renderer type: " + rendererType; + errorMessage = tr( "Unknown renderer type: " ) + rendererType; return false; } @@ -150,8 +149,8 @@ bool QgsVectorTileLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QStr if ( mRenderer ) { - QDomElement elemRenderer = doc.createElement( "renderer" ); - elemRenderer.setAttribute( "type", mRenderer->type() ); + QDomElement elemRenderer = doc.createElement( QStringLiteral( "renderer" ) ); + elemRenderer.setAttribute( QStringLiteral( "type" ), mRenderer->type() ); mRenderer->writeXml( elemRenderer, context ); elem.appendChild( elemRenderer ); } diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index 7b45197b2c66..5765c3fd510a 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -19,6 +19,7 @@ #include "qgsexpressioncontextutils.h" #include "qgsfeedback.h" +#include "qgslogger.h" #include "qgsvectortilemvtdecoder.h" #include "qgsvectortilelayer.h" @@ -48,26 +49,29 @@ bool QgsVectorTileLayerRenderer::render() QElapsedTimer tTotal; tTotal.start(); - qDebug() << "MVT rend" << ctx.extent().toString( -1 ); + QgsDebugMsg( QStringLiteral( "Vector tiles rendering extent: " ) + ctx.extent().toString( -1 ) ); + QgsDebugMsg( QStringLiteral( "Vector tiles map scale 1 : %1" ).arg( ctx.rendererScale() ) ); mTileZoom = QgsVectorTileUtils::scaleToZoomLevel( ctx.rendererScale(), mSourceMinZoom, mSourceMaxZoom ); - qDebug() << "MVT zoom level" << mTileZoom; + QgsDebugMsg( QStringLiteral( "Vector tiles zoom level: %1" ).arg( mTileZoom ) ); mTileMatrix = QgsTileMatrix::fromWebMercator( mTileZoom ); mTileRange = mTileMatrix.tileRangeFromExtent( ctx.extent() ); - qDebug() << "MVT tile range" << mTileRange.startColumn() << mTileRange.endColumn() << " | " << mTileRange.startRow() << mTileRange.endRow(); + QgsDebugMsg( QStringLiteral( "Vector tiles range X: %1 - %2 Y: %3 - %4" ) + .arg( mTileRange.startColumn() ).arg( mTileRange.endColumn() ) + .arg( mTileRange.startRow() ).arg( mTileRange.endRow() ) ); // view center is used to sort the order of tiles for fetching and rendering QPointF viewCenter = mTileMatrix.mapToTileCoordinates( ctx.extent().center() ); if ( !mTileRange.isValid() ) { - qDebug() << "outside of range"; + QgsDebugMsg( QStringLiteral( "Vector tiles - outside of range" ) ); return true; // nothing to do } - bool isAsync = ( mSourceType == "xyz" ); + bool isAsync = ( mSourceType == QStringLiteral( "xyz" ) ); std::unique_ptr asyncLoader; QList rawTiles; @@ -76,15 +80,15 @@ bool QgsVectorTileLayerRenderer::render() QElapsedTimer tFetch; tFetch.start(); rawTiles = QgsVectorTileLoader::blockingFetchTileRawData( mSourceType, mSourcePath, mTileZoom, viewCenter, mTileRange ); - qDebug() << "FETCH TIME" << tFetch.elapsed() / 1000.; - qDebug() << "fetched tiles:" << rawTiles.count(); + QgsDebugMsg( QStringLiteral( "Tile fetching time: %1" ).arg( tFetch.elapsed() / 1000. ) ); + QgsDebugMsg( QStringLiteral( "Fetched tiles: %1" ).arg( rawTiles.count() ) ); } else { asyncLoader.reset( new QgsVectorTileLoader( mSourcePath, mTileZoom, mTileRange, viewCenter, mFeedback.get() ) ); QObject::connect( asyncLoader.get(), &QgsVectorTileLoader::tileRequestFinished, [this]( const QgsVectorTileRawData & rawTile ) { - qDebug() << "got async tile" << rawTile.id.column() << rawTile.id.row() << rawTile.id.zoomLevel(); + QgsDebugMsg( QStringLiteral( "Got tile asynchronously: " ) + rawTile.id.toString() ); if ( !rawTile.data.isEmpty() ) decodeAndDrawTile( rawTile ); } ); @@ -122,9 +126,9 @@ bool QgsVectorTileLayerRenderer::render() ctx.painter()->setClipping( false ); - qDebug() << "DECODE TIME" << mTotalDecodeTime / 1000.; - qDebug() << "DRAW TIME" << mTotalDrawTime / 1000.; - qDebug() << "TOTAL TIME" << tTotal.elapsed() / 1000.; + QgsDebugMsg( QStringLiteral( "Total time for decoding: %1" ).arg( mTotalDecodeTime / 1000. ) ); + QgsDebugMsg( QStringLiteral( "Drawing time: %1" ).arg( mTotalDrawTime / 1000. ) ); + QgsDebugMsg( QStringLiteral( "Total time: %1" ).arg( tTotal.elapsed() / 1000. ) ); return !ctx.renderingStopped(); } @@ -133,7 +137,7 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & { QgsRenderContext &ctx = *renderContext(); - qDebug() << "decoding tile " << rawTile.id.zoomLevel() << rawTile.id.column() << rawTile.id.row(); + QgsDebugMsgLevel( QStringLiteral( "Drawing tile " ) + rawTile.id.toString(), 2 ); QElapsedTimer tLoad; tLoad.start(); @@ -142,7 +146,7 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & QgsVectorTileMVTDecoder decoder; if ( !decoder.decode( rawTile.id, rawTile.data ) ) { - qDebug() << "Failed to parse raw tile data!"; + QgsDebugMsg( QStringLiteral( "Failed to parse raw tile data! " ) + rawTile.id.toString() ); return; } @@ -166,8 +170,6 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & ctx.painter()->setClipRegion( QRegion( tile.tilePolygon() ) ); - qDebug() << "drawing tile" << tile.id().zoomLevel() << tile.id().column() << tile.id().row(); - QElapsedTimer tDraw; tDraw.start(); diff --git a/src/core/vectortile/qgsvectortileloader.cpp b/src/core/vectortile/qgsvectortileloader.cpp index dbd423a9bd3d..5bd526bb50a4 100644 --- a/src/core/vectortile/qgsvectortileloader.cpp +++ b/src/core/vectortile/qgsvectortileloader.cpp @@ -15,12 +15,12 @@ #include "qgsvectortileloader.h" -#include #include #include #include "qgsblockingnetworkrequest.h" +#include "qgslogger.h" #include "qgsmbtilesreader.h" #include "qgsnetworkaccessmanager.h" #include "qgsvectortileutils.h" @@ -39,7 +39,7 @@ QgsVectorTileLoader::QgsVectorTileLoader( const QString &uri, int zoomLevel, con return; } - qDebug() << "starting loader"; + QgsDebugMsg( QStringLiteral( "Starting network loader" ) ); QVector tiles = QgsVectorTileUtils::tilesInRange( range, zoomLevel ); QgsVectorTileUtils::sortTilesByDistanceFromCenter( tiles, viewCenter ); for ( QgsTileXYZ id : qgis::as_const( tiles ) ) @@ -50,7 +50,7 @@ QgsVectorTileLoader::QgsVectorTileLoader( const QString &uri, int zoomLevel, con QgsVectorTileLoader::~QgsVectorTileLoader() { - qDebug() << "terminating loader"; + QgsDebugMsg( QStringLiteral( "Terminating network loader" ) ); if ( !mReplies.isEmpty() ) { @@ -62,17 +62,17 @@ QgsVectorTileLoader::~QgsVectorTileLoader() void QgsVectorTileLoader::downloadBlocking() { - qDebug() << "starting event loop" << mReplies.count() << "requests"; - if ( mFeedback && mFeedback->isCanceled() ) { - qDebug() << "actually not - we were canceled"; + QgsDebugMsg( QStringLiteral( "downloadBlocking - not staring event loop - canceled" ) ); return; // nothing to do } + QgsDebugMsg( QStringLiteral( "Starting event loop with %1 requests" ).arg( mReplies.count() ) ); + mEventLoop->exec( QEventLoop::ExcludeUserInputEvents ); - qDebug() << "download blocking finished"; + QgsDebugMsg( QStringLiteral( "downloadBlocking finished" ) ); Q_ASSERT( mReplies.isEmpty() ); } @@ -82,7 +82,7 @@ void QgsVectorTileLoader::loadFromNetworkAsync( const QgsTileXYZ &id, const QStr QString url = QgsVectorTileUtils::formatXYZUrlTemplate( requestUrl, id ); QNetworkRequest request( url ); QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLoader" ) ); - QgsSetRequestInitiatorId( request, QStringLiteral( "X=%1 Y=%2 Z=%3" ).arg( id.column() ).arg( id.row() ).arg( id.zoomLevel() ) ); + QgsSetRequestInitiatorId( request, id.toString() ); request.setAttribute( static_cast( QNetworkRequest::User + 1 ), id.column() ); request.setAttribute( static_cast( QNetworkRequest::User + 2 ), id.row() ); @@ -110,7 +110,7 @@ void QgsVectorTileLoader::tileReplyFinished() { // TODO: handle redirections? - qDebug() << "tile reply - all good!"; + QgsDebugMsg( QStringLiteral( "Tile download successful: " ) + tileID.toString() ); QByteArray rawData = reply->readAll(); mReplies.removeOne( reply ); reply->deleteLater(); @@ -119,7 +119,7 @@ void QgsVectorTileLoader::tileReplyFinished() } else { - qDebug() << "tile reply - error! " << reply->errorString(); + QgsDebugMsg( QStringLiteral( "Tile download failed! " ) + reply->errorString() ); mReplies.removeOne( reply ); reply->deleteLater(); @@ -135,11 +135,10 @@ void QgsVectorTileLoader::tileReplyFinished() void QgsVectorTileLoader::canceled() { - qDebug() << "canceling pending requests"; + QgsDebugMsg( QStringLiteral( "Canceling %1 pending requests" ).arg( mReplies.count() ) ); const QList replies = mReplies; for ( QNetworkReply *reply : replies ) { - qDebug() << "aborting request"; reply->abort(); } } @@ -151,7 +150,7 @@ QList QgsVectorTileLoader::blockingFetchTileRawData( const QList rawTiles; QgsMBTilesReader mbReader( sourcePath ); - bool isUrl = ( sourceType == "xyz" ); + bool isUrl = ( sourceType == QStringLiteral( "xyz" ) ); if ( !isUrl ) { bool res = mbReader.open(); @@ -177,11 +176,10 @@ QByteArray QgsVectorTileLoader::loadFromNetwork( const QgsTileXYZ &id, const QSt QNetworkRequest nr; nr.setUrl( QUrl( url ) ); QgsBlockingNetworkRequest req; - qDebug() << "requestiong" << url; + QgsDebugMsg( QStringLiteral( "Blocking request: " ) + url ); QgsBlockingNetworkRequest::ErrorCode errCode = req.get( nr ); - qDebug() << "get" << errCode; QgsNetworkReplyContent reply = req.reply(); - qDebug() << "content size" << reply.content().size(); + QgsDebugMsg( QStringLiteral( "Got error code %1, content size %2" ).arg( errCode ).arg( reply.content().size() ) ); return reply.content(); } @@ -193,7 +191,7 @@ QByteArray QgsVectorTileLoader::loadFromMBTiles( const QgsTileXYZ &id, QgsMBTile QByteArray gzippedTileData = mbTileReader.tileData( id.zoomLevel(), id.column(), rowTMS ); if ( gzippedTileData.isEmpty() ) { - qDebug() << "Failed to get tile" << id.zoomLevel() << id.column() << id.row(); + QgsDebugMsg( QStringLiteral( "Failed to get tile " ) + id.toString() ); return QByteArray(); } @@ -202,11 +200,11 @@ QByteArray QgsVectorTileLoader::loadFromMBTiles( const QgsTileXYZ &id, QgsMBTile QByteArray data; if ( !decodeGzip( gzippedTileData, data ) ) { - qDebug() << "failed to decompress tile" << id.zoomLevel() << id.column() << id.row(); + QgsDebugMsg( QStringLiteral( "Failed to decompress tile " ) + id.toString() ); return QByteArray(); } - qDebug() << "tile blob size" << gzippedTileData.size() << " -> uncompressed size" << data.size(); + QgsDebugMsg( QStringLiteral( "Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ) ); return data; } diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.cpp b/src/core/vectortile/qgsvectortilemvtdecoder.cpp index d2f7edccc778..912bb250ac3d 100644 --- a/src/core/vectortile/qgsvectortilemvtdecoder.cpp +++ b/src/core/vectortile/qgsvectortilemvtdecoder.cpp @@ -14,13 +14,13 @@ ***************************************************************************/ #include -#include #include "qgsvectortilemvtdecoder.h" #include "qgsvectortilelayerrenderer.h" #include "qgsvectortileutils.h" +#include "qgslogger.h" #include "qgsmultipoint.h" #include "qgslinestring.h" #include "qgsmultilinestring.h" @@ -256,7 +256,7 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap #include -#include #include "qgscoordinatetransform.h" #include "qgsgeometrycollection.h" #include "qgsfields.h" +#include "qgslogger.h" #include "qgsmaptopixel.h" #include "qgsrectangle.h" #include "qgsvectorlayer.h" @@ -61,8 +61,6 @@ QgsFields QgsVectorTileUtils::makeQgisFields( QSet flds ) int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom ) { - qDebug() << "MVT map scale 1 :" << mapScale; - double s0 = 559082264.0287178; // scale denominator at zoom level 0 of GoogleCRS84Quad double tileZoom2 = log( s0 / mapScale ) / log( 2 ); tileZoom2 -= 1; // TODO: it seems that map scale is double (is that because of high-dpi screen?) @@ -80,9 +78,8 @@ QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer * { QgsVectorTileMVTDecoder decoder; decoder.decode( tileID, mvt->getRawTile( tileID ) ); - qDebug() << decoder.layers(); QSet fieldNames = QSet::fromList( decoder.layerFieldNames( layerName ) ); - fieldNames << "_geom_type"; + fieldNames << QStringLiteral( "_geom_type" ); QMap perLayerFields; QgsFields fields = QgsVectorTileUtils::makeQgisFields( fieldNames ); perLayerFields[layerName] = fields; @@ -105,14 +102,14 @@ QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer * featuresList[i].setGeometry( QgsGeometry( gc ) ); } - QgsVectorLayer *vl = new QgsVectorLayer( "GeometryCollection", layerName, "memory" ); + QgsVectorLayer *vl = new QgsVectorLayer( QStringLiteral( "GeometryCollection" ), layerName, QStringLiteral( "memory" ) ); vl->dataProvider()->addAttributes( fields.toList() ); vl->updateFields(); bool res = vl->dataProvider()->addFeatures( featuresList ); Q_ASSERT( res ); Q_ASSERT( featuresList.count() == vl->featureCount() ); vl->updateExtents(); - qDebug() << "layer" << layerName << "features" << vl->featureCount(); + QgsDebugMsg( QStringLiteral( "Layer %1 features %2" ).arg( layerName ).arg( vl->featureCount() ) ); return vl; } From 81a7af7c966dc526910d2b010b170e67cd7f2777 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Sat, 28 Mar 2020 13:02:41 +0100 Subject: [PATCH 16/27] Updates from review (debug msg level 2, qBound, wider lines for test) --- src/core/qgstiles.cpp | 32 ++++++------------ src/core/vectortile/qgsvectortilelayer.cpp | 4 +-- .../vectortile/qgsvectortilelayerrenderer.cpp | 28 +++++++-------- src/core/vectortile/qgsvectortileloader.cpp | 25 ++++++++------ src/core/vectortile/qgsvectortileutils.cpp | 2 +- tests/src/core/testqgsvectortilelayer.cpp | 4 +-- .../expected_render_test_basic.png | Bin 160537 -> 160537 bytes 7 files changed, 44 insertions(+), 51 deletions(-) diff --git a/src/core/qgstiles.cpp b/src/core/qgstiles.cpp index fa79e39d746e..3beade14fca8 100644 --- a/src/core/qgstiles.cpp +++ b/src/core/qgstiles.cpp @@ -15,7 +15,7 @@ #include "qgstiles.h" -#include +#include "qgslogger.h" QgsTileMatrix QgsTileMatrix::fromWebMercator( int zoomLevel ) { @@ -51,24 +51,12 @@ QgsPointXY QgsTileMatrix::tileCenter( QgsTileXYZ id ) const return QgsPointXY( x, y ); } -inline double clampDouble( double lo, double v, double hi ) -{ - return ( v < lo ) ? lo : ( hi < v ) ? hi : v; -} - -static int clampTile( int tile, int nTiles ) -{ - if ( tile < 0 ) return 0; - if ( tile >= nTiles ) return nTiles - 1; - return tile; -} - QgsTileRange QgsTileMatrix::tileRangeFromExtent( const QgsRectangle &r ) { - double x0 = clampDouble( mExtent.xMinimum(), r.xMinimum(), mExtent.xMaximum() ); - double y0 = clampDouble( mExtent.yMinimum(), r.yMinimum(), mExtent.yMaximum() ); - double x1 = clampDouble( mExtent.xMinimum(), r.xMaximum(), mExtent.xMaximum() ); - double y1 = clampDouble( mExtent.yMinimum(), r.yMaximum(), mExtent.yMaximum() ); + double x0 = qBound( mExtent.xMinimum(), r.xMinimum(), mExtent.xMaximum() ); + double y0 = qBound( mExtent.yMinimum(), r.yMinimum(), mExtent.yMaximum() ); + double x1 = qBound( mExtent.xMinimum(), r.xMaximum(), mExtent.xMaximum() ); + double y1 = qBound( mExtent.yMinimum(), r.yMaximum(), mExtent.yMaximum() ); if ( x0 >= x1 || y0 >= y1 ) return QgsTileRange(); // nothing to display @@ -77,13 +65,13 @@ QgsTileRange QgsTileMatrix::tileRangeFromExtent( const QgsRectangle &r ) double tileY1 = ( mExtent.yMaximum() - y1 ) / mTileYSpan; double tileY2 = ( mExtent.yMaximum() - y0 ) / mTileYSpan; - qDebug() << "tile range of edges" << tileX1 << tileY1 << tileX2 << tileY2; + QgsDebugMsgLevel( QStringLiteral( "Tile range of edges [%1,%2] - [%3,%4]" ).arg( tileX1 ).arg( tileY1 ).arg( tileX2 ).arg( tileY2 ), 2 ); // figure out tile range from zoom - int startColumn = clampTile( static_cast( floor( tileX1 ) ), mMatrixWidth ); - int endColumn = clampTile( static_cast( floor( tileX2 ) ), mMatrixWidth ); - int startRow = clampTile( static_cast( floor( tileY1 ) ), mMatrixHeight ); - int endRow = clampTile( static_cast( floor( tileY2 ) ), mMatrixHeight ); + int startColumn = qBound( 0, static_cast( floor( tileX1 ) ), mMatrixWidth - 1 ); + int endColumn = qBound( 0, static_cast( floor( tileX2 ) ), mMatrixWidth - 1 ); + int startRow = qBound( 0, static_cast( floor( tileY1 ) ), mMatrixHeight - 1 ); + int endRow = qBound( 0, static_cast( floor( tileY2 ) ), mMatrixHeight - 1 ); return QgsTileRange( startColumn, endColumn, startRow, endRow ); } diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index 9780b59190bc..2420bf480352 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -55,7 +55,7 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN return; } - QgsDebugMsg( QStringLiteral( "name: " ) + reader.metadataValue( QStringLiteral( "name" ) ) ); + QgsDebugMsgLevel( QStringLiteral( "name: " ) + reader.metadataValue( QStringLiteral( "name" ) ), 2 ); bool minZoomOk, maxZoomOk; int minZoom = reader.metadataValue( QStringLiteral( "minzoom" ) ).toInt( &minZoomOk ); int maxZoom = reader.metadataValue( QStringLiteral( "maxzoom" ) ).toInt( &maxZoomOk ); @@ -63,7 +63,7 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN mSourceMinZoom = minZoom; if ( maxZoomOk ) mSourceMaxZoom = maxZoom; - QgsDebugMsg( QStringLiteral( "zoom range: %1 - %2" ).arg( mSourceMinZoom ).arg( mSourceMaxZoom ) ); + QgsDebugMsgLevel( QStringLiteral( "zoom range: %1 - %2" ).arg( mSourceMinZoom ).arg( mSourceMaxZoom ), 2 ); QgsRectangle r = reader.extent(); // TODO: reproject to EPSG:3857 diff --git a/src/core/vectortile/qgsvectortilelayerrenderer.cpp b/src/core/vectortile/qgsvectortilelayerrenderer.cpp index 5765c3fd510a..6cdc4f6741eb 100644 --- a/src/core/vectortile/qgsvectortilelayerrenderer.cpp +++ b/src/core/vectortile/qgsvectortilelayerrenderer.cpp @@ -49,25 +49,25 @@ bool QgsVectorTileLayerRenderer::render() QElapsedTimer tTotal; tTotal.start(); - QgsDebugMsg( QStringLiteral( "Vector tiles rendering extent: " ) + ctx.extent().toString( -1 ) ); - QgsDebugMsg( QStringLiteral( "Vector tiles map scale 1 : %1" ).arg( ctx.rendererScale() ) ); + QgsDebugMsgLevel( QStringLiteral( "Vector tiles rendering extent: " ) + ctx.extent().toString( -1 ), 2 ); + QgsDebugMsgLevel( QStringLiteral( "Vector tiles map scale 1 : %1" ).arg( ctx.rendererScale() ), 2 ); mTileZoom = QgsVectorTileUtils::scaleToZoomLevel( ctx.rendererScale(), mSourceMinZoom, mSourceMaxZoom ); - QgsDebugMsg( QStringLiteral( "Vector tiles zoom level: %1" ).arg( mTileZoom ) ); + QgsDebugMsgLevel( QStringLiteral( "Vector tiles zoom level: %1" ).arg( mTileZoom ), 2 ); mTileMatrix = QgsTileMatrix::fromWebMercator( mTileZoom ); mTileRange = mTileMatrix.tileRangeFromExtent( ctx.extent() ); - QgsDebugMsg( QStringLiteral( "Vector tiles range X: %1 - %2 Y: %3 - %4" ) - .arg( mTileRange.startColumn() ).arg( mTileRange.endColumn() ) - .arg( mTileRange.startRow() ).arg( mTileRange.endRow() ) ); + QgsDebugMsgLevel( QStringLiteral( "Vector tiles range X: %1 - %2 Y: %3 - %4" ) + .arg( mTileRange.startColumn() ).arg( mTileRange.endColumn() ) + .arg( mTileRange.startRow() ).arg( mTileRange.endRow() ), 2 ); // view center is used to sort the order of tiles for fetching and rendering QPointF viewCenter = mTileMatrix.mapToTileCoordinates( ctx.extent().center() ); if ( !mTileRange.isValid() ) { - QgsDebugMsg( QStringLiteral( "Vector tiles - outside of range" ) ); + QgsDebugMsgLevel( QStringLiteral( "Vector tiles - outside of range" ), 2 ); return true; // nothing to do } @@ -80,15 +80,15 @@ bool QgsVectorTileLayerRenderer::render() QElapsedTimer tFetch; tFetch.start(); rawTiles = QgsVectorTileLoader::blockingFetchTileRawData( mSourceType, mSourcePath, mTileZoom, viewCenter, mTileRange ); - QgsDebugMsg( QStringLiteral( "Tile fetching time: %1" ).arg( tFetch.elapsed() / 1000. ) ); - QgsDebugMsg( QStringLiteral( "Fetched tiles: %1" ).arg( rawTiles.count() ) ); + QgsDebugMsgLevel( QStringLiteral( "Tile fetching time: %1" ).arg( tFetch.elapsed() / 1000. ), 2 ); + QgsDebugMsgLevel( QStringLiteral( "Fetched tiles: %1" ).arg( rawTiles.count() ), 2 ); } else { asyncLoader.reset( new QgsVectorTileLoader( mSourcePath, mTileZoom, mTileRange, viewCenter, mFeedback.get() ) ); QObject::connect( asyncLoader.get(), &QgsVectorTileLoader::tileRequestFinished, [this]( const QgsVectorTileRawData & rawTile ) { - QgsDebugMsg( QStringLiteral( "Got tile asynchronously: " ) + rawTile.id.toString() ); + QgsDebugMsgLevel( QStringLiteral( "Got tile asynchronously: " ) + rawTile.id.toString(), 2 ); if ( !rawTile.data.isEmpty() ) decodeAndDrawTile( rawTile ); } ); @@ -126,9 +126,9 @@ bool QgsVectorTileLayerRenderer::render() ctx.painter()->setClipping( false ); - QgsDebugMsg( QStringLiteral( "Total time for decoding: %1" ).arg( mTotalDecodeTime / 1000. ) ); - QgsDebugMsg( QStringLiteral( "Drawing time: %1" ).arg( mTotalDrawTime / 1000. ) ); - QgsDebugMsg( QStringLiteral( "Total time: %1" ).arg( tTotal.elapsed() / 1000. ) ); + QgsDebugMsgLevel( QStringLiteral( "Total time for decoding: %1" ).arg( mTotalDecodeTime / 1000. ), 2 ); + QgsDebugMsgLevel( QStringLiteral( "Drawing time: %1" ).arg( mTotalDrawTime / 1000. ), 2 ); + QgsDebugMsgLevel( QStringLiteral( "Total time: %1" ).arg( tTotal.elapsed() / 1000. ), 2 ); return !ctx.renderingStopped(); } @@ -146,7 +146,7 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData & QgsVectorTileMVTDecoder decoder; if ( !decoder.decode( rawTile.id, rawTile.data ) ) { - QgsDebugMsg( QStringLiteral( "Failed to parse raw tile data! " ) + rawTile.id.toString() ); + QgsDebugMsgLevel( QStringLiteral( "Failed to parse raw tile data! " ) + rawTile.id.toString(), 2 ); return; } diff --git a/src/core/vectortile/qgsvectortileloader.cpp b/src/core/vectortile/qgsvectortileloader.cpp index 5bd526bb50a4..bb951fce6232 100644 --- a/src/core/vectortile/qgsvectortileloader.cpp +++ b/src/core/vectortile/qgsvectortileloader.cpp @@ -39,7 +39,7 @@ QgsVectorTileLoader::QgsVectorTileLoader( const QString &uri, int zoomLevel, con return; } - QgsDebugMsg( QStringLiteral( "Starting network loader" ) ); + QgsDebugMsgLevel( QStringLiteral( "Starting network loader" ), 2 ); QVector tiles = QgsVectorTileUtils::tilesInRange( range, zoomLevel ); QgsVectorTileUtils::sortTilesByDistanceFromCenter( tiles, viewCenter ); for ( QgsTileXYZ id : qgis::as_const( tiles ) ) @@ -50,7 +50,7 @@ QgsVectorTileLoader::QgsVectorTileLoader( const QString &uri, int zoomLevel, con QgsVectorTileLoader::~QgsVectorTileLoader() { - QgsDebugMsg( QStringLiteral( "Terminating network loader" ) ); + QgsDebugMsgLevel( QStringLiteral( "Terminating network loader" ), 2 ); if ( !mReplies.isEmpty() ) { @@ -64,15 +64,15 @@ void QgsVectorTileLoader::downloadBlocking() { if ( mFeedback && mFeedback->isCanceled() ) { - QgsDebugMsg( QStringLiteral( "downloadBlocking - not staring event loop - canceled" ) ); + QgsDebugMsgLevel( QStringLiteral( "downloadBlocking - not staring event loop - canceled" ), 2 ); return; // nothing to do } - QgsDebugMsg( QStringLiteral( "Starting event loop with %1 requests" ).arg( mReplies.count() ) ); + QgsDebugMsgLevel( QStringLiteral( "Starting event loop with %1 requests" ).arg( mReplies.count() ), 2 ); mEventLoop->exec( QEventLoop::ExcludeUserInputEvents ); - QgsDebugMsg( QStringLiteral( "downloadBlocking finished" ) ); + QgsDebugMsgLevel( QStringLiteral( "downloadBlocking finished" ), 2 ); Q_ASSERT( mReplies.isEmpty() ); } @@ -110,7 +110,7 @@ void QgsVectorTileLoader::tileReplyFinished() { // TODO: handle redirections? - QgsDebugMsg( QStringLiteral( "Tile download successful: " ) + tileID.toString() ); + QgsDebugMsgLevel( QStringLiteral( "Tile download successful: " ) + tileID.toString(), 2 ); QByteArray rawData = reply->readAll(); mReplies.removeOne( reply ); reply->deleteLater(); @@ -135,7 +135,7 @@ void QgsVectorTileLoader::tileReplyFinished() void QgsVectorTileLoader::canceled() { - QgsDebugMsg( QStringLiteral( "Canceling %1 pending requests" ).arg( mReplies.count() ) ); + QgsDebugMsgLevel( QStringLiteral( "Canceling %1 pending requests" ).arg( mReplies.count() ), 2 ); const QList replies = mReplies; for ( QNetworkReply *reply : replies ) { @@ -176,10 +176,15 @@ QByteArray QgsVectorTileLoader::loadFromNetwork( const QgsTileXYZ &id, const QSt QNetworkRequest nr; nr.setUrl( QUrl( url ) ); QgsBlockingNetworkRequest req; - QgsDebugMsg( QStringLiteral( "Blocking request: " ) + url ); + QgsDebugMsgLevel( QStringLiteral( "Blocking request: " ) + url, 2 ); QgsBlockingNetworkRequest::ErrorCode errCode = req.get( nr ); + if ( errCode != QgsBlockingNetworkRequest::NoError ) + { + QgsDebugMsg( QStringLiteral( "Request failed: " ) + url ); + return QByteArray(); + } QgsNetworkReplyContent reply = req.reply(); - QgsDebugMsg( QStringLiteral( "Got error code %1, content size %2" ).arg( errCode ).arg( reply.content().size() ) ); + QgsDebugMsgLevel( QStringLiteral( "Request successful, content size %1" ).arg( reply.content().size() ), 2 ); return reply.content(); } @@ -204,7 +209,7 @@ QByteArray QgsVectorTileLoader::loadFromMBTiles( const QgsTileXYZ &id, QgsMBTile return QByteArray(); } - QgsDebugMsg( QStringLiteral( "Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ) ); + QgsDebugMsgLevel( QStringLiteral( "Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ), 2 ); return data; } diff --git a/src/core/vectortile/qgsvectortileutils.cpp b/src/core/vectortile/qgsvectortileutils.cpp index b034baa563db..5b4022a95ccc 100644 --- a/src/core/vectortile/qgsvectortileutils.cpp +++ b/src/core/vectortile/qgsvectortileutils.cpp @@ -109,7 +109,7 @@ QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer * Q_ASSERT( res ); Q_ASSERT( featuresList.count() == vl->featureCount() ); vl->updateExtents(); - QgsDebugMsg( QStringLiteral( "Layer %1 features %2" ).arg( layerName ).arg( vl->featureCount() ) ); + QgsDebugMsgLevel( QStringLiteral( "Layer %1 features %2" ).arg( layerName ).arg( vl->featureCount() ), 2 ); return vl; } diff --git a/tests/src/core/testqgsvectortilelayer.cpp b/tests/src/core/testqgsvectortilelayer.cpp index 8341efc9b04a..00ee27d5b731 100644 --- a/tests/src/core/testqgsvectortilelayer.cpp +++ b/tests/src/core/testqgsvectortilelayer.cpp @@ -80,9 +80,9 @@ void TestQgsVectorTileLayer::initTestCase() QColor polygonFillColor = Qt::blue; QColor polygonStrokeColor = polygonFillColor; polygonFillColor.setAlpha( 100 ); - double polygonStrokeWidth = DEFAULT_LINE_WIDTH; + double polygonStrokeWidth = DEFAULT_LINE_WIDTH * 2; QColor lineStrokeColor = Qt::blue; - double lineStrokeWidth = DEFAULT_LINE_WIDTH; + double lineStrokeWidth = DEFAULT_LINE_WIDTH * 2; QColor pointFillColor = Qt::red; QColor pointStrokeColor = pointFillColor; pointFillColor.setAlpha( 100 ); diff --git a/tests/testdata/control_images/vector_tile/expected_render_test_basic/expected_render_test_basic.png b/tests/testdata/control_images/vector_tile/expected_render_test_basic/expected_render_test_basic.png index 45096375f9d3b78fac3e081ff84bf75d89b54b4d..13e0421ed2b01316768aa4a2fd2208001f9f3f87 100644 GIT binary patch literal 160537 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

7QqxJ1AzHbD=HNppO7M;N&1RqGhO_ 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 Date: Sat, 28 Mar 2020 13:04:41 +0100 Subject: [PATCH 17/27] Update src/gui/qgsbrowserdockwidget_p.cpp Co-Authored-By: Nyall Dawson --- src/gui/qgsbrowserdockwidget_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgsbrowserdockwidget_p.cpp b/src/gui/qgsbrowserdockwidget_p.cpp index 5cea88a4ad52..147f008232d3 100644 --- a/src/gui/qgsbrowserdockwidget_p.cpp +++ b/src/gui/qgsbrowserdockwidget_p.cpp @@ -211,7 +211,7 @@ void QgsBrowserLayerProperties::setItem( QgsDataItem *item ) case QgsMapLayerType::VectorTileLayer: { - QgsDebugMsg( QStringLiteral( "creating vector tile layer" ) ); + QgsDebugMsgLevel( QStringLiteral( "creating vector tile layer" ), 2 ); mLayer = qgis::make_unique< QgsVectorTileLayer >( layerItem->uri(), layerItem->name() ); break; } From 8c90de901f608ce99217b4db60792603f3cf20e8 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Mon, 30 Mar 2020 21:02:53 +0200 Subject: [PATCH 18/27] Dummy commit to trigger new azure build (PR reopen does nothing) --- src/core/vectortile/qgsvectortilelayer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index 2420bf480352..7528de135f74 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -23,6 +23,7 @@ #include "qgsdatasourceuri.h" + QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseName ) : QgsMapLayer( QgsMapLayerType::VectorTileLayer, baseName ) { From 93715f7ff074256ec781abb11618e1f3c0cd1c2f Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Mon, 30 Mar 2020 23:03:51 +0200 Subject: [PATCH 19/27] Do not use pre-generated files from protoc It turns out different versions of protobuf library may not necessarily work with different versions of code generated by protoc (for example, these files worked fine on Ubuntu 18.04 but they do not work on 19.10 which has newer version of protobuf library). Also, we should be fine with using just "lite" version of the library which is about an order of magnitude smaller (lite 0.3mb vs full 2.3mb). --- external/mapbox-vector-tile/README.md | 15 - external/mapbox-vector-tile/vector_tile.pb.cc | 2527 ----------------- external/mapbox-vector-tile/vector_tile.pb.h | 1260 -------- src/core/CMakeLists.txt | 19 +- src/core/vectortile/vector_tile.proto | 82 + 5 files changed, 93 insertions(+), 3810 deletions(-) delete mode 100644 external/mapbox-vector-tile/README.md delete mode 100644 external/mapbox-vector-tile/vector_tile.pb.cc delete mode 100644 external/mapbox-vector-tile/vector_tile.pb.h create mode 100644 src/core/vectortile/vector_tile.proto diff --git a/external/mapbox-vector-tile/README.md b/external/mapbox-vector-tile/README.md deleted file mode 100644 index b6921a544e23..000000000000 --- a/external/mapbox-vector-tile/README.md +++ /dev/null @@ -1,15 +0,0 @@ - -The .pb.cc and .pb.h are generated by 'protoc' tool and got copied here from https://github.com/TimSC/mbtiles-cpp - - -Update pbf files ----------------- - -To update the protobuf files, get vector_tile.proto from https://github.com/mapbox/vector-tile-spec, remove the line "option optimize_for = LITE_RUNTIME;", then - - mkdir vector_tile21 - - protoc vector_tile.proto --cpp_out vector_tile21 - -protobuf lite is avoided because it doesn't contain SerializeToOstream functionality. - diff --git a/external/mapbox-vector-tile/vector_tile.pb.cc b/external/mapbox-vector-tile/vector_tile.pb.cc deleted file mode 100644 index 3f66c597f2ce..000000000000 --- a/external/mapbox-vector-tile/vector_tile.pb.cc +++ /dev/null @@ -1,2527 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: vector_tile.proto - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "vector_tile.pb.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace vector_tile { - -namespace { - -const ::google::protobuf::Descriptor* Tile_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Tile_reflection_ = NULL; -const ::google::protobuf::Descriptor* Tile_Value_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Tile_Value_reflection_ = NULL; -const ::google::protobuf::Descriptor* Tile_Feature_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Tile_Feature_reflection_ = NULL; -const ::google::protobuf::Descriptor* Tile_Layer_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - Tile_Layer_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* Tile_GeomType_descriptor_ = NULL; - -} // namespace - - -void protobuf_AssignDesc_vector_5ftile_2eproto() GOOGLE_ATTRIBUTE_COLD; -void protobuf_AssignDesc_vector_5ftile_2eproto() { - protobuf_AddDesc_vector_5ftile_2eproto(); - const ::google::protobuf::FileDescriptor* file = - ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "vector_tile.proto"); - GOOGLE_CHECK(file != NULL); - Tile_descriptor_ = file->message_type(0); - static const int Tile_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, layers_), - }; - Tile_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Tile_descriptor_, - Tile::default_instance_, - Tile_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, _has_bits_[0]), - -1, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, _extensions_), - sizeof(Tile), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile, _internal_metadata_), - -1); - Tile_Value_descriptor_ = Tile_descriptor_->nested_type(0); - static const int Tile_Value_offsets_[7] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, string_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, float_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, double_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, int_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, uint_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, sint_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, bool_value_), - }; - Tile_Value_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Tile_Value_descriptor_, - Tile_Value::default_instance_, - Tile_Value_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, _has_bits_[0]), - -1, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, _extensions_), - sizeof(Tile_Value), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Value, _internal_metadata_), - -1); - Tile_Feature_descriptor_ = Tile_descriptor_->nested_type(1); - static const int Tile_Feature_offsets_[4] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, id_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, tags_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, geometry_), - }; - Tile_Feature_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Tile_Feature_descriptor_, - Tile_Feature::default_instance_, - Tile_Feature_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, _has_bits_[0]), - -1, - -1, - sizeof(Tile_Feature), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Feature, _internal_metadata_), - -1); - Tile_Layer_descriptor_ = Tile_descriptor_->nested_type(2); - static const int Tile_Layer_offsets_[6] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, version_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, features_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, keys_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, values_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, extent_), - }; - Tile_Layer_reflection_ = - ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( - Tile_Layer_descriptor_, - Tile_Layer::default_instance_, - Tile_Layer_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, _has_bits_[0]), - -1, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, _extensions_), - sizeof(Tile_Layer), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Tile_Layer, _internal_metadata_), - -1); - Tile_GeomType_descriptor_ = Tile_descriptor_->enum_type(0); -} - -namespace { - -GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); -inline void protobuf_AssignDescriptorsOnce() { - ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_vector_5ftile_2eproto); -} - -void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Tile_descriptor_, &Tile::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Tile_Value_descriptor_, &Tile_Value::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Tile_Feature_descriptor_, &Tile_Feature::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Tile_Layer_descriptor_, &Tile_Layer::default_instance()); -} - -} // namespace - -void protobuf_ShutdownFile_vector_5ftile_2eproto() { - delete Tile::default_instance_; - delete Tile_reflection_; - delete Tile_Value::default_instance_; - delete Tile_Value_reflection_; - delete Tile_Feature::default_instance_; - delete Tile_Feature_reflection_; - delete Tile_Layer::default_instance_; - delete Tile_Layer_reflection_; -} - -void protobuf_AddDesc_vector_5ftile_2eproto() GOOGLE_ATTRIBUTE_COLD; -void protobuf_AddDesc_vector_5ftile_2eproto() { - static bool already_here = false; - if (already_here) return; - already_here = true; - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\021vector_tile.proto\022\013vector_tile\"\300\004\n\004Til" - "e\022\'\n\006layers\030\003 \003(\0132\027.vector_tile.Tile.Lay" - "er\032\241\001\n\005Value\022\024\n\014string_value\030\001 \001(\t\022\023\n\013fl" - "oat_value\030\002 \001(\002\022\024\n\014double_value\030\003 \001(\001\022\021\n" - "\tint_value\030\004 \001(\003\022\022\n\nuint_value\030\005 \001(\004\022\022\n\n" - "sint_value\030\006 \001(\022\022\022\n\nbool_value\030\007 \001(\010*\010\010\010" - "\020\200\200\200\200\002\032s\n\007Feature\022\r\n\002id\030\001 \001(\004:\0010\022\020\n\004tags" - "\030\002 \003(\rB\002\020\001\0221\n\004type\030\003 \001(\0162\032.vector_tile.T" - "ile.GeomType:\007UNKNOWN\022\024\n\010geometry\030\004 \003(\rB" - "\002\020\001\032\255\001\n\005Layer\022\022\n\007version\030\017 \002(\r:\0011\022\014\n\004nam" - "e\030\001 \002(\t\022+\n\010features\030\002 \003(\0132\031.vector_tile." - "Tile.Feature\022\014\n\004keys\030\003 \003(\t\022\'\n\006values\030\004 \003" - "(\0132\027.vector_tile.Tile.Value\022\024\n\006extent\030\005 " - "\001(\r:\0044096*\010\010\020\020\200\200\200\200\002\"\?\n\010GeomType\022\013\n\007UNKNO" - "WN\020\000\022\t\n\005POINT\020\001\022\016\n\nLINESTRING\020\002\022\013\n\007POLYG" - "ON\020\003*\005\010\020\020\200@", 611); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "vector_tile.proto", &protobuf_RegisterTypes); - Tile::default_instance_ = new Tile(); - Tile_Value::default_instance_ = new Tile_Value(); - Tile_Feature::default_instance_ = new Tile_Feature(); - Tile_Layer::default_instance_ = new Tile_Layer(); - Tile::default_instance_->InitAsDefaultInstance(); - Tile_Value::default_instance_->InitAsDefaultInstance(); - Tile_Feature::default_instance_->InitAsDefaultInstance(); - Tile_Layer::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_vector_5ftile_2eproto); -} - -// Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_vector_5ftile_2eproto { - StaticDescriptorInitializer_vector_5ftile_2eproto() { - protobuf_AddDesc_vector_5ftile_2eproto(); - } -} static_descriptor_initializer_vector_5ftile_2eproto_; - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* Tile_GeomType_descriptor() { - protobuf_AssignDescriptorsOnce(); - return Tile_GeomType_descriptor_; -} -bool Tile_GeomType_IsValid(int value) { - switch(value) { - case 0: - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const Tile_GeomType Tile::UNKNOWN; -const Tile_GeomType Tile::POINT; -const Tile_GeomType Tile::LINESTRING; -const Tile_GeomType Tile::POLYGON; -const Tile_GeomType Tile::GeomType_MIN; -const Tile_GeomType Tile::GeomType_MAX; -const int Tile::GeomType_ARRAYSIZE; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int Tile_Value::kStringValueFieldNumber; -const int Tile_Value::kFloatValueFieldNumber; -const int Tile_Value::kDoubleValueFieldNumber; -const int Tile_Value::kIntValueFieldNumber; -const int Tile_Value::kUintValueFieldNumber; -const int Tile_Value::kSintValueFieldNumber; -const int Tile_Value::kBoolValueFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -Tile_Value::Tile_Value() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:vector_tile.Tile.Value) -} - -void Tile_Value::InitAsDefaultInstance() { -} - -Tile_Value::Tile_Value(const Tile_Value& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:vector_tile.Tile.Value) -} - -void Tile_Value::SharedCtor() { - ::google::protobuf::internal::GetEmptyString(); - _cached_size_ = 0; - string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - float_value_ = 0; - double_value_ = 0; - int_value_ = GOOGLE_LONGLONG(0); - uint_value_ = GOOGLE_ULONGLONG(0); - sint_value_ = GOOGLE_LONGLONG(0); - bool_value_ = false; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -Tile_Value::~Tile_Value() { - // @@protoc_insertion_point(destructor:vector_tile.Tile.Value) - SharedDtor(); -} - -void Tile_Value::SharedDtor() { - string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != default_instance_) { - } -} - -void Tile_Value::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Tile_Value::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Tile_Value_descriptor_; -} - -const Tile_Value& Tile_Value::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); - return *default_instance_; -} - -Tile_Value* Tile_Value::default_instance_ = NULL; - -Tile_Value* Tile_Value::New(::google::protobuf::Arena* arena) const { - Tile_Value* n = new Tile_Value; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Tile_Value::Clear() { -// @@protoc_insertion_point(message_clear_start:vector_tile.Tile.Value) - _extensions_.Clear(); -#if defined(__clang__) -#define ZR_HELPER_(f) \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ - __builtin_offsetof(Tile_Value, f) \ - _Pragma("clang diagnostic pop") -#else -#define ZR_HELPER_(f) reinterpret_cast(\ - &reinterpret_cast(16)->f) -#endif - -#define ZR_(first, last) do {\ - ::memset(&first, 0,\ - ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ -} while (0) - - if (_has_bits_[0 / 32] & 127u) { - ZR_(double_value_, sint_value_); - if (has_string_value()) { - string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - } - } - -#undef ZR_HELPER_ -#undef ZR_ - - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (_internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->Clear(); - } -} - -bool Tile_Value::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:vector_tile.Tile.Value) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string string_value = 1; - case 1: { - if (tag == 10) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_string_value())); - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->string_value().data(), this->string_value().length(), - ::google::protobuf::internal::WireFormat::PARSE, - "vector_tile.Tile.Value.string_value"); - } else { - goto handle_unusual; - } - if (input->ExpectTag(21)) goto parse_float_value; - break; - } - - // optional float float_value = 2; - case 2: { - if (tag == 21) { - parse_float_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( - input, &float_value_))); - set_has_float_value(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(25)) goto parse_double_value; - break; - } - - // optional double double_value = 3; - case 3: { - if (tag == 25) { - parse_double_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( - input, &double_value_))); - set_has_double_value(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(32)) goto parse_int_value; - break; - } - - // optional int64 int_value = 4; - case 4: { - if (tag == 32) { - parse_int_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( - input, &int_value_))); - set_has_int_value(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(40)) goto parse_uint_value; - break; - } - - // optional uint64 uint_value = 5; - case 5: { - if (tag == 40) { - parse_uint_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &uint_value_))); - set_has_uint_value(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(48)) goto parse_sint_value; - break; - } - - // optional sint64 sint_value = 6; - case 6: { - if (tag == 48) { - parse_sint_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_SINT64>( - input, &sint_value_))); - set_has_sint_value(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(56)) goto parse_bool_value; - break; - } - - // optional bool bool_value = 7; - case 7: { - if (tag == 56) { - parse_bool_value: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( - input, &bool_value_))); - set_has_bool_value(); - } else { - goto handle_unusual; - } - if (input->ExpectAtEnd()) goto success; - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - if ((64u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:vector_tile.Tile.Value) - return true; -failure: - // @@protoc_insertion_point(parse_failure:vector_tile.Tile.Value) - return false; -#undef DO_ -} - -void Tile_Value::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:vector_tile.Tile.Value) - // optional string string_value = 1; - if (has_string_value()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->string_value().data(), this->string_value().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "vector_tile.Tile.Value.string_value"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->string_value(), output); - } - - // optional float float_value = 2; - if (has_float_value()) { - ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->float_value(), output); - } - - // optional double double_value = 3; - if (has_double_value()) { - ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->double_value(), output); - } - - // optional int64 int_value = 4; - if (has_int_value()) { - ::google::protobuf::internal::WireFormatLite::WriteInt64(4, this->int_value(), output); - } - - // optional uint64 uint_value = 5; - if (has_uint_value()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(5, this->uint_value(), output); - } - - // optional sint64 sint_value = 6; - if (has_sint_value()) { - ::google::protobuf::internal::WireFormatLite::WriteSInt64(6, this->sint_value(), output); - } - - // optional bool bool_value = 7; - if (has_bool_value()) { - ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->bool_value(), output); - } - - // Extension range [8, 536870912) - _extensions_.SerializeWithCachedSizes( - 8, 536870912, output); - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:vector_tile.Tile.Value) -} - -::google::protobuf::uint8* Tile_Value::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile.Value) - // optional string string_value = 1; - if (has_string_value()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->string_value().data(), this->string_value().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "vector_tile.Tile.Value.string_value"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->string_value(), target); - } - - // optional float float_value = 2; - if (has_float_value()) { - target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(2, this->float_value(), target); - } - - // optional double double_value = 3; - if (has_double_value()) { - target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->double_value(), target); - } - - // optional int64 int_value = 4; - if (has_int_value()) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(4, this->int_value(), target); - } - - // optional uint64 uint_value = 5; - if (has_uint_value()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(5, this->uint_value(), target); - } - - // optional sint64 sint_value = 6; - if (has_sint_value()) { - target = ::google::protobuf::internal::WireFormatLite::WriteSInt64ToArray(6, this->sint_value(), target); - } - - // optional bool bool_value = 7; - if (has_bool_value()) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->bool_value(), target); - } - - // Extension range [8, 536870912) - target = _extensions_.InternalSerializeWithCachedSizesToArray( - 8, 536870912, false, target); - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile.Value) - return target; -} - -int Tile_Value::ByteSize() const { -// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile.Value) - int total_size = 0; - - if (_has_bits_[0 / 32] & 127u) { - // optional string string_value = 1; - if (has_string_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->string_value()); - } - - // optional float float_value = 2; - if (has_float_value()) { - total_size += 1 + 4; - } - - // optional double double_value = 3; - if (has_double_value()) { - total_size += 1 + 8; - } - - // optional int64 int_value = 4; - if (has_int_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int64Size( - this->int_value()); - } - - // optional uint64 uint_value = 5; - if (has_uint_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->uint_value()); - } - - // optional sint64 sint_value = 6; - if (has_sint_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::SInt64Size( - this->sint_value()); - } - - // optional bool bool_value = 7; - if (has_bool_value()) { - total_size += 1 + 1; - } - - } - total_size += _extensions_.ByteSize(); - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Tile_Value::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile.Value) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - const Tile_Value* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile.Value) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile.Value) - MergeFrom(*source); - } -} - -void Tile_Value::MergeFrom(const Tile_Value& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile.Value) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from.has_string_value()) { - set_has_string_value(); - string_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.string_value_); - } - if (from.has_float_value()) { - set_float_value(from.float_value()); - } - if (from.has_double_value()) { - set_double_value(from.double_value()); - } - if (from.has_int_value()) { - set_int_value(from.int_value()); - } - if (from.has_uint_value()) { - set_uint_value(from.uint_value()); - } - if (from.has_sint_value()) { - set_sint_value(from.sint_value()); - } - if (from.has_bool_value()) { - set_bool_value(from.bool_value()); - } - } - _extensions_.MergeFrom(from._extensions_); - if (from._internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); - } -} - -void Tile_Value::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile.Value) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Tile_Value::CopyFrom(const Tile_Value& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile.Value) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Tile_Value::IsInitialized() const { - - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void Tile_Value::Swap(Tile_Value* other) { - if (other == this) return; - InternalSwap(other); -} -void Tile_Value::InternalSwap(Tile_Value* other) { - string_value_.Swap(&other->string_value_); - std::swap(float_value_, other->float_value_); - std::swap(double_value_, other->double_value_); - std::swap(int_value_, other->int_value_); - std::swap(uint_value_, other->uint_value_); - std::swap(sint_value_, other->sint_value_); - std::swap(bool_value_, other->bool_value_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); -} - -::google::protobuf::Metadata Tile_Value::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Tile_Value_descriptor_; - metadata.reflection = Tile_Value_reflection_; - return metadata; -} - - -// ------------------------------------------------------------------- - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int Tile_Feature::kIdFieldNumber; -const int Tile_Feature::kTagsFieldNumber; -const int Tile_Feature::kTypeFieldNumber; -const int Tile_Feature::kGeometryFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -Tile_Feature::Tile_Feature() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:vector_tile.Tile.Feature) -} - -void Tile_Feature::InitAsDefaultInstance() { -} - -Tile_Feature::Tile_Feature(const Tile_Feature& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:vector_tile.Tile.Feature) -} - -void Tile_Feature::SharedCtor() { - _cached_size_ = 0; - id_ = GOOGLE_ULONGLONG(0); - type_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -Tile_Feature::~Tile_Feature() { - // @@protoc_insertion_point(destructor:vector_tile.Tile.Feature) - SharedDtor(); -} - -void Tile_Feature::SharedDtor() { - if (this != default_instance_) { - } -} - -void Tile_Feature::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Tile_Feature::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Tile_Feature_descriptor_; -} - -const Tile_Feature& Tile_Feature::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); - return *default_instance_; -} - -Tile_Feature* Tile_Feature::default_instance_ = NULL; - -Tile_Feature* Tile_Feature::New(::google::protobuf::Arena* arena) const { - Tile_Feature* n = new Tile_Feature; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Tile_Feature::Clear() { -// @@protoc_insertion_point(message_clear_start:vector_tile.Tile.Feature) - if (_has_bits_[0 / 32] & 5u) { - id_ = GOOGLE_ULONGLONG(0); - type_ = 0; - } - tags_.Clear(); - geometry_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (_internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->Clear(); - } -} - -bool Tile_Feature::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:vector_tile.Tile.Feature) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional uint64 id = 1 [default = 0]; - case 1: { - if (tag == 8) { - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &id_))); - set_has_id(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(18)) goto parse_tags; - break; - } - - // repeated uint32 tags = 2 [packed = true]; - case 2: { - if (tag == 18) { - parse_tags: - DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, this->mutable_tags()))); - } else if (tag == 16) { - DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - 1, 18, input, this->mutable_tags()))); - } else { - goto handle_unusual; - } - if (input->ExpectTag(24)) goto parse_type; - break; - } - - // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; - case 3: { - if (tag == 24) { - parse_type: - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::vector_tile::Tile_GeomType_IsValid(value)) { - set_type(static_cast< ::vector_tile::Tile_GeomType >(value)); - } else { - mutable_unknown_fields()->AddVarint(3, value); - } - } else { - goto handle_unusual; - } - if (input->ExpectTag(34)) goto parse_geometry; - break; - } - - // repeated uint32 geometry = 4 [packed = true]; - case 4: { - if (tag == 34) { - parse_geometry: - DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, this->mutable_geometry()))); - } else if (tag == 32) { - DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - 1, 34, input, this->mutable_geometry()))); - } else { - goto handle_unusual; - } - if (input->ExpectAtEnd()) goto success; - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:vector_tile.Tile.Feature) - return true; -failure: - // @@protoc_insertion_point(parse_failure:vector_tile.Tile.Feature) - return false; -#undef DO_ -} - -void Tile_Feature::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:vector_tile.Tile.Feature) - // optional uint64 id = 1 [default = 0]; - if (has_id()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->id(), output); - } - - // repeated uint32 tags = 2 [packed = true]; - if (this->tags_size() > 0) { - ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(_tags_cached_byte_size_); - } - for (int i = 0; i < this->tags_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag( - this->tags(i), output); - } - - // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; - if (has_type()) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 3, this->type(), output); - } - - // repeated uint32 geometry = 4 [packed = true]; - if (this->geometry_size() > 0) { - ::google::protobuf::internal::WireFormatLite::WriteTag(4, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(_geometry_cached_byte_size_); - } - for (int i = 0; i < this->geometry_size(); i++) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag( - this->geometry(i), output); - } - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:vector_tile.Tile.Feature) -} - -::google::protobuf::uint8* Tile_Feature::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile.Feature) - // optional uint64 id = 1 [default = 0]; - if (has_id()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->id(), target); - } - - // repeated uint32 tags = 2 [packed = true]; - if (this->tags_size() > 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( - 2, - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - target); - target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( - _tags_cached_byte_size_, target); - } - for (int i = 0; i < this->tags_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteUInt32NoTagToArray(this->tags(i), target); - } - - // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; - if (has_type()) { - target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( - 3, this->type(), target); - } - - // repeated uint32 geometry = 4 [packed = true]; - if (this->geometry_size() > 0) { - target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( - 4, - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, - target); - target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( - _geometry_cached_byte_size_, target); - } - for (int i = 0; i < this->geometry_size(); i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteUInt32NoTagToArray(this->geometry(i), target); - } - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile.Feature) - return target; -} - -int Tile_Feature::ByteSize() const { -// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile.Feature) - int total_size = 0; - - if (_has_bits_[0 / 32] & 5u) { - // optional uint64 id = 1 [default = 0]; - if (has_id()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->id()); - } - - // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; - if (has_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); - } - - } - // repeated uint32 tags = 2 [packed = true]; - { - int data_size = 0; - for (int i = 0; i < this->tags_size(); i++) { - data_size += ::google::protobuf::internal::WireFormatLite:: - UInt32Size(this->tags(i)); - } - if (data_size > 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _tags_cached_byte_size_ = data_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - total_size += data_size; - } - - // repeated uint32 geometry = 4 [packed = true]; - { - int data_size = 0; - for (int i = 0; i < this->geometry_size(); i++) { - data_size += ::google::protobuf::internal::WireFormatLite:: - UInt32Size(this->geometry(i)); - } - if (data_size > 0) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _geometry_cached_byte_size_ = data_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - total_size += data_size; - } - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Tile_Feature::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile.Feature) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - const Tile_Feature* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile.Feature) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile.Feature) - MergeFrom(*source); - } -} - -void Tile_Feature::MergeFrom(const Tile_Feature& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile.Feature) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - tags_.MergeFrom(from.tags_); - geometry_.MergeFrom(from.geometry_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from.has_id()) { - set_id(from.id()); - } - if (from.has_type()) { - set_type(from.type()); - } - } - if (from._internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); - } -} - -void Tile_Feature::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile.Feature) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Tile_Feature::CopyFrom(const Tile_Feature& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile.Feature) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Tile_Feature::IsInitialized() const { - - return true; -} - -void Tile_Feature::Swap(Tile_Feature* other) { - if (other == this) return; - InternalSwap(other); -} -void Tile_Feature::InternalSwap(Tile_Feature* other) { - std::swap(id_, other->id_); - tags_.UnsafeArenaSwap(&other->tags_); - std::swap(type_, other->type_); - geometry_.UnsafeArenaSwap(&other->geometry_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata Tile_Feature::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Tile_Feature_descriptor_; - metadata.reflection = Tile_Feature_reflection_; - return metadata; -} - - -// ------------------------------------------------------------------- - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int Tile_Layer::kVersionFieldNumber; -const int Tile_Layer::kNameFieldNumber; -const int Tile_Layer::kFeaturesFieldNumber; -const int Tile_Layer::kKeysFieldNumber; -const int Tile_Layer::kValuesFieldNumber; -const int Tile_Layer::kExtentFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -Tile_Layer::Tile_Layer() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:vector_tile.Tile.Layer) -} - -void Tile_Layer::InitAsDefaultInstance() { -} - -Tile_Layer::Tile_Layer(const Tile_Layer& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:vector_tile.Tile.Layer) -} - -void Tile_Layer::SharedCtor() { - ::google::protobuf::internal::GetEmptyString(); - _cached_size_ = 0; - version_ = 1u; - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - extent_ = 4096u; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -Tile_Layer::~Tile_Layer() { - // @@protoc_insertion_point(destructor:vector_tile.Tile.Layer) - SharedDtor(); -} - -void Tile_Layer::SharedDtor() { - name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != default_instance_) { - } -} - -void Tile_Layer::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Tile_Layer::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Tile_Layer_descriptor_; -} - -const Tile_Layer& Tile_Layer::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); - return *default_instance_; -} - -Tile_Layer* Tile_Layer::default_instance_ = NULL; - -Tile_Layer* Tile_Layer::New(::google::protobuf::Arena* arena) const { - Tile_Layer* n = new Tile_Layer; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Tile_Layer::Clear() { -// @@protoc_insertion_point(message_clear_start:vector_tile.Tile.Layer) - _extensions_.Clear(); - if (_has_bits_[0 / 32] & 35u) { - version_ = 1u; - if (has_name()) { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - } - extent_ = 4096u; - } - features_.Clear(); - keys_.Clear(); - values_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (_internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->Clear(); - } -} - -bool Tile_Layer::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:vector_tile.Tile.Layer) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required string name = 1; - case 1: { - if (tag == 10) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE, - "vector_tile.Tile.Layer.name"); - } else { - goto handle_unusual; - } - if (input->ExpectTag(18)) goto parse_features; - break; - } - - // repeated .vector_tile.Tile.Feature features = 2; - case 2: { - if (tag == 18) { - parse_features: - DO_(input->IncrementRecursionDepth()); - parse_loop_features: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( - input, add_features())); - } else { - goto handle_unusual; - } - if (input->ExpectTag(18)) goto parse_loop_features; - input->UnsafeDecrementRecursionDepth(); - if (input->ExpectTag(26)) goto parse_keys; - break; - } - - // repeated string keys = 3; - case 3: { - if (tag == 26) { - parse_keys: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->add_keys())); - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->keys(this->keys_size() - 1).data(), - this->keys(this->keys_size() - 1).length(), - ::google::protobuf::internal::WireFormat::PARSE, - "vector_tile.Tile.Layer.keys"); - } else { - goto handle_unusual; - } - if (input->ExpectTag(26)) goto parse_keys; - if (input->ExpectTag(34)) goto parse_values; - break; - } - - // repeated .vector_tile.Tile.Value values = 4; - case 4: { - if (tag == 34) { - parse_values: - DO_(input->IncrementRecursionDepth()); - parse_loop_values: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( - input, add_values())); - } else { - goto handle_unusual; - } - if (input->ExpectTag(34)) goto parse_loop_values; - input->UnsafeDecrementRecursionDepth(); - if (input->ExpectTag(40)) goto parse_extent; - break; - } - - // optional uint32 extent = 5 [default = 4096]; - case 5: { - if (tag == 40) { - parse_extent: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &extent_))); - set_has_extent(); - } else { - goto handle_unusual; - } - if (input->ExpectTag(120)) goto parse_version; - break; - } - - // required uint32 version = 15 [default = 1]; - case 15: { - if (tag == 120) { - parse_version: - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( - input, &version_))); - set_has_version(); - } else { - goto handle_unusual; - } - if (input->ExpectAtEnd()) goto success; - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - if ((128u <= tag)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:vector_tile.Tile.Layer) - return true; -failure: - // @@protoc_insertion_point(parse_failure:vector_tile.Tile.Layer) - return false; -#undef DO_ -} - -void Tile_Layer::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:vector_tile.Tile.Layer) - // required string name = 1; - if (has_name()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "vector_tile.Tile.Layer.name"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // repeated .vector_tile.Tile.Feature features = 2; - for (unsigned int i = 0, n = this->features_size(); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 2, this->features(i), output); - } - - // repeated string keys = 3; - for (int i = 0; i < this->keys_size(); i++) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->keys(i).data(), this->keys(i).length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "vector_tile.Tile.Layer.keys"); - ::google::protobuf::internal::WireFormatLite::WriteString( - 3, this->keys(i), output); - } - - // repeated .vector_tile.Tile.Value values = 4; - for (unsigned int i = 0, n = this->values_size(); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 4, this->values(i), output); - } - - // optional uint32 extent = 5 [default = 4096]; - if (has_extent()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->extent(), output); - } - - // required uint32 version = 15 [default = 1]; - if (has_version()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(15, this->version(), output); - } - - // Extension range [16, 536870912) - _extensions_.SerializeWithCachedSizes( - 16, 536870912, output); - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:vector_tile.Tile.Layer) -} - -::google::protobuf::uint8* Tile_Layer::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile.Layer) - // required string name = 1; - if (has_name()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "vector_tile.Tile.Layer.name"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // repeated .vector_tile.Tile.Feature features = 2; - for (unsigned int i = 0, n = this->features_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 2, this->features(i), false, target); - } - - // repeated string keys = 3; - for (int i = 0; i < this->keys_size(); i++) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->keys(i).data(), this->keys(i).length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "vector_tile.Tile.Layer.keys"); - target = ::google::protobuf::internal::WireFormatLite:: - WriteStringToArray(3, this->keys(i), target); - } - - // repeated .vector_tile.Tile.Value values = 4; - for (unsigned int i = 0, n = this->values_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 4, this->values(i), false, target); - } - - // optional uint32 extent = 5 [default = 4096]; - if (has_extent()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->extent(), target); - } - - // required uint32 version = 15 [default = 1]; - if (has_version()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(15, this->version(), target); - } - - // Extension range [16, 536870912) - target = _extensions_.InternalSerializeWithCachedSizesToArray( - 16, 536870912, false, target); - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile.Layer) - return target; -} - -int Tile_Layer::RequiredFieldsByteSizeFallback() const { -// @@protoc_insertion_point(required_fields_byte_size_fallback_start:vector_tile.Tile.Layer) - int total_size = 0; - - if (has_version()) { - // required uint32 version = 15 [default = 1]; - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->version()); - } - - if (has_name()) { - // required string name = 1; - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - return total_size; -} -int Tile_Layer::ByteSize() const { -// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile.Layer) - int total_size = 0; - - if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present. - // required uint32 version = 15 [default = 1]; - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->version()); - - // required string name = 1; - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - - } else { - total_size += RequiredFieldsByteSizeFallback(); - } - // optional uint32 extent = 5 [default = 4096]; - if (has_extent()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt32Size( - this->extent()); - } - - // repeated .vector_tile.Tile.Feature features = 2; - total_size += 1 * this->features_size(); - for (int i = 0; i < this->features_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->features(i)); - } - - // repeated string keys = 3; - total_size += 1 * this->keys_size(); - for (int i = 0; i < this->keys_size(); i++) { - total_size += ::google::protobuf::internal::WireFormatLite::StringSize( - this->keys(i)); - } - - // repeated .vector_tile.Tile.Value values = 4; - total_size += 1 * this->values_size(); - for (int i = 0; i < this->values_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->values(i)); - } - - total_size += _extensions_.ByteSize(); - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Tile_Layer::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile.Layer) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - const Tile_Layer* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile.Layer) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile.Layer) - MergeFrom(*source); - } -} - -void Tile_Layer::MergeFrom(const Tile_Layer& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile.Layer) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - features_.MergeFrom(from.features_); - keys_.MergeFrom(from.keys_); - values_.MergeFrom(from.values_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from.has_version()) { - set_version(from.version()); - } - if (from.has_name()) { - set_has_name(); - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (from.has_extent()) { - set_extent(from.extent()); - } - } - _extensions_.MergeFrom(from._extensions_); - if (from._internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); - } -} - -void Tile_Layer::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile.Layer) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Tile_Layer::CopyFrom(const Tile_Layer& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile.Layer) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Tile_Layer::IsInitialized() const { - if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; - - if (!::google::protobuf::internal::AllAreInitialized(this->values())) return false; - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void Tile_Layer::Swap(Tile_Layer* other) { - if (other == this) return; - InternalSwap(other); -} -void Tile_Layer::InternalSwap(Tile_Layer* other) { - std::swap(version_, other->version_); - name_.Swap(&other->name_); - features_.UnsafeArenaSwap(&other->features_); - keys_.UnsafeArenaSwap(&other->keys_); - values_.UnsafeArenaSwap(&other->values_); - std::swap(extent_, other->extent_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); -} - -::google::protobuf::Metadata Tile_Layer::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Tile_Layer_descriptor_; - metadata.reflection = Tile_Layer_reflection_; - return metadata; -} - - -// ------------------------------------------------------------------- - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int Tile::kLayersFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -Tile::Tile() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - SharedCtor(); - // @@protoc_insertion_point(constructor:vector_tile.Tile) -} - -void Tile::InitAsDefaultInstance() { -} - -Tile::Tile(const Tile& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL) { - SharedCtor(); - MergeFrom(from); - // @@protoc_insertion_point(copy_constructor:vector_tile.Tile) -} - -void Tile::SharedCtor() { - _cached_size_ = 0; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -Tile::~Tile() { - // @@protoc_insertion_point(destructor:vector_tile.Tile) - SharedDtor(); -} - -void Tile::SharedDtor() { - if (this != default_instance_) { - } -} - -void Tile::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* Tile::descriptor() { - protobuf_AssignDescriptorsOnce(); - return Tile_descriptor_; -} - -const Tile& Tile::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_vector_5ftile_2eproto(); - return *default_instance_; -} - -Tile* Tile::default_instance_ = NULL; - -Tile* Tile::New(::google::protobuf::Arena* arena) const { - Tile* n = new Tile; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void Tile::Clear() { -// @@protoc_insertion_point(message_clear_start:vector_tile.Tile) - _extensions_.Clear(); - layers_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (_internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->Clear(); - } -} - -bool Tile::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:vector_tile.Tile) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .vector_tile.Tile.Layer layers = 3; - case 3: { - if (tag == 26) { - DO_(input->IncrementRecursionDepth()); - parse_loop_layers: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( - input, add_layers())); - } else { - goto handle_unusual; - } - if (input->ExpectTag(26)) goto parse_loop_layers; - input->UnsafeDecrementRecursionDepth(); - if (input->ExpectAtEnd()) goto success; - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - if ((128u <= tag && tag < 65536u)) { - DO_(_extensions_.ParseField(tag, input, default_instance_, - mutable_unknown_fields())); - continue; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:vector_tile.Tile) - return true; -failure: - // @@protoc_insertion_point(parse_failure:vector_tile.Tile) - return false; -#undef DO_ -} - -void Tile::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:vector_tile.Tile) - // repeated .vector_tile.Tile.Layer layers = 3; - for (unsigned int i = 0, n = this->layers_size(); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->layers(i), output); - } - - // Extension range [16, 8192) - _extensions_.SerializeWithCachedSizes( - 16, 8192, output); - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:vector_tile.Tile) -} - -::google::protobuf::uint8* Tile::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:vector_tile.Tile) - // repeated .vector_tile.Tile.Layer layers = 3; - for (unsigned int i = 0, n = this->layers_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 3, this->layers(i), false, target); - } - - // Extension range [16, 8192) - target = _extensions_.InternalSerializeWithCachedSizesToArray( - 16, 8192, false, target); - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:vector_tile.Tile) - return target; -} - -int Tile::ByteSize() const { -// @@protoc_insertion_point(message_byte_size_start:vector_tile.Tile) - int total_size = 0; - - // repeated .vector_tile.Tile.Layer layers = 3; - total_size += 1 * this->layers_size(); - for (int i = 0; i < this->layers_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->layers(i)); - } - - total_size += _extensions_.ByteSize(); - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void Tile::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:vector_tile.Tile) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - const Tile* source = - ::google::protobuf::internal::DynamicCastToGenerated( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:vector_tile.Tile) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:vector_tile.Tile) - MergeFrom(*source); - } -} - -void Tile::MergeFrom(const Tile& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:vector_tile.Tile) - if (GOOGLE_PREDICT_FALSE(&from == this)) { - ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); - } - layers_.MergeFrom(from.layers_); - _extensions_.MergeFrom(from._extensions_); - if (from._internal_metadata_.have_unknown_fields()) { - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); - } -} - -void Tile::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:vector_tile.Tile) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void Tile::CopyFrom(const Tile& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:vector_tile.Tile) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool Tile::IsInitialized() const { - - if (!::google::protobuf::internal::AllAreInitialized(this->layers())) return false; - - if (!_extensions_.IsInitialized()) return false; return true; -} - -void Tile::Swap(Tile* other) { - if (other == this) return; - InternalSwap(other); -} -void Tile::InternalSwap(Tile* other) { - layers_.UnsafeArenaSwap(&other->layers_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); - _extensions_.Swap(&other->_extensions_); -} - -::google::protobuf::Metadata Tile::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = Tile_descriptor_; - metadata.reflection = Tile_reflection_; - return metadata; -} - -#if PROTOBUF_INLINE_NOT_IN_HEADERS -// Tile_Value - -// optional string string_value = 1; -bool Tile_Value::has_string_value() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -void Tile_Value::set_has_string_value() { - _has_bits_[0] |= 0x00000001u; -} -void Tile_Value::clear_has_string_value() { - _has_bits_[0] &= ~0x00000001u; -} -void Tile_Value::clear_string_value() { - string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_string_value(); -} - const ::std::string& Tile_Value::string_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.string_value) - return string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - void Tile_Value::set_string_value(const ::std::string& value) { - set_has_string_value(); - string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.string_value) -} - void Tile_Value::set_string_value(const char* value) { - set_has_string_value(); - string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Value.string_value) -} - void Tile_Value::set_string_value(const char* value, size_t size) { - set_has_string_value(); - string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Value.string_value) -} - ::std::string* Tile_Value::mutable_string_value() { - set_has_string_value(); - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Value.string_value) - return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - ::std::string* Tile_Value::release_string_value() { - // @@protoc_insertion_point(field_release:vector_tile.Tile.Value.string_value) - clear_has_string_value(); - return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - void Tile_Value::set_allocated_string_value(::std::string* string_value) { - if (string_value != NULL) { - set_has_string_value(); - } else { - clear_has_string_value(); - } - string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value); - // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Value.string_value) -} - -// optional float float_value = 2; -bool Tile_Value::has_float_value() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -void Tile_Value::set_has_float_value() { - _has_bits_[0] |= 0x00000002u; -} -void Tile_Value::clear_has_float_value() { - _has_bits_[0] &= ~0x00000002u; -} -void Tile_Value::clear_float_value() { - float_value_ = 0; - clear_has_float_value(); -} - float Tile_Value::float_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.float_value) - return float_value_; -} - void Tile_Value::set_float_value(float value) { - set_has_float_value(); - float_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.float_value) -} - -// optional double double_value = 3; -bool Tile_Value::has_double_value() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -void Tile_Value::set_has_double_value() { - _has_bits_[0] |= 0x00000004u; -} -void Tile_Value::clear_has_double_value() { - _has_bits_[0] &= ~0x00000004u; -} -void Tile_Value::clear_double_value() { - double_value_ = 0; - clear_has_double_value(); -} - double Tile_Value::double_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.double_value) - return double_value_; -} - void Tile_Value::set_double_value(double value) { - set_has_double_value(); - double_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.double_value) -} - -// optional int64 int_value = 4; -bool Tile_Value::has_int_value() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -void Tile_Value::set_has_int_value() { - _has_bits_[0] |= 0x00000008u; -} -void Tile_Value::clear_has_int_value() { - _has_bits_[0] &= ~0x00000008u; -} -void Tile_Value::clear_int_value() { - int_value_ = GOOGLE_LONGLONG(0); - clear_has_int_value(); -} - ::google::protobuf::int64 Tile_Value::int_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.int_value) - return int_value_; -} - void Tile_Value::set_int_value(::google::protobuf::int64 value) { - set_has_int_value(); - int_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.int_value) -} - -// optional uint64 uint_value = 5; -bool Tile_Value::has_uint_value() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -void Tile_Value::set_has_uint_value() { - _has_bits_[0] |= 0x00000010u; -} -void Tile_Value::clear_has_uint_value() { - _has_bits_[0] &= ~0x00000010u; -} -void Tile_Value::clear_uint_value() { - uint_value_ = GOOGLE_ULONGLONG(0); - clear_has_uint_value(); -} - ::google::protobuf::uint64 Tile_Value::uint_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.uint_value) - return uint_value_; -} - void Tile_Value::set_uint_value(::google::protobuf::uint64 value) { - set_has_uint_value(); - uint_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.uint_value) -} - -// optional sint64 sint_value = 6; -bool Tile_Value::has_sint_value() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -void Tile_Value::set_has_sint_value() { - _has_bits_[0] |= 0x00000020u; -} -void Tile_Value::clear_has_sint_value() { - _has_bits_[0] &= ~0x00000020u; -} -void Tile_Value::clear_sint_value() { - sint_value_ = GOOGLE_LONGLONG(0); - clear_has_sint_value(); -} - ::google::protobuf::int64 Tile_Value::sint_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.sint_value) - return sint_value_; -} - void Tile_Value::set_sint_value(::google::protobuf::int64 value) { - set_has_sint_value(); - sint_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.sint_value) -} - -// optional bool bool_value = 7; -bool Tile_Value::has_bool_value() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -void Tile_Value::set_has_bool_value() { - _has_bits_[0] |= 0x00000040u; -} -void Tile_Value::clear_has_bool_value() { - _has_bits_[0] &= ~0x00000040u; -} -void Tile_Value::clear_bool_value() { - bool_value_ = false; - clear_has_bool_value(); -} - bool Tile_Value::bool_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.bool_value) - return bool_value_; -} - void Tile_Value::set_bool_value(bool value) { - set_has_bool_value(); - bool_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.bool_value) -} - -// ------------------------------------------------------------------- - -// Tile_Feature - -// optional uint64 id = 1 [default = 0]; -bool Tile_Feature::has_id() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -void Tile_Feature::set_has_id() { - _has_bits_[0] |= 0x00000001u; -} -void Tile_Feature::clear_has_id() { - _has_bits_[0] &= ~0x00000001u; -} -void Tile_Feature::clear_id() { - id_ = GOOGLE_ULONGLONG(0); - clear_has_id(); -} - ::google::protobuf::uint64 Tile_Feature::id() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.id) - return id_; -} - void Tile_Feature::set_id(::google::protobuf::uint64 value) { - set_has_id(); - id_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.id) -} - -// repeated uint32 tags = 2 [packed = true]; -int Tile_Feature::tags_size() const { - return tags_.size(); -} -void Tile_Feature::clear_tags() { - tags_.Clear(); -} - ::google::protobuf::uint32 Tile_Feature::tags(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.tags) - return tags_.Get(index); -} - void Tile_Feature::set_tags(int index, ::google::protobuf::uint32 value) { - tags_.Set(index, value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.tags) -} - void Tile_Feature::add_tags(::google::protobuf::uint32 value) { - tags_.Add(value); - // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.tags) -} - const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& -Tile_Feature::tags() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.tags) - return tags_; -} - ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* -Tile_Feature::mutable_tags() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.tags) - return &tags_; -} - -// optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; -bool Tile_Feature::has_type() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -void Tile_Feature::set_has_type() { - _has_bits_[0] |= 0x00000004u; -} -void Tile_Feature::clear_has_type() { - _has_bits_[0] &= ~0x00000004u; -} -void Tile_Feature::clear_type() { - type_ = 0; - clear_has_type(); -} - ::vector_tile::Tile_GeomType Tile_Feature::type() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.type) - return static_cast< ::vector_tile::Tile_GeomType >(type_); -} - void Tile_Feature::set_type(::vector_tile::Tile_GeomType value) { - assert(::vector_tile::Tile_GeomType_IsValid(value)); - set_has_type(); - type_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.type) -} - -// repeated uint32 geometry = 4 [packed = true]; -int Tile_Feature::geometry_size() const { - return geometry_.size(); -} -void Tile_Feature::clear_geometry() { - geometry_.Clear(); -} - ::google::protobuf::uint32 Tile_Feature::geometry(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.geometry) - return geometry_.Get(index); -} - void Tile_Feature::set_geometry(int index, ::google::protobuf::uint32 value) { - geometry_.Set(index, value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.geometry) -} - void Tile_Feature::add_geometry(::google::protobuf::uint32 value) { - geometry_.Add(value); - // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.geometry) -} - const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& -Tile_Feature::geometry() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.geometry) - return geometry_; -} - ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* -Tile_Feature::mutable_geometry() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.geometry) - return &geometry_; -} - -// ------------------------------------------------------------------- - -// Tile_Layer - -// required uint32 version = 15 [default = 1]; -bool Tile_Layer::has_version() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -void Tile_Layer::set_has_version() { - _has_bits_[0] |= 0x00000001u; -} -void Tile_Layer::clear_has_version() { - _has_bits_[0] &= ~0x00000001u; -} -void Tile_Layer::clear_version() { - version_ = 1u; - clear_has_version(); -} - ::google::protobuf::uint32 Tile_Layer::version() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.version) - return version_; -} - void Tile_Layer::set_version(::google::protobuf::uint32 value) { - set_has_version(); - version_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.version) -} - -// required string name = 1; -bool Tile_Layer::has_name() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -void Tile_Layer::set_has_name() { - _has_bits_[0] |= 0x00000002u; -} -void Tile_Layer::clear_has_name() { - _has_bits_[0] &= ~0x00000002u; -} -void Tile_Layer::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_name(); -} - const ::std::string& Tile_Layer::name() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.name) - return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - void Tile_Layer::set_name(const ::std::string& value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.name) -} - void Tile_Layer::set_name(const char* value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.name) -} - void Tile_Layer::set_name(const char* value, size_t size) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.name) -} - ::std::string* Tile_Layer::mutable_name() { - set_has_name(); - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - ::std::string* Tile_Layer::release_name() { - // @@protoc_insertion_point(field_release:vector_tile.Tile.Layer.name) - clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - void Tile_Layer::set_allocated_name(::std::string* name) { - if (name != NULL) { - set_has_name(); - } else { - clear_has_name(); - } - name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Layer.name) -} - -// repeated .vector_tile.Tile.Feature features = 2; -int Tile_Layer::features_size() const { - return features_.size(); -} -void Tile_Layer::clear_features() { - features_.Clear(); -} -const ::vector_tile::Tile_Feature& Tile_Layer::features(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.features) - return features_.Get(index); -} -::vector_tile::Tile_Feature* Tile_Layer::mutable_features(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.features) - return features_.Mutable(index); -} -::vector_tile::Tile_Feature* Tile_Layer::add_features() { - // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.features) - return features_.Add(); -} -::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >* -Tile_Layer::mutable_features() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.features) - return &features_; -} -const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >& -Tile_Layer::features() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.features) - return features_; -} - -// repeated string keys = 3; -int Tile_Layer::keys_size() const { - return keys_.size(); -} -void Tile_Layer::clear_keys() { - keys_.Clear(); -} - const ::std::string& Tile_Layer::keys(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.keys) - return keys_.Get(index); -} - ::std::string* Tile_Layer::mutable_keys(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.keys) - return keys_.Mutable(index); -} - void Tile_Layer::set_keys(int index, const ::std::string& value) { - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.keys) - keys_.Mutable(index)->assign(value); -} - void Tile_Layer::set_keys(int index, const char* value) { - keys_.Mutable(index)->assign(value); - // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.keys) -} - void Tile_Layer::set_keys(int index, const char* value, size_t size) { - keys_.Mutable(index)->assign( - reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.keys) -} - ::std::string* Tile_Layer::add_keys() { - // @@protoc_insertion_point(field_add_mutable:vector_tile.Tile.Layer.keys) - return keys_.Add(); -} - void Tile_Layer::add_keys(const ::std::string& value) { - keys_.Add()->assign(value); - // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.keys) -} - void Tile_Layer::add_keys(const char* value) { - keys_.Add()->assign(value); - // @@protoc_insertion_point(field_add_char:vector_tile.Tile.Layer.keys) -} - void Tile_Layer::add_keys(const char* value, size_t size) { - keys_.Add()->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_add_pointer:vector_tile.Tile.Layer.keys) -} - const ::google::protobuf::RepeatedPtrField< ::std::string>& -Tile_Layer::keys() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.keys) - return keys_; -} - ::google::protobuf::RepeatedPtrField< ::std::string>* -Tile_Layer::mutable_keys() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.keys) - return &keys_; -} - -// repeated .vector_tile.Tile.Value values = 4; -int Tile_Layer::values_size() const { - return values_.size(); -} -void Tile_Layer::clear_values() { - values_.Clear(); -} -const ::vector_tile::Tile_Value& Tile_Layer::values(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.values) - return values_.Get(index); -} -::vector_tile::Tile_Value* Tile_Layer::mutable_values(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.values) - return values_.Mutable(index); -} -::vector_tile::Tile_Value* Tile_Layer::add_values() { - // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.values) - return values_.Add(); -} -::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >* -Tile_Layer::mutable_values() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.values) - return &values_; -} -const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >& -Tile_Layer::values() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.values) - return values_; -} - -// optional uint32 extent = 5 [default = 4096]; -bool Tile_Layer::has_extent() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -void Tile_Layer::set_has_extent() { - _has_bits_[0] |= 0x00000020u; -} -void Tile_Layer::clear_has_extent() { - _has_bits_[0] &= ~0x00000020u; -} -void Tile_Layer::clear_extent() { - extent_ = 4096u; - clear_has_extent(); -} - ::google::protobuf::uint32 Tile_Layer::extent() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.extent) - return extent_; -} - void Tile_Layer::set_extent(::google::protobuf::uint32 value) { - set_has_extent(); - extent_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.extent) -} - -// ------------------------------------------------------------------- - -// Tile - -// repeated .vector_tile.Tile.Layer layers = 3; -int Tile::layers_size() const { - return layers_.size(); -} -void Tile::clear_layers() { - layers_.Clear(); -} -const ::vector_tile::Tile_Layer& Tile::layers(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.layers) - return layers_.Get(index); -} -::vector_tile::Tile_Layer* Tile::mutable_layers(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.layers) - return layers_.Mutable(index); -} -::vector_tile::Tile_Layer* Tile::add_layers() { - // @@protoc_insertion_point(field_add:vector_tile.Tile.layers) - return layers_.Add(); -} -::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >* -Tile::mutable_layers() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.layers) - return &layers_; -} -const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >& -Tile::layers() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.layers) - return layers_; -} - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS - -// @@protoc_insertion_point(namespace_scope) - -} // namespace vector_tile - -// @@protoc_insertion_point(global_scope) diff --git a/external/mapbox-vector-tile/vector_tile.pb.h b/external/mapbox-vector-tile/vector_tile.pb.h deleted file mode 100644 index 876720072a39..000000000000 --- a/external/mapbox-vector-tile/vector_tile.pb.h +++ /dev/null @@ -1,1260 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: vector_tile.proto - -#ifndef PROTOBUF_vector_5ftile_2eproto__INCLUDED -#define PROTOBUF_vector_5ftile_2eproto__INCLUDED - -#include - -#include - -#if GOOGLE_PROTOBUF_VERSION < 3000000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -// @@protoc_insertion_point(includes) - -namespace vector_tile { - -// Internal implementation detail -- do not call these. -void protobuf_AddDesc_vector_5ftile_2eproto(); -void protobuf_AssignDesc_vector_5ftile_2eproto(); -void protobuf_ShutdownFile_vector_5ftile_2eproto(); - -class Tile; -class Tile_Feature; -class Tile_Layer; -class Tile_Value; - -enum Tile_GeomType { - Tile_GeomType_UNKNOWN = 0, - Tile_GeomType_POINT = 1, - Tile_GeomType_LINESTRING = 2, - Tile_GeomType_POLYGON = 3 -}; -bool Tile_GeomType_IsValid(int value); -const Tile_GeomType Tile_GeomType_GeomType_MIN = Tile_GeomType_UNKNOWN; -const Tile_GeomType Tile_GeomType_GeomType_MAX = Tile_GeomType_POLYGON; -const int Tile_GeomType_GeomType_ARRAYSIZE = Tile_GeomType_GeomType_MAX + 1; - -const ::google::protobuf::EnumDescriptor* Tile_GeomType_descriptor(); -inline const ::std::string& Tile_GeomType_Name(Tile_GeomType value) { - return ::google::protobuf::internal::NameOfEnum( - Tile_GeomType_descriptor(), value); -} -inline bool Tile_GeomType_Parse( - const ::std::string& name, Tile_GeomType* value) { - return ::google::protobuf::internal::ParseNamedEnum( - Tile_GeomType_descriptor(), name, value); -} -// =================================================================== - -class Tile_Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile.Value) */ { - public: - Tile_Value(); - virtual ~Tile_Value(); - - Tile_Value(const Tile_Value& from); - - inline Tile_Value& operator=(const Tile_Value& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Tile_Value& default_instance(); - - void Swap(Tile_Value* other); - - // implements Message ---------------------------------------------- - - inline Tile_Value* New() const { return New(NULL); } - - Tile_Value* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Tile_Value& from); - void MergeFrom(const Tile_Value& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { - return InternalSerializeWithCachedSizesToArray(false, output); - } - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(Tile_Value* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string string_value = 1; - bool has_string_value() const; - void clear_string_value(); - static const int kStringValueFieldNumber = 1; - const ::std::string& string_value() const; - void set_string_value(const ::std::string& value); - void set_string_value(const char* value); - void set_string_value(const char* value, size_t size); - ::std::string* mutable_string_value(); - ::std::string* release_string_value(); - void set_allocated_string_value(::std::string* string_value); - - // optional float float_value = 2; - bool has_float_value() const; - void clear_float_value(); - static const int kFloatValueFieldNumber = 2; - float float_value() const; - void set_float_value(float value); - - // optional double double_value = 3; - bool has_double_value() const; - void clear_double_value(); - static const int kDoubleValueFieldNumber = 3; - double double_value() const; - void set_double_value(double value); - - // optional int64 int_value = 4; - bool has_int_value() const; - void clear_int_value(); - static const int kIntValueFieldNumber = 4; - ::google::protobuf::int64 int_value() const; - void set_int_value(::google::protobuf::int64 value); - - // optional uint64 uint_value = 5; - bool has_uint_value() const; - void clear_uint_value(); - static const int kUintValueFieldNumber = 5; - ::google::protobuf::uint64 uint_value() const; - void set_uint_value(::google::protobuf::uint64 value); - - // optional sint64 sint_value = 6; - bool has_sint_value() const; - void clear_sint_value(); - static const int kSintValueFieldNumber = 6; - ::google::protobuf::int64 sint_value() const; - void set_sint_value(::google::protobuf::int64 value); - - // optional bool bool_value = 7; - bool has_bool_value() const; - void clear_bool_value(); - static const int kBoolValueFieldNumber = 7; - bool bool_value() const; - void set_bool_value(bool value); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(Tile_Value) - // @@protoc_insertion_point(class_scope:vector_tile.Tile.Value) - private: - inline void set_has_string_value(); - inline void clear_has_string_value(); - inline void set_has_float_value(); - inline void clear_has_float_value(); - inline void set_has_double_value(); - inline void clear_has_double_value(); - inline void set_has_int_value(); - inline void clear_has_int_value(); - inline void set_has_uint_value(); - inline void clear_has_uint_value(); - inline void set_has_sint_value(); - inline void clear_has_sint_value(); - inline void set_has_bool_value(); - inline void clear_has_bool_value(); - - ::google::protobuf::internal::ExtensionSet _extensions_; - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::uint32 _has_bits_[1]; - mutable int _cached_size_; - ::google::protobuf::internal::ArenaStringPtr string_value_; - double double_value_; - ::google::protobuf::int64 int_value_; - float float_value_; - bool bool_value_; - ::google::protobuf::uint64 uint_value_; - ::google::protobuf::int64 sint_value_; - friend void protobuf_AddDesc_vector_5ftile_2eproto(); - friend void protobuf_AssignDesc_vector_5ftile_2eproto(); - friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); - - void InitAsDefaultInstance(); - static Tile_Value* default_instance_; -}; -// ------------------------------------------------------------------- - -class Tile_Feature : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile.Feature) */ { - public: - Tile_Feature(); - virtual ~Tile_Feature(); - - Tile_Feature(const Tile_Feature& from); - - inline Tile_Feature& operator=(const Tile_Feature& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Tile_Feature& default_instance(); - - void Swap(Tile_Feature* other); - - // implements Message ---------------------------------------------- - - inline Tile_Feature* New() const { return New(NULL); } - - Tile_Feature* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Tile_Feature& from); - void MergeFrom(const Tile_Feature& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { - return InternalSerializeWithCachedSizesToArray(false, output); - } - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(Tile_Feature* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional uint64 id = 1 [default = 0]; - bool has_id() const; - void clear_id(); - static const int kIdFieldNumber = 1; - ::google::protobuf::uint64 id() const; - void set_id(::google::protobuf::uint64 value); - - // repeated uint32 tags = 2 [packed = true]; - int tags_size() const; - void clear_tags(); - static const int kTagsFieldNumber = 2; - ::google::protobuf::uint32 tags(int index) const; - void set_tags(int index, ::google::protobuf::uint32 value); - void add_tags(::google::protobuf::uint32 value); - const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& - tags() const; - ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* - mutable_tags(); - - // optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; - bool has_type() const; - void clear_type(); - static const int kTypeFieldNumber = 3; - ::vector_tile::Tile_GeomType type() const; - void set_type(::vector_tile::Tile_GeomType value); - - // repeated uint32 geometry = 4 [packed = true]; - int geometry_size() const; - void clear_geometry(); - static const int kGeometryFieldNumber = 4; - ::google::protobuf::uint32 geometry(int index) const; - void set_geometry(int index, ::google::protobuf::uint32 value); - void add_geometry(::google::protobuf::uint32 value); - const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& - geometry() const; - ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* - mutable_geometry(); - - // @@protoc_insertion_point(class_scope:vector_tile.Tile.Feature) - private: - inline void set_has_id(); - inline void clear_has_id(); - inline void set_has_type(); - inline void clear_has_type(); - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::uint32 _has_bits_[1]; - mutable int _cached_size_; - ::google::protobuf::uint64 id_; - ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > tags_; - mutable int _tags_cached_byte_size_; - ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > geometry_; - mutable int _geometry_cached_byte_size_; - int type_; - friend void protobuf_AddDesc_vector_5ftile_2eproto(); - friend void protobuf_AssignDesc_vector_5ftile_2eproto(); - friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); - - void InitAsDefaultInstance(); - static Tile_Feature* default_instance_; -}; -// ------------------------------------------------------------------- - -class Tile_Layer : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile.Layer) */ { - public: - Tile_Layer(); - virtual ~Tile_Layer(); - - Tile_Layer(const Tile_Layer& from); - - inline Tile_Layer& operator=(const Tile_Layer& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Tile_Layer& default_instance(); - - void Swap(Tile_Layer* other); - - // implements Message ---------------------------------------------- - - inline Tile_Layer* New() const { return New(NULL); } - - Tile_Layer* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Tile_Layer& from); - void MergeFrom(const Tile_Layer& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { - return InternalSerializeWithCachedSizesToArray(false, output); - } - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(Tile_Layer* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // required uint32 version = 15 [default = 1]; - bool has_version() const; - void clear_version(); - static const int kVersionFieldNumber = 15; - ::google::protobuf::uint32 version() const; - void set_version(::google::protobuf::uint32 value); - - // required string name = 1; - bool has_name() const; - void clear_name(); - static const int kNameFieldNumber = 1; - const ::std::string& name() const; - void set_name(const ::std::string& value); - void set_name(const char* value); - void set_name(const char* value, size_t size); - ::std::string* mutable_name(); - ::std::string* release_name(); - void set_allocated_name(::std::string* name); - - // repeated .vector_tile.Tile.Feature features = 2; - int features_size() const; - void clear_features(); - static const int kFeaturesFieldNumber = 2; - const ::vector_tile::Tile_Feature& features(int index) const; - ::vector_tile::Tile_Feature* mutable_features(int index); - ::vector_tile::Tile_Feature* add_features(); - ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >* - mutable_features(); - const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >& - features() const; - - // repeated string keys = 3; - int keys_size() const; - void clear_keys(); - static const int kKeysFieldNumber = 3; - const ::std::string& keys(int index) const; - ::std::string* mutable_keys(int index); - void set_keys(int index, const ::std::string& value); - void set_keys(int index, const char* value); - void set_keys(int index, const char* value, size_t size); - ::std::string* add_keys(); - void add_keys(const ::std::string& value); - void add_keys(const char* value); - void add_keys(const char* value, size_t size); - const ::google::protobuf::RepeatedPtrField< ::std::string>& keys() const; - ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_keys(); - - // repeated .vector_tile.Tile.Value values = 4; - int values_size() const; - void clear_values(); - static const int kValuesFieldNumber = 4; - const ::vector_tile::Tile_Value& values(int index) const; - ::vector_tile::Tile_Value* mutable_values(int index); - ::vector_tile::Tile_Value* add_values(); - ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >* - mutable_values(); - const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >& - values() const; - - // optional uint32 extent = 5 [default = 4096]; - bool has_extent() const; - void clear_extent(); - static const int kExtentFieldNumber = 5; - ::google::protobuf::uint32 extent() const; - void set_extent(::google::protobuf::uint32 value); - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(Tile_Layer) - // @@protoc_insertion_point(class_scope:vector_tile.Tile.Layer) - private: - inline void set_has_version(); - inline void clear_has_version(); - inline void set_has_name(); - inline void clear_has_name(); - inline void set_has_extent(); - inline void clear_has_extent(); - - // helper for ByteSize() - int RequiredFieldsByteSizeFallback() const; - - ::google::protobuf::internal::ExtensionSet _extensions_; - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::uint32 _has_bits_[1]; - mutable int _cached_size_; - ::google::protobuf::internal::ArenaStringPtr name_; - ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature > features_; - ::google::protobuf::uint32 version_; - ::google::protobuf::uint32 extent_; - ::google::protobuf::RepeatedPtrField< ::std::string> keys_; - ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value > values_; - friend void protobuf_AddDesc_vector_5ftile_2eproto(); - friend void protobuf_AssignDesc_vector_5ftile_2eproto(); - friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); - - void InitAsDefaultInstance(); - static Tile_Layer* default_instance_; -}; -// ------------------------------------------------------------------- - -class Tile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:vector_tile.Tile) */ { - public: - Tile(); - virtual ~Tile(); - - Tile(const Tile& from); - - inline Tile& operator=(const Tile& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const Tile& default_instance(); - - void Swap(Tile* other); - - // implements Message ---------------------------------------------- - - inline Tile* New() const { return New(NULL); } - - Tile* New(::google::protobuf::Arena* arena) const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const Tile& from); - void MergeFrom(const Tile& from); - void Clear(); - bool IsInitialized() const; - - int ByteSize() const; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { - return InternalSerializeWithCachedSizesToArray(false, output); - } - int GetCachedSize() const { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const; - void InternalSwap(Tile* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } - public: - - ::google::protobuf::Metadata GetMetadata() const; - - // nested types ---------------------------------------------------- - - typedef Tile_Value Value; - typedef Tile_Feature Feature; - typedef Tile_Layer Layer; - - typedef Tile_GeomType GeomType; - static const GeomType UNKNOWN = - Tile_GeomType_UNKNOWN; - static const GeomType POINT = - Tile_GeomType_POINT; - static const GeomType LINESTRING = - Tile_GeomType_LINESTRING; - static const GeomType POLYGON = - Tile_GeomType_POLYGON; - static inline bool GeomType_IsValid(int value) { - return Tile_GeomType_IsValid(value); - } - static const GeomType GeomType_MIN = - Tile_GeomType_GeomType_MIN; - static const GeomType GeomType_MAX = - Tile_GeomType_GeomType_MAX; - static const int GeomType_ARRAYSIZE = - Tile_GeomType_GeomType_ARRAYSIZE; - static inline const ::google::protobuf::EnumDescriptor* - GeomType_descriptor() { - return Tile_GeomType_descriptor(); - } - static inline const ::std::string& GeomType_Name(GeomType value) { - return Tile_GeomType_Name(value); - } - static inline bool GeomType_Parse(const ::std::string& name, - GeomType* value) { - return Tile_GeomType_Parse(name, value); - } - - // accessors ------------------------------------------------------- - - // repeated .vector_tile.Tile.Layer layers = 3; - int layers_size() const; - void clear_layers(); - static const int kLayersFieldNumber = 3; - const ::vector_tile::Tile_Layer& layers(int index) const; - ::vector_tile::Tile_Layer* mutable_layers(int index); - ::vector_tile::Tile_Layer* add_layers(); - ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >* - mutable_layers(); - const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >& - layers() const; - - GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(Tile) - // @@protoc_insertion_point(class_scope:vector_tile.Tile) - private: - - ::google::protobuf::internal::ExtensionSet _extensions_; - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::uint32 _has_bits_[1]; - mutable int _cached_size_; - ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer > layers_; - friend void protobuf_AddDesc_vector_5ftile_2eproto(); - friend void protobuf_AssignDesc_vector_5ftile_2eproto(); - friend void protobuf_ShutdownFile_vector_5ftile_2eproto(); - - void InitAsDefaultInstance(); - static Tile* default_instance_; -}; -// =================================================================== - - -// =================================================================== - -#if !PROTOBUF_INLINE_NOT_IN_HEADERS -// Tile_Value - -// optional string string_value = 1; -inline bool Tile_Value::has_string_value() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void Tile_Value::set_has_string_value() { - _has_bits_[0] |= 0x00000001u; -} -inline void Tile_Value::clear_has_string_value() { - _has_bits_[0] &= ~0x00000001u; -} -inline void Tile_Value::clear_string_value() { - string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_string_value(); -} -inline const ::std::string& Tile_Value::string_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.string_value) - return string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void Tile_Value::set_string_value(const ::std::string& value) { - set_has_string_value(); - string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.string_value) -} -inline void Tile_Value::set_string_value(const char* value) { - set_has_string_value(); - string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Value.string_value) -} -inline void Tile_Value::set_string_value(const char* value, size_t size) { - set_has_string_value(); - string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Value.string_value) -} -inline ::std::string* Tile_Value::mutable_string_value() { - set_has_string_value(); - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Value.string_value) - return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* Tile_Value::release_string_value() { - // @@protoc_insertion_point(field_release:vector_tile.Tile.Value.string_value) - clear_has_string_value(); - return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void Tile_Value::set_allocated_string_value(::std::string* string_value) { - if (string_value != NULL) { - set_has_string_value(); - } else { - clear_has_string_value(); - } - string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value); - // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Value.string_value) -} - -// optional float float_value = 2; -inline bool Tile_Value::has_float_value() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void Tile_Value::set_has_float_value() { - _has_bits_[0] |= 0x00000002u; -} -inline void Tile_Value::clear_has_float_value() { - _has_bits_[0] &= ~0x00000002u; -} -inline void Tile_Value::clear_float_value() { - float_value_ = 0; - clear_has_float_value(); -} -inline float Tile_Value::float_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.float_value) - return float_value_; -} -inline void Tile_Value::set_float_value(float value) { - set_has_float_value(); - float_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.float_value) -} - -// optional double double_value = 3; -inline bool Tile_Value::has_double_value() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void Tile_Value::set_has_double_value() { - _has_bits_[0] |= 0x00000004u; -} -inline void Tile_Value::clear_has_double_value() { - _has_bits_[0] &= ~0x00000004u; -} -inline void Tile_Value::clear_double_value() { - double_value_ = 0; - clear_has_double_value(); -} -inline double Tile_Value::double_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.double_value) - return double_value_; -} -inline void Tile_Value::set_double_value(double value) { - set_has_double_value(); - double_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.double_value) -} - -// optional int64 int_value = 4; -inline bool Tile_Value::has_int_value() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void Tile_Value::set_has_int_value() { - _has_bits_[0] |= 0x00000008u; -} -inline void Tile_Value::clear_has_int_value() { - _has_bits_[0] &= ~0x00000008u; -} -inline void Tile_Value::clear_int_value() { - int_value_ = GOOGLE_LONGLONG(0); - clear_has_int_value(); -} -inline ::google::protobuf::int64 Tile_Value::int_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.int_value) - return int_value_; -} -inline void Tile_Value::set_int_value(::google::protobuf::int64 value) { - set_has_int_value(); - int_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.int_value) -} - -// optional uint64 uint_value = 5; -inline bool Tile_Value::has_uint_value() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void Tile_Value::set_has_uint_value() { - _has_bits_[0] |= 0x00000010u; -} -inline void Tile_Value::clear_has_uint_value() { - _has_bits_[0] &= ~0x00000010u; -} -inline void Tile_Value::clear_uint_value() { - uint_value_ = GOOGLE_ULONGLONG(0); - clear_has_uint_value(); -} -inline ::google::protobuf::uint64 Tile_Value::uint_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.uint_value) - return uint_value_; -} -inline void Tile_Value::set_uint_value(::google::protobuf::uint64 value) { - set_has_uint_value(); - uint_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.uint_value) -} - -// optional sint64 sint_value = 6; -inline bool Tile_Value::has_sint_value() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void Tile_Value::set_has_sint_value() { - _has_bits_[0] |= 0x00000020u; -} -inline void Tile_Value::clear_has_sint_value() { - _has_bits_[0] &= ~0x00000020u; -} -inline void Tile_Value::clear_sint_value() { - sint_value_ = GOOGLE_LONGLONG(0); - clear_has_sint_value(); -} -inline ::google::protobuf::int64 Tile_Value::sint_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.sint_value) - return sint_value_; -} -inline void Tile_Value::set_sint_value(::google::protobuf::int64 value) { - set_has_sint_value(); - sint_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.sint_value) -} - -// optional bool bool_value = 7; -inline bool Tile_Value::has_bool_value() const { - return (_has_bits_[0] & 0x00000040u) != 0; -} -inline void Tile_Value::set_has_bool_value() { - _has_bits_[0] |= 0x00000040u; -} -inline void Tile_Value::clear_has_bool_value() { - _has_bits_[0] &= ~0x00000040u; -} -inline void Tile_Value::clear_bool_value() { - bool_value_ = false; - clear_has_bool_value(); -} -inline bool Tile_Value::bool_value() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Value.bool_value) - return bool_value_; -} -inline void Tile_Value::set_bool_value(bool value) { - set_has_bool_value(); - bool_value_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Value.bool_value) -} - -// ------------------------------------------------------------------- - -// Tile_Feature - -// optional uint64 id = 1 [default = 0]; -inline bool Tile_Feature::has_id() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void Tile_Feature::set_has_id() { - _has_bits_[0] |= 0x00000001u; -} -inline void Tile_Feature::clear_has_id() { - _has_bits_[0] &= ~0x00000001u; -} -inline void Tile_Feature::clear_id() { - id_ = GOOGLE_ULONGLONG(0); - clear_has_id(); -} -inline ::google::protobuf::uint64 Tile_Feature::id() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.id) - return id_; -} -inline void Tile_Feature::set_id(::google::protobuf::uint64 value) { - set_has_id(); - id_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.id) -} - -// repeated uint32 tags = 2 [packed = true]; -inline int Tile_Feature::tags_size() const { - return tags_.size(); -} -inline void Tile_Feature::clear_tags() { - tags_.Clear(); -} -inline ::google::protobuf::uint32 Tile_Feature::tags(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.tags) - return tags_.Get(index); -} -inline void Tile_Feature::set_tags(int index, ::google::protobuf::uint32 value) { - tags_.Set(index, value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.tags) -} -inline void Tile_Feature::add_tags(::google::protobuf::uint32 value) { - tags_.Add(value); - // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.tags) -} -inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& -Tile_Feature::tags() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.tags) - return tags_; -} -inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* -Tile_Feature::mutable_tags() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.tags) - return &tags_; -} - -// optional .vector_tile.Tile.GeomType type = 3 [default = UNKNOWN]; -inline bool Tile_Feature::has_type() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void Tile_Feature::set_has_type() { - _has_bits_[0] |= 0x00000004u; -} -inline void Tile_Feature::clear_has_type() { - _has_bits_[0] &= ~0x00000004u; -} -inline void Tile_Feature::clear_type() { - type_ = 0; - clear_has_type(); -} -inline ::vector_tile::Tile_GeomType Tile_Feature::type() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.type) - return static_cast< ::vector_tile::Tile_GeomType >(type_); -} -inline void Tile_Feature::set_type(::vector_tile::Tile_GeomType value) { - assert(::vector_tile::Tile_GeomType_IsValid(value)); - set_has_type(); - type_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.type) -} - -// repeated uint32 geometry = 4 [packed = true]; -inline int Tile_Feature::geometry_size() const { - return geometry_.size(); -} -inline void Tile_Feature::clear_geometry() { - geometry_.Clear(); -} -inline ::google::protobuf::uint32 Tile_Feature::geometry(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Feature.geometry) - return geometry_.Get(index); -} -inline void Tile_Feature::set_geometry(int index, ::google::protobuf::uint32 value) { - geometry_.Set(index, value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Feature.geometry) -} -inline void Tile_Feature::add_geometry(::google::protobuf::uint32 value) { - geometry_.Add(value); - // @@protoc_insertion_point(field_add:vector_tile.Tile.Feature.geometry) -} -inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& -Tile_Feature::geometry() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Feature.geometry) - return geometry_; -} -inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* -Tile_Feature::mutable_geometry() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Feature.geometry) - return &geometry_; -} - -// ------------------------------------------------------------------- - -// Tile_Layer - -// required uint32 version = 15 [default = 1]; -inline bool Tile_Layer::has_version() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void Tile_Layer::set_has_version() { - _has_bits_[0] |= 0x00000001u; -} -inline void Tile_Layer::clear_has_version() { - _has_bits_[0] &= ~0x00000001u; -} -inline void Tile_Layer::clear_version() { - version_ = 1u; - clear_has_version(); -} -inline ::google::protobuf::uint32 Tile_Layer::version() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.version) - return version_; -} -inline void Tile_Layer::set_version(::google::protobuf::uint32 value) { - set_has_version(); - version_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.version) -} - -// required string name = 1; -inline bool Tile_Layer::has_name() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void Tile_Layer::set_has_name() { - _has_bits_[0] |= 0x00000002u; -} -inline void Tile_Layer::clear_has_name() { - _has_bits_[0] &= ~0x00000002u; -} -inline void Tile_Layer::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_name(); -} -inline const ::std::string& Tile_Layer::name() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.name) - return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void Tile_Layer::set_name(const ::std::string& value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.name) -} -inline void Tile_Layer::set_name(const char* value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.name) -} -inline void Tile_Layer::set_name(const char* value, size_t size) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); - // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.name) -} -inline ::std::string* Tile_Layer::mutable_name() { - set_has_name(); - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* Tile_Layer::release_name() { - // @@protoc_insertion_point(field_release:vector_tile.Tile.Layer.name) - clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void Tile_Layer::set_allocated_name(::std::string* name) { - if (name != NULL) { - set_has_name(); - } else { - clear_has_name(); - } - name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); - // @@protoc_insertion_point(field_set_allocated:vector_tile.Tile.Layer.name) -} - -// repeated .vector_tile.Tile.Feature features = 2; -inline int Tile_Layer::features_size() const { - return features_.size(); -} -inline void Tile_Layer::clear_features() { - features_.Clear(); -} -inline const ::vector_tile::Tile_Feature& Tile_Layer::features(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.features) - return features_.Get(index); -} -inline ::vector_tile::Tile_Feature* Tile_Layer::mutable_features(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.features) - return features_.Mutable(index); -} -inline ::vector_tile::Tile_Feature* Tile_Layer::add_features() { - // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.features) - return features_.Add(); -} -inline ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >* -Tile_Layer::mutable_features() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.features) - return &features_; -} -inline const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Feature >& -Tile_Layer::features() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.features) - return features_; -} - -// repeated string keys = 3; -inline int Tile_Layer::keys_size() const { - return keys_.size(); -} -inline void Tile_Layer::clear_keys() { - keys_.Clear(); -} -inline const ::std::string& Tile_Layer::keys(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.keys) - return keys_.Get(index); -} -inline ::std::string* Tile_Layer::mutable_keys(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.keys) - return keys_.Mutable(index); -} -inline void Tile_Layer::set_keys(int index, const ::std::string& value) { - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.keys) - keys_.Mutable(index)->assign(value); -} -inline void Tile_Layer::set_keys(int index, const char* value) { - keys_.Mutable(index)->assign(value); - // @@protoc_insertion_point(field_set_char:vector_tile.Tile.Layer.keys) -} -inline void Tile_Layer::set_keys(int index, const char* value, size_t size) { - keys_.Mutable(index)->assign( - reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:vector_tile.Tile.Layer.keys) -} -inline ::std::string* Tile_Layer::add_keys() { - // @@protoc_insertion_point(field_add_mutable:vector_tile.Tile.Layer.keys) - return keys_.Add(); -} -inline void Tile_Layer::add_keys(const ::std::string& value) { - keys_.Add()->assign(value); - // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.keys) -} -inline void Tile_Layer::add_keys(const char* value) { - keys_.Add()->assign(value); - // @@protoc_insertion_point(field_add_char:vector_tile.Tile.Layer.keys) -} -inline void Tile_Layer::add_keys(const char* value, size_t size) { - keys_.Add()->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_add_pointer:vector_tile.Tile.Layer.keys) -} -inline const ::google::protobuf::RepeatedPtrField< ::std::string>& -Tile_Layer::keys() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.keys) - return keys_; -} -inline ::google::protobuf::RepeatedPtrField< ::std::string>* -Tile_Layer::mutable_keys() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.keys) - return &keys_; -} - -// repeated .vector_tile.Tile.Value values = 4; -inline int Tile_Layer::values_size() const { - return values_.size(); -} -inline void Tile_Layer::clear_values() { - values_.Clear(); -} -inline const ::vector_tile::Tile_Value& Tile_Layer::values(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.values) - return values_.Get(index); -} -inline ::vector_tile::Tile_Value* Tile_Layer::mutable_values(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.Layer.values) - return values_.Mutable(index); -} -inline ::vector_tile::Tile_Value* Tile_Layer::add_values() { - // @@protoc_insertion_point(field_add:vector_tile.Tile.Layer.values) - return values_.Add(); -} -inline ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >* -Tile_Layer::mutable_values() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.Layer.values) - return &values_; -} -inline const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Value >& -Tile_Layer::values() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.Layer.values) - return values_; -} - -// optional uint32 extent = 5 [default = 4096]; -inline bool Tile_Layer::has_extent() const { - return (_has_bits_[0] & 0x00000020u) != 0; -} -inline void Tile_Layer::set_has_extent() { - _has_bits_[0] |= 0x00000020u; -} -inline void Tile_Layer::clear_has_extent() { - _has_bits_[0] &= ~0x00000020u; -} -inline void Tile_Layer::clear_extent() { - extent_ = 4096u; - clear_has_extent(); -} -inline ::google::protobuf::uint32 Tile_Layer::extent() const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.Layer.extent) - return extent_; -} -inline void Tile_Layer::set_extent(::google::protobuf::uint32 value) { - set_has_extent(); - extent_ = value; - // @@protoc_insertion_point(field_set:vector_tile.Tile.Layer.extent) -} - -// ------------------------------------------------------------------- - -// Tile - -// repeated .vector_tile.Tile.Layer layers = 3; -inline int Tile::layers_size() const { - return layers_.size(); -} -inline void Tile::clear_layers() { - layers_.Clear(); -} -inline const ::vector_tile::Tile_Layer& Tile::layers(int index) const { - // @@protoc_insertion_point(field_get:vector_tile.Tile.layers) - return layers_.Get(index); -} -inline ::vector_tile::Tile_Layer* Tile::mutable_layers(int index) { - // @@protoc_insertion_point(field_mutable:vector_tile.Tile.layers) - return layers_.Mutable(index); -} -inline ::vector_tile::Tile_Layer* Tile::add_layers() { - // @@protoc_insertion_point(field_add:vector_tile.Tile.layers) - return layers_.Add(); -} -inline ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >* -Tile::mutable_layers() { - // @@protoc_insertion_point(field_mutable_list:vector_tile.Tile.layers) - return &layers_; -} -inline const ::google::protobuf::RepeatedPtrField< ::vector_tile::Tile_Layer >& -Tile::layers() const { - // @@protoc_insertion_point(field_list:vector_tile.Tile.layers) - return layers_; -} - -#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - - -// @@protoc_insertion_point(namespace_scope) - -} // namespace vector_tile - -#ifndef SWIG -namespace google { -namespace protobuf { - -template <> struct is_proto_enum< ::vector_tile::Tile_GeomType> : ::google::protobuf::internal::true_type {}; -template <> -inline const EnumDescriptor* GetEnumDescriptor< ::vector_tile::Tile_GeomType>() { - return ::vector_tile::Tile_GeomType_descriptor(); -} - -} // namespace protobuf -} // namespace google -#endif // SWIG - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_vector_5ftile_2eproto__INCLUDED diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ffcfff73da51..1fea1be7f24a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -18,8 +18,6 @@ SET(QGIS_CORE_SRCS ${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep.cc ${CMAKE_SOURCE_DIR}/external/meshOptimizer/simplifier.cpp - ${CMAKE_SOURCE_DIR}/external/mapbox-vector-tile/vector_tile.pb.cc - callouts/qgscallout.cpp callouts/qgscalloutsregistry.cpp @@ -680,11 +678,6 @@ IF (CMAKE_CXX_COMPILER_ID MATCHES "Clang") SET_SOURCE_FILES_PROPERTIES(qgsspatialindex.cpp PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual) ENDIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang") -IF (NOT MSVC) - # automatically generated file produces warnings (unused-parameter, unused-variable, misleading-indentation) - SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/external/mapbox-vector-tile/vector_tile.pb.cc PROPERTIES COMPILE_FLAGS -w) -ENDIF (NOT MSVC) - IF (QT_MOBILITY_LOCATION_FOUND OR Qt5Positioning_FOUND) SET(QGIS_CORE_SRCS ${QGIS_CORE_SRCS} gps/qgsqtlocationconnection.cpp @@ -1388,6 +1381,16 @@ IF(NOT MSVC) ENDIF () ENDIF(NOT MSVC) +# Generate cpp+header file from .proto file using "protoc" tool (to support MVT encoding of vector tiles) +protobuf_generate_cpp(VECTOR_TILE_PROTO_SRCS VECTOR_TILE_PROTO_HDRS vectortile/vector_tile.proto) +SET(QGIS_CORE_SRCS ${QGIS_CORE_SRCS} ${VECTOR_TILE_PROTO_SRCS}) +SET(QGIS_CORE_HDRS ${QGIS_CORE_HDRS} ${VECTOR_TILE_PROTO_HDRS}) +IF (NOT MSVC) + # automatically generated file produces warnings (unused-parameter, unused-variable, misleading-indentation) + SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} PROPERTIES COMPILE_FLAGS -w) +ENDIF (NOT MSVC) + + # install headers # install qgsconfig.h and plugin.h here so they can get into # the OS X framework target @@ -1593,7 +1596,7 @@ TARGET_LINK_LIBRARIES(qgis_core ${SQLITE3_LIBRARY} ${SPATIALITE_LIBRARY} ${LIBZIP_LIBRARY} - ${Protobuf_LIBRARIES} + ${Protobuf_LITE_LIBRARY} ${ZLIB_LIBRARIES} ) diff --git a/src/core/vectortile/vector_tile.proto b/src/core/vectortile/vector_tile.proto new file mode 100644 index 000000000000..f9aa8023d786 --- /dev/null +++ b/src/core/vectortile/vector_tile.proto @@ -0,0 +1,82 @@ +syntax = "proto2"; // needed by newer protoc compilers +// The rest of the file is a verbatim copy of MVT 2.1 proto file: +// https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto + +package vector_tile; + +option optimize_for = LITE_RUNTIME; + +message Tile { + + // GeomType is described in section 4.3.4 of the specification + enum GeomType { + UNKNOWN = 0; + POINT = 1; + LINESTRING = 2; + POLYGON = 3; + } + + // Variant type encoding + // The use of values is described in section 4.1 of the specification + message Value { + // Exactly one of these values must be present in a valid message + optional string string_value = 1; + optional float float_value = 2; + optional double double_value = 3; + optional int64 int_value = 4; + optional uint64 uint_value = 5; + optional sint64 sint_value = 6; + optional bool bool_value = 7; + + extensions 8 to max; + } + + // Features are described in section 4.2 of the specification + message Feature { + optional uint64 id = 1 [ default = 0 ]; + + // Tags of this feature are encoded as repeated pairs of + // integers. + // A detailed description of tags is located in sections + // 4.2 and 4.4 of the specification + repeated uint32 tags = 2 [ packed = true ]; + + // The type of geometry stored in this feature. + optional GeomType type = 3 [ default = UNKNOWN ]; + + // Contains a stream of commands and parameters (vertices). + // A detailed description on geometry encoding is located in + // section 4.3 of the specification. + repeated uint32 geometry = 4 [ packed = true ]; + } + + // Layers are described in section 4.1 of the specification + message Layer { + // Any compliant implementation must first read the version + // number encoded in this message and choose the correct + // implementation for this version number before proceeding to + // decode other parts of this message. + required uint32 version = 15 [ default = 1 ]; + + required string name = 1; + + // The actual features in this tile. + repeated Feature features = 2; + + // Dictionary encoding for keys + repeated string keys = 3; + + // Dictionary encoding for values + repeated Value values = 4; + + // Although this is an "optional" field it is required by the specification. + // See https://github.com/mapbox/vector-tile-spec/issues/47 + optional uint32 extent = 5 [ default = 4096 ]; + + extensions 16 to max; + } + + repeated Layer layers = 3; + + extensions 16 to 8191; +} From 7749e75beedd1c8f0d21e1a5ec780bd32e9eefa3 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Mon, 30 Mar 2020 23:46:44 +0200 Subject: [PATCH 20/27] Addressed review comments for Even --- .../vectortile/qgsvectortilemvtdecoder.cpp | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/core/vectortile/qgsvectortilemvtdecoder.cpp b/src/core/vectortile/qgsvectortilemvtdecoder.cpp index 912bb250ac3d..5e261c3df572 100644 --- a/src/core/vectortile/qgsvectortilemvtdecoder.cpp +++ b/src/core/vectortile/qgsvectortilemvtdecoder.cpp @@ -132,7 +132,7 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap( feature.tags( tagNum ) ); int fieldIndex = tagKeyIndexToFieldIndex.value( keyIndex, -1 ); @@ -140,6 +140,11 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap( feature.tags( tagNum + 1 ) ); + if ( valueIndex >= layer.values_size() ) + { + QgsDebugMsg( QStringLiteral( "Invalid value index for attribute" ) ); + continue; + } const ::vector_tile::Tile_Value &value = layer.values( valueIndex ); if ( value.has_string_value() ) @@ -155,11 +160,10 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap( value.sint_value() ) ); else if ( value.has_bool_value() ) - f.setAttribute( fieldIndex, static_cast( value.bool_value() ) ); // or keep it bool? (do we have good support for that?) + f.setAttribute( fieldIndex, static_cast( value.bool_value() ) ); else { - // TODO: report - should not happen - Q_ASSERT( false ); + QgsDebugMsg( QStringLiteral( "Unexpected attribute value" ) ); } } @@ -182,6 +186,11 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap> 3; if ( cmdId == 1 ) // MoveTo { + if ( i + static_cast( cmdCount ) * 2 >= feature.geometry_size() ) + { + QgsDebugMsg( QStringLiteral( "Malformed geometry: invalid cmdCount" ) ); + break; + } for ( unsigned j = 0; j < cmdCount; j++ ) { unsigned v = feature.geometry( i + 1 ); @@ -215,6 +224,11 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap( cmdCount ) * 2 >= feature.geometry_size() ) + { + QgsDebugMsg( QStringLiteral( "Malformed geometry: invalid cmdCount" ) ); + break; + } for ( unsigned j = 0; j < cmdCount; j++ ) { unsigned v = feature.geometry( i + 1 ); @@ -247,8 +261,14 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMapaddInteriorRing( new QgsLineString( tmpPoints ) ); + if ( outputPolygons.count() != 0 ) + { + outputPolygons[outputPolygons.count() - 1]->addInteriorRing( new QgsLineString( tmpPoints ) ); + } + else + { + QgsDebugMsg( QStringLiteral( "Malformed geometry: first ring of a polygon is interior ring" ) ); + } tmpPoints.clear(); } } From 2cfd69929539cb8642446e187d735ff833fface7 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Tue, 31 Mar 2020 09:11:44 +0200 Subject: [PATCH 21/27] Make sure that "protoc" tool is available It may be in a separate package, e.g. on Ubuntu there is protobuf-compiler --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a17a6503f1d..2c76dd89c3f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,6 +333,9 @@ IF(WITH_CORE) FIND_PACKAGE(Protobuf REQUIRED) # for decoding of vector tiles in MVT format MESSAGE(STATUS "Found Protobuf: ${Protobuf_LIBRARIES}") + IF (NOT Protobuf_PROTOC_EXECUTABLE) + MESSAGE (SEND_ERROR "Protobuf library's 'protoc' tool was not found!") + ENDIF () FIND_PACKAGE(ZLIB REQUIRED) # for decompression of vector tiles in MBTiles file MESSAGE(STATUS "Found zlib: ${ZLIB_LIBRARIES}") From a475af2432d523bfe52135c53edc236b374c550c Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Tue, 31 Mar 2020 10:17:53 +0200 Subject: [PATCH 22/27] Force protobuf package installation while it is not in qgis-dev-deps --- .ci/azure-pipelines/azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/azure-pipelines/azure-pipelines.yml b/.ci/azure-pipelines/azure-pipelines.yml index 78ee121ee649..b84c6ecd2368 100644 --- a/.ci/azure-pipelines/azure-pipelines.yml +++ b/.ci/azure-pipelines/azure-pipelines.yml @@ -143,7 +143,7 @@ jobs: # osgeo4w | $(OSGEO4W_ARCH) # displayName: Cache OSGeo4W - - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache + - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache -P protobuf displayName: 'Installing OSGeo4W' - script: | From c9f519ad731cc88efb365e26c157d2f93f6e8cd7 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Wed, 1 Apr 2020 23:30:39 +0200 Subject: [PATCH 23/27] =?UTF-8?q?Revert=20last=20commit:=20qgis-dev-deps?= =?UTF-8?q?=20now=20includes=20protobuf=20(thanks=20J=C3=BCrgen!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a475af2432d523bfe52135c53edc236b374c550c. --- .ci/azure-pipelines/azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/azure-pipelines/azure-pipelines.yml b/.ci/azure-pipelines/azure-pipelines.yml index b84c6ecd2368..78ee121ee649 100644 --- a/.ci/azure-pipelines/azure-pipelines.yml +++ b/.ci/azure-pipelines/azure-pipelines.yml @@ -143,7 +143,7 @@ jobs: # osgeo4w | $(OSGEO4W_ARCH) # displayName: Cache OSGeo4W - - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache -P protobuf + - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache displayName: 'Installing OSGeo4W' - script: | From 43415ee0c0d3af3ef255d50abe0c5216f96b024d Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Wed, 1 Apr 2020 23:59:37 +0200 Subject: [PATCH 24/27] Actually try to include protobuf-devel --- .ci/azure-pipelines/azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/azure-pipelines/azure-pipelines.yml b/.ci/azure-pipelines/azure-pipelines.yml index 78ee121ee649..0ae35aa34934 100644 --- a/.ci/azure-pipelines/azure-pipelines.yml +++ b/.ci/azure-pipelines/azure-pipelines.yml @@ -143,7 +143,7 @@ jobs: # osgeo4w | $(OSGEO4W_ARCH) # displayName: Cache OSGeo4W - - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache + - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache -P protobuf-devel displayName: 'Installing OSGeo4W' - script: | From 7e71b2347189221c403adb6dc25d72cf6ff9f94b Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 2 Apr 2020 09:20:15 +0200 Subject: [PATCH 25/27] Hopefully this fixes the win build --- src/core/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1fea1be7f24a..b2b207dd79f6 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1389,6 +1389,7 @@ IF (NOT MSVC) # automatically generated file produces warnings (unused-parameter, unused-variable, misleading-indentation) SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} PROPERTIES COMPILE_FLAGS -w) ENDIF (NOT MSVC) +ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS) # install headers From 1c4042bf4664057fde52200d476b02e569f3ae50 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 2 Apr 2020 12:23:17 +0200 Subject: [PATCH 26/27] More windows build fixes - remove protobuf-devel from explicit list - should be included in deps - only use the extra #define where needed - disable vector tile test on azure for now (can't debug it) --- .ci/azure-pipelines/azure-pipelines.yml | 4 ++-- src/core/CMakeLists.txt | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.ci/azure-pipelines/azure-pipelines.yml b/.ci/azure-pipelines/azure-pipelines.yml index 0ae35aa34934..4ea567b391e4 100644 --- a/.ci/azure-pipelines/azure-pipelines.yml +++ b/.ci/azure-pipelines/azure-pipelines.yml @@ -1,7 +1,7 @@ variables: LR: release-3_12 LTR: release-3_10 - CTEST_CUSTOM_TESTS_IGNORE: "ProcessingGdalAlgorithmsRasterTest;ProcessingGdalAlgorithmsVectorTest;ProcessingGrass7AlgorithmsImageryTest;ProcessingGrass7AlgorithmsRasterTest;ProcessingGrass7AlgorithmsVectorTest;ProcessingGuiTest;ProcessingOtbAlgorithmsTest;ProcessingQgisAlgorithmsTestPt1;ProcessingQgisAlgorithmsTestPt2;ProcessingQgisAlgorithmsTestPt3;ProcessingQgisAlgorithmsTestPt4;ProcessingScriptUtilsTest;PyQgsAnnotation;PyQgsAppStartup;PyQgsAuthManagerOAuth2OWSTest;PyQgsAuthManagerPasswordOWSTest;PyQgsAuthManagerPKIOWSTest;PyQgsAuthManagerProxy;PyQgsAuthSettingsWidget;PyQgsAuxiliaryStorage;PyQgsBlockingNetworkRequest;PyQgsExifTools;PyQgsFileDownloader;PyQgsFileUtils;PyQgsGeometryTest;PyQgsImageCache;PyQgsImportIntoPostGIS;PyQgsLayoutAtlas;PyQgsLayoutLegend;PyQgsLayoutMap;PyQgsLayoutMapGrid;PyQgsMapLayer;PyQgsOfflineEditingWFS;PyQgsOGRProvider;PyQgsOGRProviderGpkg;PyQgsOGRProviderSqlite;PyQgsPalLabelingCanvas;PyQgsPalLabelingLayout;PyQgsPalLabelingPlacement;PyQgsPointDisplacementRenderer;PyQgsProject;PyQgsProviderConnectionGpkg;PyQgsProviderConnectionPostgres;PyQgsPythonProvider;PyQgsRasterFileWriter;PyQgsRasterLayer;PyQgsSelectiveMasking;PyQgsServerAccessControlWMSGetlegendgraphic;PyQgsServerApi;PyQgsServerCacheManager;PyQgsServerLocaleOverride;PyQgsServerSecurity;PyQgsServerSettings;PyQgsServerWMS;PyQgsServerWMSDimension;PyQgsServerWMSGetFeatureInfo;PyQgsServerWMSGetLegendGraphic;PyQgsServerWMSGetMap;PyQgsServerWMSGetPrint;PyQgsServerWMTS;PyQgsSettings;PyQgsShapefileProvider;PyQgsSpatialiteProvider;PyQgsSvgCache;PyQgsSymbolLayer;PyQgsTaskManager;PyQgsTextRenderer;PyQgsVectorFileWriter;PyQgsVectorLayer;PyQgsVectorLayerUtils;PyQgsVirtualLayerProvider;PyQgsWFSProviderGUI;PyQgsZipUtils;qgis_3drenderingtest;qgis_alignrastertest;qgis_arcgisrestutilstest;qgis_banned_keywords;qgis_browsermodeltest;qgis_callouttest;qgis_compositionconvertertest;qgis_coordinatereferencesystemtest;qgis_datadefinedsizelegendtest;qgis_datumtransformdialog;qgis_diagramtest;qgis_doxygen_order;qgis_dxfexporttest;qgis_expressiontest;qgis_filedownloader;qgis_geometrycheckstest;qgis_geometrytest;qgis_geonodeconnectiontest;qgis_grassprovidertest7;qgis_imagecachetest;qgis_invertedpolygonrenderertest;qgis_labelingenginetest;qgis_layerdefinitiontest;qgis_layout3dmaptest;qgis_layouthtmltest;qgis_layoutlabeltest;qgis_layoutmapgridtest;qgis_layoutmaptest;qgis_layoutpicturetest;qgis_layoutscalebartest;qgis_layouttabletest;qgis_legendrenderertest;qgis_licenses;qgis_maprendererjobtest;qgis_maprotationtest;qgis_mapsettingsutilstest;qgis_maptooladdfeatureline;qgis_mimedatautilstest;qgis_networkaccessmanagertest;qgis_openclutilstest;qgis_painteffecttest;qgis_pallabelingtest;qgis_processingtest;qgis_projecttest;qgis_qgisappclipboard;qgis_rasterlayersaveasdialog;qgis_shellcheck;qgis_sipify;qgis_sip_include;qgis_sip_uptodate;qgis_spelling;qgis_styletest;qgis_svgcachetest;qgis_taskmanagertest;qgis_transformdialog;qgis_vectorfilewritertest;qgis_wcsprovidertest;qgis_ziplayertest;qgis_meshcalculator;qgis_pointlocatortest;PyQgsExpressionBuilderWidget;PyQgsDatumTransform;qgis_vertextool;PyQgsCoordinateOperationWidget;PyQgsProviderConnectionSpatialite;qgis_maptoolsplitpartstest" + CTEST_CUSTOM_TESTS_IGNORE: "ProcessingGdalAlgorithmsRasterTest;ProcessingGdalAlgorithmsVectorTest;ProcessingGrass7AlgorithmsImageryTest;ProcessingGrass7AlgorithmsRasterTest;ProcessingGrass7AlgorithmsVectorTest;ProcessingGuiTest;ProcessingOtbAlgorithmsTest;ProcessingQgisAlgorithmsTestPt1;ProcessingQgisAlgorithmsTestPt2;ProcessingQgisAlgorithmsTestPt3;ProcessingQgisAlgorithmsTestPt4;ProcessingScriptUtilsTest;PyQgsAnnotation;PyQgsAppStartup;PyQgsAuthManagerOAuth2OWSTest;PyQgsAuthManagerPasswordOWSTest;PyQgsAuthManagerPKIOWSTest;PyQgsAuthManagerProxy;PyQgsAuthSettingsWidget;PyQgsAuxiliaryStorage;PyQgsBlockingNetworkRequest;PyQgsExifTools;PyQgsFileDownloader;PyQgsFileUtils;PyQgsGeometryTest;PyQgsImageCache;PyQgsImportIntoPostGIS;PyQgsLayoutAtlas;PyQgsLayoutLegend;PyQgsLayoutMap;PyQgsLayoutMapGrid;PyQgsMapLayer;PyQgsOfflineEditingWFS;PyQgsOGRProvider;PyQgsOGRProviderGpkg;PyQgsOGRProviderSqlite;PyQgsPalLabelingCanvas;PyQgsPalLabelingLayout;PyQgsPalLabelingPlacement;PyQgsPointDisplacementRenderer;PyQgsProject;PyQgsProviderConnectionGpkg;PyQgsProviderConnectionPostgres;PyQgsPythonProvider;PyQgsRasterFileWriter;PyQgsRasterLayer;PyQgsSelectiveMasking;PyQgsServerAccessControlWMSGetlegendgraphic;PyQgsServerApi;PyQgsServerCacheManager;PyQgsServerLocaleOverride;PyQgsServerSecurity;PyQgsServerSettings;PyQgsServerWMS;PyQgsServerWMSDimension;PyQgsServerWMSGetFeatureInfo;PyQgsServerWMSGetLegendGraphic;PyQgsServerWMSGetMap;PyQgsServerWMSGetPrint;PyQgsServerWMTS;PyQgsSettings;PyQgsShapefileProvider;PyQgsSpatialiteProvider;PyQgsSvgCache;PyQgsSymbolLayer;PyQgsTaskManager;PyQgsTextRenderer;PyQgsVectorFileWriter;PyQgsVectorLayer;PyQgsVectorLayerUtils;PyQgsVirtualLayerProvider;PyQgsWFSProviderGUI;PyQgsZipUtils;qgis_3drenderingtest;qgis_alignrastertest;qgis_arcgisrestutilstest;qgis_banned_keywords;qgis_browsermodeltest;qgis_callouttest;qgis_compositionconvertertest;qgis_coordinatereferencesystemtest;qgis_datadefinedsizelegendtest;qgis_datumtransformdialog;qgis_diagramtest;qgis_doxygen_order;qgis_dxfexporttest;qgis_expressiontest;qgis_filedownloader;qgis_geometrycheckstest;qgis_geometrytest;qgis_geonodeconnectiontest;qgis_grassprovidertest7;qgis_imagecachetest;qgis_invertedpolygonrenderertest;qgis_labelingenginetest;qgis_layerdefinitiontest;qgis_layout3dmaptest;qgis_layouthtmltest;qgis_layoutlabeltest;qgis_layoutmapgridtest;qgis_layoutmaptest;qgis_layoutpicturetest;qgis_layoutscalebartest;qgis_layouttabletest;qgis_legendrenderertest;qgis_licenses;qgis_maprendererjobtest;qgis_maprotationtest;qgis_mapsettingsutilstest;qgis_maptooladdfeatureline;qgis_mimedatautilstest;qgis_networkaccessmanagertest;qgis_openclutilstest;qgis_painteffecttest;qgis_pallabelingtest;qgis_processingtest;qgis_projecttest;qgis_qgisappclipboard;qgis_rasterlayersaveasdialog;qgis_shellcheck;qgis_sipify;qgis_sip_include;qgis_sip_uptodate;qgis_spelling;qgis_styletest;qgis_svgcachetest;qgis_taskmanagertest;qgis_transformdialog;qgis_vectorfilewritertest;qgis_wcsprovidertest;qgis_ziplayertest;qgis_meshcalculator;qgis_pointlocatortest;PyQgsExpressionBuilderWidget;PyQgsDatumTransform;qgis_vertextool;PyQgsCoordinateOperationWidget;PyQgsProviderConnectionSpatialite;qgis_maptoolsplitpartstest;qgis_vectortilelayertest" Agent.Source.Git.ShallowFetchDepth: 120 trigger: @@ -143,7 +143,7 @@ jobs: # osgeo4w | $(OSGEO4W_ARCH) # displayName: Cache OSGeo4W - - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache -P protobuf-devel + - powershell: ms-windows/osgeo4w/runasadmin.ps1 c:\osgeo4w-setup.exe --autoaccept --advanced --arch $env:OSGEO4W_ARCH --quiet-mode --upgrade-also --root $env:OSGEO4W_ROOT --only-site -s http://ftp.osuosl.org/pub/osgeo/download/osgeo4w -l c:\temp\osgeo4w -P $env:OSGEO4W_DEPS -P python3-clcache displayName: 'Installing OSGeo4W' - script: | diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b2b207dd79f6..7dc56b686526 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1385,11 +1385,12 @@ ENDIF(NOT MSVC) protobuf_generate_cpp(VECTOR_TILE_PROTO_SRCS VECTOR_TILE_PROTO_HDRS vectortile/vector_tile.proto) SET(QGIS_CORE_SRCS ${QGIS_CORE_SRCS} ${VECTOR_TILE_PROTO_SRCS}) SET(QGIS_CORE_HDRS ${QGIS_CORE_HDRS} ${VECTOR_TILE_PROTO_HDRS}) -IF (NOT MSVC) +IF (MSVC) + SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} PROPERTIES COMPILE_DEFINITIONS PROTOBUF_USE_DLLS) +ELSE (MSVC) # automatically generated file produces warnings (unused-parameter, unused-variable, misleading-indentation) SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} PROPERTIES COMPILE_FLAGS -w) -ENDIF (NOT MSVC) -ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS) +ENDIF (MSVC) # install headers From 18bd8abbaa555b030b4b4647a51e5bcd74bbdd14 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 2 Apr 2020 13:07:32 +0200 Subject: [PATCH 27/27] Fix the fix on windows --- src/core/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7dc56b686526..eb2c98e50d2e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1386,7 +1386,7 @@ protobuf_generate_cpp(VECTOR_TILE_PROTO_SRCS VECTOR_TILE_PROTO_HDRS vectortile/v SET(QGIS_CORE_SRCS ${QGIS_CORE_SRCS} ${VECTOR_TILE_PROTO_SRCS}) SET(QGIS_CORE_HDRS ${QGIS_CORE_HDRS} ${VECTOR_TILE_PROTO_HDRS}) IF (MSVC) - SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} PROPERTIES COMPILE_DEFINITIONS PROTOBUF_USE_DLLS) + SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} vectortile/qgsvectortilemvtdecoder.cpp PROPERTIES COMPILE_DEFINITIONS PROTOBUF_USE_DLLS) ELSE (MSVC) # automatically generated file produces warnings (unused-parameter, unused-variable, misleading-indentation) SET_SOURCE_FILES_PROPERTIES(${VECTOR_TILE_PROTO_SRCS} PROPERTIES COMPILE_FLAGS -w)