{"id":274,"date":"2022-01-05T21:40:15","date_gmt":"2022-01-05T13:40:15","guid":{"rendered":"http:\/\/purplepoolobservatory.com\/?p=274"},"modified":"2022-01-05T21:40:15","modified_gmt":"2022-01-05T13:40:15","slug":"%e8%ae%a1%e7%ae%97%e4%b8%a4%e7%82%b9%e9%97%b4%e7%9a%84%e8%b7%9d%e7%a6%bb","status":"publish","type":"post","link":"https:\/\/purplepoolobservatory.com\/?p=274","title":{"rendered":"\u8ba1\u7b97\u4e24\u70b9\u95f4\u7684\u8ddd\u79bb"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>from great_circle_calculator.__conversion import _point_to_radians, _point_to_degrees, _radians_to_degrees, \\\r\n    _degrees_to_radians\r\nfrom great_circle_calculator.__error_checking import _error_check_point\r\nfrom great_circle_calculator._constants import *\r\n\r\n\r\ndef distance_between_points(p1, p2, unit='meters', haversine=True):\r\n    \"\"\" This function computes the distance between two points in the unit given in the unit parameter.  It will\r\n    calculate the distance using the haversine unless the user specifies haversine to be False.  Then law of cosines\r\n    will be used\r\n    :param p1: tuple point of (lon, lat)\r\n    :param p2: tuple point of (lon, lat)\r\n    :param unit: unit of measurement. List can be found in constants.eligible_units\r\n    :param haversine: True (default) uses haversine distance, False uses law of cosines\r\n    :return: Distance between p1 and p2 in the units specified.\r\n    \"\"\"\r\n    lon1, lat1 = _point_to_radians(_error_check_point(p1))\r\n    lon2, lat2 = _point_to_radians(_error_check_point(p2))\r\n    r_earth = getattr(radius_earth, unit, 'meters')\r\n    if haversine:\r\n        # Haversine\r\n        d_lat, d_lon = lat2 - lat1, lon2 - lon1\r\n        a = sin(d_lat \/ 2) * sin(d_lat \/ 2) + cos(lat1) * cos(lat2) * sin(d_lon \/ 2) * sin(d_lon \/ 2)\r\n        c = 2 * atan2(sqrt(a), sqrt((1 - a)))\r\n        dist = r_earth * c\r\n        return dist\r\n    # Spherical Law Of Cosines\r\n    dist = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1)) * r_earth\r\n    return dist\r\n\r\n\r\ndef bearing_at_p1(p1, p2):\r\n    \"\"\" This function computes the bearing (i.e. course) at p1 given a destination of p2.  Use in conjunction with\r\n    midpoint(*) and intermediate_point(*) to find the course along the route.  Use bearing_at_p2(*) to find the bearing\r\n    at the endpoint\r\n    :param p1: tuple point of (lon, lat)\r\n    :param p2: tuple point of (lon, lat)\r\n    :return: Course, in degrees\r\n    \"\"\"\r\n    lon1, lat1 = _point_to_radians(_error_check_point(p1))\r\n    lon2, lat2 = _point_to_radians(_error_check_point(p2))\r\n    x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1)\r\n    y = sin(lon2 - lon1) * cos(lat2)\r\n    course = atan2(y, x)\r\n    return _radians_to_degrees(course)\r\n\r\n\r\ndef bearing_at_p2(p1, p2):\r\n    \"\"\" This function computes the bearing (i.e. course) at p2 given a starting point of p1.  Use in conjunction with\r\n    midpoint(*) and intermediate_point(*) to find the course along the route.  Use bearing_at_p1(*) to find the bearing\r\n    at the endpoint\r\n    :param p1: tuple point of (lon, lat)\r\n    :param p2: tuple point of (lon, lat)\r\n    :return: Course, in degrees\r\n    \"\"\"\r\n    return (bearing_at_p1(p2, p1) + 180) % 360\r\n\r\n\r\ndef midpoint(p1, p2):\r\n    \"\"\" This is the half-way point along a great circle path between the two points.\r\n    :param p1: tuple point of (lon, lat)\r\n    :param p2: tuple point of (lon, lat)\r\n    :return: point (lon, lat)\r\n    \"\"\"\r\n    lon1, lat1 = _point_to_radians(_error_check_point(p1))\r\n    lon2, lat2 = _point_to_radians(_error_check_point(p2))\r\n    b_x = cos(lat2) * cos(lon2 - lon1)\r\n    b_y = cos(lat2) * sin(lon2 - lon1)\r\n    lat3 = atan2(sin(lat1) + sin(lat2), sqrt((cos(lat1) + b_x) * (cos(lat1) + b_x) + b_y * b_y))\r\n    lon3 = lon1 + atan2(b_y, cos(lat1) + b_x)\r\n    lat3 = _radians_to_degrees(lat3)\r\n    lon3 = (_radians_to_degrees(lon3) + 540) % 360 - 180\r\n    p3 = (lon3, lat3)\r\n    return p3\r\n\r\n\r\ndef intermediate_point(p1, p2, fraction=0.5):\r\n    \"\"\" This function calculates the intermediate point along the course laid out by p1 to p2.  fraction is the fraction\r\n    of the distance between p1 and p2, where 0 is p1, 0.5 is equivalent to midpoint(*), and 1 is p2.\r\n    :param p1: tuple point of (lon, lat)\r\n    :param p2: tuple point of (lon, lat)\r\n    :param fraction: the fraction of the distance along the path.\r\n    :return: point (lon, lat)\r\n    \"\"\"\r\n    lon1, lat1 = _point_to_radians(_error_check_point(p1))\r\n    lon2, lat2 = _point_to_radians(_error_check_point(p2))\r\n    delta = distance_between_points(p1, p2) \/ radius_earth.meters\r\n    a = sin((1 - fraction) * delta) \/ sin(delta)\r\n    b = sin(fraction * delta) \/ sin(delta)\r\n    x = a * cos(lat1) * cos(lon1) + b * cos(lat2) * cos(lon2)\r\n    y = a * cos(lat1) * sin(lon1) + b * cos(lat2) * sin(lon2)\r\n    z = a * sin(lat1) + b * sin(lat2)\r\n    lat3 = atan2(z, sqrt(x * x + y * y))\r\n    lon3 = atan2(y, x)\r\n    return _point_to_degrees((lon3, lat3))\r\n\r\n\r\ndef point_given_start_and_bearing(p1, course, distance, unit='meters'):\r\n    \"\"\" Given a start point, initial bearing, and distance, this will calculate the destina\u00adtion point and final\r\n    bearing travelling along a (shortest distance) great circle arc.\r\n    :param p1: tuple point of (lon, lat)\r\n    :param course: Course, in degrees\r\n    :param distance: a length in unit\r\n    :param unit: unit of measurement. List can be found in constants.eligible_units\r\n    :return: point (lon, lat)\r\n    \"\"\"\r\n    lon1, lat1 = _point_to_radians(_error_check_point(p1))\r\n    brng = _degrees_to_radians(course)\r\n    r_earth = getattr(radius_earth, unit, 'meters')\r\n    delta = distance \/ r_earth\r\n    lat2 = asin(sin(lat1) * cos(delta) + cos(lat1) * sin(delta) * cos(brng))\r\n    lon2 = lon1 + atan2(sin(brng) * sin(delta) * cos(lat1), cos(delta) - sin(lat1) * sin(lat2))\r\n    lon2 = (_radians_to_degrees(lon2) + 540) % 360 - 180\r\n    p2 = (lon2, _radians_to_degrees(lat2))\r\n    return p2\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"gallery","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-274","post","type-post","status-publish","format-gallery","hentry","category-technology","post_format-post-format-gallery"],"_links":{"self":[{"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=\/wp\/v2\/posts\/274","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=274"}],"version-history":[{"count":1,"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=\/wp\/v2\/posts\/274\/revisions"}],"predecessor-version":[{"id":275,"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=\/wp\/v2\/posts\/274\/revisions\/275"}],"wp:attachment":[{"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=274"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=274"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/purplepoolobservatory.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=274"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}