Bug fix:  icon image is not displayed, and map is not displayed after coming back to the map page
MODIFY
src/android/plugin/google/maps/AsyncLoadImage.java
src/android/plugin/google/maps/AsyncLoadImage.java
@@ -128,6 +128,7 @@ public class AsyncLoadImage extends AsyncTask<Void, Void, AsyncLoadImage.AsyncLo
}
this.currentPageUrl = webView.getUrl();
+ Log.d(TAG, "-->currentPageUrl = " + this.currentPageUrl);
View browserView = webView.getView();
String browserViewName = browserView.getClass().getName();
@@ -167,6 +168,64 @@ public class AsyncLoadImage extends AsyncTask<Void, Void, AsyncLoadImage.AsyncLo
return null;
}
+ //Log.d(TAG, "--> iconUrl = " + iconUrl);
+ //--------------------------------
+ // Load image from local path
+ //--------------------------------
+ if (!iconUrl.startsWith("data:image")) {
+ if (!iconUrl.contains("://") &&
+ !iconUrl.startsWith("/") &&
+ !iconUrl.startsWith("www/") &&
+ !iconUrl.startsWith("data:image") &&
+ !iconUrl.startsWith("./") &&
+ !iconUrl.startsWith("../")) {
+ iconUrl = "./" + iconUrl;
+ //Log.d(TAG, "--> iconUrl = " + iconUrl);
+ }
+
+ if (iconUrl.startsWith("./") || iconUrl.startsWith("../")) {
+ iconUrl = iconUrl.replace("(\\.\\/)+", "./");
+ String currentPage = this.currentPageUrl;
+ currentPage = currentPage.replaceAll("[^\\/]*$", "");
+ currentPage = currentPage.replaceAll("#.*$", "");
+ currentPage = currentPage.replaceAll("\\/[^\\/]+\\.[^\\/]+$", "");
+ if (!currentPage.endsWith("/")) {
+ currentPage = currentPage + "/";
+ }
+ iconUrl = currentPage + iconUrl;
+ iconUrl = iconUrl.replaceAll("(\\/\\.\\/+)+", "/");
+ //Log.d(TAG, "--> iconUrl = " + iconUrl);
+ }
+
+ if (iconUrl.indexOf("file://") == 0 &&
+ !iconUrl.contains("file:///android_asset/")) {
+ iconUrl = iconUrl.replace("file://", "");
+ } else {
+ //Log.d(TAG, "--> iconUrl = " + iconUrl);
+
+ if (iconUrl.indexOf("file:///android_asset/") == 0) {
+ iconUrl = iconUrl.replace("file:///android_asset/", "");
+ }
+
+ //Log.d(TAG, "iconUrl = " + iconUrl);
+ if (iconUrl.contains("./")) {
+ try {
+ boolean isAbsolutePath = iconUrl.startsWith("/");
+ File relativePath = new File(iconUrl);
+ iconUrl = relativePath.getCanonicalPath();
+ //Log.d(TAG, "iconUrl = " + iconUrl);
+ if (!isAbsolutePath) {
+ iconUrl = iconUrl.substring(1);
+ }
+ //Log.d(TAG, "iconUrl = " + iconUrl);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
String cacheKey = null;
if (iconUrl.indexOf("http") == 0) {
//--------------------------------
@@ -296,6 +355,35 @@ public class AsyncLoadImage extends AsyncTask<Void, Void, AsyncLoadImage.AsyncLo
} else {
+ //Log.d(TAG, "--> iconUrl = " + iconUrl);
+ cacheKey = getCacheKey(iconUrl, mWidth, mHeight);
+
+ image = getBitmapFromMemCache(cacheKey);
+ if (image != null) {
+ AsyncLoadImageResult result = new AsyncLoadImageResult();
+ result.image = image;
+ result.cacheHit = true;
+ result.cacheKey = cacheKey;
+ return result;
+ }
+ if (iconUrl.indexOf("data:image/") == 0 && iconUrl.contains(";base64,")) {
+
+
+ String[] tmp = iconUrl.split(",");
+ image = PluginUtil.getBitmapFromBase64encodedImage(tmp[1]);
+ } else {
+ AssetManager assetManager = cordova.getActivity().getAssets();
+ InputStream inputStream;
+ try {
+ inputStream = assetManager.open(iconUrl);
+ image = BitmapFactory.decodeStream(inputStream);
+ inputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ /*
//--------------------------------
// Load image from local path
//--------------------------------
@@ -306,13 +394,21 @@ public class AsyncLoadImage extends AsyncTask<Void, Void, AsyncLoadImage.AsyncLo
!iconUrl.startsWith("./") &&
!iconUrl.startsWith("../")) {
iconUrl = "./" + iconUrl;
+ Log.d(TAG, "--> iconUrl = " + iconUrl);
}
if (iconUrl.startsWith("./") || iconUrl.startsWith("../")) {
iconUrl = iconUrl.replace("(\\.\\/)+", "./");
String currentPage = this.currentPageUrl;
currentPage = currentPage.replaceAll("[^\\/]*$", "");
- iconUrl = currentPage + "/" + iconUrl;
+ currentPage = currentPage.replaceAll("#.*$", "");
+ currentPage = currentPage.replaceAll("\\/[^\\/]+\\.[^\\/]+$", "");
+ if (!currentPage.endsWith("/")) {
+ currentPage = currentPage + "/";
+ }
+ iconUrl = currentPage + iconUrl;
+ iconUrl = iconUrl.replaceAll("(\\/\\.\\/+)+", "/");
+ Log.d(TAG, "--> iconUrl = " + iconUrl);
}
if (iconUrl.indexOf("data:image/") == 0 && iconUrl.contains(";base64,")) {
@@ -353,7 +449,7 @@ public class AsyncLoadImage extends AsyncTask<Void, Void, AsyncLoadImage.AsyncLo
return null;
}
} else {
- //Log.d(TAG, "--> iconUrl = " + iconUrl);
+ Log.d(TAG, "--> iconUrl = " + iconUrl);
cacheKey = getCacheKey(iconUrl, mWidth, mHeight);
image = getBitmapFromMemCache(cacheKey);
@@ -365,38 +461,29 @@ public class AsyncLoadImage extends AsyncTask<Void, Void, AsyncLoadImage.AsyncLo
return result;
}
- //Log.d(TAG, "iconUrl = " + iconUrl);
+ Log.d(TAG, "iconUrl = " + iconUrl);
if (iconUrl.indexOf("file:///android_asset/") == 0) {
iconUrl = iconUrl.replace("file:///android_asset/", "");
}
- //Log.d(TAG, "iconUrl = " + iconUrl);
+ Log.d(TAG, "iconUrl = " + iconUrl);
if (iconUrl.contains("./")) {
try {
boolean isAbsolutePath = iconUrl.startsWith("/");
File relativePath = new File(iconUrl);
iconUrl = relativePath.getCanonicalPath();
- //Log.d(TAG, "iconUrl = " + iconUrl);
+ Log.d(TAG, "iconUrl = " + iconUrl);
if (!isAbsolutePath) {
iconUrl = iconUrl.substring(1);
}
- //Log.d(TAG, "iconUrl = " + iconUrl);
+ Log.d(TAG, "iconUrl = " + iconUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
+ */
- AssetManager assetManager = cordova.getActivity().getAssets();
- InputStream inputStream;
- try {
- inputStream = assetManager.open(iconUrl);
- image = BitmapFactory.decodeStream(inputStream);
- inputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- }
+ //}
if (mWidth > 0 && mHeight > 0) {
mWidth = Math.round(mWidth * density);

MODIFY
src/ios/GoogleMaps/PluginMarker.m
src/ios/GoogleMaps/PluginMarker.m
if (self.mapCtrl.debuggable) {
NSLog(@"---- setIcon_ : %@", iconPath);
}
+
+ // `animation` property
+ NSString *animationValue = nil;
+ if ([iconProperty valueForKey:@"animation"]) {
+ animationValue = [iconProperty valueForKey:@"animation"];
+ }
+ __block NSString *animation = animationValue;
+
+ //--------------------------------
+ // the icon property is color name
+ //--------------------------------
+ NSLog(@"iconProperty = %@", iconProperty);
+ if ([iconProperty valueForKey:@"iconColor"]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIColor *iconColor = [iconProperty valueForKey:@"iconColor"];
+ marker.icon = [GMSMarker markerImageWithColor:iconColor];
+
+ // The `visible` property
+ if (iconProperty[@"visible"]) {
+ marker.map = self.mapCtrl.map;
+ }
+
+ if (animation) {
+ // Do animation, then send the result
+ [self setMarkerAnimation_:animation marker:marker callbackBlock:^(void) {
+ callbackBlock(YES, marker);
+ }];
+ } else {
+ // Send the result
+ callbackBlock(YES, marker);
+ }
+ });
+ return;
+ }
+
+ if (iconPath == nil) {
+ callbackBlock(NO, @"icon property is null");
+ return;
+ }
+
// `size` property
if ([iconProperty valueForKey:@"size"]) {
NSDictionary *size = [iconProperty valueForKey:@"size"];
height = [[size objectForKey:@"height"] floatValue];
}
- // `animation` property
- NSString *animationValue = nil;
- if ([iconProperty valueForKey:@"animation"]) {
- animationValue = [iconProperty valueForKey:@"animation"];
+
+
+
+
+
+
+
+
+
+ if (self.mapCtrl.debuggable) {
+ NSLog(@"iconPath = %@", iconPath);
}
- __block NSString *animation = animationValue;
+
+ NSRange range = [iconPath rangeOfString:@"data:image"];
+ if (range.location != 0) {
+
+ if (![iconPath containsString:@"://"] &&
+ ![iconPath hasPrefix:@"/"] &&
+ ![iconPath hasPrefix:@"www"] &&
+ ![iconPath hasPrefix:@"./"] &&
+ ![iconPath hasPrefix:@"../"]) {
+ iconPath = [NSString stringWithFormat:@"./%@", iconPath];
+ }
+
+ if ([iconPath hasPrefix:@"./"] || [iconPath hasPrefix:@"../"]) {
+ NSError *error = nil;
+
+ // replace repeated "./" (i.e ./././test.png)
+ NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\.\\/)+" options:NSRegularExpressionCaseInsensitive error:&error];
+ iconPath = [regex stringByReplacingMatchesInString:iconPath options:0 range:NSMakeRange(0, [iconPath length]) withTemplate:@"./"];
+
+
+ // Get the current URL, then calculate the relative path.
+ CDVViewController *cdvViewController = (CDVViewController*)self.viewController;
+
+ id webview = cdvViewController.webView;
+ NSString *clsName = [webview className];
+ NSURL *url;
+ if ([clsName isEqualToString:@"UIWebView"]) {
+ url = ((UIWebView *)cdvViewController.webView).request.URL;
+ } else {
+ url = [webview URL];
+ }
+ NSString *currentURL = url.absoluteString;
+
+ // remove page unchor (i.e index.html#page=test, index.html?key=value)
+ regex = [NSRegularExpression regularExpressionWithPattern:@"[#\\?].*$" options:NSRegularExpressionCaseInsensitive error:&error];
+ currentURL = [regex stringByReplacingMatchesInString:currentURL options:0 range:NSMakeRange(0, [currentURL length]) withTemplate:@""];
+
+ // remove file name (i.e /index.html)
+ regex = [NSRegularExpression regularExpressionWithPattern:@"\\/[^\\/]+\\.[^\\/]+$" options:NSRegularExpressionCaseInsensitive error:&error];
+ currentURL = [regex stringByReplacingMatchesInString:currentURL options:0 range:NSMakeRange(0, [currentURL length]) withTemplate:@""];
+
+ if (![currentURL hasSuffix:@"/"]) {
+ currentURL = [NSString stringWithFormat:@"%@/", currentURL];
+ }
+ iconPath = [NSString stringWithFormat:@"%@%@", currentURL, iconPath];
+
+ // remove file name (i.e /index.html)
+ regex = [NSRegularExpression regularExpressionWithPattern:@"(\\/\\.\\/+)+" options:NSRegularExpressionCaseInsensitive error:&error];
+ iconPath = [regex stringByReplacingMatchesInString:iconPath options:0 range:NSMakeRange(0, [iconPath length]) withTemplate:@"/"];
+ NSLog(@"--->iconPath = %@", iconPath);
+ }
+
+
+ range = [iconPath rangeOfString:@"cdvfile://"];
+ if ([iconPath hasPrefix:@"cdvfile://"]) {
+
+ iconPath = [PluginUtil getAbsolutePathFromCDVFilePath:self.webView cdvFilePath:iconPath];
+
+ if (iconPath == nil) {
+ if (self.mapCtrl.debuggable) {
+ NSLog(@"(debug)Can not convert '%@' to device full path.", iconPath);
+ }
+ //[self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
+ callbackBlock(NO, [NSString stringWithFormat:@"Can not convert '%@' to device full path.", iconPath]);
+ return;
+ }
+ }
+
+
+ UIImage *image;
+
+ range = [iconPath rangeOfString:@"://"];
+
+ if (range.location == 0) {
+ /**
+ * Load the icon from local path
+ */
+
+ if ([iconPath hasPrefix:@"/"]) {
+ // Get the current URL, then calculate the relative path.
+ CDVViewController *cdvViewController = (CDVViewController*)self.viewController;
+
+ id webview = cdvViewController.webView;
+ NSString *clsName = [webview className];
+ NSURL *url;
+ if ([clsName isEqualToString:@"UIWebView"]) {
+ url = ((UIWebView *)cdvViewController.webView).request.URL;
+ } else {
+ url = [webview URL];
+ }
+ NSString *currentURL = url.absoluteString;
+ currentURL = [currentURL stringByDeletingLastPathComponent];
+ currentURL = [currentURL stringByReplacingOccurrencesOfString:@"file:" withString:@""];
+ currentURL = [currentURL stringByReplacingOccurrencesOfString:@"//" withString:@"/"];
+ iconPath = [NSString stringWithFormat:@"file://%@/%@", currentURL, iconPath];
+ } else {
+ iconPath = [NSString stringWithFormat:@"file://%@", iconPath];
+ }
+ }
+
+ if ([iconPath hasPrefix:@"file://"]) {
+ iconPath = [iconPath stringByReplacingOccurrencesOfString:@"file://" withString:@""];
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ if (![fileManager fileExistsAtPath:iconPath]) {
+ //if (self.mapCtrl.debuggable) {
+ NSLog(@"(error)There is no file at '%@'.", iconPath);
+ //}
+ //[self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId];
+ callbackBlock(NO, [NSString stringWithFormat:@"There is no file at '%@'.", iconPath]);
+ return;
+ }
+ }
+
+ image = [UIImage imageNamed:iconPath];
+
+ if (width && height) {
+ image = [image resize:width height:height];
+ }
+ }
+
+
+
+
+
+
+
+
+ //---------------------------------------
+ // If the image is cached, return it
+ //---------------------------------------
NSString *iconCacheKey = [NSString stringWithFormat:@"%lu/%d,%d", (unsigned long)iconPath.hash, (int)width, (int)height];
NSData *cache = [self.icons objectForKey:iconCacheKey];
return;
}
+
+
+
+
+
if (iconPath) {
+ NSLog(@"1030 iconPath = %@", iconPath);
if (self.mapCtrl.debuggable) {
NSLog(@"iconPath = %@", iconPath);
/**
* Load the icon from local path
*/
-
+/*
range = [iconPath rangeOfString:@"cdvfile://"];
if (range.location != NSNotFound) {
return;
}
}
-
+*/
image = [UIImage imageNamed:iconPath];
if (width && height) {
}
- } else if ([iconProperty valueForKey:@"iconColor"]) {
- dispatch_async(dispatch_get_main_queue(), ^{
- UIColor *iconColor = [iconProperty valueForKey:@"iconColor"];
- marker.icon = [GMSMarker markerImageWithColor:iconColor];
-
- // The `visible` property
- if (iconProperty[@"visible"]) {
- marker.map = self.mapCtrl.map;
- }
-
- if (animation) {
- // Do animation, then send the result
- [self setMarkerAnimation_:animation marker:marker callbackBlock:^(void) {
- callbackBlock(YES, marker);
- }];
- } else {
- // Send the result
- callbackBlock(YES, marker);
- }
- });
-
}
}

MODIFY
www/Map.js
www/Map.js
@@ -519,12 +519,9 @@ Map.prototype.remove = function(callback) {
div = div.parentNode;
}
}
- self.trigger("remove");
self.set('div', undefined);
- self.clear();
- self.empty();
- self.off();
exec(function() {
+ self.trigger("remove");
if (typeof callback === "function") {
callback.call(self);
}

MODIFY
www/googlemaps-cdv-plugin.js
www/googlemaps-cdv-plugin.js
@@ -471,9 +471,9 @@ if (!cordova) {
*/
map.one('remove', function() {
document.removeEventListener(mapId, nativeCallback);
- MAPS[mapId].clear();
+ MAPS[mapId].destroy();
delete MAPS[mapId];
- map = null;
+ map = undefined;
});
MAP_CNT++;
MAPS[mapId] = map;
@@ -642,7 +642,7 @@ function _exec() {
}
_isResizeMapExecuting = true;
}
- if (_stopRequested && methodName !== "remove") {
+ if (_stopRequested && (methodName !== "remove" || methodName !== "clear")) {
_executingCnt--;
continue;
}

Bug fix:  icon image is not displayed, and map is not displayed after coming back to the map page #1614