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

Android tileoverlay #278

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
833 changes: 833 additions & 0 deletions android/assets/Leaflet.Providers.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
dependencies {
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.maps.android:android-maps-utils:2.0.3'
implementation 'androidx.fragment:fragment:1.1.0'
implementation 'androidx.fragment:fragment:1.2.5'
}
7 changes: 5 additions & 2 deletions android/example/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ var rows = [
require('tests/annotations'),
require('tests/routes'),
require('tests/3d'),
require('tests/drawing'),
require('tests/lite')
require('tests/drawing'),
];

if (IOS) {
rows.push(require('tests/camera'));
rows.push(require('tests/properties'));
}
if (ANDROID) {
rows.push(require('tests/lite'));
rows.push(require('tests/tileoverlay'));
}

if (ANDROID && Map.isGooglePlayServicesAvailable() != Map.SUCCESS) {
alert ("Google Play Services is not installed/updated/available");
Expand Down
43 changes: 21 additions & 22 deletions android/example/tests/lite.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
exports.title = 'Lite Mode';

exports.run = function(UI, Map) {
var win = UI.createWindow(exports.title);
const win = UI.createWindow(exports.title);
function createMap(liteMode) {
var map = Map.createView({
top: 10,
right: 0,
width: Ti.UI.FILL,
height: 200,
liteMode: liteMode,
region: {
zoom: 10,
const map = Map.createView({
top: 10,
right: 0,
width: Ti.UI.FILL,
height: 200,
liteMode: liteMode,
region: {
zoom: 10,
latitude: 46.893234,
longitude: 1.346569,
}
});
const an = Map.createAnnotation({
title: 'Title',
latitude: 46.893234,
longitude: 1.346569,
}
});
var an = Map.createAnnotation({
title: 'Title',
latitude: 46.893234,
longitude: 1.346569,
})
map.addAnnotation(an);
win.add(map);
}

createMap(true); // false for normal mode
win.open();
});
map.addAnnotation(an);
win.add(map);
}

createMap(true); // false for normal mode
win.open();
};
2 changes: 1 addition & 1 deletion android/example/tests/multiMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ exports.run = function(UI, Map) {
win.add(map1);
win.add(map2);
win.add(map3);
win.add(map4);
win.add(map4);
};
121 changes: 121 additions & 0 deletions android/example/tests/tileoverlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
exports.title = 'Tile Overlays';

const Sydney = {
latitude: -33.87365,
longitude: 151.20689,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Paris = {
latitude: 48.864716,
longitude: 2.349014,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Vienna = {
latitude: 48.210033,
longitude: 16.363449,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Slovakia = {
latitude: 48.148598,
longitude: 17.107748,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Stockholm = {
latitude: 59.334591,
longitude: 18.063240,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Edinburgh = {
latitude: 55.953251,
longitude: -3.188267,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Singapore = {
latitude: 1.290270,
longitude: 103.851959,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const Amsterdam = {
latitude: 52.377956,
longitude: 4.897070,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
const NewYork = {
latitude: 40.730610,
longitude: -73.935242,
zoom: 7 // max zoom for NASA/JusticeMap is around 8/9
};

exports.run = function(UI, Map) {
const win = UI.createWindow(exports.title);

const map = Map.createView({
region: Sydney,
top: '50%',
enableZoomControls: true
});

let overlay;
function switchOverlay(newOverlay) {
if (overlay) {
map.removeTileOverlay(overlay);
}
if (newOverlay.name.startsWith('GeoportailFrance')) {
map.setLocation(Paris);
} else if (newOverlay.name.startsWith('BasemapAT')) {
map.setLocation(Vienna);
} else if (newOverlay.name.startsWith('FreeMapSK')) {
map.setLocation(Slovakia);
} else if (newOverlay.name.startsWith('Hydda')) {
map.setLocation(Stockholm);
} else if (newOverlay.name.startsWith('NLS')) {
map.setLocation(Edinburgh);
} else if (newOverlay.name.startsWith('OneMapSG')) {
map.setLocation(Singapore);
} else if (newOverlay.name.startsWith('nlmaps')) {
map.setLocation(Amsterdam);
} else if (newOverlay.name.startsWith('JusticeMap') || newOverlay.name.startsWith('NASAGIBS')) {
map.setLocation(NewYork);
}
overlay = newOverlay;
map.addTileOverlay(overlay);
}

const DB = Map.createLeafletProviders();
const names = DB.getAllNames();
// FIXME: Sort ignoring case
const rows = names.sort().map(name => {
return {
title: name,
color: 'black',
run: () => {
// TODO: Can we get the merged max/min zoom levels for the given provider to determine zoom level?
switchOverlay(Map.createTileOverlay({
service: Map.TILE_OVERLAY_TYPE_XYZ,
name,
debuglevel: 2
}));
}
};
});

const tableView = Ti.UI.createTableView({
top: 0,
bottom: '50%',
data: rows
});
win.add(tableView);
tableView.addEventListener('click', function(e) {
rows[e.index].run && rows[e.index].run();
});

win.add(map);
};
Binary file added android/lib/android-async-http-1.4.9.jar
Binary file not shown.
Binary file not shown.
Binary file added android/lib/jcoord-1.0.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion android/manifest
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
version: 5.2.1
version: 5.3.0
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86 x86_64
description: External version of Map module using native Google Maps library
Expand Down
155 changes: 155 additions & 0 deletions android/src/ti/map/HeatmapOverlayProxy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package ti.map;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
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;
// from: https://github.com/googlemaps/android-maps-utils
import com.google.maps.android.heatmaps.HeatmapTileProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.TiConvert;

@Kroll.proxy(creatableInModule = MapModule.class)
public class HeatmapOverlayProxy extends KrollProxy
{
/**
* Colors for default gradient. Array of colors, represented by ints.
*/
private static final int[] DEFAULT_GRADIENT_COLORS = { Color.rgb(102, 225, 0), Color.rgb(255, 0, 0) };
private static final float[] DEFAULT_GRADIENT_START_POINTS = { 0.2f, 1f };
private static final int DEFAULT_RADIUS = 20;
private float[] gradientStartPoints = { DEFAULT_GRADIENT_START_POINTS[0], DEFAULT_GRADIENT_START_POINTS[1] };
private int[] gradientColors = { DEFAULT_GRADIENT_COLORS[0], DEFAULT_GRADIENT_COLORS[1] };
private int radius = DEFAULT_RADIUS;

public static final Gradient DEFAULT_GRADIENT =
new Gradient(DEFAULT_GRADIENT_COLORS, DEFAULT_GRADIENT_START_POINTS);
private Gradient gradient = new Gradient(gradientColors, gradientStartPoints);

private float opacity = 1.0f;
private int zIndex = 0;
private TileOverlay tileOverlay;
public String LCAT = MapModule.LCAT + "Heatmap";
HeatmapTileProvider heatmapTileProvider;

private List<LatLng> pointList = null;

public HeatmapOverlayProxy()
{
super();
}

private void addLocation(Object loc, List<LatLng> locationArray)
{

if (loc instanceof HashMap) {
Log.d(LCAT, "type HashMap");
HashMap<String, String> point = (HashMap<String, String>) loc;
Object latitude = point.get(TiC.PROPERTY_LATITUDE);
Object longitude = point.get(TiC.PROPERTY_LONGITUDE);
if (longitude != null && latitude != null) {
LatLng location = new LatLng(TiConvert.toDouble(latitude), TiConvert.toDouble(longitude));
locationArray.add(location);
}
} else if (loc instanceof Object[]) {

Object[] temp = (Object[]) loc;
LatLng location = new LatLng(TiConvert.toDouble(temp[1]), TiConvert.toDouble(temp[0]));
locationArray.add(location);
}
}

private List<LatLng> processPoints(Object points)
{
List<LatLng> locationArray = new ArrayList<LatLng>();
if (points instanceof Object[]) {
Object[] pointsArray = (Object[]) points;
for (int i = 0; i < pointsArray.length; i++) {
Object obj = pointsArray[i];
addLocation(obj, locationArray);
}
return locationArray;
}
addLocation(points, locationArray);
return locationArray;
}

// http://stackoverflow.com/questions/23806348/blurred-custom-tiles-on-android-maps-v2
@Override
public void handleCreationDict(KrollDict o)
{
super.handleCreationDict(o);
String sql = null;
String dbname = null;

if (o.containsKeyAndNotNull(TiC.PROPERTY_OPACITY)) {
opacity = TiConvert.toFloat(o.getDouble(TiC.PROPERTY_OPACITY));
}
if (o.containsKeyAndNotNull(TiC.PROPERTY_ZINDEX)) {
zIndex = o.getInt(TiC.PROPERTY_ZINDEX);
}
if (o.containsKeyAndNotNull(MapModule.PROPERTY_POINTS)) {
pointList = processPoints(getProperty(MapModule.PROPERTY_POINTS));
}
if (o.containsKeyAndNotNull("dbname")) {
dbname = o.getString("dbname");
}
if (o.containsKeyAndNotNull("sql")) {
sql = o.getString("sql");
}
if (dbname != null && sql != null) {
importFromDB(dbname, sql);
}
}

private void importFromDB(String dbname, String sql)
{
Context ctx = TiApplication.getInstance().getApplicationContext();
List<LatLng> locationArray = new ArrayList<LatLng>();
SQLiteDatabase db = ctx.openOrCreateDatabase(dbname, Context.MODE_PRIVATE, null);
Cursor c = db.rawQuery(sql, null);
if (c.moveToFirst()) {
do {
locationArray.add(new LatLng(c.getDouble(0), c.getDouble(1)));
} while (c.moveToNext());
}
c.close();
db.close();
}

public void setHeatmapOverlay(TileOverlay tileOverlay)
{
this.tileOverlay = tileOverlay;
}

public TileOverlayOptions getTileOverlayOptions()
{
Log.d(LCAT, "TileOverlayOptions getOptions");
if (pointList != null)
Log.d(LCAT, pointList.toString());
else
Log.d(LCAT, "pointList ist null");
// https://developers.google.com/maps/documentation/android-sdk/utility/heatmap
heatmapTileProvider = new HeatmapTileProvider.Builder()
.data(pointList)
.opacity(opacity)
.radius(radius)
.gradient(gradient)
.build();
TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();
tileOverlayOptions.tileProvider(heatmapTileProvider);
return tileOverlayOptions;
}
}
Loading