Created
February 12, 2013 18:06
-
-
Save carlosefonseca/4771881 to your computer and use it in GitHub Desktop.
Given a KML with multiple point placemarks and a line at the end, compares all placemarks with the line and checks if the line contains a point that is close enough to each point. Returns a √ or an X for each placemark and the distance to the closest point on the line.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
import math | |
import sys | |
from bs4 import BeautifulSoup | |
def distance_on_unit_sphere(lat1, long1, lat2, long2): | |
# Convert latitude and longitude to | |
# spherical coordinates in radians. | |
degrees_to_radians = math.pi/180.0 | |
# phi = 90 - latitude | |
phi1 = (90.0 - lat1)*degrees_to_radians | |
phi2 = (90.0 - lat2)*degrees_to_radians | |
# theta = longitude | |
theta1 = long1*degrees_to_radians | |
theta2 = long2*degrees_to_radians | |
# Compute spherical distance from spherical coordinates. | |
# For two locations in spherical coordinates | |
# (1, theta, phi) and (1, theta, phi) | |
# cosine( arc length ) = | |
# sin phi sin phi' cos(theta-theta') + cos phi cos phi' | |
# distance = rho * arc length | |
cos = (math.sin(phi1)*math.sin(phi2)*math.cos(theta1 - theta2) + | |
math.cos(phi1)*math.cos(phi2)) | |
arc = math.acos( cos ) | |
# Remember to multiply arc by the radius of the earth | |
# in your favorite set of units to get length. | |
return arc | |
def distance(lat1, long1, lat2, long2): | |
return distance_on_unit_sphere(lat1, long1, lat2, long2)*6373*1000 | |
def readKML(path): | |
soup = BeautifulSoup(open(path), "xml") | |
doc = soup.find("Document") | |
line = doc.find_all("Placemark")[-1].extract().find("coordinates").string.split() | |
linecoords = [] | |
for point in line: | |
c = point.split(",")[0:2] | |
linecoords.append([float(c[1]),float(c[0])]) | |
#print linecoords | |
for pm in doc.find_all("Placemark"): | |
c = pm.find("coordinates").string.split(",")[0:2] | |
coords = ([float(c[1]),float(c[0])]) | |
mindist = 99999; | |
for point in linecoords: | |
d = distance(coords[0],coords[1],point[0],point[1]) | |
if mindist > d: | |
mindist = d | |
if mindist>5: | |
print u"X {0:{1}<35}".format(pm.find("name").string.strip(), " "),int(mindist) | |
else: | |
print u"√ {0:{1}<35}".format(pm.find("name").string.strip(), " "),int(mindist) | |
readKML(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment