Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

extract_smoke_points.py 3.5 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  1. #!/usr/bin/env python
  2. import os
  3. import click
  4. from pathlib import Path
  5. import json
  6. import numpy as np
  7. from tqdm import tqdm
  8. import shapefile as shp
  9. from zipfile import ZipFile
  10. from datetime import datetime as dt
  11. from shapely.geometry import Polygon, Point
  12. # Quiet warnings about incorrect polygon orientation
  13. shp.VERBOSE = False
  14. SMOKE_EXT = '.zip'
  15. DENSITY_ORDERING = (
  16. 'None',
  17. 'NA',
  18. 'Light',
  19. 'Medium',
  20. 'Heavy',
  21. )
  22. def read_polygons(shapefile):
  23. basename = os.path.splitext(os.path.basename(shapefile))[0]
  24. date = dt.strptime(basename, 'hms_smoke%Y%m%d')
  25. polygons = []
  26. with ZipFile(shapefile, 'r') as zfile:
  27. with zfile.open(basename + '.shp') as sfile:
  28. with zfile.open(basename + '.dbf') as dfile:
  29. with zfile.open(basename + '.shx') as xfile:
  30. reader = shp.Reader(shp=sfile, shx=xfile, dbf=dfile)
  31. for poly in reader.shapeRecords():
  32. info = poly.__geo_interface__
  33. density = info['properties']['Density']
  34. if density not in DENSITY_ORDERING:
  35. print(f'Warning: unknown density {density}')
  36. assert info['geometry']['type'] == 'Polygon'
  37. coords = info['geometry']['coordinates']
  38. assert len(coords) == 1
  39. polygons.append((Polygon(coords[0]), density))
  40. return date, polygons
  41. def load_smoke_points(smokepointsfile):
  42. with open(smokepointsfile, 'r') as f:
  43. data = json.load(f)
  44. get = lambda f: np.array([d[f] for d in data])
  45. names = get('name')
  46. latitudes = get('latitude')
  47. longitudes = get('longitude')
  48. points = [Point(lon, lat) for lon, lat in zip(longitudes, latitudes)]
  49. return names, latitudes, longitudes, points
  50. def get_densities(points, polygons):
  51. densities = []
  52. for point in points:
  53. density_idx = 0
  54. for polygon, density in polygons:
  55. if polygon.contains(point):
  56. didx = DENSITY_ORDERING.index(density)
  57. if didx > density_idx:
  58. density_idx = didx
  59. densities.append(density_idx)
  60. return densities
  61. @click.command()
  62. @click.argument('smokedir', type=click.Path(
  63. path_type=Path, exists=True
  64. ))
  65. @click.argument('smokepoints', type=click.Path(
  66. path_type=Path, exists=True
  67. ))
  68. @click.argument('outputfile', type=click.Path(
  69. path_type=Path
  70. ))
  71. def main(smokedir, smokepoints, outputfile):
  72. names, lats, lons, points = load_smoke_points(smokepoints)
  73. smoke_files = []
  74. for d, dirs, files in os.walk(smokedir):
  75. for f in files:
  76. if f.endswith(SMOKE_EXT):
  77. smoke_files.append(os.path.join(d, f))
  78. dates = []
  79. densities = []
  80. for sm in tqdm(sorted(smoke_files), 'Reading polygons'):
  81. try:
  82. date, polygons = read_polygons(sm)
  83. except IndexError as e:
  84. print(f'Warning: error parsing {sm}')
  85. continue
  86. dates.append(date)
  87. densities.append(get_densities(points, polygons))
  88. dates = np.array(dates, dtype='datetime64[D]')
  89. densities = np.array(densities, dtype=int)
  90. result = {
  91. 'names': names,
  92. 'latitudes': lats,
  93. 'longitudes': lons,
  94. 'dates': dates,
  95. 'densities': densities,
  96. 'density_categories': np.array(DENSITY_ORDERING),
  97. }
  98. np.savez_compressed(outputfile, **result)
  99. if __name__ == '__main__':
  100. main()
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...