Search code examples
google-maps-api-3kmlinfowindow

Google maps KML InfoWindow not rendering


I am using the Google Maps API v3 to call a KML file into a Google map. This is something that has been working for me for some time, with simple polygons and custom icons (map pins). I now want to enhance my implementation to add InfoWindows that should open when the icon is clicked.

In my test kml file, I have 1 polygon and two icons, each contained in a placemark. Each placemark has an associated style. The two icons each have a BalloonStyle that will display relevant text in an associated InfoWindow. The two icons are to be rendered within the polygon.

All three items render correctly and the kmlStatus comes back as 'OK'. However, the InfoWindow opens fine on the first pin (Style id="destPin"), but not the second (Style id="tractPin1").

I have researched this for 2 days on https://developers.google.com/maps/documentation/javascript/ and other relevant sites; so I am starting to think that this is either a profound lack of understanding on my part, or some quirk of the Google KML implementation.

Here is the .KML file:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
    <Document>
        <name>example26.kml</name>
        <Style id="destPin">
            <IconStyle>
                <Icon>
                    <href>https://example.com/dest_marker.png</href>
                </Icon>
            </IconStyle>
            <BalloonStyle>
                <text><![CDATA[$[address]]]></text>
            </BalloonStyle>
        </Style>

        <Style id="tractPin1">
            <IconStyle>
                <Icon>
                    <href>https://example.com/pin_1.png</href>
                </Icon>
            </IconStyle>
            <BalloonStyle>
                <text><![CDATA[Census Tract $[name] <HR> $[description]]]></text>
            </BalloonStyle>
        </Style>

        <Style id="tractPoly">
            <LineStyle>
                <color>64000000</color>
                <width>2</width>
            </LineStyle>
            <PolyStyle>
                <color>50F00014</color>
                <fill>1</fill>
                <outline>1</outline>
            </PolyStyle>
        </Style>

        <Placemark>
            <name>Census Tract 322.14</name>
            <styleUrl>#tractPoly</styleUrl>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>-122.026918,47.588168,0 -122.014066,47.588019,0 -122.00872,47.587924,0 -122.008683,47.595191,0 -122.008679,47.596783,0 -122.008692,47.596982,0 -122.007825,47.601505,0 -122.007278,47.60524,0 -122.005975,47.609314,0 -122.005302,47.61252,0 -122.004694,47.616446,0 -122.013867,47.616726,0 -122.035479,47.616536,0 -122.035478,47.605487,0 -122.035514,47.601784,0 -122.035438,47.595471,0 -122.035458,47.59174,0 -122.035448,47.588478,0 -122.035455,47.588268,0 -122.026918,47.588168,0 </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>

        <Placemark>
            <address>destination address, WA</address>
            <styleUrl>#destPin</styleUrl>
            <Point>
                <coordinates>-122.03388,47.6142212,0</coordinates>
            </Point>
        </Placemark>

        <Placemark>
            <name>322.14</name>
            <description>2010 Census Population 6264 - 2015 Population Estimate 6867</description>
            <styleUrl>#tractPin1</styleUrl>
            <Point>
                <coordinates>-122.022,47.603,0</coordinates>
            </Point>
        </Placemark>

    </Document>
</kml>

...and here is the javascript that submits the KML to Google.

    // Displays the map for a given kml file
    function displayMap(kmlFile) {

        var mapOptions = {
            position: mapCenter,
            mapTypeControl: true,
            mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
            navigationControl: true,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
        infowindow = new google.maps.InfoWindow({}); // copied from geocodezip

        var kmlOptions = {
            //suppressInfoWindows: false,
            preserveViewport: false
            //map: map
        };

        kmlLayer = new google.maps.KmlLayer(kmlFile, kmlOptions);

        google.maps.event.addListener(kmlLayer, "status_changed", function() {
            console.log('KML status = ', kmlLayer.getStatus());
        });

        kmlLayer.setMap(map);  // this is copied from geocodezip

    } // end of function displayMap

Solution

  • Turns out I had a bug in my code that rendered the map.

    The mapOptions object:

    var mapOptions = {
        position: mapCenter,
        mapTypeControl: true,
        mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
        navigationControl: true,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    

    ...contains an error in the line:

       position: mapCenter,
    

    ...which should actually be:

      center: mapCenter,
    

    The strange thing was that the map rendered OK, along with the kmlLayer. Also, the first map pin displays its infoWindow, but that simple error somehow prevents the other placemarks from rendering their infoWindows. Just that simple oversight cost me a ton of time; not to mention 2 reputation.