Search code examples
xmlgoogle-maps-api-3google-maps-markerskmlpolygons

kml polygons and markers together


I have set up a map api v3 with my polygons (kml file) but now I would like to put the markers on the same map. Markers (lat, lang) are coming directly from MySQL database.

Here is a code of my page:

<?
require("markers/dbcon.php");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="css2.css" media="screen" />
    <title>StanOnline</title>

<style type="text/css">
  html, body, #map_canvas {
width:   100%;
height:  100%;
margin:  0;
padding: 0;
   }
.infowindow * {font-size: 90%; margin: 0}
 </style>

    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">
    </script>
    <script type="text/javascript" src="http://geoxml3.googlecode.com/svn/branches/polys/geoxml3.js">
    </script>
    <script type="text/javascript" src="http://geoxml3.googlecode.com/svn/trunk/ProjectedOverlay.js">
    </script>
    <script language="JavaScript">
<!--Show / Hide div dmenu-->
function toggle(id) {
    var state = document.getElementById(id).style.display;
        if (state == 'block') {
            document.getElementById(id).style.display = 'block';
        } else {
            document.getElementById(id).style.display = 'none';
        }
    } 
</script>


    <script type="text/javascript">

    var geoXml = null;
    var geoXmlDoc = null;
    var map = null;
    var myLatLng = null;
    var myGeoXml3Zoom = true;
    var sidebarHtml = "";
    var infowindow = null;
    var kmlLayer = null;
    var preserveViewport = true;
    var filename = "http://mini.hr/stanonline/mo_bck.kml";
    var icon = new            google.maps.MarkerImage("http://localhost/projekt/7stanonline/img/punkt.gif",
    new google.maps.Size(32, 32), new google.maps.Point(0, 0),
    new google.maps.Point(16, 32));
    var currentPopup;

    function addMarker(lat, lng, info) {
var pt = new google.maps.LatLng(lat, lng);
bounds.extend(pt);
var marker = new google.maps.Marker({
    position: pt,
    icon: icon,
map: map
});
     var popup = new google.maps.InfoWindow({ 
     content: info,
     maxWidth: 200
     });
   google.maps.event.addListener(marker, "click", function() {
   if (currentPopup != null) {
   currentPopup.close();
   currentPopup = null;
     }
   popup.open(map, marker);
   currentPopup = popup;
    });
    google.maps.event.addListener(popup, "closeclick", function() {
    map.panTo(center);
    currentPopup = null;
     });
     }


   function MapTypeId2UrlValue(maptype) {
        var urlValue = 'm';
    switch(maptype){
  case google.maps.MapTypeId.HYBRID:    urlValue='h';
                    break;
  case google.maps.MapTypeId.SATELLITE: urlValue='k';
                    break;
  case google.maps.MapTypeId.TERRAIN:   urlValue='t';
                   break;
  default:
  case google.maps.MapTypeId.ROADMAP:   urlValue='m';
                    break;
}
return urlValue;
}


function initialize() {
    myLatLng = new google.maps.LatLng(45.345537,14.439621);
  // these set the initial center, zoom and maptype for the map 
  // if it is not specified in the query string
  var lat = 45.345537;
  var lng = 14.439621;
  var zoom = 13;
  var maptype = google.maps.MapTypeId.ROADMAP;




  // If there are any parameters at eh end of the URL, they will be in  location.search
  // looking something like  "?marker=3"

  // skip the first character, we are not interested in the "?"
  var query = location.search.substring(1);

  // split the rest at each "&" character to give a list of  "argname=value"  pairs
  var pairs = query.split("&");
  for (var i=0; i<pairs.length; i++) {
    // break each pair at the first "=" to obtain the argname and value
var pos = pairs[i].indexOf("=");
var argname = pairs[i].substring(0,pos).toLowerCase();
var value = pairs[i].substring(pos+1).toLowerCase();

    // process each possible argname  -  use unescape() if theres any chance of spaces
    if (argname == "id") {id = unescape(value);}
    if (argname == "filename") {filename = unescape(value);}

    if (argname == "lat") {lat = parseFloat(value);}
    if (argname == "lng") {lng = parseFloat(value);}
    if (argname == "zoom") {
  zoom = parseInt(value);
  myGeoXml3Zoom = false;
}
    if (argname == "type") {
// from the v3 documentation 8/24/2010
// HYBRID This map type displays a transparent layer of major streets on satellite  images. 
// ROADMAP This map type displays a normal street map. 
// SATELLITE This map type displays satellite images. 
// TERRAIN This map type displays maps with physical features such as terrain and vegetation. 
      if (value == "m") {maptype = google.maps.MapTypeId.ROADMAP;}
      if (value == "k") {maptype = google.maps.MapTypeId.SATELLITE;}
      if (value == "h") {maptype = google.maps.MapTypeId.HYBRID;}
      if (value == "t") {maptype = google.maps.MapTypeId.TERRAIN;}

    }
  }
  if (!isNaN(lat) && !isNaN(lng)) {
    myLatLng = new google.maps.LatLng(lat, lng);
  }
            var myOptions = {
                zoom: zoom,
                center: myLatLng,
                // zoom: 5,
                // center: myLatlng,
                mapTypeId: maptype
            };
            map = new google.maps.Map(document.getElementById("map_canvas"),
                  myOptions);
            infowindow = new google.maps.InfoWindow({});

geoXml = new geoXML3.parser({
                map: map,
                infoWindow: infowindow,
                singleInfoWindow: true,
        zoom: myGeoXml3Zoom,

                afterParse: useTheData
            });

            geoXml.parse(filename);
    google.maps.event.addListener(map, "bounds_changed", makeSidebar);
    google.maps.event.addListener(map, "center_changed", makeSidebar);
    google.maps.event.addListener(map, "zoom_changed", makeSidebar);
  // Make the link the first time when the page opens
  makeLink();

  // Make the link again whenever the map changes
  google.maps.event.addListener(map, 'maptypeid_changed', makeLink);
  google.maps.event.addListener(map, 'center_changed', makeLink);
  google.maps.event.addListener(map, 'bounds_changed', makeLink);
  google.maps.event.addListener(map, 'zoom_changed', makeLink);
   <?
$query = mysql_query("SELECT * FROM poi_example");
while ($row = mysql_fetch_array($query)){
$name=$row['name'];
$lat=$row['lat'];
$lon=$row['lon'];
$desc=$row['desc'];
echo ("addMarker($lat, $lon,'<b>$name</b><br/>$desc');\n");
}
?>
center = bounds.getCenter();
  };

function kmlPgClick(pm) {
if (geoXml.docs[0].placemarks[pm].polygon.getMap()) {
  google.maps.event.trigger(geoXmlDoc.placemarks[pm].polygon,"click");
 } else {
  geoXmlDoc.placemarks[pm].polygon.setMap(map);
  google.maps.event.trigger(geoXmlDoc.placemarks[pm].polygon,"click");
 }  
 }
function kmlPlClick(pm) {
 if (geoXml.docs[0].placemarks[pm].polyline.getMap()) {
  google.maps.event.trigger(geoXmlDoc.placemarks[pm].polyline,"click");
 } else {
  geoXmlDoc.placemarks[pm].polyline.setMap(map);
  google.maps.event.trigger(geoXmlDoc.placemarks[pm].polyline,"click");
  }
 }

function kmlShowPlacemark(pm) {
 if (geoXmlDoc.placemarks[pm].polygon) {
map.fitBounds(geoXmlDoc.placemarks[pm].polygon.bounds);

} else if (geoXmlDoc.placemarks[pm].polyline) {
map.fitBounds(geoXmlDoc.placemarks[pm].polyline.bounds);
 }  


 for (var i=0;i<geoXmlDoc.placemarks.length;i++) {
 var placemark = geoXmlDoc.placemarks[i];
 if (i == pm) {
   if (placemark.polygon) placemark.polygon.setMap(null);
   if (placemark.polyline) placemark.polyline.setMap(map);

 } else {
   if (placemark.polygon) placemark.polygon.setMap(map);
   if (placemark.polyline) placemark.polyline.setMap(null);
   }
 }
 }

function kmlColor (kmlIn) {
  var kmlColor = {};
if (kmlIn) {
 aa = kmlIn.substr(0,2);
 bb = kmlIn.substr(2,2);
 gg = kmlIn.substr(4,2);
 rr = kmlIn.substr(6,2);
 kmlColor.color = "#" + rr + gg + bb;
 kmlColor.opacity = parseInt(aa,16)/256;
 } else {
// defaults
kmlColor.color = randomColor();
kmlColor.opacity = 0.45;
 }
return kmlColor;
 }

function randomColor(){ 
var color="#";
var colorNum = Math.random()*8388607.0;  // 8388607 = Math.pow(2,23)-1
var colorStr = colorNum.toString(16);
color += colorStr.substring(0,colorStr.indexOf('.'));
return color;
};

var highlightOptions = {fillColor: "#b9b8a2", strokeColor: "#000000", fillOpacity: 0.4,    strokeWidth: 10};
var highlightLineOptions = {strokeColor: "#000000", strokeWidth: 80};
function kmlHighlightPoly(pm) {
  for (var i=0;i<geoXmlDoc.placemarks.length;i++) {
 var placemark = geoXmlDoc.placemarks[i];
 if (i == pm) {
   if (placemark.polygon) placemark.polygon.setOptions(highlightOptions);
   if (placemark.polyline) placemark.polyline.setOptions(highlightLineOptions);
 } else {
   if (placemark.polygon) placemark.polygon.setOptions(placemark.polygon.normalStyle);
   if (placemark.polyline)      placemark.polyline.setOptions(placemark.polyline.normalStyle);
 }
 } 
 }
function kmlUnHighlightPoly(pm) {
  for (var i=0;i<geoXmlDoc.placemarks.length;i++) {
    if (i == pm) {
   var placemark = geoXmlDoc.placemarks[i];
   if (placemark.polygon) placemark.polygon.setOptions(placemark.polygon.normalStyle);
   if (placemark.polyline)        placemark.polyline.setOptions(placemark.polyline.normalStyle);
    }
 } 
 }


function showAll() {
 map.fitBounds(geoXmlDoc.bounds); //show all bounds
 map.setZoom(13);
for (var i=0;i<geoXmlDoc.placemarks.length;i++) {
 var placemark = geoXmlDoc.placemarks[i];
 if (placemark.polygon) placemark.polygon.setMap(map);
 if (placemark.polyline) placemark.polyline.setMap(map);

 }
 }

function highlightPoly(poly, polynum) {
//    poly.setOptions({fillColor: "#0000FF", strokeColor: "#0000FF", fillOpacity: 0.3}) ;
google.maps.event.addListener(poly,"mouseover",function() {
var rowElem = document.getElementById('row'+polynum);
if (rowElem) rowElem.style.backgroundColor = "#b9b8a2"; //ovo je boja u sidebar-u
if (poly instanceof google.maps.Polygon) {
  poly.setOptions(highlightOptions);
} else if (poly instanceof google.maps.Polyline) {
  poly.setOptions(highlightLineOptions);
}
});
google.maps.event.addListener(poly,"mouseout",function() {
var rowElem = document.getElementById('row'+polynum);
if (rowElem) rowElem.style.backgroundColor = ""; //pozadina nakon mouserover-a u  sidebar-u
poly.setOptions(poly.normalStyle);
});
 }  

// == rebuilds the sidebar to match the markers currently displayed ==
function makeSidebarPolygonEntry(i) {
var name = geoXmlDoc.placemarks[i].name;
if (!name  || (name.length == 0)) name = "polygon #"+i;
// alert(name);
sidebarHtml += '<tr id="row'+i+'"><td onmouseover="kmlHighlightPoly('+i+');"onmouseout="kmlUnHighlightPoly('+i+');"><a  href="javascript:kmlPgClick('+i+');">'+name+'</a> - <a     href="javascript:kmlShowPlacemark('+i+');">odaberi</a></td></tr>';

}
function makeSidebarPolylineEntry(i) {
var name = geoXmlDoc.placemarks[i].name;
if (!name  || (name.length == 0)) name = "polyline #"+i;
// alert(name);
sidebarHtml += '<tr id="row'+i+'"><td onmouseover="kmlHighlightPoly('+i+');"      onmouseout="kmlUnHighlightPoly('+i+');"><a    href="javascript:kmlPlClick('+i+');">'+name+'</a> - <a    href="javascript:kmlShowPlacemark('+i+');">show</a></td></tr>';

}


function makeSidebar() {
sidebarHtml = '<table><tr><td><a href="javascript:showAll();">Prika&#382i sve   kvartove</a></td></tr>';
 var currentBounds = map.getBounds();
// if bounds not yet available, just use the empty bounds object;
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
if (geoXmlDoc) {
 for (var i=0; i<geoXmlDoc.placemarks.length; i++) {
 if (geoXmlDoc.placemarks[i].polygon) {
  if (currentBounds.intersects(geoXmlDoc.placemarks[i].polygon.bounds)) {
     makeSidebarPolygonEntry(i);
  }
  }
  if (geoXmlDoc.placemarks[i].polyline) {
   if (currentBounds.intersects(geoXmlDoc.placemarks[i].polyline.bounds)) {
     makeSidebarPolylineEntry(i);
   }
  }

 }
 }
 sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
 }

function useTheData(doc){
var currentBounds = map.getBounds();
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
// Geodata handling goes here, using JSON properties of the doc object
 sidebarHtml = '<table><tr><td><a href="javascript:showAll();">Show All</a></td></tr>';
 //  var sidebarHtml = '<table>';
geoXmlDoc = doc[0];
for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
// console.log(doc[0].markers[i].title);
var placemark = geoXmlDoc.placemarks[i];
if (placemark.polygon) {
  if (currentBounds.intersects(placemark.polygon.bounds)) {
    makeSidebarPolygonEntry(i);
  }
  var kmlStrokeColor = kmlColor(placemark.style.color);
  var kmlFillColor = kmlColor(placemark.style.fillcolor);
  var normalStyle = {
      strokeColor: kmlStrokeColor.color,
      strokeWeight: placemark.style.width,
      strokeOpacity: kmlStrokeColor.opacity,
      fillColor: kmlFillColor.color,
      fillOpacity: kmlFillColor.opacity
      };
  placemark.polygon.normalStyle = normalStyle;

  highlightPoly(placemark.polygon, i);
 }
 if (placemark.polyline) {
  if (currentBounds.intersects(placemark.polyline.bounds)) {
     makeSidebarPolylineEntry(i);
  }
  var kmlStrokeColor = kmlColor(placemark.style.color);
  var normalStyle = {
      strokeColor: kmlStrokeColor.color,
      strokeWeight: placemark.style.width,
      strokeOpacity: kmlStrokeColor.opacity
      };
  placemark.polyline.normalStyle = normalStyle;

  highlightPoly(placemark.polyline, i);
}


/*    doc[0].markers[i].setVisible(false); */
}
sidebarHtml += "</table>";
document.getElementById("sidebar").innerHTML = sidebarHtml;
};


function hide_kml(){

        geoXml.hideDocument();  

}

function unhide_kml(){

        geoXml.showDocument();  

}
function reload_kml(){
geoXml.hideDocument();
delete geoXml;
geoXml = new geoXML3.parser({
                map: map,
                singleInfoWindow: true,
                afterParse: useTheData,
                preserveViewport: true
 });
 geoXml.parse(filename); 

}


 function hide_polys_kml(){
 for (var i=0;i<geoXmlDoc.gpolylines.length;i++) {
   geoXmlDoc.gpolylines[i].setMap(null);
 }
 }

function unhide_polys_kml(){
 for (var i=0;i<geoXmlDoc.gpolylines.length;i++) {
   geoXmlDoc.gpolylines[i].setMap(map);
  }
 }
 function load_kmlLayer() {
 kmlLayer = new google.maps.KmlLayer(filename);
 google.maps.event.addListener(kmlLayer, "status_changed", function() {
   document.getElementById('kmlstatus').innerHTML = "Kml Status:"+kmlLayer.getStatus();
 });
 kmlLayer.setMap(map);
 }
 function hide_kmlLayer() {
 kmlLayer.setMap(null);
 }
 function show_kmlLayer() {
 kmlLayer.setMap(map);
 }

    </script>
</head>
<body onload="initialize()">
    <div id="map_canvas" style="width:100%; height:100%"></div>

    <div id="dmenu">
        <div id="hidden"><a href="javascript:;" onclick="toggle('dmenu');">   <img src="img/x.png"></a></div>
        <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ODABERI KVART:
            <div id="sidebar">
    </div>
        </div>
            </div>
 </body>
</html>

I added this code to function initialize()

<?
$query = mysql_query("SELECT * FROM poi_example");
while ($row = mysql_fetch_array($query)){
$name=$row['name'];
$lat=$row['lat'];
$lon=$row['lon'];
$desc=$row['desc'];
echo ("addMarker($lat, $lon,'<b>$name</b><br/>$desc');\n");
}
?>
center = bounds.getCenter();

And added function addMarker which you can see in above code

Where is a mistake in code or is something missing ?


Solution

  • It is certainly possible to have polygons and markers on the same map.

    1. you shouldn't add your generated HTML as an "answer" to your question, you should edit your question to add it.
    2. You have javascript errors
      • there is no function makeLink
      • bounds is not defined.
    3. your addMarkers function doesn't define icon.

    The kml is good:

    http://www.geocodezip.com/geoxml3_test/v3_geoxml3_kmltest_linktoB.html?filename=http://www.geocodezip.com/geoxml3_test/mini_hr_stanonline_mo_bck.kml

    Fixing those errors makes it work for me