Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] AddedMap::{set,get}LatLngBounds #8583

Merged
merged 4 commits into from
Apr 11, 2017
Merged

Conversation

brunoabinader
Copy link
Member

Implements a setter and getter for coordinate bounds in Map API - which can be used e.g. to limit the boundaries in which the user can set geographical coordinates.

Related: #3602.

@brunoabinader brunoabinader added Core The cross-platform C++ core, aka mbgl feature GL JS parity For feature parity with Mapbox GL JS labels Mar 30, 2017
@brunoabinader brunoabinader self-assigned this Mar 30, 2017
@brunoabinader brunoabinader mentioned this pull request Mar 30, 2017
Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the most part, this PR looks reasonable, but I have some concerns about the antimeridian edge case (the gift that keeps on giving). I’d also defer to someone on the Android side to speak to whether this addresses the Android SDK’s needs.

#3602 (comment) called for a setMinTilt() and setMaxTilt(), which would imply a setMinPitch() and setMaxPitch() in mbgl::Map. Would that fall within the scope of this PR?

std::swap(bounds.sw, bounds.ne);
return bounds;
}

// Constructs a LatLngBounds object with the tile's exact boundaries.
LatLngBounds(const CanonicalTileID&);

explicit operator bool() const {
return (sw.latitude <= ne.latitude) && (sw.longitude <= ne.longitude);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be consistent with the GeoJSON specification, but inconsistent with GeoJSONVT’s behavior of allowing a single feature or annotation to span the antimeridian (#6088), correct? If one were to calculate the bounding box of an annotation, would this operator end up evaluating to false? Would it still be possible to fit the bounds to the annotation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of LatLngBounds::extend is that it preserves the assertion above. Also, this should be fine as long as the coordinates used are unwrapped.

Nonetheless, we can add a unit test to verify 👍

@brunoabinader
Copy link
Member Author

I have some concerns about the antimeridian edge case (the gift that keeps on giving)

Do you have one in particular? From my tests, this shouldn't be an issue as every coordinate passed to the map gets unwrapped e.g. here.

@brunoabinader
Copy link
Member Author

#3602 (comment) called for a setMinTilt() and setMaxTilt(), which would imply a setMinPitch() and setMaxPitch() in mbgl::Map. Would that fall within the scope of this PR?

Yep, we can certainly add it too 😃

@1ec5
Copy link
Contributor

1ec5 commented Mar 30, 2017

I have some concerns about the antimeridian edge case (the gift that keeps on giving)

Do you have one in particular? From my tests, this shouldn't be an issue as every coordinate passed to the map gets unwrapped e.g. here.

I was referring to #8583 (comment). But as long as you’ve considered this possibility, 👍.

LatLng(double lat = 0, double lon = 0, WrapMode mode = Unwrapped)
constexpr LatLng(null) : latitude(std::numeric_limits<double>::quiet_NaN()), longitude(latitude) {}

constexpr LatLng(double lat, double lon, WrapMode mode = Unwrapped)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By making LatLngBounds::world() constexpr here, LatLngBounds needed a constexpr ctor, which required its members (LatLng for southwest and northeast bounds) to also have a constexpr ctor. We useLatLngBounds::world() to initialize the default TransformState bounds here.

if (std::isnan(minZoom)) return;
state.setMinZoom(minZoom);
}

void Transform::setMaxZoom(const double maxZoom) {
void Transform::setMaxZoom(double maxZoom) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove const? I generally don't add it in the headers, but do add it in the implementation files to avoid modifying the parameter. Those definitions are compatible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you mentioned, there is no point in adding this to headers. Also, const-pass-by-value is not a common behavior in our codebase.

For me, it is clear that a non-const pass-by-value is a different object from the one it has been copied from i.e. declaring it const does not guarantee that the original object remains immutable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, what I meant to say is that I'm doing this as a convention to avoid accidental changes to the parameter that might get read later on in the function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack - let's add them back on the definition file 👍


ScreenCoordinate point = {
-latLng.longitude * Bc,
-constrained.longitude * Bc,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reasoning for this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's where we constrain the received LatLng to the specified bounds. I preferred this to be done when inserting because I suppose we set LatLng values much less than we request them from TransformState.

@tobrun tobrun mentioned this pull request Apr 3, 2017
@tobrun
Copy link
Member

tobrun commented Apr 3, 2017

Been testing out and adding binding integration in #8622,
thank you for picking this up @brunoabinader.

@brunoabinader
Copy link
Member Author

Removed the constexpr-related changes and added {set,get}{Min,Max}Pitch.

}
return LatLng {
p.latitude < sw.latitude ? sw.latitude : p.latitude > ne.latitude ? ne.latitude : p.latitude,
p.longitude < sw.longitude ? sw.longitude : p.longitude > ne.longitude ? ne.longitude : p.longitude,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parentheses to clarify operator precedence would make the code mode readable

@brunoabinader
Copy link
Member Author

@kkaefer can you please re-review?

@brunoabinader brunoabinader merged commit c4fc899 into master Apr 11, 2017
@brunoabinader brunoabinader deleted the map-latlngbounds branch April 11, 2017 09:51
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl feature GL JS parity For feature parity with Mapbox GL JS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants