void reprojectLineLabels(gfx::VertexVector<gfx::Vertex<SymbolDynamicLayoutAttributes>>& dynamicVertexArray, const std::vector<PlacedSymbol>& placedSymbols,
			const mat4& posMatrix, bool pitchWithMap, bool rotateWithMap, bool keepUpright,
            const RenderTile& tile, const SymbolSizeBinder& sizeBinder, const TransformState& state) {

        const ZoomEvaluatedSize partiallyEvaluatedSize = sizeBinder.evaluateForZoom(state.getZoom());

        const std::array<double, 2> clippingBuffer = {{ 256.0 / state.getSize().width * 2.0 + 1.0, 256.0 / state.getSize().height * 2.0 + 1.0 }};

        const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1, state.getZoom());

        const mat4 labelPlaneMatrix = getLabelPlaneMatrix(posMatrix, pitchWithMap,
                rotateWithMap, state, pixelsToTileUnits);
        
        const mat4 glCoordMatrix = getGlCoordMatrix(posMatrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits);
        
        dynamicVertexArray.clear();
        
        bool useVertical = false;

        for (auto& placedSymbol : placedSymbols) {
            // Don't do calculations for vertical glyphs unless the previous symbol was horizontal
            // and we determined that vertical glyphs were necessary.
            // Also don't do calculations for symbols that are collided and fully faded out
            if (placedSymbol.hidden || (placedSymbol.writingModes == WritingModeType::Vertical && !useVertical)) {
                hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray);
                continue;
            }
            // Awkward... but we're counting on the paired "vertical" symbol coming immediately after its horizontal counterpart
            useVertical = false;
            
			vec4 anchorPos = {{ placedSymbol.anchorPoint.x, placedSymbol.anchorPoint.y, 0, 1 }};
            matrix::transformMat4(anchorPos, anchorPos, posMatrix);

            // Don't bother calculating the correct point for invisible labels.
            if (!isVisible(anchorPos, clippingBuffer)) {
                hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray);
                continue;
            }

            const float cameraToAnchorDistance = anchorPos[3];
            const float perspectiveRatio = 0.5 + 0.5 * (cameraToAnchorDistance / state.getCameraToCenterDistance());

            const float fontSize = evaluateSizeForFeature(partiallyEvaluatedSize, placedSymbol);
            const float pitchScaledFontSize = pitchWithMap ?
                fontSize * perspectiveRatio :
                fontSize / perspectiveRatio;
            
            const Point<float> anchorPoint = project(placedSymbol.anchorPoint, labelPlaneMatrix).first;

            PlacementResult placeUnflipped = placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, false /*unflipped*/, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray, anchorPoint, state.getSize().aspectRatio());
            
            useVertical = placeUnflipped == PlacementResult::UseVertical;

            if (placeUnflipped == PlacementResult::NotEnoughRoom || useVertical ||
                (placeUnflipped == PlacementResult::NeedsFlipping &&
                 placeGlyphsAlongLine(placedSymbol, pitchScaledFontSize, true /*flipped*/, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, dynamicVertexArray, anchorPoint, state.getSize().aspectRatio()) == PlacementResult::NotEnoughRoom)) {
                hideGlyphs(placedSymbol.glyphOffsets.size(), dynamicVertexArray);
            }
        }
    }
Example #2
0
mat4 RenderTile::translatedMatrix(const std::array<float, 2>& translation,
                                  TranslateAnchorType anchor,
                                  const TransformState& state) const {
    if (translation[0] == 0 && translation[1] == 0) {
        return matrix;
    }

    mat4 vtxMatrix;

    if (anchor == TranslateAnchorType::Viewport) {
        const double sin_a = std::sin(-state.getAngle());
        const double cos_a = std::cos(-state.getAngle());
        matrix::translate(vtxMatrix, matrix,
                id.pixelsToTileUnits(translation[0] * cos_a - translation[1] * sin_a, state.getZoom()),
                id.pixelsToTileUnits(translation[0] * sin_a + translation[1] * cos_a, state.getZoom()),
                0);
    } else {
        matrix::translate(vtxMatrix, matrix,
                id.pixelsToTileUnits(translation[0], state.getZoom()),
                id.pixelsToTileUnits(translation[1], state.getZoom()),
                0);
    }

    return vtxMatrix;
}
mat4 RenderTile::translateVtxMatrix(const mat4& tileMatrix,
                                    const std::array<float, 2>& translation,
                                    TranslateAnchorType anchor,
                                    const TransformState& state,
                                    const bool inViewportPixelUnits) const {
    if (translation[0] == 0 && translation[1] == 0) {
        return tileMatrix;
    }

    mat4 vtxMatrix;

    const float angle = inViewportPixelUnits ?
        (anchor == TranslateAnchorType::Map ? state.getAngle() : 0) :
        (anchor == TranslateAnchorType::Viewport ? -state.getAngle() : 0);

    Point<float> translate = util::rotate(Point<float>{ translation[0], translation[1] }, angle);

    if (inViewportPixelUnits) {
        matrix::translate(vtxMatrix, tileMatrix, translate.x, translate.y, 0);
    } else {
        matrix::translate(vtxMatrix, tileMatrix,
                          id.pixelsToTileUnits(translate.x, state.getZoom()),
                          id.pixelsToTileUnits(translate.y, state.getZoom()),
                          0);
    }

    return vtxMatrix;
}
void GeometryTile::queryRenderedFeatures(
    std::unordered_map<std::string, std::vector<Feature>>& result,
    const GeometryCoordinates& queryGeometry,
    const TransformState& transformState,
    const std::vector<const RenderLayer*>& layers,
    const RenderedQueryOptions& options,
    const mat4& projMatrix) {

    if (!getData()) return;

    const float queryPadding = getQueryPadding(layers);

    mat4 posMatrix;
    transformState.matrixFor(posMatrix, id.toUnwrapped());
    matrix::multiply(posMatrix, projMatrix, posMatrix);

    latestFeatureIndex->query(result,
                              queryGeometry,
                              transformState,
                              posMatrix,
                              util::tileSize * id.overscaleFactor(),
                              std::pow(2, transformState.getZoom() - id.overscaledZ),
                              options,
                              id.toUnwrapped(),
                              layers,
                              queryPadding * transformState.maxPitchScaleFactor());
}
void CustomLayer::render(const TransformState& state) const {
    assert(renderFn);

    CustomLayerRenderParameters parameters;

    parameters.width = state.getWidth();
    parameters.height = state.getHeight();
    parameters.latitude = state.getLatLng().latitude;
    parameters.longitude = state.getLatLng().longitude;
    parameters.zoom = state.getZoom();
    parameters.bearing = -state.getAngle() * util::RAD2DEG;
    parameters.pitch = state.getPitch();
    parameters.altitude = state.getAltitude();

    renderFn(context, parameters);
}
Values makeValues(const RenderLinePaintProperties::PossiblyEvaluated& properties,
                  const RenderTile& tile,
                  const TransformState& state,
                  const std::array<float, 2>& pixelsToGLUnits,
                  Args&&... args) {

    return Values {
        uniforms::u_matrix::Value{
            tile.translatedMatrix(properties.get<LineTranslate>(),
                                  properties.get<LineTranslateAnchor>(),
                                  state)
        },
        uniforms::u_ratio::Value{ 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) },
        uniforms::u_gl_units_to_pixels::Value{{{ 1.0f / pixelsToGLUnits[0], 1.0f / pixelsToGLUnits[1] }}},
        std::forward<Args>(args)...
    };
}
Example #7
0
void GeometryTile::queryRenderedFeatures(
    std::unordered_map<std::string, std::vector<Feature>>& result,
    const GeometryCoordinates& queryGeometry,
    const TransformState& transformState,
    const optional<std::vector<std::string>>& layerIDs) {

    if (!featureIndex || !data) return;

    featureIndex->query(result,
                        queryGeometry,
                        transformState.getAngle(),
                        util::tileSize * id.overscaleFactor(),
                        std::pow(2, transformState.getZoom() - id.overscaledZ),
                        layerIDs,
                        *data,
                        id.canonical,
                        style);
}
Example #8
0
double Source::getZoom(const TransformState& state) const {
    double offset = std::log(util::tileSize / info.tile_size) / std::log(2);
    offset += (state.getPixelRatio() > 1.0 ? 1 :0);
    return state.getZoom() + offset;
}