summaryrefslogtreecommitdiff
path: root/gpsd.php.in
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-10-01 18:26:31 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-10-01 18:26:31 -0400
commit282122c022d42765b491a11ced84b1749469c726 (patch)
tree9073a8a76bfd266aa7b23590ae24ab2aa644e6bd /gpsd.php.in
parenta98e65e54178c39d6b15d64f87c9c560149bbac5 (diff)
downloadgpsd-282122c022d42765b491a11ced84b1749469c726.tar.gz
Factor out or remove URLs. No code changes yet except in gpsd.php (now .in).
This was the easy part. Remaining removals will require more decisions.
Diffstat (limited to 'gpsd.php.in')
-rw-r--r--gpsd.php.in596
1 files changed, 596 insertions, 0 deletions
diff --git a/gpsd.php.in b/gpsd.php.in
new file mode 100644
index 00000000..ea0466f6
--- /dev/null
+++ b/gpsd.php.in
@@ -0,0 +1,596 @@
+<?php
+
+# Copyright (c) 2006,2010 Chris Kuethe <chris.kuethe@gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+global $head, $blurb, $title, $googlemap, $autorefresh, $footer, $gmap_key;
+global $server, $advertise, $port, $open, $swap_ew, $testmode;
+$testmode = 1; # leave this set to 1
+
+# Public script parameters:
+# host: host name or address where GPSd runs. Default: from config file
+# port: port of GPSd. Default: from config file
+# op=view: show just the skyview image instead of the whole HTML page
+# sz=small: used with op=view, display a small (240x240px) skyview
+# op=json: respond with the GPSd POLL JSON structure
+# jsonp=prefix: used with op=json, wrap the POLL JSON in parentheses
+# and prepend prefix
+
+# If you're running PHP with the Suhosin patch (like the Debian PHP5 package),
+# it may be necessary to increase the value of the
+# suhosin.get.max_value_length parameter to 2048. The imgdata parameter used
+# for displaying the skyview is longer than the default 512 allowed by Suhosin.
+# Debian has the config file at /etc/php5/conf.d/suhosin.ini.
+
+# this script shouldn't take more than a few seconds to run
+set_time_limit(3);
+ini_set('max_execution_time', 3);
+
+if (!file_exists("gpsd_config.inc"))
+ write_config();
+
+require_once("gpsd_config.inc");
+
+# sample data
+$resp = <<<EOF
+{"class":"POLL","time":"2010-04-05T21:27:54.84Z","active":1,
+ "tpv":[{"class":"TPV","tag":"MID41","device":"/dev/ttyUSB0",
+ "time":1270517264.240,"ept":0.005,"lat":40.035093060,
+ "lon":-75.519748733,"alt":31.1,"track":99.4319,
+ "speed":0.123,"mode":3}],
+ "sky":[{"class":"SKY","tag":"MID41","device":"/dev/ttyUSB0",
+ "time":"2010-04-05T21:27:44.84Z","hdop":9.20,"vdop":12.1,
+ "satellites":[{"PRN":16,"el":55,"az":42,"ss":36,"used":true},
+ {"PRN":19,"el":25,"az":177,"ss":0,"used":false},
+ {"PRN":7,"el":13,"az":295,"ss":0,"used":false},
+ {"PRN":6,"el":56,"az":135,"ss":32,"used":true},
+ {"PRN":13,"el":47,"az":304,"ss":0,"used":false},
+ {"PRN":23,"el":66,"az":259,"ss":40,"used":true},
+ {"PRN":20,"el":7,"az":226,"ss":0,"used":false},
+ {"PRN":3,"el":52,"az":163,"ss":32,"used":true},
+ {"PRN":31,"el":16,"az":102,"ss":0,"used":false}
+ ]
+ }
+ ]
+}
+EOF;
+
+
+
+# if we're passing in a query, let's unpack and use it
+$op = isset($_GET['op']) ? $_GET['op'] : '';
+if (isset($_GET['imgdata']) && $op == 'view'){
+ $resp = base64_decode($_GET['imgdata']);
+ if ($resp){
+ gen_image($resp);
+ exit(0);
+ }
+} else {
+ if (isset($_GET['host']))
+ if (!preg_match('/[^a-zA-Z0-9\.-]/', $_GET['host']))
+ $server = $_GET['host'];
+
+ if (isset($_GET['port']))
+ if (!preg_match('/\D/', $_GET['port']) && ($port>0) && ($port<65536))
+ $port = $_GET['port'];
+
+ if ($testmode){
+ $sock = @fsockopen($server, $port, $errno, $errstr, 2);
+ @fwrite($sock, "?POLL;\n");
+ for($tries = 0; $tries < 10; $tries++){
+ $resp = @fread($sock, 1536); # SKY can be pretty big
+ if (preg_match('/{"class":"POLL".+}/i', $resp, $m)){
+ $resp = $m[0];
+ break;
+ }
+ }
+ @fclose($sock);
+ if (!$resp)
+ $resp = '{"class":"ERROR","message":"no response from GPS daemon"}';
+ }
+}
+
+if ($op == 'view')
+ gen_image($resp);
+else if ($op == 'json')
+ write_json($resp);
+else
+ write_html($resp);
+
+exit(0);
+
+###########################################################################
+function colorsetup($im){
+ $C['white'] = imageColorAllocate($im, 255, 255, 255);
+ $C['ltgray'] = imageColorAllocate($im, 191, 191, 191);
+ $C['mdgray'] = imageColorAllocate($im, 127, 127, 127);
+ $C['dkgray'] = imageColorAllocate($im, 63, 63, 63);
+ $C['black'] = imageColorAllocate($im, 0, 0, 0);
+ $C['red'] = imageColorAllocate($im, 255, 0, 0);
+ $C['brightgreen'] = imageColorAllocate($im, 0, 255, 0);
+ $C['darkgreen'] = imageColorAllocate($im, 0, 192, 0);
+ $C['blue'] = imageColorAllocate($im, 0, 0, 255);
+ $C['cyan'] = imageColorAllocate($im, 0, 255, 255);
+ $C['magenta'] = imageColorAllocate($im, 255, 0, 255);
+ $C['yellow'] = imageColorAllocate($im, 255, 255, 0);
+ $C['orange'] = imageColorAllocate($im, 255, 128, 0);
+
+ return $C;
+}
+
+function legend($im, $sz, $C){
+ $r = 30;
+ $fn = 5;
+ $x = $sz - (4*$r+7) - 2;
+ $y = $sz - $r - 3;
+
+ imageFilledRectangle($im, $x, $y, $x + 4*$r + 7, $y + $r +1, $C['dkgray']);
+ imageRectangle($im, $x+0*$r+1, $y+1, $x + 1*$r + 0, $y + $r, $C['red']);
+ imageRectangle($im, $x+1*$r+2, $y+1, $x + 2*$r + 2, $y + $r, $C['yellow']);
+ imageRectangle($im, $x+2*$r+4, $y+1, $x + 3*$r + 4, $y + $r, $C['darkgreen']);
+ imageRectangle($im, $x+4*$r+6, $y+1, $x + 3*$r + 6, $y + $r, $C['brightgreen']);
+ imageString($im, $fn, $x+3+0*$r, $y+$r/3, "<30", $C['red']);
+ imageString($im, $fn, $x+5+1*$r, $y+$r/3, "30+", $C['yellow']);
+ imageString($im, $fn, $x+7+2*$r, $y+$r/3, "35+", $C['darkgreen']);
+ imageString($im, $fn, $x+9+3*$r, $y+$r/3, "40+", $C['brightgreen']);
+}
+
+function radial($angle, $sz){
+ #turn into radians
+ $angle = deg2rad($angle);
+
+ # determine length of radius
+ $r = $sz * 0.5 * 0.95;
+
+ # and convert length/azimuth to cartesian
+ $x0 = sprintf("%d", (($sz * 0.5) - ($r * cos($angle))));
+ $y0 = sprintf("%d", (($sz * 0.5) - ($r * sin($angle))));
+ $x1 = sprintf("%d", (($sz * 0.5) + ($r * cos($angle))));
+ $y1 = sprintf("%d", (($sz * 0.5) + ($r * sin($angle))));
+
+ return array($x0, $y0, $x1, $y1);
+}
+
+function azel2xy($az, $el, $sz){
+ global $swap_ew;
+ #rotate coords... 90deg W = 180deg trig
+ $az += 270;
+
+ #turn into radians
+ $az = deg2rad($az);
+
+ # determine length of radius
+ $r = $sz * 0.5 * 0.95;
+ $r -= ($r * ($el/90));
+
+ # and convert length/azimuth to cartesian
+ $x = sprintf("%d", (($sz * 0.5) + ($r * cos($az))));
+ $y = sprintf("%d", (($sz * 0.5) + ($r * sin($az))));
+ if ($swap_ew == 0)
+ $x = $sz - $x;
+
+ return array($x, $y);
+}
+
+function splot($im, $sz, $C, $e){
+ if ((0 == $e['PRN']) || (0 == $e['az'] + $e['el'] + $e['ss']) ||
+ ($e['az'] < 0) || ($e['el'] < 0))
+ return;
+
+ $color = $C['brightgreen'];
+ if ($e['ss'] < 40)
+ $color = $C['darkgreen'];
+ if ($e['ss'] < 35)
+ $color = $C['yellow'];
+ if ($e['ss'] < 30)
+ $color = $C['red'];
+ if ($e['el']<10)
+ $color = $C['blue'];
+ if ($e['ss'] < 10)
+ $color = $C['black'];
+
+ list($x, $y) = azel2xy($e['az'], $e['el'], $sz);
+
+ $r = 12;
+ if (isset($_GET['sz']) && ($_GET['sz'] == 'small'))
+ $r = 8;
+
+ imageString($im, 3, $x+4, $y+4, $e['PRN'], $C['black']);
+ if ($e['used'] == true)
+ if ($e['PRN'] > 32)
+ imageFilledDiamond($im, $x, $y, $r, $color);
+ else
+ imageFilledArc($im, $x, $y, $r, $r, 0, 360, $color, 0);
+ else
+ if ($e['PRN'] > 32)
+ imageDiamond($im, $x, $y, $r, $color);
+ else
+ imageArc($im, $x, $y, $r, $r, 0, 360, $color);
+}
+
+function imageDiamond($im, $x, $y, $r, $color){
+ $t = $r/2;
+ # this lunacy is because imagesetthickness doesn't seem to work
+ $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t );
+ imagepolygon($im, $vx, 4, $color);
+ $t--;
+ $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t );
+ imagepolygon($im, $vx, 4, $color);
+ $t--;
+ $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t );
+ imagepolygon($im, $vx, 4, $color);
+}
+
+function imageFilledDiamond($im, $x, $y, $r, $color){
+ $t = $r/2;
+ while($t){
+ $vx = array ( $x+$t, $y, $x, $y+$t, $x-$t, $y, $x, $y-$t );
+ imagepolygon($im, $vx, 4, $color);
+ $t -= 0.5;
+ }
+}
+
+function elevation($im, $sz, $C, $a){
+ $b = 90 - $a;
+ $a = $sz * 0.95 * ($a/180);
+ imageArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['ltgray']);
+ $x = $sz/2 - 16;
+ $y = $sz/2 - $a;
+ imageString($im, 2, $x, $y, $b, $C['ltgray']);
+}
+
+function skyview($im, $sz, $C){
+ global $swap_ew;
+ $a = 90; $a = $sz * 0.95 * ($a/180);
+ imageFilledArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['mdgray'], 0);
+ imageArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['black']);
+ $x = $sz/2 - 16; $y = $sz/2 - $a;
+ imageString($im, 2, $x, $y, "0", $C['ltgray']);
+
+ $a = 85; $a = $sz * 0.95 * ($a/180);
+ imageFilledArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['white'], 0);
+ imageArc($im, $sz/2, $sz/2, $a*2, $a*2, 0, 360, $C['ltgray']);
+ imageString($im, 1, $sz/2 - 6, $sz+$a, '5', $C['black']);
+ $x = $sz/2 - 16; $y = $sz/2 - $a;
+ imageString($im, 2, $x, $y, "5", $C['ltgray']);
+
+ for($i = 0; $i < 180; $i += 15){
+ list($x0, $y0, $x1, $y1) = radial($i, $sz);
+ imageLine($im, $x0, $y0, $x1, $y1, $C['ltgray']);
+ }
+
+ for($i = 15; $i < 90; $i += 15)
+ elevation($im, $sz, $C, $i);
+
+ $x = $sz/2 - 16; $y = $sz/2 - 8;
+ /* imageString($im, 2, $x, $y, "90", $C['ltgray']); */
+
+ imageString($im, 4, $sz/2 + 4, 2 , 'N', $C['black']);
+ imageString($im, 4, $sz/2 + 4, $sz - 16 , 'S', $C['black']);
+ if ($swap_ew == 0){
+ imageString($im, 4, 4 , $sz/2 + 4, 'E', $C['black']);
+ imageString($im, 4, $sz - 10 , $sz/2 + 4, 'W', $C['black']);
+ } else {
+ imageString($im, 4, 4 , $sz/2 + 4, 'W', $C['black']);
+ imageString($im, 4, $sz - 10 , $sz/2 + 4, 'E', $C['black']);
+ }
+}
+
+function gen_image($resp){
+ $sz = 600;
+ if (isset($_GET['sz']) && ($_GET['sz'] == 'small'))
+ $sz = 240;
+
+ $GPS = json_decode($resp, true);
+ if ($GPS['class'] != "POLL"){
+ die("json_decode error: $resp");
+ }
+
+ $im = imageCreate($sz, $sz);
+ $C = colorsetup($im);
+ skyview($im, $sz, $C);
+ if ($sz > 240)
+ legend($im, $sz, $C);
+
+ for($i = 0; $i < count($GPS['sky'][0]['satellites']); $i++){
+ splot($im, $sz, $C, $GPS['sky'][0]['satellites'][$i]);
+ }
+
+ header("Content-type: image/png");
+ imagePNG($im);
+ imageDestroy($im);
+}
+
+function dfix($x, $y, $z){
+ if ($x < 0){
+ $x = sprintf("%f %s", -1 * $x, $z);
+ } else {
+ $x = sprintf("%f %s", $x, $y);
+ }
+ return $x;
+}
+
+function write_html($resp){
+ global $sock, $errstr, $errno, $server, $port, $head, $body, $open;
+ global $blurb, $title, $autorefresh, $googlemap, $gmap_key, $footer;
+ global $testmode, $advertise;
+
+ $GPS = json_decode($resp, true);
+ if ($GPS['class'] != 'POLL'){
+ die("json_decode error: $resp");
+ }
+
+ header("Content-type: text/html; charset=UTF-8");
+
+ global $lat, $lon;
+ $lat = (float)$GPS['tpv'][0]['lat'];
+ $lon = (float)$GPS['tpv'][0]['lon'];
+ $x = $server; $y = $port;
+ $imgdata = base64_encode($resp);
+ $server = $x; $port = $y;
+
+ if ($autorefresh > 0)
+ $autorefresh = "<meta http-equiv='Refresh' content='$autorefresh'/>";
+ else
+ $autorefresh = '';
+
+ $gmap_head = $gmap_body = $gmap_code = '';
+ if ($googlemap){
+ $gmap_head = gen_gmap_head();
+ $gmap_body = 'onload="Load()" onunload="GUnload()"';
+ $gmap_code = gen_gmap_code();
+ }
+ $part1 = <<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+{$head}
+{$gmap_head}
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<meta http-equiv="Content-Language" content="en,en-us"/>
+<title>{$title} - GPSD Test Station {$lat}, {$lon}</title>
+{$autorefresh}
+<style>
+.warning {
+ color: #FF0000;
+}
+
+.fixed {
+ font-family: mono-space;
+}
+
+.caption {
+ text-align: left;
+ margin: 1ex 3em 1ex 3em; /* top right bottom left */
+}
+
+.administrivia {
+ font-size: small;
+ font-family: verdana, sans-serif;
+}
+</style>
+</head>
+
+<body {$body} {$gmap_body}>
+<center>
+<table border="0">
+<tr><td align="justify">
+{$blurb}
+</td>
+EOF;
+
+ if (!strlen($advertise))
+ $advertise = $server;
+
+ if ($testmode && !$sock)
+ $part2 = "";
+ else
+ $part2 = <<<EOF
+<!-- ------------------------------------------------------------ -->
+
+<td rowspan="4" align="center" valign="top">
+<img src="?op=view&amp;imgdata={$imgdata}"
+width="600" height="600"/>
+<br clear="all"/>
+<p class="caption">A filled circle means the satellite was used in
+the last fix. Green-yellow-red colors indicate signal strength in dB,
+green=most and red=least. Diamonds indicate SBAS satellites.</p>
+{$gmap_code}</td>
+</tr>
+EOF;
+
+ if (!$open)
+ $part3 = '';
+ else
+ $part3 = <<<EOF
+<!-- ------------------------------------------------------------ -->
+
+<tr><td align="justify">To get real-time information, connect to
+<span class="fixed">telnet://{$advertise}:{$port}/</span> and type "?POLL;"
+or "?WATCH={"enable":true,"raw":true}".<br/>
+Use a different server:<br/>
+<form method=GET action="${_SERVER['SCRIPT_NAME']}">
+<input name="host" value="{$advertise}">:
+<input name="port" value="{$port}" size="5" maxlength="5">
+<input type=submit value="Get Position"><input type=reset></form>
+<br/>
+</td>
+</tr>
+EOF;
+
+ if ($testmode && !$sock)
+ $part4 = "<tr><td class='warning'>The gpsd instance that this page monitors is not running.</td></tr>";
+ else {
+ $fix = $GPS['tpv'][0];
+ $sky = $GPS['sky'][0];
+ $sats = $sky['satellites'];
+
+ $nsv = count($sats);
+ $ts = $fix['time'];
+ $sat = '';
+ foreach($sats as $s)
+ $sat .= sprintf(
+ "\t<tr><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%s</td></tr>\n",
+ $s['PRN'], $s['el'], $s['az'], $s['ss'], $s['used'] ? 'Y' : 'N'
+ );
+ $part4 = <<<EOF
+<!-- ------------------------------------------------------------ -->
+<tr><td align=center valign=top>
+ <table border=1>
+ <tr><th colspan=2 align=center>Current Information</th></tr>
+ <tr><td>Time (UTC)</td><td>{$ts}</td></tr>
+ <tr><td>Latitude</td><td>{$fix['lat']}</td></tr>
+ <tr><td>Longitude</td><td>{$fix['lon']}</td></tr>
+ <tr><td>Altitude</td><td>{$fix['alt']}</td></tr>
+ <tr><td>Fix Type</td><td>{$fix['mode']}</td></tr>
+ <tr><td>Satellites</td><td>{$nsv}</td></tr>
+ <tr><td>HDOP</td><td>{$sky['hdop']}</td></tr>
+ <tr><td>VDOP</td><td>{$sky['vdop']}</td></tr>
+ </table>
+ <br/>
+ <table border=1>
+ <tr><th colspan=5 align=center>Current Satellites</th></tr>
+ <tr><th>PRN</th><th>Elevation</th><th>Azimuth</th><th>SS</th><th>Used</th></tr>
+$sat </table>
+</td></tr>
+
+<!-- raw response:
+{$resp}
+-->
+EOF;
+ }
+
+ $part5 = <<<EOF
+
+</table>
+</center>
+{$footer}
+<hr/>
+<p class="administrivia">This script is distributed by the
+<a href="@WEBSITE@">GPSD project</a>.</p>
+
+</body>
+</html>
+EOF;
+
+print $part1 . $part2 . $part3 . $part4 . $part5;
+
+}
+
+function write_json($resp){
+ header('Content-Type: text/javascript');
+ if (isset($_GET['jsonp']))
+ print "{$_GET['jsonp']}({$resp})";
+ else
+ print $resp;
+}
+
+function write_config(){
+ $f = fopen("gpsd_config.inc", "a");
+ if (!$f)
+ die("can't generate prototype config file. try running this script as root in DOCUMENT_ROOT");
+
+ $buf = <<<EOB
+<?PHP
+\$title = 'My GPS Server';
+\$server = 'localhost';
+#\$advertise = 'localhost';
+\$port = 2947;
+\$autorefresh = 0; # number of seconds after which to refresh
+\$googlemap = 0; # set to 1 if you want to have a google map
+\$gmap_key = 'GetYourOwnGoogleKey'; # your google API key goes here
+\$swap_ew = 0; # set to 1 if you don't understand projections
+\$open = 0; # set to 1 to show the form to change the GPSd server
+
+## You can read the header, footer and blurb from a file...
+# \$head = file_get_contents('/path/to/header.inc');
+# \$body = file_get_contents('/path/to/body.inc');
+# \$footer = file_get_contents('/path/to/footer.hinc');
+# \$blurb = file_get_contents('/path/to/blurb.inc');
+
+## ... or you can just define them here
+\$head = '';
+\$body = '';
+\$footer = '';
+\$blurb = <<<EOT
+This is a
+<a href="@WEBSITE@">gpsd</a>
+server <blink><font color="red">located someplace</font></blink>.
+
+The hardware is a
+<blink><font color="red">hardware description and link</font></blink>.
+
+This machine is maintained by
+<a href="mailto:you@example.com">Your Name Goes Here</a>.<br/>
+EOT;
+
+?>
+
+EOB;
+ fwrite($f, $buf);
+ fclose($f);
+}
+
+function gen_gmap_head() {
+global $gmap_key;
+return <<<EOT
+<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key={$gmap_key}" type="text/javascript"></script>
+<script type="text/javascript">
+<!--
+// Create a base icon for all of our markers that specifies the shadow, icon
+// dimensions, etc.
+function Load() {
+ if (GBrowserIsCompatible()) {
+ var map = new GMap2(document.getElementById("map"));
+ var point = new GLatLng( {$GLOBALS['lat']}, {$GLOBALS['lon']} );
+ map.setCenter( point, 14);
+ map.addControl(new GLargeMapControl());
+ map.addControl(new GMapTypeControl());
+
+ var baseIcon = new GIcon();
+ baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
+ baseIcon.iconSize = new GSize(20, 34);
+ baseIcon.shadowSize = new GSize(37, 34);
+ baseIcon.iconAnchor = new GPoint(9, 34);
+ baseIcon.infoWindowAnchor = new GPoint(9, 2);
+ baseIcon.infoShadowAnchor = new GPoint(18, 25);
+
+ var icon = new GIcon(baseIcon);
+ icon.image = "http://www.google.com/mapfiles/marker.png";
+ var marker = new GMarker(point, icon);
+ map.addOverlay(marker);
+ }
+}
+-->
+</script>
+EOT;
+
+}
+
+function gen_gmap_code() {
+return <<<EOT
+<br/>
+<div id="map" style="width: 550px; height: 400px; border:1px; border-style: solid;">
+ Loading...
+ <noscript>
+ <span class='warning'>Sorry: you must enable javascript to view our maps.</span><br/>
+ </noscript>
+</div>
+
+EOT;
+}
+
+?>