-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsnappy_utils.py
117 lines (101 loc) · 4.07 KB
/
snappy_utils.py
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
import numpy as np
import os
import sys
snappy_dir = os.path.join(os.path.expanduser("~"), ".snap", "snap-python")
if os.path.isdir(snappy_dir):
sys.path.append(snappy_dir)
else:
dir_path = os.path.dirname(os.path.realpath(__file__))
snappy_dir = os.path.join(dir_path, "..", "..", "..", "snap-python")
sys.path.append(snappy_dir)
from snappy import ProductIO, Product, ProductData, ProductUtils, String
def read_snappy_product(file_path, band_name=None):
prod = ProductIO.readProduct(file_path)
width = prod.getSceneRasterWidth()
height = prod.getSceneRasterHeight()
geo_coding = prod.getSceneGeoCoding()
data = np.empty((height, width))
if band_name is not None:
band = prod.getBand(band_name)
else:
band = prod.getBandAt(0)
try:
band.readPixels(0, 0, width, height, data)
except AttributeError:
prod.closeIO()
raise RuntimeError(file_path + " does not contain band " + band_name)
prod.closeIO()
return data, geo_coding
def write_snappy_product(file_path, bands, product_name, geo_coding):
try:
(height, width) = bands[0]['band_data'].shape
except AttributeError:
raise RuntimeError(bands[0]['band_name'] + "contains no data.")
product = Product(product_name, product_name, width, height)
product.setSceneGeoCoding(geo_coding)
# Ensure that output is saved in BEAM-DIMAP format, otherwise writeHeader does not work.
file_path = os.path.splitext(file_path)[0] + '.dim'
# Bands have to be created before header is written but header has to be written before band
# data is written.
for b in bands:
band = product.addBand(b['band_name'], ProductData.TYPE_FLOAT32)
if 'description' in b.keys():
band.setDescription(b['description'])
if 'unit' in b.keys():
band.setUnit(b['unit'])
product.setProductWriter(ProductIO.getProductWriter('BEAM-DIMAP'))
product.writeHeader(String(file_path))
for b in bands:
band = product.getBand(b['band_name'])
band.writePixels(0, 0, width, height, b['band_data'].astype(np.float32))
product.closeIO()
def copy_bands_to_file(src_file_path, dst_file_path, bands=None):
# Get info from source product
src_prod = ProductIO.readProduct(src_file_path)
prod_name = src_prod.getName()
prod_type = src_prod.getProductType()
width = src_prod.getSceneRasterWidth()
height = src_prod.getSceneRasterHeight()
if bands is None:
bands = src_prod.getBandNames()
# Copy geocoding and selected bands from source to destination product
dst_prod = Product(prod_name, prod_type, width, height)
ProductUtils.copyGeoCoding(src_prod.getBandAt(0), dst_prod)
for band in bands:
r = ProductUtils.copyBand(band, src_prod, dst_prod, True)
if r is None:
src_prod.closeIO()
raise RuntimeError(src_file_path + " does not contain band " + band)
# Write destination product to disk
ext = os.path.splitext(dst_file_path)[1]
if ext == '.dim':
file_type = 'BEAM_DIMAP'
elif ext == '.nc':
file_type = 'NetCDF-CF'
elif ext == '.tif':
file_type = 'GeoTIFF-BigTIFF'
else:
file_type = 'GeoTIFF-BigTIFF'
ProductIO.writeProduct(dst_prod, dst_file_path, file_type)
src_prod.closeIO()
dst_prod.closeIO()
def get_bands_info(src_file_path):
# Get info from source product
src_prod = ProductIO.readProduct(src_file_path)
bands = src_prod.getBands()
bands_info = []
for band in bands:
bands_info.append({'band_name': band.getName(), 'description': band.getDescription(),
'unit': band.getUnit()})
src_prod.closeIO()
return bands_info
def get_product_info(src_file_path):
# Get info from source product
prod = ProductIO.readProduct(src_file_path)
width = prod.getSceneRasterWidth()
height = prod.getSceneRasterHeight()
geo_coding = prod.getSceneGeoCoding()
name = prod.getName()
prod_type = prod.getProductType()
prod.closeIO()
return name, geo_coding, prod_type, width, height