Search code examples
pythonpandaskml

Python Simplekml if folder already exists append the data inside folder as placemark tag


I have question related to SimpleKML. How to create(Append) a placemark inside a folder having the same name tag? Meaning inside one folder 2 data points are seen. Below is the output I am looking for. Thanks in advance.

Output looking for.

  <Folder>
        <name>MISCELNOUS</name>
        <Placemark>
            <name>GLEACHER CENTER</name>
            <Snippet maxLines="0"></Snippet>
            <description>Center<description>
            <LookAt>
                <longitude>-87.62224000000001</longitude>
                <latitude>41.889645</latitude>
            </LookAt>
            <Point>
                <coordinates>-87.62224000000001,41.889645,0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <name>TRANSUNION BUILDING</name>
            <Snippet maxLines="0"></Snippet>
            <description>the post</description>
            <LookAt>
                <longitude>-87.641824</longitude>
                <latitude>41.878961</latitude>
            </LookAt>
            <Point>
                <coordinates>-87.641824,41.878961,0</coordinates>
            </Point>
        </Placemark>
    </Folder>
    <Folder>
            <name>Office</name>
            <Placemark>
                <name>EAST NORTH ACADEMY</name>
                <Snippet maxLines="0"></Snippet>
                <description>My hero Academia</description>
                <LookAt>
                    <longitude>-82.38971100000001</longitude>
                    <latitude>34.852488</latitude>
                </LookAt>
                <Point>
                <coordinates>-82.38971100000001,34.852488,0</coordinates>
                </Point>
            </Placemark> 
        </Folder>

My code:

kml = simplekml.Kml()
kml.newdocument(name="PCI Data")
for i, j in df_small.iterrows():
  try:
     fol = kml.newfolder()
     fol.name = j['folder']
     pnt = fol.newpoint(name=j['Name'], coords=[[j['latitude'], j['longitude']]])
     #pnt.lookat = simplekml.LookAt(gxaltitudemode=simplekml.GxAltitudeMode.relativetoseafloor,latitude=j['latitude'], longitude=j['longitude'], range=1000, heading=0, tilt=0)
  except Exception as e:
     print(e)
    
print(kml.kml())

My output:

<?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
    <Document id="635">
        <Document id="636">
            <name>PCI Data</name>
        </Document>
        <Folder id="637">
            <name>MISCELNOUS</name>
            <Placemark id="639">
                <name>SOKA BAU GP-FK00</name>
                <Point id="638">
                    <coordinates>32.77815,-96.7954,0.0</coordinates>
                </Point>
            </Placemark>
        </Folder>
        <Folder id="640">
            <name>MISCELNOUS</name>
            <Placemark id="642">
                <name>Thematic Platform LP FA01</name>
                <Point id="641">
                    <coordinates>32.77815,-96.7954,0.0</coordinates>
                </Point>
            </Placemark>
        </Folder>
    </Document>
</kml>

Also I have more folder to be created and and it should contain more placemark inside them.

Currently, I'm trying to work it out like this, But not successful in getting the result. Any guidance would be helpful.

 kml = simplekml.Kml()
 doc = kml.newdocument(name="PCI Data")
 for i, j in df_small.iterrows():
     try:
         if 'MISCELNOUS' or 'Office' in [x.name for x in kml.containers]:
             fol.name = j['primary_property_type']
             pnt = fol.newpoint(name=j['Name'], coords=[[j['latitude'], j['longitude']]])
             pnt = fol.newpoint(name=j['Name'], coords=[[j['latitude'], j['longitude']]])
             pnt.lookat = simplekml.LookAt(gxaltitudemode=simplekml.GxAltitudeMode.relativetoseafloor,latitude=j['latitude'], longitude=j['longitude'], range=1000, heading=0, tilt=0)
         else:
             fol = kml.newfolder()
             fol.name = j['primary_property_type']
             pnt = fol.newpoint(name=j['Name'], coords=[[j['latitude'], j['longitude']]])
             pnt.lookat = simplekml.LookAt(gxaltitudemode=simplekml.GxAltitudeMode.relativetoseafloor,latitude=j['latitude'], longitude=j['longitude'], range=1000, heading=0, tilt=0)
     except Exception as e:
         print(e)
    
 print(kml.kml())

Sample Dataset:

 df_sample = pd.DataFrame({'Name': ['GLEACHER CENTER', 'TRANSUNION BUILDING', 'EAST NORTH ACADEMY'], 
           'description': ['Center', 'the post', 'My hero Academia'],
            'longitude' : [-87.62224000000001, -87.641824, -82.38971100000001],
            'latitude'  : [41.889645, 41.878961, 34.852488],
            'folder'    : ['MISCELNOUS', 'MISCELNOUS', 'Office']})

Solution

  • Simply initialize the simpleKML Folder once outside the rowwise loop. Then add newpoints to this single Folder. To separate out the folder tags, run a groupby iteration and assign folder name before running data frame rowwise iteration.

    kml = simplekml.Kml() 
    doc = kml.newdocument(name="PCI Data")
    
    for grp, sub in df_sample.groupby("folder"):
        fol = kml.newfolder(name=grp)
    
        for row in sub.iterrows():
            try: 
                fol.newpoint(
                    name=row['Name'], 
                    description=row['description'], 
                    coords=[[row['latitude'], row['longitude']]]
                )
    
            except Exception as e: 
                print(e)
    
    print(kml.kml())