Intersection coordinates (lat/lon) of two circles (given the coordinates of the center and the radius) on earth

后端 未结 1 1572
名媛妹妹
名媛妹妹 2020-12-22 14:02

I am not that experienced in python but improving it thanks to this community! I desperately need a function which takes the input and gives the ouput below:

相关标签:
1条回答
  • 2020-12-22 14:30

    Depending on the precision you need, you may or may not consider the Earth as a sphere. In the second case, calculations become more complex.

    The best option for precise measurements when the radius is small (as in your example) is to use a projection (UTM for example) and then apply the common flat euclidean calculations.

    Let's first copy the flat circle intersection function from https://stackoverflow.com/a/55817881/2148416:

    def circle_intersection(x0, y0, r0, x1, y1, r1):
    
        d = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
    
        if d > r0 + r1:             # non intersecting
            return None
        if d < abs(r0 - r1):        # one circle within other
            return None
        if d == 0 and r0 == r1:     # coincident circles
            return None
    
        a = (r0 ** 2 - r1 ** 2 + d ** 2) / (2 * d)
        h = math.sqrt(r0 ** 2 - a ** 2)
        x2 = x0 + a * (x1 - x0) / d
        y2 = y0 + a * (y1 - y0) / d
        x3 = x2 + h * (y1 - y0) / d
        y3 = y2 - h * (x1 - x0) / d
    
        x4 = x2 - h * (y1 - y0) / d
        y4 = y2 + h * (x1 - x0) / d
    
        return (x3, y3), (x4, y4)
    

    The precise calculation for a small radius (up to a few kilometers) can be done in UTM coordinates with the help of the utm library. It handles all the complications regarding the fact the the Earth is more an ellipsoid than a sphere:

    import utm
    
    def geo_circle_intersection(latlon0, radius0, latlon1, radius1):
    
        # Convert lat/lon to UTM
        x0, y0, zone, letter = utm.from_latlon(latlon0[0], latlon0[1])
        x1, y1, _, _ = utm.from_latlon(latlon1[0], latlon1 [1], force_zone_number=zone)
    
        # Calculate intersections in UTM coordinates
        a_utm, b_utm = circle_intersection(x0, y0, r0, x1, y1, r1)
    
        # Convert intersections from UTM back to lat/lon
        a = utm.to_latlon(a_utm[0], a_utm[1], zone, letter)
        b = utm.to_latlon(b_utm[0], b_utm[1], zone, letter)
    
        return a, b
    

    Using your example (with slightly larger radii):

    >>> p0 = 50.851295, 5.667969
    >>> r0 = 2000
    >>> p1 = 50.844101, 5.725889
    >>> r1 = 3000
    >>> a, b = geo_circle_intersection(p0, r0, p1, r1)
    >>> print(a)
    (50.836848562566004, 5.684869539768468)
    >>> print(b)
    (50.860635308778285, 5.692236858407678)
    
    0 讨论(0)
提交回复
热议问题