<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=James+Linden</id>
	<title>Second Life Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=James+Linden"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/wiki/Special:Contributions/James_Linden"/>
	<updated>2026-07-25T02:41:47Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlEmail&amp;diff=284012</id>
		<title>LlEmail</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlEmail&amp;diff=284012"/>
		<updated>2009-03-18T21:18:56Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Function&lt;br /&gt;
|func_id=119|func_sleep=20.0|func_energy=10.0&lt;br /&gt;
|sort=Email|func=llEmail&lt;br /&gt;
|p1_type=string|p1_name=address&lt;br /&gt;
|p2_type=string|p2_name=subject&lt;br /&gt;
|p3_type=string|p3_name=message&lt;br /&gt;
|func_footnote=The entire message (including the address, subject and other miscellaneous fields) can&#039;t be longer than 4096 bytes combined.&lt;br /&gt;
|func_desc=Sends an email to &#039;&#039;&#039;address&#039;&#039;&#039; with &#039;&#039;&#039;subject&#039;&#039;&#039; and &#039;&#039;&#039;message&#039;&#039;&#039;.&lt;br /&gt;
|return_text&lt;br /&gt;
|spec=The &#039;&#039;&#039;message&#039;&#039;&#039; is prefixed with information about the prim sending the email.&lt;br /&gt;
{{{!}}{{Prettytable}}&lt;br /&gt;
{{!}}-{{Hl2}}&lt;br /&gt;
!Template&lt;br /&gt;
!Example&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}}&amp;lt;pre&amp;gt;&lt;br /&gt;
Object-Name: *prim*&lt;br /&gt;
Region: *simname* (*simpos.x*, *simpos.y*)&lt;br /&gt;
Local-Position: (*primpos.x*, *primpos.y*, *primpos.z*)&lt;br /&gt;
&lt;br /&gt;
*message*&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{!}}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Object-Name: Object&lt;br /&gt;
Region: Gibson (254976, 256000)&lt;br /&gt;
Local-Position: (117, 129, 50)&lt;br /&gt;
&lt;br /&gt;
The real message starts here.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{!}}}&lt;br /&gt;
|caveats=* There is a limit to the number of email messages an object can send in a given amount of time. &lt;br /&gt;
* There is a limit of 500 messages from a single agent&#039;s objects in a one hour period.&lt;br /&gt;
* The 4096 byte size limit includes the subject line and automatically added text.  The practical maximum body size is approximately 3600 bytes.&lt;br /&gt;
* (Sept-2008) The Email Throttle was modified slightly, Per Prospero Linden&#039;s comments: &amp;quot;there has long been a throttle that makes a single script sleep for 20 seconds after sending an email. The new throttle is per user... some were using many, many different scripts to send spam. (the new throttle applies) when the destination is outside of Second Life. I know that messages within the same region were not throttled (beyond the 20-second delay), and I *believe* that messages between different sims were not throttled (between the 20-second delay).&amp;quot;&lt;br /&gt;
* Due to the bug {{Jira|SVC-23}} (present since 2005), objects may stop receiving emails completely until either the region is restarted or the object crosses a region boundary (resetting the script doesn&#039;t help).  Emails sent may eventually be received after a restart/region-cross.  Hence, don&#039;t rely on this function for reliable inter-region messaging. &lt;br /&gt;
|constants&lt;br /&gt;
|examples=&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string email_address = &amp;quot;somebody@example.com&amp;quot;; // who will receive the messages&lt;br /&gt;
 &lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry() {&lt;br /&gt;
 &lt;br /&gt;
        //Send an email to a normal email account&lt;br /&gt;
        llEmail( email_address, &amp;quot;Look it&#039;s an email subject line!&amp;quot;, &amp;quot;Testing 1 2 3&amp;quot; );&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    touch_start( integer num_detected ) {&lt;br /&gt;
        integer i = 0;&lt;br /&gt;
 &lt;br /&gt;
        // Send another email, telling who touched the prim.&lt;br /&gt;
        do&lt;br /&gt;
            llEmail( email_address, &amp;quot;No touching!&amp;quot;, &amp;quot;I was defiled by: &amp;quot; + llDetectedName(i) + &amp;quot;\nKey: &amp;quot; + (string) llDetectedKey(i) );&lt;br /&gt;
        while(++i &amp;lt; num_detected);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
|also_functions=&lt;br /&gt;
{{LSL DefineRow|[[llGetNextEmail]]}}&lt;br /&gt;
{{LSL DefineRow|[[llMessageLinked]]}}&lt;br /&gt;
|also_events=&lt;br /&gt;
{{LSL DefineRow|[[email]]}}&lt;br /&gt;
{{LSL DefineRow|[[link message]]}}&lt;br /&gt;
|also_tests&lt;br /&gt;
|also_articles&lt;br /&gt;
|notes=* Because of the long delay on this function, it is often called from a second script triggered by [[link_message]].&lt;br /&gt;
* If you are sending email to a prim within Second Life, its address is &#039;&#039;[key]&#039;&#039;@lsl.secondlife.com&lt;br /&gt;
** Which means if the key returned by [[llGetKey]] is &amp;quot;a2e76fcd-9360-4f6d-a924-000000000003&amp;quot;, then its email address is &amp;quot;a2e76fcd-9360-4f6d-a924-000000000003@lsl.secondlife.com&amp;quot;.&lt;br /&gt;
** Agents do not have fixed email addresses, use [[llInstantMessage]] or [[llOwnerSay]].&lt;br /&gt;
&lt;br /&gt;
===Prim2Prim Email===&lt;br /&gt;
&lt;br /&gt;
In LSL you can both send email with llEmail and receive it with the [[email]] event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The email event is triggered with 5 pieces of information.&lt;br /&gt;
{{{!}}&lt;br /&gt;
{{LSL DefineRow|string|time|When the message was sent, in the &amp;lt;code&amp;gt;(string)[[llGetUnixTime]]&amp;lt;/code&amp;gt; format}}&lt;br /&gt;
{{LSL DefineRow|string|address|Who sent the message}}&lt;br /&gt;
{{LSL DefineRow|string|subject|Subject of the message}}&lt;br /&gt;
{{LSL DefineRow|string|message|Body of the message}}&lt;br /&gt;
{{LSL DefineRow|integer|num_left|The number of emails left in the email queue}}&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When receiving a message sent with [[llEmail]] it helps to separate the message from the prefixed header. The header and original message body are separated by &amp;quot;\n\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;integer divide = llSubStringIndex(message, &amp;quot;\n\n&amp;quot;);&lt;br /&gt;
string header = llDeleteSubString(message, divide, -1);&lt;br /&gt;
message = llDeleteSubString(message, 0, divide + 1);&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get just 1 of the header items, do this:&lt;br /&gt;
&amp;lt;lsl&amp;gt;list lines = llParseStringKeepNulls(header, [&amp;quot;\n&amp;quot;], []);&lt;br /&gt;
string objname_line = llList2String(lines, 0);&lt;br /&gt;
string region_line = llList2String(lines, 1);&lt;br /&gt;
string localpos_line = llList2String(lines, 2);&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a pure region name, do this:&lt;br /&gt;
&amp;lt;lsl&amp;gt;string region_name = llStringTrim(&lt;br /&gt;
            (string)llDeleteSubList(&lt;br /&gt;
                llParseStringKeepNulls(&lt;br /&gt;
                    llDeleteSubString(region_line, 0, 12),&lt;br /&gt;
                    [], &lt;br /&gt;
                    [&amp;quot;(&amp;quot;]&lt;br /&gt;
                ), -2, -1), STRING_TRIM);&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This application uses email to have objects check with a central server to see if the owner has the latest version. In the objects:&lt;br /&gt;
&amp;lt;lsl&amp;gt;string version = &amp;quot;1&amp;quot;; //&lt;br /&gt;
string type = &amp;quot;lolcube&amp;quot;;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llEmail(&amp;quot;5a634b27-f032-283f-2df2-55ead7724b23@lsl.secondlife.com&amp;quot;,&lt;br /&gt;
            version,&lt;br /&gt;
            (string)llGetOwner() + &amp;quot;,&amp;quot; + type);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
The server:&lt;br /&gt;
&amp;lt;lsl&amp;gt;default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSetTimerEvent(15.0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    email( string time, string address, string version, string message, integer num_left )&lt;br /&gt;
    {    &lt;br /&gt;
        if ((integer)version &amp;lt; 2)&lt;br /&gt;
        {&lt;br /&gt;
            list info = llCSV2List( llDeleteSubString(message, 0, llSubStringIndex(message, &amp;quot;\n\n&amp;quot;) + 1));&lt;br /&gt;
            llGiveInventory(llList2Key(info,0), llList2String(info,1));&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if(num_left)&lt;br /&gt;
            llGetNextEmail(&amp;quot;&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
|helpers=&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
email( string time, string address, string subj, string message, integer num_left )&lt;br /&gt;
{&lt;br /&gt;
    if(llGetSubString(address, -19, -1) == &amp;quot;@lsl.secondlife.com&amp;quot;)//trim the header&lt;br /&gt;
        message = llDeleteSubString(message, 0, llSubStringIndex(message, &amp;quot;\n\n&amp;quot;) + 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
|permission&lt;br /&gt;
|negative_index&lt;br /&gt;
|cat1=Communications&lt;br /&gt;
|cat2=Email&lt;br /&gt;
|cat3&lt;br /&gt;
|cat4&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
== Open Source Portal ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
{{OSWikiFeatureNav}}&lt;br /&gt;
=== Feature Design Document ===&lt;br /&gt;
(none)&lt;br /&gt;
&lt;br /&gt;
=== Functional Spec ===&lt;br /&gt;
(none)&lt;br /&gt;
&lt;br /&gt;
=== Test scripts ===&lt;br /&gt;
[https://osiris.lindenlab.com/mediawiki/index.php/Email_Test internal test]&lt;br /&gt;
&lt;br /&gt;
=== Discussion for future improvements ===&lt;br /&gt;
(none)&lt;br /&gt;
&lt;br /&gt;
=== Relationship to other features ===&lt;br /&gt;
&amp;lt;b&amp;gt; List of features that need to be tested when this feature changes, and why. &amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[IM to email]] - verify IM -&amp;gt; email still works.&lt;br /&gt;
&lt;br /&gt;
[[Postcards]] - Postcards use email out?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== User Guides ===&lt;br /&gt;
[http://lslwiki.net/lslwiki/wakka.php?wakka=llemail llEmail on LSLwiki.net]&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Category:LSL_XML-RPC&amp;diff=234242</id>
		<title>Category:LSL XML-RPC</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Category:LSL_XML-RPC&amp;diff=234242"/>
		<updated>2009-02-11T20:15:51Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Added curl / raw XML example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header|ml=*}}{{LSLC|}}{{LSLC|Communications}}&lt;br /&gt;
[http://en.wikipedia.org/wiki/XMLRPC XML-RPC] is a standard for sending Procedure Calls (e.g. function calls) to Remote systems.  It sends [http://en.wikipedia.org/wiki/XML XML] data over HTTP that remote system then handles.&lt;br /&gt;
&lt;br /&gt;
LSL receives XML-RPC requests and passes them to the prim specified.  It may not establish this connection, but it may reply and keep two-way communication with that server.  These responses seem to be able to transport the largest amount of data out of Second Life (vs. [[Email]] and {{LSLGC|HTTP}} Requests).&lt;br /&gt;
&lt;br /&gt;
=== NOTE: ===&lt;br /&gt;
&lt;br /&gt;
XML-RPC requests often time-out due to the front-end server being overloaded.  LL has continued to upgrade the server hardware periodically, but it has remained unreliable.  LL developers have advised that the XML-RPC design isn&#039;t scalable (due to the single server bottle-neck) and that the service is &amp;quot;deprecated&amp;quot;.  They suggest using HTTP polling as an alternative.  If an XML-RPC request does time-out the script&#039;s remote_data event may or may not be triggered (and any script response is lost).&lt;br /&gt;
&lt;br /&gt;
=== IMPORTANT IMPLEMENTATION NOTE: ===&lt;br /&gt;
&lt;br /&gt;
The current implementation of XML-RPC only allows ONE request to be queued on the front-end server (xmlrpc.secondlife.com) at a time. Any additional requests to the same data channel overwrite any pending one. This has serious ramifications for the design of XML-RPC communications where the in-world object could receive requests faster than it can respond to them. In addition, the 3-second delay in [[llRemoteDataReply]] exacerbates this problem even more.&lt;br /&gt;
&lt;br /&gt;
The observed issue is this: if you send multiple quick requests to an in-world object via XML-RPC, one which is scripted to perform some processing and then return a response (via llRemoteDataReply), there is a potential for earlier requests to get lost on the front end server (they still should generate [[remote_data]] events, though), and have the response meant for an earlier request end up being passed back to a later one, while the earlier requests will time out back at your external application.&lt;br /&gt;
&lt;br /&gt;
As a result, if you intend to do any serious work with XML-RPC, you will have to design your external client application to manually serialize all requests to each individual RPC channel. That means you have to wait for a response from the previous request before you attempt to send the next one. If you don&#039;t care about receiving responses, then this problem is not an issue, as all requests seem to get passed on to the script, regardless of the queueing issue.&lt;br /&gt;
&lt;br /&gt;
Also note that there is NO way to get around the 3-second delay for llRemoteDataReply; you cannot use the multiple-slave-comm-script trick, because XML-RPC channels are *script-specific*, NOT *object-specific*.&lt;br /&gt;
&lt;br /&gt;
For more information, see these forum threads [http://forums.secondlife.com/showthread.php?t=158437 here] and [http://forums.secondlife.com/showthread.php?p=1379244 here].&lt;br /&gt;
&lt;br /&gt;
==Other Resources==&lt;br /&gt;
* [http://www.xmlrpc.com/ XMLRPC.com]&lt;br /&gt;
* [http://scripts.incutio.com/xmlrpc/ Incutio&#039;s XML-RPC PHP library]&lt;br /&gt;
* [http://perisic.com/sl/ A simple form to launch an XMLRPC request into Second Life]&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
=php=&lt;br /&gt;
&lt;br /&gt;
To initialize a xmlrpc from an external server you&#039;ll need some kind of web-application.&lt;br /&gt;
One language to create a webapplication in is PHP.&lt;br /&gt;
Here is an example of how to send a xmlrpc message to your SL-script from a webserver using PHP:&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php&lt;br /&gt;
	echo &#039;&amp;lt;pre&amp;gt;&#039;;&lt;br /&gt;
	$channel = &amp;quot;&amp;quot;; //Fill in the channel you are using (key)&lt;br /&gt;
	$intvalue = &amp;quot;&amp;quot;; //Fill in the intvalue you are using (integer)&lt;br /&gt;
	$strvalue = &amp;quot;&amp;quot;; //Fill in the strvalue you are using (string)&lt;br /&gt;
	$xmldata = &amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot;?&amp;gt;&amp;lt;methodCall&amp;gt;&amp;lt;methodName&amp;gt;llRemoteData&amp;lt;/methodName&amp;gt;&lt;br /&gt;
&amp;lt;params&amp;gt;&amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;struct&amp;gt;&lt;br /&gt;
&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;Channel&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;&amp;lt;string&amp;gt;&amp;quot;.$channel.&amp;quot;&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&lt;br /&gt;
&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;IntValue&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;&amp;lt;int&amp;gt;&amp;quot;.$intvalue.&amp;quot;&amp;lt;/int&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&lt;br /&gt;
&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;StringValue&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;&amp;lt;string&amp;gt;&amp;quot;.$strvalue.&amp;quot;&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&lt;br /&gt;
&amp;lt;/struct&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;&amp;lt;/params&amp;gt;&amp;lt;/methodCall&amp;gt;&amp;quot;;&lt;br /&gt;
	echo sendToHost(&amp;quot;xmlrpc.secondlife.com&amp;quot;, &amp;quot;POST&amp;quot;, &amp;quot;/cgi-bin/xmlrpc.cgi&amp;quot;, $xmldata);&lt;br /&gt;
	echo &#039;&amp;lt;/pre&amp;gt;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	function sendToHost($host,$method,$path,$data,$useragent=0)&lt;br /&gt;
	{ &lt;br /&gt;
		$buf=&amp;quot;&amp;quot;;&lt;br /&gt;
		// Supply a default method of GET if the one passed was empty &lt;br /&gt;
		if (empty($method)) &lt;br /&gt;
			$method = &#039;GET&#039;; &lt;br /&gt;
		$method = strtoupper($method); &lt;br /&gt;
	&lt;br /&gt;
		$fp = fsockopen($host, 80, $errno, $errstr, 30);&lt;br /&gt;
	&lt;br /&gt;
		if( !$fp )&lt;br /&gt;
		{&lt;br /&gt;
			$buf = &amp;quot;$errstr ($errno)&amp;lt;br /&amp;gt;\n&amp;quot;;&lt;br /&gt;
		}else&lt;br /&gt;
		{&lt;br /&gt;
			if ($method == &#039;GET&#039;) &lt;br /&gt;
			$path .= &#039;?&#039; . $data; &lt;br /&gt;
			fputs($fp, &amp;quot;$method $path HTTP/1.1\r\n&amp;quot;); &lt;br /&gt;
			fputs($fp, &amp;quot;Host: $host\r\n&amp;quot;); &lt;br /&gt;
			fputs($fp, &amp;quot;Content-type: text/xml\r\n&amp;quot;); &lt;br /&gt;
			fputs($fp, &amp;quot;Content-length: &amp;quot; . strlen($data) . &amp;quot;\r\n&amp;quot;); &lt;br /&gt;
			if ($useragent) &lt;br /&gt;
				fputs($fp, &amp;quot;User-Agent: MSIE\r\n&amp;quot;); &lt;br /&gt;
			fputs($fp, &amp;quot;Connection: close\r\n\r\n&amp;quot;); &lt;br /&gt;
			if ($method == &#039;POST&#039;) &lt;br /&gt;
				fputs($fp, $data); &lt;br /&gt;
			while (!feof($fp)) &lt;br /&gt;
				$buf .= fgets($fp,128); &lt;br /&gt;
			fclose($fp); &lt;br /&gt;
		}&lt;br /&gt;
		return $buf; &lt;br /&gt;
	} &lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=perl=&lt;br /&gt;
&lt;br /&gt;
The perl code and corresponding LSL code to contact an object in Second Life is given below. The perl code makes use of the RPC::XML module. You can run the perl code from the command line. It creates an rpc object and sends a message to an object that is rezzed on the grid. Note that you have to supply the UUID of the object within the perl code.&lt;br /&gt;
&lt;br /&gt;
The perl code sends the message that contains the string &amp;quot;Message to pass&amp;quot; and the number &amp;quot;2007.&amp;quot; The LSL code responds by sending the string &amp;quot;I got it&amp;quot; and the number &amp;quot;2008.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;#!/usr/bin/perl&lt;br /&gt;
# &lt;br /&gt;
&lt;br /&gt;
use RPC::XML;&lt;br /&gt;
use RPC::XML::Parser;&lt;br /&gt;
use RPC::XML::Client;&lt;br /&gt;
&lt;br /&gt;
my $llURL = &amp;quot;http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi&amp;quot;;&lt;br /&gt;
$P = RPC::XML::Parser-&amp;gt;new();&lt;br /&gt;
&lt;br /&gt;
my $cli = RPC::XML::Client-&amp;gt;new($llURL);&lt;br /&gt;
my $req = RPC::XML::request-&amp;gt;new(&lt;br /&gt;
        &amp;quot;llRemoteData&amp;quot;,&lt;br /&gt;
        {&#039;Channel&#039; =&amp;gt; RPC::XML::string-&amp;gt;new(&amp;quot;UUID for the open channel from the object GOES HERE!&amp;quot;),&lt;br /&gt;
        &#039;IntValue&#039; =&amp;gt; RPC::XML::int-&amp;gt;new(2007),&lt;br /&gt;
        &#039;StringValue&#039; =&amp;gt; RPC::XML::string-&amp;gt;new(&amp;quot;message to pass&amp;quot;)});&lt;br /&gt;
&lt;br /&gt;
#  Print out the message to send&lt;br /&gt;
print &amp;quot;ref(req): &amp;quot;,ref($req),&amp;quot;\n&amp;quot;;&lt;br /&gt;
$xml = $req-&amp;gt;as_string();&lt;br /&gt;
print &amp;quot;Length: &amp;quot;,$req-&amp;gt;length,&amp;quot;\n\n&amp;quot;,$xml,&amp;quot;\n\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$res = $P-&amp;gt;parse($xml);&lt;br /&gt;
print ref($res),&amp;quot;\n&amp;quot;;&lt;br /&gt;
if (ref($res)) {&lt;br /&gt;
    %h = %{$res-&amp;gt;args-&amp;gt;[0]-&amp;gt;value};&lt;br /&gt;
    foreach $lupe (keys %h) {&lt;br /&gt;
       print &amp;quot;$lupe: $h{$lupe}\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#  Submit the request to send the information above.&lt;br /&gt;
my $resp = $cli-&amp;gt;send_request($req);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#  Print out the response&lt;br /&gt;
print &amp;quot;\n\n\nResponse\n&amp;quot;;&lt;br /&gt;
print &amp;quot;ref(resp): &amp;quot;,ref($resp),&amp;quot;\n&amp;quot;;&lt;br /&gt;
$xml = $resp-&amp;gt;as_string();&lt;br /&gt;
print &amp;quot;Length: &amp;quot;,$resp-&amp;gt;length,&amp;quot;\n\n&amp;quot;,$xml,&amp;quot;\n\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$res = $P-&amp;gt;parse($xml);&lt;br /&gt;
print ref($res),&amp;quot;\n&amp;quot;;&lt;br /&gt;
if (ref($res)) {&lt;br /&gt;
    %h = %{$res-&amp;gt;value};&lt;br /&gt;
    foreach $lupe (keys %h) {&lt;br /&gt;
       $val =  $h{$lupe};&lt;br /&gt;
       print &amp;quot;$lupe: $val\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Java=&lt;br /&gt;
&lt;br /&gt;
This Java code uses the org.apache.xmlrpc library, a jar file for this can be found at http://www.perisic.com/xmlrpc/cis69mc.jar (the code has been tested with this). See http://perisic.com/xmlrpc for a simple introduction into Java &amp;amp; XMLRPC if necessary. &lt;br /&gt;
* Save the code in a file named SLClient.java and download the jar file cis69mc.jar from the location above.&lt;br /&gt;
* Add the channel id where it says &#039;&amp;lt;add channel id here!!!&amp;gt;&#039;, so this line may eventually look similar to &amp;lt;code&amp;gt;theData.put(&amp;quot;Channel&amp;quot;, &amp;quot;24a2c834-c984-9209-78df-20608d4c8ade&amp;quot;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* Compile the code with the command: javac -classpath &amp;quot;cis69mc.jar;.&amp;quot; SLClient.jar (you may get a note about unchecked or unsafe operations, ignore that).  &lt;br /&gt;
* Run the code with the command: java -classpath &amp;quot;cis69mc.jar;.&amp;quot; SLClient &lt;br /&gt;
&lt;br /&gt;
&amp;lt;java&amp;gt;import java.util.*;&lt;br /&gt;
import org.apache.xmlrpc.*;&lt;br /&gt;
&lt;br /&gt;
public class SLClient {&lt;br /&gt;
 public static void main (String [] args) {&lt;br /&gt;
  try {&lt;br /&gt;
   Hashtable theData = new Hashtable(); &lt;br /&gt;
   XmlRpcClient server = new XmlRpcClient(&amp;quot;http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi&amp;quot;); //&lt;br /&gt;
   theData.put(&amp;quot;Channel&amp;quot;, &amp;quot;&amp;lt;add channel id here!!!&amp;gt;&amp;quot;); &lt;br /&gt;
   theData.put(&amp;quot;IntValue&amp;quot;, 2483); &lt;br /&gt;
   theData.put(&amp;quot;StringValue&amp;quot;, &amp;quot;The date is: &amp;quot;+ (new Date()).toString() ); &lt;br /&gt;
   Vector params = new Vector(); &lt;br /&gt;
   params.add(theData); &lt;br /&gt;
   &lt;br /&gt;
   Object result = server.execute(&amp;quot;llRemoteData&amp;quot;, params ); &lt;br /&gt;
  &lt;br /&gt;
  } catch (Exception exception) {&lt;br /&gt;
   System.err.println(&amp;quot;SL_Client: &amp;quot; + exception);&lt;br /&gt;
   exception.printStackTrace(); &lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/java&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Visual Basic 6=&lt;br /&gt;
&lt;br /&gt;
This piece of Visual Basic 6 code makes use of the Microsoft WinSock 6.0 control. Make a new project, and place a Winsock control on the form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vb&amp;gt;&lt;br /&gt;
Dim Channel As String&lt;br /&gt;
Dim IntValue As Integer&lt;br /&gt;
Dim StrValue As String&lt;br /&gt;
Dim XMLData As String&lt;br /&gt;
&lt;br /&gt;
Private Sub Form_Load()&lt;br /&gt;
    Channel = &amp;quot;&amp;lt;add channel id here!!!&amp;gt;&amp;quot;&lt;br /&gt;
    IntValue = 2007&lt;br /&gt;
    StrValue = &amp;quot;This is a test string.&amp;quot;&lt;br /&gt;
    XMLData = &amp;quot;&amp;lt;?xml version=&amp;quot;&amp;quot;1.0&amp;quot;&amp;quot;?&amp;gt;&amp;lt;methodCall&amp;gt;&amp;lt;methodName&amp;gt;llRemoteData&amp;lt;/methodName&amp;gt;&amp;lt;params&amp;gt;&amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;struct&amp;gt;&amp;quot;&lt;br /&gt;
    XMLData = XMLData &amp;amp; &amp;quot;&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;Channel&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;&amp;lt;string&amp;gt;&amp;quot; &amp;amp; Channel &amp;amp; &amp;quot;&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&amp;quot;&lt;br /&gt;
    XMLData = XMLData &amp;amp; &amp;quot;&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;IntValue&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;&amp;lt;int&amp;gt;&amp;quot; &amp;amp; CStr(IntValue) &amp;amp; &amp;quot;&amp;lt;/int&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&amp;quot;&lt;br /&gt;
    XMLData = XMLData &amp;amp; &amp;quot;&amp;lt;member&amp;gt;&amp;lt;name&amp;gt;StringValue&amp;lt;/name&amp;gt;&amp;lt;value&amp;gt;&amp;lt;string&amp;gt;&amp;quot; &amp;amp; StrValue &amp;amp; &amp;quot;&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/member&amp;gt;&amp;quot;&lt;br /&gt;
    XMLData = XMLData &amp;amp; &amp;quot;&amp;lt;/struct&amp;gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;&amp;lt;/params&amp;gt;&amp;lt;/methodCall&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    Winsock1.Connect &amp;quot;xmlrpc.secondlife.com&amp;quot;, 80&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub Winsock1_Connect()&lt;br /&gt;
    WinsockSend &amp;quot;POST /cgi-bin/xmlrpc.cgi HTTP/1.1&amp;quot; &amp;amp; vbCrLf&lt;br /&gt;
    WinsockSend &amp;quot;Host: xmlrpc.secondlife.com&amp;quot; &amp;amp; vbCrLf&lt;br /&gt;
    WinsockSend &amp;quot;Content-type: text/xml&amp;quot; &amp;amp; vbCrLf&lt;br /&gt;
    WinsockSend &amp;quot;Content-length: &amp;quot; &amp;amp; CStr(Len(XMLData)) &amp;amp; vbCrLf&lt;br /&gt;
    WinsockSend &amp;quot;Connection: close&amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf&lt;br /&gt;
    WinsockSend XMLData &amp;amp; vbCrLf&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)&lt;br /&gt;
    Dim TempStr As String&lt;br /&gt;
    Winsock1.GetData TempStr&lt;br /&gt;
    MsgBox TempStr&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Sub WinsockSend(str As String)&lt;br /&gt;
    Winsock1.SendData str&lt;br /&gt;
End Sub&lt;br /&gt;
&amp;lt;/vb&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Command line curl=&lt;br /&gt;
If you want to debug XML-RPC from the command line you can use &amp;quot;curl&amp;quot; to do so.  Put this in a file called &amp;lt;code&amp;gt;rpc.xml&amp;lt;/code&amp;gt;, replacing the UUID for Channel with your script&#039;s channel id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;methodCall&amp;gt;&lt;br /&gt;
    &amp;lt;methodName&amp;gt;llRemoteData&amp;lt;/methodName&amp;gt;&lt;br /&gt;
    &amp;lt;params&amp;gt;&lt;br /&gt;
        &amp;lt;param&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;&lt;br /&gt;
                &amp;lt;struct&amp;gt;&lt;br /&gt;
                    &amp;lt;member&amp;gt;&lt;br /&gt;
                        &amp;lt;name&amp;gt;Channel&amp;lt;/name&amp;gt;&lt;br /&gt;
                        &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;1ee246fc-e60d-2fd3-6242-f5fc5d19850f&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
                    &amp;lt;/member&amp;gt;&lt;br /&gt;
                    &amp;lt;member&amp;gt;&lt;br /&gt;
                        &amp;lt;name&amp;gt;IntValue&amp;lt;/name&amp;gt;&lt;br /&gt;
                        &amp;lt;value&amp;gt;&amp;lt;int&amp;gt;42&amp;lt;/int&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
                    &amp;lt;/member&amp;gt;&lt;br /&gt;
                    &amp;lt;member&amp;gt;&lt;br /&gt;
                        &amp;lt;name&amp;gt;StringValue&amp;lt;/name&amp;gt;&lt;br /&gt;
                        &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;Hello, world!&amp;lt;/string&amp;gt;&amp;lt;/value&amp;gt;&lt;br /&gt;
                    &amp;lt;/member&amp;gt;&lt;br /&gt;
                &amp;lt;/struct&amp;gt;&lt;br /&gt;
            &amp;lt;/value&amp;gt;&lt;br /&gt;
        &amp;lt;/param&amp;gt;&lt;br /&gt;
    &amp;lt;/params&amp;gt;&lt;br /&gt;
&amp;lt;/methodCall&amp;gt;&lt;br /&gt;
&amp;lt;/xml&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then call curl to make a POST to the XMLRPC server:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
curl --verbose --data &amp;quot;@rpc.xml&amp;quot; http://xmlrpc.secondlife.com/cgi-bin/xmlrpc.cgi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=LSL Server Code=&lt;br /&gt;
&lt;br /&gt;
Corresponding LSL code (copy and paste this code as a script in an object, save and rezz it, a message with the channel id (and other stuff) will be printed):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;key remoteChannel;&lt;br /&gt;
init() {&lt;br /&gt;
    llOpenRemoteDataChannel(); // create an XML-RPC channel&lt;br /&gt;
    llOwnerSay(&amp;quot;My key is &amp;quot; + (string)llGetKey());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    state_exit() {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
                                &lt;br /&gt;
    on_rez(integer param) {&lt;br /&gt;
        llResetScript();        &lt;br /&gt;
    }&lt;br /&gt;
                                &lt;br /&gt;
    remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) {&lt;br /&gt;
         if (type == REMOTE_DATA_CHANNEL) { // channel created&lt;br /&gt;
             llSay(DEBUG_CHANNEL,&amp;quot;Channel opened for REMOTE_DATA_CHANNEL&amp;quot; + &lt;br /&gt;
                (string)channel + &amp;quot; &amp;quot; + (string)message_id + &amp;quot; &amp;quot; + (string)sender + &amp;quot; &amp;quot; +                         &lt;br /&gt;
                (string)ival + &amp;quot; &amp;quot; + (string)sval);&lt;br /&gt;
             remoteChannel = channel;&lt;br /&gt;
             llOwnerSay(&amp;quot;Ready to receive requests on channel \&amp;quot;&amp;quot; + (string)channel + &amp;quot;\&amp;quot;&amp;quot;);                        &lt;br /&gt;
             state receiving; // start handling requests&lt;br /&gt;
         } else {&lt;br /&gt;
             llSay(DEBUG_CHANNEL,&amp;quot;Unexpected event type&amp;quot;); &lt;br /&gt;
         }                      &lt;br /&gt;
     }                 &lt;br /&gt;
}                     &lt;br /&gt;
                                &lt;br /&gt;
&lt;br /&gt;
state receiving {&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        llOwnerSay(&amp;quot;Ready to receive information from outside SL&amp;quot;);&lt;br /&gt;
    }  &lt;br /&gt;
    &lt;br /&gt;
    state_exit() {&lt;br /&gt;
        llOwnerSay(&amp;quot;No longer receiving information from outside SL.&amp;quot;);&lt;br /&gt;
        llCloseRemoteDataChannel(remoteChannel);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param) {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval) {&lt;br /&gt;
        if (type == REMOTE_DATA_REQUEST) { // handle requests sent to us&lt;br /&gt;
             llSay(DEBUG_CHANNEL,&amp;quot;Request received for REMOTE_DATA_REQUEST &amp;quot; + (string)channel + &amp;quot; &amp;quot; +&lt;br /&gt;
                (string)message_id + &amp;quot; &amp;quot; + (string)sender + &amp;quot; &amp;quot; + (string)ival + &amp;quot; &amp;quot; + (string)sval);&lt;br /&gt;
            llRemoteDataReply(channel,NULL_KEY,&amp;quot;I got it&amp;quot;,2008);&lt;br /&gt;
            llOwnerSay(&amp;quot;I just received data in &amp;quot;+ llGetRegionName() + &lt;br /&gt;
                        &amp;quot; at position &amp;quot; + (string)llGetPos() + &amp;quot;\n&amp;quot; +&lt;br /&gt;
                       &amp;quot;The string was &amp;quot; +  sval + &amp;quot;\nThe number was &amp;quot; + (string)ival + &amp;quot;.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=232142</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=232142"/>
		<updated>2009-02-10T16:56:24Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Accessing map images directly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the Map API, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Map API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the map images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI features ===&lt;br /&gt;
&lt;br /&gt;
The Map API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default map interface looks as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Map_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].  &lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window; see &#039;&#039;&#039;Teleport window&#039;&#039;&#039; below.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Map_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Map_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Teleport window&#039;&#039;&#039;&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
Clicking anywhere on the map opens a window,  such as the one shown at left, indicating the point on which you clicked.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.  This feature is implemented with the [[Map_API_Reference#Global_functions|gotoSLURL()]] global function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Map API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Map API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Map API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Map API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Map API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Map API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 2.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Map API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Map API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| b_map_yellow.gif&lt;br /&gt;
| &amp;lt;br&amp;gt;http://slurl.com/examples/b_map_yellow.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
| fountain.gif&lt;br /&gt;
| http://slurl.com/examples/fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| forsale.png&lt;br /&gt;
| http://slurl.com/examples/forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
| forsale-shadow.png&lt;br /&gt;
|http://slurl.com/examples/forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Map API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format (new as of February 10, 2009):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  &lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z with the filename map-Z-X&#039;-Y&#039;-objects.jpg where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
===Implementation notes===  &lt;br /&gt;
&lt;br /&gt;
The map generation process is more scalable than the previous release, and is able to image the entire Second Life grid of about 30,000 regions in less than two days.  &lt;br /&gt;
&lt;br /&gt;
There is a &amp;quot;decay period&amp;quot; for offline regions. If a region is disabled, the tile will stay up for several days (in case it comes back or something else has gone wrong) before the tile disappears. That several-day period will be longer than the time it takes to update existing regions or put new regions on the map.&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    url += &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC), updated by [[User:James Linden|James Linden]] 20:51, 7 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Release notes ==&lt;br /&gt;
&lt;br /&gt;
This section describes new features and known issues with the current release of the Map API.  See also [http://blog.secondlife.com/2009/01/22/improvements-to-mapping-and-upgrade-to-slurlcom/ Philip Linden&#039;s blog post announcement].&lt;br /&gt;
&lt;br /&gt;
The current release of the Map API was released on Jan 15, 2009.&lt;br /&gt;
&lt;br /&gt;
=== New features ===&lt;br /&gt;
&lt;br /&gt;
This release of the Map API provides significant performance improvements over the previous release, including:&lt;br /&gt;
* Map loads faster and operates more smoothly.&lt;br /&gt;
* Map images are updated more accurately and rapidly.  Changes to the Second Life Grid or content will now be visible within about two days.   &lt;br /&gt;
* Map images look smoother and are more accurate when compared to the actual in-world content.&lt;br /&gt;
&lt;br /&gt;
Changes in functionality:&lt;br /&gt;
* You can now single-click on any location on the map and teleport directly there.  &lt;br /&gt;
* Zoom levels go up to eight, so you can now zoom out and see how big SL has really become!&lt;br /&gt;
* More intuitive map tile image file naming convention.&lt;br /&gt;
&lt;br /&gt;
The Map API now gets map tile images directly from [http://aws.amazon.com/s3/ Amazon S3], and the file naming convention will make it easier to develop other third party maps based on the tiles we are generating.&lt;br /&gt;
&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
&lt;br /&gt;
These need to be confirmed.&lt;br /&gt;
--[[User:Rand Linden|Rand Linden]] 23:29, 6 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
* Can&#039;t set Map object click and doubleclick handlers.  They always have the default behavior.  &lt;br /&gt;
* Method &#039;&#039;&#039;SLMap.clickMarker(marker)&#039;&#039;&#039; doesn&#039;t work.&lt;br /&gt;
* Marker options apparently not working:&lt;br /&gt;
** &#039;&#039;&#039;centerOnClick: true&#039;&#039;&#039; - This works, but does NOT work if you open a window onclicking the marker.&lt;br /&gt;
** &#039;&#039;&#039;autopanOnClick: false&#039;&#039;&#039; - Always autopans&lt;br /&gt;
** &#039;&#039;&#039;autopanPadding: n&#039;&#039;&#039; - No effect&lt;br /&gt;
* Setting a different marker image/icon for each zoom level doesn&#039;t work - always uses first icon.&lt;br /&gt;
* Window width option doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Questions:&#039;&#039;&#039;&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6? &lt;br /&gt;
* Old docs said that Map object clickhandler and doubleclickhander have (x,y) passed to them.  Is that true (or rather, will it be true when they work?)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=232132</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=232132"/>
		<updated>2009-02-10T16:54:33Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Removed references to old tile URL format, updated example URLs to use new tile URL format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the Map API, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Map API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the map images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI features ===&lt;br /&gt;
&lt;br /&gt;
The Map API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default map interface looks as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Map_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].  &lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window; see &#039;&#039;&#039;Teleport window&#039;&#039;&#039; below.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Map_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Map_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Teleport window&#039;&#039;&#039;&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
Clicking anywhere on the map opens a window,  such as the one shown at left, indicating the point on which you clicked.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.  This feature is implemented with the [[Map_API_Reference#Global_functions|gotoSLURL()]] global function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Map API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Map API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Map API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Map API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Map API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Map API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 2.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Map API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Map API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| b_map_yellow.gif&lt;br /&gt;
| &amp;lt;br&amp;gt;http://slurl.com/examples/b_map_yellow.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
| fountain.gif&lt;br /&gt;
| http://slurl.com/examples/fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| forsale.png&lt;br /&gt;
| http://slurl.com/examples/forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
| forsale-shadow.png&lt;br /&gt;
|http://slurl.com/examples/forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Map API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format (new as of February 10, 2009):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  &lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z at the directory Z/X&#039;/Y&#039; where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
===Implementation notes===  &lt;br /&gt;
&lt;br /&gt;
The map generation process is more scalable than the previous release, and is able to image the entire Second Life grid of about 30,000 regions in less than two days.  &lt;br /&gt;
&lt;br /&gt;
There is a &amp;quot;decay period&amp;quot; for offline regions. If a region is disabled, the tile will stay up for several days (in case it comes back or something else has gone wrong) before the tile disappears. That several-day period will be longer than the time it takes to update existing regions or put new regions on the map.&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    url += &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC), updated by [[User:James Linden|James Linden]] 20:51, 7 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Release notes ==&lt;br /&gt;
&lt;br /&gt;
This section describes new features and known issues with the current release of the Map API.  See also [http://blog.secondlife.com/2009/01/22/improvements-to-mapping-and-upgrade-to-slurlcom/ Philip Linden&#039;s blog post announcement].&lt;br /&gt;
&lt;br /&gt;
The current release of the Map API was released on Jan 15, 2009.&lt;br /&gt;
&lt;br /&gt;
=== New features ===&lt;br /&gt;
&lt;br /&gt;
This release of the Map API provides significant performance improvements over the previous release, including:&lt;br /&gt;
* Map loads faster and operates more smoothly.&lt;br /&gt;
* Map images are updated more accurately and rapidly.  Changes to the Second Life Grid or content will now be visible within about two days.   &lt;br /&gt;
* Map images look smoother and are more accurate when compared to the actual in-world content.&lt;br /&gt;
&lt;br /&gt;
Changes in functionality:&lt;br /&gt;
* You can now single-click on any location on the map and teleport directly there.  &lt;br /&gt;
* Zoom levels go up to eight, so you can now zoom out and see how big SL has really become!&lt;br /&gt;
* More intuitive map tile image file naming convention.&lt;br /&gt;
&lt;br /&gt;
The Map API now gets map tile images directly from [http://aws.amazon.com/s3/ Amazon S3], and the file naming convention will make it easier to develop other third party maps based on the tiles we are generating.&lt;br /&gt;
&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
&lt;br /&gt;
These need to be confirmed.&lt;br /&gt;
--[[User:Rand Linden|Rand Linden]] 23:29, 6 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
* Can&#039;t set Map object click and doubleclick handlers.  They always have the default behavior.  &lt;br /&gt;
* Method &#039;&#039;&#039;SLMap.clickMarker(marker)&#039;&#039;&#039; doesn&#039;t work.&lt;br /&gt;
* Marker options apparently not working:&lt;br /&gt;
** &#039;&#039;&#039;centerOnClick: true&#039;&#039;&#039; - This works, but does NOT work if you open a window onclicking the marker.&lt;br /&gt;
** &#039;&#039;&#039;autopanOnClick: false&#039;&#039;&#039; - Always autopans&lt;br /&gt;
** &#039;&#039;&#039;autopanPadding: n&#039;&#039;&#039; - No effect&lt;br /&gt;
* Setting a different marker image/icon for each zoom level doesn&#039;t work - always uses first icon.&lt;br /&gt;
* Window width option doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Questions:&#039;&#039;&#039;&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6? &lt;br /&gt;
* Old docs said that Map object clickhandler and doubleclickhander have (x,y) passed to them.  Is that true (or rather, will it be true when they work?)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=229323</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=229323"/>
		<updated>2009-02-08T00:12:46Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Release notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the Map API, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Map API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the map images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI features ===&lt;br /&gt;
&lt;br /&gt;
The Map API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default map interface looks as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Map_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].  &lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window; see &#039;&#039;&#039;Teleport window&#039;&#039;&#039; below.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Map_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Map_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Teleport window&#039;&#039;&#039;&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
Clicking anywhere on the map opens a window,  such as the one shown at left, indicating the point on which you clicked.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.  This feature is implemented with the [[Map_API_Reference#Global_functions|gotoSLURL()]] global function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Map API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Map API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Map API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Map API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Map API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Map API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 2.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Map API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Map API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| b_map_yellow.gif&lt;br /&gt;
| &amp;lt;br&amp;gt;http://slurl.com/examples/b_map_yellow.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
| fountain.gif&lt;br /&gt;
| http://slurl.com/examples/fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| forsale.png&lt;br /&gt;
| http://slurl.com/examples/forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
| forsale-shadow.png&lt;br /&gt;
|http://slurl.com/examples/forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Map API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/Z/XXXXX/YYYYY/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  Starting the week of February 9, 2009 tiles will be switching to newer, simpler URLs:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  &lt;br /&gt;
** In the &amp;quot;directory path&amp;quot; (not the file name), pad the coordinate values to five characters with leading zeros; so for the previous coordinates, the path would be &amp;quot;00997/01002&amp;quot;.&lt;br /&gt;
** The padding requirement will go away the week of February 9, 2009.  [[User:James Linden|James Linden]]&lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z at the directory Z/X&#039;/Y&#039; where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/1/01000/01000/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01000/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01000/01001/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01001/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/2/01000/01000/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com/8/01024/00896/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com/1/01027/01019/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
===Implementation notes===  &lt;br /&gt;
&lt;br /&gt;
The map generation process is more scalable than the previous release, and is able to image the entire Second Life grid of about 30,000 regions in less than two days.  &lt;br /&gt;
&lt;br /&gt;
There is a &amp;quot;decay period&amp;quot; for offline regions. If a region is disabled, the tile will stay up for several days (in case it comes back or something else has gone wrong) before the tile disappears. That several-day period will be longer than the time it takes to update existing regions or put new regions on the map.&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com.s3.amazonaws.com/1/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    string x0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(x)), STRING_TRIM_HEAD) + x;&lt;br /&gt;
    string y0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(y)), STRING_TRIM_HEAD) + y;&lt;br /&gt;
    url += x0 + &amp;quot;/&amp;quot; + y0 + &amp;quot;/&amp;quot; + &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Starting the week of February 9, 2009, I recommend switching to this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    url += &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:James Linden|James Linden]] 20:51, 7 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Release notes ==&lt;br /&gt;
&lt;br /&gt;
This section describes new features and known issues with the current release of the Map API.  See also [http://blog.secondlife.com/2009/01/22/improvements-to-mapping-and-upgrade-to-slurlcom/ Philip Linden&#039;s blog post announcement].&lt;br /&gt;
&lt;br /&gt;
The current release of the Map API was released on Jan 15, 2009.&lt;br /&gt;
&lt;br /&gt;
=== New features ===&lt;br /&gt;
&lt;br /&gt;
This release of the Map API provides significant performance improvements over the previous release, including:&lt;br /&gt;
* Map loads faster and operates more smoothly.&lt;br /&gt;
* Map images are updated more accurately and rapidly.  Changes to the Second Life Grid or content will now be visible within about two days.   &lt;br /&gt;
* Map images look smoother and are more accurate when compared to the actual in-world content.&lt;br /&gt;
&lt;br /&gt;
Changes in functionality:&lt;br /&gt;
* You can now single-click on any location on the map and teleport directly there.  &lt;br /&gt;
* Zoom levels go up to eight, so you can now zoom out and see how big SL has really become!&lt;br /&gt;
* More intuitive map tile image file naming convention.&lt;br /&gt;
&lt;br /&gt;
The Map API now gets map tile images directly from [http://aws.amazon.com/s3/ Amazon S3], and the file naming convention will make it easier to develop other third party maps based on the tiles we are generating.&lt;br /&gt;
&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
&lt;br /&gt;
These need to be confirmed.&lt;br /&gt;
--[[User:Rand Linden|Rand Linden]] 23:29, 6 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
* Can&#039;t set Map object click and doubleclick handlers.  They always have the default behavior.  &lt;br /&gt;
* Method &#039;&#039;&#039;SLMap.clickMarker(marker)&#039;&#039;&#039; doesn&#039;t work.&lt;br /&gt;
* Marker options apparently not working:&lt;br /&gt;
** &#039;&#039;&#039;centerOnClick: true&#039;&#039;&#039; - This works, but does NOT work if you open a window onclicking the marker.&lt;br /&gt;
** &#039;&#039;&#039;autopanOnClick: false&#039;&#039;&#039; - Always autopans&lt;br /&gt;
** &#039;&#039;&#039;autopanPadding: n&#039;&#039;&#039; - No effect&lt;br /&gt;
* Setting a different marker image/icon for each zoom level doesn&#039;t work - always uses first icon.&lt;br /&gt;
* Window width option doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Questions:&#039;&#039;&#039;&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6? &lt;br /&gt;
* Old docs said that Map object clickhandler and doubleclickhander have (x,y) passed to them.  Is that true (or rather, will it be true when they work?)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=229283</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=229283"/>
		<updated>2009-02-07T20:51:21Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Updated docs for new URL format we&amp;#039;re switching to next week.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the Map API, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Map API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the map images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI features ===&lt;br /&gt;
&lt;br /&gt;
The Map API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default map interface looks as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Map_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].  &lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window; see &#039;&#039;&#039;Teleport window&#039;&#039;&#039; below.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Map_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Map_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Teleport window&#039;&#039;&#039;&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
Clicking anywhere on the map opens a window,  such as the one shown at left, indicating the point on which you clicked.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.  This feature is implemented with the [[Map_API_Reference#Global_functions|gotoSLURL()]] global function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Map API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Map API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Map API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Map API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Map API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Map API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 2.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Map API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Map API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| b_map_yellow.gif&lt;br /&gt;
| &amp;lt;br&amp;gt;http://slurl.com/examples/b_map_yellow.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
| fountain.gif&lt;br /&gt;
| http://slurl.com/examples/fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| forsale.png&lt;br /&gt;
| http://slurl.com/examples/forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
| forsale-shadow.png&lt;br /&gt;
|http://slurl.com/examples/forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Map API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/Z/XXXXX/YYYYY/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  Starting the week of February 9, 2009 tiles will be switching to newer, simpler URLs:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  &lt;br /&gt;
** In the &amp;quot;directory path&amp;quot; (not the file name), pad the coordinate values to five characters with leading zeros; so for the previous coordinates, the path would be &amp;quot;00997/01002&amp;quot;.&lt;br /&gt;
** The padding requirement will go away the week of February 9, 2009.  [[User:James Linden|James Linden]]&lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z at the directory Z/X&#039;/Y&#039; where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/1/01000/01000/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01000/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01000/01001/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01001/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/2/01000/01000/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com/8/01024/00896/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com/1/01027/01019/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
===Implementation notes===  &lt;br /&gt;
&lt;br /&gt;
The map generation process is more scalable than the previous release, and is able to image the entire Second Life grid of about 30,000 regions in less than two days.  &lt;br /&gt;
&lt;br /&gt;
There is a &amp;quot;decay period&amp;quot; for offline regions. If a region is disabled, the tile will stay up for several days (in case it comes back or something else has gone wrong) before the tile disappears. That several-day period will be longer than the time it takes to update existing regions or put new regions on the map.&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com.s3.amazonaws.com/1/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    string x0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(x)), STRING_TRIM_HEAD) + x;&lt;br /&gt;
    string y0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(y)), STRING_TRIM_HEAD) + y;&lt;br /&gt;
    url += x0 + &amp;quot;/&amp;quot; + y0 + &amp;quot;/&amp;quot; + &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
Starting the week of February 9, 2009, I recommend switching to this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    url += &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[User:James Linden|James Linden]] 20:51, 7 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Release notes ==&lt;br /&gt;
&lt;br /&gt;
This section describes new features and known issues with the current release of the Map API.  See also [http://blog.secondlife.com/2009/01/22/improvements-to-mapping-and-upgrade-to-slurlcom/ Philip Linden&#039;s blog post announcement].&lt;br /&gt;
&lt;br /&gt;
The current release of the Map API was release on Jan 15, 2009.&lt;br /&gt;
&lt;br /&gt;
=== New features ===&lt;br /&gt;
&lt;br /&gt;
This release of the Map API provides significant performance improvements over the previous release, including:&lt;br /&gt;
* Map loads faster and operates more smoothly.&lt;br /&gt;
* Map images are updated more accurately and rapidly.  Changes to the Second Life Grid or content will now be visible within about two days.   &lt;br /&gt;
* Map images look smoother and are more accurate when compared to the actual in-world content.&lt;br /&gt;
&lt;br /&gt;
Changes in functionality:&lt;br /&gt;
* You can now single-click on any location on the map and teleport directly there.  &lt;br /&gt;
* Zoom levels go up to eight, so you can now zoom out and see how big SL has really become!&lt;br /&gt;
* More intuitive map tile image file naming convention.&lt;br /&gt;
&lt;br /&gt;
The Map API now gets map tile images directly from [http://aws.amazon.com/s3/ Amazon S3], and the file naming convention will make it easier to develop other third party maps based on the tiles we are generating.&lt;br /&gt;
&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
&lt;br /&gt;
These need to be confirmed.&lt;br /&gt;
--[[User:Rand Linden|Rand Linden]] 23:29, 6 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
* Can&#039;t set Map object click and doubleclick handlers.  They always have the default behavior.  &lt;br /&gt;
* Method &#039;&#039;&#039;SLMap.clickMarker(marker)&#039;&#039;&#039; doesn&#039;t work.&lt;br /&gt;
* Marker options apparently not working:&lt;br /&gt;
** &#039;&#039;&#039;centerOnClick: true&#039;&#039;&#039; - This works, but does NOT work if you open a window onclicking the marker.&lt;br /&gt;
** &#039;&#039;&#039;autopanOnClick: false&#039;&#039;&#039; - Always autopans&lt;br /&gt;
** &#039;&#039;&#039;autopanPadding: n&#039;&#039;&#039; - No effect&lt;br /&gt;
* Setting a different marker image/icon for each zoom level doesn&#039;t work - always uses first icon.&lt;br /&gt;
* Window width option doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Questions:&#039;&#039;&#039;&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6? &lt;br /&gt;
* Old docs said that Map object clickhandler and doubleclickhander have (x,y) passed to them.  Is that true (or rather, will it be true when they work?)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=229273</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=229273"/>
		<updated>2009-02-07T20:47:48Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Bumping browser compatibility to FF 2 and up. We haven&amp;#039;t tested with FF1 for a long time.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the Map API, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Map API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the map images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI features ===&lt;br /&gt;
&lt;br /&gt;
The Map API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default map interface looks as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Map_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].  &lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window; see &#039;&#039;&#039;Teleport window&#039;&#039;&#039; below.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Map_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Map_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Teleport window&#039;&#039;&#039;&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
Clicking anywhere on the map opens a window,  such as the one shown at left, indicating the point on which you clicked.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.  This feature is implemented with the [[Map_API_Reference#Global_functions|gotoSLURL()]] global function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Map API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Map API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Map API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Map API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Map API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Map API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 2.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Map API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Map API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| b_map_yellow.gif&lt;br /&gt;
| &amp;lt;br&amp;gt;http://slurl.com/examples/b_map_yellow.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
| fountain.gif&lt;br /&gt;
| http://slurl.com/examples/fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| forsale.png&lt;br /&gt;
| http://slurl.com/examples/forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
| forsale-shadow.png&lt;br /&gt;
|http://slurl.com/examples/forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Map API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;b_map_yellow.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/Z/XXXXX/YYYYY/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  In the &amp;quot;directory path&amp;quot; (not the file name), pad the coordinate values to five characters with leading zeros; so for the previous coordinates, the path would be &amp;quot;00997/01002&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z at the directory Z/X&#039;/Y&#039; where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/1/01000/01000/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01000/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01000/01001/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01001/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/2/01000/01000/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com/8/01024/00896/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com/1/01027/01019/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
===Implementation notes===  &lt;br /&gt;
&lt;br /&gt;
The map generation process is more scalable than the previous release, and is able to image the entire Second Life grid of about 30,000 regions in less than two days.  &lt;br /&gt;
&lt;br /&gt;
There is a &amp;quot;decay period&amp;quot; for offline regions. If a region is disabled, the tile will stay up for several days (in case it comes back or something else has gone wrong) before the tile disappears. That several-day period will be longer than the time it takes to update existing regions or put new regions on the map.&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com.s3.amazonaws.com/1/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    string x0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(x)), STRING_TRIM_HEAD) + x;&lt;br /&gt;
    string y0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(y)), STRING_TRIM_HEAD) + y;&lt;br /&gt;
    url += x0 + &amp;quot;/&amp;quot; + y0 + &amp;quot;/&amp;quot; + &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Release notes ==&lt;br /&gt;
&lt;br /&gt;
This section describes new features and known issues with the current release of the Map API.  See also [http://blog.secondlife.com/2009/01/22/improvements-to-mapping-and-upgrade-to-slurlcom/ Philip Linden&#039;s blog post announcement].&lt;br /&gt;
&lt;br /&gt;
The current release of the Map API was release on Jan 15, 2009.&lt;br /&gt;
&lt;br /&gt;
=== New features ===&lt;br /&gt;
&lt;br /&gt;
This release of the Map API provides significant performance improvements over the previous release, including:&lt;br /&gt;
* Map loads faster and operates more smoothly.&lt;br /&gt;
* Map images are updated more accurately and rapidly.  Changes to the Second Life Grid or content will now be visible within about two days.   &lt;br /&gt;
* Map images look smoother and are more accurate when compared to the actual in-world content.&lt;br /&gt;
&lt;br /&gt;
Changes in functionality:&lt;br /&gt;
* You can now single-click on any location on the map and teleport directly there.  &lt;br /&gt;
* Zoom levels go up to eight, so you can now zoom out and see how big SL has really become!&lt;br /&gt;
* More intuitive map tile image file naming convention.&lt;br /&gt;
&lt;br /&gt;
The Map API now gets map tile images directly from [http://aws.amazon.com/s3/ Amazon S3], and the file naming convention will make it easier to develop other third party maps based on the tiles we are generating.&lt;br /&gt;
&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
&lt;br /&gt;
These need to be confirmed.&lt;br /&gt;
--[[User:Rand Linden|Rand Linden]] 23:29, 6 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
* Can&#039;t set Map object click and doubleclick handlers.  They always have the default behavior.  &lt;br /&gt;
* Method &#039;&#039;&#039;SLMap.clickMarker(marker)&#039;&#039;&#039; doesn&#039;t work.&lt;br /&gt;
* Marker options apparently not working:&lt;br /&gt;
** &#039;&#039;&#039;centerOnClick: true&#039;&#039;&#039; - This works, but does NOT work if you open a window onclicking the marker.&lt;br /&gt;
** &#039;&#039;&#039;autopanOnClick: false&#039;&#039;&#039; - Always autopans&lt;br /&gt;
** &#039;&#039;&#039;autopanPadding: n&#039;&#039;&#039; - No effect&lt;br /&gt;
* Setting a different marker image/icon for each zoom level doesn&#039;t work - always uses first icon.&lt;br /&gt;
* Window width option doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Questions:&#039;&#039;&#039;&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6? &lt;br /&gt;
* Old docs said that Map object clickhandler and doubleclickhander have (x,y) passed to them.  Is that true (or rather, will it be true when they work?)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Rand_Linden/Notes&amp;diff=221373</id>
		<title>User:Rand Linden/Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Rand_Linden/Notes&amp;diff=221373"/>
		<updated>2009-02-02T19:28:08Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Technical questions and issues: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Map API questions and issues ==&lt;br /&gt;
&lt;br /&gt;
===Technical questions and issues:===&lt;br /&gt;
* I can&#039;t seem to set the Map object click and doubleclick handlers.  They have the default behavior exhibited on slurl.com, but I&#039;m supposed to be able to override or supplement that (which?).  Also, is (x,y) passed to these event handlers?&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6?&lt;br /&gt;
* Had some problems with getCurrentZoomLevel() working at levels 7 and 8.&lt;br /&gt;
* I think someone needs to confirm that [[Webmap_API#Accessing_map_images_directly]] is correct.   It&#039;s not clear to me, but it may be OK.&lt;br /&gt;
** The math section is correct.  The example had a typo, which I fixed. [[User:James Linden|James Linden]]&lt;br /&gt;
&lt;br /&gt;
===Other questions and issue: ===&lt;br /&gt;
&lt;br /&gt;
* Thoughts about calling it &amp;quot;Map API&amp;quot; instead of &amp;quot;Webmap API&amp;quot;?  Latter just seems awkward.&lt;br /&gt;
** Works for me. [[User:James Linden|James Linden]]&lt;br /&gt;
* Is the API still in beta?  Are we going to put a version number on this, since the recent changes (e.g. 1.1?)  &lt;br /&gt;
** I think we should number it, and use version 2.0 or 2.1 to match the underlying Google Map API version (which is 2). [[User:James Linden|James Linden]]&lt;br /&gt;
* Should we provide &amp;quot;Release Notes&amp;quot; listing new features and known bugs, etc?&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Rand_Linden/Notes&amp;diff=221363</id>
		<title>User:Rand Linden/Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Rand_Linden/Notes&amp;diff=221363"/>
		<updated>2009-02-02T19:27:38Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Other questions and issue: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Map API questions and issues ==&lt;br /&gt;
&lt;br /&gt;
===Technical questions and issues:===&lt;br /&gt;
* I can&#039;t seem to set the Map object click and doubleclick handlers.  They have the default behavior exhibited on slurl.com, but I&#039;m supposed to be able to override or supplement that (which?).  Also, is (x,y) passed to these event handlers?&lt;br /&gt;
* Now that there are 8 zoom levels instead of 6, when you instantiate a Marker, do you use an array of images of size 8 instead of 6?&lt;br /&gt;
* Had some problems with getCurrentZoomLevel() working at levels 7 and 8.&lt;br /&gt;
* I think someone needs to confirm that [[Webmap_API#Accessing_map_images_directly]] is correct.   It&#039;s not clear to me, but it may be OK.&lt;br /&gt;
&lt;br /&gt;
===Other questions and issue: ===&lt;br /&gt;
&lt;br /&gt;
* Thoughts about calling it &amp;quot;Map API&amp;quot; instead of &amp;quot;Webmap API&amp;quot;?  Latter just seems awkward.&lt;br /&gt;
** Works for me. [[User:James Linden|James Linden]]&lt;br /&gt;
* Is the API still in beta?  Are we going to put a version number on this, since the recent changes (e.g. 1.1?)  &lt;br /&gt;
** I think we should number it, and use version 2.0 or 2.1 to match the underlying Google Map API version (which is 2). [[User:James Linden|James Linden]]&lt;br /&gt;
* Should we provide &amp;quot;Release Notes&amp;quot; listing new features and known bugs, etc?&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=221353</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=221353"/>
		<updated>2009-02-02T19:25:57Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Fix zoom level in example, use &amp;quot;map.secondlife.com&amp;quot; in URLs instead of including s3.amazonaws.com&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the webmap, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Webmap API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the webmap images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI Features ===&lt;br /&gt;
&lt;br /&gt;
The Webmap API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default Webmap interface looks like the diagram at right.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window that displays the name of the region where you clicked and a button you can click to launch Second Life and teleport to that location.&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Webmap_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].&lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Webmap_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Webmap_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
When you click anywhere on the map, a teleport window opens, such as the one shown at left.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Webmap API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Webmap API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Webmap API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Webmap API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Webmap API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Webmap API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 1.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Webmap API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Webmap API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| Yellow marker.gif&lt;br /&gt;
| https://wiki.secondlife.com/w/images/2/23/Yellow_marker.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
|Fountain.gif&lt;br /&gt;
| https://wiki.secondlife.com/w/images/6/60/Fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| Forsale.png&lt;br /&gt;
| https://wiki.secondlife.com/wiki/Image:Forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
|Forsale-shadow.png&lt;br /&gt;
|https://wiki.secondlife.com/w/images/d/d9/Forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Webmap API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;Yellow_marker.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;Yellow_marker.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a windows ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;Yellow_marker.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;Fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/Z/XXXXX/YYYYY/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  In the &amp;quot;directory path&amp;quot; (not the file name), pad the coordinate values to five characters with leading zeros; so for the previous coordinates, the path would be &amp;quot;00997/01002&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z at the directory Z/X&#039;/Y&#039; where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/1/01000/01000/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01000/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01000/01001/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01001/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/2/01000/01000/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com/8/01024/00896/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com/1/01027/01019/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com.s3.amazonaws.com/1/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    string x0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(x)), STRING_TRIM_HEAD) + x;&lt;br /&gt;
    string y0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(y)), STRING_TRIM_HEAD) + y;&lt;br /&gt;
    url += x0 + &amp;quot;/&amp;quot; + y0 + &amp;quot;/&amp;quot; + &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=221343</id>
		<title>Linden Lab Official:Map API</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Linden_Lab_Official:Map_API&amp;diff=221343"/>
		<updated>2009-02-02T19:25:18Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help/Box|Update notice|&amp;lt;b&amp;gt;We&#039;ve made improvements and changes to the webmap, effective January 15, 2009.&amp;lt;br&amp;gt;Some information here may be out of date as we update this wiki with the changes.  Thanks for your patience.&amp;lt;/b&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{:API Portal/navigation}}&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
The Second Life Webmap API is a set of Javascript objects and functions that enable you to embed Second Life maps onto your web pages.  It is a purely client-side Javascript API.  If needed, you can also [[#Accessing_map_images_directly|directly access]] the webmap images.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
This API is still in beta.  URLs and API signatures may change.&lt;br /&gt;
&lt;br /&gt;
=== Map UI Features ===&lt;br /&gt;
&lt;br /&gt;
The Webmap API enables you to create web pages that have Google Maps functionality, using maps of Second Life, rather than Earth.  In general, the default Webmap interface looks like the diagram at right.&lt;br /&gt;
&lt;br /&gt;
[[Image:Map ui cropped.png|right]]&lt;br /&gt;
&lt;br /&gt;
The main map display area shows the current map area.  By default, the map provides the following features:&lt;br /&gt;
&lt;br /&gt;
* Click anywhere on the map to open a &amp;quot;teleport&amp;quot; window that displays the name of the region where you clicked and a button you can click to launch Second Life and teleport to that location.&lt;br /&gt;
* Click and drag the mouse pointer to pan the map view up, down, left, and right.  If desired, you can [[Webmap_API_Advanced_Examples#Disabling_and_enabling_dragging|disable this behavior]].&lt;br /&gt;
* Double-click to zoom in by one level (power of two) and display the teleport window.&lt;br /&gt;
* Use the mouse wheel to zoom in and out.  See [[#Zoom_levels|Zoom levels]] for more information about zoom levels.&lt;br /&gt;
* Use the zoom and pan controls at upper left to zoom the view in and out and to pan the view up, down, left, and right.  If desired, you can easily [[Webmap_API_Advanced_Examples#Customizing_zoom_and_pan_controls|create your own custom zoom and pan controls]].&lt;br /&gt;
* Use the overview control to move the view around by clicking and dragging, or double-clicking.  Close the overview control by clicking on the diagonal arrow at the very bottom right of the map.  You can specify whether the map provides an overview control when you [[Webmap_API_Reference#MarkerOptions|create the map object]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Teleport window.png|left]]&lt;br /&gt;
When you click anywhere on the map, a teleport window opens, such as the one shown at left.  Clicking on the teleport button in the window then starts the Second Life Viewer, automatically teleporting you to the window&#039;s location.&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using slurl.com and DirectSLurl ===&lt;br /&gt;
&lt;br /&gt;
The website http://slurl.com uses the Webmap API to provide a mechanism to teleport directly to locations in Second Life from web pages.&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Using Second Life URLs (SLURLs)]].&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
To use the Second Life Webmap API in a web page, you must first:&lt;br /&gt;
 &lt;br /&gt;
* [http://www.google.com/apis/maps/signup.html Sign up for a Google Maps API key].  This enables you to use the Google Maps API, which is required to use SLMAPI.  See the [http://code.google.com/apis/maps/documentation/ Google Maps API documentation] for more information.&lt;br /&gt;
* Add the [[#Common_HTML_header|common header code]] at the beginning of each HTML file.  This code loads the Google Maps and Webmap Javascript libraries, the Webmap cascading stylesheet (CSS), and some other basic code.&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, it is best to reference the Webmap API Javascript library and CSS files that are on http://slurl.com.  Although you can download these files locally and modify them for your own use, if Linden Lab updates or changes these files, your applications will not get the benefit and may even stop working properly.   &lt;br /&gt;
&lt;br /&gt;
=== Common HTML header ===&lt;br /&gt;
&lt;br /&gt;
To use the Webmap API, put the following lines at the beginning of each HTML page.  This includes:&lt;br /&gt;
* Statements to load the required Second Life Webmap API and Google Maps Javascript libraries.&lt;br /&gt;
* Link to the Webmap cascading style sheet.&lt;br /&gt;
* Style declaration for the map div element.  This defines the size and other layout attributes of the map display.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key={GOOGLE MAPS KEY}&amp;quot;&lt;br /&gt;
  type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace {GOOGLE MAPS KEY} with you Google Maps Key.&lt;br /&gt;
&lt;br /&gt;
All the examples also require additional script statements in the HTML header.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stylesheet&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To use your own stylesheet, just include it AFTER the Webmap CSS, for example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;myStyleSheet.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use the following body element in your HTML document:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body load=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload();&amp;quot;&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GUnload()&#039;&#039;&#039; function is a Google Maps API  function that reduces memory leaks, particularly with Internet Explorer.  For more information, see the [http://code.google.com/apis/maps/documentation/#Memory_Leaks Google Maps API documentation].&lt;br /&gt;
&lt;br /&gt;
=== Browser compatibility ===&lt;br /&gt;
The Webmap API has been tested to work with the following browsers:&lt;br /&gt;
* Internet Explorer 6.0&lt;br /&gt;
* Internet Explorer 7.0&lt;br /&gt;
* Firefox 1.0 or greater &lt;br /&gt;
* Safari 2.0&lt;br /&gt;
&lt;br /&gt;
Other browsers may work but little issues may appear. Unless otherwise noted, all features work in all supported browsers.&lt;br /&gt;
&lt;br /&gt;
=== Comments and feedback ===&lt;br /&gt;
&lt;br /&gt;
If you encounter problems or bugs or have feature requests, please email &#039;&#039;&#039;webmap@secondlife.com&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Happy coding from the Second Life Web team!&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
The Webmap API&#039;s fundamental class is [[Webmap_API_Reference#SLMap|SLMap]].  It is a Javascript object representing the map with a large number of methods, enabling you to zoom, pan the view, and so on.&lt;br /&gt;
&lt;br /&gt;
Additionally, the API includes the following key classes:&lt;br /&gt;
* [[Webmap_API_Reference#Marker|Marker]] - represents an image to display at a specify (x,y) point on the map.  You provide a set of images to display at each zoom level.  Contains several event handlers and other properties.  See [[#Map_with_a_marker|Map with a marker]] for a basic example.&lt;br /&gt;
* [[Webmap_API_Reference#MapWindow|Window]] - represents a captioned balloon pointing to a specified map location.  See [[Webmap_API#Map_with_an_initial_open_window|Map with an initial open window]] for a basic example. &lt;br /&gt;
* [[Webmap_API_Reference#Img|Img]] and [[Webmap_API_Reference#Icon|Icon]] - represent an image to use for markers, controls, or in windows.&lt;br /&gt;
&lt;br /&gt;
===About coordinates===&lt;br /&gt;
&lt;br /&gt;
Map coordinates are based on the Second Life grid system for positioning regions. &lt;br /&gt;
&lt;br /&gt;
[[Image:Webmap coords.jpg]]&lt;br /&gt;
&lt;br /&gt;
As illustrated in the diagram above, the Webmap API maps the Second Life world to the upper right quadrant of the Google world map.  A large scaling value&lt;br /&gt;
called slGridEdgeSizeInRegions (equal to 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; or 1,048,576) defines the largest region coordinate at the top and far right edge of the displayed area.  This value creates a map area with room for one trillion sims.&lt;br /&gt;
&lt;br /&gt;
The little blue square illustrates where the populated sims are in Second Life.&lt;br /&gt;
&lt;br /&gt;
=== Zoom levels ===&lt;br /&gt;
There are eight zoom levels: one through eight, one being the closest and eight being the farthest. Each level zooms by a power of two. In other words, at zoom level five, each region is twice the width as it was at zoom level six.&lt;br /&gt;
&lt;br /&gt;
== Basic Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Required image files ===&lt;br /&gt;
&lt;br /&gt;
Some of the following examples use image files for markers.  To run the examples with the code as shown, download the image files and save them in the same directory as the example HTML files.  Alternatively, create the Img objects using the URLs listed in the table below that refer to the images stored on this wiki.&lt;br /&gt;
&lt;br /&gt;
The following table lists the images used in the examples:&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-{{Hl2}}&lt;br /&gt;
! Image&lt;br /&gt;
! File name&lt;br /&gt;
! URL&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Yellow marker.gif]]&lt;br /&gt;
| Yellow marker.gif&lt;br /&gt;
| https://wiki.secondlife.com/w/images/2/23/Yellow_marker.gif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Fountain.gif]] &lt;br /&gt;
|Fountain.gif&lt;br /&gt;
| https://wiki.secondlife.com/w/images/6/60/Fountain.gif&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [[Image:Forsale.png]]&lt;br /&gt;
| Forsale.png&lt;br /&gt;
| https://wiki.secondlife.com/wiki/Image:Forsale.png&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|[[Image:Forsale-shadow.png]]&lt;br /&gt;
|Forsale-shadow.png&lt;br /&gt;
|https://wiki.secondlife.com/w/images/d/d9/Forsale-shadow.png&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple map ===&lt;br /&gt;
&lt;br /&gt;
The first example is a map with basic panning and zooming capabilities.  When you are done, it will look as shown here.&lt;br /&gt;
&lt;br /&gt;
[[Image:MapAPI ex1.png|thumb|right|Simple map]]&lt;br /&gt;
&lt;br /&gt;
You can pan the map and zoom in and out.&lt;br /&gt;
&lt;br /&gt;
To create this example, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Add common HTML header code.&lt;br /&gt;
# Add HTML body element.&lt;br /&gt;
# Add &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. &lt;br /&gt;
# Save and test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Add common HTML header&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
First, include the [[Webmap_API#Common_HTML_header|common header code]], required by all Webmap applications.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={GOOGLE MAPS KEY}&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to replace {GOOGLE MAPS KEY} with your Google Map key.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Add HTML body element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Next, add the HTML body element to contain your map. The body contains a Javascript onload event handler that calls the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function you will define in the next step.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The div element is passed to the SLMap object constructor, using the  &amp;lt;code&amp;gt;document.getElementById(&#039;map-container&#039;)&amp;lt;/code&amp;gt; DOM method call.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want the position attribute of the div element to be absolute, either set it programmatically using Javascript or using the style attribute tag.  Setting the position attribute of this element in the CSS stylesheet will not work.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3. Add loadmap() function&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The body element you just added has a Javascript event handler for the &amp;quot;onload&amp;quot; event, called when the browser initially loads the page.  You deifined this to call a &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function.  Now, define that Javascript function in the head of your page (after the code that is already there), as follows: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script&amp;gt;&lt;br /&gt;
 function loadmap() {&lt;br /&gt;
   mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
   mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line defines a new Map object from the HTML div element.  The second line centers the map at a specific point, and zooms it to zoom level three.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4. Save and test&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
When you are done, save the file, and then load it into your web browser.  Try panning the map by clicking and dragging the mouse cursor; you can also pan by clicking on the arrow icons on the four sides.  Also try zooming the view in and out by clicking the &amp;quot;+&amp;quot; and &amp;quot;-&amp;quot; icons.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Complete source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=iso-8859-1&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=[GOOGLE MAPS KEY]&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;http://slurl.com/_scripts/slmapapi.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://slurl.com/_styles/MAIN.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
div#map-container {&lt;br /&gt;
      width: 500px;&lt;br /&gt;
      height: 500px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with Marker.png|thumb|right|Map with a marker]]&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;marker&#039;&#039; is simply an image displayed at a specific location on the map.  The Webmap API enables you to define an image for each zoom level, so the marker can appear differently at each zoom level if you wish.&lt;br /&gt;
&lt;br /&gt;
This example shows how to make a map with a marker. The code is the same as the first example, with with addition of some Javascript after the initialization of the map in the page&#039;s onload event handler function, &#039;&#039;&#039;loadmap()&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
To use the code below verbatim, you must download the marker image as described in [[#Required_image_files|Required image files]]; you can also use the URL of the wiki image if you prefer.  &lt;br /&gt;
&lt;br /&gt;
The code first creates the icon for the marker, then places it on the map at (997, 1002) at the welcome area fountain.  Because the same icon is specified for every zoom level, it appears the same size regardless of zoom level.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Create the icons&lt;br /&gt;
var yellow_dot_image = new Img(&amp;quot;Yellow_marker.gif&amp;quot;, 9, 9);&lt;br /&gt;
var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
&lt;br /&gt;
// Create the marker&lt;br /&gt;
var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
mapInstance.addMarker(marker);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, clicking on the marker does nothing.  Subsequent examples illustrate adding some onClick behavior. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // creates the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 2);&lt;br /&gt;
  &lt;br /&gt;
  // creates the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;Yellow_marker.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // creates the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  mapInstance.addMarker(marker);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;There should be a yellow marker in the center of this map:&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with an initial open window ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map_with_window.png|thumb|right|Map with a window]]&lt;br /&gt;
&lt;br /&gt;
A Webmap &#039;&#039;window&#039;&#039; is a caption pointing to a specific point on the map, as shown in the screenshot at right.  It looks something like a comic book dialog bubble.  &lt;br /&gt;
&lt;br /&gt;
Use the [[Webmap_API_Reference#MapWindow|MapWindow]] object to create a window.&lt;br /&gt;
For example, to create a window that opens initially when the page loads:&lt;br /&gt;
# Instantiate a [[Webmap_API_Reference#MapWindow|MapWindow]] object with the desired caption.&lt;br /&gt;
# Call the &#039;&#039;&#039;addMapWindow()&#039;&#039;&#039; method on the [[Webmap_API_Reference#SLMap|SLMap]] object to add the window to the map. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// creates a window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code adds an open window to the map positioned again at (997, 1002), right above the welcome area fountain. &lt;br /&gt;
&lt;br /&gt;
NOTE: after the user closes the window there is no way to bring it back.  A subsequent example will show how to enable the user to reopen the window, by using markers with windows. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make the map initially centered on the fountain, change the call to &#039;&#039;&#039;centerAndZoomAtSLCoord()&#039;&#039;&#039; as follows:&lt;br /&gt;
&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a window. The code is the same as the first example, with the addition of some lines of Javascript after the initialization of the map, in the &#039;&#039;&#039;loadmap()&#039;&#039;&#039; function. In addition, the map is centered in a different location in order to make the window fully visible. &lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!-- Insert common HTML header --&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997, 1002), 3);&lt;br /&gt;
  &lt;br /&gt;
  // Create window&lt;br /&gt;
var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!!&amp;quot;);&lt;br /&gt;
mapInstance.addMapWindow(mapWindow, new XYPoint(997, 1002));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;h1&amp;gt;Simple Map Example&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map with a marker that opens a windows ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Map with marker and window.png|thumb|right|Map with marker that opens a window]]&lt;br /&gt;
&lt;br /&gt;
This example shows how to create a map with a marker which opens a window when clicked.   It is a combination of the previous two examples, because the code first creates a marker and a window.  &lt;br /&gt;
&lt;br /&gt;
The difference comes in adding the marker to the map: this time you provide the window object as well as the marker object in the call to &#039;&#039;&#039;addMarker()&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
&lt;br /&gt;
Doing this adds the marker and causes it to open the specified window when the user clicks it.  If the user subsequently closes the window, s/he can open it again by clicking on the marker.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Source code&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Replace the first line comment below with the [[Webmap_API#Common_HTML_header|common header code]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!--- Insert common HTML header ---&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
function loadmap() {&lt;br /&gt;
  // Create the map&lt;br /&gt;
  var mapInstance = new SLMap(document.getElementById(&#039;map-container&#039;));&lt;br /&gt;
  mapInstance.centerAndZoomAtSLCoord(new XYPoint(997.5, 1001.5), 2);&lt;br /&gt;
  &lt;br /&gt;
  // Create the icons&lt;br /&gt;
  var yellow_dot_image = new Img(&amp;quot;Yellow_marker.gif&amp;quot;, 9, 9);&lt;br /&gt;
  var yellow_icon = new Icon(yellow_dot_image);&lt;br /&gt;
  var all_images = [yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon, yellow_icon];&lt;br /&gt;
  &lt;br /&gt;
  // Create the marker&lt;br /&gt;
  var marker = new Marker(all_images, new XYPoint(997, 1002));&lt;br /&gt;
  &lt;br /&gt;
  // Create a window&lt;br /&gt;
  var mapWindow = new MapWindow(&amp;quot;This is where the welcome area fountain is!! &amp;lt;br&amp;gt;&amp;lt;img src=&#039;Fountain.gif&#039;&amp;gt;&amp;quot;);&lt;br /&gt;
  &lt;br /&gt;
  // Adds the marker to the map&lt;br /&gt;
  mapInstance.addMarker(marker, mapWindow);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body onload=&amp;quot;loadmap()&amp;quot; onunload=&amp;quot;GUnload()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;This map shows a yellow marker on the welcome fountain.  When you click the marker, &lt;br /&gt;
a window appears with a screenshot of the fountain.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;map-container&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessing map images directly ==&lt;br /&gt;
&lt;br /&gt;
The Second Life map images are stored on [http://aws.amazon.com/s3/ Amazon Simple Storage Service (Amazon S3)].  You can access the map images directly on the Amazon S3 servers using the following URL format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://map.secondlife.com/Z/XXXXX/YYYYY/map-Z-X-Y-objects.jpg&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* Z - Zoom level desired: &lt;br /&gt;
** One (1) is the most zoomed-in view, showing individual region tiles. &lt;br /&gt;
** Eight (8) is the maximum zoom level, showing the entire world. &lt;br /&gt;
* X,Y - X and Y coordinates on the Second Life Grid of the region, for example, region Ahern is (997,1002).  In the &amp;quot;directory path&amp;quot; (not the file name), pad the coordinate values to five characters with leading zeros; so for the previous coordinates, the path would be &amp;quot;00997/01002&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Tiles with zoom greater than one are stored at the lower left corner coordinate of the tiles that are included in the image.&lt;br /&gt;
In other words, you can find the zoom tile containing region (X,Y) for zoom level Z at the directory Z/X&#039;/Y&#039; where:&lt;br /&gt;
&lt;br /&gt;
X&#039; = X - (X % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
Y&#039; = Y - (Y % (2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt;) )&lt;br /&gt;
&lt;br /&gt;
Note that 2&amp;lt;sup&amp;gt;Z - 1&amp;lt;/sup&amp;gt; is the number of regions encompassed by the width of a tile at resolution Z. &lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
For example: if Z = 1, the four region tiles are:&lt;br /&gt;
&lt;br /&gt;
* http://map.secondlife.com/1/01000/01000/map-1-1000-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01000/map-1-1001-1000-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01000/01001/map-1-1000-1001-objects.jpg&lt;br /&gt;
* http://map.secondlife.com/1/01001/01001/map-1-1001-1001-objects.jpg&lt;br /&gt;
&lt;br /&gt;
These four region tiles are compressed into the single tile:&lt;br /&gt;
&lt;br /&gt;
http://map.secondlife.com/2/01000/01000/map-2-1000-1000-objects.jpg&lt;br /&gt;
&lt;br /&gt;
The following shows the map zoomed all the way out, showing the entire Second Life world view:&lt;br /&gt;
http://map.secondlife.com.s3.amazonaws.com/8/01024/00896/map-8-1024-896-objects.jpg &lt;br /&gt;
&lt;br /&gt;
The following displays a single tile contained in the view above, zoomed all the way in:&lt;br /&gt;
http://map.secondlife.com.s3.amazonaws.com/1/01027/01019/map-1-1027-1019-objects.jpg&lt;br /&gt;
&lt;br /&gt;
=== Getting a map URL from LSL ===&lt;br /&gt;
&lt;br /&gt;
The following LSL script illustrates how to display a map of the current region to an avatar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
ShowMap(key avatar) {&lt;br /&gt;
    string url = &amp;quot;http://map.secondlife.com.s3.amazonaws.com/1/&amp;quot;;&lt;br /&gt;
    vector sim_coord = llGetRegionCorner();&lt;br /&gt;
    string x = (string)((integer)(sim_coord.x / 256.0));&lt;br /&gt;
    string y = (string)((integer)(sim_coord.y / 256.0));&lt;br /&gt;
    string x0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(x)), STRING_TRIM_HEAD) + x;&lt;br /&gt;
    string y0 = llStringTrim(llGetSubString(&amp;quot; 00000&amp;quot;, 0, 5 - llStringLength(y)), STRING_TRIM_HEAD) + y;&lt;br /&gt;
    url += x0 + &amp;quot;/&amp;quot; + y0 + &amp;quot;/&amp;quot; + &amp;quot;map-1-&amp;quot; + x + &amp;quot;-&amp;quot; + y + &amp;quot;-objects.jpg&amp;quot;;&lt;br /&gt;
    llLoadURL(avatar, &amp;quot;View the sim map&amp;quot;, url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Contributed under GPL v3 license by [[User:Henri Beauchamp|Henri Beauchamp]] 09:00, 24 January 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Windows_Icon_Test&amp;diff=94798</id>
		<title>Windows Icon Test</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Windows_Icon_Test&amp;diff=94798"/>
		<updated>2008-10-08T17:44:31Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Goal ==&lt;br /&gt;
Make sure Windows icon set is correct for installer and Second Life applications.&lt;br /&gt;
&lt;br /&gt;
=== Installer Icons ===&lt;br /&gt;
# Uninstall all copies of SL from your machine&lt;br /&gt;
# Browse through C:\Program Files to make sure all SecondLife* directories are gone&lt;br /&gt;
## If you find a C:\Program Files\SecondLife* directory, delete it&lt;br /&gt;
# Download the test installer&lt;br /&gt;
# Put it in a folder&lt;br /&gt;
# Cycle through all icon views (Extra Large, Large, Medium, Small, List, Details, Tiles)&lt;br /&gt;
# Verify the installer icon looks sharp at each view&lt;br /&gt;
&lt;br /&gt;
=== Application Icons ===&lt;br /&gt;
# Run the installer&lt;br /&gt;
# Verify the installer window icons are sharp&lt;br /&gt;
# Verify the SL shortcut on the desktop has a hand icon&lt;br /&gt;
# Verify the SL shortcut in the Start menu has a hand icon&lt;br /&gt;
# Browse to C:\Program Files\SecondLife&lt;br /&gt;
# Cycle through all icon views (Extra Large, Large, Medium, Small, List, Details, Tiles)&lt;br /&gt;
# Verify the application icon looks sharp at each view&lt;br /&gt;
&lt;br /&gt;
=== Window Icons ===&lt;br /&gt;
# Launch SL&lt;br /&gt;
# Verify the window icon (top left) is sharp and is a hand&lt;br /&gt;
# Quit SL&lt;br /&gt;
&lt;br /&gt;
=== Uninstaller Icons ===&lt;br /&gt;
# Go to Control Panels &amp;gt; Add/Remove Programs (on XP) or Uninstall Programs (Vista)&lt;br /&gt;
# Verify the uninstaller has an icon&lt;br /&gt;
# Run the uninstaller&lt;br /&gt;
# Verify the uninstaller window has sharp icons&lt;br /&gt;
[[Category:Test Scripts]]&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Windows_Icon_Test&amp;diff=94797</id>
		<title>Windows Icon Test</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Windows_Icon_Test&amp;diff=94797"/>
		<updated>2008-10-08T17:44:15Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: == Goal == Make sure Windows icon set is correct for installer and Second Life applications.  === Installer Icons === # Uninstall all copies of SL from your machine # Browse through C:\Pro...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Goal ==&lt;br /&gt;
Make sure Windows icon set is correct for installer and Second Life applications.&lt;br /&gt;
&lt;br /&gt;
=== Installer Icons ===&lt;br /&gt;
# Uninstall all copies of SL from your machine&lt;br /&gt;
# Browse through C:\Program Files to make sure all SecondLife* directories are gone&lt;br /&gt;
## If you find a C:\Program Files\SecondLife* directory, delete it&lt;br /&gt;
# Download the test installer&lt;br /&gt;
# Put it in a folder&lt;br /&gt;
# Cycle through all icon views (Extra Large, Large, Medium, Small, List, Details, Tiles)&lt;br /&gt;
# Verify the installer icon looks sharp at each view&lt;br /&gt;
&lt;br /&gt;
=== Application Icons ===&lt;br /&gt;
# Run the installer&lt;br /&gt;
# Verify the installer window icons are sharp&lt;br /&gt;
# Verify the SL shortcut on the desktop has a hand icon&lt;br /&gt;
# Verify the SL shortcut in the Start menu has a hand icon&lt;br /&gt;
# Browse to C:\Program Files\SecondLife&lt;br /&gt;
# Cycle through all icon views (Extra Large, Large, Medium, Small, List, Details, Tiles)&lt;br /&gt;
# Verify the application icon looks sharp at each view&lt;br /&gt;
&lt;br /&gt;
=== Window Icons ===&lt;br /&gt;
# Launch SL&lt;br /&gt;
# Verify the window icon (top left) is sharp and is a hand&lt;br /&gt;
# Quit SL&lt;br /&gt;
&lt;br /&gt;
=== Uninstaller Icons ===&lt;br /&gt;
# Go to Control Panels &amp;gt; Add/Remove Programs (on XP) or Uninstall Programs (Vista)&lt;br /&gt;
# Verify the uninstaller has an icon&lt;br /&gt;
# Run the uninstaller&lt;br /&gt;
# Verify the uninstaller window has sharp icons&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=91415</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=91415"/>
		<updated>2008-09-15T21:50:35Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
aka Application SLURL&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
Most secondlife:///app URLs only work from browser instances running inside Second Life because of a denial-of-service attack using secondlife:///app/teleport links to force repeated teleports.  SLURLs that work with external browsers include:&lt;br /&gt;
* secondlife://&amp;lt;region name&amp;gt;&lt;br /&gt;
* secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login &#039;&#039;log in on launch. External and internal browsers.&#039;&#039;&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /group&lt;br /&gt;
*** /&amp;lt;group_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing group&#039;&#039;&lt;br /&gt;
*** /create &#039;&#039;open the create group dialog, added in 1.20&#039;&#039;&lt;br /&gt;
*** /list&lt;br /&gt;
**** /show &#039;&#039;open the list of groups to which user belongs, added in 1.20&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Second_Life_Browser_User_Agent&amp;diff=77060</id>
		<title>Second Life Browser User Agent</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Second_Life_Browser_User_Agent&amp;diff=77060"/>
		<updated>2008-07-08T18:16:29Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: The embedded Mozilla browser in Second Life identifies itself with a special user agent string.  The format of this string has changed over the years.  The user agent strings in 1.20 RC13 ...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The embedded Mozilla browser in Second Life identifies itself with a special user agent string.  The format of this string has changed over the years.  The user agent strings in 1.20 RC13 and beyond should conform to the HTTP 1.1 specification ([http://www.w3.org/Protocols/rfc2616/rfc2616.html RFC 2616]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// As of 1.20.13&lt;br /&gt;
Mozilla/5.0 (Windows; U; Windows NT 5.1; chrome://navigator/locale/navigator.properties; rv:1.8.1.13) Gecko/20080314 SecondLife/1.20.13.0 (Second Life Release; default skin)&lt;br /&gt;
&lt;br /&gt;
// As of 1.18.2.1&lt;br /&gt;
Mozilla/5.0 (Windows; U; Windows NT 5.1; chrome://navigator/locale/navigator.properties; rv:1.8.0.12) Gecko/20070605 [Second Life (Second Life Release) - 1.18.2.1]&lt;br /&gt;
&lt;br /&gt;
// Prior to 1.18.2.1&lt;br /&gt;
Mozilla/5.0 (Windows; U; Windows NT 5.1; chrome://navigator/locale/navigator.properties; rv:1.8.0.12) Gecko/20070605 [Second Life 1.18.2.1]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Web_Browser&amp;diff=77057</id>
		<title>Web Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Web_Browser&amp;diff=77057"/>
		<updated>2008-07-08T18:13:14Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SecondLife uses the Gecko engine from the Mozilla project to display web pages.&lt;br /&gt;
&lt;br /&gt;
*  [[LLMozLib2]] - The Linden Lab integration layer and modified version of Mozilla for OpenGL compatibility.&lt;br /&gt;
* [[Second Life Browser User Agent]] - the user agent strings reported by the embedded Mozilla browser in Second Life&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67257</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67257"/>
		<updated>2008-05-13T22:57:19Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Removed app/help, as it is not supported in the current (1.20) code base.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
aka Application SLURL&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login&lt;br /&gt;
*** log in on launch&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /group&lt;br /&gt;
*** /&amp;lt;group_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing group&#039;&#039;&lt;br /&gt;
*** /create &#039;&#039;open the create group dialog, added in 1.20&#039;&#039;&lt;br /&gt;
*** /list&lt;br /&gt;
**** /show &#039;&#039;open the list of groups to which user belongs, added in 1.20&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67203</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67203"/>
		<updated>2008-05-13T18:14:55Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
aka Application SLURL&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login&lt;br /&gt;
*** log in on launch&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /group&lt;br /&gt;
*** /&amp;lt;group_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing group&#039;&#039;&lt;br /&gt;
*** /list&lt;br /&gt;
**** /show &#039;&#039;open the list of groups to which user belongs, added in 1.20&#039;&#039;&lt;br /&gt;
*** /create &#039;&#039;open the create group dialog, added in 1.20&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /help &#039;&#039;open F1 help floater&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67204</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67204"/>
		<updated>2008-05-13T18:14:23Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
aka Application SLURL&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login&lt;br /&gt;
*** log in on launch&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /group&lt;br /&gt;
*** /&amp;lt;group_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing group&#039;&#039;&lt;br /&gt;
*** /create &#039;&#039;open the create group dialog, added in 1.20&#039;&#039;&lt;br /&gt;
*** /list&lt;br /&gt;
**** /show &#039;&#039;open the list of groups to which user belongs, added in 1.20&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /help &#039;&#039;open F1 help floater&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67200</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=67200"/>
		<updated>2008-05-13T18:10:52Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
aka Application SLURL&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login&lt;br /&gt;
*** log in on launch&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /group&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing group&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /help &#039;&#039;open F1 help floater&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Category:Design_Documents&amp;diff=53540</id>
		<title>Category:Design Documents</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Category:Design_Documents&amp;diff=53540"/>
		<updated>2008-02-11T19:47:29Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: Design for new features and large project descriptions should have the category &amp;quot;Design Documents&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Design for new features and large project descriptions should have the category &amp;quot;Design Documents&amp;quot;&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:Viewer_URI_Name_Space&amp;diff=47889</id>
		<title>Talk:Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:Viewer_URI_Name_Space&amp;diff=47889"/>
		<updated>2008-01-09T01:12:54Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: Does this mean that no region can be named &amp;#039;app&amp;#039;? Phoenix 17:27, 23 July 2007 (PDT) :Yes, no region can be named &amp;quot;app&amp;quot;.  I had to pick some prefix, this one seemed reasona...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Does this mean that no region can be named &#039;app&#039;? [[User:Phoenix|Phoenix]] 17:27, 23 July 2007 (PDT)&lt;br /&gt;
:Yes, no region can be named &amp;quot;app&amp;quot;.  I had to pick some prefix, this one seemed reasonable.  Unfortunately, also any string starting with secondlife:// can be legally parsed as a region name.  [[User:James|James]] 08:54, 24 July 2007 (PDT)&lt;br /&gt;
::I think this is a really bad direction to start down -- it artificially limits our usable space. I think we should instead make a new protocol for local resources, or make a more general url syntax. For example:&lt;br /&gt;
&lt;br /&gt;
slclient://locally/available/resource&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
secondlifegrid://localhost/locally/available/resource&lt;br /&gt;
&lt;br /&gt;
[[User:Phoenix|Phoenix]] 09:39, 24 July 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
I agree with Phoenix here.  Extending the secondlife: scheme is a mistake, since it&#039;s already well defined what it means:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Via the Second Life protocol I am access Region Foo at x,y,z&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Mozilla uses the uri scheme chrome for &amp;quot;locally accessable resources that are accessed without knowing their precise filesystem location&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
secondlife:// as a region name is actually okay.  In URI form, it would be secondlife://secondlife%3A%2F%2F/1/2/3&lt;br /&gt;
&lt;br /&gt;
From what I can tell, something like slchrome:// or slui:// would be better.&lt;br /&gt;
&lt;br /&gt;
[[User:Mark|Mark]] 10:07, 24 July 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
Yes, I see your point and agree.  I initially chose secondlife:// for expedience, as the installer already registered it on all platforms, the embedded mozilla already had callbacks for the links, etc.  But we need a different protocol for this type of command.&lt;br /&gt;
&lt;br /&gt;
I&#039;m going to use slclient:// because the word &amp;quot;client&amp;quot; is probably more understandable to an end user (who might see the raw link in a browser warning dialog) than &amp;quot;chrome&amp;quot; or &amp;quot;ui&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[User:James|James]] 10:30, 24 July 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Well, while it is ugly, and unfortunate, I don&#039;t think a &amp;quot;one-time&amp;quot; fix of inserting &amp;quot;/app&amp;quot; at the top level is that bad.  I think there are plenty of downsides to creating another scheme identifier.  A way to make this more palatable is to fix the top level of the path, so whereas before you had:&lt;br /&gt;
 secondlife://Obscure/123/98&lt;br /&gt;
you&#039;d now have:&lt;br /&gt;
 secondlife://location/Obscure/123/98&lt;br /&gt;
The old one would be deprecated, and yes, regions with the name &amp;quot;app&amp;quot; or &amp;quot;location&amp;quot; or whatever else we put a the top level wouldn&#039;t work with the old style.&lt;br /&gt;
&lt;br /&gt;
The primary reason for having a scheme is that it is the way to get an operating system to open up another application with a class of URIs.  Hence, everything in such a URI namespace is really the name for something the running viewer can do.  We shouldn&#039;t use the secondlife: scheme to address elements of our network at all.  Hence, I don&#039;t think the need for a top level &#039;/localhost&#039; in the examples above.&lt;br /&gt;
&lt;br /&gt;
Since the scheme is entirely for the purpose of directing the viewer, it is reasonable to think of all those resources named as actions or concepts in the viewer.  In otherwords, the URI&lt;br /&gt;
 secondlife://event/&amp;lt;uuid&amp;gt;&lt;br /&gt;
should be though of as the viewer&#039;s concept of that event in our system.  And this should conceptually distinct from, say:&lt;br /&gt;
 http://services.agni.lindenlab.com/event/&amp;lt;uuid&amp;gt;&lt;br /&gt;
which would be a reference to the event resource back at the grid.&lt;br /&gt;
&lt;br /&gt;
As such, such URIs really should only imply viewer actions on those objects:  I could see secondlife: URIs that open an event in the viewer (but one wonders why?), but not one that creates an event that way.  For the most part, I think we should be steering such functionality to the web services.&lt;br /&gt;
&lt;br /&gt;
Lastly, a big problem with the URI tree proposed is that it puts all content into global name spaces by type.  In particular:&lt;br /&gt;
 secondlife://app/parcel/&amp;lt;uuid&amp;gt;&lt;br /&gt;
implies that one can reach ANY parcel that way.  This is bad as it forces us to think in terms of a single global list.  Much better would be&lt;br /&gt;
 secondlife://app/grid/agni/region-by-name/Obscure/parcels/&amp;lt;uuid&amp;gt;/view&lt;br /&gt;
Though, admittadly, the &amp;quot;/grid/agni&amp;quot; part may be overkilll.... but perhaps not...&lt;br /&gt;
&lt;br /&gt;
[[User:ZeroLinden|ZeroLinden]] 10:38, 24 July 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
The primary motivation for this is to make clicking on links in a Find All search results page (output by Google Search Appliance) show SL UI with details on that data.  Even if we move that data display to HTML, we&#039;ll still need a way to have links/buttons that offer teleports, open the IM window, etc.  So we need a commmand format.&lt;br /&gt;
&lt;br /&gt;
At the time the parcel links in the HTML pages for search are made, I do not have access to the region name or other information other than the UUID of the parcel.  For example, top picks only store the parcel UUIDs.  I could thrash the database during the static HTML page generation for search to look up the region names for each parcel UUID I encountered, but that seems a waste of effort to me.&lt;br /&gt;
&lt;br /&gt;
I could imagine having special links that opened, say, the event UI as a useful way to share references to information in our system, on outside web pages, in our own IM, and in tutorials.  Since I have to do some internal link management for search, it seems reasonable to me to expose those URLs to the outside world.&lt;br /&gt;
&lt;br /&gt;
I would prefer to reserve the words &amp;quot;event&amp;quot;, &amp;quot;classified&amp;quot;, &amp;quot;place&amp;quot;, &amp;quot;parcel&amp;quot;, &amp;quot;agent&amp;quot;, &amp;quot;resident&amp;quot;, &amp;quot;person&amp;quot; and &amp;quot;group&amp;quot; as being invalid region names.  secondlife://agent/&amp;lt;agent_id&amp;gt; looks cleaner to me than secondlife://app/...&lt;br /&gt;
&lt;br /&gt;
Without slclient://, all these links are working now.  Do we really want slclient://?  Also, our entire system for places/events/top picks currently stores only parcel ids.  I&#039;m not thrilled about embarking on a huge refactoring of this system just to get search to work.&lt;br /&gt;
&lt;br /&gt;
[[User:James|James]] 10:56, 24 July 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Non-Standard ==&lt;br /&gt;
&lt;br /&gt;
Bah!  I can&#039;t believe I didn&#039;t notice this before: Our syntax doesn&#039;t follow the recommended syntax for path based URI schemes!  It should start with &amp;lt;b&amp;gt;three&amp;lt;/b&amp;gt; slashes, not two, like file: does.  This is because the thing after the double slash is the &amp;lt;i&amp;gt;authority&amp;lt;/i&amp;gt; section, containing a hostname and port (and other stuff optionally as well...).&lt;br /&gt;
&lt;br /&gt;
It might be worse - depending on one&#039;s reading of section 3 of RFC 3986, our use of double slashes without an authority section could be seen as illegal.  Of course, we &amp;lt;i&amp;gt;could&amp;lt;/i&amp;gt; claim that the region name or &amp;quot;app&amp;quot; was the authority (and hence host).... but I bet w don&#039;t follow all the proper conventions for host names.   Fie!&lt;br /&gt;
&lt;br /&gt;
See http://tools.ietf.org/html/rfc3986&lt;br /&gt;
&lt;br /&gt;
[[User:ZeroLinden|ZeroLinden]] 15:33, 6 September 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;James writes:&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looks like &amp;lt;code&amp;gt;secondlife:///&amp;lt;/code&amp;gt; is what we want.  My only concern would be&lt;br /&gt;
that crappy IRC clients and other programs that attempt to automatically&lt;br /&gt;
identify URLs in text would choke.  Colloquy does it correctly.  I will&lt;br /&gt;
try other clients in the office tomorrow.&lt;br /&gt;
&lt;br /&gt;
Changing to &amp;lt;code&amp;gt;secondlife:///&amp;lt;/code&amp;gt; is trivial in my code.  Any reason I&lt;br /&gt;
shouldn&#039;t just do it?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Well, we have to continue to handle the existant URLs.  So perhaps we take this moment to &amp;quot;fix&amp;quot; the whole scheme:&lt;br /&gt;
&lt;br /&gt;
 secondlife://&amp;lt;region name&amp;gt;/&amp;lt;x&amp;gt;/&amp;lt;y&amp;gt;/&amp;lt;z&amp;gt;&lt;br /&gt;
  -- old style, still accepted&lt;br /&gt;
 &lt;br /&gt;
 secondlife:///viewer/go/&amp;lt;region name/&amp;lt;x&amp;gt;/&amp;lt;y&amp;gt;/&amp;lt;z&amp;gt;&lt;br /&gt;
  -- new style, with well defined rules about encoding region names&lt;br /&gt;
 &lt;br /&gt;
 secondlife:///viewer/agent/&amp;lt;agent_id&amp;gt;&lt;br /&gt;
 secondlife:///viewer/group/&amp;lt;group_id&amp;gt;&lt;br /&gt;
  -- etc., the controls being added for search&lt;br /&gt;
  -- (that these are an implicit &amp;quot;open a floater on this item&amp;quot; verb is a little odd,&lt;br /&gt;
   what&#039;s the URL for &amp;quot;IM this line of text to this agent&amp;quot;?)&lt;br /&gt;
 &lt;br /&gt;
 secondlife:///viewer/login/...&lt;br /&gt;
  -- the login work for web site auth.&lt;br /&gt;
&lt;br /&gt;
[[User:ZeroLinden|ZeroLinden]] 08:57, 7 September 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I will of course support legacy URLs.  I see no strong reason to switch from &amp;quot;app&amp;quot; to &amp;quot;viewer&amp;quot;.  Likewise, my initial syntax for agents/groups/etc. is of the form:&lt;br /&gt;
&lt;br /&gt;
  secondlife:///app/agent/&amp;lt;agent_id&amp;gt;/about&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;about&amp;quot; is the verb.  Thus we can add &amp;quot;im&amp;quot;, &amp;quot;offer-teleport&amp;quot;, etc.&lt;br /&gt;
&lt;br /&gt;
Any reason I should not just implement secondlife:///app/agent/&amp;lt;agent_id&amp;gt;/about ?&lt;br /&gt;
&lt;br /&gt;
[[User:James|James]] 09:57, 7 September 2007 (PDT)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=47887</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=47887"/>
		<updated>2008-01-09T01:12:16Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: {{ProtocolNav}} aka Viewer URL Namespace  aka SLAPP URLs  Category: Name Spaces Category: Search  The SL client supports links of the format secondlife://Region/123/45/67/, which h...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login&lt;br /&gt;
*** log in on launch&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /help &#039;&#039;open F1 help floater&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Secondlife://_URL_scheme&amp;diff=47885</id>
		<title>Secondlife:// URL scheme</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Secondlife://_URL_scheme&amp;diff=47885"/>
		<updated>2008-01-09T01:09:22Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page answers the question, &amp;quot;How does the secondlife:// URL scheme work?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For details on special secondlife:///app/ URLs that control the user interface for login and search, see [[Viewer URI Name Space]]&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
The Second Life client utilizes the windows registry to tell the browser which application to launch when it sees secondlife:// as the prefix to a URL.  During installation of the client, if the channel is &amp;quot;Second Life Release&amp;quot; (the default channel for the client) and the grid the client is installed for is &amp;quot;agni&amp;quot;, the register entry is replaced with the path to the executable.  The register entry states that whenever a browser sees secondlife:// that particular installation of the Second Life client is invoked with the arguments -url &amp;lt;URL&amp;gt;.&lt;br /&gt;
=== No Client is Running ===&lt;br /&gt;
When there is no client already running, the executed client will parse the -url argument and execute according to how it is parsed.&lt;br /&gt;
=== There is already a Client Running ===&lt;br /&gt;
The client looks to see if any applications running with the class name (specific to windows) &amp;quot;Second Life&amp;quot; is up.  If so, it serializes the &amp;lt;URL&amp;gt; and sends it across the other client.&lt;br /&gt;
&lt;br /&gt;
== Macintosh ==&lt;br /&gt;
The Mac client registers a GURL handler as soon as the Second Life Application is dragged from another volume onto your startup volume.&lt;br /&gt;
=== No Client is Running ===&lt;br /&gt;
That client will be launched and its GURL handler will handle the GURL event issued by the operating system.&lt;br /&gt;
=== There is already a Client Running and it&#039;s the GURL Client ===&lt;br /&gt;
The client will handle the GURL event&lt;br /&gt;
=== There is already a Client Running and it&#039;s *not* the GURL Client ===&lt;br /&gt;
The GURL client will be launched and it will fail with the message &amp;quot;Another instance of Second Life is running.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Linux ==&lt;br /&gt;
Coming soon!&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Secondlife://_URL_scheme&amp;diff=47884</id>
		<title>Secondlife:// URL scheme</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Secondlife://_URL_scheme&amp;diff=47884"/>
		<updated>2008-01-09T01:08:27Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOCright}}&lt;br /&gt;
This wiki page answers the question, &amp;quot;How does the secondlife:// URL scheme work?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For details on special secondlife:///app/ URLs that control the user interface for login and search, see [[Viewer URI Name Space]]&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
The Second Life client utilizes the windows registry to tell the browser which application to launch when it sees secondlife:// as the prefix to a URL.  During installation of the client, if the channel is &amp;quot;Second Life Release&amp;quot; (the default channel for the client) and the grid the client is installed for is &amp;quot;agni&amp;quot;, the register entry is replaced with the path to the executable.  The register entry states that whenever a browser sees secondlife:// that particular installation of the Second Life client is invoked with the arguments -url &amp;lt;URL&amp;gt;.&lt;br /&gt;
=== No Client is Running ===&lt;br /&gt;
When there is no client already running, the executed client will parse the -url argument and execute according to how it is parsed.&lt;br /&gt;
=== There is already a Client Running ===&lt;br /&gt;
The client looks to see if any applications running with the class name (specific to windows) &amp;quot;Second Life&amp;quot; is up.  If so, it serializes the &amp;lt;URL&amp;gt; and sends it across the other client.&lt;br /&gt;
&lt;br /&gt;
== Macintosh ==&lt;br /&gt;
The Mac client registers a GURL handler as soon as the Second Life Application is dragged from another volume onto your startup volume.&lt;br /&gt;
=== No Client is Running ===&lt;br /&gt;
That client will be launched and its GURL handler will handle the GURL event issued by the operating system.&lt;br /&gt;
=== There is already a Client Running and it&#039;s the GURL Client ===&lt;br /&gt;
The client will handle the GURL event&lt;br /&gt;
=== There is already a Client Running and it&#039;s *not* the GURL Client ===&lt;br /&gt;
The GURL client will be launched and it will fail with the message &amp;quot;Another instance of Second Life is running.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Linux ==&lt;br /&gt;
Coming soon!&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=34626</id>
		<title>Adding a dialog</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=34626"/>
		<updated>2007-10-07T16:42:04Z</updated>

		<summary type="html">&lt;p&gt;James Linden: How to add file to linux build system&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox|parent=Viewer architecture}}&lt;br /&gt;
[[Category:Viewer Architecture]]&lt;br /&gt;
&lt;br /&gt;
Windows and dialogs in Second Life are implemented as LLFloater objects.  The class hierarchy is:&lt;br /&gt;
&lt;br /&gt;
 LLFloaterFoo - a &amp;quot;foo&amp;quot; dialog&lt;br /&gt;
 LLFloater - generic window or dialog with close box, minimize box, etc.&lt;br /&gt;
 LLPanel - rectangular area with dark background, has functions like childSetText(), childGetValue()&lt;br /&gt;
 LLUICtrl - any widget that can take keyboard focus&lt;br /&gt;
 LLView - base class, container for UI widget children&lt;br /&gt;
&lt;br /&gt;
Create a new C++ header and source file to hold your new class.  By convention these are called llfloaterfoo.h and .cpp.  Place them in the newview directory.&lt;br /&gt;
&lt;br /&gt;
Make the build system aware of your new files:&lt;br /&gt;
* Windows - add to Visual Studio &amp;quot;newview&amp;quot; project file&lt;br /&gt;
* Mac - add to macview.xcodeproj file&lt;br /&gt;
* Linux - add a line referencing the only the cpp file to newview/files.lst&lt;br /&gt;
&lt;br /&gt;
You&#039;ll also need a new XML description file.  These are found in the indra/newview/skins/xui/en-us directory.  It&#039;s easiest to copy an existing file and modify it.  Name the new file floater_foo.xml.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039; - Second Life UI uses OpenGL coordinates, so 0,0 is at the &#039;&#039;&#039;bottom&#039;&#039;&#039; left corner.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s make a floater that has a text label &amp;quot;bar&amp;quot;, a text line input field &amp;quot;baz&amp;quot;, and a button &amp;quot;hippo&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A basic floater header looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;llfloater.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class LLFloaterFoo : public LLFloater&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    LLFloaterFoo();&lt;br /&gt;
&lt;br /&gt;
    virtual ~LLFloaterFoo();&lt;br /&gt;
&lt;br /&gt;
    // by convention, this shows the floater and does instance management&lt;br /&gt;
    static void show(void*);&lt;br /&gt;
 &lt;br /&gt;
private:&lt;br /&gt;
    // when a line editor loses keyboard focus, it is committed.&lt;br /&gt;
    // commit callbacks are named onCommitWidgetName by convention.&lt;br /&gt;
    static void onCommitBaz(LLUICtrl* ctrl, void *userdata);&lt;br /&gt;
 &lt;br /&gt;
    // by convention, button callbacks are named onClickButtonLabel&lt;br /&gt;
    static void onClickHippo(void* userdata);&lt;br /&gt;
 &lt;br /&gt;
    // no pointers to widgets here - they are referenced by name&lt;br /&gt;
&lt;br /&gt;
    //assuming we just need one, which is typical&lt;br /&gt;
    static LLFloaterFoo* sInstance;&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The XML data definition should look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;!-- All our XML is utf-8 encoded. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Floaters can optionally have their titlebar drag handle on the left.&lt;br /&gt;
     If so, the title is not visible.&lt;br /&gt;
     When a floater is resizable, a min_width and min_height must be specified. --&amp;gt;&lt;br /&gt;
&amp;lt;floater&lt;br /&gt;
	name=&amp;quot;foo_floater&amp;quot;&lt;br /&gt;
	title=&amp;quot;Foo&amp;quot;&lt;br /&gt;
	can_resize=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_minimize=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_close=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_drag_on_left=&amp;quot;false&amp;quot;&lt;br /&gt;
	width=&amp;quot;275&amp;quot;&lt;br /&gt;
	height=&amp;quot;250&amp;quot;&lt;br /&gt;
	min_width=&amp;quot;80&amp;quot;&lt;br /&gt;
	min_height=&amp;quot;220&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 By convention text fields are suffixed with _text.&lt;br /&gt;
 Common fonts include SansSerif and SansSerifSmall. See LLFontGL::fontFromName for more.&lt;br /&gt;
 Positions may be in absolute coordinates or as deltas.&lt;br /&gt;
 bottom_delta = -40 indicates 40 pixels from the top edge.&lt;br /&gt;
 follows indicates how the widget should move when the container is resized.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;text name=&amp;quot;bar_text&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerifSmall&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-40&amp;quot;&lt;br /&gt;
		width=&amp;quot;260&amp;quot;&lt;br /&gt;
		height=&amp;quot;16&amp;quot;&lt;br /&gt;
                follows=&amp;quot;left|top&amp;quot;&lt;br /&gt;
		&amp;gt;&lt;br /&gt;
bar is a generic programming identifier&lt;br /&gt;
	&amp;lt;/text&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
  Line editor names end in _edit by convention.&lt;br /&gt;
  mouse_opaque means it blocks mouse clicks, rather than passing on to underlying view&lt;br /&gt;
  max_length is in bytes, not Unicode characters&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;line_editor&lt;br /&gt;
		name=&amp;quot;baz_edit&amp;quot;&lt;br /&gt;
		width=&amp;quot;120&amp;quot;&lt;br /&gt;
		height=&amp;quot;20&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-30&amp;quot;&lt;br /&gt;
		follows=&amp;quot;left|bottom&amp;quot;&lt;br /&gt;
		hidden=&amp;quot;false&amp;quot;&lt;br /&gt;
		mouse_opaque=&amp;quot;true&amp;quot;&lt;br /&gt;
		max_length=&amp;quot;31&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerif&amp;quot;&lt;br /&gt;
		bevel_style=&amp;quot;in&amp;quot;&lt;br /&gt;
		border_style=&amp;quot;line&amp;quot;&lt;br /&gt;
		border_thickness=&amp;quot;1&amp;quot;&lt;br /&gt;
		select_all_on_focus_received=&amp;quot;true&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
  Buttons are suffixed with _btn by convention.&lt;br /&gt;
  Note there is no association with a callback function here - it must be connected&lt;br /&gt;
  in the C++ code.&lt;br /&gt;
  bottom_delta here means from the TOP of the last widget, not the bottom.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;button&lt;br /&gt;
		name=&amp;quot;hippo_btn&amp;quot;&lt;br /&gt;
		label=&amp;quot;Hippo&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerifSmall&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-25&amp;quot;&lt;br /&gt;
		width=&amp;quot;100&amp;quot;&lt;br /&gt;
		height=&amp;quot;20&amp;quot;&lt;br /&gt;
		follows=&amp;quot;bottom|left&amp;quot;&lt;br /&gt;
		/&amp;gt;&lt;br /&gt;
&amp;lt;/floater&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The C++ code for this floater looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;llviewerprecompiledheaders.h&amp;quot; // must be first include&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;llfloaterfoo.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;llvieweruictrlfactory.h&amp;quot; // builds floaters from XML&lt;br /&gt;
&lt;br /&gt;
// Statics&lt;br /&gt;
LLFloaterFoo* LLFloaterFoo::sInstance = NULL;&lt;br /&gt;
&lt;br /&gt;
LLFloaterFoo::LLFloaterFoo()&lt;br /&gt;
:   LLFloater(&amp;quot;floater_foo&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    gUICtrlFactory-&amp;gt;buildFloater(this, &amp;quot;floater_foo.xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    childSetCommitCallback(&amp;quot;baz_edit&amp;quot;, onCommitBaz, this);&lt;br /&gt;
&lt;br /&gt;
    childSetAction(&amp;quot;hippo_btn&amp;quot;, onClickHippo, this);&lt;br /&gt;
    setDefaultBtn(&amp;quot;hippo_btn&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// static&lt;br /&gt;
void LLFloaterFoo::show(void*)&lt;br /&gt;
{&lt;br /&gt;
    if (!sInstance)&lt;br /&gt;
	sInstance = new LLFloaterFoo();&lt;br /&gt;
&lt;br /&gt;
    sInstance-&amp;gt;open();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
LLFloaterFoo::~LLFloaterFoo()&lt;br /&gt;
{&lt;br /&gt;
    sInstance=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// static&lt;br /&gt;
void LLFloaterFoo::onCommitBaz(LLUICtrl* ctrl, void* userdata)&lt;br /&gt;
{&lt;br /&gt;
    LLFloaterFoo* self = (LLFloaterFoo*)userdata;&lt;br /&gt;
    LLString text = self-&amp;gt;childGetText(&amp;quot;baz_edit&amp;quot;);&lt;br /&gt;
    llinfos &amp;lt;&amp;lt; &amp;quot;baz contains: &amp;quot; &amp;lt;&amp;lt; text &amp;lt;&amp;lt; llendl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// static&lt;br /&gt;
void LLFloaterFoo::onClickHippo(void* userdata)&lt;br /&gt;
{&lt;br /&gt;
    LLFloaterFoo* self = (LLFloaterFoo*)userdata;&lt;br /&gt;
    llinfos &amp;lt;&amp;lt; &amp;quot;Hippo! from &amp;quot; &amp;lt;&amp;lt; self-&amp;gt;getName() &amp;lt;&amp;lt; llendl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, to test out this floater you&#039;ll need to add a menu item that calls the show() method.  See [[Adding a menu item]].&lt;br /&gt;
&lt;br /&gt;
====Hints:====&lt;br /&gt;
You will need to add &amp;lt;pre&amp;gt;#include &amp;quot;llfloaterfoo.h&amp;quot;&amp;lt;/pre&amp;gt; to the file llviewermenu.cpp.&lt;br /&gt;
The show method is called with the following command: &amp;lt;pre&amp;gt;LLFloaterFoo::show(NULL);&amp;lt;/pre&amp;gt;&lt;br /&gt;
Put that command in the class LLToolsFoo you made in the previous example, [[Adding a menu item]].&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_menu_item&amp;diff=34623</id>
		<title>Adding a menu item</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_menu_item&amp;diff=34623"/>
		<updated>2007-10-07T16:37:41Z</updated>

		<summary type="html">&lt;p&gt;James Linden: Changed to reflect updated initialize_menus() function&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox|parent=Viewer architecture}}&lt;br /&gt;
[[Category:Viewer Architecture]]&lt;br /&gt;
&lt;br /&gt;
Menu items in the viewer are specified in XML files, located in the indra/newview/skins/xui/en-us/ directory.&lt;br /&gt;
&lt;br /&gt;
There are separate XML files for various categories of menu.  They are:&lt;br /&gt;
 menu_viewer.xml - top of screen&lt;br /&gt;
 menu_inventory.xml - right-click on inventory item&lt;br /&gt;
 menu_pie_attachment.xml - right-click on your own attachment&lt;br /&gt;
 menu_pie_avatar.xml - right-click on other avatar or their attachments&lt;br /&gt;
 menu_pie_land.xml - right-click on land&lt;br /&gt;
 menu_pie_self.xml - right-click on your avatar&lt;br /&gt;
&lt;br /&gt;
The menu callbacks are set up in llviewermenu.cpp.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a menu item named &amp;quot;Foo&amp;quot; to the Tools menu.&lt;br /&gt;
* In menu_viewer.xml find the &amp;quot;Tools&amp;quot; menu item.  It is inside a &amp;lt;menu&amp;gt; tag.&lt;br /&gt;
* Tear-off sub menus use the &amp;lt;tearoff_menu&amp;gt; tag.&lt;br /&gt;
* Find the &amp;quot;Reset Scripts in Selection&amp;quot; menu item.&lt;br /&gt;
* After it, add the following text:&lt;br /&gt;
 &amp;lt;menu_item_call label=&amp;quot;Foo&amp;quot; enabled=&amp;quot;true&amp;quot; name=&amp;quot;foo_menu&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;on_click function=&amp;quot;Tools.Foo&amp;quot; userdata=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/menu_item_call&amp;gt;&lt;br /&gt;
* This sets up a menu item that will call a function. It can be referenced in C++ by the name &amp;quot;foo_menu&amp;quot;.  The user-visible label is &amp;quot;Foo&amp;quot;.  It defaults to enabled.&lt;br /&gt;
* Open newview/llviewermenu.cpp&lt;br /&gt;
* Create an event handler class for this menu item.  By convention these are named after the menu name and item name.&lt;br /&gt;
 class LLToolsFoo : public view_listener_t&lt;br /&gt;
 {&lt;br /&gt;
     bool handleEvent(LLPointer&amp;lt;LLEvent&amp;gt; event, const LLSD&amp;amp; userdata)&lt;br /&gt;
     {&lt;br /&gt;
         llinfos &amp;lt;&amp;lt; &amp;quot;foo!&amp;quot; &amp;lt;&amp;lt; llendl;&lt;br /&gt;
         return true;&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
* This class will listen for events from a &amp;quot;view&amp;quot;, the base class for all UI widgets.  LLPointer is a reference counting smart pointer.  LLSD is a structured data class similar to a Perl or Python variable - it can hold data of any type.&lt;br /&gt;
* llinfos is the output stream for informational messages.  It goes to the ctrl-shift-4 debug console, stdout, and the log file.&lt;br /&gt;
&lt;br /&gt;
* Now associate the &amp;quot;Tools.Foo&amp;quot; function with a C++ class.  Open newview/llviewermenu.cpp.&lt;br /&gt;
* In the function initialize_menus() add the line:&lt;br /&gt;
 addMenu(new LLToolsFoo(), &amp;quot;Tools.Foo&amp;quot;);&lt;br /&gt;
* This associates your listener with the &amp;quot;Tools.Foo&amp;quot; event.&lt;br /&gt;
&lt;br /&gt;
If you added a new source file to implement your new dialog, be sure to include it in newview/files.lst so the build system is aware of it.&lt;br /&gt;
&lt;br /&gt;
Compile and run!&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_Architecture&amp;diff=33187</id>
		<title>Viewer Architecture</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_Architecture&amp;diff=33187"/>
		<updated>2007-09-27T18:14:21Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Learn by Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
[[Category:Viewer Architecture]]&lt;br /&gt;
&lt;br /&gt;
The Second Life client (also known as the &amp;quot;viewer&amp;quot;) is a complex piece of software. It can be visualized as a streaming media client like RealPlayer, a game engine like Quake 3, or a web browser.&lt;br /&gt;
&lt;br /&gt;
First you&#039;ll need to learn some terminology like &amp;quot;agent&amp;quot;, &amp;quot;sim&amp;quot;, and &amp;quot;region&amp;quot; in the [[glossary]].&lt;br /&gt;
&lt;br /&gt;
== Learn by Example ==&lt;br /&gt;
* [[Adding a menu item]]&lt;br /&gt;
* [[Adding a dialog]]&lt;br /&gt;
* [[Adding a cursor]]&lt;br /&gt;
* [[How movement works]]&lt;br /&gt;
* [[How the camera works]]&lt;br /&gt;
* [[How login works]]&lt;br /&gt;
* [[Hegemons Login Analysis]]&lt;br /&gt;
* [[How keyboard processing works]]&lt;br /&gt;
* [[How scripts work]]&lt;br /&gt;
* [[The lifetime of a session]]&lt;br /&gt;
* [[How preferences work]]&lt;br /&gt;
&lt;br /&gt;
== Major Systems ==&lt;br /&gt;
* [[Asset System]] - transport for animations, sounds, notecards, scripts, etc.&lt;br /&gt;
* [[Avatar Appearance]] - appearance is constructed from a mesh, parameters to deform the mesh, and textures to describe clothing&lt;br /&gt;
* [[Avatar Profiles]]&lt;br /&gt;
* [[Culling]] - octree and occlusion based culling to speed rendering&lt;br /&gt;
* [[Error Logging System]] - command and control of debugging output&lt;br /&gt;
* [[Groups]]&lt;br /&gt;
* [[Image System]] - prioritizes and decodes JPEG2000 images into OpenGL textures&lt;br /&gt;
** [[Texture cache]] - used for reading and writing texture data to the local disk cache &lt;br /&gt;
** [[Image Pipeline]] - fetches textures from the servers and decodes them&lt;br /&gt;
* [[Inventory]] - server-side storage of assets for each user&lt;br /&gt;
* [[L$ System]]&lt;br /&gt;
* [[Message System]] - reliable and unreliable transport over UDP&lt;br /&gt;
* [[Movie System]] - QuickTime-based video on object surfaces&lt;br /&gt;
* [[Muting Objects and Agents]] - How the viewer manages the muted object list &lt;br /&gt;
* [[Rendering System]] - from viewer object to drawable to face to vertices to graphics card&lt;br /&gt;
* [[Selection Manager]] - holds extended information for selected objects and allows editing&lt;br /&gt;
* [[Sound System]] - cross platform audio based on FMOD&lt;br /&gt;
* [[Tools]] - anything that takes effect when you click your mouse on the world view.&lt;br /&gt;
* [[UI Widgets]] - cross platform buttons, scroll bars, etc.&lt;br /&gt;
* [[UI Floaters]] - dialogs and windows built from XML files&lt;br /&gt;
* [[VFS]] - cached data is held in two &amp;quot;virtual file systems&amp;quot; in large files on the client&lt;br /&gt;
* [[Viewer Object System]] - objects in scene for rendering and editing&lt;br /&gt;
* [[Web Browser]] - the integration of the viewer with the web.&lt;br /&gt;
&lt;br /&gt;
== Threads ==&lt;br /&gt;
The viewer is a single process with a few threads:&lt;br /&gt;
* Main thread -- The input/output main program function (including rendering).&lt;br /&gt;
* VFS thread -- Thread responsible for reading/writing to the local virtual file system.&lt;br /&gt;
* LFS thread -- Thread responsible for some reading/writing to the local native file system.&lt;br /&gt;
** Used by the {{OSWiki|Threaded_Image_Pipeline}} project&lt;br /&gt;
* Image thread -- Thread responsible for requesting and decoding image data&lt;br /&gt;
** Used by the {{OSWiki|Threaded_Image_Pipeline}} project&lt;br /&gt;
* Error Thread -- Thread responsible for catching exceptions, calling the (currently unused?) error handler, and retiring&lt;br /&gt;
* Worker Threads -- Threads designed to do cpu intensive background tasks&lt;br /&gt;
** These threads may be paused during rendering so as not to reduce performance (design in-progress)&lt;br /&gt;
&lt;br /&gt;
== Program Flow ==&lt;br /&gt;
# Initialize - newview/viewer.cpp :: main()&lt;br /&gt;
# Loop  - newview/viewer.cpp :: main_loop()&lt;br /&gt;
#* Gathers  keyboard and mouse input&lt;br /&gt;
#* Pumps the TCP i/o&lt;br /&gt;
#* idle()&lt;br /&gt;
#* Render the frame&lt;br /&gt;
#* let filesystem and worker threads process&lt;br /&gt;
# Shutdown&lt;br /&gt;
One way to see what goes on in the main loop is to bring up the debug menus (Ctrl-Alt-D) then Client-&amp;gt;Consoles-&amp;gt;Fast Timers (or Ctrl-Shift-9) and expand the entries in the caption.&lt;br /&gt;
&lt;br /&gt;
== Sources of Input ==&lt;br /&gt;
* The [[Message System]].&lt;br /&gt;
** Assets through the [[Asset System]], transmitted using the [[Transfer Manager]], and extracted from the [[VFS]].&lt;br /&gt;
** Files through [[Xfer Manager]].&lt;br /&gt;
* Files copied out of a [[VFS]] into local file store and read through c/c++/ll file API.&lt;br /&gt;
* XMLRPC calls such as [[Authentication Flow|login]] and [[Buying Land and Currency]].&lt;br /&gt;
* HTTP GET/POST to the [[Backbone]]. This is not yet in use.&lt;br /&gt;
* Streaming music and videos.&lt;br /&gt;
** Quicktime.&lt;br /&gt;
** FMOD.&lt;br /&gt;
* The web browser.&lt;br /&gt;
&lt;br /&gt;
== User Guides ==&lt;br /&gt;
&lt;br /&gt;
* [[Viewer coordinate frames]].&lt;br /&gt;
* Known [[Client_parameters]]&lt;br /&gt;
* Known Client Parameters on [http://lslwiki.net/lslwiki/wakka.php?wakka=newview&amp;amp;show_comments=1 LSLwiki.net]&lt;br /&gt;
* Known [[defines]]&lt;br /&gt;
* [[Godmode]] - what Lindens can do&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_cursor&amp;diff=33188</id>
		<title>Adding a cursor</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_cursor&amp;diff=33188"/>
		<updated>2007-09-27T18:12:56Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: * Add new entry to enum ECursorType in llwindow.h ** For example, UI_CURSOR_STUFF === Windows === * Create art for Windows ** Go into indra/newview/res ** Duplicate toolopen.cur ** Name ne...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Add new entry to enum ECursorType in llwindow.h&lt;br /&gt;
** For example, UI_CURSOR_STUFF&lt;br /&gt;
=== Windows ===&lt;br /&gt;
* Create art for Windows&lt;br /&gt;
** Go into indra/newview/res&lt;br /&gt;
** Duplicate toolopen.cur&lt;br /&gt;
** Name new file something like toolstuff.cur&lt;br /&gt;
** Visual Studio &amp;gt; View &amp;gt; Resource View&lt;br /&gt;
** Right-click newViewRes.rc &amp;gt; Cursor&lt;br /&gt;
** Add Resource...&lt;br /&gt;
** Import...&lt;br /&gt;
** Select toolstuff.cur&lt;br /&gt;
** Edit the cursor using Visual Studio bitmap tools&lt;br /&gt;
** Open Properties view&lt;br /&gt;
** Click on name IDC_CURSOR_6&lt;br /&gt;
** Rename to &amp;quot;TOOLSTUFF&amp;quot;&lt;br /&gt;
* Link to Windows code&lt;br /&gt;
** Add to llwindowwin32.cpp, LLWindowWin32::initCursors()&lt;br /&gt;
** mCursor[UI_CURSOR_TOOLSTUFF] = loadColorCursor(TEXT(&amp;quot;TOOLSTUFF&amp;quot;));&lt;br /&gt;
=== Mac ===&lt;br /&gt;
* Create art for Mac&lt;br /&gt;
** indra/newview/cursors_mac&lt;br /&gt;
** duplicate UI_CURSOR_TOOLOPEN.tif&lt;br /&gt;
** Save cursor as 32-bit TIFF&lt;br /&gt;
* Link to Mac code&lt;br /&gt;
** Edit llwindowmacosx.cpp cursorIDToName()&lt;br /&gt;
** Add &amp;quot;UI_CURSOR_TOOLSTUFF&amp;quot;&lt;br /&gt;
=== Linux ===&lt;br /&gt;
* Create art for Linux&lt;br /&gt;
** indra/newview/res_sdl&lt;br /&gt;
** duplicate toolopen.BMP&lt;br /&gt;
** save as 24-bit BMP&lt;br /&gt;
** Alpha is color-keyed to 200, 200, 200&lt;br /&gt;
* Link to code&lt;br /&gt;
** Edit llwindowsdl.cpp LLWindowSDL::initCursors()&lt;br /&gt;
** mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP(&amp;quot;toolplay.BMP&amp;quot;,0,0);&lt;br /&gt;
** Hot-spot is hard-coded in above function call&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Mouse_Navigation&amp;diff=31392</id>
		<title>Mouse Navigation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Mouse_Navigation&amp;diff=31392"/>
		<updated>2007-09-13T18:23:52Z</updated>

		<summary type="html">&lt;p&gt;James Linden: New page: For a while I&amp;#039;ve been thinking about how to make SL easier for new users to navigate.  In some user tests (circa 2005) I observed several users trying what I call &amp;quot;coffee cup&amp;quot; navigation -...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For a while I&#039;ve been thinking about how to make SL easier for new users to navigate.  In some user tests (circa 2005) I observed several users trying what I call &amp;quot;coffee cup&amp;quot; navigation -- hold something in their left hand and try to navigate SL using just the mouse.&lt;br /&gt;
&lt;br /&gt;
This doesn&#039;t work for several reasons.&lt;br /&gt;
* Click-drag on avatar rotates camera, but doesn&#039;t move it.&lt;br /&gt;
* Arrow keys are on the right edge of the keyboard, meaning right handed users move their right hand back and forth between arrow keys and mouse.&lt;br /&gt;
* Users new to 3D environments don&#039;t discover AWSD navigation.&lt;br /&gt;
* Once they discover AWSD navigation they make frequent errors with typing navigation input into chat and vice versa.&lt;br /&gt;
* Alt-Zoom requires two-handed control, yet is important for getting good views of many pieces of content.&lt;br /&gt;
&lt;br /&gt;
== Proposed Mouse Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== Primary Navigation ===&lt;br /&gt;
* Left click on avatar walks forward&lt;br /&gt;
* Drag left turns left, drag right turns right&lt;br /&gt;
* Drag slightly back stops walking&lt;br /&gt;
* Drag more back walks backward&lt;br /&gt;
* Drag forward starts running&lt;br /&gt;
&lt;br /&gt;
To help users discover this:&lt;br /&gt;
* Hovering over your avatar changes cursor to special &amp;quot;walking&amp;quot; icon&lt;br /&gt;
* When mouse is down on avatar, transparent arrows appear on screen representing forward/back/turn with the currently active arrow highlighted&lt;br /&gt;
* Arrows surround cursor position, suggesting dragging towards the one you want&lt;br /&gt;
* Of course, arrows can be turned off by advanced users&lt;br /&gt;
&lt;br /&gt;
=== Flying ===&lt;br /&gt;
* Flying is hard because the mouse is a 2D input device, but flying is 3D&lt;br /&gt;
* Maybe just navigate in 2D, with on-screen widgets to go up and down?&lt;br /&gt;
&lt;br /&gt;
=== Alt-Zoom ===&lt;br /&gt;
* Show explicit &amp;quot;tool&amp;quot; icons in the toolbar for arrow vs. zoom vs. orbit&lt;br /&gt;
* Holding down Alt highlights the zoom icon&lt;br /&gt;
* Mouse wheel switches between tools&lt;br /&gt;
** Thus you can both move avatar and move camera using only a wheel mouse&lt;br /&gt;
* Tool tip for zoom and orbit icons shows keyboard shortcuts&lt;br /&gt;
&lt;br /&gt;
=== Go To Point ===&lt;br /&gt;
* This is hard because the most interesting place to walk is right in front of you, which you can&#039;t click because the avatar is in the way&lt;br /&gt;
* Double-click on ground does a stupid walk-to-point autopilot&lt;br /&gt;
* Users can tag objects as being &amp;quot;walls&amp;quot;&lt;br /&gt;
* Double-clicking a &amp;quot;wall&amp;quot; walks toward it&lt;br /&gt;
* Auto-pilot doesn&#039;t try to walk around objects.  It turns off if it gets stuck.&lt;br /&gt;
* Auto-pilot is driven by the server, so motion is smooth in the face of network latency&lt;br /&gt;
&lt;br /&gt;
=== Object Selection ===&lt;br /&gt;
* Right now you must do right-click of objects to select them and issue a command&lt;br /&gt;
* This limits the commands to what fits in the right-click menu&lt;br /&gt;
* For non-wall objects:&lt;br /&gt;
** Single click selects and shows highlight&lt;br /&gt;
** Objects can specify an &amp;quot;info window&amp;quot; to appear on the edge of the screen&lt;br /&gt;
** Info window can contain:&lt;br /&gt;
*** Picture&lt;br /&gt;
*** Buttons that issue chat commands to a script in the object&lt;br /&gt;
*** HTML page?&lt;br /&gt;
*** Information about creator/owner/script status, etc.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User_Interface_Improvements&amp;diff=31389</id>
		<title>User Interface Improvements</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User_Interface_Improvements&amp;diff=31389"/>
		<updated>2007-09-13T18:03:11Z</updated>

		<summary type="html">&lt;p&gt;James Linden: /* Movement components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes a proposed project to design and implement an improved User Interface for the Second Life Viewer. The intention of posting this proposal to the Wiki is to increase transparency by including Residents in the project definition and design.&lt;br /&gt;
&lt;br /&gt;
=== Project Goal ===&lt;br /&gt;
&lt;br /&gt;
The Second Life Viewer is a complex, multi-layered application, consisting of many sub-systems (such as Inventory, Building, Scripting). The current user interface (UI) is intimidating to new users and cumbersome even for power users. The goal of this project is to create a new Viewer UI that is less intimidating for new users yet still flexible enough for power users. The design objective is to improve access to frequently-used features while exposing advanced functionality in a task- or context-sensitive manner. Specific goals include:&lt;br /&gt;
&lt;br /&gt;
* Eliminate the current menu system as the primary mechanism for accessing features&lt;br /&gt;
* Minimize the amount of UI &amp;quot;chrome&amp;quot; displayed at any given time to provide an uninterrupted view of the Second Life world&lt;br /&gt;
* Improve users&#039; ability to learn and use avatar and camera movement controls&lt;br /&gt;
&lt;br /&gt;
=== Project Scope ===&lt;br /&gt;
&lt;br /&gt;
Recognizing that it is not feasible to address usability issues across the full range of the Viewer&#039;s sub-systems in the course of a single project, this project is limited to re-organizing existing Viewer functionality. Insofar as possible, the project will not affect the following:&lt;br /&gt;
&lt;br /&gt;
* Existing &amp;quot;sub-applications&amp;quot; (Inventory, Search, Map, etc)&lt;br /&gt;
* Design and behavior of child windows (&amp;quot;floaters&amp;quot;)&lt;br /&gt;
* Pop-up notification system&lt;br /&gt;
* &amp;quot;Out of box&amp;quot; experience (registration, download, orientation)&lt;br /&gt;
&lt;br /&gt;
Visual design will be limited to new functionality as outlined below and should conform to the latest art assets and color palettes.&lt;br /&gt;
&lt;br /&gt;
=== Proposed Solution ===&lt;br /&gt;
&lt;br /&gt;
We propose a browser-like concept which has regions of the screen (&amp;quot;zones of control&amp;quot;) that summon UI when the user moves the mouse to that area. The UI in these regions could be fixed using a gesture (such as a pushpin) or autohide such that they only appear when summoned. The preliminary design has five zones: Navigation, Search/Status, Communication, Movement, and Tools (for accessing the rest of the SL sub-applications - Inventory, Appearance, Map, Preferences, etc).&lt;br /&gt;
&lt;br /&gt;
The concept is illustrated in this high-level mockup (note that the mockup is not intended to illustrate actual visual design or intended functionality):&lt;br /&gt;
&lt;br /&gt;
[[Image:ZonesConcept.jpg|thumb|none|600px|Mockup of proposed design]]&lt;br /&gt;
&lt;br /&gt;
=== Required Design &amp;amp; Development Work ===&lt;br /&gt;
&lt;br /&gt;
===== Preliminary design tasks =====&lt;br /&gt;
* Stakeholder interviews/discovery&lt;br /&gt;
* User research/ethnography&lt;br /&gt;
* Personas/scenarios (as appropriate)&lt;br /&gt;
* Information architecture design&lt;br /&gt;
&lt;br /&gt;
===== General components =====&lt;br /&gt;
* Interaction design for auto-hiding &amp;amp; pinning UI elements&lt;br /&gt;
* Visual design of pinning affordance&lt;br /&gt;
* Implementation of auto-hide behavior and pinning UI controls&lt;br /&gt;
&lt;br /&gt;
===== Navigation components =====&lt;br /&gt;
* Interaction design for navigating between recent locations (History)&lt;br /&gt;
* Interaction design for bookmarking/organizing locations (Landmarks)&lt;br /&gt;
* Visual design of Navigation panel&lt;br /&gt;
** Back/Forward controls&lt;br /&gt;
** Location bar, region/parcel name, rating, etc&lt;br /&gt;
** Landmarks UI&lt;br /&gt;
* Implementation of History features&lt;br /&gt;
* Implementation of Landmarks features&lt;br /&gt;
&lt;br /&gt;
===== Search/Status components =====&lt;br /&gt;
* Interaction design for Search bar (mostly complete)&lt;br /&gt;
* Visual design of Search/Status panel&lt;br /&gt;
** Search bar/icon&lt;br /&gt;
** Help button&lt;br /&gt;
** Visual design of status information (L$ balance, time, parcel state, etc)&lt;br /&gt;
* Implementation of overall panel layout&lt;br /&gt;
&lt;br /&gt;
===== Communication components =====&lt;br /&gt;
* Interaction design for expanding in-world chat into full-featured chat console&lt;br /&gt;
* Visual design of panel and related elements&lt;br /&gt;
* Implementation of panel layout and new UI affordances (as required)&lt;br /&gt;
&lt;br /&gt;
===== Movement components =====&lt;br /&gt;
* Interaction design for on-screen controls for moving avatar and camera&lt;br /&gt;
* Visual design of on-screen controls for each mode (walk, fly, camera)&lt;br /&gt;
* Implementation of on-screen movement panel and controls&lt;br /&gt;
* Possibility of purely mouse-driven [[Mouse Navigation]]&lt;br /&gt;
&lt;br /&gt;
===== Tools/extensibility component =====&lt;br /&gt;
* Interaction design of mechanism for accessing tools as required by the user&lt;br /&gt;
* Visual design of minimized/hidden tools and expand/collapse affordances&lt;br /&gt;
* Implementation of UI behavior&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:Inventory_UI_Design&amp;diff=15366</id>
		<title>Talk:Inventory UI Design</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:Inventory_UI_Design&amp;diff=15366"/>
		<updated>2007-03-12T23:40:20Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I think the initial interface should not require the use of nested folders.  I&#039;d rather have a dialog that listed all my outfits and had buttons with the common operations to perform on each one.  Creating nested folders is an advanced user operation.&lt;br /&gt;
&lt;br /&gt;
Witness Microsoft and Apple&#039;s recent Save As... dialogs.  Apple defaults you to selecting a name for the file and one item from a menu of recent destination directories, defaulting to the Documents folder.&lt;br /&gt;
&lt;br /&gt;
[[User:James Linden|James Linden]] 16:40, 12 March 2007 (PDT)&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=How_the_camera_works&amp;diff=12314</id>
		<title>How the camera works</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=How_the_camera_works&amp;diff=12314"/>
		<updated>2007-02-22T05:33:15Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ViewerArchNav}}&lt;br /&gt;
&lt;br /&gt;
The viewer is authoritative about camera position.  The server uses the client&#039;s reported camera position to decide which objects to transmit to the client.&lt;br /&gt;
&lt;br /&gt;
Second Life uses a different coordinate frame than OpenGL.  Our frame is X-at, Y-right, Z-up.&lt;br /&gt;
&lt;br /&gt;
The viewer camera is implemented in newview/llviewercamera.cpp based on llmath/llcamera.cpp.&lt;br /&gt;
&lt;br /&gt;
The camera position and look-at vector is transmitted by send_agent_update() in llviewermessage.cpp.  This function is called once per frame and can transmit packets up to 20 times per second.  Note that it does not transmit unless the agent or camera position or rotation have changed.&lt;br /&gt;
&lt;br /&gt;
Camera movement can be accomplished with the keyboard (Ctrl-Alt-AWSD) or mouse (Alt-drag).  Movement commands call into LLAgent::cameraOrbitAround() and similar functions.  This accumulates motion and rotation through the frame.&lt;br /&gt;
&lt;br /&gt;
The camera has several &amp;quot;modes&amp;quot;, including third person, first person (&amp;quot;mouselook&amp;quot;), appearance editing, etc.  These are managed in LLAgent, not LLViewerCamera.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=How_the_camera_works&amp;diff=1797</id>
		<title>How the camera works</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=How_the_camera_works&amp;diff=1797"/>
		<updated>2006-11-04T00:52:28Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The viewer is authoritative about camera position.  The server uses the client&#039;s reported camera position to decide which objects to transmit to the client.&lt;br /&gt;
&lt;br /&gt;
Second Life uses a different coordinate frame than OpenGL.  Our frame is Z-at, X-up, Y-right.&lt;br /&gt;
&lt;br /&gt;
The viewer camera is implemented in newview/llviewercamera.cpp based on llmath/llcamera.cpp.&lt;br /&gt;
&lt;br /&gt;
The camera position and look-at vector is transmitted by send_agent_update() in llviewermessage.cpp.  This function is called once per frame and can transmit packets up to 20 times per second.  Note that it does not transmit unless the agent or camera position or rotation have changed.&lt;br /&gt;
&lt;br /&gt;
Camera movement can be accomplished with the keyboard (alt-AWSD) or mouse (Alt-drag).  Movement commands call into LLAgent::cameraOrbitAround() and similar functions.  This accumulates motion and rotation through the frame.&lt;br /&gt;
&lt;br /&gt;
The camera has several &amp;quot;modes&amp;quot;, including third person, first person (&amp;quot;mouselook&amp;quot;), appearance editing, etc.  These are managed in LLAgent, not LLViewerCamera.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=How_movement_works&amp;diff=1796</id>
		<title>How movement works</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=How_movement_works&amp;diff=1796"/>
		<updated>2006-11-04T00:00:06Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox|parent=Viewer architecture}}&lt;br /&gt;
The server is authoritative about agent position.  The client is authoritative about camera position and rotation.&lt;br /&gt;
&lt;br /&gt;
The viewer sends an upstream packet up to 20 times per second with information about movement keys (forward, backward, up, down).  The message is named &amp;quot;AgentUpdate&amp;quot; and contains a U32 &amp;quot;ControlFlags&amp;quot;.  The control flag constants are in llagentconstants.h.&lt;br /&gt;
&lt;br /&gt;
The agent is physically simulated on the simulator as a vertically stretched sphere.  It is moved by application of impulses.  In order to impart velocity with brief keypresses the viewer first sends a &amp;quot;nudge&amp;quot;, then the normal key press.  See AGENT_CONTROL_NUDGE_AT_POS.&lt;br /&gt;
&lt;br /&gt;
The agent can be moved with the arrow keys or with ASWD when the chat bar is closed.  The viewer maintains its own view of which keys are down during any particular frame.  This is maintained in LLKeyboard (llkeyboard.cpp).&lt;br /&gt;
&lt;br /&gt;
Every frame, LLKeyboard::scanKeys() is called, resulting in calls to functions like agent_push_forward() in llviewerkeyboard.cpp.  The key to function mapping is provided in the file app_settings/keys.ini.  These functions set variables in LLAgent indicating what keys have been pushed that frame by calling functions like LLAgent::moveAt() or LLAgent::moveYaw().  This sets an internal mControlFlags mask.&lt;br /&gt;
&lt;br /&gt;
Once per frame, send_agent_update() in llviewermessage.cpp is called.  This constructs the complete set of control flags for the agent and, if different, transmits the new set to the server.  The server then handles computation of current position and transmits the position back through the ObjectUpdate pathway used for all object position transmission.&lt;br /&gt;
&lt;br /&gt;
Note that agent positions are velocity and acceleration interpolated, so if there is a delay in network transmission the agent may appear to move through a wall or floor.  The client does not perform collision detection.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=How_movement_works&amp;diff=1795</id>
		<title>How movement works</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=How_movement_works&amp;diff=1795"/>
		<updated>2006-11-03T23:25:07Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The server is authoritative about agent position.  The client is authoritative about camera position and rotation.&lt;br /&gt;
&lt;br /&gt;
The viewer sends an upstream packet up to 20 times per second with information about movement keys (forward, backward, up, down).  The message is named &amp;quot;AgentUpdate&amp;quot; and contains a U32 &amp;quot;ControlFlags&amp;quot;.  The control flag constants are in llagentconstants.h.&lt;br /&gt;
&lt;br /&gt;
The agent is physically simulated on the simulator as a vertically stretched sphere.  It is moved by application of impulses.  In order to impart velocity with brief keypresses the viewer first sends a &amp;quot;nudge&amp;quot;, then the normal key press.  See AGENT_CONTROL_NUDGE_AT_POS.&lt;br /&gt;
&lt;br /&gt;
The agent can be moved with the arrow keys or with ASWD when the chat bar is closed.  The viewer maintains its own view of which keys are down during any particular frame.  This is maintained in LLKeyboard (llkeyboard.cpp).&lt;br /&gt;
&lt;br /&gt;
Every frame, LLKeyboard::scanKeys() is called, resulting in calls to functions like agent_push_forward() in llviewerkeyboard.cpp.  The key to function mapping is provided in the file app_settings/keys.ini.  These functions set variables in LLAgent indicating what keys have been pushed that frame by calling functions like LLAgent::moveAt() or LLAgent::moveYaw().  This sets an internal mControlFlags mask.&lt;br /&gt;
&lt;br /&gt;
Once per frame, send_agent_update() in llviewermessage.cpp is called.  This constructs the complete set of control flags for the agent and, if different, transmits the new set to the server.  The server then handles computation of current position and transmits the position back through the ObjectUpdate pathway used for all object position transmission.&lt;br /&gt;
&lt;br /&gt;
Note that agent positions are velocity and acceleration interpolated, so if there is a delay in network transmission the agent may appear to move through a wall or floor.  The client does not perform collision detection.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Server_architecture&amp;diff=1794</id>
		<title>Server architecture</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Server_architecture&amp;diff=1794"/>
		<updated>2006-11-03T22:40:06Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
&lt;br /&gt;
This wiki is mainly focused on the viewer, since that is the portion of the system that is open source.  However, because the viewer interacts with the Second Life servers in somewhat complicated ways, it is helpful to have an understanding of what components do what on the server side.&lt;br /&gt;
&lt;br /&gt;
Much of what you&#039;ll need to understand is actually covered in the [[protocol|protocol documentation]].  In particular, take a look at [[Authentication Flow]], which outlines the process by which the viewer establishes connections with a number of components.&lt;br /&gt;
&lt;br /&gt;
==== login server ====&lt;br /&gt;
CGI script running on login.agni.lindenlab.com.  Handles verification of user name and password.  Determines the login region based on home vs. last location vs. URL specified location.  Finds the simulator process running that region and verifies user is allowed to connect there.  Alerts the simulator to expect a connection.  Informs the viewer of where to connect.&lt;br /&gt;
&lt;br /&gt;
==== userserver ====&lt;br /&gt;
Historically, the user server handled login.  Now it handles instant message sessions, particularly for groups.&lt;br /&gt;
&lt;br /&gt;
==== spaceserver ====&lt;br /&gt;
Handles routing of messages based on grid x,y locations.&lt;br /&gt;
&lt;br /&gt;
==== dataserver ====&lt;br /&gt;
Handles connections to the central database, log database, inventory database(s) and search database(s).  Performs queries on behalf of the simulator process.&lt;br /&gt;
&lt;br /&gt;
==== simulator ====&lt;br /&gt;
The primary SL server process. Each simulator process simulates one 256x256 meter region. As the viewer moves through the world it is handled off from one simulator to another.  It handles storing object state, land parcel state, and terrain height-map state. It performs visibility calculations on objects and land and transmits the data to the client.  It transmits image data in a prioritized queue.  Physics simulation is handled with the Havok physics library.  Chat and instant messages are processed here.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Server_architecture&amp;diff=1793</id>
		<title>Server architecture</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Server_architecture&amp;diff=1793"/>
		<updated>2006-11-03T22:39:16Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
&lt;br /&gt;
This wiki is mainly focused on the viewer, since that is the portion of the system that is open source.  However, because the viewer interacts with the Second Life servers in somewhat complicated ways, it is helpful to have an understanding of what components do what on the server side.&lt;br /&gt;
&lt;br /&gt;
Much of what you&#039;ll need to understand is actually covered in the [[protocol|protocol documentation]].  In particular, take a look at [[Authentication Flow]], which outlines the process by which the viewer establishes connections with a number of components.&lt;br /&gt;
&lt;br /&gt;
==== login server ====&lt;br /&gt;
CGI script running on login.agni.lindenlab.com.  Handles verification of user name and password.  Determines the login region based on home vs. last location vs. URL specified location.  Finds the simulator process running that region and verifies user is allowed to connect there.  Alerts the simulator to expect a connection.  Informs the viewer of where to connect.&lt;br /&gt;
&lt;br /&gt;
==== userserver ====&lt;br /&gt;
Historically, the user server handled login.  Now it handles instant message sessions, particularly for groups.&lt;br /&gt;
&lt;br /&gt;
==== spaceserver ====&lt;br /&gt;
Handles routing of messages based on grid x,y locations.&lt;br /&gt;
&lt;br /&gt;
=== dataserver ====&lt;br /&gt;
Handles connections to the central database, log database, inventory database(s) and search database(s).  Performs queries on behalf of the simulator process.&lt;br /&gt;
&lt;br /&gt;
==== simulator ====&lt;br /&gt;
The primary SL server process. Each simulator process simulates one 256x256 meter region. As the viewer moves through the world it is handled off from one simulator to another.  It handles storing object state, land parcel state, and terrain height-map state. It performs visibility calculations on objects and land and transmits the data to the client.  It transmits image data in a prioritized queue.  Physics simulation is handled with the Havok physics library.  Chat and instant messages are processed here.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Documentation&amp;diff=1790</id>
		<title>Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Documentation&amp;diff=1790"/>
		<updated>2006-11-03T20:20:42Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
A lot of the documentation below is geared toward developers.  However, many aspects of the system don&#039;t require a deep technical background to learn.  Much of this is still a work in progress, but since this is a wiki, you can help fill in the blanks!&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[Features]]&#039;&#039;&#039; - An overview of the major components of the system as seen from an end user&#039;s perspective.  Links to specifications, test plans and other documentation can be found here.  &lt;br /&gt;
* &#039;&#039;&#039;[[Glossary]]&#039;&#039;&#039; - System terminology&lt;br /&gt;
* &#039;&#039;&#039;[[Viewer architecture]]&#039;&#039;&#039; - Overview of the viewer from a developer&#039;s perspective. &lt;br /&gt;
* &#039;&#039;&#039;[[Protocol]]&#039;&#039;&#039; - In-depth documentation of the protocol.&lt;br /&gt;
* &#039;&#039;&#039;[[Third Party Libraries]]&#039;&#039;&#039; - The third party libraries used by the viewer.&lt;br /&gt;
* &#039;&#039;&#039;[[Server architecture]]&#039;&#039;&#039; - Brief description of server processes with which the viewer communicates.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=1788</id>
		<title>Adding a dialog</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=1788"/>
		<updated>2006-11-03T20:09:41Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox|parent=Viewer architecture}}&lt;br /&gt;
Windows and dialogs in Second Life are implemented as LLFloater objects.  The class hierarchy is:&lt;br /&gt;
&lt;br /&gt;
 LLFloaterFoo - a &amp;quot;foo&amp;quot; dialog&lt;br /&gt;
 LLFloater - generic window or dialog with close box, minimize box, etc.&lt;br /&gt;
 LLPanel - rectangular area with dark background, has functions like childSetText(), childGetValue()&lt;br /&gt;
 LLUICtrl - any widget that can take keyboard focus&lt;br /&gt;
 LLView - base class, container for UI widget children&lt;br /&gt;
&lt;br /&gt;
Create a new C++ header and source file to hold your new class.  By convention these are called llfloaterfoo.h and .cpp.  Place them in the newview directory.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll also need a new XML description file.  These are found in the indra/newview/skins/xui/en-us directory.  It&#039;s easiest to copy an existing file and modify it.  Name the new file floater_foo.xml.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039; - Second Life UI uses OpenGL coordinates, so 0,0 is at the &#039;&#039;&#039;bottom&#039;&#039;&#039; left corner.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s make a floater that has a text label &amp;quot;bar&amp;quot;, a text line input field &amp;quot;baz&amp;quot;, and a button &amp;quot;hippo&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A basic floater header looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;llfloater.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class LLFloaterFoo : public LLFloater&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    LLFloaterFoo();&lt;br /&gt;
&lt;br /&gt;
    // by convention, this shows the floater and does instance management&lt;br /&gt;
    static void show(void*);&lt;br /&gt;
 &lt;br /&gt;
private:&lt;br /&gt;
    // when a line editor loses keyboard focus, it is committed.&lt;br /&gt;
    // commit callbacks are named onCommitWidgetName by convention.&lt;br /&gt;
    void onCommitBaz(LLUICtrl* ctrl, void *userdata);&lt;br /&gt;
 &lt;br /&gt;
    // by convention, button callbacks are named onClickButtonLabel&lt;br /&gt;
    void onClickHippo(void* userdata);&lt;br /&gt;
 &lt;br /&gt;
    // no pointers to widgets here - they are referenced by name&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
The XML data definition should look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;!-- All our XML is utf-8 encoded. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Floaters can optionally have their titlebar drag handle on the left.&lt;br /&gt;
     If so, the title is not visible.&lt;br /&gt;
     When a floater is resizable, a min_width and min_height must be specified. --&amp;gt;&lt;br /&gt;
&amp;lt;floater&lt;br /&gt;
	name=&amp;quot;foo_floater&amp;quot;&lt;br /&gt;
	title=&amp;quot;Foo&amp;quot;&lt;br /&gt;
	can_resize=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_minimize=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_close=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_drag_on_left=&amp;quot;false&amp;quot;&lt;br /&gt;
	width=&amp;quot;275&amp;quot;&lt;br /&gt;
	height=&amp;quot;250&amp;quot;&lt;br /&gt;
	min_width=&amp;quot;80&amp;quot;&lt;br /&gt;
	min_height=&amp;quot;220&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 By convention text fields are suffixed with _text.&lt;br /&gt;
 Common fonts include SansSerif and SansSerifSmall. See LLFontGL::fontFromName for more.&lt;br /&gt;
 Positions may be in absolute coordinates or as deltas.&lt;br /&gt;
 bottom_delta = -40 indicates 40 pixels from the top edge.&lt;br /&gt;
 follows indicates how the widget should move when the container is resized.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;text name=&amp;quot;bar_text&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerifSmall&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-40&amp;quot;&lt;br /&gt;
		width=&amp;quot;260&amp;quot;&lt;br /&gt;
		height=&amp;quot;16&amp;quot;&lt;br /&gt;
                follows=&amp;quot;left|top&amp;quot;&lt;br /&gt;
		&amp;gt;&lt;br /&gt;
bar is a generic programming identifier&lt;br /&gt;
	&amp;lt;/text&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
  Line editor names end in _edit by convention.&lt;br /&gt;
  mouse_opaque means it blocks mouse clicks, rather than passing on to underlying view&lt;br /&gt;
  max_length is in bytes, not Unicode characters&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;line_editor&lt;br /&gt;
		name=&amp;quot;baz_edit&amp;quot;&lt;br /&gt;
		width=&amp;quot;120&amp;quot;&lt;br /&gt;
		height=&amp;quot;20&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-30&amp;quot;&lt;br /&gt;
		follows=&amp;quot;left|bottom&amp;quot;&lt;br /&gt;
		hidden=&amp;quot;false&amp;quot;&lt;br /&gt;
		mouse_opaque=&amp;quot;true&amp;quot;&lt;br /&gt;
		max_length=&amp;quot;31&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerif&amp;quot;&lt;br /&gt;
		bevel_style=&amp;quot;in&amp;quot;&lt;br /&gt;
		border_style=&amp;quot;line&amp;quot;&lt;br /&gt;
		border_thickness=&amp;quot;1&amp;quot;&lt;br /&gt;
		select_all_on_focus_received=&amp;quot;true&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
  Buttons are suffixed with _btn by convention.&lt;br /&gt;
  Note there is no association with a callback function here - it must be connected&lt;br /&gt;
  in the C++ code.&lt;br /&gt;
  bottom_delta here means from the TOP of the last widget, not the bottom.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;button&lt;br /&gt;
		name=&amp;quot;hippo_btn&amp;quot;&lt;br /&gt;
		label=&amp;quot;Hippo&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerifSmall&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-25&amp;quot;&lt;br /&gt;
		width=&amp;quot;100&amp;quot;&lt;br /&gt;
		height=&amp;quot;20&amp;quot;&lt;br /&gt;
		follows=&amp;quot;bottom|left&amp;quot;&lt;br /&gt;
		/&amp;gt;&lt;br /&gt;
&amp;lt;/floater&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The C++ code for this floater looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;llviewerprecompiledheaders.h&amp;quot; // must be first include&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;llfloaterfoo.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;llvieweruictrlfactory.h&amp;quot; // builds floaters from XML&lt;br /&gt;
&lt;br /&gt;
LLFloaterFoo::LLFloaterFoo()&lt;br /&gt;
:   LLFloater(&amp;quot;floater_foo&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    gUICtrlFactory-&amp;gt;buildFloater(this, &amp;quot;floater_foo.xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    childSetCommitCallback(&amp;quot;baz_edit&amp;quot;, onCommitBaz, this);&lt;br /&gt;
&lt;br /&gt;
    childSetAction(&amp;quot;hippo_btn&amp;quot;, onClickHippo, this);&lt;br /&gt;
    setDefaultBtn(&amp;quot;hippo_btn&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// static&lt;br /&gt;
void LLFloaterFoo::show(void*)&lt;br /&gt;
{&lt;br /&gt;
    LLFloaterFoo* self = new LLFloaterFoo();&lt;br /&gt;
    self-&amp;gt;open();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// static&lt;br /&gt;
void LLFloaterFoo::onCommitBaz(LLUICtrl* ctrl, void* userdata)&lt;br /&gt;
{&lt;br /&gt;
    LLFloaterFoo* self = (LLFloaterFoo*)userdata;&lt;br /&gt;
    LLString text = self-&amp;gt;childGetText(&amp;quot;baz_edit&amp;quot;);&lt;br /&gt;
    llinfos &amp;lt;&amp;lt; &amp;quot;baz contains: &amp;quot; &amp;lt;&amp;lt; text &amp;lt;&amp;lt; llendl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// static&lt;br /&gt;
void LLFloaterFoo::onClickHippo(void* userdata)&lt;br /&gt;
{&lt;br /&gt;
    LLFloaterFoo* self = (LLFloaterFoo*)userdata;&lt;br /&gt;
    llinfos &amp;lt;&amp;lt; &amp;quot;Hippo! from &amp;quot; &amp;lt;&amp;lt; self-&amp;gt;getName() &amp;lt;&amp;lt; llendl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, to test out this floater you&#039;ll need to add a menu item that calls the show() method.  See [Adding a menu item].&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=1787</id>
		<title>Adding a dialog</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=1787"/>
		<updated>2006-11-03T18:45:09Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Windows and dialogs in Second Life are implemented as LLFloater objects.  The class hierarchy is:&lt;br /&gt;
&lt;br /&gt;
 LLFloaterFoo - a &amp;quot;foo&amp;quot; dialog&lt;br /&gt;
 LLFloater - generic window or dialog with close box, minimize box, etc.&lt;br /&gt;
 LLPanel - rectangular area with dark background, has functions like childSetText(), childGetValue()&lt;br /&gt;
 LLUICtrl - any widget that can take keyboard focus&lt;br /&gt;
 LLView - base class, container for UI widget children&lt;br /&gt;
&lt;br /&gt;
Create a new C++ header and source file to hold your new class.  By convention these are called llfloaterfoo.h and .cpp.  Place them in the newview directory.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll also need a new XML description file.  These are found in the indra/newview/skins/xui/en-us directory.  It&#039;s easiest to copy an existing file and modify it.  Name the new file floater_foo.xml.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039; - Second Life UI uses OpenGL coordinates, so 0,0 is at the &#039;&#039;&#039;bottom&#039;&#039;&#039; left corner.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s make a floater that has a text label &amp;quot;bar&amp;quot;, a text line input field &amp;quot;baz&amp;quot;, and a button &amp;quot;hippo&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A basic floater header looks like this:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;llfloater.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 class LLFloaterFoo : public LLFloater&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
     LLFloaterFoo();&lt;br /&gt;
     virtual ~LLFloaterFoo();&lt;br /&gt;
 &lt;br /&gt;
     // by convention, this shows the floater and does instance management&lt;br /&gt;
     static void show(void*);&lt;br /&gt;
 &lt;br /&gt;
 private:&lt;br /&gt;
     // when a line editor loses keyboard focus, it is committed.&lt;br /&gt;
     // commit callbacks are named onCommitWidgetName by convention.&lt;br /&gt;
     void onCommitBaz(LLUICtrl* ctrl, void *userdata);&lt;br /&gt;
 &lt;br /&gt;
     // by convention, button callbacks are named onClickButtonLabel&lt;br /&gt;
     void onClickHippo(void* userdata);&lt;br /&gt;
 &lt;br /&gt;
     // no points to widget here - they are referenced by name&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
The XML data definition should look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;!-- All our XML is utf-8 encoded. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Floaters can optionally have their titlebar drag handle on the left.&lt;br /&gt;
     If so, the title is not visible.&lt;br /&gt;
     When a floater is resizable, a min_width and min_height must be specified. --&amp;gt;&lt;br /&gt;
&amp;lt;floater&lt;br /&gt;
	name=&amp;quot;foo_floater&amp;quot;&lt;br /&gt;
	title=&amp;quot;Foo&amp;quot;&lt;br /&gt;
	can_resize=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_minimize=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_close=&amp;quot;true&amp;quot;&lt;br /&gt;
	can_drag_on_left=&amp;quot;false&amp;quot;&lt;br /&gt;
	width=&amp;quot;275&amp;quot;&lt;br /&gt;
	height=&amp;quot;250&amp;quot;&lt;br /&gt;
	min_width=&amp;quot;80&amp;quot;&lt;br /&gt;
	min_height=&amp;quot;220&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 By convention text fields are suffixed with _text.&lt;br /&gt;
 Common fonts include SansSerif and SansSerifSmall. See LLFontGL::fontFromName for more.&lt;br /&gt;
 Positions may be in absolute coordinates or as deltas.&lt;br /&gt;
 bottom_delta = -40 indicates 40 pixels from the top edge.&lt;br /&gt;
 follows indicates how the widget should move when the container is resized.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;text name=&amp;quot;bar_text&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerifSmall&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-40&amp;quot;&lt;br /&gt;
		width=&amp;quot;260&amp;quot;&lt;br /&gt;
		height=&amp;quot;16&amp;quot;&lt;br /&gt;
                follows=&amp;quot;left|top&amp;quot;&lt;br /&gt;
		&amp;gt;&lt;br /&gt;
bar is a generic programming identifier&lt;br /&gt;
	&amp;lt;/text&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
  Buttons are suffixed with _btn by convention.&lt;br /&gt;
  Note there is no association with a callback function here - it must be connected&lt;br /&gt;
  in the C++ code.&lt;br /&gt;
  bottom_delta here means from the TOP of the last widget, not the bottom.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;button&lt;br /&gt;
		name=&amp;quot;hippo_btn&amp;quot;&lt;br /&gt;
		label=&amp;quot;Hippo&amp;quot;&lt;br /&gt;
		font=&amp;quot;SansSerifSmall&amp;quot;&lt;br /&gt;
		left=&amp;quot;10&amp;quot;&lt;br /&gt;
		bottom_delta=&amp;quot;-25&amp;quot;&lt;br /&gt;
		width=&amp;quot;100&amp;quot;&lt;br /&gt;
		height=&amp;quot;20&amp;quot;&lt;br /&gt;
		follows=&amp;quot;top|left&amp;quot;&lt;br /&gt;
		/&amp;gt;&lt;br /&gt;
&amp;lt;/floater&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=1786</id>
		<title>Adding a dialog</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_dialog&amp;diff=1786"/>
		<updated>2006-11-03T18:27:09Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Windows and dialogs in Second Life are implemented as LLFloater objects.  The class hierarchy is:&lt;br /&gt;
&lt;br /&gt;
 LLFloaterFoo - a &amp;quot;foo&amp;quot; dialog&lt;br /&gt;
 LLFloater - generic window or dialog with close box, minimize box, etc.&lt;br /&gt;
 LLPanel - rectangular area with dark background, has functions like childSetText(), childGetValue()&lt;br /&gt;
 LLUICtrl - any widget that can take keyboard focus&lt;br /&gt;
 LLView - base class, container for UI widget children&lt;br /&gt;
&lt;br /&gt;
Create a new C++ header and source file to hold your new class.  By convention these are called llfloaterfoo.h and .cpp.  Place them in the newview directory.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll also need a new XML description file.  These are found in the indra/newview/skins/xui/en-us directory.  It&#039;s easiest to copy an existing file and modify it.  Name the new file floater_foo.xml.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s make a floater that has a text label, a text line input field, and a button.&lt;br /&gt;
&lt;br /&gt;
A basic floater header looks like this:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;llfloater.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 class LLFloaterFoo : public LLFloater&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
     LLFloaterFoo();           // no options to constructor&lt;br /&gt;
     virtual ~LLFloaterFoo();&lt;br /&gt;
&lt;br /&gt;
     static void show(void*);  // by convention, this shows the floater and does instance management&lt;br /&gt;
&lt;br /&gt;
 private:&lt;br /&gt;
     void onClickBar(void* userdata);   // by convention, button callbacks are named onClickButtonLabel&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Adding_a_menu_item&amp;diff=1676</id>
		<title>Adding a menu item</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Adding_a_menu_item&amp;diff=1676"/>
		<updated>2006-11-01T20:21:59Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Menu items in the viewer are specified in XML files, located in the indra/newview/skins/xui/en-us/ directory.&lt;br /&gt;
&lt;br /&gt;
There are separate XML files for various categories of menu.  They are:&lt;br /&gt;
 menu_viewer.xml - top of screen&lt;br /&gt;
 menu_inventory.xml - right-click on inventory item&lt;br /&gt;
 menu_pie_attachment.xml - right-click on your own attachment&lt;br /&gt;
 menu_pie_avatar.xml - right-click on other avatar or their attachments&lt;br /&gt;
 menu_pie_land.xml - right-click on land&lt;br /&gt;
 menu_pie_self.xml - right-click on your avatar&lt;br /&gt;
&lt;br /&gt;
The menu callbacks are set up in llviewermenu.cpp.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a menu item named &amp;quot;Foo&amp;quot; to the Tools menu.&lt;br /&gt;
* In menu_viewer.xml find the &amp;quot;Tools&amp;quot; menu item.  It is inside a &amp;lt;menu&amp;gt; tag.&lt;br /&gt;
* Tear-off sub menus use the &amp;lt;tearoff_menu&amp;gt; tag.&lt;br /&gt;
* Find the &amp;quot;Reset Scripts in Selection&amp;quot; menu item.&lt;br /&gt;
* After it, add the following text:&lt;br /&gt;
 &amp;lt;menu_item_call label=&amp;quot;Foo&amp;quot; enabled=&amp;quot;true&amp;quot; name=&amp;quot;foo_menu&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;on_click function=&amp;quot;Tools.Foo&amp;quot; userdata=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/menu_item_call&amp;gt;&lt;br /&gt;
* This sets up a menu item that will call a function. It can be referenced in C++ by the name &amp;quot;foo_menu&amp;quot;.  The user-visible label is &amp;quot;Foo&amp;quot;.  It defaults to enabled.&lt;br /&gt;
* Open newview/llviewermenu.cpp&lt;br /&gt;
* Create an event handler class for this menu item.  By convention these are named after the menu name and item name.&lt;br /&gt;
 class LLToolsFoo : public view_listener_t&lt;br /&gt;
 {&lt;br /&gt;
     bool handleEvent(LLPointer&amp;lt;LLEvent&amp;gt; event, const LLSD&amp;amp; userdata)&lt;br /&gt;
     {&lt;br /&gt;
         llinfos &amp;lt;&amp;lt; &amp;quot;foo!&amp;quot; &amp;lt;&amp;lt; llendl;&lt;br /&gt;
         return true;&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
* This class will listen for events from a &amp;quot;view&amp;quot;, the base class for all UI widgets.  LLPointer is a reference counting smart pointer.  LLSD is a structured data class similar to a Perl or Python variable - it can hold data of any type.&lt;br /&gt;
* llinfos is the output stream for informational messages.  It goes to the ctrl-shift-4 debug console, stdout, and the log file.&lt;br /&gt;
&lt;br /&gt;
* Now associate the &amp;quot;Tools.Foo&amp;quot; function with a C++ class.  Open newview/llviewermenu.cpp.&lt;br /&gt;
* In the function initialize_menu_actions() add the line:&lt;br /&gt;
 (new LLToolsFoo())-&amp;gt;registerListener(gMenuHolder, &amp;quot;Tools.Foo&amp;quot;);&lt;br /&gt;
* This makes your LLToolsFoo class listen to events from the gMenuHolder, a view which contains all the menu UI widgets.&lt;br /&gt;
* It also associates this listener with the &amp;quot;Tools.Foo&amp;quot; event.&lt;br /&gt;
&lt;br /&gt;
Compile and run!&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Glossary&amp;diff=1670</id>
		<title>Glossary</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Glossary&amp;diff=1670"/>
		<updated>2006-11-01T18:48:58Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==== SL ====&lt;br /&gt;
Common abbreviation for Second Life&lt;br /&gt;
&lt;br /&gt;
==== Viewer ====&lt;br /&gt;
Client software, written in C++, that runs on the user’s Windows, Macintosh, or Linux computer. The process is named “newview” for historical reasons.&lt;br /&gt;
&lt;br /&gt;
==== Simulator ====&lt;br /&gt;
The primary SL server process. Each simulator process simulates one 256x256 meter region. As the viewer moves through the world it is handled off from one simulator to another. Multiple simulator processes run on each server host, currently 2 to 16.&lt;br /&gt;
&lt;br /&gt;
==== Sim ====&lt;br /&gt;
Server host machine, for example sim1234.agni.lindenlab.com. The SL server grid consists of 2000+ sims. Sometimes “sim” is used incorrectly to mean simulator process or region.&lt;br /&gt;
&lt;br /&gt;
==== Host ====&lt;br /&gt;
Any server computer, but usually a sim.&lt;br /&gt;
&lt;br /&gt;
==== Region ====&lt;br /&gt;
Data set for a region of the world, like “Orientation Island” or “Ahern”. A region can be run by any simulator process, and regions move from sim to sim as the hosts are shut down, crash, etc.&lt;br /&gt;
&lt;br /&gt;
==== Grid ====&lt;br /&gt;
A collection of sims. Linden Lab runs several grids for internal and external testing.&lt;br /&gt;
&lt;br /&gt;
==== Farm ====&lt;br /&gt;
synonym for grid.&lt;br /&gt;
&lt;br /&gt;
==== Agni ====&lt;br /&gt;
The primary SL grid to which users connect.&lt;br /&gt;
&lt;br /&gt;
==== Parcel ====&lt;br /&gt;
An area of land owned by a single user or group. Parcels are composed of square blocks measuring 4x4 meters, but the blocks do not have to be contiguous. Parcels have both an integer local id and a global UUID.&lt;br /&gt;
&lt;br /&gt;
==== Estate ====&lt;br /&gt;
A collection of regions with a particular set of rules, such as banned users, sun position, etc. Each estate has an owner, either a user or “Governor Linden”. Most privately owned regions are in their own estates. Estates have integer identifiers. The “mainland” is estate id 1.&lt;br /&gt;
&lt;br /&gt;
==== Avatar ====&lt;br /&gt;
The graphical representation of a user. Implemented in the class LLVOAvatar on the viewer.&lt;br /&gt;
&lt;br /&gt;
==== Agent ====&lt;br /&gt;
The data representation of the current user. In general “agent” means you and “avatar” means someone else. Identified by a UUID, usually called “agent_id” in the code.&lt;br /&gt;
&lt;br /&gt;
==== Asset ====&lt;br /&gt;
A data resource such as an image, sound, script, object, etc. Assets can be downloaded to the viewer or uploaded into a central asset store. Assets are identified by UUID and type. Types are in llassettype.h.&lt;br /&gt;
&lt;br /&gt;
==== Texture ====&lt;br /&gt;
An image applied to the surface of an object.&lt;br /&gt;
&lt;br /&gt;
==== Floater ====&lt;br /&gt;
A dialog or window appearing in the user interface. Implemented in classes titled “LLFloater*”&lt;br /&gt;
&lt;br /&gt;
==== Vector ====&lt;br /&gt;
An array of floating point values used to represent positions, colors, etc. Implemented in LLVector3, LLVector4, LLColor4, etc.&lt;br /&gt;
&lt;br /&gt;
==== Quaternion ====&lt;br /&gt;
Representation of a rotation. SL uses unit quaternions represented in four floats. This allows only three floats to be transmitted and the remaining value reconstructed on the viewer. See GameDev article on [http://www.gamedev.net/reference/articles/article1095.asp quaternions].&lt;br /&gt;
&lt;br /&gt;
==== Message Template ====&lt;br /&gt;
The protocol description for UDP packet communication between the viewer and servers. Described in the text file app_settings/message_template.msg.&lt;br /&gt;
&lt;br /&gt;
==== LSL ====&lt;br /&gt;
Linden Scripting Language, a C-like language used for server-side scripting of objects.&lt;br /&gt;
&lt;br /&gt;
==== Primitive ====&lt;br /&gt;
3D object in the world. Each prim is represented by a set of parameters, including position, scale, rotation, shape, cut, hollow, etc. Prims can be linked together into link sets. They can also be attached to avatars, but this process is separate from linking. Primitives are implemented in LLPrimitive, with vertex generation performed in LLVolume and rendering in LLVOVolume.&lt;br /&gt;
&lt;br /&gt;
==== Prim ====&lt;br /&gt;
Abbreviation for primitive.&lt;br /&gt;
&lt;br /&gt;
==== Task ====&lt;br /&gt;
Server-side representation of a primitive or link set. Since primitives can contain scripts or be physically simulated each task adds load to the server process. The agent is also represented as a task on the server, but has extensive additional processing.&lt;br /&gt;
&lt;br /&gt;
==== FMOD ====&lt;br /&gt;
Cross-platform audio library. Used to play decompressed sound effects and stream MP3 music to users on particular parcels. See [http://www.fmod.org/ FMOD.org].&lt;br /&gt;
&lt;br /&gt;
==== JPEG2000 ====&lt;br /&gt;
Wavelet based image compression format. Inherently progressive, so images can be displayed with only partial data available, without increases in file size. See the Wikipedia entry on [http://en.wikipedia.org/wiki/JPEG_2000 JPEG2000].&lt;br /&gt;
&lt;br /&gt;
==== Kakadu ====&lt;br /&gt;
Cross-platform high-performance JPEG2000 library. Linden Lab does not have redistribution rights to Kakadu so the open source viewer ships with [http://www.openjpeg.org/ OpenJPEG].&lt;br /&gt;
&lt;br /&gt;
==== Ogg Vorbis ====&lt;br /&gt;
Open source audio compression library. Sound effects are stored as .ogg files in the asset system. See Ogg Vorbis.&lt;br /&gt;
&lt;br /&gt;
==== UUID ====&lt;br /&gt;
Globally unique identifier, a 128-bit number represented as a 16-byte binary value or 36-byte hexadecimal string. UUIDs can be generated by any part of the system and are guaranteed to be unique.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Glossary&amp;diff=1669</id>
		<title>Glossary</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Glossary&amp;diff=1669"/>
		<updated>2006-11-01T18:34:04Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Second Life Terminology&lt;br /&gt;
&lt;br /&gt;
== SL ==&lt;br /&gt;
Common abbreviation for Second Life&lt;br /&gt;
&lt;br /&gt;
=== Viewer ===&lt;br /&gt;
Client software, written in C++, that runs on the user’s Windows, Macintosh, or Linux computer. The process is named “newview” for historical reasons.&lt;br /&gt;
&lt;br /&gt;
==== Simulator ====&lt;br /&gt;
The primary SL server process. Each simulator process simulates one 256x256 meter region. As the viewer moves through the world it is handled off from one simulator to another. Multiple simulator processes run on each server host, currently 2 to 16.&lt;br /&gt;
&lt;br /&gt;
Sim – Server host machine, for example sim1234.agni.lindenlab.com. The SL server grid consists of 2000+ sims. Sometimes “sim” is used incorrectly to mean simulator process or region.&lt;br /&gt;
&lt;br /&gt;
Host – Any server computer, but usually a sim.&lt;br /&gt;
&lt;br /&gt;
Region – Data set for a region of the world, like “Orientation Island” or “Ahern”. A region can be run by any simulator process, and regions move from sim to sim as the hosts are shut down, crash, etc.&lt;br /&gt;
&lt;br /&gt;
Grid – A collection of sims. Linden Lab runs several grids for internal and external testing.&lt;br /&gt;
&lt;br /&gt;
Farm – synonym for grid.&lt;br /&gt;
&lt;br /&gt;
Agni – The primary SL grid to which users connect.&lt;br /&gt;
&lt;br /&gt;
Parcel – An area of land owned by a single user or group. Parcels are composed of square blocks measuring 4x4 meters, but the blocks do not have to be contiguous. Parcels have both an integer local id and a global UUID.&lt;br /&gt;
&lt;br /&gt;
Estate – A collection of regions with a particular set of rules, such as banned users, sun position, etc. Each estate has an owner, either a user or “Governor Linden”. Most privately owned regions are in their own estates. Estates have integer identifiers. The “mainland” is estate id 1.&lt;br /&gt;
&lt;br /&gt;
Avatar – The graphical representation of a user. Implemented in the class LLVOAvatar on the viewer.&lt;br /&gt;
&lt;br /&gt;
Agent – The data representation of the current user. In general “agent” means you and “avatar” means someone else. Identified by a UUID, usually called “agent_id” in the code.&lt;br /&gt;
&lt;br /&gt;
Asset – A data resource such as an image, sound, script, object, etc. Assets can be downloaded to the viewer or uploaded into a central asset store. Assets are identified by UUID and type. Types are in llassettype.h.&lt;br /&gt;
&lt;br /&gt;
Texture – An image applied to the surface of an object.&lt;br /&gt;
&lt;br /&gt;
Floater – A dialog or window appearing in the user interface. Implemented in classes titled “LLFloater*”&lt;br /&gt;
&lt;br /&gt;
Vector – An array of floating point values used to represent positions, colors, etc. Implemented in LLVector3, LLVector4, LLColor4, etc.&lt;br /&gt;
&lt;br /&gt;
Quaternion – Representation of a rotation. SL uses unit quaternions represented in four floats. This allows only three floats to be transmitted and the remaining value reconstructed on the viewer. See GameDev article on [[http://www.gamedev.net/reference/articles/article1095.asp quaternions]].&lt;br /&gt;
&lt;br /&gt;
Message Template – The protocol description for UDP packet communication between the viewer and servers. Described in the text file app_settings/message_template.msg.&lt;br /&gt;
&lt;br /&gt;
LSL – Linden Scripting Language, a C-like language used for server-side scripting of objects.&lt;br /&gt;
&lt;br /&gt;
Prim/Primitive – 3D object in the world. Each prim is represented by a set of parameters, including position, scale, rotation, shape, cut, hollow, etc. Prims can be linked together into link sets. They can also be attached to avatars, but this process is separate from linking. Primitives are implemented in LLPrimitive, with vertex generation performed in LLVolume and rendering in LLVOVolume.&lt;br /&gt;
&lt;br /&gt;
Task – Server-side representation of a primitive or link set. Since primitives can contain scripts or be physically simulated each task adds load to the server process. The agent is also represented as a task on the server, but has extensive additional processing.&lt;br /&gt;
&lt;br /&gt;
FMOD – Cross-platform audio library. Used to play decompressed sound effects and stream MP3 music to users on particular parcels. See FMOD.&lt;br /&gt;
&lt;br /&gt;
JPEG2000 – Wavelet based image compression format. Inherently progressive, so images can be displayed with only partial data available, without increases in file size. See JPEG2000.&lt;br /&gt;
&lt;br /&gt;
Kakadu – Cross-platform high-performance JPEG2000 library. Linden Lab does not have redistribution rights to Kakadu so the open source viewer ships with OpenJPEG.&lt;br /&gt;
&lt;br /&gt;
Ogg Vorbis – Open source audio compression library. Sound effects are stored as .ogg files in the asset system. See Ogg Vorbis.&lt;br /&gt;
&lt;br /&gt;
UUID – Globally unique identifier, a 128-bit number represented as a 16-byte binary value or 36-byte hexadecimal string. UUIDs can be generated by any part of the system and are guaranteed to be unique.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Glossary&amp;diff=1668</id>
		<title>Glossary</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Glossary&amp;diff=1668"/>
		<updated>2006-11-01T18:19:45Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Second Life Terminology&lt;br /&gt;
&lt;br /&gt;
SL – Common abbreviation for Second Life&lt;br /&gt;
&lt;br /&gt;
Viewer – Client software, written in C++, that runs on the user’s Windows, Macintosh, or Linux computer. The process is named “newview” for historical reasons.&lt;br /&gt;
&lt;br /&gt;
Simulator – The primary SL server process. Each simulator process simulates one 256x256 meter region. As the viewer moves through the world it is handled off from one simulator to another. Multiple simulator processes run on each server host, currently 2 to 16.&lt;br /&gt;
&lt;br /&gt;
Sim – Server host machine, for example sim1234.agni.lindenlab.com. The SL server grid consists of 2000+ sims. Sometimes “sim” is used incorrectly to mean simulator process or region.&lt;br /&gt;
&lt;br /&gt;
Host – Any server computer, but usually a sim.&lt;br /&gt;
&lt;br /&gt;
Region – Data set for a region of the world, like “Orientation Island” or “Ahern”. A region can be run by any simulator process, and regions move from sim to sim as the hosts are shut down, crash, etc.&lt;br /&gt;
&lt;br /&gt;
Grid – A collection of sims. Linden Lab runs several grids for internal and external testing.&lt;br /&gt;
&lt;br /&gt;
Farm – synonym for grid.&lt;br /&gt;
&lt;br /&gt;
Agni – The primary SL grid to which users connect.&lt;br /&gt;
&lt;br /&gt;
Parcel – An area of land owned by a single user or group. Parcels are composed of square blocks measuring 4x4 meters, but the blocks do not have to be contiguous. Parcels have both an integer local id and a global UUID.&lt;br /&gt;
&lt;br /&gt;
Estate – A collection of regions with a particular set of rules, such as banned users, sun position, etc. Each estate has an owner, either a user or “Governor Linden”. Most privately owned regions are in their own estates. Estates have integer identifiers. The “mainland” is estate id 1.&lt;br /&gt;
&lt;br /&gt;
Avatar – The graphical representation of a user. Implemented in the class LLVOAvatar on the viewer.&lt;br /&gt;
&lt;br /&gt;
Agent – The data representation of the current user. In general “agent” means you and “avatar” means someone else. Identified by a UUID, usually called “agent_id” in the code.&lt;br /&gt;
&lt;br /&gt;
Asset – A data resource such as an image, sound, script, object, etc. Assets can be downloaded to the viewer or uploaded into a central asset store. Assets are identified by UUID and type. Types are in llassettype.h.&lt;br /&gt;
&lt;br /&gt;
Texture – An image applied to the surface of an object.&lt;br /&gt;
&lt;br /&gt;
Floater – A dialog or window appearing in the user interface. Implemented in classes titled “LLFloater*”&lt;br /&gt;
&lt;br /&gt;
Vector – An array of floating point values used to represent positions, colors, etc. Implemented in LLVector3, LLVector4, LLColor4, etc.&lt;br /&gt;
&lt;br /&gt;
Quaternion – Representation of a rotation. SL uses unit quaternions represented in four floats. This allows only three floats to be transmitted and the remaining value reconstructed on the viewer. See Quaternion.&lt;br /&gt;
&lt;br /&gt;
Message Template – The protocol description for UDP packet communication between the viewer and servers. Described in the text file app_settings/message_template.msg.&lt;br /&gt;
&lt;br /&gt;
LSL – Linden Scripting Language, a C-like language used for server-side scripting of objects.&lt;br /&gt;
&lt;br /&gt;
Prim/Primitive – 3D object in the world. Each prim is represented by a set of parameters, including position, scale, rotation, shape, cut, hollow, etc. Prims can be linked together into link sets. They can also be attached to avatars, but this process is separate from linking. Primitives are implemented in LLPrimitive, with vertex generation performed in LLVolume and rendering in LLVOVolume.&lt;br /&gt;
&lt;br /&gt;
Task – Server-side representation of a primitive or link set. Since primitives can contain scripts or be physically simulated each task adds load to the server process. The agent is also represented as a task on the server, but has extensive additional processing.&lt;br /&gt;
&lt;br /&gt;
FMOD – Cross-platform audio library. Used to play decompressed sound effects and stream MP3 music to users on particular parcels. See FMOD.&lt;br /&gt;
&lt;br /&gt;
JPEG2000 – Wavelet based image compression format. Inherently progressive, so images can be displayed with only partial data available, without increases in file size. See JPEG2000.&lt;br /&gt;
&lt;br /&gt;
Kakadu – Cross-platform high-performance JPEG2000 library. Linden Lab does not have redistribution rights to Kakadu so the open source viewer ships with OpenJPEG.&lt;br /&gt;
&lt;br /&gt;
Ogg Vorbis – Open source audio compression library. Sound effects are stored as .ogg files in the asset system. See Ogg Vorbis.&lt;br /&gt;
&lt;br /&gt;
UUID – Globally unique identifier, a 128-bit number represented as a 16-byte binary value or 36-byte hexadecimal string. UUIDs can be generated by any part of the system and are guaranteed to be unique.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_Architecture&amp;diff=1624</id>
		<title>Viewer Architecture</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_Architecture&amp;diff=1624"/>
		<updated>2006-10-31T00:52:45Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
&lt;br /&gt;
The Second Life client (also known as the &amp;quot;viewer&amp;quot;) is a complex piece of software. It can be visualized as a streaming media client like RealPlayer, a game engine like Quake 3, or a web browser.&lt;br /&gt;
&lt;br /&gt;
First you&#039;ll need to learn some [[Second Life Terminology]], like &amp;quot;agent&amp;quot;, &amp;quot;sim&amp;quot;, and &amp;quot;region&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If you like to learn by example, you can learn about:&lt;br /&gt;
* [[Adding a menu item]]&lt;br /&gt;
* [[Adding a dialog]]&lt;br /&gt;
* [[How movement works]]&lt;br /&gt;
* [[How the camera works]]&lt;br /&gt;
* [[How login works]]&lt;br /&gt;
* [[How keyboard processing works]]&lt;br /&gt;
* [[How scripts work]]&lt;br /&gt;
&lt;br /&gt;
If you prefer a more hierarchical approach, the viewer is built from:&lt;br /&gt;
* [[Message System]] - reliable and unreliable transport over UDP&lt;br /&gt;
* [[Image System]] - prioritizes and decodes JPEG2000 images into OpenGL textures&lt;br /&gt;
* [[Viewer Object System]] - objects in scene for rendering and editing&lt;br /&gt;
* [[Rendering System]] - from viewer object to drawable to face to vertices to graphics card&lt;br /&gt;
* [[Culling]] - octree and occlusion based culling to speed rendering&lt;br /&gt;
* [[UI Widgets]] - cross platform buttons, scroll bars, etc.&lt;br /&gt;
* [[UI Floaters]] - dialogs and windows built from XML files&lt;br /&gt;
* [[Asset System]] - transport for animations, sounds, notecards, scripts, etc.&lt;br /&gt;
* [[Inventory]] - server-side storage of assets for each user&lt;br /&gt;
* [[Sound System]] - cross platform audio based on FMOD&lt;br /&gt;
* [[Movie System]] - QuickTime-based video on object surfaces&lt;br /&gt;
* [[VFS]] - cached data is held in two &amp;quot;virtual file systems&amp;quot; in large files on the client&lt;br /&gt;
* [[Selection Manager]] - holds extended information for selected objects and allows editing&lt;br /&gt;
* [[Avatar Appearance]] - appearance is constructed from a mesh, parameters to deform the mesh, and textures to describe clothing&lt;br /&gt;
* [[Avatar Profiles]]&lt;br /&gt;
* [[Groups]]&lt;br /&gt;
* [[Money]]&lt;br /&gt;
&lt;br /&gt;
== Threads ==&lt;br /&gt;
The viewer is a single process with a few threads:&lt;br /&gt;
* Main thread -- The input/output main program function.&lt;br /&gt;
* VFS Thread -- Thread responsible for reading/writing to the virtual file system.&lt;br /&gt;
* LFS Thread -- Thread responsible for some reading/writing to the local file system. Not sure if this is actually used anywhere.&lt;br /&gt;
&lt;br /&gt;
== Program Flow ==&lt;br /&gt;
* Initialize&lt;br /&gt;
* Loop&lt;br /&gt;
** Gathers input&lt;br /&gt;
** Pumps the TCP i/o&lt;br /&gt;
** Render the frame&lt;br /&gt;
** &lt;br /&gt;
* Shutdown&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Documentation&amp;diff=1619</id>
		<title>Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Documentation&amp;diff=1619"/>
		<updated>2006-10-31T00:36:59Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
A lot of the documentation below is geared toward developers.  However, many aspects of the system don&#039;t require a deep technical background to learn.  Much of this is still a work in progress, but since this is a wiki, you can help fill in the blanks!&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[Features]]&#039;&#039;&#039; - An overview of the major components of the system as seen from an end user&#039;s perspective.  Links to specifications, test plans and other documentation can be found here.  &lt;br /&gt;
* &#039;&#039;&#039;[[Viewer architecture]]&#039;&#039;&#039; - Overview of the viewer from a developer&#039;s perspective. &lt;br /&gt;
* &#039;&#039;&#039;[[Protocol]]&#039;&#039;&#039; - In-depth documentation of the protocol.&lt;br /&gt;
* &#039;&#039;&#039;[[Third Party Libraries]]&#039;&#039;&#039; - The third party libraries used by the viewer.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Documentation&amp;diff=1618</id>
		<title>Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Documentation&amp;diff=1618"/>
		<updated>2006-10-31T00:36:37Z</updated>

		<summary type="html">&lt;p&gt;James Linden: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{OSWikiLearnBox}}&lt;br /&gt;
A lot of the documentation below is geared toward developers.  However, many aspects of the system don&#039;t require a deep technical background to learn.  Much of this is still a work in progress, but since this is a wiki, you can help fill in the blanks!&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[Features]]&#039;&#039;&#039; - An overview of the major components of the system as seen from an end user&#039;s perspective.  Links to specifications, test plans and other documentation can be found here.  &lt;br /&gt;
* &#039;&#039;&#039;[[Viewer Architecture]]&#039;&#039;&#039; - Overview of the viewer from a developer&#039;s perspective. &lt;br /&gt;
* &#039;&#039;&#039;[[Protocol]]&#039;&#039;&#039; - In-depth documentation of the protocol.&lt;br /&gt;
* &#039;&#039;&#039;[[Third Party Libraries]]&#039;&#039;&#039; - The third party libraries used by the viewer.&lt;/div&gt;</summary>
		<author><name>James Linden</name></author>
	</entry>
</feed>