how can i get the length of a route?
I have been looking at this basic code of a route from a to b:
// Get the DOM node to which we will append the map
var mapContainer = document.getElementById("mapContainer");
// Create a map inside the map container DOM node
var map = new nokia.maps.map.Display(mapContainer, {
// Initial center and zoom level of the map
center: [52.51, 13.4],
zoomLevel: 7,
// We add the behavior component to allow panning / zooming of the map
components:[new nokia.maps.map.component.Behavior()]
}),
router = new nokia.maps.routing.Manager(); // create a route manager;
// The function onRouteCalculated will be called when a route was calculated
var onRouteCalculated = function (observedRouter, key, value) {
if (value == "finished") {
var routes = observedRouter.getRoutes();
//create the default map representation of a route
var mapRoute = new nokia.maps.routing.component.RouteResultSet(routes[0]).container;
map.objects.add(mapRoute);
//Zoom to the bounding box of the route
map.zoomTo(mapRoute.getBoundingBox(), false, "default");
} else if (value == "failed") {
alert("The routing request failed.");
}
};
/* We create on observer on router's "state" property so the above created
* onRouteCalculated we be called once the route is calculated
*/
router.addObserver("state", onRouteCalculated);
// Create waypoints
var waypoints = new nokia.maps.routing.WaypointParameterList();
waypoints.addCoordinate(new nokia.maps.geo.Coordinate(52.51652540955727, 13.380154923889933));
waypoints.addCoordinate(new nokia.maps.geo.Coordinate(52.52114106145058,13.40921934080231));
/* Properties such as type, transportModes, options, trafficMode can be
* specified as second parameter in performing the routing request.
* See for the mode options the "nokia.maps.routing.Mode" section in the developer's guide
*/
var modes = [{
type: "shortest",
transportModes: ["car"],
options: "avoidTollroad",
trafficMode: "default"
}];
// Calculate the route (and call onRouteCalculated afterwards)
router.calculateRoute(waypoints, modes);shortest
When the route is successfully calculated, the call-back function holds an array of one or more routes.
Code:
var routes = observedRouter.getRoutes();
Each of these holds a route summary, where you can obtain useful info about the route.
Code:
alert ("Route Length = " + routes[0].totalLength + " m.");
alert ("As the crow flies = " + routes[0].waypoints[0].mappedPosition.distance(routes[0].waypoints[1].mappedPosition) + " m.");
(Obviously you'll need to use waypoints.length -1 for a calculation with stop-overs)
Here is your code example, with the extra two lines added, You need to use your own app id and token to get it to work.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
Example from Nokia Maps API Playground, for more information visit http://api.maps.nokia.com
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9"/>
<base href="http://developer.here.net/apiexplorer/examples/api-for-js/routing/map-with-route-from-a-to-b.html" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Nokia Maps API Example: Add route from A to B</title>
<meta name="description" content="Routing Manager offers the ability to request a route with various modes between two points"/>
<meta name="keywords" content="routing, services, a to b, route, direction, navigation"/>
<!-- For scaling content for mobile devices, setting the viewport to the width of the device-->
<meta name=viewport content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<!-- Styling for example container (NoteContainer & Logger) -->
<link rel="stylesheet" type="text/css" href="http://developer.here.net/apiexplorer/examples/templates/js/exampleHelpers.css"/>
<!-- By default we add ?with=all to load every package available, it's better to change this parameter to your use case. Options ?with=maps|positioning|places|placesdata|directions|datarendering|all -->
<script type="text/javascript" charset="UTF-8" src="http://api.maps.nokia.com/2.2.3/jsl.js?with=all"></script>
<style type="text/css">
html {
overflow:hidden;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
height: 100%;
position: absolute;
}
#mapContainer {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
}
</style>
</head>
<body>
<div id="mapContainer"></div>
<script type="text/javascript" id="exampleJsSource">
/* Set authentication token and appid
* WARNING: this is a demo-only key
* please register on http://api.developer.nokia.com/
* and obtain your own developer's API key
*/
nokia.Settings.set("appId", "YOUR APP ID");
nokia.Settings.set("authenticationToken", "YOUR TOKEN");
// Get the DOM node to which we will append the map
var mapContainer = document.getElementById("mapContainer");
// Create a map inside the map container DOM node
var map = new nokia.maps.map.Display(mapContainer, {
// Initial center and zoom level of the map
center: [52.51, 13.4],
zoomLevel: 7,
// We add the behavior component to allow panning / zooming of the map
components:[new nokia.maps.map.component.Behavior()]
}),
router = new nokia.maps.routing.Manager(); // create a route manager;
// The function onRouteCalculated will be called when a route was calculated
var onRouteCalculated = function (observedRouter, key, value) {
if (value == "finished") {
var routes = observedRouter.getRoutes();
//create the default map representation of a route
var mapRoute = new nokia.maps.routing.component.RouteResultSet(routes[0]).container;
map.objects.add(mapRoute);
//Zoom to the bounding box of the route
map.zoomTo(mapRoute.getBoundingBox(), false, "default");
alert ("Route Length = " + routes[0].totalLength + " m.");
alert ("As the crow flies = "
routes[0].waypoints[0].mappedPosition.distance(
routes[0].waypoints[1].mappedPosition) + " m.");
} else if (value == "failed") {
alert("The routing request failed.");
}
};
/* We create on observer on router's "state" property so the above created
* onRouteCalculated we be called once the route is calculated
*/
router.addObserver("state", onRouteCalculated);
// Create waypoints
var waypoints = new nokia.maps.routing.WaypointParameterList();
waypoints.addCoordinate(new nokia.maps.geo.Coordinate(52.51652540955727, 13.380154923889933));
waypoints.addCoordinate(new nokia.maps.geo.Coordinate(52.52114106145058, 13.40921934080231));
/* Properties such as type, transportModes, options, trafficMode can be
* specified as second parameter in performing the routing request.
*
* See for the mode options the "nokia.maps.routing.Mode" section in the developer's guide
*/
var modes = [{
type: "shortest",
transportModes: ["car"],
options: "avoidTollroad",
trafficMode: "default"
}];
// Calculate the route (and call onRouteCalculated afterwards)
router.calculateRoute(waypoints, modes);
</script>
</body>
</html>
Related
I have a question about using TensorFlow.js to detect objects with webcam. Currently I am using the pre-trained model coco-ssd.
index.html:
<html lang="en">
<head>
<title>Multiple object detection using pre trained model in TensorFlow.js</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import the webpage's stylesheet -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Multiple object detection using pre trained model in TensorFlow.js</h1>
<p>Wait for the model to load before clicking the button to enable the webcam - at which point it will become visible to use.</p>
<section id="demos" class="invisible">
<p>Hold some objects up close to your webcam to get a real-time classification! When ready click "enable webcam" below and accept access to the webcam when the browser asks (check the top left of your window)</p>
<div id="liveView" class="camView">
<button id="webcamButton">Enable Webcam</button>
<video id="webcam" autoplay width="640" height="480"></video>
</div>
</section>
<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/#tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
<!-- Load the coco-ssd model to use to recognize things in images -->
<script src="https://cdn.jsdelivr.net/npm/#tensorflow-models/coco-ssd"></script>
<!-- Import the page's JavaScript to do some stuff -->
<script src="script.js" defer></script>
</body>
</html>
script.js:
const video = document.getElementById('webcam');
const liveView = document.getElementById('liveView');
const demosSection = document.getElementById('demos');
const enableWebcamButton = document.getElementById('webcamButton');
// Check if webcam access is supported.
function getUserMediaSupported() {
return !!(navigator.mediaDevices &&
navigator.mediaDevices.getUserMedia);
}
// If webcam supported, add event listener to button for when user
// wants to activate it to call enableCam function which we will
// define in the next step.
if (getUserMediaSupported()) {
enableWebcamButton.addEventListener('click', enableCam);
} else {
console.warn('getUserMedia() is not supported by your browser');
}
// Enable the live webcam view and start classification.
function enableCam(event) {
// Only continue if the COCO-SSD has finished loading.
if (!model) {
return;
}
// Hide the button once clicked.
event.target.classList.add('removed');
// getUsermedia parameters to force video but not audio.
const constraints = {
video: true
};
// Activate the webcam stream.
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
video.srcObject = stream;
video.addEventListener('loadeddata', predictWebcam);
});
}
// Store the resulting model in the global scope of our app.
var model = undefined;
// Before we can use COCO-SSD class we must wait for it to finish
// loading. Machine Learning models can be large and take a moment
// to get everything needed to run.
// Note: cocoSsd is an external object loaded from our index.html
// script tag import so ignore any warning in Glitch.
cocoSsd.load().then(function (loadedModel) {
model = loadedModel;
// Show demo section now model is ready to use.
demosSection.classList.remove('invisible');
});
var children = [];
function predictWebcam() {
// Now let's start classifying a frame in the stream.
model.detect(video).then(function (predictions) {
// Remove any highlighting we did previous frame.
for (let i = 0; i < children.length; i++) {
liveView.removeChild(children[i]);
}
children.splice(0);
// Now lets loop through predictions and draw them to the live view if
// they have a high confidence score.
for (let n = 0; n < predictions.length; n++) {
// If we are over 66% sure we are sure we classified it right, draw it!
if (predictions[n].score > 0.66) {
const p = document.createElement('p');
p.innerText = predictions[n].class + ' - with '
+ Math.round(parseFloat(predictions[n].score) * 100)
+ '% confidence.';
p.style = 'margin-left: ' + predictions[n].bbox[0] + 'px; margin-top: '
+ (predictions[n].bbox[1] - 10) + 'px; width: '
+ (predictions[n].bbox[2] - 10) + 'px; top: 0; left: 0;';
const highlighter = document.createElement('div');
highlighter.setAttribute('class', 'highlighter');
highlighter.style = 'left: ' + predictions[n].bbox[0] + 'px; top: '
+ predictions[n].bbox[1] + 'px; width: '
+ predictions[n].bbox[2] + 'px; height: '
+ predictions[n].bbox[3] + 'px;';
liveView.appendChild(highlighter);
liveView.appendChild(p);
children.push(highlighter);
children.push(p);
}
}
// Call this function again to keep predicting when the browser is ready.
window.requestAnimationFrame(predictWebcam);
});
}
Now I would like to customize the script to use my own model, which I previously created and trained with Tensorflow for Python. I have already converted it with the converter tfjs_convert into a .json format.
Files of my own model
How do I modify my code so that my own model is now used? I have already tried a few things, but unfortunately have not made any progress.
You can use loadGraphModel from #tensorflow/tfjs-converter to load from Json.
I love this example.
I am modifying bellow script to see how can i move an Icon by following Array of Lat/lon , but it always say error such , but I am providing as an Array
Can any one please help me to understand what i am doing wrong ?
I am revering this example
https://www.mapbox.com/mapbox-gl-js/example/animate-marker/
Error :
lng_lat.js:121 Uncaught Error: `LngLatLike` argument must be specified as a LngLat instance, an object {lng: <lng>, lat: <lat>}, an object {lon: <lng>, lat: <lat>}, or an array of [<lng>, <lat>]
at Function.yu.convert (lng_lat.js:121)
at o.setLngLat (marker.js:251)
at animateMarker (animate.html:33)
Modified Code : -
<html>
<head>
<meta charset='utf-8' />
<title>Animate a marker</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = '';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [90.35388165034988, 23.725173272533567],
zoom: 10
});
var marker = new mapboxgl.Marker();
function animateMarker() {
var radius = 20;
// Update the data to a new position based on the animation timestamp. The
// divisor in the expression `timestamp / 1000` controls the animation speed.
marker.setLngLat([
[90.35388165034988, 23.725173272533567],
[90.37379437008741, 23.732873570085644] ,
[90.38563900508132, 23.72297310398119],
[90.35388165034988, 23.725173272533567],
[90.35388165034988, 23.725173272533567]
]);
// Ensure it's added to the map. This is safe to call if it's already added.
marker.addTo(map);
// Request the next frame of the animation.
requestAnimationFrame(animateMarker);
}
// Start the animation.
requestAnimationFrame(animateMarker);
</script>
</body>
</html>
You can only pass a single coordinate to setLngLat. You cannot pass an array. Here's a crude example where inside the animation function, we use time to pick a position from the array of points and pass that one position to the marker.
var controlPoints = [
[90.35388165034988, 23.725173272533567],
[90.37379437008741, 23.732873570085644] ,
[90.38563900508132, 23.72297310398119],
[90.35388165034988, 23.725173272533567],
[90.35388165034988, 23.725173272533567]
];
function animateMarker(timestamp) {
// stay at each point for 1 second, then move to the next
// (lower 1000 to 500 to move 2x as fast)
var position = Math.floor(timestamp / 1000) % controlPoints.length;
marker.setLngLat(controlPoints[position])
// Ensure it's added to the map. This is safe to call if it's already added.
marker.addTo(map);
// Request the next frame of the animation.
requestAnimationFrame(animateMarker);
}
This animation will be crude. Ideally, you'd take those control points and create a polyline or linear ring, then your animation function would interpolate along the polyline at a set speed (like 30 km/s). You would end up with a very nice animation that followed the path of the control points.
I am trying to switch over from Google Maps to Here in a lot of my code. One thing that is hanging me up is the need for Geodesic lines versus "straight lines"
An example of this can be found here: http://www.2timothy42.org/Travel/?Mode=
There is another Stack Overflow question with the answer here but the link doesn't work anymore.
The example posted by HERE Developer Support gets you there, but the code has extra stuff in it that isn't necessary and it also has a few JS references that are relative and don't work once entered into my code.
This relates to one of the key difference I noticed between Google Maps API and HERE API is that Google Maps use one JS call, where as HERE has a few and if they aren't included correctly produce some issues.
HEAD
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
<script src="https://tcs.ext.here.com/assets/geodesic-polyline-955f4bde9d216d0e89b88f4ba29c75fd1407f30f905380039e312976f3e30c88.js"></script>
BODY
<div id="map" style='width: 600px; height: 300px; border: 1px solid #000000;'></div>
<script type="text/javascript" charset="UTF-8" >
// Check whether the environment should use hi-res maps
var hidpi = ('devicePixelRatio' in window && devicePixelRatio > 1);
// check if the site was loaded via secure connection
var secure = (location.protocol === 'https:') ? true : false;
// Create a platform object to communicate with the HERE REST APIs
var platform = new H.service.Platform({
useCIT: true,
useHTTPS: secure,
app_id: 'API_APP_ID',
app_code: 'API_APP_CODE'
}),
maptypes = platform.createDefaultLayers(hidpi ? 512 : 256, hidpi ? 320 : null);
// Instantiate a map in the 'map' div, set the base map to normal
var map = new H.Map(document.getElementById('map'), maptypes.normal.map, {
center: {lat:32.00, lng:-110.00},
zoom: 1,
pixelRatio: hidpi ? 2 : 1
});
// Enable the map event system
var mapevents = new H.mapevents.MapEvents(map);
// Enable map interaction (pan, zoom, pinch-to-zoom)
var behavior = new H.mapevents.Behavior(mapevents);
// Enable the default UI
var ui = H.ui.UI.createDefault(map, maptypes);
window.addEventListener('resize', function() { map.getViewPort().resize(); });
var npoints = 100,
offset = 20;
// Tokyo -> san Francisco
add([35.68019,139.81194],[37.77712,-122.41964], {style: { strokeColor: "rgba(0,0,255,0.7)", lineWidth: 4}});
function add(s,e,options) {
var start_ll = new H.geo.Point(s[0],s[1]),
end_ll = new H.geo.Point(e[0],e[1]),
start_coord = {x: start_ll.lng, y:start_ll.lat},
end_coord = {x:end_ll.lng, y:end_ll.lat};
description = ''+s[0]+','+s[1]+'=>'+e[0]+','+e[1]+'',
gc0 = new arc.GreatCircle(start_coord,end_coord, {'name': 'line', 'color':'#ff7200','description':description}),
line0 = gc0.Arc(npoints,{offset:offset}),
strip = line0.strip();
map.addObject(new H.map.Polyline(strip, options));
}
</script>
I am currently working on a live tracking application for Cesium, but am having some issues when I display the point in the browser.
So far my Cesium viewer receives the data from the server (in JSON format) and displays the point properly on the map, but the only way to have it update the location on the map is to refresh the page. Note that the location.json file it is reading the location from is being updated with a new location every second or so from the server.
Now I figured it would do this, as the client side code has no "update" function to dynamically change the point location on the map.
So what is the easiest way to have Cesium constantly update the point on the map, without the user constantly refreshing the page? Based on my research I have found some examples that involve streaming of CZML files or making my JSON into a data source, but these seem a bit complex for what seems to be a simple task. Is there not a simple "update" function that will change the point dynamically?
Here is my client side code:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8">
<!-- Tell IE to use the latest, best version (or Chrome Frame if pre-IE11). -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Hello World!</title>
<script src="../Build/Cesium/Cesium.js"></script>
<style>
#import url(../Build/Cesium/Widgets/widgets.css);
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
var viewer = new Cesium.Viewer('cesiumContainer');
Cesium.loadJson('/location.json').then(function(data) {
console.log(data);
viewer.entities.add({
name : data.name,
position : Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : data.name,
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
});
</script>
</body>
</html>
If you need any more information from me, I will be happy to provide it.
Thanks!
You will need to keep a reference to each of this points and then simply update that elements position according to some unique id. If a name is unique then you can use that, otherwise you need to implement some way to identify each point after update.
You can check if the point is a new one or existing one in a loadJSON callback function by calling var currentPoint = viewer.entities.getById(data.id). Then you can choose which one of these function will you call. First one for new points (when currentpoint == undefined):
function addNewPoint(
var point = new Cesium.Entity(
{
id : data.id,
name : data.name,
position : Cesium.Cartesian3.fromDegrees(data.lon, data.lat),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : data.name,
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
}
);
viewer.entities.add(point);
);
Otherwise you call updatePoint function that will just update position
function updatePosition(currentPoint, data)
{
var newPos = new Cesium.Cartesian3.fromDegrees(data.lon, data.lat);
currentPoint.position = newPos;
}
I'm using the Nokia API for my web app (Javascript), and I draw circles in my map with different radium. The thing is when I zoom in, the circle has the same size, which means that when I zoom in, there's a level where I can't see anything else since it covers the whole map. Hence, I want the circle to keep the same size even if I zoom in.
For that, I tried SVG Markers, which solve this problem, but the thing is I had to program when I click on one of them, the color has to change (it's all a mess, and it reduces the performance of the app).
If anyone can help me, that would be awesome !
There are three key points which need to be answered to find a solution your question.
To add functionality when a marker is clicked, you need to add a listener to the click event i.e. marker.addListener("click", function (evt) { ...etc
To switch the color of an SVG marker you need two separate icons for that marker. The icon property is immutable, and hence it should only be updated using the set() method i.e. marker.set("icon", markerIcon);
To force a refresh of the screen after the new icon has been set you need to update the map display - map.update(-1, 0);
Combining these points togther there is a working example appended below. You need to substitute in your own app id and token to get it to work of course.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9" />
<title>Highlighing a marker: Istanbul (Not Constantinople)</title>
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script language="javascript" src="http://api.maps.nokia.com/2.2.4/jsl.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<p> Click on the marker to change it.</p>
<div id="gmapcanvas" style="width:600px; height:600px;" > </div><br/><br/>
<script type="text/javascript">
// <![CDATA[
/////////////////////////////////////////////////////////////////////////////////////
// Don't forget to set your API credentials
//
// Replace with your appId and token which you can obtain when you
// register on http://api.developer.nokia.com/
//
nokia.Settings.set( "appId", "YOUR APP ID GOES HERE");
nokia.Settings.set( "authenticationToken", "YOUR AUTHENTICATION TOKEN GOES HERE");
/////////////////////////////////////////////////////////////////////////////////////
map = new nokia.maps.map.Display(document.getElementById('gmapcanvas'), {
'components': [
// Behavior collection
new nokia.maps.map.component.Behavior(),
new nokia.maps.map.component.ZoomBar()
],
'zoomLevel': 5, // Zoom level for the map
'center': [41.0125,28.975833] // Center coordinates
});
// Remove zoom.MouseWheel behavior for better page scrolling experience
map.removeComponent(map.getComponentById("zoom.MouseWheel"));
var iconSVG =
'<svg width="33" height="33" xmlns="http://www.w3.org/2000/svg">' +
'<circle stroke="__ACCENTCOLOR__" fill="__MAINCOLOR__" cx="16" cy="16" r="16" />' +
'<text x="16" y="20" font-size="10pt" font-family="arial" font-weight="bold" text-anchor="middle" fill="__ACCENTCOLOR__" textContent="__TEXTCONTENT__">__TEXT__</text>' +
'</svg>',
svgParser = new nokia.maps.gfx.SvgParser(),
// Helper function that allows us to easily set the text and color of our SVG marker.
createIcon = function (text, mainColor, accentColor) {
var svg = iconSVG
.replace(/__TEXTCONTENT__/g, text)
.replace(/__TEXT__/g, text)
.replace(/__ACCENTCOLOR__/g, accentColor)
.replace(/__MAINCOLOR__/g, mainColor);
return new nokia.maps.gfx.GraphicsImage(svgParser.parseSvg(svg));
};
/* On mouse over we want to change the marker's color and text
* hence we create two svg icons which we flip on mouse over.
*/
var markerText = "1";
var colors = ["#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#00FFFF", "#FF00FF" , "#000000"];
var markerIcon= createIcon("1", "#F00", "#FFF");
map.addListener("click", function (evt) {
var target = evt.target;
if (target instanceof nokia.maps.map.Marker && (target.clickCount === undefined) == false){
target.clickCount++;
var icon = createIcon(target.clickCount, colors[target.clickCount%7], "#FFF");
target.set("icon", icon);
map.update(-1, 0);
}
if (evt.target instanceof nokia.maps.map.Spatial) {
evt.stopImmediatePropagation();
}
});
var istanbul = new nokia.maps.map.Marker(
// Geo coordinate of Istanbul
[41.0125,28.975833],
{
icon: markerIcon,
clickCount : 1
}
);
/// Let's add another marker for comparison:
var bucharest = new nokia.maps.map.Marker(
// Geo coordinate of Bucharest
[44.4325, 26.103889],
{
icon: markerIcon,
clickCount: 1
}
);
// We add the marker to the map's object collection so it will be rendered onto the map.
map.objects.addAll([istanbul, bucharest]);
// ]]>
</script>
</body>
</html>