This
post summarizes the process of using Google Maps API with ServiceNow. With
the withdrawal of NPAPI API, the Google Earth plugin went out of the market. To
combat the situation, we used Google Maps Satellite view to provide almost the
same image.
The
points defined are –
- Using Google Maps API with SNOW
- Extracting Attachment Data to
Table
- Using Markers and Overlays
- Setting up the data on the map
Over
six years ago, Google has introduced the Google
Earth API enabling developers to build rich 3D mapping applications in the
browser using JavaScript. And over the years, developers have built quite a
number of fascinating applications.
However,
the Earth API is built on a technology called the NPAPI plugin framework,
and recently, for security reasons,
both Chrome and Firefox have announced that they’re
removing support for this framework. These security reasons, combined with
dwindling cross-platform support (particularly on mobile devices), had made
building applications that leverage the Earth API untenable for developers.
Therefore,
Google decided to retire the Google Earth API. The API was supported for one
more year and then turned off on December 12, 2015.
Due
to this reason, all the existing reports which were using Google Earth API will
no longer be functional now. We have to come up with an alternative.
Without
NPAPI plugin framework, we cannot have Google Earth. Chrome are Firefox are
leading browsers and are extensively used by almost everyone so we cannot take
the risk of not supporting these browsers. Also, we cannot guarantee that for
how long other browsers will keep on supporting this plugin.
ServiceNow
was facing the same issue. We can have map – based reports in ServiceNow as
well and many people can have it using the Google Earth API. All that would
have stopped working.
We
had such reports as well. These reports are used to show the statuses or
coverage zones of various sites planted at different geographical regions.
Below
is a screenshot of the earlier Google Earth view.
These
reports have to be map – based to provide a clear picture of the areas and
regions. This Google Earth plugin uses a KML (Keyhole Markup Language) file
with the plotting data in it being similar to XML tags to plot the images on
Map with the desired shape and size. It contains the east, west, north and
south point coordinates where the four corner lies and Google Earth plots them
in the same fashion.
To
combat the situation, the alternative we are using is the Satellite view of Google Maps. This is quite similar to
the Google Earth view but it is not a three – dimensional view. We can use the
same KMLs for plotting the data by fetching their data to a table and passing
that data to the Google Maps API functions.
The
KML file was present as an attachment to a particular table record. We fetched
the data from that KML to a SNOW table using XMLHelper. XMLHelper is used to fetch data from XML files and since
the structure of a KML file is similar to an XML file, we can use the same for
KMLs as well. Below is the code snippet used –
getParametersFromXml:
function(soapRequestXML, nodeBody ) //soapRequestXML is the complete string in
KML and nodeBody is the parent tag
{
var
soapObject = new XMLHelper(soapRequestXML).toObject();
this.getRecordObj(soapObject,
nodeBody);
return
this.recordObject;
},
getRecordObj:
function(obj, requestBodyElement){
for
(x in obj){
if(x==requestBodyElement){
this.recordObject
= obj[x];
}
this.getRecordObj(obj[x],
requestBodyElement);
}
}
Once
you have the returned value from this function, you can dot – walk on it to
reach your particular tag whose value is desired.
This
way, the data can be stored in any desired SNOW table per tag. Every row in
that table will contain a marker to be plotted on the map.
Now,
we will actually plot the data on map using Google Map API functions. For that,
we will need an array of all the markers that need to be plotted. In our case,
we had different checkboxes and dropdown menus to choose the report to be
displayed. Hence, there was different set of markers for every selection. We
created a GlideRecord of all the records in the table that are to be plotted
and created an item out of it. Below is the code snippet used –
var markerArray =
this.newItem("marker"); //Create an array and name it marker
favs.setAttribute("name", gr.u_
name); //Set the values you need
Now,
we will fetch this array in our UI page and plot the values on the map. This
functionality is provided by various functions in the API according to various
needs. The one we used was OverlayView
and Marker. First we created the map
–
myMap = new
google.maps.Map(document.getElementById('map'), {
zoom: zoom,
center: goldCoast,
mapTypeId: mapType
});
This
map object must be global since we’ll be using it at various points. Next,
below is the code to create an OverlayView.
DebugOverlay.prototype =
new google.maps.OverlayView();
function
DebugOverlay(bounds, image, myMap) { //bounds is an object of google.maps.LatLng
type which contains Latitude and Longitude value separated by comma, image is
the reference of the image to be plotted and myMap is the reference to our map
object
this.bounds_ = bounds;
this.image_ = image;
this.map_ = myMap;
this.div_ = null;
this.setMap(myMap);
}
//Below are the various
functions which will be called at different times by the constructor and
destructor
DebugOverlay.prototype.onAdd
= function() {
var div = document.createElement('div');
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
var img = document.createElement('img');
img.src = this.image_;
img.style.width = '100%';
img.style.height = '100%';
img.style.opacity = '0.20';
img.style.position = 'absolute';
div.appendChild(img);
this.div_ = div;
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
};
DebugOverlay.prototype.draw
= function() {
var overlayProjection = this.getProjection();
var sw =
overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne =
overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 'px';
div.style.width = (ne.x - sw.x) + 'px';
div.style.height = (sw.y - ne.y) + 'px';
};
DebugOverlay.prototype.updateBounds
= function(bounds){
this.bounds_ = bounds;
this.draw();
};
DebugOverlay.prototype.onRemove
= function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
To
create the markers, the point where we are to show the image on one particular
coordinate and not over an area, we can use the below code –
function
addMarker(location, icon, title, disp) { //
var marker = new google.maps.Marker({
position: location,
map: myMap,
icon: icon,
title: disp
});
if(title != '') //create a popup dialog showing the
relevant information
{
var infowindow = new google.maps.InfoWindow({
content: title
});
marker.addListener('click', function() {
infowindow.open(myMap, marker);
});
}
markers.push(marker);
}
We
can use Google Maps API over SNOW to create map – based reports using list
data. To show the markers we need the longitude and latitude of the point and
to create an overlay, the east, west, north and south points are required. You
can control the type of map from Satellite, Terrain or Hybrid, the zoom – level
and the center of the map on load. The data can be refreshed into the table
itself to update. There is so much more in the API that can be used as per the
requirements.
This
can help users to demonstrate any location – based reports and findings.
- https://developers.google.com/maps/documentation/javascript/examples/
- http://gmaps-samples-v3.googlecode.com/svn/trunk/map_events/map_events.html
- https://community.servicenow.com/thread/154141
- http://tuhrig.de/visualizing-kml-files-in-google-maps/
While every effort has been made to provide all the information and the correct things, please feel free to reach out in case you find any issues or need further information. :) :)