Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 6.4.1 #517

Merged
merged 52 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
0c3dd98
Bump aws-actions/amazon-ecr-login from 1 to 2
dependabot[bot] Oct 3, 2023
fccf005
Merge pull request #495 from ASFHyP3/dependabot/github_actions/aws-ac…
jtherrmann Oct 26, 2023
4415430
reproject into the correct coordinate system
AndrewPlayer3 Oct 30, 2023
483a534
need libspatialindex-dev and rtree library to make the geopandas.clip…
cirrusasf Oct 31, 2023
5001bc2
modify the code style
cirrusasf Oct 31, 2023
b474ccb
Merge pull request #508 from ASFHyP3/water_mask_error_jz
AndrewPlayer3 Oct 31, 2023
83b80bd
added hyp3-isce2's water masking improvements
AndrewPlayer3 Oct 31, 2023
ce2c168
read parquet file, add needed libraries in the environmenmt file
cirrusasf Oct 31, 2023
a0029e5
added newline
AndrewPlayer3 Oct 31, 2023
0baea5a
updated changelog
AndrewPlayer3 Oct 31, 2023
e0affe1
Merge pull request #509 from ASFHyP3/water-mask-error
AndrewPlayer3 Oct 31, 2023
1dace92
add s3fs to requirements
AndrewPlayer3 Oct 31, 2023
d4b74c7
add pyarrow to requirements
AndrewPlayer3 Oct 31, 2023
8805d4a
Merge pull request #510 from ASFHyP3/water-mask-error
AndrewPlayer3 Oct 31, 2023
4d5427d
add shapely>=2.0 in the setup.py and environment.yml
cirrusasf Nov 1, 2023
7bd14d6
downgrade shapely to v 1.8.0, in order to keep its compibible to GAMM…
cirrusasf Nov 1, 2023
ca36460
remove import shapely statement in water_mask.py
cirrusasf Nov 1, 2023
0760fc0
Update hyp3_gamma/water_mask.py
cirrusasf Nov 1, 2023
fc3f59d
Merge pull request #511 from ASFHyP3/water_mask_error_jz_t2
cirrusasf Nov 1, 2023
7273723
need to add libspatialindex-dev and rtree for making the geopandas.cl…
cirrusasf Nov 1, 2023
54dad01
modify environment.yml to install rtree and pyarrow with conda
cirrusasf Nov 1, 2023
27dd145
Update environment.yml
jhkennedy Nov 2, 2023
b347024
Merge pull request #512 from ASFHyP3/water_mask_error_jz_t2
cirrusasf Nov 2, 2023
fcbf490
back to the previous way of reasding the mask with geopandas.read_fil…
cirrusasf Nov 2, 2023
7afee62
keep rtree library to make geopandas.clip works
cirrusasf Nov 2, 2023
8f65479
add geopandasa.clip() to clip mask to the extent
cirrusasf Nov 2, 2023
9fdc17d
solve the partition issue when read the parquet file and filter forma…
cirrusasf Nov 4, 2023
af06197
modify code style
cirrusasf Nov 4, 2023
9faeb97
refactoring
AndrewPlayer3 Nov 6, 2023
4bb89c7
refactoring
AndrewPlayer3 Nov 6, 2023
2ed0654
Merge pull request #514 from ASFHyP3/water_mask_error_jz_t3
cirrusasf Nov 6, 2023
171b462
fixed errors in water masking
AndrewPlayer3 Nov 6, 2023
3598496
Merge pull request #515 from ASFHyP3/water-mask-fixes
AndrewPlayer3 Nov 6, 2023
3a7b0f3
do not split the antimeridian extent, but convert it into UTM, then d…
cirrusasf Nov 7, 2023
cc8fe60
code style
cirrusasf Nov 7, 2023
80dbe28
code style
cirrusasf Nov 7, 2023
3780588
refactor code
cirrusasf Nov 7, 2023
812485d
code style
cirrusasf Nov 7, 2023
eb3d747
remove split_antimeridian function and its test function
cirrusasf Nov 7, 2023
a796cc1
Update hyp3_gamma/water_mask.py
cirrusasf Nov 7, 2023
76e35e2
use pyogrio engine to do geopandas.read_file
cirrusasf Nov 7, 2023
c493ed7
add pyogrio library in the environment.yml and setup.py
cirrusasf Nov 7, 2023
1210f3d
code style
cirrusasf Nov 7, 2023
d592504
decide use geopandas.read_file with mask equal to envelope in the inp…
cirrusasf Nov 7, 2023
5a8514a
Merge pull request #516 from ASFHyP3/water_mask_antimeridian
cirrusasf Nov 7, 2023
f24d9a4
remove unused imports
AndrewPlayer3 Nov 8, 2023
2637c55
keep rtree and delete s3fs and pyarrow in both environment.yml and s…
cirrusasf Nov 9, 2023
3be96c1
Merge pull request #518 from ASFHyP3/remove-imports
AndrewPlayer3 Nov 9, 2023
4de5927
fixed docstring
AndrewPlayer3 Nov 9, 2023
f6e8d90
Merge pull request #519 from ASFHyP3/docstring-update
AndrewPlayer3 Nov 9, 2023
4c63fb7
better changelog
AndrewPlayer3 Nov 9, 2023
cc9ff25
Merge pull request #520 from ASFHyP3/changelog-fix
AndrewPlayer3 Nov 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-and-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v1
uses: aws-actions/amazon-ecr-login@v2

- name: Fetch GAMMA
run: |
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [PEP 440](https://www.python.org/dev/peps/pep-0440/)
and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [6.4.1]

### Fixed
- Incorrect / blank water masks in some areas (primarily Europe), by clipping the water mask to the envelope of the product before rasterization.

## [6.4.0]

### Added
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies:
- numpy>=1.21,<1.22
- pillow
- python-dateutil
- rtree
# Addresses https://github.com/ASFHyP3/hyp3-gamma/issues/421
# - hyp3lib>=1.7.0,<2
# - lxml
Expand Down
67 changes: 47 additions & 20 deletions hyp3_gamma/water_mask.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
"""Create and apply a water body mask"""
import json
import subprocess
from pathlib import Path
from tempfile import TemporaryDirectory

import geopandas
import geopandas as gpd
from osgeo import gdal
from pyproj import CRS
from shapely import geometry


from hyp3_gamma.util import GDALConfigManager

gdal.UseExceptions()


def split_geometry_on_antimeridian(geometry: dict):
geometry_as_bytes = json.dumps(geometry).encode()
cmd = ['ogr2ogr', '-wrapdateline', '-datelineoffset', '20', '-f', 'GeoJSON', '/vsistdout/', '/vsistdin/']
geojson_str = subprocess.run(cmd, input=geometry_as_bytes, stdout=subprocess.PIPE, check=True).stdout
return json.loads(geojson_str)['features'][0]['geometry']
def get_envelope(input_image: str):
""" Get the envelope of the input_image

Args:
input_image: Path for the input GDAL-compatible image

Returns:
(envelope, epsg): The envelope and epsg code of the GeoTIFF.
"""
info = gdal.Info(input_image, format='json')
prj = CRS.from_wkt(info["coordinateSystem"]["wkt"])
epsg = prj.to_epsg()
extent = info['wgs84Extent']
extent_gdf = gpd.GeoDataFrame(index=[0], geometry=[geometry.shape(extent)], crs='EPSG:4326').to_crs(epsg)
return extent_gdf.envelope, epsg


def create_water_mask(input_tif: str, output_tif: str):
def create_water_mask(input_image: str, output_image: str, gdal_format='GTiff'):
"""Create a water mask GeoTIFF with the same geometry as a given input GeoTIFF

The water mask is assembled from GSHHG v2.3.7 Levels 1, 2, 3, and 5 at full resolution. To learn more, visit
Expand All @@ -28,25 +40,40 @@ def create_water_mask(input_tif: str, output_tif: str):
land in the pixel.

Args:
input_tif: Path for the input GeoTIFF
output_tif: Path for the output GeoTIFF
input_image: Path for the input GDAL-compatible image
output_image: Path for the output image
gdal_format: GDAL format name to create output image as
"""
mask_location = '/vsicurl/https://asf-dem-west.s3.amazonaws.com/WATER_MASK/GSHHG/hyp3_water_mask_20220912.shp'
src_ds = gdal.Open(input_image)

src_ds = gdal.Open(input_tif)
driver_options = []
if gdal_format == 'GTiff':
driver_options = ['COMPRESS=LZW', 'TILED=YES', 'NUM_THREADS=ALL_CPUS']

dst_ds = gdal.GetDriverByName('GTiff').Create(output_tif, src_ds.RasterXSize, src_ds.RasterYSize, 1, gdal.GDT_Byte)
dst_ds = gdal.GetDriverByName(gdal_format).Create(
output_image,
src_ds.RasterXSize,
src_ds.RasterYSize,
1,
gdal.GDT_Byte,
driver_options,
)
dst_ds.SetGeoTransform(src_ds.GetGeoTransform())
dst_ds.SetProjection(src_ds.GetProjection())
dst_ds.SetMetadataItem('AREA_OR_POINT', src_ds.GetMetadataItem('AREA_OR_POINT'))

extent = gdal.Info(input_tif, format='json')['wgs84Extent']
extent = split_geometry_on_antimeridian(extent)
envelope, epsg = get_envelope(input_image)

mask_location = '/vsicurl/https://asf-dem-west.s3.amazonaws.com/WATER_MASK/GSHHG/hyp3_water_mask_20220912.shp'

mask = gpd.read_file(mask_location, mask=envelope).to_crs(epsg)

mask = gpd.clip(mask, envelope)

mask = geopandas.read_file(mask_location, mask=extent)
with TemporaryDirectory() as temp_shapefile:
mask.to_file(temp_shapefile, driver='ESRI Shapefile')
with TemporaryDirectory() as temp_dir:
temp_file = str(Path(temp_dir) / 'mask.shp')
mask.to_file(temp_file, driver='ESRI Shapefile')
with GDALConfigManager(OGR_ENABLE_PARTIAL_REPROJECTION='YES'):
gdal.Rasterize(dst_ds, temp_shapefile, allTouched=True, burnValues=[1])
gdal.Rasterize(dst_ds, temp_file, allTouched=True, burnValues=[1])

del src_ds, dst_ds
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
'numpy>=1.21,<1.22',
'pillow',
'python-dateutil',
'rtree'
],

extras_require={
Expand Down
46 changes: 0 additions & 46 deletions tests/test_water_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,6 @@
gdal.UseExceptions()


def test_split_geometry_on_antimeridian():
geometry = {
'type': 'Polygon',
'coordinates': [[
[170, 50],
[175, 55],
[-170, 55],
[-175, 50],
[170, 50],
]],
}
result = water_mask.split_geometry_on_antimeridian(geometry)
assert result == {
'type': 'MultiPolygon',
'coordinates': [
[[
[175.0, 55.0],
[180.0, 55.0],
[180.0, 50.0],
[170.0, 50.0],
[175.0, 55.0],
]],
[[
[-170.0, 55.0],
[-175.0, 50.0],
[-180.0, 50.0],
[-180.0, 55.0],
[-170.0, 55.0],
]],
],
}

geometry = {
'type': 'Polygon',
'coordinates': [[
[150, 50],
[155, 55],
[-150, 55],
[-155, 50],
[150, 50],
]],
}
result = water_mask.split_geometry_on_antimeridian(geometry)
assert result == geometry


def test_create_water_mask_with_no_water(tmp_path, test_data_dir):
input_tif = str(test_data_dir / 'test_geotiff.tif')
output_tif = str(tmp_path / 'water_mask.tif')
Expand Down
Loading