I am working with GOLD Satellite Data. I am trying to regrid the latitude and longitude variables to 1-D.
Right now the lats and lons are given like this, with nlats as the latitude grid dimension, and nlons as the longitude grid dimension.
I want to regrid these into 1-D, in order to select a rectangular area of lats and lons to study.
lats = file.variables['latitude'][:,:] # Latitude(nlons,nlats)
lons = file.variables['longitude'][:,:] # Longitude(nlons,nlats)
I tried to select my area using:
#defining the latitude values covered
reallat = lats
reallat[reallat < 24] = np.nan
reallat[reallat > 31] = np.nan
#defining the longitude values covered
reallon = lons
reallon[reallon < -92] = np.nan
reallon[reallon > -84] = np.nan
#making a list of the coordinates that select good values
loncoord = np.where(~np.isnan(reallon))
latcoord = np.where(~np.isnan(reallat))
#printing means and st devs of disk temperautres corresponding to the right coordinates
print("Average Temps of Longtidue Values")
alon= np.nanmean(tdisk[:,loncoord[0],loncoord[1]])
print(alon)
I'm new to python and NetCDF, so I was wondering if it was possible to convert these 2D coordinates into nominal 1D lat/lon dimensions.
Related
I am trying to reproject polar data into Cartesian data that matches along latitude / longitude lines. The code that I have thus far is as follows:
latitude = 35.6655197143554
longitude = -78.48975372314453
# Convert to Cartesian
x = ranges * np.sin(np.deg2rad(azimuths))[:,None]
y = ranges * np.cos(np.deg2rad(azimuths))[:,None]
# Setup a projection
dataproj = Proj(f"+proj=stere +lat_0={latitude} +lat_ts={latitude} +lon_0={longitude} +ellps=WGS84 +units=m")
lons,lats = dataproj(x,y,inverse=True)
...
...
# Plot
im = ax.pcolormesh(lons,lats,data,cmap=cmap_data,norm=norm_cmap)
where the data is a [720,1832] array. The output from plotting looks like below:
Notice how the individual colored pixels move across the latitude and longitude lines. How might I add and/or change the code I have thus far to make the data aligned along lat/lons?
I am working on geographical data and want to divide an area of interest into grids of 4*4 each. How can I do the same in python ? I have the lat and long of the upper right corner and lower left corner of the bounding box ?
min_lon, min_lat = (76.8672,8.2720) # Lower-left corner
max_lon, max_lat = (77.17,8.54) # Upper-right corner
bbox = (min_lon, min_lat, max_lon, max_lat)
There may be other, cooler ways to do this. The method I have devised is to create a sequence of 5 equal parts of the least and greatest in latitude and longitude, respectively. I then loop through it by latitude and longitude to find the coordinates of each rectangle. For the coordinates I find, I create a 4x4 using the rectangles.
import numpy as np
min_lon, min_lat = (76.8672,8.2720) # Lower-left corner
max_lon, max_lat = (77.17,8.54) # Upper-right corner
#bbox = (min_lon, min_lat, max_lon, max_lat)
lon = np.linspace(min_lon, max_lon, 5)
lat = np.linspace(min_lat, max_lat, 5)
latlons = []
for i in range(len(lat)-1):
for k in range(len(lon)-1):
latlons.append((lat[k], lon[i], lat[k+1], lon[i+1]))
import folium
m = folium.Map(location=((min_lat+max_lat)/2,(min_lon+max_lon)/2), zoom_start=11)
for k in latlons:
folium.Rectangle([(k[0], k[1]), (k[2], k[3])],
color='red',
fill='pink',
fill_opcity=0.5).add_to(m)
m
I have an array that has 14000 columns and 7000 rows of terrain data for the US that are equally spaced 500m apart. I also have the lower-left latitude and longitude:
ncols = 14000
nrows = 7000
xllcorner = -130
yllcorner = 20
cellsize = 0.05
I also have another dataset (polar --> Cartesian radar data) that is already in a projected coordinate system:
# radial data being converted to Cartesian
x = rangee * np.sin(np.deg2rad(az))[:,None]
y = rangee * np.cos(np.deg2rad(az))[:,None]
latitude = 35.9339
longitude = -80.0212
dataproj = Proj(f"+proj=stere +lat_0={latitude} +lat_ts={latitude} +lon_0={longitude} +ellps=WGS84 +units=m")
lons,lats = dataproj(x,y,inverse=True)
It should be noted that the terrain data spans throughout the US, whereas the radar data is located over North Carolina. Therefore, I have two separate gridded datasets where I would like to be able to match the terrain data as best as possible to the radar data. In other words, whether through interpolation and/or other methods, there should be one value of terrain for each [x,y] location of the radar data.
How could one achieve this?
I would recommend using rioxarray. It has a method called reproject_match to make the two grids align:
https://corteva.github.io/rioxarray/stable/examples/reproject_match.html
I have a large list of longitude latitude points and want to find the nearest rectangle (so which rectangle contains the point) in a given raster of geographic coordinates.
However, for the raster I only have the centroids of each rectangle (polygon) in the raster. I know though that the rectangles have a size of 250m x 250m.
Just checking for absolute distance or geographic distance to the centers does not work, as the rectangles are not necessarily aligned. I am happy to get ideas.
I think you could generate your raster of geographic coordinates that represent raster cells following this approach: https://gis.stackexchange.com/questions/177061/ascii-file-with-latitude-longitude-and-data-to-geotiff-using-python
And then if you created a shapefile of your latitute and longitude points you could get raster cell ID for each point using this approach:
def GetRasterValueAtPoints(rasterfile, shapefile, fieldname):
'''
__author__ = "Marc Weber <weber.marc#epa.gov>"
Original code attribution: https://gis.stackexchange.com/a/46898/2856
returns raster values at points in a point shapefile
assumes same projection in shapefile and raster file
Arguments
---------
rasterfile : a raster file with full pathname and extension
shapefile : a shapefile with full pathname and extension
fieldname : field name in the shapefile to identify values
'''
src_ds=gdal.Open(rasterfile)
no_data = src_ds.GetRasterBand(1).GetNoDataValue()
gt=src_ds.GetGeoTransform()
rb=src_ds.GetRasterBand(1)
df = pd.DataFrame(columns=(fieldname, "RasterVal"))
i = 0
ds=ogr.Open(shapefile)
lyr=ds.GetLayer()
for feat in lyr:
geom = feat.GetGeometryRef()
name = feat.GetField(fieldname)
mx,my=geom.GetX(), geom.GetY() #coord in map units
#Convert from map to pixel coordinates.
#Only works for geotransforms with no rotation.
px = int((mx - gt[0]) / gt[1]) #x pixel
py = int((my - gt[3]) / gt[5]) #y pixel
intval = rb.ReadAsArray(px,py,1,1)
if intval == no_data:
intval = -9999
df.set_value(i,fieldname,name)
df.set_value(i,"RasterVal",float(intval))
i+=1
return df
I am new to python, and I can't figure out how to find the minimum distance from a given lat/lon point (which is not given from the grid, but selected by me) to a find the closest indices of a lat/lon point on a grid.
Basically , I am reading in an ncfile that contains 2D coordinates:
coords = 'coords.nc'
fh = Dataset(coords,mode='r')
lons = fh.variables['latitudes'][:,:]
lats = fh.variables['longitudes'][:,:]
fh.close()
>>> lons.shape
(94, 83)
>>> lats.shape
(94, 83)
I want to find the indices in the above grid for the nearest lat lon to the below values:
sel_lat=71.60556
sel_lon=-161.458611
I tried to make lat/lon pairs in order to use the scipy.spatial.distance function, but I still am having problems because I did not set up the input arrays to the format it wants, but I don't understand how to do that:
latLon_pairsGrid = np.vstack(([lats.T],[lons.T])).T
>>> latLon_pairsGrid.shape
(94, 83, 2)
distance.cdist([sel_lat,sel_lon],latLon_pairsGrid,'euclidean')
Any help or hints would be appreciated
Checkout the pyresample package. It provides spatial nearest neighbour search using a fast kdtree approach:
import pyresample
import numpy as np
# Define lat-lon grid
lon = np.linspace(30, 40, 100)
lat = np.linspace(10, 20, 100)
lon_grid, lat_grid = np.meshgrid(lon, lat)
grid = pyresample.geometry.GridDefinition(lats=lat_grid, lons=lon_grid)
# Generate some random data on the grid
data_grid = np.random.rand(lon_grid.shape[0], lon_grid.shape[1])
# Define some sample points
my_lons = np.array([34.5, 36.5, 38.5])
my_lats = np.array([12.0, 14.0, 16.0])
swath = pyresample.geometry.SwathDefinition(lons=my_lons, lats=my_lats)
# Determine nearest (w.r.t. great circle distance) neighbour in the grid.
_, _, index_array, distance_array = pyresample.kd_tree.get_neighbour_info(
source_geo_def=grid, target_geo_def=swath, radius_of_influence=50000,
neighbours=1)
# get_neighbour_info() returns indices in the flattened lat/lon grid. Compute
# the 2D grid indices:
index_array_2d = np.unravel_index(index_array, grid.shape)
print "Indices of nearest neighbours:", index_array_2d
print "Longitude of nearest neighbours:", lon_grid[index_array_2d]
print "Latitude of nearest neighbours:", lat_grid[index_array_2d]
print "Great Circle Distance:", distance_array
There is also a shorthand method for directly obtaining the data values at the nearest grid points:
data_swath = pyresample.kd_tree.resample_nearest(
source_geo_def=grid, target_geo_def=swath, data=data_grid,
radius_of_influence=50000)
print "Data at nearest grid points:", data_swath
I think I found an answer, but it is a workaround that avoids calculating distance between the chosen lat/lon and the lat/lons on the grid. This doesn't seem completely accurate because I am never calculating distances, just the closest difference between lat/lon values themselves.
I used the answer to the question find (i,j) location of closest (long,lat) values in a 2D array
a = abs(lats-sel_lat)+abs(lons-sel_lon)
i,j = np.unravel_index(a.argmin(),a.shape)
Using those returned indices i,j, I can then find on the grid the coordinates that correspond most closely to my selected lat, lon value:
>>> lats[i,j]
71.490295
>>> lons[i,j]
-161.65045