Azure Maps - How to put a map line layer into edit mode? - azure-maps

I create a line layer and add it to the map.
But I then need to put this line layer into edit mode the user can stretch and manipulate the line, or whatever shape that I had added to the map.
The only reference I could find in MS Docs is how to put a 'shape' into edit mode, but this does not seem to be relevant and after trying their example, nothing works for me.
//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
//Create a line and add it to the data source.
dataSource.add(new atlas.data.LineString([[-73.972340, 40.743270], [-74.004420, 40.756800]]));
//Create a line layer to render the line to the map.
map.layers.add(new atlas.layer.LineLayer(dataSource, null, {
strokeColor: 'blue',
strokeWidth: 5
}));
The code above creates the line, renders it to the map, but when clicking/hovering over the line I can't select it to edit it, really need some help with the missing code to do this. thanks

I think you need to use the drawing module for that. It allows you to create a DrawingManager to edit a shape by setting the mode to edit-geometry.
I reworked a bit your example with the LineString to put it automatically on edit when the map is ready.
<!DOCTYPE html>
<html lang="en">
<head>
<title>AzureMaps</title>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/favicon.ico" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css"
type="text/css" />
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.css"
type="text/css" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>
<script src="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.js"></script>
<script type='text/javascript'>
function GetMap() {
//Initialize a map instance.
const map = new atlas.Map('myMap', {
view: 'Auto',
center: [-73.972340, 40.743270],
zoom: 13,
//Add your Azure Maps key to the map SDK. Get an Azure Maps key at https://azure.com/maps. NOTE: The primary key should be used as the key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<enter-your-subscription-key>'
}
});
map.events.add('ready', () => {
//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
const lineString = new atlas.data.LineString([[-73.972340, 40.743270], [-74.004420, 40.756800]]);
//Create a line and add it to the data source.
dataSource.add(lineString);
const lineStringShape = dataSource.getShapes()[0];
//Create a line layer to render the line to the map.
map.layers.add(new atlas.layer.LineLayer(dataSource, null, {
strokeColor: 'blue',
strokeWidth: 5
}));
var drawingManager = new atlas.drawing.DrawingManager(map, {
mode: 'edit-geometry'
});
drawingManager.edit(lineStringShape);
});
}
</script>
</head>
<body onload="GetMap()">
<div id="myMap" style="position:relative;width:100%;min-width:290px;height:600px;"></div>
</body>
</html>
Important thing is, you need to reference the atlas-drawing scripts and styles :
<script src="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.js"></script>
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.css"
type="text/css" />
You can find more information on the Drawing Manager here.
Edit - Change only color and width
If you want to change only the strokeColor and the strokeWidth of your line string, you don't actually need the drawing manager for that. I would recommend to set expressions on the strokeColor and strokeWidth of your line layer to read the values from the properties of each shape.
The following example displays two line strings with different width and colors :
//Initialize a map instance.
const map = new atlas.Map('myMap', {
view: 'Auto',
center: [-73.972340, 40.743270],
zoom: 13,
//Add your Azure Maps key to the map SDK. Get an Azure Maps key at https://azure.com/maps. NOTE: The primary key should be used as the key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<enter-your-subscription-key>'
}
});
map.events.add('ready', () => {
//Create a data source and add it to the map.
const dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
const firstLineString = new atlas.data.LineString([[-73.972340, 40.743270], [-74.004420, 40.756800]]);
const secondLineString = new atlas.data.LineString([[-73.972340, 40.733270], [-74.004420, 40.746800]]);
//Create a line and add it to the data source.
dataSource.add(firstLineString);
dataSource.add(secondLineString);
//Add properties on the shapes
const shapes = dataSource.getShapes()
const firstLineStringShape = shapes[0];
firstLineStringShape.addProperty('color', '#ed5a10');
firstLineStringShape.addProperty('strokeWidth', 10);
const secondLineStringShape = shapes[1];
secondLineStringShape.addProperty('color', '#0e41ea');
secondLineStringShape.addProperty('strokeWidth', 5);
//Create a line layer to render the line to the map.
//strokeColor and strokeWidth are defined on the properties of each line string
map.layers.add(new atlas.layer.LineLayer(dataSource, null, {
strokeColor: ['get', 'color'],
strokeWidth: ['get', 'strokeWidth']
}));
});
It is still done when the map is ready in this example for convenience, but you can set the properties of a shape whenever you need to update it using either addProperty if your property was never set, or a combination of getProperties and setProperties.
You can find more information on the data driven expressions here : https://learn.microsoft.com/en-us/azure/azure-maps/data-driven-style-expressions-web-sdk

Related

How to Use Tableau WDC in a ReactJs app the correct way

I keep getting this error ReferenceError: Can't find variable: Set file: http://localhost:1337/bundle.min.js line: 33098
It looks like window.tableau.getSchema() and myConnector.getData() have never been called. I add a log message, but it has never been executed.
Solution from #redec is to add polyfill for react. But I still got error.
Here is my html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Dashboard</title>
<link rel="shortcut icon" href="favicon.ico">
</head>
<body>
<div id="app">
</div>
<script src="https://connectors.tableau.com/libs/tableauwdc-2.3.latest.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.min.js"
type="text/javascript"></script>
</body>
</html>
Here is the component that will display on Tableu WDC, the route will be enter via WDC on Tableu Desktop app is http://localhost:1337/tableau/wdc
import React, { Component } from 'react';
class TableauWDC extends Component {
constructor(props, context) {
super(props, context);
this.state = {
isScriptLoaded: false
};
}
componentDidMount() {
// Create the connector object
var myConnector = window.tableau.makeConnector();
// Define the schema
myConnector.getSchema = function (schemaCallback) {
window.tableau.log("getSchema")
var cols = [{
id: "id",
dataType: window.tableau.dataTypeEnum.string
}, {
id: "mag",
alias: "magnitude",
dataType: window.tableau.dataTypeEnum.float
}, {
id: "title",
alias: "title",
dataType: window.tableau.dataTypeEnum.string
}, {
id: "location",
dataType: window.tableau.dataTypeEnum.geometry
}];
var tableSchema = {
id: "earthquakeFeed",
alias: "Earthquakes with magnitude greater than 4.5 in the last seven days",
columns: cols
};
schemaCallback([tableSchema]);
};
// Download the data
myConnector.getData = function (table, doneCallback) {
window.tableau.log("getData")
this.loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson',
function (data) {
var feat = data.features,
tableData = [];
// Iterate over the JSON object
for (var i = 0, len = feat.length; i < len; i++) {
tableData.push({
"id": feat[i].id,
"mag": feat[i].properties.mag,
"title": feat[i].properties.title,
"location": feat[i].geometry
});
}
table.appendRows(tableData);
doneCallback();
},
function (xhr) { console.error(xhr); }
);
};
window.tableau.registerConnector(myConnector);
}
loadJSON(path, success, error) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
if (success)
success(JSON.parse(xhr.responseText));
} else {
if (error)
error(xhr);
}
}
};
xhr.open("GET", path, true);
xhr.send();
}
submit() {
window.tableau.connectionName = "USGS Earthquake Feed"; // This will be the data source name in Tableau
window.tableau.submit(); // This sends the connector object to Tableau
}
render() {
return (
<div style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "calc( 90vh - 65px)"
}}>
<button onClick={() => this.submit()} className="btn btn-success" >Get Earthquake Data!</button>
</div>
);
}
}
export default TableauWDC;
I keep getting these errors.
A snippet from the error is below here
The web data connector has reported an unrecoverable error and cannot proceed. If the connector has reported details of the error, they are displayed in the pane below.
Script error. file: line: 0
Unfortunately the browser that tableau uses is not es6 compliant so it is missing some es6 components that react needs (such as Set and Map)...so you need to polyfill them. Add this after your tableau <script> tag:
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.min.js" type="text/javascript"></script>�
Currently tableau uses an old version of QtWebKit, but rumors say they'll be switching to chromium within the next couple of releases.
It is also a little weird that your registration is being done from a click handler on a div? I would expect that to be done on componentDidMount so it is done as soon as the WDC loads (otherwise tableau will display a warning banner)
Starting with Tableau v2019.4, it is using QTWebEngine ~5.10 which supports ES6 so your code should work without any shims.

Leaflet: create individual Event-listeners inside For-loops

I want want to put several markers on the map, these markers are consisting of "parent" markers and "child" markers. All parent markers should be visible on the map the same time, whereas the child-markers of a specific parent-marker should be toggled on/off if clicking onto the specific parent-marker
I created the following working example to demonstrate:
<!DOCTYPE html>
<html>
<head>
<title>Test 1</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.0.1/dist/leaflet.js"></script>
<style>
body {padding: 0; margin: 0;}
html, body, #map {height: 100%;}
</style>
</head>
<body>
<div id='map'></div>
<script>
var thunder = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png', {subdomains:'abc', attribution:'Thunderforest | OpenStreetMap' });
var map = L.map('map',{layers: [thunder]}).setView([50.08, 10.08], 12);
var parent1 = L.marker([50.0, 10.0]).bindPopup('Marker 1');
var parent2 = L.marker([50.1, 10.1]).bindPopup('Marker 2');;
var layergroupParents = L.layerGroup([parent1, parent2]);
layergroupParents.addTo(map);
var child1a = L.marker([50.02, 10.02],{title: 'Child 1a'});
var child1b = L.marker([50.04, 10.04],{title: 'Child 1b'});
var layergroupChilds1 = L.layerGroup([child1a, child1b]);
var child2a = L.marker([50.12, 10.12],{title: 'Child 2a'});
var child2b = L.marker([50.14, 10.14],{title: 'Child 2b'});
var layergroupChilds2 = L.layerGroup([child2a, child2b]);
parent1.on('click', function(){
if (map.hasLayer(layergroupChilds1)) {
map.removeLayer(layergroupChilds1)
} else {
layergroupChilds1.addTo(map);
}
});
parent2.on('click', function(){
if (map.hasLayer(layergroupChilds2)) {
map.removeLayer(layergroupChilds2)
} else {
layergroupChilds2.addTo(map);
}
});
</script>
</body>
</html>
Since I want to display quite a lot markers, I want put the marker's properties into an Array ("markerArray") and process its markers by the help of For-Loops:
<!DOCTYPE html>
<html>
<head>
<title>Test 2</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.0.1/dist/leaflet.js"></script>
<style>
body {padding: 0; margin: 0;}
html, body, #map {height: 100%;}
</style>
</head>
<body>
<div id='map'></div>
<script>
var thunder = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png', {subdomains:'abc', attribution:'Thunderforest | OpenStreetMap' });
var map = L.map('map',{layers: [thunder]}).setView([50.08, 10.08], 12);
var markerArray = [
["Marker 1", 50.0, 10.0, [["Child 1a", 50.02, 10.02], ["Child 1b", 50.04, 10.04]]],
["Marker 2", 50.1, 10.1, [["Child 1a", 50.12, 10.12], ["Child 1b", 50.14, 10.14]]],
];
var numberParents = markerArray.length;
var layergroupParents = L.layerGroup();
for (cnt1=0; cnt1<numberParents; cnt1++) {
var parentObject = L.marker([markerArray[cnt1][1], markerArray[cnt1][2]]);
parentObject.bindPopup(markerArray[cnt1][0]);
layergroupParents.addLayer (parentObject);
var numberChilds = markerArray[cnt1][3].length;
var layergroupChilds = L.layerGroup();
for (cnt2=0; cnt2<numberChilds; cnt2++) {
var childObject = L.marker([markerArray[cnt1][3][cnt2][1], markerArray[cnt1][3][cnt2][2]], {title: markerArray[cnt1][3][cnt2][0]});
layergroupChilds.addLayer (childObject);
}
parentObject.on('click', function(){
if (map.hasLayer(layergroupChilds)) {
map.removeLayer(layergroupChilds)
} else {
layergroupChilds.addTo(map);
}
});
}
layergroupParents.addTo(map);
</script>
</body>
</html>
If you execute these script you will see, that there's some problem with assigning an individual 'click' event to each individual parent-marker. Right now just the child-markers of the last parent-marker are toggled on/off even if I click onto the first parent-marker.
Do you have an idea how I could solve these problem and Script 2 is working like in Script 1?
For it to work, you have to attach the children to the parent (using a javascript property)
var layergroupChilds = L.layerGroup();
parentObject.layergroupChilds = layergroupChilds;
When parent receives a click, you can find the parent object in the event e, and hence its children.
parentObject.on('click', function(e){
if (map.hasLayer(e.target.layergroupChilds)) {
map.removeLayer(e.target.layergroupChilds)
} else {
e.target.layergroupChilds.addTo(map);
}
});
Here is your code with corrections

Bing Maps Polygon InfoBox

I have setup a map with polygons around the countries on the map, and want to add an infobox so that on hover some information will be displayed for each country.
I can get infoboxes displaying easy enough without the polygons, but when assigning them to the PolygonOptions class, nothing happens. The docs say that so long as I have the Bing Themes module loaded (Which I do), the infoboxes will show up on hover and click.
There seems to be zero documentation/examples of this, so hoping you clever folks can help out.
Here is some of the relevant code;
var center = this.map.getCenter();
// Create an info box
var infoboxOptions = {
width: 300,
height: 100,
title: 'Testing', // sourceItems.data.dataset[0].data[index].key,
description: "Visits: 20", // + sourceItems.data.dataset[0].data[index].visits,
showPointer: true,
titleClickHandler: this.polygonInfo,
offset: new Microsoft.Maps.Point(-100, 0),
typeName: Microsoft.Maps.InfoboxType.mini,
zIndex: 1000
};
var polyinfobox = new Microsoft.Maps.Infobox(center, infoboxOptions);
var polygonOptions = {
fillColor: Microsoft.Maps.Color.fromHex(fillColour),
strokeColor: Microsoft.Maps.Color.fromHex(fillColour),
strokeThickness: 1,
infobox: polyinfobox
};
var result = new Microsoft.Maps.Polygon(vertices, polygonOptions);
There is a working code sample in the interactive SDK for the Bing Maps V7 control here: http://www.bingmapsportal.com/ISDK/AjaxV7#BingThemeModule6
Note that creating an infobox for each shape is very inefficient and will hurt performance if you have a lot of shapes. A better method is to have one infobox and dynamically populate it's data. I wrote a blog post on this here: http://rbrundritt.wordpress.com/2011/10/13/multiple-pushpins-and-infoboxes-in-bing-maps-v7/ If you want to use this approach here is a code sample:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map, dataLayer, infobox;
function GetMap()
{
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), {
credentials: "YOUR_BING_MAPS_KEY"
});
dataLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(dataLayer);
var infoboxLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(infoboxLayer);
infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
infoboxLayer.push(infobox);
AddData();
}
function AddData(){
var polygon = new Microsoft.Maps.Polygon([
new Microsoft.Maps.Location(45, -110),
new Microsoft.Maps.Location(65, -90),
new Microsoft.Maps.Location(45, -70)]);
polygon.Metadata = {
title: 'Hello',
description: 'World'
};
dataLayer.push(polygon);
Microsoft.Maps.Events.addHandler(polygon, 'click', displayInfobox);
Microsoft.Maps.Events.addHandler(polygon, 'mouseover', displayInfobox);
}
function displayInfobox(e){
if(e.target){
var point = new Microsoft.Maps.Point(e.getX(), e.getY());
var loc = map.tryPixelToLocation(point);
infobox.setLocation(loc);
var opt = e.target.Metadata;
if(opt){
if(e.target.getIcon){ //is pushpin
opt.offset = new Microsoft.Maps.Point(0,20);
}else{
opt.offset = new Microsoft.Maps.Point(0,0);
}
opt.visible = true;
infobox.setOptions(opt);
}
}
}
</script>
</head>
<body onload="GetMap();">
<div id='mapDiv' style="position:relative; width:600px; height:600px;"></div>
</body>
</html>

Custom links to create defect in an app with sdk 2.0

I wrote an application which displays testCases in a treePanel. In that pannel, I have a specific column with icons for actions user can perform on a test case (show details, edit, add a bug...). In the column config, the renderer call this function, where data is an object with a _ref attribut like /testcase/123456/ :
_gridDataFormatTestCaseIcons:function(data)
{
var IconsString = Ext.String.format('<span class="icon-testCase"></span>', Rally.nav.Manager.getDetailUrl(data));
IconsString+= ' ';
IconsString+= '<span class="icon-edit"></span>';
IconsString+= ' ';
IconsString+= '<span class="icon-defect"></span>';
return IconsString ;
}
My first icon opens a new tab with details about the TestCase : OK. My 2nd icon opens a popup where I can edit my TestCase : OK. My third icon opens a popup where I can create a new bug. OK, but... I need to fill all the fileds, included the ones I guess it could be filled automatically.
So my question is about the third icon and the arguments of the function Rally.nav.Manager.create('defect') : the SDK 2.0rc2 docs here says it can take another argument args but don't give any details about it. Can i use it to specify the Owner and Test Case fields for example and how ?
You are correct, the args parameter can be an object that includes default attributes to populate into the Create Dialog. Only a limited subset of fields are accepted however:
Allowed args keys
User Story:
defaultName
rank
iteration
release
parent
dpyOid {dependency}
Defect:
defaultName
defectSuiteOid {Defect Suites}
testCaseResult
testCase
requirement
iteration
Defect Suite:
defaultName
rank
iteration
Portfolio Item:
defaultName
rank
parent
Task:
workProduct
Test Case:
testfolderOid {Test Folder}
artifactOid {Artifact}
It looks like the docs are a bit misleading, i.e., since we're creating a new object, instead of including a ref to an existing defect:
//Launch the create dialog
Rally.nav.Manager.create('/defect/12345');
The docs should read:
//Launch the create dialog
Rally.nav.Manager.create('defect');
Here's a quick example that pops and editor using a Button and sets the Defect Name and Default Iteration. Note that the Rally.nav.Manager functions generally only work when the app is installed and running inside Rally.
<!DOCTYPE html>
<html>
<head>
<title>Create Example</title>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/2.0rc2/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var myButtonContainer = Ext.create('Ext.Container', {
items: [{
xtype: 'rallybutton',
text: 'Click Here to Create a New Defect',
handler: function() {
//Launch the create dialog
var defectDefaults = {
defaultName: "My Defect",
iteration: "12345678910"
};
Rally.nav.Manager.create('defect', defectDefaults);
}
}],
});
this.add(myButtonContainer);
}
});
Rally.launchApp('CustomApp', {
name: 'Create Example'
});
});
</script>
<style type="text/css">
</style>
</head>
<body></body>
</html>

Here/Nokia Map markers not always shown

I have a few map markers that are located all over the place and I want to auto zoom to show them all.
The code I have should work fine but sometimes (seems to depend whereabouts the map markers are) it doesn't always zoom correctly to show the markers.
Here's a fiddle (with example markers to show the problem): http://jsfiddle.net/amnesia7/9YUVe/embedded/result/ using the following marker locations:
// Add markers to the map for each location
addMarker(1, "Hello 1", [-18,178.333]);
addMarker(2, "Hello 2", [-18.5,180]);
addMarker(3, "Hello 3", [-18.5,-178.333]);
The auto-zoom has gone completely wrong and seems to be zoomed in on the sea somewhere.
Looks to be a bug to me because it seems to depend on whereabouts the map markers are as to whether it zoom correctly or not.
UPDATE
I've created, what I hope will be, a simpler version using the HERE developer demo for "Zoom to a set of markers"
http://jsfiddle.net/amnesia7/uhZVz/
You need to zoom the map out to see the markers that should be in view by default.
Thanks
It looks like a bug to me too, and only occurs when markers cluster around the 180th line of longitude.
Seems that the zoomTo() calculation is incorrect in this case, only taking in to account the last marker since it is on the "wrong" side of the international date line.
Anyway, getWidth() on the viewport does seem to work, so you could hack in your own zoomTo() function as shown in the kludge below.
Also note the use of kml=auto&map=js-p2d-dom when loading the library - this uses the DOM implementation rather than the canvas implementation this properly shows markers on both sides of the 180th line of longitude.
<!DOCTYPE HTML SYSTEM>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9" />
<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>
<script type="text/javascript" charset="UTF-8" src="http://api.maps.nokia.com/2.2.3/jsl.js?kml=auto&map=js-p2d-dom"></script>
</head>
<body>
<div id="mapContainer"></div>
<script type="text/javascript">
/* 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", "APP_ID");
nokia.Settings.set("authenticationToken", "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: 13,
components: [
// We add the behavior component to allow panning / zooming of the map
new nokia.maps.map.component.Behavior()
]
});
// We create an instance of Container to store markers per city
var myContainer = new nokia.maps.map.Container();
/* We add all of the city containers to map's object collection so that
* when we add markers to them they will be rendered onto the map
*/
map.objects.add(myContainer);
// We create several of marker for a variety of famous landmarks
var firstMarker = new nokia.maps.map.StandardMarker(
[-18, 178.333],
{ text: 1 }
),
secondMarker = new nokia.maps.map.StandardMarker(
[-18.5, 180],
{ text: 2 }
),
thirdMarker = new nokia.maps.map.StandardMarker(
[-18.5, -178.333],
{ text: 3 }
);
// Add the newly created landmakers per city to its container
myContainer.objects.addAll([firstMarker, secondMarker, thirdMarker]);
/* Now we calculate the bounding boxes for every container.
* A bounding box represents a rectangular area in the geographic coordinate system.
*/
var myBoundingBox = myContainer.getBoundingBox();
zoom = 1;
map.setCenter(myBoundingBox.getCenter());
map.setZoomLevel(zoom);
while (map.getViewBounds().getWidth() > myBoundingBox.getWidth()) {
zoom++;
map.setZoomLevel(zoom);
}
zoom--
map.setZoomLevel(zoom--);
</script>
</body>
</html>

Resources