google-mapskmlarcgis-serverkmz

How to improve kml performance when dealing with too much data?


I had to write a tool to export our webmaps as KML as many users need that, initially we were using a service version that would just make image requests to the server, but our users needed the actual vectors downloaded.

So we end up with KML files of 20mb+ containing more than 30 thousand placemarks, google earth simply can't handle it, it is completely unusable in any of our computers.

Is there anything I can do while maintaining it as vectorial data (a hard, local copy of our serviced maps)?


Solution

  • A KML file with 30,000 placemarks is typically not too large for Google Earth to handle. For example, this tool generates a KMZ file with up to 25,000 placemarks for testing. A KML file created with up to 100,000 placemarks in Google Earth still works with little performance degradation. A sample of one of your KML files and/or a notional example of it could help identify the primary issue you're seeing. In any case, there are a number of techniques that can be employed in the design of KML to scale to large numbers.

    Google Earth can scale to a large number of features (50,000 or much larger) if the features are split into multiple KML files and the KML is defined such that all the sub-KML files are not displayed at once. KML provides mechanisms to control which features or sub-KML files are displayed using time, region, or altitude level filtering.

    Large KML files can scale using any of the following techniques:

    1. NetworkLinks
    2. Regions Folder
    3. Radio style or explicit visiblity=0

    NetworkLinks

    A NetworkLink provides a reference to another KML file either with a relative file reference or absolute URL. You can have any level of NetworkLinks from within your root KML file from flat (single KML file with many Networklinks to all other KML files) to deep (with each KML file with a NetworkLink to other KML files each with its own NetworkLinks). Depends on how you need to structure your KML and how large the data is.

    The key is that Google Earth chooses the first KML as the root KML file so you must ensure that the first file (typically named doc.kml) is the root KML file that loads the other KML files via network links. A common structure is to include additional KML files in a "kml" sub-folder to differentiate it from the root KML file.

    Here's a KMZ example with 4 file entries: root KML file (doc.kml) that contains a NetworkLink to "kml/sub1.kml" and another to "kml/sub2.kml", which in turn has a NetworkLink to "sub3.kml" also in "kml" sub-folder.

    == test.kmz ==
    
    +doc.kml
       NetworkLink > kml/sub1.kml
       NetworkLink > kml/sub2.kml
    +kml/sub1.kml
    +kml/sub2.kml
       NetworkLink > sub3.kml
    +kml/sub3.kml
    

    Here is the structure of such a doc.kml file:

    <?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2">
      <Document>
        <NetworkLink>
            <name>NetworkLinked sub-item</name>
            <Link>
              <href> kml/sub1.kml </href>
            </Link>
        </NetworkLink>
        <NetworkLink>
            <name>NetworkLinked sub-item</name>
            <Link>
              <href> kml/sub2.kml </href>
            </Link>
        </NetworkLink>
        ...
      </Document>
    </kml>
    

    Regions

    A Region affects visibility of a Placemark's geometry or an Overlay's image. Regions combined with NetworkLinks enables access to massive amounts of data in KML files. A region can optionally have a min and max altitude for altitude level filtering.

    For more details, here's a tutorial on Regions in KML https://developers.google.com/kml/documentation/regions

    Radio Folders

    You can further restrict what is displayed at a given time using radio folders.

    Here's a radio folder example allowing the user to only choose one of the NetworkLinks at a time. This is used when the content is mutually exclusive and only one set of features should appear at any given time.

    <?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2">
        <Document>
            <Style id="rf">
                <ListStyle>
                    <listItemType>radioFolder</listItemType>
                </ListStyle>
            </Style>
    
            <Folder>        
                <name>One at a time example</name>
                <open>1</open>
                <description>Link 1 visible by default</description>
                <styleUrl>#rf</styleUrl>
    
                <NetworkLink>
                    <name>NetworkLinked sub-item-1</name>
                    <Link>
                        <href> kml/sub1.kml </href>
                    </Link>
                </NetworkLink>
    
                <NetworkLink>
                    <name>NetworkLinked sub-item-2</name>
                    <visibility>0</visibility>
                    <Link>
                        <href> kml/sub2.kml </href>
                    </Link>
                </NetworkLink>
    
            </Folder>
        </Document>
    </kml>
    

    UPDATE:

    Not only can a large number of features cause performance problems but even a single polygon with for example 350K points and 7000 inner holes is problematic. A high-resolution polygon of a country's border including the coast line with such numbers of points would need to be simplified to reduce the number of points. You can use QGIS to open a KML file then apply a simplify algorithm on the polygon. In QGIS select Vector menu -> Geometry tools -> Simplify

    Alternatively, a polygon might be broken into several smaller polygons and combined in a MultiGeometry.