Beispiel #1
0
 def test_geographic_distance(self):
     actual = angles.geographic_distance(0., 0., 1., 0.)
     expected = 111194.87 # 60 nautical miles in kilometers
     self.assertAlmostEqual(actual, expected, 1)
     actual = angles.geographic_distance(0., 0.5, 0., -0.5)
     self.assertAlmostEqual(actual, expected, 1)
     actual = angles.geographic_distance(0., 0.5, 0., 0.5)
     self.assertAlmostEqual(actual, 0., 1)
Beispiel #2
0
def bounding_box(fcst, pad=0.1, lon_pad=None, lat_pad=None):
    lons = np.unique(fcst['longitude'].values)
    lats = np.unique(fcst['latitude'].values)

    lon_diffs = angles.angle_diff(lons[:, None], lons)
    lat_diffs = angles.angle_diff(lats[:, None], lats)

    western_most_ind = np.nonzero(np.all(lon_diffs >= 0., axis=0))[0]
    western_most = np.unique(lons[western_most_ind]).item()
    eastern_most_ind = np.nonzero(np.all(lon_diffs <= 0., axis=0))[0]
    eastern_most = np.unique(lons[eastern_most_ind]).item()

    northern_most_ind = np.nonzero(np.all(lat_diffs <= 0., axis=0))[0]
    northern_most = np.unique(lats[northern_most_ind]).item()
    southern_most_ind = np.nonzero(np.all(lat_diffs >= 0., axis=0))[0]
    southern_most = np.unique(lats[southern_most_ind]).item()

    # count the number of lons greater than and less than each lon
    # and take the difference.  The longitude (or pair of lons) that
    # minimize this help us determine the median.  This allows different
    # definitions of longitude.
    lon_rel_loc = np.abs(np.sum(lon_diffs >= 0., axis=0) -
                         np.sum(lon_diffs <= 0., axis=0))
    central_lons = lons[lon_rel_loc == np.min(lon_rel_loc)]
    # make sure the central two aren't too far apart.
    assert np.max(central_lons) - np.min(central_lons) < 90
    median_lon = np.median(central_lons)

    lat_rel_loc = np.abs(np.sum(lat_diffs >= 0., axis=0) -
                         np.sum(lat_diffs <= 0., axis=0))
    central_lats = lats[lat_rel_loc == np.min(lat_rel_loc)]
    median_lat = np.median(central_lats)

    width = angles.geographic_distance(western_most, median_lat,
                                       eastern_most, median_lat)
    height = angles.geographic_distance(median_lon, northern_most,
                                        median_lon, southern_most)
    if lon_pad is None:
        lon_pad = pad * np.abs(angles.angle_diff(eastern_most,
                                                 western_most))
    if lat_pad is None:
        lat_pad = pad * np.abs(angles.angle_diff(northern_most,
                                                 southern_most))

    return {'llcrnrlon': western_most - lon_pad,
            'urcrnrlon': eastern_most + lon_pad,
            'urcrnrlat': northern_most + lat_pad,
            'llcrnrlat': southern_most - lat_pad,
            'width': width * (1. + 2 * pad),
            'height': height * (1. + 2 * pad),
            'lon_0': median_lon,
            'lat_0': median_lat}