Search code examples
google-maps-api-3geoxml3

geoXML3 "not a LatLngBounds" error in custom createPolygon function


I'm trying to use the createPolygon option of geoXML3.parser to customise how Polygon elements imported from my KML file are rendered on my map (Google maps api v3), but I'm getting an error in the console, and the map fails to load. Here's a minimal example.

<!DOCTYPE html>
<html>
<head>
    <title>GeoXML issue</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    <style>
        #map {
            height: 500px;
        }
    </style>

    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&key=#mykey#&libraries=places&sensor=false"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script type="text/javascript" src="/geoxml3/polys/geoxml3.js"></script>
    <script type="text/javascript" src="/geoxml3/ProjectedOverlay.js"></script>
</head>

<body>
    <script type="text/javascript">

    $(document).ready(function(){
        var map = new google.maps.Map(document.getElementById("map"), {
            zoom: 12,
            mapTypeId: 'roadmap'
        });
                    
      
        var geoXml = new geoXML3.parser({
            map: map,
            createPolygon: myPolygons,
            singleInfoWindow: true
        });

        geoXml.parse('myKml.kml');

        function myPolygons(p) {
            console.log("I'll do stuff here");
            geoXml.createPolygon(p);
            return p;
        }
    });

    </script>

    <div id="map"></div>
</body>

</html>

Here's my kml file

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
    <Folder>
        <description><![CDATA[My KML]]></description>
        <Placemark>
            <name><![CDATA[41400]]></name>
            <visibility>1</visibility>
            <open>0</open>
            <Style>
                <LineStyle>
                    <color>FF000000</color>
                    <width>1</width>
                </LineStyle>
                <PolyStyle>
                    <fill>1</fill>
                    <outline>1</outline>
                    <color>FFFFFFFF</color>
                </PolyStyle>
            </Style>
            <Polygon>
                <extrude>1</extrude>
                <altitudeMode>clampToGround</altitudeMode>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>-6.84733,53.360684,0
              -7.312225,53.32858,0
              -7.294876,53.294378,0
              -7.225435,53.195982,0
              -6.918459,53.183257,0
              -6.792612,53.201241,0
              -6.690876,53.292838,0
              -6.647491,53.293932,0
              -6.658125,53.344486,0
              -6.84733,53.360684,0</coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <name><![CDATA[41403]]></name>
            <visibility>1</visibility>
            <open>0</open>
            <Style>
                <LineStyle>
                    <color>FF000000</color>
                    <width>1</width>
                </LineStyle>
                <PolyStyle>
                    <fill>1</fill>
                    <outline>1</outline>
                    <color>FFFFFFFF</color>
                </PolyStyle>
            </Style>
            <Polygon>
                <extrude>1</extrude>
                <altitudeMode>clampToGround</altitudeMode>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>-7.717841,53.456508,0
              -7.389035,53.446422,0
              -6.892437,53.666006,0
              -6.967472,53.698911,0
              -7.082074,53.690988,0
              -7.46291,53.86158,0
              -7.650731,53.78538,0
              -7.740906,53.788201,0
              -7.717841,53.456508,0</coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <name><![CDATA[41402]]></name>
            <visibility>1</visibility>
            <open>0</open>
            <Style>
                <LineStyle>
                    <color>FF000000</color>
                    <width>1</width>
                </LineStyle>
                <PolyStyle>
                    <fill>1</fill>
                    <outline>1</outline>
                    <color>FFFFFFFF</color>
                </PolyStyle>
            </Style>
            <Polygon>
                <extrude>1</extrude>
                <altitudeMode>clampToGround</altitudeMode>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>-6.658178,53.525725,0
              -6.600668,53.530331,0
              -6.892437,53.666006,0
              -7.389035,53.446422,0
              -6.658178,53.525725,0</coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <name><![CDATA[41401]]></name>
            <visibility>1</visibility>
            <open>0</open>
            <Style>
                <LineStyle>
                    <color>FF000000</color>
                    <width>1</width>
                </LineStyle>
                <PolyStyle>
                    <fill>1</fill>
                    <outline>1</outline>
                    <color>FFFFFFFF</color>
                </PolyStyle>
            </Style>
            <Polygon>
                <extrude>1</extrude>
                <altitudeMode>clampToGround</altitudeMode>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>-7.389035,53.446422,0
              -7.312225,53.32858,0
              -6.84733,53.360684,0
              -6.658125,53.344486,0
              -6.620126,53.41344,0
              -6.570206,53.428354,0
              -6.562111,53.450037,0
              -6.658178,53.525725,0
              -7.389035,53.446422,0</coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>
</kml>

And here's a log of my console when the error happens

map_test2.php:39 I'll do stuff here
js?v=3&key=#mykey#&libraries=places&sensor=false:100 Uncaught ge {message: "not a LatLngBounds or LatLngBoundsLiteral: not an Object", name: "InvalidValueError", stack: "Error↵    at new ge (https://maps.googleapis.com/m…/michael.ran.ie/geoxml3/polys/geoxml3.js:1189:11)"}message: "not a LatLngBounds or LatLngBoundsLiteral: not an Object"name: "InvalidValueError"stack: "Error\n    at new ge (https://maps.googleapis.com/maps/api/js?v=3&key=#mykey#&libraries=places&sensor=false:78:72)\n    at Object._.he (https://maps.googleapis.com/maps/api/js?v=3&key=#mykey#&libraries=places&sensor=false:78:182)\n    at Object._.Tf (https://maps.googleapis.com/maps/api/js?v=3&key=#mykey#&libraries=places&sensor=false:100:120)\n    at _.Qf.union (https://maps.googleapis.com/maps/api/js?v=3&key=#mykey#&libraries=places&sensor=false:236:38)\n    at render (https://michael.ran.ie/geoxml3/polys/geoxml3.js:529:23)\n    at https://michael.ran.ie/geoxml3/polys/geoxml3.js:160:54\n    at XMLHttpRequest.xhrFetcher.fetcher.onreadystatechange (https://michael.ran.ie/geoxml3/polys/geoxml3.js:1189:11)"__proto__: Error
_.Tf @ js?v=3&key=#mykey#&libraries=places&sensor=false:100
_.Qf.union @ js?v=3&key=#mykey#&libraries=places&sensor=false:236
render @ geoxml3.js:529
(anonymous) @ geoxml3.js:160
xhrFetcher.fetcher.onreadystatechange @ geoxml3.js:1189
XMLHttpRequest.send (async)
geoXML3.fetchXML @ geoxml3.js:1196
fetchDoc @ geoxml3.js:160
parse @ geoxml3.js:155
(anonymous) @ map_test2.php:36
n @ jquery.min.js:2
fireWith @ jquery.min.js:2
ready @ jquery.min.js:2
B @ jquery.min.js:2

If I comment out the the createPolygon option, or indeed the geoXml.createPolygon(p) line in myPolygons, the map renders fine.

What's the issue here? Is my code wrong? Or the kml file?


Solution

  • The return value from your createPolygon function is not correct, you are throwing away the return value of the native geoXml.createPolygon function and returning the input arguement.

    Instead of:

    function myPolygons(p) {
      console.log("I'll do stuff here");
      geoXml.createPolygon(p);
      return p;
    }
    
    

    Return the result of the native createPolygon function (or create one of your own that returns a google.maps.Polygon with a bounds attribute):

    function myPolygons(p) {
      console.log("I'll do stuff here");
      return geoXml.createPolygon(p);;
    }
    

    or:

    function myPolygons(p) {
      console.log("I'll do stuff here");
      var polygon = geoXml.createPolygon(p);
      return polygon;
    }
    

    proof of concept fiddle

    code snippet:

    var kmlStr = '<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><Folder><description><![CDATA[My KML]]></description><Placemark><name><![CDATA[41400]]></name><visibility>1</visibility><open>0</open><Style><LineStyle><color>FF000000</color><width>1</width></LineStyle><PolyStyle><fill>1</fill><outline>1</outline><color>FFFFFFFF</color></PolyStyle></Style><Polygon><extrude>1</extrude><altitudeMode>clampToGround</altitudeMode><tessellate>1</tessellate><outerBoundaryIs><LinearRing><coordinates>-6.84733,53.360684,0 -7.312225,53.32858,0 -7.294876,53.294378,0 -7.225435,53.195982,0 -6.918459,53.183257,0 -6.792612,53.201241,0 -6.690876,53.292838,0 -6.647491,53.293932,0 -6.658125,53.344486,0 -6.84733,53.360684,0</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark><Placemark><name><![CDATA[41403]]></name><visibility>1</visibility><open>0</open><Style><LineStyle><color>FF000000</color><width>1</width></LineStyle><PolyStyle><fill>1</fill><outline>1</outline><color>FFFFFFFF</color></PolyStyle></Style><Polygon><extrude>1</extrude><altitudeMode>clampToGround</altitudeMode><tessellate>1</tessellate><outerBoundaryIs><LinearRing><coordinates>-7.717841,53.456508,0 -7.389035,53.446422,0 -6.892437,53.666006,0 -6.967472,53.698911,0 -7.082074,53.690988,0 -7.46291,53.86158,0 -7.650731,53.78538,0 -7.740906,53.788201,0 -7.717841,53.456508,0</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark><Placemark><name><![CDATA[41402]]></name><visibility>1</visibility><open>0</open><Style><LineStyle><color>FF000000</color><width>1</width></LineStyle><PolyStyle><fill>1</fill><outline>1</outline><color>FFFFFFFF</color></PolyStyle></Style><Polygon><extrude>1</extrude><altitudeMode>clampToGround</altitudeMode><tessellate>1</tessellate><outerBoundaryIs><LinearRing><coordinates>-6.658178,53.525725,0 -6.600668,53.530331,0 -6.892437,53.666006,0 -7.389035,53.446422,0 -6.658178,53.525725,0</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark><Placemark><name><![CDATA[41401]]></name><visibility>1</visibility><open>0</open><Style>eStyle><color>FF000000</color><width>1</width></LineStyle><PolyStyle><fill>1</fill><outline>1</outline><color>FFFFFFFF</color></PolyStyle></Style><Polygon><extrude>1</extrude><altitudeMode>clampToGround</altitudeMode><tessellate>1</tessellate><outerBoundaryIs><LinearRing><coordinates>-7.389035,53.446422,0 -7.312225,53.32858,0 -6.84733,53.360684,0 -6.658125,53.344486,0 -6.620126,53.41344,0 -6.570206,53.428354,0 -6.562111,53.450037,0 -6.658178,53.525725,0 -7.389035,53.446422,0</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark></Folder></kml>'
    /* Always set the map height explicitly to define the size of the div
           * element that contains the map. */
    #map {
      height: 100%;
    }
    
    /* Optional: Makes the sample page fill the window. */
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <!DOCTYPE html>
    <html>
    
      <head>
        <title>Simple Polygon</title>
        <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
        <!-- jsFiddle will insert css and js -->
        <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
        <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/geocodezip/geoxml3@master/polys/geoxml3.js"></script>
        <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/geocodezip/geoxml3@master/ProjectedOverlay.js"></script>
    
      </head>
    
      <body>
        <div id="map"></div>
        <script type="text/javascript">
          $(document).ready(function() {
            var map = new google.maps.Map(document.getElementById("map"), {
              zoom: 12,
              mapTypeId: 'roadmap'
            });
    
    
            var geoXml = new geoXML3.parser({
              map: map,
              createPolygon: myPolygons,
              singleInfoWindow: true
            });
            geoXml.parseKmlString(kmlStr);
    
            function myPolygons(p) {
              console.log("I'll do stuff here");
              return geoXml.createPolygon(p);;
            }
          });
    
        </script>
        <!-- Async script executes immediately and must be after any DOM elements used in callback. -->
    
      </body>
    
    </html>