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

Commit

Permalink
[core, ios, osx, android, glfw] Flipped origin of Map::latLngForPixel…
Browse files Browse the repository at this point in the history
…(), Map::pixelForLatLng()

Map and Transform methods assume an origin at the top-left corner of the view, like iOS, Android, and GLFW but unlike OS X.

Fixes #3574.
  • Loading branch information
1ec5 committed Jan 15, 2016
1 parent 8d94d76 commit 336a572
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2264,9 +2264,6 @@ public LatLng fromScreenLocation(@NonNull PointF point) {
float x = point.x;
float y = point.y;

// flip y direction vertically to match core GL
y = getHeight() - y;

return mNativeMapView.latLngForPixel(new PointF(x / mScreenDensity, y / mScreenDensity));
}

Expand All @@ -2289,9 +2286,6 @@ public PointF toScreenLocation(@NonNull LatLng location) {
float x = point.x * mScreenDensity;
float y = point.y * mScreenDensity;

// flip y direction vertically to match core GL
y = getHeight() - y;

return new PointF(x, y);
}

Expand Down
13 changes: 6 additions & 7 deletions platform/default/glfw_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
}

mbgl::LatLng GLFWView::makeRandomPoint() const {
const auto sw = map->latLngForPixel({ 0, 0 });
const auto ne = map->latLngForPixel({ double(width), double(height) });
const auto nw = map->latLngForPixel({ 0, 0 });
const auto se = map->latLngForPixel({ double(width), double(height) });

const double lon = sw.longitude + (ne.longitude - sw.longitude) * (double(std::rand()) / RAND_MAX);
const double lat = sw.latitude + (ne.latitude - sw.latitude) * (double(std::rand()) / RAND_MAX);
const double lon = nw.longitude + (se.longitude - nw.longitude) * (double(std::rand()) / RAND_MAX);
const double lat = se.latitude + (nw.latitude - se.latitude) * (double(std::rand()) / RAND_MAX);

return { lat, lon };
}
Expand Down Expand Up @@ -368,10 +368,9 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
double dx = x - view->lastX;
double dy = y - view->lastY;
if (dx || dy) {
double flippedY = view->height - y;
view->map->setLatLng(
view->map->latLngForPixel(mbgl::PrecisionPoint(x - dx, flippedY + dy)),
mbgl::PrecisionPoint(x, flippedY));
view->map->latLngForPixel(mbgl::PrecisionPoint(x - dx, y + dy)),
mbgl::PrecisionPoint(x, y));
}
} else if (view->rotating) {
view->map->rotateBy({ view->lastX, view->lastY }, { x, y });
Expand Down
27 changes: 3 additions & 24 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ @interface MGLMapView () <UIGestureRecognizerDelegate,
@property (nonatomic) UIView<MGLCalloutView> *calloutViewForSelectedAnnotation;
@property (nonatomic) MGLUserLocationAnnotationView *userLocationAnnotationView;
@property (nonatomic) CLLocationManager *locationManager;
@property (nonatomic) CGPoint centerPoint;
@property (nonatomic) CGFloat scale;
@property (nonatomic) CGFloat angle;
@property (nonatomic) CGFloat quickZoomStart;
Expand Down Expand Up @@ -961,27 +960,15 @@ - (void)handlePanGesture:(UIPanGestureRecognizer *)pan
{
[self trackGestureEvent:MGLEventGesturePanStart forRecognizer:pan];

self.centerPoint = CGPointMake(0, 0);

self.userTrackingMode = MGLUserTrackingModeNone;

[self notifyGestureDidBegin];
}
else if (pan.state == UIGestureRecognizerStateChanged)
{
CGPoint delta = CGPointMake([pan translationInView:pan.view].x - self.centerPoint.x,
[pan translationInView:pan.view].y - self.centerPoint.y);

double flippedY = self.bounds.size.height - [pan locationInView:pan.view].y;
_mbglMap->setLatLng(
_mbglMap->latLngForPixel(mbgl::PrecisionPoint(
[pan locationInView:pan.view].x - delta.x,
flippedY + delta.y)),
mbgl::PrecisionPoint(
[pan locationInView:pan.view].x,
flippedY));

self.centerPoint = CGPointMake(self.centerPoint.x + delta.x, self.centerPoint.y + delta.y);
CGPoint delta = [pan translationInView:pan.view];
_mbglMap->moveBy({ delta.x, delta.y });
[pan setTranslation:CGPointZero inView:pan.view];

[self notifyMapChange:mbgl::MapChangeRegionIsChanging];
}
Expand Down Expand Up @@ -1948,10 +1935,6 @@ - (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(null
- (mbgl::LatLng)convertPoint:(CGPoint)point toLatLngFromView:(nullable UIView *)view
{
CGPoint convertedPoint = [self convertPoint:point fromView:view];

// Flip y coordinate for iOS view origin in the top left corner.
convertedPoint.y = self.bounds.size.height - convertedPoint.y;

return _mbglMap->latLngForPixel(mbgl::PrecisionPoint(convertedPoint.x, convertedPoint.y));
}

Expand All @@ -1964,10 +1947,6 @@ - (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(n
- (CGPoint)convertLatLng:(mbgl::LatLng)latLng toPointToView:(nullable UIView *)view
{
mbgl::vec2<double> pixel = _mbglMap->pixelForLatLng(latLng);

// Flip y coordinate for iOS view origin in the top left corner.
pixel.y = self.bounds.size.height - pixel.y;

return [self convertPoint:CGPointMake(pixel.x, pixel.y) toView:view];
}

Expand Down
8 changes: 7 additions & 1 deletion platform/osx/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,8 @@ - (NSPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(n
/// Converts a geographic coordinate to a point in the view’s coordinate system.
- (NSPoint)convertLatLng:(mbgl::LatLng)latLng toPointToView:(nullable NSView *)view {
mbgl::vec2<double> pixel = _mbglMap->pixelForLatLng(latLng);
// Cocoa origin is at the lower-left corner.
pixel.y = NSHeight(self.bounds) - pixel.y;
return [self convertPoint:NSMakePoint(pixel.x, pixel.y) toView:view];
}

Expand All @@ -2143,7 +2145,11 @@ - (CLLocationCoordinate2D)convertPoint:(NSPoint)point toCoordinateFromView:(null
/// Converts a point in the view’s coordinate system to a geographic coordinate.
- (mbgl::LatLng)convertPoint:(NSPoint)point toLatLngFromView:(nullable NSView *)view {
NSPoint convertedPoint = [self convertPoint:point fromView:view];
return _mbglMap->latLngForPixel(mbgl::PrecisionPoint(convertedPoint.x, convertedPoint.y));
return _mbglMap->latLngForPixel({
convertedPoint.x,
// mbgl origin is at the top-left corner.
NSHeight(self.bounds) - convertedPoint.y,
});
}

- (NSRect)convertCoordinateBounds:(MGLCoordinateBounds)bounds toRectToView:(nullable NSView *)view {
Expand Down
16 changes: 12 additions & 4 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,13 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, const Ed
// Calculate the bounds of the possibly rotated shape with respect to the viewport.
PrecisionPoint nePixel = {-INFINITY, -INFINITY};
PrecisionPoint swPixel = {INFINITY, INFINITY};
double viewportHeight = getHeight();
for (LatLng latLng : latLngs) {
PrecisionPoint pixel = pixelForLatLng(latLng);
swPixel.x = std::min(swPixel.x, pixel.x);
nePixel.x = std::max(nePixel.x, pixel.x);
swPixel.y = std::min(swPixel.y, pixel.y);
nePixel.y = std::max(nePixel.y, pixel.y);
swPixel.y = std::min(swPixel.y, viewportHeight - pixel.y);
nePixel.y = std::max(nePixel.y, viewportHeight - pixel.y);
}
double width = nePixel.x - swPixel.x;
double height = nePixel.y - swPixel.y;
Expand All @@ -289,6 +290,9 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, const Ed
(paddedNEPixel.x + paddedSWPixel.x) / 2,
(paddedNEPixel.y + paddedSWPixel.y) / 2,
};

// CameraOptions origin is at the top-left corner.
centerPixel.y = viewportHeight - centerPixel.y;

options.center = latLngForPixel(centerPixel);
options.zoom = zoom;
Expand Down Expand Up @@ -397,11 +401,15 @@ LatLng Map::latLngForProjectedMeters(const ProjectedMeters& projectedMeters) con
}

PrecisionPoint Map::pixelForLatLng(const LatLng& latLng) const {
return transform->getState().latLngToPoint(latLng);
PrecisionPoint point = transform->getState().latLngToPoint(latLng);
point.y = getHeight() - point.y;
return point;
}

LatLng Map::latLngForPixel(const PrecisionPoint& pixel) const {
return transform->getState().pointToLatLng(pixel);
PrecisionPoint flippedPoint = pixel;
flippedPoint.y = getHeight() - flippedPoint.y;
return transform->getState().pointToLatLng(flippedPoint);
}

#pragma mark - Annotations
Expand Down

0 comments on commit 336a572

Please sign in to comment.