Difference between revisions of "Linden Lab Official:Map API Advanced Examples"

From Second Life Wiki
Jump to navigation Jump to search
 
(57 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Help/Box|Update notice|<b>We've made improvements and changes to the webmap, effective January 15, 2009.<br>Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.</b>}}
{{Supported API}}
{{:API Portal/navigation|map}}


See [http://slurl.com/examples/ Second Life Map API Examples] to see these examples in action.


{{:API Portal/navigation}}
'''NOTE:'''
This API is still in beta.  URLs and API signatures may change.  See the [[Map API#Release notes|Release Notes]] for information on new features and known issues.


== Linking to a Second Life coordinate using x and y coordinates (NEW) ==
== Linking to a Second Life coordinate (NEW) ==
We've created an easy function to teleport users to an absolute coordinate, for example 1000.5, 1000.5. If you'd like, skip to the example.


<pre>
[[Image:Teleport window.png|right]]
gotoSLURL(997,1002);
 
</pre>
The '''gotoSLURL()''' global function enables the user to teleport to the specified x,y coordinates, given a valid [[Webmap_API_Reference#SLMap|SLMap]] instance.  It first opens a window displaying the region name and a "Teleport" button, for example as shown at right.
 
<br>
<br>
 
For example, the following method call will pop-up the window illustrated here; the user can the click the "Teleport" button to open the Second Life Viewer and teleport to (997,1002). 
 
<javascript>gotoSLURL(997,1002, mapInstance);</javascript>
 
The example code below provides several similar examples.
 
'''Source code'''
 
<html4strict><!-- Insert HTML header here -->
<script>
var mapInstance;
function loadmap() {
  // creates the map
  mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<div id="map-container"></div>
<p>Click on these links to be teleported into Second Life via a SLURL:
<p><a href="javascript:gotoSLURL(997, 1002, mapInstance)"> Go to (997, 1002) </a>(where the welcome fountain is) <br />
<a href="javascript:gotoSLURL(996.5, 1001.6, mapInstance)"> Go to (996.5, 1001.6) </a> <br />


The above code will open up the Second Life client and then teleport the user to (997,1002) (where the welcome area fountain is).
<a href="javascript:gotoSLURL(1000, 1000, mapInstance)"> Go to (1000, 1000) </a><br />
</body></html4strict>


== Working with maps ==
== Working with maps ==
The [[Webmap_API_Reference#SLMap|SLMap]] object provides a great deal of control over how you display and interact with the map.  You can:
* Customize the zoom and pan controls.
* Disable and enable dragging the map.
* Pan/re-center the map to a specified location.
* Define event handler functions, called when:
** The user zooms or pans the map.
** The user clicks on the map.
** The user double-clicks on the map.
* Get the cooridnates of the map's center and bounds.
See [http://slurl.com/examples/ Second Life Map API Examples] to see these examples in action.


=== Customizing zoom and pan controls ===
=== Customizing zoom and pan controls ===


If you'd like to remove all the panning and zooming controls, or would like to create your own, its all pretty easy. If you'd like, skip to the example.
It's easy to remove all the zoom and pan controls or create your own. When you create the SLMap object, simply specify false for the [[Webmap_API_Reference#SLMapOptions|SLMapOptions]] properties hasZoomControls and hasPanningControls, for example:


<pre>
<javascript>mapInstance = new SLMap(document.getElementById('map-container'),  
mapInstance = new SLMap(document.getElementById('map-container'),  
                         {hasZoomControls: false,  
                         {hasZoomControls: false,  
                         hasPanningControls: false});
                         hasPanningControls: false});</javascript>
</pre>
 
This code creates a map with no zoom and pan controls.
 
To create your own zoom controls use the SLMap methods:
* setCurrentZoomLevel()
* getCurrentZoomLevel()
* zoomIn()
* zoomOut()
 
To create your own panning controls, use the SLMap methods:
* panLeft()
* panRight()
* panUp()
* panDown()
 
The following example contains a set of anchored links that call a function when clicked.
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header -->
<script>
var mapInstance;
 
function loadmap() {
  // creates the map
  mapInstance = new SLMap(document.getElementById('map-container'),
                          {hasZoomControls: false, hasPanningControls: false});
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();
}
 
function setZoom(level) {
  mapInstance.setCurrentZoomLevel(level);
  (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();
}
 
function zoomIn() {
  mapInstance.zoomIn();
  (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();
}
 
function zoomOut() {
  mapInstance.zoomOut();
  (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>This map has the usual pan/zoom controls disabled, and the hyperlinks
below implement custom pan/zoom controls via SLMap Javascript calls.
<h2>Set the zoom level</h2>
<h3>The Current Zoom Level is <span style='color:red' id='zoom_level'></span></h3>


The above code sets the map options hasZoomControls and hasPanControls to false.
<a href="javascript: setZoom(1);">1</a>
<a href="javascript: setZoom(2);">2</a>
<a href="javascript: setZoom(3);">3</a>
<a href="javascript: setZoom(4);">4</a>
<a href="javascript: setZoom(5);">5</a>
<a href="javascript: setZoom(6);">6</a>
<a href="javascript: setZoom(7);">7</a>
<a href="javascript: setZoom(8);">8</a>
<a href="javascript: zoomIn();">zoom in</a>
<a href="javascript: zoomOut();">zoom out</a>


Now, if we'd like to create our own zoom and pan controls, its not that hard either. We have created functions setCurrentZoomLevel(), getCurrentZoomLevel(), zoomIn(), zoomOut, panLeft, panRight, panUp and panDown so that you can essentially skin your maps.
<h2>Pan Around</h2>


In our example we've created an anchored link for each function, which will call its respective function when it is clicked.
<a href="javascript: mapInstance.panLeft();">left</a>
<a href="javascript: mapInstance.panRight();">right</a>
<a href="javascript: mapInstance.panUp();">up</a>
<a href="javascript: mapInstance.panDown();">down</a>
<br><br>
<div id="map-container"></div>
</body></html4strict>


=== Disabling and enabling dragging ===
=== Disabling and enabling dragging ===
Say you'd like to disable dragging on the map. No problem. If you'd like, skip to the example.  
To disable dragging on the map, simply call '''disableDragging()''' on the map object.


<pre>
<javascript>mapInstance.disableDragging();</javascript>
mapInstance.disableDragging();
 
</pre>
When you are done  call '''enableDragging()''' on the map object to re-enable dragging.
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header -->
<script>
var mapInstance;
 
function loadmap() {
  mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
}


</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p><a href="javascript: mapInstance.disableDragging();">Click to disable dragging map</a>
<p><a href="javascript: mapInstance.enableDragging();">Click to enable dragging map</a>


This one is simple, simply call disableDragging on the map object. When you are done just call enableDragging() on the map object to make it all normal again.
<div id="map-container"></div>
</body></html4strict>


=== Panning or re-centering the map ===
=== Panning or re-centering the map ===
This feature will let you pan the map to a specific coordinate. If the coordinate is not currently visible on the map, the map will instead just recenter the map to this location. If you'd like, skip to the example.


<pre>
Use the map object's '''panOrRecenterToSLCoord()''' method to pan the map to a specific point, providing the following parameters:
mapInstance.panOrRecenterToSLCoord(new XYPoint(1000,1000), true);
* An [[Webmap_API_Reference#XYPoint|XYPoint]] object, that identifies a specific x, y point.
</pre>
* Whether to recenter the map if the specified point is not currently visible.  This parameter is optional and defaults to false.
 
For example:
 
<javascript>mapInstance.panOrRecenterToSLCoord(new XYPoint(1000, 1000), true);</javascript>
 
The above code pans or recenters the map to (1000, 1000) depending on the current view.
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header -->
<script>
var mapInstance;
 
function loadmap() {
  // creates the map
  mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(998.5, 1001), 2);
 
  var mapWindow1 = new MapWindow("This is (997, 1002)");
  var mapWindow2 = new MapWindow("This is (1000, 1000)");
  var mapWindow3 = new MapWindow("This is (1010.5, 1000.5)");
 
  mapInstance.addMapWindow(mapWindow1, new XYPoint(997, 1002));
  mapInstance.addMapWindow(mapWindow2, new XYPoint(1000, 1000));
  mapInstance.addMapWindow(mapWindow3, new XYPoint(1010.5, 1000.5));
}
 
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>Click the links to pan or re-center the map on the indicated co-ordinates:
<p><a href="javascript: mapInstance.panOrRecenterToSLCoord(new XYPoint(1000, 1000), true);">
Pan or recenter to (1000, 1000)</a></p>
<p><a href="javascript: mapInstance.panOrRecenterToSLCoord(new XYPoint(1010.5, 1000.5), true);">
Pan or recenter to (1010.5, 1000.5)</a></p>
 
<div id="map-container"></div>
</body></html4strict>
 
=== Setting the onStateChangedHandler event handler ===
 
The map object has an onStateChangedHandler option that is a function called whenever the user pans or zooms the map.  Specify it in the [[Webmap_API_Reference#SLMapOptions|options]] when you initially create the map object.  For example:
 
<javascript>mapInstance = new SLMap(document.getElementById('map-container'), {onStateChangedHandler: doSomething});</javascript>
 
Whenever the user zooms or pans the map, the Map API will call the doSomething function.
 
This feature is handy when you want to show markers only currently in the user's viewport: in the event handler function, simply remove all the current markers, then place a new set of markers on the map based on the current map bounds.
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header --> 
<script>
function loadmap() {
  // creates the map
  mapInstance = new SLMap(document.getElementById('map-container'),
                          {onStateChangedHandler: doSomething});
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
}
function doSomething() {
  alert("The map state has changed!!");
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>This map will display an alert whenever the map's state changes (i.e. the map is panned or zoomed)
<div id="map-container"></div>
</body></html4strict>
 
=== Setting click and double-click event handlers ===
You can define a double click event handler function, that gets called when the user double-clicks on the map.  For example:
 
<javascript>// creates a function that we will bind to the double click action
var doubleClickHandlerFunction = function(x,y) {
  alert("you double clicked at (" + x + "," + y + ")");
};
 
var clickHandlerFunction = function(x,y) {
  alert("you double clicked at (" + x + "," + y + ")");
};
 
// creates the map
var mapInstance = new SLMap(document.getElementById('map-container'),
                            {doubleClickHandler: doubleClickHandlerFunction
                            clickHandler: clickHandlerFunction});
mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);</javascript>
 
{{Hilite|This does not appear to work currently.}}
 
The above code pops up a Javascript alert box showing the X and Y coordinate clicked. The X and Y coordinate will be passed as parameters to event handler functions.
{{Hilite|Is this still true?}}
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header -->
<script>
function doubleClickHandlerFunction() {
      alert("You double-clicked!")
}


The above code pans or recenters to (1000,1000) depending on the current view. The second parameter is optional, and if it is set to true, centers the map on the coordinate even if it is currently in the viewport.
function clickHandlerFunction() {
      alert("You clicked!")
}


=== Setting a onStateChangedHandler event handler ===
function loadmap() {
Lets say whenever the user moves around or zooms on the map, we want to fire off some function. With the onStateChangedHandler option, we can set a handler function to be called whenever this happens. If you'd like, skip to the example.
  // creates the map
  var mapInstance = new SLMap(document.getElementById('map-container'),
                              {doubleClickHandler: doubleClickHandlerFunction,
                                clickHandler: clickHandlerFunction});


<pre>
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
mapInstance = new SLMap(document.getElementById('map-container'), {onStateChangedHandler: doSomething});
}
</pre>


Whenever the state of the map changes, the doSomething function will be called. Hint: This feature is very handy when you only want to show markers currently in the user's viewport: whenever this handler is called, simply remove all the current markers, then grab a new set of markers to place on the map based on the current map bounds.
</script>
<body onload="loadmap()" onunload="GUnload()">
<p>There should be a yellow marker in the center of this map:
<div id="map-container"></div>
</body></html4strict>


=== Getting current map center and bounds ===
=== Getting current map center and bounds ===
These features will let you see where the map is currently centered and what the current bounds of the map are. If you'd like, skip to the example.


<pre>
Use the map object's '''getViewportBounds()''' method to get the bounds of the map.  This method returns a [[Webmap_API_Reference#Bounds|Bounds]] object that has xMin, xMax, yMin, and yMax properties for the current viewport.  For example:
var bounds = mapInstance.getViewportBounds();
 
var center = mapInstance.getMapCenter();  
var bounds = mapInstance.getViewportBounds();
</pre>
 
Use the map object's '''getMapCenter()''' method to get the coordinates of map.  This method returns an [[Webmap_API_Reference#XYPoint|XYPoint]] object representing the center of the map.  For example:
 
var center = mapInstance.getMapCenter();
 
These methods are handy to display only markers inside the current map viewport, or display markers based on the proximity from the map center.
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header -->
<script>
var mapInstance;
 
function loadmap() {
  // creates the map
  mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(998.5, 1001), 2);
 
  var mapWindow1 = new MapWindow("This is (997, 1002)");
  var mapWindow2 = new MapWindow("This is (1000, 1000)");
  var mapWindow3 = new MapWindow("This is (1020, 1020)");
 
  mapInstance.addMapWindow(mapWindow1, new XYPoint(997, 1002));
  mapInstance.addMapWindow(mapWindow2, new XYPoint(1000, 1000));
  mapInstance.addMapWindow(mapWindow3, new XYPoint(1020, 1020));
 
  checkBounds();
}
 
function checkBounds() {
  var bounds = mapInstance.getViewportBounds();
  var center = mapInstance.getMapCenter();
 
  document.getElementById('cent').innerHTML = "(" + center.x + "," + center.y + ")";
  document.getElementById('xMin').innerHTML = bounds.xMin;
  document.getElementById('xMax').innerHTML = bounds.xMax;
  document.getElementById('yMin').innerHTML = bounds.yMin;
  document.getElementById('yMax').innerHTML = bounds.yMax;
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>Drag/zoom the map and then <a href="javascript: checkBounds();">click here</a>
to check the current viewport bounds and center coordinate</p>


The getCodeBounds function will return a Bounds object, which basically contains xMin, xMax, yMin, and yMax attributes of the current viewport. The getMapCenter function will return an XYPoint object representing the center of the map.
<p>Center: <span id='cent'></span></p>
<p>X-Min: <span id='xMin'></span></p>


Tips: We can imagine this feature would be handy if you were only showing markers inside the current map viewport, or showing markers based on the proximity from the map center.
<p>X-Max: <span id='xMax'></span></p>
<p>Y-Min: <span id='yMin'></span></p>
<p>Y-Max: <span id='yMax'></span></p>
<div id="map-container"></div>
</body></html4strict>


== Working with markers ==
== Working with markers ==


There are a variety of window options you can set. Please refer to the API Classes and Methods page for a complete explanation.
The Marker object displays a small image at a particular x, y point on the map.
 
See [http://slurl.com/examples/ Second Life Map API Examples] to see these examples in action.


=== Setting a marker's event handlers ===
=== Setting a marker's event handlers ===
The following two features enable you great flexibility in customizing the behavior of maps.


Lets say you want to something else to happen besides a window opening when a marker is clicked. Like, for example, to retrieve a page about that specific coordinate or to show trigger some other javascript functionality you have on your page? Well, all this is possible.
The Marker object has three event handlers:
* clickHandler - function called when user clicks on the marker.
* mouseOverHandler - function called when user moves mouser pointer over marker.
* mouseOutHandler - function called when user moves mouse pointer off marker.


<pre>
Set these event handlers to Javascript functions when you construct the Map object.  For example:
// creates a function that we will bind to the marker click action
 
<javascript>// creates a function that we will bind to the marker click action
var doMarkerAction = function(marker) {
var doMarkerAction = function(marker) {
alert("an event occured at (" + marker.slCoord.x + "," + marker.slCoord.y + ")");
  alert("an event occured at (" + marker.slCoord.x + "," + marker.slCoord.y + ")");
};
};


// creates the marker and sets its event handlers
// creates the marker and sets its event handlers
var marker = new Marker(all_images,  
var marker = new Marker(all_images,  
                         new XYPoint(997,1002),  
                         new XYPoint(997, 1002),  
                         {clickHandler: doMarkerAction,  
                         {clickHandler: doMarkerAction,  
                         onMouseOutHandler: doMarkerAction,  
                         onMouseOutHandler: doMarkerAction,  
                         onMouseOverHandler: doMarkerAction});
                         onMouseOverHandler: doMarkerAction});</javascript>
</pre>
 
The code above simple sets all three event handlers of the marker to the '''doMarkerAction()''' function. The marker is passed as a parameter to this function.
 
'''Example source code'''
 
<html4strict><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container1
{
      width: 400px;
      height: 400px;
}
 
div#map-container2
{
      width: 400px;
      height: 400px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP API KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a global, so that the removeMarker function can access them
var mapInstance, marker;
 
var myClickHandler = function(marker)
{
    alert("Click handler for marker at ("+ marker.slCoord.x + ", " + marker.slCoord.y + ")");
}
 
function loadmap()
{
  // create the icons for use as a marker
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // First map
  mapInstance1 = new SLMap(document.getElementById('map-container1'));
  mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker1 = new Marker(all_images, new XYPoint(997, 1002));
  mapInstance1.addMarker(marker1);


The code above simple sets the click handler, onmouseover, and onmouseout handlers of the marker to a function we've defined: doMarkerAction(). The marker is passed as a parameter to this function, so, if we want, we can remove it from the map, or just see what coordinate it lies on.
  // Second map
  mapInstance2 = new SLMap(document.getElementById('map-container2'));
  mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker2 = new Marker(all_images, new XYPoint(997, 1002), {clickHandler: myClickHandler});
  mapInstance2.addMarker(marker2);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>No clickhandler (default):
<div id="map-container1"></div>
<p>Click handler installed:
<div id="map-container2"></div>
</body></html4strict>


=== Setting a double click handler ===
<!--
This feature of the map is very similar to the previous example, except it instead of the user having to click on a marker, he can click on anywhere on the map. Cool? Yes we think so. Heres an simpler example to look at.
Additional examples from old doc:


== Marker mouseout handler ==
<pre>
<pre>
// creates a function that we will bind to the double click action
<html>
var doubleClickHandlerFunction = function(x,y) {
<head>
alert("you double clicked at (" + x + "," + y + ")");
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
};
<style>
div#map-container1
{
      width: 400px;
      height: 400px;
}
 
div#map-container2
{
      width: 400px;
      height: 400px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a glabal, so that the removeMarker function can access them
var mapInstance, marker;
 
var myEventHandler = function(marker)
{
    alert("Mouse out handler for marker at ("+ marker.slCoord.x + ", " + marker.slCoord.y + ")");
}
 
function loadmap()
{
  // create the icons for use as a marker
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // First map
  mapInstance1 = new SLMap(document.getElementById('map-container1'));
  mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker1 = new Marker(all_images, new XYPoint(997,1002));
  mapInstance1.addMarker(marker1);


// creates the map
  // Second map
var mapInstance = new SLMap(document.getElementById('map-container'),
  mapInstance2 = new SLMap(document.getElementById('map-container2'));
                            {doubleClickHandler: doubleClickHandlerFunction});
  mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5,1001.5),2);
 
  // creates the marker
  marker2 = new Marker(all_images, new XYPoint(997, 1002), {onMouseOutHandler: myEventHandler});
  mapInstance2.addMarker(marker2);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>No mouseout handler (default):
<div id="map-container1"></div>
<p>Mouse out handler installed:
<div id="map-container2"></div>
</body>
</pre>
</pre>


The above code will fire off a javascript alert with the X and Y coordinate clicked. The X and Y coordinate will be passed as parameters to the function you specify to be the double click handler.
== Marker mouseover event handler ==
<pre>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container1
{
      width: 400px;
      height: 400px;
}


Similarly to the doubleClickHandler option, you can now set the singleClickHandler option. Please refer to this example
div#map-container2
{
      width: 400px;
      height: 400px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a glabal, so that the removeMarker function can access them
var mapInstance, marker;
 
var myEventHandler = function(marker)
{
    alert("Mouse over handler for marker at ("+ marker.slCoord.x + ", " + marker.slCoord.y + ")");
}
 
function loadmap()
{
  // create the icons for use as a marker
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // First map
  mapInstance1 = new SLMap(document.getElementById('map-container1'));
  mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker1 = new Marker(all_images, new XYPoint(997, 1002));
  mapInstance1.addMarker(marker1);
 
  // Second map
  mapInstance2 = new SLMap(document.getElementById('map-container2'));
  mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker2 = new Marker(all_images, new XYPoint(997, 1002), {onMouseOverHandler: myEventHandler});
  mapInstance2.addMarker(marker2);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>No mouseover handler (default):
<div id="map-container1"></div>
<p>Mouse over handler installed:
<div id="map-container2"></div>
</body>
</pre>
-->


=== Removing a marker ===
=== Removing a marker ===
Markers can be removed by passing the original marker to the removeMarker function. If you'd like, skip to the example.


<pre>
Call the map object's '''removeMarker()''' method to remove a marker, passing the marker object as the parameter.  For example:
mapInstance.removeMarker(marker);
 
</pre>
<javascript>mapInstance.removeMarker(myMarker);</javascript>
 
The above code removes the marker myMarker.
 
 
'''Example source code'''
 
<html4strict><script>
<!-- Insert common HTML header -->
// mapInstance and marker are global, so removeMarker() can access them.
var mapInstance, marker;
 
function loadmap() {
  // Creates the map
  mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // Creates the icons
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // Creates the marker
  marker = new Marker(all_images, new XYPoint(997, 1002));
  mapInstance.addMarker(marker);
}


The above code simply removes the marker, where marker is a reference to the original marker.
function removeMarker() {
  // Removes the marker
  mapInstance.removeMarker(marker);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<a href="javascript: removeMarker();">Click to remove the yellow marker from the map</a>
<div id="map-container"></div>
</body></html4strict>


=== Triggering a marker click ===
=== Triggering a marker click ===
This feature simulates clicking a certain marker. If the marker currently isn't in the map viewport, it will recenter the map to this coordinate. If you'd like, skip to the example.


<pre>
To simulate clicking on a marker, use the Map object's '''clickMarker()''' method, passing the marker as the parameter.  For example:
mapInstance.clickMarker(marker);
 
</pre>
mapInstance.clickMarker(marker);
 
This method can come in handy if you are listing links somewhere else on the page, and want links to open up markers with more information.


Tips: This feature can come in handy if you are listing links somewhere else on the page, and want links to open up markers with more information.  
=== Creating markers with shadows ===
You can use a PNG image to make a marker appear to have a "shadow." To do this:
* Create two [[Webmap_API_Reference#Img|Img]] objects, one for the marker image and one for the shadow image.
* When creating the [[Webmap_API_Reference#Img|Img]] objects, provide "true" as the fourth argument to the constructor, indicating to create the image with an alpha channel (which provides transparency).
* When creating the [[Webmap_API_Reference#Icon|Icon]]  object, provide both Img objects as  arguments to the constructor.  


=== Using PNG images and shadows with markers ===
For example:
You can also use PNG Images to make your icons even more pretty. If you'd like, skip to the example.
<javascript>// creates the icons
<pre>
var forsale_sign = new Img("forsale.png", 80, 83, true); // note how the fourth parameter is set true!
// creates the icons
var forsale_shadow = new Img("forsale-shadow.png", 98, 83, true);
var forsale_sign = new Img("forsale.png",80,83, true); // note how the fourth parameter is set true!
var forsale_shadow = new Img("forsale-shadow.png",98,83, true);
var forsale_icon = new Icon(forsale_sign, forsale_shadow);
var forsale_icon = new Icon(forsale_sign, forsale_shadow);
var all_images = [forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon];
var all_images = [forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon];


// creates the marker
// creates the marker
var marker = new Marker(all_images, new XYPoint(995,1004));
var marker = new Marker(all_images, new XYPoint(995, 1004));
mapInstance.addMarker(marker);
mapInstance.addMarker(marker);</javascript>
 
== Additional examples ==
 
See [http://slurl.com/examples/ Second Life Map API Examples] to see these examples in action.
 
<!-- Doesn't work
=== Closing a map window automatically when user pans the map ===
<pre>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container {
      width: 500px;
      height: 500px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP API KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
function loadmap() {
  // creates the map
  var mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);
 
  // creates a window
  var mapWindow = new MapWindow("This is where the welcome area fountain is!! <br><img src='fountain.gif'>",
                                {closeOnMove: true});
  mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>When you drag this map, the info window should disappear:<br />
<div id="map-container"></div>
</body>
</pre>
</pre>
The above code is almost identical to example two, except that when we define an Img, we specify a fourth argument in the constructor, telling the class to create the image with an alpha channel (alpha channel basically means that fancy transparency you cant get with GIF's). Also, when we create the Icon, we also specify another Img as the second argument, which specifies a shadow. Thats pretty much all you have to do to get pretty PNG icons.  
-->
 
=== Aligning marker images ===
<html4strict><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container1
{
      width: 400px;
      height: 400px;
}
 
div#map-container2
{
      width: 400px;
      height: 400px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a glabal, so that the removeMarker function can access them
var mapInstance, marker;
 
function loadmap()
{
  // create the icons for use as a marker
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // First map
  mapInstance1 = new SLMap(document.getElementById('map-container1'));
  mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker1 = new Marker(all_images, new XYPoint(997,1002),
                        {verticalAlign: "top", horizontalAlign: "left"});
  mapInstance1.addMarker(marker1);
 
  // Second map
  mapInstance2 = new SLMap(document.getElementById('map-container2'));
  mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  marker2 = new Marker(all_images, new XYPoint(997,1002),
                        {verticalAlign: "bottom", horizontalAlign: "right"});
  mapInstance2.addMarker(marker2);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>Marker icon aligned to top-left:
<div id="map-container1"></div>
<p>Marker icon aligned to bottom-right:
<div id="map-container2"></div>
</body></html4strict>
 
=== Centering the map on a marker when user clicks it ===
<html4strict><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container1
{
      width: 400px;
      height: 400px;
}
 
div#map-container2
{
      width: 400px;
      height: 400px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a glabal, so that the removeMarker function can access them
var mapInstance, marker;
 
function loadmap()
{
  // create the icons for use as a marker
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // First map
  mapInstance1 = new SLMap(document.getElementById('map-container1'));
  mapInstance1.centerAndZoomAtSLCoord(new XYPoint(996,1001),2);
 
  // creates the marker
  marker1 = new Marker(all_images, new XYPoint(997,1002));
  mapInstance1.addMarker(marker1);
 
  // Second map
  mapInstance2 = new SLMap(document.getElementById('map-container2'));
  mapInstance2.centerAndZoomAtSLCoord(new XYPoint(996,1001),2);
 
  // creates the marker
  marker2 = new Marker(all_images, new XYPoint(997,1002), {centerOnClick: true});
  mapInstance2.addMarker(marker2);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>Clicking on this marker should have no effect:
<div id="map-container1"></div>
<p>Clicking on this marker should center the map on the marker:
<div id="map-container2"></div>
</body></html4strict>
 
=== Controlling marker z-order ===
<html4strict><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container1
{
      width: 400px;
      height: 400px;
}
 
div#map-container2
{
      width: 400px;
      height: 400px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a glabal, so that the removeMarker function can access them
var mapInstance, marker;
 
function loadmap()
{
  // create the icons for use as a marker
  var marker1_image = new Img("marker_1.gif", 64, 64);
  var marker1_icon = new Icon(marker1_image);
  var marker1_images = [marker1_icon, marker1_icon, marker1_icon, marker1_icon, marker1_icon, marker1_icon];
 
  var marker2_image = new Img("marker_2.gif", 64, 64);
  var marker2_icon = new Icon(marker2_image);
  var marker2_images = [marker2_icon, marker2_icon, marker2_icon, marker2_icon, marker2_icon, marker2_icon];
 
  // First map
  var mapInstance1 = new SLMap(document.getElementById('map-container1'));
  mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  var marker1a = new Marker(marker1_images, new XYPoint(997, 1002),
                        {zLayer: 1});
  mapInstance1.addMarker(marker1a);
 
  var marker1b = new Marker(marker2_images, new XYPoint(997.15, 1002.15),
                        {zLayer: 0});
  mapInstance1.addMarker(marker1b);
 
  // Second map
  mapInstance2 = new SLMap(document.getElementById('map-container2'));
  mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the marker
  var marker2a = new Marker(marker1_images, new XYPoint(997, 1002),
                        {zLayer: 0});
  mapInstance2.addMarker(marker2a);
 
  var marker2b = new Marker(marker2_images, new XYPoint(997.15, 1002.15),
                        {zLayer: 1});
  mapInstance2.addMarker(marker2b);
 
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>The '1' marker icon should be on top of the '2' marker icon:
<div id="map-container1"></div>
<p>The '2' marker icon should be on top of the '1' marker icon:
<div id="map-container2"></div>
</body></html4strict>
 
=== Removing all markers from a map ===
<html4strict><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style>
div#map-container {
      width: 500px;
      height: 500px;
}
</style>
 
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=[GOOGLE MAP KEY]"
  type="text/javascript"></script>
<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script>
<script>
// mapInstance and marker is set as a glabal, so that the removeMarker function can access them
var mapInstance, marker;
 
function loadmap() {
  // creates the map
  mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
  // creates the icons
  var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
  var yellow_icon = new Icon(yellow_dot_image);
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
  // creates the markers
  var marker = new Marker(all_images, new XYPoint(997,1002));
  mapInstance.addMarker(marker);
  marker = new Marker(all_images, new XYPoint(997.4,1002));
  mapInstance.addMarker(marker);
  marker = new Marker(all_images, new XYPoint(997.2,1002.8));
  mapInstance.addMarker(marker);
  marker = new Marker(all_images, new XYPoint(997.8,1002.2));
  mapInstance.addMarker(marker);
  marker = new Marker(all_images, new XYPoint(997.1,1002.65));
  mapInstance.addMarker(marker);
}
 
function removeAllMarkers()
{
  // removes all the the marker
  mapInstance.removeAllMarkers();
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<a href="javascript: mapInstance.removeAllMarkers();">Click to remove all the markers</a>
<div id="map-container"></div>
</body></html4strict>
 
'''Example source code'''
 
<html4strict><!-- Insert common HTML header -->
<script>
function loadmap() {
  // creates the map
  var mapInstance = new SLMap(document.getElementById('map-container'));
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(995,1004),2);
 
  // creates the icons
  var forsale_sign = new Img("forsale.png",80,83, true);
  var forsale_shadow = new Img("forsale-shadow.png", 98, 83, true);
  var forsale_icon = new Icon(forsale_sign, forsale_shadow);
  var all_images = [forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon];
 
  // creates the marker
  var marker = new Marker(all_images, new XYPoint(995, 1004));
  mapInstance.addMarker(marker);
}
</script>
</head>
<body onload="loadmap()" onunload="GUnload()">
<p>The map shows a 'for sale' sign marker with smooth edges, and an anti-aliased shadow.
<div id="map-container"></div>
</body></html4strict>


<!--
== Using Second Life region names (NOT IMPLEMENTED) ==
== Using Second Life region names (NOT IMPLEMENTED) ==
I know you've been wondering, what if I don't know which XY coordinate corresponds to which region name? Well, with this feature you can now use region names to define locations on the map instead of XY coordinates. If you'd like, skip to the example.  
I know you've been wondering, what if I don't know which XY coordinate corresponds to which region name? Well, with this feature you can now use region names to define locations on the map instead of XY coordinates. If you'd like, skip to the example.  
Line 163: Line 963:
SLPoint("dA bOOm")
SLPoint("dA bOOm")
</pre>
</pre>
-->

Latest revision as of 13:28, 4 May 2011

NOTE: This is an official Second Life API provided and documented by Linden Lab. Its use is subject to the API Terms of Use.

See Second Life Map API Examples to see these examples in action.

NOTE: This API is still in beta. URLs and API signatures may change. See the Release Notes for information on new features and known issues.

Linking to a Second Life coordinate (NEW)

Teleport window.png

The gotoSLURL() global function enables the user to teleport to the specified x,y coordinates, given a valid SLMap instance. It first opens a window displaying the region name and a "Teleport" button, for example as shown at right.



For example, the following method call will pop-up the window illustrated here; the user can the click the "Teleport" button to open the Second Life Viewer and teleport to (997,1002).

<javascript>gotoSLURL(997,1002, mapInstance);</javascript>

The example code below provides several similar examples.

Source code

<html4strict> <script> var mapInstance; function loadmap() {

 // creates the map
 mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

Click on these links to be teleported into Second Life via a SLURL:

<a href="javascript:gotoSLURL(997, 1002, mapInstance)"> Go to (997, 1002) </a>(where the welcome fountain is)
<a href="javascript:gotoSLURL(996.5, 1001.6, mapInstance)"> Go to (996.5, 1001.6) </a>
<a href="javascript:gotoSLURL(1000, 1000, mapInstance)"> Go to (1000, 1000) </a>
</body></html4strict>

Working with maps

The SLMap object provides a great deal of control over how you display and interact with the map. You can:

  • Customize the zoom and pan controls.
  • Disable and enable dragging the map.
  • Pan/re-center the map to a specified location.
  • Define event handler functions, called when:
    • The user zooms or pans the map.
    • The user clicks on the map.
    • The user double-clicks on the map.
  • Get the cooridnates of the map's center and bounds.

See Second Life Map API Examples to see these examples in action.

Customizing zoom and pan controls

It's easy to remove all the zoom and pan controls or create your own. When you create the SLMap object, simply specify false for the SLMapOptions properties hasZoomControls and hasPanningControls, for example:

<javascript>mapInstance = new SLMap(document.getElementById('map-container'),

                       {hasZoomControls: false, 
                        hasPanningControls: false});</javascript>

This code creates a map with no zoom and pan controls.

To create your own zoom controls use the SLMap methods:

  • setCurrentZoomLevel()
  • getCurrentZoomLevel()
  • zoomIn()
  • zoomOut()

To create your own panning controls, use the SLMap methods:

  • panLeft()
  • panRight()
  • panUp()
  • panDown()

The following example contains a set of anchored links that call a function when clicked.

Example source code

<html4strict> <script> var mapInstance;

function loadmap() {

 // creates the map
 mapInstance = new SLMap(document.getElementById('map-container'), 
                         {hasZoomControls: false, hasPanningControls: false});
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();

}

function setZoom(level) {

 mapInstance.setCurrentZoomLevel(level);
 (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();

}

function zoomIn() {

 mapInstance.zoomIn();
 (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();

}

function zoomOut() {

 mapInstance.zoomOut();
 (document.getElementById('zoom_level')).innerHTML = mapInstance.getCurrentZoomLevel();

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

This map has the usual pan/zoom controls disabled, and the hyperlinks below implement custom pan/zoom controls via SLMap Javascript calls.

Set the zoom level

The Current Zoom Level is

<a href="javascript: setZoom(1);">1</a> <a href="javascript: setZoom(2);">2</a> <a href="javascript: setZoom(3);">3</a> <a href="javascript: setZoom(4);">4</a> <a href="javascript: setZoom(5);">5</a> <a href="javascript: setZoom(6);">6</a> <a href="javascript: setZoom(7);">7</a> <a href="javascript: setZoom(8);">8</a> <a href="javascript: zoomIn();">zoom in</a> <a href="javascript: zoomOut();">zoom out</a>

Pan Around

<a href="javascript: mapInstance.panLeft();">left</a> <a href="javascript: mapInstance.panRight();">right</a> <a href="javascript: mapInstance.panUp();">up</a> <a href="javascript: mapInstance.panDown();">down</a>

</body></html4strict>

Disabling and enabling dragging

To disable dragging on the map, simply call disableDragging() on the map object.

<javascript>mapInstance.disableDragging();</javascript>

When you are done call enableDragging() on the map object to re-enable dragging.

Example source code

<html4strict> <script> var mapInstance;

function loadmap() {

 mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);

}

</script> </head> <body onload="loadmap()" onunload="GUnload()">

<a href="javascript: mapInstance.disableDragging();">Click to disable dragging map</a>

<a href="javascript: mapInstance.enableDragging();">Click to enable dragging map</a>

</body></html4strict>

Panning or re-centering the map

Use the map object's panOrRecenterToSLCoord() method to pan the map to a specific point, providing the following parameters:

  • An XYPoint object, that identifies a specific x, y point.
  • Whether to recenter the map if the specified point is not currently visible. This parameter is optional and defaults to false.

For example:

<javascript>mapInstance.panOrRecenterToSLCoord(new XYPoint(1000, 1000), true);</javascript>

The above code pans or recenters the map to (1000, 1000) depending on the current view.

Example source code

<html4strict> <script> var mapInstance;

function loadmap() {

 // creates the map
 mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(998.5, 1001), 2);
 
 var mapWindow1 = new MapWindow("This is (997, 1002)");
 var mapWindow2 = new MapWindow("This is (1000, 1000)");
 var mapWindow3 = new MapWindow("This is (1010.5, 1000.5)");
 
 mapInstance.addMapWindow(mapWindow1, new XYPoint(997, 1002));
 mapInstance.addMapWindow(mapWindow2, new XYPoint(1000, 1000));
 mapInstance.addMapWindow(mapWindow3, new XYPoint(1010.5, 1000.5));

}

</script> </head> <body onload="loadmap()" onunload="GUnload()">

Click the links to pan or re-center the map on the indicated co-ordinates:

<a href="javascript: mapInstance.panOrRecenterToSLCoord(new XYPoint(1000, 1000), true);"> Pan or recenter to (1000, 1000)</a>

<a href="javascript: mapInstance.panOrRecenterToSLCoord(new XYPoint(1010.5, 1000.5), true);"> Pan or recenter to (1010.5, 1000.5)</a>

</body></html4strict>

Setting the onStateChangedHandler event handler

The map object has an onStateChangedHandler option that is a function called whenever the user pans or zooms the map. Specify it in the options when you initially create the map object. For example:

<javascript>mapInstance = new SLMap(document.getElementById('map-container'), {onStateChangedHandler: doSomething});</javascript>

Whenever the user zooms or pans the map, the Map API will call the doSomething function.

This feature is handy when you want to show markers only currently in the user's viewport: in the event handler function, simply remove all the current markers, then place a new set of markers on the map based on the current map bounds.

Example source code

<html4strict> <script> function loadmap() {

 // creates the map
 mapInstance = new SLMap(document.getElementById('map-container'), 
                         {onStateChangedHandler: doSomething});
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);

} function doSomething() {

 alert("The map state has changed!!");

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

This map will display an alert whenever the map's state changes (i.e. the map is panned or zoomed)

</body></html4strict>

Setting click and double-click event handlers

You can define a double click event handler function, that gets called when the user double-clicks on the map. For example:

<javascript>// creates a function that we will bind to the double click action var doubleClickHandlerFunction = function(x,y) {

 alert("you double clicked at (" + x + "," + y + ")");

};

var clickHandlerFunction = function(x,y) {

 alert("you double clicked at (" + x + "," + y + ")");

};

// creates the map var mapInstance = new SLMap(document.getElementById('map-container'),

                           {doubleClickHandler: doubleClickHandlerFunction
                            clickHandler: clickHandlerFunction});

mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);</javascript>

This does not appear to work currently.

The above code pops up a Javascript alert box showing the X and Y coordinate clicked. The X and Y coordinate will be passed as parameters to event handler functions. Is this still true?

Example source code

<html4strict> <script> function doubleClickHandlerFunction() {

     alert("You double-clicked!")

}

function clickHandlerFunction() {

     alert("You clicked!")

}

function loadmap() {

 // creates the map
 var mapInstance = new SLMap(document.getElementById('map-container'),
                             {doubleClickHandler: doubleClickHandlerFunction,
                               clickHandler: clickHandlerFunction});
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);

}

</script> <body onload="loadmap()" onunload="GUnload()">

There should be a yellow marker in the center of this map:

</body></html4strict>

Getting current map center and bounds

Use the map object's getViewportBounds() method to get the bounds of the map. This method returns a Bounds object that has xMin, xMax, yMin, and yMax properties for the current viewport. For example:

var bounds = mapInstance.getViewportBounds();

Use the map object's getMapCenter() method to get the coordinates of map. This method returns an XYPoint object representing the center of the map. For example:

var center = mapInstance.getMapCenter(); 

These methods are handy to display only markers inside the current map viewport, or display markers based on the proximity from the map center.

Example source code

<html4strict> <script> var mapInstance;

function loadmap() {

 // creates the map
 mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(998.5, 1001), 2);
 
 var mapWindow1 = new MapWindow("This is (997, 1002)");
 var mapWindow2 = new MapWindow("This is (1000, 1000)");
 var mapWindow3 = new MapWindow("This is (1020, 1020)");
 
 mapInstance.addMapWindow(mapWindow1, new XYPoint(997, 1002));
 mapInstance.addMapWindow(mapWindow2, new XYPoint(1000, 1000));
 mapInstance.addMapWindow(mapWindow3, new XYPoint(1020, 1020)); 
 
 checkBounds();

}

function checkBounds() {

 var bounds = mapInstance.getViewportBounds();
 var center = mapInstance.getMapCenter();
 
 document.getElementById('cent').innerHTML = "(" + center.x + "," + center.y + ")";
 document.getElementById('xMin').innerHTML = bounds.xMin;
 document.getElementById('xMax').innerHTML = bounds.xMax;
 document.getElementById('yMin').innerHTML = bounds.yMin;
 document.getElementById('yMax').innerHTML = bounds.yMax;

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

Drag/zoom the map and then <a href="javascript: checkBounds();">click here</a> to check the current viewport bounds and center coordinate

Center:

X-Min:

X-Max:

Y-Min:

Y-Max:

</body></html4strict>

Working with markers

The Marker object displays a small image at a particular x, y point on the map.

See Second Life Map API Examples to see these examples in action.

Setting a marker's event handlers

The Marker object has three event handlers:

  • clickHandler - function called when user clicks on the marker.
  • mouseOverHandler - function called when user moves mouser pointer over marker.
  • mouseOutHandler - function called when user moves mouse pointer off marker.

Set these event handlers to Javascript functions when you construct the Map object. For example:

<javascript>// creates a function that we will bind to the marker click action var doMarkerAction = function(marker) {

 alert("an event occured at (" + marker.slCoord.x + "," + marker.slCoord.y + ")");

};

// creates the marker and sets its event handlers var marker = new Marker(all_images,

                       new XYPoint(997, 1002), 
                       {clickHandler: doMarkerAction, 
                        onMouseOutHandler: doMarkerAction, 
                        onMouseOverHandler: doMarkerAction});</javascript>

The code above simple sets all three event handlers of the marker to the doMarkerAction() function. The marker is passed as a parameter to this function.

Example source code

<html4strict><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <style> div#map-container1 {

     width: 400px;
     height: 400px;

}

div#map-container2 {

     width: 400px;
     height: 400px;

} </style>

<script src="http://maps.google.com/maps?file=api&v=2&key=[GOOGLE MAP API KEY]"

 type="text/javascript"></script>

<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script> <script> // mapInstance and marker is set as a global, so that the removeMarker function can access them var mapInstance, marker;

var myClickHandler = function(marker) {

   alert("Click handler for marker at ("+ marker.slCoord.x + ", " + marker.slCoord.y + ")");

}

function loadmap() {

 // create the icons for use as a marker
 var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
 var yellow_icon = new Icon(yellow_dot_image);
 var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
 // First map
 mapInstance1 = new SLMap(document.getElementById('map-container1'));
 mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the marker
 marker1 = new Marker(all_images, new XYPoint(997, 1002));
 mapInstance1.addMarker(marker1);
 // Second map
 mapInstance2 = new SLMap(document.getElementById('map-container2'));
 mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the marker
 marker2 = new Marker(all_images, new XYPoint(997, 1002), {clickHandler: myClickHandler});
 mapInstance2.addMarker(marker2);

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

No clickhandler (default):

Click handler installed:

</body></html4strict>


Removing a marker

Call the map object's removeMarker() method to remove a marker, passing the marker object as the parameter. For example:

<javascript>mapInstance.removeMarker(myMarker);</javascript>

The above code removes the marker myMarker.


Example source code

<html4strict><script> // mapInstance and marker are global, so removeMarker() can access them. var mapInstance, marker;

function loadmap() {

 // Creates the map
 mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // Creates the icons
 var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
 var yellow_icon = new Icon(yellow_dot_image);
 var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
 // Creates the marker
 marker = new Marker(all_images, new XYPoint(997, 1002));
 mapInstance.addMarker(marker);

}

function removeMarker() {

 // Removes the marker
 mapInstance.removeMarker(marker);

} </script> </head> <body onload="loadmap()" onunload="GUnload()"> <a href="javascript: removeMarker();">Click to remove the yellow marker from the map</a>

</body></html4strict>

Triggering a marker click

To simulate clicking on a marker, use the Map object's clickMarker() method, passing the marker as the parameter. For example:

mapInstance.clickMarker(marker);

This method can come in handy if you are listing links somewhere else on the page, and want links to open up markers with more information.

Creating markers with shadows

You can use a PNG image to make a marker appear to have a "shadow." To do this:

  • Create two Img objects, one for the marker image and one for the shadow image.
  • When creating the Img objects, provide "true" as the fourth argument to the constructor, indicating to create the image with an alpha channel (which provides transparency).
  • When creating the Icon object, provide both Img objects as arguments to the constructor.

For example: <javascript>// creates the icons var forsale_sign = new Img("forsale.png", 80, 83, true); // note how the fourth parameter is set true! var forsale_shadow = new Img("forsale-shadow.png", 98, 83, true); var forsale_icon = new Icon(forsale_sign, forsale_shadow); var all_images = [forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon];

// creates the marker var marker = new Marker(all_images, new XYPoint(995, 1004)); mapInstance.addMarker(marker);</javascript>

Additional examples

See Second Life Map API Examples to see these examples in action.


Aligning marker images

<html4strict><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <style> div#map-container1 {

     width: 400px;
     height: 400px;

}

div#map-container2 {

     width: 400px;
     height: 400px;

} </style>

<script src="http://maps.google.com/maps?file=api&v=2&key=[GOOGLE MAP KEY]"

 type="text/javascript"></script>

<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script> <script> // mapInstance and marker is set as a glabal, so that the removeMarker function can access them var mapInstance, marker;

function loadmap() {

 // create the icons for use as a marker
 var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
 var yellow_icon = new Icon(yellow_dot_image);
 var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
 // First map
 mapInstance1 = new SLMap(document.getElementById('map-container1'));
 mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the marker
 marker1 = new Marker(all_images, new XYPoint(997,1002),
                       {verticalAlign: "top", horizontalAlign: "left"});
 mapInstance1.addMarker(marker1);
 // Second map
 mapInstance2 = new SLMap(document.getElementById('map-container2'));
 mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the marker
 marker2 = new Marker(all_images, new XYPoint(997,1002), 
                       {verticalAlign: "bottom", horizontalAlign: "right"});
 mapInstance2.addMarker(marker2);

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

Marker icon aligned to top-left:

Marker icon aligned to bottom-right:

</body></html4strict>

Centering the map on a marker when user clicks it

<html4strict><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <style> div#map-container1 {

     width: 400px;
     height: 400px;

}

div#map-container2 {

     width: 400px;
     height: 400px;

} </style>

<script src="http://maps.google.com/maps?file=api&v=2&key=[GOOGLE MAP KEY]"

 type="text/javascript"></script>

<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script> <script> // mapInstance and marker is set as a glabal, so that the removeMarker function can access them var mapInstance, marker;

function loadmap() {

 // create the icons for use as a marker
 var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
 var yellow_icon = new Icon(yellow_dot_image);
 var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
 // First map
 mapInstance1 = new SLMap(document.getElementById('map-container1'));
 mapInstance1.centerAndZoomAtSLCoord(new XYPoint(996,1001),2);
 
 // creates the marker
 marker1 = new Marker(all_images, new XYPoint(997,1002));
 mapInstance1.addMarker(marker1);
 // Second map
 mapInstance2 = new SLMap(document.getElementById('map-container2'));
 mapInstance2.centerAndZoomAtSLCoord(new XYPoint(996,1001),2);
 
 // creates the marker
 marker2 = new Marker(all_images, new XYPoint(997,1002), {centerOnClick: true});
 mapInstance2.addMarker(marker2);

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

Clicking on this marker should have no effect:

Clicking on this marker should center the map on the marker:

</body></html4strict>

Controlling marker z-order

<html4strict><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <style> div#map-container1 {

     width: 400px;
     height: 400px;

}

div#map-container2 {

     width: 400px;
     height: 400px;

} </style>

<script src="http://maps.google.com/maps?file=api&v=2&key=[GOOGLE MAP KEY]"

 type="text/javascript"></script>

<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script> <script> // mapInstance and marker is set as a glabal, so that the removeMarker function can access them var mapInstance, marker;

function loadmap() {

 // create the icons for use as a marker
 var marker1_image = new Img("marker_1.gif", 64, 64);
 var marker1_icon = new Icon(marker1_image);
 var marker1_images = [marker1_icon, marker1_icon, marker1_icon, marker1_icon, marker1_icon, marker1_icon];
 
 var marker2_image = new Img("marker_2.gif", 64, 64);
 var marker2_icon = new Icon(marker2_image);
 var marker2_images = [marker2_icon, marker2_icon, marker2_icon, marker2_icon, marker2_icon, marker2_icon];
 
 // First map
 var mapInstance1 = new SLMap(document.getElementById('map-container1'));
 mapInstance1.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the marker
 var marker1a = new Marker(marker1_images, new XYPoint(997, 1002),
                       {zLayer: 1});
 mapInstance1.addMarker(marker1a);
 var marker1b = new Marker(marker2_images, new XYPoint(997.15, 1002.15),
                       {zLayer: 0});
 mapInstance1.addMarker(marker1b);
 // Second map
 mapInstance2 = new SLMap(document.getElementById('map-container2'));
 mapInstance2.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the marker
 var marker2a = new Marker(marker1_images, new XYPoint(997, 1002),
                       {zLayer: 0});
 mapInstance2.addMarker(marker2a);
 var marker2b = new Marker(marker2_images, new XYPoint(997.15, 1002.15),
                       {zLayer: 1});
 mapInstance2.addMarker(marker2b);

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

The '1' marker icon should be on top of the '2' marker icon:

The '2' marker icon should be on top of the '1' marker icon:

</body></html4strict>

Removing all markers from a map

<html4strict><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <style> div#map-container {

     width: 500px;
     height: 500px;

} </style>

<script src="http://maps.google.com/maps?file=api&v=2&key=[GOOGLE MAP KEY]"

 type="text/javascript"></script>

<script src="http://slurl.com/_scripts/slmapapi.js" type="text/javascript"></script> <script> // mapInstance and marker is set as a glabal, so that the removeMarker function can access them var mapInstance, marker;

function loadmap() {

 // creates the map
 mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);
 
 // creates the icons
 var yellow_dot_image = new Img("b_map_yellow.gif", 9, 9);
 var yellow_icon = new Icon(yellow_dot_image);
 var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];
 
 // creates the markers
 var marker = new Marker(all_images, new XYPoint(997,1002));
 mapInstance.addMarker(marker);
 marker = new Marker(all_images, new XYPoint(997.4,1002));
 mapInstance.addMarker(marker);
 marker = new Marker(all_images, new XYPoint(997.2,1002.8));
 mapInstance.addMarker(marker);
 marker = new Marker(all_images, new XYPoint(997.8,1002.2));
 mapInstance.addMarker(marker);
 marker = new Marker(all_images, new XYPoint(997.1,1002.65));
 mapInstance.addMarker(marker);

}

function removeAllMarkers() {

 // removes all the the marker
 mapInstance.removeAllMarkers();

} </script> </head> <body onload="loadmap()" onunload="GUnload()"> <a href="javascript: mapInstance.removeAllMarkers();">Click to remove all the markers</a>

</body></html4strict>

Example source code

<html4strict> <script> function loadmap() {

 // creates the map
 var mapInstance = new SLMap(document.getElementById('map-container'));
 mapInstance.centerAndZoomAtSLCoord(new XYPoint(995,1004),2);
 
 // creates the icons
 var forsale_sign = new Img("forsale.png",80,83, true);
 var forsale_shadow = new Img("forsale-shadow.png", 98, 83, true);
 var forsale_icon = new Icon(forsale_sign, forsale_shadow);
 var all_images = [forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon, forsale_icon];
 
 // creates the marker
 var marker = new Marker(all_images, new XYPoint(995, 1004));
 mapInstance.addMarker(marker);

} </script> </head> <body onload="loadmap()" onunload="GUnload()">

The map shows a 'for sale' sign marker with smooth edges, and an anti-aliased shadow.

</body></html4strict>