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:
Tobrun
2016-10-17 14:51:39 +02:00
committed by GitHub
parent d22d8a6c9b
commit 1bee9d34f5
2 changed files with 28 additions and 13 deletions

View File

@@ -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);
}
}

View File

@@ -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;
}
/**