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); } } }
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)... }; }
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); }
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; }