Saturday, 3 November 2018

raster - Adding a field with a unique value to vector layer in kml file (need this to burn values with gdal.RasterizeLayer)


I would like to create a field ID in my kml file, with a unique value so that I can use gdal.RasterizeLayer to burn the value to an image like this:


gdal.RasterizeLayer(target_ds, [1], source_layer, options = ["ATTRIBUTE=ID"])

This means I need to create an attribute called ID in my .kml file so that gdal.RasterizeLayer will be able to recognize this and burn the correct ID value. I tried this and it seems like I create a new field but when I run gdal.RasterizeLayer, nothing is rasterized. My current kml file has several Placemark/Polygon objects and I wish to give each of them a unique id.



import pykml.parser as kml_parser
from lxml import etree

kml_file = 'test.kml'

with open(kml_file) as f:
root = kml_file.parse(f).getroot()

for i, Placemark in enumerate(root.Document.Folder.Placemark):
Placemark.addattr('id', i + 1)


tree = etree.ElementTree(root)
tree.write('new.kml')

Does anyone know what the proper way to create attributes in kml file is?



Answer



You can add an ID field simply using the GDAL Python bindings without introducing further dependencies:


(GDAL >= 2.1.0)


from osgeo import gdal


path = "mask.kml"
ds = gdal.OpenEx(path)
sql = "select FID as ID, FIELD1, FIELD2, ..., FIELDN FROM {}".format(ds.GetLayer().GetName())
ds2 = gdal.VectorTranslate("mask_with_IDs.kml", ds, format = 'KML', SQLStatement = sql, SQLDialect = "OGRSQL")
ds2 = None

where FID (i.e. feature id) is a special field available in OGR SQL, while FIELD1, FIELD2, ..., FIELDN are your fields of interest.




(GDAL < 2.1.0)


from osgeo import ogr

import os

ogr.UseExceptions()

inFileName = "mask.kml"
inDriver = ogr.GetDriverByName("KML")
inDataSource = inDriver.Open(inFileName, 0)
inLayer = inDataSource.GetLayer()
result = inDataSource.ExecuteSQL("select FID, * from {}".format(inLayer.GetName()))


outFileName = "mask_with_IDs.kml"
outDriver = ogr.GetDriverByName("KML")
if os.path.exists(outFileName):
outDriver.DeleteDataSource(outFileName)
outDataSource = outDriver.CreateDataSource(outFileName)
outLayer = outDataSource.CopyLayer(result, "mask_with_IDs")

inDataSource.ReleaseResultSet(result)
outDataSource = None

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...