From db2e1b2e5fccd74ef8344ff70f04ea4e00b48d6b Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 13 Nov 2018 20:42:48 +0200 Subject: [core] Add RendererState::{pixelForLatLng,latLngForPixel} --- include/mbgl/renderer/renderer_state.hpp | 14 ++++++++++---- platform/default/mbgl/gl/headless_frontend.cpp | 15 +++++++++++++++ platform/default/mbgl/gl/headless_frontend.hpp | 3 +++ src/mbgl/renderer/renderer_state.cpp | 23 +++++++++++++++++++---- test/map/map.test.cpp | 10 ++++++++++ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/include/mbgl/renderer/renderer_state.hpp b/include/mbgl/renderer/renderer_state.hpp index 27985ae996..71011389ec 100644 --- a/include/mbgl/renderer/renderer_state.hpp +++ b/include/mbgl/renderer/renderer_state.hpp @@ -15,16 +15,22 @@ class RendererState { public: // Obtains a CameraOptions out of a given UpdateParameters object. - static CameraOptions getCameraOptions(UpdateParameters&, const EdgeInsets& = {}); + static CameraOptions getCameraOptions(const UpdateParameters&, const EdgeInsets& = {}); // Returns whether an image with the given ID exists from a given UpdateParamters object. - static bool hasImage(UpdateParameters&, const std::string& id); + static bool hasImage(const UpdateParameters&, const std::string& id); // Returns whether a layer with the given ID exists from a given UpdateParamters object. - static bool hasLayer(UpdateParameters&, const std::string& id); + static bool hasLayer(const UpdateParameters&, const std::string& id); // Returns whether a source with the given ID exists from a given UpdateParamters object. - static bool hasSource(UpdateParameters&, const std::string& id); + static bool hasSource(const UpdateParameters&, const std::string& id); + + // Obtains the geographical coordinate out of a given screen coordinate. + static ScreenCoordinate pixelForLatLng(const UpdateParameters&, const LatLng&); + + // Obtains the screen coordinate out of a given geographical coordinate. + static LatLng latLngForPixel(const UpdateParameters&, const ScreenCoordinate&); }; } // namespace mbgl diff --git a/platform/default/mbgl/gl/headless_frontend.cpp b/platform/default/mbgl/gl/headless_frontend.cpp index 30def38f71..37b0f91f32 100644 --- a/platform/default/mbgl/gl/headless_frontend.cpp +++ b/platform/default/mbgl/gl/headless_frontend.cpp @@ -87,6 +87,21 @@ bool HeadlessFrontend::hasSource(const std::string& id) { return false; } +ScreenCoordinate HeadlessFrontend::pixelForLatLng(const LatLng& coordinate) { + if (updateParameters) { + return RendererState::pixelForLatLng(*updateParameters, coordinate); + } + + return ScreenCoordinate {}; +} + +LatLng HeadlessFrontend::latLngForPixel(const ScreenCoordinate& point) { + if (updateParameters) { + return RendererState::latLngForPixel(*updateParameters, point); + } + + return LatLng {}; +} void HeadlessFrontend::setSize(Size size_) { if (size != size_) { diff --git a/platform/default/mbgl/gl/headless_frontend.hpp b/platform/default/mbgl/gl/headless_frontend.hpp index 45586033b0..18f0cfa537 100644 --- a/platform/default/mbgl/gl/headless_frontend.hpp +++ b/platform/default/mbgl/gl/headless_frontend.hpp @@ -39,6 +39,9 @@ public: bool hasLayer(const std::string&); bool hasSource(const std::string&); + ScreenCoordinate pixelForLatLng(const LatLng&); + LatLng latLngForPixel(const ScreenCoordinate&); + PremultipliedImage readStillImage(); PremultipliedImage render(Map&); diff --git a/src/mbgl/renderer/renderer_state.cpp b/src/mbgl/renderer/renderer_state.cpp index a024f37dfc..33f6eb27dd 100644 --- a/src/mbgl/renderer/renderer_state.cpp +++ b/src/mbgl/renderer/renderer_state.cpp @@ -7,11 +7,11 @@ namespace mbgl { -CameraOptions RendererState::getCameraOptions(UpdateParameters& updateParameters, const EdgeInsets& padding) { +CameraOptions RendererState::getCameraOptions(const UpdateParameters& updateParameters, const EdgeInsets& padding) { return updateParameters.transformState.getCameraOptions(padding); } -bool RendererState::hasImage(UpdateParameters& updateParameters, const std::string& id) { +bool RendererState::hasImage(const UpdateParameters& updateParameters, const std::string& id) { for (const auto& image : *updateParameters.images) { if (image.get()->id == id) { return true; @@ -20,7 +20,7 @@ bool RendererState::hasImage(UpdateParameters& updateParameters, const std::stri return false; } -bool RendererState::hasLayer(UpdateParameters& updateParameters, const std::string& id) { +bool RendererState::hasLayer(const UpdateParameters& updateParameters, const std::string& id) { for (const auto& layer : *updateParameters.layers) { if (layer.get()->id == id) { return true; @@ -29,7 +29,7 @@ bool RendererState::hasLayer(UpdateParameters& updateParameters, const std::stri return false; } -bool RendererState::hasSource(UpdateParameters& updateParameters, const std::string& id) { +bool RendererState::hasSource(const UpdateParameters& updateParameters, const std::string& id) { for (const auto& source : *updateParameters.sources) { if (source.get()->id == id) { return true; @@ -38,5 +38,20 @@ bool RendererState::hasSource(UpdateParameters& updateParameters, const std::str return false; } +ScreenCoordinate RendererState::pixelForLatLng(const UpdateParameters& updateParameters, const LatLng& latLng) { + // If the center and point longitudes are not in the same side of the + // antimeridian, we unwrap the point longitude so it would be seen if + // e.g. the next antimeridian side is visible. + LatLng unwrappedLatLng = latLng.wrapped(); + unwrappedLatLng.unwrapForShortestPath(updateParameters.transformState.getLatLng()); + const ScreenCoordinate point = updateParameters.transformState.latLngToScreenCoordinate(latLng); + return ScreenCoordinate { point.x, updateParameters.transformState.size.height - point.y }; +} + +LatLng RendererState::latLngForPixel(const UpdateParameters& updateParameters, const ScreenCoordinate& point) { + ScreenCoordinate flippedPoint = point; + flippedPoint.y = updateParameters.transformState.size.height - flippedPoint.y; + return updateParameters.transformState.screenCoordinateToLatLng(flippedPoint); +} } // namespace mbgl diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index c57fe28ae5..690df6b3e9 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -79,6 +79,16 @@ TEST(Map, RendererState) { ASSERT_DOUBLE_EQ(*options.pitch, pitchInDegrees); EXPECT_NEAR(*options.angle, bearingInDegrees, 1e-7); + { + const LatLng& latLng = test.frontend.latLngForPixel(ScreenCoordinate { 0, 0 }); + const ScreenCoordinate& point = test.frontend.pixelForLatLng(coordinate); + EXPECT_NEAR(coordinate.latitude(), latLng.latitude(), 1e-1); + EXPECT_NEAR(coordinate.longitude(), latLng.longitude(), 1e-1); + const Size size = test.map.getSize(); + EXPECT_NEAR(point.x, size.width / 2.0, 1e-7); + EXPECT_NEAR(point.y, size.height / 2.0, 1e-7); + } + // RendererState::hasImage test.map.getStyle().addImage(std::make_unique("default_marker", decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0)); -- cgit v1.2.1