(longitudes)
return lower_bound, upper_bound
Estimate longitude bound with 2*sample standard deviation

    Note that longitudes wrap around, so have to use parameter
    estimation for wrapped probability distribution.

    See https://en.wikipedia.org/wiki/Wrapped_normal_distribution
    and https://en.wikipedia.org/wiki/Directional_statistics
    for how to calculate the relevant statistics.
Estimate longitude bound with 2*sample standard deviation
Estimate longitude bound with 2 * sample standard deviation
def longitude_bounds(longitudes):
    """
    Estimate longitude bound with 2*sample standard deviation

    Note that longitudes wrap around, so have to use parameter
    estimation for wrapped probability distribution.

    See https://en.wikipedia.org/wiki/Wrapped_normal_distribution
    and https://en.wikipedia.org/wiki/Directional_statistics
    for how to calculate the relevant statistics.
    """
    normalized_longitudes = [
        _normalize_longitude(longitude) for longitude in longitudes
    ]
    if max(normalized_longitudes) - min(normalized_longitudes) < 2.0*EPSILON:
        mean_longitude = 0.5 * (
            max(normalized_longitudes) + min(normalized_longitudes)
        )
        upper_bound = mean_longitude + EPSILON
        lower_bound = mean_longitude - EPSILON
    else:
        N = float(len(longitudes))
        radians = [
            math.radians(longitude) for longitude in normalized_longitudes
        ]
        sum_cos = sum(math.cos(r) for r in radians)
        sum_cos_sq = sum_cos**2
        sum_sin = sum(math.sin(r) for r in radians)
        sum_sin_sq = sum_sin**2
        mean_radians = math.atan2(sum_sin, sum_cos)
        mean_degrees = math.degrees(mean_radians)
        Rsq = (1/N**2) * (sum_cos_sq + sum_sin_sq)
        standard_deviation = math.sqrt(-math.log(Rsq))
        extent = 2.0*math.degrees(standard_deviation)
        if extent > 180.0:
            # longitudes cover entire map
            upper_bound = 180.0 - EPSILON
            lower_bound = -upper_bound
        else:
            lower_bound = _normalize_longitude(mean_degrees - extent)
            upper_bound = _normalize_longitude(mean_degrees + extent)
    return lower_bound, upper_bound
def longitude_bounds ( longitudes ) : normalized_longitudes = [ _normalize_longitude ( longitude ) for longitude in longitudes ] if max ( normalized_longitudes ) - min ( normalized_longitudes ) < 2.0 * EPSILON : mean_longitude = 0.5 * ( max ( normalized_longitudes ) + min ( normalized_longitudes ) ) upper_bound = mean_longitude + EPSILON lower_bound = mean_longitude - EPSILON else : N = float ( len ( longitudes ) ) radians = [ math . radians ( longitude ) for longitude in normalized_longitudes ] sum_cos = sum ( math . cos ( r ) for r in radians ) sum_cos_sq = sum_cos ** 2 sum_sin = sum ( math . sin ( r ) for r in radians ) sum_sin_sq = sum_sin ** 2 mean_radians = math . atan2 ( sum_sin , sum_cos ) mean_degrees = math . degrees ( mean_radians ) Rsq = ( 1 / N ** 2 ) * ( sum_cos_sq + sum_sin_sq ) standard_deviation = math . sqrt ( - math . log ( Rsq ) ) extent = 2.0 * math . degrees ( standard_deviation ) if extent > 180.0 : # longitudes cover entire map upper_bound = 180.0 - EPSILON lower_bound = - upper_bound else : lower_bound = _normalize_longitude ( mean_degrees - extent ) upper_bound = _normalize_longitude ( mean_degrees + extent ) return lower_bound , upper_bound