ebird-api icon indicating copy to clipboard operation
ebird-api copied to clipboard

is it possible to get species list from lat-lon?

Open sammlapp opened this issue 6 months ago • 1 comments

Thanks for implementing this package!

From a look at the eBird API, I can see API methods to

  • get species list from region code
  • get recent observations from species code or from lat/lon

But there is no "get species list from lat lon (radius <50km)". I guess this is not implemented?

If this is not possible with the eBird API, it would be useful to be able to determine the local region code from a lat-lon (I'm not sure how to determine the eBird region code in general?) so that we could get a species list from lat-lon based on the local region code:

region_code = ebird_region_from_lat_lon(lat,lon,level='subnational2 region')
species_list = ebird.api.get_observations(api_key, region_code)

sammlapp avatar Aug 25 '25 03:08 sammlapp

FWIW, here's a workaround I'm going to use for now: I find a recent nearby observation (past 30 days) based on lat-lon, and use that to then find a region/location ID. Requires that there is a recent checklist within 50 km of the lat/lon. I iteratively check for a checklist within 10km, then in 10km increments up to the max of 50, using the max window of 30 days.

def get_location_from_recent_obs_near_lat_lon(lat, lon):
    nearby_obs = None
    search_dist = 10
    while not nearby_obs:
        nearby_obs_list = get_nearby_observations(
            ebird_api_key, lat, lon, dist=search_dist, back=30, max_results=1
        )
        # drop "private" location entries
        nearby_obs_list = [
            obs for obs in nearby_obs_list if not obs.get("locationPrivate", False)
        ]

        if nearby_obs_list:
            nearby_obs = nearby_obs_list[0]
            # find location details

        if search_dist >= 50:
            raise ValueError(f"No nearby observations found within {search_dist} km")
        else:
            search_dist += 10

    loc = ebird.api.get_location(ebird_api_key, nearby_obs["locId"])
    return {
        k: v
        for k, v in loc.items()
        if k
        in [
            "countryCode",
            "countryName",
            "subnational1Code",
            "subnational1Name",
            "subnational2Code",
            "subnational2Name",
            "locId",
            "locName",
            "lat",
            "lng",
        ]
    }

# example usage:
loc_info = get_location_from_recent_obs_near_lat_lon(55.467, 10.383)
codes = ebird.api.get_species_list(ebird_api_key, loc_info["subnational1Code"])

sammlapp avatar Aug 25 '25 05:08 sammlapp