[core] Remove optional from Map::setLatLngBounds()

This is a first step into grouping together bounds related Map methods
into one that takes a "BoundOptions" object. LatLngBounds::unbounded()
replaces an undefined optional<LatLngBounds>.

v2: Document LatLngBounds::unbounded()
This commit is contained in:
Ander Conselvan de Oliveira
2019-03-08 15:53:25 +02:00
parent a73cc9d8e3
commit 11de777628
10 changed files with 56 additions and 42 deletions

View File

@@ -77,8 +77,8 @@ public:
LatLngBounds latLngBoundsForCamera(const CameraOptions&) const;
// Bounds
void setLatLngBounds(optional<LatLngBounds>);
optional<LatLngBounds> getLatLngBounds() const;
void setLatLngBounds(LatLngBounds);
LatLngBounds getLatLngBounds() const;
void setMinZoom(double);
double getMinZoom() const;
void setMaxZoom(double);

View File

@@ -105,6 +105,15 @@ public:
return bounds;
}
/// Returns an infinite bound, a bound for which the constrain method returns its
/// input unmodified.
///
/// Note: this is different than LatLngBounds::world() since arbitrary unwrapped
/// coordinates are also inside the bounds.
static LatLngBounds unbounded() {
return {};
}
// Constructs a LatLngBounds object with the tile's exact boundaries.
LatLngBounds(const CanonicalTileID&);
@@ -159,15 +168,19 @@ public:
private:
LatLng sw;
LatLng ne;
bool bounded = true;
LatLngBounds(LatLng sw_, LatLng ne_)
: sw(std::move(sw_)), ne(std::move(ne_)) {}
LatLngBounds()
: sw({-90, -180}), ne({90, 180}), bounded(false) {}
bool containsLatitude(double latitude) const;
bool containsLongitude(double longitude, LatLng::WrapMode wrap) const;
friend bool operator==(const LatLngBounds& a, const LatLngBounds& b) {
return a.sw == b.sw && a.ne == b.ne;
return (!a.bounded && !b.bounded) || (a.bounded && b.bounded && a.sw == b.sw && a.ne == b.ne);
}
friend bool operator!=(const LatLngBounds& a, const LatLngBounds& b) {

View File

@@ -288,7 +288,7 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
mbgl::LatLngBounds::hull(mbgl::LatLng { -45.0, -170.0 }, mbgl::LatLng { 45.0, 170.0 }), // inside
mbgl::LatLngBounds::hull(mbgl::LatLng { -45.0, -200.0 }, mbgl::LatLng { 45.0, -160.0 }), // left IDL
mbgl::LatLngBounds::hull(mbgl::LatLng { -45.0, 160.0 }, mbgl::LatLng { 45.0, 200.0 }), // right IDL
mbgl::LatLngBounds::world()
mbgl::LatLngBounds::unbounded()
};
static size_t nextBound = 0u;
static mbgl::AnnotationID boundAnnotationID = std::numeric_limits<mbgl::AnnotationID>::max();
@@ -296,29 +296,27 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
mbgl::LatLngBounds bound = bounds[nextBound++];
nextBound = nextBound % bounds.size();
if (bound == mbgl::LatLngBounds::world()) {
view->map->setLatLngBounds({});
view->map->setLatLngBounds(bound);
if (bound == mbgl::LatLngBounds::unbounded()) {
view->map->removeAnnotation(boundAnnotationID);
boundAnnotationID = std::numeric_limits<mbgl::AnnotationID>::max();
break;
} else {
view->map->setLatLngBounds(bound);
}
mbgl::Polygon<double> rect;
rect.push_back({
mbgl::Point<double>{ bound.west(), bound.north() },
mbgl::Point<double>{ bound.east(), bound.north() },
mbgl::Point<double>{ bound.east(), bound.south() },
mbgl::Point<double>{ bound.west(), bound.south() },
});
mbgl::Polygon<double> rect;
rect.push_back({
mbgl::Point<double>{ bound.west(), bound.north() },
mbgl::Point<double>{ bound.east(), bound.north() },
mbgl::Point<double>{ bound.east(), bound.south() },
mbgl::Point<double>{ bound.west(), bound.south() },
});
auto boundAnnotation = mbgl::FillAnnotation { rect, 0.5f, { view->makeRandomColor() }, { view->makeRandomColor() } };
auto boundAnnotation = mbgl::FillAnnotation { rect, 0.5f, { view->makeRandomColor() }, { view->makeRandomColor() } };
if (boundAnnotationID == std::numeric_limits<mbgl::AnnotationID>::max()) {
boundAnnotationID = view->map->addAnnotation(boundAnnotation);
} else {
view->map->updateAnnotation(boundAnnotationID, boundAnnotation);
if (boundAnnotationID == std::numeric_limits<mbgl::AnnotationID>::max()) {
boundAnnotationID = view->map->addAnnotation(boundAnnotation);
} else {
view->map->updateAnnotation(boundAnnotationID, boundAnnotation);
}
}
} break;
}

View File

@@ -275,13 +275,13 @@ LatLngBounds Map::latLngBoundsForCamera(const CameraOptions& camera) const {
#pragma mark - Bounds
optional<LatLngBounds> Map::getLatLngBounds() const {
LatLngBounds Map::getLatLngBounds() const {
return impl->transform.getState().getLatLngBounds();
}
void Map::setLatLngBounds(optional<LatLngBounds> bounds) {
void Map::setLatLngBounds(LatLngBounds bounds) {
impl->cameraMutated = true;
impl->transform.setLatLngBounds(bounds);
impl->transform.setLatLngBounds(std::move(bounds));
impl->onUpdate();
}

View File

@@ -85,7 +85,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
const EdgeInsets& padding = camera.padding;
LatLng startLatLng = getLatLng(padding, LatLng::Unwrapped);
const LatLng& unwrappedLatLng = camera.center.value_or(startLatLng);
const LatLng& latLng = state.bounds ? unwrappedLatLng : unwrappedLatLng.wrapped();
const LatLng& latLng = state.bounds != LatLngBounds::unbounded() ? unwrappedLatLng : unwrappedLatLng.wrapped();
double zoom = camera.zoom.value_or(getZoom());
double bearing = camera.bearing ? -*camera.bearing * util::DEG2RAD : getBearing();
double pitch = camera.pitch ? *camera.pitch * util::DEG2RAD : getPitch();
@@ -94,7 +94,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
return;
}
if (!state.bounds) {
if (state.bounds == LatLngBounds::unbounded()) {
if (isGestureInProgress()) {
// If gesture in progress, we transfer the wrap rounds from the end longitude into
// start, so the "scroll effect" of rounding the world is the same while assuring the
@@ -344,11 +344,11 @@ double Transform::getZoom() const {
#pragma mark - Bounds
void Transform::setLatLngBounds(optional<LatLngBounds> bounds) {
if (bounds && !bounds->valid()) {
void Transform::setLatLngBounds(LatLngBounds bounds) {
if (!bounds.valid()) {
throw std::runtime_error("failed to set bounds: bounds are invalid");
}
state.setLatLngBounds(bounds);
state.setLatLngBounds(std::move(bounds));
}
void Transform::setMinZoom(const double minZoom) {

View File

@@ -52,7 +52,7 @@ public:
// Bounds
void setLatLngBounds(optional<LatLngBounds>);
void setLatLngBounds(LatLngBounds);
void setMinZoom(double);
void setMaxZoom(double);

View File

@@ -9,7 +9,8 @@
namespace mbgl {
TransformState::TransformState(ConstrainMode constrainMode_, ViewportMode viewportMode_)
: constrainMode(constrainMode_)
: bounds(LatLngBounds::unbounded())
, constrainMode(constrainMode_)
, viewportMode(viewportMode_)
{
}
@@ -185,14 +186,14 @@ double TransformState::getZoomFraction() const {
#pragma mark - Bounds
void TransformState::setLatLngBounds(optional<LatLngBounds> bounds_) {
void TransformState::setLatLngBounds(LatLngBounds bounds_) {
if (bounds_ != bounds) {
bounds = bounds_;
setLatLngZoom(getLatLng(LatLng::Unwrapped), getZoom());
}
}
optional<LatLngBounds> TransformState::getLatLngBounds() const {
LatLngBounds TransformState::getLatLngBounds() const {
return bounds;
}
@@ -379,9 +380,7 @@ void TransformState::moveLatLng(const LatLng& latLng, const ScreenCoordinate& an
void TransformState::setLatLngZoom(const LatLng& latLng, double zoom) {
LatLng constrained = latLng;
if (bounds) {
constrained = bounds->constrain(latLng);
}
constrained = bounds.constrain(latLng);
double newScale = util::clamp(zoomScale(zoom), min_scale, max_scale);
const double newWorldSize = newScale * util::tileSize;

View File

@@ -55,8 +55,8 @@ public:
double getZoomFraction() const;
// Bounds
void setLatLngBounds(optional<LatLngBounds>);
optional<LatLngBounds> getLatLngBounds() const;
void setLatLngBounds(LatLngBounds);
LatLngBounds getLatLngBounds() const;
void setMinZoom(double);
double getMinZoom() const;
void setMaxZoom(double);
@@ -93,7 +93,7 @@ private:
bool rotatedNorth() const;
void constrain(double& scale, double& x, double& y) const;
optional<LatLngBounds> bounds;
LatLngBounds bounds;
// Limit the amount of zooming possible on the map.
double min_scale = std::pow(2, 0);

View File

@@ -92,6 +92,10 @@ bool LatLngBounds::intersects(const LatLngBounds area, LatLng::WrapMode wrap /*=
}
LatLng LatLngBounds::constrain(const LatLng& p) const {
if (!bounded) {
return p;
}
double lat = p.latitude();
double lng = p.longitude();

View File

@@ -583,7 +583,7 @@ TEST(Transform, LatLngBounds) {
transform.jumpTo(CameraOptions().withCenter(LatLng()).withZoom(transform.getState().getMaxZoom()));
// Default bounds.
ASSERT_EQ(transform.getState().getLatLngBounds(), optional<LatLngBounds> {});
ASSERT_EQ(transform.getState().getLatLngBounds(), LatLngBounds::unbounded());
ASSERT_EQ(transform.getLatLng(), nullIsland);
// Invalid bounds.
@@ -591,7 +591,7 @@ TEST(Transform, LatLngBounds) {
transform.setLatLngBounds(LatLngBounds::empty());
ASSERT_TRUE(false) << "Should throw";
} catch (...) {
ASSERT_EQ(transform.getState().getLatLngBounds(), optional<LatLngBounds> {});
ASSERT_EQ(transform.getState().getLatLngBounds(), LatLngBounds::unbounded());
}
transform.jumpTo(CameraOptions().withCenter(sanFrancisco));