Example #1
0
void TileWorker::parseLayer(const StyleLayer* layer, const GeometryTile& geometryTile) {
    // Cancel early when parsing.
    if (state == TileData::State::obsolete)
        return;

    // Background and custom layers are special cases.
    if (layer->is<BackgroundLayer>() || layer->is<CustomLayer>())
        return;

    // Skip this bucket if we are to not render this
    if ((layer->source != sourceID) ||
        (id.z < std::floor(layer->minZoom)) ||
        (id.z >= std::ceil(layer->maxZoom)) ||
        (layer->visibility == VisibilityType::None)) {
        return;
    }

    auto geometryLayer = geometryTile.getLayer(layer->sourceLayer);
    if (!geometryLayer) {
        // The layer specified in the bucket does not exist. Do nothing.
        if (debug::tileParseWarnings) {
            Log::Warning(Event::ParseTile, "layer '%s' does not exist in tile %d/%d/%d",
                    layer->sourceLayer.c_str(), id.z, id.x, id.y);
        }
        return;
    }

    StyleBucketParameters parameters(id,
                                     *geometryLayer,
                                     state,
                                     reinterpret_cast<uintptr_t>(this),
                                     partialParse,
                                     spriteStore,
                                     glyphAtlas,
                                     glyphStore,
                                     *collisionTile);

    std::unique_ptr<Bucket> bucket = layer->createBucket(parameters);

    if (layer->is<SymbolLayer>() && partialParse) {
        // We cannot parse this bucket yet. Instead, we're saving it for later.
        pending.emplace_back(layer->as<SymbolLayer>(), std::move(bucket));
    } else {
        insertBucket(layer->bucketName(), std::move(bucket));
    }
}
void FeatureIndex::addFeature(
    std::unordered_map<std::string, std::vector<Feature>>& result,
    const IndexedSubfeature& indexedFeature,
    const GeometryCollection& queryGeometry,
    const optional<std::vector<std::string>>& filterLayerIDs,
    const GeometryTile& geometryTile,
    const Style& style,
    const float bearing,
    const float pixelsToTileUnits) const {

    auto& layerIDs = bucketLayerIDs.at(indexedFeature.bucketName);

    if (filterLayerIDs && !vectorsIntersect(layerIDs, *filterLayerIDs)) return;

    auto sourceLayer = geometryTile.getLayer(indexedFeature.sourceLayerName);
    assert(sourceLayer);
    auto geometryTileFeature = sourceLayer->getFeature(indexedFeature.index);
    assert(geometryTileFeature);

    for (auto& layerID : layerIDs) {

        if (filterLayerIDs && !vectorContains(*filterLayerIDs, layerID)) continue;

        auto styleLayer = style.getLayer(layerID);
        if (!styleLayer) continue;

        if (!styleLayer->is<SymbolLayer>()) {
            auto geometries = getGeometries(*geometryTileFeature);
            if (!styleLayer->queryIntersectsGeometry(queryGeometry, geometries, bearing, pixelsToTileUnits)) continue;
        }

        Feature feature { mapbox::geometry::point<double>() };
        feature.properties = geometryTileFeature->getProperties();

        optional<uint64_t> id = geometryTileFeature->getID();
        if (id) {
            feature.id = Value(*id);
        }

        result[layerID].push_back(std::move(feature));
    }
}
void FeatureIndex::addFeature(
    std::unordered_map<std::string, std::vector<Feature>>& result,
    const IndexedSubfeature& indexedFeature,
    const GeometryCollection& queryGeometry,
    const optional<std::vector<std::string>>& filterLayerIDs,
    const GeometryTile& geometryTile,
    const CanonicalTileID& tileID,
    const style::Style& style,
    const float bearing,
    const float pixelsToTileUnits) const {

    auto& layerIDs = bucketLayerIDs.at(indexedFeature.bucketName);
    if (filterLayerIDs && !vectorsIntersect(layerIDs, *filterLayerIDs)) {
        return;
    }

    auto sourceLayer = geometryTile.getLayer(indexedFeature.sourceLayerName);
    assert(sourceLayer);

    auto geometryTileFeature = sourceLayer->getFeature(indexedFeature.index);
    assert(geometryTileFeature);

    for (const auto& layerID : layerIDs) {
        if (filterLayerIDs && !vectorContains(*filterLayerIDs, layerID)) {
            continue;
        }

        auto styleLayer = style.getLayer(layerID);
        if (!styleLayer ||
            (!styleLayer->is<style::SymbolLayer>() &&
             !styleLayer->baseImpl->queryIntersectsGeometry(queryGeometry, geometryTileFeature->getGeometries(), bearing, pixelsToTileUnits))) {
            continue;
        }

        result[layerID].push_back(convertFeature(*geometryTileFeature, tileID));
    }
}
Example #4
0
void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometryTile) {
    // Cancel early when parsing.
    if (state == TileData::State::obsolete)
        return;

    // Background is a special case.
    if (layer.isBackground())
        return;

    if (!layer.bucket) {
        Log::Warning(Event::ParseTile, "layer '%s' does not have buckets", layer.id.c_str());
        return;
    }

    // This is a singular layer. Check if this bucket already exists.
    if (getBucket(layer))
        return;

    const StyleBucket& styleBucket = *layer.bucket;

    // Skip this bucket if we are to not render this
    if (styleBucket.source != sourceID)
        return;
    if (id.z < std::floor(styleBucket.min_zoom) && std::floor(styleBucket.min_zoom) < maxZoom)
        return;
    if (id.z >= std::ceil(styleBucket.max_zoom))
        return;
    if (styleBucket.visibility == mbgl::VisibilityType::None)
        return;

    auto geometryLayer = geometryTile.getLayer(styleBucket.source_layer);
    if (!geometryLayer) {
        // The layer specified in the bucket does not exist. Do nothing.
        if (debug::tileParseWarnings) {
            Log::Warning(Event::ParseTile, "layer '%s' does not exist in tile %d/%d/%d",
                    styleBucket.source_layer.c_str(), id.z, id.x, id.y);
        }
        return;
    }

    std::unique_ptr<Bucket> bucket;

    if (styleBucket.type == StyleLayerType::Fill) {
        bucket = createFillBucket(*geometryLayer, styleBucket);
    } else if (styleBucket.type == StyleLayerType::Line) {
        bucket = createLineBucket(*geometryLayer, styleBucket);
    } else if (styleBucket.type == StyleLayerType::Symbol) {
        bucket = createSymbolBucket(*geometryLayer, styleBucket);
    } else if (styleBucket.type == StyleLayerType::Raster) {
        return;
    } else {
        Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')",
                styleBucket.name.c_str(), styleBucket.source_layer.c_str());
    }

    // Bucket creation might fail because the data tile may not
    // contain any data that falls into this bucket.
    if (!bucket)
        return;

    std::lock_guard<std::mutex> lock(bucketsMutex);
    buckets[styleBucket.name] = std::move(bucket);
}