|
33 | 33 | "\n", |
34 | 34 | "This notebook converts normal GeoTIFFs into cloud optimized-GeoTIFFs (COGs) compatible with Google Maps Platform APIs and the Ground data collection platform Android app.\n", |
35 | 35 | "\n", |
36 | | - "We've affectionally dubbed these Maps-optimized COGs as \"MOGs\" for convenience and brevity. See [README.md](https://github.com/google/ground-android/blob/master/ground/src/main/java/com/google/android/ground/ui/map/gms/mog/README.md) in Android implementation for details.\n", |
| 36 | + "We've affectionately dubbed these Maps-optimized COGs as \"MOGs\" for convenience and brevity. See [README.md](https://github.com/google/ground-android/blob/master/ground/src/main/java/com/google/android/ground/ui/map/gms/mog/README.md) in Android implementation for details.\n", |
37 | 37 | "\n", |
38 | 38 | "Be sure [Generate Ground offline imagery](https://colab.research.google.com/github/google/ground-platform/blob/master/notebooks/generate_offline_imagery1.ipynb) has been run and Earth Engine tasks have completed before running this notebook.\n", |
39 | 39 | "\n", |
40 | | - "By default, only new input images will be converted. GeoTIFF which already have a correspondign MOG will be skipped unless `OVERWRITE_EXISTING` is set `True`." |
| 40 | + "By default, only new input images will be converted. GeoTIFFs which already have a corresponding MOG will be skipped unless `OVERWRITE_EXISTING` is set `True`." |
41 | 41 | ], |
42 | 42 | "metadata": { |
43 | 43 | "id": "MN0yiT1u74PH" |
|
64 | 64 | { |
65 | 65 | "cell_type": "code", |
66 | 66 | "source": [ |
67 | | - "SRC_BUCKET_NAME=input('ID of bucket containing raw GeoTIFFs : ')\n", |
| 67 | + "SRC_BUCKET_NAME=input('ID of bucket containing raw GeoTIFFs: ')\n", |
68 | 68 | "\n", |
69 | | - "DEST_BUCKET_NAME=input('ID of bucket project where processed imagery is to be written: ')" |
| 69 | + "DEST_BUCKET_NAME=input('ID of bucket where processed imagery is to be written: ')" |
70 | 70 | ], |
71 | 71 | "metadata": { |
72 | 72 | "id": "wqIeqxMEI5-3" |
|
79 | 79 | "source": [ |
80 | 80 | "### Custom paths\n", |
81 | 81 | "\n", |
82 | | - "The can be adjusted as needed." |
| 82 | + "These can be adjusted as needed." |
83 | 83 | ], |
84 | 84 | "metadata": { |
85 | 85 | "id": "lTpntWE-JxHs" |
|
88 | 88 | { |
89 | 89 | "cell_type": "code", |
90 | 90 | "source": [ |
91 | | - "SRC_PATH=\"raw-imagery/s2/2022\"\n", |
92 | | - "DEST_PATH=\"offline-imagery/default\"" |
| 91 | + "SRC_PATH = \"raw-imagery/s2/2022\"\n", |
| 92 | + "DEST_PATH = \"offline-imagery/default\"" |
93 | 93 | ], |
94 | 94 | "metadata": { |
95 | 95 | "id": "O4yVrj-6JrBM" |
|
113 | 113 | "source": [ |
114 | 114 | "from math import pi\n", |
115 | 115 | "\n", |
116 | | - "HI_RES_MOG_MIN_ZOOM=8\n", |
117 | | - "HI_RES_MOG_MAX_ZOOM=14\n", |
118 | | - "TILE_SIZE=256\n", |
119 | | - "NODATA_VALUE=0\n", |
120 | | - "OVERVIEW_FILENAME=\"overview.tif\"\n", |
121 | | - "OVERWRITE_EXISTING=False\n", |
122 | | - "\n", |
123 | | - "SRC_PREFIX=f\"{SRC_PATH}/{HI_RES_MOG_MIN_ZOOM}\"\n", |
124 | | - "OVERVIEW_TIFF_PATH=f\"{SRC_PREFIX}/{OVERVIEW_FILENAME}\"\n", |
125 | | - "DEST_PREFIX=f\"{DEST_PATH}/{HI_RES_MOG_MIN_ZOOM}\"\n", |
126 | | - "OVERVIEW_COG_PATH=f\"{DEST_PREFIX}/{OVERVIEW_FILENAME}\"\n", |
127 | | - "\n", |
128 | | - "# Constants\n", |
129 | | - "TMP_FILENAME=\"temp.tif\"\n", |
130 | | - "GCS_BROWSER_BASE_URL=\"https://console.cloud.google.com/storage/browser\"\n", |
131 | | - "GCS_DETAILS_BASE_URL=\"https://console.cloud.google.com/storage/browser/_details\"\n", |
| 116 | + "HI_RES_MOG_MIN_ZOOM = 8\n", |
| 117 | + "HI_RES_MOG_MAX_ZOOM = 14\n", |
| 118 | + "TILE_SIZE = 256\n", |
| 119 | + "NODATA_VALUE = 0\n", |
| 120 | + "OVERVIEW_FILENAME = \"overview.tif\"\n", |
| 121 | + "OVERWRITE_EXISTING = False\n", |
| 122 | + "\n", |
| 123 | + "SRC_PREFIX = f\"{SRC_PATH}/{HI_RES_MOG_MIN_ZOOM}\"\n", |
| 124 | + "OVERVIEW_TIFF_PATH = f\"{SRC_PREFIX}/{OVERVIEW_FILENAME}\"\n", |
| 125 | + "DEST_PREFIX = f\"{DEST_PATH}/{HI_RES_MOG_MIN_ZOOM}\"\n", |
| 126 | + "OVERVIEW_COG_PATH = f\"{DEST_PREFIX}/{OVERVIEW_FILENAME}\"\n", |
| 127 | + "\n", |
| 128 | + "TMP_FILENAME = \"temp.tif\"\n", |
| 129 | + "GCS_BROWSER_BASE_URL = \"https://console.cloud.google.com/storage/browser\"\n", |
| 130 | + "GCS_DETAILS_BASE_URL = \"https://console.cloud.google.com/storage/browser/_details\"\n", |
132 | 131 | "EPSG_3857_MAX = pi * 6378137\n", |
133 | | - "EPSG_3857_WORLD_BOUNDS=(-EPSG_3857_MAX, -EPSG_3857_MAX, EPSG_3857_MAX, EPSG_3857_MAX)" |
| 132 | + "EPSG_3857_WORLD_BOUNDS = (-EPSG_3857_MAX, -EPSG_3857_MAX, EPSG_3857_MAX, EPSG_3857_MAX)" |
134 | 133 | ], |
135 | 134 | "metadata": { |
136 | 135 | "id": "FFNaHNCUJpBE" |
|
205 | 204 | "import rasterio\n", |
206 | 205 | "from rasterio.transform import from_origin\n", |
207 | 206 | "from rasterio.enums import Resampling\n", |
208 | | - "from rasterio.windows import from_bounds\n", |
209 | 207 | "from osgeo import gdal # https://gdal.org/api/python/osgeo.gdal.html\n", |
210 | 208 | "import os\n", |
211 | 209 | "from rasterio.plot import show\n", |
212 | 210 | "import matplotlib.pyplot as plt\n", |
213 | 211 | "import numpy as np\n", |
214 | | - "import re\n", |
215 | 212 | "import tempfile\n", |
216 | 213 | "\n", |
217 | 214 | "storage_client = storage.Client()\n", |
|
246 | 243 | "cell_type": "code", |
247 | 244 | "source": [ |
248 | 245 | "def show_size(path):\n", |
249 | | - " file_stats=os.stat(path)\n", |
| 246 | + " file_stats = os.stat(path)\n", |
250 | 247 | " print(f'{path}: {file_stats.st_size / (1024 * 1024):.2f} MB')\n", |
251 | 248 | "\n", |
252 | 249 | "def show_thumbnail(src_path):\n", |
|
261 | 258 | " gdal.UseExceptions()\n", |
262 | 259 | "\n", |
263 | 260 | " # Open the input raster\n", |
264 | | - " src=gdal.Open(src_path)\n", |
| 261 | + " src = gdal.Open(src_path)\n", |
265 | 262 | "\n", |
266 | | - " # Open the output raster\n", |
267 | | - " ds=gdal.Translate(\n", |
| 263 | + " # Create the output raster\n", |
| 264 | + " ds = gdal.Translate(\n", |
268 | 265 | " destName=TMP_FILENAME,\n", |
269 | 266 | " srcDS=src,\n", |
270 | 267 | " format=\"COG\",\n", |
|
280 | 277 | "\n", |
281 | 278 | " # Close the output raster to flush buffer.\n", |
282 | 279 | " ds = None\n", |
283 | | - " tmp_ds = None\n", |
| 280 | + " src = None\n", |
284 | 281 | "\n", |
285 | 282 | " file_size = os.stat(TMP_FILENAME).st_size / (1024 * 1024)\n", |
286 | 283 | " print(f\"Uploading {file_size:.1f} MB to {dst_path}\")\n", |
|
313 | 310 | "print(f\"Output: https://console.cloud.google.com/storage/browser/{DEST_BUCKET_NAME}/{DEST_PREFIX}\")\n", |
314 | 311 | "\n", |
315 | 312 | "for subpath in src_paths:\n", |
316 | | - " src_path=f\"/vsigs_streaming/{SRC_BUCKET_NAME}/{subpath}\"\n", |
317 | | - " dst_path=DEST_PREFIX + subpath[len(SRC_PREFIX):]\n", |
| 313 | + " src_path = f\"/vsigs_streaming/{SRC_BUCKET_NAME}/{subpath}\"\n", |
| 314 | + " dst_path = DEST_PREFIX + subpath[len(SRC_PREFIX):]\n", |
318 | 315 | " blob = storage.Blob(dst_path, dest_bucket)\n", |
319 | 316 | " if (not OVERWRITE_EXISTING and blob.exists(storage_client)):\n", |
320 | 317 | " print(f\"{dst_path} exists, skipping.\")\n", |
|
0 commit comments