1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
import json
import math
from collections import defaultdict
from usgs import CATALOG_NODES, USGSDependencyRequired
def dataset_filters(dataset):
"""
This request is used to return the metadata filter fields for the specified
dataset. These values can be used as additional criteria when submitting search
and hit queries.
:param str dataset:
"""
return json.dumps({
"datasetName": dataset,
})
def download_options(dataset, entity_ids):
"""
The download options request is used to discover downloadable products for
each dataset. If a download is marked as not available, an order must be
placed to generate that product.
:param str dataset:
:param str entity_ids:
"""
payload = {
"datasetName": dataset,
"entityIds": entity_ids
}
return json.dumps(payload)
def dataset_download_options(dataset):
"""
The dataset download options request is used to discover downloadable
products for a specified dataset. Unlike the `download_options` request,
this does not check product availability.
:param str dataset: Used to identify the which dataset to return results for.
"""
payload = {"datasetName": dataset}
return json.dumps(payload)
def download_request(dataset, entity_id, product_id):
"""
The use of this request will be to obtain valid data download URLs.
:param str dataset:
:param str entity_id:
:param str product_id:
"""
payload = {
"downloads": [
{
"entityId": entity_id,
"productId": product_id
}
],
"downloadApplication": "EE"
}
return json.dumps(payload)
def dataset_search(dataset, catalog, start_date=None, end_date=None, ll=None, ur=None):
"""
This method is used to find datasets available for searching. By passing only
an API Key, all available datasets are returned. Additional parameters such
as temporal range and spatial bounding box can be used to find datasets that
provide more specific data. The dataset name parameter can be used to limit
the results based on matching the supplied value against the public dataset
name with assumed wildcards at the beginning and end.
:param str dataset:
:param str catalog:
:param start_date:
Used for searching scene acquisition - will accept anything
that the PHP strtotime function can understand
:param end_date:
Used for searching scene acquisition - will accept anything
that the PHP strtotime function can understand
:param ll:
Lower left corner of an AOI bounding box - in decimal form
Longitude/Latitude dictionary
e.g. { "longitude": 0.0, "latitude": 0.0 }
:param ur:
Upper right corner of an AOI bounding box - in decimal form
Longitude/Latitude dictionary
e.g. { "longitude": 0.0, "latitude": 0.0 }
"""
payload = {
"datasetName": dataset,
"catalog": catalog
}
if start_date and end_date:
payload["temporalFilter"] = {
"start": start_date,
"end": end_date
}
if ll and ur:
payload["spatialFilter"] = {
"filterType": "mbr",
"lowerLeft": {
"latitude": ll["latitude"],
"longitude": ll["longitude"]
},
"upperRight": {
"latitude": ur["latitude"],
"longitude": ur["longitude"]
}
}
return json.dumps(payload)
def login(username, password):
"""
Upon a successful login, an API key will be returned. This key will be active
for two hours and should be destroyed upon final use of the service by calling
the logout method.
:param str username:
:param str password:
"""
payload = {
"username": username,
"password": password
}
return json.dumps(payload)
def scene_metadata(dataset, entity_id):
"""
The use of the metadata request is intended for those who have
acquired scene IDs from a different source. It will return the
same metadata that is available via the search request.
:param dataset:
:param entity_id:
"""
payload = {
"datasetName": dataset,
"entityId": entity_id,
"metadataType": "full"
}
return json.dumps(payload)
def great_circle_dist(lat, lng, dist):
lat = math.radians(lat)
lng = math.radians(lng)
brng = math.radians(45.0)
ibrng = math.radians(225.0)
earth_radius = 6371000.0
dR = (dist / 2.0)/ earth_radius
lat1 = math.asin( math.sin(lat)*math.cos(dR) +
math.cos(lat)*math.sin(dR)*math.cos(brng) );
lng1 = lng + math.atan2(math.sin(brng)*math.sin(dR)*math.cos(lat),
math.cos(dR)-math.sin(lat)*math.sin(lat1));
lat2 = math.asin( math.sin(lat)*math.cos(dR) +
math.cos(lat)*math.sin(dR)*math.cos(ibrng) );
lng2 = lng + math.atan2(math.sin(ibrng)*math.sin(dR)*math.cos(lat),
math.cos(dR)-math.sin(lat)*math.sin(lat2));
return [math.degrees(lat1), math.degrees(lat2)], [math.degrees(lng1), math.degrees(lng2)]
def scene_search(
dataset, max_results=None, metadata_type=None, start_date=None,
end_date=None, ll=None, ur=None,
lat=None, lng=None, distance=100,
where=None, starting_number=None):
payload = defaultdict(dict, {
"datasetName": dataset,
"maxResults": max_results,
"startingNumber": starting_number,
"metadataType": metadata_type
})
if (start_date is not None) and (end_date is not None):
payload["sceneFilter"]["acquisitionFilter"] = {
"start": start_date,
"end": end_date
}
# Latitude and longitude take precedence over ll and ur
if lat and lng:
lats, lngs = great_circle_dist(lat, lng, distance / 2.0)
ll = { "longitude": min(*lngs), "latitude": min(*lats) }
ur = { "longitude": max(*lngs), "latitude": max(*lats) }
if ll and ur:
payload["sceneFilter"]["spatialFilter"] = {
"filterType": "mbr",
"lowerLeft": ll,
"upperRight": ur
}
if where:
payload["sceneFilter"]["metadataFilter"] = {
"filterType": "value",
"filterId": where["filter_id"],
"value": where["value"],
"operand": "="
}
return json.dumps(payload)
|