summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineMapDownload.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineMapDownload.java')
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineMapDownload.java409
1 files changed, 409 insertions, 0 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineMapDownload.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineMapDownload.java
new file mode 100644
index 0000000000..0ee820d401
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineMapDownload.java
@@ -0,0 +1,409 @@
+package com.mapbox.mapboxsdk.testapp.activity.offline;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+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.utils.OfflineUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import timber.log.Timber;
+
+/**
+ * Created by osanababayan on 11/28/17.
+ */
+
+public class OfflineMapDownload extends AppCompatActivity
+ implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
+
+ private EditText regionNameView;
+ private Spinner spinner;
+ private TextView minZoomView, maxZoomView;
+ private SeekBar minZoomSeekBar, maxZoomSeekBar;
+ private EditText latNorthView, latSouthView, lonEastView, lonWestView;
+ private TextView downloadProgressView;
+ private Button actionButton;
+
+ private OfflineRegion offlineRegion = null;
+ private OfflineRegionStatus status = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_offline_map_form);
+
+ initUI();
+ }
+
+ @Override
+ protected void onDestroy() {
+ cleanUI();
+
+ stopDownload();
+
+ if (offlineRegion != null) {
+ offlineRegion.setObserver(null);
+ offlineRegion = null;
+ }
+
+ super.onDestroy();
+ }
+
+ private void initUI() {
+ regionNameView = (EditText)findViewById(R.id.name);
+
+ spinner = (Spinner)findViewById(R.id.style);
+ initSpinner();
+
+ minZoomView = (TextView)findViewById(R.id.minzoom);
+ maxZoomView = (TextView)findViewById(R.id.maxzoom);
+
+ minZoomSeekBar = (SeekBar) findViewById(R.id.minzoom_slider);
+ minZoomSeekBar.setOnSeekBarChangeListener(this);
+ maxZoomSeekBar = (SeekBar) findViewById(R.id.maxzoom_slider);
+ maxZoomSeekBar.setOnSeekBarChangeListener(this);
+
+ latNorthView = (EditText)findViewById(R.id.lat_north);
+ lonEastView = (EditText)findViewById(R.id.lon_east);
+
+ latSouthView = (EditText)findViewById(R.id.lat_south);
+ lonWestView = (EditText)findViewById(R.id.lon_west);
+
+ downloadProgressView = (TextView)findViewById(R.id.download_progress);
+
+ actionButton = (Button)findViewById(R.id.action_button);
+ actionButton.setOnClickListener(this);
+
+ // Set Default values;
+ minZoomSeekBar.setProgress(0);
+ maxZoomSeekBar.setProgress(15);
+
+ // New York
+ latNorthView.setText("40.7589372691904");
+ lonEastView.setText("-73.96024123810196");
+ latSouthView.setText("40.740763489055496");
+ lonWestView.setText("-73.97569076188057");
+
+ // Berlin
+// latNorthView.setText("52.6780473464");
+// lonEastView.setText("13.7603759766");
+// latSouthView.setText("52.3305137868");
+// lonWestView.setText("13.0627441406");
+ // styleView.setText(style);
+ }
+
+ private void cleanUI() {
+ actionButton.setOnClickListener(null);
+ minZoomSeekBar.setOnSeekBarChangeListener(null);
+ maxZoomSeekBar.setOnSeekBarChangeListener(null);
+ }
+
+
+ private void initSpinner() {
+ List<String> styleList = new ArrayList<String>();
+ List<String> list = new ArrayList<String>(Arrays.asList(
+ Style.MAPBOX_STREETS,
+ Style.OUTDOORS,
+ Style.LIGHT,
+ Style.DARK,
+ Style.SATELLITE,
+ Style.SATELLITE_STREETS,
+ Style.TRAFFIC_DAY,
+ Style.TRAFFIC_NIGHT,
+ "CUSTOM"));
+
+ ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, list);
+ dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(dataAdapter);
+ }
+
+ public void onClick(View button) {
+
+ Timber.e(">>>>> complete=" +isDownloadComplete()+ " isDownloading=" +isDownloading());
+
+ if (isDownloadComplete()) {
+ // Display offline map in a new Activity
+
+ showRegion(offlineRegion);
+
+ } else if (isDownloading()) {
+ actionButton.setText("Pause download");
+ stopDownload();
+
+ } else {
+
+ actionButton.setText("Downloading...");
+ // Create offline Region and
+ // start download it once it is created
+ createOfflineRegionAndStartDownload();
+ }
+
+ }
+
+
+ public void createOfflineRegionAndStartDownload() {
+ // get data from UI
+ String regionName = regionNameView.getText().toString();
+ double latitudeNorth = Double.parseDouble(latNorthView.getText().toString());
+ double longitudeEast = Double.parseDouble(lonEastView.getText().toString());
+ double latitudeSouth = Double.parseDouble(latSouthView.getText().toString());
+ double longitudeWest = Double.parseDouble(lonWestView.getText().toString());
+
+ float pixelDensity = getResources().getDisplayMetrics().density;
+
+ String styleUrl = getStyleUrl();
+ double offlineRegionMinZoom = minZoomSeekBar.getProgress();
+ double offlineRegionMaxZoom = maxZoomSeekBar.getProgress();
+
+ // create offline definition from data
+ OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
+ styleUrl,
+ new LatLngBounds.Builder()
+ .include(new LatLng(latitudeNorth, longitudeEast))
+ .include(new LatLng(latitudeSouth, longitudeWest))
+ .build(),
+ offlineRegionMinZoom,
+ offlineRegionMaxZoom,
+ pixelDensity
+ );
+
+ Timber.e(">>>>>> Create Offline Region with minZoom=" +offlineRegionMinZoom+ " maxZoom=" +offlineRegionMaxZoom+
+ " styleUrl=" +getStyleUrl()+ " bounds=" +definition.getBounds());
+
+
+ OfflineManager.getInstance(this.getApplicationContext())
+ .createOfflineRegion(definition,
+ OfflineUtils.convertRegionName(regionName),
+ new OfflineManager.CreateOfflineRegionCallback() {
+ @Override
+ public void onCreate(OfflineRegion offlineRegion) {
+ Timber.e(">>>> Region created >>> start Download");
+ startDownLoad(offlineRegion);
+ }
+
+ @Override
+ public void onError(String error) {
+ Timber.e("Failed to create offline Region");
+ }
+ }
+ );
+ }
+
+
+ private void startDownLoad(OfflineRegion offlineRegion) {
+ if (offlineRegion != null && !isDownloading()) {
+ Timber.e(">>>> Start Download offlineRegion=" +offlineRegion);
+ this.offlineRegion = offlineRegion;
+
+ // Get observing offline region's status.
+ offlineRegion.getStatus(new OfflineRegion.OfflineRegionStatusCallback() {
+ @Override
+ public void onStatus(OfflineRegionStatus status) {
+ onDownloadStatusChanged(status);
+ }
+
+ @Override
+ public void onError(String error) {
+ Timber.e("Failed to get status");
+ }
+ });
+
+ //Start observing offline region's status
+ offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() {
+ @Override
+ public void onStatusChanged(OfflineRegionStatus status) {
+
+ // Stop downlaod !
+ if (status.isComplete()) {
+
+ stopMeasuringDownload();
+ Toast.makeText(OfflineMapDownload.this,
+ "Download is complete - turn off WiFi to Test",
+ Toast.LENGTH_SHORT)
+ .show();
+ actionButton.setText("Show Offline Region");
+ }
+
+ onDownloadStatusChanged(status);
+ }
+
+ @Override
+ public void onError(OfflineRegionError error) {
+ Timber.e("Failed to report status " +error.getMessage());
+ }
+
+ @Override
+ public void mapboxTileCountLimitExceeded(long limit) {
+
+ }
+ });
+
+ startMeasuringDownload();
+ this.offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);
+ }
+ }
+
+ private void stopDownload() {
+ if (isDownloading() && offlineRegion != null) {
+ offlineRegion.setDownloadState(OfflineRegion.STATE_INACTIVE);
+ stopMeasuringDownload();
+ }
+ }
+
+ private void showRegion(OfflineRegion region) {
+
+ OfflineTilePyramidRegionDefinition definition = (OfflineTilePyramidRegionDefinition)region.getDefinition();
+
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(SimpleMapViewActivity.BOUNDS_ARG, region.getDefinition().getBounds());
+ bundle.putString(SimpleMapViewActivity.STYLE_ARG, getStyleUrl());
+ bundle.putDouble(SimpleMapViewActivity.MINZOOM_ARG, definition.getMinZoom());
+ bundle.putDouble(SimpleMapViewActivity.MAXZOOM_ARG, definition.getMaxZoom()); // should be taken from definition
+
+ Timber.e(" >>>> SHOW StyleURl: =" + getStyleUrl());
+ Timber.e(" >>>> SHOW Bounds: =" + region.getDefinition().getBounds());
+ Timber.e(" >>>> SHOW Min ZOOM: =" + definition.getMinZoom());
+ Timber.e(" >>>> SHOW Max ZOOM: =" + definition.getMaxZoom());
+
+ Intent intent = new Intent(this, SimpleMapViewActivity.class);
+ intent.putExtras(bundle);
+ startActivity(intent);
+ }
+
+
+ String getStyleUrl() {
+ String style =(String) spinner.getSelectedItem();
+ if ("CUSTOM".equals(style)) {
+ return getResources().getString(R.string.custom_style_url);
+ }
+
+ return style;
+ }
+
+ private void onDownloadStatusChanged(OfflineRegionStatus status) {
+
+ this.status = status;
+
+ // Compute a percentage
+ final int percentage = status.getRequiredResourceCount() >= 0 ?
+ (int)(100.0 * status.getCompletedResourceCount() / status.getRequiredResourceCount()) : 0;
+ String progressStr = getSize(status.getCompletedResourceSize()) + ", " + percentage + " %";
+
+ if (status.isComplete()) {
+ progressStr += " " +TimeUnit.MILLISECONDS.toMinutes(downloadTime) + " minutes";
+ }
+ downloadProgressView.setText(progressStr);
+
+ Timber.e(String.format("REGION STATUS CHANGED: %s - %s/%s resources; %s bytes downloaded.",
+ status.isComplete() ? " COMPLETE " : (isDownloading() ? " DOWNLOADING " : " AVAILABLE"),
+ String.valueOf(status.getCompletedResourceCount()),
+ String.valueOf(status.getRequiredResourceCount()),
+ String.valueOf(status.getCompletedResourceSize())));
+ }
+
+ private boolean isDownloading() {
+ return status != null && status.getDownloadState() == OfflineRegion.STATE_ACTIVE;
+ }
+
+ private boolean isDownloadComplete() {
+ return status != null && status.isComplete();
+ }
+
+ static String getSize(long size) {
+ if (size == 0) {
+ return "0 B";
+ } else if (size < 1024) {
+ return size + " B";
+ } else if (size < 1048576){
+ return size / 1024 + " KB";
+ } else {
+ return size /1048576 + " MB";
+ }
+ }
+
+ //https://en.wikipedia.org/wiki/Haversine_formula
+ static double latLongToMeters(LatLngBounds bounds) {
+ double lat1 = bounds.getLatNorth();
+ double lon1 = bounds.getLonEast();
+ double lat2 = bounds.getLatSouth();
+ double lon2 = bounds.getLonWest();
+
+ double R = 6378.137; // Radius of earth in KM
+ double dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
+ double dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
+ double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
+ Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
+ Math.sin(dLon/2) * Math.sin(dLon/2);
+ double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+ double d = R * c;
+ return d * 1000; // meters
+ }
+
+
+ private long startTime = 0;
+ private long downloadTime = 0;
+
+ private long getDownloadTime() {
+ if (startTime > 0) {
+ downloadTime = startTime - System.currentTimeMillis();
+ }
+ return downloadTime;
+ }
+
+
+ private void startMeasuringDownload() {
+ startTime = System.currentTimeMillis();
+ }
+
+ private void stopMeasuringDownload() {
+ downloadTime = startTime - System.currentTimeMillis();
+
+ Timber.e(" >>>>> It took " + TimeUnit.MILLISECONDS.toMinutes(downloadTime) + " minutes to load " +
+ getSize(status.getCompletedResourceSize()) + " the map of " +
+ OfflineUtils.convertRegionName(offlineRegion.getMetadata()) );
+
+ startTime = 0;
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ if (seekBar == minZoomSeekBar) {
+ minZoomView.setText(String.valueOf(i));
+ } else {
+ maxZoomView.setText(String.valueOf(i));
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+}