[英]How to ofsetting cartopy coast line to match with actual lat and lon
I am using Arch Linux with cartopy version 0.17.0 installed on the system through packagemanager.我正在使用 Arch Linux,并通过 packagemanager 安装在系统上的 cartopy 版本 0.17.0。 I am trying to plot a simple satellite image from hdf5 file with cartopy as plotting tool.我正在尝试使用 cartopy 作为绘图工具从 hdf5 文件绘制一个简单的卫星图像。 Following is the sample code I am trying to do to produce image:-以下是我试图用来生成图像的示例代码:-
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import h5py
import numpy as np
import cartopy
import matplotlib.pyplot as plt
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
input_file = "../input/satellite/3RIMG_27MAR2020_0545_L1C_ASIA_MER.h5"
fh=h5py.File(input_file, 'r')
X = fh["X"][()]
Y = fh["Y"][()]
IMG_TIR1 = fh["IMG_TIR1"][()][0, ::-1, :]
lower_latitude, left_longitude = fh['Projection_Information'].attrs["lower_left_lat_lon(degrees)"]
upper_latitude, right_longitude = fh['Projection_Information'].attrs["upper_right_lat_lon(degrees)"]
lons_values = np.linspace(left_longitude, right_longitude, X.shape[0])
lats_values = np.linspace(lower_latitude, upper_latitude, Y.shape[0])
print(lons_values)
print(lats_values)
lons, lats = np.meshgrid(lons_values, lats_values)
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(projection=cartopy.crs.Mercator()))
ax.pcolormesh(lons, lats, IMG_TIR1, cmap=plt.cm.gist_gray, transform=cartopy.crs.PlateCarree())
ax.coastlines('50m', linewidth=0.8, color='black')
gl = ax.gridlines(draw_labels=True)
gl.xformatter = LONGITUDE_FORMATTER
plt.title('IMG_TIR1')
# plt.savefig('INSAT3D_IMG_TIR1_cartopy.png', bbox_inches='tight', dpi=100)
plt.show()
The result is shown below:-结果如下图所示:-
All looks fine.一切看起来都很好。 But if you look at the image closely, you will find that there is a huge mismatch or offset between the actual dataset and cartopy coast line.但是如果仔细观察图像,您会发现实际数据集和 cartopy 海岸线之间存在巨大的不匹配或偏移。
Can some some one help me why the coastline is hugely offset and how to correct it.有人可以帮助我为什么海岸线偏移很大以及如何纠正它。 Any help is appreciated.任何帮助表示赞赏。
Update 1 Uploading metadata of the hdf file using ncdump.更新 1使用 ncdump 上传 hdf 文件的元数据。
dimensions:
GreyCount = 1024 ;
X = 1737 ;
Y = 1616 ;
proj_dim = 1 ;
time = 1 ;
variables:
int GreyCount(GreyCount) ;
ushort IMG_MIR(time, Y, X) ;
IMG_MIR:long_name = "Middle Infrared Count" ;
IMG_MIR:invert = "true" ;
IMG_MIR:central_wavelength = 3.907f ;
IMG_MIR:bandwidth = 0.2f ;
IMG_MIR:wavelength_unit = "micron" ;
IMG_MIR:bits_per_pixel = 10 ;
IMG_MIR:resolution = 4.f ;
IMG_MIR:resolution_unit = "km" ;
IMG_MIR:_FillValue = 1023US ;
IMG_MIR:lab_radiance_scale_factor = 0.000294963f ;
IMG_MIR:lab_radiance_add_offset = -0.00477786f ;
IMG_MIR:lab_radiance_quad = -2.00028e-12 ;
IMG_MIR:lab_radiance_scale_factor_gsics = 0.000326854f ;
IMG_MIR:lab_radiance_add_offset_gsics = -0.0131381f ;
IMG_MIR:lab_radiance_quad_gsics = -2.21654e-12 ;
IMG_MIR:radiance_units = "mW.cm-2.sr-1.micron-1" ;
IMG_MIR:grid_mapping = "Projection_Information" ;
float IMG_MIR_RADIANCE(GreyCount) ;
IMG_MIR_RADIANCE:long_name = "Middle Infrared Radiance" ;
IMG_MIR_RADIANCE:invert = "true" ;
IMG_MIR_RADIANCE:units = "mW.cm-2.sr-1.micron-1" ;
IMG_MIR_RADIANCE:_FillValue = 999.f ;
float IMG_MIR_TEMP(GreyCount) ;
IMG_MIR_TEMP:long_name = "Middle Infrared Brightness Temperature" ;
IMG_MIR_TEMP:invert = "true" ;
IMG_MIR_TEMP:units = "K" ;
IMG_MIR_TEMP:_FillValue = 999.f ;
ushort IMG_SWIR(time, Y, X) ;
IMG_SWIR:long_name = "Shortwave Infrared Count" ;
IMG_SWIR:invert = "false" ;
IMG_SWIR:central_wavelength = 1.625f ;
IMG_SWIR:bandwidth = 0.15f ;
IMG_SWIR:wavelength_unit = "micron" ;
IMG_SWIR:bits_per_pixel = 10 ;
IMG_SWIR:resolution = 4.f ;
IMG_SWIR:resolution_unit = "km" ;
IMG_SWIR:_FillValue = 0US ;
IMG_SWIR:lab_radiance_scale_factor = 0.00689f ;
IMG_SWIR:lab_radiance_add_offset = -0.1674f ;
IMG_SWIR:lab_radiance_quad = 0. ;
IMG_SWIR:lab_radiance_scale_factor_gsics = 0.00689f ;
IMG_SWIR:lab_radiance_add_offset_gsics = -0.1674f ;
IMG_SWIR:lab_radiance_quad_gsics = 0. ;
IMG_SWIR:radiance_units = "mW.cm-2.sr-1.micron-1" ;
IMG_SWIR:grid_mapping = "Projection_Information" ;
float IMG_SWIR_RADIANCE(GreyCount) ;
IMG_SWIR_RADIANCE:long_name = "Shortwave Infrared Radiance" ;
IMG_SWIR_RADIANCE:invert = "false" ;
IMG_SWIR_RADIANCE:units = "mW.cm-2.sr-1.micron-1" ;
IMG_SWIR_RADIANCE:_FillValue = 999.f ;
ushort IMG_TIR1(time, Y, X) ;
IMG_TIR1:long_name = "Thermal Infrared1 Count" ;
IMG_TIR1:invert = "true" ;
IMG_TIR1:central_wavelength = 10.785f ;
IMG_TIR1:bandwidth = 1.f ;
IMG_TIR1:wavelength_unit = "micron" ;
IMG_TIR1:bits_per_pixel = 10 ;
IMG_TIR1:resolution = 4.f ;
IMG_TIR1:resolution_unit = "km" ;
IMG_TIR1:_FillValue = 1023US ;
IMG_TIR1:lab_radiance_scale_factor = 0.001708f ;
IMG_TIR1:lab_radiance_add_offset = -0.0145189f ;
IMG_TIR1:lab_radiance_quad = -4.23297e-07 ;
IMG_TIR1:lab_radiance_scale_factor_gsics = 0.00250456f ;
IMG_TIR1:lab_radiance_add_offset_gsics = -0.209975f ;
IMG_TIR1:lab_radiance_quad_gsics = -6.20708e-07 ;
IMG_TIR1:radiance_units = "mW.cm-2.sr-1.micron-1" ;
IMG_TIR1:grid_mapping = "Projection_Information" ;
float IMG_TIR1_RADIANCE(GreyCount) ;
IMG_TIR1_RADIANCE:long_name = "Thermal Infrared1 Radiance" ;
IMG_TIR1_RADIANCE:invert = "true" ;
IMG_TIR1_RADIANCE:units = "mW.cm-2.sr-1.micron-1" ;
IMG_TIR1_RADIANCE:_FillValue = 999.f ;
float IMG_TIR1_TEMP(GreyCount) ;
IMG_TIR1_TEMP:_FillValue = 999.f ;
IMG_TIR1_TEMP:long_name = "Thermal Infrared1 Brightness Temperature" ;
IMG_TIR1_TEMP:invert = "true" ;
IMG_TIR1_TEMP:units = "K" ;
ushort IMG_TIR2(time, Y, X) ;
IMG_TIR2:long_name = "Thermal Infrared2 Count" ;
IMG_TIR2:invert = "true" ;
IMG_TIR2:central_wavelength = 11.966f ;
IMG_TIR2:bandwidth = 1.f ;
IMG_TIR2:wavelength_unit = "micron" ;
IMG_TIR2:bits_per_pixel = 10 ;
IMG_TIR2:resolution = 4.f ;
IMG_TIR2:resolution_unit = "km" ;
IMG_TIR2:_FillValue = 1023US ;
IMG_TIR2:lab_radiance_scale_factor = 0.001549f ;
IMG_TIR2:lab_radiance_add_offset = -0.0113878f ;
IMG_TIR2:lab_radiance_quad = -4.33804e-07 ;
IMG_TIR2:lab_radiance_scale_factor_gsics = 0.00242858f ;
IMG_TIR2:lab_radiance_add_offset_gsics = -0.195822f ;
IMG_TIR2:lab_radiance_quad_gsics = -6.80131e-07 ;
IMG_TIR2:radiance_units = "mW.cm-2.sr-1.micron-1" ;
IMG_TIR2:grid_mapping = "Projection_Information" ;
float IMG_TIR2_RADIANCE(GreyCount) ;
IMG_TIR2_RADIANCE:units = "mW.cm-2.sr-1.micron-1" ;
IMG_TIR2_RADIANCE:_FillValue = 999.f ;
IMG_TIR2_RADIANCE:long_name = "Thermal Infrared2 Radiance" ;
IMG_TIR2_RADIANCE:invert = "true" ;
float IMG_TIR2_TEMP(GreyCount) ;
IMG_TIR2_TEMP:long_name = "Thermal Infrared2 Brightness Temperature" ;
IMG_TIR2_TEMP:invert = "true" ;
IMG_TIR2_TEMP:units = "K" ;
IMG_TIR2_TEMP:_FillValue = 999.f ;
ushort IMG_VIS(time, Y, X) ;
IMG_VIS:long_name = "Visible Count" ;
IMG_VIS:invert = "false" ;
IMG_VIS:central_wavelength = 0.65f ;
IMG_VIS:wavelength_unit = "micron" ;
IMG_VIS:bandwidth = 0.25f ;
IMG_VIS:bits_per_pixel = 10 ;
IMG_VIS:resolution = 4.f ;
IMG_VIS:resolution_unit = "km" ;
IMG_VIS:_FillValue = 0US ;
IMG_VIS:lab_radiance_scale_factor = 0.06131f ;
IMG_VIS:lab_radiance_add_offset = -2.643f ;
IMG_VIS:lab_radiance_quad = 0. ;
IMG_VIS:lab_radiance_scale_factor_gsics = 0.06131f ;
IMG_VIS:lab_radiance_add_offset_gsics = -2.643f ;
IMG_VIS:lab_radiance_quad_gsics = 0. ;
IMG_VIS:radiance_units = "mW.cm-2.sr-1.micron-1" ;
IMG_VIS:grid_mapping = "Projection_Information" ;
float IMG_VIS_ALBEDO(GreyCount) ;
IMG_VIS_ALBEDO:long_name = "Visible Albedo" ;
IMG_VIS_ALBEDO:invert = "false" ;
IMG_VIS_ALBEDO:units = "%" ;
float IMG_VIS_RADIANCE(GreyCount) ;
IMG_VIS_RADIANCE:long_name = "Visible Radiance" ;
IMG_VIS_RADIANCE:invert = "false" ;
IMG_VIS_RADIANCE:units = "mW.cm-2.sr-1.micron-1" ;
IMG_VIS_RADIANCE:_FillValue = 999.f ;
ushort IMG_WV(time, Y, X) ;
IMG_WV:long_name = "Water Vapor Count" ;
IMG_WV:invert = "true" ;
IMG_WV:wavelength_unit = "micron" ;
IMG_WV:central_wavelength = 6.866f ;
IMG_WV:bandwidth = 0.6f ;
IMG_WV:bits_per_pixel = 10 ;
IMG_WV:resolution = 4.f ;
IMG_WV:resolution_unit = "km" ;
IMG_WV:_FillValue = 1023US ;
IMG_WV:lab_radiance_scale_factor = 0.00114622f ;
IMG_WV:lab_radiance_add_offset = -0.010913f ;
IMG_WV:lab_radiance_quad = -2.06407e-07 ;
IMG_WV:lab_radiance_scale_factor_gsics = 0.00145709f ;
IMG_WV:lab_radiance_add_offset_gsics = -0.0332341f ;
IMG_WV:lab_radiance_quad_gsics = -2.62387e-07 ;
IMG_WV:radiance_units = "mW.cm-2.sr-1.micron-1" ;
IMG_WV:grid_mapping = "Projection_Information" ;
float IMG_WV_RADIANCE(GreyCount) ;
IMG_WV_RADIANCE:long_name = "Water Vapor Radiance" ;
IMG_WV_RADIANCE:invert = "true" ;
IMG_WV_RADIANCE:units = "mW.cm-2.sr-1.micron-1" ;
IMG_WV_RADIANCE:_FillValue = 999.f ;
float IMG_WV_TEMP(GreyCount) ;
IMG_WV_TEMP:long_name = "Water Vapor Brightness Temperature" ;
IMG_WV_TEMP:invert = "true" ;
IMG_WV_TEMP:units = "K" ;
IMG_WV_TEMP:_FillValue = 999.f ;
int Projection_Information(proj_dim) ;
Projection_Information:upper_left_lat_lon\(degrees\) = 45.5, 44.5 ;
Projection_Information:upper_right_lat_lon\(degrees\) = 45.5, 110. ;
Projection_Information:lower_left_lat_lon\(degrees\) = -10., 44.5 ;
Projection_Information:lower_right_lat_lon\(degrees\) = -10., 110. ;
Projection_Information:upper_left_xy\(meters\) = -3473242.733735, 5401854.420193 ;
Projection_Information:grid_mapping_name = "mercator" ;
Projection_Information:false_easting = 0. ;
Projection_Information:false_northing = 0. ;
Projection_Information:longitude_of_projection_origin = 77.25 ;
Projection_Information:semi_major_axis = 6378137. ;
Projection_Information:semi_minor_axis = 6356752.3142 ;
Projection_Information:standard_parallel = 17.75 ;
ushort Sat_Azimuth(time, Y, X) ;
Sat_Azimuth:scale_factor = 0.01f ;
Sat_Azimuth:_FillValue = 65535US ;
Sat_Azimuth:long_name = "Satellite Azimuth" ;
Sat_Azimuth:add_offset = 0.f ;
Sat_Azimuth:units = "degree" ;
Sat_Azimuth:grid_mapping = "Projection_Information" ;
short Sat_Elevation(time, Y, X) ;
Sat_Elevation:long_name = "Satellite Elevation" ;
Sat_Elevation:units = "degree" ;
Sat_Elevation:add_offset = 0.f ;
Sat_Elevation:scale_factor = 0.01f ;
Sat_Elevation:grid_mapping = "Projection_Information" ;
Sat_Elevation:_FillValue = 32767s ;
ushort Sun_Azimuth(time, Y, X) ;
Sun_Azimuth:add_offset = 0.f ;
Sun_Azimuth:scale_factor = 0.01f ;
Sun_Azimuth:units = "degree" ;
Sun_Azimuth:long_name = "Sun Azimuth" ;
Sun_Azimuth:_FillValue = 65535US ;
Sun_Azimuth:grid_mapping = "Projection_Information" ;
short Sun_Elevation(time, Y, X) ;
Sun_Elevation:long_name = "Sun Elevation" ;
Sun_Elevation:add_offset = 0.f ;
Sun_Elevation:scale_factor = 0.01f ;
Sun_Elevation:units = "degree" ;
Sun_Elevation:_FillValue = 32767s ;
Sun_Elevation:grid_mapping = "Projection_Information" ;
double X(X) ;
X:long_name = "x coordinate of projection" ;
X:standard_name = "projection_x_coordinate" ;
X:units = "m" ;
double Y(Y) ;
Y:long_name = "y coordinate of projection" ;
Y:standard_name = "projection_y_coordinate" ;
Y:units = "m" ;
int proj_dim(proj_dim) ;
double time(time) ;
time:units = "minutes since 2000-01-01 00:00:00" ;
// global attributes:
:conventions = "CF-1.6" ;
:title = "3RIMG_27MAR2020_0545_ASIA_MER_L1C" ;
:institute = "BES,SAC/ISRO,Ahmedabad,INDIA." ;
:source = "BES,SAC/ISRO,Ahmedabad,INDIA." ;
:Unique_Id = "3RIMG_27MAR2020_0545_ASIA_MER" ;
:Satellite_Name = "INSAT-3DR" ;
:Sensor_Id = "IMG" ;
:Sensor_Name = "IMAGER" ;
:HDF_Product_File_Name = "3RIMG_27MAR2020_0545_L1C_ASIA_MER.h5" ;
:Output_Format = "hdf5-1.8.8" ;
:Station_Id = "BES" ;
:Ground_Station = "BES,SAC/ISRO,Ahmedabad,INDIA." ;
:Product_Type = "SECTOR" ;
:Processing_Level = "L1C" ;
:Acquisition_Date = "27MAR2020" ;
:Acquisition_Time_in_GMT = "0545" ;
:Acquisition_Start_Time = "27-MAR-2020T05:45:15" ;
:Acquisition_End_Time = "27-MAR-2020T06:12:09" ;
:Product_Creation_Time = "2020-03-27T11:49:58" ;
:Nominal_Altitude\(km\) = 36000.f ;
:Nominal_Central_Point_Coordinates\(degrees\)_Latitude_Longitude = 0., 74. ;
:Software_Version = "1.0" ;
:left_longitude = 44.5f ;
:right_longitude = 110.f ;
:upper_latitude = 45.5f ;
:lower_latitude = -10.f ;
:Datum = "WGS84" ;
:Ellipsoid = "WGS84" ;
}
Update 2更新 2
It appears that it is the problem with conversion from X, Y coordinates to lats and lons.似乎是从 X、Y 坐标转换为纬度和经度的问题。 The X and Y data is in meters. X 和 Y 数据以米为单位。 I have converted this 1D data to 2D using X& Y dimesion along with meshgrid command.我已经使用 X&Y 维度和 meshgrid 命令将此一维数据转换为二维数据。 Here is the sample X and Y data for review:-以下是供审查的样本 X 和 Y 数据:-
X = -3473242.733735, -3469241.30201411, -3465239.87029321,
-3461238.43857232, -3457237.00685143, -3453235.57513054,
-3449234.14340964, -3445232.71168875, -3441231.27996786,
-3437229.84824696, -3433228.41652607, -3429226.98480518,
-3425225.55308429, -3421224.12136339, -3417222.6896425,
-3413221.25792161, -3409219.82620071, -3405218.39447982,
-3401216.96275893, -3397215.53103804, -3393214.09931714,
Y = 5401854.420193, 5397853.95696842, 5393853.49374385, 5389853.03051927,
5385852.5672947, 5381852.10407012, 5377851.64084554, 5373851.17762097,
5369850.71439639, 5365850.25117182, 5361849.78794724, 5357849.32472267,
5353848.86149809, 5349848.39827351, 5345847.93504894, 5341847.47182436,
5337847.00859979, 5333846.54537521, 5329846.08215063, 5325845.61892606,
5321845.15570148, 5317844.69247691, 5313844.22925233, 5309843.76602776,
5305843.30280318, 5301842.8395786, 5297842.37635403, 5293841.91312945,
Does your data file have information about the original projection?您的数据文件是否包含有关原始投影的信息? This looks like it could be an issue with a globe mismatch (CartoPy defaults to WGS84) or missing some kind of projection parameter, like latitude at origin.这看起来可能是地球不匹配(CartoPy 默认为 WGS84)或缺少某种投影参数(如原点纬度)的问题。
Edited based on other answer根据其他答案编辑
So now with the proper projection information, this is how I would plot your data:所以现在有了正确的投影信息,这就是我绘制数据的方式:
import h5py
import numpy as np
import cartopy
import matplotlib.pyplot as plt
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
input_file = "../input/satellite/3RIMG_27MAR2020_0545_L1C_ASIA_MER.h5"
fh = h5py.File(input_file, 'r')
X = fh["X"][()]
Y = fh["Y"][()]
IMG_TIR1 = fh["IMG_TIR1"][()][0, ::-1, :]
globe = ccrs.Globe(semimajor_axis=6378137, semiminor_axis=6356752.3142)
proj = ccrs.Mercator(central_longitude=77.25,
latitude_true_scale=17.75, globe=globe)
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(projection=proj))
ax.pcolormesh(X, Y, IMG_TIR1, cmap=plt.cm.gist_gray)
ax.coastlines('50m', linewidth=0.8, color='black')
gl = ax.gridlines(draw_labels=True)
gl.xformatter = LONGITUDE_FORMATTER
plt.title('IMG_TIR1')
plt.show()
Got it solved by myself after hours of finding information about the projection systems.在寻找有关投影系统的信息数小时后,我自己解决了这个问题。 The issue was that X and Y are projection coordinates and not lons and lats.问题是 X 和 Y 是投影坐标,而不是 lons 和 lats。 Therefore, it need to be projected to mercator first before proceeding for plotting.因此,在进行绘图之前,需要先将其投影到墨卡托上。 Got all the clues about projection information from metadata of hdf file (see update 1) and then used following code to convert to lons and lats grid:-从 hdf 文件的元数据中获取有关投影信息的所有线索(请参阅更新 1),然后使用以下代码转换为 lons 和 lats 网格:-
import pyproj
fh=h5py.File(input_file, 'r')
X = fh["X"][()]
Y = fh["Y"][()]
p = pyproj.Proj("+proj=merc +lon_0=77.25 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6356752.3142 +lat_ts=17.75 "
"+ellps=WGS84 +datum=WGS84 +towgs84=0,0,0 +units=m +no_defs")
xv, yv = np.meshgrid(X, Y)
lon_grid, lat_grid = p(xv, yv, inverse=True)
.
.
.
Thereafter, processed the data as usual and the result is shown below:此后,照常处理数据,结果如下所示:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.