├── Dockerfile
├── README.md
├── app.py
├── docker-compose.yml
├── poetry.lock
├── pyproject.toml
├── src
├── model.py
└── utils.py
├── static
├── css
│ ├── ol3-sidebar.css
│ └── ol3-sidebar.min.css
└── js
│ ├── main.js
│ ├── ol3-sidebar.js
│ └── ol3-sidebar.min.js
└── template
└── map.html
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | LABEL maintainer="csaybar -- Copernicus Master in Digital Earth (CDE)"
3 |
4 | # Global ARG
5 | ARG YOUR_ENV
6 | ENV YOUR_ENV=${YOUR_ENV} \
7 | PYTHONFAULTHANDLER=1 \
8 | PYTHONUNBUFFERED=1 \
9 | PYTHONHASHSEED=random \
10 | PIP_NO_CACHE_DIR=off \
11 | PIP_DISABLE_PIP_VERSION_CHECK=on \
12 | PIP_DEFAULT_TIMEOUT=100 \
13 | POETRY_VERSION=1.0.0
14 |
15 | # Install Python3-dev
16 | RUN apt-get update && apt-get install -y python3-dev build-essential
17 |
18 | # Install poetry
19 | RUN pip install poetry==$POETRY_VERSION
20 |
21 | # Copy all files
22 | COPY . .
23 |
24 | # Init the project
25 | RUN poetry config virtualenvs.create false \
26 | && poetry install $(test "$YOUR_ENV" == production && echo "--no-dev") --no-interaction --no-ansi
27 |
28 | EXPOSE 80
29 |
30 | CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ee-fastapi: Flood Detection System
6 |
7 |
8 |
9 |
10 | A **ee-fastapi** is a simple [FastAPI](https://fastapi.tiangolo.com/) web application for performing flood detection using Google Earth Engine in the backend. The module [src/model.py](src/model.py) was adapted and translated to Python from [Radar-based Flood Mapping](https://www.un-spider.org/advisory-support/recommended-practices/recommended-practice-radar-based-flood-mapping). If you want to cite the methodology, takes a look at the bibliography available [here](https://www.un-spider.org/advisory-support/recommended-practices/recommended-practice-flood-mapping/in-detail).
11 |
12 |
13 | ### Installation
14 |
15 | 1. Install [Docker Compose](https://docs.docker.com/compose/install/)
16 |
17 | 2. Install the [EarthEngine Python API](https://developers.google.com/earth-engine/guides/python_install). You must have an active Earth Engine account (the credentials are copied to the app through [volumes](https://docs.docker.com/storage/volumes/))
18 |
19 | 3. Run the command
20 |
21 | ```
22 | docker-compose up
23 | ```
24 |
25 | and point your browser to
26 |
27 | ```
28 | 0.0.0.0:80
29 | ```
30 | to start work
31 |
32 |
33 | ### Functionality
34 |
35 | **ee-fastapi** use ready-to-use data freely available in the [Earth Engine Data Catalog](https://developers.google.com/earth-engine/datasets). **ee-fastapi** use the following public dataset:
36 |
37 | - [**Sentinel-1 GRD: C-band Synthetic Aperture Radar**](https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S1_GRD): A composite after and before the flood. Main resource.
38 | - [**MERIT DEM: Multi-Error-Removed Improved-Terrain DEM**](https://developers.google.com/earth-engine/datasets/catalog/MERIT_DEM_v1_0_3): To avoid areas with high slope.
39 | - [**JRC Global Surface Water Metadata, v.1.2**](https://developers.google.com/earth-engine/datasets/catalog/JRC_GSW1_2_Metadata): To avoid water body areas.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Flood range dates, a hand-selected ROI, and the flood threshold are sent from the front-end to the back-end using [fetch](https://github.com/csaybar/ee-fastapi/blob/43f25d171a5bb17171d64de15af2d4170ca43c12/static/js/main.js#L158). The users control the response through two buttons: **display** and **download**. The display button will attach XYZ map tile resources with the results to the OpenLayer map. These tiles are obtained after running the model and the [ee.data.getMapId](https://developers.google.com/earth-engine/apidocs/ee-data-getmapid) method. On the other hand, the download button will download the flood area in a GeoPackage vector format.
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | ### Design decisions
57 |
58 | #### Why OpenLayer?
59 |
60 | It was my first project using OpenLayer, and I can say that I did not miss Leaflet at all!. In my opinion, OpenLayers has much more advantages
61 | over Leaflet. Here are some reasons from the point of view of a novice Web GIS user:
62 |
63 | - OpenLayer counts with a complex API. There is no reason to load external plugins for simple tasks like in Leaflet.
64 | - Great documentation and thousand of examples.
65 | - Better map projection support
66 | - I found the OpenLayer API more intuitive.
67 |
68 | #### Why Google Earth Engine?
69 |
70 | Google Earth Engine has everything: tons of publicly available datasets, a great well-documented API, and high-performance computing.
71 |
72 | #### Why fetch?
73 |
74 | Fetch API does not need to be installed as a dependency. It utilizes a modern JS syntax and is based on promise rather than callbacks.
75 |
76 |
77 | ### Student personal information
78 |
79 | - **Name**: Cesar Luis Aybar Camacho
80 | - **Program**: Copernicus Master in Digital Earth – CDE
81 | - **Student ID**: s1078735
82 | - **Course**: Geo-application Development
83 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from fastapi import FastAPI, Request, Form
2 | from fastapi.middleware.cors import CORSMiddleware
3 | from fastapi.templating import Jinja2Templates
4 | from fastapi.staticfiles import StaticFiles
5 |
6 | from src.utils import searching_all_files, raster_to_vector
7 | from src.model import db_creator, flood_estimation, display
8 | from zipfile import ZipFile
9 | import geopandas as gpd
10 | import uvicorn
11 | import ee, os, time
12 |
13 | # from src.utils import load_credentials
14 |
15 | # Init Earth Engine
16 | # load_credentials() -> useful to deploy with heroku
17 | ee.Initialize()
18 |
19 | app = FastAPI()
20 |
21 | origins = [
22 | "http://localhost",
23 | "http://localhost:8000"
24 | "http://localhost:8080",
25 | "http://127.0.0.1",
26 | "http://0.0.0.0",
27 | "http://0.0.0.0:80",
28 | "http://127.0.0.1:8000",
29 | "http://127.0.0.1:8080"
30 | ]
31 | app.add_middleware(
32 | CORSMiddleware,
33 | allow_origins=origins,
34 | allow_credentials=True,
35 | allow_methods=["*"],
36 | allow_headers=["*"],
37 | )
38 |
39 | # mount static folder in the app
40 | app.mount("/static", StaticFiles(directory="static"), name="static")
41 | app.mount("/output", StaticFiles(directory="output"), name="output")
42 |
43 | # Load html templates
44 | templates = Jinja2Templates(directory="template")
45 |
46 | # display map
47 | @app.get("/")
48 | async def map(request: Request):
49 | return templates.TemplateResponse("map.html", {"request": request})
50 |
51 | @app.post("/flood_download")
52 | async def flood_model(request: Request):
53 | # request parameters
54 | request_params = await request.json()
55 |
56 | # get parameters
57 | xmin, ymin, xmax, ymax = [float(x) for x in request_params["bbox"].split(",")]
58 | init_start = request_params["init_start"]
59 | init_last = request_params["init_last"]
60 | flood_start = request_params["flood_start"]
61 | flood_last = request_params["flood_last"]
62 | flood_threshold = float(request_params["flood_threshold"])
63 |
64 | # 1. Create geometry
65 | ee_rectangle = ee.Geometry.Rectangle(xmin, ymin, xmax, ymax)
66 |
67 | # 2. Create range dates
68 | base_period = (init_start, init_last)
69 | flood_period = (flood_start, flood_last)
70 |
71 | # 3. Run the flood model
72 | dict_db = db_creator(base_period, flood_period, ee_rectangle)
73 | flood_added = flood_estimation(dict_db, difference_threshold=flood_threshold)
74 |
75 | # 4. Create GeoJSON
76 | geo_file_geojson = 'output/flood_area_%s.gpkg' % (time.strftime("%Y%m%d%H%M%S", time.gmtime()))
77 | final_flood_area = raster_to_vector(flood_added["flood_results"], ee_rectangle)
78 | final_flood_area_gpd = gpd.GeoDataFrame.from_features(final_flood_area["features"])
79 | final_flood_area_gpd[final_flood_area_gpd.label == 1].to_file(geo_file_geojson, driver="GPKG")
80 | print(geo_file_geojson)
81 | return geo_file_geojson
82 |
83 | # model
84 | @app.post("/flood_display")
85 | async def flood_model(request: Request):
86 | # 1. request parameters
87 | request_params = await request.json()
88 |
89 | # 2. get parameters
90 | xmin, ymin, xmax, ymax = [float(x) for x in request_params["bbox"].split(",")]
91 | init_start = request_params["init_start"]
92 | init_last = request_params["init_last"]
93 | flood_start = request_params["flood_start"]
94 | flood_last = request_params["flood_last"]
95 | flood_threshold = float(request_params["flood_threshold"])
96 |
97 | # 3. Create geometry
98 | ee_rectangle = ee.Geometry.Rectangle(xmin, ymin, xmax, ymax)
99 |
100 | # 4. Create range dates
101 | base_period = (init_start, init_last)
102 | flood_period = (flood_start, flood_last)
103 |
104 | # 5. Run the flood model
105 | dict_db = db_creator(base_period, flood_period, ee_rectangle)
106 | flood_added = flood_estimation(dict_db, difference_threshold=flood_threshold)
107 |
108 | # 6. Upload gee tileid
109 | tileids = display(flood_added)
110 |
111 | return tileids
112 |
113 | if __name__ == "__main__":
114 | uvicorn.run(app, host="0.0.0.0", port=80)
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 |
3 | services:
4 | app:
5 | container_name: flood-fastapi
6 | image: flood/fastapi
7 | build:
8 | context: .
9 | dockerfile: Dockerfile
10 | ports:
11 | - "80:80"
12 | volumes:
13 | - $HOME/.config/earthengine:/root/.config/earthengine/
14 |
--------------------------------------------------------------------------------
/poetry.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "aiofiles"
3 | version = "0.6.0"
4 | description = "File support for asyncio."
5 | category = "main"
6 | optional = false
7 | python-versions = "*"
8 |
9 | [[package]]
10 | name = "arrow"
11 | version = "1.0.3"
12 | description = "Better dates & times for Python"
13 | category = "main"
14 | optional = false
15 | python-versions = ">=3.6"
16 |
17 | [package.dependencies]
18 | python-dateutil = ">=2.7.0"
19 |
20 | [[package]]
21 | name = "atomicwrites"
22 | version = "1.4.0"
23 | description = "Atomic file writes."
24 | category = "dev"
25 | optional = false
26 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
27 |
28 | [[package]]
29 | name = "attrs"
30 | version = "20.3.0"
31 | description = "Classes Without Boilerplate"
32 | category = "main"
33 | optional = false
34 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
35 |
36 | [package.extras]
37 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"]
38 | docs = ["furo", "sphinx", "zope.interface"]
39 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
40 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
41 |
42 | [[package]]
43 | name = "cachetools"
44 | version = "4.2.1"
45 | description = "Extensible memoizing collections and decorators"
46 | category = "main"
47 | optional = false
48 | python-versions = "~=3.5"
49 |
50 | [[package]]
51 | name = "certifi"
52 | version = "2020.12.5"
53 | description = "Python package for providing Mozilla's CA Bundle."
54 | category = "main"
55 | optional = false
56 | python-versions = "*"
57 |
58 | [[package]]
59 | name = "cffi"
60 | version = "1.14.5"
61 | description = "Foreign Function Interface for Python calling C code."
62 | category = "main"
63 | optional = false
64 | python-versions = "*"
65 |
66 | [package.dependencies]
67 | pycparser = "*"
68 |
69 | [[package]]
70 | name = "chardet"
71 | version = "4.0.0"
72 | description = "Universal encoding detector for Python 2 and 3"
73 | category = "main"
74 | optional = false
75 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
76 |
77 | [[package]]
78 | name = "click"
79 | version = "7.1.2"
80 | description = "Composable command line interface toolkit"
81 | category = "main"
82 | optional = false
83 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
84 |
85 | [[package]]
86 | name = "click-plugins"
87 | version = "1.1.1"
88 | description = "An extension module for click to enable registering CLI commands via setuptools entry-points."
89 | category = "main"
90 | optional = false
91 | python-versions = "*"
92 |
93 | [package.dependencies]
94 | click = ">=4.0"
95 |
96 | [package.extras]
97 | dev = ["pytest (>=3.6)", "pytest-cov", "wheel", "coveralls"]
98 |
99 | [[package]]
100 | name = "cligj"
101 | version = "0.7.1"
102 | description = "Click params for commmand line interfaces to GeoJSON"
103 | category = "main"
104 | optional = false
105 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4"
106 |
107 | [package.dependencies]
108 | click = ">=4.0,<8"
109 |
110 | [package.extras]
111 | test = ["pytest-cov"]
112 |
113 | [[package]]
114 | name = "colorama"
115 | version = "0.4.4"
116 | description = "Cross-platform colored terminal text."
117 | category = "dev"
118 | optional = false
119 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
120 |
121 | [[package]]
122 | name = "earthengine-api"
123 | version = "0.1.262"
124 | description = "Earth Engine Python API"
125 | category = "main"
126 | optional = false
127 | python-versions = "*"
128 |
129 | [package.dependencies]
130 | future = "*"
131 | google-api-python-client = ">=1.12.1,<2"
132 | google-auth = ">=1.4.1"
133 | google-auth-httplib2 = ">=0.0.3"
134 | google-cloud-storage = "*"
135 | httplib2 = ">=0.9.2,<1dev"
136 | httplib2shim = "*"
137 | six = "*"
138 |
139 | [[package]]
140 | name = "fastapi"
141 | version = "0.63.0"
142 | description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
143 | category = "main"
144 | optional = false
145 | python-versions = ">=3.6"
146 |
147 | [package.dependencies]
148 | pydantic = ">=1.0.0,<2.0.0"
149 | starlette = "0.13.6"
150 |
151 | [package.extras]
152 | all = ["requests (>=2.24.0,<3.0.0)", "aiofiles (>=0.5.0,<0.6.0)", "jinja2 (>=2.11.2,<3.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "itsdangerous (>=1.1.0,<2.0.0)", "pyyaml (>=5.3.1,<6.0.0)", "graphene (>=2.1.8,<3.0.0)", "ujson (>=3.0.0,<4.0.0)", "orjson (>=3.2.1,<4.0.0)", "email_validator (>=1.1.1,<2.0.0)", "uvicorn[standard] (>=0.12.0,<0.14.0)", "async_exit_stack (>=1.0.1,<2.0.0)", "async_generator (>=1.10,<2.0.0)"]
153 | dev = ["python-jose[cryptography] (>=3.1.0,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.14.0)", "graphene (>=2.1.8,<3.0.0)"]
154 | doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=6.1.4,<7.0.0)", "markdown-include (>=0.5.1,<0.6.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.2.0)", "typer-cli (>=0.0.9,<0.0.10)", "pyyaml (>=5.3.1,<6.0.0)"]
155 | test = ["pytest (==5.4.3)", "pytest-cov (==2.10.0)", "pytest-asyncio (>=0.14.0,<0.15.0)", "mypy (==0.790)", "flake8 (>=3.8.3,<4.0.0)", "black (==20.8b1)", "isort (>=5.0.6,<6.0.0)", "requests (>=2.24.0,<3.0.0)", "httpx (>=0.14.0,<0.15.0)", "email_validator (>=1.1.1,<2.0.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "databases[sqlite] (>=0.3.2,<0.4.0)", "orjson (>=3.2.1,<4.0.0)", "async_exit_stack (>=1.0.1,<2.0.0)", "async_generator (>=1.10,<2.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "aiofiles (>=0.5.0,<0.6.0)", "flask (>=1.1.2,<2.0.0)"]
156 |
157 | [[package]]
158 | name = "fiona"
159 | version = "1.8.19"
160 | description = "Fiona reads and writes spatial data files"
161 | category = "main"
162 | optional = false
163 | python-versions = "*"
164 |
165 | [package.dependencies]
166 | attrs = ">=17"
167 | certifi = "*"
168 | click = ">=4.0,<8"
169 | click-plugins = ">=1.0"
170 | cligj = ">=0.5"
171 | munch = "*"
172 | six = ">=1.7"
173 |
174 | [package.extras]
175 | all = ["pytest (>=3)", "pytest-cov", "shapely", "boto3 (>=1.2.4)", "mock"]
176 | calc = ["shapely"]
177 | s3 = ["boto3 (>=1.2.4)"]
178 | test = ["pytest (>=3)", "pytest-cov", "boto3 (>=1.2.4)", "mock"]
179 |
180 | [[package]]
181 | name = "future"
182 | version = "0.18.2"
183 | description = "Clean single-source support for Python 3 and 2"
184 | category = "main"
185 | optional = false
186 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
187 |
188 | [[package]]
189 | name = "geopandas"
190 | version = "0.9.0"
191 | description = "Geographic pandas extensions"
192 | category = "main"
193 | optional = false
194 | python-versions = ">=3.6"
195 |
196 | [package.dependencies]
197 | fiona = ">=1.8"
198 | pandas = ">=0.24.0"
199 | pyproj = ">=2.2.0"
200 | shapely = ">=1.6"
201 |
202 | [[package]]
203 | name = "google-api-core"
204 | version = "1.26.3"
205 | description = "Google API client core library"
206 | category = "main"
207 | optional = false
208 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
209 |
210 | [package.dependencies]
211 | google-auth = ">=1.21.1,<2.0dev"
212 | googleapis-common-protos = ">=1.6.0,<2.0dev"
213 | packaging = ">=14.3"
214 | protobuf = ">=3.12.0"
215 | pytz = "*"
216 | requests = ">=2.18.0,<3.0.0dev"
217 | six = ">=1.13.0"
218 |
219 | [package.extras]
220 | grpc = ["grpcio (>=1.29.0,<2.0dev)"]
221 | grpcgcp = ["grpcio-gcp (>=0.2.2)"]
222 | grpcio-gcp = ["grpcio-gcp (>=0.2.2)"]
223 |
224 | [[package]]
225 | name = "google-api-python-client"
226 | version = "1.12.8"
227 | description = "Google API Client Library for Python"
228 | category = "main"
229 | optional = false
230 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
231 |
232 | [package.dependencies]
233 | google-api-core = ">=1.21.0,<2dev"
234 | google-auth = ">=1.16.0"
235 | google-auth-httplib2 = ">=0.0.3"
236 | httplib2 = ">=0.15.0,<1dev"
237 | six = ">=1.13.0,<2dev"
238 | uritemplate = ">=3.0.0,<4dev"
239 |
240 | [[package]]
241 | name = "google-auth"
242 | version = "1.29.0"
243 | description = "Google Authentication Library"
244 | category = "main"
245 | optional = false
246 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
247 |
248 | [package.dependencies]
249 | cachetools = ">=2.0.0,<5.0"
250 | pyasn1-modules = ">=0.2.1"
251 | rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""}
252 | six = ">=1.9.0"
253 |
254 | [package.extras]
255 | aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"]
256 | pyopenssl = ["pyopenssl (>=20.0.0)"]
257 | reauth = ["pyu2f (>=0.1.5)"]
258 |
259 | [[package]]
260 | name = "google-auth-httplib2"
261 | version = "0.1.0"
262 | description = "Google Authentication Library: httplib2 transport"
263 | category = "main"
264 | optional = false
265 | python-versions = "*"
266 |
267 | [package.dependencies]
268 | google-auth = "*"
269 | httplib2 = ">=0.15.0"
270 | six = "*"
271 |
272 | [[package]]
273 | name = "google-cloud-core"
274 | version = "1.6.0"
275 | description = "Google Cloud API client core library"
276 | category = "main"
277 | optional = false
278 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
279 |
280 | [package.dependencies]
281 | google-api-core = ">=1.21.0,<2.0.0dev"
282 | google-auth = ">=1.24.0,<2.0dev"
283 | six = ">=1.12.0"
284 |
285 | [package.extras]
286 | grpc = ["grpcio (>=1.8.2,<2.0dev)"]
287 |
288 | [[package]]
289 | name = "google-cloud-storage"
290 | version = "1.37.1"
291 | description = "Google Cloud Storage API client library"
292 | category = "main"
293 | optional = false
294 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
295 |
296 | [package.dependencies]
297 | google-auth = ">=1.11.0,<2.0dev"
298 | google-cloud-core = ">=1.4.1,<2.0dev"
299 | google-resumable-media = ">=1.2.0,<2.0dev"
300 | requests = ">=2.18.0,<3.0.0dev"
301 |
302 | [[package]]
303 | name = "google-crc32c"
304 | version = "1.1.2"
305 | description = "A python wrapper of the C library 'Google CRC32C'"
306 | category = "main"
307 | optional = false
308 | python-versions = ">=3.6"
309 |
310 | [package.dependencies]
311 | cffi = ">=1.0.0"
312 |
313 | [package.extras]
314 | testing = ["pytest"]
315 |
316 | [[package]]
317 | name = "google-resumable-media"
318 | version = "1.2.0"
319 | description = "Utilities for Google Media Downloads and Resumable Uploads"
320 | category = "main"
321 | optional = false
322 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
323 |
324 | [package.dependencies]
325 | google-crc32c = {version = ">=1.0,<2.0dev", markers = "python_version >= \"3.5\""}
326 | six = "*"
327 |
328 | [package.extras]
329 | aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"]
330 | requests = ["requests (>=2.18.0,<3.0.0dev)"]
331 |
332 | [[package]]
333 | name = "googleapis-common-protos"
334 | version = "1.53.0"
335 | description = "Common protobufs used in Google APIs"
336 | category = "main"
337 | optional = false
338 | python-versions = ">=3.6"
339 |
340 | [package.dependencies]
341 | protobuf = ">=3.12.0"
342 |
343 | [package.extras]
344 | grpc = ["grpcio (>=1.0.0)"]
345 |
346 | [[package]]
347 | name = "h11"
348 | version = "0.12.0"
349 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
350 | category = "main"
351 | optional = false
352 | python-versions = ">=3.6"
353 |
354 | [[package]]
355 | name = "httplib2"
356 | version = "0.19.1"
357 | description = "A comprehensive HTTP client library."
358 | category = "main"
359 | optional = false
360 | python-versions = "*"
361 |
362 | [package.dependencies]
363 | pyparsing = ">=2.4.2,<3"
364 |
365 | [[package]]
366 | name = "httplib2shim"
367 | version = "0.0.3"
368 | description = "A wrapper over urllib3 that matches httplib2's interface"
369 | category = "main"
370 | optional = false
371 | python-versions = "*"
372 |
373 | [package.dependencies]
374 | certifi = "*"
375 | httplib2 = "*"
376 | six = "*"
377 | urllib3 = "*"
378 |
379 | [[package]]
380 | name = "idna"
381 | version = "2.10"
382 | description = "Internationalized Domain Names in Applications (IDNA)"
383 | category = "main"
384 | optional = false
385 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
386 |
387 | [[package]]
388 | name = "jinja2"
389 | version = "2.11.3"
390 | description = "A very fast and expressive template engine."
391 | category = "main"
392 | optional = false
393 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
394 |
395 | [package.dependencies]
396 | MarkupSafe = ">=0.23"
397 |
398 | [package.extras]
399 | i18n = ["Babel (>=0.8)"]
400 |
401 | [[package]]
402 | name = "jinja2-time"
403 | version = "0.2.0"
404 | description = "Jinja2 Extension for Dates and Times"
405 | category = "main"
406 | optional = false
407 | python-versions = "*"
408 |
409 | [package.dependencies]
410 | arrow = "*"
411 | jinja2 = "*"
412 |
413 | [[package]]
414 | name = "markupsafe"
415 | version = "1.1.1"
416 | description = "Safely add untrusted strings to HTML/XML markup."
417 | category = "main"
418 | optional = false
419 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
420 |
421 | [[package]]
422 | name = "more-itertools"
423 | version = "8.7.0"
424 | description = "More routines for operating on iterables, beyond itertools"
425 | category = "dev"
426 | optional = false
427 | python-versions = ">=3.5"
428 |
429 | [[package]]
430 | name = "munch"
431 | version = "2.5.0"
432 | description = "A dot-accessible dictionary (a la JavaScript objects)"
433 | category = "main"
434 | optional = false
435 | python-versions = "*"
436 |
437 | [package.dependencies]
438 | six = "*"
439 |
440 | [package.extras]
441 | testing = ["pytest", "coverage", "astroid (>=1.5.3,<1.6.0)", "pylint (>=1.7.2,<1.8.0)", "astroid (>=2.0)", "pylint (>=2.3.1,<2.4.0)"]
442 | yaml = ["PyYAML (>=5.1.0)"]
443 |
444 | [[package]]
445 | name = "numpy"
446 | version = "1.20.2"
447 | description = "NumPy is the fundamental package for array computing with Python."
448 | category = "main"
449 | optional = false
450 | python-versions = ">=3.7"
451 |
452 | [[package]]
453 | name = "packaging"
454 | version = "20.9"
455 | description = "Core utilities for Python packages"
456 | category = "main"
457 | optional = false
458 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
459 |
460 | [package.dependencies]
461 | pyparsing = ">=2.0.2"
462 |
463 | [[package]]
464 | name = "pandas"
465 | version = "1.2.4"
466 | description = "Powerful data structures for data analysis, time series, and statistics"
467 | category = "main"
468 | optional = false
469 | python-versions = ">=3.7.1"
470 |
471 | [package.dependencies]
472 | numpy = ">=1.16.5"
473 | python-dateutil = ">=2.7.3"
474 | pytz = ">=2017.3"
475 |
476 | [package.extras]
477 | test = ["pytest (>=5.0.1)", "pytest-xdist", "hypothesis (>=3.58)"]
478 |
479 | [[package]]
480 | name = "pluggy"
481 | version = "0.13.1"
482 | description = "plugin and hook calling mechanisms for python"
483 | category = "dev"
484 | optional = false
485 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
486 |
487 | [package.extras]
488 | dev = ["pre-commit", "tox"]
489 |
490 | [[package]]
491 | name = "protobuf"
492 | version = "3.15.8"
493 | description = "Protocol Buffers"
494 | category = "main"
495 | optional = false
496 | python-versions = "*"
497 |
498 | [package.dependencies]
499 | six = ">=1.9"
500 |
501 | [[package]]
502 | name = "py"
503 | version = "1.10.0"
504 | description = "library with cross-python path, ini-parsing, io, code, log facilities"
505 | category = "dev"
506 | optional = false
507 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
508 |
509 | [[package]]
510 | name = "pyasn1"
511 | version = "0.4.8"
512 | description = "ASN.1 types and codecs"
513 | category = "main"
514 | optional = false
515 | python-versions = "*"
516 |
517 | [[package]]
518 | name = "pyasn1-modules"
519 | version = "0.2.8"
520 | description = "A collection of ASN.1-based protocols modules."
521 | category = "main"
522 | optional = false
523 | python-versions = "*"
524 |
525 | [package.dependencies]
526 | pyasn1 = ">=0.4.6,<0.5.0"
527 |
528 | [[package]]
529 | name = "pycparser"
530 | version = "2.20"
531 | description = "C parser in Python"
532 | category = "main"
533 | optional = false
534 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
535 |
536 | [[package]]
537 | name = "pydantic"
538 | version = "1.8.1"
539 | description = "Data validation and settings management using python 3.6 type hinting"
540 | category = "main"
541 | optional = false
542 | python-versions = ">=3.6.1"
543 |
544 | [package.dependencies]
545 | typing-extensions = ">=3.7.4.3"
546 |
547 | [package.extras]
548 | dotenv = ["python-dotenv (>=0.10.4)"]
549 | email = ["email-validator (>=1.0.3)"]
550 |
551 | [[package]]
552 | name = "pyparsing"
553 | version = "2.4.7"
554 | description = "Python parsing module"
555 | category = "main"
556 | optional = false
557 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
558 |
559 | [[package]]
560 | name = "pyproj"
561 | version = "3.0.1"
562 | description = "Python interface to PROJ (cartographic projections and coordinate transformations library)"
563 | category = "main"
564 | optional = false
565 | python-versions = ">=3.6"
566 |
567 | [package.dependencies]
568 | certifi = "*"
569 |
570 | [[package]]
571 | name = "pytest"
572 | version = "5.4.3"
573 | description = "pytest: simple powerful testing with Python"
574 | category = "dev"
575 | optional = false
576 | python-versions = ">=3.5"
577 |
578 | [package.dependencies]
579 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
580 | attrs = ">=17.4.0"
581 | colorama = {version = "*", markers = "sys_platform == \"win32\""}
582 | more-itertools = ">=4.0.0"
583 | packaging = "*"
584 | pluggy = ">=0.12,<1.0"
585 | py = ">=1.5.0"
586 | wcwidth = "*"
587 |
588 | [package.extras]
589 | checkqa-mypy = ["mypy (==v0.761)"]
590 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
591 |
592 | [[package]]
593 | name = "python-dateutil"
594 | version = "2.8.1"
595 | description = "Extensions to the standard Python datetime module"
596 | category = "main"
597 | optional = false
598 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
599 |
600 | [package.dependencies]
601 | six = ">=1.5"
602 |
603 | [[package]]
604 | name = "python-multipart"
605 | version = "0.0.5"
606 | description = "A streaming multipart parser for Python"
607 | category = "main"
608 | optional = false
609 | python-versions = "*"
610 |
611 | [package.dependencies]
612 | six = ">=1.4.0"
613 |
614 | [[package]]
615 | name = "pytz"
616 | version = "2021.1"
617 | description = "World timezone definitions, modern and historical"
618 | category = "main"
619 | optional = false
620 | python-versions = "*"
621 |
622 | [[package]]
623 | name = "requests"
624 | version = "2.25.1"
625 | description = "Python HTTP for Humans."
626 | category = "main"
627 | optional = false
628 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
629 |
630 | [package.dependencies]
631 | certifi = ">=2017.4.17"
632 | chardet = ">=3.0.2,<5"
633 | idna = ">=2.5,<3"
634 | urllib3 = ">=1.21.1,<1.27"
635 |
636 | [package.extras]
637 | security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
638 | socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
639 |
640 | [[package]]
641 | name = "rsa"
642 | version = "4.7.2"
643 | description = "Pure-Python RSA implementation"
644 | category = "main"
645 | optional = false
646 | python-versions = ">=3.5, <4"
647 |
648 | [package.dependencies]
649 | pyasn1 = ">=0.1.3"
650 |
651 | [[package]]
652 | name = "shapely"
653 | version = "1.7.1"
654 | description = "Geometric objects, predicates, and operations"
655 | category = "main"
656 | optional = false
657 | python-versions = "*"
658 |
659 | [package.extras]
660 | all = ["numpy", "pytest", "pytest-cov"]
661 | test = ["pytest", "pytest-cov"]
662 | vectorized = ["numpy"]
663 |
664 | [[package]]
665 | name = "six"
666 | version = "1.15.0"
667 | description = "Python 2 and 3 compatibility utilities"
668 | category = "main"
669 | optional = false
670 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
671 |
672 | [[package]]
673 | name = "starlette"
674 | version = "0.13.6"
675 | description = "The little ASGI library that shines."
676 | category = "main"
677 | optional = false
678 | python-versions = ">=3.6"
679 |
680 | [package.extras]
681 | full = ["aiofiles", "graphene", "itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests", "ujson"]
682 |
683 | [[package]]
684 | name = "typing-extensions"
685 | version = "3.7.4.3"
686 | description = "Backported and Experimental Type Hints for Python 3.5+"
687 | category = "main"
688 | optional = false
689 | python-versions = "*"
690 |
691 | [[package]]
692 | name = "uritemplate"
693 | version = "3.0.1"
694 | description = "URI templates"
695 | category = "main"
696 | optional = false
697 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
698 |
699 | [[package]]
700 | name = "urllib3"
701 | version = "1.26.4"
702 | description = "HTTP library with thread-safe connection pooling, file post, and more."
703 | category = "main"
704 | optional = false
705 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
706 |
707 | [package.extras]
708 | secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
709 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
710 | brotli = ["brotlipy (>=0.6.0)"]
711 |
712 | [[package]]
713 | name = "uvicorn"
714 | version = "0.13.4"
715 | description = "The lightning-fast ASGI server."
716 | category = "main"
717 | optional = false
718 | python-versions = "*"
719 |
720 | [package.dependencies]
721 | click = ">=7.0.0,<8.0.0"
722 | h11 = ">=0.8"
723 |
724 | [package.extras]
725 | standard = ["websockets (>=8.0.0,<9.0.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "httptools (>=0.1.0,<0.2.0)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
726 |
727 | [[package]]
728 | name = "wcwidth"
729 | version = "0.2.5"
730 | description = "Measures the displayed width of unicode strings in a terminal"
731 | category = "dev"
732 | optional = false
733 | python-versions = "*"
734 |
735 | [metadata]
736 | lock-version = "1.1"
737 | python-versions = "^3.8"
738 | content-hash = "57e8fdcc5e19a467caa2be8b9b7021ab7f83869712f60c00e6669ad62b57153a"
739 |
740 | [metadata.files]
741 | aiofiles = [
742 | {file = "aiofiles-0.6.0-py3-none-any.whl", hash = "sha256:bd3019af67f83b739f8e4053c6c0512a7f545b9a8d91aaeab55e6e0f9d123c27"},
743 | {file = "aiofiles-0.6.0.tar.gz", hash = "sha256:e0281b157d3d5d59d803e3f4557dcc9a3dff28a4dd4829a9ff478adae50ca092"},
744 | ]
745 | arrow = [
746 | {file = "arrow-1.0.3-py3-none-any.whl", hash = "sha256:3515630f11a15c61dcb4cdd245883270dd334c83f3e639824e65a4b79cc48543"},
747 | {file = "arrow-1.0.3.tar.gz", hash = "sha256:399c9c8ae732270e1aa58ead835a79a40d7be8aa109c579898eb41029b5a231d"},
748 | ]
749 | atomicwrites = [
750 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
751 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
752 | ]
753 | attrs = [
754 | {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"},
755 | {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"},
756 | ]
757 | cachetools = [
758 | {file = "cachetools-4.2.1-py3-none-any.whl", hash = "sha256:1d9d5f567be80f7c07d765e21b814326d78c61eb0c3a637dffc0e5d1796cb2e2"},
759 | {file = "cachetools-4.2.1.tar.gz", hash = "sha256:f469e29e7aa4cff64d8de4aad95ce76de8ea1125a16c68e0d93f65c3c3dc92e9"},
760 | ]
761 | certifi = [
762 | {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"},
763 | {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"},
764 | ]
765 | cffi = [
766 | {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"},
767 | {file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"},
768 | {file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"},
769 | {file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"},
770 | {file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"},
771 | {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"},
772 | {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"},
773 | {file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"},
774 | {file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"},
775 | {file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"},
776 | {file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"},
777 | {file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"},
778 | {file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"},
779 | {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"},
780 | {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"},
781 | {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"},
782 | {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"},
783 | {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"},
784 | {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"},
785 | {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"},
786 | {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"},
787 | {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"},
788 | {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"},
789 | {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"},
790 | {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"},
791 | {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"},
792 | {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"},
793 | {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"},
794 | {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"},
795 | {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"},
796 | {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"},
797 | {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"},
798 | {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"},
799 | {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"},
800 | {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"},
801 | {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
802 | {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
803 | ]
804 | chardet = [
805 | {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
806 | {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
807 | ]
808 | click = [
809 | {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
810 | {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
811 | ]
812 | click-plugins = [
813 | {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"},
814 | {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"},
815 | ]
816 | cligj = [
817 | {file = "cligj-0.7.1-py3-none-any.whl", hash = "sha256:07171c1e287f45511f97df4ea071abc5d19924153413d5683a8e4866369bc676"},
818 | {file = "cligj-0.7.1.tar.gz", hash = "sha256:b2f1f7247d59a5387bd3013a08b9ed6829e96fafa4a6e6292341efdb46fe6220"},
819 | ]
820 | colorama = [
821 | {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
822 | {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
823 | ]
824 | earthengine-api = [
825 | {file = "earthengine-api-0.1.262.tar.gz", hash = "sha256:68902b20873960503e276c7481c127eda11746e470c151bca80830f508886144"},
826 | ]
827 | fastapi = [
828 | {file = "fastapi-0.63.0-py3-none-any.whl", hash = "sha256:98d8ea9591d8512fdadf255d2a8fa56515cdd8624dca4af369da73727409508e"},
829 | {file = "fastapi-0.63.0.tar.gz", hash = "sha256:63c4592f5ef3edf30afa9a44fa7c6b7ccb20e0d3f68cd9eba07b44d552058dcb"},
830 | ]
831 | fiona = [
832 | {file = "Fiona-1.8.19-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4e54e9b176f42aa1243dbc9f89509866dc0242cffdde40948d0055041bc80735"},
833 | {file = "Fiona-1.8.19-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:dd6ce1f64b535ad923d72a6e08eff3becb75d8f416e51c221c06c4fe49b86e3b"},
834 | {file = "Fiona-1.8.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:553036b0891d5a8747759b7e16708e816e0dbb55322f392df7ebcb777133ef78"},
835 | {file = "Fiona-1.8.19-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4a59f0d9044a4aeb2d8f098888a5c117997e45106b3382badc395d28b32d533"},
836 | {file = "Fiona-1.8.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:658ce97ccd4022d4de75d2f68a087e9e74d5a894a2f8635fbb74d1a6bd9ddd49"},
837 | {file = "Fiona-1.8.19-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c0e509661ed89f831218a17ba46a3d978be6f07491889d9b434888cfe646768f"},
838 | {file = "Fiona-1.8.19-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6155f3be8ba00591898b1cdde06bef20901b25a4d3c2b4cf842c278a5169e65a"},
839 | {file = "Fiona-1.8.19.tar.gz", hash = "sha256:b9059e0b29c2e9e6b817e53f941e77e1aca7075f986005d38db307067b60458f"},
840 | ]
841 | future = [
842 | {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
843 | ]
844 | geopandas = [
845 | {file = "geopandas-0.9.0-py2.py3-none-any.whl", hash = "sha256:79f6e557ba0dba76eec44f8351b1c6b42a17c38f5f08fef347e98fe4dae563c7"},
846 | {file = "geopandas-0.9.0.tar.gz", hash = "sha256:63972ab4dc44c4029f340600dcb83264eb8132dd22b104da0b654bef7f42630a"},
847 | ]
848 | google-api-core = [
849 | {file = "google-api-core-1.26.3.tar.gz", hash = "sha256:b914345c7ea23861162693a27703bab804a55504f7e6e9abcaff174d80df32ac"},
850 | {file = "google_api_core-1.26.3-py2.py3-none-any.whl", hash = "sha256:099762d4b4018cd536bcf85136bf337957da438807572db52f21dc61251be089"},
851 | ]
852 | google-api-python-client = [
853 | {file = "google-api-python-client-1.12.8.tar.gz", hash = "sha256:f3b9684442eec2cfe9f9bb48e796ef919456b82142c7528c5fd527e5224f08bb"},
854 | {file = "google_api_python_client-1.12.8-py2.py3-none-any.whl", hash = "sha256:3c4c4ca46b5c21196bec7ee93453443e477d82cbfa79234d1ce0645f81170eaf"},
855 | ]
856 | google-auth = [
857 | {file = "google-auth-1.29.0.tar.gz", hash = "sha256:010f011c4e27d3d5eb01106fba6aac39d164842dfcd8709955c4638f5b11ccf8"},
858 | {file = "google_auth-1.29.0-py2.py3-none-any.whl", hash = "sha256:f30a672a64d91cc2e3137765d088c5deec26416246f7a9e956eaf69a8d7ed49c"},
859 | ]
860 | google-auth-httplib2 = [
861 | {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"},
862 | {file = "google_auth_httplib2-0.1.0-py2.py3-none-any.whl", hash = "sha256:31e49c36c6b5643b57e82617cb3e021e3e1d2df9da63af67252c02fa9c1f4a10"},
863 | ]
864 | google-cloud-core = [
865 | {file = "google-cloud-core-1.6.0.tar.gz", hash = "sha256:c6abb18527545379fc82efc4de75ce9a3772ccad2fc645adace593ba097cbb02"},
866 | {file = "google_cloud_core-1.6.0-py2.py3-none-any.whl", hash = "sha256:40d9c2da2d03549b5ac3dcccf289d4f15e6d1210044c6381ce45c92913e62904"},
867 | ]
868 | google-cloud-storage = [
869 | {file = "google-cloud-storage-1.37.1.tar.gz", hash = "sha256:e06a4797c87ac73c4a74801539fdf0a91761c3014281ff58b7b29f15b34c206e"},
870 | {file = "google_cloud_storage-1.37.1-py2.py3-none-any.whl", hash = "sha256:63a9dab155bf81c51354db3d11f3e83a1db7d58eff453f1ce51ffa565d32617b"},
871 | ]
872 | google-crc32c = [
873 | {file = "google-crc32c-1.1.2.tar.gz", hash = "sha256:dff5bd1236737f66950999d25de7a78144548ebac7788d30ada8c1b6ead60b27"},
874 | {file = "google_crc32c-1.1.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8ed8f6dc4f55850cba2eb22b78902ad37f397ee02692d3b8e00842e9af757321"},
875 | {file = "google_crc32c-1.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:110157fb19ab5db15603debfaf5fcfbac9627576787d9caf8618ff96821a7a1f"},
876 | {file = "google_crc32c-1.1.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:80abca603187093ea089cd1215c3779040dda55d3cdabc0cd5ea0e10df7bff99"},
877 | {file = "google_crc32c-1.1.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6789db0b12aab12a0f04de22ed8412dfa5f6abd5a342ea19f15355064e1cc387"},
878 | {file = "google_crc32c-1.1.2-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ea170341a4a9078a067b431044cd56c73553425833a7c2bb81734777a230ad4b"},
879 | {file = "google_crc32c-1.1.2-cp36-cp36m-win32.whl", hash = "sha256:a64e0e8ed6076a8d867fc4622ad821c55eba8dff1b48b18f56b7c2392e22ab9d"},
880 | {file = "google_crc32c-1.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9372211acbcc207f63ffaffea1d05f3244a21311e4710721ffff3e8b7a0d24d0"},
881 | {file = "google_crc32c-1.1.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:0ae3cf54e0d4d83c8af1afe96fc0970fbf32f1b29275f3bfd44ce25c4b622a2b"},
882 | {file = "google_crc32c-1.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:34a97937f164147aefa53c3277364fd3bfa7fd244cbebbd5a976fa8325fb496b"},
883 | {file = "google_crc32c-1.1.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:91ad96ee2958311d0bb75ffe5c25c87fb521ef547c09e04a8bb6143e75fb1367"},
884 | {file = "google_crc32c-1.1.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b5ea1055fe470334ced844270e7c808b04fe31e3e6394675daa77f6789ca9eff"},
885 | {file = "google_crc32c-1.1.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:e6458c41236d37cb982120b070ebcc115687c852bee24cdd18792da2640cf44d"},
886 | {file = "google_crc32c-1.1.2-cp37-cp37m-win32.whl", hash = "sha256:e5af77656e8d367701f40f80a91c985ca43319f322f0a36ba9f93909d0bc4cb2"},
887 | {file = "google_crc32c-1.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:ae7b9e7e2ca1b06c3a68b6ef223947a52c30ffae329b1a2be3402756073f2732"},
888 | {file = "google_crc32c-1.1.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:7c5138ed2e815189ba524756e027ac5833365e86115b1c2e6d9e833974a58d82"},
889 | {file = "google_crc32c-1.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a6c8a712ffae56c805ca732b735af02860b246bed2c1acb38ea954a8b2dc4581"},
890 | {file = "google_crc32c-1.1.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:49838ede42592154f9fcd21d07c7a43a67b00a36e252f82ae72542fde09dc51f"},
891 | {file = "google_crc32c-1.1.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:ef2ed6d0ac4de4ac602903e203eccd25ec8e37f1446fe1a3d2953a658035e0a5"},
892 | {file = "google_crc32c-1.1.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:51f4aa06125bf0641f65fb83268853545dbeb36b98ccfec69ef57dcb6b73b176"},
893 | {file = "google_crc32c-1.1.2-cp38-cp38-win32.whl", hash = "sha256:1dc6904c0d958f43102c85d70792cca210d3d051ddbeecd0eff10abcd981fdfa"},
894 | {file = "google_crc32c-1.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:298a9a922d35b123a73be80233d0f19c6ea01f008743561a8937f9dd83fb586b"},
895 | {file = "google_crc32c-1.1.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:ab2b31395fbeeae6d15c98bd7f8b9fb76a18f18f87adc11b1f6dbe8f90d8382f"},
896 | {file = "google_crc32c-1.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:d4a0d4fb938c2c3c0076445c9bd1215a3bd3df557b88d8b05ec2889ca0c92f8d"},
897 | {file = "google_crc32c-1.1.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:d0630670d27785d7e610e72752dc8087436d00d2c7115e149c0a754babb56d3e"},
898 | {file = "google_crc32c-1.1.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:364eb36e8d9d34542c17b0c410035b0557edd4300a92ed736b237afaa0fd6dae"},
899 | {file = "google_crc32c-1.1.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:0dd9b61d0c63043b013349c9ec8a83ec2b05c96410c5bc257da5d0de743fc171"},
900 | {file = "google_crc32c-1.1.2-cp39-cp39-win32.whl", hash = "sha256:92ed6062792b989e84621e07a5f3d37da9cc3153b77d23a582921f14863af31d"},
901 | {file = "google_crc32c-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:78cf5b1bd30f3a6033b41aa4ce8c796870bc4645a15d3ef47a4b05d31b0a6dc1"},
902 | ]
903 | google-resumable-media = [
904 | {file = "google-resumable-media-1.2.0.tar.gz", hash = "sha256:ee98b1921e5bda94867a08c864e55b4763d63887664f49ee1c231988f56b9d43"},
905 | {file = "google_resumable_media-1.2.0-py2.py3-none-any.whl", hash = "sha256:dbe670cd7f02f3586705fd5a108c8ab8552fa36a1cad8afbc5a54e982cf34f0c"},
906 | ]
907 | googleapis-common-protos = [
908 | {file = "googleapis-common-protos-1.53.0.tar.gz", hash = "sha256:a88ee8903aa0a81f6c3cec2d5cf62d3c8aa67c06439b0496b49048fb1854ebf4"},
909 | {file = "googleapis_common_protos-1.53.0-py2.py3-none-any.whl", hash = "sha256:f6d561ab8fb16b30020b940e2dd01cd80082f4762fa9f3ee670f4419b4b8dbd0"},
910 | ]
911 | h11 = [
912 | {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
913 | {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
914 | ]
915 | httplib2 = [
916 | {file = "httplib2-0.19.1-py3-none-any.whl", hash = "sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4"},
917 | {file = "httplib2-0.19.1.tar.gz", hash = "sha256:0b12617eeca7433d4c396a100eaecfa4b08ee99aa881e6df6e257a7aad5d533d"},
918 | ]
919 | httplib2shim = [
920 | {file = "httplib2shim-0.0.3.tar.gz", hash = "sha256:7c61daebd93ed7930df9ded4dbf47f87d35a8f29363d6e399fbf9fec930f8d17"},
921 | ]
922 | idna = [
923 | {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
924 | {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
925 | ]
926 | jinja2 = [
927 | {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
928 | {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
929 | ]
930 | jinja2-time = [
931 | {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"},
932 | {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"},
933 | ]
934 | markupsafe = [
935 | {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
936 | {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
937 | {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
938 | {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
939 | {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
940 | {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
941 | {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
942 | {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
943 | {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
944 | {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
945 | {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
946 | {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
947 | {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
948 | {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
949 | {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
950 | {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
951 | {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
952 | {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
953 | {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"},
954 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
955 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
956 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"},
957 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"},
958 | {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"},
959 | {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
960 | {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
961 | {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
962 | {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"},
963 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
964 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
965 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"},
966 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"},
967 | {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"},
968 | {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
969 | {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
970 | {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
971 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
972 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
973 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"},
974 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"},
975 | {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"},
976 | {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
977 | {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
978 | {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"},
979 | {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"},
980 | {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"},
981 | {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"},
982 | {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"},
983 | {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"},
984 | {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"},
985 | {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"},
986 | {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
987 | ]
988 | more-itertools = [
989 | {file = "more-itertools-8.7.0.tar.gz", hash = "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"},
990 | {file = "more_itertools-8.7.0-py3-none-any.whl", hash = "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced"},
991 | ]
992 | munch = [
993 | {file = "munch-2.5.0-py2.py3-none-any.whl", hash = "sha256:6f44af89a2ce4ed04ff8de41f70b226b984db10a91dcc7b9ac2efc1c77022fdd"},
994 | {file = "munch-2.5.0.tar.gz", hash = "sha256:2d735f6f24d4dba3417fa448cae40c6e896ec1fdab6cdb5e6510999758a4dbd2"},
995 | ]
996 | numpy = [
997 | {file = "numpy-1.20.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e9459f40244bb02b2f14f6af0cd0732791d72232bbb0dc4bab57ef88e75f6935"},
998 | {file = "numpy-1.20.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a8e6859913ec8eeef3dbe9aed3bf475347642d1cdd6217c30f28dee8903528e6"},
999 | {file = "numpy-1.20.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:9cab23439eb1ebfed1aaec9cd42b7dc50fc96d5cd3147da348d9161f0501ada5"},
1000 | {file = "numpy-1.20.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9c0fab855ae790ca74b27e55240fe4f2a36a364a3f1ebcfd1fb5ac4088f1cec3"},
1001 | {file = "numpy-1.20.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:61d5b4cf73622e4d0c6b83408a16631b670fc045afd6540679aa35591a17fe6d"},
1002 | {file = "numpy-1.20.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d15007f857d6995db15195217afdbddfcd203dfaa0ba6878a2f580eaf810ecd6"},
1003 | {file = "numpy-1.20.2-cp37-cp37m-win32.whl", hash = "sha256:d76061ae5cab49b83a8cf3feacefc2053fac672728802ac137dd8c4123397677"},
1004 | {file = "numpy-1.20.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bad70051de2c50b1a6259a6df1daaafe8c480ca98132da98976d8591c412e737"},
1005 | {file = "numpy-1.20.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:719656636c48be22c23641859ff2419b27b6bdf844b36a2447cb39caceb00935"},
1006 | {file = "numpy-1.20.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:aa046527c04688af680217fffac61eec2350ef3f3d7320c07fd33f5c6e7b4d5f"},
1007 | {file = "numpy-1.20.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2428b109306075d89d21135bdd6b785f132a1f5a3260c371cee1fae427e12727"},
1008 | {file = "numpy-1.20.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:e8e4fbbb7e7634f263c5b0150a629342cc19b47c5eba8d1cd4363ab3455ab576"},
1009 | {file = "numpy-1.20.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:edb1f041a9146dcf02cd7df7187db46ab524b9af2515f392f337c7cbbf5b52cd"},
1010 | {file = "numpy-1.20.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:c73a7975d77f15f7f68dacfb2bca3d3f479f158313642e8ea9058eea06637931"},
1011 | {file = "numpy-1.20.2-cp38-cp38-win32.whl", hash = "sha256:6c915ee7dba1071554e70a3664a839fbc033e1d6528199d4621eeaaa5487ccd2"},
1012 | {file = "numpy-1.20.2-cp38-cp38-win_amd64.whl", hash = "sha256:471c0571d0895c68da309dacee4e95a0811d0a9f9f532a48dc1bea5f3b7ad2b7"},
1013 | {file = "numpy-1.20.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4703b9e937df83f5b6b7447ca5912b5f5f297aba45f91dbbbc63ff9278c7aa98"},
1014 | {file = "numpy-1.20.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:abc81829c4039e7e4c30f7897938fa5d4916a09c2c7eb9b244b7a35ddc9656f4"},
1015 | {file = "numpy-1.20.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:377751954da04d4a6950191b20539066b4e19e3b559d4695399c5e8e3e683bf6"},
1016 | {file = "numpy-1.20.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:6e51e417d9ae2e7848314994e6fc3832c9d426abce9328cf7571eefceb43e6c9"},
1017 | {file = "numpy-1.20.2-cp39-cp39-win32.whl", hash = "sha256:780ae5284cb770ade51d4b4a7dce4faa554eb1d88a56d0e8b9f35fca9b0270ff"},
1018 | {file = "numpy-1.20.2-cp39-cp39-win_amd64.whl", hash = "sha256:924dc3f83de20437de95a73516f36e09918e9c9c18d5eac520062c49191025fb"},
1019 | {file = "numpy-1.20.2-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:97ce8b8ace7d3b9288d88177e66ee75480fb79b9cf745e91ecfe65d91a856042"},
1020 | {file = "numpy-1.20.2.zip", hash = "sha256:878922bf5ad7550aa044aa9301d417e2d3ae50f0f577de92051d739ac6096cee"},
1021 | ]
1022 | packaging = [
1023 | {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"},
1024 | {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"},
1025 | ]
1026 | pandas = [
1027 | {file = "pandas-1.2.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c601c6fdebc729df4438ec1f62275d6136a0dd14d332fc0e8ce3f7d2aadb4dd6"},
1028 | {file = "pandas-1.2.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8d4c74177c26aadcfb4fd1de6c1c43c2bf822b3e0fc7a9b409eeaf84b3e92aaa"},
1029 | {file = "pandas-1.2.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:b730add5267f873b3383c18cac4df2527ac4f0f0eed1c6cf37fcb437e25cf558"},
1030 | {file = "pandas-1.2.4-cp37-cp37m-win32.whl", hash = "sha256:2cb7e8f4f152f27dc93f30b5c7a98f6c748601ea65da359af734dd0cf3fa733f"},
1031 | {file = "pandas-1.2.4-cp37-cp37m-win_amd64.whl", hash = "sha256:2111c25e69fa9365ba80bbf4f959400054b2771ac5d041ed19415a8b488dc70a"},
1032 | {file = "pandas-1.2.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:167693a80abc8eb28051fbd184c1b7afd13ce2c727a5af47b048f1ea3afefff4"},
1033 | {file = "pandas-1.2.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:612add929bf3ba9d27b436cc8853f5acc337242d6b584203f207e364bb46cb12"},
1034 | {file = "pandas-1.2.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:971e2a414fce20cc5331fe791153513d076814d30a60cd7348466943e6e909e4"},
1035 | {file = "pandas-1.2.4-cp38-cp38-win32.whl", hash = "sha256:68d7baa80c74aaacbed597265ca2308f017859123231542ff8a5266d489e1858"},
1036 | {file = "pandas-1.2.4-cp38-cp38-win_amd64.whl", hash = "sha256:bd659c11a4578af740782288cac141a322057a2e36920016e0fc7b25c5a4b686"},
1037 | {file = "pandas-1.2.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9db70ffa8b280bb4de83f9739d514cd0735825e79eef3a61d312420b9f16b758"},
1038 | {file = "pandas-1.2.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:298f0553fd3ba8e002c4070a723a59cdb28eda579f3e243bc2ee397773f5398b"},
1039 | {file = "pandas-1.2.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52d2472acbb8a56819a87aafdb8b5b6d2b3386e15c95bde56b281882529a7ded"},
1040 | {file = "pandas-1.2.4-cp39-cp39-win32.whl", hash = "sha256:d0877407359811f7b853b548a614aacd7dea83b0c0c84620a9a643f180060950"},
1041 | {file = "pandas-1.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:2b063d41803b6a19703b845609c0b700913593de067b552a8b24dd8eeb8c9895"},
1042 | {file = "pandas-1.2.4.tar.gz", hash = "sha256:649ecab692fade3cbfcf967ff936496b0cfba0af00a55dfaacd82bdda5cb2279"},
1043 | ]
1044 | pluggy = [
1045 | {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
1046 | {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
1047 | ]
1048 | protobuf = [
1049 | {file = "protobuf-3.15.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fad4f971ec38d8df7f4b632c819bf9bbf4f57cfd7312cf526c69ce17ef32436a"},
1050 | {file = "protobuf-3.15.8-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f17b352d7ce33c81773cf81d536ca70849de6f73c96413f17309f4b43ae7040b"},
1051 | {file = "protobuf-3.15.8-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:4a054b0b5900b7ea7014099e783fb8c4618e4209fffcd6050857517b3f156e18"},
1052 | {file = "protobuf-3.15.8-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:efa4c4d4fc9ba734e5e85eaced70e1b63fb3c8d08482d839eb838566346f1737"},
1053 | {file = "protobuf-3.15.8-cp35-cp35m-win32.whl", hash = "sha256:07eec4e2ccbc74e95bb9b3afe7da67957947ee95bdac2b2e91b038b832dd71f0"},
1054 | {file = "protobuf-3.15.8-cp35-cp35m-win_amd64.whl", hash = "sha256:f9cadaaa4065d5dd4d15245c3b68b967b3652a3108e77f292b58b8c35114b56c"},
1055 | {file = "protobuf-3.15.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2dc0e8a9e4962207bdc46a365b63a3f1aca6f9681a5082a326c5837ef8f4b745"},
1056 | {file = "protobuf-3.15.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f80afc0a0ba13339bbab25ca0409e9e2836b12bb012364c06e97c2df250c3343"},
1057 | {file = "protobuf-3.15.8-cp36-cp36m-win32.whl", hash = "sha256:c5566f956a26cda3abdfacc0ca2e21db6c9f3d18f47d8d4751f2209d6c1a5297"},
1058 | {file = "protobuf-3.15.8-cp36-cp36m-win_amd64.whl", hash = "sha256:dab75b56a12b1ceb3e40808b5bd9dfdaef3a1330251956e6744e5b6ed8f8830b"},
1059 | {file = "protobuf-3.15.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3053f13207e7f13dc7be5e9071b59b02020172f09f648e85dc77e3fcb50d1044"},
1060 | {file = "protobuf-3.15.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1f0b5d156c3df08cc54bc2c8b8b875648ea4cd7ebb2a9a130669f7547ec3488c"},
1061 | {file = "protobuf-3.15.8-cp37-cp37m-win32.whl", hash = "sha256:90270fe5732c1f1ff664a3bd7123a16456d69b4e66a09a139a00443a32f210b8"},
1062 | {file = "protobuf-3.15.8-cp37-cp37m-win_amd64.whl", hash = "sha256:f42c2f5fb67da5905bfc03733a311f72fa309252bcd77c32d1462a1ad519521e"},
1063 | {file = "protobuf-3.15.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6077db37bfa16494dca58a4a02bfdacd87662247ad6bc1f7f8d13ff3f0013e1"},
1064 | {file = "protobuf-3.15.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:510e66491f1a5ac5953c908aa8300ec47f793130097e4557482803b187a8ee05"},
1065 | {file = "protobuf-3.15.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5ff9fa0e67fcab442af9bc8d4ec3f82cb2ff3be0af62dba047ed4187f0088b7d"},
1066 | {file = "protobuf-3.15.8-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1c0e9e56202b9dccbc094353285a252e2b7940b74fdf75f1b4e1b137833fabd7"},
1067 | {file = "protobuf-3.15.8-py2.py3-none-any.whl", hash = "sha256:a0a08c6b2e6d6c74a6eb5bf6184968eefb1569279e78714e239d33126e753403"},
1068 | {file = "protobuf-3.15.8.tar.gz", hash = "sha256:0277f62b1e42210cafe79a71628c1d553348da81cbd553402a7f7549c50b11d0"},
1069 | ]
1070 | py = [
1071 | {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"},
1072 | {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"},
1073 | ]
1074 | pyasn1 = [
1075 | {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"},
1076 | {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"},
1077 | {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"},
1078 | {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"},
1079 | {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
1080 | {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"},
1081 | {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"},
1082 | {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"},
1083 | {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"},
1084 | {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"},
1085 | {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"},
1086 | {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"},
1087 | {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
1088 | ]
1089 | pyasn1-modules = [
1090 | {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"},
1091 | {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"},
1092 | {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"},
1093 | {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"},
1094 | {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"},
1095 | {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"},
1096 | {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"},
1097 | {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"},
1098 | {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"},
1099 | {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"},
1100 | {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"},
1101 | {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"},
1102 | {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"},
1103 | ]
1104 | pycparser = [
1105 | {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
1106 | {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
1107 | ]
1108 | pydantic = [
1109 | {file = "pydantic-1.8.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0c40162796fc8d0aa744875b60e4dc36834db9f2a25dbf9ba9664b1915a23850"},
1110 | {file = "pydantic-1.8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:fff29fe54ec419338c522b908154a2efabeee4f483e48990f87e189661f31ce3"},
1111 | {file = "pydantic-1.8.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:fbfb608febde1afd4743c6822c19060a8dbdd3eb30f98e36061ba4973308059e"},
1112 | {file = "pydantic-1.8.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:eb8ccf12295113ce0de38f80b25f736d62f0a8d87c6b88aca645f168f9c78771"},
1113 | {file = "pydantic-1.8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:20d42f1be7c7acc352b3d09b0cf505a9fab9deb93125061b376fbe1f06a5459f"},
1114 | {file = "pydantic-1.8.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dde4ca368e82791de97c2ec019681ffb437728090c0ff0c3852708cf923e0c7d"},
1115 | {file = "pydantic-1.8.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3bbd023c981cbe26e6e21c8d2ce78485f85c2e77f7bab5ec15b7d2a1f491918f"},
1116 | {file = "pydantic-1.8.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:830ef1a148012b640186bf4d9789a206c56071ff38f2460a32ae67ca21880eb8"},
1117 | {file = "pydantic-1.8.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:fb77f7a7e111db1832ae3f8f44203691e15b1fa7e5a1cb9691d4e2659aee41c4"},
1118 | {file = "pydantic-1.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3bcb9d7e1f9849a6bdbd027aabb3a06414abd6068cb3b21c49427956cce5038a"},
1119 | {file = "pydantic-1.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2287ebff0018eec3cc69b1d09d4b7cebf277726fa1bd96b45806283c1d808683"},
1120 | {file = "pydantic-1.8.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:4bbc47cf7925c86a345d03b07086696ed916c7663cb76aa409edaa54546e53e2"},
1121 | {file = "pydantic-1.8.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:6388ef4ef1435364c8cc9a8192238aed030595e873d8462447ccef2e17387125"},
1122 | {file = "pydantic-1.8.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:dd4888b300769ecec194ca8f2699415f5f7760365ddbe243d4fd6581485fa5f0"},
1123 | {file = "pydantic-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:8fbb677e4e89c8ab3d450df7b1d9caed23f254072e8597c33279460eeae59b99"},
1124 | {file = "pydantic-1.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2f2736d9a996b976cfdfe52455ad27462308c9d3d0ae21a2aa8b4cd1a78f47b9"},
1125 | {file = "pydantic-1.8.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3114d74329873af0a0e8004627f5389f3bb27f956b965ddd3e355fe984a1789c"},
1126 | {file = "pydantic-1.8.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:258576f2d997ee4573469633592e8b99aa13bda182fcc28e875f866016c8e07e"},
1127 | {file = "pydantic-1.8.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:c17a0b35c854049e67c68b48d55e026c84f35593c66d69b278b8b49e2484346f"},
1128 | {file = "pydantic-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:e8bc082afef97c5fd3903d05c6f7bb3a6af9fc18631b4cc9fedeb4720efb0c58"},
1129 | {file = "pydantic-1.8.1-py3-none-any.whl", hash = "sha256:e3f8790c47ac42549dc8b045a67b0ca371c7f66e73040d0197ce6172b385e520"},
1130 | {file = "pydantic-1.8.1.tar.gz", hash = "sha256:26cf3cb2e68ec6c0cfcb6293e69fb3450c5fd1ace87f46b64f678b0d29eac4c3"},
1131 | ]
1132 | pyparsing = [
1133 | {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
1134 | {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
1135 | ]
1136 | pyproj = [
1137 | {file = "pyproj-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f942a976ea3de6a519cf48be30a12f465e44d0ac0c38a0d820ab3acfcc0a48a6"},
1138 | {file = "pyproj-3.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:09db64a8088b23f001e574d92bcc3080bf7de44ddca152d0282a2b50c918a64a"},
1139 | {file = "pyproj-3.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:cba99e171d744969e13a865ad28fa9c949c4400b0e9c431a802cdd804f52f632"},
1140 | {file = "pyproj-3.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:81c06df20d09d621e52791c19ce3c880695fb430061e59c2472fa5467e890391"},
1141 | {file = "pyproj-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:3e7e851e6d58c16ac2cd920a1bacb7fbb24758a6fcd7f234d594a88ebae04ec9"},
1142 | {file = "pyproj-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:aa0a2981b25145523ca17a643c5be077fe13e514fdca9b6d1c412a95d723a5a5"},
1143 | {file = "pyproj-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:708d6e01b9ff3d6dc62a5ad2d2ba1264a863eaa657c1a9bf713a10cc35d34553"},
1144 | {file = "pyproj-3.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:36ba436675f9dea4ab3db7d9a32d3ff11c2fbb4d6690a83454d2f3c5c0b54041"},
1145 | {file = "pyproj-3.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:489a96da87d8846c34c90da90e637544e4f4f50a13589b5aac54297f5ee1b01d"},
1146 | {file = "pyproj-3.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:4a333f3e46fe8b2eb4647a3daa3a2cec52ddc6c107c653b45880526114942ee8"},
1147 | {file = "pyproj-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:9e2ef75401f17062166d3fe53c555cd62c9577697a2f5ded916b23c54e5db497"},
1148 | {file = "pyproj-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7bfaa34e8bb0510d4380310374deecd9e4328b9cf556925cfb45b5a94d5bbdbe"},
1149 | {file = "pyproj-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9666d01faf4e758ac68f2c16695c90de49c3170e3760988bf76a34aae11f4e15"},
1150 | {file = "pyproj-3.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c658afc8a6115b58b02aa53d27bf2a67c1b00b55067edb1b7711c6c7391cfaa9"},
1151 | {file = "pyproj-3.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fee7517bd389a1db7b8bebb18838d04dedca9eaacda01d353d98f5ee421f263e"},
1152 | {file = "pyproj-3.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:86ef2fcd584a3222bf73e2befc24b2badd139b3371f4a1e88649978ef7649540"},
1153 | {file = "pyproj-3.0.1-cp38-cp38-win32.whl", hash = "sha256:d27d40ec541ef69a5107bfcd85f40170e9e122ceb6315ce508cd44d199983d41"},
1154 | {file = "pyproj-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:bc70b6adcfa713d89bc561673cb57af5fb3a1718cd7d57ec537430cd1007a864"},
1155 | {file = "pyproj-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b845510255f9580d7e226dd3321a51c468cefb7be24e46415caf67caa4287c4"},
1156 | {file = "pyproj-3.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7ae8e7052f18fde1884574da449010e94fa205ad27aeeaa34a097f49a1ed6a2b"},
1157 | {file = "pyproj-3.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:a3805e026a5547be205a5e322c08e3069f0a48c63bbd53dbc7a8e3499bc66d58"},
1158 | {file = "pyproj-3.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1be7d54900eb7e2d1e637319080b3a047c70d1fb2f3c12d3400c0fa8a90cf440"},
1159 | {file = "pyproj-3.0.1-cp39-cp39-win32.whl", hash = "sha256:09bead60769e69b592e8cb3ac51b5215f75e9bb9c213ce575031961deb48d6da"},
1160 | {file = "pyproj-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:a3a8ab19232bf4f4bb2590536538881b7bd0c07df23e0c2a792402ca2476c197"},
1161 | {file = "pyproj-3.0.1.tar.gz", hash = "sha256:bfbac35490dd17f706700673506eeb8170f8a2a63fb5878171d4e6eef242d141"},
1162 | ]
1163 | pytest = [
1164 | {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
1165 | {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
1166 | ]
1167 | python-dateutil = [
1168 | {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
1169 | {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
1170 | ]
1171 | python-multipart = [
1172 | {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"},
1173 | ]
1174 | pytz = [
1175 | {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
1176 | {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
1177 | ]
1178 | requests = [
1179 | {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
1180 | {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
1181 | ]
1182 | rsa = [
1183 | {file = "rsa-4.7.2-py3-none-any.whl", hash = "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2"},
1184 | {file = "rsa-4.7.2.tar.gz", hash = "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9"},
1185 | ]
1186 | shapely = [
1187 | {file = "Shapely-1.7.1-1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:46da0ea527da9cf9503e66c18bab6981c5556859e518fe71578b47126e54ca93"},
1188 | {file = "Shapely-1.7.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4c10f317e379cc404f8fc510cd9982d5d3e7ba13a9cfd39aa251d894c6366798"},
1189 | {file = "Shapely-1.7.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:17df66e87d0fe0193910aeaa938c99f0b04f67b430edb8adae01e7be557b141b"},
1190 | {file = "Shapely-1.7.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:da38ed3d65b8091447dc3717e5218cc336d20303b77b0634b261bc5c1aa2bae8"},
1191 | {file = "Shapely-1.7.1-cp35-cp35m-win32.whl", hash = "sha256:8e7659dd994792a0aad8fb80439f59055a21163e236faf2f9823beb63a380e19"},
1192 | {file = "Shapely-1.7.1-cp35-cp35m-win_amd64.whl", hash = "sha256:791477edb422692e7dc351c5ed6530eb0e949a31b45569946619a0d9cd5f53cb"},
1193 | {file = "Shapely-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3afccf0437edc108eef1e2bb9cc4c7073e7705924eb4cd0bf7715cd1ef0ce1b"},
1194 | {file = "Shapely-1.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8f15b6ce67dcc05b61f19c689b60f3fe58550ba994290ff8332f711f5aaa9840"},
1195 | {file = "Shapely-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:60e5b2282619249dbe8dc5266d781cc7d7fb1b27fa49f8241f2167672ad26719"},
1196 | {file = "Shapely-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:de618e67b64a51a0768d26a9963ecd7d338a2cf6e9e7582d2385f88ad005b3d1"},
1197 | {file = "Shapely-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:182716ffb500d114b5d1b75d7fd9d14b7d3414cef3c38c0490534cc9ce20981a"},
1198 | {file = "Shapely-1.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4f3c59f6dbf86a9fc293546de492f5e07344e045f9333f3a753f2dda903c45d1"},
1199 | {file = "Shapely-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:6871acba8fbe744efa4f9f34e726d070bfbf9bffb356a8f6d64557846324232b"},
1200 | {file = "Shapely-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:35be1c5d869966569d3dfd4ec31832d7c780e9df760e1fe52131105685941891"},
1201 | {file = "Shapely-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:052eb5b9ba756808a7825e8a8020fb146ec489dd5c919e7d139014775411e688"},
1202 | {file = "Shapely-1.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:90a3e2ae0d6d7d50ff2370ba168fbd416a53e7d8448410758c5d6a5920646c1d"},
1203 | {file = "Shapely-1.7.1-cp38-cp38-win32.whl", hash = "sha256:a3774516c8a83abfd1ddffb8b6ec1b0935d7fe6ea0ff5c31a18bfdae567b4eba"},
1204 | {file = "Shapely-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:6593026cd3f5daaea12bcc51ae5c979318070fefee210e7990cb8ac2364e79a1"},
1205 | {file = "Shapely-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:617bf046a6861d7c6b44d2d9cb9e2311548638e684c2cd071d8945f24a926263"},
1206 | {file = "Shapely-1.7.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b40cc7bb089ae4aa9ddba1db900b4cd1bce3925d2a4b5837b639e49de054784f"},
1207 | {file = "Shapely-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2df5260d0f2983309776cb41bfa85c464ec07018d88c0ecfca23d40bfadae2f1"},
1208 | {file = "Shapely-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:a5c3a50d823c192f32615a2a6920e8c046b09e07a58eba220407335a9cd2e8ea"},
1209 | {file = "Shapely-1.7.1.tar.gz", hash = "sha256:1641724c1055459a7e2b8bbe47ba25bdc89554582e62aec23cb3f3ca25f9b129"},
1210 | ]
1211 | six = [
1212 | {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
1213 | {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
1214 | ]
1215 | starlette = [
1216 | {file = "starlette-0.13.6-py3-none-any.whl", hash = "sha256:bd2ffe5e37fb75d014728511f8e68ebf2c80b0fa3d04ca1479f4dc752ae31ac9"},
1217 | {file = "starlette-0.13.6.tar.gz", hash = "sha256:ebe8ee08d9be96a3c9f31b2cb2a24dbdf845247b745664bd8a3f9bd0c977fdbc"},
1218 | ]
1219 | typing-extensions = [
1220 | {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"},
1221 | {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"},
1222 | {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
1223 | ]
1224 | uritemplate = [
1225 | {file = "uritemplate-3.0.1-py2.py3-none-any.whl", hash = "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f"},
1226 | {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"},
1227 | ]
1228 | urllib3 = [
1229 | {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"},
1230 | {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"},
1231 | ]
1232 | uvicorn = [
1233 | {file = "uvicorn-0.13.4-py3-none-any.whl", hash = "sha256:7587f7b08bd1efd2b9bad809a3d333e972f1d11af8a5e52a9371ee3a5de71524"},
1234 | {file = "uvicorn-0.13.4.tar.gz", hash = "sha256:3292251b3c7978e8e4a7868f4baf7f7f7bb7e40c759ecc125c37e99cdea34202"},
1235 | ]
1236 | wcwidth = [
1237 | {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
1238 | {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
1239 | ]
1240 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "dev"
3 | version = "0.1.0"
4 | description = ""
5 | authors = ["csaybar "]
6 |
7 | [tool.poetry.dependencies]
8 | python = "^3.8"
9 | fastapi = "^0.63.0"
10 | uvicorn = "^0.13.4"
11 | aiofiles = "^0.6.0"
12 | Jinja2 = "^2.11.3"
13 | jinja2-time = "^0.2.0"
14 | earthengine-api = "^0.1.262"
15 | python-multipart = "^0.0.5"
16 | geopandas = "^0.9.0"
17 |
18 | [tool.poetry.dev-dependencies]
19 | pytest = "^5.2"
20 |
21 | [build-system]
22 | requires = ["poetry-core>=1.0.0"]
23 | build-backend = "poetry.core.masonry.api"
24 |
--------------------------------------------------------------------------------
/src/model.py:
--------------------------------------------------------------------------------
1 | """SAR-FLOOD MAPPING USING A CHANGE DETECTION APPROACH
2 |
3 | This script use SAR Sentinel-1 images to generate a flood extent map. A
4 | change detection approach was chosen, where a before- and after-flood
5 | event image will be compared. The dataset available in the Earth Engine
6 | Data Catalog includes the following preprocessing steps: Thermal-Noise
7 | Removal, Radiometric calibration, and Terrain-correction.
8 | """
9 |
10 | import ee
11 |
12 | # Earth Engine Viz Parameters
13 | geoviz_app = {
14 | "s1_img": {"min": -25, "max": 0},
15 | "diff_s1": {"min": 0, "max": 2},
16 | "flood": {"palette": "0000FF"},
17 | "populationCountVis": {
18 | "min": 0, "max": 200.0,
19 | "palette": ['060606', '337663', '337663', 'ffffff']
20 | },
21 | "populationExposedVis": {
22 | "min": 0, "max": 200.0,
23 | "palette": ['yellow', 'orange', 'red']
24 | },
25 | "LCVis": {
26 | "min": 1.0, "max": 17.0,
27 | "palette": [
28 | '05450a', '086a10', '54a708', '78d203',
29 | '009900', 'c6b044', 'dcd159', 'dade48',
30 | 'fbff13', 'b6ff05', '27ff87', 'c24f44',
31 | 'a5a5a5', 'ff6d4c', '69fff8', 'f9ffa4',
32 | '1c0dff'
33 | ]
34 | },
35 | "croplandVis": {"min": 0, "max": 14.0, "palette": ['30b21c']},
36 | "urbanVis": {"min": 0, "max": 13.0, "palette": ['grey']}
37 | }
38 |
39 |
40 | # Display basemap
41 | def display(dict_db):
42 | """ Display a basic Earth Engine map
43 | Returns:
44 | str: earthengine tiles googleapis
45 | """
46 |
47 | # S1 before flood
48 | s1_bf = ee.Image.visualize(dict_db["before_flood"], **geoviz_app["s1_img"])
49 | s1_bf_id = ee.data.getMapId({"image": s1_bf})["tile_fetcher"].url_format
50 |
51 | # S1 after flood
52 | s1_af = ee.Image.visualize(dict_db["after_flood"], **geoviz_app["s1_img"])
53 | s1_af_id = ee.data.getMapId({"image": s1_af})["tile_fetcher"].url_format
54 |
55 | # Flood results
56 | s1_fresults = ee.Image.visualize(dict_db["flood_results"], **geoviz_app["flood"])
57 | s1_fresults_id = ee.data.getMapId({"image": s1_fresults})["tile_fetcher"].url_format
58 |
59 | layer_to_display = {
60 | "before_flood": s1_bf_id,
61 | "after_flood": s1_af_id,
62 | "s1_fresults_id": s1_fresults_id
63 | }
64 | return layer_to_display
65 |
66 | # Extract date from meta data
67 | def dates(imgcol):
68 | range = imgcol.reduceColumns(ee.Reducer.minMax(), ["system:time_start"])
69 | ee_min = ee.Date(range.get('min')).format('YYYY-MM-dd').getInfo()
70 | ee_max = ee.Date(range.get('max')).format('YYYY-MM-dd').getInfo()
71 | printed = "from %s to %s" % (ee_min, ee_max)
72 | return printed
73 |
74 |
75 | def db_creator(base_period , flood_period, geometry, polarization="VH",
76 | pass_direction="DESCENDING", quiet=False):
77 |
78 | # rename selected geometry feature
79 | aoi = ee.FeatureCollection(geometry)
80 |
81 | # Load and filter Sentinel-1 GRD data by predefined parameters
82 | collection = ee.ImageCollection("COPERNICUS/S1_GRD")\
83 | .filter(ee.Filter.eq("instrumentMode", "IW"))\
84 | .filter(ee.Filter.listContains("transmitterReceiverPolarisation", polarization))\
85 | .filter(ee.Filter.eq("orbitProperties_pass",pass_direction))\
86 | .filter(ee.Filter.eq("resolution_meters",10)) \
87 | .filterBounds(aoi)\
88 | .select(polarization)
89 | # .filter(ee.Filter.eq('relativeOrbitNumber_start', relative_orbit)) \
90 |
91 | # Select images by predefined dates
92 | before_collection = collection.filterDate(base_period[0], base_period[1])
93 | after_collection = collection.filterDate(flood_period[0], flood_period[1])
94 |
95 | if quiet:
96 | # print dates of before images to console
97 | before_count = before_collection.size().getInfo()
98 | print("Tiles selected: Before Flood (%s) \n %s" % (before_count, dates(before_collection)))
99 |
100 | # print dates of after images to console
101 | after_count = before_collection.size().getInfo()
102 | print("Tiles selected: After Flood (%s) \n %s" % (after_count, dates(after_collection)))
103 |
104 | # Create a mosaic of selected tiles and clip to study area
105 | before = before_collection.mosaic().clip(aoi)
106 | after = after_collection.mosaic().clip(aoi)
107 |
108 | # Apply reduce the radar speckle by smoothing
109 | smoothing_radius = 50
110 | before_filtered = before.focal_mean(smoothing_radius, "circle", "meters")
111 | after_filtered = after.focal_mean(smoothing_radius, "circle", "meters")
112 | dict_preprocessing = dict(before_flood=before_filtered,
113 | after_flood=after_filtered,
114 | base_period=base_period,
115 | flood_period=flood_period,
116 | aoi=aoi,
117 | polarization=polarization)
118 | return dict_preprocessing
119 |
120 |
121 | def flood_estimation(dict_db, difference_threshold=1.25, stats=True):
122 |
123 | before_filtered = dict_db["before_flood"]
124 | after_filtered = dict_db["after_flood"]
125 | polarization = dict_db["polarization"]
126 | aoi = dict_db["aoi"]
127 |
128 | # Calculate the difference between the before and after images
129 | difference = after_filtered.divide(before_filtered)
130 |
131 | # Apply the predefined difference-threshold and create the flood extent mask
132 | threshold = difference_threshold
133 | difference_binary = difference.gt(threshold)
134 |
135 | # Refine flood result using additional datasets
136 | # Include JRC layer on surface water seasonality to mask flood pixels from areas
137 | # of "permanent" water (where there is water > 10 months of the year)
138 | swater = ee.Image('JRC/GSW1_0/GlobalSurfaceWater').select('seasonality')
139 | swater_mask = swater.gte(10).updateMask(swater.gte(10))
140 |
141 | # Flooded layer where perennial water bodies (water > 10 mo/yr) is assigned a 0 value
142 | flooded_mask = difference_binary.where(swater_mask, 0)
143 | # final flooded area without pixels in perennial waterbodies
144 | flooded = flooded_mask.updateMask(flooded_mask)
145 |
146 | # Compute connectivity of pixels to eliminate those connected to 8 or fewer neighbours
147 | # This operation reduces noise of the flood extent product
148 | connections = flooded.connectedPixelCount()
149 | flooded = flooded.updateMask(connections.gte(8))
150 |
151 | # Mask out areas with more than 5 percent slope using a Digital Elevation Model
152 | DEM = ee.Image('WWF/HydroSHEDS/03VFDEM')
153 | terrain = ee.Algorithms.Terrain(DEM)
154 | slope = terrain.select('slope')
155 | flooded = flooded.updateMask(slope.lt(5))
156 |
157 | dict_db.update({"flood_results": flooded}) # add flood mask results to the db
158 |
159 | if stats:
160 | # Calculate flood extent area
161 | # Create a raster layer containing the area information of each pixel
162 | flood_pixelarea = flooded.select(polarization).multiply(ee.Image.pixelArea())
163 |
164 | # Sum the areas of flooded pixels
165 | # default is set to 'bestEffort: true' in order to reduce compuation time, for a more
166 | # accurate result set bestEffort to false and increase 'maxPixels'.
167 | flood_stats = flood_pixelarea.reduceRegion(
168 | reducer=ee.Reducer.sum(),
169 | geometry=aoi,
170 | scale=10, # native resolution
171 | bestEffort=True
172 | )
173 |
174 | # Convert the flood extent to hectares (area calculations are originally given in meters)
175 | flood_area_ha = flood_stats\
176 | .getNumber(polarization)\
177 | .divide(10000)\
178 | .round() \
179 | .getInfo()
180 | dict_db.update({"flood_area_stats":flood_area_ha}) # add flood stats results to the db
181 | return dict_db
--------------------------------------------------------------------------------
/src/utils.py:
--------------------------------------------------------------------------------
1 | import os, re
2 | from pathlib import Path
3 | from typing import List
4 |
5 | # Copy the token to the container
6 | def load_credentials():
7 | ee_token = os.environ['EARTHENGINE_TOKEN']
8 | credential = '{"refresh_token":"%s"}' % ee_token
9 | credential_file_path = os.path.expanduser("~/.config/earthengine/")
10 | os.makedirs(credential_file_path,exist_ok=True)
11 | with open(credential_file_path + 'credentials', 'w') as file:
12 | file.write(credential)
13 | return True
14 |
15 |
16 | def replace_line(file_name: str, line_num: int, text: str):
17 | """ Replace a specific line in a file
18 |
19 | Args:
20 | file_name (str): file path
21 | line_num (int): line to replace.
22 | text (str): Text to put in the line.
23 |
24 | Returns:
25 | bool: If the line was replaced will return True.
26 | """
27 | with open(file_name, 'r+') as f:
28 | lines = f.readlines()
29 | lines[line_num] = text
30 | f.writelines(lines)
31 | with open(file_name, 'w') as fw:
32 | fw.writelines(lines)
33 | return True
34 |
35 | def searching_all_files(path:str = ".", pattern : str="\.tiff$|\.csv$") -> List:
36 | dirpath = Path(path)
37 | assert(dirpath.is_dir())
38 | file_list = []
39 | for x in dirpath.iterdir():
40 | if x.is_file() and re.search(pattern, x.as_posix()):
41 | file_list.append(x.absolute().as_posix())
42 | elif x.is_dir():
43 | file_list.extend(searching_all_files(x, pattern))
44 | return file_list
45 |
46 | def raster_to_vector(image, geom):
47 | vector_img = image.unmask(0).reduceToVectors(
48 | geometry = geom,
49 | scale = 10,
50 | bestEffort =True
51 | )
52 | return vector_img.getInfo()
--------------------------------------------------------------------------------
/static/css/ol3-sidebar.css:
--------------------------------------------------------------------------------
1 | .sidebar {
2 | position: absolute;
3 | top: 0;
4 | bottom: 0;
5 | width: 100%;
6 | overflow: hidden;
7 | z-index: 2000; }
8 | .sidebar.collapsed {
9 | width: 40px; }
10 | @media (min-width: 768px) {
11 | .sidebar {
12 | top: 6px;
13 | bottom: 6px;
14 | transition: width 500ms; } }
15 | @media (min-width: 768px) and (max-width: 991px) {
16 | .sidebar {
17 | width: 305px; } }
18 | @media (min-width: 992px) and (max-width: 1199px) {
19 | .sidebar {
20 | width: 390px; } }
21 | @media (min-width: 1200px) {
22 | .sidebar {
23 | width: 460px; } }
24 |
25 | .sidebar-left {
26 | left: 0; }
27 | @media (min-width: 768px) {
28 | .sidebar-left {
29 | left: 6px; } }
30 |
31 | .sidebar-right {
32 | right: 0; }
33 | @media (min-width: 768px) {
34 | .sidebar-right {
35 | right: 6px; } }
36 |
37 | .sidebar-tabs {
38 | top: 0;
39 | bottom: 0;
40 | height: 100%;
41 | background-color: rgba(0, 60, 136, 0.5); }
42 | .sidebar-left .sidebar-tabs {
43 | left: 0; }
44 | .sidebar-right .sidebar-tabs {
45 | right: 0; }
46 | .sidebar-tabs, .sidebar-tabs > ul {
47 | position: absolute;
48 | width: 40px;
49 | margin: 0;
50 | padding: 0;
51 | list-style-type: none; }
52 | .sidebar-tabs > li, .sidebar-tabs > ul > li {
53 | width: 100%;
54 | height: 40px;
55 | color: #fff;
56 | font-size: 12pt;
57 | overflow: hidden;
58 | transition: all 80ms; }
59 | .sidebar-tabs > li:hover, .sidebar-tabs > ul > li:hover {
60 | color: #fff;
61 | background-color: rgba(0, 60, 136, 0.6); }
62 | .sidebar-tabs > li.active, .sidebar-tabs > ul > li.active {
63 | color: #fff;
64 | background-color: #0074d9; }
65 | .sidebar-tabs > li.disabled, .sidebar-tabs > ul > li.disabled {
66 | color: rgba(255, 255, 255, 0.4); }
67 | .sidebar-tabs > li.disabled:hover, .sidebar-tabs > ul > li.disabled:hover {
68 | background: transparent; }
69 | .sidebar-tabs > li.disabled > a, .sidebar-tabs > ul > li.disabled > a {
70 | cursor: default; }
71 | .sidebar-tabs > li > a, .sidebar-tabs > ul > li > a {
72 | display: block;
73 | width: 100%;
74 | height: 100%;
75 | line-height: 40px;
76 | color: inherit;
77 | text-decoration: none;
78 | text-align: center; }
79 | .sidebar-tabs > ul + ul {
80 | bottom: 0; }
81 |
82 | .sidebar-content {
83 | position: absolute;
84 | top: 0;
85 | bottom: 0;
86 | background-color: rgba(255, 255, 255, 0.95);
87 | overflow-x: hidden;
88 | overflow-y: auto; }
89 | .sidebar-left .sidebar-content {
90 | left: 40px;
91 | right: 0; }
92 | .sidebar-right .sidebar-content {
93 | left: 0;
94 | right: 40px; }
95 | .sidebar.collapsed > .sidebar-content {
96 | overflow-y: hidden; }
97 |
98 | .sidebar-pane {
99 | display: none;
100 | left: 0;
101 | right: 0;
102 | box-sizing: border-box;
103 | padding: 10px 20px; }
104 | .sidebar-pane.active {
105 | display: block; }
106 | @media (min-width: 768px) and (max-width: 991px) {
107 | .sidebar-pane {
108 | min-width: 265px; } }
109 | @media (min-width: 992px) and (max-width: 1199px) {
110 | .sidebar-pane {
111 | min-width: 350px; } }
112 | @media (min-width: 1200px) {
113 | .sidebar-pane {
114 | min-width: 420px; } }
115 |
116 | .sidebar-header {
117 | margin: -10px -20px 0;
118 | height: 40px;
119 | padding: 0 20px;
120 | line-height: 40px;
121 | font-size: 14.4pt;
122 | color: #fff;
123 | background-color: #0074d9; }
124 | .sidebar-right .sidebar-header {
125 | padding-left: 40px; }
126 |
127 | .sidebar-close {
128 | position: absolute;
129 | top: 0;
130 | width: 40px;
131 | height: 40px;
132 | text-align: center;
133 | cursor: pointer; }
134 | .sidebar-left .sidebar-close {
135 | right: 0; }
136 | .sidebar-right .sidebar-close {
137 | left: 0; }
138 |
139 | .sidebar {
140 | background-color: rgba(255, 255, 255, 0.4); }
141 | @media (min-width: 768px) {
142 | .sidebar {
143 | border: 3px solid transparent;
144 | border-radius: 4px; } }
145 |
146 | .sidebar-left {
147 | border-right: 3px solid transparent; }
148 |
149 | .sidebar-right {
150 | border-left: 3px solid transparent; }
151 |
152 | .sidebar-tabs {
153 | overflow: hidden; }
154 | @media (min-width: 768px) {
155 | .sidebar-tabs {
156 | border-radius: 2px 0 0 2px; }
157 | .collapsed .sidebar-tabs {
158 | border-radius: 2px; } }
159 |
160 | @media (min-width: 768px) {
161 | .sidebar-content {
162 | border-radius: 0 2px 2px 0; } }
163 |
164 | .sidebar-left ~ .sidebar-map .ol-zoom, .sidebar-left ~ .sidebar-map .ol-scale-line {
165 | margin-left: 46px; }
166 | @media (min-width: 768px) {
167 | .sidebar-left ~ .sidebar-map .ol-zoom, .sidebar-left ~ .sidebar-map .ol-scale-line {
168 | transition: margin-left 500ms; } }
169 | @media (min-width: 768px) and (max-width: 991px) {
170 | .sidebar-left ~ .sidebar-map .ol-zoom, .sidebar-left ~ .sidebar-map .ol-scale-line {
171 | margin-left: 317px; } }
172 | @media (min-width: 992px) and (max-width: 1199px) {
173 | .sidebar-left ~ .sidebar-map .ol-zoom, .sidebar-left ~ .sidebar-map .ol-scale-line {
174 | margin-left: 402px; } }
175 | @media (min-width: 1200px) {
176 | .sidebar-left ~ .sidebar-map .ol-zoom, .sidebar-left ~ .sidebar-map .ol-scale-line {
177 | margin-left: 472px; } }
178 |
179 | @media (min-width: 768px) {
180 | .sidebar-left.collapsed ~ .sidebar-map .ol-zoom, .sidebar-left.collapsed ~ .sidebar-map .ol-scale-line {
181 | margin-left: 52px; } }
182 |
183 | .sidebar-right ~ .sidebar-map .ol-rotate,
184 | .sidebar-right ~ .sidebar-map .ol-attribution,
185 | .sidebar-right ~ .sidebar-map .ol-full-screen {
186 | margin-right: 46px; }
187 | @media (min-width: 768px) {
188 | .sidebar-right ~ .sidebar-map .ol-rotate,
189 | .sidebar-right ~ .sidebar-map .ol-attribution,
190 | .sidebar-right ~ .sidebar-map .ol-full-screen {
191 | transition: margin-right 500ms; } }
192 | @media (min-width: 768px) and (max-width: 991px) {
193 | .sidebar-right ~ .sidebar-map .ol-rotate,
194 | .sidebar-right ~ .sidebar-map .ol-attribution,
195 | .sidebar-right ~ .sidebar-map .ol-full-screen {
196 | margin-right: 317px; } }
197 | @media (min-width: 992px) and (max-width: 1199px) {
198 | .sidebar-right ~ .sidebar-map .ol-rotate,
199 | .sidebar-right ~ .sidebar-map .ol-attribution,
200 | .sidebar-right ~ .sidebar-map .ol-full-screen {
201 | margin-right: 402px; } }
202 | @media (min-width: 1200px) {
203 | .sidebar-right ~ .sidebar-map .ol-rotate,
204 | .sidebar-right ~ .sidebar-map .ol-attribution,
205 | .sidebar-right ~ .sidebar-map .ol-full-screen {
206 | margin-right: 472px; } }
207 |
208 | @media (min-width: 768px) {
209 | .sidebar-right.collapsed ~ .sidebar-map .ol-rotate,
210 | .sidebar-right.collapsed ~ .sidebar-map .ol-attribution,
211 | .sidebar-right.collapsed ~ .sidebar-map .ol-full-screen {
212 | margin-right: 52px; } }
213 |
--------------------------------------------------------------------------------
/static/css/ol3-sidebar.min.css:
--------------------------------------------------------------------------------
1 | .sidebar{position:absolute;top:0;bottom:0;width:100%;overflow:hidden;z-index:2000}.sidebar.collapsed{width:40px}@media (min-width:768px) and (max-width:991px){.sidebar{width:305px}.sidebar-pane{min-width:265px}}@media (min-width:992px) and (max-width:1199px){.sidebar{width:390px}}@media (min-width:1200px){.sidebar{width:460px}}.sidebar-left{left:0;border-right:3px solid transparent}.sidebar-right{right:0;border-left:3px solid transparent}@media (min-width:768px){.sidebar{top:6px;bottom:6px;transition:width .5s;border:3px solid transparent;border-radius:4px}.sidebar-left{left:6px}.sidebar-right{right:6px}}.sidebar-tabs{top:0;bottom:0;height:100%;background-color:rgba(0,60,136,.5)}.sidebar-left .sidebar-tabs{left:0}.sidebar-right .sidebar-tabs{right:0}.sidebar-tabs,.sidebar-tabs>ul{position:absolute;width:40px;margin:0;padding:0;list-style-type:none}.sidebar-tabs>li,.sidebar-tabs>ul>li{width:100%;height:40px;color:#fff;font-size:12pt;overflow:hidden;transition:80ms}.sidebar-tabs>li:hover,.sidebar-tabs>ul>li:hover{color:#fff;background-color:rgba(0,60,136,.6)}.sidebar-tabs>li.active,.sidebar-tabs>ul>li.active{color:#fff;background-color:#0074d9}.sidebar-tabs>li.disabled,.sidebar-tabs>ul>li.disabled{color:rgba(255,255,255,.4)}.sidebar-tabs>li.disabled:hover,.sidebar-tabs>ul>li.disabled:hover{background:0 0}.sidebar-tabs>li.disabled>a,.sidebar-tabs>ul>li.disabled>a{cursor:default}.sidebar-tabs>li>a,.sidebar-tabs>ul>li>a{display:block;width:100%;height:100%;line-height:40px;color:inherit;text-decoration:none;text-align:center}.sidebar-tabs>ul+ul{bottom:0}.sidebar-content{position:absolute;top:0;bottom:0;background-color:rgba(255,255,255,.95);overflow-x:hidden;overflow-y:auto}.sidebar-left .sidebar-content{left:40px;right:0}.sidebar-right .sidebar-content{left:0;right:40px}.sidebar.collapsed>.sidebar-content{overflow-y:hidden}.sidebar-pane{display:none;left:0;right:0;box-sizing:border-box;padding:10px 20px}.sidebar-pane.active{display:block}.sidebar-header{margin:-10px -20px 0;height:40px;padding:0 20px;line-height:40px;font-size:14.4pt;color:#fff;background-color:#0074d9}.sidebar-right .sidebar-header{padding-left:40px}.sidebar-close{position:absolute;top:0;width:40px;height:40px;text-align:center;cursor:pointer}.sidebar-left .sidebar-close{right:0}.sidebar-right .sidebar-close{left:0}.sidebar{background-color:rgba(255,255,255,.4)}.sidebar-tabs{overflow:hidden}.sidebar-left~.sidebar-map .ol-scale-line,.sidebar-left~.sidebar-map .ol-zoom{margin-left:46px}.sidebar-right~.sidebar-map .ol-attribution,.sidebar-right~.sidebar-map .ol-full-screen,.sidebar-right~.sidebar-map .ol-rotate{margin-right:46px}@media (min-width:768px) and (max-width:991px){.sidebar-left~.sidebar-map .ol-scale-line,.sidebar-left~.sidebar-map .ol-zoom{margin-left:317px}.sidebar-right~.sidebar-map .ol-attribution,.sidebar-right~.sidebar-map .ol-full-screen,.sidebar-right~.sidebar-map .ol-rotate{margin-right:317px}}@media (min-width:992px) and (max-width:1199px){.sidebar-pane{min-width:350px}.sidebar-left~.sidebar-map .ol-scale-line,.sidebar-left~.sidebar-map .ol-zoom{margin-left:402px}.sidebar-right~.sidebar-map .ol-attribution,.sidebar-right~.sidebar-map .ol-full-screen,.sidebar-right~.sidebar-map .ol-rotate{margin-right:402px}}@media (min-width:1200px){.sidebar-pane{min-width:420px}.sidebar-left~.sidebar-map .ol-scale-line,.sidebar-left~.sidebar-map .ol-zoom{margin-left:472px}.sidebar-right~.sidebar-map .ol-attribution,.sidebar-right~.sidebar-map .ol-full-screen,.sidebar-right~.sidebar-map .ol-rotate{margin-right:472px}}@media (min-width:768px){.sidebar-tabs{border-radius:2px 0 0 2px}.collapsed .sidebar-tabs{border-radius:2px}.sidebar-content{border-radius:0 2px 2px 0}.sidebar-left~.sidebar-map .ol-scale-line,.sidebar-left~.sidebar-map .ol-zoom{transition:margin-left .5s}.sidebar-left.collapsed~.sidebar-map .ol-scale-line,.sidebar-left.collapsed~.sidebar-map .ol-zoom{margin-left:52px}.sidebar-right~.sidebar-map .ol-attribution,.sidebar-right~.sidebar-map .ol-full-screen,.sidebar-right~.sidebar-map .ol-rotate{transition:margin-right .5s}.sidebar-right.collapsed~.sidebar-map .ol-attribution,.sidebar-right.collapsed~.sidebar-map .ol-full-screen,.sidebar-right.collapsed~.sidebar-map .ol-rotate{margin-right:52px}}
--------------------------------------------------------------------------------
/static/js/main.js:
--------------------------------------------------------------------------------
1 | var origin = "http://0.0.0.0"
2 | var port = "80"
3 |
4 | // raster layer (OSM)
5 | var raster = new ol.layer.Tile({
6 | title:"OSM basemap",
7 | source: new ol.source.OSM(),
8 | })
9 |
10 | // vector layer (bbox)
11 | var source = new ol.source.Vector({wrapX: false});
12 | var vector = new ol.layer.Vector({
13 | title:"geometry",
14 | source: source,
15 | });
16 |
17 | // Map Creator
18 | function CreateMap(layers) {
19 | var map = new ol.Map({
20 | target: 'map',
21 | layers: layers,
22 | view: new ol.View({
23 | center: ol.proj.transform([34.09, -17.87], 'EPSG:4326', 'EPSG:3857'),
24 | zoom: 8
25 | })
26 | });
27 | return map
28 | }
29 |
30 | var map = CreateMap(layers=[raster, vector]);
31 |
32 | // Add sidebar
33 | var sidebar = new ol.control.Sidebar({ element: 'sidebar', position: 'left' });
34 | map.addControl(sidebar);
35 |
36 | // Draw a box
37 | var draw; // global so we can remove it later
38 | function addInteraction() {
39 | draw = new ol.interaction.Draw({
40 | source: source,
41 | type: "Circle",
42 | geometryFunction: ol.interaction.Draw.createBox()
43 | });
44 |
45 | // Add vector draw layer to the main map
46 | map.addInteraction(draw);
47 | }
48 |
49 | // Handle change event.
50 | document.getElementById('undo').addEventListener('click', function () {
51 | map.getLayers().getArray().forEach(layer => {
52 | if (layer.values_.title == "Flood Area" | layer.values_.title == "After Flood" | layer.values_.title == "Before Flood"){
53 | map.removeLayer(layer)
54 | }
55 | });
56 |
57 | map.getLayers().getArray().forEach(layer => {
58 | if (layer.values_.title == "Flood Area" | layer.values_.title == "After Flood" | layer.values_.title == "Before Flood"){
59 | map.removeLayer(layer)
60 | }
61 | });
62 |
63 | var features = source.getFeatures();
64 | var lastFeature = features[features.length - 1];
65 | source.removeFeature(lastFeature);
66 | });
67 |
68 | // Handle change event.
69 | document.getElementById('download').addEventListener('click', function () {
70 |
71 | document.getElementById('download').value = '...'
72 |
73 | // Obtain ROI
74 | var features = source.getFeatures();
75 | var lastFeature = features[features.length - 1].clone();
76 | var bbox = lastFeature.getGeometry().transform('EPSG:3857', 'EPSG:4326').getExtent().toString();
77 |
78 | // Obtain Dates
79 | var init_start = document.getElementById("init_start").value;
80 | var init_last = document.getElementById("init_last").value;
81 |
82 | var flood_start = document.getElementById("flood_start").value;
83 | var flood_last = document.getElementById("flood_last").value;
84 |
85 | // Obtain threshold
86 | var flood_threshold = document.getElementById("threshold").value;
87 |
88 | const request = new Request(
89 | origin.concat(":").concat(port).concat("/flood_download/"),
90 | {
91 | method: 'POST',
92 | body: JSON.stringify(
93 | {
94 | bbox: bbox,
95 | init_start: init_start,
96 | init_last: init_last,
97 | flood_start: flood_start,
98 | flood_last: flood_last,
99 | flood_threshold: flood_threshold
100 | }
101 | )
102 | }
103 | );
104 |
105 | fetch(request)
106 | .then(response => {
107 | if (response.status === 200) {
108 | return response.json();
109 | } else {
110 | throw new Error('Something went wrong on api server!');
111 | }
112 | })
113 | .then(response => {
114 | document.location.href = origin.concat(":").concat(port).concat("/").concat(response);
115 | document.getElementById('download').value = 'download'
116 | }).catch(error => {
117 | console.error(error);
118 | });
119 | });
120 |
121 | // Handle change event.
122 | document.getElementById('display').addEventListener('click', function () {
123 |
124 | document.getElementById('display').value = '...'
125 |
126 | // Obtain ROI
127 | var features = source.getFeatures();
128 | var lastFeature = features[features.length - 1].clone();
129 | var bbox = lastFeature.getGeometry().transform('EPSG:3857', 'EPSG:4326').getExtent().toString();
130 |
131 | // Obtain Dates
132 | var init_start = document.getElementById("init_start").value;
133 | var init_last = document.getElementById("init_last").value;
134 |
135 | var flood_start = document.getElementById("flood_start").value;
136 | var flood_last = document.getElementById("flood_last").value;
137 |
138 | // Obtain threshold
139 | var flood_threshold = document.getElementById("threshold").value;
140 |
141 | const request = new Request(
142 | origin.concat(":").concat(port).concat("/flood_display/"),
143 | {
144 | method: 'POST',
145 | body: JSON.stringify(
146 | {
147 | bbox: bbox,
148 | init_start: init_start,
149 | init_last: init_last,
150 | flood_start: flood_start,
151 | flood_last: flood_last,
152 | flood_threshold: flood_threshold
153 | }
154 | )
155 | }
156 | );
157 |
158 | fetch(request)
159 | .then(response => {
160 | if (response.status === 200) {
161 | return response.json();
162 | } else {
163 | throw new Error('Something went wrong on api server!');
164 | }
165 | })
166 | .then(response => {
167 | // Before Flood
168 | bflood = new ol.layer.Tile({
169 | source: new ol.source.XYZ({
170 | url: response["before_flood"]
171 | }),
172 | title: "Before Flood"
173 | });
174 | // After Flood
175 | aflood = new ol.layer.Tile({
176 | source: new ol.source.XYZ({
177 | url: response["after_flood"]
178 | }),
179 | title: "After Flood",
180 | });
181 |
182 | // Flood Area
183 | final = new ol.layer.Tile({
184 | source: new ol.source.XYZ({
185 | url: response["s1_fresults_id"]
186 | }),
187 | title: "Flood Area"
188 | });
189 |
190 | map.addLayer(final);
191 | map.addLayer(aflood);
192 | map.addLayer(bflood);
193 |
194 | var layerSwitcher = new ol.control.LayerSwitcher();
195 | map.addControl(layerSwitcher);
196 | document.getElementById('display').value = 'display'
197 |
198 | }).catch(error => {
199 | console.error(error);
200 | });
201 | });
202 |
203 | addInteraction()
--------------------------------------------------------------------------------
/static/js/ol3-sidebar.js:
--------------------------------------------------------------------------------
1 | /* global ol */
2 |
3 | ol.control.Sidebar = function (settings) {
4 |
5 | var defaults = {
6 | element: null,
7 | position: 'left'
8 | }, i, child;
9 |
10 | this._options = Object.assign({}, defaults, settings);
11 |
12 | ol.control.Control.call(this, {
13 | element: document.getElementById(this._options.element),
14 | target: this._options.target
15 | });
16 |
17 | // Attach .sidebar-left/right class
18 | this.element.classList.add('sidebar-' + this._options.position);
19 |
20 | // Find sidebar > div.sidebar-content
21 | for (i = this.element.children.length - 1; i >= 0; i--) {
22 | child = this.element.children[i];
23 | if (child.tagName === 'DIV' &&
24 | child.classList.contains('sidebar-content')) {
25 | this._container = child;
26 | }
27 | }
28 |
29 | // Find sidebar ul.sidebar-tabs > li, sidebar .sidebar-tabs > ul > li
30 | this._tabitems = this.element.querySelectorAll('ul.sidebar-tabs > li, .sidebar-tabs > ul > li');
31 | for (i = this._tabitems.length - 1; i >= 0; i--) {
32 | this._tabitems[i]._sidebar = this;
33 | }
34 |
35 | // Find sidebar > div.sidebar-content > div.sidebar-pane
36 | this._panes = [];
37 | this._closeButtons = [];
38 | for (i = this._container.children.length - 1; i >= 0; i--) {
39 | child = this._container.children[i];
40 | if (child.tagName == 'DIV' &&
41 | child.classList.contains('sidebar-pane')) {
42 | this._panes.push(child);
43 |
44 | var closeButtons = child.querySelectorAll('.sidebar-close');
45 | for (var j = 0, len = closeButtons.length; j < len; j++) {
46 | this._closeButtons.push(closeButtons[j]);
47 | }
48 | }
49 | }
50 | };
51 |
52 | if ('inherits' in ol) {
53 | ol.inherits(ol.control.Sidebar, ol.control.Control);
54 | } else {
55 | ol.control.Sidebar.prototype = Object.create(ol.control.Control.prototype);
56 | ol.control.Sidebar.prototype.constructor = ol.control.Sidebar;
57 | }
58 |
59 | ol.control.Sidebar.prototype.setMap = function(map) {
60 | var i, child;
61 |
62 | for (i = this._tabitems.length - 1; i >= 0; i--) {
63 | child = this._tabitems[i];
64 | var sub = child.querySelector('a');
65 | if (sub.hasAttribute('href') && sub.getAttribute('href').slice(0,1) == '#') {
66 | sub.onclick = this._onClick.bind(child);
67 | }
68 | }
69 |
70 | for (i = this._closeButtons.length - 1; i >= 0; i--) {
71 | child = this._closeButtons[i];
72 | child.onclick = this._onCloseClick.bind(this);
73 | }
74 | };
75 |
76 | ol.control.Sidebar.prototype.open = function(id) {
77 | var i, child;
78 |
79 | // hide old active contents and show new content
80 | for (i = this._panes.length - 1; i >= 0; i--) {
81 | child = this._panes[i];
82 | if (child.id == id)
83 | child.classList.add('active');
84 | else if (child.classList.contains('active'))
85 | child.classList.remove('active');
86 | }
87 |
88 | // remove old active highlights and set new highlight
89 | for (i = this._tabitems.length - 1; i >= 0; i--) {
90 | child = this._tabitems[i];
91 | if (child.querySelector('a').hash == '#' + id)
92 | child.classList.add('active');
93 | else if (child.classList.contains('active'))
94 | child.classList.remove('active');
95 | }
96 |
97 | // open sidebar (if necessary)
98 | if (this.element.classList.contains('collapsed')) {
99 | this.element.classList.remove('collapsed');
100 | }
101 |
102 | return this;
103 | };
104 |
105 | ol.control.Sidebar.prototype.close = function() {
106 | // remove old active highlights
107 | for (var i = this._tabitems.length - 1; i >= 0; i--) {
108 | var child = this._tabitems[i];
109 | if (child.classList.contains('active'))
110 | child.classList.remove('active');
111 | }
112 |
113 | // close sidebar
114 | if (!this.element.classList.contains('collapsed')) {
115 | this.element.classList.add('collapsed');
116 | }
117 |
118 | return this;
119 | };
120 |
121 | ol.control.Sidebar.prototype._onClick = function(evt) {
122 | evt.preventDefault();
123 | if (this.classList.contains('active')) {
124 | this._sidebar.close();
125 | } else if (!this.classList.contains('disabled')) {
126 | this._sidebar.open(this.querySelector('a').hash.slice(1));
127 | }
128 | };
129 |
130 | ol.control.Sidebar.prototype._onCloseClick = function() {
131 | this.close();
132 | };
133 |
--------------------------------------------------------------------------------
/static/js/ol3-sidebar.min.js:
--------------------------------------------------------------------------------
1 | ol.control.Sidebar=function(t){var e,s;for(this._options=Object.assign({},{element:null,position:"left"},t),ol.control.Control.call(this,{element:document.getElementById(this._options.element),target:this._options.target}),this.element.classList.add("sidebar-"+this._options.position),e=this.element.children.length-1;e>=0;e--)"DIV"===(s=this.element.children[e]).tagName&&s.classList.contains("sidebar-content")&&(this._container=s);for(this._tabitems=this.element.querySelectorAll("ul.sidebar-tabs > li, .sidebar-tabs > ul > li"),e=this._tabitems.length-1;e>=0;e--)this._tabitems[e]._sidebar=this;for(this._panes=[],this._closeButtons=[],e=this._container.children.length-1;e>=0;e--)if("DIV"==(s=this._container.children[e]).tagName&&s.classList.contains("sidebar-pane")){this._panes.push(s);for(var i=s.querySelectorAll(".sidebar-close"),o=0,l=i.length;o=0;e--){var i=(s=this._tabitems[e]).querySelector("a");i.hasAttribute("href")&&"#"==i.getAttribute("href").slice(0,1)&&(i.onclick=this._onClick.bind(s))}for(e=this._closeButtons.length-1;e>=0;e--)(s=this._closeButtons[e]).onclick=this._onCloseClick.bind(this)},ol.control.Sidebar.prototype.open=function(t){var e,s;for(e=this._panes.length-1;e>=0;e--)(s=this._panes[e]).id==t?s.classList.add("active"):s.classList.contains("active")&&s.classList.remove("active");for(e=this._tabitems.length-1;e>=0;e--)(s=this._tabitems[e]).querySelector("a").hash=="#"+t?s.classList.add("active"):s.classList.contains("active")&&s.classList.remove("active");return this.element.classList.contains("collapsed")&&this.element.classList.remove("collapsed"),this},ol.control.Sidebar.prototype.close=function(){for(var t=this._tabitems.length-1;t>=0;t--){var e=this._tabitems[t];e.classList.contains("active")&&e.classList.remove("active")}return this.element.classList.contains("collapsed")||this.element.classList.add("collapsed"),this},ol.control.Sidebar.prototype._onClick=function(t){t.preventDefault(),this.classList.contains("active")?this._sidebar.close():this.classList.contains("disabled")||this._sidebar.open(this.querySelector("a").hash.slice(1))},ol.control.Sidebar.prototype._onCloseClick=function(){this.close()};
--------------------------------------------------------------------------------
/template/map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Flood Detection System
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
30 |
31 |
32 |
33 |
87 |
88 |
89 |
90 |
91 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------