Reusable point fromScreenLocation (#6652)
* Fixed bug where fromScreenLocation would modify the actual Point being passed in * [android] - move reused point to Projection class, migrated screen density logic to projection fixup code to be unit testable
This commit is contained in:
@@ -132,6 +132,8 @@ public class MapView extends FrameLayout {
|
||||
private MyLocationView myLocationView;
|
||||
private LocationListener myLocationListener;
|
||||
|
||||
private Projection projection;
|
||||
|
||||
private CopyOnWriteArrayList<OnMapChangedListener> onMapChangedListener;
|
||||
private ZoomButtonsController zoomButtonsController;
|
||||
private ConnectivityReceiver connectivityReceiver;
|
||||
@@ -196,6 +198,8 @@ public class MapView extends FrameLayout {
|
||||
onMapReadyCallbackList = new ArrayList<>();
|
||||
onMapChangedListener = new CopyOnWriteArrayList<>();
|
||||
mapboxMap = new MapboxMap(this);
|
||||
projection = mapboxMap.getProjection();
|
||||
|
||||
icons = new ArrayList<>();
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
|
||||
setWillNotDraw(false);
|
||||
@@ -977,21 +981,24 @@ public class MapView extends FrameLayout {
|
||||
// Projection
|
||||
//
|
||||
|
||||
LatLng fromScreenLocation(@NonNull PointF point) {
|
||||
/*
|
||||
* Internal use only, use Projection#fromScreenLocation instead
|
||||
*/
|
||||
LatLng fromNativeScreenLocation(@NonNull PointF point) {
|
||||
if (destroyed) {
|
||||
return new LatLng();
|
||||
}
|
||||
point.set(point.x / screenDensity, point.y / screenDensity);
|
||||
return nativeMapView.latLngForPixel(point);
|
||||
}
|
||||
|
||||
PointF toScreenLocation(@NonNull LatLng location) {
|
||||
/*
|
||||
* Internal use only, use Projection#toScreenLocation instead.
|
||||
*/
|
||||
PointF toNativeScreenLocation(@NonNull LatLng location) {
|
||||
if (destroyed || location == null) {
|
||||
return new PointF();
|
||||
}
|
||||
PointF pointF = nativeMapView.pixelForLatLng(location);
|
||||
pointF.set(pointF.x * screenDensity, pointF.y * screenDensity);
|
||||
return pointF;
|
||||
return nativeMapView.pixelForLatLng(location);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1640,7 +1647,7 @@ public class MapView extends FrameLayout {
|
||||
* @param yCoordinate Original y screen cooridnate at start of gesture
|
||||
*/
|
||||
private void trackGestureEvent(@NonNull String gestureId, @NonNull float xCoordinate, @NonNull float yCoordinate) {
|
||||
LatLng tapLatLng = fromScreenLocation(new PointF(xCoordinate, yCoordinate));
|
||||
LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
|
||||
|
||||
// NaN and Infinite checks to prevent JSON errors at send to server time
|
||||
if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
|
||||
@@ -1672,7 +1679,7 @@ public class MapView extends FrameLayout {
|
||||
* @param yCoordinate Orginal y screen coordinate at end of drag
|
||||
*/
|
||||
private void trackGestureDragEndEvent(@NonNull float xCoordinate, @NonNull float yCoordinate) {
|
||||
LatLng tapLatLng = fromScreenLocation(new PointF(xCoordinate, yCoordinate));
|
||||
LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
|
||||
|
||||
// NaN and Infinite checks to prevent JSON errors at send to server time
|
||||
if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
|
||||
@@ -1889,7 +1896,7 @@ public class MapView extends FrameLayout {
|
||||
// notify app of map click
|
||||
MapboxMap.OnMapClickListener listener = mapboxMap.getOnMapClickListener();
|
||||
if (listener != null) {
|
||||
LatLng point = fromScreenLocation(tapPoint);
|
||||
LatLng point = projection.fromScreenLocation(tapPoint);
|
||||
listener.onMapClick(point);
|
||||
}
|
||||
}
|
||||
@@ -1903,7 +1910,7 @@ public class MapView extends FrameLayout {
|
||||
public void onLongPress(MotionEvent motionEvent) {
|
||||
MapboxMap.OnMapLongClickListener listener = mapboxMap.getOnMapLongClickListener();
|
||||
if (listener != null && !quickZoom) {
|
||||
LatLng point = fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()));
|
||||
LatLng point = projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()));
|
||||
listener.onMapLongClick(point);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,15 @@ import com.mapbox.mapboxsdk.geometry.VisibleRegion;
|
||||
*/
|
||||
public class Projection {
|
||||
|
||||
private MapView mapView;
|
||||
private final MapView mapView;
|
||||
private final float screenDensity;
|
||||
private final PointF screenLocationPoint;
|
||||
|
||||
Projection(@NonNull MapView mapView) {
|
||||
this.mapView = mapView;
|
||||
this.screenLocationPoint = new PointF();
|
||||
this.screenDensity = mapView.getContext() != null ? /* return default if unit test */
|
||||
mapView.getContext().getResources().getDisplayMetrics().density : 1.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +50,8 @@ public class Projection {
|
||||
* the given screen point does not intersect the ground plane.
|
||||
*/
|
||||
public LatLng fromScreenLocation(PointF point) {
|
||||
return mapView.fromScreenLocation(point);
|
||||
screenLocationPoint.set(point.x / screenDensity, point.y / screenDensity);
|
||||
return mapView.fromNativeScreenLocation(screenLocationPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +90,9 @@ public class Projection {
|
||||
* @return A Point representing the screen location in screen pixels.
|
||||
*/
|
||||
public PointF toScreenLocation(LatLng location) {
|
||||
return mapView.toScreenLocation(location);
|
||||
PointF pointF = mapView.toNativeScreenLocation(location);
|
||||
pointF.set(pointF.x * screenDensity, pointF.y * screenDensity);
|
||||
return pointF;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user