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

move calculation of LatLngBounds to core #8765

Merged
merged 1 commit into from
Apr 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
* Expose source layer identifier [#8709](https://github.com/mapbox/mapbox-gl-native/pull/8709).
* Ensure surface is created after display and context [#8759](https://github.com/mapbox/mapbox-gl-native/pull/8759)
* Harden telemetry event dispatch [#8767](https://github.com/mapbox/mapbox-gl-native/pull/8767)
* Move LatLngBounds calculation for CameraUpdateFactory to core [#8765](https://github.com/mapbox/mapbox-gl-native/pull/8765)

## 5.0.2 - April 3, 2017

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,24 +231,6 @@ public Builder(CameraUpdateFactory.ZoomUpdate update) {
}
}

/**
* Create Builder from an existing array of doubles.
* <p>
* These values conform to map.ccp representation of a camera position.
* </p>
*
* @param nativeCameraValues Values containing target, bearing, tilt and zoom
*/
public Builder(double[] nativeCameraValues) {
super();
if (nativeCameraValues != null && nativeCameraValues.length == 5) {
target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]).wrap());
bearing(MathUtils.convertNativeBearing(nativeCameraValues[2]));
tilt(nativeCameraValues[3]);
zoom(nativeCameraValues[4]);
}
}

/**
* Sets the direction that the camera is pointing in, in degrees clockwise from north.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.RectF;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;

Expand All @@ -11,7 +10,6 @@
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;
import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.services.android.telemetry.utils.MathUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand Down Expand Up @@ -199,17 +197,13 @@ public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
static final class CameraBoundsUpdate implements CameraUpdate {

private LatLngBounds bounds;
private RectF padding;
private int[] padding;

CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
this.bounds = bounds;
this.padding = padding;
}

CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
}

CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
this(bounds, new int[] {paddingLeft, paddingTop, paddingRight, paddingBottom});
}
Expand All @@ -218,64 +212,13 @@ public LatLngBounds getBounds() {
return bounds;
}

public RectF getPadding() {
public int[] getPadding() {
return padding;
}

@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
// Get required objects
Projection projection = mapboxMap.getProjection();
UiSettings uiSettings = mapboxMap.getUiSettings();

// calculate correct padding
int[] mapPadding = mapboxMap.getPadding();
RectF latLngPadding = getPadding();
RectF padding = new RectF(latLngPadding.left + mapPadding[0],
latLngPadding.top + mapPadding[1],
latLngPadding.right + mapPadding[2],
latLngPadding.bottom + mapPadding[3]);

// Calculate the bounds of the possibly rotated shape with respect to the viewport
PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE);
PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE);
float viewportHeight = uiSettings.getHeight();
for (LatLng latLng : getBounds().toLatLngs()) {
PointF pixel = projection.toScreenLocation(latLng);
swPixel.x = Math.min(swPixel.x, pixel.x);
nePixel.x = Math.max(nePixel.x, pixel.x);
swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
}

// Calculate width/height
float width = nePixel.x - swPixel.x;
float height = nePixel.y - swPixel.y;

double zoom = 0;
float minScale = 1;
// Calculate the zoom level
if (padding != null) {
float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
minScale = scaleX < scaleY ? scaleX : scaleY;
zoom = projection.calculateZoom(minScale);
zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel());
}

// Calculate the center point
PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
centerPixel.y = viewportHeight - centerPixel.y;
LatLng center = projection.fromScreenLocation(centerPixel);

return new CameraPosition.Builder()
.target(center)
.zoom(zoom)
.tilt(0)
.bearing(0)
.build();
return mapboxMap.getCameraForLatLngBounds(bounds, padding);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,27 @@ public void setLatLngBoundsForCameraTarget(@Nullable LatLngBounds latLngBounds)
nativeMapView.setLatLngBounds(latLngBounds);
}

/**
* Gets a camera position that would fit a bounds.
*
* @param latLngBounds the bounds to constrain the map with
*/
public CameraPosition getCameraForLatLngBounds(@Nullable LatLngBounds latLngBounds, int[] padding) {
// calculate and set additional bounds padding
int[] mapPadding = getPadding();
for (int i = 0; i < padding.length; i++) {
padding[i] = mapPadding[i] + padding[i];
}
projection.setContentPadding(padding, myLocationViewSettings.getPadding());

// get padded camera position from LatLngBounds
CameraPosition cameraPosition = nativeMapView.getCameraForLatLngBounds(latLngBounds);

// reset map padding
setPadding(mapPadding);
return cameraPosition;
}

//
// Padding
//
Expand All @@ -1544,7 +1565,11 @@ public void setLatLngBoundsForCameraTarget(@Nullable LatLngBounds latLngBounds)
* @param bottom The bottom margin in pixels.
*/
public void setPadding(int left, int top, int right, int bottom) {
projection.setContentPadding(new int[] {left, top, right, bottom}, myLocationViewSettings.getPadding());
setPadding(new int[] {left, top, right, bottom});
}

private void setPadding(int[] padding) {
projection.setContentPadding(padding, myLocationViewSettings.getPadding());
uiSettings.invalidate();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
Expand Down Expand Up @@ -317,6 +318,13 @@ public LatLng getLatLng() {
return nativeGetLatLng().wrap();
}

public CameraPosition getCameraForLatLngBounds(LatLngBounds latLngBounds) {
if (isDestroyedOn("getCameraForLatLngBounds")) {
return null;
}
return nativeGetCameraForLatLngBounds(latLngBounds);
}

public void resetPosition() {
if (isDestroyedOn("resetPosition")) {
return;
Expand Down Expand Up @@ -676,11 +684,11 @@ public void flyTo(double angle, LatLng center, long duration, double pitch, doub
nativeFlyTo(angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom);
}

public double[] getCameraValues() {
public CameraPosition getCameraPosition() {
if (isDestroyedOn("getCameraValues")) {
return new double[] {};
return new CameraPosition.Builder().build();
}
return nativeGetCameraValues();
return nativeGetCameraPosition();
}

// Runtime style Api
Expand Down Expand Up @@ -970,6 +978,8 @@ private native void nativeInitialize(NativeMapView nativeMapView,

private native LatLng nativeGetLatLng();

private native CameraPosition nativeGetCameraForLatLngBounds(LatLngBounds latLngBounds);

private native void nativeResetPosition();

private native double nativeGetPitch();
Expand Down Expand Up @@ -1054,7 +1064,7 @@ private native void nativeEaseTo(double angle, double latitude, double longitude
private native void nativeFlyTo(double angle, double latitude, double longitude,
long duration, double pitch, double zoom);

private native double[] nativeGetCameraValues();
private native CameraPosition nativeGetCameraPosition();

private native long nativeGetTransitionDuration();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationM
@Nullable
CameraPosition invalidateCameraPosition() {
if (mapView != null) {
cameraPosition = new CameraPosition.Builder(mapView.getCameraValues()).build();
cameraPosition = mapView.getCameraPosition();
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(this.cameraPosition);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
package com.mapbox.mapboxsdk.testapp.activity.camera;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;

import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.camera.CameraUpdate;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.testapp.R;

import java.util.ArrayList;
import java.util.List;

import timber.log.Timber;

/**
* Test activity showcasing using the LatLngBounds camera API.
* <p>
Expand All @@ -31,6 +27,9 @@ public class LatLngBoundsActivity extends AppCompatActivity implements OnMapRead
private static final LatLng LOS_ANGELES = new LatLng(34.053940, -118.242622);
private static final LatLng NEW_YORK = new LatLng(40.712730, -74.005953);

private final LatLng CHINA_BOTTOM_LEFT = new LatLng(15.68169, 73.499857);
private final LatLng CHINA_TOP_RIGHT = new LatLng(53.560711, 134.77281);

private MapView mapView;
private MapboxMap mapboxMap;

Expand All @@ -46,41 +45,31 @@ protected void onCreate(Bundle savedInstanceState) {
}

@Override
public void onMapReady(MapboxMap map) {
public void onMapReady(final MapboxMap map) {
mapboxMap = map;
UiSettings uiSettings = mapboxMap.getUiSettings();
uiSettings.setAllGesturesEnabled(false);

mapboxMap.addMarker(new MarkerOptions()
.title("Los Angeles")
.snippet("City Hall")
.position(LOS_ANGELES));

mapboxMap.addMarker(new MarkerOptions()
.title("New York")
.snippet("City Hall")
.position(NEW_YORK));

List<LatLng> points = new ArrayList<>();
points.add(NEW_YORK);
points.add(LOS_ANGELES);

// Create Bounds
final LatLngBounds bounds = new LatLngBounds.Builder()
.includes(points)
.build();

// Add map padding
int mapPadding = (int) getResources().getDimension(R.dimen.fab_margin);
mapboxMap.setPadding(mapPadding, mapPadding, mapPadding, mapPadding);

// Move camera to the bounds with added padding
int padding = (int) getResources().getDimension(R.dimen.coordinatebounds_margin);
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, padding), 1500);

// Log data
Timber.e("Move to bounds: " + bounds.toString());
Timber.e("Resulting bounds:" + mapboxMap.getProjection().getVisibleRegion().latLngBounds.toString());
moveToBounds(new LatLngBounds.Builder().include(NEW_YORK).include(LOS_ANGELES).build(), new int[] {0, 0, 0, 0});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
moveToBounds(new LatLngBounds.Builder().include(CHINA_BOTTOM_LEFT).include(CHINA_TOP_RIGHT).build(),
new int[] {100, 100, 100, 100 });
}
}, 5000);
}

private void moveToBounds(LatLngBounds latLngBounds, int[] padding) {
mapboxMap.clear();
mapboxMap.addMarker(new MarkerOptions().position(latLngBounds.getNorthEast()));
mapboxMap.addMarker(new MarkerOptions().position(latLngBounds.getSouthEast()));
mapboxMap.addMarker(new MarkerOptions().position(latLngBounds.getSouthWest()));
mapboxMap.addMarker(new MarkerOptions().position(latLngBounds.getNorthWest()));
CameraUpdate update =
CameraUpdateFactory.newLatLngBounds(latLngBounds,
padding[0],
padding[1],
padding[2],
padding[3]);
mapboxMap.moveCamera(update);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,6 @@ public void testTypedArrayBuilder() {
assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
}

@Test
public void testJniBuilder() {
double bearing = 180;
double zoom = 12;
double latitude = 10;
double longitude = 11;
double tilt = 44;

double[] cameraVars = new double[]{latitude, longitude, bearing, tilt, zoom};
CameraPosition cameraPosition = new CameraPosition.Builder(cameraVars).build();
assertEquals("bearing should match", bearing, cameraPosition.bearing, DELTA);
assertEquals("latlng should match", new LatLng(latitude, longitude), cameraPosition.target);
assertEquals("tilt should match", tilt, cameraPosition.tilt, DELTA);
assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
}

@Test
public void testToString() {
LatLng latLng = new LatLng(1, 2);
Expand Down
2 changes: 2 additions & 0 deletions platform/android/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ add_library(mbgl-android STATIC
platform/android/src/style/conversion/property_value.hpp
platform/android/src/style/conversion/types.hpp
platform/android/src/style/conversion/types_string_values.hpp
platform/android/src/map/camera_position.cpp
platform/android/src/map/camera_position.hpp

# Style conversion Java -> C++
platform/android/src/style/android_conversion.hpp
Expand Down
3 changes: 3 additions & 0 deletions platform/android/src/jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ void registerNatives(JavaVM *vm) {
IdentityStops::registerNative(env);
IntervalStops::registerNative(env);

// Map
CameraPosition::registerNative(env);

// Connectivity
ConnectivityListener::registerNative(env);

Expand Down
Loading