5

I've written a script in python that will convert a CSV file to a KML file using the simplekml python package. It's not finished yet as it needs to also scale and color my points based on one of my data values. Right now I'm playing around with this if/else just to see if I can use a shared style, then edit the color and scale of each point (I plan on changing this to use a range of colors, but for now I'm just trying to figure out what works and what doesn't). My data has 5000 rows, so I wanted to use a shared style to keep the resulting KML as short as possible, then use the for loop to assign color and scale along with the schema data.

My problem is this: the if/else executes, but it changes the shared style icon color to the lime green. The result is every single point is lime green. Is there a way to use a shared style and also edit just color and scale without it overwriting the shared style? If I remove the shared style, the colors work as expected but my KML file is huge. I'm very new to python, I just learned last week. So any help or tips is appreciated.

EDIT: It seems as if I cannot do what I set out to do with the shared style there. I can use if/else to compare and assign colors but it only works if I get rid of the shared style. I think that just overwrites everything. If there is a way to do this however, that would make my output files much smaller (with the shared style they are about 4mb, without they are about 7mb and I know this will be used with much larger datasets in the future).

Here is my code for reference:

import simplekml
import csv
import math

kml = simplekml.Kml()
style = simplekml.Style() #creates shared style for all points
style.iconstyle.icon.href ='http://maps.google.com/mapfiles/kml/shapes/target.png' #can change to any desired icon URL
style.iconstyle.scale = 1
schema = kml.newschema(name= '') #creates schema
schema.newsimplefield(name= 'realization', type = 'string', display name = 'Realization')
schema.newsimplefield(name= 'diameter', type = 'string', displayname = 'Diameter')
schema.newsimplefield(name= 'density', type = 'string', displayname = 'Density')
schema.newsimplefield(name= 'strength', type = 'string', displayname = 'Strength')
schema.newsimplefield(name= 'velocity', type = 'string', displayname = 'Velocity (mps)')
schema.newsimplefield(name= 'entry', type = 'string', displayname = 'Entry Angle')
schema.newsimplefield(name= 'casualties', type = 'float', displayname = 'Casualties')
schema.newsimplefield(name= 'damagesource', type = 'string', displayname = 'Damage Source')
schema.newsimplefield(name= 'blastrad', type = 'string', displayname = 'Blast Radius')

#loads csv and sets delimiter
myfile = open(raw_input("Enter file path: "))
data = csv.DictReader(myfile, delimiter = ',') #create new kml file

for row in data:
  cas_log = float(row[' Casualties ']) + 1 #change 0 values to 1
  newlog = math.log10(cas_log)
  row[' Casualties '] = newlog #changes the values to their log10
  pnt = kml.newpoint(name = "", coords = [(float(row[' Longitude ']),float(row['  Latitude ']))])
  pnt.style = style #assigns shared style to every point
  pnt.extendeddata.schemadata.schemaurl = schema.id #assigns schema data to each point for display in
  pnt.extendeddata.schemadata.newsimpledata('realization', row['Realization '])
  pnt.extendeddata.schemadata.newsimpledata('diameter', row[' Diameter '])
  pnt.extendeddata.schemadata.newsimpledata('density', row[' Density '])
  pnt.extendeddata.schemadata.newsimpledata('strength', row[' Strength '])
  pnt.extendeddata.schemadata.newsimpledata('velocity', row[' Velocity_mps '])
  pnt.extendeddata.schemadata.newsimpledata('entry', row[' EntryAngle '])
  pnt.extendeddata.schemadata.newsimpledata('casualties', row[' Casualties '])
  pnt.extendeddata.schemadata.newsimpledata('damagesource', row[' DamageSource'])
  pnt.extendeddata.schemadata.newsimpledata('blastrad', row[' BlastRadMajor_m '])
  if row[' Casualties '] == 0.0: # color test
     pnt.style.iconstyle.color = 'ffff00ff' #magenta
  else:
     pnt.style.iconstyle.color = 'ff32cd32' #lime green


kml.save("csv2kml.kml") #saves new KML file by this name in the user directory

print "File created."
CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
R.P.
  • 51
  • 1
  • 5
  • Something you will discover is that Google Earth will "optimize" your KML when loaded so it is very difficult to finely tune your output. You may be stuck with the huge file if consistent output is the goal. – rheitzman Jul 25 '16 at 20:20
  • 5000 rows and 7MB is not considered a large KML file but 500K is getting to a large size. Also, you need to remove the whitespace in the dictionary references in the python code; e.g. `row[' Casualties ']` > `row['Casualties']`. – CodeMonkey Apr 08 '17 at 21:02

1 Answers1

1

To use shared styles in simplekml you need to create a style for each of colors then refer to its variable on the point based on criteria for color which in this case is the log of the number of casualties.

Create multiple shared styles in your KML

style1 = simplekml.Style() #creates shared style for all points
style1.iconstyle.color = 'ffff00ff' #magenta
style1.iconstyle.icon.href ='http://maps.google.com/mapfiles/kml/shapes/target.png' #can change to any desired icon URL
style1.iconstyle.scale = 1

style2 = simplekml.Style() #creates shared style for all points
style2.iconstyle.color = 'ff32cd32' #lime green
style2.iconstyle.icon.href ='http://maps.google.com/mapfiles/kml/shapes/target.png' #can change to any desired icon URL
style2.iconstyle.scale = 1

Next, assign the style to the point based on the color test

if row['Casualties'] >= 5.0: # color test
   pnt.style = style1 # magenta
else:
   pnt.style = style2 # lime green
CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
  • If png is a solid color Google Earth replaces the primary color with the color as defined in icon style. If specify color=white (default) then uses icon image as-is. Try different colors in the KML to see how the icon changes when displayed in Google Earth. – CodeMonkey Jul 04 '20 at 17:15
  • seems reasonable. But I'm not seeing any change. Kinda weird, I ended up moving over to something else. But may give a look at it sometime in the future. – Pedro Rodrigues Jul 04 '20 at 22:34