1
1
import argparse
2
2
import os
3
- import sys
4
- from importlib import import_module
3
+ from pathlib import Path
5
4
6
- named_libs = [('fiona' , 'fiona' ), ('geopandas' , 'gpd' ), ('pandas' , 'pd' )]
7
-
8
- for (name , short ) in named_libs :
9
- try :
10
- lib = import_module (name )
11
- except :
12
- print (sys .exc_info ())
13
- else :
14
- globals ()[short ] = lib
5
+ try :
6
+ import fiona
7
+ import geopandas as gpd
8
+ import pandas as pd
9
+ except ImportError :
10
+ print ("ERROR: fiona, geopandas, and pandas are required for this script." )
11
+ raise
15
12
16
13
from osgeo import osr
17
14
from shapely .geometry import Polygon
@@ -25,34 +22,27 @@ def command_line_parser():
25
22
'''
26
23
Command line parser
27
24
'''
28
- parser = argparse .ArgumentParser (description = """
29
- Create a burst map for a single slc""" ,
30
- formatter_class = argparse .ArgumentDefaultsHelpFormatter )
31
- parser .add_argument ('-s' , '--slc' , type = str , action = 'store' ,
32
- dest = 'slc' ,
33
- help = "slc to map" )
34
- parser .add_argument ('-d' , '--orbit-dir' , type = str , dest = 'orbit_dir' ,
35
- help = "Directory containing orbit files" )
25
+ parser = argparse .ArgumentParser (
26
+ description = "Create a burst map for a single slc" ,
27
+ formatter_class = argparse .ArgumentDefaultsHelpFormatter
28
+ )
29
+ parser .add_argument ('-s' , '--slc' , help = "Sentinel-1 product to load." )
30
+ parser .add_argument ('-d' , '--orbit-dir' , help = "Directory containing orbit files" )
36
31
parser .add_argument ('-x' , '--x-spacing' , type = float , default = 5 ,
37
- dest = 'x_spacing' ,
38
32
help = 'Spacing of the geogrid in x direction' )
39
33
parser .add_argument ('-y' , '--y-spacing' , type = float , default = 10 ,
40
- dest = 'y_spacing' ,
41
34
help = 'Spacing of the geogrid in y direction' )
42
- parser .add_argument ('-e' , '--epsg' , type = int , dest = 'epsg' ,
43
- help = 'EPSG for output coordinates' )
44
- parser .add_argument ('-o' , '--output' , type = str , default = 'burst_map.gpkg' ,
45
- dest = 'output' ,
35
+ parser .add_argument ('-e' , '--epsg' , type = int , help = 'EPSG for output coordinates' )
36
+ parser .add_argument ('-o' , '--output' , default = 'burst_map.gpkg' , dest = 'output' ,
46
37
help = 'Base filename for all output burst map products' )
47
38
return parser .parse_args ()
48
39
49
40
50
- def burst_map (slc , orbit_dir , x_spacing ,
51
- y_spacing , epsg ,
52
- output_filename ):
53
- """
54
- Create a CSV of SLC metadata and plot bursts
55
- Parameters:
41
+ def burst_map (slc , orbit_dir , x_spacing , y_spacing , epsg , output_filename ):
42
+ """Create a CSV of SLC metadata and plot bursts.
43
+
44
+ Parameters
45
+ ----------
56
46
slc: str
57
47
Path to SLC file
58
48
orbit_dir: str
@@ -65,11 +55,11 @@ def burst_map(slc, orbit_dir, x_spacing,
65
55
EPSG code for the output coodrdinates
66
56
output_filename: str
67
57
Filename used for the output CSV, shp, html, and kml files
68
-
69
- Returns:
58
+
59
+ Returns
60
+ -------
70
61
output_filename.csv, output_filename.shp, output_filename.html, output_filename.kml
71
62
"""
72
-
73
63
# Initialize dictionary that will contain all the info for geocoding
74
64
burst_map = {'burst_id' :[], 'length' : [], 'width' : [],
75
65
'spacing_x' : [], 'spacing_y' :[], 'min_x' : [],
@@ -78,7 +68,7 @@ def burst_map(slc, orbit_dir, x_spacing,
78
68
'border' :[]}
79
69
i_subswath = [1 , 2 , 3 ]
80
70
pol = 'vv'
81
- orbit_path = get_orbit_file_from_dir (slc , orbit_dir )
71
+ orbit_path = get_orbit_file_from_dir (slc , orbit_dir ) if orbit_dir else None
82
72
83
73
for subswath in i_subswath :
84
74
ref_bursts = load_bursts (slc , orbit_path , subswath , pol )
@@ -93,6 +83,8 @@ def burst_map(slc, orbit_dir, x_spacing,
93
83
burst_map ['first_valid_sample' ].append (burst .first_valid_sample )
94
84
burst_map ['last_valid_sample' ].append (burst .last_valid_sample )
95
85
86
+ # TODO: this will ignore the other border for bursts on the antimeridian.
87
+ # Should probably turn into a MultiPolygon
96
88
poly = burst .border [0 ]
97
89
# Give some margin to the polygon
98
90
margin = 0.001
@@ -113,6 +105,7 @@ def burst_map(slc, orbit_dir, x_spacing,
113
105
tgt_x .append (dummy_x )
114
106
tgt_y .append (dummy_y )
115
107
108
+ # TODO: Get the min/max from the burst database
116
109
if epsg == 4326 :
117
110
x_min = x_spacing * (min (tgt_x ) / x_spacing )
118
111
y_min = y_spacing * (min (tgt_y ) / y_spacing )
@@ -130,28 +123,29 @@ def burst_map(slc, orbit_dir, x_spacing,
130
123
burst_map ['max_x' ].append (x_max )
131
124
burst_map ['max_y' ].append (y_max )
132
125
126
+ out_path = Path (output_filename )
127
+
133
128
# Save generated burst map as csv
134
129
data = pd .DataFrame .from_dict (burst_map )
135
- data .to_csv (f' { output_filename } .csv' )
130
+ data .to_csv (out_path . with_suffix ( ' .csv') )
136
131
137
132
# Create GeoDataFrame to plot bursts on a map
138
133
df = data
139
134
df ['border' ] = df ['border' ].apply (wkt .loads )
140
- gdf = gpd .GeoDataFrame (df , crs = 'epsg:4326' )
141
- gdf = gdf . rename ( columns = { 'border' : 'geometry' }). set_geometry ( 'geometry' )
142
-
135
+ gdf = gpd .GeoDataFrame (df . rename ( columns = { 'border' : 'geometry' }) , crs = 'epsg:4326' )
136
+
137
+ gdf . to_file ( out_path . with_suffix ( '.gpkg' ), driver = 'GPKG' )
143
138
# Save the GeoDataFrame as a shapefile (some people may prefer the format)
144
- gdf .to_file (f' { output_filename } .shp' )
145
-
139
+ gdf .to_file (out_path . with_suffix ( ' .shp') )
140
+
146
141
# Save the GeoDataFrame as a kml
147
- kml_path = f' { output_filename } .kml'
148
- if os . path . isfile ( kml_path ):
149
- os . remove ( kml_path )
150
-
142
+ kml_path = out_path . with_suffix ( ' .kml')
143
+ if kml_path . exists ( ):
144
+ kml_path . unlink ( )
145
+
151
146
fiona .supported_drivers ['KML' ] = 'rw'
152
- gdf .to_file (f'{ output_filename } .kml' , driver = 'KML' )
153
-
154
-
147
+ gdf .to_file (kml_path , driver = 'KML' )
148
+
155
149
# Plot bursts on an interactive map
156
150
m = gdf .explore (
157
151
column = "burst_id" , # make choropleth based on "Burst ID" column
@@ -162,8 +156,8 @@ def burst_map(slc, orbit_dir, x_spacing,
162
156
style_kwds = dict (color = "black" ) # use black outline
163
157
)
164
158
165
- m .save (f' { output_filename } .html' )
166
-
159
+ m .save (out_path . with_suffix ( ' .html') )
160
+
167
161
168
162
if __name__ == '__main__' :
169
163
cmd = command_line_parser ()
0 commit comments