In June 2018, Google decided to start charging consumers for the use of their Maps API (along with the rest of their APIs), as long as they went beyond 100.000 loads of static maps. We faced a similar situation with a client, so we strongly believe this resolution is worthwhile sharing with our fellow readers.
For AEM 6.2 we came up with a clever solution: no, you won’t need to sell your soul to the devil or summon any sort of God to help you with this. You just got to be smart about it. So without further ado, here are the steps for not falling into Google’s trap:
First, you’ve got to load the map (just once) and save this image into the DAM. So next time you load the page, the maps will load directly from the DAM without making a call to the Google Maps API.
Next, create the URL into a class to request the map’s image to the Google Maps’ API. Get the following parameters: the Google key and the map’s data (scale, format, mapType, size, latitude, longitude, zoom, and markers).
Third, build the URL and create the connection. The URL should look something like this:
https://maps.googleapis.com/maps/api/staticmap?center=40.718217,-73.998284&zoom=13&size=600×300&maptype=roadmap&markers=color:red%7Clabel:7C40.718217,-73.998284&key=yourKey
Then, follow up by creating a method in the service; this will store the image’s response into the DAM.
private Asset storeImage(ResourceResolver resourceResolver, String imgPath, SlingHttpServletRequest request) {
try {
String latitude = request.getParameter("latitude");
String longitude = request.getParameter("longitude");
String zoom = request.getParameter("zoom");
Boolean gmapMarker = request.getParameter("includeGmapMarker") != null ? true : false;
GoogleMapsConnection connection = new GoogleMapsConnection();
List<Location> locations = getAllLocations(request);
InputStream in = connection.createConnection(key, scale, format, mapType, size, locations, latitude, longitude, zoom,gmapMarker);
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "LocationsImageService");
ResourceResolver serviceResourceResolver = resolverFactory.getServiceResourceResolver(param);
if(serviceResourceResolver != null){
AssetManager manager = serviceResourceResolver.adaptTo(AssetManager.class);
Asset asset = manager.createAsset(imgPath, in, String.format("image/%s", format), true);
in.close();
return asset;
}else{
log.warn("Configuration error. Could not get service ResourceResolver for LocationsImageService.");
}
} catch (IOException | LoginException e) {
log.warn(e.getMessage());
}
return null;
}
If you happen to need to load the image of a map, first check if it already exists in the DAM folder (where the saved maps are located). If not found, you will need to search the image directly from Google Maps’ API and save it.
public static String getGmapURL(Location location, ResourceResolver resolver, String query){
String pathQuery = PathUtils.getSourcePath(query);
String gmapDAMPath = String.format("/content/dam/"+ pathQuery +"/website/maps/%s/%s-%s-%s", location.getName().charAt(0),location.getId(), location.getCoords().getLat(), location.getCoords().getLon());
if (resolver.getResource(gmapDAMPath) != null ) {
return gmapDAMPath +"/image";
}else {
return String.format("/bin/chi-digital-style-guide/locations/image?componentPath="+gmapDAMPath+"&latitude=%s&longitude=%s&zoom=%s&includeGmapMarker=true",location.getCoords().getLat(), location.getCoords().getLon(), 14);
}
}
After that, create a system user and a group. Remember to give access to the /useradmin to modify, read, create, and delete the folder in the DAM. Also, create an ACL within the DAM folder of the CRX giving it privileges to jcr:read and jcr:write.
This way, it will call the API one time per image – and not every time the page is loaded by the user.
Keep in mind that you’ll need a Google Key. Of course, Google will charge a monthly fee for this, but it will definitely be way cheaper in the long run. Remember, the goal of this article is for you to stop overpaying.
public static String getGmapURL(Location location, ResourceResolver resolver, String query){
String pathQuery = PathUtils.getSourcePath(query);
String gmapDAMPath = String.format("/content/dam/"+ pathQuery +"/website/maps/%s/%s-%s-%s", location.getName().charAt(0),location.getId(), location.getCoords().getLat(), location.getCoords().getLon());
if (resolver.getResource(gmapDAMPath) != null ) {
return gmapDAMPath +"/image";
}else {
return String.format("/bin/chi-digital-style-guide/locations/image?componentPath="+gmapDAMPath+"&latitude=%s&longitude=%s&zoom=%s&includeGmapMarker=true",location.getCoords().getLat(), location.getCoords().getLon(), 14);
}
}
After that, create a system user and a group. Remember to give access to the /useradmin to modify, read, create, and delete the folder in the DAM. Also, create an ACL within the DAM folder of the CRX giving it privileges to jcr:read and jcr:write.
This way, it will call the API one time per image – and not every time the page is loaded by the user.
Keep in mind that you’ll need a Google Key. Of course, Google will charge a monthly fee for this, but it will definitely be way cheaper in the long run. Remember, the goal of this article is for you to stop overpaying.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.