How to Draw Circles On Google Earth with SimpleKML and Python?

110 views Asked by At

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?

1

There are 1 answers

0
J.R. Woodcock On BEST ANSWER

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")