Skip to content

Commit 71eae86

Browse files
committed
Add feature creation script
1 parent 02d4c67 commit 71eae86

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env python
2+
"""
3+
Download the BedMachine topography
4+
----------------------------------
5+
1. Go tohttps://nsidc.org/data/nsidc-0756/versions/3
6+
2. Click on "HTTPS File System"
7+
3. Log in or create and account.
8+
5. Under "1970.01.01" choose "BedMachineAntarctica-v3.nc"
9+
10+
On Anvil or Chrysalis, BedMachine Antarctica v3 is available so create a
11+
symlink with:
12+
ln -s /lcrc/group/e3sm/public_html/mpas_standalonedata/mpas-ocean/bathymetry_database/BedMachineAntarctica-v3.nc
13+
"""
14+
15+
import shutil
16+
17+
import matplotlib.pyplot as plt
18+
import numpy as np
19+
import shapely
20+
import xarray as xr
21+
from pyproj import Transformer
22+
23+
from geometric_features import GeometricFeatures, FeatureCollection
24+
from geometric_features.feature_collection import _round_coords
25+
from geometric_features.utils import write_feature_names_and_tags
26+
27+
28+
def get_longest_contour(contour_value, author):
29+
30+
def stereo_to_lon_lat(x, y):
31+
lat, lon = transformer.transform(x, y)
32+
return lon, lat
33+
34+
with xr.open_dataset('BedMachineAntarctica-v3.nc') as ds:
35+
# the bed but only in the open ocean or under floating ice
36+
bed = xr.where(np.logical_or(ds.mask == 0, ds.mask == 3),
37+
ds.bed, 0.).values
38+
x = ds.x.values
39+
y = ds.y.values
40+
41+
# plot contours
42+
plt.figure()
43+
cs = plt.contour(x, y, bed, (contour_value,))
44+
paths = cs.allsegs[0]
45+
46+
path_lengths = [len(paths[i]) for i in range(len(paths))]
47+
ilongest = np.argmax(path_lengths)
48+
49+
v = paths[ilongest]
50+
x = v[:, 0]
51+
y = v[:, 1]
52+
53+
# the starting index should be the point closest to the positive x axis
54+
mask = x > 0.
55+
indices = np.arange(y.shape[0])[mask]
56+
index = np.argmin(np.abs(y[mask]))
57+
first = indices[index]
58+
x = np.append(x[first:], x[:first])
59+
y = np.append(y[first:], y[:first])
60+
61+
# Antarctic stereographic to lat/lon
62+
transformer = Transformer.from_crs('epsg:3031', 'epsg:4326')
63+
64+
transect = shapely.geometry.LineString([(i[0], i[1]) for i in zip(x, y)])
65+
66+
# cut a tiny weged out to break the shape into 2 at the antimeridian
67+
epsilon = 1e-14
68+
minY = np.amin(y)
69+
wedge = shapely.geometry.Polygon([(epsilon, minY),
70+
(epsilon**2, -epsilon),
71+
(0, epsilon),
72+
(-epsilon**2, -epsilon),
73+
(-epsilon, minY),
74+
(epsilon, minY)])
75+
76+
difference = transect.difference(wedge)
77+
78+
transect_latlon = shapely.ops.transform(stereo_to_lon_lat, difference)
79+
80+
plt.figure()
81+
for geom in transect_latlon.geoms:
82+
x, y = geom.xy
83+
plt.plot(x, y)
84+
85+
fc = FeatureCollection()
86+
87+
geometry = shapely.geometry.mapping(transect_latlon)
88+
# get rid of the wedge again by rounding the coordinates
89+
geometry['coordinates'] = _round_coords(geometry['coordinates'])
90+
91+
fc.add_feature(
92+
{'type': 'Feature',
93+
'properties': {'name': f'Antarctic isobath at {contour_value} m',
94+
'author': author,
95+
'object': 'transect',
96+
'component': 'ocean',
97+
'tags': 'Antarctic'},
98+
'geometry': geometry})
99+
100+
return fc
101+
102+
103+
def main():
104+
xylar = 'Xylar Asay-Davis'
105+
106+
# make a geometric fieatures object that knows about the geometric data
107+
# cache up a couple of directories
108+
gf = GeometricFeatures('../../geometric_data')
109+
110+
fc = get_longest_contour(contour_value=-1000., author=xylar)
111+
112+
# "split" these features into individual files in the geometric data cache
113+
gf.split(fc)
114+
115+
# update the database of feature names and tags
116+
write_feature_names_and_tags(gf.cacheLocation)
117+
# move the resulting file into place
118+
shutil.copyfile('features_and_tags.json',
119+
'../../geometric_features/features_and_tags.json')
120+
121+
plt.show()
122+
123+
124+
if __name__ == '__main__':
125+
main()

0 commit comments

Comments
 (0)