Convert KML file to GeoJSON

Hi - I'm trying to import a kml file (a polygon) from Google Maps and convert it to a GeoJSON format using:

Here's my JS code:

var file = fileDropzoneTerritories.value;
var kml = (new DOMParser()).parseFromString(file, 'text/xml');

var converted = toGeoJSON.kml(kml);

return converted;

Here's the contents of the KML file exported from Google Maps that is being uploaded in a file dropzone element:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <name>Territory Border</name>
    <Style id="poly-795548-6601-33-nodesc-normal">
      <LineStyle>
        <color>ff485579</color>
        <width>6.601</width>
      </LineStyle>
      <PolyStyle>
        <color>21485579</color>
        <fill>1</fill>
        <outline>1</outline>
      </PolyStyle>
      <BalloonStyle>
        <text><![CDATA[<h3>$[name]</h3>]]></text>
      </BalloonStyle>
    </Style>
    <Style id="poly-795548-6601-33-nodesc-highlight">
      <LineStyle>
        <color>ff485579</color>
        <width>9.9015</width>
      </LineStyle>
      <PolyStyle>
        <color>21485579</color>
        <fill>1</fill>
        <outline>1</outline>
      </PolyStyle>
      <BalloonStyle>
        <text><![CDATA[<h3>$[name]</h3>]]></text>
      </BalloonStyle>
    </Style>
    <StyleMap id="poly-795548-6601-33-nodesc">
      <Pair>
        <key>normal</key>
        <styleUrl>#poly-795548-6601-33-nodesc-normal</styleUrl>
      </Pair>
      <Pair>
        <key>highlight</key>
        <styleUrl>#poly-795548-6601-33-nodesc-highlight</styleUrl>
      </Pair>
    </StyleMap>
    <Placemark>
      <name>Shadow Hills English</name>
      <styleUrl>#poly-795548-6601-33-nodesc</styleUrl>
      <Polygon>
        <outerBoundaryIs>
          <LinearRing>
            <tessellate>1</tessellate>
            <coordinates>
              -118.4156697,34.238932,0
              -118.4098761,34.233823,0
              -118.4094469,34.2322619,0
              -118.4093611,34.2307007,0
              -118.4098761,34.2268686,0
              -118.4110777,34.226017,0
              -118.4102194,34.2217589,0
              -118.4326643,34.2216879,0
              -118.4323209,34.2201621,0
              -118.4318059,34.2195233,0
              -118.4310871,34.2185297,0
              -118.4308404,34.217607,0
              -118.4307975,34.2098882,0
              -118.430937,34.209103,0
              -118.4310979,34.2081935,0
              -118.4312052,34.2058778,0
              -118.4311193,34.1939871,0
              -118.4231049,34.1939345,0
              -118.4170644,34.1939347,0
              -118.4024518,34.1938983,0
              -118.4031813,34.198282,0
              -118.4038679,34.2011926,0
              -118.3995122,34.2011039,0
              -118.3978598,34.2008377,0
              -118.3964437,34.2006424,0
              -118.3964651,34.2012991,0
              -118.3935684,34.2007489,0
              -118.3702223,34.1961878,0
              -118.3702438,34.2011394,0
              -118.3623367,34.2011927,0
              -118.362004,34.2012813,0
              -118.3628624,34.2067828,0
              -118.3536679,34.2066728,0
              -118.3528635,34.2066692,0
              -118.3518982,34.2066618,0
              -118.3510835,34.2066116,0
              -118.3461496,34.2065463,0
              -118.341732,34.2064864,0
              -118.3414798,34.2065617,0
              -118.3406751,34.2062687,0
              -118.3396666,34.20586,0
              -118.3404947,34.209571,0
              -118.3398637,34.2097684,0
              -118.3398034,34.2102697,0
              -118.339511,34.2104915,0
              -118.3386688,34.2107222,0
              -118.3380572,34.2108287,0
              -118.3366839,34.2143776,0
              -118.3365444,34.2154156,0
              -118.3362977,34.2157084,0
              -118.3354394,34.2165335,0
              -118.334667,34.2172521,0
              -118.3353751,34.2184587,0
              -118.3365766,34.2204814,0
              -118.3355467,34.2360937,0
              -118.3573262,34.2470206,0
              -118.3573209,34.2494416,0
              -118.357337,34.2527139,0
              -118.3573263,34.2585136,0
              -118.3576136,34.2588611,0
              -118.3577937,34.259315,0
              -118.3578104,34.2596553,0
              -118.3577152,34.2603004,0
              -118.3577394,34.2607393,0
              -118.3578306,34.2611206,0
              -118.35797,34.2613866,0
              -118.3582061,34.2617059,0
              -118.3591234,34.261462,0
              -118.3597832,34.2613955,0
              -118.3604591,34.2614044,0
              -118.3617338,34.2616588,0
              -118.3625579,34.261789,0
              -118.3639487,34.2620495,0
              -118.3650564,34.2622158,0
              -118.3656841,34.2621581,0
              -118.3664673,34.2621493,0
              -118.3673933,34.2619833,0
              -118.3679546,34.261835,0
              -118.3684763,34.2616095,0
              -118.3690476,34.2613712,0
              -118.3695465,34.2610719,0
              -118.3700722,34.2606862,0
              -118.3705656,34.2602694,0
              -118.3711064,34.2596558,0
              -118.3714754,34.259131,0
              -118.3718272,34.2585069,0
              -118.3719729,34.2579682,0
              -118.3721355,34.2573165,0
              -118.3722032,34.2565095,0
              -118.3722528,34.2559597,0
              -118.3724379,34.2553212,0
              -118.3726792,34.2545409,0
              -118.3730655,34.254266,0
              -118.3739452,34.2536275,0
              -118.3752435,34.2526609,0
              -118.3771747,34.2512775,0
              -118.378253,34.2504571,0
              -118.379224,34.249761,0
              -118.3794607,34.2496083,0
              -118.3796008,34.2495975,0
              -118.3798596,34.2497355,0
              -118.380034,34.2494262,0
              -118.3802754,34.2490559,0
              -118.3805651,34.2487766,0
              -118.3812303,34.248342,0
              -118.3818311,34.247872,0
              -118.3838051,34.2464442,0
              -118.38815,34.2504793,0
              -118.3906124,34.2529003,0
              -118.3918919,34.2540842,0
              -118.3932036,34.255339,0
              -118.4032146,34.2482003,0
              -118.4156697,34.238932,0
            </coordinates>
          </LinearRing>
        </outerBoundaryIs>
      </Polygon>
    </Placemark>
  </Document>
</kml>

Hey @finedesignz!

In order to use toGeoJSON you'll want to first make sure it's imported as a library. Having done some testing it looks as though the following cdnjs link should work for that https://cdnjs.cloudflare.com/ajax/libs/togeojson/0.16.0/togeojson.min.js.

You'll also want to turn on "Parse files" on your button component:

And then reference the string stored in the parsedValue array so as to reference the string and not the base-64 data:

Let me know if that ends up working for you as well or if you run into any trouble!

Thank you! I believe I have mirrored your configuration and am now loading the toGeoJSON library. The js seems to be processing the file as I'm getting no errors.

However, unlike your results, I'm getting zero features returned in the output. I've tested multiple kml files and all produce the same results.

Any thoughts?

I'm curious if you see the same thing when hardcoding the string into the JS query. Can you try copying this and seeing if that works?

var file = `<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
 <Document>
 <name>Territory Border</name>
 <Style id="poly-795548-6601-33-nodesc-normal">
 <LineStyle>
 <color>ff485579</color>
 <width>6.601</width>
 </LineStyle>
 <PolyStyle>
 <color>21485579</color>
 <fill>1</fill>
 <outline>1</outline>
 </PolyStyle>
 <BalloonStyle>
 <text><![CDATA[<h3>$[name]</h3>]]></text>
 </BalloonStyle>
 </Style>
 <Style id="poly-795548-6601-33-nodesc-highlight">
 <LineStyle>
 <color>ff485579</color>
 <width>9.9015</width>
 </LineStyle>
 <PolyStyle>
 <color>21485579</color>
 <fill>1</fill>
 <outline>1</outline>
 </PolyStyle>
 <BalloonStyle>
 <text><![CDATA[<h3>$[name]</h3>]]></text>
 </BalloonStyle>
 </Style>
 <StyleMap id="poly-795548-6601-33-nodesc">
 <Pair>
 <key>normal</key>
 <styleUrl>#poly-795548-6601-33-nodesc-normal</styleUrl>
 </Pair>
 <Pair>
 <key>highlight</key>
 <styleUrl>#poly-795548-6601-33-nodesc-highlight</styleUrl>
 </Pair>
 </StyleMap>
 <Placemark>
 <name>Shadow Hills English</name>
 <styleUrl>#poly-795548-6601-33-nodesc</styleUrl>
 <Polygon>
 <outerBoundaryIs>
 <LinearRing>
 <tessellate>1</tessellate>
 <coordinates>
 -118.4156697,34.238932,0
 -118.4098761,34.233823,0
 -118.4094469,34.2322619,0
 -118.4093611,34.2307007,0
 -118.4098761,34.2268686,0
 -118.4110777,34.226017,0
 -118.4102194,34.2217589,0
 -118.4326643,34.2216879,0
 -118.4323209,34.2201621,0
 -118.4318059,34.2195233,0
 -118.4310871,34.2185297,0
 -118.4308404,34.217607,0
 -118.4307975,34.2098882,0
 -118.430937,34.209103,0
 -118.4310979,34.2081935,0
 -118.4312052,34.2058778,0
 -118.4311193,34.1939871,0
 -118.4231049,34.1939345,0
 -118.4170644,34.1939347,0
 -118.4024518,34.1938983,0
 -118.4031813,34.198282,0
 -118.4038679,34.2011926,0
 -118.3995122,34.2011039,0
 -118.3978598,34.2008377,0
 -118.3964437,34.2006424,0
 -118.3964651,34.2012991,0
 -118.3935684,34.2007489,0
 -118.3702223,34.1961878,0
 -118.3702438,34.2011394,0
 -118.3623367,34.2011927,0
 -118.362004,34.2012813,0
 -118.3628624,34.2067828,0
 -118.3536679,34.2066728,0
 -118.3528635,34.2066692,0
 -118.3518982,34.2066618,0
 -118.3510835,34.2066116,0
 -118.3461496,34.2065463,0
 -118.341732,34.2064864,0
 -118.3414798,34.2065617,0
 -118.3406751,34.2062687,0
 -118.3396666,34.20586,0
 -118.3404947,34.209571,0
 -118.3398637,34.2097684,0
 -118.3398034,34.2102697,0
 -118.339511,34.2104915,0
 -118.3386688,34.2107222,0
 -118.3380572,34.2108287,0
 -118.3366839,34.2143776,0
 -118.3365444,34.2154156,0
 -118.3362977,34.2157084,0
 -118.3354394,34.2165335,0
 -118.334667,34.2172521,0
 -118.3353751,34.2184587,0
 -118.3365766,34.2204814,0
 -118.3355467,34.2360937,0
 -118.3573262,34.2470206,0
 -118.3573209,34.2494416,0
 -118.357337,34.2527139,0
 -118.3573263,34.2585136,0
 -118.3576136,34.2588611,0
 -118.3577937,34.259315,0
 -118.3578104,34.2596553,0
 -118.3577152,34.2603004,0
 -118.3577394,34.2607393,0
 -118.3578306,34.2611206,0
 -118.35797,34.2613866,0
 -118.3582061,34.2617059,0
 -118.3591234,34.261462,0
 -118.3597832,34.2613955,0
 -118.3604591,34.2614044,0
 -118.3617338,34.2616588,0
 -118.3625579,34.261789,0
 -118.3639487,34.2620495,0
 -118.3650564,34.2622158,0
 -118.3656841,34.2621581,0
 -118.3664673,34.2621493,0
 -118.3673933,34.2619833,0
 -118.3679546,34.261835,0
 -118.3684763,34.2616095,0
 -118.3690476,34.2613712,0
 -118.3695465,34.2610719,0
 -118.3700722,34.2606862,0
 -118.3705656,34.2602694,0
 -118.3711064,34.2596558,0
 -118.3714754,34.259131,0
 -118.3718272,34.2585069,0
 -118.3719729,34.2579682,0
 -118.3721355,34.2573165,0
 -118.3722032,34.2565095,0
 -118.3722528,34.2559597,0
 -118.3724379,34.2553212,0
 -118.3726792,34.2545409,0
 -118.3730655,34.254266,0
 -118.3739452,34.2536275,0
 -118.3752435,34.2526609,0
 -118.3771747,34.2512775,0
 -118.378253,34.2504571,0
 -118.379224,34.249761,0
 -118.3794607,34.2496083,0
 -118.3796008,34.2495975,0
 -118.3798596,34.2497355,0
 -118.380034,34.2494262,0
 -118.3802754,34.2490559,0
 -118.3805651,34.2487766,0
 -118.3812303,34.248342,0
 -118.3818311,34.247872,0
 -118.3838051,34.2464442,0
 -118.38815,34.2504793,0
 -118.3906124,34.2529003,0
 -118.3918919,34.2540842,0
 -118.3932036,34.255339,0
 -118.4032146,34.2482003,0
 -118.4156697,34.238932,0
 </coordinates>
 </LinearRing>
 </outerBoundaryIs>
 </Polygon>
 </Placemark>
 </Document>
</kml>`;
var kml = (new DOMParser()).parseFromString(file, 'text/xml');

var converted = toGeoJSON.kml(kml);

return converted;

Along that same line I'd also be curious to see what fileButtonTerritory.parsedValue[0] looks like in your left panel browser.

Thanks again for the reply. Putting the XML directly in the code worked.

fileButtonTerritory.parsedValue[0] is returning null. :face_with_monocle:

Hmm.. would you mind uploading a screenshot of fileButtonTerritory expanded in the left panel after uploading a kml file? Curious to see what value and parsedValue are showing there.

Sorry for the delay. Here's what I see on the left.

value expanded:

parsedValue expanded:

Just tried downloading a kml file directly from Google and it appears Retool isn't parsing that correctly for some reason :thinking: can you try the following?

var file = fileButton1.value[0];
var parsedFile = atob(file);
var kml = (new DOMParser()).parseFromString(parsedFile, 'text/xml');

var converted = toGeoJSON.kml(kml);

return converted;

This takes the base64 string directly and adds an additional layer of parsing with atob

That worked! Thanks Kabirdas!