import solara
import geopandas as gpd
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shapereader
from matplotlib.figure import Figure
satellite_height=solara.reactive(705000)
country=solara.reactive('Saudi Arabia')
countries = shapereader.natural_earth(resolution='110m',
category='cultural',
name='admin_0_countries')
country_shapes = shapereader.Reader(countries)
country_names = [country.attributes['NAME'] for country in country_shapes.records()]
def coord_lister(geom):
return list(geom.exterior.coords)
def patch_from_geom(geom, **kwargs):
"""
Create a mpatch from one geometry
"""
xy = np.array(coord_lister(geom))
return mpatches.Polygon(xy, **kwargs)
def globe_plot(ax, country_shape):
"""
Plots a globe + country shape + region shapes
"""
ax.add_feature(cfeature.OCEAN, zorder=0)
ax.add_feature(cfeature.LAND, zorder=0, edgecolor='black')#, fc="white")
ax.set_global()
# Country shape
country_patch = patch_from_geom(country_shape.geometry, closed=False, edgecolor="black", fill=False,transform=ccrs.Geodetic())
ax.add_patch(country_patch)
ax.gridlines(zorder=0)
@solara.component
def Page():
solara.Select(label='Country', value=country, values=country_names)
solara.InputFloat(label='Satellite height', value=satellite_height)
for c in country_shapes.records():
if c.attributes['NAME'] == country.value:
country_shape = c
break
else:
raise ValueError('Unable to find the selected country boundary.')
centroid = country_shape.geometry.centroid
fig = plt.figure(figsize=(4,4))
globe_proj = ccrs.NearsidePerspective(centroid.x, centroid.y, satellite_height=satellite_height.value)
ax1 = fig.add_subplot(1, 1, 1, projection=globe_proj) # globe
globe_plot(ax1, country_shape)
fig.tight_layout()
solara.FigureMatplotlib(fig, format="png", transparent_bg=True, dpi=300)