#include #include #include #include namespace mbgl { // Implements a simple in-memory Tile type that holds GeoJSON values. A GeoJSON tile can only have // one layer, and it is always returned regardless of which layer is requested. class GeoJSONTileFeature : public GeometryTileFeature { public: GeoJSONTileFeature(FeatureType, GeometryCollection&&, PropertyMap&&); FeatureType getType() const override; optional getValue(const std::string&) const override; PropertyMap getProperties() const override { return properties; } GeometryCollection getGeometries() const override; private: const FeatureType type; const GeometryCollection geometries; const PropertyMap properties; }; class GeoJSONTileLayer : public GeometryTileLayer { public: using Features = std::vector>; GeoJSONTileLayer(Features&&); std::size_t featureCount() const override; util::ptr getFeature(std::size_t) const override; std::string getName() const override { return ""; }; private: const Features features; }; class GeoJSONTileData : public GeometryTileData { public: GeoJSONTileData(std::shared_ptr); util::ptr getLayer(const std::string&) const override; private: const std::shared_ptr layer; }; // Converts the geojsonvt::Tile to a a GeoJSONTile. They have a differing internal structure. std::unique_ptr convertTile(const mapbox::geojsonvt::Tile& tile) { std::shared_ptr layer; if (!tile.features.empty()) { std::vector> features; GeometryCoordinates line; ToFeatureType toFeatureType; ToGeometryCollection toGeometryCollection; for (auto& feature : tile.features) { const FeatureType featureType = apply_visitor(toFeatureType, feature.geometry); if (featureType == FeatureType::Unknown) { continue; } GeometryCollection geometry = apply_visitor(toGeometryCollection, feature.geometry); // https://github.com/mapbox/geojson-vt-cpp/issues/44 if (featureType == FeatureType::Polygon) { geometry = fixupPolygons(geometry); } PropertyMap properties = feature.properties; features.emplace_back(std::make_shared( featureType, std::move(geometry), std::move(properties))); } layer = std::make_unique(std::move(features)); } return std::make_unique(layer); } GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID, std::string sourceID_, const style::UpdateParameters& parameters, mapbox::geojsonvt::GeoJSONVT& geojsonvt) : GeometryTile(overscaledTileID, sourceID_, parameters.style, parameters.mode) { setData(convertTile(geojsonvt.getTile(id.canonical.z, id.canonical.x, id.canonical.y))); } void GeoJSONTile::setNecessity(Necessity) {} GeoJSONTileFeature::GeoJSONTileFeature(FeatureType type_, GeometryCollection&& geometries_, PropertyMap&& properties_) : type(type_), geometries(std::move(geometries_)), properties(std::move(properties_)) { } FeatureType GeoJSONTileFeature::getType() const { return type; } optional GeoJSONTileFeature::getValue(const std::string& key) const { auto it = properties.find(key); if (it != properties.end()) { return optional(it->second); } return optional(); } GeometryCollection GeoJSONTileFeature::getGeometries() const { return geometries; } GeoJSONTileLayer::GeoJSONTileLayer(Features&& features_) : features(std::move(features_)) { } std::size_t GeoJSONTileLayer::featureCount() const { return features.size(); } util::ptr GeoJSONTileLayer::getFeature(std::size_t i) const { return features[i]; } GeoJSONTileData::GeoJSONTileData(std::shared_ptr layer_) : layer(std::move(layer_)) { } util::ptr GeoJSONTileData::getLayer(const std::string&) const { // We're ignoring the layer name because GeoJSON tiles only have one layer. return layer; } } // namespace mbgl