chrispaton
asked on
Create XML source from mySQL to populate Google Maps
Hi,
I am trying to populate a google map nested within my website page to display a number of different markers from an XML source which I have working.
What I want to do is create the XML source on the fly from a mySQL database without having to create the file everytime the page is called as the map will be on shown on different pages with different markers. I have tried to use XML Serialisation to create the XML but cannot find away to create and use the XML without creating the file.
Here is the xml source that is used to populate the map that I need to create;
<markers>
<marker name="House 2" content="Blah Blah Blah" lat="47.608940" lng="-122.340141" type="house" />
<marker name="House 2" content="Blah Blah Blah" lat="47.613590" lng="-122.344391" type="house" />
</markers>
I have the name, content, lat, lng and type fields in the database.
Thanks
Chris
I am trying to populate a google map nested within my website page to display a number of different markers from an XML source which I have working.
What I want to do is create the XML source on the fly from a mySQL database without having to create the file everytime the page is called as the map will be on shown on different pages with different markers. I have tried to use XML Serialisation to create the XML but cannot find away to create and use the XML without creating the file.
Here is the xml source that is used to populate the map that I need to create;
<markers>
<marker name="House 2" content="Blah Blah Blah" lat="47.608940" lng="-122.340141" type="house" />
<marker name="House 2" content="Blah Blah Blah" lat="47.613590" lng="-122.344391" type="house" />
</markers>
I have the name, content, lat, lng and type fields in the database.
Thanks
Chris
You may want to look at it a little differently.
Instead of creating an XML file, try using a custom .NET control (free download) to populate with the results of your SQL query.
http://en.googlemaps.subgurim.net/
Using this free control, I created my own types and methods like "GoogleMap1.AddPushpin(lat ,long,name ,html)" inside a loop through the records in my query.
The documentation is very good with Subgurium, I suggest you take a look.
Instead of creating an XML file, try using a custom .NET control (free download) to populate with the results of your SQL query.
http://en.googlemaps.subgurim.net/
Using this free control, I created my own types and methods like "GoogleMap1.AddPushpin(lat
The documentation is very good with Subgurium, I suggest you take a look.
ASKER
I have changed your suggestion into asp which is a much easier method of creating the xml source than I was trying but when I use this as the source in the javascript for the Google Maps I receive a null error
Message: 'documentElement' is null or not an object
I have copied the xml text direct from the source file that is working and added this direct to the javascript as var xmlsource to see where the error is and it also fails with the same error, the only change I have made is to the here is the line 'var xml = xmlsource.responseXML; which was var xml = data.responseXML; with data being the url of the file
var xmlsource = '<markers><marker name="Pan Africa Market" address="1521 1st Ave, Seattle, WA" lat="47.608940" lng="-122.340141" type="restaurant" /><marker name="Buddha Thai & Bar" address="2222 2nd Ave, Seattle, WA" lat="47.613590" lng="-122.344391" type="bar" /><marker name="The Melting Pot" address="14 Mercer St, Seattle, WA" lat="47.624561" lng="-122.356445" type="restaurant" /><marker name="Ipanema Grill" address="1225 1st Ave, Seattle, WA" lat="47.606365" lng="-122.337654" type="restaurant" /><marker name="Sake House" address="2230 1st Ave, Seattle, WA" lat="47.612823" lng="-122.345673" type="bar" /><marker name="Crab Pot" address="1301 Alaskan Way, Seattle, WA" lat="47.605961" lng="-122.340363" type="restaurant" /><marker name="Mama&apos;s Mexican Kitchen" address="2234 2nd Ave, Seattle, WA" lat="47.613976" lng="-122.345467" type="bar" /><marker name="Wingdome" address="1416 E Olive Way, Seattle, WA" lat="47.617214" lng="-122.326584" type="bar" /><marker name="Piroshky Piroshky" address="1908 Pike pl, Seattle, WA" lat="47.610126" lng="-122.342834" type="restaurant" /></markers>';
Message: 'documentElement' is null or not an object
I have copied the xml text direct from the source file that is working and added this direct to the javascript as var xmlsource to see where the error is and it also fails with the same error, the only change I have made is to the here is the line 'var xml = xmlsource.responseXML; which was var xml = data.responseXML; with data being the url of the file
var xmlsource = '<markers><marker name="Pan Africa Market" address="1521 1st Ave, Seattle, WA" lat="47.608940" lng="-122.340141" type="restaurant" /><marker name="Buddha Thai & Bar" address="2222 2nd Ave, Seattle, WA" lat="47.613590" lng="-122.344391" type="bar" /><marker name="The Melting Pot" address="14 Mercer St, Seattle, WA" lat="47.624561" lng="-122.356445" type="restaurant" /><marker name="Ipanema Grill" address="1225 1st Ave, Seattle, WA" lat="47.606365" lng="-122.337654" type="restaurant" /><marker name="Sake House" address="2230 1st Ave, Seattle, WA" lat="47.612823" lng="-122.345673" type="bar" /><marker name="Crab Pot" address="1301 Alaskan Way, Seattle, WA" lat="47.605961" lng="-122.340363" type="restaurant" /><marker name="Mama&apos;s Mexican Kitchen" address="2234 2nd Ave, Seattle, WA" lat="47.613976" lng="-122.345467" type="bar" /><marker name="Wingdome" address="1416 E Olive Way, Seattle, WA" lat="47.617214" lng="-122.326584" type="bar" /><marker name="Piroshky Piroshky" address="1908 Pike pl, Seattle, WA" lat="47.610126" lng="-122.342834" type="restaurant" /></markers>';
{
var xml = xmlsource.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = '<div id="content">' + '<div id="siteNotice">' + '</div>' + '<h3 id="firstHeading" class="firstHeading">Villa Name </h3>' + '<div id="bodyContent">' + '<img src="/images/map/villa.jpg" height="120" width="160"/><br /><b>Malaga, Costa del Sol</b><br />4 Star, Sleeps 6,' + '<p>Availability and Prices' + '</div>' + '</div>';
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({ map: map, position: point, icon: icon.icon, shadow: icon.shadow });
bindInfoWindow(marker, map, infoWindow, html);
}
ASKER
chrisrbloom - I have taken a look at this control but this only supports the v2 API and I wanted to use the latest v3.
I have tried to change the xml source string using XML DOM but still get the document Null element, the map loads ok but still no markers.
I have tried to change the xml source string using XML DOM but still get the document Null element, the map loads ok but still no markers.
var customIcons = { villa: { icon: '/images/map/villa.gif'} };
function load() {
geocoder = new google.maps.Geocoder();
var address = ("Address");
var map = new google.maps.Map(document.getElementById("map"),
{
center: new google.maps.LatLng(47.6145, -122.3418),
zoom: 12,
mapTypeId: 'roadmap'
});
{
var infoWindow = new google.maps.InfoWindow;
var text = '<markers><marker name="Pan Africa Market" address="1521 1st Ave, Seattle, WA" lat="47.608940" lng="-122.340141" type="restaurant" /></markers>';
if (window.DOMParser) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(text, "text/xml");
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(text);
}
var xml = xmlDoc.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = '<div id="content">' + '<div id="siteNotice">' + '</div>' + '<h3 id="firstHeading" class="firstHeading">Villa Name </h3>' + '<div id="bodyContent">' + '<img src="/images/map/villa.jpg" height="120" width="160"/><br /><b>Malaga, Costa del Sol</b><br />4 Star, Sleeps 6,' + '<p>Availability and Prices' + '</div>' + '</div>';
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({ map: map, position: point, icon: icon.icon, shadow: icon.shadow });
bindInfoWindow(marker, map, infoWindow, html);
}
};
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'mouseover',
function() { infoWindow.setContent(html); infoWindow.open(map, marker); });
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest; request.onreadystatechange = function() {
if (request.readyState == 4) { request.onreadystatechange = doNothing; callback(request, request.status); }
};
request.open('GET', url, true); request.send(null);
}
function doNothing() { }
This is PHP, so it is not really a good answer, but I can show you how I have done this using PHP and MySQL. The page is available here:
http://www.landonbaseball.com/site_visitors.php
The CREATE TABLE statement for visitors looks like this:
$sql
= "CREATE TABLE visitors
( _key INT NOT NULL AUTO_INCREMENT
, dov DATETIME
, lat DECIMAL(7,3) NOT NULL DEFAULT '0.0'
, lon DECIMAL(7,3) NOT NULL DEFAULT '0.0'
, PRIMARY KEY (_key)
, UNIQUE (lat, lon)
)"
;
http://www.landonbaseball.com/site_visitors.php
The CREATE TABLE statement for visitors looks like this:
$sql
= "CREATE TABLE visitors
( _key INT NOT NULL AUTO_INCREMENT
, dov DATETIME
, lat DECIMAL(7,3) NOT NULL DEFAULT '0.0'
, lon DECIMAL(7,3) NOT NULL DEFAULT '0.0'
, PRIMARY KEY (_key)
, UNIQUE (lat, lon)
)"
;
<?php // landonbaseball.com/site_visitors.php
require_once('header.php');
?>
<h3>LandonBaseball.com</h3>
<p>... was recently visited by folks from these locations: </p>
<?php
// MAKE A GOOGLE STATIC MAP OBJECT
$gsm = new GSM;
// DRAW THE LOCAL MAP
$gsm->setWidth(620);
$gsm->setHeight(400);
$gsm->setZoom(11);
// SET A CENTER POINT
$gsm->setCenter("Landon School, Bethesda, MD");
// GET THE LAT/LON PAIRS AND SET THE MARKERS
$sql = "SELECT lat, lon FROM visitors ORDER BY dov DESC LIMIT 30";
$res = mysql_query($sql);
if (!$res) die( mysql_error() );
while ($row = mysql_fetch_assoc($res))
{
$lat = $row["lat"];
$lon = $row["lon"];
// SET A MARKER ICON BY GEOCODE (LAT/LON PAIR)
$gsm->setMarker("$lat,$lon", 'orange', 'small', NULL);
}
// SET LANDON ICON LAST (ON TOP OF OTHER MARKERS)
$gsm->setIcon("Landon School, Bethesda, MD", 'http://www.landonbaseball.com/ikons/L32.png');
// ECHO THE <img /> TAG INTO OUR HTML TO DRAW THE MAP
echo $gsm->asIMG();
echo "<br/>" . PHP_EOL;
// END OF JOB
require_once('_footer.php');
die();
// DEFINE THE GOOGLE STATIC MAPPING CLASS
class GSM
{
// THE MAP CENTER GEOCODE, ADDRESS OR LANDMARK
protected $center;
// MARKER DATA ARRAY
protected $markers;
protected $default_icon;
// OUR VARIABLES FOR THE MAP DISPLAY
protected $maptype;
protected $width;
protected $height;
protected $zoom;
protected $format;
// OUR VARIABLES FOR THE GOOGLE URL AND IMAGE TAG
protected $alt;
protected $title;
protected $class;
protected $id;
protected $usemap;
protected $sensor;
protected $url;
private $img;
// A CONSTRUCTOR TO SET THE DEFAULT VALUES
public function __construct()
{
// THE URL AND IMG TAG PARAMETERS
$this->alt = FALSE;
$this->class = FALSE;
$this->id = FALSE;
$this->usemap = FALSE;
$this->sensor = FALSE;
$this->title = TRUE;
$this->url = '';
$this->img = '';
// THE CENTER AND ZOOM SCALE OF THE MAP (IF OMITTED, GOOGLE WILL CALCULATE)
$this->center = NULL;
$this->zoom = NULL;
// THE CHARACTERISTICS OF THE MAP IMAGE
$this->maptype = 'hybrid'; // CHOOSE
$this->maptype = 'terrain'; // AMONG
$this->maptype = 'satellite'; // THESE
$this->maptype = 'roadmap'; // OPTIONS
$this->width = '640';
$this->height = '640';
$this->format = 'png';
// THE DEFAULT ICON
$this->default_icon = 'http://maps.google.com/mapfiles/ms/micons/question.png';
// AN ARRAY OF MARKER ARRAYS
$this->clearMarkers();
} // END CONSTRUCTOR
// A METHOD TO CLEAR THE MARKERS
public function clearMarkers()
{
$this->markers = array();
}
// A SETTER TO ADD MARKERS TO THE MAP
public function setMarker($geocode, $color='blue', $size='normal', $label='X')
{
$this->markers[]
= array
( 'color' => $color
, 'label' => $label
, 'geocode' => $geocode
, 'size' => $size
, 'icon' => FALSE
)
;
}
// A SETTER TO ADD ICONS TO THE MAP - VIEW SOURCE HERE: http://www.visual-case.it/cgi-bin/vc/GMapsIcons.pl
public function setIcon($geocode, $icon=FALSE)
{
if (!$icon) $icon = $this->default_icon;
$this->markers[]
= array
( 'color' => FALSE
, 'label' => FALSE
, 'geocode' => $geocode
, 'icon' => $icon
)
;
}
// A SETTER TO OVERRIDE EACH OF THE DEFAULT VALUES
public function setCenter($geocode=NULL)
{
$this->center = $geocode;
}
public function setMaptype($x)
{
$this->maptype = $x;
}
public function setFormat($x)
{
$this->format = $x;
}
public function setWidth($x)
{
$this->width = $x;
}
public function setHeight($x)
{
$this->height = $x;
}
public function setZoom($x=NULL)
{
$this->zoom = $x;
}
public function setAlt($x=FALSE)
{
$this->alt = $x;
}
public function setTitle($x=TRUE)
{
$this->title = $x;
}
public function setClass($x=FALSE)
{
$this->class = $x;
}
public function setId($x=FALSE)
{
$this->id = $x;
}
public function setUsemap($x=FALSE)
{
$this->usemap = $x;
}
public function setSensor($x=FALSE)
{
$this->sensor = $x;
}
// A METHOD TO PREPARE AND RETRIEVE THE MAPPING URL
public function asURL()
{
$s = 'false'; // SEE http://code.google.com/apis/maps/documentation/staticmaps/#Sensor
if ($this->sensor) $s = 'true';
// IF ICONS OR MARKERS ARE ON THE MAP, 'IMPLODE' THE DATA INTO THE URL
$marker_string = '';
foreach ($this->markers as $marker)
{
// PROCESS FOR CUSTOM ICONS
if ($marker['icon'])
{
$marker_string
= $marker_string
. '&markers='
. 'icon:'
. urlencode($marker['icon'])
. '|'
. $marker['geocode']
;
continue;
}
// PROCESS FOR STANDARD MARKERS
$marker_string
= $marker_string
. '&markers='
. 'color:'
. $marker['color']
. '|'
. 'label:'
. $marker['label']
. '|'
. 'size:'
. $marker['size']
. '|'
. $marker['geocode']
;
}
// SET CENTER AND ZOOM, IF PRESENT
$c = '';
if ($this->center) $c = "¢er=$this->center";
$z = '';
if ($this->zoom) $z = "&zoom=$this->zoom";
// MAKE THE URL
$this->url
= "http://maps.google.com/maps/api/staticmap?sensor=$s"
. $c
. $z
. "&size=$this->width" . 'x' . "$this->height"
. "&format=$this->format"
. "&maptype=$this->maptype"
. "$marker_string"
;
return $this->url;
}
// A METHOD TO PREPARE AND RETRIEVE THE HTML IMAGE TAG
public function asIMG()
{
// GET THE URL
if (!$this->url) $this->url = $this->asURL();
// GET THE ALT TEXT
$a = "$this->maptype" . ' centered ' . "$this->center";
if ($this->alt !== FALSE) $a = $this->alt;
// REQUIRED FIELDS
$this->img = '<img src="' . $this->url . '" alt="' . $a . '"';
// OPTIONAL FIELDS - PROVIDE A DEFAULT TITLE
$t = "$this->maptype" . ' centered ' . "$this->center";
if ($this->title === TRUE ) { $this->img .= ' title="' . $t . '"'; }
elseif ($this->title !== FALSE) { $this->img .= ' title="' . $this->title . '"'; }
// OPTIONAL FIELDS MAY BE OMITTED
if ($this->class !== FALSE) { $this->img .= ' class="' . $this->class . '"'; }
if ($this->id !== FALSE) { $this->img .= ' id="' . $this->id . '"'; }
if ($this->usemap !== FALSE) { $this->img .= ' usemap="' . $this->usemap . '"'; }
// CLOSE THE IMAGE TAG AND CLEAR THE CONSUMED URL
$this->img .= ' />';
$this->url = FALSE;
return $this->img;
}
} // END CLASS
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi leakim971,
Thanks three great solutions, I have tried all three which all work perfectly in firefox and chrome but none work in ie, the map loads but no markers appear.
Thanks three great solutions, I have tried all three which all work perfectly in firefox and chrome but none work in ie, the map loads but no markers appear.
ASKER
Had a search and found a solution to the IE problem by adding this in,
var xmlDoc;
if (window.DOMParser) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(xml source, "text/xml");
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.X MLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(xmlsource);
}
all is now working.
var xmlDoc;
if (window.DOMParser) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(xml
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.X
xmlDoc.async = "false";
xmlDoc.loadXML(xmlsource);
}
all is now working.
ASKER
Thanks Leakim971, great solutions offered
I use PHP to create a sitemap.
First I select the information from mySQL
$sql = "SELECT name FROM `".$config_databaseTablePr
I then work on the XML structure and add in the fields from the SQL query.
foreach($rows as $row)
{
print "<sitemap>";
$sitemapHREF = "sitemap.php?supplier=".ur
print "<loc>".$sitemapBaseHREF.$
print "<lastmod>".date("Y-m-d",$
print "</sitemap>";
}
}
print "</sitemapindex>";
}