How to get the longitude/latitude from a linestring - python

I have a dataframe with a column of linestrings. I want to convert the linestrings to its corresponding latitude/longitude so that I can plot it with basemap. My code is as follows:
gdf = gpd.read_file('./call2016.shp') #read the data into a variable
streetsaslinestring = gdf.loc[: , "geometry"] #getting the linestring column
Next, I want to convert the data as described as lon/lat.
streetsinlatlong = convert_etrs89_to_lonlat(streetsaslinestring)
streetsinlatlong.to_file('./streetslonglat.shp') #store it as .shp in order to plot it with basemap
m.readshapefile('./streetslonglat', 'streets') #read as shape file
The geometry column looks like this:geometry column
How can I convert the longstring data?

I think you can simply use
Lats, Lons = LineStringObject.coords.xy
It will return the latitude and longitude array separately.

Related

Converting Sentinel 3 LST image with netcdf format to tiff with proper coordinates python

I have a Sentinel 3 image which is stored in a number of netcdf files. The variable is stored in the file "LST_in.nc" with dimensions = rows and columns of the image. The lat and long are in another file "geodetic_in.nc". I want to export the image with the lat and long to tiff format.
To my understanding, the names of dimensions and coordinates should be the same, while I failed to do this
here are my attempts
import rioxarray as rio
import xarray as xr
xds = xr.open_dataset('LST_in.nc')
coord =xr.open_dataset('geodetic_in.nc')
lat, lon = coord.latitude_in.data, coord.longitude_in.data
xds = xds.assign_coords({"lat":(["rows","columns"], lat), "lon":(["rows","columns"], lon)})
xds = xds.rename_dims({"rows": "lon", "columns": 'lat'})
Here I received this error
ValueError: Cannot rename rows to lon because lon already exists. Try using swap_dims instead.
Then I tried this
xds = xds.swap_dims({'rows' : 'lon', 'columns' : 'lat'})
but received another error
ValueError: replacement dimension 'lon' is not a 1D variable along the old dimension 'rows'
Also this one
lst = xds.LST
lst.rio.set_spatial_dims(x_dim = 'lon', y_dim = 'lat', inplace = True)
Error: MissingSpatialDimensionError: x dimension (lon) not found. Data variable: LST
The only one that works but with the wrong coordinates is
lst = xds.LST
lst.rio.set_spatial_dims(x_dim = 'columns', y_dim = 'rows', inplace = True)
lst.rio.write_crs("epsg:4326", inplace = True)
lst.rio.to_raster("lst.tif")
I would appreciate your help. attached is the image files
https://wetransfer.com/downloads/e3711adf56f73cd07119b43d19f7360820220117154330/c46b21
The short answer is: you can't. Because both netCDF and grib are gridded data format and the current data points positions can't be described using a regular latitude/longitude grid.
I plotted a sample of your data points latitude and longitude:
As you can see, the data points are not placed on lines of constant latitude and longitude, they do not follow any pattern that could be describe with projected grid, rotated grid or curvilinear grid either.
If you want to make a gridded file with the LST values and latitude and longitude as coordinates, you will have to reproject your data. You can use the rasterio.warp module, see here for more information.

Get nearest pixel value from satellite image using latitude longitude coordinates

I have a satellite image file. Loaded into dask array. I want to get pixel value (nearest) of a latitude, longitude of interest.
Satellite image is in GEOS projection. I have longitude and latitude information as 2D numpy arrays.
Satellite Image file
I have loaded it into a dask data array
from satpy import Scene
import matplotlib as plt
import os
cwd = os.getcwd()
fn = os.path.join(cwd, 'EUMETSAT_data/1Jan21/MSG1-SEVI-MSG15-0100-NA-20210101185741.815000000Z-20210101185757-1479430.nat')
files = [fn]
scn = Scene(filenames=files, reader='seviri_l1b_native')
scn.load(["VIS006"])
da = scn['VIS006']
This is what the dask array looks like:
I read lon lats from the area attribute with the help of satpy:
lon, lat = scn['VIS006'].attrs['area'].get_lonlats()
print(lon.shape)
print(lat.shape)
(1179, 808)
(1179, 808)
I get a 2d numpy array each, for longitude and latitude that are coordinates but I can not use them for slicing or selecting.
What is the best practice/method to get nearest lat long, pixel information?
How do I project the data onto lat long coordinates that I can then use for indexing to arrive at the pixel value.
At the end, I want to get pixel value (nearest) of lat long of interest.
Thanks in advance!!!
The AreaDefinition object you are using (.attrs['area']) has a few methods for getting different coordinate information.
area = scn['VIS006'].attrs['area']
col_idx, row_idx = area.get_xy_from_lonlat(lons, lats)
scn['VIS006'].values[row_idx, col_idx]
Note that row and column are flipped. The get_xy_from_lonlat method should work for arrays or scalars.
There are other methods for getting X/Y coordinates of each pixel if that is what you're interesting in.
You can find the location with following:
import numpy as np
px,py = (23.0,55.0) # some location to take out values:
dist = np.sqrt(np.cos(lat*np.pi/180.0)*(lon-px)**2+(lat-py)**2); # this is the distance matrix from point (px,py)
kkout = np.squeeze(np.where(np.abs(dist)==np.nanmin(dist))); # find location where distance is minimum
print(kkout) # you will see the row and column, where to take out data
#serge ballesta - thanks for the direction
Answering my own question.
Project the latitude and longitude (platecaree projection) onto the GEOS projection CRS. Find x and y. Use this x and y and nearest select method of xarray to get pixel value from dask array.
import cartopy.crs as ccrs
data_crs = ccrs.Geostationary(central_longitude=41.5, satellite_height=35785831, false_easting=0, false_northing=0, globe=None, sweep_axis='y')
lon = 77.541677 # longitude of interest
lat = 8.079148 # latitude of interst
# lon lat system in
x, y = data_crs.transform_point(lon, lat, src_crs=ccrs.PlateCarree())
dn = ds.sel(x=x,y=y, method='nearest')

Expanding coordinates of a variable using other two variables of xarray in Python

Let's say I have data of 16 grid cells (4 * 4) which has a corresponding index (0~15) as dimension & coordinates and variables (a, longitude and latitude) for each cell. Here is the code to create this data.
import xarray as xr
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(16,3), \
columns=['a','longitude', 'latitude'], \
index=range(16))
ds = df.to_xarray()
ds
What I want to do is:
Expand the coordination of data a from (index) to (longitude, latitude) using longitude and latitude variables of each cell.
So, the resulting DataSet will include longitude and latitude as its dimension and coordinates as well as variable a of (longitude, latitude)
How can I do this within xarray functionality?
Thanks!
Here is a way to solve that:
# convert the index as a MultiIndex containing longitude and latitude
dat_2d = ds.set_index({'index': ['longitude', 'latitude']})
# unstack the MultiIndex
unstacked = dat_2d.unstack('index')
# plot
unstacked['a'].plot()

Change order of geo coordinates python

I have a pandas dataframe containing MULTIPOLYGON coordinates in (LON, LAT) format. I need to use this coordinates to add a polygon to an ipyleaflet map but I need to change the order of the coordinates to (LAT, LON)
df['Footprint'][0]
''MULTIPOLYGON (((-3.870231 39.827106,-3.49322 41.329609,-6.624273 41.739006,-6.931492 40.237854,-3.870231 39.827106)))''
# Here in locations, I have manually changed the order
polygon = Polygon(
locations=[(39.827106,-3.870231),(41.329609,-3.49322),(41.739006,-6.624273),(40.237854,-6.931492),(39.827106,-3.870231)],
color="green",
fill_color="green"
)
m = Map(center=(39.5531, -3.6914), zoom=6)
m.add_layer(polygon);
m
Any idea on how to do the trick?

How do I produce a table of converted coordinates from Equatorial to AltAz?

I have tried debugging my code and I've realised that ultimately it breaks down when I try to save my AltAz coordinates into a .csv file because its not a numpy array, its a SkyCoord object. Could someone suggest a simple of way of converting a large table of Equatorial coordinates to AltAz or how I can get my code to save to file.
# Get time now
time = astropy.time.Time.now()
time.delta_ut1_utc = 0
# Geodetic coordinates of observatory (example here: Munich)
observatory = astropy.coordinates.EarthLocation(
lat=48.21*u.deg, lon=11.18*u.deg, height=532*u.m)
# Alt/az reference frame at observatory, now
frame = astropy.coordinates.AltAz(obstime=time, location=observatory)
# Look up (celestial) spherical polar coordinates of HEALPix grid.
theta, phi = hp.pix2ang(nside, np.arange(npix))
# Convert to Equatorial coordinates
radecs = astropy.coordinates.SkyCoord(
ra=phi*u.rad, dec=(0.5*np.pi - theta)*u.rad)
# Transform grid to alt/az coordinates at observatory, now
altaz = radecs.transform_to(frame)
#Transpose array from rows to columns
altaz_trans=np.transpose(altaz)
np.savetxt('altaz.csv',altaz_trans,fmt='%s', delimiter=',')
You'll want to use the to_string() method on altaz. That will give you a list of strings, each entry of which is has an altitude an azimuth number (they are separated by a space, so you can .split() them or whatever). Then you can write it out with numpy or your other library of choice.
Alternately, if you want to go straight to a file, you can create an astropy Table, and have columns 'alt' and 'az' that you respectively set equal to altaz.alt and altaz.az. Then you can .write(format='ascii') that table.

Categories