Giter VIP home page Giter VIP logo

dem-stitcher's Introduction

dem-stitcher

PyPI license PyPI pyversions PyPI version Conda version Conda platforms

This tool provides a raster of a Digital Elevation Model (DEM) over an area of interest utilizing global or continental, publicly available tile sets such as the Global Copernicus Digital Elevation Model at 30 meter resolution. See the Datasets section below for all the tiles supported and their shortnames. This tool also performs some standard transformations for processing such as:

  • the conversion of the vertical datum from a reference geoid to the WGS84 ellipsoidal
  • the accounting of a coordinate reference system centered at either the upper-left corner (Area tag) or center of the pixel (Point tag).

We rely on the GIS formats from rasterio. The API can be summarized as

from dem_stitcher import stitch_dem

# as xmin, ymin, xmax, ymax in epsg:4326
bounds = [-119.085, 33.402, -118.984, 35.435]

X, p = stitch_dem(bounds,
                  dem_name='glo_30',  # Global Copernicus 30 meter resolution DEM
                  dst_ellipsoidal_height=False,
                  dst_area_or_point='Point')
# X is an m x n numpy array
# p is a dictionary (or a rasterio profile) including relevant GIS metadata; CRS is epsg:4326

Then, to save the DEM raster to disk:

import rasterio

with rasterio.open('dem.tif', 'w', **p) as ds:
   ds.write(X, 1)
   ds.update_tags(AREA_OR_POINT='Point')

The rasters are returned in the global lat/lon projection epsg:4326 and the API assumes that bounds are supplied in this format.

Installation

In order to easily manage dependencies, we recommend using dedicated project environments via Anaconda/Miniconda. or Python virtual environments.

dem_stitcher can be installed into a conda environment with

conda install -c conda-forge dem_stitcher

or into a virtual environment with

python -m pip install dem_stitcher

Currently, python 3.9+ is supported.

With ISCE2 or gdal

Although the thrust of using this package is for staging DEMs for InSAR (particularly ISCE2), testing and maintaining suitable environments to use with InSAR processors is beyond the scope of what we are attempting to accomplish here. We provide an example notebook here that demonstrates how to stage a DEM for ISCE2, which requires additional packages than required for the package on its own. For the notebook, we use the environment found in environment.yml of the Dockerized TopsApp repository, used to generate interferograms (GUNWs) in the cloud.

About the raster metadata

The creation metadata unrelated to georeferencing (e.g. the compress key or various other options here) returned in the dictionary profile from the stitch_dem API is copied directly from the source tiles being used if they are GeoTiff formatted (such as glo_30) else the creation metadata are copied from the GeoTiff Default Profile in rasterio (see here excluding nodata and dtype). Such metadata creation options are beyond the scope of this library.

Credentials

The accessing of NASADEM and SRTM require earthdata login credentials to be put into the ~/.netrc file. If these are not present, the stitcher will fail with BadZipFile Error as we use requests to obtain zipped data and load the data using rasterio. An entry in the .netrc will look like:

machine urs.earthdata.nasa.gov
    login <username>
    password <password>

Notebooks

We have notebooks to demonstrate common usage:

We also demonstrate how the tiles used to organize the urls for the DEMs were generated for this tool were generated in this notebook.

DEMs Supported

The DEMs that are currently supported are:

In [1]: from dem_stitcher.datasets import DATASETS; DATASETS
Out[1]: ['srtm_v3', 'nasadem', 'glo_90_missing', 'glo_30', '3dep', 'glo_90']

The shortnames aboves are the strings required to use stitch_dem. Below, we expound upon these DEM shortnames and link to their respective data repositories.

  1. glo_30/glo_90: Copernicus GLO-30/GLO-90 DEM. The tile sets are the 30 and 90 meter resolution, respectively [link].
  2. The USGS DEM 3dep: 3Dep 1/3 arc-second over North America - we are storing the ~10 meter resolution dataset. There are many more as noted here. The files for these DEMs are here
  3. srtm_v3: SRTM v3 [link]
  4. nasadem: Nasadem [link]
  5. glo_90_missing: these are tiles that are in glo_90 but not in glo_30. They are over the countries Armenia and Azerbaijan. Used internally to help fill in gaps in coverage of glo_30.

All the tiles are given in lat/lon CRS (i.e. epsg:4326 for global tiles or epsg:4269 for USGS tiles in North America). A notable omission to the tile sets is the Artic DEM here, which is suitable for DEMs merged at the north pole of the globe due to lat/lon distortion.

If there are issues with obtaining dem tiles from urls embedded within the geojson tiles (e.g. a 404 error as here), please see the Development section below and/or open an issue ticket.

DEM Transformations

Wherever possible, we do not resample the original DEMs unless specified by the user to do so. When extents are specified, we obtain the the minimum pixel extent within the merged tile DEMs that contain that extent. Any required resampling (e.g. updating the CRS or updating the resolution because the tiles have non-square resolution at high latitudes) is done after these required translations. We importantly note that order in which these transformations are done is crucial, i.e. first translating the DEM (to either pixel- or area-center coordinates) and then resampling is different than first resampling and then translation (as affine transformations are not commutative). Here are some notes/discussions:

  1. All DEMs are resampled to epsg:4326. Most DEMs are already in this CRS except the USGS DEMs over North America, which are in epsg:4269, whose xy projection is also lon/lat but has different vertical data. For our purposes, these two CRSs are almost identical. The nuanced differences between these CRS's is noted here.
  2. All DEM outputs will have origin and pixel spacing aligning with the original DEM tiles unless a resolution for the final product is specified, which will alter the pixel spacing.
  3. Georeferenced rasters can be tied to map coordintaes using either (a) upper-left corners of pixels or (b) the pixel centers i.e. Point and Area tags in gdal, respectively, and seen as {'AREA_OR_POINT: 'Point'}. Note that tying a pixel to the upper-left cortner (i.e. Area tag) is the default pixel reference for gdal as indicated here. Some helpful resources in reference to DEMs about this book-keeping are below.
    • SRTM v3, NASADEM, and TDX are Pixel-centered, i.e. {'AREA_OR_POINT: 'Point'}.
    • The USGS DEMs are not, i.e. {'AREA_OR_POINT: 'Area'}.
  4. Transform geoid heights to WGS84 Ellipsoidal height. This is done using the rasters here. We:
    • Adjust the geoid to pixel/area coordinates
    • resample the geoids into the DEM reference frame
    • Adjust the vertical datum
  5. All DEMs are converted to float32 and have nodata np.nan. Although this can increase data size of certain rasters (SRTM is distributed in which pixels are recorded as integers), this ensures (a) easy comparison across DEMs and (b) no side-effects of the stitcher due to dtypes and/or nodata values. There is one caveat: the user can ensure that DEM nodata pixels are set to 0 using merge_nodata_value in stitch_dem, in which case 0 is filled in where np.nan was. We note specifying this "fill value" via merge_nodata_value does not change the nodata value of output DEM dataset (i.e. nodata in the rasterio profile will remain np.nan). When transforming to ellipsoidal heights and setting 0 as merge_nodata_value, the geoid values are filled in the DEMs nodata areas; if the geoid has nodata in the bounding box, this will be the source of subsequent no data. For reference, this datatype and nodata is specified in merge_tile_datasets in merge.py. Other nodata values can be specified outside the stitcher for the application of choice (e.g. ISCE2 requires nodata to be filled as 0).

There are some notebooks that illustrate how tiles are merged by comparing the output of our stitcher with the original tiles.

As a performance note, when merging DEM tiles, we merge the needed tiles within the extent in memory and this process has an associated overhead. An alternative approach would be to download the tiles to disk and use virtual warping or utilize VRTs more effectively. Ultimately, the accuracy of the final DEM is our prime focus and these minor performance tradeoffs are sidelined.

Dateline support

We assume that the supplied bounds overlap the standard lat/lon CRS grid i.e. longitudes between -/+ 180 longitude and are within -/+ 90 latitude. If there is a single dateline crossing by the supplied bounds, then the tiles are wrapped the dateline and individually translated to a particular hemisphere dicated by the bounds provided to generate a continuous raster over the area provided. We assume a maximum of one dateline crossing in the bounds you specified (if you have multiple dateline crossings, then stitch_dem will run out of memory). Similar wrapping tiles around the North and South poles (i.e. at -/+ 90 latitude) is not supported (a different CRS is what's required) and an exception will be raised.

For Development

This is almost identical to normal installation:

  1. Clone this repo git clone https://github.com/ACCESS-Cloud-Based-InSAR/dem-stitcher.git
  2. Navigate with your terminal to the repo.
  3. Create a new environment and install requirements using conda env update --file environment.yml (or use mamba to speed the install up)
  4. Install the package from cloned repo using python -m pip install -e .

DEM Urls

If urls or readers need to be updated (they consistently do) or you want to add a new global or large DEM, then there are two points of contact:

  1. The notebooks that format the geojsons used for this library are here
  2. The readers are here

The former is the more likely. When re-generating tiles, make sure to run all tests including integration tests (i.e. pytest tests). For example, if regenerating glo tiles, glo-30 requires both resolution parameters (30 meters and 90 meters) and an additional notebook for filling in missing 30 meter tiles. These should be clearly spelled out in the notebook linked above.

Testing

For the test suite:

  1. Install pytest via conda-forge
  2. Run pytest tests

There are two category of tests: unit tests and integration tests. The former can be run using pytest tests -m 'not integration' and similarly the latter with pytest tests -m 'integration'. Our unit tests are those marked without the integration tag (via pytest) that use synthetic data or data within the library to verify correct outputs of the library (e.g. that a small input raster is modified correctly). Integration tests ensure the dem-stitcher API works as expected, downloading the DEM tiles from their respective servers to ensure the stitcher runs to completion - the integration tests only make very basic checks to ensure the format of the ouptut data is correct (e.g. checking the output raster has a particular shape or that nodata is np.nan). Our integration tests also include tests that run the notebooks that serve as documentation via papermill (such tests have an additional tag notebook). Integration tests will require the ~/.netrc setup above and working internet. Our testing workflow via Github actions currently runs the entire test suite except those tagged with notebook, as these tests take considerably longer to run.

Contributing

We welcome contributions to this open-source package. To do so:

  1. Create an GitHub issue ticket desrcribing what changes you need (e.g. issue-1)
  2. Fork this repo
  3. Make your modifications in your own fork
  4. Make a pull-request (PR) in this repo with the code in your fork and tag the repo owner or a relevant contributor.

We use flake8 and associated linting packages to ensure some basic code quality (see the environment.yml). These will be checked for each commit in a PR. Try to write tests wherever possible.

Support

  1. Create an GitHub issue ticket desrcribing what changes you would like to see or to report a bug.
  2. We will work on solving this issue (hopefully with you).

Acknowledgements

This tool was developed to support cloud SAR processing using ISCE2 and various research projects at JPL. The early work of this repository was done by Charlie Marshak, David Bekaert, Michael Denbina, and Marc Simard. Since the utilization of this package for GUNW generation (see this repo), a subset of the ACCESS team, including Joseph (Joe) H. Kennedy, Simran Sangha, Grace Bato, Andrew Johnston, and Charlie Marshak, have improved this repository greatly. In particular, Joe Kennedy has lead the inclusion/development of actions, tests, packaging, distribution (including PyPI and conda-forge) and all the things to make this package more reliable, accessible, readable, etc. Simran Sangha has helped make sure output rasters are compatible with ISCE2 and other important bug-fixes.

dem-stitcher's People

Contributors

cmarshak avatar dependabot[bot] avatar jhkennedy avatar sssangha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

dem-stitcher's Issues

Resampling and Profile Translations are Non-commutative and related Errors

The bug

Simple demonstration of bug:

If we specify extents contained entirely within a DEM tile and require no transformations (e.g. do not remove geoid and keep pixel center or area center coordinate system of the original tiles), we want dem-stitcher to return a subset of that tile that contains the extent. This is not the case. We will post a notebook to demonstrate this issue is resolved as well as an integration test.

In original version, we (well, the error was mine) used rasterio.merge (link) with the bounds keyword argument. I believed this function to be obtaining a window around the bound extents; however, as the rasterio source code reveals, there is resampling that is done to ensure that the extents fit nicely into the CRS, which may be beneficial in many, if not most, GIS applications.

More precisely, to go from Pixel center to Area center coordinates, we need to translate the original rasters and then perform any necessary resampling. If resampling is done before a translation of the geo-transform, then things go wrong (majorly).

Further, the window operations were also resampling under the hood. All these issues need to be fixed.

In a general sense, if we have two affine transformations T_r and T_t representing "resampling" and "translation" resepectively, then T_r * T_t is not the same as T_t * T_r (it's worth checking this on simple examples i.e. seeing that both the geo-transform/affine transformaion and the resulting rasters are different).

This was further complicated when we wanted to change the resolution at higher latitudes because glo-30 shrinks latitude spacing as documented here. Thus, more resampling was done.

Which order is correct? We will take the approach T_r * T_t i.e.:

  1. First translating profiles (if required) on raw data
  2. Resampling (if required) at the end of all transformations.

To Reproduce

To be filled in later.

Additional context

The issue #31 points out is due the fact this resampling is done so a shift was selected based on investigating sites. However, this is not a totally correct approach.

Work to be done

We need tests to make sure that the above bug is removed.

Missing glo-30 DEM tiles over Azerbaijan, Armenia

The bug

Glo-30 tiles have missing tiles over said areas. There are downstream implications related to removing topographic phase for GUNWs.

A reference to some of the missing tiles: https://twitter.com/EricFielding/status/1531639815610830848

Country identifier | GeoCell ID
Armenia | N38E046
Armenia | N39E044
Armenia | N39E045
Armenia | N39E046
Armenia | N40E043
Armenia | N40E044
Armenia | N40E045
Armenia | N41E043
Armenia | N41E044
Armenia | N41E045
Azerbaijan | N38E046
Azerbaijan | N39E045
Azerbaijan | N39E046
Azerbaijan | N39E047
Azerbaijan | N40E045
Azerbaijan | N40E046
Azerbaijan | N40E047
Azerbaijan | N38E045
Azerbaijan | N38E046
Azerbaijan | N38E048
Azerbaijan | N38E049
Azerbaijan | N39E044
Azerbaijan | N39E045
Azerbaijan | N39E046
Azerbaijan | N39E047
Azerbaijan | N39E048
Azerbaijan | N39E049
Azerbaijan | N40E044
Azerbaijan | N40E045
Azerbaijan | N40E046
Azerbaijan | N40E047
Azerbaijan | N40E048
Azerbaijan | N40E049
Azerbaijan | N40E050
Azerbaijan | N41E044
Azerbaijan | N41E045
Azerbaijan | N41E046
Azerbaijan | N41E047
Azerbaijan | N41E048
Azerbaijan | N41E049

To Reproduce

Check this package data file and verify above tiles doe not exist

Additional context

Downstream topographic phase removal - see Issue #67

Access NASADEM Water Body layer (SWB)

Hi!

First of all, thanks for the great package. I was wondering if there is a simple way to access the water bodies layer of the NASADEM-HGT product. It is listed here as the third layer. I assume your stitch_dem function always returns the first layer only?

In the merge_and_transform_dem_tiles function there are two calls where you set:

dem_arr = dem_arr[0, ...]

I assume this is where you drop all but the first layer (i.e. all but the DEM layer)?

I hope the question is somewhat clear; please let me know if not.

Best,
Konstantin

Add Python 3.10 Back

Background

Some issues with gdal version 3.4 were noted here. Appears 3.5+ solves those issues.

Describe the solution you'd like

Pytest passes

Alternatives

N/A

Additional context

Want to have 3.10 via conda-forge

Left, bottom boundaries of the DEM are getting rounded to an integer

The bug

While the right/top boundaries are exactly as specified, the left/bottm (western/southern) boundaries seem to get rounded.

To Reproduce

(following the README)

import rasterio
bounds = [176.678207, 50.908962, 179.697601, 52.754662]
X, p = dem_stitcher.stitch_dem(bounds, dem_name='glo_30')
with rasterio.open('dem.tif', 'w', **p) as ds:
    ds.write(X2, 1)
    ds.update_tags(AREA_OR_POINT='Point')
$ rio bounds --bbox dem.tif
[177.0, 51.0, 179.69791666666666, 52.75472222222222]

Additional context

In [36]: rio.show_versions()
rasterio info:
  rasterio: 1.3.8
      GDAL: 3.7.1
      PROJ: 9.2.1
      GEOS: 3.12.0
 PROJ DATA: /Users/staniewi/miniconda3/envs/dem-env/share/proj
 GDAL DATA: /Users/staniewi/miniconda3/envs/dem-env/share/gdal

System:
    python: 3.11.5 | packaged by conda-forge | (main, Aug 27 2023, 03:33:12) [Clang 15.0.7 ]
executable: /Users/staniewi/miniconda3/envs/dem-env/bin/python3.11
   machine: macOS-13.5.1-arm64-arm-64bit

Python deps:
    affine: 2.4.0
     attrs: 23.1.0
   certifi: 2023.07.22
     click: 8.1.7
     cligj: 0.7.2
    cython: None
     numpy: 1.25.2
    snuggs: 1.4.7
click-plugins: None
setuptools: 68.1.2

edge problem? I'm getting vertical of zero pixels at tile edge here

I want to use the glo30 DEM with ISCE. I basically use the notebook here, 'staging for isce2', but with a boundary [-74, 41,-70, 44].
The result is a vertical line of 0 valued pixels (~1 pixel wide) going across the stitched tile at about the -72.00000 coordinate through the entire region. This results in a problem with ISCE2 processing. Here is a picture:

bug

Install via Conda-Forge

Background

Install via conda-forge to ensure environment restrictions and more reliable for DockerizedTopsApp.

Describe the solution you'd like

In readme, conda install -c conda-forge dem_stitcher

Alternatives

Not applicable

Additional context

environment.yml will provide better restrictions on installation.

Anti-meridian

The bug

At the antimeridian line, there is no "unwrapping" of the tiles and therefore only longitudes -180 to 180 are included.

To Reproduce

bounds = [-180.25, 51.25, -179.75, 51.75]
X, p = stitch_dem(bounds,
                               dem_name='glo_30')

Additional context

The above should yield the same as

bounds = [179.75, 51.25, 180.25, 51.75]
X, p = stitch_dem(bounds,
                               dem_name='glo_30')

Removal of `2021` from AWS Glo Registry

The bug

The example on the github homepage does not work due to removal of 2021 prefix in glo-30 aws bucket.

To Reproduce

bounds = [-119.085, 33.402, -118.984, 35.435]
X, p = stitch_dem(bounds,
                  dem_name='glo_30',
                  dst_ellipsoidal_height=False,
                  dst_area_or_point='Point')
---------------------------------------------------------------------------
CPLE_HttpResponseError                    Traceback (most recent call last)
File rasterio/_base.pyx:261, in rasterio._base.DatasetBase.__init__()

File rasterio/_shim.pyx:78, in rasterio._shim.open_dataset()

File rasterio/_err.pyx:216, in rasterio._err.exc_wrap_pointer()

CPLE_HttpResponseError: HTTP response code: 404

During handling of the above exception, another exception occurred:

RasterioIOError                           Traceback (most recent call last)
Input In [22], in <cell line: 2>()
      1 bounds = [-119.085, 33.402, -118.984, 35.435]
----> 2 X, p = stitch_dem(bounds,
      3                   dem_name='glo_30',
      4                   dst_ellipsoidal_height=False,
      5                   dst_area_or_point='Point')

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/site-packages/dem_stitcher/stitcher.py:304, in stitch_dem(bounds, dem_name, dst_ellipsoidal_height, dst_area_or_point, dst_resolution, n_threads_reproj, n_threads_downloading, driver, fill_in_glo_30)
    302     return RASTER_READERS[dem_name](url)
    303 with ThreadPoolExecutor(max_workers=n_threads_downloading) as executor:
--> 304     results = list(tqdm(executor.map(reader, urls),
    305                         total=len(urls),
    306                         desc=f'Reading {dem_name} Datasets'))
    308 # If datasets are non-existent, returns None
    309 datasets = list(filter(lambda x: x is not None, results))

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/site-packages/tqdm/std.py:1195, in tqdm.__iter__(self)
   1192 time = self._time
   1194 try:
-> 1195     for obj in iterable:
   1196         yield obj
   1197         # Update and possibly print the progressbar.
   1198         # Note: does not call self.update(1) for speed optimisation.

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/concurrent/futures/_base.py:609, in Executor.map.<locals>.result_iterator()
    606 while fs:
    607     # Careful not to keep a reference to the popped future
    608     if timeout is None:
--> 609         yield fs.pop().result()
    610     else:
    611         yield fs.pop().result(end_time - time.monotonic())

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/concurrent/futures/_base.py:446, in Future.result(self, timeout)
    444     raise CancelledError()
    445 elif self._state == FINISHED:
--> 446     return self.__get_result()
    447 else:
    448     raise TimeoutError()

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/concurrent/futures/_base.py:391, in Future.__get_result(self)
    389 if self._exception:
    390     try:
--> 391         raise self._exception
    392     finally:
    393         # Break a reference cycle with the exception in self._exception
    394         self = None

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/concurrent/futures/thread.py:58, in _WorkItem.run(self)
     55     return
     57 try:
---> 58     result = self.fn(*self.args, **self.kwargs)
     59 except BaseException as exc:
     60     self.future.set_exception(exc)

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/site-packages/dem_stitcher/stitcher.py:302, in stitch_dem.<locals>.reader(url)
    301 def reader(url):
--> 302     return RASTER_READERS[dem_name](url)

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/site-packages/dem_stitcher/dem_readers.py:12, in read_dem(dem_path)
     11 def read_dem(dem_path: str) -> rasterio.DatasetReader:
---> 12     ds = rasterio.open(dem_path)
     13     return ds

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/site-packages/rasterio/env.py:437, in ensure_env_with_credentials.<locals>.wrapper(*args, **kwds)
    434     session = DummySession()
    436 with env_ctor(session=session):
--> 437     return f(*args, **kwds)

File ~/opt/anaconda3/envs/dem-stitcher/lib/python3.9/site-packages/rasterio/__init__.py:220, in open(fp, mode, driver, width, height, count, crs, transform, dtype, nodata, sharing, **kwargs)
    216 # Create dataset instances and pass the given env, which will
    217 # be taken over by the dataset's context manager if it is not
    218 # None.
    219 if mode == 'r':
--> 220     s = DatasetReader(path, driver=driver, sharing=sharing, **kwargs)
    221 elif mode == "r+":
    222     s = get_writer_for_path(path, driver=driver)(
    223         path, mode, driver=driver, sharing=sharing, **kwargs
    224     )

File rasterio/_base.pyx:263, in rasterio._base.DatasetBase.__init__()

RasterioIOError: HTTP response code: 404

BadZipFile: File is not a zip file

The bug

/usr/local/lib/python3.10/dist-packages/dem_stitcher/stitcher.py:138: UserWarning: We need to localize the tiles as a Geotiff. Saving to tmp_f08d402f-9a1f-4ccc-907c-c35741d781ab
  warn(f"We need to localize the tiles as a Geotiff. Saving to {str(tile_dir)}", category=UserWarning)
Downloading srtm_v3 tiles:   0%|          | 0/2 [00:00<?, ?it/s]
---------------------------------------------------------------------------
BadZipFile                                Traceback (most recent call last)
[<ipython-input-22-1ebc4ae49366>](https://localhost:8080/#) in <cell line: 26>()
     24 area_or_point = 'Point'
     25 
---> 26 X, p = stitch_dem(bounds_tif, 
     27                   dem_name = 'srtm_v3',  # srtm_v3, nasadem
     28                   dst_ellipsoidal_height = ellipsoidal_height,

14 frames
[/usr/lib/python3.10/zipfile.py](https://localhost:8080/#) in _RealGetContents(self)
   1334             raise BadZipFile("File is not a zip file")
   1335         if not endrec:
-> 1336             raise BadZipFile("File is not a zip file")
   1337         if self.debug > 1:
   1338             print(endrec)

BadZipFile: File is not a zip file

To Reproduce

from dem_stitcher import stitch_dem
from dem_stitcher.datasets import DATASETS
from geopy.geocoders import Nominatim

geolocator = Nominatim(user_agent = "Chrome")

location = geolocator.geocode('rome, italy')

latitude = location.latitude
longitude = location.longitude

factor_lat = 0.2
factor_lon = 0.2

min_lat = float("{:.1f}".format(latitude - factor_lat) )
max_lat = float("{:.1f}".format(latitude + factor_lat) )
min_lon = float("{:.1f}".format(longitude - factor_lon) )
max_lon = float("{:.1f}".format(longitude + factor_lon) )

# as xmin, ymin, xmax, ymax in epsg:4326
bounds_tif = [min_lon, min_lat, max_lon, max_lat]
ellipsoidal_height = False
area_or_point = 'Point'

X, p = stitch_dem(bounds_tif, 
                  dem_name = 'srtm_v3',  # srtm_v3, nasadem
                  dst_ellipsoidal_height = ellipsoidal_height,
                  dst_area_or_point = area_or_point)

Additional context

error only occurs when use dem_name :
srtm_v3
and
nasadem

best regards

Update ISCE2 Ingest and Clarification of how to stage DEMs

Do not want to include ISCE2 as requirement here.

Will clarify how to stage DEMs for ISCE2 including using fixImageXML.py from ISCE2 as done here.

Basically, make sure:

  1. driver is ISCE
  2. Tagged with ellipsoidal heights
  3. Run the paths in the XML metadata file.

Reading tile imagery take long time in wsl (windows subsidiary linux tested os : ubuntu and debian)

The bug

Reading tile imagery take long time in wsl (windows subsidiary linux tested os : ubuntu and debian)
host os : win 11
ram : 8 gb

Opening glo_30 Datasets: 100%|██████████| 1/1 [00:02<00:00,  2.18s/it]
Reading tile metadata: 100%|██████████| 1/1 [00:00<00:00, 664.71it/s]
Reading tile imagery:   0%|          | 0/1 [00:00<?, ?it/s]

To Reproduce

1 create virtual environment,
2 install dem-stitcher on virtual environment created above
3 use the code from pypi

from dem_stitcher import stitch_dem

# as xmin, ymin, xmax, ymax in epsg:4326
bounds = [-119.085, 33.402, -118.984, 35.435]

X, p = stitch_dem(bounds,
                  dem_name='glo_30',  # Global Copernicus 30 meter resolution DEM
                  dst_ellipsoidal_height=False,
                  dst_area_or_point='Point')

4 save is app.py
5 execute python app.py

Additional context

the same code took from pypi
run well in google colab

steps for additional context
1 install dem-stitcher
2 use code from pypi above
3 execute the code

best regards

pip install for Python <=3.7 is v. 0.0.1

Platform:
Mac OS Big Sur, 11.6.4 (20G417) AND google Colab
Python v. 3.7

"pip install dem-stitcher"
Output:
Successfully installed dem-stitcher-0.0.1

It seems only 0.0.1 gets installed with Python <=3.7. Can you make this and/or a prior version compatible with at least Python=3? This is quite useful for Google Colab in particular, which only runs python 3.7.

Pixel shift when dst_area_or_point == 'Point'

Hi,

Here is a slice of code in the stitcher.py:

    if dst_area_or_point == 'Point' and src_area_or_point == 'Area':
        x_shift = 1
        y_shift = 1
        array_shifted, profile_shifted = gdal_translate_profile(filepath, x_shift, y_shift)
    elif (dst_area_or_point == 'Area') and (src_area_or_point == 'Point'):
        shift = .5
        array_shifted, profile_shifted = gdal_translate_profile(filepath, shift, shift)
    # half shift down if glo30
    elif (dst_area_or_point == 'Point') and (src_area_or_point == 'Point'):
        x_shift = 1
        y_shift = 1
        array_shifted, profile_shifted = gdal_translate_profile(filepath, x_shift, y_shift)

I notice that x_shift and y_shift always equal to 1 if dst_area_or_point == 'Point' and no matter what src_area_or_point is. This looks a little strange to me. Is it a typo? If there is some reason behind it, I will appreciate it if you let me know.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.