|
| 1 | +## Case of Study - Open Aeria Map (OAM) |
1 | 2 |
|
2 | | -1. Get list of images |
| 3 | +https://map.openaerialmap.org |
3 | 4 |
|
4 | | -```bash |
5 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=1 | jq '.results[]' -c > oam.njson |
6 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=2 | jq '.results[]' -c >> oam.njson |
7 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=3 | jq '.results[]' -c >> oam.njson |
8 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=4 | jq '.results[]' -c >> oam.njson |
9 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=5 | jq '.results[]' -c >> oam.njson |
10 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=6 | jq '.results[]' -c >> oam.njson |
11 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=7 | jq '.results[]' -c >> oam.njson |
12 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=8 | jq '.results[]' -c >> oam.njson |
13 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=9 | jq '.results[]' -c >> oam.njson |
14 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=10 | jq '.results[]' -c >> oam.njson |
15 | | -curl https://api.openaerialmap.org/meta\?limit\=1000\&page\=11 | jq '.results[]' -c >> oam.njson |
16 | | -``` |
| 5 | +> OpenAerialMap (OAM) is a set of tools for searching, sharing, and using openly licensed satellite and unmanned aerial vehicle (UAV) imagery. |
17 | 6 |
|
18 | | -2. Create items |
| 7 | +Believe it or not but OAM was created more than 9 years ago!!! The design was innovative and the backend was also in advance. It was one of the first application using dynamic tiling (https://github.com/mojodna/marblecutter-openaerialmap) and STAC like metadata (https://github.com/hotosm/oam-api). |
19 | 8 |
|
20 | | -```python |
21 | | -import pystac |
22 | | -import json |
23 | | - |
24 | | -from pystac.utils import datetime_to_str, str_to_datetime |
25 | | - |
26 | | - |
27 | | -with open("oam.njson", "r") as fin: |
28 | | - with open("oam_items.njson", "w") as fout: |
29 | | - for line in fin.readlines(): |
30 | | - try: |
31 | | - itm = json.loads(line) |
32 | | - item = pystac.Item( |
33 | | - id=itm["_id"], |
34 | | - geometry=itm["geojson"], |
35 | | - bbox=itm["bbox"], |
36 | | - collection="openaerialmap", |
37 | | - stac_extensions=[], |
38 | | - datetime=None, |
39 | | - properties={ |
40 | | - "title": itm["title"], |
41 | | - "platform": itm["platform"], |
42 | | - "provider": itm["provider"], |
43 | | - "contact": itm["contact"], |
44 | | - "start_datetime": datetime_to_str(str_to_datetime(itm['acquisition_start'])), |
45 | | - "end_datetime": datetime_to_str(str_to_datetime(itm['acquisition_end'])), |
46 | | - }, |
47 | | - ) |
48 | | - |
49 | | - item.add_link( |
50 | | - pystac.Link( |
51 | | - pystac.RelType.COLLECTION, |
52 | | - "openaerialmap", |
53 | | - media_type=pystac.MediaType.JSON, |
54 | | - ) |
55 | | - ) |
56 | | - |
57 | | - item.add_asset( |
58 | | - key="image", |
59 | | - asset=pystac.Asset(href=itm["uuid"], media_type=pystac.MediaType.COG), |
60 | | - ) |
61 | | - # Here we make sure to remove any invalid character |
62 | | - fout.write(json.dumps(item.to_dict(), ensure_ascii=False).encode("ascii", "ignore").decode("utf-8").replace('\\"', "") + "\n") |
63 | | - except: |
64 | | - continue |
65 | | -``` |
66 | | - |
67 | | -Note: You may want to remove really old imagery (e.g the one from 1949) to avoid creating partition for only one image. |
68 | | - |
69 | | -3. create oam_collection.json |
70 | | -```json |
71 | | -{"id": "openaerialmap", "title": "OpenAerialMap", "description": "OpenAerialMap Dataset", "stac_version": "1.0.0", "license": "public-domain", "links": [], "extent": {"spatial": {"bbox": [[-180, -90, 180, 90]]}, "temporal": {"interval": [["1944-12-31T13:00:00.000Z", "null"]]}}} |
72 | | -``` |
73 | | - |
74 | | -Note: the json must be in form of NewLine delimited (one item/collection per line). |
75 | | - |
76 | | -4. upload collection and items to the RDS postgres instance (using pypgstac) |
77 | | - |
78 | | - |
79 | | -```bash |
80 | | -$ pypgstac load collections oam_collection.json --dsn postgresql://{db-user}:{db-password}@{db-host}:{db-port}/{db-name} --method insert |
81 | | - |
82 | | -$ pypgstac load items oam_items.njson --dsn postgresql://{db-user}:{db-password}@{db-host}:{db-port}/{db-name} --method insert |
83 | | -``` |
84 | | - |
85 | | - |
86 | | -Note: |
87 | | - |
88 | | -- You may have to add you address IP to the VPC inbounds rules to be able to connect to the RDS instance. |
89 | | -- You can find the database info in your AWS Lambda configuration (host, user, password, post) |
| 9 | +Looking at the web page and backend today, it feels still great and better than a lot of similar projects. |
0 commit comments