2

I get a regularly updated KML file which I need to pull into QGIS. It has different folders/layers (about 12), and features in each folder/layer have different <styleURL>s. I need to access each feature's styleURL (along with name, description, and the location) for processing in QGIS.

1st attempt - just import the KML file inside QGIS. I get one layer per folder (well, lines and points separately), but the styleURL is not an accessible field.

2nd attempt by manually running ogr2ogr and using the special field OGR_STYLE:

ogr2ogr -f GPKG -oo LIBKML_RESOLVE_STYLE=YES -sql "select *, OGR_STYLE from Boundaries" twinrock_test.gpkg twinrock13.kml

Works fine for a single named folder, Boundaries, but I need to run it for all folders in the kml file, as if I just did ogr2ogr -f GPKG twinrock_test.gpkg twinrock13.kml (without the mucking around with OGR_STYLE).

3rd attempt:

ogr2ogr -f GPKG -oo LIBKML_RESOLVE_STYLE=YES -select Name,description,OGR_STYLE twinrock_test2.gpkg twinrock13.kml

Fails since the special field OGR_STYLE seems only accessible via -sql, not -select.

Any ideas?

1

Well, no answers in 2.5 weeks, so I did my best: the idea is to essentially use my 2nd attempt above, and then use the Categorized renderer in QGIS (on OGR_STYLE) with saved QGIS styles that recreate and improve the KML styling, applies consistently for all folders/layers.

Sharing in PyQGIS in case useful (be gentle, please - started learning Python only this week):

from osgeo import ogr, gdal

gdal.UseExceptions() 
ogr.UseExceptions()

# figure out list of folders in kmlfile
kmlLayers = []
driver = ogr.GetDriverByName("LIBKML")
kml = driver.Open(kmlfile, 0)
for idx in range(kml.GetLayerCount()):
    kmlLayers.append(kml.GetLayerByIndex(idx).GetName())
del kml

# now iterate through them with gdal.VectorTranslate, using special SQL statement to capture OGR_STYLE as well as other fields, storing in gpkgfile
vtParams = {
    'destNameOrDestDS': gpkgfile
    , 'srcDS': kmlfile
    , 'format': "GPKG" # could use other formats, this is convenient
    , 'options': ['-update','-overwrite','-oo','LIBKML_RESOLVE_STYLE=YES']
    # SQLStatement added below in for loop
}

for layerName in kmlLayers:
    vtParams.update({
        'SQLStatement': 'select *, OGR_STYLE AS Style from "{}"'.format(layerName)
    })
    gdal.VectorTranslate(**vtParams)

# now go on to reload and repaint layers on current map canvas that reference them, as well as to add and conditionally style (based on Style) any new folders added

I've also submitted a feature request for QGIS Desktop to pass OGR_STYLE on import through ogr, which would make this all easier!

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.