#include #include #include #include #include #include #include #include namespace mbgl { namespace style { class GeoJSONVTData : public GeoJSONData { public: GeoJSONVTData(const GeoJSON& geoJSON, const mapbox::geojsonvt::Options& options) : impl(geoJSON, options) { } mapbox::feature::feature_collection getTile(const CanonicalTileID& tileID) final { return impl.getTile(tileID.z, tileID.x, tileID.y).features; } mapbox::feature::feature_collection getChildren(const std::uint32_t) final { return {}; } mapbox::feature::feature_collection getLeaves(const std::uint32_t, const std::uint32_t, const std::uint32_t) final { return {}; } std::uint8_t getClusterExpansionZoom(std::uint32_t) final { return 0; } private: mapbox::geojsonvt::GeoJSONVT impl; }; class SuperclusterData : public GeoJSONData { public: SuperclusterData(const mapbox::feature::feature_collection& features, const mapbox::supercluster::Options& options) : impl(features, options) { } mapbox::feature::feature_collection getTile(const CanonicalTileID& tileID) final { return impl.getTile(tileID.z, tileID.x, tileID.y); } mapbox::feature::feature_collection getChildren(const std::uint32_t cluster_id) final { return impl.getChildren(cluster_id); } mapbox::feature::feature_collection getLeaves(const std::uint32_t cluster_id, const std::uint32_t limit, const std::uint32_t offset) final { return impl.getLeaves(cluster_id, limit, offset); } std::uint8_t getClusterExpansionZoom(std::uint32_t cluster_id) final { return impl.getClusterExpansionZoom(cluster_id); } private: mapbox::supercluster::Supercluster impl; }; template T evaluateFeature(const mapbox::feature::feature& f, const std::shared_ptr& expression, optional accumulated = nullopt) { const expression::EvaluationResult result = expression->evaluate(accumulated, f); if (result) { optional typed = expression::fromExpressionValue(*result); if (typed) { return std::move(*typed); } } return T(); } GeoJSONSource::Impl::Impl(std::string id_, optional options_) : Source::Impl(SourceType::GeoJSON, std::move(id_)) { options = options_ ? std::move(*options_) : GeoJSONOptions{}; } GeoJSONSource::Impl::Impl(const Impl& other, const GeoJSON& geoJSON) : Source::Impl(other), options(other.options) { constexpr double scale = util::EXTENT / util::tileSize; if (options.cluster && geoJSON.is>() && !geoJSON.get>().empty()) { mapbox::supercluster::Options clusterOptions; clusterOptions.maxZoom = options.clusterMaxZoom; clusterOptions.extent = util::EXTENT; clusterOptions.radius = ::round(scale * options.clusterRadius); Feature feature; clusterOptions.map = [&](const PropertyMap& properties) -> PropertyMap { PropertyMap ret{}; if (properties.empty()) return ret; for (const auto& p : options.clusterProperties) { feature.properties = properties; ret[p.first] = evaluateFeature(feature, p.second.first); } return ret; }; clusterOptions.reduce = [&](PropertyMap& toReturn, const PropertyMap& toFill) { for (const auto& p : options.clusterProperties) { if (toFill.count(p.first) == 0) { continue; } feature.properties = toFill; optional accumulated(toReturn[p.first]); toReturn[p.first] = evaluateFeature(feature, p.second.second, accumulated); } }; data = std::make_shared( geoJSON.get>(), clusterOptions); } else { mapbox::geojsonvt::Options vtOptions; vtOptions.maxZoom = options.maxzoom; vtOptions.extent = util::EXTENT; vtOptions.buffer = ::round(scale * options.buffer); vtOptions.tolerance = scale * options.tolerance; vtOptions.lineMetrics = options.lineMetrics; data = std::make_shared(geoJSON, vtOptions); } } GeoJSONSource::Impl::~Impl() = default; Range GeoJSONSource::Impl::getZoomRange() const { return { options.minzoom, options.maxzoom }; } std::weak_ptr GeoJSONSource::Impl::getData() const { return data; } optional GeoJSONSource::Impl::getAttribution() const { return {}; } } // namespace style } // namespace mbgl