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