I am new to Python and KML/Google Earth but am trying to learn. I've run countless searches for drawing circles on Google Earth using Python and the SimpleKML module. My idea is to draw them as complex polygons and I need the radius to be 3000 feet. Here is my code:
My KMY.py Module
import math
def calc_angular_distance(radius):
'''(number) -> float
Return the angular distance from radius
Precondition: radius is measure in feet
>>>calc_angular_distance(1500)
7.176267461936767e-05
>>>calc_angular_distance(3000)
0.00014352534923873535
>>>calc_angular_distance(5000)
0.00023920891539789223
'''
# Mean Earth radius in feet (needed for calculations)
earth_radius_ft = 20902230.971129
#Calculate Angular Distance
return radius / earth_radius_ft
def generate_circle(lat_deg, lon_deg, radius):
# Generates a circle of radius radius centered at lat_deg, lon_deg
# lat_deg and lon_deg are in degrees
# radius is in feet
#Calculate Angular Distance
angular_distance = calc_angular_distance(radius)
# Calculate latitude and longitude in radians
lat_rad = math.radians(lat_deg)
lon_rad = math.radians(lon_deg)
# Create a list of angles at which to create points
# I.E. # of points the circle will consist of
num_points = range(0, 360, 5)
angles = []
for x in num_points:
angles.append(float(x))
angles.append(float(0))
coordinates = []
for angle in angles:
#Convert beraing to radians
bearing = math.radians(angle)
# Calculate New Longitude and New Latitude coordinates of points on circle
new_lat = math.asin(
math.sin(lat_rad) * math.cos(angular_distance) +
math.cos(lat_rad) * math.sin(angular_distance) * math.cos(bearing))
new_log = lon_rad + math.atan2(
math.sin(bearing) * math.sin(angular_distance) * math.cos(lat_rad),
math.cos(angular_distance) - math.sin(lat_rad) * math.sin(new_lat))
# Convert radians to degrees
new_lat = math.degrees(new_lat)
new_log = math.degrees(new_log)
# Append to coordinates list
coordinates.append((new_lat, new_log))
return coordinates
My main.py:
import kml
import simplekml
collection = kml.generate_circle(lat_deg=-88.88155337981863, lon_deg=30.442919411754943, radius=3000)
kml = simplekml.Kml()
pol = kml.newpolygon()
pol.tessellate = 1
pol.altitudemode = simplekml.AltitudeMode.clamptoground
# print(pol.outerboundaryis) # Shows that the outer boundary of a polygon is a linear ring
pol.outerboundaryis.coords = collection
kml.save("LinearRing.kml")
The problem is, when I import the KML file into Google Earth, it shows as an elongated ellipsis that is overly too large. For the life of me, I can not seem to find out what I am doing wrong. Is there an easier way? Am I overcomplicating this?
Well, apparently I was way off base. Here's what I ended up with that actually works:
import simplekml
import math
import os
def create_kml_circle(latitude, longitude, radius_feet):
# Create a Placemark for the circle
plts = []
for angle in range(0, 360, 1): # Create points for the circle
x = radius_feet * math.cos(math.radians(angle))
y = radius_feet * math.sin(math.radians(angle))
plts += [(longitude + x/364573, latitude + y/364573)] # Convert feet to degrees
print(plts)
return(plts)
if __name__ == "__main__":
# Coordinates for the center of the circle ,
longitude = -89.27338097601184 # Example latitude (Eupora High Scool)
latitude = 33.54505548413079 # Example longitude (Eupora High School)
# Radius of the circle in feet
radius_feet = 3000
# Create an instance of Kml
kml = simplekml.Kml(name="Basics", open=1)
# Create a new document
doc = kml.newdocument(name="A Document")
# Create a nested document
nestdoc = doc.newdocument()
nestdoc.name = "A Nested Document"
nestdoc.description = "\u2013 This is the nested document's description with unicode."
# Create a new folder at the top level
fol = kml.newfolder()
fol.name = "A Folder"
fol.description = "Description of a folder"
# Folder containing polygons with style
fol = kml.newfolder(name="School", description="Description of Polgon Folder")
pol = fol.newpolygon(name='Eupora High School', description='A aquarium with fish.',
outerboundaryis=create_kml_circle(latitude, longitude, radius_feet))
pol.style.linestyle.color = 'ff0000ff'
pol.linestyle.width = 5
pol.style.polystyle.color = 'ffff00ff'
# Save the file
kml.save(os.path.splitext(__file__)[0] + ".kml")