×
Namespaces

Variants
Actions

Converting Ovi Maps to HERE Maps

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to port a typical web page from the deprecated Ovi Map API to use the current HERE Maps API for JavaScript

Article Metadata
Code ExampleTested with
Devices(s): Internet Explorer, Google Chrome, Firefox
Article
Keywords: HERE Maps, Ovi Maps, JavaScript
Created: jasfox (07 Feb 2013)
Last edited: jasfox (12 Sep 2013)

Contents

Introduction

The original Ovi Maps API for JavaScript has been superseded by the newer, re-branded HERE Maps API and indeed this is the reason that the HERE Maps API for JavaScript already holds a "2-point-O" major version number. As an updated version of the same API, the path of upgrading from Ovi Maps to HERE Maps is relatively painless procedure, and the steps to do so are described below.

OviToNokia.png

Screenshot showing a Map of Paris using both Ovi Maps (left) and HERE Maps 2.2.3 (right)

Header

Ovi Map Nokia Map
<script type="text/javascript"
src="http://api.maps.ovi.com/jsl.js" charset="utf-8">
</script>
<script type="text/javascript"
src="http://js.api.here.com/se/2.5.3/jsl.js" charset="utf-8">
</script>

The first stage in any conversion is to alter the <script> tag in the <header> to point to the latest version of the API. The HERE Maps API holds a version number within the URL of the src. At the time of writing, the current version of the HERE Maps API is 2.5.3 .You can check to ensure that you are using the latest version of the HERE Maps API by looking at the versioning page of developer.here.com.

Authentication

Ovi Map Nokia Map
ovi.mapsapi.util.ApplicationContext.set(
"authenticationToken", "<Token>");
nokia.Settings.set("app_id", "YOUR APP ID"); 
nokia.Settings.set("app_code", "YOUR TOKEN");

Authentication is mandatory in the latest version of the HERE Maps API, you can obtain your own free app id and token through following the instructions here, failure to do this will result in a blank page rather than a map. The corresponding Ovi Map authentication should be removed.

Basic Map

see also: Basic Map

Ovi Map Nokia Map
var mapContainer = document.getElementById("map");
 
var map = (window.display = new ovi.mapsapi.map.Display(mapContainer, {
center: [48.8567, 2.3508],
zoomLevel: 10,
fading: 250, // fading duration of tiles in miliseconds
components: [
new ovi.mapsapi.map.component.Behavior(),
new ovi.mapsapi.map.component.TypeSelector(),
new ovi.mapsapi.map.component.ZoomBar(),
new ovi.mapsapi.map.component.ScaleBar(),
new ovi.mapsapi.map.component.Overview(),
new ovi.mapsapi.map.component.ViewControl(),
new ovi.mapsapi.map.component.RightClick()]
}));
var mapContainer = document.getElementById("mapContainer");
 
var map = new nokia.maps.map.Display(mapContainer, {
center: [48.8567, 2.3508],
zoomLevel: 10,
components: [
new nokia.maps.map.component.ZoomBar(),
new nokia.maps.map.component.Behavior(),
new nokia.maps.map.component.TypeSelector(),
new nokia.maps.map.component.Traffic(),
new nokia.maps.map.component.PublicTransport(),
new nokia.maps.map.component.DistanceMeasurement(),
new nokia.maps.map.component.Overview(),
new nokia.maps.map.component.ScaleBar(),
new nokia.maps.positioning.component.Positioning(),
new nokia.maps.map.component.ContextMenu()]
});

Most of the old Ovi Map components have a direct analog in the updated API. The only change is in the namespace. Indeed this is the case throughout the API, all instances of the old ovi.mapsapi namespace need to be replaced in the code with nokia.maps. The RightClick component has been replaced with the ContextMenu component (see HERE Maps API - How to create a Context Menu for details), and the ViewControl has been removed from the API altogether and needs to be deleted. As expected, the new API offers many more standard MapComponents, and these can be added as desired.

Markers and GeoObjects

see also: Markers and GeoShapes

Ovi Map Nokia Map
var markerContainer = new ovi.mapsapi.map.Container(); 
markerContainer.objects.add(new ovi.mapsapi.map.StandardMarker([52.45705,13.21173]));
 
var polyline = new ovi.mapsapi.map.Polyline(
[
new ovi.mapsapi.geo.Coordinate(52.45705,13.21173),
new ovi.mapsapi.geo.Coordinate(52.5705,13.41173),
new ovi.mapsapi.geo.Coordinate(52.46705,13.61173)
],
{
color: "#823f",
width: 4
}
);
markerContainer.objects.add(polyline);
 
var polygon = new ovi.mapsapi.map.Polygon(
[
new ovi.mapsapi.geo.Coordinate(52.45705,13.21173),
new ovi.mapsapi.geo.Coordinate(52.36705,13.41173),
new ovi.mapsapi.geo.Coordinate(52.46705,13.61173)
],
{
color: "#823f",
fillColor: "#2387",
width: 5
}
);
 
markerContainer.objects.add(polygon);
 
map.objects.add(markerContainer);
map.zoomTo(markerContainer.getBoundingBox(),false,true);
markerContainer = new nokia.maps.map.Container();
markerContainer.objects.add(new nokia.maps.map.StandardMarker([52.45705,13.21173]));
 
var polyline = new nokia.maps.map.Polyline(
[
new nokia.maps.geo.Coordinate(52.45705,13.21173),
new nokia.maps.geo.Coordinate(52.5705,13.41173),
new nokia.maps.geo.Coordinate(52.46705,13.61173)
],
{
color: "#823f",
width: 4
}
);
markerContainer.objects.add(polyline);
 
var polygon = new nokia.maps.map.Polygon(
[
new nokia.maps.geo.Coordinate(52.45705,13.21173),
new nokia.maps.geo.Coordinate(52.36705,13.41173),
new nokia.maps.geo.Coordinate(52.46705,13.61173)
],
{
color: "#823f",
fillColor: "#2387",
width: 5
 
}
);
markerContainer.objects.add(polygon);
 
map.objects.add(markerContainer);
map.zoomTo(markerContainer.getBoundingBox(),false,true);

The code used to create standard markers and geo-objects has not changed. The only difference between the two code snippets is the name space. Again all instances of the old ovi.mapsapi namespace need to be replaced in the code with nokia.maps.

Geocoding

see also: Geocode example

Ovi Map Nokia Map
var searchManager = new ovi.mapsapi.search.Manager();
searchManager.addObserver("state",
function(observedManager, key, value) {
if(value == "finished") {
if (observedManager.locations.length > 0) {
rs = (new ovi.mapsapi.search.component.
SearchResultSet(observedManager.locations)).container;
//push markers to map
map.objects.add(rs);
map.zoomTo(rs.getBoundingBox(), false);
}
} else if(value == "failed") {
alert("The request failed.");
}
});
 
 
var searchTerm = "Champ de Mars, Paris";
var prox = {
center: new ovi.mapsapi.geo.Coordinate(48.8567, 2.3508),
radius: 1200
};
 
//make a geocode request
searchManager.geocode(searchTerm, prox);
var searchManager = nokia.places.search.manager,
resultSet;
 
// Function for receiving search results from places search and process them
var processResults = function (data, requestStatus, requestId) {
var i, len, locations, marker;
 
if (requestStatus == "OK") {
locations = data.results ? data.results.items : [data.location];
if (locations.length > 0) {
resultSet = new nokia.maps.map.Container();
for (i = 0, len = locations.length; i < len; i++) {
marker = new nokia.maps.map.StandardMarker(
locations[i].position, { text: i+1 });
resultSet.objects.add(marker);
}
map.objects.add(resultSet);
map.zoomTo(resultSet.getBoundingBox(), false);
}
} else {
alert("The search request failed");
}
};
 
var searchTerm = "Champ de Mars, Paris";
searchManager.geoCode({
searchTerm: searchTerm,
onComplete: processResults
});

Since the switch to HERE Maps, search has become purely the responsibility of places in the new API. This should improve search results, but does mean a code break has occurred. The nokia.places.search.manager is now a static function as opposed to being created as an object. The geocoder no longer requires a location as a hint, but where one is needed (such as a Places "explore" free text search, a Coordinate can be created as shown:

searchCenter = new nokia.maps.geo.Coordinate(52.51, 13.4);

Reverse Geocoding

see also: Reverse Geocode example

Ovi Map Nokia Map
var currentBubble = null;
var infobubbles = new ovi.mapsapi.map.component.InfoBubbles();
var searchManager= new ovi.mapsapi.search.Manager();
 
searchManager.addObserver("state",
function(observedManager, key, value) {
if(value == "finished") {
if (observedManager.locations.length > 0) {
// hide any existing bubbles
if(currentBubble != null){
infobubbles.removeBubble(currentBubble);
currentBubble = null;
}
 
currentBubble = infobubbles.addBubble(
observedManager.locations[0],
observedManager.locations[0].displayPosition);
}
} else if(value == "failed") {
alert("The request failed.");
}
});
 
//make a reverse geocode request
searchManager.clear();
searchManager.addObserver("state", revgeoCallBack);
searchManager.reverseGeocode(new ovi.mapsapi.geo.Coordinate(48.837, 2.436 ));
var currentBubble = null;
var infobubbles = new nokia.maps.map.component.InfoBubbles();
var searchManager = nokia.places.search.manager,
resultSet;
 
// Function for receiving search results from places search and process them
var processResults = function (data, requestStatus, requestId) {
 
if (requestStatus == "OK") {
locations = data.results ? data.results.items : [data.location];
if (locations.length > 0) {
// hide any existing bubbles
if(currentBubble != null){
infobubbles.closeBubble(currentBubble);
currentBubble = null;
}
currentBubble = infobubbles.openBubble(
locations[0].address.text, locations[0].position);
}
}else {
alert("The request failed.");
}
}
 
//make a reverse geocode request
var reverseGeoCodeTerm = new nokia.maps.geo.Coordinate(48.837, 2.436 );
searchManager.reverseGeoCode({
latitude: reverseGeoCodeTerm.latitude,
longitude: reverseGeoCodeTerm.longitude,
onComplete: processResults
});

Once again, reverse geocoding has become the responsibility of places in the new API. The code needs to be updated in a similar manner to the geocoding example. When displaying the result on screen, InfoBubbles.removeBubble() and InfoBubbles.addBubble() have been deprecated - the should be replace with InfoBubbles.closeBubble() and InfoBubbles.openBubble() respectively.

Custom Control

Ovi Map Nokia Map
 
var myCustomComponentSimple = new ovi.Class({
Exends: ovi.mapsapi.map.component.Component,
 
initialize: function (callback) {
myNode = document.createElement("div");
this.callback = callback;
},
myNode: null,
callback: null,
getId: function() { return "MySimpleCustomComponent"; },
attach: function(display) {
 
var myHTML = '<div style="position: absolute; left: 25px; top: 25px;
background: #ff0; border: 1px solid #000; padding: 10px;">'
+
'<h1>Hello World!</h1>' +
'<p>I am a custom component. </p>' +
'<p>' +
'<div id="myCustomComponentButton" style="margin: 10px;
padding: 5px; background: #ccc; border: 1px solid #000;">
Close me!</div>'
+
'</p>' +
'</div>';
 
myNode.innerHTML = myHTML;
 
display._uiContainer.appendChild(myNode);
if(!this.button) {
this.button = ovi.mapsapi.dom.EventTarget(
document.getElementById(
"myCustomComponentButton"));
}
 
this.button.addListener("click", this.callback);
},
detach: function(display) {
display._uiContainer.removeChild(myNode);
this.button.removeListener("click", this.callback);
},
});
function extend(B, A) {
function I() {}
I.prototype = A.prototype;
B.prototype = new I();
B.prototype.constructor = B;
}
 
var myCustomComponentSimple = function (callback) {
var myNode = document.createElement("div");
this.callback = callback;
this.getId = function() { return "MySimpleCustomComponent"; };
this.attach = function(display) {
 
var myHTML = '<div style="position: absolute; left: 25px; top: 25px;
background: #ff0; border: 1px solid #000; padding: 10px;">'
+
'<h1>Hello World!</h1>' +
'<p>I am a custom component. </p>' +
'<p>' +
'<div id="myCustomComponentButton" style="margin: 10px;
padding: 5px; background: #ccc; border: 1px solid #000;">
Close me!</div>'
+
'</p>' +
'</div>';
 
myNode.innerHTML = myHTML;
 
display.getUIContainer().appendChild(myNode);
if(!this.button) {
this.button = nokia.maps.dom.EventTarget(
document.getElementById(
"myCustomComponentButton"));
}
 
this.button.addListener("click", this.callback);
};
this.detach = function(display) {
display.getUIContainer().removeChild(myNode);
this.button.removeListener("click", this.callback);
};
 
// Call the "super" constructor to initialize properties
nokia.maps.map.component.Component.call(this);
 
};
extend(myCustomComponentSimple,
nokia.maps.map.component.Component);

The ovi.Class no longer exists, it should be replaced with a boilerplate extend() function. The final two lines of the HERE Maps code snippet call the super class of the Component and ensure that the component itself is properly wired up in the tool chain. Note that any code that directly accesses private properties (such as _uiContainer needs to be replaced with the equivalent function call. There is no guarantee that the names of private properties will remain constant across API versions. To handle events, the ovi.mapsapi.dom.EventTarget can be directly replaced with a nokia.maps.dom.EventTarget.

Summary

In most cases upgrading from Ovi Maps to HERE Maps is merely a process of changing the JavaScript library used, and globally switching namespaces. A series of examples have been converted from Ovi to HERE Maps in the Maps Examples for HERE Maps API Look at the versions of each of the following examples to see how to upgrade

This page was last modified on 12 September 2013, at 17:54.
191 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×