Dynamically access Wayback imagery
Browse files- app.py +41 -1
- sandbox.ipynb +376 -2
app.py
CHANGED
@@ -15,6 +15,7 @@ import plotly.express as px
|
|
15 |
import branca.colormap as cm
|
16 |
|
17 |
from functions import *
|
|
|
18 |
|
19 |
st.set_page_config(layout="wide")
|
20 |
|
@@ -146,8 +147,47 @@ buffer_geometry_gdf = (
|
|
146 |
) # reset index forces GeoSeries to GeoDataFrame
|
147 |
buffer_geometry_gdf["Name"] = "Buffer"
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
# visualize the geometry
|
150 |
-
wayback_df = pd.read_parquet("./wayback.parquet").set_index("date")
|
151 |
first_item = wayback_df.iloc[0]
|
152 |
wayback_title = "Esri " + first_item["Title"]
|
153 |
wayback_url = (
|
|
|
15 |
import branca.colormap as cm
|
16 |
|
17 |
from functions import *
|
18 |
+
import xml.etree.ElementTree as ET
|
19 |
|
20 |
st.set_page_config(layout="wide")
|
21 |
|
|
|
147 |
) # reset index forces GeoSeries to GeoDataFrame
|
148 |
buffer_geometry_gdf["Name"] = "Buffer"
|
149 |
|
150 |
+
# Get Wayback data
|
151 |
+
# <old code>
|
152 |
+
# wayback_df = pd.read_parquet("./wayback.parquet").set_index("date")
|
153 |
+
# </old code>
|
154 |
+
# <new code 2nd Feb 2025 by Zeel>
|
155 |
+
# Fetch XML data
|
156 |
+
url = "https://wayback.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/1.0.0/WMTSCapabilities.xml"
|
157 |
+
response = requests.get(url)
|
158 |
+
response.raise_for_status() # Ensure request was successful
|
159 |
+
|
160 |
+
# Parse XML
|
161 |
+
root = ET.fromstring(response.content)
|
162 |
+
|
163 |
+
ns = {
|
164 |
+
"wmts": "https://www.opengis.net/wmts/1.0",
|
165 |
+
"ows": "https://www.opengis.net/ows/1.1",
|
166 |
+
"xlink": "https://www.w3.org/1999/xlink",
|
167 |
+
}
|
168 |
+
|
169 |
+
layers = root.findall(".//wmts:Contents/wmts:Layer", ns)
|
170 |
+
|
171 |
+
layer_data = []
|
172 |
+
for layer in layers:
|
173 |
+
title = layer.find("ows:Title", ns)
|
174 |
+
identifier = layer.find("ows:Identifier", ns)
|
175 |
+
resource = layer.find("wmts:ResourceURL", ns) # Tile URL template
|
176 |
+
|
177 |
+
title_text = title.text if title is not None else "N/A"
|
178 |
+
identifier_text = identifier.text if identifier is not None else "N/A"
|
179 |
+
url_template = resource.get("template") if resource is not None else "N/A"
|
180 |
+
|
181 |
+
layer_data.append({"Title": title_text, "ResourceURL_Template": url_template})
|
182 |
+
|
183 |
+
wayback_df = pd.DataFrame(layer_data)
|
184 |
+
wayback_df["date"] = pd.to_datetime(wayback_df["Title"].str.extract(r"(\d{4}-\d{2}-\d{2})").squeeze(), errors="coerce")
|
185 |
+
wayback_df.set_index("date", inplace=True)
|
186 |
+
print(wayback_df)
|
187 |
+
|
188 |
+
# </new code 2nd Feb 2025 by Zeel>
|
189 |
+
|
190 |
# visualize the geometry
|
|
|
191 |
first_item = wayback_df.iloc[0]
|
192 |
wayback_title = "Esri " + first_item["Title"]
|
193 |
wayback_url = (
|
sandbox.ipynb
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
-
"execution_count":
|
6 |
"metadata": {},
|
7 |
"outputs": [],
|
8 |
"source": [
|
@@ -10,8 +10,250 @@
|
|
10 |
"import kml2geojson\n",
|
11 |
"import requests\n",
|
12 |
"import geopandas as gpd\n",
|
|
|
13 |
"\n",
|
14 |
-
"data = requests.get(\"https://drive.google.com/uc?id=1bN8lkSQkGZcSmZPLF8jm-AWTRA7FsEcr\")"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
]
|
16 |
},
|
17 |
{
|
@@ -169,6 +411,138 @@
|
|
169 |
"# kml2geojson.convert(BytesIO(data.content))[0]['features']"
|
170 |
]
|
171 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
{
|
173 |
"cell_type": "code",
|
174 |
"execution_count": 14,
|
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
+
"execution_count": 2,
|
6 |
"metadata": {},
|
7 |
"outputs": [],
|
8 |
"source": [
|
|
|
10 |
"import kml2geojson\n",
|
11 |
"import requests\n",
|
12 |
"import geopandas as gpd\n",
|
13 |
+
"import pandas as pd\n",
|
14 |
"\n",
|
15 |
+
"# data = requests.get(\"https://drive.google.com/uc?id=1bN8lkSQkGZcSmZPLF8jm-AWTRA7FsEcr\")"
|
16 |
+
]
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"cell_type": "code",
|
20 |
+
"execution_count": 3,
|
21 |
+
"metadata": {},
|
22 |
+
"outputs": [
|
23 |
+
{
|
24 |
+
"data": {
|
25 |
+
"text/html": [
|
26 |
+
"<div>\n",
|
27 |
+
"<style scoped>\n",
|
28 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
29 |
+
" vertical-align: middle;\n",
|
30 |
+
" }\n",
|
31 |
+
"\n",
|
32 |
+
" .dataframe tbody tr th {\n",
|
33 |
+
" vertical-align: top;\n",
|
34 |
+
" }\n",
|
35 |
+
"\n",
|
36 |
+
" .dataframe thead th {\n",
|
37 |
+
" text-align: right;\n",
|
38 |
+
" }\n",
|
39 |
+
"</style>\n",
|
40 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
41 |
+
" <thead>\n",
|
42 |
+
" <tr style=\"text-align: right;\">\n",
|
43 |
+
" <th></th>\n",
|
44 |
+
" <th>Title</th>\n",
|
45 |
+
" <th>Identifier</th>\n",
|
46 |
+
" <th>LowerCorner</th>\n",
|
47 |
+
" <th>UpperCorner</th>\n",
|
48 |
+
" <th>Format</th>\n",
|
49 |
+
" <th>TileMatrixSetLinks</th>\n",
|
50 |
+
" <th>ResourceURL_Template</th>\n",
|
51 |
+
" <th>date</th>\n",
|
52 |
+
" </tr>\n",
|
53 |
+
" </thead>\n",
|
54 |
+
" <tbody>\n",
|
55 |
+
" <tr>\n",
|
56 |
+
" <th>0</th>\n",
|
57 |
+
" <td>World Imagery (Wayback 2024-10-10)</td>\n",
|
58 |
+
" <td>WB_2024_R11</td>\n",
|
59 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
60 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
61 |
+
" <td>NaN</td>\n",
|
62 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
63 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
64 |
+
" <td>2024-10-10</td>\n",
|
65 |
+
" </tr>\n",
|
66 |
+
" <tr>\n",
|
67 |
+
" <th>1</th>\n",
|
68 |
+
" <td>World Imagery (Wayback 2024-09-19)</td>\n",
|
69 |
+
" <td>WB_2024_R10</td>\n",
|
70 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
71 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
72 |
+
" <td>NaN</td>\n",
|
73 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
74 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
75 |
+
" <td>2024-09-19</td>\n",
|
76 |
+
" </tr>\n",
|
77 |
+
" <tr>\n",
|
78 |
+
" <th>2</th>\n",
|
79 |
+
" <td>World Imagery (Wayback 2024-08-15)</td>\n",
|
80 |
+
" <td>WB_2024_R08</td>\n",
|
81 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
82 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
83 |
+
" <td>NaN</td>\n",
|
84 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
85 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
86 |
+
" <td>2024-08-15</td>\n",
|
87 |
+
" </tr>\n",
|
88 |
+
" <tr>\n",
|
89 |
+
" <th>3</th>\n",
|
90 |
+
" <td>World Imagery (Wayback 2024-06-27)</td>\n",
|
91 |
+
" <td>WB_2024_R07</td>\n",
|
92 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
93 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
94 |
+
" <td>NaN</td>\n",
|
95 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
96 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
97 |
+
" <td>2024-06-27</td>\n",
|
98 |
+
" </tr>\n",
|
99 |
+
" <tr>\n",
|
100 |
+
" <th>4</th>\n",
|
101 |
+
" <td>World Imagery (Wayback 2024-06-06)</td>\n",
|
102 |
+
" <td>WB_2024_R06</td>\n",
|
103 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
104 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
105 |
+
" <td>NaN</td>\n",
|
106 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
107 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
108 |
+
" <td>2024-06-06</td>\n",
|
109 |
+
" </tr>\n",
|
110 |
+
" <tr>\n",
|
111 |
+
" <th>...</th>\n",
|
112 |
+
" <td>...</td>\n",
|
113 |
+
" <td>...</td>\n",
|
114 |
+
" <td>...</td>\n",
|
115 |
+
" <td>...</td>\n",
|
116 |
+
" <td>...</td>\n",
|
117 |
+
" <td>...</td>\n",
|
118 |
+
" <td>...</td>\n",
|
119 |
+
" <td>...</td>\n",
|
120 |
+
" </tr>\n",
|
121 |
+
" <tr>\n",
|
122 |
+
" <th>170</th>\n",
|
123 |
+
" <td>World Imagery (Wayback 2014-06-11)</td>\n",
|
124 |
+
" <td>WB_2014_R08</td>\n",
|
125 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
126 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
127 |
+
" <td>NaN</td>\n",
|
128 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
129 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
130 |
+
" <td>2014-06-11</td>\n",
|
131 |
+
" </tr>\n",
|
132 |
+
" <tr>\n",
|
133 |
+
" <th>171</th>\n",
|
134 |
+
" <td>World Imagery (Wayback 2014-05-14)</td>\n",
|
135 |
+
" <td>WB_2014_R06</td>\n",
|
136 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
137 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
138 |
+
" <td>NaN</td>\n",
|
139 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
140 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
141 |
+
" <td>2014-05-14</td>\n",
|
142 |
+
" </tr>\n",
|
143 |
+
" <tr>\n",
|
144 |
+
" <th>172</th>\n",
|
145 |
+
" <td>World Imagery (Wayback 2014-04-30)</td>\n",
|
146 |
+
" <td>WB_2014_R05</td>\n",
|
147 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
148 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
149 |
+
" <td>NaN</td>\n",
|
150 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
151 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
152 |
+
" <td>2014-04-30</td>\n",
|
153 |
+
" </tr>\n",
|
154 |
+
" <tr>\n",
|
155 |
+
" <th>173</th>\n",
|
156 |
+
" <td>World Imagery (Wayback 2014-03-26)</td>\n",
|
157 |
+
" <td>WB_2014_R03</td>\n",
|
158 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
159 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
160 |
+
" <td>NaN</td>\n",
|
161 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
162 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
163 |
+
" <td>2014-03-26</td>\n",
|
164 |
+
" </tr>\n",
|
165 |
+
" <tr>\n",
|
166 |
+
" <th>174</th>\n",
|
167 |
+
" <td>World Imagery (Wayback 2014-02-20)</td>\n",
|
168 |
+
" <td>WB_2014_R01</td>\n",
|
169 |
+
" <td>-2.003750722959434E7 -2.003750722959434E7</td>\n",
|
170 |
+
" <td>2.003750722959434E7 2.003750722959434E7</td>\n",
|
171 |
+
" <td>NaN</td>\n",
|
172 |
+
" <td>default028mm, GoogleMapsCompatible</td>\n",
|
173 |
+
" <td>https://wayback.maptiles.arcgis.com/arcgis/res...</td>\n",
|
174 |
+
" <td>2014-02-20</td>\n",
|
175 |
+
" </tr>\n",
|
176 |
+
" </tbody>\n",
|
177 |
+
"</table>\n",
|
178 |
+
"<p>175 rows × 8 columns</p>\n",
|
179 |
+
"</div>"
|
180 |
+
],
|
181 |
+
"text/plain": [
|
182 |
+
" Title Identifier \\\n",
|
183 |
+
"0 World Imagery (Wayback 2024-10-10) WB_2024_R11 \n",
|
184 |
+
"1 World Imagery (Wayback 2024-09-19) WB_2024_R10 \n",
|
185 |
+
"2 World Imagery (Wayback 2024-08-15) WB_2024_R08 \n",
|
186 |
+
"3 World Imagery (Wayback 2024-06-27) WB_2024_R07 \n",
|
187 |
+
"4 World Imagery (Wayback 2024-06-06) WB_2024_R06 \n",
|
188 |
+
".. ... ... \n",
|
189 |
+
"170 World Imagery (Wayback 2014-06-11) WB_2014_R08 \n",
|
190 |
+
"171 World Imagery (Wayback 2014-05-14) WB_2014_R06 \n",
|
191 |
+
"172 World Imagery (Wayback 2014-04-30) WB_2014_R05 \n",
|
192 |
+
"173 World Imagery (Wayback 2014-03-26) WB_2014_R03 \n",
|
193 |
+
"174 World Imagery (Wayback 2014-02-20) WB_2014_R01 \n",
|
194 |
+
"\n",
|
195 |
+
" LowerCorner \\\n",
|
196 |
+
"0 -2.003750722959434E7 -2.003750722959434E7 \n",
|
197 |
+
"1 -2.003750722959434E7 -2.003750722959434E7 \n",
|
198 |
+
"2 -2.003750722959434E7 -2.003750722959434E7 \n",
|
199 |
+
"3 -2.003750722959434E7 -2.003750722959434E7 \n",
|
200 |
+
"4 -2.003750722959434E7 -2.003750722959434E7 \n",
|
201 |
+
".. ... \n",
|
202 |
+
"170 -2.003750722959434E7 -2.003750722959434E7 \n",
|
203 |
+
"171 -2.003750722959434E7 -2.003750722959434E7 \n",
|
204 |
+
"172 -2.003750722959434E7 -2.003750722959434E7 \n",
|
205 |
+
"173 -2.003750722959434E7 -2.003750722959434E7 \n",
|
206 |
+
"174 -2.003750722959434E7 -2.003750722959434E7 \n",
|
207 |
+
"\n",
|
208 |
+
" UpperCorner Format \\\n",
|
209 |
+
"0 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
210 |
+
"1 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
211 |
+
"2 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
212 |
+
"3 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
213 |
+
"4 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
214 |
+
".. ... ... \n",
|
215 |
+
"170 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
216 |
+
"171 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
217 |
+
"172 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
218 |
+
"173 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
219 |
+
"174 2.003750722959434E7 2.003750722959434E7 NaN \n",
|
220 |
+
"\n",
|
221 |
+
" TileMatrixSetLinks \\\n",
|
222 |
+
"0 default028mm, GoogleMapsCompatible \n",
|
223 |
+
"1 default028mm, GoogleMapsCompatible \n",
|
224 |
+
"2 default028mm, GoogleMapsCompatible \n",
|
225 |
+
"3 default028mm, GoogleMapsCompatible \n",
|
226 |
+
"4 default028mm, GoogleMapsCompatible \n",
|
227 |
+
".. ... \n",
|
228 |
+
"170 default028mm, GoogleMapsCompatible \n",
|
229 |
+
"171 default028mm, GoogleMapsCompatible \n",
|
230 |
+
"172 default028mm, GoogleMapsCompatible \n",
|
231 |
+
"173 default028mm, GoogleMapsCompatible \n",
|
232 |
+
"174 default028mm, GoogleMapsCompatible \n",
|
233 |
+
"\n",
|
234 |
+
" ResourceURL_Template date \n",
|
235 |
+
"0 https://wayback.maptiles.arcgis.com/arcgis/res... 2024-10-10 \n",
|
236 |
+
"1 https://wayback.maptiles.arcgis.com/arcgis/res... 2024-09-19 \n",
|
237 |
+
"2 https://wayback.maptiles.arcgis.com/arcgis/res... 2024-08-15 \n",
|
238 |
+
"3 https://wayback.maptiles.arcgis.com/arcgis/res... 2024-06-27 \n",
|
239 |
+
"4 https://wayback.maptiles.arcgis.com/arcgis/res... 2024-06-06 \n",
|
240 |
+
".. ... ... \n",
|
241 |
+
"170 https://wayback.maptiles.arcgis.com/arcgis/res... 2014-06-11 \n",
|
242 |
+
"171 https://wayback.maptiles.arcgis.com/arcgis/res... 2014-05-14 \n",
|
243 |
+
"172 https://wayback.maptiles.arcgis.com/arcgis/res... 2014-04-30 \n",
|
244 |
+
"173 https://wayback.maptiles.arcgis.com/arcgis/res... 2014-03-26 \n",
|
245 |
+
"174 https://wayback.maptiles.arcgis.com/arcgis/res... 2014-02-20 \n",
|
246 |
+
"\n",
|
247 |
+
"[175 rows x 8 columns]"
|
248 |
+
]
|
249 |
+
},
|
250 |
+
"execution_count": 3,
|
251 |
+
"metadata": {},
|
252 |
+
"output_type": "execute_result"
|
253 |
+
}
|
254 |
+
],
|
255 |
+
"source": [
|
256 |
+
"pd.read_parquet(\"wayback.parquet\")"
|
257 |
]
|
258 |
},
|
259 |
{
|
|
|
411 |
"# kml2geojson.convert(BytesIO(data.content))[0]['features']"
|
412 |
]
|
413 |
},
|
414 |
+
{
|
415 |
+
"cell_type": "code",
|
416 |
+
"execution_count": 24,
|
417 |
+
"metadata": {},
|
418 |
+
"outputs": [],
|
419 |
+
"source": [
|
420 |
+
"import requests\n",
|
421 |
+
"import pandas as pd\n",
|
422 |
+
"import xml.etree.ElementTree as ET\n",
|
423 |
+
"\n",
|
424 |
+
"# Fetch XML data\n",
|
425 |
+
"url = \"https://wayback.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/1.0.0/WMTSCapabilities.xml\"\n",
|
426 |
+
"response = requests.get(url)\n",
|
427 |
+
"response.raise_for_status() # Ensure request was successful\n",
|
428 |
+
"\n",
|
429 |
+
"# Parse XML\n",
|
430 |
+
"root = ET.fromstring(response.content)"
|
431 |
+
]
|
432 |
+
},
|
433 |
+
{
|
434 |
+
"cell_type": "code",
|
435 |
+
"execution_count": 25,
|
436 |
+
"metadata": {},
|
437 |
+
"outputs": [
|
438 |
+
{
|
439 |
+
"name": "stdout",
|
440 |
+
"output_type": "stream",
|
441 |
+
"text": [
|
442 |
+
"Found 178 layers\n"
|
443 |
+
]
|
444 |
+
}
|
445 |
+
],
|
446 |
+
"source": [
|
447 |
+
"ns = {\"wmts\": \"https://www.opengis.net/wmts/1.0\"}\n",
|
448 |
+
"layers = root.findall(\".//wmts:Layer\", ns)\n",
|
449 |
+
"print(f\"Found {len(layers)} layers\")"
|
450 |
+
]
|
451 |
+
},
|
452 |
+
{
|
453 |
+
"cell_type": "code",
|
454 |
+
"execution_count": 35,
|
455 |
+
"metadata": {},
|
456 |
+
"outputs": [
|
457 |
+
{
|
458 |
+
"name": "stdout",
|
459 |
+
"output_type": "stream",
|
460 |
+
"text": [
|
461 |
+
"Found 178 layers\n",
|
462 |
+
" Title \\\n",
|
463 |
+
"date \n",
|
464 |
+
"2025-01-30 World Imagery (Wayback 2025-01-30) \n",
|
465 |
+
"2024-12-12 World Imagery (Wayback 2024-12-12) \n",
|
466 |
+
"2024-11-18 World Imagery (Wayback 2024-11-18) \n",
|
467 |
+
"2024-10-10 World Imagery (Wayback 2024-10-10) \n",
|
468 |
+
"2024-09-19 World Imagery (Wayback 2024-09-19) \n",
|
469 |
+
"... ... \n",
|
470 |
+
"2014-06-11 World Imagery (Wayback 2014-06-11) \n",
|
471 |
+
"2014-05-14 World Imagery (Wayback 2014-05-14) \n",
|
472 |
+
"2014-04-30 World Imagery (Wayback 2014-04-30) \n",
|
473 |
+
"2014-03-26 World Imagery (Wayback 2014-03-26) \n",
|
474 |
+
"2014-02-20 World Imagery (Wayback 2014-02-20) \n",
|
475 |
+
"\n",
|
476 |
+
" ResourceURL_Template \n",
|
477 |
+
"date \n",
|
478 |
+
"2025-01-30 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
479 |
+
"2024-12-12 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
480 |
+
"2024-11-18 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
481 |
+
"2024-10-10 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
482 |
+
"2024-09-19 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
483 |
+
"... ... \n",
|
484 |
+
"2014-06-11 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
485 |
+
"2014-05-14 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
486 |
+
"2014-04-30 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
487 |
+
"2014-03-26 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
488 |
+
"2014-02-20 https://wayback.maptiles.arcgis.com/arcgis/res... \n",
|
489 |
+
"\n",
|
490 |
+
"[178 rows x 2 columns]\n"
|
491 |
+
]
|
492 |
+
}
|
493 |
+
],
|
494 |
+
"source": [
|
495 |
+
"ns = {\n",
|
496 |
+
" \"wmts\": \"https://www.opengis.net/wmts/1.0\",\n",
|
497 |
+
" \"ows\": \"https://www.opengis.net/ows/1.1\",\n",
|
498 |
+
" \"xlink\": \"https://www.w3.org/1999/xlink\"\n",
|
499 |
+
"}\n",
|
500 |
+
"\n",
|
501 |
+
"layers = root.findall(\".//wmts:Contents/wmts:Layer\", ns)\n",
|
502 |
+
"print(f\"Found {len(layers)} layers\")\n",
|
503 |
+
"\n",
|
504 |
+
"layer_data = []\n",
|
505 |
+
"for layer in layers:\n",
|
506 |
+
" title = layer.find(\"ows:Title\", ns)\n",
|
507 |
+
" identifier = layer.find(\"ows:Identifier\", ns)\n",
|
508 |
+
" resource = layer.find(\"wmts:ResourceURL\", ns) # Tile URL template\n",
|
509 |
+
" \n",
|
510 |
+
" title_text = title.text if title is not None else \"N/A\"\n",
|
511 |
+
" identifier_text = identifier.text if identifier is not None else \"N/A\"\n",
|
512 |
+
" url_template = resource.get(\"template\") if resource is not None else \"N/A\"\n",
|
513 |
+
"\n",
|
514 |
+
" layer_data.append({\n",
|
515 |
+
" \"Title\": title_text,\n",
|
516 |
+
" \"ResourceURL_Template\": url_template\n",
|
517 |
+
" })\n",
|
518 |
+
"\n",
|
519 |
+
"import pandas as pd\n",
|
520 |
+
"df = pd.DataFrame(layer_data)\n",
|
521 |
+
"df['date'] = pd.to_datetime(df['Title'].str.extract(r\"(\\d{4}-\\d{2}-\\d{2})\").squeeze(), errors='coerce')\n",
|
522 |
+
"df.set_index('date', inplace=True)\n",
|
523 |
+
"print(df)"
|
524 |
+
]
|
525 |
+
},
|
526 |
+
{
|
527 |
+
"cell_type": "code",
|
528 |
+
"execution_count": 32,
|
529 |
+
"metadata": {},
|
530 |
+
"outputs": [
|
531 |
+
{
|
532 |
+
"data": {
|
533 |
+
"text/plain": [
|
534 |
+
"'https://wayback.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/WMTS/1.0.0/{TileMatrixSet}/MapServer/tile/36557/{TileMatrix}/{TileRow}/{TileCol}'"
|
535 |
+
]
|
536 |
+
},
|
537 |
+
"execution_count": 32,
|
538 |
+
"metadata": {},
|
539 |
+
"output_type": "execute_result"
|
540 |
+
}
|
541 |
+
],
|
542 |
+
"source": [
|
543 |
+
"df['Tile URL'].iloc[0]"
|
544 |
+
]
|
545 |
+
},
|
546 |
{
|
547 |
"cell_type": "code",
|
548 |
"execution_count": 14,
|