コード例 #1
0
    def search_proximity(cls, lat=50.848, lon=4.351, radius=8):
        """List stations within given radius from a location.

        Args:
            lat: latitude of the center of search, in decimal degrees
            lon: longitude of the center of search, in decimal degrees
            radius: maximum distance from center, in kilometers

        Default values are the approximate center and radius of
        Brussels.

        Returns:
            Dataframe of matching stations, listing sensor types,
                locations and distances in kilometers from the search
                center, indexed by station ID

        The search is based on the station list retrieved as part of the
        metadata.

        The irceline.be API offers an alternative way to get an
        (unordered) list of stations near a location:
        `https://geo.irceline.be/sos/api/v1/stations?
        near={{"center":{{"type":"Point","coordinates":[{lon},
        {lat}]}},"radius":{radius}}}`
        """
        near_stations = cls.stations.copy()
        near_stations["distance"] = (near_stations.apply(
            lambda x: haversine(lat, lon, x["lat"], x["lon"]), axis=1))
        near_stations = (near_stations[
            near_stations["distance"] <= radius].sort_values("distance"))
        return near_stations
コード例 #2
0
def search_proximity(lat=50.848, lon=4.351, radius=8):
    """Find sensors within given radius from a location.

    Args:
        lat: latitude of the center of search, in decimal degrees
        lon: longitude of the center of search, in decimal degrees
        radius: maximum distance from center, in kilometers

    Default values are the approximate center and radius of Brussels.

    Returns:
        Dataframe of matching sensors, listing sensor types, locations
        and distances in kilometers from the search center, indexed by
        sensor ID

    Raises:
        requests.HTTPError if request failed
    """
    url = (API_ENDPOINTS["proximity search pattern"].format(lat=lat,
                                                            lon=lon,
                                                            radius=radius))
    call_rate_limiter()
    response = requests.get(url)
    response.raise_for_status()
    sensors = json_normalize(response.json())
    if len(sensors) == 0:
        sensors = pd.DataFrame(
            columns=["sensor_type", "latitude", "longitude", "distance"])
        sensors.index.name = "sensor_id"
        return sensors
    sensors = (sensors[[
        "sensor.id", "sensor.sensor_type.name", "location.latitude",
        "location.longitude"
    ]].rename(
        columns={
            "sensor.id": "sensor_id",
            "sensor.sensor_type.name": "sensor_type",
            "location.latitude": "latitude",
            "location.longitude": "longitude"
        }))
    for col in "latitude", "longitude":
        sensors[col] = pd.to_numeric(sensors[col], downcast="float")
    sensors.set_index("sensor_id", inplace=True)

    # Drop duplicates - sensors appear once for each measurement in past 5 mins
    sensors = sensors[~sensors.index.duplicated()]

    # Calculate distances from search center and sort by those distances
    sensors["distance"] = sensors.apply(lambda x: utils.haversine(
        lat, lon, float(x["latitude"]), float(x["longitude"])),
                                        axis=1)
    sensors.sort_values("distance", inplace=True)

    return sensors
コード例 #3
0
    def query_time_series(cls, phenomenon, lat_nearest=None, lon_nearest=None):
        """Convenience method to filter time series for those that
        measure a given phenomenon, and sort by distance to a point if
        given.

        Args:
            phenomenon: character sequence or regular expression to
                filter phenomena by; operates on the "phenomenon" column
                of the time_series dataframe
            lat_nearest: latitude of the reference point
            lon_nearest: longitude of the reference point

        Returns:
            Subset of time_series property. If lat_nearest and
                lon_nearest are given, the result has an additional
                column indicating distance in km from that point, and is
                sorted by that distance.

        Raises:
            ValueError if only one of lat_nearest, lon_nearest is given
        """
        if bool(lat_nearest is None) != bool(lon_nearest is None):
            raise ValueError("Provide both or none of lat_nearest, "
                             "lon_nearest")
        phenomena_lower = cls.time_series["phenomenon"].str.lower()
        matches = phenomena_lower.str.contains(phenomenon.lower())
        results = cls.time_series[matches].copy()
        if lat_nearest is None:
            return results
        if len(results) == 0:
            results["distance"] = None
            return results
        results["distance"] = results.apply(lambda row: haversine(
            lat_nearest, lon_nearest, row["station_lat"], row["station_lon"]),
                                            axis=1)
        results = results.sort_values("distance")
        return results