csparpa / pyowm

A Python wrapper around the OpenWeatherMap web API
https://pyowm.readthedocs.io
MIT License
791 stars 175 forks source link

Implement Satellite imagery support [Agro] #270

Closed csparpa closed 5 years ago

csparpa commented 6 years ago

See https://agromonitoring.com/api/images for reference

csparpa commented 5 years ago

Steps: ONE: you POST a search for available imagery over a specified polygon

TWO: you get back a list of available image products (with their URLs) organized in the following categories: "image", "tile", "stats", and "data":

THREE: you fetch the image that you need by calling its URL. Additional notes:

Example calls

### Search Imagery
GET http://api.agromonitoring.com/agro/1.0/image/search?start={start date}&end={end date}&polyid={ID of polygon}&appid={API key}
{  
   "dt":1500940800,
   "type":"Landsat 8",
   "dc":100,
   "cl":1.56,
   "sun":{  
      "azimuth":126.742,
      "elevation":63.572
   },
   "image":{  
      "truecolor":"http://api.agromonitoring.com/image/1.0/00059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "falsecolor":"http://api.agromonitoring.com/image/1.0/01059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "ndvi":"http://api.agromonitoring.com/image/1.0/02059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "evi":"http://api.agromonitoring.com/image/1.0/03059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7"
   },
   "tile":{  
      "truecolor":"http://api.agromonitoring.com/tile/1.0/{z}/{x}/{y}/00059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "falsecolor":"http://api.agromonitoring.com/tile/1.0/{z}/{x}/{y}/01059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "ndvi":"http://api.agromonitoring.com/tile/1.0/{z}/{x}/{y}/02059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "evi":"http://api.agromonitoring.com/tile/1.0/{z}/{x}/{y}/03059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7"
   },
   "stats":{  
      "ndvi":"http://api.agromonitoring.com/stats/1.0/02359768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "evi":"http://api.agromonitoring.com/stats/1.0/03359768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7"
   },
   "data":{  
      "truecolor":"http://api.agromonitoring.com/data/1.0/00159768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "falsecolor":"http://api.agromonitoring.com/data/1.0/01159768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "ndvi":"http://api.agromonitoring.com/data/1.0/02259768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7",
      "evi":"http://api.agromonitoring.com/data/1.0/03259768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7"
   }
}

### GET image
GET http://api.agromonitoring.com/image/1.0/02059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7&paletteid=1
(You get an image)

### GET tile
GET http://api.agromonitoring.com/tile/1.0/{z}/{x}/{y}/00059768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7
(You get an image)

### GET stats
GET http://api.agromonitoring.com/stats/1.0/02359768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7
{
   "std":0.19696951630010479,
   "p25":0.3090659340659341,
   "num":57162,
   "min":-0.2849250197316496,
   "max":0.8658669574700109,
   "median":0.45692992317131553,
   "p75":0.6432460461498574,
   "mean":0.47631485576814037
}

### GET data (geoTIFF)
GET http://api.agromonitoring.com/data/1.0/02259768a00/5ac22f004b1ae4000b5b97cf?appid=bb0664ed43c153aa072c760594d775a7
(you get an image)
csparpa commented 5 years ago

PyOWM high-level interface and entities

Entities

We have enums:

We need a class representing image metadata referring to a satellite imagery search result: MetaImage

Each MetaImage instance contains:

# Metadata (fetched with the search call)
 - acquisition_time (int/datetime/str - Unix time, UTC)
 - satellite_name (str - values from SatelliteNameEnum)
 - valida_data_percentage (float, Approximate percent of valid data coverage)
 - cloud_coverage_percentage (float, Approximate percent of cloud coverage)
 - sun_azimuth (float, Sun azimuth angle at scene acquisition time)
 - sun _elevation (float, Sun zenith angle at scene acquisition time)

# Attributes
 - url (str, URL needed to download the img)
 - img_type (str, MIME type between PNG and GEOTIFF)
 - preset (str, values from `MetaImagePresetEnum`)
 - reference to an HTTP client or a TileClient (depending on the subtype)

The idea is that the Agro Manager takes a MetaImage and downloads the corresponding image, generating a SatelliteImage instance (note: you need to specify x, y and zoom to download a tile)

A SatelliteImage class embeds both image metadata (aMetaImage instance) and actual image data (either a Tile or Image object)

High-level APIs

list_of_metaimages = agro.search_satellite_imagery(polygon_id, img_type, preset)
metaimg = list_of_metaimages[0]
result = agro.download_satellite_image(metaimg, x=x, y=y, zoom=zoom)   # (x, y, zoom) are needed for Tiles
result  # result a SatelliteImage object, embedding both a MetaImage instance and a Tile/Image instance

agro.stats_for_satellite_image(result)   # gives a dict for presets 'EVI' and 'NDVI', None otherwise
csparpa commented 5 years ago

Closed with 7c45c6b81f528e55eedfb612b89d516566277750