Passing XML markers to Google Map

2019-08-14 05:45发布

问题:

I've been creating a V3 Google map based on this example from Mike Williams http://www.geocodezip.com/v3_MW_example_linktomap.html

I've run into a bit of a problem though. If I have no parameters in my URL then I get the error "id is undefined idmarkers [id.toLowerCase()] = marker;" in Firebug and only one marker will show up. If I have a parameter (?id=105 for example) then all the sidebar links say 105 (or whatever the parameter in the URL was) instead of their respective label as listed in the XML file and a random infowindow will be opened instead of the window for the id in the URL. Here is my javascript:

        var map = null;
        var lastmarker = null;
                // ========== Read paramaters that have been passed in ==========

                // Before we go looking for the passed parameters, set some defaults
                // in case there are no parameters
        var id;
        var index = -1;

                // these set the initial center, zoom and maptype for the map 
                // if it is not specified in the query string
        var lat = 42.194741;
        var lng = -121.700301;
        var zoom = 18;
        var maptype = google.maps.MapTypeId.HYBRID;

        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;
        }
                // 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 == "marker") { index = parseFloat(value); }
            if (argname == "lat") { lat = parseFloat(value); }
            if (argname == "lng") { lng = parseFloat(value); }
            if (argname == "zoom") { zoom = parseInt(value); }
            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; }

            }
        }

                // this variable will collect the html which will eventually be placed in the side_bar 
        var side_bar_html = "";

                // arrays to hold copies of the markers and html used by the side_bar 
                // because the function closure trick doesnt work there 
        var gmarkers = [];
        var idmarkers = [];

                // global "map" variable
        var map = null;
        // A function to create the marker and set up the event window function 
        function createMarker(point, icon, label, html) {
            var contentString = html;
            var marker = new google.maps.Marker({
                position: point,
                map: map,
                title: label,
                icon: icon,
                zIndex: Math.round(point.lat() * -100000) << 5
            });
            marker.id = id;
            marker.index = gmarkers.length;
            google.maps.event.addListener(marker, 'click', function () {
                lastmarker = new Object;
                lastmarker.id = marker.id;
                lastmarker.index = marker.index;
                infowindow.setContent(contentString);
                infowindow.open(map, marker);
            });
            // save the info we need to use later for the side_bar
            gmarkers.push(marker);
            idmarkers[id.toLowerCase()] = marker;
            // add a line to the side_bar html
            side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length - 1) + ')">' + id + '<\/a><br>';
        }

                // This function picks up the click and opens the corresponding info window
        function myclick(i) {
            google.maps.event.trigger(gmarkers[i], "click");
        }

        function makeLink() {
            var mapinfo = "lat=" + map.getCenter().lat().toFixed(6)
                + "&lng=" + map.getCenter().lng().toFixed(6)
                    + "&zoom=" + map.getZoom()
                        + "&type=" + MapTypeId2UrlValue(map.getMapTypeId());
            if (lastmarker) {
                var a = "/about/map/default.aspx?id=" + lastmarker.id + "&" + mapinfo;
                var b = "/about/map/default.aspx?marker=" + lastmarker.index + "&" + mapinfo;
            } else {
                var a = "/about/map/default.aspx?" + mapinfo;
                var b = a;
            }

            document.getElementById("idlink").innerHTML = '<a href="' + a + '" id=url target=_new>- Link directly to this page by id</a> (id in xml file also entry &quot;name&quot; in sidebar menu)';
            document.getElementById("indexlink").innerHTML = '<a href="' + b + '" id=url target=_new>- Link directly to this page by index</a> (position in gmarkers array)';
        }


        function initialize() {
            // create the map
            var myOptions = {
                zoom: zoom,
                center: new google.maps.LatLng(lat, lng),
                mapTypeId: maptype,
                mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
                navigationControl: true,
                mapTypeId: google.maps.MapTypeId.HYBRID
            };
            map = new google.maps.Map(document.getElementById("map_canvas"),
                myOptions);
            var stylesarray = [
                {
                    featureType: "poi",
                    elementType: "labels",
                    stylers: [
                        { visibility: "off" }
                    ]
                },
                {
                    featureType: "landscape.man_made",
                    elementType: "labels",
                    stylers: [
                        { visibility: "off" }
                    ]
                }
            ];
            var options = map.setOptions({ styles: stylesarray });
            // 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);

            google.maps.event.addListener(map, 'click', function () {
                lastmarker = null;
                makeLink();
                infowindow.close();
            });
            // Read the data from example.xml
            downloadUrl("example.xml", function (doc) {
                var xmlDoc = xmlParse(doc);
                var markers = xmlDoc.documentElement.getElementsByTagName("marker");
                for (var i = 0; i < markers.length; i++) {
                    // obtain the attribues of each marker
                    var lat = parseFloat(markers[i].getAttribute("lat"));
                    var lng = parseFloat(markers[i].getAttribute("lng"));
                    var point = new google.maps.LatLng(lat, lng);
                    var html = markers[i].getAttribute("html");
                    var label = markers[i].getAttribute("label");
                    var icon = markers[i].getAttribute("icon");
                    // create the marker
                    var marker = createMarker(point, icon, label, html);
                }
                // put the assembled side_bar_html contents into the side_bar div
                document.getElementById("side_bar").innerHTML = side_bar_html;
                // ========= If a parameter was passed, open the info window ==========
                if (id) {
                    if (idmarkers[id]) {
                        google.maps.event.trigger(idmarkers[id], "click");
                    } else {
                        alert("id " + id + " does not match any marker");
                    }
                }
                if (index > -1) {
                    if (index < gmarkers.length) {
                        google.maps.event.trigger(gmarkers[index], "click");
                    } else {
                        alert("marker " + index + " does not exist");
                    }
                }
            });
        }

        var infowindow = new google.maps.InfoWindow(
            {
                size: new google.maps.Size(150, 50)
            });

        google.maps.event.addDomListener(window, "load", initialize);

And here is an example of my XML formatting

<marker lat="42.196175"
        lng="-121.699224"
        html="This is the information about 104"
        iconimage="/about/map/images/104.png"
        label="104" />

UPDATE: I've had a basic map working. What I'm trying to accomplish here is to be able to assign IDs to the markers so that specific markers can be triggered on page load from an external URL. It works on the example page. I've actually had it paritally working on my page (as long as I don't try to incorporate custom icons).

回答1:

As I tried to say. You have a global:

var id;

And the only place it seems to be set (or not) is from the query string. Yet when you loop thru your xml input you call createMarker() which uses that global id.

function createMarker(point, icon, label, html) {
        var contentString = html;
        var marker = new google.maps.Marker({
            position: point,
            map: map,
            title: label,
            icon: icon,
            zIndex: Math.round(point.lat() * -100000) << 5
        });
        marker.id = id;


 ....

Thus each marker gets the same id. If I was you I'd add the "id" to the xml file as another attribute and set it from there and use the query string id to only execute your selection logic.