Converting shapefiles feature layers into individual KML files with attributes using Python

Shoaib Akhtar
2 min readJun 21, 2021

So this is my first article on any platform, and it’s always a pleasure to write for the community. Things began when a buddy of mine requested me to design a unique solution for him that was as easy to implement as a cup of coffee.

The goal was to convert a random shapefile into numerous KML formats, considering each unique feature layer as a separate KML file with the name provided in the shapefile’s attributes.

Why one need to convert shapefile into KML?

Working with shapefiles in the field necessitates the use of specialized software such as ArcMap, QGIS, and others, which take up so much space and demand so much RAM to operate properly that it is not a viable choice if simply displaying the data on a map is the only option.

Google provides a simple program for this purpose that uses fewer resources and allows users to easily change and update the form geometry, style, and characteristics saved.

For the conversion python is used with osgeo library, it first take the shapefile gets its layer and all the attributes, the code is shown below:

from osgeo import ogr


file = ogr.Open("shp/polygons.shp")
shape = file.GetLayer(0)
attribute_names = []
ldefn = shape.GetLayerDefn()
for n in range(ldefn.GetFieldCount()):
fdefn = ldefn.GetFieldDefn(n)
attribute_names.append(fdefn.name)
print(attribute_names)

In the function below, it converts the shapefile features into kml files, for now it is written for the polygon only but it can be upgraded.

def convert_to_kml(shape, attribute_names):
for obj in shape:
constant = '<?xml version="1.0" encoding="UTF-8"?>' \
'<kml ' \
'xmlns="http://www.opengis.net/kml/2.2" ' \
'xmlns:atom="http://www.w3.org/2005/Atom" ' \
'xmlns:gx="http://www.google.com/kml/ext/2.2" ' \
'xmlns:kml="http://www.opengis.net/kml/2.2">' \
'<name>%s</name>' \
'<Document>' \
'<Style id="s_ylw-pushpin_hl"><IconStyle><scale>1.3</scale>' \
'<Icon><href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href></Icon>' \
'<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/></IconStyle>' \
'<LineStyle><color>ff0000ff</color><width>2</width></LineStyle>' \
'<PolyStyle><fill>0</fill></PolyStyle></Style>' \
'<StyleMap id="m_ylw-pushpin"><Pair><key>normal</key><styleUrl>#s_ylw-pushpin</styleUrl></Pair>' \
'<Pair><key>highlight</key><styleUrl>#s_ylw-pushpin_hl</styleUrl></Pair></StyleMap>' \
'<Style id="s_ylw-pushpin"><IconStyle><scale>1.1</scale>' \
'<Icon><href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href></Icon>' \
'<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/></IconStyle>' \
'<LineStyle><color>ff0000ff</color><width>2</width></LineStyle><PolyStyle><fill>0</fill>' \
'</PolyStyle></Style>' \
'<Placemark>' \
'<styleUrl>#m_ylw-pushpin</styleUrl>' \
'<ExtendedData>'
end_tag = '{}</Placemark></Document></kml>'.format(obj.GetGeometryRef().ExportToKML())
filler = '<Data name="{}"><value>{}</value></Data>'
closing_tag = '</ExtendedData>'
# constant + filler + closing + end_tag
data = []
for attribute in attribute_names:
data.append(filler.format(attribute, obj.GetField(attribute)))
data = ''.join(data)
kml = ''.join([constant, data, closing_tag, end_tag])
filename = obj.GetField('name')

out_file = open(f"kml/{filename}.kml", "w")
out_file.write(kml)
out_file.close()

convert_to_kml(shape, attribute_names)

--

--