Migrate examples in android TestApp to Kotlin (#416)
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:name=".MapboxApplication"
|
||||
android:name=".MapLibreApplication"
|
||||
android:allowBackup="true"
|
||||
android:exported="true"
|
||||
android:fullBackupContent="true"
|
||||
@@ -77,7 +77,7 @@
|
||||
android:value=".activity.FeatureOverviewActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.annotation.AnimatedSymbolLayerActivity"
|
||||
android:name=".activity.style.AnimatedSymbolLayerActivity"
|
||||
android:description="@string/description_animated_symbollayer"
|
||||
android:exported="true"
|
||||
android:label="@string/activity_animated_symbollayer">
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.mapbox.mapboxsdk.testapp
|
||||
|
||||
import android.app.Application
|
||||
import android.os.StrictMode
|
||||
import android.os.StrictMode.ThreadPolicy
|
||||
import android.os.StrictMode.VmPolicy
|
||||
import android.text.TextUtils
|
||||
import com.mapbox.mapboxsdk.MapStrictMode
|
||||
import com.mapbox.mapboxsdk.Mapbox
|
||||
import com.mapbox.mapboxsdk.WellKnownTileServer
|
||||
import com.mapbox.mapboxsdk.log.Logger
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ApiKeyUtils
|
||||
import com.mapbox.mapboxsdk.testapp.utils.TileLoadingMeasurementUtils
|
||||
import com.mapbox.mapboxsdk.testapp.utils.TimberLogger
|
||||
import com.squareup.leakcanary.LeakCanary
|
||||
import timber.log.Timber
|
||||
import timber.log.Timber.DebugTree
|
||||
|
||||
/**
|
||||
* Application class of the test application.
|
||||
*
|
||||
*
|
||||
* Initialises components as LeakCanary, Strictmode, Timber and Mapbox
|
||||
*
|
||||
*/
|
||||
class MapLibreApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (!initializeLeakCanary()) {
|
||||
return
|
||||
}
|
||||
initializeLogger()
|
||||
initializeStrictMode()
|
||||
initializeMapbox()
|
||||
}
|
||||
|
||||
protected fun initializeLeakCanary(): Boolean {
|
||||
if (LeakCanary.isInAnalyzerProcess(this)) {
|
||||
// This process is dedicated to LeakCanary for heap analysis.
|
||||
// You should not init your app in this process.
|
||||
return false
|
||||
}
|
||||
LeakCanary.install(this)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun initializeLogger() {
|
||||
Logger.setLoggerDefinition(TimberLogger())
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(DebugTree())
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeStrictMode() {
|
||||
StrictMode.setThreadPolicy(
|
||||
ThreadPolicy.Builder()
|
||||
.detectDiskReads()
|
||||
.detectDiskWrites()
|
||||
.detectNetwork()
|
||||
.penaltyLog()
|
||||
.build()
|
||||
)
|
||||
StrictMode.setVmPolicy(
|
||||
VmPolicy.Builder()
|
||||
.detectLeakedSqlLiteObjects()
|
||||
.penaltyLog()
|
||||
.penaltyDeath()
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun initializeMapbox() {
|
||||
val apiKey = ApiKeyUtils.getApiKey(applicationContext)
|
||||
validateApiKey(apiKey)
|
||||
Mapbox.getInstance(applicationContext, apiKey, TILE_SERVER)
|
||||
TileLoadingMeasurementUtils.setUpTileLoadingMeasurement()
|
||||
MapStrictMode.setStrictModeEnabled(true)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TILE_SERVER = WellKnownTileServer.MapTiler
|
||||
private const val DEFAULT_API_KEY = "YOUR_API_KEY_GOES_HERE"
|
||||
private const val API_KEY_NOT_SET_MESSAGE =
|
||||
(
|
||||
"In order to run the Test App you need to set a valid " +
|
||||
"API key. During development, you can set the MGL_API_KEY environment variable for the SDK to " +
|
||||
"automatically include it in the Test App. Otherwise, you can manually include it in the " +
|
||||
"res/values/developer-config.xml file in the MapboxGLAndroidSDKTestApp folder."
|
||||
)
|
||||
|
||||
private fun validateApiKey(apiKey: String) {
|
||||
if (TextUtils.isEmpty(apiKey) || apiKey == DEFAULT_API_KEY) {
|
||||
Timber.e(API_KEY_NOT_SET_MESSAGE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.StrictMode;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mapbox.mapboxsdk.MapStrictMode;
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.WellKnownTileServer;
|
||||
import com.mapbox.mapboxsdk.log.Logger;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.TileLoadingMeasurementUtils;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.TimberLogger;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ApiKeyUtils;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static timber.log.Timber.DebugTree;
|
||||
|
||||
/**
|
||||
* Application class of the test application.
|
||||
* <p>
|
||||
* Initialises components as LeakCanary, Strictmode, Timber and Mapbox
|
||||
* </p>
|
||||
*/
|
||||
public class MapboxApplication extends Application {
|
||||
|
||||
public static final WellKnownTileServer TILE_SERVER = WellKnownTileServer.MapTiler;
|
||||
|
||||
private static final String DEFAULT_API_KEY = "YOUR_API_KEY_GOES_HERE";
|
||||
private static final String API_KEY_NOT_SET_MESSAGE = "In order to run the Test App you need to set a valid "
|
||||
+ "API key. During development, you can set the MGL_API_KEY environment variable for the SDK to "
|
||||
+ "automatically include it in the Test App. Otherwise, you can manually include it in the "
|
||||
+ "res/values/developer-config.xml file in the MapboxGLAndroidSDKTestApp folder.";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if (!initializeLeakCanary()) {
|
||||
return;
|
||||
}
|
||||
initializeLogger();
|
||||
initializeStrictMode();
|
||||
initializeMapbox();
|
||||
}
|
||||
|
||||
protected boolean initializeLeakCanary() {
|
||||
if (LeakCanary.isInAnalyzerProcess(this)) {
|
||||
// This process is dedicated to LeakCanary for heap analysis.
|
||||
// You should not init your app in this process.
|
||||
return false;
|
||||
}
|
||||
LeakCanary.install(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initializeLogger() {
|
||||
Logger.setLoggerDefinition(new TimberLogger());
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(new DebugTree());
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeStrictMode() {
|
||||
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
||||
.detectDiskReads()
|
||||
.detectDiskWrites()
|
||||
.detectNetwork()
|
||||
.penaltyLog()
|
||||
.build());
|
||||
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
|
||||
.detectLeakedSqlLiteObjects()
|
||||
.penaltyLog()
|
||||
.penaltyDeath()
|
||||
.build());
|
||||
}
|
||||
|
||||
private void initializeMapbox() {
|
||||
String apiKey = ApiKeyUtils.getApiKey(getApplicationContext());
|
||||
validateApiKey(apiKey);
|
||||
|
||||
Mapbox.getInstance(getApplicationContext(), apiKey, TILE_SERVER);
|
||||
|
||||
TileLoadingMeasurementUtils.setUpTileLoadingMeasurement();
|
||||
|
||||
MapStrictMode.setStrictModeEnabled(true);
|
||||
}
|
||||
|
||||
private static void validateApiKey(String apiKey) {
|
||||
if (TextUtils.isEmpty(apiKey) || apiKey.equals(DEFAULT_API_KEY)) {
|
||||
Timber.e(API_KEY_NOT_SET_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,444 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.TypeEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.geojson.FeatureCollection;
|
||||
import com.mapbox.geojson.Point;
|
||||
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.Style;
|
||||
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.turf.TurfMeasurement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconRotate;
|
||||
|
||||
/**
|
||||
* Test activity showcasing animating a SymbolLayer.
|
||||
*/
|
||||
public class AnimatedSymbolLayerActivity extends AppCompatActivity {
|
||||
|
||||
private static final String PASSENGER = "passenger";
|
||||
private static final String PASSENGER_LAYER = "passenger-layer";
|
||||
private static final String PASSENGER_SOURCE = "passenger-source";
|
||||
private static final String TAXI = "taxi";
|
||||
private static final String TAXI_LAYER = "taxi-layer";
|
||||
private static final String TAXI_SOURCE = "taxi-source";
|
||||
private static final String RANDOM_CAR_LAYER = "random-car-layer";
|
||||
private static final String RANDOM_CAR_SOURCE = "random-car-source";
|
||||
private static final String RANDOM_CAR_IMAGE_ID = "random-car";
|
||||
private static final String PROPERTY_BEARING = "bearing";
|
||||
private static final String WATERWAY_LAYER_ID = "water_intermittent";
|
||||
private static final int DURATION_RANDOM_MAX = 1500;
|
||||
private static final int DURATION_BASE = 3000;
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private Style style;
|
||||
|
||||
private List<Car> randomCars = new ArrayList<>();
|
||||
private GeoJsonSource randomCarSource;
|
||||
private Car taxi;
|
||||
private GeoJsonSource taxiSource;
|
||||
private LatLng passenger;
|
||||
|
||||
private List<Animator> animators = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_animated_marker);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(map -> {
|
||||
this.mapboxMap = map;
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
this.style = style;
|
||||
setupCars();
|
||||
animateRandomRoutes();
|
||||
animateTaxi();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void setupCars() {
|
||||
addRandomCars();
|
||||
addPassenger();
|
||||
addMainCar();
|
||||
}
|
||||
|
||||
private void animateRandomRoutes() {
|
||||
final Car longestDrive = getLongestDrive();
|
||||
final Random random = new Random();
|
||||
for (final Car car : randomCars) {
|
||||
final boolean isLongestDrive = longestDrive.equals(car);
|
||||
ValueAnimator valueAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), car.current, car.next);
|
||||
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
|
||||
private LatLng latLng;
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
latLng = (LatLng) animation.getAnimatedValue();
|
||||
car.current = latLng;
|
||||
if (isLongestDrive) {
|
||||
updateRandomCarSource();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (isLongestDrive) {
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
updateRandomDestinations();
|
||||
animateRandomRoutes();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
super.onAnimationStart(animation);
|
||||
car.feature.properties().addProperty("bearing", Car.getBearing(car.current, car.next));
|
||||
}
|
||||
});
|
||||
|
||||
int offset = random.nextInt(2) == 0 ? 0 : random.nextInt(1000) + 250;
|
||||
valueAnimator.setStartDelay(offset);
|
||||
valueAnimator.setDuration(car.duration - offset);
|
||||
valueAnimator.setInterpolator(new LinearInterpolator());
|
||||
valueAnimator.start();
|
||||
|
||||
animators.add(valueAnimator);
|
||||
}
|
||||
}
|
||||
|
||||
private void animateTaxi() {
|
||||
ValueAnimator valueAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), taxi.current, taxi.next);
|
||||
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
|
||||
private LatLng latLng;
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
latLng = (LatLng) animation.getAnimatedValue();
|
||||
taxi.current = latLng;
|
||||
updateTaxiSource();
|
||||
}
|
||||
});
|
||||
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
updatePassenger();
|
||||
animateTaxi();
|
||||
}
|
||||
});
|
||||
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
super.onAnimationStart(animation);
|
||||
taxi.feature.properties().addProperty("bearing", Car.getBearing(taxi.current, taxi.next));
|
||||
}
|
||||
});
|
||||
|
||||
valueAnimator.setDuration((long) (7 * taxi.current.distanceTo(taxi.next)));
|
||||
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||
valueAnimator.start();
|
||||
|
||||
animators.add(valueAnimator);
|
||||
}
|
||||
|
||||
private void updatePassenger() {
|
||||
passenger = getLatLngInBounds();
|
||||
updatePassengerSource();
|
||||
taxi.setNext(passenger);
|
||||
}
|
||||
|
||||
private void updatePassengerSource() {
|
||||
GeoJsonSource source = style.getSourceAs(PASSENGER_SOURCE);
|
||||
FeatureCollection featureCollection = FeatureCollection.fromFeatures(new Feature[] {
|
||||
Feature.fromGeometry(
|
||||
Point.fromLngLat(
|
||||
passenger.getLongitude(),
|
||||
passenger.getLatitude()
|
||||
)
|
||||
)
|
||||
});
|
||||
source.setGeoJson(featureCollection);
|
||||
}
|
||||
|
||||
private void updateTaxiSource() {
|
||||
taxi.updateFeature();
|
||||
taxiSource.setGeoJson(taxi.feature);
|
||||
}
|
||||
|
||||
private void updateRandomDestinations() {
|
||||
for (Car randomCar : randomCars) {
|
||||
randomCar.setNext(getLatLngInBounds());
|
||||
}
|
||||
}
|
||||
|
||||
private Car getLongestDrive() {
|
||||
Car longestDrive = null;
|
||||
for (Car randomCar : randomCars) {
|
||||
if (longestDrive == null) {
|
||||
longestDrive = randomCar;
|
||||
} else if (longestDrive.duration < randomCar.duration) {
|
||||
longestDrive = randomCar;
|
||||
}
|
||||
}
|
||||
return longestDrive;
|
||||
}
|
||||
|
||||
private void updateRandomCarSource() {
|
||||
for (Car randomCarsRoute : randomCars) {
|
||||
randomCarsRoute.updateFeature();
|
||||
}
|
||||
randomCarSource.setGeoJson(featuresFromRoutes());
|
||||
}
|
||||
|
||||
private FeatureCollection featuresFromRoutes() {
|
||||
List<Feature> features = new ArrayList<>();
|
||||
for (Car randomCarsRoute : randomCars) {
|
||||
features.add(randomCarsRoute.feature);
|
||||
}
|
||||
return FeatureCollection.fromFeatures(features);
|
||||
}
|
||||
|
||||
private long getDuration() {
|
||||
return random.nextInt(DURATION_RANDOM_MAX) + DURATION_BASE;
|
||||
}
|
||||
|
||||
private void addRandomCars() {
|
||||
LatLng latLng;
|
||||
LatLng next;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
latLng = getLatLngInBounds();
|
||||
next = getLatLngInBounds();
|
||||
|
||||
JsonObject properties = new JsonObject();
|
||||
properties.addProperty(PROPERTY_BEARING, Car.getBearing(latLng, next));
|
||||
|
||||
Feature feature = Feature.fromGeometry(
|
||||
Point.fromLngLat(
|
||||
latLng.getLongitude(),
|
||||
latLng.getLatitude()
|
||||
), properties);
|
||||
|
||||
randomCars.add(
|
||||
new Car(feature, next, getDuration())
|
||||
);
|
||||
}
|
||||
|
||||
randomCarSource = new GeoJsonSource(RANDOM_CAR_SOURCE, featuresFromRoutes());
|
||||
style.addSource(randomCarSource);
|
||||
style.addImage(RANDOM_CAR_IMAGE_ID,
|
||||
((BitmapDrawable) getResources().getDrawable(R.drawable.ic_car_top)).getBitmap());
|
||||
|
||||
SymbolLayer symbolLayer = new SymbolLayer(RANDOM_CAR_LAYER, RANDOM_CAR_SOURCE);
|
||||
symbolLayer.withProperties(
|
||||
iconImage(RANDOM_CAR_IMAGE_ID),
|
||||
iconAllowOverlap(true),
|
||||
iconRotate(get(PROPERTY_BEARING)),
|
||||
iconIgnorePlacement(true)
|
||||
);
|
||||
|
||||
style.addLayerBelow(symbolLayer, WATERWAY_LAYER_ID);
|
||||
}
|
||||
|
||||
private void addPassenger() {
|
||||
passenger = getLatLngInBounds();
|
||||
FeatureCollection featureCollection = FeatureCollection.fromFeatures(new Feature[] {
|
||||
Feature.fromGeometry(
|
||||
Point.fromLngLat(
|
||||
passenger.getLongitude(),
|
||||
passenger.getLatitude()
|
||||
)
|
||||
)
|
||||
});
|
||||
|
||||
style.addImage(PASSENGER,
|
||||
((BitmapDrawable) getResources().getDrawable(R.drawable.icon_burned)).getBitmap());
|
||||
|
||||
GeoJsonSource geoJsonSource = new GeoJsonSource(PASSENGER_SOURCE, featureCollection);
|
||||
style.addSource(geoJsonSource);
|
||||
|
||||
SymbolLayer symbolLayer = new SymbolLayer(PASSENGER_LAYER, PASSENGER_SOURCE);
|
||||
symbolLayer.withProperties(
|
||||
iconImage(PASSENGER),
|
||||
iconIgnorePlacement(true),
|
||||
iconAllowOverlap(true)
|
||||
);
|
||||
style.addLayerBelow(symbolLayer, RANDOM_CAR_LAYER);
|
||||
}
|
||||
|
||||
private void addMainCar() {
|
||||
LatLng latLng = getLatLngInBounds();
|
||||
JsonObject properties = new JsonObject();
|
||||
properties.addProperty(PROPERTY_BEARING, Car.getBearing(latLng, passenger));
|
||||
Feature feature = Feature.fromGeometry(
|
||||
Point.fromLngLat(
|
||||
latLng.getLongitude(),
|
||||
latLng.getLatitude()), properties);
|
||||
FeatureCollection featureCollection = FeatureCollection.fromFeatures(new Feature[] {feature});
|
||||
|
||||
taxi = new Car(feature, passenger, getDuration());
|
||||
style.addImage(TAXI,
|
||||
((BitmapDrawable) getResources().getDrawable(R.drawable.ic_taxi_top)).getBitmap());
|
||||
taxiSource = new GeoJsonSource(TAXI_SOURCE, featureCollection);
|
||||
style.addSource(taxiSource);
|
||||
|
||||
SymbolLayer symbolLayer = new SymbolLayer(TAXI_LAYER, TAXI_SOURCE);
|
||||
symbolLayer.withProperties(
|
||||
iconImage(TAXI),
|
||||
iconRotate(get(PROPERTY_BEARING)),
|
||||
iconAllowOverlap(true),
|
||||
iconIgnorePlacement(true)
|
||||
|
||||
);
|
||||
style.addLayer(symbolLayer);
|
||||
}
|
||||
|
||||
private LatLng getLatLngInBounds() {
|
||||
LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds;
|
||||
Random generator = new Random();
|
||||
double randomLat = bounds.getLatSouth() + generator.nextDouble()
|
||||
* (bounds.getLatNorth() - bounds.getLatSouth());
|
||||
double randomLon = bounds.getLonWest() + generator.nextDouble()
|
||||
* (bounds.getLonEast() - bounds.getLonWest());
|
||||
return new LatLng(randomLat, randomLon);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
for (Animator animator : animators) {
|
||||
if (animator != null) {
|
||||
animator.removeAllListeners();
|
||||
animator.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluator for LatLng pairs
|
||||
*/
|
||||
private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
|
||||
|
||||
private LatLng latLng = new LatLng();
|
||||
|
||||
@Override
|
||||
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
|
||||
latLng.setLatitude(startValue.getLatitude()
|
||||
+ ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
|
||||
latLng.setLongitude(startValue.getLongitude()
|
||||
+ ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
|
||||
return latLng;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Car {
|
||||
private Feature feature;
|
||||
private LatLng next;
|
||||
private LatLng current;
|
||||
private long duration;
|
||||
|
||||
Car(Feature feature, LatLng next, long duration) {
|
||||
this.feature = feature;
|
||||
Point point = ((Point) feature.geometry());
|
||||
this.current = new LatLng(point.latitude(), point.longitude());
|
||||
this.duration = duration;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
void setNext(LatLng next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
void updateFeature() {
|
||||
feature = Feature.fromGeometry(Point.fromLngLat(
|
||||
current.getLongitude(),
|
||||
current.getLatitude())
|
||||
);
|
||||
feature.properties().addProperty("bearing", getBearing(current, next));
|
||||
}
|
||||
|
||||
private static float getBearing(LatLng from, LatLng to) {
|
||||
return (float) TurfMeasurement.bearing(
|
||||
Point.fromLngLat(from.getLongitude(), from.getLatitude()),
|
||||
Point.fromLngLat(to.getLongitude(), to.getLatitude())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing adding a large amount of Markers.
|
||||
*/
|
||||
public class BulkMarkerActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private List<LatLng> locations;
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_marker_bulk);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this::initMap);
|
||||
}
|
||||
|
||||
private void initMap(MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(
|
||||
this, R.array.bulk_marker_list, android.R.layout.simple_spinner_item);
|
||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
getMenuInflater().inflate(R.menu.menu_bulk_marker, menu);
|
||||
MenuItem item = menu.findItem(R.id.spinner);
|
||||
Spinner spinner = (Spinner) MenuItemCompat.getActionView(item);
|
||||
spinner.setAdapter(spinnerAdapter);
|
||||
spinner.setOnItemSelectedListener(BulkMarkerActivity.this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
int amount = Integer.valueOf(getResources().getStringArray(R.array.bulk_marker_list)[position]);
|
||||
if (locations == null) {
|
||||
progressDialog = ProgressDialog.show(this, "Loading", "Fetching markers", false);
|
||||
new LoadLocationTask(this, amount).execute();
|
||||
} else {
|
||||
showMarkers(amount);
|
||||
}
|
||||
}
|
||||
|
||||
private void onLatLngListLoaded(List<LatLng> latLngs, int amount) {
|
||||
progressDialog.hide();
|
||||
locations = latLngs;
|
||||
showMarkers(amount);
|
||||
}
|
||||
|
||||
private void showMarkers(int amount) {
|
||||
if (mapboxMap == null || locations == null || mapView.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mapboxMap.clear();
|
||||
if (locations.size() < amount) {
|
||||
amount = locations.size();
|
||||
}
|
||||
|
||||
showGlMarkers(amount);
|
||||
}
|
||||
|
||||
private void showGlMarkers(int amount) {
|
||||
List<MarkerOptions> markerOptionsList = new ArrayList<>();
|
||||
DecimalFormat formatter = new DecimalFormat("#.#####");
|
||||
Random random = new Random();
|
||||
int randomIndex;
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
randomIndex = random.nextInt(locations.size());
|
||||
LatLng latLng = locations.get(randomIndex);
|
||||
markerOptionsList.add(new MarkerOptions()
|
||||
.position(latLng)
|
||||
.title(String.valueOf(i))
|
||||
.snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude())));
|
||||
}
|
||||
|
||||
mapboxMap.addMarkers(markerOptionsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// nothing selected, nothing to do!
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (progressDialog != null) {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
private static class LoadLocationTask extends AsyncTask<Void, Integer, List<LatLng>> {
|
||||
|
||||
private WeakReference<BulkMarkerActivity> activity;
|
||||
private int amount;
|
||||
|
||||
private LoadLocationTask(BulkMarkerActivity activity, int amount) {
|
||||
this.amount = amount;
|
||||
this.activity = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<LatLng> doInBackground(Void... params) {
|
||||
BulkMarkerActivity activity = this.activity.get();
|
||||
if (activity != null) {
|
||||
String json = null;
|
||||
try {
|
||||
json = GeoParseUtil.loadStringFromAssets(activity.getApplicationContext(), "points.geojson");
|
||||
} catch (IOException exception) {
|
||||
Timber.e(exception, "Could not add markers");
|
||||
}
|
||||
|
||||
if (json != null) {
|
||||
return GeoParseUtil.parseGeoJsonCoordinates(json);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<LatLng> locations) {
|
||||
super.onPostExecute(locations);
|
||||
BulkMarkerActivity activity = this.activity.get();
|
||||
if (activity != null) {
|
||||
activity.onLatLngListLoaded(locations, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation
|
||||
|
||||
import android.app.ProgressDialog
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemSelectedListener
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Spinner
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.MenuItemCompat
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import java.lang.ref.WeakReference
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Test activity showcasing adding a large amount of Markers.
|
||||
*/
|
||||
class BulkMarkerActivity : AppCompatActivity(), OnItemSelectedListener {
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var mapView: MapView
|
||||
private var locations: List<LatLng>? = null
|
||||
private var progressDialog: ProgressDialog? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_marker_bulk)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(OnMapReadyCallback { mapboxMap: MapboxMap -> initMap(mapboxMap) })
|
||||
}
|
||||
|
||||
private fun initMap(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val spinnerAdapter = ArrayAdapter.createFromResource(
|
||||
this,
|
||||
R.array.bulk_marker_list,
|
||||
android.R.layout.simple_spinner_item
|
||||
)
|
||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
menuInflater.inflate(R.menu.menu_bulk_marker, menu)
|
||||
val item = menu.findItem(R.id.spinner)
|
||||
val spinner = MenuItemCompat.getActionView(item) as Spinner
|
||||
spinner.adapter = spinnerAdapter
|
||||
spinner.onItemSelectedListener = this@BulkMarkerActivity
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
val amount = Integer.valueOf(resources.getStringArray(R.array.bulk_marker_list)[position])
|
||||
if (locations == null) {
|
||||
progressDialog = ProgressDialog.show(this, "Loading", "Fetching markers", false)
|
||||
LoadLocationTask(this, amount).execute()
|
||||
} else {
|
||||
showMarkers(amount)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onLatLngListLoaded(latLngs: List<LatLng>?, amount: Int) {
|
||||
progressDialog!!.hide()
|
||||
locations = latLngs
|
||||
showMarkers(amount)
|
||||
}
|
||||
|
||||
private fun showMarkers(amount: Int) {
|
||||
var amount = amount
|
||||
if (mapboxMap == null || locations == null || mapView!!.isDestroyed) {
|
||||
return
|
||||
}
|
||||
mapboxMap!!.clear()
|
||||
if (locations!!.size < amount) {
|
||||
amount = locations!!.size
|
||||
}
|
||||
showGlMarkers(amount)
|
||||
}
|
||||
|
||||
private fun showGlMarkers(amount: Int) {
|
||||
val markerOptionsList: MutableList<MarkerOptions> = ArrayList()
|
||||
val formatter = DecimalFormat("#.#####")
|
||||
val random = Random()
|
||||
var randomIndex: Int
|
||||
for (i in 0 until amount) {
|
||||
randomIndex = random.nextInt(locations!!.size)
|
||||
val latLng = locations!![randomIndex]
|
||||
markerOptionsList.add(
|
||||
MarkerOptions()
|
||||
.position(latLng)
|
||||
.title(i.toString())
|
||||
.snippet(formatter.format(latLng.latitude) + ", " + formatter.format(latLng.longitude))
|
||||
)
|
||||
}
|
||||
mapboxMap!!.addMarkers(markerOptionsList)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
// nothing selected, nothing to do!
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (progressDialog != null) {
|
||||
progressDialog!!.dismiss()
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
private class LoadLocationTask constructor(
|
||||
activity: BulkMarkerActivity,
|
||||
private val amount: Int
|
||||
) : AsyncTask<Void?, Int?, List<LatLng>?>() {
|
||||
private val activity: WeakReference<BulkMarkerActivity>
|
||||
override fun doInBackground(vararg p0: Void?): List<LatLng>? {
|
||||
val activity = activity.get()
|
||||
if (activity != null) {
|
||||
var json: String? = null
|
||||
try {
|
||||
json = GeoParseUtil.loadStringFromAssets(
|
||||
activity.applicationContext,
|
||||
"points.geojson"
|
||||
)
|
||||
} catch (exception: IOException) {
|
||||
Timber.e(exception, "Could not add markers")
|
||||
}
|
||||
if (json != null) {
|
||||
return GeoParseUtil.parseGeoJsonCoordinates(json)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onPostExecute(locations: List<LatLng>?) {
|
||||
super.onPostExecute(locations)
|
||||
val activity = activity.get()
|
||||
activity?.onLatLngListLoaded(locations, amount)
|
||||
}
|
||||
|
||||
init {
|
||||
this.activity = WeakReference(activity)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.IconUtils;
|
||||
|
||||
/**
|
||||
* Test activity showcasing updating a Marker position, title, icon and snippet.
|
||||
*/
|
||||
public class DynamicMarkerChangeActivity extends AppCompatActivity {
|
||||
|
||||
private static final LatLng LAT_LNG_CHELSEA = new LatLng(51.481670, -0.190849);
|
||||
private static final LatLng LAT_LNG_ARSENAL = new LatLng(51.555062, -0.108417);
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private Marker marker;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_dynamic_marker);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.setTag(false);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
|
||||
DynamicMarkerChangeActivity.this.mapboxMap = mapboxMap;
|
||||
// Create marker
|
||||
MarkerOptions markerOptions = new MarkerOptions()
|
||||
.position(LAT_LNG_CHELSEA)
|
||||
.icon(IconUtils.drawableToIcon(DynamicMarkerChangeActivity.this, R.drawable.ic_stars,
|
||||
ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme())))
|
||||
.title(getString(R.string.dynamic_marker_chelsea_title))
|
||||
.snippet(getString(R.string.dynamic_marker_chelsea_snippet));
|
||||
marker = mapboxMap.addMarker(markerOptions);
|
||||
});
|
||||
|
||||
FloatingActionButton fab = findViewById(R.id.fab);
|
||||
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
|
||||
fab.setOnClickListener(view -> {
|
||||
if (mapboxMap != null) {
|
||||
updateMarker();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateMarker() {
|
||||
// update model
|
||||
boolean first = (boolean) mapView.getTag();
|
||||
mapView.setTag(!first);
|
||||
|
||||
// update marker
|
||||
marker.setPosition(first ? LAT_LNG_CHELSEA : LAT_LNG_ARSENAL);
|
||||
marker.setIcon(IconUtils.drawableToIcon(this, R.drawable.ic_stars, first
|
||||
? ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme()) :
|
||||
ResourcesCompat.getColor(getResources(), R.color.redAccent, getTheme())
|
||||
));
|
||||
|
||||
marker.setTitle(first
|
||||
? getString(R.string.dynamic_marker_chelsea_title) : getString(R.string.dynamic_marker_arsenal_title));
|
||||
marker.setSnippet(first
|
||||
? getString(R.string.dynamic_marker_chelsea_snippet) : getString(R.string.dynamic_marker_arsenal_snippet));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.annotations.Marker
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.IconUtils
|
||||
|
||||
/**
|
||||
* Test activity showcasing updating a Marker position, title, icon and snippet.
|
||||
*/
|
||||
class DynamicMarkerChangeActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private var marker: Marker? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_dynamic_marker)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.setTag(false)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
this@DynamicMarkerChangeActivity.mapboxMap = mapboxMap
|
||||
// Create marker
|
||||
val markerOptions = MarkerOptions()
|
||||
.position(LAT_LNG_CHELSEA)
|
||||
.icon(
|
||||
IconUtils.drawableToIcon(
|
||||
this@DynamicMarkerChangeActivity,
|
||||
R.drawable.ic_stars,
|
||||
ResourcesCompat.getColor(resources, R.color.blueAccent, theme)
|
||||
)
|
||||
)
|
||||
.title(getString(R.string.dynamic_marker_chelsea_title))
|
||||
.snippet(getString(R.string.dynamic_marker_chelsea_snippet))
|
||||
marker = mapboxMap.addMarker(markerOptions)
|
||||
}
|
||||
)
|
||||
val fab = findViewById<FloatingActionButton>(R.id.fab)
|
||||
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary))
|
||||
fab.setOnClickListener { view: View? ->
|
||||
if (mapboxMap != null) {
|
||||
updateMarker()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMarker() {
|
||||
// update model
|
||||
val first = mapView!!.tag as Boolean
|
||||
mapView!!.tag = !first
|
||||
|
||||
// update marker
|
||||
marker!!.position =
|
||||
if (first) LAT_LNG_CHELSEA else LAT_LNG_ARSENAL
|
||||
marker!!.icon = IconUtils.drawableToIcon(
|
||||
this,
|
||||
R.drawable.ic_stars,
|
||||
if (first) ResourcesCompat.getColor(
|
||||
resources,
|
||||
R.color.blueAccent,
|
||||
theme
|
||||
) else ResourcesCompat.getColor(
|
||||
resources,
|
||||
R.color.redAccent,
|
||||
theme
|
||||
)
|
||||
)
|
||||
marker!!.title =
|
||||
if (first) getString(R.string.dynamic_marker_chelsea_title) else getString(R.string.dynamic_marker_arsenal_title)
|
||||
marker!!.snippet =
|
||||
if (first) getString(R.string.dynamic_marker_chelsea_snippet) else getString(R.string.dynamic_marker_arsenal_snippet)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LAT_LNG_CHELSEA = LatLng(51.481670, -0.190849)
|
||||
private val LAT_LNG_ARSENAL = LatLng(51.555062, -0.108417)
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Polygon;
|
||||
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.BLUE_COLOR;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.BROKEN_SHAPE_POINTS;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.FULL_ALPHA;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.NO_ALPHA;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.PARTIAL_ALPHA;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.RED_COLOR;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.STAR_SHAPE_HOLES;
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.Config.STAR_SHAPE_POINTS;
|
||||
|
||||
/**
|
||||
* Test activity to showcase the Polygon annotation API & programmatically creating a MapView.
|
||||
* <p>
|
||||
* Shows how to change Polygon features as visibility, alpha, color and points.
|
||||
* </p>
|
||||
*/
|
||||
public class PolygonActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
private Polygon polygon;
|
||||
private boolean fullAlpha = true;
|
||||
private boolean visible = true;
|
||||
private boolean color = true;
|
||||
private boolean allPoints = true;
|
||||
private boolean holes = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// configure inital map state
|
||||
MapboxMapOptions options = MapboxMapOptions.createFromAttributes(this, null)
|
||||
.attributionTintColor(RED_COLOR)
|
||||
.compassFadesWhenFacingNorth(false)
|
||||
.camera(new CameraPosition.Builder()
|
||||
.target(new LatLng(45.520486, -122.673541))
|
||||
.zoom(12)
|
||||
.tilt(40)
|
||||
.build());
|
||||
|
||||
// create map
|
||||
mapView = new MapView(this, options);
|
||||
mapView.setId(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
|
||||
setContentView(mapView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
|
||||
map.setOnPolygonClickListener(polygon -> Toast.makeText(
|
||||
PolygonActivity.this,
|
||||
"You clicked on polygon with id = " + polygon.getId(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show());
|
||||
|
||||
polygon = mapboxMap.addPolygon(new PolygonOptions()
|
||||
.addAll(STAR_SHAPE_POINTS)
|
||||
.fillColor(BLUE_COLOR));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_id_alpha:
|
||||
fullAlpha = !fullAlpha;
|
||||
polygon.setAlpha(fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA);
|
||||
return true;
|
||||
case R.id.action_id_visible:
|
||||
visible = !visible;
|
||||
polygon.setAlpha(visible ? (fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA) : NO_ALPHA);
|
||||
return true;
|
||||
case R.id.action_id_points:
|
||||
allPoints = !allPoints;
|
||||
polygon.setPoints(allPoints ? STAR_SHAPE_POINTS : BROKEN_SHAPE_POINTS);
|
||||
return true;
|
||||
case R.id.action_id_color:
|
||||
color = !color;
|
||||
polygon.setFillColor(color ? BLUE_COLOR : RED_COLOR);
|
||||
return true;
|
||||
case R.id.action_id_holes:
|
||||
holes = !holes;
|
||||
polygon.setHoles(holes ? STAR_SHAPE_HOLES : Collections.<List<LatLng>>emptyList());
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_polygon, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
static final class Config {
|
||||
static final int BLUE_COLOR = Color.parseColor("#3bb2d0");
|
||||
static final int RED_COLOR = Color.parseColor("#AF0000");
|
||||
|
||||
static final float FULL_ALPHA = 1.0f;
|
||||
static final float PARTIAL_ALPHA = 0.5f;
|
||||
static final float NO_ALPHA = 0.0f;
|
||||
|
||||
static final List<LatLng> STAR_SHAPE_POINTS = new ArrayList<LatLng>() {
|
||||
{
|
||||
add(new LatLng(45.522585, -122.685699));
|
||||
add(new LatLng(45.534611, -122.708873));
|
||||
add(new LatLng(45.530883, -122.678833));
|
||||
add(new LatLng(45.547115, -122.667503));
|
||||
add(new LatLng(45.530643, -122.660121));
|
||||
add(new LatLng(45.533529, -122.636260));
|
||||
add(new LatLng(45.521743, -122.659091));
|
||||
add(new LatLng(45.510677, -122.648792));
|
||||
add(new LatLng(45.515008, -122.664070));
|
||||
add(new LatLng(45.502496, -122.669048));
|
||||
add(new LatLng(45.515369, -122.678489));
|
||||
add(new LatLng(45.506346, -122.702007));
|
||||
add(new LatLng(45.522585, -122.685699));
|
||||
}
|
||||
};
|
||||
|
||||
static final List<LatLng> BROKEN_SHAPE_POINTS =
|
||||
STAR_SHAPE_POINTS.subList(0, STAR_SHAPE_POINTS.size() - 3);
|
||||
|
||||
static final List<? extends List<LatLng>> STAR_SHAPE_HOLES = new ArrayList<List<LatLng>>() {
|
||||
{
|
||||
add(new ArrayList<>(new ArrayList<LatLng>() {
|
||||
{
|
||||
add(new LatLng(45.521743, -122.669091));
|
||||
add(new LatLng(45.530483, -122.676833));
|
||||
add(new LatLng(45.520483, -122.676833));
|
||||
add(new LatLng(45.521743, -122.669091));
|
||||
}
|
||||
}));
|
||||
add(new ArrayList<>(new ArrayList<LatLng>() {
|
||||
{
|
||||
add(new LatLng(45.529743, -122.662791));
|
||||
add(new LatLng(45.525543, -122.662791));
|
||||
add(new LatLng(45.525543, -122.660));
|
||||
add(new LatLng(45.527743, -122.660));
|
||||
add(new LatLng(45.529743, -122.662791));
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.annotations.Polygon
|
||||
import com.mapbox.mapboxsdk.annotations.PolygonOptions
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.* // ktlint-disable no-wildcard-imports
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* Test activity to showcase the Polygon annotation API & programmatically creating a MapView.
|
||||
*
|
||||
*
|
||||
* Shows how to change Polygon features as visibility, alpha, color and points.
|
||||
*
|
||||
*/
|
||||
class PolygonActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private var mapView: MapView? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var polygon: Polygon? = null
|
||||
private var fullAlpha = true
|
||||
private var polygonIsVisible = true
|
||||
private var color = true
|
||||
private var allPoints = true
|
||||
private var holes = false
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// configure inital map state
|
||||
val options = MapboxMapOptions.createFromAttributes(this, null)
|
||||
.attributionTintColor(Config.RED_COLOR)
|
||||
.compassFadesWhenFacingNorth(false)
|
||||
.camera(
|
||||
CameraPosition.Builder()
|
||||
.target(LatLng(45.520486, -122.673541))
|
||||
.zoom(12.0)
|
||||
.tilt(40.0)
|
||||
.build()
|
||||
)
|
||||
|
||||
// create map
|
||||
mapView = MapView(this, options)
|
||||
mapView!!.id = R.id.mapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync(this)
|
||||
setContentView(mapView)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
map.setOnPolygonClickListener { polygon: Polygon ->
|
||||
Toast.makeText(
|
||||
this@PolygonActivity,
|
||||
"You clicked on polygon with id = " + polygon.id,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
polygon = mapboxMap!!.addPolygon(
|
||||
PolygonOptions()
|
||||
.addAll(Config.STAR_SHAPE_POINTS)
|
||||
.fillColor(Config.BLUE_COLOR)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_id_alpha -> {
|
||||
fullAlpha = !fullAlpha
|
||||
polygon!!.alpha =
|
||||
if (fullAlpha) Config.FULL_ALPHA else Config.PARTIAL_ALPHA
|
||||
true
|
||||
}
|
||||
R.id.action_id_visible -> {
|
||||
polygonIsVisible = !polygonIsVisible
|
||||
polygon!!.alpha =
|
||||
if (polygonIsVisible) if (fullAlpha) Config.FULL_ALPHA else Config.PARTIAL_ALPHA else Config.NO_ALPHA
|
||||
true
|
||||
}
|
||||
R.id.action_id_points -> {
|
||||
allPoints = !allPoints
|
||||
polygon!!.points =
|
||||
if (allPoints) Config.STAR_SHAPE_POINTS else Config.BROKEN_SHAPE_POINTS
|
||||
true
|
||||
}
|
||||
R.id.action_id_color -> {
|
||||
color = !color
|
||||
polygon!!.fillColor =
|
||||
if (color) Config.BLUE_COLOR else Config.RED_COLOR
|
||||
true
|
||||
}
|
||||
R.id.action_id_holes -> {
|
||||
holes = !holes
|
||||
polygon!!.holes =
|
||||
if (holes) Config.STAR_SHAPE_HOLES else emptyList()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_polygon, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
internal object Config {
|
||||
val BLUE_COLOR = Color.parseColor("#3bb2d0")
|
||||
val RED_COLOR = Color.parseColor("#AF0000")
|
||||
const val FULL_ALPHA = 1.0f
|
||||
const val PARTIAL_ALPHA = 0.5f
|
||||
const val NO_ALPHA = 0.0f
|
||||
val STAR_SHAPE_POINTS: ArrayList<LatLng?> = object : ArrayList<LatLng?>() {
|
||||
init {
|
||||
add(LatLng(45.522585, -122.685699))
|
||||
add(LatLng(45.534611, -122.708873))
|
||||
add(LatLng(45.530883, -122.678833))
|
||||
add(LatLng(45.547115, -122.667503))
|
||||
add(LatLng(45.530643, -122.660121))
|
||||
add(LatLng(45.533529, -122.636260))
|
||||
add(LatLng(45.521743, -122.659091))
|
||||
add(LatLng(45.510677, -122.648792))
|
||||
add(LatLng(45.515008, -122.664070))
|
||||
add(LatLng(45.502496, -122.669048))
|
||||
add(LatLng(45.515369, -122.678489))
|
||||
add(LatLng(45.506346, -122.702007))
|
||||
add(LatLng(45.522585, -122.685699))
|
||||
}
|
||||
}
|
||||
val BROKEN_SHAPE_POINTS = STAR_SHAPE_POINTS.subList(0, STAR_SHAPE_POINTS.size - 3)
|
||||
val STAR_SHAPE_HOLES: ArrayList<List<LatLng?>?> = object : ArrayList<List<LatLng?>?>() {
|
||||
init {
|
||||
add(
|
||||
ArrayList<LatLng>(object : ArrayList<LatLng?>() {
|
||||
init {
|
||||
add(LatLng(45.521743, -122.669091))
|
||||
add(LatLng(45.530483, -122.676833))
|
||||
add(LatLng(45.520483, -122.676833))
|
||||
add(LatLng(45.521743, -122.669091))
|
||||
}
|
||||
})
|
||||
)
|
||||
add(
|
||||
ArrayList<LatLng>(object : ArrayList<LatLng?>() {
|
||||
init {
|
||||
add(LatLng(45.529743, -122.662791))
|
||||
add(LatLng(45.525543, -122.662791))
|
||||
add(LatLng(45.525543, -122.660))
|
||||
add(LatLng(45.527743, -122.660))
|
||||
add(LatLng(45.529743, -122.662791))
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing the Camera API and listen to camera updates by animating the camera above London.
|
||||
* <p>
|
||||
* Shows how to use animate, ease and move camera update factory methods.
|
||||
* </p>
|
||||
*/
|
||||
public class CameraAnimationTypeActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private static final LatLng LAT_LNG_LONDON_EYE = new LatLng(51.50325, -0.11968);
|
||||
private static final LatLng LAT_LNG_TOWER_BRIDGE = new LatLng(51.50550, -0.07520);
|
||||
|
||||
private final MapboxMap.CancelableCallback callback = new MapboxMap.CancelableCallback() {
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Timber.i("Duration onCancel Callback called.");
|
||||
Toast.makeText(
|
||||
CameraAnimationTypeActivity.this.getApplicationContext(),
|
||||
"Ease onCancel Callback called.",
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
Timber.i("Duration onFinish Callback called.");
|
||||
Toast.makeText(
|
||||
CameraAnimationTypeActivity.this.getApplicationContext(),
|
||||
"Ease onFinish Callback called.",
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
};
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private boolean cameraState;
|
||||
|
||||
private MapboxMap.OnCameraIdleListener cameraIdleListener = new MapboxMap.OnCameraIdleListener() {
|
||||
@Override
|
||||
public void onCameraIdle() {
|
||||
if (mapboxMap != null) {
|
||||
Timber.w(mapboxMap.getCameraPosition().toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_camera_animation_types);
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.getPredefinedStyle("Streets")));
|
||||
mapboxMap.getUiSettings().setAttributionEnabled(false);
|
||||
mapboxMap.getUiSettings().setLogoEnabled(false);
|
||||
mapboxMap.addOnCameraIdleListener(cameraIdleListener);
|
||||
|
||||
// handle move button clicks
|
||||
View moveButton = findViewById(R.id.cameraMoveButton);
|
||||
if (moveButton != null) {
|
||||
moveButton.setOnClickListener(view -> {
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.target(getNextLatLng())
|
||||
.zoom(14)
|
||||
.tilt(30)
|
||||
.tilt(0)
|
||||
.build();
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||
});
|
||||
}
|
||||
|
||||
// handle ease button clicks
|
||||
View easeButton = findViewById(R.id.cameraEaseButton);
|
||||
if (easeButton != null) {
|
||||
easeButton.setOnClickListener(view -> {
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.target(getNextLatLng())
|
||||
.zoom(15)
|
||||
.bearing(180)
|
||||
.tilt(30)
|
||||
.build();
|
||||
mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 7500, callback);
|
||||
});
|
||||
}
|
||||
|
||||
// handle animate button clicks
|
||||
View animateButton = findViewById(R.id.cameraAnimateButton);
|
||||
if (animateButton != null) {
|
||||
animateButton.setOnClickListener(view -> {
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.target(getNextLatLng())
|
||||
.bearing(270)
|
||||
.tilt(20)
|
||||
.build();
|
||||
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 7500, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private LatLng getNextLatLng() {
|
||||
cameraState = !cameraState;
|
||||
return cameraState ? LAT_LNG_TOWER_BRIDGE : LAT_LNG_LONDON_EYE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnCameraIdleListener(cameraIdleListener);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.CancelableCallback
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Test activity showcasing the Camera API and listen to camera updates by animating the camera
|
||||
* above London.
|
||||
*
|
||||
* Shows how to use animate, ease and move camera update factory methods.
|
||||
*/
|
||||
class CameraAnimationTypeActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private val callback: CancelableCallback =
|
||||
object : CancelableCallback {
|
||||
override fun onCancel() {
|
||||
Timber.i("Duration onCancel Callback called.")
|
||||
Toast.makeText(
|
||||
this@CameraAnimationTypeActivity.applicationContext,
|
||||
"Ease onCancel Callback called.",
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
Timber.i("Duration onFinish Callback called.")
|
||||
Toast.makeText(
|
||||
this@CameraAnimationTypeActivity.applicationContext,
|
||||
"Ease onFinish Callback called.",
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var mapView: MapView
|
||||
private var cameraState = false
|
||||
private val cameraIdleListener = OnCameraIdleListener {
|
||||
if (mapboxMap != null) {
|
||||
Timber.w(mapboxMap!!.cameraPosition.toString())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_camera_animation_types)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(Style.getPredefinedStyle("Streets")))
|
||||
mapboxMap!!.uiSettings.isAttributionEnabled = false
|
||||
mapboxMap!!.uiSettings.isLogoEnabled = false
|
||||
mapboxMap!!.addOnCameraIdleListener(cameraIdleListener)
|
||||
|
||||
// handle move button clicks
|
||||
val moveButton = findViewById<View>(R.id.cameraMoveButton)
|
||||
moveButton?.setOnClickListener { view: View? ->
|
||||
val cameraPosition =
|
||||
CameraPosition.Builder()
|
||||
.target(nextLatLng)
|
||||
.zoom(14.0)
|
||||
.tilt(30.0)
|
||||
.tilt(0.0)
|
||||
.build()
|
||||
mapboxMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
}
|
||||
|
||||
// handle ease button clicks
|
||||
val easeButton = findViewById<View>(R.id.cameraEaseButton)
|
||||
easeButton?.setOnClickListener { view: View? ->
|
||||
val cameraPosition =
|
||||
CameraPosition.Builder()
|
||||
.target(nextLatLng)
|
||||
.zoom(15.0)
|
||||
.bearing(180.0)
|
||||
.tilt(30.0)
|
||||
.build()
|
||||
mapboxMap!!.easeCamera(
|
||||
CameraUpdateFactory.newCameraPosition(cameraPosition),
|
||||
7500,
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
// handle animate button clicks
|
||||
val animateButton = findViewById<View>(R.id.cameraAnimateButton)
|
||||
animateButton?.setOnClickListener { view: View? ->
|
||||
val cameraPosition =
|
||||
CameraPosition.Builder().target(nextLatLng).bearing(270.0).tilt(20.0).build()
|
||||
mapboxMap!!.animateCamera(
|
||||
CameraUpdateFactory.newCameraPosition(cameraPosition),
|
||||
7500,
|
||||
callback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val nextLatLng: LatLng
|
||||
private get() {
|
||||
cameraState = !cameraState
|
||||
return if (cameraState) LAT_LNG_TOWER_BRIDGE else LAT_LNG_LONDON_EYE
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnCameraIdleListener(cameraIdleListener)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LAT_LNG_LONDON_EYE = LatLng(51.50325, -0.11968)
|
||||
private val LAT_LNG_TOWER_BRIDGE = LatLng(51.50550, -0.07520)
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.TypeEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnticipateOvershootInterpolator;
|
||||
import android.view.animation.BounceInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.collection.LongSparseArray;
|
||||
import androidx.core.view.animation.PathInterpolatorCompat;
|
||||
import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using Android SDK animators to animate camera position changes.
|
||||
*/
|
||||
public class CameraAnimatorActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private static final double ANIMATION_DELAY_FACTOR = 1.5;
|
||||
private static final LatLng START_LAT_LNG = new LatLng(37.787947, -122.407432);
|
||||
|
||||
private final LongSparseArray<Animator> animators = new LongSparseArray<>();
|
||||
private Animator set;
|
||||
|
||||
{
|
||||
AnimatorSet accelerateDecelerateAnimatorSet = new AnimatorSet();
|
||||
accelerateDecelerateAnimatorSet.playTogether(
|
||||
createLatLngAnimator(START_LAT_LNG, new LatLng(37.826715, -122.422795)),
|
||||
obtainExampleInterpolator(new FastOutSlowInInterpolator(), 2500)
|
||||
);
|
||||
animators.put(R.id.menu_action_accelerate_decelerate_interpolator, accelerateDecelerateAnimatorSet);
|
||||
|
||||
AnimatorSet bounceAnimatorSet = new AnimatorSet();
|
||||
bounceAnimatorSet.playTogether(
|
||||
createLatLngAnimator(START_LAT_LNG, new LatLng(37.787947, -122.407432)),
|
||||
obtainExampleInterpolator(new BounceInterpolator(), 3750)
|
||||
);
|
||||
animators.put(R.id.menu_action_bounce_interpolator, bounceAnimatorSet);
|
||||
|
||||
animators.put(R.id.menu_action_anticipate_overshoot_interpolator,
|
||||
obtainExampleInterpolator(new AnticipateOvershootInterpolator(), 2500)
|
||||
);
|
||||
|
||||
animators.put(R.id.menu_action_path_interpolator, obtainExampleInterpolator(
|
||||
PathInterpolatorCompat.create(.22f, .68f, 0, 1.71f), 2500));
|
||||
}
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_camera_animator);
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
if (mapView != null) {
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull final MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
initFab();
|
||||
}
|
||||
|
||||
private void initFab() {
|
||||
findViewById(R.id.fab).setOnClickListener(view -> {
|
||||
view.setVisibility(View.GONE);
|
||||
|
||||
CameraPosition animatedPosition = new CameraPosition.Builder()
|
||||
.target(new LatLng(37.789992, -122.402214))
|
||||
.tilt(60)
|
||||
.zoom(14.5f)
|
||||
.bearing(135)
|
||||
.build();
|
||||
|
||||
set = createExampleAnimator(mapboxMap.getCameraPosition(), animatedPosition);
|
||||
set.start();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Animator API used for the animation on the FAB
|
||||
//
|
||||
|
||||
private Animator createExampleAnimator(CameraPosition currentPosition, CameraPosition targetPosition) {
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.play(createLatLngAnimator(currentPosition.target, targetPosition.target));
|
||||
animatorSet.play(createZoomAnimator(currentPosition.zoom, targetPosition.zoom));
|
||||
animatorSet.play(createBearingAnimator(currentPosition.bearing, targetPosition.bearing));
|
||||
animatorSet.play(createTiltAnimator(currentPosition.tilt, targetPosition.tilt));
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
private Animator createLatLngAnimator(LatLng currentPosition, LatLng targetPosition) {
|
||||
ValueAnimator latLngAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), currentPosition, targetPosition);
|
||||
latLngAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR));
|
||||
latLngAnimator.setInterpolator(new FastOutSlowInInterpolator());
|
||||
latLngAnimator.addUpdateListener(animation -> mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newLatLng((LatLng) animation.getAnimatedValue()))
|
||||
);
|
||||
return latLngAnimator;
|
||||
}
|
||||
|
||||
private Animator createZoomAnimator(double currentZoom, double targetZoom) {
|
||||
ValueAnimator zoomAnimator = ValueAnimator.ofFloat((float) currentZoom, (float) targetZoom);
|
||||
zoomAnimator.setDuration((long) (2200 * ANIMATION_DELAY_FACTOR));
|
||||
zoomAnimator.setStartDelay((long) (600 * ANIMATION_DELAY_FACTOR));
|
||||
zoomAnimator.setInterpolator(new AnticipateOvershootInterpolator());
|
||||
zoomAnimator.addUpdateListener(animation -> mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.zoomTo((Float) animation.getAnimatedValue()))
|
||||
);
|
||||
return zoomAnimator;
|
||||
}
|
||||
|
||||
private Animator createBearingAnimator(double currentBearing, double targetBearing) {
|
||||
ValueAnimator bearingAnimator = ValueAnimator.ofFloat((float) currentBearing, (float) targetBearing);
|
||||
bearingAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR));
|
||||
bearingAnimator.setStartDelay((long) (1000 * ANIMATION_DELAY_FACTOR));
|
||||
bearingAnimator.setInterpolator(new FastOutLinearInInterpolator());
|
||||
bearingAnimator.addUpdateListener(animation -> mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.bearingTo((Float) animation.getAnimatedValue()))
|
||||
);
|
||||
return bearingAnimator;
|
||||
}
|
||||
|
||||
private Animator createTiltAnimator(double currentTilt, double targetTilt) {
|
||||
ValueAnimator tiltAnimator = ValueAnimator.ofFloat((float) currentTilt, (float) targetTilt);
|
||||
tiltAnimator.setDuration((long) (1000 * ANIMATION_DELAY_FACTOR));
|
||||
tiltAnimator.setStartDelay((long) (1500 * ANIMATION_DELAY_FACTOR));
|
||||
tiltAnimator.addUpdateListener(animation -> mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.tiltTo((Float) animation.getAnimatedValue()))
|
||||
);
|
||||
return tiltAnimator;
|
||||
}
|
||||
|
||||
//
|
||||
// Interpolator examples
|
||||
//
|
||||
|
||||
private Animator obtainExampleInterpolator(int menuItemId) {
|
||||
return animators.get(menuItemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_animator, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (mapboxMap == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.getItemId() != android.R.id.home) {
|
||||
findViewById(R.id.fab).setVisibility(View.GONE);
|
||||
resetCameraPosition();
|
||||
playAnimation(item.getItemId());
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void resetCameraPosition() {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
|
||||
new CameraPosition.Builder()
|
||||
.target(START_LAT_LNG)
|
||||
.zoom(11)
|
||||
.bearing(0)
|
||||
.tilt(0)
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
private void playAnimation(int itemId) {
|
||||
Animator animator = obtainExampleInterpolator(itemId);
|
||||
if (animator != null) {
|
||||
animator.cancel();
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
private Animator obtainExampleInterpolator(Interpolator interpolator, long duration) {
|
||||
ValueAnimator zoomAnimator = ValueAnimator.ofFloat(11.0f, 16.0f);
|
||||
zoomAnimator.setDuration((long) (duration * ANIMATION_DELAY_FACTOR));
|
||||
zoomAnimator.setInterpolator(interpolator);
|
||||
zoomAnimator.addUpdateListener(animation -> mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.zoomTo((Float) animation.getAnimatedValue()))
|
||||
);
|
||||
return zoomAnimator;
|
||||
}
|
||||
|
||||
//
|
||||
// MapView lifecycle
|
||||
//
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
for (int i = 0; i < animators.size(); i++) {
|
||||
animators.get(animators.keyAt(i)).cancel();
|
||||
}
|
||||
if (set != null) {
|
||||
set.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to evaluate LatLng objects with a ValueAnimator
|
||||
*/
|
||||
private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
|
||||
|
||||
private final LatLng latLng = new LatLng();
|
||||
|
||||
@Override
|
||||
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
|
||||
latLng.setLatitude(startValue.getLatitude()
|
||||
+ ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
|
||||
latLng.setLongitude(startValue.getLongitude()
|
||||
+ ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
|
||||
return latLng;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.TypeEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.animation.AnticipateOvershootInterpolator
|
||||
import android.view.animation.BounceInterpolator
|
||||
import android.view.animation.Interpolator
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.collection.LongSparseArray
|
||||
import androidx.core.view.animation.PathInterpolatorCompat
|
||||
import androidx.interpolator.view.animation.FastOutLinearInInterpolator
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/** Test activity showcasing using Android SDK animators to animate camera position changes. */
|
||||
class CameraAnimatorActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private val animators = LongSparseArray<Animator>()
|
||||
private lateinit var set: Animator
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_camera_animator)
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
if (mapView != null) {
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
initFab()
|
||||
}
|
||||
|
||||
private fun initFab() {
|
||||
findViewById<View>(R.id.fab).setOnClickListener { view: View ->
|
||||
view.visibility = View.GONE
|
||||
val animatedPosition =
|
||||
CameraPosition.Builder()
|
||||
.target(LatLng(37.789992, -122.402214))
|
||||
.tilt(60.0)
|
||||
.zoom(14.5)
|
||||
.bearing(135.0)
|
||||
.build()
|
||||
set = createExampleAnimator(mapboxMap!!.cameraPosition, animatedPosition)
|
||||
set!!.start()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Animator API used for the animation on the FAB
|
||||
//
|
||||
private fun createExampleAnimator(
|
||||
currentPosition: CameraPosition,
|
||||
targetPosition: CameraPosition
|
||||
): Animator {
|
||||
val animatorSet = AnimatorSet()
|
||||
animatorSet.play(createLatLngAnimator(currentPosition.target, targetPosition.target))
|
||||
animatorSet.play(createZoomAnimator(currentPosition.zoom, targetPosition.zoom))
|
||||
animatorSet.play(createBearingAnimator(currentPosition.bearing, targetPosition.bearing))
|
||||
animatorSet.play(createTiltAnimator(currentPosition.tilt, targetPosition.tilt))
|
||||
return animatorSet
|
||||
}
|
||||
|
||||
private fun createLatLngAnimator(currentPosition: LatLng, targetPosition: LatLng): Animator {
|
||||
val latLngAnimator =
|
||||
ValueAnimator.ofObject(LatLngEvaluator(), currentPosition, targetPosition)
|
||||
latLngAnimator.duration = (1000 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
latLngAnimator.interpolator = FastOutSlowInInterpolator()
|
||||
latLngAnimator.addUpdateListener { animation: ValueAnimator ->
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.newLatLng((animation.animatedValue as LatLng))
|
||||
)
|
||||
}
|
||||
return latLngAnimator
|
||||
}
|
||||
|
||||
private fun createZoomAnimator(currentZoom: Double, targetZoom: Double): Animator {
|
||||
val zoomAnimator = ValueAnimator.ofFloat(currentZoom.toFloat(), targetZoom.toFloat())
|
||||
zoomAnimator.duration = (2200 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
zoomAnimator.startDelay = (600 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
zoomAnimator.interpolator = AnticipateOvershootInterpolator()
|
||||
zoomAnimator.addUpdateListener { animation: ValueAnimator ->
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.zoomTo((animation.animatedValue as Float).toDouble())
|
||||
)
|
||||
}
|
||||
return zoomAnimator
|
||||
}
|
||||
|
||||
private fun createBearingAnimator(currentBearing: Double, targetBearing: Double): Animator {
|
||||
val bearingAnimator =
|
||||
ValueAnimator.ofFloat(currentBearing.toFloat(), targetBearing.toFloat())
|
||||
bearingAnimator.duration = (1000 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
bearingAnimator.startDelay = (1000 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
bearingAnimator.interpolator = FastOutLinearInInterpolator()
|
||||
bearingAnimator.addUpdateListener { animation: ValueAnimator ->
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.bearingTo((animation.animatedValue as Float).toDouble())
|
||||
)
|
||||
}
|
||||
return bearingAnimator
|
||||
}
|
||||
|
||||
private fun createTiltAnimator(currentTilt: Double, targetTilt: Double): Animator {
|
||||
val tiltAnimator = ValueAnimator.ofFloat(currentTilt.toFloat(), targetTilt.toFloat())
|
||||
tiltAnimator.duration = (1000 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
tiltAnimator.startDelay = (1500 * ANIMATION_DELAY_FACTOR).toLong()
|
||||
tiltAnimator.addUpdateListener { animation: ValueAnimator ->
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.tiltTo((animation.animatedValue as Float).toDouble())
|
||||
)
|
||||
}
|
||||
return tiltAnimator
|
||||
}
|
||||
|
||||
//
|
||||
// Interpolator examples
|
||||
//
|
||||
private fun obtainExampleInterpolator(menuItemId: Int): Animator? {
|
||||
return animators[menuItemId.toLong()]
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_animator, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (mapboxMap == null) {
|
||||
return false
|
||||
}
|
||||
if (item.itemId != android.R.id.home) {
|
||||
findViewById<View>(R.id.fab).visibility = View.GONE
|
||||
resetCameraPosition()
|
||||
playAnimation(item.itemId)
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun resetCameraPosition() {
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.newCameraPosition(
|
||||
CameraPosition.Builder()
|
||||
.target(START_LAT_LNG)
|
||||
.zoom(11.0)
|
||||
.bearing(0.0)
|
||||
.tilt(0.0)
|
||||
.build()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun playAnimation(itemId: Int) {
|
||||
val animator = obtainExampleInterpolator(itemId)
|
||||
if (animator != null) {
|
||||
animator.cancel()
|
||||
animator.start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun obtainExampleInterpolator(interpolator: Interpolator, duration: Long): Animator {
|
||||
val zoomAnimator = ValueAnimator.ofFloat(11.0f, 16.0f)
|
||||
zoomAnimator.duration = (duration * ANIMATION_DELAY_FACTOR).toLong()
|
||||
zoomAnimator.interpolator = interpolator
|
||||
zoomAnimator.addUpdateListener { animation: ValueAnimator ->
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.zoomTo((animation.animatedValue as Float).toDouble())
|
||||
)
|
||||
}
|
||||
return zoomAnimator
|
||||
}
|
||||
|
||||
//
|
||||
// MapView lifecycle
|
||||
//
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
for (i in 0 until animators.size()) {
|
||||
animators[animators.keyAt(i)]!!.cancel()
|
||||
}
|
||||
if (set != null) {
|
||||
set!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
/** Helper class to evaluate LatLng objects with a ValueAnimator */
|
||||
private class LatLngEvaluator : TypeEvaluator<LatLng> {
|
||||
private val latLng = LatLng()
|
||||
override fun evaluate(fraction: Float, startValue: LatLng, endValue: LatLng): LatLng {
|
||||
latLng.latitude =
|
||||
(startValue.latitude + (endValue.latitude - startValue.latitude) * fraction)
|
||||
latLng.longitude =
|
||||
(startValue.longitude + (endValue.longitude - startValue.longitude) * fraction)
|
||||
return latLng
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ANIMATION_DELAY_FACTOR = 1.5
|
||||
private val START_LAT_LNG = LatLng(37.787947, -122.407432)
|
||||
}
|
||||
|
||||
init {
|
||||
val accelerateDecelerateAnimatorSet = AnimatorSet()
|
||||
accelerateDecelerateAnimatorSet.playTogether(
|
||||
createLatLngAnimator(START_LAT_LNG, LatLng(37.826715, -122.422795)),
|
||||
obtainExampleInterpolator(FastOutSlowInInterpolator(), 2500)
|
||||
)
|
||||
animators.put(
|
||||
R.id.menu_action_accelerate_decelerate_interpolator.toLong(),
|
||||
accelerateDecelerateAnimatorSet
|
||||
)
|
||||
val bounceAnimatorSet = AnimatorSet()
|
||||
bounceAnimatorSet.playTogether(
|
||||
createLatLngAnimator(START_LAT_LNG, LatLng(37.787947, -122.407432)),
|
||||
obtainExampleInterpolator(BounceInterpolator(), 3750)
|
||||
)
|
||||
animators.put(R.id.menu_action_bounce_interpolator.toLong(), bounceAnimatorSet)
|
||||
animators.put(
|
||||
R.id.menu_action_anticipate_overshoot_interpolator.toLong(),
|
||||
obtainExampleInterpolator(AnticipateOvershootInterpolator(), 2500)
|
||||
)
|
||||
animators.put(
|
||||
R.id.menu_action_path_interpolator.toLong(),
|
||||
obtainExampleInterpolator(
|
||||
PathInterpolatorCompat.create(.22f, .68f, 0f, 1.71f),
|
||||
2500
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.mapbox.mapboxsdk.constants.GeometryConstants.MAX_LATITUDE;
|
||||
import static com.mapbox.mapboxsdk.constants.GeometryConstants.MIN_LATITUDE;
|
||||
|
||||
/**
|
||||
* Test activity showcasing how to listen to camera change events.
|
||||
*/
|
||||
public class CameraPositionActivity extends FragmentActivity implements OnMapReadyCallback, View.OnClickListener,
|
||||
MapboxMap.OnMapLongClickListener {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private FloatingActionButton fab;
|
||||
private boolean logCameraChanges;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_camera_position);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(R.string.activity_camera_position);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_ab_back);
|
||||
toolbar.setNavigationOnClickListener(v -> finish());
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull final MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
map.setStyle(Style.getPredefinedStyle("Satellite Hybrid"), style -> {
|
||||
// add a listener to FAB
|
||||
fab = findViewById(R.id.fab);
|
||||
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, R.color.primary));
|
||||
fab.setOnClickListener(this);
|
||||
|
||||
toggleLogCameraChanges();
|
||||
|
||||
// listen to long click events to toggle logging camera changes
|
||||
mapboxMap.addOnMapLongClickListener(this);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMapLongClick(@NonNull LatLng point) {
|
||||
toggleLogCameraChanges();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Context context = view.getContext();
|
||||
final View dialogContent = LayoutInflater.from(context).inflate(R.layout.dialog_camera_position, null);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(R.string.dialog_camera_position);
|
||||
builder.setView(onInflateDialogContent(dialogContent));
|
||||
builder.setPositiveButton("Animate", new DialogClickListener(mapboxMap, dialogContent));
|
||||
builder.setNegativeButton("Cancel", null);
|
||||
builder.setCancelable(false);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void toggleLogCameraChanges() {
|
||||
logCameraChanges = !logCameraChanges;
|
||||
if (logCameraChanges) {
|
||||
mapboxMap.addOnCameraIdleListener(idleListener);
|
||||
mapboxMap.addOnCameraMoveCancelListener(moveCanceledListener);
|
||||
mapboxMap.addOnCameraMoveListener(moveListener);
|
||||
mapboxMap.addOnCameraMoveStartedListener(moveStartedListener);
|
||||
} else {
|
||||
mapboxMap.removeOnCameraIdleListener(idleListener);
|
||||
mapboxMap.removeOnCameraMoveCancelListener(moveCanceledListener);
|
||||
mapboxMap.removeOnCameraMoveListener(moveListener);
|
||||
mapboxMap.removeOnCameraMoveStartedListener(moveStartedListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnMapLongClickListener(this);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
private View onInflateDialogContent(View view) {
|
||||
linkTextView(view, R.id.value_lat, R.id.seekbar_lat, new LatLngChangeListener(), 180 + 38);
|
||||
linkTextView(view, R.id.value_lon, R.id.seekbar_lon, new LatLngChangeListener(), 180 - 77);
|
||||
linkTextView(view, R.id.value_zoom, R.id.seekbar_zoom, new ValueChangeListener(), 6);
|
||||
linkTextView(view, R.id.value_bearing, R.id.seekbar_bearing, new ValueChangeListener(), 90);
|
||||
linkTextView(view, R.id.value_tilt, R.id.seekbar_tilt, new ValueChangeListener(), 40);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void linkTextView(
|
||||
View view, @IdRes int textViewRes, @IdRes int seekBarRes, ValueChangeListener listener, int defaultValue) {
|
||||
final TextView value = (TextView) view.findViewById(textViewRes);
|
||||
SeekBar seekBar = (SeekBar) view.findViewById(seekBarRes);
|
||||
listener.setLinkedValueView(value);
|
||||
seekBar.setOnSeekBarChangeListener(listener);
|
||||
seekBar.setProgress(defaultValue);
|
||||
}
|
||||
|
||||
private MapboxMap.OnCameraIdleListener idleListener = new MapboxMap.OnCameraIdleListener() {
|
||||
@Override
|
||||
public void onCameraIdle() {
|
||||
Timber.e("OnCameraIdle");
|
||||
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_green_dark));
|
||||
}
|
||||
};
|
||||
|
||||
private MapboxMap.OnCameraMoveListener moveListener = new MapboxMap.OnCameraMoveListener() {
|
||||
@Override
|
||||
public void onCameraMove() {
|
||||
Timber.e("OnCameraMove");
|
||||
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_orange_dark));
|
||||
}
|
||||
};
|
||||
|
||||
private MapboxMap.OnCameraMoveCanceledListener moveCanceledListener = () -> Timber.e("OnCameraMoveCanceled");
|
||||
|
||||
private MapboxMap.OnCameraMoveStartedListener moveStartedListener = new MapboxMap.OnCameraMoveStartedListener() {
|
||||
|
||||
private final String[] REASONS = {"REASON_API_GESTURE", "REASON_DEVELOPER_ANIMATION", "REASON_API_ANIMATION"};
|
||||
|
||||
@Override
|
||||
public void onCameraMoveStarted(int reason) {
|
||||
// reason ranges from 1 <-> 3
|
||||
fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, android.R.color.holo_red_dark));
|
||||
Timber.e("OnCameraMoveStarted: %s", REASONS[reason - 1]);
|
||||
}
|
||||
};
|
||||
|
||||
private class ValueChangeListener implements SeekBar.OnSeekBarChangeListener {
|
||||
|
||||
protected TextView textView;
|
||||
|
||||
public void setLinkedValueView(TextView textView) {
|
||||
this.textView = textView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
textView.setText(String.valueOf(progress));
|
||||
}
|
||||
}
|
||||
|
||||
private class LatLngChangeListener extends ValueChangeListener {
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
super.onProgressChanged(seekBar, progress - 180, fromUser);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DialogClickListener implements DialogInterface.OnClickListener {
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private View dialogContent;
|
||||
|
||||
public DialogClickListener(MapboxMap mapboxMap, View view) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
this.dialogContent = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
double latitude = Double.parseDouble(
|
||||
((TextView) dialogContent.findViewById(R.id.value_lat)).getText().toString());
|
||||
double longitude = Double.parseDouble(
|
||||
((TextView) dialogContent.findViewById(R.id.value_lon)).getText().toString());
|
||||
double zoom = Double.parseDouble(
|
||||
((TextView) dialogContent.findViewById(R.id.value_zoom)).getText().toString());
|
||||
double bearing = Double.parseDouble(
|
||||
((TextView) dialogContent.findViewById(R.id.value_bearing)).getText().toString());
|
||||
double tilt = Double.parseDouble(
|
||||
((TextView) dialogContent.findViewById(R.id.value_tilt)).getText().toString());
|
||||
|
||||
if (latitude < MIN_LATITUDE || latitude > MAX_LATITUDE) {
|
||||
Toast.makeText(dialogContent.getContext(), "latitude value must be set "
|
||||
+ " between " + MIN_LATITUDE + " and " + MAX_LATITUDE,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.target(new LatLng(latitude, longitude))
|
||||
.zoom(zoom)
|
||||
.bearing(bearing)
|
||||
.tilt(tilt)
|
||||
.build();
|
||||
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000,
|
||||
new MapboxMap.CancelableCallback() {
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Timber.v("OnCancel called");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
Timber.v("OnFinish called");
|
||||
}
|
||||
});
|
||||
Timber.v(cameraPosition.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.SeekBar
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.constants.GeometryConstants
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.*
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import timber.log.Timber
|
||||
|
||||
/** Test activity showcasing how to listen to camera change events. */
|
||||
class CameraPositionActivity :
|
||||
FragmentActivity(), OnMapReadyCallback, View.OnClickListener, OnMapLongClickListener {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var fab: FloatingActionButton
|
||||
private var logCameraChanges = false
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_camera_position)
|
||||
val toolbar = findViewById<Toolbar>(R.id.toolbar)
|
||||
toolbar.setTitle(R.string.activity_camera_position)
|
||||
toolbar.setNavigationIcon(R.drawable.ic_ab_back)
|
||||
toolbar.setNavigationOnClickListener { v: View? -> finish() }
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
map.setStyle(Style.getPredefinedStyle("Satellite Hybrid")) { style: Style? ->
|
||||
// add a listener to FAB
|
||||
fab = findViewById(R.id.fab)
|
||||
fab.setColorFilter(ContextCompat.getColor(this@CameraPositionActivity, R.color.primary))
|
||||
fab.setOnClickListener(this)
|
||||
toggleLogCameraChanges()
|
||||
|
||||
// listen to long click events to toggle logging camera changes
|
||||
mapboxMap!!.addOnMapLongClickListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMapLongClick(point: LatLng): Boolean {
|
||||
toggleLogCameraChanges()
|
||||
return false
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
override fun onClick(view: View) {
|
||||
val context = view.context
|
||||
val dialogContent =
|
||||
LayoutInflater.from(context).inflate(R.layout.dialog_camera_position, null)
|
||||
val builder = AlertDialog.Builder(context)
|
||||
builder.setTitle(R.string.dialog_camera_position)
|
||||
builder.setView(onInflateDialogContent(dialogContent))
|
||||
builder.setPositiveButton("Animate", DialogClickListener(mapboxMap, dialogContent))
|
||||
builder.setNegativeButton("Cancel", null)
|
||||
builder.setCancelable(false)
|
||||
builder.show()
|
||||
}
|
||||
|
||||
private fun toggleLogCameraChanges() {
|
||||
logCameraChanges = !logCameraChanges
|
||||
if (logCameraChanges) {
|
||||
mapboxMap!!.addOnCameraIdleListener(idleListener)
|
||||
mapboxMap!!.addOnCameraMoveCancelListener(moveCanceledListener)
|
||||
mapboxMap!!.addOnCameraMoveListener(moveListener)
|
||||
mapboxMap!!.addOnCameraMoveStartedListener(moveStartedListener)
|
||||
} else {
|
||||
mapboxMap!!.removeOnCameraIdleListener(idleListener)
|
||||
mapboxMap!!.removeOnCameraMoveCancelListener(moveCanceledListener)
|
||||
mapboxMap!!.removeOnCameraMoveListener(moveListener)
|
||||
mapboxMap!!.removeOnCameraMoveStartedListener(moveStartedListener)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnMapLongClickListener(this)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
private fun onInflateDialogContent(view: View): View {
|
||||
linkTextView(view, R.id.value_lat, R.id.seekbar_lat, LatLngChangeListener(), 180 + 38)
|
||||
linkTextView(view, R.id.value_lon, R.id.seekbar_lon, LatLngChangeListener(), 180 - 77)
|
||||
linkTextView(view, R.id.value_zoom, R.id.seekbar_zoom, ValueChangeListener(), 6)
|
||||
linkTextView(view, R.id.value_bearing, R.id.seekbar_bearing, ValueChangeListener(), 90)
|
||||
linkTextView(view, R.id.value_tilt, R.id.seekbar_tilt, ValueChangeListener(), 40)
|
||||
return view
|
||||
}
|
||||
|
||||
private fun linkTextView(
|
||||
view: View,
|
||||
@IdRes textViewRes: Int,
|
||||
@IdRes seekBarRes: Int,
|
||||
listener: ValueChangeListener,
|
||||
defaultValue: Int
|
||||
) {
|
||||
val value = view.findViewById<View>(textViewRes) as TextView
|
||||
val seekBar = view.findViewById<View>(seekBarRes) as SeekBar
|
||||
listener.setLinkedValueView(value)
|
||||
seekBar.setOnSeekBarChangeListener(listener)
|
||||
seekBar.progress = defaultValue
|
||||
}
|
||||
|
||||
private val idleListener = OnCameraIdleListener {
|
||||
Timber.e("OnCameraIdle")
|
||||
fab!!.setColorFilter(
|
||||
ContextCompat.getColor(this@CameraPositionActivity, android.R.color.holo_green_dark)
|
||||
)
|
||||
}
|
||||
private val moveListener = OnCameraMoveListener {
|
||||
Timber.e("OnCameraMove")
|
||||
fab!!.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
this@CameraPositionActivity,
|
||||
android.R.color.holo_orange_dark
|
||||
)
|
||||
)
|
||||
}
|
||||
private val moveCanceledListener = OnCameraMoveCanceledListener {
|
||||
Timber.e("OnCameraMoveCanceled")
|
||||
}
|
||||
private val moveStartedListener: OnCameraMoveStartedListener =
|
||||
object : OnCameraMoveStartedListener {
|
||||
private val REASONS =
|
||||
arrayOf(
|
||||
"REASON_API_GESTURE",
|
||||
"REASON_DEVELOPER_ANIMATION",
|
||||
"REASON_API_ANIMATION"
|
||||
)
|
||||
|
||||
override fun onCameraMoveStarted(reason: Int) {
|
||||
// reason ranges from 1 <-> 3
|
||||
fab!!.setColorFilter(
|
||||
ContextCompat.getColor(
|
||||
this@CameraPositionActivity,
|
||||
android.R.color.holo_red_dark
|
||||
)
|
||||
)
|
||||
Timber.e("OnCameraMoveStarted: %s", REASONS[reason - 1])
|
||||
}
|
||||
}
|
||||
|
||||
private open inner class ValueChangeListener : OnSeekBarChangeListener {
|
||||
protected var textView: TextView? = null
|
||||
fun setLinkedValueView(textView: TextView?) {
|
||||
this.textView = textView
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {}
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
textView!!.text = progress.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class LatLngChangeListener : ValueChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
super.onProgressChanged(seekBar, progress - 180, fromUser)
|
||||
}
|
||||
}
|
||||
|
||||
private class DialogClickListener(
|
||||
private val mapboxMap: MapboxMap?,
|
||||
private val dialogContent: View
|
||||
) : DialogInterface.OnClickListener {
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
val latitude =
|
||||
(dialogContent.findViewById<View>(R.id.value_lat) as TextView)
|
||||
.text
|
||||
.toString()
|
||||
.toDouble()
|
||||
val longitude =
|
||||
(dialogContent.findViewById<View>(R.id.value_lon) as TextView)
|
||||
.text
|
||||
.toString()
|
||||
.toDouble()
|
||||
val zoom =
|
||||
(dialogContent.findViewById<View>(R.id.value_zoom) as TextView)
|
||||
.text
|
||||
.toString()
|
||||
.toDouble()
|
||||
val bearing =
|
||||
(dialogContent.findViewById<View>(R.id.value_bearing) as TextView)
|
||||
.text
|
||||
.toString()
|
||||
.toDouble()
|
||||
val tilt =
|
||||
(dialogContent.findViewById<View>(R.id.value_tilt) as TextView)
|
||||
.text
|
||||
.toString()
|
||||
.toDouble()
|
||||
if (latitude < GeometryConstants.MIN_LATITUDE ||
|
||||
latitude > GeometryConstants.MAX_LATITUDE
|
||||
) {
|
||||
Toast.makeText(
|
||||
dialogContent.context,
|
||||
"latitude value must be set " +
|
||||
" between " +
|
||||
GeometryConstants.MIN_LATITUDE +
|
||||
" and " +
|
||||
GeometryConstants.MAX_LATITUDE,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
return
|
||||
}
|
||||
val cameraPosition =
|
||||
CameraPosition.Builder()
|
||||
.target(LatLng(latitude, longitude))
|
||||
.zoom(zoom)
|
||||
.bearing(bearing)
|
||||
.tilt(tilt)
|
||||
.build()
|
||||
mapboxMap!!.animateCamera(
|
||||
CameraUpdateFactory.newCameraPosition(cameraPosition),
|
||||
5000,
|
||||
object : CancelableCallback {
|
||||
override fun onCancel() {
|
||||
Timber.v("OnCancel called")
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
Timber.v("OnFinish called")
|
||||
}
|
||||
}
|
||||
)
|
||||
Timber.v(cameraPosition.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,460 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.mapbox.android.gestures.AndroidGesturesManager;
|
||||
import com.mapbox.android.gestures.MoveGestureDetector;
|
||||
import com.mapbox.android.gestures.RotateGestureDetector;
|
||||
import com.mapbox.android.gestures.ShoveGestureDetector;
|
||||
import com.mapbox.android.gestures.StandardScaleGestureDetector;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.FontCache;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
/**
|
||||
* Test activity showcasing APIs around gestures implementation.
|
||||
*/
|
||||
public class GestureDetectorActivity extends AppCompatActivity {
|
||||
|
||||
private static final int MAX_NUMBER_OF_ALERTS = 30;
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private RecyclerView recyclerView;
|
||||
private GestureAlertsAdapter gestureAlertsAdapter;
|
||||
|
||||
private AndroidGesturesManager gesturesManager;
|
||||
|
||||
@Nullable
|
||||
private Marker marker;
|
||||
@Nullable
|
||||
private LatLng focalPointLatLng;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_gesture_detector);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
GestureDetectorActivity.this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
initializeMap();
|
||||
});
|
||||
|
||||
recyclerView = findViewById(R.id.alerts_recycler);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
|
||||
gestureAlertsAdapter = new GestureAlertsAdapter();
|
||||
recyclerView.setAdapter(gestureAlertsAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
gestureAlertsAdapter.cancelUpdates();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
private void initializeMap() {
|
||||
gesturesManager = mapboxMap.getGesturesManager();
|
||||
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) recyclerView.getLayoutParams();
|
||||
layoutParams.height = (int) (mapView.getHeight() / 1.75);
|
||||
layoutParams.width = (mapView.getWidth() / 3);
|
||||
recyclerView.setLayoutParams(layoutParams);
|
||||
|
||||
attachListeners();
|
||||
|
||||
fixedFocalPointEnabled(mapboxMap.getUiSettings().getFocalPoint() != null);
|
||||
}
|
||||
|
||||
public void attachListeners() {
|
||||
mapboxMap.addOnMoveListener(new MapboxMap.OnMoveListener() {
|
||||
@Override
|
||||
public void onMoveBegin(@NonNull MoveGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_START, "MOVE START"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMove(@NonNull MoveGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_PROGRESS, "MOVE PROGRESS"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveEnd(@NonNull MoveGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_END, "MOVE END"));
|
||||
recalculateFocalPoint();
|
||||
}
|
||||
});
|
||||
|
||||
mapboxMap.addOnRotateListener(new MapboxMap.OnRotateListener() {
|
||||
@Override
|
||||
public void onRotateBegin(@NonNull RotateGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_START, "ROTATE START"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRotate(@NonNull RotateGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_PROGRESS, "ROTATE PROGRESS"));
|
||||
recalculateFocalPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRotateEnd(@NonNull RotateGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_END, "ROTATE END"));
|
||||
}
|
||||
});
|
||||
|
||||
mapboxMap.addOnScaleListener(new MapboxMap.OnScaleListener() {
|
||||
@Override
|
||||
public void onScaleBegin(@NonNull StandardScaleGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_START, "SCALE START"));
|
||||
if (focalPointLatLng != null) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_OTHER, "INCREASING MOVE THRESHOLD"));
|
||||
gesturesManager.getMoveGestureDetector().setMoveThreshold(
|
||||
ResourceUtils.convertDpToPx(GestureDetectorActivity.this, 175));
|
||||
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_OTHER, "MANUALLY INTERRUPTING MOVE"));
|
||||
gesturesManager.getMoveGestureDetector().interrupt();
|
||||
}
|
||||
recalculateFocalPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScale(@NonNull StandardScaleGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_PROGRESS, "SCALE PROGRESS"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleEnd(@NonNull StandardScaleGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_END, "SCALE END"));
|
||||
|
||||
if (focalPointLatLng != null) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_OTHER, "REVERTING MOVE THRESHOLD"));
|
||||
gesturesManager.getMoveGestureDetector().setMoveThreshold(0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mapboxMap.addOnShoveListener(new MapboxMap.OnShoveListener() {
|
||||
@Override
|
||||
public void onShoveBegin(@NonNull ShoveGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_START, "SHOVE START"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShove(@NonNull ShoveGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_PROGRESS, "SHOVE PROGRESS"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShoveEnd(@NonNull ShoveGestureDetector detector) {
|
||||
gestureAlertsAdapter.addAlert(new GestureAlert(GestureAlert.TYPE_END, "SHOVE END"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_gestures, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
UiSettings uiSettings = mapboxMap.getUiSettings();
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_gesture_focus_point:
|
||||
fixedFocalPointEnabled(focalPointLatLng == null);
|
||||
return true;
|
||||
case R.id.menu_gesture_animation:
|
||||
uiSettings.setScaleVelocityAnimationEnabled(!uiSettings.isScaleVelocityAnimationEnabled());
|
||||
uiSettings.setRotateVelocityAnimationEnabled(!uiSettings.isRotateVelocityAnimationEnabled());
|
||||
uiSettings.setFlingVelocityAnimationEnabled(!uiSettings.isFlingVelocityAnimationEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_rotate:
|
||||
uiSettings.setRotateGesturesEnabled(!uiSettings.isRotateGesturesEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_tilt:
|
||||
uiSettings.setTiltGesturesEnabled(!uiSettings.isTiltGesturesEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_zoom:
|
||||
uiSettings.setZoomGesturesEnabled(!uiSettings.isZoomGesturesEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_scroll:
|
||||
uiSettings.setScrollGesturesEnabled(!uiSettings.isScrollGesturesEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_double_tap:
|
||||
uiSettings.setDoubleTapGesturesEnabled(!uiSettings.isDoubleTapGesturesEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_quick_zoom:
|
||||
uiSettings.setQuickZoomGesturesEnabled(!uiSettings.isQuickZoomGesturesEnabled());
|
||||
return true;
|
||||
case R.id.menu_gesture_scroll_horizontal:
|
||||
uiSettings.setHorizontalScrollGesturesEnabled(!uiSettings.isHorizontalScrollGesturesEnabled());
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void fixedFocalPointEnabled(boolean enabled) {
|
||||
if (enabled) {
|
||||
focalPointLatLng = new LatLng(51.50325, -0.12968);
|
||||
marker = mapboxMap.addMarker(new MarkerOptions().position(focalPointLatLng));
|
||||
mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(focalPointLatLng, 16),
|
||||
new MapboxMap.CancelableCallback() {
|
||||
@Override
|
||||
public void onCancel() {
|
||||
recalculateFocalPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
recalculateFocalPoint();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (marker != null) {
|
||||
mapboxMap.removeMarker(marker);
|
||||
marker = null;
|
||||
}
|
||||
focalPointLatLng = null;
|
||||
mapboxMap.getUiSettings().setFocalPoint(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void recalculateFocalPoint() {
|
||||
if (focalPointLatLng != null) {
|
||||
mapboxMap.getUiSettings().setFocalPoint(
|
||||
mapboxMap.getProjection().toScreenLocation(focalPointLatLng)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static class GestureAlertsAdapter extends RecyclerView.Adapter<GestureAlertsAdapter.ViewHolder> {
|
||||
|
||||
private boolean isUpdating;
|
||||
private final Handler updateHandler = new Handler();
|
||||
private final List<GestureAlert> alerts = new ArrayList<>();
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView alertMessageTv;
|
||||
|
||||
@ColorInt
|
||||
public int textColor;
|
||||
|
||||
ViewHolder(View view) {
|
||||
super(view);
|
||||
Typeface typeface = FontCache.get("Roboto-Regular.ttf", view.getContext());
|
||||
alertMessageTv = view.findViewById(R.id.alert_message);
|
||||
alertMessageTv.setTypeface(typeface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_gesture_alert, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
GestureAlert alert = alerts.get(position);
|
||||
holder.alertMessageTv.setText(alert.getMessage());
|
||||
holder.alertMessageTv.setTextColor(
|
||||
ContextCompat.getColor(holder.alertMessageTv.getContext(), alert.getColor()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return alerts.size();
|
||||
}
|
||||
|
||||
void addAlert(GestureAlert alert) {
|
||||
for (GestureAlert gestureAlert : alerts) {
|
||||
if (gestureAlert.getAlertType() != GestureAlert.TYPE_PROGRESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (alert.getAlertType() == GestureAlert.TYPE_PROGRESS && gestureAlert.equals(alert)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (getItemCount() >= MAX_NUMBER_OF_ALERTS) {
|
||||
alerts.remove(getItemCount() - 1);
|
||||
}
|
||||
|
||||
alerts.add(0, alert);
|
||||
if (!isUpdating) {
|
||||
isUpdating = true;
|
||||
updateHandler.postDelayed(updateRunnable, 250);
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable updateRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyDataSetChanged();
|
||||
isUpdating = false;
|
||||
}
|
||||
};
|
||||
|
||||
void cancelUpdates() {
|
||||
updateHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class GestureAlert {
|
||||
@Retention(SOURCE)
|
||||
@IntDef( {TYPE_NONE, TYPE_START, TYPE_PROGRESS, TYPE_END, TYPE_OTHER})
|
||||
@interface Type {
|
||||
}
|
||||
|
||||
static final int TYPE_NONE = 0;
|
||||
static final int TYPE_START = 1;
|
||||
static final int TYPE_END = 2;
|
||||
static final int TYPE_PROGRESS = 3;
|
||||
static final int TYPE_OTHER = 4;
|
||||
|
||||
@Type
|
||||
private int alertType;
|
||||
|
||||
private String message;
|
||||
|
||||
@ColorInt
|
||||
private int color;
|
||||
|
||||
GestureAlert(@Type int alertType, String message) {
|
||||
this.alertType = alertType;
|
||||
this.message = message;
|
||||
|
||||
switch (alertType) {
|
||||
case TYPE_NONE:
|
||||
color = android.R.color.black;
|
||||
break;
|
||||
case TYPE_END:
|
||||
color = android.R.color.holo_red_dark;
|
||||
break;
|
||||
case TYPE_OTHER:
|
||||
color = android.R.color.holo_purple;
|
||||
break;
|
||||
case TYPE_PROGRESS:
|
||||
color = android.R.color.holo_orange_dark;
|
||||
break;
|
||||
case TYPE_START:
|
||||
color = android.R.color.holo_green_dark;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int getAlertType() {
|
||||
return alertType;
|
||||
}
|
||||
|
||||
String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GestureAlert that = (GestureAlert) o;
|
||||
|
||||
if (alertType != that.alertType) {
|
||||
return false;
|
||||
}
|
||||
return message != null ? message.equals(that.message) : that.message == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = alertType;
|
||||
result = 31 * result + (message != null ? message.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.view.*
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.IntDef
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mapbox.android.gestures.*
|
||||
import com.mapbox.mapboxsdk.annotations.Marker
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.*
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.FontCache
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils
|
||||
import java.lang.annotation.Retention
|
||||
import java.lang.annotation.RetentionPolicy
|
||||
|
||||
/** Test activity showcasing APIs around gestures implementation. */
|
||||
class GestureDetectorActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private var gestureAlertsAdapter: GestureAlertsAdapter? = null
|
||||
private var gesturesManager: AndroidGesturesManager? = null
|
||||
private var marker: Marker? = null
|
||||
private var focalPointLatLng: LatLng? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_gesture_detector)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
this@GestureDetectorActivity.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
initializeMap()
|
||||
}
|
||||
)
|
||||
recyclerView = findViewById(R.id.alerts_recycler)
|
||||
recyclerView.setLayoutManager(LinearLayoutManager(this))
|
||||
gestureAlertsAdapter = GestureAlertsAdapter()
|
||||
recyclerView.setAdapter(gestureAlertsAdapter)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
gestureAlertsAdapter!!.cancelUpdates()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
private fun initializeMap() {
|
||||
gesturesManager = mapboxMap!!.gesturesManager
|
||||
val layoutParams = recyclerView!!.layoutParams as RelativeLayout.LayoutParams
|
||||
layoutParams.height = (mapView!!.height / 1.75).toInt()
|
||||
layoutParams.width = mapView!!.width / 3
|
||||
recyclerView!!.layoutParams = layoutParams
|
||||
attachListeners()
|
||||
fixedFocalPointEnabled(mapboxMap!!.uiSettings.focalPoint != null)
|
||||
}
|
||||
|
||||
fun attachListeners() {
|
||||
mapboxMap!!.addOnMoveListener(
|
||||
object : OnMoveListener {
|
||||
override fun onMoveBegin(detector: MoveGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_START, "MOVE START")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMove(detector: MoveGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_PROGRESS, "MOVE PROGRESS")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMoveEnd(detector: MoveGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_END, "MOVE END")
|
||||
)
|
||||
recalculateFocalPoint()
|
||||
}
|
||||
}
|
||||
)
|
||||
mapboxMap!!.addOnRotateListener(
|
||||
object : OnRotateListener {
|
||||
override fun onRotateBegin(detector: RotateGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_START, "ROTATE START")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRotate(detector: RotateGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_PROGRESS, "ROTATE PROGRESS")
|
||||
)
|
||||
recalculateFocalPoint()
|
||||
}
|
||||
|
||||
override fun onRotateEnd(detector: RotateGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_END, "ROTATE END")
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
mapboxMap!!.addOnScaleListener(
|
||||
object : OnScaleListener {
|
||||
override fun onScaleBegin(detector: StandardScaleGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_START, "SCALE START")
|
||||
)
|
||||
if (focalPointLatLng != null) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(
|
||||
GestureAlert.TYPE_OTHER,
|
||||
"INCREASING MOVE THRESHOLD"
|
||||
)
|
||||
)
|
||||
gesturesManager!!.moveGestureDetector.moveThreshold =
|
||||
ResourceUtils.convertDpToPx(this@GestureDetectorActivity, 175f)
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(
|
||||
GestureAlert.TYPE_OTHER,
|
||||
"MANUALLY INTERRUPTING MOVE"
|
||||
)
|
||||
)
|
||||
gesturesManager!!.moveGestureDetector.interrupt()
|
||||
}
|
||||
recalculateFocalPoint()
|
||||
}
|
||||
|
||||
override fun onScale(detector: StandardScaleGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_PROGRESS, "SCALE PROGRESS")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onScaleEnd(detector: StandardScaleGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_END, "SCALE END")
|
||||
)
|
||||
if (focalPointLatLng != null) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(
|
||||
GestureAlert.TYPE_OTHER,
|
||||
"REVERTING MOVE THRESHOLD"
|
||||
)
|
||||
)
|
||||
gesturesManager!!.moveGestureDetector.moveThreshold = 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
mapboxMap!!.addOnShoveListener(
|
||||
object : OnShoveListener {
|
||||
override fun onShoveBegin(detector: ShoveGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_START, "SHOVE START")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onShove(detector: ShoveGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_PROGRESS, "SHOVE PROGRESS")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onShoveEnd(detector: ShoveGestureDetector) {
|
||||
gestureAlertsAdapter!!.addAlert(
|
||||
GestureAlert(GestureAlert.TYPE_END, "SHOVE END")
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_gestures, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val uiSettings = mapboxMap!!.uiSettings
|
||||
when (item.itemId) {
|
||||
R.id.menu_gesture_focus_point -> {
|
||||
fixedFocalPointEnabled(focalPointLatLng == null)
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_animation -> {
|
||||
uiSettings.isScaleVelocityAnimationEnabled =
|
||||
!uiSettings.isScaleVelocityAnimationEnabled
|
||||
uiSettings.isRotateVelocityAnimationEnabled =
|
||||
!uiSettings.isRotateVelocityAnimationEnabled
|
||||
uiSettings.isFlingVelocityAnimationEnabled =
|
||||
!uiSettings.isFlingVelocityAnimationEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_rotate -> {
|
||||
uiSettings.isRotateGesturesEnabled = !uiSettings.isRotateGesturesEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_tilt -> {
|
||||
uiSettings.isTiltGesturesEnabled = !uiSettings.isTiltGesturesEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_zoom -> {
|
||||
uiSettings.isZoomGesturesEnabled = !uiSettings.isZoomGesturesEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_scroll -> {
|
||||
uiSettings.isScrollGesturesEnabled = !uiSettings.isScrollGesturesEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_double_tap -> {
|
||||
uiSettings.isDoubleTapGesturesEnabled = !uiSettings.isDoubleTapGesturesEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_quick_zoom -> {
|
||||
uiSettings.isQuickZoomGesturesEnabled = !uiSettings.isQuickZoomGesturesEnabled
|
||||
return true
|
||||
}
|
||||
R.id.menu_gesture_scroll_horizontal -> {
|
||||
uiSettings.isHorizontalScrollGesturesEnabled =
|
||||
!uiSettings.isHorizontalScrollGesturesEnabled
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun fixedFocalPointEnabled(enabled: Boolean) {
|
||||
if (enabled) {
|
||||
focalPointLatLng = LatLng(51.50325, -0.12968)
|
||||
marker = mapboxMap!!.addMarker(MarkerOptions().position(focalPointLatLng))
|
||||
mapboxMap!!.easeCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(focalPointLatLng!!, 16.0),
|
||||
object : CancelableCallback {
|
||||
override fun onCancel() {
|
||||
recalculateFocalPoint()
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
recalculateFocalPoint()
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
if (marker != null) {
|
||||
mapboxMap!!.removeMarker(marker!!)
|
||||
marker = null
|
||||
}
|
||||
focalPointLatLng = null
|
||||
mapboxMap!!.uiSettings.focalPoint = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun recalculateFocalPoint() {
|
||||
if (focalPointLatLng != null) {
|
||||
mapboxMap!!.uiSettings.focalPoint =
|
||||
mapboxMap!!.projection.toScreenLocation(focalPointLatLng!!)
|
||||
}
|
||||
}
|
||||
|
||||
private class GestureAlertsAdapter : RecyclerView.Adapter<GestureAlertsAdapter.ViewHolder>() {
|
||||
private var isUpdating = false
|
||||
private val updateHandler = Handler()
|
||||
private val alerts: MutableList<GestureAlert> = ArrayList()
|
||||
|
||||
class ViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
|
||||
var alertMessageTv: TextView
|
||||
|
||||
@ColorInt var textColor = 0
|
||||
|
||||
init {
|
||||
val typeface = FontCache.get("Roboto-Regular.ttf", view.context)
|
||||
alertMessageTv = view.findViewById(R.id.alert_message)
|
||||
alertMessageTv.typeface = typeface
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view =
|
||||
LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_gesture_alert, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val alert = alerts[position]
|
||||
holder.alertMessageTv.text = alert.message
|
||||
holder.alertMessageTv.setTextColor(
|
||||
ContextCompat.getColor(holder.alertMessageTv.context, alert.color)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return alerts.size
|
||||
}
|
||||
|
||||
fun addAlert(alert: GestureAlert) {
|
||||
for (gestureAlert in alerts) {
|
||||
if (gestureAlert.alertType != GestureAlert.TYPE_PROGRESS) {
|
||||
break
|
||||
}
|
||||
if (alert.alertType == GestureAlert.TYPE_PROGRESS && gestureAlert == alert) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (itemCount >= MAX_NUMBER_OF_ALERTS) {
|
||||
alerts.removeAt(itemCount - 1)
|
||||
}
|
||||
alerts.add(0, alert)
|
||||
if (!isUpdating) {
|
||||
isUpdating = true
|
||||
updateHandler.postDelayed(updateRunnable, 250)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private val updateRunnable = Runnable {
|
||||
notifyDataSetChanged()
|
||||
isUpdating = false
|
||||
}
|
||||
|
||||
fun cancelUpdates() {
|
||||
updateHandler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
}
|
||||
|
||||
private class GestureAlert
|
||||
internal constructor(
|
||||
@field:Type @param:Type
|
||||
val alertType: Int,
|
||||
val message: String?
|
||||
) {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(TYPE_NONE, TYPE_START, TYPE_PROGRESS, TYPE_END, TYPE_OTHER)
|
||||
internal annotation class Type
|
||||
|
||||
@ColorInt var color = 0
|
||||
override fun equals(o: Any?): Boolean {
|
||||
if (this === o) {
|
||||
return true
|
||||
}
|
||||
if (o == null || javaClass != o.javaClass) {
|
||||
return false
|
||||
}
|
||||
val that = o as GestureAlert
|
||||
if (alertType != that.alertType) {
|
||||
return false
|
||||
}
|
||||
return if (message != null) message == that.message else that.message == null
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = alertType
|
||||
result = 31 * result + (message?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TYPE_NONE = 0
|
||||
const val TYPE_START = 1
|
||||
const val TYPE_END = 2
|
||||
const val TYPE_PROGRESS = 3
|
||||
const val TYPE_OTHER = 4
|
||||
}
|
||||
|
||||
init {
|
||||
when (alertType) {
|
||||
TYPE_NONE -> color = android.R.color.black
|
||||
TYPE_END -> color = android.R.color.holo_red_dark
|
||||
TYPE_OTHER -> color = android.R.color.holo_purple
|
||||
TYPE_PROGRESS -> color = android.R.color.holo_orange_dark
|
||||
TYPE_START -> color = android.R.color.holo_green_dark
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_NUMBER_OF_ALERTS = 30
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,7 @@ import com.mapbox.mapboxsdk.utils.BitmapUtils
|
||||
import kotlinx.android.synthetic.main.activity_latlngbounds.*
|
||||
import java.net.URISyntaxException
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the LatLngBounds camera API.
|
||||
*/
|
||||
/** Test activity showcasing using the LatLngBounds camera API. */
|
||||
class LatLngBoundsActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
@@ -50,7 +48,8 @@ class LatLngBoundsActivity : AppCompatActivity() {
|
||||
mapView.getMapAsync { map ->
|
||||
mapboxMap = map
|
||||
|
||||
val featureCollection: FeatureCollection = fromJson(loadStringFromAssets(this, "points-sf.geojson"))
|
||||
val featureCollection: FeatureCollection =
|
||||
fromJson(loadStringFromAssets(this, "points-sf.geojson"))
|
||||
bounds = createBounds(featureCollection)
|
||||
|
||||
map.getCameraForLatLngBounds(bounds, createPadding(peekHeight))?.let {
|
||||
@@ -79,29 +78,38 @@ class LatLngBoundsActivity : AppCompatActivity() {
|
||||
)
|
||||
)
|
||||
.withSource(GeoJsonSource("symbol", featureCollection))
|
||||
.withImage("icon", BitmapUtils.getDrawableFromRes(this@LatLngBoundsActivity, R.drawable.ic_android)!!)
|
||||
.withImage(
|
||||
"icon",
|
||||
BitmapUtils.getDrawableFromRes(
|
||||
this@LatLngBoundsActivity,
|
||||
R.drawable.ic_android
|
||||
)!!
|
||||
)
|
||||
) {
|
||||
initBottomSheet()
|
||||
fab.setOnClickListener { bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED }
|
||||
fab.setOnClickListener {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initBottomSheet() {
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
|
||||
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
val offset = convertSlideOffset(slideOffset)
|
||||
val bottomPadding = (peekHeight * offset).toInt()
|
||||
bottomSheetBehavior.setBottomSheetCallback(
|
||||
object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
val offset = convertSlideOffset(slideOffset)
|
||||
val bottomPadding = (peekHeight * offset).toInt()
|
||||
|
||||
mapboxMap.getCameraForLatLngBounds(bounds, createPadding(bottomPadding))?.let {
|
||||
mapboxMap.cameraPosition = it
|
||||
mapboxMap.getCameraForLatLngBounds(bounds, createPadding(bottomPadding))
|
||||
?.let { mapboxMap.cameraPosition = it }
|
||||
}
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
// no-op
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// slideOffset ranges from NaN to -1.0, range from 1.0 to 0 instead
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing the zoom Camera API.
|
||||
* <p>
|
||||
* This includes zoomIn, zoomOut, zoomTo, zoomBy (center and custom focal point).
|
||||
* </p>
|
||||
*/
|
||||
public class ManualZoomActivity extends AppCompatActivity {
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manual_zoom);
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
ManualZoomActivity.this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.getPredefinedStyle("Satellite Hybrid")));
|
||||
UiSettings uiSettings = ManualZoomActivity.this.mapboxMap.getUiSettings();
|
||||
uiSettings.setAllGesturesEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_zoom, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case R.id.action_zoom_in:
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.zoomIn());
|
||||
return true;
|
||||
|
||||
case R.id.action_zoom_out:
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.zoomOut());
|
||||
return true;
|
||||
|
||||
case R.id.action_zoom_by:
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.zoomBy(2));
|
||||
return true;
|
||||
case R.id.action_zoom_to:
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(2));
|
||||
return true;
|
||||
|
||||
case R.id.action_zoom_to_point:
|
||||
View view = getWindow().getDecorView();
|
||||
mapboxMap.animateCamera(
|
||||
CameraUpdateFactory.zoomBy(1, new Point(view.getMeasuredWidth() / 4, view.getMeasuredHeight() / 4)));
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.graphics.Point
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing the zoom Camera API.
|
||||
*
|
||||
* This includes zoomIn, zoomOut, zoomTo, zoomBy (center and custom focal point).
|
||||
*/
|
||||
class ManualZoomActivity : AppCompatActivity() {
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var mapView: MapView
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_manual_zoom)
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
this@ManualZoomActivity.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(
|
||||
Style.Builder().fromUri(Style.getPredefinedStyle("Satellite Hybrid"))
|
||||
)
|
||||
val uiSettings = this@ManualZoomActivity.mapboxMap!!.uiSettings
|
||||
uiSettings.setAllGesturesEnabled(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_zoom, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_zoom_in -> {
|
||||
mapboxMap!!.animateCamera(CameraUpdateFactory.zoomIn())
|
||||
true
|
||||
}
|
||||
R.id.action_zoom_out -> {
|
||||
mapboxMap!!.animateCamera(CameraUpdateFactory.zoomOut())
|
||||
true
|
||||
}
|
||||
R.id.action_zoom_by -> {
|
||||
mapboxMap!!.animateCamera(CameraUpdateFactory.zoomBy(2.0))
|
||||
true
|
||||
}
|
||||
R.id.action_zoom_to -> {
|
||||
mapboxMap!!.animateCamera(CameraUpdateFactory.zoomTo(2.0))
|
||||
true
|
||||
}
|
||||
R.id.action_zoom_to_point -> {
|
||||
val view = window.decorView
|
||||
mapboxMap!!.animateCamera(
|
||||
CameraUpdateFactory.zoomBy(
|
||||
1.0,
|
||||
Point(view.measuredWidth / 4, view.measuredHeight / 4)
|
||||
)
|
||||
)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using maximum and minimum zoom levels to restrict camera movement.
|
||||
*/
|
||||
public class MaxMinZoomActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
private MapboxMap.OnMapClickListener clickListener = new MapboxMap.OnMapClickListener() {
|
||||
@Override
|
||||
public boolean onMapClick(@NonNull LatLng point) {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.getPredefinedStyle("Outdoor")));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_maxmin_zoom);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
|
||||
mapView.addOnDidFinishLoadingStyleListener(() -> Timber.d("Style Loaded"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull final MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
mapboxMap.setMinZoomPreference(3);
|
||||
mapboxMap.setMaxZoomPreference(5);
|
||||
mapboxMap.addOnMapClickListener(clickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnMapClickListener(clickListener);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishLoadingStyleListener
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import timber.log.Timber
|
||||
|
||||
/** Test activity showcasing using maximum and minimum zoom levels to restrict camera movement. */
|
||||
class MaxMinZoomActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private val clickListener = OnMapClickListener {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(Style.getPredefinedStyle("Outdoor")))
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_maxmin_zoom)
|
||||
mapView = findViewById<MapView>(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(this)
|
||||
mapView.addOnDidFinishLoadingStyleListener(
|
||||
OnDidFinishLoadingStyleListener { Timber.d("Style Loaded") }
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
mapboxMap!!.setMinZoomPreference(3.0)
|
||||
mapboxMap!!.setMaxZoomPreference(5.0)
|
||||
mapboxMap!!.addOnMapClickListener(clickListener)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnMapClickListener(clickListener)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the scrollBy Camera API by moving x,y pixels above Grenada, Spain.
|
||||
*/
|
||||
public class ScrollByActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
public static final int MULTIPLIER_PER_PIXEL = 50;
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private SeekBar seekBarX;
|
||||
private SeekBar seekBarY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_scroll_by);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
|
||||
seekBarX = findViewById(R.id.seekbar_move_x);
|
||||
TextView textViewX = findViewById(R.id.textview_x);
|
||||
seekBarX.setOnSeekBarChangeListener(new PixelBarChangeListener(textViewX, R.string.scrollby_x_value));
|
||||
|
||||
seekBarY = findViewById(R.id.seekbar_move_y);
|
||||
TextView textViewY = findViewById(R.id.textview_y);
|
||||
seekBarY.setOnSeekBarChangeListener(new PixelBarChangeListener(textViewY, R.string.scrollby_y_value));
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.setTag(true);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Pastel"));
|
||||
|
||||
UiSettings uiSettings = mapboxMap.getUiSettings();
|
||||
uiSettings.setLogoEnabled(false);
|
||||
uiSettings.setAttributionEnabled(false);
|
||||
FloatingActionButton fab = findViewById(R.id.fab);
|
||||
fab.setColorFilter(ContextCompat.getColor(ScrollByActivity.this, R.color.primary));
|
||||
fab.setOnClickListener(view -> mapboxMap.scrollBy(
|
||||
seekBarX.getProgress() * MULTIPLIER_PER_PIXEL,
|
||||
seekBarY.getProgress() * MULTIPLIER_PER_PIXEL)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PixelBarChangeListener implements SeekBar.OnSeekBarChangeListener {
|
||||
|
||||
@StringRes
|
||||
private int prefixTextResource;
|
||||
private TextView valueView;
|
||||
|
||||
PixelBarChangeListener(@NonNull TextView textView, @StringRes int textRes) {
|
||||
valueView = textView;
|
||||
prefixTextResource = textRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
int value = progress * ScrollByActivity.MULTIPLIER_PER_PIXEL;
|
||||
valueView.setText(String.format(seekBar.getResources().getString(prefixTextResource), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.camera
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.SeekBar
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the scrollBy Camera API by moving x,y pixels above Grenada, Spain.
|
||||
*/
|
||||
class ScrollByActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var seekBarX: SeekBar
|
||||
private lateinit var seekBarY: SeekBar
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_scroll_by)
|
||||
val toolbar = findViewById<Toolbar>(R.id.toolbar)
|
||||
setSupportActionBar(toolbar)
|
||||
val actionBar = supportActionBar
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
actionBar.setDisplayShowHomeEnabled(true)
|
||||
}
|
||||
seekBarX = findViewById(R.id.seekbar_move_x)
|
||||
val textViewX = findViewById<TextView>(R.id.textview_x)
|
||||
seekBarX.setOnSeekBarChangeListener(
|
||||
PixelBarChangeListener(textViewX, R.string.scrollby_x_value)
|
||||
)
|
||||
seekBarY = findViewById(R.id.seekbar_move_y)
|
||||
val textViewY = findViewById<TextView>(R.id.textview_y)
|
||||
seekBarY.setOnSeekBarChangeListener(
|
||||
PixelBarChangeListener(textViewY, R.string.scrollby_y_value)
|
||||
)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.setTag(true)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Pastel"))
|
||||
val uiSettings = mapboxMap!!.uiSettings
|
||||
uiSettings.isLogoEnabled = false
|
||||
uiSettings.isAttributionEnabled = false
|
||||
val fab = findViewById<FloatingActionButton>(R.id.fab)
|
||||
fab.setColorFilter(ContextCompat.getColor(this@ScrollByActivity, R.color.primary))
|
||||
fab.setOnClickListener { view: View? ->
|
||||
mapboxMap!!.scrollBy(
|
||||
(seekBarX!!.progress * MULTIPLIER_PER_PIXEL).toFloat(),
|
||||
(seekBarY!!.progress * MULTIPLIER_PER_PIXEL).toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
onBackPressed()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
private class PixelBarChangeListener
|
||||
internal constructor(
|
||||
private val valueView: TextView,
|
||||
@field:StringRes @param:StringRes
|
||||
private val prefixTextResource: Int
|
||||
) : OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
val value = progress * MULTIPLIER_PER_PIXEL
|
||||
valueView.text = String.format(seekBar.resources.getString(prefixTextResource), value)
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MULTIPLIER_PER_PIXEL = 50
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.customlayer;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.style.layers.CustomLayer;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.model.customlayer.ExampleCustomLayer;
|
||||
|
||||
/**
|
||||
* Test activity showcasing the Custom Layer API
|
||||
* <p>
|
||||
* Note: experimental API, do not use.
|
||||
* </p>
|
||||
*/
|
||||
public class CustomLayerActivity extends AppCompatActivity {
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private CustomLayer customLayer;
|
||||
|
||||
private FloatingActionButton fab;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_custom_layer);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(map -> {
|
||||
mapboxMap = map;
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.91448, -243.60947), 10));
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"), style -> initFab());
|
||||
});
|
||||
}
|
||||
|
||||
private void initFab() {
|
||||
fab = findViewById(R.id.fab);
|
||||
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
|
||||
fab.setOnClickListener(view -> {
|
||||
if (mapboxMap != null) {
|
||||
swapCustomLayer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void swapCustomLayer() {
|
||||
Style style = mapboxMap.getStyle();
|
||||
if (customLayer != null) {
|
||||
style.removeLayer(customLayer);
|
||||
customLayer = null;
|
||||
fab.setImageResource(R.drawable.ic_layers);
|
||||
} else {
|
||||
customLayer = new CustomLayer("custom",
|
||||
ExampleCustomLayer.createContext());
|
||||
style.addLayerBelow(customLayer, "building");
|
||||
fab.setImageResource(R.drawable.ic_layers_clear);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLayer() {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.triggerRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_custom_layer, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_update_layer:
|
||||
updateLayer();
|
||||
return true;
|
||||
case R.id.action_set_color_red:
|
||||
ExampleCustomLayer.setColor(1, 0, 0, 1);
|
||||
return true;
|
||||
case R.id.action_set_color_green:
|
||||
ExampleCustomLayer.setColor(0, 1, 0, 1);
|
||||
return true;
|
||||
case R.id.action_set_color_blue:
|
||||
ExampleCustomLayer.setColor(0, 0, 1, 1);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.customlayer
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.style.layers.CustomLayer
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.model.customlayer.ExampleCustomLayer
|
||||
|
||||
/**
|
||||
* Test activity showcasing the Custom Layer API
|
||||
*
|
||||
*
|
||||
* Note: experimental API, do not use.
|
||||
*
|
||||
*/
|
||||
class CustomLayerActivity : AppCompatActivity() {
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var mapView: MapView
|
||||
private var customLayer: CustomLayer? = null
|
||||
private lateinit var fab: FloatingActionButton
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_custom_layer)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { map: MapboxMap? ->
|
||||
mapboxMap = map!!
|
||||
mapboxMap!!.moveCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(39.91448, -243.60947),
|
||||
10.0
|
||||
)
|
||||
)
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Streets")) { style: Style? -> initFab() }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun initFab() {
|
||||
fab = findViewById(R.id.fab)
|
||||
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary))
|
||||
fab.setOnClickListener(
|
||||
View.OnClickListener { view: View? ->
|
||||
if (mapboxMap != null) {
|
||||
swapCustomLayer()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun swapCustomLayer() {
|
||||
val style = mapboxMap!!.style
|
||||
if (customLayer != null) {
|
||||
style!!.removeLayer(customLayer!!)
|
||||
customLayer = null
|
||||
fab!!.setImageResource(R.drawable.ic_layers)
|
||||
} else {
|
||||
customLayer = CustomLayer(
|
||||
"custom",
|
||||
ExampleCustomLayer.createContext()
|
||||
)
|
||||
style!!.addLayerBelow(customLayer!!, "building")
|
||||
fab!!.setImageResource(R.drawable.ic_layers_clear)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLayer() {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.triggerRepaint()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_custom_layer, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_update_layer -> {
|
||||
updateLayer()
|
||||
true
|
||||
}
|
||||
R.id.action_set_color_red -> {
|
||||
ExampleCustomLayer.setColor(1f, 0f, 0f, 1f)
|
||||
true
|
||||
}
|
||||
R.id.action_set_color_green -> {
|
||||
ExampleCustomLayer.setColor(0f, 1f, 0f, 1f)
|
||||
true
|
||||
}
|
||||
R.id.action_set_color_blue -> {
|
||||
ExampleCustomLayer.setColor(0f, 0f, 1f, 1f)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.NavUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query rendered features API to count features in a rectangle.
|
||||
*/
|
||||
public class QueryRenderedFeaturesBoxCountActivity extends AppCompatActivity {
|
||||
|
||||
public MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_query_features_box);
|
||||
|
||||
final View selectionBox = findViewById(R.id.selection_box);
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
QueryRenderedFeaturesBoxCountActivity.this.mapboxMap = mapboxMap;
|
||||
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.getPredefinedStyle("Streets")));
|
||||
|
||||
selectionBox.setOnClickListener(view -> {
|
||||
// Query
|
||||
int top = selectionBox.getTop() - mapView.getTop();
|
||||
int left = selectionBox.getLeft() - mapView.getLeft();
|
||||
RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
|
||||
Timber.i("Querying box %s", box);
|
||||
List<Feature> features = mapboxMap.queryRenderedFeatures(box);
|
||||
|
||||
// Show count
|
||||
Toast.makeText(
|
||||
QueryRenderedFeaturesBoxCountActivity.this,
|
||||
String.format("%s features in box", features.size()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
// Debug output
|
||||
debugOutput(features);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void debugOutput(List<Feature> features) {
|
||||
Timber.i("Got %s features", features.size());
|
||||
for (Feature feature : features) {
|
||||
if (feature != null) {
|
||||
Timber.i("Got feature %s with %s properties and Geometry %s",
|
||||
feature.id(),
|
||||
feature.properties() != null ? feature.properties().entrySet().size() : "<null>",
|
||||
feature.geometry() != null ? feature.geometry().getClass().getSimpleName() : "<null>"
|
||||
);
|
||||
if (feature.properties() != null) {
|
||||
for (Map.Entry<String, JsonElement> entry : feature.properties().entrySet()) {
|
||||
Timber.i("Prop %s - %s", entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.i("Got 0 features");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MapboxMap getMapboxMap() {
|
||||
return mapboxMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
|
||||
if (mapboxMap != null) {
|
||||
// Regression test for #14394
|
||||
mapboxMap.queryRenderedFeatures(new PointF(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
NavUtils.navigateHome(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature
|
||||
|
||||
import android.graphics.PointF
|
||||
import android.graphics.RectF
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.geojson.Feature
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.NavUtils
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query rendered features API to count features in a rectangle.
|
||||
*/
|
||||
class QueryRenderedFeaturesBoxCountActivity : AppCompatActivity() {
|
||||
var mapView: MapView? = null
|
||||
var mapboxMap: MapboxMap? = null
|
||||
private set
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_query_features_box)
|
||||
val selectionBox = findViewById<View>(R.id.selection_box)
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
this@QueryRenderedFeaturesBoxCountActivity.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.Builder().fromUri(Style.getPredefinedStyle("Streets")))
|
||||
selectionBox.setOnClickListener { view: View? ->
|
||||
// Query
|
||||
val top = selectionBox.top - mapView!!.top
|
||||
val left = selectionBox.left - mapView!!.left
|
||||
val box = RectF(
|
||||
left.toFloat(),
|
||||
top.toFloat(),
|
||||
(left + selectionBox.width).toFloat(),
|
||||
(top + selectionBox.height).toFloat()
|
||||
)
|
||||
Timber.i("Querying box %s", box)
|
||||
val features = mapboxMap.queryRenderedFeatures(box)
|
||||
|
||||
// Show count
|
||||
Toast.makeText(
|
||||
this@QueryRenderedFeaturesBoxCountActivity,
|
||||
String.format("%s features in box", features.size),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
// Debug output
|
||||
debugOutput(features)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun debugOutput(features: List<Feature>) {
|
||||
Timber.i("Got %s features", features.size)
|
||||
for (feature in features) {
|
||||
if (feature != null) {
|
||||
Timber.i(
|
||||
"Got feature %s with %s properties and Geometry %s",
|
||||
feature.id(),
|
||||
if (feature.properties() != null) feature.properties()!!
|
||||
.entrySet().size else "<null>",
|
||||
if (feature.geometry() != null) feature.geometry()!!::class.java.simpleName else "<null>"
|
||||
)
|
||||
if (feature.properties() != null) {
|
||||
for ((key, value) in feature.properties()!!.entrySet()) {
|
||||
Timber.i("Prop %s - %s", key, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.i("Got 0 features")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
if (mapboxMap != null) {
|
||||
// Regression test for #14394
|
||||
mapboxMap!!.queryRenderedFeatures(PointF(0F, 0F))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
NavUtils.navigateHome(this)
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.geojson.FeatureCollection;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression;
|
||||
import com.mapbox.mapboxsdk.style.layers.FillLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.lt;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.toNumber;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor;
|
||||
|
||||
/**
|
||||
* Demo's query rendered features
|
||||
*/
|
||||
public class QueryRenderedFeaturesBoxHighlightActivity extends AppCompatActivity {
|
||||
|
||||
public MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_query_features_box);
|
||||
|
||||
final View selectionBox = findViewById(R.id.selection_box);
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
QueryRenderedFeaturesBoxHighlightActivity.this.mapboxMap = mapboxMap;
|
||||
|
||||
// Add layer / source
|
||||
final GeoJsonSource source = new GeoJsonSource("highlighted-shapes-source");
|
||||
final Layer layer = new FillLayer("highlighted-shapes-layer", "highlighted-shapes-source")
|
||||
.withProperties(fillColor(Color.RED));
|
||||
|
||||
selectionBox.setOnClickListener(view -> {
|
||||
// Query
|
||||
int top = selectionBox.getTop() - mapView.getTop();
|
||||
int left = selectionBox.getLeft() - mapView.getLeft();
|
||||
RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
|
||||
Timber.i("Querying box %s for buildings", box);
|
||||
|
||||
Expression filter = lt(toNumber(get("height")), literal(10));
|
||||
List<Feature> features = mapboxMap.queryRenderedFeatures(box, filter, "building");
|
||||
|
||||
// Show count
|
||||
Toast.makeText(
|
||||
QueryRenderedFeaturesBoxHighlightActivity.this,
|
||||
String.format("%s features in box", features.size()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
// Update source data
|
||||
source.setGeoJson(FeatureCollection.fromFeatures(features));
|
||||
});
|
||||
|
||||
mapboxMap.setStyle(new Style.Builder()
|
||||
.fromUri(Style.getPredefinedStyle("Streets"))
|
||||
.withSource(source)
|
||||
.withLayer(layer)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public MapboxMap getMapboxMap() {
|
||||
return mapboxMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.RectF
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.geojson.FeatureCollection
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression
|
||||
import com.mapbox.mapboxsdk.style.layers.FillLayer
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer
|
||||
import com.mapbox.mapboxsdk.style.layers.PropertyFactory
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Demo's query rendered features
|
||||
*/
|
||||
class QueryRenderedFeaturesBoxHighlightActivity : AppCompatActivity() {
|
||||
var mapView: MapView? = null
|
||||
var mapboxMap: MapboxMap? = null
|
||||
private set
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_query_features_box)
|
||||
val selectionBox = findViewById<View>(R.id.selection_box)
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
this@QueryRenderedFeaturesBoxHighlightActivity.mapboxMap = mapboxMap
|
||||
|
||||
// Add layer / source
|
||||
val source = GeoJsonSource("highlighted-shapes-source")
|
||||
val layer: Layer = FillLayer("highlighted-shapes-layer", "highlighted-shapes-source")
|
||||
.withProperties(PropertyFactory.fillColor(Color.RED))
|
||||
selectionBox.setOnClickListener { view: View? ->
|
||||
// Query
|
||||
val top = selectionBox.top - mapView!!.top
|
||||
val left = selectionBox.left - mapView!!.left
|
||||
val box = RectF(
|
||||
left.toFloat(),
|
||||
top.toFloat(),
|
||||
(left + selectionBox.width).toFloat(),
|
||||
(top + selectionBox.height).toFloat()
|
||||
)
|
||||
Timber.i("Querying box %s for buildings", box)
|
||||
val filter = Expression.lt(
|
||||
Expression.toNumber(Expression.get("height")),
|
||||
Expression.literal(10)
|
||||
)
|
||||
val features = mapboxMap.queryRenderedFeatures(box, filter, "building")
|
||||
|
||||
// Show count
|
||||
Toast.makeText(
|
||||
this@QueryRenderedFeaturesBoxHighlightActivity,
|
||||
String.format("%s features in box", features.size),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
// Update source data
|
||||
source.setGeoJson(FeatureCollection.fromFeatures(features))
|
||||
}
|
||||
mapboxMap.setStyle(
|
||||
Style.Builder()
|
||||
.fromUri(Style.getPredefinedStyle("Streets"))
|
||||
.withSource(source)
|
||||
.withLayer(layer)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.style.layers.BackgroundLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgb;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundColor;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query rendered features API to count Symbols in a rectangle.
|
||||
*/
|
||||
public class QueryRenderedFeaturesBoxSymbolCountActivity extends AppCompatActivity {
|
||||
|
||||
public MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
private Toast toast;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_query_features_box);
|
||||
|
||||
final View selectionBox = findViewById(R.id.selection_box);
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
QueryRenderedFeaturesBoxSymbolCountActivity.this.mapboxMap = mapboxMap;
|
||||
|
||||
try {
|
||||
String testPoints = ResourceUtils.readRawResource(mapView.getContext(), R.raw.test_points_utrecht);
|
||||
Bitmap markerImage = BitmapFactory.decodeResource(getResources(), R.drawable.mapbox_marker_icon_default);
|
||||
|
||||
mapboxMap.setStyle(new Style.Builder()
|
||||
.withLayer(
|
||||
new BackgroundLayer("bg")
|
||||
.withProperties(
|
||||
backgroundColor(rgb(120, 161, 226))
|
||||
)
|
||||
)
|
||||
.withLayer(
|
||||
new SymbolLayer("symbols-layer", "symbols-source")
|
||||
.withProperties(
|
||||
iconImage("test-icon")
|
||||
)
|
||||
)
|
||||
.withSource(
|
||||
new GeoJsonSource("symbols-source", testPoints)
|
||||
)
|
||||
.withImage("test-icon", markerImage)
|
||||
);
|
||||
} catch (IOException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
selectionBox.setOnClickListener(view -> {
|
||||
// Query
|
||||
int top = selectionBox.getTop() - mapView.getTop();
|
||||
int left = selectionBox.getLeft() - mapView.getLeft();
|
||||
RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
|
||||
Timber.i("Querying box %s", box);
|
||||
List<Feature> features = mapboxMap.queryRenderedFeatures(box, "symbols-layer");
|
||||
|
||||
// Show count
|
||||
if (toast != null) {
|
||||
toast.cancel();
|
||||
}
|
||||
toast = Toast.makeText(
|
||||
QueryRenderedFeaturesBoxSymbolCountActivity.this,
|
||||
String.format("%s features in box", features.size()),
|
||||
Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public MapboxMap getMapboxMap() {
|
||||
return mapboxMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.RectF
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression
|
||||
import com.mapbox.mapboxsdk.style.layers.BackgroundLayer
|
||||
import com.mapbox.mapboxsdk.style.layers.PropertyFactory
|
||||
import com.mapbox.mapboxsdk.style.layers.SymbolLayer
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query rendered features API to count Symbols in a rectangle.
|
||||
*/
|
||||
class QueryRenderedFeaturesBoxSymbolCountActivity : AppCompatActivity() {
|
||||
var mapView: MapView? = null
|
||||
var mapboxMap: MapboxMap? = null
|
||||
private set
|
||||
private lateinit var toast: Toast
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_query_features_box)
|
||||
val selectionBox = findViewById<View>(R.id.selection_box)
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
this@QueryRenderedFeaturesBoxSymbolCountActivity.mapboxMap = mapboxMap
|
||||
try {
|
||||
val testPoints = ResourceUtils.readRawResource(
|
||||
mapView!!.context,
|
||||
R.raw.test_points_utrecht
|
||||
)
|
||||
val markerImage =
|
||||
BitmapFactory.decodeResource(resources, R.drawable.mapbox_marker_icon_default)
|
||||
mapboxMap.setStyle(
|
||||
Style.Builder()
|
||||
.withLayer(
|
||||
BackgroundLayer("bg")
|
||||
.withProperties(
|
||||
PropertyFactory.backgroundColor(Expression.rgb(120, 161, 226))
|
||||
)
|
||||
)
|
||||
.withLayer(
|
||||
SymbolLayer("symbols-layer", "symbols-source")
|
||||
.withProperties(
|
||||
PropertyFactory.iconImage("test-icon")
|
||||
)
|
||||
)
|
||||
.withSource(
|
||||
GeoJsonSource("symbols-source", testPoints)
|
||||
)
|
||||
.withImage("test-icon", markerImage)
|
||||
)
|
||||
} catch (exception: IOException) {
|
||||
exception.printStackTrace()
|
||||
}
|
||||
selectionBox.setOnClickListener { view: View? ->
|
||||
// Query
|
||||
val top = selectionBox.top - mapView!!.top
|
||||
val left = selectionBox.left - mapView!!.left
|
||||
val box = RectF(
|
||||
left.toFloat(),
|
||||
top.toFloat(),
|
||||
(left + selectionBox.width).toFloat(),
|
||||
(top + selectionBox.height).toFloat()
|
||||
)
|
||||
Timber.i("Querying box %s", box)
|
||||
val features = mapboxMap.queryRenderedFeatures(box, "symbols-layer")
|
||||
|
||||
// Show count
|
||||
if (toast != null) {
|
||||
toast!!.cancel()
|
||||
}
|
||||
toast = Toast.makeText(
|
||||
this@QueryRenderedFeaturesBoxSymbolCountActivity,
|
||||
String.format("%s features in box", features.size),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
toast.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query rendered features API to query feature properties on Map click.
|
||||
*/
|
||||
public class QueryRenderedFeaturesPropertiesActivity extends AppCompatActivity {
|
||||
|
||||
public MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private Marker marker;
|
||||
|
||||
private MapboxMap.OnMapClickListener mapClickListener = new MapboxMap.OnMapClickListener() {
|
||||
@Override
|
||||
public boolean onMapClick(@NonNull LatLng point) {
|
||||
final float density = getResources().getDisplayMetrics().density;
|
||||
final PointF pixel = mapboxMap.getProjection().toScreenLocation(point);
|
||||
Timber.i(
|
||||
"Requesting features for %sx%s (%sx%s adjusted for density)",
|
||||
pixel.x, pixel.y, pixel.x / density, pixel.y / density
|
||||
);
|
||||
List<Feature> features = mapboxMap.queryRenderedFeatures(pixel);
|
||||
|
||||
// Debug output
|
||||
debugOutput(features);
|
||||
|
||||
// Remove any previous markers
|
||||
if (marker != null) {
|
||||
mapboxMap.removeMarker(marker);
|
||||
}
|
||||
|
||||
// Add a marker on the clicked point
|
||||
marker = mapboxMap.addMarker(new CustomMarkerOptions().position(point).features(features));
|
||||
mapboxMap.selectMarker(marker);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_query_features_point);
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
QueryRenderedFeaturesPropertiesActivity.this.mapboxMap = mapboxMap;
|
||||
|
||||
// Add custom window adapter
|
||||
addCustomInfoWindowAdapter(mapboxMap);
|
||||
|
||||
// Add a click listener
|
||||
mapboxMap.addOnMapClickListener(mapClickListener);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void debugOutput(List<Feature> features) {
|
||||
Timber.i("Got %s features", features.size());
|
||||
for (Feature feature : features) {
|
||||
if (feature != null) {
|
||||
Timber.i("Got feature %s with %s properties and Geometry %s",
|
||||
feature.id(),
|
||||
feature.properties() != null ? feature.properties().entrySet().size() : "<null>",
|
||||
feature.geometry() != null ? feature.geometry().getClass().getSimpleName() : "<null>"
|
||||
);
|
||||
if (feature.properties() != null) {
|
||||
for (Map.Entry<String, JsonElement> entry : feature.properties().entrySet()) {
|
||||
Timber.i("Prop %s - %s", entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.i("Got NULL feature");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addCustomInfoWindowAdapter(MapboxMap mapboxMap) {
|
||||
mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
|
||||
|
||||
private TextView row(String text) {
|
||||
TextView view = new TextView(QueryRenderedFeaturesPropertiesActivity.this);
|
||||
view.setText(text);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getInfoWindow(@NonNull Marker marker) {
|
||||
CustomMarker customMarker = (CustomMarker) marker;
|
||||
LinearLayout view = new LinearLayout(QueryRenderedFeaturesPropertiesActivity.this);
|
||||
view.setOrientation(LinearLayout.VERTICAL);
|
||||
view.setBackgroundColor(Color.WHITE);
|
||||
|
||||
if (customMarker.features.size() > 0) {
|
||||
view.addView(row(String.format("Found %s features", customMarker.features.size())));
|
||||
Feature feature = customMarker.features.get(0);
|
||||
for (Map.Entry<String, JsonElement> prop : feature.properties().entrySet()) {
|
||||
view.addView(row(String.format("%s: %s", prop.getKey(), prop.getValue())));
|
||||
}
|
||||
} else {
|
||||
view.addView(row("No features here"));
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MapboxMap getMapboxMap() {
|
||||
return mapboxMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnMapClickListener(mapClickListener);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
private static class CustomMarker extends Marker {
|
||||
|
||||
private final List<Feature> features;
|
||||
|
||||
CustomMarker(BaseMarkerOptions baseMarkerOptions, List<Feature> features) {
|
||||
super(baseMarkerOptions);
|
||||
this.features = features;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CustomMarkerOptions extends BaseMarkerOptions<CustomMarker, CustomMarkerOptions> {
|
||||
|
||||
|
||||
private List<Feature> features;
|
||||
|
||||
public CustomMarkerOptions features(List<Feature> features) {
|
||||
this.features = features;
|
||||
return this;
|
||||
}
|
||||
|
||||
CustomMarkerOptions() {
|
||||
}
|
||||
|
||||
private CustomMarkerOptions(Parcel in) {
|
||||
// Should implement this
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomMarkerOptions getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomMarker getMarker() {
|
||||
return new CustomMarker(this, features);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<CustomMarkerOptions> CREATOR =
|
||||
new Parcelable.Creator<CustomMarkerOptions>() {
|
||||
public CustomMarkerOptions createFromParcel(Parcel in) {
|
||||
return new CustomMarkerOptions(in);
|
||||
}
|
||||
|
||||
public CustomMarkerOptions[] newArray(int size) {
|
||||
return new CustomMarkerOptions[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
// Should implement this
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
|
||||
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.geojson.Feature
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions
|
||||
import com.mapbox.mapboxsdk.annotations.Marker
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.InfoWindowAdapter
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query rendered features API to query feature properties on Map click.
|
||||
*/
|
||||
class QueryRenderedFeaturesPropertiesActivity : AppCompatActivity() {
|
||||
var mapView: MapView? = null
|
||||
var mapboxMap: MapboxMap? = null
|
||||
private set
|
||||
private var marker: Marker? = null
|
||||
private val mapClickListener = OnMapClickListener { point ->
|
||||
val density = resources.displayMetrics.density
|
||||
val pixel = mapboxMap!!.projection.toScreenLocation(point)
|
||||
Timber.i(
|
||||
"Requesting features for %sx%s (%sx%s adjusted for density)",
|
||||
pixel.x,
|
||||
pixel.y,
|
||||
pixel.x / density,
|
||||
pixel.y / density
|
||||
)
|
||||
val features = mapboxMap!!.queryRenderedFeatures(pixel)
|
||||
|
||||
// Debug output
|
||||
debugOutput(features)
|
||||
|
||||
// Remove any previous markers
|
||||
if (marker != null) {
|
||||
mapboxMap!!.removeMarker(marker!!)
|
||||
}
|
||||
|
||||
// Add a marker on the clicked point
|
||||
marker = mapboxMap!!.addMarker(CustomMarkerOptions().position(point)!!.features(features))
|
||||
mapboxMap!!.selectMarker(marker!!)
|
||||
true
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_query_features_point)
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets")) { style: Style? ->
|
||||
this@QueryRenderedFeaturesPropertiesActivity.mapboxMap = mapboxMap
|
||||
|
||||
// Add custom window adapter
|
||||
addCustomInfoWindowAdapter(mapboxMap)
|
||||
|
||||
// Add a click listener
|
||||
mapboxMap.addOnMapClickListener(mapClickListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun debugOutput(features: List<Feature>) {
|
||||
Timber.i("Got %s features", features.size)
|
||||
for (feature in features) {
|
||||
if (feature != null) {
|
||||
Timber.i(
|
||||
"Got feature %s with %s properties and Geometry %s",
|
||||
feature.id(),
|
||||
if (feature.properties() != null) feature.properties()!!
|
||||
.entrySet().size else "<null>",
|
||||
if (feature.geometry() != null) feature.geometry()!!::class.java.simpleName else "<null>"
|
||||
)
|
||||
if (feature.properties() != null) {
|
||||
for ((key, value) in feature.properties()!!.entrySet()) {
|
||||
Timber.i("Prop %s - %s", key, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.i("Got NULL feature")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCustomInfoWindowAdapter(mapboxMap: MapboxMap) {
|
||||
mapboxMap.infoWindowAdapter = object : InfoWindowAdapter {
|
||||
private fun row(text: String): TextView {
|
||||
val view = TextView(this@QueryRenderedFeaturesPropertiesActivity)
|
||||
view.text = text
|
||||
return view
|
||||
}
|
||||
|
||||
override fun getInfoWindow(marker: Marker): View? {
|
||||
val customMarker = marker as CustomMarker
|
||||
val view = LinearLayout(this@QueryRenderedFeaturesPropertiesActivity)
|
||||
view.orientation = LinearLayout.VERTICAL
|
||||
view.setBackgroundColor(Color.WHITE)
|
||||
if (customMarker.features!!.size > 0) {
|
||||
view.addView(
|
||||
row(
|
||||
String.format(
|
||||
"Found %s features",
|
||||
customMarker.features.size
|
||||
)
|
||||
)
|
||||
)
|
||||
val feature = customMarker.features[0]
|
||||
for ((key, value) in feature.properties()!!.entrySet()) {
|
||||
view.addView(row(String.format("%s: %s", key, value)))
|
||||
}
|
||||
} else {
|
||||
view.addView(row("No features here"))
|
||||
}
|
||||
return view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnMapClickListener(mapClickListener)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
private class CustomMarker internal constructor(
|
||||
baseMarkerOptions: BaseMarkerOptions<*, *>?,
|
||||
val features: List<Feature>?
|
||||
) : Marker(baseMarkerOptions)
|
||||
|
||||
private class CustomMarkerOptions : BaseMarkerOptions<CustomMarker?, CustomMarkerOptions?> {
|
||||
private var features: List<Feature>? = null
|
||||
fun features(features: List<Feature>?): CustomMarkerOptions {
|
||||
this.features = features
|
||||
return this
|
||||
}
|
||||
|
||||
internal constructor() {}
|
||||
private constructor(`in`: Parcel) {
|
||||
// Should implement this
|
||||
}
|
||||
|
||||
override fun getThis(): CustomMarkerOptions {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getMarker(): CustomMarker {
|
||||
return CustomMarker(this, features)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun writeToParcel(out: Parcel, flags: Int) {
|
||||
// Should implement this
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<CustomMarkerOptions?> =
|
||||
object : Parcelable.Creator<CustomMarkerOptions?> {
|
||||
override fun createFromParcel(`in`: Parcel): CustomMarkerOptions? {
|
||||
return CustomMarkerOptions(`in`)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<CustomMarkerOptions?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.geojson.FeatureCollection;
|
||||
import com.mapbox.geojson.Point;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression;
|
||||
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.eq;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.neq;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query source features API to query feature counts
|
||||
*/
|
||||
public class QuerySourceFeaturesActivity extends AppCompatActivity {
|
||||
|
||||
public MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_query_source_features);
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(map -> {
|
||||
this.mapboxMap = map;
|
||||
mapboxMap.getStyle(this::initStyle);
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
});
|
||||
}
|
||||
|
||||
private void initStyle(Style style) {
|
||||
JsonObject properties = new JsonObject();
|
||||
properties.addProperty("key1", "value1");
|
||||
final GeoJsonSource source = new GeoJsonSource("test-source",
|
||||
FeatureCollection.fromFeatures(new Feature[] {
|
||||
Feature.fromGeometry(Point.fromLngLat(17.1, 51), properties),
|
||||
Feature.fromGeometry(Point.fromLngLat(17.2, 51), properties),
|
||||
Feature.fromGeometry(Point.fromLngLat(17.3, 51), properties),
|
||||
Feature.fromGeometry(Point.fromLngLat(17.4, 51), properties),
|
||||
}));
|
||||
style.addSource(source);
|
||||
|
||||
Expression visible = eq(get("key1"), literal("value1"));
|
||||
Expression invisible = neq(get("key1"), literal("value1"));
|
||||
|
||||
CircleLayer layer = new CircleLayer("test-layer", source.getId())
|
||||
.withFilter(visible);
|
||||
style.addLayer(layer);
|
||||
|
||||
// Add a click listener
|
||||
mapboxMap.addOnMapClickListener(point -> {
|
||||
// Query
|
||||
List<Feature> features = source.querySourceFeatures(eq(get("key1"), literal("value1")));
|
||||
Toast.makeText(QuerySourceFeaturesActivity.this, String.format("Found %s features",
|
||||
features.size()), Toast.LENGTH_SHORT).show();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
|
||||
fab.setOnClickListener(view -> {
|
||||
Expression visibility = layer.getFilter();
|
||||
if (visibility != null && visibility.equals(visible)) {
|
||||
layer.setFilter(invisible);
|
||||
fab.setImageResource(R.drawable.ic_layers_clear);
|
||||
} else {
|
||||
layer.setFilter(visible);
|
||||
fab.setImageResource(R.drawable.ic_layers);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.feature
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.gson.JsonObject
|
||||
import com.mapbox.geojson.Feature
|
||||
import com.mapbox.geojson.FeatureCollection
|
||||
import com.mapbox.geojson.Point
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression
|
||||
import com.mapbox.mapboxsdk.style.layers.CircleLayer
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the query source features API to query feature counts
|
||||
*/
|
||||
class QuerySourceFeaturesActivity : AppCompatActivity() {
|
||||
var mapView: MapView? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_query_source_features)
|
||||
|
||||
// Initialize map as normal
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { map: MapboxMap? ->
|
||||
mapboxMap = map
|
||||
mapboxMap!!.getStyle { style: Style -> initStyle(style) }
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun initStyle(style: Style) {
|
||||
val properties = JsonObject()
|
||||
properties.addProperty("key1", "value1")
|
||||
val source = GeoJsonSource(
|
||||
"test-source",
|
||||
FeatureCollection.fromFeatures(
|
||||
arrayOf(
|
||||
Feature.fromGeometry(Point.fromLngLat(17.1, 51.0), properties),
|
||||
Feature.fromGeometry(Point.fromLngLat(17.2, 51.0), properties),
|
||||
Feature.fromGeometry(Point.fromLngLat(17.3, 51.0), properties),
|
||||
Feature.fromGeometry(Point.fromLngLat(17.4, 51.0), properties)
|
||||
)
|
||||
)
|
||||
)
|
||||
style.addSource(source)
|
||||
val visible = Expression.eq(Expression.get("key1"), Expression.literal("value1"))
|
||||
val invisible = Expression.neq(Expression.get("key1"), Expression.literal("value1"))
|
||||
val layer = CircleLayer("test-layer", source.id)
|
||||
.withFilter(visible)
|
||||
style.addLayer(layer)
|
||||
|
||||
// Add a click listener
|
||||
mapboxMap!!.addOnMapClickListener { point: LatLng? ->
|
||||
// Query
|
||||
val features = source.querySourceFeatures(
|
||||
Expression.eq(
|
||||
Expression.get("key1"),
|
||||
Expression.literal("value1")
|
||||
)
|
||||
)
|
||||
Toast.makeText(
|
||||
this@QuerySourceFeaturesActivity,
|
||||
String.format(
|
||||
"Found %s features",
|
||||
features.size
|
||||
),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
false
|
||||
}
|
||||
val fab = findViewById<View>(R.id.fab) as FloatingActionButton
|
||||
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary))
|
||||
fab.setOnClickListener { view: View? ->
|
||||
val visibility = layer.filter
|
||||
if (visibility != null && visibility == visible) {
|
||||
layer.setFilter(invisible)
|
||||
fab.setImageResource(R.drawable.ic_layers_clear)
|
||||
} else {
|
||||
layer.setFilter(visible)
|
||||
fab.setImageResource(R.drawable.ic_layers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapFragment;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the MapFragment API using SDK Fragments.
|
||||
* <p>
|
||||
* Uses MapboxMapOptions to initialise the Fragment.
|
||||
* </p>
|
||||
*/
|
||||
public class MapFragmentActivity extends AppCompatActivity implements MapFragment.OnMapViewReadyCallback,
|
||||
OnMapReadyCallback, MapView.OnDidFinishRenderingFrameListener {
|
||||
|
||||
private static final String TAG = "com.mapbox.map";
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private boolean initialCameraAnimation = true;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_fragment);
|
||||
|
||||
MapFragment mapFragment;
|
||||
if (savedInstanceState == null) {
|
||||
mapFragment = MapFragment.newInstance(createFragmentOptions());
|
||||
getFragmentManager()
|
||||
.beginTransaction()
|
||||
.add(R.id.fragment_container, mapFragment, TAG)
|
||||
.commit();
|
||||
} else {
|
||||
mapFragment = (MapFragment) getFragmentManager().findFragmentByTag(TAG);
|
||||
}
|
||||
mapFragment.getMapAsync(this);
|
||||
}
|
||||
|
||||
private MapboxMapOptions createFragmentOptions() {
|
||||
MapboxMapOptions options = MapboxMapOptions.createFromAttributes(this, null);
|
||||
|
||||
options.scrollGesturesEnabled(false);
|
||||
options.zoomGesturesEnabled(false);
|
||||
options.tiltGesturesEnabled(false);
|
||||
options.rotateGesturesEnabled(false);
|
||||
options.debugActive(false);
|
||||
|
||||
LatLng dc = new LatLng(38.90252, -77.02291);
|
||||
|
||||
options.minZoomPreference(9);
|
||||
options.maxZoomPreference(11);
|
||||
options.camera(new CameraPosition.Builder()
|
||||
.target(dc)
|
||||
.zoom(11)
|
||||
.build());
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapViewReady(MapView map) {
|
||||
mapView = map;
|
||||
mapView.addOnDidFinishRenderingFrameListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Outdoor"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapView != null) {
|
||||
mapView.removeOnDidFinishRenderingFrameListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDidFinishRenderingFrame(boolean fully) {
|
||||
if (initialCameraAnimation && fully && mapboxMap != null) {
|
||||
mapboxMap.animateCamera(
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 5000);
|
||||
initialCameraAnimation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.* // ktlint-disable no-wildcard-imports
|
||||
import com.mapbox.mapboxsdk.maps.MapFragment.OnMapViewReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishRenderingFrameListener
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the MapFragment API using SDK Fragments.
|
||||
*
|
||||
*
|
||||
* Uses MapboxMapOptions to initialise the Fragment.
|
||||
*
|
||||
*/
|
||||
class MapFragmentActivity :
|
||||
AppCompatActivity(),
|
||||
OnMapViewReadyCallback,
|
||||
OnMapReadyCallback,
|
||||
OnDidFinishRenderingFrameListener {
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var mapView: MapView? = null
|
||||
private var initialCameraAnimation = true
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_fragment)
|
||||
val mapFragment: MapFragment
|
||||
if (savedInstanceState == null) {
|
||||
mapFragment = MapFragment.newInstance(createFragmentOptions())
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
.add(R.id.fragment_container, mapFragment, TAG)
|
||||
.commit()
|
||||
} else {
|
||||
mapFragment = fragmentManager.findFragmentByTag(TAG) as MapFragment
|
||||
}
|
||||
mapFragment.getMapAsync(this)
|
||||
}
|
||||
|
||||
private fun createFragmentOptions(): MapboxMapOptions {
|
||||
val options = MapboxMapOptions.createFromAttributes(this, null)
|
||||
options.scrollGesturesEnabled(false)
|
||||
options.zoomGesturesEnabled(false)
|
||||
options.tiltGesturesEnabled(false)
|
||||
options.rotateGesturesEnabled(false)
|
||||
options.debugActive(false)
|
||||
val dc = LatLng(38.90252, -77.02291)
|
||||
options.minZoomPreference(9.0)
|
||||
options.maxZoomPreference(11.0)
|
||||
options.camera(
|
||||
CameraPosition.Builder()
|
||||
.target(dc)
|
||||
.zoom(11.0)
|
||||
.build()
|
||||
)
|
||||
return options
|
||||
}
|
||||
|
||||
override fun onMapViewReady(map: MapView) {
|
||||
mapView = map
|
||||
mapView!!.addOnDidFinishRenderingFrameListener(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Outdoor"))
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapView != null) {
|
||||
mapView!!.removeOnDidFinishRenderingFrameListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDidFinishRenderingFrame(fully: Boolean) {
|
||||
if (initialCameraAnimation && fully && mapboxMap != null) {
|
||||
mapboxMap!!.animateCamera(
|
||||
CameraUpdateFactory.newCameraPosition(CameraPosition.Builder().tilt(45.0).build()),
|
||||
5000
|
||||
)
|
||||
initialCameraAnimation = false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "com.mapbox.map"
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.SupportMapFragment;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test Activity showcasing using multiple static map fragments in one layout.
|
||||
*/
|
||||
public class MultiMapActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_multi_map);
|
||||
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
initFragmentStyle(fragmentManager, R.id.map1, Style.getPredefinedStyle("Streets"));
|
||||
initFragmentStyle(fragmentManager, R.id.map2, Style.getPredefinedStyle("Bright"));
|
||||
initFragmentStyle(fragmentManager, R.id.map3, Style.getPredefinedStyle("Satellite Hybrid"));
|
||||
initFragmentStyle(fragmentManager, R.id.map4, Style.getPredefinedStyle("Pastel"));
|
||||
}
|
||||
|
||||
private void initFragmentStyle(FragmentManager fragmentManager, int fragmentId, String styleId) {
|
||||
((SupportMapFragment) fragmentManager.findFragmentById(fragmentId))
|
||||
.getMapAsync(mapboxMap -> mapboxMap.setStyle(styleId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.maps.SupportMapFragment
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test Activity showcasing using multiple static map fragments in one layout.
|
||||
*/
|
||||
class MultiMapActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_multi_map)
|
||||
val fragmentManager = supportFragmentManager
|
||||
initFragmentStyle(fragmentManager, R.id.map1, Style.getPredefinedStyle("Streets"))
|
||||
initFragmentStyle(fragmentManager, R.id.map2, Style.getPredefinedStyle("Bright"))
|
||||
initFragmentStyle(fragmentManager, R.id.map3, Style.getPredefinedStyle("Satellite Hybrid"))
|
||||
initFragmentStyle(fragmentManager, R.id.map4, Style.getPredefinedStyle("Pastel"))
|
||||
}
|
||||
|
||||
private fun initFragmentStyle(
|
||||
fragmentManager: FragmentManager,
|
||||
fragmentId: Int,
|
||||
styleId: String
|
||||
) {
|
||||
(fragmentManager.findFragmentById(fragmentId) as SupportMapFragment?)
|
||||
?.getMapAsync(OnMapReadyCallback { mapboxMap: MapboxMap -> mapboxMap.setStyle(styleId) })
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapFragment;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.SupportMapFragment;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the MapFragment API using Support Library Fragments.
|
||||
* <p>
|
||||
* Uses MapboxMapOptions to initialise the Fragment.
|
||||
* </p>
|
||||
*/
|
||||
public class SupportMapFragmentActivity extends AppCompatActivity implements MapFragment.OnMapViewReadyCallback,
|
||||
OnMapReadyCallback, MapView.OnDidFinishRenderingFrameListener {
|
||||
|
||||
private static final String TAG = "com.mapbox.map";
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private boolean initialCameraAnimation = true;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_fragment);
|
||||
SupportMapFragment mapFragment;
|
||||
if (savedInstanceState == null) {
|
||||
mapFragment = SupportMapFragment.newInstance(createFragmentOptions());
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.add(R.id.fragment_container, mapFragment, TAG)
|
||||
.commit();
|
||||
} else {
|
||||
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag(TAG);
|
||||
}
|
||||
mapFragment.getMapAsync(this);
|
||||
|
||||
}
|
||||
|
||||
private MapboxMapOptions createFragmentOptions() {
|
||||
MapboxMapOptions options = MapboxMapOptions.createFromAttributes(this, null);
|
||||
|
||||
options.scrollGesturesEnabled(false);
|
||||
options.zoomGesturesEnabled(false);
|
||||
options.tiltGesturesEnabled(false);
|
||||
options.rotateGesturesEnabled(false);
|
||||
options.debugActive(false);
|
||||
|
||||
LatLng dc = new LatLng(38.90252, -77.02291);
|
||||
|
||||
options.minZoomPreference(9);
|
||||
options.maxZoomPreference(11);
|
||||
options.camera(new CameraPosition.Builder()
|
||||
.target(dc)
|
||||
.zoom(11)
|
||||
.build());
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapViewReady(MapView map) {
|
||||
mapView = map;
|
||||
mapView.addOnDidFinishRenderingFrameListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Satellite Hybrid"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.removeOnDidFinishRenderingFrameListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDidFinishRenderingFrame(boolean fully) {
|
||||
if (initialCameraAnimation && fully && mapboxMap != null) {
|
||||
mapboxMap.animateCamera(
|
||||
CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 5000);
|
||||
initialCameraAnimation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.fragment
|
||||
|
||||
import android.os.Bundle // ktlint-disable import-ordering
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.* // ktlint-disable no-wildcard-imports
|
||||
import com.mapbox.mapboxsdk.maps.MapFragment.OnMapViewReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishRenderingFrameListener
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the MapFragment API using Support Library Fragments.
|
||||
*
|
||||
*
|
||||
* Uses MapboxMapOptions to initialise the Fragment.
|
||||
*
|
||||
*/
|
||||
class SupportMapFragmentActivity :
|
||||
AppCompatActivity(),
|
||||
OnMapViewReadyCallback,
|
||||
OnMapReadyCallback,
|
||||
OnDidFinishRenderingFrameListener {
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var mapView: MapView? = null
|
||||
private var initialCameraAnimation = true
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_fragment)
|
||||
val mapFragment: SupportMapFragment?
|
||||
if (savedInstanceState == null) {
|
||||
mapFragment = SupportMapFragment.newInstance(createFragmentOptions())
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.add(R.id.fragment_container, mapFragment, TAG)
|
||||
.commit()
|
||||
} else {
|
||||
mapFragment = supportFragmentManager.findFragmentByTag(TAG) as SupportMapFragment?
|
||||
}
|
||||
mapFragment!!.getMapAsync(this)
|
||||
}
|
||||
|
||||
private fun createFragmentOptions(): MapboxMapOptions {
|
||||
val options = MapboxMapOptions.createFromAttributes(this, null)
|
||||
options.scrollGesturesEnabled(false)
|
||||
options.zoomGesturesEnabled(false)
|
||||
options.tiltGesturesEnabled(false)
|
||||
options.rotateGesturesEnabled(false)
|
||||
options.debugActive(false)
|
||||
val dc = LatLng(38.90252, -77.02291)
|
||||
options.minZoomPreference(9.0)
|
||||
options.maxZoomPreference(11.0)
|
||||
options.camera(
|
||||
CameraPosition.Builder()
|
||||
.target(dc)
|
||||
.zoom(11.0)
|
||||
.build()
|
||||
)
|
||||
return options
|
||||
}
|
||||
|
||||
override fun onMapViewReady(map: MapView) {
|
||||
mapView = map
|
||||
mapView!!.addOnDidFinishRenderingFrameListener(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Satellite Hybrid"))
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.removeOnDidFinishRenderingFrameListener(this)
|
||||
}
|
||||
|
||||
override fun onDidFinishRenderingFrame(fully: Boolean) {
|
||||
if (initialCameraAnimation && fully && mapboxMap != null) {
|
||||
mapboxMap!!.animateCamera(
|
||||
CameraUpdateFactory.newCameraPosition(CameraPosition.Builder().tilt(45.0).build()),
|
||||
5000
|
||||
)
|
||||
initialCameraAnimation = false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "com.mapbox.map"
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.imagegenerator;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.print.PrintHelper;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the Snaphot API to print a Map.
|
||||
*/
|
||||
public class PrintActivity extends AppCompatActivity implements MapboxMap.SnapshotReadyCallback {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_print);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this::initMap);
|
||||
|
||||
final View fab = findViewById(R.id.fab);
|
||||
if (fab != null) {
|
||||
fab.setOnClickListener(view -> {
|
||||
if (mapboxMap != null && mapboxMap.getStyle() != null) {
|
||||
mapboxMap.snapshot(PrintActivity.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void initMap(MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSnapshotReady(Bitmap snapshot) {
|
||||
PrintHelper photoPrinter = new PrintHelper(this);
|
||||
photoPrinter.setScaleMode(PrintHelper.SCALE_MODE_FIT);
|
||||
photoPrinter.printBitmap("map.jpg - mapbox print job", snapshot);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.imagegenerator
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.print.PrintHelper
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the Snaphot API to print a Map.
|
||||
*/
|
||||
class PrintActivity : AppCompatActivity(), MapboxMap.SnapshotReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_print)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(OnMapReadyCallback { mapboxMap: MapboxMap -> initMap(mapboxMap) })
|
||||
val fab = findViewById<View>(R.id.fab)
|
||||
fab?.setOnClickListener { view: View? ->
|
||||
if (mapboxMap != null && mapboxMap!!.style != null) {
|
||||
mapboxMap!!.snapshot(this@PrintActivity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initMap(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
}
|
||||
|
||||
override fun onSnapshotReady(snapshot: Bitmap) {
|
||||
val photoPrinter = PrintHelper(this)
|
||||
photoPrinter.scaleMode = PrintHelper.SCALE_MODE_FIT
|
||||
photoPrinter.printBitmap("map.jpg - mapbox print job", snapshot)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.InfoWindow;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.IconUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Test activity showcasing how to dynamically update InfoWindow when Using an MapboxMap.InfoWindowAdapter.
|
||||
*/
|
||||
public class DynamicInfoWindowAdapterActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private static final LatLng PARIS = new LatLng(48.864716, 2.349014);
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private Marker marker;
|
||||
|
||||
private MapboxMap.OnMapClickListener mapClickListener = new MapboxMap.OnMapClickListener() {
|
||||
@Override
|
||||
public boolean onMapClick(@NonNull LatLng point) {
|
||||
if (marker == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Distance from click to marker
|
||||
double distanceKm = marker.getPosition().distanceTo(point) / 1000;
|
||||
|
||||
// Get the info window
|
||||
final InfoWindow infoWindow = marker.getInfoWindow();
|
||||
|
||||
// Get the view from the info window
|
||||
if (infoWindow != null && infoWindow.getView() != null) {
|
||||
// Set the new text on the text view in the info window
|
||||
TextView textView = (TextView) infoWindow.getView();
|
||||
textView.setText(String.format(Locale.getDefault(), "%.2fkm", distanceKm));
|
||||
// Update the info window position (as the text length changes)
|
||||
textView.post(infoWindow::update);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_infowindow_adapter);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
|
||||
// Add info window adapter
|
||||
addCustomInfoWindowAdapter(mapboxMap);
|
||||
|
||||
// Keep info windows open on click
|
||||
mapboxMap.getUiSettings().setDeselectMarkersOnTap(false);
|
||||
|
||||
// Add a marker
|
||||
marker = addMarker(mapboxMap);
|
||||
mapboxMap.selectMarker(marker);
|
||||
|
||||
// On map click, change the info window contents
|
||||
mapboxMap.addOnMapClickListener(mapClickListener);
|
||||
|
||||
// Focus on Paris
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(PARIS));
|
||||
}
|
||||
|
||||
private Marker addMarker(MapboxMap mapboxMap) {
|
||||
return mapboxMap.addMarker(
|
||||
new MarkerOptions()
|
||||
.position(PARIS)
|
||||
.icon(IconUtils.drawableToIcon(this, R.drawable.ic_location_city,
|
||||
ResourcesCompat.getColor(getResources(), R.color.mapbox_blue, getTheme()))
|
||||
));
|
||||
}
|
||||
|
||||
private void addCustomInfoWindowAdapter(final MapboxMap mapboxMap) {
|
||||
final int padding = (int) getResources().getDimension(R.dimen.attr_margin);
|
||||
mapboxMap.setInfoWindowAdapter(marker -> {
|
||||
TextView textView = new TextView(DynamicInfoWindowAdapterActivity.this);
|
||||
textView.setText(marker.getTitle());
|
||||
textView.setBackgroundColor(Color.WHITE);
|
||||
textView.setText(R.string.action_calculate_distance);
|
||||
textView.setPadding(padding, padding, padding, padding);
|
||||
return textView;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnMapClickListener(mapClickListener);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.mapbox.mapboxsdk.annotations.Marker
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.InfoWindowAdapter
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.IconUtils
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Test activity showcasing how to dynamically update InfoWindow when Using an MapboxMap.InfoWindowAdapter.
|
||||
*/
|
||||
class DynamicInfoWindowAdapterActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var mapView: MapView
|
||||
private var marker: Marker? = null
|
||||
private val mapClickListener = OnMapClickListener { point ->
|
||||
if (marker == null) {
|
||||
return@OnMapClickListener false
|
||||
}
|
||||
|
||||
// Distance from click to marker
|
||||
val distanceKm = marker!!.position.distanceTo(point) / 1000
|
||||
|
||||
// Get the info window
|
||||
val infoWindow = marker!!.infoWindow
|
||||
|
||||
// Get the view from the info window
|
||||
if (infoWindow != null && infoWindow.view != null) {
|
||||
// Set the new text on the text view in the info window
|
||||
val textView = infoWindow.view as TextView?
|
||||
textView!!.text = String.format(Locale.getDefault(), "%.2fkm", distanceKm)
|
||||
// Update the info window position (as the text length changes)
|
||||
textView.post { infoWindow.update() }
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_infowindow_adapter)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
|
||||
// Add info window adapter
|
||||
addCustomInfoWindowAdapter(mapboxMap!!)
|
||||
|
||||
// Keep info windows open on click
|
||||
mapboxMap!!.uiSettings.isDeselectMarkersOnTap = false
|
||||
|
||||
// Add a marker
|
||||
marker = addMarker(mapboxMap!!)
|
||||
mapboxMap!!.selectMarker(marker!!)
|
||||
|
||||
// On map click, change the info window contents
|
||||
mapboxMap!!.addOnMapClickListener(mapClickListener)
|
||||
|
||||
// Focus on Paris
|
||||
mapboxMap!!.animateCamera(CameraUpdateFactory.newLatLng(PARIS))
|
||||
}
|
||||
|
||||
private fun addMarker(mapboxMap: MapboxMap): Marker {
|
||||
return mapboxMap.addMarker(
|
||||
MarkerOptions()
|
||||
.position(PARIS)
|
||||
.icon(
|
||||
IconUtils.drawableToIcon(
|
||||
this,
|
||||
R.drawable.ic_location_city,
|
||||
ResourcesCompat.getColor(resources, R.color.mapbox_blue, theme)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun addCustomInfoWindowAdapter(mapboxMap: MapboxMap) {
|
||||
val padding = resources.getDimension(R.dimen.attr_margin).toInt()
|
||||
mapboxMap.infoWindowAdapter = InfoWindowAdapter { marker: Marker ->
|
||||
val textView = TextView(this@DynamicInfoWindowAdapterActivity)
|
||||
textView.text = marker.title
|
||||
textView.setBackgroundColor(Color.WHITE)
|
||||
textView.setText(R.string.action_calculate_distance)
|
||||
textView.setPadding(padding, padding, padding, padding)
|
||||
textView
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnMapClickListener(mapClickListener)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PARIS = LatLng(48.864716, 2.349014)
|
||||
}
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the InfoWindow API above Washington D.C.
|
||||
* <p>
|
||||
* Allows to test mulitple concurrently open InfoWindows.
|
||||
* </p>
|
||||
*/
|
||||
public class InfoWindowActivity extends AppCompatActivity
|
||||
implements OnMapReadyCallback, MapboxMap.OnInfoWindowCloseListener, MapboxMap.OnInfoWindowClickListener,
|
||||
MapboxMap.OnInfoWindowLongClickListener {
|
||||
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private Marker customMarker;
|
||||
|
||||
private MapboxMap.OnMapLongClickListener mapLongClickListener = new MapboxMap.OnMapLongClickListener() {
|
||||
@Override
|
||||
public boolean onMapLongClick(@NonNull LatLng point) {
|
||||
if (customMarker != null) {
|
||||
// Remove previous added marker
|
||||
mapboxMap.removeAnnotation(customMarker);
|
||||
customMarker = null;
|
||||
}
|
||||
|
||||
// Add marker on long click location with default marker image
|
||||
customMarker = mapboxMap.addMarker(new MarkerOptions()
|
||||
.title("Custom Marker")
|
||||
.snippet(new DecimalFormat("#.#####").format(point.getLatitude()) + ", "
|
||||
+ new DecimalFormat("#.#####").format(point.getLongitude()))
|
||||
.position(point));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_infowindow);
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
addMarkers();
|
||||
addInfoWindowListeners();
|
||||
});
|
||||
}
|
||||
|
||||
private void addMarkers() {
|
||||
mapboxMap.addMarker(new MarkerOptions()
|
||||
.title("Intersection")
|
||||
.snippet("H St NW with 15th St NW")
|
||||
.position(new LatLng(38.9002073, -77.03364419)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().title("Intersection")
|
||||
.snippet("E St NW with 17th St NW")
|
||||
.position(new LatLng(38.8954236, -77.0394623)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().title("The Ellipse").position(new LatLng(38.89393, -77.03654)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().position(new LatLng(38.89596, -77.03434)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().snippet("Lafayette Square").position(new LatLng(38.89949, -77.03656)));
|
||||
|
||||
Marker marker = mapboxMap.addMarker(new MarkerOptions()
|
||||
.title("White House")
|
||||
.snippet("The official residence and principal workplace of the President of the United States, "
|
||||
+ "located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every"
|
||||
+ "U.S. president since John Adams in 1800.")
|
||||
.position(new LatLng(38.897705003219784, -77.03655168667463)));
|
||||
|
||||
// open InfoWindow at startup
|
||||
mapboxMap.selectMarker(marker);
|
||||
}
|
||||
|
||||
private void addInfoWindowListeners() {
|
||||
mapboxMap.setOnInfoWindowCloseListener(this);
|
||||
mapboxMap.addOnMapLongClickListener(mapLongClickListener);
|
||||
mapboxMap.setOnInfoWindowClickListener(this);
|
||||
mapboxMap.setOnInfoWindowLongClickListener(this);
|
||||
}
|
||||
|
||||
private void toggleConcurrentInfoWindow(boolean allowConcurrentInfoWindow) {
|
||||
mapboxMap.deselectMarkers();
|
||||
mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(allowConcurrentInfoWindow);
|
||||
}
|
||||
|
||||
private void toggleDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
|
||||
mapboxMap.getUiSettings().setDeselectMarkersOnTap(deselectMarkersOnTap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInfoWindowClick(@NonNull Marker marker) {
|
||||
Toast.makeText(getApplicationContext(), "OnClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
|
||||
// returning true will leave the info window open
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoWindowClose(Marker marker) {
|
||||
Toast.makeText(getApplicationContext(), "OnClose: " + marker.getTitle(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoWindowLongClick(Marker marker) {
|
||||
Toast.makeText(getApplicationContext(), "OnLongClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnMapLongClickListener(mapLongClickListener);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_infowindow, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_toggle_concurrent_infowindow:
|
||||
toggleConcurrentInfoWindow(!item.isChecked());
|
||||
item.setChecked(!item.isChecked());
|
||||
return true;
|
||||
case R.id.action_toggle_deselect_markers_on_tap:
|
||||
toggleDeselectMarkersOnTap(!item.isChecked());
|
||||
item.setChecked(!item.isChecked());
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.annotations.Marker
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowClickListener
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowCloseListener
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowLongClickListener
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapLongClickListener
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import java.text.DecimalFormat
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the InfoWindow API above Washington D.C.
|
||||
*
|
||||
*
|
||||
* Allows to test mulitple concurrently open InfoWindows.
|
||||
*
|
||||
*/
|
||||
class InfoWindowActivity :
|
||||
AppCompatActivity(),
|
||||
OnMapReadyCallback,
|
||||
OnInfoWindowCloseListener,
|
||||
OnInfoWindowClickListener,
|
||||
OnInfoWindowLongClickListener {
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var mapView: MapView? = null
|
||||
private var customMarker: Marker? = null
|
||||
private val mapLongClickListener = OnMapLongClickListener { point ->
|
||||
if (customMarker != null) {
|
||||
// Remove previous added marker
|
||||
mapboxMap!!.removeAnnotation(customMarker!!)
|
||||
customMarker = null
|
||||
}
|
||||
|
||||
// Add marker on long click location with default marker image
|
||||
customMarker = mapboxMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.title("Custom Marker")
|
||||
.snippet(
|
||||
DecimalFormat("#.#####").format(point.latitude) + ", " +
|
||||
DecimalFormat("#.#####").format(point.longitude)
|
||||
)
|
||||
.position(point)
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_infowindow)
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets")) { style: Style? ->
|
||||
addMarkers()
|
||||
addInfoWindowListeners()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addMarkers() {
|
||||
mapboxMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.title("Intersection")
|
||||
.snippet("H St NW with 15th St NW")
|
||||
.position(LatLng(38.9002073, -77.03364419))
|
||||
)
|
||||
mapboxMap!!.addMarker(
|
||||
MarkerOptions().title("Intersection")
|
||||
.snippet("E St NW with 17th St NW")
|
||||
.position(LatLng(38.8954236, -77.0394623))
|
||||
)
|
||||
mapboxMap!!.addMarker(
|
||||
MarkerOptions().title("The Ellipse").position(LatLng(38.89393, -77.03654))
|
||||
)
|
||||
mapboxMap!!.addMarker(MarkerOptions().position(LatLng(38.89596, -77.03434)))
|
||||
mapboxMap!!.addMarker(
|
||||
MarkerOptions().snippet("Lafayette Square").position(LatLng(38.89949, -77.03656))
|
||||
)
|
||||
val marker = mapboxMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.title("White House")
|
||||
.snippet(
|
||||
"The official residence and principal workplace of the President of the United States, " +
|
||||
"located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every" +
|
||||
"U.S. president since John Adams in 1800."
|
||||
)
|
||||
.position(LatLng(38.897705003219784, -77.03655168667463))
|
||||
)
|
||||
|
||||
// open InfoWindow at startup
|
||||
mapboxMap!!.selectMarker(marker)
|
||||
}
|
||||
|
||||
private fun addInfoWindowListeners() {
|
||||
mapboxMap!!.onInfoWindowCloseListener = this
|
||||
mapboxMap!!.addOnMapLongClickListener(mapLongClickListener)
|
||||
mapboxMap!!.onInfoWindowClickListener = this
|
||||
mapboxMap!!.onInfoWindowLongClickListener = this
|
||||
}
|
||||
|
||||
private fun toggleConcurrentInfoWindow(allowConcurrentInfoWindow: Boolean) {
|
||||
mapboxMap!!.deselectMarkers()
|
||||
mapboxMap!!.isAllowConcurrentMultipleOpenInfoWindows = allowConcurrentInfoWindow
|
||||
}
|
||||
|
||||
private fun toggleDeselectMarkersOnTap(deselectMarkersOnTap: Boolean) {
|
||||
mapboxMap!!.uiSettings.isDeselectMarkersOnTap = deselectMarkersOnTap
|
||||
}
|
||||
|
||||
override fun onInfoWindowClick(marker: Marker): Boolean {
|
||||
Toast.makeText(applicationContext, "OnClick: " + marker.title, Toast.LENGTH_LONG).show()
|
||||
// returning true will leave the info window open
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onInfoWindowClose(marker: Marker) {
|
||||
Toast.makeText(applicationContext, "OnClose: " + marker.title, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
override fun onInfoWindowLongClick(marker: Marker) {
|
||||
Toast.makeText(applicationContext, "OnLongClick: " + marker.title, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnMapLongClickListener(mapLongClickListener)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_infowindow, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_toggle_concurrent_infowindow -> {
|
||||
toggleConcurrentInfoWindow(!item.isChecked)
|
||||
item.isChecked = !item.isChecked
|
||||
true
|
||||
}
|
||||
R.id.action_toggle_deselect_markers_on_tap -> {
|
||||
toggleDeselectMarkersOnTap(!item.isChecked)
|
||||
item.isChecked = !item.isChecked
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.CityStateMarker;
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.CityStateMarkerOptions;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.IconUtils;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using an InfoWindowAdapter to provide a custom InfoWindow content.
|
||||
*/
|
||||
public class InfoWindowAdapterActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_infowindow_adapter);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(map -> {
|
||||
mapboxMap = map;
|
||||
map.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
addMarkers();
|
||||
addCustomInfoWindowAdapter();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void addMarkers() {
|
||||
mapboxMap.addMarker(generateCityStateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
|
||||
mapboxMap.addMarker(generateCityStateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
|
||||
mapboxMap.addMarker(generateCityStateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
|
||||
mapboxMap.addMarker(generateCityStateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
|
||||
mapboxMap.addMarker(generateCityStateMarker("San Marino", 43.942360, 12.457777, "#795548"));
|
||||
mapboxMap.addMarker(generateCityStateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
|
||||
}
|
||||
|
||||
private CityStateMarkerOptions generateCityStateMarker(String title, double lat, double lng, String color) {
|
||||
CityStateMarkerOptions marker = new CityStateMarkerOptions();
|
||||
marker.title(title);
|
||||
marker.position(new LatLng(lat, lng));
|
||||
marker.infoWindowBackground(color);
|
||||
|
||||
Icon icon = IconUtils.drawableToIcon(this, R.drawable.ic_location_city, Color.parseColor(color));
|
||||
marker.icon(icon);
|
||||
return marker;
|
||||
}
|
||||
|
||||
private void addCustomInfoWindowAdapter() {
|
||||
mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
|
||||
|
||||
private int tenDp = (int) getResources().getDimension(R.dimen.attr_margin);
|
||||
|
||||
@Override
|
||||
public View getInfoWindow(@NonNull Marker marker) {
|
||||
TextView textView = new TextView(InfoWindowAdapterActivity.this);
|
||||
textView.setText(marker.getTitle());
|
||||
textView.setTextColor(Color.WHITE);
|
||||
|
||||
if (marker instanceof CityStateMarker) {
|
||||
CityStateMarker cityStateMarker = (CityStateMarker) marker;
|
||||
textView.setBackgroundColor(Color.parseColor(cityStateMarker.getInfoWindowBackgroundColor()));
|
||||
}
|
||||
|
||||
textView.setPadding(tenDp, tenDp, tenDp, tenDp);
|
||||
return textView;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.annotations.Marker
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.InfoWindowAdapter
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.CityStateMarker
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.CityStateMarkerOptions
|
||||
import com.mapbox.mapboxsdk.testapp.utils.IconUtils
|
||||
|
||||
/**
|
||||
* Test activity showcasing using an InfoWindowAdapter to provide a custom InfoWindow content.
|
||||
*/
|
||||
class InfoWindowAdapterActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_infowindow_adapter)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { map: MapboxMap ->
|
||||
mapboxMap = map
|
||||
map.setStyle(Style.getPredefinedStyle("Streets")) { style: Style? ->
|
||||
addMarkers()
|
||||
addCustomInfoWindowAdapter()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun addMarkers() {
|
||||
mapboxMap!!.addMarker(generateCityStateMarker("Andorra", 42.505777, 1.52529, "#F44336"))
|
||||
mapboxMap!!.addMarker(generateCityStateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"))
|
||||
mapboxMap!!.addMarker(generateCityStateMarker("Monaco", 43.738418, 7.424616, "#673AB7"))
|
||||
mapboxMap!!.addMarker(
|
||||
generateCityStateMarker(
|
||||
"Vatican City",
|
||||
41.902916,
|
||||
12.453389,
|
||||
"#009688"
|
||||
)
|
||||
)
|
||||
mapboxMap!!.addMarker(
|
||||
generateCityStateMarker(
|
||||
"San Marino",
|
||||
43.942360,
|
||||
12.457777,
|
||||
"#795548"
|
||||
)
|
||||
)
|
||||
mapboxMap!!.addMarker(
|
||||
generateCityStateMarker(
|
||||
"Liechtenstein",
|
||||
47.166000,
|
||||
9.555373,
|
||||
"#FF5722"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateCityStateMarker(
|
||||
title: String,
|
||||
lat: Double,
|
||||
lng: Double,
|
||||
color: String
|
||||
): CityStateMarkerOptions {
|
||||
val marker = CityStateMarkerOptions()
|
||||
marker.title(title)
|
||||
marker.position(LatLng(lat, lng))
|
||||
marker.infoWindowBackground(color)
|
||||
val icon =
|
||||
IconUtils.drawableToIcon(this, R.drawable.ic_location_city, Color.parseColor(color))
|
||||
marker.icon(icon)
|
||||
return marker
|
||||
}
|
||||
|
||||
private fun addCustomInfoWindowAdapter() {
|
||||
mapboxMap!!.infoWindowAdapter = object : InfoWindowAdapter {
|
||||
private val tenDp = resources.getDimension(R.dimen.attr_margin).toInt()
|
||||
override fun getInfoWindow(marker: Marker): View? {
|
||||
val textView = TextView(this@InfoWindowAdapterActivity)
|
||||
textView.text = marker.title
|
||||
textView.setTextColor(Color.WHITE)
|
||||
if (marker is CityStateMarker) {
|
||||
textView.setBackgroundColor(Color.parseColor(marker.infoWindowBackgroundColor))
|
||||
}
|
||||
textView.setPadding(tenDp, tenDp, tenDp, tenDp)
|
||||
return textView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest;
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.location.Utils.getNextStyle;
|
||||
|
||||
/**
|
||||
* This activity shows a basic usage of the LocationComponent's pulsing circle. There's no
|
||||
* customization of the pulsing circle's color, radius, speed, etc.
|
||||
*/
|
||||
public class BasicLocationPulsingCircleActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private static final String SAVED_STATE_LOCATION = "saved_state_location";
|
||||
private static final String TAG = "Mbgl-BasicLocationPulsingCircleActivity";
|
||||
|
||||
private Location lastLocation;
|
||||
private MapView mapView;
|
||||
private PermissionsManager permissionsManager;
|
||||
private LocationComponent locationComponent;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_layer_basic_pulsing_circle);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION);
|
||||
}
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
checkPermissions();
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
locationComponent = mapboxMap.getLocationComponent();
|
||||
|
||||
LocationComponentOptions locationComponentOptions =
|
||||
LocationComponentOptions.builder(BasicLocationPulsingCircleActivity.this)
|
||||
.pulseEnabled(true)
|
||||
.build();
|
||||
|
||||
LocationComponentActivationOptions locationComponentActivationOptions =
|
||||
buildLocationComponentActivationOptions(style,locationComponentOptions);
|
||||
|
||||
locationComponent.activateLocationComponent(locationComponentActivationOptions);
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
locationComponent.setCameraMode(CameraMode.TRACKING);
|
||||
locationComponent.forceLocationUpdate(lastLocation);
|
||||
});
|
||||
}
|
||||
|
||||
private LocationComponentActivationOptions buildLocationComponentActivationOptions(@NonNull Style style,
|
||||
@NonNull LocationComponentOptions
|
||||
locationComponentOptions) {
|
||||
return LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationComponentOptions(locationComponentOptions)
|
||||
.useDefaultLocationEngine(true)
|
||||
.locationEngineRequest(new LocationEngineRequest.Builder(750)
|
||||
.setFastestInterval(750)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_pulsing_location_mode, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (locationComponent == null) {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_map_style_change) {
|
||||
loadNewStyle();
|
||||
return true;
|
||||
} else if (id == R.id.action_component_disable) {
|
||||
locationComponent.setLocationComponentEnabled(false);
|
||||
return true;
|
||||
} else if (id == R.id.action_component_enabled) {
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
return true;
|
||||
} else if (id == R.id.action_stop_pulsing) {
|
||||
locationComponent.applyStyle(LocationComponentOptions.builder(
|
||||
BasicLocationPulsingCircleActivity.this)
|
||||
.pulseEnabled(false)
|
||||
.build());
|
||||
return true;
|
||||
} else if (id == R.id.action_start_pulsing) {
|
||||
locationComponent.applyStyle(LocationComponentOptions.builder(
|
||||
BasicLocationPulsingCircleActivity.this)
|
||||
.pulseEnabled(true)
|
||||
.build());
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void loadNewStyle() {
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(getNextStyle()));
|
||||
}
|
||||
|
||||
private void checkPermissions() {
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this);
|
||||
} else {
|
||||
permissionsManager = new PermissionsManager(new PermissionsListener() {
|
||||
@Override
|
||||
public void onExplanationNeeded(List<String> permissionsToExplain) {
|
||||
Toast.makeText(BasicLocationPulsingCircleActivity.this, "You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean granted) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(BasicLocationPulsingCircleActivity.this);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
if (locationComponent != null) {
|
||||
outState.putParcelable(SAVED_STATE_LOCATION, locationComponent.getLastKnownLocation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.location.Location
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* This activity shows a basic usage of the LocationComponent's pulsing circle. There's no
|
||||
* customization of the pulsing circle's color, radius, speed, etc.
|
||||
*/
|
||||
class BasicLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private var lastLocation: Location? = null
|
||||
private lateinit var mapView: MapView
|
||||
private var permissionsManager: PermissionsManager? = null
|
||||
private var locationComponent: LocationComponent? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_layer_basic_pulsing_circle)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
if (savedInstanceState != null) {
|
||||
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION)
|
||||
}
|
||||
mapView.onCreate(savedInstanceState)
|
||||
checkPermissions()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets")) { style: Style ->
|
||||
locationComponent = mapboxMap.locationComponent
|
||||
val locationComponentOptions =
|
||||
LocationComponentOptions.builder(this@BasicLocationPulsingCircleActivity)
|
||||
.pulseEnabled(true)
|
||||
.build()
|
||||
val locationComponentActivationOptions =
|
||||
buildLocationComponentActivationOptions(style, locationComponentOptions)
|
||||
locationComponent!!.activateLocationComponent(locationComponentActivationOptions)
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
locationComponent!!.cameraMode = CameraMode.TRACKING
|
||||
locationComponent!!.forceLocationUpdate(lastLocation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildLocationComponentActivationOptions(
|
||||
style: Style,
|
||||
locationComponentOptions: LocationComponentOptions
|
||||
): LocationComponentActivationOptions {
|
||||
return LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationComponentOptions(locationComponentOptions)
|
||||
.useDefaultLocationEngine(true)
|
||||
.locationEngineRequest(
|
||||
LocationEngineRequest.Builder(750)
|
||||
.setFastestInterval(750)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_pulsing_location_mode, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (locationComponent == null) {
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
val id = item.itemId
|
||||
if (id == R.id.action_map_style_change) {
|
||||
loadNewStyle()
|
||||
return true
|
||||
} else if (id == R.id.action_component_disable) {
|
||||
locationComponent!!.isLocationComponentEnabled = false
|
||||
return true
|
||||
} else if (id == R.id.action_component_enabled) {
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
return true
|
||||
} else if (id == R.id.action_stop_pulsing) {
|
||||
locationComponent!!.applyStyle(
|
||||
LocationComponentOptions.builder(
|
||||
this@BasicLocationPulsingCircleActivity
|
||||
)
|
||||
.pulseEnabled(false)
|
||||
.build()
|
||||
)
|
||||
return true
|
||||
} else if (id == R.id.action_start_pulsing) {
|
||||
locationComponent!!.applyStyle(
|
||||
LocationComponentOptions.builder(
|
||||
this@BasicLocationPulsingCircleActivity
|
||||
)
|
||||
.pulseEnabled(true)
|
||||
.build()
|
||||
)
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun loadNewStyle() {
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(Utils.nextStyle()))
|
||||
}
|
||||
|
||||
private fun checkPermissions() {
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView!!.getMapAsync(this)
|
||||
} else {
|
||||
permissionsManager = PermissionsManager(object : PermissionsListener {
|
||||
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
|
||||
Toast.makeText(
|
||||
this@BasicLocationPulsingCircleActivity,
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onPermissionResult(granted: Boolean) {
|
||||
if (granted) {
|
||||
mapView!!.getMapAsync(this@BasicLocationPulsingCircleActivity)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
permissionsManager!!.requestLocationPermissions(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
if (locationComponent != null) {
|
||||
outState.putParcelable(SAVED_STATE_LOCATION, locationComponent!!.lastKnownLocation)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SAVED_STATE_LOCATION = "saved_state_location"
|
||||
private const val TAG = "Mbgl-BasicLocationPulsingCircleActivity"
|
||||
}
|
||||
}
|
||||
@@ -1,360 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Color;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.ListPopupWindow;
|
||||
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest;
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.mapbox.mapboxsdk.testapp.activity.location.Utils.getNextStyle;
|
||||
|
||||
/**
|
||||
* This activity shows how to customize the LocationComponent's pulsing circle.
|
||||
*/
|
||||
public class CustomizedLocationPulsingCircleActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
//region
|
||||
|
||||
// Adjust these variables to customize the example's pulsing circle UI
|
||||
private static final float DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS = 2300;
|
||||
private static final float SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS = 800;
|
||||
private static final float THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS = 8000;
|
||||
private static final float DEFAULT_LOCATION_CIRCLE_PULSE_RADIUS = 35;
|
||||
private static final float DEFAULT_LOCATION_CIRCLE_PULSE_ALPHA = .55f;
|
||||
private static final Interpolator DEFAULT_LOCATION_CIRCLE_INTERPOLATOR_PULSE_MODE
|
||||
= new DecelerateInterpolator();
|
||||
private static final boolean DEFAULT_LOCATION_CIRCLE_PULSE_FADE_MODE = true;
|
||||
//endregion
|
||||
|
||||
//region
|
||||
private static int LOCATION_CIRCLE_PULSE_COLOR;
|
||||
private static float LOCATION_CIRCLE_PULSE_DURATION = DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS;
|
||||
private static final String SAVED_STATE_LOCATION = "saved_state_location";
|
||||
private static final String SAVED_STATE_LOCATION_CIRCLE_PULSE_COLOR = "saved_state_color";
|
||||
private static final String SAVED_STATE_LOCATION_CIRCLE_PULSE_DURATION = "saved_state_duration";
|
||||
private static final String LAYER_BELOW_ID = "poi_transit";
|
||||
|
||||
private Location lastLocation;
|
||||
private MapView mapView;
|
||||
private Button pulsingCircleDurationButton;
|
||||
private Button pulsingCircleColorButton;
|
||||
private PermissionsManager permissionsManager;
|
||||
private LocationComponent locationComponent;
|
||||
private MapboxMap mapboxMap;
|
||||
private float currentPulseDuration;
|
||||
//endregion
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_layer_customized_pulsing_circle);
|
||||
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.BLUE;
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION);
|
||||
LOCATION_CIRCLE_PULSE_COLOR = savedInstanceState.getInt(SAVED_STATE_LOCATION_CIRCLE_PULSE_COLOR);
|
||||
LOCATION_CIRCLE_PULSE_DURATION = savedInstanceState.getFloat(SAVED_STATE_LOCATION_CIRCLE_PULSE_DURATION);
|
||||
}
|
||||
|
||||
pulsingCircleDurationButton = findViewById(R.id.button_location_circle_duration);
|
||||
pulsingCircleDurationButton.setText(String.format("%sms",
|
||||
String.valueOf(LOCATION_CIRCLE_PULSE_DURATION)));
|
||||
pulsingCircleDurationButton.setOnClickListener(v -> {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
showDurationListDialog();
|
||||
});
|
||||
|
||||
pulsingCircleColorButton = findViewById(R.id.button_location_circle_color);
|
||||
pulsingCircleColorButton.setOnClickListener(v -> {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
showColorListDialog();
|
||||
});
|
||||
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
checkPermissions();
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
locationComponent = mapboxMap.getLocationComponent();
|
||||
|
||||
LocationComponentOptions locationComponentOptions =
|
||||
buildLocationComponentOptions(
|
||||
LOCATION_CIRCLE_PULSE_COLOR,
|
||||
LOCATION_CIRCLE_PULSE_DURATION)
|
||||
.pulseEnabled(true)
|
||||
.build();
|
||||
|
||||
LocationComponentActivationOptions locationComponentActivationOptions =
|
||||
buildLocationComponentActivationOptions(style,locationComponentOptions);
|
||||
|
||||
locationComponent.activateLocationComponent(locationComponentActivationOptions);
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
locationComponent.setCameraMode(CameraMode.TRACKING);
|
||||
locationComponent.forceLocationUpdate(lastLocation);
|
||||
});
|
||||
}
|
||||
|
||||
private LocationComponentOptions.Builder buildLocationComponentOptions(int pulsingCircleColor,
|
||||
float pulsingCircleDuration
|
||||
) {
|
||||
currentPulseDuration = pulsingCircleDuration;
|
||||
return LocationComponentOptions.builder(this)
|
||||
.layerBelow(LAYER_BELOW_ID)
|
||||
.pulseFadeEnabled(DEFAULT_LOCATION_CIRCLE_PULSE_FADE_MODE)
|
||||
.pulseInterpolator(DEFAULT_LOCATION_CIRCLE_INTERPOLATOR_PULSE_MODE)
|
||||
.pulseColor(pulsingCircleColor)
|
||||
.pulseAlpha(DEFAULT_LOCATION_CIRCLE_PULSE_ALPHA)
|
||||
.pulseSingleDuration(pulsingCircleDuration)
|
||||
.pulseMaxRadius(DEFAULT_LOCATION_CIRCLE_PULSE_RADIUS);
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private void setNewLocationComponentOptions(float newPulsingDuration,
|
||||
int newPulsingColor) {
|
||||
mapboxMap.getStyle(style -> locationComponent.applyStyle(
|
||||
buildLocationComponentOptions(
|
||||
newPulsingColor,
|
||||
newPulsingDuration)
|
||||
.pulseEnabled(true)
|
||||
.build()));
|
||||
}
|
||||
|
||||
private LocationComponentActivationOptions buildLocationComponentActivationOptions(
|
||||
@NonNull Style style,
|
||||
@NonNull LocationComponentOptions locationComponentOptions) {
|
||||
return LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationComponentOptions(locationComponentOptions)
|
||||
.useDefaultLocationEngine(true)
|
||||
.locationEngineRequest(new LocationEngineRequest.Builder(750)
|
||||
.setFastestInterval(750)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_pulsing_location_mode, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (locationComponent == null) {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_map_style_change) {
|
||||
loadNewStyle();
|
||||
return true;
|
||||
} else if (id == R.id.action_component_disable) {
|
||||
locationComponent.setLocationComponentEnabled(false);
|
||||
return true;
|
||||
} else if (id == R.id.action_component_enabled) {
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
return true;
|
||||
} else if (id == R.id.action_stop_pulsing) {
|
||||
locationComponent.applyStyle(LocationComponentOptions.builder(
|
||||
CustomizedLocationPulsingCircleActivity.this)
|
||||
.pulseEnabled(false)
|
||||
.build());
|
||||
return true;
|
||||
} else if (id == R.id.action_start_pulsing) {
|
||||
locationComponent.applyStyle(buildLocationComponentOptions(
|
||||
LOCATION_CIRCLE_PULSE_COLOR,
|
||||
LOCATION_CIRCLE_PULSE_DURATION)
|
||||
.pulseEnabled(true)
|
||||
.build());
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void loadNewStyle() {
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(getNextStyle()));
|
||||
}
|
||||
|
||||
private void checkPermissions() {
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this);
|
||||
} else {
|
||||
permissionsManager = new PermissionsManager(new PermissionsListener() {
|
||||
@Override
|
||||
public void onExplanationNeeded(List<String> permissionsToExplain) {
|
||||
Toast.makeText(CustomizedLocationPulsingCircleActivity.this, "You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean granted) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(CustomizedLocationPulsingCircleActivity.this);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void showDurationListDialog() {
|
||||
List<String> modes = new ArrayList<>();
|
||||
modes.add(String.format("%sms", String.valueOf(DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS)));
|
||||
modes.add(String.format("%sms", String.valueOf(SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS)));
|
||||
modes.add(String.format("%sms", String.valueOf(THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS)));
|
||||
ArrayAdapter<String> profileAdapter = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_list_item_1, modes);
|
||||
ListPopupWindow listPopup = new ListPopupWindow(this);
|
||||
listPopup.setAdapter(profileAdapter);
|
||||
listPopup.setAnchorView(pulsingCircleDurationButton);
|
||||
listPopup.setOnItemClickListener((parent, itemView, position, id) -> {
|
||||
String selectedMode = modes.get(position);
|
||||
pulsingCircleDurationButton.setText(selectedMode);
|
||||
if (selectedMode.contentEquals(String.format("%sms",
|
||||
String.valueOf(DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS)))) {
|
||||
LOCATION_CIRCLE_PULSE_DURATION = DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS;
|
||||
setNewLocationComponentOptions(DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS, LOCATION_CIRCLE_PULSE_COLOR);
|
||||
} else if (selectedMode.contentEquals(String.format("%sms",
|
||||
String.valueOf(SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS)))) {
|
||||
LOCATION_CIRCLE_PULSE_DURATION = SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS;
|
||||
setNewLocationComponentOptions(SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS, LOCATION_CIRCLE_PULSE_COLOR);
|
||||
} else if (selectedMode.contentEquals(String.format("%sms",
|
||||
String.valueOf(THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS)))) {
|
||||
LOCATION_CIRCLE_PULSE_DURATION = THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS;
|
||||
setNewLocationComponentOptions(THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS, LOCATION_CIRCLE_PULSE_COLOR);
|
||||
}
|
||||
listPopup.dismiss();
|
||||
});
|
||||
listPopup.show();
|
||||
}
|
||||
|
||||
private void showColorListDialog() {
|
||||
List<String> trackingTypes = new ArrayList<>();
|
||||
trackingTypes.add("Blue");
|
||||
trackingTypes.add("Red");
|
||||
trackingTypes.add("Green");
|
||||
trackingTypes.add("Gray");
|
||||
ArrayAdapter<String> profileAdapter = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_list_item_1, trackingTypes);
|
||||
ListPopupWindow listPopup = new ListPopupWindow(this);
|
||||
listPopup.setAdapter(profileAdapter);
|
||||
listPopup.setAnchorView(pulsingCircleColorButton);
|
||||
listPopup.setOnItemClickListener((parent, itemView, position, id) -> {
|
||||
String selectedTrackingType = trackingTypes.get(position);
|
||||
pulsingCircleColorButton.setText(selectedTrackingType);
|
||||
if (selectedTrackingType.contentEquals("Blue")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.BLUE;
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.BLUE);
|
||||
} else if (selectedTrackingType.contentEquals("Red")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.RED;
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.RED);
|
||||
} else if (selectedTrackingType.contentEquals("Green")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.GREEN;
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.GREEN);
|
||||
} else if (selectedTrackingType.contentEquals("Gray")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.parseColor("#4a4a4a");
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.parseColor("#4a4a4a"));
|
||||
}
|
||||
listPopup.dismiss();
|
||||
});
|
||||
listPopup.show();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
if (locationComponent != null) {
|
||||
outState.putParcelable(SAVED_STATE_LOCATION, locationComponent.getLastKnownLocation());
|
||||
outState.putInt(SAVED_STATE_LOCATION_CIRCLE_PULSE_COLOR, LOCATION_CIRCLE_PULSE_COLOR);
|
||||
outState.putFloat(SAVED_STATE_LOCATION_CIRCLE_PULSE_DURATION, LOCATION_CIRCLE_PULSE_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.location.Location
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.animation.Interpolator
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.ListPopupWindow
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* This activity shows how to customize the LocationComponent's pulsing circle.
|
||||
*/
|
||||
class CustomizedLocationPulsingCircleActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private var lastLocation: Location? = null
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var pulsingCircleDurationButton: Button
|
||||
private lateinit var pulsingCircleColorButton: Button
|
||||
private var permissionsManager: PermissionsManager? = null
|
||||
private var locationComponent: LocationComponent? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var currentPulseDuration = 0f
|
||||
|
||||
//endregion
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_layer_customized_pulsing_circle)
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.BLUE
|
||||
mapView = findViewById(R.id.mapView)
|
||||
if (savedInstanceState != null) {
|
||||
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION)
|
||||
LOCATION_CIRCLE_PULSE_COLOR = savedInstanceState.getInt(
|
||||
SAVED_STATE_LOCATION_CIRCLE_PULSE_COLOR
|
||||
)
|
||||
LOCATION_CIRCLE_PULSE_DURATION = savedInstanceState.getFloat(
|
||||
SAVED_STATE_LOCATION_CIRCLE_PULSE_DURATION
|
||||
)
|
||||
}
|
||||
pulsingCircleDurationButton = findViewById(R.id.button_location_circle_duration)
|
||||
pulsingCircleDurationButton.setText(
|
||||
String.format(
|
||||
"%sms",
|
||||
LOCATION_CIRCLE_PULSE_DURATION.toString()
|
||||
)
|
||||
)
|
||||
pulsingCircleDurationButton.setOnClickListener(
|
||||
View.OnClickListener setOnClickListener@{ v: View? ->
|
||||
if (locationComponent == null) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
showDurationListDialog()
|
||||
}
|
||||
)
|
||||
pulsingCircleColorButton = findViewById(R.id.button_location_circle_color)
|
||||
pulsingCircleColorButton.setOnClickListener(
|
||||
View.OnClickListener setOnClickListener@{ v: View? ->
|
||||
if (locationComponent == null) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
showColorListDialog()
|
||||
}
|
||||
)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
checkPermissions()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets")) { style: Style ->
|
||||
locationComponent = mapboxMap.locationComponent
|
||||
val locationComponentOptions = buildLocationComponentOptions(
|
||||
LOCATION_CIRCLE_PULSE_COLOR,
|
||||
LOCATION_CIRCLE_PULSE_DURATION
|
||||
)
|
||||
.pulseEnabled(true)
|
||||
.build()
|
||||
val locationComponentActivationOptions =
|
||||
buildLocationComponentActivationOptions(style, locationComponentOptions)
|
||||
locationComponent!!.activateLocationComponent(locationComponentActivationOptions)
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
locationComponent!!.cameraMode = CameraMode.TRACKING
|
||||
locationComponent!!.forceLocationUpdate(lastLocation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildLocationComponentOptions(
|
||||
pulsingCircleColor: Int,
|
||||
pulsingCircleDuration: Float
|
||||
): LocationComponentOptions.Builder {
|
||||
currentPulseDuration = pulsingCircleDuration
|
||||
return LocationComponentOptions.builder(this)
|
||||
.layerBelow(LAYER_BELOW_ID)
|
||||
.pulseFadeEnabled(DEFAULT_LOCATION_CIRCLE_PULSE_FADE_MODE)
|
||||
.pulseInterpolator(DEFAULT_LOCATION_CIRCLE_INTERPOLATOR_PULSE_MODE)
|
||||
.pulseColor(pulsingCircleColor)
|
||||
.pulseAlpha(DEFAULT_LOCATION_CIRCLE_PULSE_ALPHA)
|
||||
.pulseSingleDuration(pulsingCircleDuration)
|
||||
.pulseMaxRadius(DEFAULT_LOCATION_CIRCLE_PULSE_RADIUS)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun setNewLocationComponentOptions(
|
||||
newPulsingDuration: Float,
|
||||
newPulsingColor: Int
|
||||
) {
|
||||
mapboxMap!!.getStyle { style: Style? ->
|
||||
locationComponent!!.applyStyle(
|
||||
buildLocationComponentOptions(
|
||||
newPulsingColor,
|
||||
newPulsingDuration
|
||||
)
|
||||
.pulseEnabled(true)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildLocationComponentActivationOptions(
|
||||
style: Style,
|
||||
locationComponentOptions: LocationComponentOptions
|
||||
): LocationComponentActivationOptions {
|
||||
return LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationComponentOptions(locationComponentOptions)
|
||||
.useDefaultLocationEngine(true)
|
||||
.locationEngineRequest(
|
||||
LocationEngineRequest.Builder(750)
|
||||
.setFastestInterval(750)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_pulsing_location_mode, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (locationComponent == null) {
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
val id = item.itemId
|
||||
if (id == R.id.action_map_style_change) {
|
||||
loadNewStyle()
|
||||
return true
|
||||
} else if (id == R.id.action_component_disable) {
|
||||
locationComponent!!.isLocationComponentEnabled = false
|
||||
return true
|
||||
} else if (id == R.id.action_component_enabled) {
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
return true
|
||||
} else if (id == R.id.action_stop_pulsing) {
|
||||
locationComponent!!.applyStyle(
|
||||
LocationComponentOptions.builder(
|
||||
this@CustomizedLocationPulsingCircleActivity
|
||||
)
|
||||
.pulseEnabled(false)
|
||||
.build()
|
||||
)
|
||||
return true
|
||||
} else if (id == R.id.action_start_pulsing) {
|
||||
locationComponent!!.applyStyle(
|
||||
buildLocationComponentOptions(
|
||||
LOCATION_CIRCLE_PULSE_COLOR,
|
||||
LOCATION_CIRCLE_PULSE_DURATION
|
||||
)
|
||||
.pulseEnabled(true)
|
||||
.build()
|
||||
)
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun loadNewStyle() {
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(Utils.nextStyle()))
|
||||
}
|
||||
|
||||
private fun checkPermissions() {
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView!!.getMapAsync(this)
|
||||
} else {
|
||||
permissionsManager = PermissionsManager(object : PermissionsListener {
|
||||
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
|
||||
Toast.makeText(
|
||||
this@CustomizedLocationPulsingCircleActivity,
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onPermissionResult(granted: Boolean) {
|
||||
if (granted) {
|
||||
mapView!!.getMapAsync(this@CustomizedLocationPulsingCircleActivity)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
permissionsManager!!.requestLocationPermissions(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDurationListDialog() {
|
||||
val modes: MutableList<String> = ArrayList()
|
||||
modes.add(String.format("%sms", DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS.toString()))
|
||||
modes.add(String.format("%sms", SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS.toString()))
|
||||
modes.add(String.format("%sms", THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS.toString()))
|
||||
val profileAdapter = ArrayAdapter(
|
||||
this,
|
||||
android.R.layout.simple_list_item_1,
|
||||
modes
|
||||
)
|
||||
val listPopup = ListPopupWindow(this)
|
||||
listPopup.setAdapter(profileAdapter)
|
||||
listPopup.anchorView = pulsingCircleDurationButton
|
||||
listPopup.setOnItemClickListener { parent: AdapterView<*>?, itemView: View?, position: Int, id: Long ->
|
||||
val selectedMode = modes[position]
|
||||
pulsingCircleDurationButton!!.text = selectedMode
|
||||
if (selectedMode.contentEquals(
|
||||
String.format(
|
||||
"%sms",
|
||||
DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS.toString()
|
||||
)
|
||||
)
|
||||
) {
|
||||
LOCATION_CIRCLE_PULSE_DURATION = DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS
|
||||
setNewLocationComponentOptions(
|
||||
DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS,
|
||||
LOCATION_CIRCLE_PULSE_COLOR
|
||||
)
|
||||
} else if (selectedMode.contentEquals(
|
||||
String.format(
|
||||
"%sms",
|
||||
SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS.toString()
|
||||
)
|
||||
)
|
||||
) {
|
||||
LOCATION_CIRCLE_PULSE_DURATION = SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS
|
||||
setNewLocationComponentOptions(
|
||||
SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS,
|
||||
LOCATION_CIRCLE_PULSE_COLOR
|
||||
)
|
||||
} else if (selectedMode.contentEquals(
|
||||
String.format(
|
||||
"%sms",
|
||||
THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS.toString()
|
||||
)
|
||||
)
|
||||
) {
|
||||
LOCATION_CIRCLE_PULSE_DURATION = THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS
|
||||
setNewLocationComponentOptions(
|
||||
THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS,
|
||||
LOCATION_CIRCLE_PULSE_COLOR
|
||||
)
|
||||
}
|
||||
listPopup.dismiss()
|
||||
}
|
||||
listPopup.show()
|
||||
}
|
||||
|
||||
private fun showColorListDialog() {
|
||||
val trackingTypes: MutableList<String> = ArrayList()
|
||||
trackingTypes.add("Blue")
|
||||
trackingTypes.add("Red")
|
||||
trackingTypes.add("Green")
|
||||
trackingTypes.add("Gray")
|
||||
val profileAdapter = ArrayAdapter(
|
||||
this,
|
||||
android.R.layout.simple_list_item_1,
|
||||
trackingTypes
|
||||
)
|
||||
val listPopup = ListPopupWindow(this)
|
||||
listPopup.setAdapter(profileAdapter)
|
||||
listPopup.anchorView = pulsingCircleColorButton
|
||||
listPopup.setOnItemClickListener { parent: AdapterView<*>?, itemView: View?, position: Int, id: Long ->
|
||||
val selectedTrackingType = trackingTypes[position]
|
||||
pulsingCircleColorButton!!.text = selectedTrackingType
|
||||
if (selectedTrackingType.contentEquals("Blue")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.BLUE
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.BLUE)
|
||||
} else if (selectedTrackingType.contentEquals("Red")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.RED
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.RED)
|
||||
} else if (selectedTrackingType.contentEquals("Green")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.GREEN
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.GREEN)
|
||||
} else if (selectedTrackingType.contentEquals("Gray")) {
|
||||
LOCATION_CIRCLE_PULSE_COLOR = Color.parseColor("#4a4a4a")
|
||||
setNewLocationComponentOptions(currentPulseDuration, Color.parseColor("#4a4a4a"))
|
||||
}
|
||||
listPopup.dismiss()
|
||||
}
|
||||
listPopup.show()
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
if (locationComponent != null) {
|
||||
outState.putParcelable(SAVED_STATE_LOCATION, locationComponent!!.lastKnownLocation)
|
||||
outState.putInt(SAVED_STATE_LOCATION_CIRCLE_PULSE_COLOR, LOCATION_CIRCLE_PULSE_COLOR)
|
||||
outState.putFloat(
|
||||
SAVED_STATE_LOCATION_CIRCLE_PULSE_DURATION,
|
||||
LOCATION_CIRCLE_PULSE_DURATION
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
companion object {
|
||||
//region
|
||||
// Adjust these variables to customize the example's pulsing circle UI
|
||||
private const val DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS = 2300f
|
||||
private const val SECOND_LOCATION_CIRCLE_PULSE_DURATION_MS = 800f
|
||||
private const val THIRD_LOCATION_CIRCLE_PULSE_DURATION_MS = 8000f
|
||||
private const val DEFAULT_LOCATION_CIRCLE_PULSE_RADIUS = 35f
|
||||
private const val DEFAULT_LOCATION_CIRCLE_PULSE_ALPHA = .55f
|
||||
private val DEFAULT_LOCATION_CIRCLE_INTERPOLATOR_PULSE_MODE: Interpolator =
|
||||
DecelerateInterpolator()
|
||||
private const val DEFAULT_LOCATION_CIRCLE_PULSE_FADE_MODE = true
|
||||
|
||||
//endregion
|
||||
//region
|
||||
private var LOCATION_CIRCLE_PULSE_COLOR = 0
|
||||
private var LOCATION_CIRCLE_PULSE_DURATION = DEFAULT_LOCATION_CIRCLE_PULSE_DURATION_MS
|
||||
private const val SAVED_STATE_LOCATION = "saved_state_location"
|
||||
private const val SAVED_STATE_LOCATION_CIRCLE_PULSE_COLOR = "saved_state_color"
|
||||
private const val SAVED_STATE_LOCATION_CIRCLE_PULSE_DURATION = "saved_state_duration"
|
||||
private const val LAYER_BELOW_ID = "poi_transit"
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode;
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LocationComponentActivationActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_layer_activation_builder);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this);
|
||||
} else {
|
||||
permissionsManager = new PermissionsManager(new PermissionsListener() {
|
||||
@Override
|
||||
public void onExplanationNeeded(List<String> permissionsToExplain) {
|
||||
Toast.makeText(LocationComponentActivationActivity.this, "You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean granted) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(LocationComponentActivationActivity.this);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Bright"),
|
||||
style -> activateLocationComponent(style));
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private void activateLocationComponent(@NonNull Style style) {
|
||||
LocationComponent locationComponent = mapboxMap.getLocationComponent();
|
||||
|
||||
LocationComponentOptions locationComponentOptions = LocationComponentOptions.builder(this)
|
||||
.elevation(5)
|
||||
.accuracyAlpha(.6f)
|
||||
.accuracyColor(Color.GREEN)
|
||||
.foregroundDrawable(R.drawable.mapbox_logo_helmet)
|
||||
.build();
|
||||
|
||||
LocationComponentActivationOptions locationComponentActivationOptions = LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationComponentOptions(locationComponentOptions)
|
||||
.useDefaultLocationEngine(true)
|
||||
.build();
|
||||
|
||||
locationComponent.activateLocationComponent(locationComponentActivationOptions);
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
locationComponent.setRenderMode(RenderMode.NORMAL);
|
||||
locationComponent.setCameraMode(CameraMode.TRACKING);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
class LocationComponentActivationActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var permissionsManager: PermissionsManager? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_layer_activation_builder)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this)
|
||||
} else {
|
||||
permissionsManager = PermissionsManager(object : PermissionsListener {
|
||||
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
|
||||
Toast.makeText(
|
||||
this@LocationComponentActivationActivity,
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onPermissionResult(granted: Boolean) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(this@LocationComponentActivationActivity)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
permissionsManager!!.requestLocationPermissions(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(
|
||||
Style.getPredefinedStyle("Bright")
|
||||
) { style: Style -> activateLocationComponent(style) }
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun activateLocationComponent(style: Style) {
|
||||
val locationComponent = mapboxMap!!.locationComponent
|
||||
val locationComponentOptions = LocationComponentOptions.builder(this)
|
||||
.elevation(5f)
|
||||
.accuracyAlpha(.6f)
|
||||
.accuracyColor(Color.GREEN)
|
||||
.foregroundDrawable(R.drawable.mapbox_logo_helmet)
|
||||
.build()
|
||||
val locationComponentActivationOptions = LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationComponentOptions(locationComponentOptions)
|
||||
.useDefaultLocationEngine(true)
|
||||
.build()
|
||||
locationComponent.activateLocationComponent(locationComponentActivationOptions)
|
||||
locationComponent.isLocationComponentEnabled = true
|
||||
locationComponent.renderMode = RenderMode.NORMAL
|
||||
locationComponent.cameraMode = CameraMode.TRACKING
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LocationMapChangeActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_layer_map_change);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
FloatingActionButton stylesFab = findViewById(R.id.fabStyles);
|
||||
|
||||
stylesFab.setOnClickListener(v -> {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Utils.getNextStyle()));
|
||||
}
|
||||
});
|
||||
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this);
|
||||
} else {
|
||||
permissionsManager = new PermissionsManager(new PermissionsListener() {
|
||||
@Override
|
||||
public void onExplanationNeeded(List<String> permissionsToExplain) {
|
||||
Toast.makeText(LocationMapChangeActivity.this, "You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean granted) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(LocationMapChangeActivity.this);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Utils.getNextStyle()),
|
||||
style -> activateLocationComponent(style));
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private void activateLocationComponent(@NonNull Style style) {
|
||||
LocationComponent locationComponent = mapboxMap.getLocationComponent();
|
||||
|
||||
locationComponent.activateLocationComponent(
|
||||
LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.useDefaultLocationEngine(true)
|
||||
.build());
|
||||
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
locationComponent.setRenderMode(RenderMode.COMPASS);
|
||||
|
||||
locationComponent.addOnLocationClickListener(
|
||||
() -> Toast.makeText(this, "Location clicked", Toast.LENGTH_SHORT).show());
|
||||
|
||||
locationComponent.addOnLocationLongClickListener(
|
||||
() -> Toast.makeText(this, "Location long clicked", Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
class LocationMapChangeActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var permissionsManager: PermissionsManager? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_layer_map_change)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
val stylesFab = findViewById<FloatingActionButton>(R.id.fabStyles)
|
||||
stylesFab.setOnClickListener { v: View? ->
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(Utils.nextStyle()))
|
||||
}
|
||||
}
|
||||
mapView.onCreate(savedInstanceState)
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this)
|
||||
} else {
|
||||
permissionsManager = PermissionsManager(object : PermissionsListener {
|
||||
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
|
||||
Toast.makeText(
|
||||
this@LocationMapChangeActivity,
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onPermissionResult(granted: Boolean) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(this@LocationMapChangeActivity)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
permissionsManager!!.requestLocationPermissions(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(
|
||||
Style.Builder().fromUri(Utils.nextStyle())
|
||||
) { style: Style -> activateLocationComponent(style) }
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun activateLocationComponent(style: Style) {
|
||||
val locationComponent = mapboxMap!!.locationComponent
|
||||
locationComponent.activateLocationComponent(
|
||||
LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.useDefaultLocationEngine(true)
|
||||
.build()
|
||||
)
|
||||
locationComponent.isLocationComponentEnabled = true
|
||||
locationComponent.renderMode = RenderMode.COMPASS
|
||||
locationComponent.addOnLocationClickListener {
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Location clicked",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
locationComponent.addOnLocationLongClickListener {
|
||||
Toast.makeText(
|
||||
this,
|
||||
"Location long clicked",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,451 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.RectF;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.ListPopupWindow;
|
||||
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
|
||||
import com.mapbox.mapboxsdk.location.OnCameraTrackingChangedListener;
|
||||
import com.mapbox.mapboxsdk.location.OnLocationCameraTransitionListener;
|
||||
import com.mapbox.mapboxsdk.location.OnLocationClickListener;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest;
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode;
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LocationModesActivity extends AppCompatActivity implements OnMapReadyCallback,
|
||||
OnLocationClickListener, OnCameraTrackingChangedListener {
|
||||
|
||||
private MapView mapView;
|
||||
private Button locationModeBtn;
|
||||
private Button locationTrackingBtn;
|
||||
private View protectedGestureArea;
|
||||
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
private LocationComponent locationComponent;
|
||||
private MapboxMap mapboxMap;
|
||||
private boolean defaultStyle = false;
|
||||
|
||||
private static final String SAVED_STATE_CAMERA = "saved_state_camera";
|
||||
private static final String SAVED_STATE_RENDER = "saved_state_render";
|
||||
private static final String SAVED_STATE_LOCATION = "saved_state_location";
|
||||
|
||||
@CameraMode.Mode
|
||||
private int cameraMode = CameraMode.TRACKING;
|
||||
|
||||
@RenderMode.Mode
|
||||
private int renderMode = RenderMode.NORMAL;
|
||||
|
||||
private Location lastLocation;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_layer_mode);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
protectedGestureArea = findViewById(R.id.view_protected_gesture_area);
|
||||
|
||||
locationModeBtn = findViewById(R.id.button_location_mode);
|
||||
locationModeBtn.setOnClickListener(v -> {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
showModeListDialog();
|
||||
});
|
||||
|
||||
locationTrackingBtn = findViewById(R.id.button_location_tracking);
|
||||
locationTrackingBtn.setOnClickListener(v -> {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
showTrackingListDialog();
|
||||
});
|
||||
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
cameraMode = savedInstanceState.getInt(SAVED_STATE_CAMERA);
|
||||
renderMode = savedInstanceState.getInt(SAVED_STATE_RENDER);
|
||||
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION);
|
||||
}
|
||||
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this);
|
||||
} else {
|
||||
permissionsManager = new PermissionsManager(new PermissionsListener() {
|
||||
@Override
|
||||
public void onExplanationNeeded(List<String> permissionsToExplain) {
|
||||
Toast.makeText(LocationModesActivity.this, "You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean granted) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(LocationModesActivity.this);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"), style -> {
|
||||
locationComponent = mapboxMap.getLocationComponent();
|
||||
locationComponent.activateLocationComponent(
|
||||
LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.useSpecializedLocationLayer(true)
|
||||
.useDefaultLocationEngine(true)
|
||||
.locationEngineRequest(new LocationEngineRequest.Builder(750)
|
||||
.setFastestInterval(750)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
toggleStyle();
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
locationComponent.addOnLocationClickListener(this);
|
||||
locationComponent.addOnCameraTrackingChangedListener(this);
|
||||
locationComponent.setCameraMode(cameraMode);
|
||||
setRendererMode(renderMode);
|
||||
locationComponent.forceLocationUpdate(lastLocation);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_location_mode, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (locationComponent == null) {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_style_change) {
|
||||
toggleStyle();
|
||||
return true;
|
||||
} else if (id == R.id.action_map_style_change) {
|
||||
toggleMapStyle();
|
||||
return true;
|
||||
} else if (id == R.id.action_component_disable) {
|
||||
locationComponent.setLocationComponentEnabled(false);
|
||||
return true;
|
||||
} else if (id == R.id.action_component_enabled) {
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
return true;
|
||||
} else if (id == R.id.action_gestures_management_disabled) {
|
||||
disableGesturesManagement();
|
||||
return true;
|
||||
} else if (id == R.id.action_gestures_management_enabled) {
|
||||
enableGesturesManagement();
|
||||
return true;
|
||||
} else if (id == R.id.action_component_throttling_enabled) {
|
||||
locationComponent.setMaxAnimationFps(5);
|
||||
} else if (id == R.id.action_component_throttling_disabled) {
|
||||
locationComponent.setMaxAnimationFps(Integer.MAX_VALUE);
|
||||
} else if (id == R.id.action_component_animate_while_tracking) {
|
||||
locationComponent.zoomWhileTracking(17, 750, new MapboxMap.CancelableCallback() {
|
||||
@Override
|
||||
public void onCancel() {
|
||||
// No impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
locationComponent.tiltWhileTracking(60);
|
||||
}
|
||||
});
|
||||
if (locationComponent.getCameraMode() == CameraMode.NONE) {
|
||||
|
||||
Toast.makeText(this, "Not possible to animate - not tracking", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void toggleStyle() {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
defaultStyle = !defaultStyle;
|
||||
LocationComponentOptions options = LocationComponentOptions.createFromAttributes(
|
||||
this, defaultStyle ? R.style.mapbox_LocationComponent : R.style.CustomLocationComponent);
|
||||
|
||||
if (defaultStyle) {
|
||||
int[] padding;
|
||||
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
padding = new int[] {0, 750, 0, 0};
|
||||
} else {
|
||||
padding = new int[] {0, 250, 0, 0};
|
||||
}
|
||||
|
||||
options = options.toBuilder()
|
||||
.padding(padding)
|
||||
.build();
|
||||
}
|
||||
|
||||
locationComponent.applyStyle(options);
|
||||
}
|
||||
|
||||
private void toggleMapStyle() {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mapboxMap.getStyle(style -> {
|
||||
String styleUrl = Style.getPredefinedStyle("Bright").equals(style.getUri())
|
||||
? Style.getPredefinedStyle("Bright")
|
||||
: Style.getPredefinedStyle("Pastel");
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(styleUrl));
|
||||
});
|
||||
}
|
||||
|
||||
private void disableGesturesManagement() {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
protectedGestureArea.getLayoutParams().height = 0;
|
||||
protectedGestureArea.getLayoutParams().width = 0;
|
||||
|
||||
LocationComponentOptions options = locationComponent
|
||||
.getLocationComponentOptions()
|
||||
.toBuilder()
|
||||
.trackingGesturesManagement(false)
|
||||
.build();
|
||||
locationComponent.applyStyle(options);
|
||||
}
|
||||
|
||||
private void enableGesturesManagement() {
|
||||
if (locationComponent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RectF rectF = new RectF(0f, 0f, mapView.getWidth() / 2f, mapView.getHeight() / 2f);
|
||||
protectedGestureArea.getLayoutParams().height = (int) rectF.bottom;
|
||||
protectedGestureArea.getLayoutParams().width = (int) rectF.right;
|
||||
|
||||
LocationComponentOptions options = locationComponent
|
||||
.getLocationComponentOptions()
|
||||
.toBuilder()
|
||||
.trackingGesturesManagement(true)
|
||||
.trackingMultiFingerProtectedMoveArea(rectF)
|
||||
.trackingMultiFingerMoveThreshold(500)
|
||||
.build();
|
||||
locationComponent.applyStyle(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
outState.putInt(SAVED_STATE_CAMERA, cameraMode);
|
||||
outState.putInt(SAVED_STATE_RENDER, renderMode);
|
||||
if (locationComponent != null) {
|
||||
outState.putParcelable(SAVED_STATE_LOCATION, locationComponent.getLastKnownLocation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationComponentClick() {
|
||||
Toast.makeText(this, "OnLocationComponentClick", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void showModeListDialog() {
|
||||
List<String> modes = new ArrayList<>();
|
||||
modes.add("Normal");
|
||||
modes.add("Compass");
|
||||
modes.add("GPS");
|
||||
ArrayAdapter<String> profileAdapter = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_list_item_1, modes);
|
||||
ListPopupWindow listPopup = new ListPopupWindow(this);
|
||||
listPopup.setAdapter(profileAdapter);
|
||||
listPopup.setAnchorView(locationModeBtn);
|
||||
listPopup.setOnItemClickListener((parent, itemView, position, id) -> {
|
||||
String selectedMode = modes.get(position);
|
||||
locationModeBtn.setText(selectedMode);
|
||||
if (selectedMode.contentEquals("Normal")) {
|
||||
setRendererMode(RenderMode.NORMAL);
|
||||
} else if (selectedMode.contentEquals("Compass")) {
|
||||
setRendererMode(RenderMode.COMPASS);
|
||||
} else if (selectedMode.contentEquals("GPS")) {
|
||||
setRendererMode(RenderMode.GPS);
|
||||
}
|
||||
listPopup.dismiss();
|
||||
});
|
||||
listPopup.show();
|
||||
}
|
||||
|
||||
private void setRendererMode(@RenderMode.Mode int mode) {
|
||||
renderMode = mode;
|
||||
locationComponent.setRenderMode(mode);
|
||||
if (mode == RenderMode.NORMAL) {
|
||||
locationModeBtn.setText("Normal");
|
||||
} else if (mode == RenderMode.COMPASS) {
|
||||
locationModeBtn.setText("Compass");
|
||||
} else if (mode == RenderMode.GPS) {
|
||||
locationModeBtn.setText("Gps");
|
||||
}
|
||||
}
|
||||
|
||||
private void showTrackingListDialog() {
|
||||
List<String> trackingTypes = new ArrayList<>();
|
||||
trackingTypes.add("None");
|
||||
trackingTypes.add("None Compass");
|
||||
trackingTypes.add("None GPS");
|
||||
trackingTypes.add("Tracking");
|
||||
trackingTypes.add("Tracking Compass");
|
||||
trackingTypes.add("Tracking GPS");
|
||||
trackingTypes.add("Tracking GPS North");
|
||||
ArrayAdapter<String> profileAdapter = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_list_item_1, trackingTypes);
|
||||
ListPopupWindow listPopup = new ListPopupWindow(this);
|
||||
listPopup.setAdapter(profileAdapter);
|
||||
listPopup.setAnchorView(locationTrackingBtn);
|
||||
listPopup.setOnItemClickListener((parent, itemView, position, id) -> {
|
||||
String selectedTrackingType = trackingTypes.get(position);
|
||||
locationTrackingBtn.setText(selectedTrackingType);
|
||||
if (selectedTrackingType.contentEquals("None")) {
|
||||
setCameraTrackingMode(CameraMode.NONE);
|
||||
} else if (selectedTrackingType.contentEquals("None Compass")) {
|
||||
setCameraTrackingMode(CameraMode.NONE_COMPASS);
|
||||
} else if (selectedTrackingType.contentEquals("None GPS")) {
|
||||
setCameraTrackingMode(CameraMode.NONE_GPS);
|
||||
} else if (selectedTrackingType.contentEquals("Tracking")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING);
|
||||
} else if (selectedTrackingType.contentEquals("Tracking Compass")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING_COMPASS);
|
||||
} else if (selectedTrackingType.contentEquals("Tracking GPS")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING_GPS);
|
||||
} else if (selectedTrackingType.contentEquals("Tracking GPS North")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING_GPS_NORTH);
|
||||
}
|
||||
listPopup.dismiss();
|
||||
});
|
||||
listPopup.show();
|
||||
}
|
||||
|
||||
private void setCameraTrackingMode(@CameraMode.Mode int mode) {
|
||||
locationComponent.setCameraMode(mode, 1200, 16.0, null, 45.0,
|
||||
new OnLocationCameraTransitionListener() {
|
||||
@Override
|
||||
public void onLocationCameraTransitionFinished(@CameraMode.Mode int cameraMode) {
|
||||
Toast.makeText(LocationModesActivity.this, "Transition finished", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationCameraTransitionCanceled(@CameraMode.Mode int cameraMode) {
|
||||
Toast.makeText(LocationModesActivity.this, "Transition canceled", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraTrackingDismissed() {
|
||||
locationTrackingBtn.setText("None");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraTrackingChanged(int currentMode) {
|
||||
this.cameraMode = currentMode;
|
||||
if (currentMode == CameraMode.NONE) {
|
||||
locationTrackingBtn.setText("None");
|
||||
} else if (currentMode == CameraMode.NONE_COMPASS) {
|
||||
locationTrackingBtn.setText("None Compass");
|
||||
} else if (currentMode == CameraMode.NONE_GPS) {
|
||||
locationTrackingBtn.setText("None GPS");
|
||||
} else if (currentMode == CameraMode.TRACKING) {
|
||||
locationTrackingBtn.setText("Tracking");
|
||||
} else if (currentMode == CameraMode.TRACKING_COMPASS) {
|
||||
locationTrackingBtn.setText("Tracking Compass");
|
||||
} else if (currentMode == CameraMode.TRACKING_GPS) {
|
||||
locationTrackingBtn.setText("Tracking GPS");
|
||||
} else if (currentMode == CameraMode.TRACKING_GPS_NORTH) {
|
||||
locationTrackingBtn.setText("Tracking GPS North");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.RectF
|
||||
import android.location.Location
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.ListPopupWindow
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentOptions
|
||||
import com.mapbox.mapboxsdk.location.OnCameraTrackingChangedListener
|
||||
import com.mapbox.mapboxsdk.location.OnLocationCameraTransitionListener
|
||||
import com.mapbox.mapboxsdk.location.OnLocationClickListener
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.CancelableCallback
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import java.util.ArrayList
|
||||
|
||||
class LocationModesActivity :
|
||||
AppCompatActivity(),
|
||||
OnMapReadyCallback,
|
||||
OnLocationClickListener,
|
||||
OnCameraTrackingChangedListener {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var locationModeBtn: Button
|
||||
private lateinit var locationTrackingBtn: Button
|
||||
private var protectedGestureArea: View? = null
|
||||
private var permissionsManager: PermissionsManager? = null
|
||||
private var locationComponent: LocationComponent? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var defaultStyle = false
|
||||
|
||||
@CameraMode.Mode
|
||||
private var cameraMode = CameraMode.TRACKING
|
||||
|
||||
@RenderMode.Mode
|
||||
private var renderMode = RenderMode.NORMAL
|
||||
private var lastLocation: Location? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_layer_mode)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
protectedGestureArea = findViewById(R.id.view_protected_gesture_area)
|
||||
locationModeBtn = findViewById(R.id.button_location_mode)
|
||||
locationModeBtn.setOnClickListener(
|
||||
View.OnClickListener setOnClickListener@{ v: View? ->
|
||||
if (locationComponent == null) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
showModeListDialog()
|
||||
}
|
||||
)
|
||||
locationTrackingBtn = findViewById(R.id.button_location_tracking)
|
||||
locationTrackingBtn.setOnClickListener(
|
||||
View.OnClickListener setOnClickListener@{ v: View? ->
|
||||
if (locationComponent == null) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
showTrackingListDialog()
|
||||
}
|
||||
)
|
||||
if (savedInstanceState != null) {
|
||||
cameraMode = savedInstanceState.getInt(SAVED_STATE_CAMERA)
|
||||
renderMode = savedInstanceState.getInt(SAVED_STATE_RENDER)
|
||||
lastLocation = savedInstanceState.getParcelable(SAVED_STATE_LOCATION)
|
||||
}
|
||||
mapView.onCreate(savedInstanceState)
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this)
|
||||
} else {
|
||||
permissionsManager = PermissionsManager(object : PermissionsListener {
|
||||
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
|
||||
Toast.makeText(
|
||||
this@LocationModesActivity,
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onPermissionResult(granted: Boolean) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(this@LocationModesActivity)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
permissionsManager!!.requestLocationPermissions(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets")) { style: Style? ->
|
||||
locationComponent = mapboxMap.locationComponent
|
||||
locationComponent!!.activateLocationComponent(
|
||||
LocationComponentActivationOptions
|
||||
.builder(this, style!!)
|
||||
.useSpecializedLocationLayer(true)
|
||||
.useDefaultLocationEngine(true)
|
||||
.locationEngineRequest(
|
||||
LocationEngineRequest.Builder(750)
|
||||
.setFastestInterval(750)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
)
|
||||
toggleStyle()
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
locationComponent!!.addOnLocationClickListener(this)
|
||||
locationComponent!!.addOnCameraTrackingChangedListener(this)
|
||||
locationComponent!!.cameraMode = cameraMode
|
||||
setRendererMode(renderMode)
|
||||
locationComponent!!.forceLocationUpdate(lastLocation)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_location_mode, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (locationComponent == null) {
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
val id = item.itemId
|
||||
if (id == R.id.action_style_change) {
|
||||
toggleStyle()
|
||||
return true
|
||||
} else if (id == R.id.action_map_style_change) {
|
||||
toggleMapStyle()
|
||||
return true
|
||||
} else if (id == R.id.action_component_disable) {
|
||||
locationComponent!!.isLocationComponentEnabled = false
|
||||
return true
|
||||
} else if (id == R.id.action_component_enabled) {
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
return true
|
||||
} else if (id == R.id.action_gestures_management_disabled) {
|
||||
disableGesturesManagement()
|
||||
return true
|
||||
} else if (id == R.id.action_gestures_management_enabled) {
|
||||
enableGesturesManagement()
|
||||
return true
|
||||
} else if (id == R.id.action_component_throttling_enabled) {
|
||||
locationComponent!!.setMaxAnimationFps(5)
|
||||
} else if (id == R.id.action_component_throttling_disabled) {
|
||||
locationComponent!!.setMaxAnimationFps(Int.MAX_VALUE)
|
||||
} else if (id == R.id.action_component_animate_while_tracking) {
|
||||
locationComponent!!.zoomWhileTracking(
|
||||
17.0,
|
||||
750,
|
||||
object : CancelableCallback {
|
||||
override fun onCancel() {
|
||||
// No impl
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
locationComponent!!.tiltWhileTracking(60.0)
|
||||
}
|
||||
}
|
||||
)
|
||||
if (locationComponent!!.cameraMode == CameraMode.NONE) {
|
||||
Toast.makeText(this, "Not possible to animate - not tracking", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun toggleStyle() {
|
||||
if (locationComponent == null) {
|
||||
return
|
||||
}
|
||||
defaultStyle = !defaultStyle
|
||||
var options = LocationComponentOptions.createFromAttributes(
|
||||
this,
|
||||
if (defaultStyle) R.style.mapbox_LocationComponent else R.style.CustomLocationComponent
|
||||
)
|
||||
if (defaultStyle) {
|
||||
val padding: IntArray
|
||||
padding =
|
||||
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
intArrayOf(0, 750, 0, 0)
|
||||
} else {
|
||||
intArrayOf(0, 250, 0, 0)
|
||||
}
|
||||
options = options.toBuilder()
|
||||
.padding(padding)
|
||||
.build()
|
||||
}
|
||||
locationComponent!!.applyStyle(options)
|
||||
}
|
||||
|
||||
private fun toggleMapStyle() {
|
||||
if (locationComponent == null) {
|
||||
return
|
||||
}
|
||||
mapboxMap!!.getStyle { style: Style ->
|
||||
val styleUrl =
|
||||
if (Style.getPredefinedStyle("Bright") == style.uri) Style.getPredefinedStyle("Bright") else Style.getPredefinedStyle(
|
||||
"Pastel"
|
||||
)
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(styleUrl))
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableGesturesManagement() {
|
||||
if (locationComponent == null) {
|
||||
return
|
||||
}
|
||||
protectedGestureArea!!.layoutParams.height = 0
|
||||
protectedGestureArea!!.layoutParams.width = 0
|
||||
val options = locationComponent!!
|
||||
.locationComponentOptions
|
||||
.toBuilder()
|
||||
.trackingGesturesManagement(false)
|
||||
.build()
|
||||
locationComponent!!.applyStyle(options)
|
||||
}
|
||||
|
||||
private fun enableGesturesManagement() {
|
||||
if (locationComponent == null) {
|
||||
return
|
||||
}
|
||||
val rectF = RectF(0f, 0f, mapView!!.width / 2f, mapView!!.height / 2f)
|
||||
protectedGestureArea!!.layoutParams.height = rectF.bottom.toInt()
|
||||
protectedGestureArea!!.layoutParams.width = rectF.right.toInt()
|
||||
val options = locationComponent!!
|
||||
.locationComponentOptions
|
||||
.toBuilder()
|
||||
.trackingGesturesManagement(true)
|
||||
.trackingMultiFingerProtectedMoveArea(rectF)
|
||||
.trackingMultiFingerMoveThreshold(500f)
|
||||
.build()
|
||||
locationComponent!!.applyStyle(options)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
outState.putInt(SAVED_STATE_CAMERA, cameraMode)
|
||||
outState.putInt(SAVED_STATE_RENDER, renderMode)
|
||||
if (locationComponent != null) {
|
||||
outState.putParcelable(SAVED_STATE_LOCATION, locationComponent!!.lastKnownLocation)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onLocationComponentClick() {
|
||||
Toast.makeText(this, "OnLocationComponentClick", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun showModeListDialog() {
|
||||
val modes: MutableList<String> = ArrayList()
|
||||
modes.add("Normal")
|
||||
modes.add("Compass")
|
||||
modes.add("GPS")
|
||||
val profileAdapter = ArrayAdapter(
|
||||
this,
|
||||
android.R.layout.simple_list_item_1,
|
||||
modes
|
||||
)
|
||||
val listPopup = ListPopupWindow(this)
|
||||
listPopup.setAdapter(profileAdapter)
|
||||
listPopup.anchorView = locationModeBtn
|
||||
listPopup.setOnItemClickListener { parent: AdapterView<*>?, itemView: View?, position: Int, id: Long ->
|
||||
val selectedMode = modes[position]
|
||||
locationModeBtn!!.text = selectedMode
|
||||
if (selectedMode.contentEquals("Normal")) {
|
||||
setRendererMode(RenderMode.NORMAL)
|
||||
} else if (selectedMode.contentEquals("Compass")) {
|
||||
setRendererMode(RenderMode.COMPASS)
|
||||
} else if (selectedMode.contentEquals("GPS")) {
|
||||
setRendererMode(RenderMode.GPS)
|
||||
}
|
||||
listPopup.dismiss()
|
||||
}
|
||||
listPopup.show()
|
||||
}
|
||||
|
||||
private fun setRendererMode(@RenderMode.Mode mode: Int) {
|
||||
renderMode = mode
|
||||
locationComponent!!.renderMode = mode
|
||||
if (mode == RenderMode.NORMAL) {
|
||||
locationModeBtn!!.text = "Normal"
|
||||
} else if (mode == RenderMode.COMPASS) {
|
||||
locationModeBtn!!.text = "Compass"
|
||||
} else if (mode == RenderMode.GPS) {
|
||||
locationModeBtn!!.text = "Gps"
|
||||
}
|
||||
}
|
||||
|
||||
private fun showTrackingListDialog() {
|
||||
val trackingTypes: MutableList<String> = ArrayList()
|
||||
trackingTypes.add("None")
|
||||
trackingTypes.add("None Compass")
|
||||
trackingTypes.add("None GPS")
|
||||
trackingTypes.add("Tracking")
|
||||
trackingTypes.add("Tracking Compass")
|
||||
trackingTypes.add("Tracking GPS")
|
||||
trackingTypes.add("Tracking GPS North")
|
||||
val profileAdapter = ArrayAdapter(
|
||||
this,
|
||||
android.R.layout.simple_list_item_1,
|
||||
trackingTypes
|
||||
)
|
||||
val listPopup = ListPopupWindow(this)
|
||||
listPopup.setAdapter(profileAdapter)
|
||||
listPopup.anchorView = locationTrackingBtn
|
||||
listPopup.setOnItemClickListener { parent: AdapterView<*>?, itemView: View?, position: Int, id: Long ->
|
||||
val selectedTrackingType = trackingTypes[position]
|
||||
locationTrackingBtn!!.text = selectedTrackingType
|
||||
if (selectedTrackingType.contentEquals("None")) {
|
||||
setCameraTrackingMode(CameraMode.NONE)
|
||||
} else if (selectedTrackingType.contentEquals("None Compass")) {
|
||||
setCameraTrackingMode(CameraMode.NONE_COMPASS)
|
||||
} else if (selectedTrackingType.contentEquals("None GPS")) {
|
||||
setCameraTrackingMode(CameraMode.NONE_GPS)
|
||||
} else if (selectedTrackingType.contentEquals("Tracking")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING)
|
||||
} else if (selectedTrackingType.contentEquals("Tracking Compass")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING_COMPASS)
|
||||
} else if (selectedTrackingType.contentEquals("Tracking GPS")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING_GPS)
|
||||
} else if (selectedTrackingType.contentEquals("Tracking GPS North")) {
|
||||
setCameraTrackingMode(CameraMode.TRACKING_GPS_NORTH)
|
||||
}
|
||||
listPopup.dismiss()
|
||||
}
|
||||
listPopup.show()
|
||||
}
|
||||
|
||||
private fun setCameraTrackingMode(@CameraMode.Mode mode: Int) {
|
||||
locationComponent!!.setCameraMode(
|
||||
mode,
|
||||
1200,
|
||||
16.0,
|
||||
null,
|
||||
45.0,
|
||||
object : OnLocationCameraTransitionListener {
|
||||
override fun onLocationCameraTransitionFinished(@CameraMode.Mode cameraMode: Int) {
|
||||
Toast.makeText(
|
||||
this@LocationModesActivity,
|
||||
"Transition finished",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onLocationCameraTransitionCanceled(@CameraMode.Mode cameraMode: Int) {
|
||||
Toast.makeText(
|
||||
this@LocationModesActivity,
|
||||
"Transition canceled",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCameraTrackingDismissed() {
|
||||
locationTrackingBtn!!.text = "None"
|
||||
}
|
||||
|
||||
override fun onCameraTrackingChanged(currentMode: Int) {
|
||||
cameraMode = currentMode
|
||||
if (currentMode == CameraMode.NONE) {
|
||||
locationTrackingBtn!!.text = "None"
|
||||
} else if (currentMode == CameraMode.NONE_COMPASS) {
|
||||
locationTrackingBtn!!.text = "None Compass"
|
||||
} else if (currentMode == CameraMode.NONE_GPS) {
|
||||
locationTrackingBtn!!.text = "None GPS"
|
||||
} else if (currentMode == CameraMode.TRACKING) {
|
||||
locationTrackingBtn!!.text = "Tracking"
|
||||
} else if (currentMode == CameraMode.TRACKING_COMPASS) {
|
||||
locationTrackingBtn!!.text = "Tracking Compass"
|
||||
} else if (currentMode == CameraMode.TRACKING_GPS) {
|
||||
locationTrackingBtn!!.text = "Tracking GPS"
|
||||
} else if (currentMode == CameraMode.TRACKING_GPS_NORTH) {
|
||||
locationTrackingBtn!!.text = "Tracking GPS North"
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SAVED_STATE_CAMERA = "saved_state_camera"
|
||||
private const val SAVED_STATE_RENDER = "saved_state_render"
|
||||
private const val SAVED_STATE_LOCATION = "saved_state_location"
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngine;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineProvider;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest;
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ManualLocationUpdatesActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private MapView mapView;
|
||||
private LocationComponent locationComponent;
|
||||
private LocationEngine locationEngine;
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_manual_update);
|
||||
|
||||
locationEngine = LocationEngineProvider.getBestLocationEngine(this, false);
|
||||
|
||||
FloatingActionButton fabManualUpdate = findViewById(R.id.fabManualLocationChange);
|
||||
fabManualUpdate.setOnClickListener(v -> {
|
||||
if (locationComponent != null && locationComponent.getLocationEngine() == null) {
|
||||
locationComponent.forceLocationUpdate(
|
||||
Utils.getRandomLocation(LatLngBounds.from(60, 25, 40, -5)));
|
||||
}
|
||||
});
|
||||
fabManualUpdate.setEnabled(false);
|
||||
|
||||
FloatingActionButton fabToggle = findViewById(R.id.fabToggleManualLocation);
|
||||
fabToggle.setOnClickListener(v -> {
|
||||
if (locationComponent != null) {
|
||||
locationComponent.setLocationEngine(locationComponent.getLocationEngine() == null ? locationEngine : null);
|
||||
|
||||
if (locationComponent.getLocationEngine() == null) {
|
||||
fabToggle.setImageResource(R.drawable.ic_layers_clear);
|
||||
fabManualUpdate.setEnabled(true);
|
||||
fabManualUpdate.setAlpha(1f);
|
||||
Toast.makeText(
|
||||
ManualLocationUpdatesActivity.this.getApplicationContext(),
|
||||
"LocationEngine disabled, use manual updates",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
fabToggle.setImageResource(R.drawable.ic_layers);
|
||||
fabManualUpdate.setEnabled(false);
|
||||
fabManualUpdate.setAlpha(0.5f);
|
||||
Toast.makeText(
|
||||
ManualLocationUpdatesActivity.this.getApplicationContext(),
|
||||
"LocationEngine enabled",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this);
|
||||
} else {
|
||||
permissionsManager = new PermissionsManager(new PermissionsListener() {
|
||||
@Override
|
||||
public void onExplanationNeeded(List<String> permissionsToExplain) {
|
||||
Toast.makeText(ManualLocationUpdatesActivity.this.getApplicationContext(),
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean granted) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(ManualLocationUpdatesActivity.this);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.getPredefinedStyle("Streets")), style -> {
|
||||
locationComponent = mapboxMap.getLocationComponent();
|
||||
|
||||
locationComponent.activateLocationComponent(
|
||||
LocationComponentActivationOptions
|
||||
.builder(this, style)
|
||||
.locationEngine(locationEngine)
|
||||
.locationEngineRequest(new LocationEngineRequest.Builder(500)
|
||||
.setFastestInterval(500)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY).build())
|
||||
.build());
|
||||
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
locationComponent.setRenderMode(RenderMode.COMPASS);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngine
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineProvider
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineRequest
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsListener
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
class ManualLocationUpdatesActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private var locationComponent: LocationComponent? = null
|
||||
private var locationEngine: LocationEngine? = null
|
||||
private var permissionsManager: PermissionsManager? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_manual_update)
|
||||
locationEngine = LocationEngineProvider.getBestLocationEngine(this, false)
|
||||
val fabManualUpdate = findViewById<FloatingActionButton>(R.id.fabManualLocationChange)
|
||||
fabManualUpdate.setOnClickListener { v: View? ->
|
||||
if (locationComponent != null && locationComponent!!.locationEngine == null) {
|
||||
locationComponent!!.forceLocationUpdate(
|
||||
Utils.getRandomLocation(LatLngBounds.from(60.0, 25.0, 40.0, -5.0))
|
||||
)
|
||||
}
|
||||
}
|
||||
fabManualUpdate.isEnabled = false
|
||||
val fabToggle = findViewById<FloatingActionButton>(R.id.fabToggleManualLocation)
|
||||
fabToggle.setOnClickListener { v: View? ->
|
||||
if (locationComponent != null) {
|
||||
locationComponent!!.locationEngine =
|
||||
if (locationComponent!!.locationEngine == null) locationEngine else null
|
||||
if (locationComponent!!.locationEngine == null) {
|
||||
fabToggle.setImageResource(R.drawable.ic_layers_clear)
|
||||
fabManualUpdate.isEnabled = true
|
||||
fabManualUpdate.alpha = 1f
|
||||
Toast.makeText(
|
||||
this@ManualLocationUpdatesActivity.applicationContext,
|
||||
"LocationEngine disabled, use manual updates",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
fabToggle.setImageResource(R.drawable.ic_layers)
|
||||
fabManualUpdate.isEnabled = false
|
||||
fabManualUpdate.alpha = 0.5f
|
||||
Toast.makeText(
|
||||
this@ManualLocationUpdatesActivity.applicationContext,
|
||||
"LocationEngine enabled",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
mapView.getMapAsync(this)
|
||||
} else {
|
||||
permissionsManager = PermissionsManager(object : PermissionsListener {
|
||||
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
|
||||
Toast.makeText(
|
||||
this@ManualLocationUpdatesActivity.applicationContext,
|
||||
"You need to accept location permissions.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onPermissionResult(granted: Boolean) {
|
||||
if (granted) {
|
||||
mapView.getMapAsync(this@ManualLocationUpdatesActivity)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
permissionsManager!!.requestLocationPermissions(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
mapboxMap.setStyle(
|
||||
Style.Builder().fromUri(Style.getPredefinedStyle("Streets"))
|
||||
) { style: Style? ->
|
||||
locationComponent = mapboxMap.locationComponent
|
||||
locationComponent!!.activateLocationComponent(
|
||||
LocationComponentActivationOptions
|
||||
.builder(this, style!!)
|
||||
.locationEngine(locationEngine)
|
||||
.locationEngineRequest(
|
||||
LocationEngineRequest.Builder(500)
|
||||
.setFastestInterval(500)
|
||||
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY).build()
|
||||
)
|
||||
.build()
|
||||
)
|
||||
locationComponent!!.isLocationComponentEnabled = true
|
||||
locationComponent!!.renderMode = RenderMode.COMPASS
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Useful utilities used throughout the test app.
|
||||
*/
|
||||
public class Utils {
|
||||
|
||||
private static final String[] STYLES = new String[] {
|
||||
Style.getPredefinedStyle("Streets"),
|
||||
Style.getPredefinedStyle("Outdoor"),
|
||||
Style.getPredefinedStyle("Bright"),
|
||||
Style.getPredefinedStyle("Pastel"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid")
|
||||
};
|
||||
|
||||
private static int index;
|
||||
|
||||
/**
|
||||
* Utility to cycle through map styles. Useful to test if runtime styling source and layers transfer over to new
|
||||
* style.
|
||||
*
|
||||
* @return a string ID representing the map style
|
||||
*/
|
||||
public static String getNextStyle() {
|
||||
index++;
|
||||
if (index == STYLES.length) {
|
||||
index = 0;
|
||||
}
|
||||
return STYLES[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for getting a random coordinate inside a provided bounds and creates a {@link Location} from it.
|
||||
*
|
||||
* @param bounds bounds of the generated location
|
||||
* @return a {@link Location} object using the random coordinate
|
||||
*/
|
||||
public static Location getRandomLocation(LatLngBounds bounds) {
|
||||
Random random = new Random();
|
||||
|
||||
double randomLat = bounds.getLatSouth() + (bounds.getLatNorth() - bounds.getLatSouth()) * random.nextDouble();
|
||||
double randomLon = bounds.getLonWest() + (bounds.getLonEast() - bounds.getLonWest()) * random.nextDouble();
|
||||
|
||||
Location location = new Location("random-loc");
|
||||
location.setLongitude(randomLon);
|
||||
location.setLatitude(randomLat);
|
||||
Timber.d("getRandomLatLng: %s", location.toString());
|
||||
return location;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.location
|
||||
|
||||
import android.location.Location
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Useful utilities used throughout the test app.
|
||||
*/
|
||||
object Utils {
|
||||
private val STYLES = arrayOf(
|
||||
Style.getPredefinedStyle("Streets"),
|
||||
Style.getPredefinedStyle("Outdoor"),
|
||||
Style.getPredefinedStyle("Bright"),
|
||||
Style.getPredefinedStyle("Pastel"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid")
|
||||
)
|
||||
private var index = 0
|
||||
|
||||
/**
|
||||
* Utility to cycle through map styles. Useful to test if runtime styling source and layers transfer over to new
|
||||
* style.
|
||||
*
|
||||
* @return a string ID representing the map style
|
||||
*/
|
||||
fun nextStyle(): String {
|
||||
index++
|
||||
if (index == STYLES.size) {
|
||||
index = 0
|
||||
}
|
||||
return STYLES[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for getting a random coordinate inside a provided bounds and creates a [Location] from it.
|
||||
*
|
||||
* @param bounds bounds of the generated location
|
||||
* @return a [Location] object using the random coordinate
|
||||
*/
|
||||
fun getRandomLocation(bounds: LatLngBounds): Location {
|
||||
val random = Random()
|
||||
val randomLat = bounds.latSouth + (bounds.latNorth - bounds.latSouth) * random.nextDouble()
|
||||
val randomLon = bounds.lonWest + (bounds.lonEast - bounds.lonWest) * random.nextDouble()
|
||||
val location = Location("random-loc")
|
||||
location.longitude = randomLon
|
||||
location.latitude = randomLat
|
||||
Timber.d("getRandomLatLng: %s", location.toString())
|
||||
return location
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.utils.MapFragmentUtils;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using a bottomView with a MapView and stacking map fragments below.
|
||||
*/
|
||||
public class BottomSheetActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG_MAIN_FRAGMENT = "com.mapbox.mapboxsdk.fragment.tag.main";
|
||||
private static final String TAG_BOTTOM_FRAGMENT = "com.mapbox.mapboxsdk.fragment.tag.bottom";
|
||||
private static final String AMOUNT_OF_MAIN_MAP_FRAGMENTS = "Amount of main map fragments: %s";
|
||||
private boolean bottomSheetFragmentAdded;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_bottom_sheet);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
findViewById(R.id.fabFragment).setOnClickListener(v -> addMapFragment());
|
||||
|
||||
findViewById(R.id.fabBottomSheet).setOnClickListener(v -> toggleBottomSheetMapFragment());
|
||||
|
||||
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
|
||||
bottomSheetBehavior.setPeekHeight((int) (64 * getResources().getDisplayMetrics().density));
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
toggleBottomSheetMapFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
|
||||
if (fragmentManager.getBackStackEntryCount() > 0) {
|
||||
fragmentManager.popBackStack();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private void addMapFragment() {
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
int fragmentCount = fragmentManager.getBackStackEntryCount();
|
||||
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
MainMapFragment mainMapFragment = MainMapFragment.newInstance(this, fragmentCount);
|
||||
if (fragmentCount == 0) {
|
||||
fragmentTransaction.add(R.id.fragment_container, mainMapFragment, TAG_MAIN_FRAGMENT);
|
||||
} else {
|
||||
fragmentTransaction.replace(R.id.fragment_container, mainMapFragment, TAG_MAIN_FRAGMENT);
|
||||
}
|
||||
fragmentTransaction.addToBackStack(String.valueOf(mainMapFragment.hashCode()));
|
||||
fragmentTransaction.commit();
|
||||
Toast.makeText(getApplicationContext(),
|
||||
String.format(AMOUNT_OF_MAIN_MAP_FRAGMENTS, (fragmentCount + 1)),
|
||||
Toast.LENGTH_SHORT
|
||||
).show();
|
||||
}
|
||||
|
||||
private void toggleBottomSheetMapFragment() {
|
||||
if (!bottomSheetFragmentAdded) {
|
||||
addBottomSheetMapFragment();
|
||||
} else {
|
||||
removeBottomSheetFragment();
|
||||
}
|
||||
bottomSheetFragmentAdded = !bottomSheetFragmentAdded;
|
||||
}
|
||||
|
||||
private void addBottomSheetMapFragment() {
|
||||
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
|
||||
fragmentTransaction.add(R.id.fragment_container_bottom, BottomSheetFragment.newInstance(this), TAG_BOTTOM_FRAGMENT);
|
||||
fragmentTransaction.commit();
|
||||
}
|
||||
|
||||
private void removeBottomSheetFragment() {
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_BOTTOM_FRAGMENT);
|
||||
if (fragment != null) {
|
||||
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MainMapFragment extends Fragment implements OnMapReadyCallback {
|
||||
|
||||
private static final String[] STYLES = new String[] {
|
||||
Style.getPredefinedStyle("Streets"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid"),
|
||||
Style.getPredefinedStyle("Bright"),
|
||||
Style.getPredefinedStyle("Pastel"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid"),
|
||||
Style.getPredefinedStyle("Outdoor")
|
||||
};
|
||||
|
||||
private MapView map;
|
||||
|
||||
public static MainMapFragment newInstance(Context context, int mapCounter) {
|
||||
MainMapFragment mapFragment = new MainMapFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("mapcounter", mapCounter);
|
||||
mapFragment.setArguments(bundle);
|
||||
MapboxMapOptions mapboxMapOptions = MapboxMapOptions.createFromAttributes(context);
|
||||
mapFragment.setArguments(MapFragmentUtils.createFragmentArgs(mapboxMapOptions));
|
||||
return mapFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
Context context = inflater.getContext();
|
||||
return map = new MapView(context, MapFragmentUtils.resolveArgs(context, getArguments()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
map.onCreate(savedInstanceState);
|
||||
map.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.760545, -122.436055), 15));
|
||||
mapboxMap.setStyle(
|
||||
new Style.Builder().fromUri(
|
||||
STYLES[Math.min(Math.max(getArguments().getInt("mapcounter"), 0), STYLES.length - 1)]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
map.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
map.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
map.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
map.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
map.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
map.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
map.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BottomSheetFragment extends Fragment implements OnMapReadyCallback {
|
||||
|
||||
private MapView map;
|
||||
|
||||
public static BottomSheetFragment newInstance(Context context) {
|
||||
BottomSheetFragment mapFragment = new BottomSheetFragment();
|
||||
MapboxMapOptions mapboxMapOptions = MapboxMapOptions.createFromAttributes(context);
|
||||
mapboxMapOptions.renderSurfaceOnTop(true);
|
||||
mapFragment.setArguments(MapFragmentUtils.createFragmentArgs(mapboxMapOptions));
|
||||
return mapFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
Context context = inflater.getContext();
|
||||
return map = new MapView(context, MapFragmentUtils.resolveArgs(context, getArguments()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
map.onCreate(savedInstanceState);
|
||||
map.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.760545, -122.436055), 15));
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Bright"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
map.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
map.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
map.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
map.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
map.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
map.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
map.onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.maplayout.BottomSheetActivity.BottomSheetFragment
|
||||
import com.mapbox.mapboxsdk.testapp.activity.maplayout.BottomSheetActivity.MainMapFragment
|
||||
import com.mapbox.mapboxsdk.utils.MapFragmentUtils
|
||||
|
||||
/**
|
||||
* Test activity showcasing using a bottomView with a MapView and stacking map fragments below.
|
||||
*/
|
||||
class BottomSheetActivity : AppCompatActivity() {
|
||||
private var bottomSheetFragmentAdded = false
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_bottom_sheet)
|
||||
val actionBar = supportActionBar
|
||||
actionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
findViewById<View>(R.id.fabFragment).setOnClickListener { v: View? -> addMapFragment() }
|
||||
findViewById<View>(R.id.fabBottomSheet).setOnClickListener { v: View? -> toggleBottomSheetMapFragment() }
|
||||
val bottomSheetBehavior: BottomSheetBehavior<*> =
|
||||
BottomSheetBehavior.from(findViewById<View>(R.id.bottom_sheet))
|
||||
bottomSheetBehavior.peekHeight = (64 * resources.displayMetrics.density).toInt()
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
toggleBottomSheetMapFragment()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == android.R.id.home) {
|
||||
onBackPressed()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
val fragmentManager = supportFragmentManager
|
||||
if (fragmentManager.backStackEntryCount > 0) {
|
||||
fragmentManager.popBackStack()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addMapFragment() {
|
||||
val fragmentManager = supportFragmentManager
|
||||
val fragmentCount = fragmentManager.backStackEntryCount
|
||||
val fragmentTransaction = fragmentManager.beginTransaction()
|
||||
val mainMapFragment = MainMapFragment.newInstance(this, fragmentCount)
|
||||
if (fragmentCount == 0) {
|
||||
fragmentTransaction.add(R.id.fragment_container, mainMapFragment, TAG_MAIN_FRAGMENT)
|
||||
} else {
|
||||
fragmentTransaction.replace(R.id.fragment_container, mainMapFragment, TAG_MAIN_FRAGMENT)
|
||||
}
|
||||
fragmentTransaction.addToBackStack(mainMapFragment.hashCode().toString())
|
||||
fragmentTransaction.commit()
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
String.format(AMOUNT_OF_MAIN_MAP_FRAGMENTS, fragmentCount + 1),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun toggleBottomSheetMapFragment() {
|
||||
if (!bottomSheetFragmentAdded) {
|
||||
addBottomSheetMapFragment()
|
||||
} else {
|
||||
removeBottomSheetFragment()
|
||||
}
|
||||
bottomSheetFragmentAdded = !bottomSheetFragmentAdded
|
||||
}
|
||||
|
||||
private fun addBottomSheetMapFragment() {
|
||||
val fragmentTransaction = supportFragmentManager.beginTransaction()
|
||||
fragmentTransaction.add(
|
||||
R.id.fragment_container_bottom,
|
||||
BottomSheetFragment.newInstance(this),
|
||||
TAG_BOTTOM_FRAGMENT
|
||||
)
|
||||
fragmentTransaction.commit()
|
||||
}
|
||||
|
||||
private fun removeBottomSheetFragment() {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(TAG_BOTTOM_FRAGMENT)
|
||||
if (fragment != null) {
|
||||
supportFragmentManager.beginTransaction().remove(fragment).commit()
|
||||
}
|
||||
}
|
||||
|
||||
class MainMapFragment : Fragment(), OnMapReadyCallback {
|
||||
private var map: MapView? = null
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
val context = inflater.context
|
||||
return MapView(context, MapFragmentUtils.resolveArgs(context, arguments)).also {
|
||||
map = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
map!!.onCreate(savedInstanceState)
|
||||
map!!.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(37.760545, -122.436055),
|
||||
15.0
|
||||
)
|
||||
)
|
||||
mapboxMap.setStyle(
|
||||
Style.Builder().fromUri(
|
||||
STYLES[
|
||||
Math.min(
|
||||
Math.max(arguments!!.getInt("mapcounter"), 0),
|
||||
STYLES.size - 1
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
map!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
map!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
map!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
map!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
map!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
map!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
map!!.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val STYLES = arrayOf(
|
||||
Style.getPredefinedStyle("Streets"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid"),
|
||||
Style.getPredefinedStyle("Bright"),
|
||||
Style.getPredefinedStyle("Pastel"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid"),
|
||||
Style.getPredefinedStyle("Outdoor")
|
||||
)
|
||||
|
||||
fun newInstance(context: Context?, mapCounter: Int): MainMapFragment {
|
||||
val mapFragment = MainMapFragment()
|
||||
val bundle = Bundle()
|
||||
bundle.putInt("mapcounter", mapCounter)
|
||||
mapFragment.arguments = bundle
|
||||
val mapboxMapOptions = MapboxMapOptions.createFromAttributes(context!!)
|
||||
mapFragment.arguments = MapFragmentUtils.createFragmentArgs(mapboxMapOptions)
|
||||
return mapFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BottomSheetFragment : Fragment(), OnMapReadyCallback {
|
||||
private var map: MapView? = null
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
val context = inflater.context
|
||||
return MapView(context, MapFragmentUtils.resolveArgs(context, arguments)).also {
|
||||
map = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
map!!.onCreate(savedInstanceState)
|
||||
map!!.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(37.760545, -122.436055),
|
||||
15.0
|
||||
)
|
||||
)
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Bright"))
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
map!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
map!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
map!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
map!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
map!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
map!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
map!!.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(context: Context?): BottomSheetFragment {
|
||||
val mapFragment = BottomSheetFragment()
|
||||
val mapboxMapOptions = MapboxMapOptions.createFromAttributes(context!!)
|
||||
mapboxMapOptions.renderSurfaceOnTop(true)
|
||||
mapFragment.arguments = MapFragmentUtils.createFragmentArgs(mapboxMapOptions)
|
||||
return mapFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG_MAIN_FRAGMENT = "com.mapbox.mapboxsdk.fragment.tag.main"
|
||||
private const val TAG_BOTTOM_FRAGMENT = "com.mapbox.mapboxsdk.fragment.tag.bottom"
|
||||
private const val AMOUNT_OF_MAIN_MAP_FRAGMENTS = "Amount of main map fragments: %s"
|
||||
}
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
import com.mapbox.mapboxsdk.style.layers.Property;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
|
||||
|
||||
/**
|
||||
* Test activity showcasing the different debug modes and allows to cycle between the default map styles.
|
||||
*/
|
||||
public class DebugModeActivity extends AppCompatActivity implements OnMapReadyCallback, MapboxMap.OnFpsChangedListener {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private MapboxMap.OnCameraMoveListener cameraMoveListener;
|
||||
private ActionBarDrawerToggle actionBarDrawerToggle;
|
||||
private int currentStyleIndex;
|
||||
private boolean isReportFps = true;
|
||||
|
||||
private static final String[] STYLES = new String[] {
|
||||
Style.getPredefinedStyle("Streets"),
|
||||
Style.getPredefinedStyle("Outdoor"),
|
||||
Style.getPredefinedStyle("Bright"),
|
||||
Style.getPredefinedStyle("Pastel"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid") };
|
||||
private TextView fpsView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_debug_mode);
|
||||
setupToolbar();
|
||||
setupMapView(savedInstanceState);
|
||||
setupDebugChangeView();
|
||||
setupStyleChangeView();
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
|
||||
actionBarDrawerToggle = new ActionBarDrawerToggle(this,
|
||||
drawerLayout,
|
||||
R.string.navigation_drawer_open,
|
||||
R.string.navigation_drawer_close
|
||||
);
|
||||
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
|
||||
actionBarDrawerToggle.syncState();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMapView(Bundle savedInstanceState) {
|
||||
MapboxMapOptions mapboxMapOptions = setupMapboxMapOptions();
|
||||
mapView = new MapView(this, mapboxMapOptions);
|
||||
((ViewGroup) findViewById(R.id.coordinator_layout)).addView(mapView, 0);
|
||||
mapView.addOnDidFinishLoadingStyleListener(() -> {
|
||||
if (mapboxMap != null) {
|
||||
setupNavigationView(mapboxMap.getStyle().getLayers());
|
||||
}
|
||||
});
|
||||
|
||||
mapView.setTag(true);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
mapView.addOnDidFinishLoadingStyleListener(() -> Timber.d("Style loaded"));
|
||||
}
|
||||
|
||||
protected MapboxMapOptions setupMapboxMapOptions() {
|
||||
return MapboxMapOptions.createFromAttributes(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(
|
||||
new Style.Builder().fromUri(STYLES[currentStyleIndex]), style -> setupNavigationView(style.getLayers())
|
||||
);
|
||||
setupZoomView();
|
||||
setFpsView();
|
||||
}
|
||||
|
||||
private void setFpsView() {
|
||||
fpsView = findViewById(R.id.fpsView);
|
||||
mapboxMap.setOnFpsChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFpsChanged(double fps) {
|
||||
fpsView.setText(String.format(Locale.US, "FPS: %4.2f", fps));
|
||||
}
|
||||
|
||||
private void setupNavigationView(List<Layer> layerList) {
|
||||
Timber.v("New style loaded with JSON: %s", mapboxMap.getStyle().getJson());
|
||||
final LayerListAdapter adapter = new LayerListAdapter(this, layerList);
|
||||
ListView listView = findViewById(R.id.listView);
|
||||
listView.setAdapter(adapter);
|
||||
listView.setOnItemClickListener((parent, view, position, id) -> {
|
||||
Layer clickedLayer = adapter.getItem(position);
|
||||
toggleLayerVisibility(clickedLayer);
|
||||
closeNavigationView();
|
||||
});
|
||||
}
|
||||
|
||||
private void toggleLayerVisibility(Layer layer) {
|
||||
boolean isVisible = layer.getVisibility().getValue().equals(Property.VISIBLE);
|
||||
layer.setProperties(
|
||||
visibility(
|
||||
isVisible ? Property.NONE : Property.VISIBLE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void closeNavigationView() {
|
||||
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
|
||||
drawerLayout.closeDrawers();
|
||||
}
|
||||
|
||||
private void setupZoomView() {
|
||||
final TextView textView = findViewById(R.id.textZoom);
|
||||
mapboxMap.addOnCameraMoveListener(cameraMoveListener = new MapboxMap.OnCameraMoveListener() {
|
||||
@Override
|
||||
public void onCameraMove() {
|
||||
textView.setText(String.format(DebugModeActivity.this.getString(
|
||||
R.string.debug_zoom), mapboxMap.getCameraPosition().zoom));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupDebugChangeView() {
|
||||
FloatingActionButton fabDebug = findViewById(R.id.fabDebug);
|
||||
fabDebug.setOnClickListener(view -> {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.setDebugActive(!mapboxMap.isDebugActive());
|
||||
Timber.d("Debug FAB: isDebug Active? %s", mapboxMap.isDebugActive());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupStyleChangeView() {
|
||||
FloatingActionButton fabStyles = findViewById(R.id.fabStyles);
|
||||
fabStyles.setOnClickListener(view -> {
|
||||
if (mapboxMap != null) {
|
||||
currentStyleIndex++;
|
||||
if (currentStyleIndex == STYLES.length) {
|
||||
currentStyleIndex = 0;
|
||||
}
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(STYLES[currentStyleIndex]));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.menu_action_toggle_report_fps) {
|
||||
isReportFps = !isReportFps;
|
||||
fpsView.setVisibility(isReportFps ? View.VISIBLE : View.GONE);
|
||||
mapboxMap.setOnFpsChangedListener(isReportFps ? this : null);
|
||||
} else if (itemId == R.id.menu_action_limit_to_30_fps) {
|
||||
mapView.setMaximumFps(30);
|
||||
} else if (itemId == R.id.menu_action_limit_to_60_fps) {
|
||||
mapView.setMaximumFps(60);
|
||||
}
|
||||
|
||||
return actionBarDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_debug, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.removeOnCameraMoveListener(cameraMoveListener);
|
||||
}
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
private static class LayerListAdapter extends BaseAdapter {
|
||||
|
||||
private LayoutInflater layoutInflater;
|
||||
private List<Layer> layers;
|
||||
|
||||
LayerListAdapter(Context context, List<Layer> layers) {
|
||||
this.layoutInflater = LayoutInflater.from(context);
|
||||
this.layers = layers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layer getItem(int position) {
|
||||
return layers.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Layer layer = layers.get(position);
|
||||
View view = convertView;
|
||||
if (view == null) {
|
||||
view = layoutInflater.inflate(android.R.layout.simple_list_item_2, parent, false);
|
||||
ViewHolder holder = new ViewHolder(
|
||||
view.findViewById(android.R.id.text1),
|
||||
view.findViewById(android.R.id.text2)
|
||||
);
|
||||
view.setTag(holder);
|
||||
}
|
||||
ViewHolder holder = (ViewHolder) view.getTag();
|
||||
holder.text.setText(layer.getClass().getSimpleName());
|
||||
holder.subText.setText(layer.getId());
|
||||
return view;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
final TextView text;
|
||||
final TextView subText;
|
||||
|
||||
ViewHolder(TextView text, TextView subText) {
|
||||
this.text = text;
|
||||
this.subText = subText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnFpsChangedListener
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer
|
||||
import com.mapbox.mapboxsdk.style.layers.Property
|
||||
import com.mapbox.mapboxsdk.style.layers.PropertyFactory
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.maplayout.DebugModeActivity.LayerListAdapter
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Test activity showcasing the different debug modes and allows to cycle between the default map styles.
|
||||
*/
|
||||
open class DebugModeActivity : AppCompatActivity(), OnMapReadyCallback, OnFpsChangedListener {
|
||||
private var mapView: MapView? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var cameraMoveListener: OnCameraMoveListener? = null
|
||||
private var actionBarDrawerToggle: ActionBarDrawerToggle? = null
|
||||
private var currentStyleIndex = 0
|
||||
private var isReportFps = true
|
||||
private var fpsView: TextView? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_debug_mode)
|
||||
setupToolbar()
|
||||
setupMapView(savedInstanceState)
|
||||
setupDebugChangeView()
|
||||
setupStyleChangeView()
|
||||
}
|
||||
|
||||
private fun setupToolbar() {
|
||||
val actionBar = supportActionBar
|
||||
if (actionBar != null) {
|
||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar!!.setHomeButtonEnabled(true)
|
||||
val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout)
|
||||
actionBarDrawerToggle = ActionBarDrawerToggle(
|
||||
this,
|
||||
drawerLayout,
|
||||
R.string.navigation_drawer_open,
|
||||
R.string.navigation_drawer_close
|
||||
)
|
||||
actionBarDrawerToggle!!.isDrawerIndicatorEnabled = true
|
||||
actionBarDrawerToggle!!.syncState()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupMapView(savedInstanceState: Bundle?) {
|
||||
val mapboxMapOptions = setupMapboxMapOptions()
|
||||
mapView = MapView(this, mapboxMapOptions)
|
||||
(findViewById<View>(R.id.coordinator_layout) as ViewGroup).addView(mapView, 0)
|
||||
mapView!!.addOnDidFinishLoadingStyleListener {
|
||||
if (mapboxMap != null) {
|
||||
setupNavigationView(mapboxMap!!.style!!.layers)
|
||||
}
|
||||
}
|
||||
mapView!!.tag = true
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync(this)
|
||||
mapView!!.addOnDidFinishLoadingStyleListener { Timber.d("Style loaded") }
|
||||
}
|
||||
|
||||
protected open fun setupMapboxMapOptions(): MapboxMapOptions {
|
||||
return MapboxMapOptions.createFromAttributes(this, null)
|
||||
}
|
||||
|
||||
override fun onMapReady(map: MapboxMap) {
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(
|
||||
Style.Builder().fromUri(STYLES[currentStyleIndex])
|
||||
) { style: Style -> setupNavigationView(style.layers) }
|
||||
setupZoomView()
|
||||
setFpsView()
|
||||
}
|
||||
|
||||
private fun setFpsView() {
|
||||
fpsView = findViewById(R.id.fpsView)
|
||||
mapboxMap!!.setOnFpsChangedListener(this)
|
||||
}
|
||||
|
||||
override fun onFpsChanged(fps: Double) {
|
||||
fpsView!!.text = String.format(Locale.US, "FPS: %4.2f", fps)
|
||||
}
|
||||
|
||||
private fun setupNavigationView(layerList: List<Layer>) {
|
||||
Timber.v("New style loaded with JSON: %s", mapboxMap!!.style!!.json)
|
||||
val adapter = LayerListAdapter(this, layerList)
|
||||
val listView = findViewById<ListView>(R.id.listView)
|
||||
listView.adapter = adapter
|
||||
listView.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { parent: AdapterView<*>?, view: View?, position: Int, id: Long ->
|
||||
val clickedLayer = adapter.getItem(position)
|
||||
toggleLayerVisibility(clickedLayer)
|
||||
closeNavigationView()
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleLayerVisibility(layer: Layer) {
|
||||
val isVisible = layer.visibility.getValue() == Property.VISIBLE
|
||||
layer.setProperties(
|
||||
PropertyFactory.visibility(
|
||||
if (isVisible) Property.NONE else Property.VISIBLE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun closeNavigationView() {
|
||||
val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout)
|
||||
drawerLayout.closeDrawers()
|
||||
}
|
||||
|
||||
private fun setupZoomView() {
|
||||
val textView = findViewById<TextView>(R.id.textZoom)
|
||||
mapboxMap!!.addOnCameraMoveListener(
|
||||
OnCameraMoveListener {
|
||||
textView.text = String.format(
|
||||
this@DebugModeActivity.getString(
|
||||
R.string.debug_zoom
|
||||
),
|
||||
mapboxMap!!.cameraPosition.zoom
|
||||
)
|
||||
}.also { cameraMoveListener = it }
|
||||
)
|
||||
}
|
||||
|
||||
private fun setupDebugChangeView() {
|
||||
val fabDebug = findViewById<FloatingActionButton>(R.id.fabDebug)
|
||||
fabDebug.setOnClickListener { view: View? ->
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.isDebugActive = !mapboxMap!!.isDebugActive
|
||||
Timber.d("Debug FAB: isDebug Active? %s", mapboxMap!!.isDebugActive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupStyleChangeView() {
|
||||
val fabStyles = findViewById<FloatingActionButton>(R.id.fabStyles)
|
||||
fabStyles.setOnClickListener { view: View? ->
|
||||
if (mapboxMap != null) {
|
||||
currentStyleIndex++
|
||||
if (currentStyleIndex == STYLES.size) {
|
||||
currentStyleIndex = 0
|
||||
}
|
||||
mapboxMap!!.setStyle(Style.Builder().fromUri(STYLES[currentStyleIndex]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val itemId = item.itemId
|
||||
if (itemId == R.id.menu_action_toggle_report_fps) {
|
||||
isReportFps = !isReportFps
|
||||
fpsView!!.visibility = if (isReportFps) View.VISIBLE else View.GONE
|
||||
mapboxMap!!.setOnFpsChangedListener(if (isReportFps) this else null)
|
||||
} else if (itemId == R.id.menu_action_limit_to_30_fps) {
|
||||
mapView!!.setMaximumFps(30)
|
||||
} else if (itemId == R.id.menu_action_limit_to_60_fps) {
|
||||
mapView!!.setMaximumFps(60)
|
||||
}
|
||||
return actionBarDrawerToggle!!.onOptionsItemSelected(item) || super.onOptionsItemSelected(
|
||||
item
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_debug, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap!!.removeOnCameraMoveListener(cameraMoveListener!!)
|
||||
}
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
private class LayerListAdapter internal constructor(context: Context?, layers: List<Layer>) :
|
||||
BaseAdapter() {
|
||||
private val layoutInflater: LayoutInflater
|
||||
private val layers: List<Layer>
|
||||
override fun getCount(): Int {
|
||||
return layers.size
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Layer {
|
||||
return layers[position]
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return position.toLong()
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
|
||||
val layer = layers[position]
|
||||
var view = convertView
|
||||
if (view == null) {
|
||||
view = layoutInflater.inflate(android.R.layout.simple_list_item_2, parent, false)
|
||||
val holder = ViewHolder(
|
||||
view.findViewById(android.R.id.text1),
|
||||
view.findViewById(android.R.id.text2)
|
||||
)
|
||||
view.tag = holder
|
||||
}
|
||||
val holder = view.tag as ViewHolder
|
||||
holder.text.text = layer.javaClass.simpleName
|
||||
holder.subText.text = layer.id
|
||||
return view
|
||||
}
|
||||
|
||||
private class ViewHolder internal constructor(val text: TextView, val subText: TextView)
|
||||
|
||||
init {
|
||||
layoutInflater = LayoutInflater.from(context)
|
||||
this.layers = layers
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val STYLES = arrayOf(
|
||||
Style.getPredefinedStyle("Streets"),
|
||||
Style.getPredefinedStyle("Outdoor"),
|
||||
Style.getPredefinedStyle("Bright"),
|
||||
Style.getPredefinedStyle("Pastel"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid"),
|
||||
Style.getPredefinedStyle("Satellite Hybrid")
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.utils.MapFragmentUtils;
|
||||
|
||||
/**
|
||||
* Test activity showcasing having 2 maps on top of each other.
|
||||
* <p>
|
||||
* The small map is using the `mapbox_enableZMediaOverlay="true"` configuration
|
||||
* </p>
|
||||
*/
|
||||
public class DoubleMapActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG_FRAGMENT = "map";
|
||||
private static final LatLng MACHU_PICCHU = new LatLng(-13.1650709, -72.5447154);
|
||||
private static final double ZOOM_IN = 12;
|
||||
private static final double ZOOM_OUT = 4;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_fragment);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
MapboxMapOptions options = MapboxMapOptions.createFromAttributes(this, null);
|
||||
options.camera(new CameraPosition.Builder()
|
||||
.target(MACHU_PICCHU)
|
||||
.zoom(ZOOM_IN)
|
||||
.build()
|
||||
);
|
||||
|
||||
DoubleMapFragment doubleMapFragment = new DoubleMapFragment();
|
||||
doubleMapFragment.setArguments(MapFragmentUtils.createFragmentArgs(options));
|
||||
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
transaction.add(R.id.fragment_container, doubleMapFragment, TAG_FRAGMENT);
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom fragment containing 2 MapViews.
|
||||
*/
|
||||
public static class DoubleMapFragment extends Fragment {
|
||||
|
||||
private MapView mapView;
|
||||
private MapView mapViewMini;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_double_map, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// MapView large
|
||||
mapView = new MapView(view.getContext(), MapFragmentUtils.resolveArgs(view.getContext(), getArguments()));
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(Style.getPredefinedStyle("Streets")));
|
||||
((ViewGroup) view.findViewById(R.id.container)).addView(mapView, 0);
|
||||
|
||||
// MapView mini
|
||||
mapViewMini = view.findViewById(R.id.mini_map);
|
||||
mapViewMini.onCreate(savedInstanceState);
|
||||
mapViewMini.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
|
||||
new CameraPosition.Builder().target(MACHU_PICCHU)
|
||||
.zoom(ZOOM_OUT)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.getPredefinedStyle("Bright")));
|
||||
|
||||
UiSettings uiSettings = mapboxMap.getUiSettings();
|
||||
uiSettings.setAllGesturesEnabled(false);
|
||||
uiSettings.setCompassEnabled(false);
|
||||
uiSettings.setAttributionEnabled(false);
|
||||
uiSettings.setLogoEnabled(false);
|
||||
|
||||
mapboxMap.addOnMapClickListener(point -> {
|
||||
// test if we can open 2 activities after each other
|
||||
Toast.makeText(mapViewMini.getContext(), "Creating a new Activity instance", Toast.LENGTH_SHORT).show();
|
||||
startActivity(new Intent(mapViewMini.getContext(), DoubleMapActivity.class));
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
mapViewMini.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
mapViewMini.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
mapViewMini.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
mapViewMini.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mapView.onDestroy();
|
||||
mapViewMini.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
mapViewMini.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
// Mini map view is not interactive in this case, so we shouldn't save the instance.
|
||||
// If we'd like to support state saving for both maps, they'd have to be kept in separate fragments.
|
||||
//mapViewMini.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.maplayout.DoubleMapActivity.DoubleMapFragment
|
||||
import com.mapbox.mapboxsdk.utils.MapFragmentUtils
|
||||
|
||||
/**
|
||||
* Test activity showcasing having 2 maps on top of each other.
|
||||
*
|
||||
*
|
||||
* The small map is using the `mapbox_enableZMediaOverlay="true"` configuration
|
||||
*
|
||||
*/
|
||||
class DoubleMapActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_fragment)
|
||||
if (savedInstanceState == null) {
|
||||
val options = MapboxMapOptions.createFromAttributes(this, null)
|
||||
options.camera(
|
||||
CameraPosition.Builder()
|
||||
.target(MACHU_PICCHU)
|
||||
.zoom(ZOOM_IN)
|
||||
.build()
|
||||
)
|
||||
val doubleMapFragment = DoubleMapFragment()
|
||||
doubleMapFragment.arguments = MapFragmentUtils.createFragmentArgs(options)
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
transaction.add(R.id.fragment_container, doubleMapFragment, TAG_FRAGMENT)
|
||||
transaction.commit()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom fragment containing 2 MapViews.
|
||||
*/
|
||||
class DoubleMapFragment : Fragment() {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var mapViewMini: MapView
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_double_map, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// MapView large
|
||||
mapView = MapView(view.context, MapFragmentUtils.resolveArgs(view.context, arguments))
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
mapboxMap.setStyle(
|
||||
Style.getPredefinedStyle(
|
||||
"Streets"
|
||||
)
|
||||
)
|
||||
}
|
||||
(view.findViewById<View>(R.id.container) as ViewGroup).addView(mapView, 0)
|
||||
|
||||
// MapView mini
|
||||
mapViewMini = view.findViewById(R.id.mini_map)
|
||||
mapViewMini.onCreate(savedInstanceState)
|
||||
mapViewMini.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newCameraPosition(
|
||||
CameraPosition.Builder().target(MACHU_PICCHU)
|
||||
.zoom(ZOOM_OUT)
|
||||
.build()
|
||||
)
|
||||
)
|
||||
mapboxMap.setStyle(Style.Builder().fromUri(Style.getPredefinedStyle("Bright")))
|
||||
val uiSettings = mapboxMap.uiSettings
|
||||
uiSettings.setAllGesturesEnabled(false)
|
||||
uiSettings.isCompassEnabled = false
|
||||
uiSettings.isAttributionEnabled = false
|
||||
uiSettings.isLogoEnabled = false
|
||||
mapboxMap.addOnMapClickListener { point: LatLng? ->
|
||||
// test if we can open 2 activities after each other
|
||||
Toast.makeText(
|
||||
mapViewMini.getContext(),
|
||||
"Creating a new Activity instance",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
startActivity(Intent(mapViewMini.getContext(), DoubleMapActivity::class.java))
|
||||
false
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
mapViewMini!!.onResume()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
mapViewMini!!.onStart()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
mapViewMini!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
mapViewMini!!.onStop()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
mapView!!.onDestroy()
|
||||
mapViewMini!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
mapViewMini!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
// Mini map view is not interactive in this case, so we shouldn't save the instance.
|
||||
// If we'd like to support state saving for both maps, they'd have to be kept in separate fragments.
|
||||
// mapViewMini.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG_FRAGMENT = "map"
|
||||
private val MACHU_PICCHU = LatLng(-13.1650709, -72.5447154)
|
||||
private const val ZOOM_IN = 12.0
|
||||
private const val ZOOM_OUT = 4.0
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
|
||||
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.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing restricting user gestures to a bounds around Iceland, almost worldview and IDL.
|
||||
*/
|
||||
public class LatLngBoundsForCameraActivity extends AppCompatActivity implements OnMapReadyCallback {
|
||||
|
||||
private static final LatLngBounds ICELAND_BOUNDS = new LatLngBounds.Builder()
|
||||
.include(new LatLng(66.852863, -25.985652))
|
||||
.include(new LatLng(62.985661, -12.626277))
|
||||
.build();
|
||||
|
||||
private static final LatLngBounds ALMOST_WORLD_BOUNDS = new LatLngBounds.Builder()
|
||||
.include(new LatLng(20.0, 170.0))
|
||||
.include(new LatLng(-20, -170.0))
|
||||
.build();
|
||||
|
||||
private static final LatLngBounds CROSS_IDL_BOUNDS = new LatLngBounds.Builder()
|
||||
.include(new LatLng(20.0, 170.0))
|
||||
.include(new LatLng(-20, 190.0))
|
||||
.build();
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_restricted_bounds);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Satellite Hybrid"));
|
||||
mapboxMap.setMinZoomPreference(2);
|
||||
mapboxMap.getUiSettings().setFlingVelocityAnimationEnabled(false);
|
||||
showCrosshair();
|
||||
setupBounds(ICELAND_BOUNDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_bounds, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_action_allmost_world_bounds:
|
||||
setupBounds(ALMOST_WORLD_BOUNDS);
|
||||
return true;
|
||||
case R.id.menu_action_cross_idl:
|
||||
setupBounds(CROSS_IDL_BOUNDS);
|
||||
return true;
|
||||
case R.id.menu_action_reset:
|
||||
setupBounds(null);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setupBounds(@Nullable LatLngBounds bounds) {
|
||||
mapboxMap.setLatLngBoundsForCameraTarget(bounds);
|
||||
showBoundsArea(bounds);
|
||||
}
|
||||
|
||||
private void showBoundsArea(@Nullable LatLngBounds bounds) {
|
||||
mapboxMap.clear();
|
||||
if (bounds != null) {
|
||||
PolygonOptions boundsArea = new PolygonOptions()
|
||||
.add(bounds.getNorthWest())
|
||||
.add(bounds.getNorthEast())
|
||||
.add(bounds.getSouthEast())
|
||||
.add(bounds.getSouthWest());
|
||||
boundsArea.alpha(0.25f);
|
||||
boundsArea.fillColor(Color.RED);
|
||||
mapboxMap.addPolygon(boundsArea);
|
||||
}
|
||||
}
|
||||
|
||||
private void showCrosshair() {
|
||||
View crosshair = new View(this);
|
||||
crosshair.setLayoutParams(new FrameLayout.LayoutParams(10, 10, Gravity.CENTER));
|
||||
crosshair.setBackgroundColor(Color.BLUE);
|
||||
mapView.addView(crosshair);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.FrameLayout
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.annotations.PolygonOptions
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing restricting user gestures to a bounds around Iceland, almost worldview and IDL.
|
||||
*/
|
||||
class LatLngBoundsForCameraActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
private lateinit var mapView: MapView
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_restricted_bounds)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(mapboxMap: MapboxMap) {
|
||||
this.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Satellite Hybrid"))
|
||||
mapboxMap.setMinZoomPreference(2.0)
|
||||
mapboxMap.uiSettings.isFlingVelocityAnimationEnabled = false
|
||||
showCrosshair()
|
||||
setupBounds(ICELAND_BOUNDS)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_bounds, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.menu_action_allmost_world_bounds -> {
|
||||
setupBounds(ALMOST_WORLD_BOUNDS)
|
||||
return true
|
||||
}
|
||||
R.id.menu_action_cross_idl -> {
|
||||
setupBounds(CROSS_IDL_BOUNDS)
|
||||
return true
|
||||
}
|
||||
R.id.menu_action_reset -> {
|
||||
setupBounds(null)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun setupBounds(bounds: LatLngBounds?) {
|
||||
mapboxMap!!.setLatLngBoundsForCameraTarget(bounds)
|
||||
showBoundsArea(bounds)
|
||||
}
|
||||
|
||||
private fun showBoundsArea(bounds: LatLngBounds?) {
|
||||
mapboxMap!!.clear()
|
||||
if (bounds != null) {
|
||||
val boundsArea = PolygonOptions()
|
||||
.add(bounds.northWest)
|
||||
.add(bounds.northEast)
|
||||
.add(bounds.southEast)
|
||||
.add(bounds.southWest)
|
||||
boundsArea.alpha(0.25f)
|
||||
boundsArea.fillColor(Color.RED)
|
||||
mapboxMap!!.addPolygon(boundsArea)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCrosshair() {
|
||||
val crosshair = View(this)
|
||||
crosshair.layoutParams = FrameLayout.LayoutParams(10, 10, Gravity.CENTER)
|
||||
crosshair.setBackgroundColor(Color.BLUE)
|
||||
mapView!!.addView(crosshair)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ICELAND_BOUNDS = LatLngBounds.Builder()
|
||||
.include(LatLng(66.852863, -25.985652))
|
||||
.include(LatLng(62.985661, -12.626277))
|
||||
.build()
|
||||
private val ALMOST_WORLD_BOUNDS = LatLngBounds.Builder()
|
||||
.include(LatLng(20.0, 170.0))
|
||||
.include(LatLng((-20).toDouble(), -170.0))
|
||||
.build()
|
||||
private val CROSS_IDL_BOUNDS = LatLngBounds.Builder()
|
||||
.include(LatLng(20.0, 170.0))
|
||||
.include(LatLng((-20).toDouble(), 190.0))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity that displays the city of Suzhou with a mixture of server-generated
|
||||
* latin glyphs and CJK glyphs generated locally using "Droid Sans" as a font family.
|
||||
*/
|
||||
public class LocalGlyphActivity extends AppCompatActivity {
|
||||
private MapView mapView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_local_glyph);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
// Set initial position to Suzhou
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
|
||||
new CameraPosition.Builder()
|
||||
.target(new LatLng(31.3003, 120.7457))
|
||||
.zoom(11)
|
||||
.bearing(0)
|
||||
.tilt(0)
|
||||
.build()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity that displays the city of Suzhou with a mixture of server-generated
|
||||
* latin glyphs and CJK glyphs generated locally using "Droid Sans" as a font family.
|
||||
*/
|
||||
class LocalGlyphActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_local_glyph)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
// Set initial position to Suzhou
|
||||
mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newCameraPosition(
|
||||
CameraPosition.Builder()
|
||||
.target(LatLng(31.3003, 120.7457))
|
||||
.zoom(11.0)
|
||||
.bearing(0.0)
|
||||
.tilt(0.0)
|
||||
.build()
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing how to listen to map change events.
|
||||
*/
|
||||
public class MapChangeActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_simple);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.addOnCameraIsChangingListener(() -> Timber.v("OnCameraIsChanging"));
|
||||
mapView.addOnCameraDidChangeListener(animated -> Timber.v("OnCamaraDidChange: animated: %s", animated));
|
||||
mapView.addOnCameraWillChangeListener(animated -> Timber.v("OnCameraWilChange: animated: %s", animated));
|
||||
mapView.addOnDidFailLoadingMapListener(errorMessage -> Timber.v("OnDidFailLoadingMap: %s", errorMessage));
|
||||
mapView.addOnDidFinishLoadingMapListener(() -> Timber.v("OnDidFinishLoadingMap"));
|
||||
mapView.addOnDidFinishLoadingStyleListener(() -> Timber.v("OnDidFinishLoadingStyle"));
|
||||
mapView.addOnDidFinishRenderingFrameListener(fully -> Timber.v("OnDidFinishRenderingFrame: fully: %s", fully));
|
||||
mapView.addOnDidFinishRenderingMapListener(fully -> Timber.v("OnDidFinishRenderingMap: fully: %s", fully));
|
||||
mapView.addOnDidBecomeIdleListener(() -> Timber.v("OnDidBecomeIdle"));
|
||||
mapView.addOnSourceChangedListener(sourceId -> Timber.v("OnSourceChangedListener: source with id: %s", sourceId));
|
||||
mapView.addOnWillStartLoadingMapListener(() -> Timber.v("OnWillStartLoadingMap"));
|
||||
mapView.addOnWillStartRenderingFrameListener(() -> Timber.v("OnWillStartRenderingFrame"));
|
||||
mapView.addOnWillStartRenderingMapListener(() -> Timber.v("OnWillStartRenderingMap"));
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
new LatLng(55.754020, 37.620948), 12), 9000);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnCameraDidChangeListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnCameraIsChangingListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnCameraWillChangeListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidBecomeIdleListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFailLoadingMapListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishLoadingMapListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishLoadingStyleListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishRenderingFrameListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnDidFinishRenderingMapListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnSourceChangedListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnWillStartLoadingMapListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnWillStartRenderingFrameListener
|
||||
import com.mapbox.mapboxsdk.maps.MapView.OnWillStartRenderingMapListener
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Test activity showcasing how to listen to map change events.
|
||||
*/
|
||||
class MapChangeActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_simple)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.addOnCameraIsChangingListener(OnCameraIsChangingListener { Timber.v("OnCameraIsChanging") })
|
||||
mapView.addOnCameraDidChangeListener(
|
||||
OnCameraDidChangeListener { animated: Boolean ->
|
||||
Timber.v(
|
||||
"OnCamaraDidChange: animated: %s",
|
||||
animated
|
||||
)
|
||||
}
|
||||
)
|
||||
mapView.addOnCameraWillChangeListener(
|
||||
OnCameraWillChangeListener { animated: Boolean ->
|
||||
Timber.v(
|
||||
"OnCameraWilChange: animated: %s",
|
||||
animated
|
||||
)
|
||||
}
|
||||
)
|
||||
mapView.addOnDidFailLoadingMapListener(
|
||||
OnDidFailLoadingMapListener { errorMessage: String? ->
|
||||
Timber.v(
|
||||
"OnDidFailLoadingMap: %s",
|
||||
errorMessage
|
||||
)
|
||||
}
|
||||
)
|
||||
mapView.addOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener { Timber.v("OnDidFinishLoadingMap") })
|
||||
mapView.addOnDidFinishLoadingStyleListener(OnDidFinishLoadingStyleListener { Timber.v("OnDidFinishLoadingStyle") })
|
||||
mapView.addOnDidFinishRenderingFrameListener(
|
||||
OnDidFinishRenderingFrameListener { fully: Boolean ->
|
||||
Timber.v(
|
||||
"OnDidFinishRenderingFrame: fully: %s",
|
||||
fully
|
||||
)
|
||||
}
|
||||
)
|
||||
mapView.addOnDidFinishRenderingMapListener(
|
||||
OnDidFinishRenderingMapListener { fully: Boolean ->
|
||||
Timber.v(
|
||||
"OnDidFinishRenderingMap: fully: %s",
|
||||
fully
|
||||
)
|
||||
}
|
||||
)
|
||||
mapView.addOnDidBecomeIdleListener(OnDidBecomeIdleListener { Timber.v("OnDidBecomeIdle") })
|
||||
mapView.addOnSourceChangedListener(
|
||||
OnSourceChangedListener { sourceId: String? ->
|
||||
Timber.v(
|
||||
"OnSourceChangedListener: source with id: %s",
|
||||
sourceId
|
||||
)
|
||||
}
|
||||
)
|
||||
mapView.addOnWillStartLoadingMapListener(OnWillStartLoadingMapListener { Timber.v("OnWillStartLoadingMap") })
|
||||
mapView.addOnWillStartRenderingFrameListener(OnWillStartRenderingFrameListener { Timber.v("OnWillStartRenderingFrame") })
|
||||
mapView.addOnWillStartRenderingMapListener(OnWillStartRenderingMapListener { Timber.v("OnWillStartRenderingMap") })
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
mapboxMap.animateCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(55.754020, 37.620948),
|
||||
12.0
|
||||
),
|
||||
9000
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing showing a Map inside of a DialogFragment.
|
||||
*/
|
||||
public class MapInDialogActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_in_dialog);
|
||||
|
||||
Button button = findViewById(R.id.button_open_dialog);
|
||||
button.setOnClickListener(view -> {
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
MapDialogFragment editNameDialogFragment = MapDialogFragment.newInstance("Map Dialog");
|
||||
editNameDialogFragment.show(fm, "fragment_dialog_map");
|
||||
});
|
||||
}
|
||||
|
||||
public static class MapDialogFragment extends DialogFragment {
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
public MapDialogFragment() {
|
||||
}
|
||||
|
||||
public static MapDialogFragment newInstance(String title) {
|
||||
MapDialogFragment frag = new MapDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString("title", title);
|
||||
frag.setArguments(args);
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_dialog_map, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mapView = view.findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(Style.getPredefinedStyle("Outdoor")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mapView.onDestroy();
|
||||
mapView = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
if (mapView != null) {
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mapView != null) {
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.maplayout.MapInDialogActivity.MapDialogFragment
|
||||
|
||||
/**
|
||||
* Test activity showcasing showing a Map inside of a DialogFragment.
|
||||
*/
|
||||
class MapInDialogActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_in_dialog)
|
||||
val button = findViewById<Button>(R.id.button_open_dialog)
|
||||
button.setOnClickListener { view: View? ->
|
||||
val fm = supportFragmentManager
|
||||
val editNameDialogFragment = MapDialogFragment.newInstance("Map Dialog")
|
||||
editNameDialogFragment.show(fm, "fragment_dialog_map")
|
||||
}
|
||||
}
|
||||
|
||||
class MapDialogFragment : DialogFragment() {
|
||||
private lateinit var mapView: MapView
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.fragment_dialog_map, container)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mapView = view.findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
mapboxMap.setStyle(
|
||||
Style.getPredefinedStyle("Outdoor")
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
if (mapView != null) {
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
if (mapView != null) {
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(title: String?): MapDialogFragment {
|
||||
val frag = MapDialogFragment()
|
||||
val args = Bundle()
|
||||
args.putString("title", title)
|
||||
frag.arguments = args
|
||||
return frag
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the map padding API.
|
||||
*/
|
||||
public class MapPaddingActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_padding);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.setTag(true);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
MapPaddingActivity.this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
|
||||
int paddingLeft = (int) getResources().getDimension(R.dimen.map_padding_left);
|
||||
int paddingBottom = (int) getResources().getDimension(R.dimen.map_padding_bottom);
|
||||
int paddingRight = (int) getResources().getDimension(R.dimen.map_padding_right);
|
||||
int paddingTop = (int) getResources().getDimension(R.dimen.map_padding_top);
|
||||
mapboxMap.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
|
||||
|
||||
UiSettings settings = mapboxMap.getUiSettings();
|
||||
settings.setLogoMargins(paddingLeft, 0, 0, paddingBottom);
|
||||
settings.setCompassMargins(0, paddingTop, paddingRight, 0);
|
||||
settings.setAttributionEnabled(false);
|
||||
|
||||
moveToBangalore();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_padding, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void moveToBangalore() {
|
||||
LatLng bangalore = new LatLng(12.9810816, 77.6368034);
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.zoom(16)
|
||||
.target(bangalore)
|
||||
.bearing(40)
|
||||
.tilt(45)
|
||||
.build();
|
||||
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||
mapboxMap.addMarker(new MarkerOptions().title("Center map").position(bangalore));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case R.id.action_bangalore:
|
||||
if (mapboxMap != null) {
|
||||
moveToBangalore();
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
|
||||
/**
|
||||
* Test activity showcasing using the map padding API.
|
||||
*/
|
||||
class MapPaddingActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_padding)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.setTag(true)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
this@MapPaddingActivity.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
val paddingLeft = resources.getDimension(R.dimen.map_padding_left).toInt()
|
||||
val paddingBottom = resources.getDimension(R.dimen.map_padding_bottom).toInt()
|
||||
val paddingRight = resources.getDimension(R.dimen.map_padding_right).toInt()
|
||||
val paddingTop = resources.getDimension(R.dimen.map_padding_top).toInt()
|
||||
mapboxMap.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
|
||||
val settings = mapboxMap.uiSettings
|
||||
settings.setLogoMargins(paddingLeft, 0, 0, paddingBottom)
|
||||
settings.setCompassMargins(0, paddingTop, paddingRight, 0)
|
||||
settings.isAttributionEnabled = false
|
||||
moveToBangalore()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_padding, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun moveToBangalore() {
|
||||
val bangalore = LatLng(12.9810816, 77.6368034)
|
||||
val cameraPosition = CameraPosition.Builder()
|
||||
.zoom(16.0)
|
||||
.target(bangalore)
|
||||
.bearing(40.0)
|
||||
.tilt(45.0)
|
||||
.build()
|
||||
mapboxMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
mapboxMap!!.addMarker(MarkerOptions().title("Center map").position(bangalore))
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_bangalore -> {
|
||||
if (mapboxMap != null) {
|
||||
moveToBangalore()
|
||||
}
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.NavUtils;
|
||||
import com.mapbox.mapboxsdk.util.DefaultStyle;
|
||||
|
||||
/**
|
||||
* Test activity showcasing a simple MapView without any MapboxMap interaction.
|
||||
*/
|
||||
public class SimpleMapActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_simple);
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
DefaultStyle[] styles = Style.getPredefinedStyles();
|
||||
if (styles != null && styles.length > 0) {
|
||||
String styleUrl = styles[0].getUrl();
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(styleUrl));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
NavUtils.navigateHome(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.utils.NavUtils
|
||||
|
||||
/**
|
||||
* Test activity showcasing a simple MapView without any MapboxMap interaction.
|
||||
*/
|
||||
class SimpleMapActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_simple)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { mapboxMap: MapboxMap ->
|
||||
val styles = Style.getPredefinedStyles()
|
||||
if (styles != null && styles.size > 0) {
|
||||
val styleUrl = styles[0].url
|
||||
mapboxMap.setStyle(Style.Builder().fromUri(styleUrl))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
// activity uses singleInstance for testing purposes
|
||||
// code below provides a default navigation when using the app
|
||||
NavUtils.navigateHome(this)
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Test activity showcasing visibility changes to the mapview.
|
||||
*/
|
||||
public class VisibilityChangeActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private Handler handler = new Handler();
|
||||
private Runnable runnable;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_visibility);
|
||||
|
||||
mapView = findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(map -> {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setStyle(Style.getPredefinedStyle("Streets"));
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
new LatLng(55.754020, 37.620948), 12), 9000);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
handler.post(runnable = new VisibilityRunner(mapView, findViewById(R.id.viewParent), handler));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
private static class VisibilityRunner implements Runnable {
|
||||
|
||||
private MapView mapView;
|
||||
private View viewParent;
|
||||
private Handler handler;
|
||||
private int currentStep;
|
||||
|
||||
VisibilityRunner(MapView mapView, View viewParent, Handler handler) {
|
||||
this.mapView = mapView;
|
||||
this.viewParent = viewParent;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isViewHiearchyReady()) {
|
||||
if (isEvenStep()) {
|
||||
viewParent.setVisibility(View.VISIBLE);
|
||||
mapView.setVisibility(View.VISIBLE);
|
||||
} else if (isFirstOrThirdStep()) {
|
||||
mapView.setVisibility(getVisibilityForStep());
|
||||
} else if (isFifthOrSeventhStep()) {
|
||||
viewParent.setVisibility(getVisibilityForStep());
|
||||
}
|
||||
updateStep();
|
||||
}
|
||||
handler.postDelayed(this, 1500);
|
||||
}
|
||||
|
||||
private void updateStep() {
|
||||
if (currentStep == 7) {
|
||||
currentStep = 0;
|
||||
} else {
|
||||
currentStep++;
|
||||
}
|
||||
}
|
||||
|
||||
private int getVisibilityForStep() {
|
||||
return (currentStep == 1 || currentStep == 5) ? View.GONE : View.INVISIBLE;
|
||||
}
|
||||
|
||||
private boolean isFifthOrSeventhStep() {
|
||||
return currentStep == 5 || currentStep == 7;
|
||||
}
|
||||
|
||||
private boolean isFirstOrThirdStep() {
|
||||
return currentStep == 1 || currentStep == 3;
|
||||
}
|
||||
|
||||
private boolean isEvenStep() {
|
||||
return currentStep == 0 || currentStep % 2 == 0;
|
||||
}
|
||||
|
||||
private boolean isViewHiearchyReady() {
|
||||
return mapView != null && viewParent != null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (runnable != null) {
|
||||
handler.removeCallbacks(runnable);
|
||||
runnable = null;
|
||||
}
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.maplayout
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.*
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.maplayout.VisibilityChangeActivity.VisibilityRunner
|
||||
|
||||
/**
|
||||
* Test activity showcasing visibility changes to the mapview.
|
||||
*/
|
||||
class VisibilityChangeActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private val handler = Handler()
|
||||
private var runnable: Runnable? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_map_visibility)
|
||||
mapView = findViewById(R.id.mapView)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
mapView.getMapAsync(
|
||||
OnMapReadyCallback { map: MapboxMap? ->
|
||||
mapboxMap = map
|
||||
mapboxMap!!.setStyle(Style.getPredefinedStyle("Streets"))
|
||||
mapboxMap!!.animateCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(55.754020, 37.620948),
|
||||
12.0
|
||||
),
|
||||
9000
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
handler.post(
|
||||
VisibilityRunner(
|
||||
mapView,
|
||||
findViewById(R.id.viewParent),
|
||||
handler
|
||||
).also { runnable = it }
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
private class VisibilityRunner internal constructor(
|
||||
private val mapView: MapView?,
|
||||
private val viewParent: View?,
|
||||
private val handler: Handler
|
||||
) : Runnable {
|
||||
private var currentStep = 0
|
||||
override fun run() {
|
||||
if (isViewHiearchyReady) {
|
||||
if (isEvenStep) {
|
||||
viewParent!!.visibility = View.VISIBLE
|
||||
mapView!!.visibility = View.VISIBLE
|
||||
} else if (isFirstOrThirdStep) {
|
||||
mapView!!.visibility = visibilityForStep
|
||||
} else if (isFifthOrSeventhStep) {
|
||||
viewParent!!.visibility = visibilityForStep
|
||||
}
|
||||
updateStep()
|
||||
}
|
||||
handler.postDelayed(this, 1500)
|
||||
}
|
||||
|
||||
private fun updateStep() {
|
||||
if (currentStep == 7) {
|
||||
currentStep = 0
|
||||
} else {
|
||||
currentStep++
|
||||
}
|
||||
}
|
||||
|
||||
private val visibilityForStep: Int
|
||||
private get() = if (currentStep == 1 || currentStep == 5) View.GONE else View.INVISIBLE
|
||||
private val isFifthOrSeventhStep: Boolean
|
||||
private get() = currentStep == 5 || currentStep == 7
|
||||
private val isFirstOrThirdStep: Boolean
|
||||
private get() = currentStep == 1 || currentStep == 3
|
||||
private val isEvenStep: Boolean
|
||||
private get() = currentStep == 0 || currentStep % 2 == 0
|
||||
private val isViewHiearchyReady: Boolean
|
||||
private get() = mapView != null && viewParent != null
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
if (runnable != null) {
|
||||
handler.removeCallbacks(runnable)
|
||||
runnable = null
|
||||
}
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test activity showing integration of deleting an OfflineRegion.
|
||||
*/
|
||||
public class DeleteRegionActivity extends AppCompatActivity implements AdapterView.OnItemClickListener,
|
||||
AdapterView.OnItemLongClickListener {
|
||||
|
||||
private OfflineRegionAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_offline_region_delete);
|
||||
|
||||
ListView listView = findViewById(R.id.listView);
|
||||
listView.setAdapter(adapter = new OfflineRegionAdapter(this));
|
||||
listView.setEmptyView(findViewById(android.R.id.empty));
|
||||
listView.setOnItemClickListener(this);
|
||||
listView.setOnItemLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final OfflineRegion region = adapter.getItem(position);
|
||||
String metadata = OfflineUtils.convertRegionName(region.getMetadata());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Delete region");
|
||||
|
||||
final TextView input = new TextView(this);
|
||||
input.setText(metadata);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("OK", (dialog, which) -> delete(region));
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final OfflineRegion region = adapter.getItem(position);
|
||||
region.invalidate(new OfflineRegion.OfflineRegionInvalidateCallback() {
|
||||
@Override
|
||||
public void onInvalidate() {
|
||||
Toast.makeText(DeleteRegionActivity.this, "Invalidate region success", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(DeleteRegionActivity.this, "Error:" + error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private void delete(OfflineRegion region) {
|
||||
region.delete(new OfflineRegion.OfflineRegionDeleteCallback() {
|
||||
@Override
|
||||
public void onDelete() {
|
||||
Toast.makeText(
|
||||
DeleteRegionActivity.this,
|
||||
"Region deleted",
|
||||
Toast.LENGTH_SHORT
|
||||
).show();
|
||||
loadOfflineRegions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(
|
||||
DeleteRegionActivity.this,
|
||||
"Region deletion failed with " + error,
|
||||
Toast.LENGTH_LONG
|
||||
).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
loadOfflineRegions();
|
||||
}
|
||||
|
||||
private void loadOfflineRegions() {
|
||||
OfflineManager.getInstance(this).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
if (offlineRegions != null && offlineRegions.length > 0) {
|
||||
adapter.setOfflineRegions(Arrays.asList(offlineRegions));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(DeleteRegionActivity.this, "Error loading regions " + error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class OfflineRegionAdapter extends BaseAdapter {
|
||||
|
||||
private Context context;
|
||||
private List<OfflineRegion> offlineRegions;
|
||||
|
||||
OfflineRegionAdapter(Context ctx) {
|
||||
context = ctx;
|
||||
offlineRegions = new ArrayList<>();
|
||||
}
|
||||
|
||||
void setOfflineRegions(List<OfflineRegion> offlineRegions) {
|
||||
this.offlineRegions = offlineRegions;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return offlineRegions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflineRegion getItem(int position) {
|
||||
return offlineRegions.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new ViewHolder();
|
||||
convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
|
||||
holder.text = (TextView) convertView.findViewById(android.R.id.text1);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.text.setText(OfflineUtils.convertRegionName(getItem(position).getMetadata()));
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager.ListOfflineRegionsCallback
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion.OfflineRegionDeleteCallback
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion.OfflineRegionInvalidateCallback
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.offline.DeleteRegionActivity.OfflineRegionAdapter
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Test activity showing integration of deleting an OfflineRegion.
|
||||
*/
|
||||
class DeleteRegionActivity :
|
||||
AppCompatActivity(),
|
||||
AdapterView.OnItemClickListener,
|
||||
AdapterView.OnItemLongClickListener {
|
||||
private var adapter: OfflineRegionAdapter? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_offline_region_delete)
|
||||
val listView = findViewById<ListView>(R.id.listView)
|
||||
listView.adapter = OfflineRegionAdapter(this).also { adapter = it }
|
||||
listView.emptyView = findViewById(android.R.id.empty)
|
||||
listView.onItemClickListener = this
|
||||
listView.onItemLongClickListener = this
|
||||
}
|
||||
|
||||
override fun onItemClick(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
val region = adapter!!.getItem(position)
|
||||
val metadata = OfflineUtils.convertRegionName(region.metadata)
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle("Delete region")
|
||||
val input = TextView(this)
|
||||
input.text = metadata
|
||||
builder.setView(input)
|
||||
builder.setPositiveButton("OK") { dialog: DialogInterface?, which: Int -> delete(region) }
|
||||
builder.setNegativeButton("Cancel") { dialog: DialogInterface, which: Int -> dialog.cancel() }
|
||||
builder.show()
|
||||
}
|
||||
|
||||
override fun onItemLongClick(
|
||||
parent: AdapterView<*>?,
|
||||
view: View,
|
||||
position: Int,
|
||||
id: Long
|
||||
): Boolean {
|
||||
val region = adapter!!.getItem(position)
|
||||
region.invalidate(object : OfflineRegionInvalidateCallback {
|
||||
override fun onInvalidate() {
|
||||
Toast.makeText(
|
||||
this@DeleteRegionActivity,
|
||||
"Invalidate region success",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Toast.makeText(this@DeleteRegionActivity, "Error:$error", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
private fun delete(region: OfflineRegion) {
|
||||
region.delete(object : OfflineRegionDeleteCallback {
|
||||
override fun onDelete() {
|
||||
Toast.makeText(
|
||||
this@DeleteRegionActivity,
|
||||
"Region deleted",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
loadOfflineRegions()
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Toast.makeText(
|
||||
this@DeleteRegionActivity,
|
||||
"Region deletion failed with $error",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
loadOfflineRegions()
|
||||
}
|
||||
|
||||
private fun loadOfflineRegions() {
|
||||
OfflineManager.getInstance(this).listOfflineRegions(object : ListOfflineRegionsCallback {
|
||||
override fun onList(offlineRegions: Array<OfflineRegion>) {
|
||||
if (offlineRegions != null && offlineRegions.size > 0) {
|
||||
adapter!!.setOfflineRegions(Arrays.asList(*offlineRegions))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Toast.makeText(
|
||||
this@DeleteRegionActivity,
|
||||
"Error loading regions $error",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private class OfflineRegionAdapter internal constructor(private val context: Context) :
|
||||
BaseAdapter() {
|
||||
private var offlineRegions: List<OfflineRegion>
|
||||
fun setOfflineRegions(offlineRegions: List<OfflineRegion>) {
|
||||
this.offlineRegions = offlineRegions
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return offlineRegions.size
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): OfflineRegion {
|
||||
return offlineRegions[position]
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return position.toLong()
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
|
||||
var convertView = convertView
|
||||
val holder: ViewHolder
|
||||
if (convertView == null) {
|
||||
holder = ViewHolder()
|
||||
convertView = LayoutInflater.from(context)
|
||||
.inflate(android.R.layout.simple_list_item_1, parent, false)
|
||||
holder.text = convertView.findViewById<View>(android.R.id.text1) as TextView
|
||||
convertView.tag = holder
|
||||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
holder.text!!.text = OfflineUtils.convertRegionName(getItem(position).metadata)
|
||||
return convertView
|
||||
}
|
||||
|
||||
internal class ViewHolder {
|
||||
var text: TextView? = null
|
||||
}
|
||||
|
||||
init {
|
||||
offlineRegions = ArrayList()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,321 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
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.Style;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegionError;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegionStatus;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.model.other.OfflineDownloadRegionDialog;
|
||||
import com.mapbox.mapboxsdk.testapp.model.other.OfflineListRegionsDialog;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing the Offline API.
|
||||
* <p>
|
||||
* Shows a map of Manhattan and allows the user to download and name a region.
|
||||
* </p>
|
||||
*/
|
||||
public class OfflineActivity extends AppCompatActivity
|
||||
implements OfflineDownloadRegionDialog.DownloadRegionDialogListener {
|
||||
|
||||
// JSON encoding/decoding
|
||||
public static final String JSON_CHARSET = "UTF-8";
|
||||
public static final String JSON_FIELD_REGION_NAME = "FIELD_REGION_NAME";
|
||||
|
||||
// Style URL
|
||||
public static final String STYLE_URL = Style.getPredefinedStyle("Streets");
|
||||
|
||||
/*
|
||||
* UI elements
|
||||
*/
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private ProgressBar progressBar;
|
||||
private Button downloadRegion;
|
||||
private Button listRegions;
|
||||
|
||||
private boolean isEndNotified;
|
||||
|
||||
/*
|
||||
* Offline objects
|
||||
*/
|
||||
private OfflineManager offlineManager;
|
||||
private OfflineRegion offlineRegion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_offline);
|
||||
|
||||
// You can use Mapbox.setConnected(Boolean) to manually set the connectivity
|
||||
// state of your app. This will override any checks performed via the ConnectivityManager.
|
||||
// Mapbox.getInstance().setConnected(false);
|
||||
Boolean connected = Mapbox.isConnected();
|
||||
Timber.d("Mapbox is connected: %s", connected);
|
||||
|
||||
// Set up map
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
Timber.d("Map is ready");
|
||||
OfflineActivity.this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(new Style.Builder().fromUri(STYLE_URL));
|
||||
// Set initial position to UNHQ in NYC
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
|
||||
new CameraPosition.Builder()
|
||||
.target(new LatLng(40.749851, -73.967966))
|
||||
.zoom(14)
|
||||
.bearing(0)
|
||||
.tilt(0)
|
||||
.build()));
|
||||
});
|
||||
|
||||
// The progress bar
|
||||
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
|
||||
|
||||
// Set up button listeners
|
||||
downloadRegion = (Button) findViewById(R.id.button_download_region);
|
||||
downloadRegion.setOnClickListener(view -> handleDownloadRegion());
|
||||
|
||||
listRegions = (Button) findViewById(R.id.button_list_regions);
|
||||
listRegions.setOnClickListener(view -> handleListRegions());
|
||||
|
||||
// Set up the OfflineManager
|
||||
offlineManager = OfflineManager.getInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
/*
|
||||
* Buttons logic
|
||||
*/
|
||||
private void handleDownloadRegion() {
|
||||
Timber.d("handleDownloadRegion");
|
||||
|
||||
// Show dialog
|
||||
OfflineDownloadRegionDialog offlineDownloadRegionDialog = new OfflineDownloadRegionDialog();
|
||||
offlineDownloadRegionDialog.show(getSupportFragmentManager(), "download");
|
||||
}
|
||||
|
||||
private void handleListRegions() {
|
||||
Timber.d("handleListRegions");
|
||||
|
||||
// Query the DB asynchronously
|
||||
offlineManager.listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
// Check result
|
||||
if (offlineRegions == null || offlineRegions.length == 0) {
|
||||
Toast.makeText(OfflineActivity.this, "You have no regions yet.", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get regions info
|
||||
ArrayList<String> offlineRegionsNames = new ArrayList<>();
|
||||
for (OfflineRegion offlineRegion : offlineRegions) {
|
||||
offlineRegionsNames.add(OfflineUtils.convertRegionName(offlineRegion.getMetadata()));
|
||||
}
|
||||
|
||||
// Create args
|
||||
Bundle args = new Bundle();
|
||||
args.putStringArrayList(OfflineListRegionsDialog.ITEMS, offlineRegionsNames);
|
||||
|
||||
// Show dialog
|
||||
OfflineListRegionsDialog offlineListRegionsDialog = new OfflineListRegionsDialog();
|
||||
offlineListRegionsDialog.setArguments(args);
|
||||
offlineListRegionsDialog.show(getSupportFragmentManager(), "list");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Timber.e("Error: %s" , error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Dialogs
|
||||
*/
|
||||
@Override
|
||||
public void onDownloadRegionDialogPositiveClick(final String regionName) {
|
||||
if (TextUtils.isEmpty(regionName)) {
|
||||
Toast.makeText(OfflineActivity.this, "Region name cannot be empty.", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start progress bar
|
||||
Timber.d("Download started: %s", regionName);
|
||||
startProgress();
|
||||
|
||||
// Definition
|
||||
LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds;
|
||||
double minZoom = mapboxMap.getCameraPosition().zoom;
|
||||
double maxZoom = mapboxMap.getMaxZoomLevel();
|
||||
float pixelRatio = this.getResources().getDisplayMetrics().density;
|
||||
OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
|
||||
STYLE_URL, bounds, minZoom, maxZoom, pixelRatio);
|
||||
|
||||
// Sample way of encoding metadata from a JSONObject
|
||||
byte[] metadata = OfflineUtils.convertRegionName(regionName);
|
||||
|
||||
// Create region
|
||||
offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() {
|
||||
@Override
|
||||
public void onCreate(OfflineRegion offlineRegion) {
|
||||
Timber.d("Offline region created: %s" , regionName);
|
||||
OfflineActivity.this.offlineRegion = offlineRegion;
|
||||
launchDownload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Timber.e("Error: %s", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void launchDownload() {
|
||||
// Set an observer
|
||||
offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() {
|
||||
@Override
|
||||
public void onStatusChanged(OfflineRegionStatus status) {
|
||||
// Compute a percentage
|
||||
double percentage = status.getRequiredResourceCount() >= 0
|
||||
? (100.0 * status.getCompletedResourceCount() / status.getRequiredResourceCount()) :
|
||||
0.0;
|
||||
|
||||
if (status.isComplete()) {
|
||||
// Download complete
|
||||
endProgress("Region downloaded successfully.");
|
||||
offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE);
|
||||
offlineRegion.setObserver(null);
|
||||
return;
|
||||
} else if (status.isRequiredResourceCountPrecise()) {
|
||||
// Switch to determinate state
|
||||
setPercentage((int) Math.round(percentage));
|
||||
}
|
||||
|
||||
// Debug
|
||||
Timber.d("%s/%s resources; %s bytes downloaded.",
|
||||
String.valueOf(status.getCompletedResourceCount()),
|
||||
String.valueOf(status.getRequiredResourceCount()),
|
||||
String.valueOf(status.getCompletedResourceSize()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(OfflineRegionError error) {
|
||||
Timber.e("onError: %s, %s", error.getReason(), error.getMessage());
|
||||
offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapboxTileCountLimitExceeded(long limit) {
|
||||
Timber.e("Mapbox tile count limit exceeded: %s", limit);
|
||||
offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE);
|
||||
}
|
||||
});
|
||||
|
||||
// Change the region state
|
||||
offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Progress bar
|
||||
*/
|
||||
private void startProgress() {
|
||||
// Disable buttons
|
||||
downloadRegion.setEnabled(false);
|
||||
listRegions.setEnabled(false);
|
||||
|
||||
// Start and show the progress bar
|
||||
isEndNotified = false;
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void setPercentage(final int percentage) {
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setProgress(percentage);
|
||||
}
|
||||
|
||||
private void endProgress(final String message) {
|
||||
// Don't notify more than once
|
||||
if (isEndNotified) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable buttons
|
||||
downloadRegion.setEnabled(true);
|
||||
listRegions.setEnabled(true);
|
||||
|
||||
// Stop and hide the progress bar
|
||||
isEndNotified = true;
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
// Show a toast
|
||||
Toast.makeText(OfflineActivity.this, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.Mapbox
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager.CreateOfflineRegionCallback
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager.ListOfflineRegionsCallback
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion.OfflineRegionObserver
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegionError
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegionStatus
|
||||
import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.model.other.OfflineDownloadRegionDialog
|
||||
import com.mapbox.mapboxsdk.testapp.model.other.OfflineDownloadRegionDialog.DownloadRegionDialogListener
|
||||
import com.mapbox.mapboxsdk.testapp.model.other.OfflineListRegionsDialog
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils
|
||||
import timber.log.Timber
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* Test activity showcasing the Offline API.
|
||||
*
|
||||
*
|
||||
* Shows a map of Manhattan and allows the user to download and name a region.
|
||||
*
|
||||
*/
|
||||
class OfflineActivity : AppCompatActivity(), DownloadRegionDialogListener {
|
||||
/*
|
||||
* UI elements
|
||||
*/
|
||||
private var mapView: MapView? = null
|
||||
private var mapboxMap: MapboxMap? = null
|
||||
private var progressBar: ProgressBar? = null
|
||||
private var downloadRegion: Button? = null
|
||||
private var listRegions: Button? = null
|
||||
private var isEndNotified = false
|
||||
|
||||
/*
|
||||
* Offline objects
|
||||
*/
|
||||
private var offlineManager: OfflineManager? = null
|
||||
private var offlineRegion: OfflineRegion? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_offline)
|
||||
|
||||
// You can use Mapbox.setConnected(Boolean) to manually set the connectivity
|
||||
// state of your app. This will override any checks performed via the ConnectivityManager.
|
||||
// Mapbox.getInstance().setConnected(false);
|
||||
val connected = Mapbox.isConnected()
|
||||
Timber.d("Mapbox is connected: %s", connected)
|
||||
|
||||
// Set up map
|
||||
mapView = findViewById<View>(R.id.mapView) as MapView
|
||||
mapView!!.onCreate(savedInstanceState)
|
||||
mapView!!.getMapAsync { mapboxMap: MapboxMap ->
|
||||
Timber.d("Map is ready")
|
||||
this@OfflineActivity.mapboxMap = mapboxMap
|
||||
mapboxMap.setStyle(Style.Builder().fromUri(STYLE_URL))
|
||||
// Set initial position to UNHQ in NYC
|
||||
mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newCameraPosition(
|
||||
CameraPosition.Builder()
|
||||
.target(LatLng(40.749851, -73.967966))
|
||||
.zoom(14.0)
|
||||
.bearing(0.0)
|
||||
.tilt(0.0)
|
||||
.build()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// The progress bar
|
||||
progressBar = findViewById<View>(R.id.progress_bar) as ProgressBar
|
||||
|
||||
// Set up button listeners
|
||||
downloadRegion = findViewById<View>(R.id.button_download_region) as Button
|
||||
downloadRegion!!.setOnClickListener { view: View? -> handleDownloadRegion() }
|
||||
listRegions = findViewById<View>(R.id.button_list_regions) as Button
|
||||
listRegions!!.setOnClickListener { view: View? -> handleListRegions() }
|
||||
|
||||
// Set up the OfflineManager
|
||||
offlineManager = OfflineManager.getInstance(this)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
mapView!!.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView!!.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapView!!.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
mapView!!.onStop()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView!!.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapView!!.onLowMemory()
|
||||
}
|
||||
|
||||
/*
|
||||
* Buttons logic
|
||||
*/
|
||||
private fun handleDownloadRegion() {
|
||||
Timber.d("handleDownloadRegion")
|
||||
|
||||
// Show dialog
|
||||
val offlineDownloadRegionDialog = OfflineDownloadRegionDialog()
|
||||
offlineDownloadRegionDialog.show(supportFragmentManager, "download")
|
||||
}
|
||||
|
||||
private fun handleListRegions() {
|
||||
Timber.d("handleListRegions")
|
||||
|
||||
// Query the DB asynchronously
|
||||
offlineManager!!.listOfflineRegions(object : ListOfflineRegionsCallback {
|
||||
override fun onList(offlineRegions: Array<OfflineRegion>) {
|
||||
// Check result
|
||||
if (offlineRegions == null || offlineRegions.size == 0) {
|
||||
Toast.makeText(
|
||||
this@OfflineActivity,
|
||||
"You have no regions yet.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return
|
||||
}
|
||||
|
||||
// Get regions info
|
||||
val offlineRegionsNames = ArrayList<String>()
|
||||
for (offlineRegion in offlineRegions) {
|
||||
offlineRegionsNames.add(OfflineUtils.convertRegionName(offlineRegion.metadata))
|
||||
}
|
||||
|
||||
// Create args
|
||||
val args = Bundle()
|
||||
args.putStringArrayList(OfflineListRegionsDialog.ITEMS, offlineRegionsNames)
|
||||
|
||||
// Show dialog
|
||||
val offlineListRegionsDialog = OfflineListRegionsDialog()
|
||||
offlineListRegionsDialog.arguments = args
|
||||
offlineListRegionsDialog.show(supportFragmentManager, "list")
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Timber.e("Error: %s", error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Dialogs
|
||||
*/
|
||||
override fun onDownloadRegionDialogPositiveClick(regionName: String) {
|
||||
if (TextUtils.isEmpty(regionName)) {
|
||||
Toast.makeText(this@OfflineActivity, "Region name cannot be empty.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
return
|
||||
}
|
||||
|
||||
// Start progress bar
|
||||
Timber.d("Download started: %s", regionName)
|
||||
startProgress()
|
||||
|
||||
// Definition
|
||||
val bounds = mapboxMap!!.projection.visibleRegion.latLngBounds
|
||||
val minZoom = mapboxMap!!.cameraPosition.zoom
|
||||
val maxZoom = mapboxMap!!.maxZoomLevel
|
||||
val pixelRatio = this.resources.displayMetrics.density
|
||||
val definition = OfflineTilePyramidRegionDefinition(
|
||||
STYLE_URL,
|
||||
bounds,
|
||||
minZoom,
|
||||
maxZoom,
|
||||
pixelRatio
|
||||
)
|
||||
|
||||
// Sample way of encoding metadata from a JSONObject
|
||||
val metadata = OfflineUtils.convertRegionName(regionName)
|
||||
|
||||
// Create region
|
||||
offlineManager!!.createOfflineRegion(
|
||||
definition,
|
||||
metadata,
|
||||
object : CreateOfflineRegionCallback {
|
||||
override fun onCreate(offlineRegion: OfflineRegion) {
|
||||
Timber.d("Offline region created: %s", regionName)
|
||||
this@OfflineActivity.offlineRegion = offlineRegion
|
||||
launchDownload()
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Timber.e("Error: %s", error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun launchDownload() {
|
||||
// Set an observer
|
||||
offlineRegion!!.setObserver(object : OfflineRegionObserver {
|
||||
override fun onStatusChanged(status: OfflineRegionStatus) {
|
||||
// Compute a percentage
|
||||
val percentage =
|
||||
if (status.requiredResourceCount >= 0) 100.0 * status.completedResourceCount / status.requiredResourceCount else 0.0
|
||||
if (status.isComplete) {
|
||||
// Download complete
|
||||
endProgress("Region downloaded successfully.")
|
||||
offlineRegion!!.setDownloadState(OfflineRegion.STATE_INACTIVE)
|
||||
offlineRegion!!.setObserver(null)
|
||||
return
|
||||
} else if (status.isRequiredResourceCountPrecise) {
|
||||
// Switch to determinate state
|
||||
setPercentage(Math.round(percentage).toInt())
|
||||
}
|
||||
|
||||
// Debug
|
||||
Timber.d(
|
||||
"%s/%s resources; %s bytes downloaded.",
|
||||
status.completedResourceCount.toString(),
|
||||
status.requiredResourceCount.toString(),
|
||||
status.completedResourceSize.toString()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onError(error: OfflineRegionError) {
|
||||
Timber.e("onError: %s, %s", error.reason, error.message)
|
||||
offlineRegion!!.setDownloadState(OfflineRegion.STATE_INACTIVE)
|
||||
}
|
||||
|
||||
override fun mapboxTileCountLimitExceeded(limit: Long) {
|
||||
Timber.e("Mapbox tile count limit exceeded: %s", limit)
|
||||
offlineRegion!!.setDownloadState(OfflineRegion.STATE_INACTIVE)
|
||||
}
|
||||
})
|
||||
|
||||
// Change the region state
|
||||
offlineRegion!!.setDownloadState(OfflineRegion.STATE_ACTIVE)
|
||||
}
|
||||
|
||||
/*
|
||||
* Progress bar
|
||||
*/
|
||||
private fun startProgress() {
|
||||
// Disable buttons
|
||||
downloadRegion!!.isEnabled = false
|
||||
listRegions!!.isEnabled = false
|
||||
|
||||
// Start and show the progress bar
|
||||
isEndNotified = false
|
||||
progressBar!!.isIndeterminate = true
|
||||
progressBar!!.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun setPercentage(percentage: Int) {
|
||||
progressBar!!.isIndeterminate = false
|
||||
progressBar!!.progress = percentage
|
||||
}
|
||||
|
||||
private fun endProgress(message: String) {
|
||||
// Don't notify more than once
|
||||
if (isEndNotified) {
|
||||
return
|
||||
}
|
||||
|
||||
// Enable buttons
|
||||
downloadRegion!!.isEnabled = true
|
||||
listRegions!!.isEnabled = true
|
||||
|
||||
// Stop and hide the progress bar
|
||||
isEndNotified = true
|
||||
progressBar!!.isIndeterminate = false
|
||||
progressBar!!.visibility = View.GONE
|
||||
|
||||
// Show a toast
|
||||
Toast.makeText(this@OfflineActivity, message, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
// JSON encoding/decoding
|
||||
const val JSON_CHARSET = "UTF-8"
|
||||
const val JSON_FIELD_REGION_NAME = "FIELD_REGION_NAME"
|
||||
|
||||
// Style URL
|
||||
val STYLE_URL = Style.getPredefinedStyle("Streets")
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test activity showing integration of updating metadata of an OfflineRegion.
|
||||
*/
|
||||
public class UpdateMetadataActivity extends AppCompatActivity implements AdapterView.OnItemClickListener,
|
||||
AdapterView.OnItemLongClickListener {
|
||||
|
||||
private OfflineRegionMetadataAdapter adapter;
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_metadata_update);
|
||||
|
||||
ListView listView = findViewById(R.id.listView);
|
||||
listView.setAdapter(adapter = new OfflineRegionMetadataAdapter(this));
|
||||
listView.setEmptyView(findViewById(android.R.id.empty));
|
||||
listView.setOnItemClickListener(this);
|
||||
listView.setOnItemLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final OfflineRegion region = adapter.getItem(position);
|
||||
String metadata = OfflineUtils.convertRegionName(region.getMetadata());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Rename metadata");
|
||||
|
||||
final EditText input = new EditText(this);
|
||||
input.setText(metadata);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
if (metadata != null) {
|
||||
input.setSelection(metadata.length());
|
||||
}
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("OK", (dialog, which) ->
|
||||
updateMetadata(region, OfflineUtils.convertRegionName(input.getText().toString()))
|
||||
);
|
||||
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
ViewGroup container = findViewById(R.id.container);
|
||||
container.removeAllViews();
|
||||
container.addView(mapView = new MapView(view.getContext()));
|
||||
mapView.onCreate(null);
|
||||
mapView.getMapAsync(map -> map.setOfflineRegionDefinition(adapter.getItem(position).getDefinition()));
|
||||
mapView.onStart();
|
||||
mapView.onResume();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateMetadata(OfflineRegion region, byte[] metadata) {
|
||||
region.updateMetadata(metadata, new OfflineRegion.OfflineRegionUpdateMetadataCallback() {
|
||||
@Override
|
||||
public void onUpdate(byte[] metadata) {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(
|
||||
UpdateMetadataActivity.this,
|
||||
"Region metadata update failed with " + error,
|
||||
Toast.LENGTH_LONG
|
||||
).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
loadOfflineRegions();
|
||||
}
|
||||
|
||||
private void loadOfflineRegions() {
|
||||
OfflineManager.getInstance(this).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
if (offlineRegions != null && offlineRegions.length > 0) {
|
||||
adapter.setOfflineRegions(Arrays.asList(offlineRegions));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Toast.makeText(UpdateMetadataActivity.this, "Error loading regions " + error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mapView != null) {
|
||||
mapView.onPause();
|
||||
mapView.onStop();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
private static class OfflineRegionMetadataAdapter extends BaseAdapter {
|
||||
|
||||
private Context context;
|
||||
private List<OfflineRegion> offlineRegions;
|
||||
|
||||
OfflineRegionMetadataAdapter(Context ctx) {
|
||||
context = ctx;
|
||||
offlineRegions = new ArrayList<>();
|
||||
}
|
||||
|
||||
void setOfflineRegions(List<OfflineRegion> offlineRegions) {
|
||||
this.offlineRegions = offlineRegions;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return offlineRegions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflineRegion getItem(int position) {
|
||||
return offlineRegions.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
holder = new ViewHolder();
|
||||
convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
|
||||
holder.text = (TextView) convertView.findViewById(android.R.id.text1);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
holder.text.setText(OfflineUtils.convertRegionName(getItem(position).getMetadata()));
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.offline
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mapbox.mapboxsdk.maps.MapView
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager.ListOfflineRegionsCallback
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion
|
||||
import com.mapbox.mapboxsdk.offline.OfflineRegion.OfflineRegionUpdateMetadataCallback
|
||||
import com.mapbox.mapboxsdk.testapp.R
|
||||
import com.mapbox.mapboxsdk.testapp.activity.offline.UpdateMetadataActivity.OfflineRegionMetadataAdapter
|
||||
import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Test activity showing integration of updating metadata of an OfflineRegion.
|
||||
*/
|
||||
class UpdateMetadataActivity :
|
||||
AppCompatActivity(),
|
||||
AdapterView.OnItemClickListener,
|
||||
AdapterView.OnItemLongClickListener {
|
||||
private var adapter: OfflineRegionMetadataAdapter? = null
|
||||
private var mapView: MapView? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_metadata_update)
|
||||
val listView = findViewById<ListView>(R.id.listView)
|
||||
listView.adapter = OfflineRegionMetadataAdapter(this).also { adapter = it }
|
||||
listView.emptyView = findViewById(android.R.id.empty)
|
||||
listView.onItemClickListener = this
|
||||
listView.onItemLongClickListener = this
|
||||
}
|
||||
|
||||
override fun onItemClick(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
val region = adapter!!.getItem(position)
|
||||
val metadata = OfflineUtils.convertRegionName(region.metadata)
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle("Rename metadata")
|
||||
val input = EditText(this)
|
||||
input.setText(metadata)
|
||||
input.inputType = InputType.TYPE_CLASS_TEXT
|
||||
if (metadata != null) {
|
||||
input.setSelection(metadata.length)
|
||||
}
|
||||
builder.setView(input)
|
||||
builder.setPositiveButton(
|
||||
"OK"
|
||||
) { dialog: DialogInterface?, which: Int ->
|
||||
updateMetadata(
|
||||
region,
|
||||
OfflineUtils.convertRegionName(input.text.toString())
|
||||
)
|
||||
}
|
||||
builder.setNegativeButton("Cancel") { dialog: DialogInterface, which: Int -> dialog.cancel() }
|
||||
builder.show()
|
||||
}
|
||||
|
||||
override fun onItemLongClick(
|
||||
parent: AdapterView<*>?,
|
||||
view: View,
|
||||
position: Int,
|
||||
id: Long
|
||||
): Boolean {
|
||||
val container = findViewById<ViewGroup>(R.id.container)
|
||||
container.removeAllViews()
|
||||
container.addView(MapView(view.context).also { mapView = it })
|
||||
mapView!!.onCreate(null)
|
||||
mapView!!.getMapAsync { map: MapboxMap ->
|
||||
map.setOfflineRegionDefinition(
|
||||
adapter!!.getItem(position).definition
|
||||
)
|
||||
}
|
||||
mapView!!.onStart()
|
||||
mapView!!.onResume()
|
||||
return true
|
||||
}
|
||||
|
||||
private fun updateMetadata(region: OfflineRegion, metadata: ByteArray) {
|
||||
region.updateMetadata(
|
||||
metadata,
|
||||
object : OfflineRegionUpdateMetadataCallback {
|
||||
override fun onUpdate(metadata: ByteArray) {
|
||||
adapter!!.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Toast.makeText(
|
||||
this@UpdateMetadataActivity,
|
||||
"Region metadata update failed with $error",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
loadOfflineRegions()
|
||||
}
|
||||
|
||||
private fun loadOfflineRegions() {
|
||||
OfflineManager.getInstance(this).listOfflineRegions(object : ListOfflineRegionsCallback {
|
||||
override fun onList(offlineRegions: Array<OfflineRegion>) {
|
||||
if (offlineRegions != null && offlineRegions.size > 0) {
|
||||
adapter!!.setOfflineRegions(Arrays.asList(*offlineRegions))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Toast.makeText(
|
||||
this@UpdateMetadataActivity,
|
||||
"Error loading regions $error",
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mapView != null) {
|
||||
mapView!!.onPause()
|
||||
mapView!!.onStop()
|
||||
mapView!!.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
private class OfflineRegionMetadataAdapter internal constructor(private val context: Context) :
|
||||
BaseAdapter() {
|
||||
private var offlineRegions: List<OfflineRegion>
|
||||
fun setOfflineRegions(offlineRegions: List<OfflineRegion>) {
|
||||
this.offlineRegions = offlineRegions
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return offlineRegions.size
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): OfflineRegion {
|
||||
return offlineRegions[position]
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return position.toLong()
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
|
||||
var convertView = convertView
|
||||
val holder: ViewHolder
|
||||
if (convertView == null) {
|
||||
holder = ViewHolder()
|
||||
convertView = LayoutInflater.from(context)
|
||||
.inflate(android.R.layout.simple_list_item_1, parent, false)
|
||||
holder.text = convertView.findViewById<View>(android.R.id.text1) as TextView
|
||||
convertView.tag = holder
|
||||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
holder.text!!.text = OfflineUtils.convertRegionName(getItem(position).metadata)
|
||||
return convertView
|
||||
}
|
||||
|
||||
internal class ViewHolder {
|
||||
var text: TextView? = null
|
||||
}
|
||||
|
||||
init {
|
||||
offlineRegions = ArrayList()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,369 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.Gravity;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Activity that generates map snapshots based on the node render test suite.
|
||||
*/
|
||||
public class RenderTestActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TEST_BASE_PATH = "integration";
|
||||
private static final String RENDER_TEST_BASE_PATH = TEST_BASE_PATH + "/render-tests";
|
||||
|
||||
// We additionally read out excluded tests from `/platform/node/test/ignore.json`
|
||||
private static final List<String> EXCLUDED_TESTS = new ArrayList<String>() {
|
||||
{
|
||||
add("overlay,background-opacity");
|
||||
add("collision-lines-pitched,debug");
|
||||
add("1024-circle,extent");
|
||||
add("empty,empty");
|
||||
add("rotation-alignment-map,icon-pitch-scaling");
|
||||
add("rotation-alignment-viewport,icon-pitch-scaling");
|
||||
add("pitch15,line-pitch");
|
||||
add("pitch30,line-pitch");
|
||||
add("line-placement-true-pitched,text-keep-upright");
|
||||
add("180,raster-rotation");
|
||||
add("45,raster-rotation");
|
||||
add("90,raster-rotation");
|
||||
add("overlapping,raster-masking");
|
||||
add("missing,raster-loading");
|
||||
add("pitchAndBearing,line-pitch");
|
||||
add("overdraw,sparse-tileset");
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<RenderTestDefinition, Bitmap> renderResultMap = new HashMap<>();
|
||||
private List<RenderTestDefinition> renderTestDefinitions;
|
||||
private OnRenderTestCompletionListener onRenderTestCompletionListener;
|
||||
private MapSnapshotter mapSnapshotter;
|
||||
private ImageView imageView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(imageView = new ImageView(RenderTestActivity.this));
|
||||
imageView.setLayoutParams(new FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (mapSnapshotter != null) {
|
||||
mapSnapshotter.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loads the ignore tests from assets folder
|
||||
//
|
||||
private static class LoadRenderIgnoreTask extends AsyncTask<Void, Void, List<String>> {
|
||||
|
||||
private WeakReference<RenderTestActivity> renderTestActivityWeakReference;
|
||||
|
||||
LoadRenderIgnoreTask(RenderTestActivity renderTestActivity) {
|
||||
this.renderTestActivityWeakReference = new WeakReference<>(renderTestActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> doInBackground(Void... voids) {
|
||||
return loadIgnoreList(renderTestActivityWeakReference.get().getAssets());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<String> strings) {
|
||||
super.onPostExecute(strings);
|
||||
if (renderTestActivityWeakReference.get() != null) {
|
||||
renderTestActivityWeakReference.get().onLoadIgnoreList(strings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Loads the render test definitions from assets folder
|
||||
//
|
||||
private static class LoadRenderDefinitionTask extends AsyncTask<Void, Void, List<RenderTestDefinition>> {
|
||||
|
||||
private WeakReference<RenderTestActivity> renderTestActivityWeakReference;
|
||||
|
||||
LoadRenderDefinitionTask(RenderTestActivity renderTestActivity) {
|
||||
this.renderTestActivityWeakReference = new WeakReference<>(renderTestActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RenderTestDefinition> doInBackground(Void... voids) {
|
||||
List<RenderTestDefinition> definitions = new ArrayList<>();
|
||||
AssetManager assetManager = renderTestActivityWeakReference.get().getAssets();
|
||||
String[] categories = new String[0];
|
||||
try {
|
||||
categories = assetManager.list(RENDER_TEST_BASE_PATH);
|
||||
} catch (IOException exception) {
|
||||
Timber.e(exception);
|
||||
}
|
||||
for (int counter = categories.length - 1; counter >= 0; counter--) {
|
||||
try {
|
||||
String[] tests = assetManager.list(String.format("%s/%s", RENDER_TEST_BASE_PATH, categories[counter]));
|
||||
for (String test : tests) {
|
||||
String styleJson = loadStyleJson(assetManager, categories[counter], test);
|
||||
RenderTestStyleDefinition renderTestStyleDefinition = new Gson()
|
||||
.fromJson(styleJson, RenderTestStyleDefinition.class);
|
||||
RenderTestDefinition definition = new RenderTestDefinition(
|
||||
categories[counter], test, styleJson, renderTestStyleDefinition);
|
||||
if (!definition.hasOperations()) {
|
||||
if (!EXCLUDED_TESTS.contains(definition.getName() + "," + definition.getCategory())) {
|
||||
definitions.add(definition);
|
||||
}
|
||||
} else {
|
||||
Timber.e("could not add test, test requires operations: %s from %s", test, categories[counter]);
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
Timber.e(exception);
|
||||
}
|
||||
}
|
||||
return definitions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<RenderTestDefinition> renderTestDefinitions) {
|
||||
super.onPostExecute(renderTestDefinitions);
|
||||
RenderTestActivity renderTestActivity = renderTestActivityWeakReference.get();
|
||||
if (renderTestActivity != null) {
|
||||
renderTestActivity.startRenderTests(renderTestDefinitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> loadIgnoreList(AssetManager assets) {
|
||||
List<String> ignores = new ArrayList<>();
|
||||
try (InputStream input = assets.open(String.format("%s/ignores.json", TEST_BASE_PATH))) {
|
||||
BufferedSource source = Okio.buffer(Okio.source(input));
|
||||
String styleJson = source.readByteString().string(Charset.forName("utf-8"));
|
||||
JsonObject object = new Gson().fromJson(styleJson, JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> stringJsonElementEntry : object.entrySet()) {
|
||||
String[] parts = stringJsonElementEntry.getKey().split("/");
|
||||
ignores.add(String.format("%s,%s", parts[2], parts[1]));
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
Timber.e(exception);
|
||||
}
|
||||
return ignores;
|
||||
}
|
||||
|
||||
private static String loadStyleJson(AssetManager assets, String category, String test) {
|
||||
String styleJson = null;
|
||||
try (InputStream input = assets.open(String.format("%s/%s/%s/style.json", RENDER_TEST_BASE_PATH, category, test))) {
|
||||
BufferedSource source = Okio.buffer(Okio.source(input));
|
||||
styleJson = source.readByteString().string(Charset.forName("utf-8"));
|
||||
} catch (IOException exception) {
|
||||
Timber.e(exception);
|
||||
}
|
||||
return styleJson;
|
||||
}
|
||||
|
||||
private void startRenderTests(List<RenderTestDefinition> renderTestDefinitions) {
|
||||
this.renderTestDefinitions = renderTestDefinitions;
|
||||
if (!renderTestDefinitions.isEmpty()) {
|
||||
render(renderTestDefinitions.get(0), renderTestDefinitions.size());
|
||||
} else {
|
||||
// no definitions, finish test without rendering
|
||||
onRenderTestCompletionListener.onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
private void render(final RenderTestDefinition renderTestDefinition, final int testSize) {
|
||||
Timber.d("Render test %s,%s", renderTestDefinition.getName(), renderTestDefinition.getCategory());
|
||||
mapSnapshotter = new RenderTestSnapshotter(this, renderTestDefinition.toOptions());
|
||||
mapSnapshotter.start(result -> {
|
||||
Bitmap snapshot = result.getBitmap();
|
||||
imageView.setImageBitmap(snapshot);
|
||||
renderResultMap.put(renderTestDefinition, snapshot);
|
||||
if (renderResultMap.size() != testSize) {
|
||||
continueTesting(renderTestDefinition);
|
||||
} else {
|
||||
finishTesting();
|
||||
}
|
||||
}, error -> Timber.e(error));
|
||||
}
|
||||
|
||||
private void continueTesting(RenderTestDefinition renderTestDefinition) {
|
||||
int next = renderTestDefinitions.indexOf(renderTestDefinition) + 1;
|
||||
Timber.d("Next test: %s / %s", next, renderTestDefinitions.size());
|
||||
render(renderTestDefinitions.get(next), renderTestDefinitions.size());
|
||||
}
|
||||
|
||||
private void finishTesting() {
|
||||
new SaveResultToDiskTask(onRenderTestCompletionListener, renderResultMap).execute();
|
||||
}
|
||||
|
||||
//
|
||||
// Save tests results to disk
|
||||
//
|
||||
private static class SaveResultToDiskTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private OnRenderTestCompletionListener onRenderTestCompletionListener;
|
||||
private Map<RenderTestDefinition, Bitmap> renderResultMap;
|
||||
|
||||
SaveResultToDiskTask(OnRenderTestCompletionListener onRenderTestCompletionListener,
|
||||
Map<RenderTestDefinition, Bitmap> renderResultMap) {
|
||||
this.onRenderTestCompletionListener = onRenderTestCompletionListener;
|
||||
this.renderResultMap = renderResultMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
if (isExternalStorageWritable()) {
|
||||
try {
|
||||
File testResultDir = FileUtils.createTestResultRootFolder();
|
||||
String basePath = testResultDir.getAbsolutePath();
|
||||
for (Map.Entry<RenderTestDefinition, Bitmap> testResult : renderResultMap.entrySet()) {
|
||||
writeResultToDisk(basePath, testResult);
|
||||
}
|
||||
} catch (final Exception exception) {
|
||||
Timber.e(exception);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void writeResultToDisk(String path, Map.Entry<RenderTestDefinition, Bitmap> result) {
|
||||
RenderTestDefinition definition = result.getKey();
|
||||
String categoryName = definition.getCategory();
|
||||
String categoryPath = String.format("%s/%s", path, categoryName);
|
||||
FileUtils.createCategoryDirectory(categoryPath);
|
||||
String testName = result.getKey().getName();
|
||||
String testDir = FileUtils.createTestDirectory(categoryPath, testName);
|
||||
FileUtils.writeTestResultToDisk(testDir, result.getValue());
|
||||
}
|
||||
|
||||
private boolean isExternalStorageWritable() {
|
||||
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
super.onPostExecute(aVoid);
|
||||
if (onRenderTestCompletionListener != null) {
|
||||
onRenderTestCompletionListener.onFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Callback configuration to notify test executor of test finishing
|
||||
//
|
||||
public interface OnRenderTestCompletionListener {
|
||||
void onFinish();
|
||||
}
|
||||
|
||||
public void setOnRenderTestCompletionListener(OnRenderTestCompletionListener listener) {
|
||||
this.onRenderTestCompletionListener = listener;
|
||||
new LoadRenderIgnoreTask(this).execute();
|
||||
}
|
||||
|
||||
public void onLoadIgnoreList(List<String> ignoreList) {
|
||||
Timber.e("We loaded %s of tests to be ignored", ignoreList.size());
|
||||
EXCLUDED_TESTS.addAll(ignoreList);
|
||||
new LoadRenderDefinitionTask(this).execute();
|
||||
}
|
||||
|
||||
//
|
||||
// FileUtils
|
||||
//
|
||||
|
||||
private static class FileUtils {
|
||||
|
||||
private static void createCategoryDirectory(String catPath) {
|
||||
File testResultDir = new File(catPath);
|
||||
if (testResultDir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!testResultDir.mkdirs()) {
|
||||
throw new RuntimeException("can't create root test directory");
|
||||
}
|
||||
}
|
||||
|
||||
private static File createTestResultRootFolder() {
|
||||
File testResultDir = new File(Environment.getExternalStorageDirectory()
|
||||
+ File.separator + "mapbox" + File.separator + "render");
|
||||
if (testResultDir.exists()) {
|
||||
// cleanup old files
|
||||
deleteRecursive(testResultDir);
|
||||
}
|
||||
|
||||
if (!testResultDir.mkdirs()) {
|
||||
throw new RuntimeException("can't create root test directory");
|
||||
}
|
||||
return testResultDir;
|
||||
}
|
||||
|
||||
private static void deleteRecursive(File fileOrDirectory) {
|
||||
if (fileOrDirectory.isDirectory()) {
|
||||
File[] files = fileOrDirectory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
deleteRecursive(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileOrDirectory.delete()) {
|
||||
Timber.e("can't delete directory");
|
||||
}
|
||||
}
|
||||
|
||||
private static String createTestDirectory(String basePath, String testName) {
|
||||
File testDir = new File(basePath + "/" + testName);
|
||||
if (!testDir.exists()) {
|
||||
if (!testDir.mkdir()) {
|
||||
throw new RuntimeException("can't create sub directory for " + testName);
|
||||
}
|
||||
}
|
||||
return testDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
private static void writeTestResultToDisk(String testPath, Bitmap testResult) {
|
||||
String filePath = testPath + "/actual.png";
|
||||
try (FileOutputStream out = new FileOutputStream(filePath)) {
|
||||
testResult.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
} catch (IOException exception) {
|
||||
Timber.e(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render
|
||||
|
||||
import android.content.res.AssetManager
|
||||
import android.graphics.Bitmap
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshot
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter
|
||||
import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity.LoadRenderDefinitionTask
|
||||
import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity.LoadRenderIgnoreTask
|
||||
import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity.OnRenderTestCompletionListener
|
||||
import com.mapbox.mapboxsdk.testapp.activity.render.RenderTestActivity.SaveResultToDiskTask
|
||||
import okio.Okio
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.lang.Exception
|
||||
import java.lang.RuntimeException
|
||||
import java.lang.ref.WeakReference
|
||||
import java.nio.charset.Charset
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
|
||||
/**
|
||||
* Activity that generates map snapshots based on the node render test suite.
|
||||
*/
|
||||
class RenderTestActivity : AppCompatActivity() {
|
||||
private val renderResultMap: MutableMap<RenderTestDefinition, Bitmap> = HashMap()
|
||||
private var renderTestDefinitions: List<RenderTestDefinition>? = null
|
||||
private var onRenderTestCompletionListener: OnRenderTestCompletionListener? = null
|
||||
private lateinit var mapSnapshotter: MapSnapshotter
|
||||
private var imageView: ImageView? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(ImageView(this@RenderTestActivity).also { imageView = it })
|
||||
imageView!!.layoutParams = FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
Gravity.CENTER
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
if (mapSnapshotter != null) {
|
||||
mapSnapshotter!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loads the ignore tests from assets folder
|
||||
//
|
||||
private class LoadRenderIgnoreTask internal constructor(renderTestActivity: RenderTestActivity?) :
|
||||
AsyncTask<Void?, Void?, List<String>>() {
|
||||
private val renderTestActivityWeakReference: WeakReference<RenderTestActivity?>
|
||||
protected override fun doInBackground(vararg p0: Void?): List<String>? {
|
||||
return loadIgnoreList(
|
||||
renderTestActivityWeakReference.get()!!.assets
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPostExecute(strings: List<String>) {
|
||||
super.onPostExecute(strings)
|
||||
if (renderTestActivityWeakReference.get() != null) {
|
||||
renderTestActivityWeakReference.get()!!.onLoadIgnoreList(strings)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
renderTestActivityWeakReference = WeakReference(renderTestActivity)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loads the render test definitions from assets folder
|
||||
//
|
||||
private class LoadRenderDefinitionTask internal constructor(renderTestActivity: RenderTestActivity) :
|
||||
AsyncTask<Void?, Void?, List<RenderTestDefinition>>() {
|
||||
private val renderTestActivityWeakReference: WeakReference<RenderTestActivity>
|
||||
protected override fun doInBackground(vararg p0: Void?): List<RenderTestDefinition>? {
|
||||
val definitions: MutableList<RenderTestDefinition> = ArrayList()
|
||||
val assetManager = renderTestActivityWeakReference.get()!!.assets
|
||||
var categories = arrayOfNulls<String>(0)
|
||||
try {
|
||||
categories = assetManager.list(RENDER_TEST_BASE_PATH)
|
||||
} catch (exception: IOException) {
|
||||
Timber.e(exception)
|
||||
}
|
||||
for (counter in categories.indices.reversed()) {
|
||||
try {
|
||||
val tests = assetManager.list(
|
||||
String.format(
|
||||
"%s/%s",
|
||||
RENDER_TEST_BASE_PATH,
|
||||
categories[counter]
|
||||
)
|
||||
)
|
||||
for (test in tests) {
|
||||
val styleJson = loadStyleJson(assetManager, categories[counter], test)
|
||||
val renderTestStyleDefinition = Gson()
|
||||
.fromJson(styleJson, RenderTestStyleDefinition::class.java)
|
||||
val definition = RenderTestDefinition(
|
||||
categories[counter],
|
||||
test,
|
||||
styleJson,
|
||||
renderTestStyleDefinition
|
||||
)
|
||||
if (!definition.hasOperations()) {
|
||||
if (!EXCLUDED_TESTS.contains(definition.name + "," + definition.category)) {
|
||||
definitions.add(definition)
|
||||
}
|
||||
} else {
|
||||
Timber.e(
|
||||
"could not add test, test requires operations: %s from %s",
|
||||
test,
|
||||
categories[counter]
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
Timber.e(exception)
|
||||
}
|
||||
}
|
||||
return definitions
|
||||
}
|
||||
|
||||
override fun onPostExecute(renderTestDefinitions: List<RenderTestDefinition>) {
|
||||
super.onPostExecute(renderTestDefinitions)
|
||||
val renderTestActivity = renderTestActivityWeakReference.get()
|
||||
renderTestActivity?.startRenderTests(renderTestDefinitions)
|
||||
}
|
||||
|
||||
init {
|
||||
renderTestActivityWeakReference = WeakReference(renderTestActivity)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startRenderTests(renderTestDefinitions: List<RenderTestDefinition>) {
|
||||
this.renderTestDefinitions = renderTestDefinitions
|
||||
if (!renderTestDefinitions.isEmpty()) {
|
||||
render(renderTestDefinitions[0], renderTestDefinitions.size)
|
||||
} else {
|
||||
// no definitions, finish test without rendering
|
||||
onRenderTestCompletionListener!!.onFinish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun render(renderTestDefinition: RenderTestDefinition, testSize: Int) {
|
||||
Timber.d("Render test %s,%s", renderTestDefinition.name, renderTestDefinition.category)
|
||||
mapSnapshotter = RenderTestSnapshotter(this, renderTestDefinition.toOptions())
|
||||
mapSnapshotter.start(
|
||||
MapSnapshotter.SnapshotReadyCallback { result: MapSnapshot ->
|
||||
val snapshot = result.bitmap
|
||||
imageView!!.setImageBitmap(snapshot)
|
||||
renderResultMap[renderTestDefinition] = snapshot
|
||||
if (renderResultMap.size != testSize) {
|
||||
continueTesting(renderTestDefinition)
|
||||
} else {
|
||||
finishTesting()
|
||||
}
|
||||
},
|
||||
MapSnapshotter.ErrorHandler { error: String? -> Timber.e(error) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun continueTesting(renderTestDefinition: RenderTestDefinition) {
|
||||
val next = renderTestDefinitions!!.indexOf(renderTestDefinition) + 1
|
||||
Timber.d("Next test: %s / %s", next, renderTestDefinitions!!.size)
|
||||
render(renderTestDefinitions!![next], renderTestDefinitions!!.size)
|
||||
}
|
||||
|
||||
private fun finishTesting() {
|
||||
SaveResultToDiskTask(onRenderTestCompletionListener, renderResultMap).execute()
|
||||
}
|
||||
|
||||
//
|
||||
// Save tests results to disk
|
||||
//
|
||||
private class SaveResultToDiskTask internal constructor(
|
||||
private val onRenderTestCompletionListener: OnRenderTestCompletionListener?,
|
||||
private val renderResultMap: Map<RenderTestDefinition, Bitmap>
|
||||
) : AsyncTask<Void?, Void?, Void?>() {
|
||||
protected override fun doInBackground(vararg p0: Void?): Void? {
|
||||
if (isExternalStorageWritable) {
|
||||
try {
|
||||
val testResultDir = FileUtils.createTestResultRootFolder()
|
||||
val basePath = testResultDir.absolutePath
|
||||
for (testResult in renderResultMap.entries) {
|
||||
writeResultToDisk(basePath, testResult)
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
Timber.e(exception)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun writeResultToDisk(
|
||||
path: String,
|
||||
result: Map.Entry<RenderTestDefinition, Bitmap>
|
||||
) {
|
||||
val definition = result.key
|
||||
val categoryName = definition.category
|
||||
val categoryPath = String.format("%s/%s", path, categoryName)
|
||||
FileUtils.createCategoryDirectory(categoryPath)
|
||||
val testName = result.key.name
|
||||
val testDir = FileUtils.createTestDirectory(categoryPath, testName)
|
||||
FileUtils.writeTestResultToDisk(testDir, result.value)
|
||||
}
|
||||
|
||||
private val isExternalStorageWritable: Boolean
|
||||
private get() = Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()
|
||||
|
||||
override fun onPostExecute(aVoid: Void?) {
|
||||
super.onPostExecute(aVoid)
|
||||
onRenderTestCompletionListener?.onFinish()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Callback configuration to notify test executor of test finishing
|
||||
//
|
||||
interface OnRenderTestCompletionListener {
|
||||
fun onFinish()
|
||||
}
|
||||
|
||||
fun setOnRenderTestCompletionListener(listener: OnRenderTestCompletionListener?) {
|
||||
onRenderTestCompletionListener = listener
|
||||
LoadRenderIgnoreTask(this).execute()
|
||||
}
|
||||
|
||||
fun onLoadIgnoreList(ignoreList: List<String>) {
|
||||
Timber.e("We loaded %s of tests to be ignored", ignoreList.size)
|
||||
EXCLUDED_TESTS.addAll(ignoreList)
|
||||
LoadRenderDefinitionTask(this).execute()
|
||||
}
|
||||
|
||||
//
|
||||
// FileUtils
|
||||
//
|
||||
private object FileUtils {
|
||||
fun createCategoryDirectory(catPath: String) {
|
||||
val testResultDir = File(catPath)
|
||||
if (testResultDir.exists()) {
|
||||
return
|
||||
}
|
||||
if (!testResultDir.mkdirs()) {
|
||||
throw RuntimeException("can't create root test directory")
|
||||
}
|
||||
}
|
||||
|
||||
fun createTestResultRootFolder(): File {
|
||||
val testResultDir = File(
|
||||
Environment.getExternalStorageDirectory()
|
||||
.toString() + File.separator + "mapbox" + File.separator + "render"
|
||||
)
|
||||
if (testResultDir.exists()) {
|
||||
// cleanup old files
|
||||
deleteRecursive(testResultDir)
|
||||
}
|
||||
if (!testResultDir.mkdirs()) {
|
||||
throw RuntimeException("can't create root test directory")
|
||||
}
|
||||
return testResultDir
|
||||
}
|
||||
|
||||
private fun deleteRecursive(fileOrDirectory: File) {
|
||||
if (fileOrDirectory.isDirectory) {
|
||||
val files = fileOrDirectory.listFiles()
|
||||
if (files != null) {
|
||||
for (file in files) {
|
||||
deleteRecursive(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fileOrDirectory.delete()) {
|
||||
Timber.e("can't delete directory")
|
||||
}
|
||||
}
|
||||
|
||||
fun createTestDirectory(basePath: String, testName: String?): String {
|
||||
val testDir = File("$basePath/$testName")
|
||||
if (!testDir.exists()) {
|
||||
if (!testDir.mkdir()) {
|
||||
throw RuntimeException("can't create sub directory for $testName")
|
||||
}
|
||||
}
|
||||
return testDir.absolutePath
|
||||
}
|
||||
|
||||
fun writeTestResultToDisk(testPath: String, testResult: Bitmap) {
|
||||
val filePath = "$testPath/actual.png"
|
||||
try {
|
||||
FileOutputStream(filePath).use { out ->
|
||||
testResult.compress(
|
||||
Bitmap.CompressFormat.PNG,
|
||||
100,
|
||||
out
|
||||
)
|
||||
}
|
||||
} catch (exception: IOException) {
|
||||
Timber.e(exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TEST_BASE_PATH = "integration"
|
||||
private const val RENDER_TEST_BASE_PATH = TEST_BASE_PATH + "/render-tests"
|
||||
|
||||
// We additionally read out excluded tests from `/platform/node/test/ignore.json`
|
||||
private val EXCLUDED_TESTS: ArrayList<String?> = object : ArrayList<String?>() {
|
||||
init {
|
||||
add("overlay,background-opacity")
|
||||
add("collision-lines-pitched,debug")
|
||||
add("1024-circle,extent")
|
||||
add("empty,empty")
|
||||
add("rotation-alignment-map,icon-pitch-scaling")
|
||||
add("rotation-alignment-viewport,icon-pitch-scaling")
|
||||
add("pitch15,line-pitch")
|
||||
add("pitch30,line-pitch")
|
||||
add("line-placement-true-pitched,text-keep-upright")
|
||||
add("180,raster-rotation")
|
||||
add("45,raster-rotation")
|
||||
add("90,raster-rotation")
|
||||
add("overlapping,raster-masking")
|
||||
add("missing,raster-loading")
|
||||
add("pitchAndBearing,line-pitch")
|
||||
add("overdraw,sparse-tileset")
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadIgnoreList(assets: AssetManager): List<String> {
|
||||
val ignores: MutableList<String> = ArrayList()
|
||||
try {
|
||||
assets.open(String.format("%s/ignores.json", TEST_BASE_PATH)).use { input ->
|
||||
val source = Okio.buffer(Okio.source(input))
|
||||
val styleJson = source.readByteString().string(Charset.forName("utf-8"))
|
||||
val `object` = Gson().fromJson(styleJson, JsonObject::class.java)
|
||||
for ((key) in `object`.entrySet()) {
|
||||
val parts = key.split("/").toTypedArray()
|
||||
ignores.add(String.format("%s,%s", parts[2], parts[1]))
|
||||
}
|
||||
}
|
||||
} catch (exception: IOException) {
|
||||
Timber.e(exception)
|
||||
}
|
||||
return ignores
|
||||
}
|
||||
|
||||
private fun loadStyleJson(assets: AssetManager, category: String?, test: String): String? {
|
||||
var styleJson: String? = null
|
||||
try {
|
||||
assets.open(
|
||||
String.format(
|
||||
"%s/%s/%s/style.json",
|
||||
RENDER_TEST_BASE_PATH,
|
||||
category,
|
||||
test
|
||||
)
|
||||
).use { input ->
|
||||
val source = Okio.buffer(Okio.source(input))
|
||||
styleJson = source.readByteString().string(Charset.forName("utf-8"))
|
||||
}
|
||||
} catch (exception: IOException) {
|
||||
Timber.e(exception)
|
||||
}
|
||||
return styleJson
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter;
|
||||
|
||||
public class RenderTestDefinition {
|
||||
|
||||
private static final int DEFAULT_WIDTH = 512;
|
||||
private static final int DEFAULT_HEIGHT = 512;
|
||||
|
||||
private String category; // eg. background-color
|
||||
private String name; // eg. colorSpace-hcl
|
||||
private String styleJson;
|
||||
private RenderTestStyleDefinition definition;
|
||||
|
||||
RenderTestDefinition(String category, String name, String styleJson, RenderTestStyleDefinition definition) {
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
this.styleJson = styleJson;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
RenderTestStyleDefinition.Test test = getTest();
|
||||
if (test != null) {
|
||||
Integer testWidth = test.getWidth();
|
||||
if (testWidth != null && testWidth > 0) {
|
||||
return testWidth;
|
||||
}
|
||||
}
|
||||
return DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
RenderTestStyleDefinition.Test test = getTest();
|
||||
if (test != null) {
|
||||
Integer testHeight = test.getHeight();
|
||||
if (testHeight != null && testHeight > 0) {
|
||||
return testHeight;
|
||||
}
|
||||
}
|
||||
return DEFAULT_HEIGHT;
|
||||
}
|
||||
|
||||
public float getPixelRatio() {
|
||||
RenderTestStyleDefinition.Test test = getTest();
|
||||
if (test != null) {
|
||||
Float pixelRatio = test.getPixelRatio();
|
||||
if (pixelRatio != null && pixelRatio > 0) {
|
||||
return pixelRatio;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getStyleJson() {
|
||||
return styleJson;
|
||||
}
|
||||
|
||||
public boolean hasOperations() {
|
||||
return getTest().getOperations() != null;
|
||||
}
|
||||
|
||||
public RenderTestStyleDefinition.Test getTest() {
|
||||
return definition.getMetadata().getTest();
|
||||
}
|
||||
|
||||
public MapSnapshotter.Options toOptions() {
|
||||
return new MapSnapshotter
|
||||
.Options(getWidth(), getHeight())
|
||||
.withStyleBuilder(new Style.Builder().fromJson(styleJson))
|
||||
.withPixelRatio(getPixelRatio())
|
||||
.withLogo(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RenderTestDefinition{"
|
||||
+ "category='" + category + '\''
|
||||
+ ", name='" + name + '\''
|
||||
+ ", styleJson='" + styleJson + '\''
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.Style
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter
|
||||
|
||||
class RenderTestDefinition internal constructor( // eg. background-color
|
||||
val category: String?, // eg. colorSpace-hcl
|
||||
val name: String,
|
||||
val styleJson: String?,
|
||||
private val definition: RenderTestStyleDefinition
|
||||
) {
|
||||
val width: Int
|
||||
get() {
|
||||
val test = test
|
||||
if (test != null) {
|
||||
val testWidth = test.width
|
||||
if (testWidth != null && testWidth > 0) {
|
||||
return testWidth
|
||||
}
|
||||
}
|
||||
return DEFAULT_WIDTH
|
||||
}
|
||||
val height: Int
|
||||
get() {
|
||||
val test = test
|
||||
if (test != null) {
|
||||
val testHeight = test.height
|
||||
if (testHeight != null && testHeight > 0) {
|
||||
return testHeight
|
||||
}
|
||||
}
|
||||
return DEFAULT_HEIGHT
|
||||
}
|
||||
val pixelRatio: Float
|
||||
get() {
|
||||
val test = test
|
||||
if (test != null) {
|
||||
val pixelRatio = test.pixelRatio
|
||||
if (pixelRatio != null && pixelRatio > 0) {
|
||||
return pixelRatio
|
||||
}
|
||||
}
|
||||
return 1F
|
||||
}
|
||||
|
||||
fun hasOperations(): Boolean {
|
||||
return test?.operations != null
|
||||
}
|
||||
|
||||
val test: RenderTestStyleDefinition.Test?
|
||||
get() = definition.metadata?.test
|
||||
|
||||
fun toOptions(): MapSnapshotter.Options {
|
||||
return MapSnapshotter.Options(width, height)
|
||||
.withStyleBuilder(Style.Builder().fromJson(styleJson!!))
|
||||
.withPixelRatio(pixelRatio)
|
||||
.withLogo(false)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return (
|
||||
"RenderTestDefinition{" +
|
||||
"category='" + category + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", styleJson='" + styleJson + '\'' +
|
||||
'}'
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_WIDTH = 512
|
||||
private const val DEFAULT_HEIGHT = 512
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshot;
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter;
|
||||
|
||||
public class RenderTestSnapshotter extends MapSnapshotter {
|
||||
|
||||
RenderTestSnapshotter(@NonNull Context context, @NonNull Options options) {
|
||||
super(context, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOverlay(MapSnapshot mapSnapshot) {
|
||||
// don't add an overlay
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render
|
||||
|
||||
import android.content.Context
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshot
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter
|
||||
|
||||
class RenderTestSnapshotter internal constructor(context: Context, options: Options) :
|
||||
MapSnapshotter(context, options) {
|
||||
override fun addOverlay(mapSnapshot: MapSnapshot) {
|
||||
// don't add an overlay
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RenderTestStyleDefinition {
|
||||
|
||||
private Integer version;
|
||||
private Metadata metadata;
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
public Integer getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Metadata getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public void setMetadata(Metadata metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
public class Metadata {
|
||||
|
||||
private Test test;
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
public Test getTest() {
|
||||
return test;
|
||||
}
|
||||
|
||||
public void setTest(Test test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public class Test {
|
||||
|
||||
private Integer width;
|
||||
private Integer height;
|
||||
private Float pixelRatio;
|
||||
private List<Integer> center = null;
|
||||
private Integer zoom;
|
||||
private Double diff;
|
||||
private List<List<String>> operations = null;
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
public Integer getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Integer getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Integer height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public Float getPixelRatio() {
|
||||
return pixelRatio;
|
||||
}
|
||||
|
||||
public List<Integer> getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
public void setCenter(List<Integer> center) {
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
public Integer getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public void setZoom(Integer zoom) {
|
||||
this.zoom = zoom;
|
||||
}
|
||||
|
||||
public Double getDiff() {
|
||||
return diff;
|
||||
}
|
||||
|
||||
public void setDiff(Double diff) {
|
||||
this.diff = diff;
|
||||
}
|
||||
|
||||
public List<List<String>> getOperations() {
|
||||
return operations;
|
||||
}
|
||||
|
||||
public void setOperations(List<List<String>> operations) {
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.render
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
class RenderTestStyleDefinition {
|
||||
var version: Int? = null
|
||||
var metadata: Metadata? = null
|
||||
private val additionalProperties: MutableMap<String, Any> = HashMap()
|
||||
fun getAdditionalProperties(): Map<String, Any> {
|
||||
return additionalProperties
|
||||
}
|
||||
|
||||
fun setAdditionalProperty(name: String, value: Any) {
|
||||
additionalProperties[name] = value
|
||||
}
|
||||
|
||||
inner class Metadata {
|
||||
var test: Test? = null
|
||||
private val additionalProperties: MutableMap<String, Any> = HashMap()
|
||||
fun getAdditionalProperties(): Map<String, Any> {
|
||||
return this.additionalProperties
|
||||
}
|
||||
|
||||
fun setAdditionalProperty(name: String, value: Any) {
|
||||
this.additionalProperties[name] = value
|
||||
}
|
||||
}
|
||||
|
||||
inner class Test {
|
||||
var width: Int? = null
|
||||
var height: Int? = null
|
||||
val pixelRatio: Float? = null
|
||||
var center: List<Int>? = null
|
||||
var zoom: Int? = null
|
||||
var diff: Double? = null
|
||||
var operations: List<List<String>>? = null
|
||||
private val additionalProperties: MutableMap<String, Any> = HashMap()
|
||||
fun getAdditionalProperties(): Map<String, Any> {
|
||||
return this.additionalProperties
|
||||
}
|
||||
|
||||
fun setAdditionalProperty(name: String, value: Any) {
|
||||
this.additionalProperties[name] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.snapshot;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.GridLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.mapbox.geojson.Feature;
|
||||
import com.mapbox.geojson.FeatureCollection;
|
||||
import com.mapbox.geojson.Point;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter;
|
||||
import com.mapbox.mapboxsdk.style.layers.Property;
|
||||
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.style.sources.RasterSource;
|
||||
import com.mapbox.mapboxsdk.style.sources.Source;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.utils.BitmapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.toBool;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAnchor;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
|
||||
|
||||
/**
|
||||
* Test activity showing how to use a the {@link com.mapbox.mapboxsdk.snapshotter.MapSnapshotter}
|
||||
*/
|
||||
public class MapSnapshotterActivity extends AppCompatActivity {
|
||||
private static final String ID_FEATURE_PROPERTY = "id";
|
||||
private static final String SELECTED_FEATURE_PROPERTY = "selected";
|
||||
private static final String TITLE_FEATURE_PROPERTY = "title";
|
||||
// layer & source constants
|
||||
private static final String MARKER_SOURCE = "marker-source";
|
||||
private static final String MARKER_LAYER = "marker-layer";
|
||||
|
||||
public GridLayout grid;
|
||||
private List<MapSnapshotter> snapshotters = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_map_snapshotter);
|
||||
|
||||
// Find the grid view and start snapshotting as soon
|
||||
// as the view is measured
|
||||
grid = findViewById(R.id.snapshot_grid);
|
||||
grid.getViewTreeObserver()
|
||||
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
//noinspection deprecation
|
||||
grid.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
addSnapshots();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addSnapshots() {
|
||||
Timber.i("Creating snapshotters");
|
||||
|
||||
for (int row = 0; row < grid.getRowCount(); row++) {
|
||||
for (int column = 0; column < grid.getColumnCount(); column++) {
|
||||
startSnapShot(row, column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startSnapShot(final int row, final int column) {
|
||||
// Optionally the style
|
||||
Style.Builder builder = new Style.Builder()
|
||||
.fromUri((column + row) % 2 == 0 ? Style.getPredefinedStyle("Streets") : Style.getPredefinedStyle("Pastel"));
|
||||
|
||||
// Define the dimensions
|
||||
MapSnapshotter.Options options = new MapSnapshotter.Options(
|
||||
grid.getMeasuredWidth() / grid.getColumnCount(),
|
||||
grid.getMeasuredHeight() / grid.getRowCount()
|
||||
)
|
||||
// Optionally the pixel ratio
|
||||
.withPixelRatio(1)
|
||||
.withLocalIdeographFontFamily(MapboxConstants.DEFAULT_FONT);
|
||||
|
||||
// Optionally the visible region
|
||||
if (row % 2 == 0) {
|
||||
options.withRegion(new LatLngBounds.Builder()
|
||||
.include(new LatLng(randomInRange(-80, 80), randomInRange(-160, 160)))
|
||||
.include(new LatLng(randomInRange(-80, 80), randomInRange(-160, 160)))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
// Optionally the camera options
|
||||
if (column % 2 == 0) {
|
||||
options.withCameraPosition(new CameraPosition.Builder()
|
||||
.target(options.getRegion() != null
|
||||
? options.getRegion().getCenter()
|
||||
: new LatLng(randomInRange(-80, 80), randomInRange(-160, 160)))
|
||||
.bearing(randomInRange(0, 360))
|
||||
.tilt(randomInRange(0, 60))
|
||||
.zoom(randomInRange(0, 10))
|
||||
.padding(1, 1, 1, 1)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
if (row == 0 && column == 0) {
|
||||
// Add a source
|
||||
Source source = new RasterSource("my-raster-source", "maptiler://sources/satellite", 512);
|
||||
builder.withLayerAbove(
|
||||
new RasterLayer("satellite-layer", "my-raster-source"),
|
||||
(column + row) % 2 == 0 ? "country_1" : "country_label");
|
||||
builder.withSource(source);
|
||||
} else if (row == 0 && column == 2) {
|
||||
|
||||
Bitmap carBitmap = BitmapUtils.getBitmapFromDrawable(
|
||||
getResources().getDrawable(R.drawable.ic_directions_car_black));
|
||||
|
||||
// marker source
|
||||
FeatureCollection markerCollection = FeatureCollection.fromFeatures(new Feature[] {
|
||||
Feature.fromGeometry(Point.fromLngLat(4.91638, 52.35673), featureProperties("1", "Android")),
|
||||
Feature.fromGeometry(Point.fromLngLat(4.91638, 12.34673), featureProperties("2", "Car"))
|
||||
});
|
||||
Source markerSource = new GeoJsonSource(MARKER_SOURCE, markerCollection);
|
||||
|
||||
// marker layer
|
||||
SymbolLayer markerSymbolLayer = new SymbolLayer(MARKER_LAYER, MARKER_SOURCE)
|
||||
.withProperties(
|
||||
iconImage(get(TITLE_FEATURE_PROPERTY)),
|
||||
iconIgnorePlacement(true),
|
||||
iconAllowOverlap(true),
|
||||
iconSize(switchCase(toBool(get(SELECTED_FEATURE_PROPERTY)), literal(1.5f), literal(1.0f))),
|
||||
iconAnchor(Property.ICON_ANCHOR_BOTTOM),
|
||||
iconColor(Color.BLUE)
|
||||
);
|
||||
|
||||
builder.withImage("Car", Objects.requireNonNull(carBitmap), false)
|
||||
.withSources(markerSource)
|
||||
.withLayers(markerSymbolLayer);
|
||||
options
|
||||
.withRegion(null)
|
||||
.withCameraPosition(new CameraPosition.Builder()
|
||||
.target(new LatLng(5.537109374999999,
|
||||
52.07950600379697))
|
||||
.zoom(1)
|
||||
.padding(1, 1, 1, 1)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
options.withStyleBuilder(builder);
|
||||
MapSnapshotter snapshotter = new MapSnapshotter(MapSnapshotterActivity.this, options);
|
||||
snapshotter.setObserver(new MapSnapshotter.Observer() {
|
||||
@Override
|
||||
public void onDidFinishLoadingStyle() {
|
||||
Timber.i("onDidFinishLoadingStyle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStyleImageMissing(String imageName) {
|
||||
Bitmap androidIcon = BitmapUtils.getBitmapFromDrawable(getResources().getDrawable(R.drawable.ic_android_2));
|
||||
snapshotter.addImage(imageName, androidIcon, false);
|
||||
}
|
||||
});
|
||||
|
||||
snapshotter.start(snapshot -> {
|
||||
Timber.i("Got the snapshot");
|
||||
ImageView imageView = new ImageView(MapSnapshotterActivity.this);
|
||||
imageView.setImageBitmap(snapshot.getBitmap());
|
||||
grid.addView(
|
||||
imageView,
|
||||
new GridLayout.LayoutParams(GridLayout.spec(row), GridLayout.spec(column))
|
||||
);
|
||||
});
|
||||
snapshotters.add(snapshotter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
// Make sure to stop the snapshotters on pause
|
||||
for (MapSnapshotter snapshotter : snapshotters) {
|
||||
snapshotter.cancel();
|
||||
}
|
||||
snapshotters.clear();
|
||||
}
|
||||
|
||||
private static Random random = new Random();
|
||||
|
||||
public static float randomInRange(float min, float max) {
|
||||
return (random.nextFloat() * (max - min)) + min;
|
||||
}
|
||||
|
||||
private JsonObject featureProperties(@NonNull String id, @NonNull String title) {
|
||||
JsonObject object = new JsonObject();
|
||||
object.add(ID_FEATURE_PROPERTY, new JsonPrimitive(id));
|
||||
object.add(TITLE_FEATURE_PROPERTY, new JsonPrimitive(title));
|
||||
object.add(SELECTED_FEATURE_PROPERTY, new JsonPrimitive(false));
|
||||
return object;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user