ローカルJSONデータをベクタータイルジオメトリと統合
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:mapbox="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.mapbox.mapboxandroiddemo.examples.dds.ChoroplethJsonVectorMixActivity"> <com.mapbox.mapboxsdk.maps.MapViewandroid:id="@+id/mapView"android:layout_width="match_parent"android:layout_height="match_parent"mapbox:mapbox_cameraTargetLat="38.00312"mapbox:mapbox_cameraTargetLng="-98.398423"mapbox:mapbox_cameraZoom="1"/> </FrameLayout>
ChoroplethJsonVectorMixActivity.java
package com.mapbox.mapboxandroiddemo.examples.dds; import android.os.AsyncTask;import android.os.Bundle;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.appcompat.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.maps.Style;import com.mapbox.mapboxsdk.style.expressions.Expression;import com.mapbox.mapboxsdk.style.layers.FillLayer;import com.mapbox.mapboxsdk.style.sources.VectorSource; import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject; import java.io.InputStream;import java.lang.ref.WeakReference;import java.util.Scanner; import timber.log.Timber; import static com.mapbox.mapboxsdk.style.expressions.Expression.get;import static com.mapbox.mapboxsdk.style.expressions.Expression.match;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.toNumber;import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor; /*** Style a choropleth map by merging local JSON data with vector tile geometries*/public class ChoroplethJsonVectorMixActivity extends AppCompatActivity implements OnMapReadyCallback { private static final String STATE_UNEMPLOYMENT_INFO_JSON_FILE = "state_unemployment_info.json";private static final String VECTOR_SOURCE_NAME = "states";private static final String DATA_MATCH_PROP = "STATE_ID";private static final String DATA_STYLE_UNEMPLOYMENT_PROP = "unemployment"; private MapView mapView;private MapboxMap mapboxMap;private JSONArray statesArray; @Overrideprotected 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 account managersetContentView(R.layout.activity_choropleth_json_vector_mix); mapView = findViewById(R.id.mapView);mapView.onCreate(savedInstanceState);mapView.getMapAsync(this);} @Overridepublic void onMapReady(@NonNull final MapboxMap map) { this.mapboxMap = map;map.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {@Overridepublic void onStyleLoaded(@NonNull Style style) { // Add Mapbox-hosted vector source for state polygonsstyle.addSource(new VectorSource(VECTOR_SOURCE_NAME, "mapbox://mapbox.us_census_states_2015")); new LoadJson(ChoroplethJsonVectorMixActivity.this).execute();}});} /*** Create layer from the vector tile source with data-driven style** @param stops the array of stops to use in the FillLayer*/private void addDataToMap(@NonNull Expression.Stop[] stops) { FillLayer statesJoinLayer = new FillLayer("states-join", VECTOR_SOURCE_NAME);statesJoinLayer.setSourceLayer(VECTOR_SOURCE_NAME);statesJoinLayer.withProperties(fillColor(match(toNumber(get(DATA_MATCH_PROP)),rgba(0, 0, 0, 1), stops))); // Add layer to map below the "waterway-label" layerif (mapboxMap != null) {mapboxMap.getStyle(style -> style.addLayerAbove(statesJoinLayer, "waterway-label"));}} private static class LoadJson extends AsyncTask<Void, Void, Expression.Stop[]> { private WeakReference<ChoroplethJsonVectorMixActivity> weakReference;private static final String TAG = "ChJSonVectorMix"; LoadJson(ChoroplethJsonVectorMixActivity activity) {this.weakReference = new WeakReference<>(activity);} @Overrideprotected Expression.Stop[] doInBackground(Void... voids) {try {ChoroplethJsonVectorMixActivity activity = weakReference.get();if (activity != null) { InputStream inputStream = activity.getAssets().open(STATE_UNEMPLOYMENT_INFO_JSON_FILE); activity.statesArray = new JSONArray(convertStreamToString(inputStream)); // Create stops arrayExpression.Stop[] stops = new Expression.Stop[activity.statesArray.length()]; for (int x = 0; x < activity.statesArray.length(); x++) {try {// Generate green color value for each state/stopJSONObject singleState = activity.statesArray.getJSONObject(x);double green = singleState.getDouble(DATA_STYLE_UNEMPLOYMENT_PROP) / 14 * 255; // Add new stop to array of stopsstops[x] = stop(Double.parseDouble(singleState.getString(DATA_MATCH_PROP)),rgba(0, green, 0, 1)); } catch (JSONException exception) {throw new RuntimeException(exception);}} return stops;}} catch (Exception exception) {Timber.d("Exception Loading GeoJSON: %s", exception.toString());}return null;} static String convertStreamToString(InputStream is) {Scanner scanner = new Scanner(is).useDelimiter("\\A");return scanner.hasNext() ? scanner.next() : "";} @Overrideprotected void onPostExecute(@Nullable Expression.Stop[] stopsArray) {super.onPostExecute(stopsArray);ChoroplethJsonVectorMixActivity activity = weakReference.get();if (activity != null && stopsArray != null) {activity.addDataToMap(stopsArray);}}} @Overrideprotected void onStart() {super.onStart();mapView.onStart();} @Overridepublic void onResume() {super.onResume();mapView.onResume();} @Overridepublic void onPause() {super.onPause();mapView.onPause();} @Overrideprotected void onStop() {super.onStop();mapView.onStop();} @Overridepublic void onLowMemory() {super.onLowMemory();mapView.onLowMemory();} @Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();} @Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);}}