Implement: tileOverlayOptions.getTile() for Android
MODIFY
src/android/plugin/google/maps/PluginTileOverlay.java
src/android/plugin/google/maps/PluginTileOverlay.java
@@ -2,9 +2,11 @@ package plugin.google.maps;
import android.content.res.AssetManager;
import android.util.Log;
+import android.webkit.WebView;
import com.google.android.gms.maps.model.TileOverlay;
import com.google.android.gms.maps.model.TileOverlayOptions;
+import com.google.android.gms.maps.model.TileProvider;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
@@ -27,7 +29,6 @@ public class PluginTileOverlay extends MyPlugin implements MyPluginInterface {
final JSONObject opts = args.getJSONObject(1);
final int tileSize = opts.getInt("tileSize");
- final String tileUrlFormat = opts.getString("tileUrlFormat");
final TileOverlayOptions options = new TileOverlayOptions();
@@ -40,6 +41,7 @@ public class PluginTileOverlay extends MyPlugin implements MyPluginInterface {
if (opts.has("opacity")) {
options.transparency((float)(1 - opts.getDouble("opacity")));
}
+ final String id = opts.getString("_id");
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
@@ -56,7 +58,7 @@ public class PluginTileOverlay extends MyPlugin implements MyPluginInterface {
String currentPageUrl = webView.getUrl();
AssetManager assetManager = cordova.getActivity().getAssets();
- final PluginTileProvider tileProvider = new PluginTileProvider(assetManager, currentPageUrl, userAgent, tileUrlFormat,tileSize);
+ final PluginTileProvider tileProvider = new PluginTileProvider(pluginMap.mapId, id, webView, assetManager, currentPageUrl, userAgent, tileSize);
tileProvider.setOnCacheClear(new PluginTileProvider.OnCacheClear() {
@Override
public void onCacheClear(int hashCode) {
@@ -71,7 +73,7 @@ public class PluginTileOverlay extends MyPlugin implements MyPluginInterface {
TileOverlay tileOverlay = map.addTileOverlay(options);
- String id = tileOverlay.getId();
+ //String id = tileOverlay.getId();
self.objects.put("tileoverlay_" + id, tileOverlay);
self.objects.put("tileprovider_" + id, tileProvider);
@@ -88,6 +90,17 @@ public class PluginTileOverlay extends MyPlugin implements MyPluginInterface {
}
});
}
+ public void onGetTileUrlFromJS(final JSONArray args, final CallbackContext callbackContext) throws JSONException {
+ String id = args.getString(0);
+ String tileUrl = args.getString(1);
+ String pluginId = "tileprovider_" + id;
+ ((PluginTileProvider)(this.objects.get(pluginId))).onGetTileUrlFromJS(tileUrl);
+ }
+
+ public void onGetTileUrlFromJS(String pluginId, String tileUrl) {
+ pluginId = "tileprovider_" + pluginId;
+ ((PluginTileProvider)(this.objects.get(pluginId))).onGetTileUrlFromJS(tileUrl);
+ }
/**
* set z-index

MODIFY
src/android/plugin/google/maps/PluginTileProvider.java
src/android/plugin/google/maps/PluginTileProvider.java
package plugin.google.maps;
+import android.annotation.SuppressLint;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
@@ -7,12 +8,18 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
+import android.webkit.JavascriptInterface;
+import android.webkit.WebView;
import com.google.android.gms.maps.model.Tile;
import com.google.android.gms.maps.model.TileProvider;
import org.apache.cordova.CordovaResourceApi;
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.PluginEntry;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -20,9 +27,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.Locale;
public class PluginTileProvider implements TileProvider {
- private String tileUrlFormat = null;
private int tileSize = 256;
private Paint tilePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
private String userAgent = null;
@@ -30,14 +37,21 @@ public class PluginTileProvider implements TileProvider {
private OnCacheClear listener = null;
private String webPageUrl = null;
private AssetManager assetManager;
+ private CordovaWebView webView;
+ private String mapId, pluginId;
+ private String tileUrl;
+ private Handler handler;
- public PluginTileProvider(AssetManager assetManager, String webPageUrl, String userAgent, String tileUrlFormat, int tileSize) {
- this.tileUrlFormat = tileUrlFormat;
+ @SuppressLint({"NewApi", "JavascriptInterface"})
+ public PluginTileProvider(String mapId, String pluginId, CordovaWebView webView, AssetManager assetManager, String webPageUrl, String userAgent, int tileSize) {
this.tileSize = tileSize;
//this.tilePaint.setAlpha((int) (opacity * 255));
this.userAgent = userAgent == null ? "Mozilla" : userAgent;
this.webPageUrl = webPageUrl;
this.assetManager = assetManager;
+ this.webView = webView;
+ this.mapId = mapId;
+ this.pluginId = pluginId;
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
@@ -48,12 +62,22 @@ public class PluginTileProvider implements TileProvider {
int cacheSize = maxMemory / 8;
tileCache = new BitmapCache(cacheSize);
+
+ handler = new Handler(Looper.getMainLooper());
+
}
public interface OnCacheClear {
public void onCacheClear(int hashCode);
}
+ public void onGetTileUrlFromJS(String tileUrl) {
+ this.tileUrl = tileUrl;
+ synchronized (this) {
+ this.notify();
+ }
+ }
+
public void setOnCacheClear(OnCacheClear listener) {
this.listener = listener;
}
@@ -61,9 +85,30 @@ public class PluginTileProvider implements TileProvider {
@Override
public Tile getTile(int x, int y, int zoom) {
+ /*
String urlStr = tileUrlFormat.replaceAll("<x>", x + "")
.replaceAll("<y>", y + "")
.replaceAll("<zoom>", zoom + "");
+ */
+ String urlStr = null;
+ synchronized (this) {
+ final String js = String.format(Locale.ENGLISH, "javascript:cordova.fireDocumentEvent('%s-%s-tileoverlay', {x: %d, y: %d, zoom: %d})",
+ mapId, pluginId, x, y, zoom);
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ webView.loadUrl(js);
+ }
+ });
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ urlStr = tileUrl;
+ }
Tile tile = null;
try {
@@ -196,7 +241,6 @@ public class PluginTileProvider implements TileProvider {
return null;
}
}
- Log.d("PluginTileProvider", "cacheKey = " + cacheKey);
if (image != null) {
if (image.getWidth() != tileSize || image.getHeight() != tileSize) {
Bitmap tileImage = this.resizeForTile(image);

MODIFY
www/Map.js
www/Map.js
@@ -739,8 +739,16 @@ Map.prototype.addTileOverlay = function(tilelayerOptions, callback) {
var self = this;
tilelayerOptions = tilelayerOptions || {};
tilelayerOptions.tileUrlFormat = tilelayerOptions.tileUrlFormat || null;
- if (typeof tilelayerOptions.tileUrlFormat !== "string") {
- throw new Error("tilelayerOptions.tileUrlFormat should set a string.");
+ if (tilelayerOptions.tileUrlFormat === "string") {
+ console.log("[deprecated] the tileUrlFormat property is now deprecated. Use the getTile property.");
+ tilelayerOptions.getTile = function(x, y, zoom) {
+ return tilelayerOptions.tileUrlFormat.replace(/<x>/gi, x).
+ tileUrlFormat.replace(/<y>/gi, y).
+ tileUrlFormat.replace(/<zoom>/gi, zoom);
+ };
+ }
+ if (typeof tilelayerOptions.getTile !== "function") {
+ throw new Error("[error] the getTile property is required.");
}
tilelayerOptions.visible = common.defaultTrueOption(tilelayerOptions.visible);
tilelayerOptions.zIndex = tilelayerOptions.zIndex || 0;
@@ -748,6 +756,23 @@ Map.prototype.addTileOverlay = function(tilelayerOptions, callback) {
tilelayerOptions.opacity = tilelayerOptions.opacity || 1;
tilelayerOptions.userAgent = tilelayerOptions.userAgent || navigator.userAgent;
+ var options = {
+ visible: tilelayerOptions.visible,
+ zIndex: tilelayerOptions.zIndex,
+ tileSize: tilelayerOptions.tileSize,
+ opacity: tilelayerOptions.opacity,
+ userAgent: tilelayerOptions.userAgent,
+ _id : Math.floor(Math.random() * Date.now())
+ };
+
+ //console.log(self.id + "-" + options._id + "-tileoverlay");
+ document.addEventListener(self.id + "-" + options._id + "-tileoverlay", function(params) {
+ //console.log("--> " + self.id + "-tileoverlay");
+ // console.log("--> " + "tileoverlay_" + options._id);
+ var url = tilelayerOptions.getTile(params.x, params.y, params.zoom);
+ exec(null, self.errorHandler, self.id + "-tileoverlay", 'onGetTileUrlFromJS', [options._id, url]);
+ });
+
exec(function(result) {
tilelayerOptions.hashCode = result.hashCode;
var tileOverlay = new TileOverlay(self, result.id, tilelayerOptions);
@@ -760,9 +785,10 @@ Map.prototype.addTileOverlay = function(tilelayerOptions, callback) {
if (typeof callback === "function") {
callback.call(self, tileOverlay, self);
}
- }, self.errorHandler, self.id, 'loadPlugin', ['TileOverlay', tilelayerOptions]);
+ }, self.errorHandler, self.id, 'loadPlugin', ['TileOverlay', options]);
};
+
//-------------
// Polygon
//-------------

Implement: tileOverlayOptions.getTile() for Android