shancx 1.9.33.171__py3-none-any.whl → 1.9.33.174__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shancx/H9/__init__.py +126 -0
- shancx/H9/ahi_read_hsd.py +877 -0
- shancx/H9/ahisearchtable.py +298 -0
- shancx/H9/geometry.py +2439 -0
- shancx/NN/__init__.py +71 -8
- {shancx-1.9.33.171.dist-info → shancx-1.9.33.174.dist-info}/METADATA +1 -1
- {shancx-1.9.33.171.dist-info → shancx-1.9.33.174.dist-info}/RECORD +9 -5
- {shancx-1.9.33.171.dist-info → shancx-1.9.33.174.dist-info}/WHEEL +0 -0
- {shancx-1.9.33.171.dist-info → shancx-1.9.33.174.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
'''
|
|
3
|
+
@Project : fypy
|
|
4
|
+
|
|
5
|
+
@File : ahisearchtable.py
|
|
6
|
+
|
|
7
|
+
@Modify Time : 2022/11/10 14:45
|
|
8
|
+
|
|
9
|
+
@Author : fypy Team
|
|
10
|
+
|
|
11
|
+
@Version : 1.0
|
|
12
|
+
|
|
13
|
+
@Description :
|
|
14
|
+
|
|
15
|
+
'''
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
import numpy as np
|
|
20
|
+
import datetime
|
|
21
|
+
|
|
22
|
+
# TWOPI = 6.28318530717958648
|
|
23
|
+
# DPAI = 6.28318530717958648
|
|
24
|
+
#
|
|
25
|
+
deg2rad = np.pi / 180.0
|
|
26
|
+
rad2deg = 180.0 / np.pi
|
|
27
|
+
|
|
28
|
+
class ahisearchtable :
|
|
29
|
+
|
|
30
|
+
def __init__(self, subpoint, resolution):
|
|
31
|
+
|
|
32
|
+
self.ea = 6378.137 # 地球长半轴
|
|
33
|
+
self.eb = 6356.7523 # 地球短半轴
|
|
34
|
+
self.H = 42164.0 # 地心到卫星质心的距离
|
|
35
|
+
|
|
36
|
+
self.subpoint = subpoint
|
|
37
|
+
self.resolution = resolution
|
|
38
|
+
|
|
39
|
+
if resolution == 0.0025 : # 250米
|
|
40
|
+
self.coff = 21983.5
|
|
41
|
+
self.cfac = 163730199
|
|
42
|
+
self.loff = 21983.5
|
|
43
|
+
self.lfac = 163730199
|
|
44
|
+
self.rowmax = 44000
|
|
45
|
+
self.colmax = 44000
|
|
46
|
+
elif resolution == 0.005 :
|
|
47
|
+
self.coff = 10991.5
|
|
48
|
+
self.cfac = 81865099
|
|
49
|
+
self.loff = 10991.5
|
|
50
|
+
self.lfac = 81865099
|
|
51
|
+
self.rowmax = 22000
|
|
52
|
+
self.colmax = 22000
|
|
53
|
+
elif resolution == 0.01 :
|
|
54
|
+
self.coff = 5495.5
|
|
55
|
+
self.cfac = 40932549
|
|
56
|
+
self.loff = 5495.5
|
|
57
|
+
self.lfac = 40932549
|
|
58
|
+
self.rowmax = 11000
|
|
59
|
+
self.colmax = 11000
|
|
60
|
+
elif resolution == 0.02 :
|
|
61
|
+
self.coff = 2747.5
|
|
62
|
+
self.cfac = 20466274
|
|
63
|
+
self.loff = 2747.5
|
|
64
|
+
self.lfac = 20466274
|
|
65
|
+
self.rowmax = 5500
|
|
66
|
+
self.colmax = 5500
|
|
67
|
+
else:
|
|
68
|
+
raise Exception("resolution error! please input [0.0025, 0.005, 0.01, 0.02, 0.04]")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
self.FLAT = 0.00335281317789691
|
|
72
|
+
self.AE = 6378.137
|
|
73
|
+
self.E2 = 0.0066943800699785
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def xy2latlon(self, x, y, fillvalue=65535):
|
|
77
|
+
'''
|
|
78
|
+
行列号转经纬度
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
x: numpy.array
|
|
83
|
+
列号
|
|
84
|
+
y: numpy.array
|
|
85
|
+
行号
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
numpy.array
|
|
90
|
+
返回纬度、经度
|
|
91
|
+
'''
|
|
92
|
+
|
|
93
|
+
row = np.array(y)
|
|
94
|
+
col = np.array(x)
|
|
95
|
+
|
|
96
|
+
fillflag = (row < 0) | (row >= self.rowmax) | (col < 0) | (col >= self.colmax)
|
|
97
|
+
|
|
98
|
+
x = deg2rad * (col - self.coff) / (2**-16 * self.cfac)
|
|
99
|
+
y = deg2rad * (row - self.loff) / (2**-16 * self.lfac)
|
|
100
|
+
|
|
101
|
+
sd = (self.H * np.cos(x) * np.cos(y)) * (self.H * np.cos(x) * np.cos(y)) \
|
|
102
|
+
- (np.cos(y) * np.cos(y) + (self.ea * self.ea) / (self.eb * self.eb) \
|
|
103
|
+
* np.sin(y) * np.sin(y)) * ((self.H * self.H) - self.ea * self.ea)
|
|
104
|
+
|
|
105
|
+
flag = sd < 0
|
|
106
|
+
|
|
107
|
+
sd[sd>=0] = np.sqrt(sd[sd>=0])
|
|
108
|
+
|
|
109
|
+
sn = (self.H * np.cos(x) * np.cos(y) - sd) / \
|
|
110
|
+
(np.cos(y) * np.cos(y) + (self.ea * self.ea) / (self.eb * self.eb) * np.sin(y) * np.sin(y))
|
|
111
|
+
|
|
112
|
+
S1 = self.H - (sn * np.cos(x) * np.cos(y))
|
|
113
|
+
S2 = sn * np.sin(x) * np.cos(y)
|
|
114
|
+
S3 = -sn * np.sin(y)
|
|
115
|
+
Sxy = np.sqrt(S1 * S1 + S2 * S2)
|
|
116
|
+
|
|
117
|
+
lon = rad2deg * np.arctan2(S2 , S1) + self.subpoint
|
|
118
|
+
lat = rad2deg * np.arctan((self.ea * self.ea) / (self.eb * self.eb) * S3 / Sxy)
|
|
119
|
+
|
|
120
|
+
lon[lon > 180] -= 360.0
|
|
121
|
+
lon[lon < -180] += 360.0
|
|
122
|
+
|
|
123
|
+
lon[flag] = fillvalue
|
|
124
|
+
lat[flag] = fillvalue
|
|
125
|
+
|
|
126
|
+
lon[fillflag] = fillvalue
|
|
127
|
+
lat[fillflag] = fillvalue
|
|
128
|
+
|
|
129
|
+
lat = np.array(lat, dtype=np.float32)
|
|
130
|
+
lon = np.array(lon, dtype=np.float32)
|
|
131
|
+
|
|
132
|
+
return lon, lat
|
|
133
|
+
|
|
134
|
+
def latlon2xy(self, lat, lon, fillvalue=65535):
|
|
135
|
+
'''
|
|
136
|
+
经纬度转行列号
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
lat : numpy.array
|
|
141
|
+
纬度, -90.0 ~ 90.0
|
|
142
|
+
lon : numpy.array
|
|
143
|
+
经度, -180.0 ~ 180.0
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
numpy.array
|
|
148
|
+
返回行号、列号
|
|
149
|
+
'''
|
|
150
|
+
|
|
151
|
+
lat1 = np.array(lat.copy())
|
|
152
|
+
lon1 = np.array(lon.copy())
|
|
153
|
+
|
|
154
|
+
fillflag = (lat1<-90) | (lat1 > 90) | \
|
|
155
|
+
(lon1<-180) | (lon1 > 180)
|
|
156
|
+
|
|
157
|
+
lon1 = lon1 * deg2rad
|
|
158
|
+
lat1 = lat1 * deg2rad
|
|
159
|
+
|
|
160
|
+
phi_e = np.arctan(self.eb ** 2 * np.tan(lat1) / self.ea ** 2)
|
|
161
|
+
re = self.eb / np.sqrt(1-(self.ea**2 - self.eb**2) * np.cos(phi_e)**2/self.ea**2)
|
|
162
|
+
r1 = self.H - re * np.cos(phi_e) * np.cos(lon1 - self.subpoint * deg2rad)
|
|
163
|
+
r2 = -re * np.cos(phi_e) * np.sin(lon1 - self.subpoint * deg2rad)
|
|
164
|
+
r3 = re * np.sin(phi_e)
|
|
165
|
+
rn = np.sqrt(r1**2 + r2**2 + r3**2)
|
|
166
|
+
x = np.arctan2(-r2, r1)*180/np.pi
|
|
167
|
+
# x = np.arctan(-r2/r1)*180/np.pi
|
|
168
|
+
y = np.arcsin(-r3/rn)*180/np.pi
|
|
169
|
+
col = self.coff + x * 2**(-16) * self.cfac
|
|
170
|
+
line = self.loff + y * 2**(-16) * self.lfac
|
|
171
|
+
|
|
172
|
+
# 对外太空进行判断
|
|
173
|
+
tmp = r1 * (r1 - self.H) + r2 **2 + r3**2
|
|
174
|
+
flag = tmp > 0
|
|
175
|
+
|
|
176
|
+
line = np.array(line+0.5, dtype=np.int32)
|
|
177
|
+
col = np.array(col+0.5, dtype=np.int32)
|
|
178
|
+
|
|
179
|
+
line[(line<0) | (line >= self.rowmax)] = fillvalue
|
|
180
|
+
col[(col<0) | (col>=self.colmax)] = fillvalue
|
|
181
|
+
col[fillflag] = fillvalue
|
|
182
|
+
line[fillflag] = fillvalue
|
|
183
|
+
|
|
184
|
+
return col, line
|
|
185
|
+
|
|
186
|
+
def calSolarAngle(self, lat, lon, nowdate, fillvalue=65535):
|
|
187
|
+
''' 计算太阳天顶角SOZ和方位角SOA '''
|
|
188
|
+
|
|
189
|
+
dHours, dMinutes, dSeconds = nowdate.hour, nowdate.minute, nowdate.second
|
|
190
|
+
iYear, iMonth, iDay = nowdate.year, nowdate.month, nowdate.day
|
|
191
|
+
|
|
192
|
+
dEarthMeanRadius = 6371.01
|
|
193
|
+
dAstronomicalUnit = 149597890
|
|
194
|
+
|
|
195
|
+
dDecimalHours = dHours + (dMinutes + dSeconds / 60.) / 60.
|
|
196
|
+
|
|
197
|
+
liAux1 = int((iMonth - 14.) / 12.)
|
|
198
|
+
liAux2 = int((1461. * (iYear + 4800. + liAux1)) / 4.) + int((367. * (iMonth - 2. - 12. * liAux1)) / 12.) - int(
|
|
199
|
+
(3. * int((iYear + 4900. + liAux1) / 100.)) / 4.) + iDay - 32075.
|
|
200
|
+
dJulianDate = liAux2 - 0.5 + dDecimalHours / 24.
|
|
201
|
+
|
|
202
|
+
dElapsedJulianDays = dJulianDate - 2451545.0
|
|
203
|
+
|
|
204
|
+
dOmega = 2.1429 - 0.0010394594 * dElapsedJulianDays
|
|
205
|
+
dMeanLongitude = 4.8950630 + 0.017202791698 * dElapsedJulianDays # Radians
|
|
206
|
+
dMeanAnomaly = 6.2400600 + 0.0172019699 * dElapsedJulianDays
|
|
207
|
+
dEclipticLongitude = dMeanLongitude + 0.03341607 * np.sin(dMeanAnomaly) + 0.00034894 * np.sin(
|
|
208
|
+
2. * dMeanAnomaly) - 0.0001134 - 0.0000203 * np.sin(dOmega)
|
|
209
|
+
dEclipticObliquity = 0.4090928 - 6.2140e-9 * dElapsedJulianDays + 0.0000396 * np.cos(dOmega)
|
|
210
|
+
|
|
211
|
+
dSin_EclipticLongitude = np.sin(dEclipticLongitude)
|
|
212
|
+
dY = np.cos(dEclipticObliquity) * dSin_EclipticLongitude
|
|
213
|
+
dX = np.cos(dEclipticLongitude)
|
|
214
|
+
dRightAscension = np.arctan2(dY, dX)
|
|
215
|
+
if dRightAscension < 0.0:
|
|
216
|
+
dRightAscension = dRightAscension + 2.0 * np.pi
|
|
217
|
+
dDeclination = np.arcsin(np.sin(dEclipticObliquity) * dSin_EclipticLongitude)
|
|
218
|
+
|
|
219
|
+
dGreenwichMeanSiderealTime = 6.6974243242 + 0.0657098283 * dElapsedJulianDays + dDecimalHours
|
|
220
|
+
dLocalMeanSiderealTime = np.deg2rad(dGreenwichMeanSiderealTime * 15. + lon)
|
|
221
|
+
dHourAngle = dLocalMeanSiderealTime - dRightAscension
|
|
222
|
+
dLatitudeInRadians = np.deg2rad(lat)
|
|
223
|
+
dCos_Latitude = np.cos(dLatitudeInRadians)
|
|
224
|
+
dSin_Latitude = np.sin(dLatitudeInRadians)
|
|
225
|
+
dCos_HourAngle = np.cos(dHourAngle)
|
|
226
|
+
Zenith = (np.arccos(dCos_Latitude * dCos_HourAngle * np.cos(dDeclination)
|
|
227
|
+
+ np.sin(dDeclination) * dSin_Latitude))
|
|
228
|
+
dY = -np.sin(dHourAngle)
|
|
229
|
+
dX = np.tan(dDeclination) * dCos_Latitude - dSin_Latitude * dCos_HourAngle
|
|
230
|
+
Azimuth = np.arctan2(dY, dX)
|
|
231
|
+
Azimuth[Azimuth < 0.0] = Azimuth[Azimuth < 0.0] + 2.0 * np.pi
|
|
232
|
+
Azimuth = np.rad2deg(Azimuth)
|
|
233
|
+
# Parallax Correction
|
|
234
|
+
dParallax = (dEarthMeanRadius / dAstronomicalUnit) * np.sin(Zenith)
|
|
235
|
+
Zenith = np.rad2deg(Zenith + dParallax)
|
|
236
|
+
|
|
237
|
+
flag = (lat <-90) | (lat > 90) | \
|
|
238
|
+
(lon < -180) | (lon > 180)
|
|
239
|
+
Azimuth[flag] = fillvalue
|
|
240
|
+
Zenith[flag] = fillvalue
|
|
241
|
+
|
|
242
|
+
return Azimuth, Zenith
|
|
243
|
+
|
|
244
|
+
def calSatAngle(self, lat, lon, fillvalue=65535):
|
|
245
|
+
''' 计算卫星的天顶角和方位角 '''
|
|
246
|
+
|
|
247
|
+
S = self.subpoint / 180. * np.pi
|
|
248
|
+
N = lon / 180. * np.pi
|
|
249
|
+
L = lat / 180. * np.pi
|
|
250
|
+
G = S - N
|
|
251
|
+
|
|
252
|
+
LL = np.sqrt(1 - (np.cos(G) * np.cos(L)) ** 2)
|
|
253
|
+
E = np.arctan((np.cos(G) * np.cos(L) - 0.15127) / LL)
|
|
254
|
+
# Azimuth
|
|
255
|
+
A = np.pi - np.arctan2(np.tan(G), np.sin(L))
|
|
256
|
+
# 弧度->度
|
|
257
|
+
Azimuth = A / np.pi * 180
|
|
258
|
+
Elevat = E / np.pi * 180
|
|
259
|
+
Zenith = (90 - Elevat)
|
|
260
|
+
|
|
261
|
+
flag = (lat <-90) | (lat > 90) | \
|
|
262
|
+
(lon < -180) | (lon > 180)
|
|
263
|
+
Azimuth[flag] = fillvalue
|
|
264
|
+
Zenith[flag] = fillvalue
|
|
265
|
+
|
|
266
|
+
return Azimuth, Zenith
|
|
267
|
+
|
|
268
|
+
def calSunGL(self, satz, sunz, rela):
|
|
269
|
+
'''
|
|
270
|
+
|
|
271
|
+
:param satz:
|
|
272
|
+
:param sunz:
|
|
273
|
+
:param rela:
|
|
274
|
+
:return:
|
|
275
|
+
'''
|
|
276
|
+
fillflag = (satz < -360) | (satz > 360) | (sunz < -360) | (sunz > 360) | (rela < -360) | (rela > 360)
|
|
277
|
+
|
|
278
|
+
data = np.cos(satz * deg2rad) * np.cos(sunz * deg2rad) \
|
|
279
|
+
+ np.sin(satz * deg2rad) * np.sin(sunz * deg2rad) * np.cos(rela * deg2rad)
|
|
280
|
+
# cos_solzen * cos_satzen + sin_solzen * sin_satzen * cos_relaz
|
|
281
|
+
|
|
282
|
+
data[data > 1.0] = 0.0
|
|
283
|
+
SunGL = np.arccos(data) * rad2deg
|
|
284
|
+
SunGL[fillflag] = -999.0
|
|
285
|
+
|
|
286
|
+
return SunGL
|
|
287
|
+
|
|
288
|
+
def calRelativeAzimuth(self, sata, suna, fillvalue=65535):
|
|
289
|
+
fillflag = (sata > 360) | (sata < 0) | (suna > 360) | (suna < 0)
|
|
290
|
+
|
|
291
|
+
RelativeAzi = np.fabs(sata - suna) + 180.0 # ???? + 180
|
|
292
|
+
|
|
293
|
+
RelativeAzi[fillflag] = fillvalue
|
|
294
|
+
|
|
295
|
+
return RelativeAzi
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|