Java tutorial
/* * Copyright 2014 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.maps.android.utils.demo; import android.graphics.Color; import android.text.Html; import android.text.method.LinkMovementMethod; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.TileOverlay; import com.google.android.gms.maps.model.TileOverlayOptions; import com.google.maps.android.heatmaps.Gradient; import com.google.maps.android.heatmaps.HeatmapTileProvider; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Scanner; /** * A demo of the Heatmaps library. Demonstrates how the HeatmapTileProvider can be used to create * a colored map overlay that visualises many points of weighted importance/intensity, with * different colors representing areas of high and low concentration/combined intensity of points. */ public class HeatmapsDemoActivity extends BaseDemoActivity { /** * Alternative radius for convolution */ private static final int ALT_HEATMAP_RADIUS = 10; /** * Alternative opacity of heatmap overlay */ private static final double ALT_HEATMAP_OPACITY = 0.4; /** * Alternative heatmap gradient (blue -> red) * Copied from Javascript version */ private static final int[] ALT_HEATMAP_GRADIENT_COLORS = { Color.argb(0, 0, 255, 255), // transparent Color.argb(255 / 3 * 2, 0, 255, 255), Color.rgb(0, 191, 255), Color.rgb(0, 0, 127), Color.rgb(255, 0, 0) }; public static final float[] ALT_HEATMAP_GRADIENT_START_POINTS = { 0.0f, 0.10f, 0.20f, 0.60f, 1.0f }; public static final Gradient ALT_HEATMAP_GRADIENT = new Gradient(ALT_HEATMAP_GRADIENT_COLORS, ALT_HEATMAP_GRADIENT_START_POINTS); private HeatmapTileProvider mProvider; private TileOverlay mOverlay; private boolean mDefaultGradient = true; private boolean mDefaultRadius = true; private boolean mDefaultOpacity = true; /** * Maps name of data set to data (list of LatLngs) * Also maps to the URL of the data set for attribution */ private HashMap<String, DataSet> mLists = new HashMap<String, DataSet>(); @Override protected int getLayoutId() { return R.layout.heatmaps_demo; } @Override protected void startDemo() { getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-25, 143), 4)); // Set up the spinner/dropdown list Spinner spinner = (Spinner) findViewById(R.id.spinner); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.heatmaps_datasets_array, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); spinner.setOnItemSelectedListener(new SpinnerActivity()); try { mLists.put(getString(R.string.police_stations), new DataSet(readItems(R.raw.police), getString(R.string.police_stations_url))); mLists.put(getString(R.string.medicare), new DataSet(readItems(R.raw.medicare), getString(R.string.medicare_url))); } catch (JSONException e) { Toast.makeText(this, "Problem reading list of markers.", Toast.LENGTH_LONG).show(); } // Make the handler deal with the map // Input: list of WeightedLatLngs, minimum and maximum zoom levels to calculate custom // intensity from, and the map to draw the heatmap on // radius, gradient and opacity not specified, so default are used } public void changeRadius(View view) { if (mDefaultRadius) { mProvider.setRadius(ALT_HEATMAP_RADIUS); } else { mProvider.setRadius(HeatmapTileProvider.DEFAULT_RADIUS); } mOverlay.clearTileCache(); mDefaultRadius = !mDefaultRadius; } public void changeGradient(View view) { if (mDefaultGradient) { mProvider.setGradient(ALT_HEATMAP_GRADIENT); } else { mProvider.setGradient(HeatmapTileProvider.DEFAULT_GRADIENT); } mOverlay.clearTileCache(); mDefaultGradient = !mDefaultGradient; } public void changeOpacity(View view) { if (mDefaultOpacity) { mProvider.setOpacity(ALT_HEATMAP_OPACITY); } else { mProvider.setOpacity(HeatmapTileProvider.DEFAULT_OPACITY); } mOverlay.clearTileCache(); mDefaultOpacity = !mDefaultOpacity; } // Dealing with spinner choices public class SpinnerActivity implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { String dataset = parent.getItemAtPosition(pos).toString(); TextView attribution = ((TextView) findViewById(R.id.attribution)); // Check if need to instantiate (avoid setData etc twice) if (mProvider == null) { mProvider = new HeatmapTileProvider.Builder() .data(mLists.get(getString(R.string.police_stations)).getData()).build(); mOverlay = getMap().addTileOverlay(new TileOverlayOptions().tileProvider(mProvider)); // Render links attribution.setMovementMethod(LinkMovementMethod.getInstance()); } else { mProvider.setData(mLists.get(dataset).getData()); mOverlay.clearTileCache(); } // Update attribution attribution.setText( Html.fromHtml(String.format(getString(R.string.attrib_format), mLists.get(dataset).getUrl()))); } public void onNothingSelected(AdapterView<?> parent) { // Another interface callback } } // Datasets from http://data.gov.au private ArrayList<LatLng> readItems(int resource) throws JSONException { ArrayList<LatLng> list = new ArrayList<LatLng>(); InputStream inputStream = getResources().openRawResource(resource); String json = new Scanner(inputStream).useDelimiter("\\A").next(); JSONArray array = new JSONArray(json); for (int i = 0; i < array.length(); i++) { JSONObject object = array.getJSONObject(i); double lat = object.getDouble("lat"); double lng = object.getDouble("lng"); list.add(new LatLng(lat, lng)); } return list; } /** * Helper class - stores data sets and sources. */ private class DataSet { private ArrayList<LatLng> mDataset; private String mUrl; public DataSet(ArrayList<LatLng> dataSet, String url) { this.mDataset = dataSet; this.mUrl = url; } public ArrayList<LatLng> getData() { return mDataset; } public String getUrl() { return mUrl; } } }