用于谷歌地球坐标的python中的距离计算

时间:2013-06-24 10:20:11

标签: python python-2.7 python-3.x

您好我有一个名为Placemark的kml文件和位于Google地球上某个区域的4个节点(地标)。每个地标节点都有经度和纬度。

<?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" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>placemarks.kml</name>
    <StyleMap id="m_ylw-pushpin">
        <Pair>
            <key>normal</key>
            <styleUrl>#s_ylw-pushpin</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#s_ylw-pushpin_hl</styleUrl>
        </Pair>
    </StyleMap>
    <Style id="s_ylw-pushpin_hl">
        <IconStyle>
            <scale>1.3</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
    </Style>
    <Style id="s_ylw-pushpin">
        <IconStyle>
            <scale>1.1</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
    </Style>
    <Folder>
        <name>placemarks</name>
        <open>1</open>
        <Placemark>
            <name>node0</name>
            <LookAt>
                <longitude>21.78832062146911</longitude>
                <latitude>38.28791526390673</latitude>
                <altitude>0</altitude>
                <heading>0.001539813336055052</heading>
                <tilt>44.99941206765101</tilt>
                <range>990.2435222326291</range>
                <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
            </LookAt>
            <styleUrl>#m_ylw-pushpin</styleUrl>
            <Point>
                <coordinates>21.78400936610002,38.2874355527483,67.51641688336248</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <name>node1</name>
            <LookAt>
                <longitude>21.78832062146911</longitude>
                <latitude>38.28791526390673</latitude>
                <altitude>0</altitude>
                <heading>0.001539813336055052</heading>
                <tilt>44.99941206765101</tilt>
                <range>990.2435222326291</range>
                <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
            </LookAt>
            <styleUrl>#m_ylw-pushpin</styleUrl>
            <Point>
                <coordinates>21.78453228393861,38.28690995466475,67.51641688336248</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <name>node2</name>
            <LookAt>
                <longitude>21.78832062146911</longitude>
                <latitude>38.28791526390673</latitude>
                <altitude>0</altitude>
                <heading>0.001539813336055052</heading>
                <tilt>44.99941206765101</tilt>
                <range>990.2435222326291</range>
                <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
            </LookAt>
            <styleUrl>#m_ylw-pushpin</styleUrl>
            <Point>
                <coordinates>21.7848823502596,38.2869152766261,67.51641688336248</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <name>node3</name>
            <LookAt>
                <longitude>21.78832062146911</longitude>
                <latitude>38.28791526390673</latitude>
                <altitude>0</altitude>
                <heading>0.001539813336055052</heading>
                <tilt>44.99941206765101</tilt>
                <range>990.2435222326291</range>
                <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
            </LookAt>
            <styleUrl>#m_ylw-pushpin</styleUrl>
            <Point>
                <coordinates>21.78459887820567,38.28740826552452,67.51641688336248</coordinates>
            </Point>
        </Placemark>
    </Folder>
</Document>
</kml>

我想要的是计算node0和node2,3,4之间的距离......(在距离函数中保持node0不变)然后打印结果。

使用以下代码:(我需要修改它以便输出如下)

 # adapted from haversine.py <https://gist.github.com/rochacbruno/2883505>
    # see also <http://en.wikipedia.org/wiki/Haversine_formula>
    from math import atan2, cos, sin, sqrt, radians

    def calc_distance(origin, destination):
        """great-circle distance between two points on a sphere
           from their longitudes and latitudes"""
        lat1, lon1 = origin
        lat2, lon2 = destination
        radius = 6371 # km. earth

        dlat = radians(lat2-lat1)
        dlon = radians(lon2-lon1)
        a = (sin(dlat/2) * sin(dlat/2) + cos(radians(lat1)) * cos(radians(lat2)) *
             sin(dlon/2) * sin(dlon/2))
        c = 2 * atan2(sqrt(a), sqrt(1-a))
        d = radius * c

        return d

    from xml.dom import minidom

    xmldoc = minidom.parse("placemarks.kml")
    kml = xmldoc.getElementsByTagName("kml")[0]
    document = kml.getElementsByTagName("Document")[0]
    placemarks = document.getElementsByTagName("Placemark")

    nodes = {}
    for placemark in placemarks:
        nodename = placemark.getElementsByTagName("name")[0].firstChild.data[:-1]
        coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data
        lst1 = coords.split(",")
        longitude = float(lst1[0])
        latitude = float(lst1[1])
        nodes[nodename] = (latitude, longitude)

Ang获得如下输出:

node1: (21.78453228393861, 38.28690995466475), distance from node0: 
node2: (21.78488235025960, 38.28691527662610), distance from node0: 
node3: (21.78459887820567, 38.28740826552452), distance from node0: 

1 个答案:

答案 0 :(得分:0)

在收集从KML文件中提取的节点的代码中,当您从XML中提取节点时,节点的名称始终相同,因此当您尝试将其存储在字典nodes中时最后得到一点。这是一个经过修正的脚本(只有最后一部分,需要修复),我认为这是你所需要的(请告诉我们,如果不是这样,你需要别的东西):

nodes = {}
for placemark in placemarks:
    nodename = placemark.getElementsByTagName("name")[0].firstChild.data
    coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data
    lst1 = coords.split(",")
    longitude = float(lst1[0])
    latitude = float(lst1[1])
    nodes[nodename] = (latitude, longitude)

for n in nodes:
    if n == 'node0':
        continue
    print n, nodes[n], 'distance from node0:', calc_distance(nodes['node0'], nodes[n])

这是输出:

node1 (38.28690995466475, 21.78453228393861) distance from node0: 0.074152874049
node3 (38.28740826552452, 21.78459887820567) distance from node0: 0.0515409901388
node2 (38.2869152766261, 21.7848823502596) distance from node0: 0.0956671636024