Esempio n. 1
0
def test_matchcrs(geometry_urb):
    bounds = geometry_urb.bounds
    points = ((bounds[0], bounds[2]), (bounds[1], bounds[3]))
    coords = MatchCRS.coords(points, DEF_CRS, ALT_CRS)
    bbox = MatchCRS.bounds(geometry_urb.bounds, DEF_CRS, ALT_CRS)
    geom = MatchCRS.geometry(geometry_urb, DEF_CRS, ALT_CRS)
    assert (abs(geom.centroid.x * 1e-4 - (-362.099)) < 1e-3
            and abs(bbox[0] * 1e-4 - (-365.403)) < 1e-3
            and abs(coords[0][-1] * 1e-4 == (-287.707)) < 1e-3)
Esempio n. 2
0
def elevation_byloc(coord: Tuple[float, float], crs: str = DEF_CRS):
    """Get elevation from USGS 3DEP service for a coordinate.

    Parameters
    ----------
    coord : tuple
        Coordinates of the location as a tuple
    crs : str, optional
        The spatial reference of the input coord, defaults to epsg:4326 (lon, lat)

    Returns
    -------
    float
        Elevation in meter
    """
    if not isinstance(coord, tuple) or len(coord) != 2:
        raise InvalidInputType("coord", "tuple of length 2", "(x, y)")

    lon, lat = MatchCRS.coords(([coord[0]], [coord[1]]), crs, DEF_CRS)

    url = "https://nationalmap.gov/epqs/pqs.php"
    payload = {"output": "json", "x": lon[0], "y": lat[0], "units": "Meters"}
    r = RetrySession().get(url, payload)
    root = r.json()["USGS_Elevation_Point_Query_Service"]
    elevation = float(root["Elevation_Query"]["Elevation"])

    if abs(elevation - (-1000000)) < 1e-3:
        raise ValueError(
            f"The elevation of the requested coordinate ({coord[0]}, {coord[1]}) cannot be found."
        )

    return elevation
Esempio n. 3
0
def test_grid(geometry):
    geo_crs = DEF_CRS
    crs = "+proj=lcc +lat_1=25 +lat_2=60 +lat_0=42.5 +lon_0=-100 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs"
    geom = MatchCRS.geometry(geometry, geo_crs, crs)
    xmin, ymin, xmax, ymax = geom.bounds
    res = 1e3
    gx = np.arange(xmin, xmax, res)
    gy = np.arange(ymin, ymax, res)
    elev = py3dep.elevation_bygrid(gx, gy, crs, res)
    assert abs(elev.mean().item() - 295.763) < 1e-3
Esempio n. 4
0
    def navigate_byloc(
        self,
        coords: Tuple[float, float],
        navigation: Optional[str] = None,
        source: Optional[str] = None,
        loc_crs: str = DEF_CRS,
        distance: int = 500,
        comid_only: bool = False,
    ) -> gpd.GeoDataFrame:
        """Navigate the NHDPlus databse from a coordinate.

        Parameters
        ----------
        coordinate : tuple
            A tuple of length two (x, y).
        navigation : str, optional
            The navigation method, defaults to None which throws an exception
            if comid_only is False.
        source : str, optional
            Return the data from another source after navigating
            the features using fsource, defaults to None which throws an exception
            if comid_only is False.
        loc_crs : str, optional
            The spatial reference of the input coordinate, defaults to EPSG:4326.
        distance : int, optional
            Limit the search for navigation up to a distance in km,
            defaults to 500 km. Note that this is an expensive request so you
            have be mindful of the value that you provide. If you want to get
            all the available features you can pass a large distance like 9999999.
        comid_only : bool, optional
            Whether to return the nearest comid without navigation.

        Returns
        -------
        geopandas.GeoDataFrame
            NLDI indexed features in EPSG:4326.
        """
        _coords = MatchCRS().coords(((coords[0], ), (coords[1], )), loc_crs,
                                    DEF_CRS)
        lon, lat = _coords[0][0], _coords[1][0]

        url = "/".join([self.base_url, "linked-data", "comid", "position"])
        payload = {"coords": f"POINT({lon} {lat})"}
        rjson = self._geturl(url, payload)
        comid = geoutils.json2geodf(rjson, ALT_CRS, DEF_CRS).comid.iloc[0]

        if comid_only:
            return comid

        if navigation is None or source is None:
            raise MissingItems(["navigation", "source"])

        return self.navigate_byid("comid", comid, navigation, source, distance)
Esempio n. 5
0
File: pynhd.py Progetto: jsta/pynhd
    def bydistance(self,
                   coords: Tuple[float, float],
                   distance: int,
                   loc_crs: str = DEF_CRS) -> gpd.GeoDataFrame:
        """Get features within a radius (in meters) of a point."""
        if isinstance(coords, (list, tuple)) and len(coords) != 2:
            raise InvalidInputType("coords", "tuple or list of length 2.")

        _coords = MatchCRS.coords(((coords[0], ), (coords[1], )), loc_crs,
                                  ALT_CRS)
        cql_filter = (
            f"DWITHIN(the_geom,POINT({_coords[1][0]:.6f} {_coords[0][0]:.6f}),{distance},meters)"
        )
        resp = self.wfs.getfeature_byfilter(cql_filter, "GET")
        return self._to_geodf(resp)
Esempio n. 6
0
File: pynhd.py Progetto: jsta/pynhd
    def comid_byloc(
        self,
        coords: Union[Tuple[float, float], List[Tuple[float, float]]],
        loc_crs: str = DEF_CRS,
    ) -> Union[gpd.GeoDataFrame, Tuple[gpd.GeoDataFrame, List[Tuple[float,
                                                                    float]]]]:
        """Get the closest ComID(s) based on coordinates.

        Parameters
        ----------
        coords : tuple or list
            A tuple of length two (x, y) or a list of them.
        loc_crs : str, optional
            The spatial reference of the input coordinate, defaults to EPSG:4326.

        Returns
        -------
        geopandas.GeoDataFrame or (geopandas.GeoDataFrame, list)
            NLDI indexed ComID(s) in EPSG:4326. If some coords don't return any ComID
            a list of missing coords are returnd as well.
        """
        coords = coords if isinstance(coords, list) else [coords]
        coords_4326 = list(
            zip(*MatchCRS.coords(tuple(zip(*coords)), loc_crs, DEF_CRS)))

        base_url = "/".join(
            [self.base_url, "linked-data", "comid", "position"])
        urls = {(coords[i][0], coords[i][1]):
                f"{base_url}?coords=POINT({lon} {lat})"
                for i, (lon, lat) in enumerate(coords_4326)}
        comids, not_found = self._get_urls(urls)
        comids = comids.reset_index(level=2, drop=True)

        if len(not_found) > 0:
            self._missing_warning(len(not_found), len(coords))
            return comids, not_found

        return comids
Esempio n. 7
0
def elevation_bycoords(coords: List[Tuple[float, float]],
                       crs: str = DEF_CRS) -> List[int]:
    """Get elevation from Airmap for a list of coordinates.

    Parameters
    ----------
    coords : list of tuples
        Coordinates of the location as a tuple
    crs : str, optional
        The spatial reference of the input coord, defaults to epsg:4326 (lon, lat)

    Returns
    -------
    list of int
        Elevation in meter
    """
    if not isinstance(coords, (list, Iterator)):
        raise InvalidInputType("coord",
                               "list (or iterator) of tuples of length 2",
                               "[(x, y), ...]")

    if isinstance(coords, list) and any(len(c) != 2 for c in coords):
        raise InvalidInputType("coord", "list of tuples of length 2",
                               "[(x, y), ...]")

    coords_reproj = zip(*MatchCRS.coords(tuple(zip(*coords)), crs, DEF_CRS))
    coords_reproj = tlz.partition_all(100, coords_reproj)

    headers = {"Content-Type": "application/json", "charset": "utf-8"}
    elevations = []
    for chunk in coords_reproj:
        payload = {"points": ",".join(f"{lat},{lon}" for lon, lat in chunk)}
        resp = RetrySession().get(ServiceURL().restful.airmap,
                                  payload=payload,
                                  headers=headers)
        elevations.append(resp.json()["data"])

    return list(tlz.concat(elevations))
Esempio n. 8
0
def get_byloc(
    coords: Tuple[float, float],
    dates: Union[Tuple[str, str], Union[int, List[int]]],
    crs: str = DEF_CRS,
    variables: Optional[Union[List[str], str]] = None,
    pet: bool = False,
) -> pd.DataFrame:
    """Get daily climate data from Daymet for a single point.

    Parameters
    ----------
    coords : tuple
        Longitude and latitude of the location of interest as a tuple (lon, lat)
    dates : tuple or list
        Either a tuple (start, end) or a list of years [YYYY, ...].
    crs :  str, optional
        The spatial reference of the input coordinates, defaults to epsg:4326
    variables : str or list or tuple, optional
        List of variables to be downloaded. The acceptable variables are:
        ``tmin``, ``tmax``, ``prcp``, ``srad``, ``vp``, ``swe``, ``dayl``
        Descriptions can be found `here <https://daymet.ornl.gov/overview>`__.
        Defaults to None i.e., all the variables are downloaded.
    pet : bool, optional
        Whether to compute evapotranspiration based on
        `UN-FAO 56 paper <http://www.fao.org/docrep/X0490E/X0490E00.htm>`__.
        The default is False

    Returns
    -------
    pandas.DataFrame
        Daily climate data for a location
    """
    daymet = Daymet(variables, pet)

    if isinstance(dates, tuple) and len(dates) == 2:
        dates_dict = daymet.dates_todict(dates)
    elif isinstance(dates, (list, int)):
        dates_dict = daymet.years_todict(dates)
    else:
        raise InvalidInputType("dates", "tuple or list",
                               "(start, end) or [2001, 2010, ...]")

    if isinstance(coords, tuple) and len(coords) == 2:
        _coords = MatchCRS.coords(((coords[0], ), (coords[1], )), crs, DEF_CRS)
        lon, lat = (_coords[0][0], _coords[1][0])
    else:
        raise InvalidInputType("coords", "tuple", "(lon, lat)")

    if not ((14.5 < lat < 52.0) or (-131.0 < lon < -53.0)):
        raise InvalidInputRange(
            "The location is outside the Daymet dataset. " +
            "The acceptable range is: " +
            "14.5 < lat < 52.0 and -131.0 < lon < -53.0")

    payload = {
        "lat": f"{lat:.6f}",
        "lon": f"{lon:.6f}",
        "vars": ",".join(daymet.variables),
        "format": "json",
        **dates_dict,
    }

    r = daymet.session.get(ServiceURL().restful.daymet_point, payload)

    clm = pd.DataFrame(r.json()["data"])
    clm.index = pd.to_datetime(clm.year * 1000.0 + clm.yday, format="%Y%j")
    clm = clm.drop(["year", "yday"], axis=1)

    if pet:
        clm = daymet.pet_byloc(clm, (lon, lat))
    return clm