Example #1
0
    def test_great_distance_scalars(self):
        # One decimal degree at the equator is about 111.32km
        latitude_start = 0.
        latitude_end = 0.
        longitude_start = 50.
        longitude_end = 52.
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2

        # One decimal degree is 111000m
        latitude_start = 0.
        latitude_end = 0.
        longitude_start = [49., 75.]
        longitude_end = [50., 76.]
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.allclose(gd["distance"] / 1000, 111.32)

        latitude_start = np.nan
        latitude_end = np.nan
        longitude_start = np.nan
        longitude_end = np.nan
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.isnan(gd['distance'])
Example #2
0
    def test_great_distance_numpy(self):
        latitude_start  = np.asarray([0.])
        latitude_end    = np.asarray([0.])
        longitude_start = np.asarray([50.])
        longitude_end   = np.asarray([52.])
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2

        latitude_start  = np.asarray([0.])
        latitude_end    = np.asarray([0.])
        longitude_start = 50.
        longitude_end   = 52.
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2
Example #3
0
def great_circle(start_point, end_point, n_points):

    # Check if input are Points
    if start_point is None or end_point is None:
        raise Exception('geom is required')
    if start_point.type != 'Point' or end_point.type != 'Point':
        raise Exception('start_point and end_point should be a LineString')

    start_coords = list(geojson.utils.coords(start_point))
    end_coords = list(geojson.utils.coords(end_point))

    distance_dict = pygc.great_distance(
        start_latitude=start_coords[0][1],
        start_longitude=start_coords[0][0],
        end_latitude=end_coords[0][1],
        end_longitude=end_coords[0][0],
    )
    segments = linspace(start=0, stop=distance_dict['distance'], num=n_points)
    points_dict = pygc.great_circle(
        distance=segments,
        azimuth=distance_dict['azimuth'],
        latitude=start_coords[0][1],
        longitude=start_coords[0][0],
    )

    coords = []
    for i in range(n_points):
        coords.append(
            [points_dict['longitude'][i], points_dict['latitude'][i]])

    return geojson.LineString(coords, precision=PRECISION)
Example #4
0
def distance_to_point(point_a, point_b):
    """Calculate distance between to points
    """
    result = great_distance(start_latitude=point_a.lat,
                            start_longitude=point_a.lng,
                            end_latitude=point_b.lat,
                            end_longitude=point_b.lng)
    return int(result['distance'])
Example #5
0
def heading_to_point(point_a, point_b):
    """Calculate heading between two points
    """
    result = great_distance(start_latitude=point_a.lat,
                            start_longitude=point_a.lng,
                            end_latitude=point_b.lat,
                            end_longitude=point_b.lng)
    return int(result['azimuth'])
def grcrcl2(startlong, startlat, endlong, endlat):

    res = great_distance(start_latitude=startlat,
                         start_longitude=startlong,
                         end_latitude=endlat,
                         end_longitude=endlong)

    return float(res['distance'])
Example #7
0
 def test_great_distance_empty_numpy(self):
     latitude_start  = np.ma.asarray([])
     latitude_end    = np.ma.asarray([])
     longitude_start = np.ma.asarray([])
     longitude_end   = np.ma.asarray([])
     gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
     assert np.all(gd['distance'].mask == True)  # noqa
     assert np.all(gd['azimuth'].mask == True)  # noqa
     assert np.all(gd['reverse_azimuth'].mask == True)  # noqa
Example #8
0
    def test_great_distance_numpy(self):
        latitude_start = np.asarray([0.])
        latitude_end = np.asarray([0.])
        longitude_start = np.asarray([50.])
        longitude_end = np.asarray([52.])
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2

        latitude_start = np.asarray([0.])
        latitude_end = np.asarray([0.])
        longitude_start = 50.
        longitude_end = 52.
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2
Example #9
0
    def test_great_distance_numpy(self):
        # One decimal degree is 111000m
        latitude_start = 0.
        latitude_end = 0.
        longitude_start = [49., 75.]
        longitude_end = [50., 76.]

        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.allclose(gd["distance"] / 1000, 111.32)
Example #10
0
    def test_great_distance_scalars(self):
        # One decimal degree at the equator is about 111.32km
        latitude_start = 0.
        latitude_end = 0.
        longitude_start = 50.
        longitude_end = 52.

        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert round(gd['distance'] / 1000, 2) == 111.32 * 2
Example #11
0
 def test_great_distance_empty_numpy(self):
     latitude_start = np.ma.asarray([])
     latitude_end = np.ma.asarray([])
     longitude_start = np.ma.asarray([])
     longitude_end = np.ma.asarray([])
     gd = great_distance(start_latitude=latitude_start,
                         start_longitude=longitude_start,
                         end_latitude=latitude_end,
                         end_longitude=longitude_end)
     assert np.all(gd['distance'].mask == True)  # noqa
     assert np.all(gd['azimuth'].mask == True)  # noqa
     assert np.all(gd['reverse_azimuth'].mask == True)  # noqa
Example #12
0
def _reproject(lats, lngs, latA, lngA, latB, lngB):
    """
    lat,lng -- wgs84 input arrays
    latA,lngA,latB,lngB -- ref coordinates
    return -- x,y numpy array
    """
    lats = np.array(lats)
    lngs = np.array(lngs)

    vincenty = great_distance(start_latitude=latA,
                              start_longitude=lngA,
                              end_latitude=latB,
                              end_longitude=lngB)
    alpha = vincenty['azimuth']

    p1 = pyproj.Proj(proj='longlat', datum='WGS84')

    if alpha == 0 or alpha == 180 or (latA == 0 and
                                      (alpha == 90 or alpha == 270)) or (
                                          latA >= 90 or latA <= -90):
        # TODO: Use transverse mercator / simple mercator when appropriate, else libproj4 will throw
        #       "RuntimeError: lat_1=lat_2 or lat_1=0 or lat_2=90"
        raise NotImplementedError(
            "Proj.4 doesn't support omerc projection perfectly aligned with a meridian, perfectly aligned with equator, or at pole"
        )

    if alpha <= 90 or alpha > 270:
        p2 = pyproj.Proj(
            proj='omerc',
            lat_0=latA,
            lonc=lngA,
            alpha=alpha,
            gamma=0,
        )
        xs, ys = pyproj.transform(p1, p2, lngs, lats)
    else:
        # Workaround bug in Proj.4 when alpha is in south direction: https://github.com/OSGeo/proj.4/issues/331
        # For south facing angles, use opposite north facing direction, and flip results
        alpha = (alpha - 180) % 360
        p2 = pyproj.Proj(
            proj='omerc',
            lat_0=latA,
            lonc=lngA,
            alpha=alpha,
            gamma=0,
        )
        xs, ys = pyproj.transform(p1, p2, lngs, lats)
        xs = -xs
        ys = -ys

    return xs, ys
Example #13
0
    def test_great_distance_scalars(self):
        # One decimal degree at the equator is about 111.32km
        latitude_start  = 0.
        latitude_end    = 0.
        longitude_start = 50.
        longitude_end   = 52.
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2

        # One decimal degree is 111000m
        latitude_start  = 0.
        latitude_end    = 0.
        longitude_start = [49., 75.]
        longitude_end   = [50., 76.]
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.allclose(gd["distance"] / 1000, 111.32)

        latitude_start  = np.nan
        latitude_end    = np.nan
        longitude_start = np.nan
        longitude_end   = np.nan
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.isnan(gd['distance'])
Example #14
0
    def test_great_distance_masked_numpy(self):
        with self.assertRaises(ValueError):
            latitude_start  = np.ma.asarray([0.])
            latitude_end    = 0.
            longitude_start = 50.
            longitude_end   = 52.
            great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)

        latitude_start  = np.ma.asarray([0.])
        latitude_end    = np.ma.asarray([0.])
        longitude_start = np.ma.asarray([50.])
        longitude_end   = np.ma.asarray([52.])
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2

        xmask = np.load(os.path.join(os.path.dirname(__file__), 'xmask.npy'))
        ymask = np.load(os.path.join(os.path.dirname(__file__), 'ymask.npy'))
        xdata = np.load(os.path.join(os.path.dirname(__file__), 'x.npy'))
        x = np.ma.fix_invalid(xdata, mask=xmask)
        ydata = np.load(os.path.join(os.path.dirname(__file__), 'y.npy'))
        y = np.ma.fix_invalid(ydata, mask=ymask)
        gd = great_distance(start_latitude=y[0:-1], start_longitude=x[0:-1], end_latitude=y[1:], end_longitude=x[1:])

        latitude_start  = np.ma.MaskedArray(np.ma.asarray([0.]), mask=[1])
        latitude_end    = np.ma.MaskedArray(np.ma.asarray([0.]), mask=[1])
        longitude_start = np.ma.MaskedArray(np.ma.asarray([50.]), mask=[1])
        longitude_end   = np.ma.MaskedArray(np.ma.asarray([52.]), mask=[1])
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert np.all(gd['distance'].mask == True)  # noqa
        assert np.all(gd['azimuth'].mask == True)  # noqa
        assert np.all(gd['reverse_azimuth'].mask == True)  # noqa

        latitude_start  = np.ma.MaskedArray(np.ma.asarray([0., 1.]), mask=[1, 0])
        latitude_end    = np.ma.MaskedArray(np.ma.asarray([0., 1.]), mask=[1, 0])
        longitude_start = np.ma.MaskedArray(np.ma.asarray([49., 75.]), mask=[1, 0])
        longitude_end   = np.ma.MaskedArray(np.ma.asarray([50., 76.]), mask=[1, 0])
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert gd['distance'].mask.tolist() == [True, False]
        assert gd['azimuth'].mask.tolist() == [True, False]
        assert gd['reverse_azimuth'].mask.tolist() == [True, False]

        latitude_start  = np.ma.MaskedArray(np.ma.asarray([0., 1.]), mask=[1, 1])
        latitude_end    = np.ma.MaskedArray(np.ma.asarray([0., 1.]), mask=[1, 1])
        longitude_start = np.ma.MaskedArray(np.ma.asarray([49., 75.]), mask=[1, 1])
        longitude_end   = np.ma.MaskedArray(np.ma.asarray([50., 76.]), mask=[1, 1])
        gd = great_distance(start_latitude=latitude_start, start_longitude=longitude_start, end_latitude=latitude_end, end_longitude=longitude_end)
        assert gd['distance'].mask.tolist() == [True, True]
        assert gd['azimuth'].mask.tolist() == [True, True]
        assert gd['reverse_azimuth'].mask.tolist() == [True, True]
def grcrcl2(startlong, startlat, endlong, endlat):
    """
    Geodesic distance computation with Pygc
    https://github.com/axiom-data-science/pygc
    
    Geodesic distance calculations using Vincenty's formulae:
        http://en.wikipedia.org/wiki/Vincenty%27s_formulae
    
    Default values used (WGS84):
    https://github.com/axiom-data-science/pygc/blob/master/pygc/gc.py
        - Semi-major axis: 6378137.0
        - Semi-minor axis: 6356752.3142
    Therefore:
        - Flattening: 0.0033528106718309896
        - Inverse flattening: 298.2572229328697
    
    """
    
    res = great_distance(start_latitude=startlat, start_longitude=startlong, 
                        end_latitude=endlat, end_longitude=endlong)
    
    return float(res['distance'])
Example #16
0
    def to_dataframe(self, clean_cols=True, clean_rows=True):

        zvar = self.z_axes()[0]
        zs = len(self.dimensions[zvar.dimensions[0]])

        # Profiles
        pvar = self.get_variables_by_attributes(cf_role='profile_id')[0]
        try:
            p = normalize_array(pvar)
        except ValueError:
            p = np.asarray(list(range(len(pvar))), dtype=np.integer)
        ps = p.size
        p = p.repeat(zs)
        logger.debug(['profile data size: ', p.size])

        # Z
        z = generic_masked(zvar[:], attrs=self.vatts(zvar.name)).round(5)
        try:
            z = np.tile(z, ps)
        except ValueError:
            z = z.flatten()
        logger.debug(['z data size: ', z.size])

        # T
        tvar = self.t_axes()[0]
        t = nc4.num2date(tvar[:], tvar.units,
                         getattr(tvar, 'calendar', 'standard'))
        if isinstance(t, datetime):
            # Size one
            t = np.array([t.isoformat()], dtype='datetime64')
        t = t.repeat(zs)
        logger.debug(['time data size: ', t.size])

        # X
        xvar = self.x_axes()[0]
        x = generic_masked(xvar[:].repeat(zs),
                           attrs=self.vatts(xvar.name)).round(5)
        logger.debug(['x data size: ', x.size])

        # Y
        yvar = self.y_axes()[0]
        y = generic_masked(yvar[:].repeat(zs),
                           attrs=self.vatts(yvar.name)).round(5)
        logger.debug(['y data size: ', y.size])

        # Distance
        d = np.ma.zeros(y.size, dtype=np.float64)
        d[1:] = great_distance(start_latitude=y[0:-1],
                               end_latitude=y[1:],
                               start_longitude=x[0:-1],
                               end_longitude=x[1:])['distance']
        d = generic_masked(np.cumsum(d), minv=0).round(2)
        logger.debug(['distance data size: ', d.size])

        df_data = {'t': t, 'x': x, 'y': y, 'z': z, 'profile': p, 'distance': d}

        building_index_to_drop = np.ones(t.size, dtype=bool)
        extract_vars = list(set(self.data_vars() + self.ancillary_vars()))
        for i, dvar in enumerate(extract_vars):
            vdata = np.ma.fix_invalid(
                np.ma.MaskedArray(dvar[:].round(3).flatten()))
            building_index_to_drop = (building_index_to_drop == True) & (
                vdata.mask == True)  # noqa
            df_data[dvar.name] = vdata

        df = pd.DataFrame(df_data)

        # Drop all data columns with no data
        if clean_cols:
            df = df.dropna(axis=1, how='all')

        # Drop all data rows with no data variable data
        if clean_rows:
            df = df.iloc[~building_index_to_drop]

        return df
Example #17
0
    def to_dataframe(self, clean_cols=True, clean_rows=True):
        # The index variable (trajectory_index) is identified by having an
        # attribute with name of instance_dimension whose value is the instance
        # dimension name (trajectory in this example). The index variable must
        # have the profile dimension as its sole dimension, and must be type
        # integer. Each value in the index variable is the zero-based trajectory
        # index that the profile belongs to i.e. profile p belongs to trajectory
        # i=trajectory_index(p), as in section H.2.5.
        r_index_var = self.get_variables_by_attributes(
            instance_dimension=lambda x: x is not None)[0]
        p_dim = self.dimensions[r_index_var.dimensions[0]]  # Profile dimension
        r_dim = self.dimensions[
            r_index_var.instance_dimension]  # Trajectory dimension

        # The count variable (row_size) contains the number of elements for
        # each profile, which must be written contiguously. The count variable
        # is identified by having an attribute with name sample_dimension whose
        # value is the sample dimension (obs in this example) being counted. It
        # must have the profile dimension as its sole dimension, and must be
        # type integer
        o_index_var = self.get_variables_by_attributes(
            sample_dimension=lambda x: x is not None)[0]
        o_dim = self.dimensions[
            o_index_var.sample_dimension]  # Sample dimension

        try:
            rvar = self.get_variables_by_attributes(cf_role='trajectory_id')[0]
            traj_indexes = normalize_array(rvar)
            assert traj_indexes.size == r_dim.size
        except BaseException:
            logger.warning(
                'Could not pull trajectory values a variable with "cf_role=trajectory_id", using a computed range.'
            )
            traj_indexes = np.arange(r_dim.size)
        try:
            pvar = self.get_variables_by_attributes(cf_role='profile_id')[0]
            profile_indexes = normalize_array(pvar)
            assert profile_indexes.size == p_dim.size
        except BaseException:
            logger.warning(
                'Could not pull profile values from a variable with "cf_role=profile_id", using a computed range.'
            )
            profile_indexes = np.arange(p_dim.size)

        # Profile dimension
        tvars = self.t_axes()
        if len(tvars) > 1:
            tvar = [
                v for v in self.t_axes() if v.dimensions == (
                    p_dim.name, ) and getattr(v, 'axis', '').lower() == 't'
            ][0]
        else:
            tvar = tvars[0]

        xvars = self.x_axes()
        if len(xvars) > 1:
            xvar = [
                v for v in self.x_axes() if v.dimensions == (
                    p_dim.name, ) and getattr(v, 'axis', '').lower() == 'x'
            ][0]
        else:
            xvar = xvars[0]

        yvars = self.y_axes()
        if len(yvars) > 1:
            yvar = [
                v for v in self.y_axes() if v.dimensions == (
                    p_dim.name, ) and getattr(v, 'axis', '').lower() == 'y'
            ][0]
        else:
            yvar = yvars[0]

        zvars = self.z_axes()
        if len(zvars) > 1:
            zvar = [
                v for v in self.z_axes() if v.dimensions == (
                    o_dim.name, ) and getattr(v, 'axis', '').lower() == 'z'
            ][0]
        else:
            zvar = zvars[0]

        p = np.ma.masked_all(o_dim.size, dtype=profile_indexes.dtype)
        r = np.ma.masked_all(o_dim.size, dtype=traj_indexes.dtype)
        t = np.ma.masked_all(o_dim.size, dtype=tvar.dtype)
        x = np.ma.masked_all(o_dim.size, dtype=xvar.dtype)
        y = np.ma.masked_all(o_dim.size, dtype=yvar.dtype)
        si = 0

        for i in np.arange(profile_indexes.size):
            ei = si + o_index_var[i]
            p[si:ei] = profile_indexes[i]
            r[si:ei] = traj_indexes[r_index_var[i]]
            t[si:ei] = tvar[i]
            x[si:ei] = xvar[i]
            y[si:ei] = yvar[i]
            si = ei

        t_mask = False
        tfill = get_fill_value(tvar)
        if tfill is not None:
            t_mask = np.copy(np.ma.getmaskarray(t))
            t[t_mask] = 1

        t = np.ma.MaskedArray(
            nc4.num2date(t, tvar.units, getattr(tvar, 'calendar', 'standard')))
        # Patch the time variable back to its original mask, since num2date
        # breaks any missing/fill values
        t[t_mask] = np.ma.masked

        # X and Y
        x = generic_masked(x, minv=-180, maxv=180).round(5)
        y = generic_masked(y, minv=-90, maxv=90).round(5)

        # Distance
        d = np.ma.zeros(o_dim.size, dtype=np.float64)
        d[1:] = great_distance(start_latitude=y[0:-1],
                               end_latitude=y[1:],
                               start_longitude=x[0:-1],
                               end_longitude=x[1:])['distance']
        d = generic_masked(np.cumsum(d), minv=0).round(2)

        # Sample dimension
        z = generic_masked(zvar[:].flatten(),
                           attrs=self.vatts(zvar.name)).round(5)

        df_data = {
            't': t,
            'x': x,
            'y': y,
            'z': z,
            'trajectory': r,
            'profile': p,
            'distance': d
        }

        building_index_to_drop = np.ones(o_dim.size, dtype=bool)
        extract_vars = list(set(self.data_vars() + self.ancillary_vars()))
        for i, dvar in enumerate(extract_vars):

            # Profile dimensions
            if dvar.dimensions == (p_dim.name, ):
                vdata = np.ma.masked_all(o_dim.size, dtype=dvar.dtype)
                si = 0
                for j in np.arange(profile_indexes.size):
                    ei = si + o_index_var[j]
                    vdata[si:ei] = dvar[j]
                    si = ei

            # Sample dimensions
            elif dvar.dimensions == (o_dim.name, ):
                vdata = generic_masked(dvar[:].flatten(),
                                       attrs=self.vatts(dvar.name)).round(3)

            else:
                logger.warning(
                    "Skipping variable {}... it didn't seem like a data variable"
                    .format(dvar))

            building_index_to_drop = (building_index_to_drop == True) & (
                vdata.mask == True)  # noqa
            df_data[dvar.name] = vdata

        df = pd.DataFrame(df_data)

        # Drop all data columns with no data
        if clean_cols:
            df = df.dropna(axis=1, how='all')

        # Drop all data rows with no data variable data
        if clean_rows:
            df = df.iloc[~building_index_to_drop]

        return df
def grcrcl2(startlong, startlat, endlong, endlat):
    
    res = great_distance(start_latitude=startlat, start_longitude=startlong, 
                        end_latitude=endlat, end_longitude=endlong)
    
    return float(res['distance'])
Example #19
0
def location_test(lon: Sequence[N],
                  lat: Sequence[N],
                  bbox: Tuple[N, N, N, N] = (-180, -90, 180, 90),
                  range_max: N = None) -> np.ma.core.MaskedArray:
    """Checks that a location is within reasonable bounds.

    Checks that longitude and latitude are within reasonable bounds defaulting
    to lon = [-180, 180] and lat = [-90, 90].  Optionally, check for a maximum
    range parameter in great circle distance defaulting to meters which can
    also use a unit from the quantities library. Missing and masked data is
    flagged as UNKNOWN.

    Args:
        lon: Longitudes as a numeric numpy array or a list of numbers.
        lat: Latitudes as a numeric numpy array or a list of numbers.
        bbox: A length 4 tuple expressed in (minx, miny, maxx, maxy) [optional].
        range_max: Maximum allowed range expressed in geodesic curve distance (meters).

    Returns:
        A masked array of flag values equal in size to that of the input.
    """

    bboxnt = namedtuple('BBOX', 'minx miny maxx maxy')
    if bbox is not None:
        assert isfixedlength(bbox, 4)
        bbox = bboxnt(*bbox)

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        lat = np.ma.masked_invalid(np.array(lat).astype(np.floating))
        lon = np.ma.masked_invalid(np.array(lon).astype(np.floating))

    if lon.shape != lat.shape:
        raise ValueError(
            'Lon ({0.shape}) and lat ({1.shape}) are different shapes'.format(
                lon, lat))

    # Save original shape
    original_shape = lon.shape
    lon = lon.flatten()
    lat = lat.flatten()

    # Start with everything as passing (1)
    flag_arr = np.ma.ones(lon.size, dtype='uint8')

    # If either lon or lat are masked we just set the flag to MISSING
    mloc = lon.mask & lat.mask
    flag_arr[mloc] = QartodFlags.MISSING

    # If there is only one masked value fail the location test
    mismatch = lon.mask != lat.mask
    flag_arr[mismatch] = QartodFlags.FAIL

    if range_max is not None and lon.size > 1:
        # Calculating the great_distance between each point
        # Flag suspect any distance over range_max
        d = np.ma.zeros(lon.size, dtype=np.float64)
        d[1:] = great_distance(start_latitude=lat[:-1],
                               end_latitude=lat[1:],
                               start_longitude=lon[:-1],
                               end_longitude=lon[1:])['distance']
        flag_arr[d > range_max] = QartodFlags.SUSPECT

    # Ignore warnings when comparing NaN values even though they are masked
    # https://github.com/numpy/numpy/blob/master/doc/release/1.8.0-notes.rst#runtime-warnings-when-comparing-nan-numbers
    with np.errstate(invalid='ignore'):
        flag_arr[(lon < bbox.minx) | (lat < bbox.miny) | (lon > bbox.maxx) |
                 (lat > bbox.maxy)] = QartodFlags.FAIL

    return flag_arr.reshape(original_shape)
Example #20
0
import vincenty
import pygc
import random

for i in range(1000):
    lat1 = random.uniform(-80, 80)
    lng1 = random.uniform(-180, 180)
    lat2 = random.uniform(-80, 80)
    lng2 = random.uniform(-80, 80)

    d, a_initial, a_final = vincenty.dist_bear_vincenty(lat1, lng1, lat2, lng2)
    assert a_final >= 0.0
    # print d, a_initial, a_final

    p = pygc.great_distance(start_latitude=lat1,
                            start_longitude=lng1,
                            end_latitude=lat2,
                            end_longitude=lng2)
    # print p

    assert math.fabs(d * 1000.0 - p['distance']) < .1
    assert math.fabs(a_initial - p['azimuth']) < 1e-6
    assert math.fabs(a_final - p['reverse_azimuth']) < 1e-6

print 'direct'

for i in range(1000):
    lat = random.uniform(-80, 80)
    lng = random.uniform(-180, 180)
    dist = random.uniform(10, 1000000)
    bearing = random.uniform(-180, 180)
Example #21
0
    def to_dataframe(self, clean_cols=True, clean_rows=True):
        # Z
        zvar = self.z_axes()[0]
        z = np.ma.fix_invalid(np.ma.MaskedArray(zvar[:]))
        z = z.flatten().round(5)
        logger.debug(['z data size: ', z.size])

        # T
        tvar = self.t_axes()[0]
        t = np.ma.MaskedArray(nc4.num2date(tvar[:], tvar.units, getattr(tvar, 'calendar', 'standard'))).flatten()
        # Patch the time variable back to its original mask, since num2date
        # breaks any missing/fill values
        if hasattr(tvar[0], 'mask'):
            t.mask = tvar[:].mask
        logger.debug(['time data size: ', t.size])

        # X
        xvar = self.x_axes()[0]
        x = np.ma.fix_invalid(np.ma.MaskedArray(xvar[:])).flatten().round(5)
        logger.debug(['x data size: ', x.size])

        # Y
        yvar = self.y_axes()[0]
        y = np.ma.fix_invalid(np.ma.MaskedArray(yvar[:])).flatten().round(5)
        logger.debug(['y data size: ', y.size])

        # Trajectories
        pvar = self.get_variables_by_attributes(cf_role='trajectory_id')[0]

        try:
            p = normalize_array(pvar)
        except BaseException:
            logger.exception('Could not pull trajectory values from the variable, using indexes.')
            p = np.asarray(list(range(len(pvar))), dtype=np.integer)

        # The Dimension that the trajectory id variable doesn't have is what
        # the trajectory data needs to be repeated by
        dim_diff = self.dimensions[list(set(tvar.dimensions).difference(set(pvar.dimensions)))[0]]
        if dim_diff:
            p = p.repeat(dim_diff.size)
        logger.debug(['trajectory data size: ', p.size])

        # Distance
        d = np.append([0], great_distance(start_latitude=y[0:-1], end_latitude=y[1:], start_longitude=x[0:-1], end_longitude=x[1:])['distance'])
        d = np.ma.fix_invalid(np.ma.MaskedArray(np.cumsum(d)).astype(np.float64).round(2))
        logger.debug(['distance data size: ', d.size])

        df_data = {
            't': t,
            'x': x,
            'y': y,
            'z': z,
            'trajectory': p,
            'distance': d
        }

        building_index_to_drop = np.ones(t.size, dtype=bool)
        extract_vars = list(set(self.data_vars() + self.ancillary_vars()))
        for i, dvar in enumerate(extract_vars):
            vdata = np.ma.fix_invalid(np.ma.MaskedArray(dvar[:].round(3).flatten()))
            building_index_to_drop = (building_index_to_drop == True) & (vdata.mask == True)  # noqa
            df_data[dvar.name] = vdata

        df = pd.DataFrame(df_data)

        # Drop all data columns with no data
        if clean_cols:
            df = df.dropna(axis=1, how='all')

        # Drop all data rows with no data variable data
        if clean_rows:
            df = df.iloc[~building_index_to_drop]

        return df
Example #22
0
    def test_great_distance_masked_numpy(self):
        with self.assertRaises(ValueError):
            latitude_start = np.ma.asarray([0.])
            latitude_end = 0.
            longitude_start = 50.
            longitude_end = 52.
            great_distance(start_latitude=latitude_start,
                           start_longitude=longitude_start,
                           end_latitude=latitude_end,
                           end_longitude=longitude_end)

        latitude_start = np.ma.asarray([0.])
        latitude_end = np.ma.asarray([0.])
        longitude_start = np.ma.asarray([50.])
        longitude_end = np.ma.asarray([52.])
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.round(gd['distance'] / 1000, 2) == 111.32 * 2

        xmask = np.load(os.path.join(os.path.dirname(__file__), 'xmask.npy'))
        ymask = np.load(os.path.join(os.path.dirname(__file__), 'ymask.npy'))
        xdata = np.load(os.path.join(os.path.dirname(__file__), 'x.npy'))
        x = np.ma.fix_invalid(xdata, mask=xmask)
        ydata = np.load(os.path.join(os.path.dirname(__file__), 'y.npy'))
        y = np.ma.fix_invalid(ydata, mask=ymask)
        gd = great_distance(start_latitude=y[0:-1],
                            start_longitude=x[0:-1],
                            end_latitude=y[1:],
                            end_longitude=x[1:])

        latitude_start = np.ma.MaskedArray(np.ma.asarray([0.]), mask=[1])
        latitude_end = np.ma.MaskedArray(np.ma.asarray([0.]), mask=[1])
        longitude_start = np.ma.MaskedArray(np.ma.asarray([50.]), mask=[1])
        longitude_end = np.ma.MaskedArray(np.ma.asarray([52.]), mask=[1])
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert np.all(gd['distance'].mask == True)  # noqa
        assert np.all(gd['azimuth'].mask == True)  # noqa
        assert np.all(gd['reverse_azimuth'].mask == True)  # noqa

        latitude_start = np.ma.MaskedArray(np.ma.asarray([0., 1.]),
                                           mask=[1, 0])
        latitude_end = np.ma.MaskedArray(np.ma.asarray([0., 1.]), mask=[1, 0])
        longitude_start = np.ma.MaskedArray(np.ma.asarray([49., 75.]),
                                            mask=[1, 0])
        longitude_end = np.ma.MaskedArray(np.ma.asarray([50., 76.]),
                                          mask=[1, 0])
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert gd['distance'].mask.tolist() == [True, False]
        assert gd['azimuth'].mask.tolist() == [True, False]
        assert gd['reverse_azimuth'].mask.tolist() == [True, False]

        latitude_start = np.ma.MaskedArray(np.ma.asarray([0., 1.]),
                                           mask=[1, 1])
        latitude_end = np.ma.MaskedArray(np.ma.asarray([0., 1.]), mask=[1, 1])
        longitude_start = np.ma.MaskedArray(np.ma.asarray([49., 75.]),
                                            mask=[1, 1])
        longitude_end = np.ma.MaskedArray(np.ma.asarray([50., 76.]),
                                          mask=[1, 1])
        gd = great_distance(start_latitude=latitude_start,
                            start_longitude=longitude_start,
                            end_latitude=latitude_end,
                            end_longitude=longitude_end)
        assert gd['distance'].mask.tolist() == [True, True]
        assert gd['azimuth'].mask.tolist() == [True, True]
        assert gd['reverse_azimuth'].mask.tolist() == [True, True]