sat-utils/sat-api

Search STAC items by full-featured filtering for a specific scene

Closed this issue · 10 comments

Based on an example in the api docs (https://github.com/sat-utils/sat-api/blob/master/docs/api.md), I managed to use the parameters below in Python to search for a specific landsat for a given period, but the results are not accurate. I added the collection and limit parameters. Inside the query, I added the path (column) and row of the search landsat.
Code:
**import requests
headers = {'Content-Type': 'application/json', 'Accept': 'application/geo+json'}

r = requests.post('https://sat-api.developmentseed.org/stac/search',\
params={"collection":"landsat-8-l1", "bbox": 'null',\
"limit": 5,
"time": "2019-01-01/2019-01-31",\
"query": {"eo:cloud_cover": {"lt": 30}, \
"eo:column": "182", "eo:row": "063"},\
"sort": [{"field": "eo:cloud_cover","direction": "desc"}]\
}, headers = headers)

print r.json()**

Could you please check and fix what I made wrong or show more examples on the queryFilter with many parameters in the documentation

Hi @vick25 , thanks for the issue, your query is not quite correct. It should be

{  
   "page":1,
   "limit":0,
   "query":{  
      "eo:cloud_cover":{  
         "lt":"30"
      },
      "eo:column":{  
         "eq":"182"
      },
      "eo:row":{  
         "eq":"063"
      },
      "collection":{  
         "eq":"landsat-8-l1"
      }
   },
   "time":"2019-01-01/2019-01-31"
}

You left the "eq" out of the row and column properties.

Also note that you can use sat-search for this as well, as a CLI:

$ sat-search search -c landsat-8-l1 --datetime 2019-01-01/2019-01-31 \
   -p 'eo:cloud_cover<30' 'eo:column=182' 'eo:row=063' --found -v 4

The --found switch only gets a count of records found, it doesn't return the items. The -v4 prints out the actual payload:

DEBUG:satsearch.search:Query 
URL: https://sat-api.developmentseed.org/stac/search, 
Body: {"page": 1, "limit": 0, "query": {"eo:cloud_cover": {"lt": "30"}, 
"eo:column": {"eq": "182"}, "eo:row": {"eq": "063"}, "collection": {"eq": "landsat-8-l1"}},
"time": "2019-01-01/2019-01-31"}

You can use it as a Python library as well, see the tutorial.

In the case of this search though there weren't any records found, looks like both scenes have high cloud cover:

$ sat-search search -c landsat-8-l1 --datetime 2019-01-01/2019-01-31 \
   -p 'eo:column=182' 'eo:row=063' --print-md date id eo:cloud_cover --print-cal

image

Great. Thanks very much @matthewhanson for the correction and more explanation.

Using the sat-search as CLI works perfect. But after running the python code again by replacing my search body with yours it did not yield accurate results (let's say empty/zero as there were no records with less than 30% cloud coverage)...
new_search.txt

@vick25 Not sure I understand, your new search has cloud_cover < 60 so should have found 1 result (2019-01-02), are you saying it also returned 0 when cloud_cover < 60 ?

No. I just attached the file for testing multiple values. But with cloud_cover < 60, instead of 1 result, the print r.json() output too many things

ah, I tested it out and saw the same thing, didn't see the problem right away.

In the requests library params is used to create the query string while data is used for the body of the request. So your code would work by making one of the changes below:

  • Change requests.post to requests.get
    or
  • Change the params keyword to data

Did as you said, Either way did not work.
Errors: -with data {u'message': u'Internal server error'}
-with requests.post {u'code': 500, u'description': u'Unexpected token c in JSON at position 0'}

Oh sorry @vick25, forgot something. When posting data you need to encode the dictionary as JSON:

import json
import requests

def main():
    headers = {'Content-Type': 'application/json', 'Accept': 'application/geo+json'}

    r = requests.post('https://sat-api.developmentseed.org/stac/search',
       data = json.dumps({
       "limit":0,
       "query":{
            "eo:cloud_cover":{
                "lt":"60"
            },
            "eo:column":{
                "eq":"182"
            },
            "eo:row":{
                "eq":"063"
            },
            "collection":{
                "eq":"landsat-8-l1"
            }
        },
      "time":"2019-01-01/2019-01-31"
    }))

    print(r.json())

if __name__ == '__main__':
    main()

@matthewhanson Once more thanks. It seems now to work but I have got acquainted with using the CLI as it gives many results in different output.

@vick25 Great, glad to hear. I'm going to close this issue but if you have any issues with sat-search, or feedback or feature requests please post over there: https://github.com/sat-utils/sat-search