Bug fix: Marker cluster is unstable when add a marker
MODIFY
src/android/plugin/google/maps/PluginMarkerCluster.java
src/android/plugin/google/maps/PluginMarkerCluster.java
@@ -144,6 +144,7 @@ public class PluginMarkerCluster extends PluginMarker {
if (self.objects.containsKey(clusterId_markerId) || pluginMarkers.containsKey(clusterId_markerId)) {
updateClusterIDs.put(clusterId_markerId, clusterId_markerId);
} else {
+
if (reuseCnt < deleteCnt) {
//---------------
// Reuse a marker
@@ -332,10 +333,10 @@ public class PluginMarkerCluster extends PluginMarker {
}
}
}
+ marker.hideInfoWindow();
markerProperties = changeProperties.get(newMarkerId);
if (STATUS.DELETED.equals(pluginMarkers.get(newMarkerId))) {
-
synchronized (waitCntManager) {
int waitCnt = waitCntManager.get(clusterId);
waitCnt = waitCnt - 1;
@@ -462,6 +463,9 @@ public class PluginMarkerCluster extends PluginMarker {
// No icon for marker
//--------------------
marker.setIcon(null);
+ synchronized (pluginMarkers) {
+ pluginMarkers.put(targetMarkerId, STATUS.CREATED);
+ }
synchronized (waitCntManager) {
int waitCnt = waitCntManager.get(clusterId);
waitCnt = waitCnt - 1;
@@ -484,10 +488,10 @@ public class PluginMarkerCluster extends PluginMarker {
iterator = deleteClusterIDs.iterator();
while (iterator.hasNext()) {
oldMarkerId = iterator.next();
- //Log.d(TAG, "delete : " + oldMarkerId);
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);

MODIFY
src/ios/GoogleMaps/PluginMarkerCluster.m
src/ios/GoogleMaps/PluginMarkerCluster.m
@@ -289,6 +289,8 @@ NSObject *dummyObject;
marker.tracksInfoWindowChanges = NO;
marker.map = nil;
}
+ } else {
+ marker.map = nil;
}
}
@@ -316,7 +318,6 @@ NSObject *dummyObject;
marker.snippet = nil;
}
marker.userData = newMarkerId;
- marker.map = self.mapCtrl.map;
targetMarkerId = newMarkerId;
if ([markerProperties objectForKey:@"geocell"]) {
@@ -377,10 +378,16 @@ NSObject *dummyObject;
[self setIconToClusterMarker:targetMarkerId marker:marker iconProperty:icon callbackBlock:^(BOOL successed, id resultObj) {
if (successed == NO) {
NSLog(@"(error) %@", resultObj);
+ } else {
+ marker.map = self_.mapCtrl.map;
}
[self_ decreaseWaitCntOrExit:clusterId command:command];
}];
} else {
+ marker.map = self.mapCtrl.map;
+ @synchronized (self.pluginMarkers) {
+ [self.pluginMarkers setObject:@"CREATED" forKey:targetMarkerId];
+ }
[self decreaseWaitCntOrExit:clusterId command:command];
marker.icon = nil;
}

MODIFY
www/Common.js
www/Common.js
@@ -537,6 +537,56 @@ function convertToPositionArray(array) {
return array;
}
+function markerOptionsFilter(markerOptions) {
+ markerOptions = markerOptions || {};
+
+ markerOptions.animation = markerOptions.animation || undefined;
+ markerOptions.position = markerOptions.position || {};
+ markerOptions.position.lat = markerOptions.position.lat || 0.0;
+ markerOptions.position.lng = markerOptions.position.lng || 0.0;
+ markerOptions.draggable = markerOptions.draggable === true;
+ markerOptions.icon = markerOptions.icon || undefined;
+ markerOptions.snippet = typeof(markerOptions.snippet) === "string" ? markerOptions.snippet : undefined;
+ markerOptions.title = typeof(markerOptions.title) === "string" ? markerOptions.title : undefined;
+ markerOptions.visible = defaultTrueOption(markerOptions.visible);
+ markerOptions.flat = markerOptions.flat === true;
+ markerOptions.rotation = markerOptions.rotation || 0;
+ markerOptions.opacity = parseFloat("" + markerOptions.opacity, 10) || 1;
+ markerOptions.disableAutoPan = markerOptions.disableAutoPan === true;
+ markerOptions.useHtmlInfoWnd = !markerOptions.title && !markerOptions.snippet;
+ markerOptions.noCache = markerOptions.noCache === true; //experimental
+ if (typeof markerOptions.icon === "object") {
+ if ("anchor" in markerOptions.icon &&
+ !Array.isArray(markerOptions.icon.anchor) &&
+ "x" in markerOptions.icon.anchor &&
+ "y" in markerOptions.icon.anchor) {
+ markerOptions.icon.anchor = [markerOptions.icon.anchor.x, markerOptions.icon.anchor.y];
+ }
+ if ("infoWindowAnchor" in markerOptions.icon &&
+ !Array.isArray(markerOptions.icon.infoWindowAnchor) &&
+ "x" in markerOptions.icon.infoWindowAnchor &&
+ "y" in markerOptions.icon.infoWindowAnchor) {
+ markerOptions.icon.infoWindowAnchor = [markerOptions.icon.infoWindowAnchor.x, markerOptions.infoWindowAnchor.anchor.y];
+ }
+ }
+
+ if ("styles" in markerOptions) {
+ markerOptions.styles = typeof markerOptions.styles === "object" ? markerOptions.styles : {};
+
+ if ("color" in markerOptions.styles) {
+ markerOptions.styles.color = HTMLColor2RGBA(markerOptions.styles.color || "#000000");
+ }
+ }
+ if (markerOptions.icon && isHTMLColorString(markerOptions.icon)) {
+ markerOptions.icon = HTMLColor2RGBA(markerOptions.icon);
+ }
+ if (markerOptions.icon && markerOptions.icon.label &&
+ isHTMLColorString(markerOptions.icon.label.color)) {
+ markerOptions.icon.label.color = HTMLColor2RGBA(markerOptions.icon.label.color);
+ }
+ return markerOptions;
+}
+
module.exports = {
getZIndex: getZIndex,
getDomDepth: getDomDepth,
@@ -553,5 +603,6 @@ module.exports = {
getStyle: getStyle,
convertToPositionArray: convertToPositionArray,
getLatLng: getLatLng,
- shouldWatchByNative: shouldWatchByNative
+ shouldWatchByNative: shouldWatchByNative,
+ markerOptionsFilter: markerOptionsFilter
};

MODIFY
www/MarkerCluster.js
www/MarkerCluster.js
@@ -81,45 +81,17 @@ var MarkerCluster = function(map, id, markerClusterOptions) {
markerOptions = common.markerOptionsFilter(markerOptions);
var geocell = geomodel.getGeocell(markerOptions.position.lat, markerOptions.position.lng, 9);
-
var marker = new Marker(self, "marker_" + idxCount, markerOptions, "markercluster");
- marker.set("isAdded", true);
+ marker.set("isAdded", false);
marker.set("geocell", geocell);
marker.set("position", markerOptions.position);
self._markers.push(marker);
-
- // Add or pdate the cluster
-
- var geocell = geocell.substr(0, resolution + 1)
- var clusterId = geocell;
- var cluster = self.getClusterByGeocellAndResolution(geocell, resolution);
- cluster.addMarkers([marker]);
- var clusterIcon = self.getClusterIcon(cluster);
- if (!clusterIcon) {
- clusterIcon = markerOptions.icon;
- cluster.setMode(cluster.NO_CLUSTER_MODE);
- clusterId += ";" + (cluster.getItemLength() - 1);
- geocell = undefined;
- } else {
- cluster.setMode(cluster.CLUSTER_MODE);
- }
- var clusters = [{
- "count": cluster.getItemLength(),
- "position": markerOptions.position,
- "id": clusterId,
- "icon": clusterIcon,
- "geocell": geocell
- }];
-
- exec(null, self.errorHandler, self.getPluginName(), 'redrawClusters', [self.getId(), {
- "resolution": resolution,
- "new_or_update": clusters
- }]);
+ self.redraw(true);
};
map.on(event.CAMERA_MOVE_END, self.redraw.bind(self));
- self.redraw();
+ self.redraw(false);
return self;
};
@@ -154,7 +126,7 @@ MarkerCluster.prototype.getClusterByClusterId = function(clusterId) {
};
-MarkerCluster.prototype.redraw = function() {
+MarkerCluster.prototype.redraw = function(force) {
var self = this,
map = self.map,
currentZoomLevel = Math.floor(self.map.getCameraZoom()),
@@ -188,7 +160,7 @@ MarkerCluster.prototype.redraw = function() {
// Remove the clusters that is in outside of the visible region
//----------------------------------------------------------------
self._clusters[resolution] = self._clusters[resolution] || {};
- var deleteClusters = [];
+ var deleteClusters = {};
var cellLen = resolution + 1;
var keys;
if (prevResolution === -1) {
@@ -198,7 +170,7 @@ MarkerCluster.prototype.redraw = function() {
}
if (resolution !== -1 || !visibleRegion.contains(marker.getPosition())) {
marker.set("isAdded", false);
- deleteClusters.push(marker.getId());
+ deleteClusters[marker.getId()] = 1;
}
});
} else if (resolution === prevResolution) {
@@ -213,10 +185,10 @@ MarkerCluster.prototype.redraw = function() {
if (cluster.getMode() === cluster.NO_CLUSTER_MODE) {
cluster.getMarkers().forEach(function(marker, idx) {
- deleteClusters.push(marker.getId());
+ deleteClusters[marker.getId()] = 1;
});
} else {
- deleteClusters.push(geocell);
+ deleteClusters[geocell] = 1;
}
cluster.remove();
delete self._clusters[resolution][geocell];
@@ -229,10 +201,10 @@ MarkerCluster.prototype.redraw = function() {
cluster = self._clusters[prevResolution][geocell];
if (cluster.getMode() === cluster.NO_CLUSTER_MODE) {
cluster.getMarkers().forEach(function(marker, idx) {
- deleteClusters.push(marker.getId());
+ deleteClusters[marker.getId()] = 1;
});
} else {
- deleteClusters.push(geocell);
+ deleteClusters[geocell] = 1;
}
cluster.remove();
});
@@ -244,9 +216,10 @@ MarkerCluster.prototype.redraw = function() {
//--------------------------------
var prevSWcell = self.get("prevSWcell");
var prevNEcell = self.get("prevNEcell");
- var clusters = [];
+ var new_or_update_clusters = [];
- if (resolution !== prevResolution ||
+ if (force ||
+ resolution !== prevResolution ||
prevSWcell !== swCell ||
prevNEcell !== neCell) {
@@ -290,18 +263,19 @@ MarkerCluster.prototype.redraw = function() {
clusterOpts.icon = icon;
if (cluster.getMode() === cluster.NO_CLUSTER_MODE) {
cluster.getMarkers().forEach(function(marker, idx) {
- deleteClusters.push(marker.getId());
+ deleteClusters[marker.getId()] = 1;
});
}
cluster.setMode(cluster.CLUSTER_MODE);
- clusters.push(clusterOpts);
+ new_or_update_clusters.push(clusterOpts);
return;
}
cluster.getMarkers().forEach(function(marker, idx) {
+ delete deleteClusters[marker.getId()];
var markerOptions = marker.getOptions();
markerOptions.count = 1;
- clusters.push(markerOptions);
+ new_or_update_clusters.push(markerOptions);
});
cluster.setMode(cluster.NO_CLUSTER_MODE);
});
@@ -313,20 +287,22 @@ MarkerCluster.prototype.redraw = function() {
if (visibleRegion.contains(marker.getPosition())) {
var markerOptions = marker.getOptions();
markerOptions.count = 1;
+ delete deleteClusters[marker.getId()];
marker.set("isAdded", true);
- clusters.push(markerOptions);
+ new_or_update_clusters.push(markerOptions);
}
});
}
}
- if (clusters.length === 0 && deleteClusters === 0) {
+ var delete_clusters = Object.keys(deleteClusters);
+ if (new_or_update_clusters.length === 0 && delete_clusters === 0) {
return;
}
exec(null, self.errorHandler, self.getPluginName(), 'redrawClusters', [self.getId(), {
"resolution": resolution,
- "new_or_update": clusters,
- "delete": deleteClusters
+ "new_or_update": new_or_update_clusters,
+ "delete": delete_clusters
}]);

Bug fix: Marker cluster is unstable when add a marker