Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(android): add heatmap support #472

Merged
merged 6 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 2 additions & 21 deletions android/src/ti/map/CircleProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import java.util.HashMap;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.AsyncResult;
Expand Down Expand Up @@ -77,7 +76,7 @@ public boolean handleMessage(Message msg)
switch (msg.what) {
case MSG_SET_CENTER: {
result = (AsyncResult) msg.obj;
LatLng location = parseLocation(result.getArg());
LatLng location = TiMapUtils.parseLocation(result.getArg());
circle.setCenter(location);
result.setResult(null);
return true;
Expand Down Expand Up @@ -149,7 +148,7 @@ public void processOptions()
options = new CircleOptions();

if (hasProperty(MapModule.PROPERTY_CENTER)) {
options.center(parseLocation(getProperty(MapModule.PROPERTY_CENTER)));
options.center(TiMapUtils.parseLocation(getProperty(MapModule.PROPERTY_CENTER)));
}

if (hasProperty(MapModule.PROPERTY_RADIUS)) {
Expand Down Expand Up @@ -252,24 +251,6 @@ public boolean getClickable()
return clickable;
}

// A location can either be a an array of longitude, latitude pairings or
// an array of longitude, latitude objects.
// e.g. [123.33, 34.44], OR {longitude: 123.33, latitude, 34.44}
private LatLng parseLocation(Object loc)
{
LatLng location = null;
if (loc instanceof HashMap) {
HashMap<String, String> point = (HashMap<String, String>) loc;
location = new LatLng(TiConvert.toDouble(point.get(TiC.PROPERTY_LATITUDE)),
TiConvert.toDouble(point.get(TiC.PROPERTY_LONGITUDE)));
} else if (loc instanceof Object[]) {
Object[] temp = (Object[]) loc;
location = new LatLng(TiConvert.toDouble(temp[1]), TiConvert.toDouble(temp[0]));
}
// Log.w("TiApp MAP", "center lat lng " + location.latitude + ", " + location.longitude);
return location;
}

public String getApiName()
{
return "Ti.Map.Circle";
Expand Down
21 changes: 2 additions & 19 deletions android/src/ti/map/PolygonProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void processOptions()

public void addLocation(Object loc, ArrayList<LatLng> locationArray, boolean list)
{
LatLng location = parseLocation(loc);
LatLng location = TiMapUtils.parseLocation(loc);
if (list) {
locationArray.add(location);
} else {
Expand Down Expand Up @@ -195,7 +195,7 @@ public ArrayList<ArrayList<LatLng>> processHoles(Object holesList, boolean list)
if (pointsArray instanceof Object[]) {
for (int i = 0; i < pointsArray.length; i++) {
Object obj = pointsArray[i];
holeContainerArray.add(parseLocation(obj));
holeContainerArray.add(TiMapUtils.parseLocation(obj));
}
}

Expand Down Expand Up @@ -301,23 +301,6 @@ else if (name.equals(TiC.PROPERTY_TOUCH_ENABLED)) {
}
}

// A location can either be a an array of longitude, latitude pairings or
// an array of longitude, latitude objects.
// e.g. [123.33, 34.44], OR {longitude: 123.33, latitude, 34.44}
private LatLng parseLocation(Object loc)
{
LatLng location = null;
if (loc instanceof HashMap) {
HashMap<String, String> point = (HashMap<String, String>) loc;
location = new LatLng(TiConvert.toDouble(point.get(TiC.PROPERTY_LATITUDE)),
TiConvert.toDouble(point.get(TiC.PROPERTY_LONGITUDE)));
} else if (loc instanceof Object[]) {
Object[] temp = (Object[]) loc;
location = new LatLng(TiConvert.toDouble(temp[1]), TiConvert.toDouble(temp[0]));
}
return location;
}

public String getApiName()
{
return "Ti.Map.Polygon";
Expand Down
19 changes: 1 addition & 18 deletions android/src/ti/map/PolylineProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void processOptions()

public void addLocation(Object loc, ArrayList<LatLng> locationArray, boolean list)
{
LatLng location = parseLocation(loc);
LatLng location = TiMapUtils.parseLocation(loc);
if (list) {
locationArray.add(location);
} else {
Expand Down Expand Up @@ -283,23 +283,6 @@ else if (name.equals(TiC.PROPERTY_TOUCH_ENABLED)) {
}
}

// A location can either be a an array of longitude, latitude pairings or
// an array of longitude, latitude objects.
// e.g. [123.33, 34.44], OR {longitude: 123.33, latitude, 34.44}
private LatLng parseLocation(Object loc)
{
LatLng location = null;
if (loc instanceof HashMap) {
HashMap<String, String> point = (HashMap<String, String>) loc;
location = new LatLng(TiConvert.toDouble(point.get(TiC.PROPERTY_LATITUDE)),
TiConvert.toDouble(point.get(TiC.PROPERTY_LONGITUDE)));
} else if (loc instanceof Object[]) {
Object[] temp = (Object[]) loc;
location = new LatLng(TiConvert.toDouble(temp[1]), TiConvert.toDouble(temp[0]));
}
return location;
}

private List<PatternItem> processPatternDefinition(HashMap definition)
{
List<PatternItem> pattern = null;
Expand Down
56 changes: 56 additions & 0 deletions android/src/ti/map/TiMapUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2021-present by Axway, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package ti.map;

import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.PolyUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.TiConvert;

public class TiMapUtils
{
// A location can either be a an array of longitude, latitude pairings or
// an array of longitude, latitude objects.
// e.g. [123.33, 34.44], OR {longitude: 123.33, latitude, 34.44}
public static LatLng parseLocation(Object loc)
{
LatLng location = null;
if (loc instanceof HashMap) {
HashMap<String, String> point = (HashMap<String, String>) loc;
location = new LatLng(TiConvert.toDouble(point.get(TiC.PROPERTY_LATITUDE)),
TiConvert.toDouble(point.get(TiC.PROPERTY_LONGITUDE)));
} else if (loc instanceof Object[]) {
Object[] temp = (Object[]) loc;
location = new LatLng(TiConvert.toDouble(temp[1]), TiConvert.toDouble(temp[0]));
}
return location;
}

public static ArrayList<LatLng> processPoints(Object points)
{
ArrayList<LatLng> locationArray = new ArrayList<>();

// encoded (result from routing API)
if (points instanceof String) {
List<LatLng> locationList = PolyUtil.decode((String) points);
return new ArrayList<>(locationList);
// multiple points
} else if (points instanceof Object[]) {
Object[] pointsArray = (Object[]) points;
for (int i = 0; i < pointsArray.length; i++) {
Object obj = pointsArray[i];
LatLng location = TiMapUtils.parseLocation(obj);
locationArray.add(location);
}
return locationArray;
}
return locationArray;
}
}
4 changes: 4 additions & 0 deletions android/src/ti/map/TiUIMapView.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.TileOverlayOptions;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.clustering.view.DefaultClusterRenderer;
Expand Down Expand Up @@ -180,6 +181,9 @@ protected void processPreloadPolylines()

protected void processOverlaysList()
{
for (TileOverlayOptions options : ((ViewProxy) proxy).getTileOverlayOptionsList()) {
this.map.addTileOverlay(options);
}
for (ImageOverlayProxy imageOverlayProxy : ((ViewProxy) proxy).getOverlaysList()) {
addImageOverlay(imageOverlayProxy);
}
Expand Down
58 changes: 56 additions & 2 deletions android/src/ti/map/ViewProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@
import android.os.Message;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
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.HeatmapTileProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollFunction;
import org.appcelerator.kroll.KrollObject;
Expand Down Expand Up @@ -76,11 +82,14 @@ public class ViewProxy extends TiViewProxy implements AnnotationDelegate
private static final int MSG_REMOVE_IMAGE_OVERLAY = MSG_FIRST_ID + 932;
private static final int MSG_REMOVE_ALL_IMAGE_OVERLAYS = MSG_FIRST_ID + 933;

private static final int MSG_ADD_HEAT_MAP = MSG_FIRST_ID + 941;

private final ArrayList<RouteProxy> preloadRoutes;
private final ArrayList<PolygonProxy> preloadPolygons;
private final ArrayList<PolylineProxy> preloadPolylines;
private final ArrayList<CircleProxy> preloadCircles;
private final ArrayList<ImageOverlayProxy> preloadOverlaysList;
private final ArrayList<TileOverlayOptions> preloadTileOverlayOptionsList;

public ViewProxy()
{
Expand All @@ -95,6 +104,7 @@ public ViewProxy()
preloadPolylines = new ArrayList<PolylineProxy>();
preloadCircles = new ArrayList<CircleProxy>();
preloadOverlaysList = new ArrayList<ImageOverlayProxy>();
preloadTileOverlayOptionsList = new ArrayList<TileOverlayOptions>();
}

@Override
Expand All @@ -109,6 +119,7 @@ public void clearPreloadObjects()
preloadPolygons.clear();
preloadPolylines.clear();
preloadCircles.clear();
preloadTileOverlayOptionsList.clear();
}

@Override
Expand Down Expand Up @@ -315,7 +326,14 @@ public boolean handleMessage(Message msg)

case MSG_SHOW_ANNOTATIONS: {
result = ((AsyncResult) msg.obj);
handleShowAnnotations((Object[]) result.getArg());
handleShowAnnotations(result.getArg());
result.setResult(null);
return true;
}

case MSG_ADD_HEAT_MAP: {
result = ((AsyncResult) msg.obj);
handleAddHeatMap(result.getArg());
result.setResult(null);
return true;
}
Expand Down Expand Up @@ -637,14 +655,45 @@ public void handleDeselectAnnotation(Object annotation)
@Kroll.method
public void addRoute(RouteProxy route)
{

if (TiApplication.isUIThread()) {
handleAddRoute(route);
} else {
TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_ADD_ROUTE), route);
}
}

@Kroll.method
public void addHeatMap(Object coordinates)
{
if (TiApplication.isUIThread()) {
handleAddHeatMap(coordinates);
} else {
TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_ADD_HEAT_MAP), coordinates);
}
}

public void handleAddHeatMap(Object coordinates)
{
// Validate.
if (coordinates == null) {
return;
}

// Create a heatmap overlay using given coordinates.
List<LatLng> data = TiMapUtils.processPoints(coordinates);
HeatmapTileProvider provider = new HeatmapTileProvider.Builder().data(data).build();
TileOverlayOptions tileOverlayOptions = new TileOverlayOptions().tileProvider(provider);

// Add heatmap overlay to map.
TiUIView view = peekView();
GoogleMap map = (view instanceof TiUIMapView) ? ((TiUIMapView) view).getMap() : null;
if (map != null) {
map.addTileOverlay(tileOverlayOptions);
} else {
this.preloadTileOverlayOptionsList.add(tileOverlayOptions);
}
}

public void handleAddRoute(Object route)
{
if (route == null) {
Expand Down Expand Up @@ -761,6 +810,11 @@ public ArrayList<ImageOverlayProxy> getOverlaysList()
return preloadOverlaysList;
}

public ArrayList<TileOverlayOptions> getTileOverlayOptionsList()
{
return this.preloadTileOverlayOptionsList;
}

/**
* Polygons
**/
Expand Down
10 changes: 10 additions & 0 deletions apidoc/View.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ methods:
summary: Modules.Map.Route
type: Modules.Map.Route

- name: addHeatmap
summary: Adds a heatmap to the map.
description: A heatmap is defined by an array of coordinates.
parameters:
- name: coordinates
summary: An array of coordinates
type: MapPointType
platforms: [android]
since: "10.1.0"

- name: containsCoordinate
summary: |
Validated whether or not a given coordinate is currently visible
Expand Down