Bug fix: After zoom out the markers are still on the map, clusters are shown too.
Only Android at this time.
MODIFY
plugin.xml
plugin.xml
<?xml version='1.0' encoding='utf-8'?>
-<plugin id="cordova-plugin-googlemaps" version="cluster-20170727-1527" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+<plugin id="cordova-plugin-googlemaps" version="cluster-20170727-2327" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>cordova-plugin-googlemaps</name>
<js-module name="BaseClass" src="www/BaseClass.js">
<runs />

MODIFY
src/android/plugin/google/maps/MyPlugin.java
src/android/plugin/google/maps/MyPlugin.java
@@ -24,16 +24,15 @@ import org.json.JSONException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyPlugin extends CordovaPlugin implements MyPluginInterface {
- protected final HashMap<String, Object> objects = new HashMap<String, Object>();
+ protected final ConcurrentHashMap<String, Object> objects = new ConcurrentHashMap<String, Object>();
public MyPlugin self = null;
public final ConcurrentHashMap<String, Method> methods = new ConcurrentHashMap<String, Method>();
- private static ExecutorService executorService = null;
+ protected static ExecutorService executorService = null;
public CordovaGoogleMaps mapCtrl = null;
public GoogleMap map = null;
@@ -66,7 +65,7 @@ public class MyPlugin extends CordovaPlugin implements MyPluginInterface {
@Override
public boolean execute(final String action, final JSONArray args, final CallbackContext callbackContext) {
self = this;
- executorService.execute(new Runnable() {
+ executorService.submit(new Runnable() {
@Override
public void run() {
@@ -136,14 +135,14 @@ public class MyPlugin extends CordovaPlugin implements MyPluginInterface {
protected synchronized Circle getCircle(String id) {
if (!this.objects.containsKey(id)) {
- Log.e(TAG, "---> can not find the circle : " + id);
+ //Log.e(TAG, "---> can not find the circle : " + id);
return null;
}
return (Circle)this.objects.get(id);
}
protected synchronized GroundOverlay getGroundOverlay(String id) {
if (!this.objects.containsKey(id)) {
- Log.e(TAG, "---> can not find the ground overlay : " + id);
+ //Log.e(TAG, "---> can not find the ground overlay : " + id);
return null;
}
return (GroundOverlay)this.objects.get(id);
@@ -157,21 +156,21 @@ public class MyPlugin extends CordovaPlugin implements MyPluginInterface {
}
protected synchronized Polyline getPolyline(String id) {
if (!this.objects.containsKey(id)) {
- Log.e(TAG, "---> can not find the polyline : " + id);
+ //Log.e(TAG, "---> can not find the polyline : " + id);
return null;
}
return (Polyline)this.objects.get(id);
}
protected synchronized Polygon getPolygon(String id) {
if (!this.objects.containsKey(id)) {
- Log.e(TAG, "---> can not find the polygon : " + id);
+ //Log.e(TAG, "---> can not find the polygon : " + id);
return null;
}
return (Polygon)this.objects.get(id);
}
protected synchronized TileOverlay getTileOverlay(String id) {
if (!this.objects.containsKey(id)) {
- Log.e(TAG, "---> can not find the tileoverlay : " + id);
+ //Log.e(TAG, "---> can not find the tileoverlay : " + id);
return null;
}
return (TileOverlay)this.objects.get(id);

MODIFY
src/android/plugin/google/maps/PluginMarkerCluster.java
src/android/plugin/google/maps/PluginMarkerCluster.java
package plugin.google.maps;
-import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
@@ -8,14 +7,10 @@ import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
-import com.google.android.gms.maps.model.Polygon;
-import com.google.android.gms.maps.model.PolygonOptions;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.PluginEntry;
-import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -24,17 +19,16 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
public class PluginMarkerCluster extends PluginMarker {
private final static ConcurrentHashMap<String, STATUS> pluginMarkers = new ConcurrentHashMap<String, STATUS>();
private final static ConcurrentHashMap<String, Integer> waitCntManager = new ConcurrentHashMap<String, Integer>();
+ private final static ConcurrentHashMap<String, Boolean> debugFlags = new ConcurrentHashMap<String, Boolean>();
+ private final static ArrayList<String> deleteMarkers = new ArrayList<String>();
private final Object dummyObj = new Object();
- private boolean recyleOption = false;
+ private boolean stopFlag = false;
enum STATUS {
WORKING,
@@ -45,11 +39,15 @@ public class PluginMarkerCluster extends PluginMarker {
@Override
public void initialize(CordovaInterface cordova, final CordovaWebView webView) {
super.initialize(cordova, webView);
+ if (!deleteThread.isAlive()) {
+ deleteThread.start();
+ }
}
@Override
public void onDestroy() {
super.onDestroy();
+ stopFlag = true;
this.clear();
}
@@ -59,6 +57,60 @@ public class PluginMarkerCluster extends PluginMarker {
}
+ private Thread deleteThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while(!stopFlag) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (deleteMarkers.size() == 0) {
+ continue;
+ }
+
+ cordova.getActivity().runOnUiThread(removeOverlaysOnUiThread);
+ }
+ }
+ });
+
+ private Runnable removeOverlaysOnUiThread = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (deleteMarkers) {
+ String markerId;
+ Marker marker;
+ STATUS status;
+ String[] targetIDs = deleteMarkers.toArray(new String[deleteMarkers.size()]);
+
+ for (int i = targetIDs.length - 1; i > -1; i--) {
+ markerId = targetIDs[i];
+
+ marker = self.getMarker(markerId);
+ synchronized (pluginMarkers) {
+ status = pluginMarkers.get(markerId);
+ //Log.d(TAG, "delete : " + markerId + " = " + status);
+ if (!STATUS.WORKING.equals(status)) {
+ synchronized (self.objects) {
+ _removeMarker(marker);
+ marker = null;
+ objects.remove(markerId);
+ objects.remove("marker_property_" + markerId);
+ }
+ pluginMarkers.remove(markerId);
+ deleteMarkers.remove(i);
+ } else {
+ pluginMarkers.put(markerId, STATUS.DELETED);
+ }
+ }
+
+ }
+ }
+ }
+ };
+
+
/**
* Create a marker
*
@@ -80,6 +132,7 @@ public class PluginMarkerCluster extends PluginMarker {
}
String id = "markercluster_" + callbackContext.hashCode();
+ debugFlags.put(id, params.getBoolean("debug"));
final JSONObject result = new JSONObject();
try {
@@ -98,9 +151,9 @@ public class PluginMarkerCluster extends PluginMarker {
final HashMap<String, String> updateClusterIDs = new HashMap<String, String>();
- final ArrayList<String> deleteClusterIDs = new ArrayList<String>();
final HashMap<String, Bundle> changeProperties = new HashMap<String, Bundle>();
final String clusterId = args.getString(0);
+ final boolean isDebug = debugFlags.get(clusterId);
synchronized (dummyObj) {
JSONObject params = args.getJSONObject(1);
@@ -117,17 +170,16 @@ public class PluginMarkerCluster extends PluginMarker {
int deleteCnt = 0;
int new_or_updateCnt = 0;
- int reuseCnt = 0;
if (deleteClusters != null) {
deleteCnt = deleteClusters.length();
+ for (int i = 0; i < deleteCnt; i++) {
+ markerId = deleteClusters.getString(i);
+ deleteMarkers.add(clusterId + "-" + markerId);
+ }
}
if (new_or_update != null) {
new_or_updateCnt = new_or_update.length();
}
- for (int i = 0; i < deleteCnt; i++) {
- markerId = deleteClusters.getString(i);
- deleteClusterIDs.add(clusterId + "-" + markerId);
- }
//---------------------------
// Determine new or update
@@ -145,26 +197,11 @@ public class PluginMarkerCluster extends PluginMarker {
if (self.objects.containsKey(clusterId_markerId) || pluginMarkers.containsKey(clusterId_markerId)) {
updateClusterIDs.put(clusterId_markerId, clusterId_markerId);
} else {
-
-
- if (recyleOption && reuseCnt < deleteCnt) {
- //---------------
- // Reuse a marker
- //---------------
- deleteMarkerId = deleteClusterIDs.remove(0);
- deleteCnt--;
- updateClusterIDs.put(deleteMarkerId, clusterId_markerId);
- reuseCnt++;
- } else {
pluginMarkers.put(clusterId_markerId, STATUS.WORKING);
updateClusterIDs.put(clusterId_markerId, null);
}
- }
properites = new Bundle();
- if (clusterData.has("geocell")) {
- properites.putString("geocell", clusterData.getString("geocell"));
- }
properites.putDouble("lat", positionJSON.getDouble("lat"));
properites.putDouble("lng", positionJSON.getDouble("lng"));
if (clusterData.has("title")) {
@@ -185,16 +222,24 @@ public class PluginMarkerCluster extends PluginMarker {
Bundle iconProperties = PluginUtil.Json2Bundle(icon);
if (icon.has("label")) {
JSONObject label = icon.getJSONObject("label");
+ if (isDebug) {
+ label.put("text", markerId);
+ } else {
label.put("text", clusterData.getInt("count") + "");
+ }
if (label.has("color")) {
label.put("color", PluginUtil.parsePluginColor(label.getJSONArray("color")));
}
iconProperties.putBundle("label", PluginUtil.Json2Bundle(label));
} else {
Bundle label = new Bundle();
+ if (isDebug) {
+ label.putString("text", markerId);
+ } else {
label.putInt("fontSize", 20);
label.putBoolean("bold", true);
label.putString("text", clusterData.getInt("count") + "");
+ }
iconProperties.putBundle("label", label);
}
if (icon.has("anchor")) {
@@ -250,11 +295,10 @@ public class PluginMarkerCluster extends PluginMarker {
@Override
public void run() {
Iterator<String> iterator;
- String oldMarkerId, newMarkerId, targetMarkerId;
+ String markerId;
Bundle markerProperties;
Marker marker;
- Polygon polygon;
- LatLngBounds bounds;
+ Boolean isNew;
//---------
// reuse or update
@@ -262,184 +306,44 @@ public class PluginMarkerCluster extends PluginMarker {
waitCntManager.put(clusterId, updateClusterIDs.size());
iterator = updateClusterIDs.keySet().iterator();
while (iterator.hasNext()) {
- oldMarkerId = iterator.next();
- newMarkerId = updateClusterIDs.get(oldMarkerId);
- if (newMarkerId == null) {
- targetMarkerId = oldMarkerId;
- markerProperties = changeProperties.get(oldMarkerId);
+ markerId = iterator.next();
+ synchronized (pluginMarkers) {
+ pluginMarkers.put(markerId, STATUS.WORKING);
+ }
+ isNew = !objects.containsKey(markerId);
+ markerProperties = changeProperties.get(markerId);
+ if (isNew) {
marker = map.addMarker(new MarkerOptions()
.position(new LatLng(markerProperties.getDouble("lat"), markerProperties.getDouble("lng")))
.visible(false));
if (markerProperties.containsKey("title")) {
marker.setTitle(markerProperties.getString("title"));
- } else {
- marker.setTitle(null);
}
if (markerProperties.containsKey("snippet")) {
marker.setSnippet(markerProperties.getString("snippet"));
- } else {
- marker.setSnippet(null);
}
marker.setTag(markerProperties.getString("id"));
- synchronized (self.objects) {
- self.objects.put(oldMarkerId, marker);
- //self.objects.put("marker_property_" + markerProperties.getString("id"), markerProperties);
- pluginMarkers.put(oldMarkerId, STATUS.WORKING);
- }
-
- if (markerProperties.containsKey("geocell")) {
- bounds = computeBox(markerProperties.getString("geocell"));
- polygon = map.addPolygon(new PolygonOptions()
- .add(bounds.northeast)
- .add(new LatLng(bounds.northeast.latitude, bounds.southwest.longitude))
- .add(bounds.southwest)
- .add(new LatLng(bounds.southwest.latitude, bounds.northeast.longitude))
- .visible(true)
- .strokeColor(Color.BLUE)
- .strokeWidth(2 * density));
- polygon.setTag("polygon");
- self.objects.put("polygon" + oldMarkerId, polygon);
- }
-
} else {
- //if (STATUS.DELETED.equals(pluginMarkers.get(oldMarkerId))) {
- // continue;
- //}
- marker = null;
- polygon = null;
- while (marker == null) {
- marker = self.getMarker(oldMarkerId);
- polygon = self.getPolygon("polygon" + oldMarkerId);
-
- if (marker == null || marker.getTag() == null) {
- synchronized (objects) {
- objects.remove(oldMarkerId);
- objects.remove("marker_property_" + oldMarkerId);
- if (pluginMarkers.get(oldMarkerId) == STATUS.DELETED) {
- pluginMarkers.remove(oldMarkerId);
- } else {
- pluginMarkers.put(oldMarkerId, STATUS.DELETED);
- }
- polygon = getPolygon("polygon" + oldMarkerId);
- if (polygon != null && polygon.getTag() != null) {
- polygon.setTag(null);
- polygon.remove();
- polygon = null;
- objects.remove("polygon" + oldMarkerId);
+ marker = getMarker(markerId);
}
- }
- if (deleteClusterIDs.size() > 0) {
- oldMarkerId = deleteClusterIDs.remove(0);
- } else {
- marker = map.addMarker(new MarkerOptions()
- .position(new LatLng(0, 0))
- .visible(false));
- }
- }
- }
- marker.hideInfoWindow();
-
- markerProperties = changeProperties.get(newMarkerId);
- if (STATUS.DELETED.equals(pluginMarkers.get(newMarkerId))) {
- synchronized (waitCntManager) {
- int waitCnt = waitCntManager.get(clusterId);
- waitCnt = waitCnt - 1;
- if (waitCnt == 0) {
- synchronized (dummyObj) {
- dummyObj.notify();
+ synchronized (self.objects) {
+ self.objects.put(markerId, marker);
}
+ if (!isNew) {
+ synchronized (pluginMarkers) {
+ pluginMarkers.put(markerId, STATUS.CREATED);
}
- waitCntManager.put(clusterId, waitCnt);
- }
+ decreaseWaitCnt(clusterId);
continue;
}
- marker.setPosition(new LatLng(markerProperties.getDouble("lat"), markerProperties.getDouble("lng")));
- if (markerProperties.containsKey("title")) {
- marker.setTitle(markerProperties.getString("title"));
- } else {
- marker.setTitle(null);
- }
- if (markerProperties.containsKey("snippet")) {
- marker.setSnippet(markerProperties.getString("snippet"));
- } else {
- marker.setSnippet(null);
- }
- marker.setTag(newMarkerId);
- targetMarkerId = newMarkerId;
- if (markerProperties.containsKey("geocell")) {
- bounds = computeBox(markerProperties.getString("geocell"));
- if (polygon == null || polygon.getTag() == null) {
-
- polygon = map.addPolygon(new PolygonOptions()
- .add(bounds.northeast)
- .add(new LatLng(bounds.northeast.latitude, bounds.southwest.longitude))
- .add(bounds.southwest)
- .add(new LatLng(bounds.southwest.latitude, bounds.northeast.longitude))
- .visible(true)
- .strokeColor(Color.BLUE)
- .strokeWidth(2 * density));
- polygon.setTag("polygon");
- } else {
- ArrayList<LatLng> points = new ArrayList<LatLng>();
- points.add(bounds.northeast);
- points.add(new LatLng(bounds.northeast.latitude, bounds.southwest.longitude));
- points.add(bounds.southwest);
- points.add(new LatLng(bounds.southwest.latitude, bounds.northeast.longitude));
- polygon.setPoints(points);
- }
- } else if (polygon != null && polygon.getTag() != null) {
- polygon.setTag(null);
- polygon.remove();
- polygon = null;
- objects.remove("polygon" + newMarkerId);
- }
-
- if (oldMarkerId.hashCode() != newMarkerId.hashCode()) {
- //Log.d(TAG, "reuse : " + oldMarkerId + " -> " + newMarkerId + ", polygon = " + polygon);
- synchronized (self.objects) {
- self.objects.put(newMarkerId, marker);
- ////////self.objects.put("marker_property_" + newMarkerId, markerProperties);
- if (polygon != null) {
- self.objects.put("polygon" + newMarkerId, polygon);
- }
- pluginMarkers.put(newMarkerId, STATUS.CREATED);
- self.objects.remove(oldMarkerId);
- self.objects.remove("marker_property_" + oldMarkerId);
- self.objects.remove("polygon" + oldMarkerId);
- pluginMarkers.remove(oldMarkerId);
- }
- } else {
- //Log.d(TAG, "update : " + newGeocell);
- synchronized (self.objects) {
- self.objects.put(newMarkerId, marker);
- if (polygon != null) {
- self.objects.put("polygon" + newMarkerId, polygon);
- }
- }
- }
- }
-
if (markerProperties.containsKey("icon")) {
Bundle icon = markerProperties.getBundle("icon");
//Log.d(TAG, "---> targetMarkerId = " + targetMarkerId + ", marker = " + marker);
- setIconToClusterMarker(targetMarkerId, marker, icon, new PluginAsyncInterface() {
+ setIconToClusterMarker(markerId, marker, icon, new PluginAsyncInterface() {
@Override
public void onPostExecute(Object object) {
- //--------------------------------------
- // Icon is set to marker
- //--------------------------------------
- synchronized (waitCntManager) {
- int waitCnt = waitCntManager.get(clusterId);
- waitCnt = waitCnt - 1;
- if (waitCnt == 0) {
- synchronized (dummyObj) {
- dummyObj.notify();
- }
-
- }
- waitCntManager.put(clusterId, waitCnt);
- }
+ decreaseWaitCnt(clusterId);
}
@Override
@@ -448,75 +352,23 @@ public class PluginMarkerCluster extends PluginMarker {
// Could not read icon for some reason
//--------------------------------------
Log.e(TAG, errorMsg);
- synchronized (waitCntManager) {
- int waitCnt = waitCntManager.get(clusterId);
- waitCnt = waitCnt - 1;
- if (waitCnt == 0) {
- synchronized (dummyObj) {
- dummyObj.notify();
- }
-
- }
- waitCntManager.put(clusterId, waitCnt);
- }
+ decreaseWaitCnt(clusterId);
}
});
} else {
//--------------------
// No icon for marker
//--------------------
- marker.setIcon(null);
synchronized (pluginMarkers) {
- pluginMarkers.put(targetMarkerId, STATUS.CREATED);
- }
- synchronized (waitCntManager) {
- int waitCnt = waitCntManager.get(clusterId);
- waitCnt = waitCnt - 1;
- if (waitCnt == 0) {
- synchronized (dummyObj) {
- dummyObj.notify();
- }
-
- }
- waitCntManager.put(clusterId, waitCnt);
+ //Log.d(TAG, "create : " + markerId + " = CREATED");
+ pluginMarkers.put(markerId, STATUS.CREATED);
}
+ decreaseWaitCnt(clusterId);
}
}
updateClusterIDs.clear();
- //---------
- // delete
- //---------
- iterator = deleteClusterIDs.iterator();
- while (iterator.hasNext()) {
- oldMarkerId = iterator.next();
- marker = self.getMarker(oldMarkerId);
- polygon = self.getPolygon("polygon" + oldMarkerId);
- synchronized (pluginMarkers) {
- //Log.d(TAG, "delete : " + oldMarkerId + " = " + pluginMarkers.get(oldMarkerId));
- if (!STATUS.WORKING.equals(pluginMarkers.get(oldMarkerId))) {
- if (polygon != null && polygon.getTag() != null) {
- polygon.setTag(null);
- polygon.remove();
- polygon = null;
- }
- synchronized (self.objects) {
- _removeMarker(marker);
- marker = null;
- objects.remove(oldMarkerId);
- objects.remove("marker_property_" + oldMarkerId);
- objects.remove("polygon" + oldMarkerId);
- pluginMarkers.remove(oldMarkerId);
- }
- pluginMarkers.remove(oldMarkerId);
- } else {
- pluginMarkers.put(oldMarkerId, STATUS.DELETED);
- }
- }
- }
- deleteClusterIDs.clear();
-
}
});
synchronized (dummyObj) {
@@ -530,6 +382,24 @@ public class PluginMarkerCluster extends PluginMarker {
}
+ private void decreaseWaitCnt(String clusterId) {
+
+ //--------------------------------------
+ // Icon is set to marker
+ //--------------------------------------
+ synchronized (waitCntManager) {
+ int waitCnt = waitCntManager.get(clusterId);
+ waitCnt = waitCnt - 1;
+ if (waitCnt == 0) {
+ synchronized (dummyObj) {
+ dummyObj.notify();
+ }
+
+ }
+ waitCntManager.put(clusterId, waitCnt);
+ }
+ }
+
private void setIconToClusterMarker(final String markerId, final Marker marker, final Bundle iconProperty, final PluginAsyncInterface callback) {
synchronized (pluginMarkers) {
if (STATUS.DELETED.equals(pluginMarkers.get(markerId))) {
@@ -539,16 +409,9 @@ public class PluginMarkerCluster extends PluginMarker {
self.objects.remove("marker_property_" + markerId);
}
pluginMarkers.remove(markerId);
- Polygon polygon = self.getPolygon("polygon" + markerId);
- if (polygon != null && polygon.getTag() != null) {
- polygon.setTag(null);
- polygon.remove();
- polygon = null;
- }
callback.onError("marker has been removed");
return;
}
- pluginMarkers.put(markerId, STATUS.WORKING);
}
PluginMarkerCluster.super.setIcon_(marker, iconProperty, new PluginAsyncInterface() {
@Override
@@ -562,22 +425,16 @@ public class PluginMarkerCluster extends PluginMarker {
self.objects.remove("marker_property_" + markerId);
}
pluginMarkers.remove(markerId);
- Polygon polygon = self.getPolygon("polygon" + markerId);
- if (polygon != null && polygon.getTag() != null) {
- polygon.setTag(null);
- polygon.remove();
- polygon = null;
- }
callback.onPostExecute(null);
return;
}
- }
-
marker.setVisible(true);
+ Log.d(TAG, "create : " + markerId + " = CREATED");
pluginMarkers.put(markerId, STATUS.CREATED);
callback.onPostExecute(object);
}
+ }
@Override
public void onError(String errorMsg) {
@@ -589,13 +446,6 @@ public class PluginMarkerCluster extends PluginMarker {
self.objects.remove("marker_property_" + markerId);
pluginMarkers.remove(markerId);
objects.remove(markerId);
- Polygon polygon = getPolygon("polygon" + markerId);
- if (polygon != null && polygon.getTag() != null) {
- polygon.setTag(null);
- polygon.remove();
- polygon = null;
- }
- objects.remove("polygon" + markerId);
}
callback.onPostExecute(errorMsg);
}

MODIFY
www/MarkerCluster.js
www/MarkerCluster.js
@@ -49,6 +49,7 @@ var MarkerCluster = function(map, id, markerClusterOptions) {
value: id,
writable: false
});
+ self.taskQueue = [];
//----------------------------------------------------
// If a marker has been removed,
@@ -121,6 +122,12 @@ var MarkerCluster = function(map, id, markerClusterOptions) {
self._onCameraMoved(false);
+ if (self.debug) {
+ setInterval(function() {
+ console.log("self.taskQueue.push = " + self.taskQueue.length);
+ }, 5000);
+ }
+
return self;
};
@@ -181,6 +188,19 @@ MarkerCluster.prototype.getClusterByClusterId = function(clusterId) {
MarkerCluster.prototype.redraw = function(clusterDistance, force) {
+ var self = this;
+
+ self.taskQueue.push([clusterDistance, force]);
+ if (self.debug) {
+ console.log("self.taskQueue.push = " + self.taskQueue.length);
+ }
+ if (self.taskQueue.length > 1) {
+ return;
+ }
+ var taskParams = self.taskQueue.shift();
+ self._redraw.apply(self, taskParams);
+};
+MarkerCluster.prototype._redraw = function(clusterDistance, force) {
var self = this,
map = self.map,
currentZoomLevel = Math.floor(self.map.getCameraZoom()),
@@ -226,6 +246,7 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
var allGeocells = [];
if (prevResolution === -1) {
if (resolution === -1) {
+ self.nextTask();
return;
}
keys = Object.keys(self._markerMap);
@@ -268,9 +289,15 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
if (cluster.getMode() === cluster.NO_CLUSTER_MODE) {
cluster.getMarkers().forEach(function(marker, idx) {
deleteClusters[marker.getId()] = 1;
+ if (self.debug) {
+ console.log("---> (js)delete:" + marker.getId());
+ }
});
} else {
deleteClusters[geocell] = 1;
+ if (self.debug) {
+ console.log("---> (js)delete:" + geocell);
+ }
}
cluster.remove();
delete self._clusters[resolution][geocell];
@@ -298,10 +325,16 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
marker.set("isAdded", false, true);
targetMarkers.push(marker);
if (noClusterMode) {
+ if (self.debug) {
+ console.log("---> (js)delete:" + marker.getId());
+ }
deleteClusters[marker.getId()] = 1;
}
});
if (!noClusterMode) {
+ if (self.debug) {
+ console.log("---> (js)delete:" + geocell);
+ }
deleteClusters[geocell] = 1;
}
cluster.remove();
@@ -316,6 +349,9 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
cluster.getMarkers().forEach(function(marker, idx) {
marker.set("isAdded", false, true);
if (noClusterMode) {
+ if (self.debug) {
+ console.log("---> (js)delete:" + marker.getId());
+ }
deleteClusters[marker.getId()] = 1;
}
});
@@ -429,7 +465,7 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
var cluster, anotherCluster;
var unionedMarkers = [];
i = 0;
- var hit = false;
+ var tmp, hit = false;
while (i < sortedClusters.length) {
cluster = sortedClusters[i];
hit = false;
@@ -437,7 +473,16 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
anotherCluster = sortedClusters[j];
var distance = spherical.computeDistanceBetween(cluster._markerCenter, anotherCluster._markerCenter);
if (distance < clusterDistance) {
+ if (cluster.getItemLength() < anotherCluster.getItemLength()) {
+ tmp = anotherCluster;
+ anotherCluster = cluster;
+ cluster = tmp;
+ }
+ if (self.debug) {
+ console.log("---> (js)delete:" + anotherCluster.geocell);
+ }
cluster.addMarkers(anotherCluster.getMarkers());
+ deleteClusters[anotherCluster.geocell] = 1;
delete self._clusters[resolution][anotherCluster.geocell];
self._clusters[resolution][cluster.geocell] = cluster;
i = j;
@@ -469,8 +514,14 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
if (cluster.getMode() === cluster.NO_CLUSTER_MODE) {
cluster.getMarkers().forEach(function(marker, idx) {
deleteClusters[marker.getId()] = 1;
+ if (self.debug) {
+ console.log("---> (js)delete:" + marker.getId());
+ }
});
}
+ if (self.debug) {
+ console.log("---> (js)add:" + clusterOpts.id);
+ }
cluster.setMode(cluster.CLUSTER_MODE);
new_or_update_clusters.push(clusterOpts);
return;
@@ -480,6 +531,10 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
delete deleteClusters[marker.getId()];
var markerOptions = marker.getOptions();
markerOptions.count = 1;
+ markerOptions.title = marker.getId();
+ if (self.debug) {
+ console.log("---> (js)add:" + marker.getId());
+ }
new_or_update_clusters.push(markerOptions);
});
cluster.setMode(cluster.NO_CLUSTER_MODE);
@@ -492,6 +547,9 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
if (visibleRegion.contains(marker.getPosition())) {
var markerOptions = marker.getOptions();
markerOptions.count = 1;
+ if (self.debug) {
+ console.log("---> (js)add:" + marker.getId());
+ }
delete deleteClusters[marker.getId()];
marker.set("isAdded", true, true);
new_or_update_clusters.push(markerOptions);
@@ -501,10 +559,14 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
}
var delete_clusters = Object.keys(deleteClusters);
if (new_or_update_clusters.length === 0 && delete_clusters === 0) {
+ self.nextTask();
return;
}
- exec(null, self.errorHandler, self.getPluginName(), 'redrawClusters', [self.getId(), {
+
+ exec(function() {
+ self.nextTask();
+ }, self.errorHandler, self.getPluginName(), 'redrawClusters', [self.getId(), {
"resolution": resolution,
"new_or_update": new_or_update_clusters,
"delete": delete_clusters
@@ -512,6 +574,11 @@ MarkerCluster.prototype.redraw = function(clusterDistance, force) {
};
+MarkerCluster.prototype.nextTask = function() {
+ var self = this;
+ self.redraw();
+};
+
MarkerCluster.prototype.getClusterIcon = function(cluster) {
var self = this,
hit,

Bug fix: After zoom out the markers are still on the map, clusters are shown too. (#1)

Only Android at this time.