5

I'd like to open a USGS KML file of bedrock geology for an entire county, but there are over 2,000 individual polygon layers. Does anyone know if there is a way to merge all of these layers together into one file before opening in QGIS?

  • 2
    Your initial statement is a bit confusing. Do you have one kml file with multiple polygons in it, or do you have 2000 individual kml files representing the bedrock geology types? – Get Spatial Jul 22 '12 at 20:31
  • 1
    One thing you might do is use python and the QGIS API to do it. This question and answer provides a means to get started: How to write standalone Python scripts using QGIS – Get Spatial Jul 22 '12 at 20:32
  • Yes it is one kml file with multiple polygon files. I was hoping for a plugin, because I know nothing about programming with python, but maybe now is a good time to start learning! Thanks. – Patrick Jul 23 '12 at 15:55
  • 1
    I am not sure I understand, if I have a kml file with multiple lines, that would just open as one layer with multiple lines in QGIS. If on the other hand you have multiple kml files, you can open them all in Google earth, put them in one folder and export the folder as a new kml. – Ecodiv Aug 1 '12 at 7:38
  • It seems foolish/dangerous to try to include all the files in one uber-file. A pain to process, and likely to cause crashing. – Mox Apr 25 at 23:15
6

Here a simple shell script ("ogr_kml_merge.sh") which uses ogr2ogr:

#!/bin/sh

# Markus Neteler, 2008
# merge KML files

PROG=`basename $0`

if [ $# -lt 1 ] ; then
 echo "Merges KML files together (mosaik)"
 echo "Usage:"
 echo "  $PROG *.kml"
 echo "  $PROG a.kml b.kml c.kml"
 echo "At then end of the merge you can select a new name"
 exit 1
fi

LIST="$@"
OUT=file_merged

rm -f $OUT.kml

ogr2ogr -f KML $OUT.kml $1
shift

for i in `seq 1 $#` ; do
  echo "Appending #$i: $1"
  ogr2ogr -f KML -update -append $OUT.kml $1 -nln $OUT `basename $1 .kml`
  shift
done

echo "Written: $OUT.kml"

echo -n "Enter file name for new KML (or CTRL-C): "
read NEW
NEW=`basename $NEW .kml`
mv $OUT.kml $NEW.kml

echo "Written as: $NEW.kml"

Hope this gives the idea.

  • Tried it, but I get: ERROR 1: Unable to open existing output datasource file_merged.kml – tokland Feb 3 '17 at 12:17
3

One option would be to write a "wrapper" KML file and include links to each file in the wrapper, using the KML NetworkLink. Although it says "network", the Link element can contain a local file path instead. You can also use this in a KMZ structure

  • @ BradHards your link "KMZ structure" is not working any more. – SIslam May 25 '15 at 5:45
  • @SIslam: the link has been updated. – BradHards May 25 '15 at 11:09
2

Create a folder in which you'll then add the individual kml/kmz files. Go to Save as and in your destination, save this folder as a kml.Your result will be a single kml file. Hope this helps

1

With the plug in MMQGIS is possible to merge to many .kml files into one only shape file once you have uploaded all of you .kml files in Q-GIS.

To install the MMQGIS, simply you have to go to the plugin bottom, and select in manage sources and plugin.

Once the plugin is installed, go to combine, and after merge layers. Done!

0

I assume that the issue is not that there are multiple files, but there is a single KML/KMZ with lots of folders that is loading as individual layers, which is generally unsuitable for manipulation and performance. You can see why this would be a problem:

The QGIS Add Vector Layer dialog, displaying a repetitive list of layers with names like "Run-200", "Run-201"... with each layer containing only one feature.

Given that you asked how to merge all these layers together before opening in QGIS, there are two approaches:

Quick solution: Use KML Merger, an online tool located at https://kmlmerger.com/. Do note that you'll have to feed it two KML files, so you might need to create a KML with no data present, or create a dummy KML with one element of your original data set, then delete that element in the exported file. This can easily be done with a text editor.

Automated solution: Try this Python script to flatten XML files. It does read the KML line by line as if it were text, so it may not work on some valid KML files.


"""kmlflatten.py: reads a KML file as text, and strips out all Folder tags except the first and last.  usage: python kmlflatten.py IN [OUT]"""

import os
import sys

if len(sys.argv) >= 2:
    kmlfilein = sys.argv[1]
    if len(sys.argv) >= 3:
        kmlfileout = sys.argv[2]
    else:
        dotext = kmlfilein[kmlfilein.rfind(os.extsep):]
        fname, ext = os.splitext(kmlfilein)
        kmlfileout = fname + '_flattened' + ext
else:
    kmlfilein = 'doc.kml'
    kmlfileout = 'doc_flattened.kml'


with open(kmlfilein, 'r') as fi:
    with open(kmlfileout, 'w') as fo:
        folder, skip = False, False
        for line in fi.readlines():
            stline = line.strip() #remove indents, but hang onto original line.
            if not folder: #copy up to first <Folder> tag
                if stline == '<Folder>':
                    folder, skip = True, True
                    fo.write(line) # write the first folder!
                else:
                    fo.write(line)
            if folder: #copy lines except for the <Folder> tags and the <name> tag immediately proceeding
                if skip:
                    skip = False
                elif stline == '</Document>':
                    fo.write('\t</Folder>\n</Document>\n') # make sure to write the last </Folder> before done
                elif stline == '<Folder>':
                    skip = True
                elif stline == '</Folder>':
                    pass
                else:
                    fo.write(line)

A more suitable solution would be to use an XML parsing library to move all Placemark nodes into the first Folder, and perhaps first save any data about the Folder (like order or name) into the Placemark feature itself before it's destroyed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.