如何在Mapbox Android上向热图添加用户位置?

时间:2018-06-22 16:04:18

标签: android location mapbox heatmap

如何在Mapbox Android上将用户的位置添加到热图?我在Android上使用Mapbox,由于我认为是类行为,因此在将热图与用户位置混合时遇到问题。我尝试混合所有内容,但我只有黑屏! 我将热图代码添加到位置代码中。 当然可以,但是我不明白是什么。

package com.mapbox.mapboxandroiddemo.examples.plugins;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxandroiddemo.examples.dds.HeatmapActivity;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode;

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

import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.HeatmapLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;

import java.net.MalformedURLException;
import java.net.URL;

import timber.log.Timber;

import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.heatmapDensity;
import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate;
import static com.mapbox.mapboxsdk.style.expressions.Expression.linear;
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgb;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgba;
import static com.mapbox.mapboxsdk.style.expressions.Expression.stop;
import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
import staticcom.mapbox.mapboxsdk.style.layers.PropertyFactory.circleOpacity;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeWidth;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapIntensity;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapOpacity;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapWeight;




import java.util.List;

/**
 * Use the Location Layer plugin to easily add a device location "puck" to a Mapbox map.
 */
public class LocationPluginActivity extends AppCompatActivity implements
    OnMapReadyCallback, PermissionsListener {

  private static final String EARTHQUAKE_SOURCE_URL = "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson";
  private static final String EARTHQUAKE_SOURCE_ID = "earthquakes";
  private static final String HEATMAP_LAYER_ID = "earthquakes-heat";
  private static final String HEATMAP_LAYER_SOURCE = "earthquakes";
  private static final String CIRCLE_LAYER_ID = "earthquakes-circle";

  private PermissionsManager permissionsManager;
  private MapboxMap mapboxMap;
  private MapView mapView;





  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Mapbox access token is configured here. This needs to be called either in your application
    // object or in the same activity which contains the mapview.
    Mapbox.getInstance(this, getString(R.string.access_token));

    // This contains the MapView in XML and needs to be called after the access token is configured.
    setContentView(R.layout.activity_location_plugin);

    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(new OnMapReadyCallback() {
      @Override
      public void onMapReady(MapboxMap mapboxMap) {
        LocationPluginActivity.this.mapboxMap = mapboxMap;
        addEarthquakeSource();
        addHeatmapLayer();
        addCircleLayer();
      }
    });
  }


  private void addEarthquakeSource() {
    try {
      mapboxMap.addSource(new GeoJsonSource(EARTHQUAKE_SOURCE_ID, new URL(EARTHQUAKE_SOURCE_URL)));
    } catch (MalformedURLException malformedUrlException) {
      Timber.e(malformedUrlException, "That's not an url... ");
    }
  }

  private void addHeatmapLayer() {
    HeatmapLayer layer = new HeatmapLayer(HEATMAP_LAYER_ID, EARTHQUAKE_SOURCE_ID);
    layer.setMaxZoom(9);
    layer.setSourceLayer(HEATMAP_LAYER_SOURCE);
    layer.setProperties(

            // Color ramp for heatmap.  Domain is 0 (low) to 1 (high).
            // Begin color ramp at 0-stop with a 0-transparancy color
            // to create a blur-like effect.
            heatmapColor(
                    interpolate(
                            linear(), heatmapDensity(),
                            literal(0), rgba(33, 102, 172, 0),
                            literal(0.2), rgb(103, 169, 207),
                            literal(0.4), rgb(209, 229, 240),
                            literal(0.6), rgb(253, 219, 199),
                            literal(0.8), rgb(239, 138, 98),
                            literal(1), rgb(178, 24, 43)
                    )
            ),

            // Increase the heatmap weight based on frequency and property magnitude
            heatmapWeight(
                    interpolate(
                            linear(), get("mag"),
                            stop(0, 0),
                            stop(6, 1)
                    )
            ),

            // Increase the heatmap color weight weight by zoom level
            // heatmap-intensity is a multiplier on top of heatmap-weight
            heatmapIntensity(
                    interpolate(
                            linear(), zoom(),
                            stop(0, 1),
                            stop(9, 3)
                    )
            ),

            // Adjust the heatmap radius by zoom level
            heatmapRadius(
                    interpolate(
                            linear(), zoom(),
                            stop(0, 2),
                            stop(9, 20)
                    )
            ),

            // Transition from heatmap to circle layer by zoom level
            heatmapOpacity(
                    interpolate(
                            linear(), zoom(),
                            stop(7, 1),
                            stop(9, 0)
                    )
            )
    );

    mapboxMap.addLayerAbove(layer, "waterway-label");
  }

  private void addCircleLayer() {
    CircleLayer circleLayer = new CircleLayer(CIRCLE_LAYER_ID, EARTHQUAKE_SOURCE_ID);
    circleLayer.setProperties(

            // Size circle radius by earthquake magnitude and zoom level
            circleRadius(
                    interpolate(
                            linear(), zoom(),
                            literal(7), interpolate(
                                    linear(), get("mag"),
                                    stop(1, 1),
                                    stop(6, 4)
                            ),
                            literal(16), interpolate(
                                    linear(), get("mag"),
                                    stop(1, 5),
                                    stop(6, 50)
                            )
                    )
            ),

            // Color circle by earthquake magnitude
            circleColor(
                    interpolate(
                            linear(), get("mag"),
                            literal(1), rgba(33, 102, 172, 0),
                            literal(2), rgb(103, 169, 207),
                            literal(3), rgb(209, 229, 240),
                            literal(4), rgb(253, 219, 199),
                            literal(5), rgb(239, 138, 98),
                            literal(6), rgb(178, 24, 43)
                    )
            ),

            // Transition from heatmap to circle layer by zoom level
            circleOpacity(
                    interpolate(
                            linear(), zoom(),
                            stop(7, 0),
                            stop(8, 1)
                    )
            ),
            circleStrokeColor("white"),
            circleStrokeWidth(1.0f)
    );

    mapboxMap.addLayerBelow(circleLayer, HEATMAP_LAYER_ID);
  }


  @Override
  public void onMapReady(MapboxMap mapboxMap) {
    LocationPluginActivity.this.mapboxMap = mapboxMap;
    enableLocationPlugin();
  }

  @SuppressWarnings( {"MissingPermission"})
  private void enableLocationPlugin() {
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {

      // Create an instance of the plugin. Adding in LocationLayerOptions is also an optional
      // parameter
      LocationLayerPlugin locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap);

      // Set the plugin's camera mode
      locationLayerPlugin.setCameraMode(CameraMode.TRACKING);
      getLifecycle().addObserver(locationLayerPlugin);
    } else {
      permissionsManager = new PermissionsManager(this);
      permissionsManager.requestLocationPermissions(this);
    }
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }

  @Override
  public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
  }

  @Override
  public void onPermissionResult(boolean granted) {
    if (granted) {
      enableLocationPlugin();
    } else {
      Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
      finish();
    }
  }

  @Override
  @SuppressWarnings( {"MissingPermission"})
  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();
  }
}