long startTime = System.currentTimeMillis();
int initSize = knownMarkers.size();
List<String> markersFromThisUpdate = new ArrayList<String>();
for (int i = 0; i < array.size(); i++) {
JSONObject jsMarker;
JSONString jsMID, jsTitle, jsIcon;
JSONNumber jsLat, jsLng;
JSONBoolean jsVisible, jsHasInfo, jsDraggable;
Marker marker = null;
boolean isOldMarker = false;
boolean replaceMarker = false;
if ((jsMarker = array.get(i).isObject()) == null) {
continue;
}
// Read marker id
if ((value = jsMarker.get("mid")) == null) {
continue;
}
if ((jsMID = value.isString()) == null) {
continue;
}
if ((value = jsMarker.get("draggable")) == null) {
continue;
} else {
if (knownMarkers.containsKey(jsMID.toString())) {
marker = knownMarkers.get(jsMID.toString());
marker.setDraggingEnabled((((JSONBoolean) jsMarker
.get("draggable")).booleanValue()));
isOldMarker = true;
}
}
// Add maker to list of markers in this update
markersFromThisUpdate.add(jsMID.toString());
// Read marker latitude
if ((value = jsMarker.get("lat")) == null) {
if (!isOldMarker)
continue;
}
if ((jsLat = value.isNumber()) == null) {
if (!isOldMarker)
continue;
}
// Read marker longitude
if ((value = jsMarker.get("lng")) == null) {
if (!isOldMarker)
continue;
}
if ((jsLng = value.isNumber()) == null) {
if (!isOldMarker)
continue;
} else {
// marker.setLatLng(jsLng.doubleValue());
}
// Read marker title
if ((value = jsMarker.get("title")) == null) {
if (!isOldMarker)
continue;
}
if ((jsTitle = value.isString()) == null) {
if (!isOldMarker)
continue;
} else {
if (isOldMarker && marker != null) {
String title = marker.getTitle();
// if title is changed
if (!jsTitle.stringValue().equals(title)) {
replaceMarker = true;
log(1, "Title changed: " + marker.getTitle());
}
}
}
// Read marker visibility
if ((value = jsMarker.get("visible")) == null) {
if (!isOldMarker)
continue;
}
if ((jsVisible = value.isBoolean()) == null) {
if (!isOldMarker)
continue;
} else {
if (marker != null) {
boolean old = marker.isVisible();
marker.setVisible(jsVisible.booleanValue());
if (old != marker.isVisible()) {
log(1,
"Toggled marker '" + marker.getTitle()
+ "' visibility to "
+ jsVisible.booleanValue());
}
}
}
// Read marker draggability (is that a word? :)
if ((value = jsMarker.get("draggable")) == null) {
if (!isOldMarker)
continue;
}
if ((jsDraggable = value.isBoolean()) == null) {
if (!isOldMarker)
continue;
}
// Change position, if changed
if (marker != null && jsLat != null && jsLng != null
&& marker.getLatLng() != null) {
LatLng llang = marker.getLatLng();
LatLng llang2 = LatLng.newInstance(jsLat.doubleValue(),
jsLng.doubleValue());
if (!llang.isEquals(llang2)) {
marker.setLatLng(llang2);
}
}
// Read marker icon
if ((value = jsMarker.get("icon")) == null) {
jsIcon = null;
if (marker != null) {
String currentURL = getMarkerIconURL(marker);
if (!currentURL
.startsWith("http://maps.gstatic.com")
&& currentURL != null && currentURL != "") {
replaceMarker = true;
log(1, "Icon url changed " + marker.getTitle()
+ " from '" + currentURL + "'");
}
}
} else if ((jsIcon = value.isString()) == null) {
if (!isOldMarker)
continue;
} else {
if (marker != null
&& getMarkerIconURL(marker) != jsIcon
.toString()) {
replaceMarker = true;
log(1, "Icon url changed 2 " + marker.getTitle());
}
}
int iconAnchorX = 0;
if ((value = jsMarker.get("iconAnchorX")) != null) {
JSONNumber jsAnchorX;
if ((jsAnchorX = value.isNumber()) != null) {
log(1, "Anchor X: " + jsAnchorX.toString());
iconAnchorX = (int) Math.round(jsAnchorX
.doubleValue());
} else {
log(1, "Anchor X NaN");
}
}
int iconAnchorY = 0;
if ((value = jsMarker.get("iconAnchorY")) != null) {
JSONNumber jsAnchorY;
if ((jsAnchorY = value.isNumber()) != null) {
iconAnchorY = (int) Math.round(jsAnchorY
.doubleValue());
}
}
// do not create new one if old found (only if we want to
// replace it)
if (isOldMarker && !replaceMarker)
continue;
if (!isOldMarker)
replaceMarker = false; // Never replace a marker if
// there is no previous one
if (replaceMarker) {
log(1, "Replacing marker " + marker.getTitle());
map.removeOverlay(marker);
markersFromThisUpdate.remove(marker);
}
marker = createMarker(jsLat, jsLng, jsTitle, jsVisible,
jsIcon, iconAnchorX, iconAnchorY, jsDraggable);
if (marker != null) {
map.addOverlay(marker);
// Add dragEnd handlers to marker
marker.addMarkerDragEndHandler(VGoogleMap.this);
// Read boolean telling if marker has a info window
if ((value = jsMarker.get("info")) != null) {
if ((jsHasInfo = value.isBoolean()) != null
&& jsHasInfo.booleanValue()) {
marker.addMarkerClickHandler(new InfoWindowOpener(
jsMID.stringValue()));