Migrate examples in android TestApp to Kotlin (#416)

This commit is contained in:
Birk Skyum
2022-09-09 14:04:13 +02:00
committed by GitHub
parent bd2c4e2edf
commit 3e98f60efa
172 changed files with 13887 additions and 14599 deletions

View File

@@ -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">

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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"
}
}

View File

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

View File

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

View File

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

View File

@@ -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"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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"
}
}

View File

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

View File

@@ -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"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 + '\''
+ '}';
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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