Skip to content

Commit

Permalink
Change common import in all modules (#980)
Browse files Browse the repository at this point in the history
* Change common import in maplibre

* Fix bug

* Import get_api_key

* Update leafmap module

* Update leafmap and folium modules

* Update more modules

* Update more modules

* Fix import error

* Add Any import

* Update pc import

* Add missing import

* Fix all maplibre examples

* Update all modules
  • Loading branch information
giswqs authored Nov 16, 2024
1 parent 142cb07 commit d6de523
Show file tree
Hide file tree
Showing 13 changed files with 710 additions and 319 deletions.
73 changes: 58 additions & 15 deletions leafmap/bokehmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,52 @@
from bokeh.plotting import figure, show, save
from bokeh.io import output_notebook
from .basemaps import xyz_to_bokeh
from .common import *
from . import common
from typing import Optional, List, Dict

from .common import (
add_crs,
basemap_xyz_tiles,
cog_bands,
cog_bounds,
cog_center,
cog_tile,
convert_lidar,
csv_to_df,
csv_to_geojson,
csv_to_shp,
download_file,
download_from_url,
download_ned,
gdf_to_geojson,
get_api_key,
get_census_dict,
image_to_numpy,
netcdf_to_tif,
numpy_to_cog,
planet_monthly_tiles,
planet_quarterly_tiles,
planet_tiles,
plot_raster,
plot_raster_3d,
pmtiles_metadata,
pmtiles_style,
read_lidar,
read_netcdf,
search_qms,
search_xyz_services,
set_api_key,
stac_assets,
stac_bands,
stac_bounds,
stac_center,
stac_info,
stac_stats,
stac_tile,
view_lidar,
write_lidar,
)

os.environ["OUTPUT_NOTEBOOK"] = "False"
basemaps = Box(xyz_to_bokeh(), frozen_box=True)

Expand Down Expand Up @@ -36,9 +79,9 @@ def __init__(
kwargs["height"] = height

if "x_range" not in kwargs:
kwargs["x_range"] = center_zoom_to_xy_range(center, zoom)[0]
kwargs["x_range"] = common.center_zoom_to_xy_range(center, zoom)[0]
if "y_range" not in kwargs:
kwargs["y_range"] = center_zoom_to_xy_range(center, zoom)[1]
kwargs["y_range"] = common.center_zoom_to_xy_range(center, zoom)[1]

fig = figure(**kwargs)
self.figure = fig
Expand Down Expand Up @@ -150,7 +193,7 @@ def add_cog_layer(
apply a rescaling to multiple bands, use something like `rescale=["164,223","130,211","99,212"]`.
**kwargs: Arbitrary keyword arguments for bokeh.figure.add_tile() function, such as alpha, visible, etc.
"""
tile_url = cog_tile(url, bands, titiler_endpoint, **cog_args)
tile_url = common.cog_tile(url, bands, titiler_endpoint, **cog_args)
tile_options = {
"url": tile_url,
"attribution": attribution,
Expand All @@ -159,7 +202,7 @@ def add_cog_layer(
self.figure.add_tile(tile_source, **kwargs)

if fit_bounds:
self.fit_bounds(cog_bounds(url, titiler_endpoint))
self.fit_bounds(common.cog_bounds(url, titiler_endpoint))

def add_raster(
self,
Expand Down Expand Up @@ -197,9 +240,9 @@ def add_raster(
"""

if source.startswith("http"):
source = download_file(source)
source = common.download_file(source)

tile_layer, client = get_local_tile_layer(
tile_layer, client = common.get_local_tile_layer(
source,
indexes=indexes,
colormap=colormap,
Expand Down Expand Up @@ -252,7 +295,7 @@ def add_stac_layer(
**kwargs: Arbitrary keyword arguments for bokeh.figure.add_tile() function, such as alpha, visible, etc.
"""
tile_url = stac_tile(
tile_url = common.stac_tile(
url, collection, item, assets, bands, titiler_endpoint, **open_args
)
tile_options = {
Expand All @@ -263,7 +306,7 @@ def add_stac_layer(
self.figure.add_tile(tile_source, **kwargs)

if fit_bounds:
self.fit_bounds(stac_bounds(url, collection, item, titiler_endpoint))
self.fit_bounds(common.stac_bounds(url, collection, item, titiler_endpoint))

def add_gdf(
self,
Expand All @@ -287,7 +330,7 @@ def add_gdf(
if not isinstance(gdf, gpd.GeoDataFrame):
raise TypeError("gdf must be a GeoDataFrame")

geom_type = gdf_geom_type(gdf)
geom_type = common.gdf_geom_type(gdf)
gdf_new = gdf.to_crs(to_crs)

columns = gdf_new.columns.to_list()
Expand Down Expand Up @@ -340,7 +383,7 @@ def add_geojson(
import geopandas as gpd

if filename.startswith("http"):
filename = github_raw_url(filename)
filename = common.github_raw_url(filename)

gdf = gpd.read_file(filename, encoding=encoding, **read_file_args)
self.add_gdf(
Expand Down Expand Up @@ -374,15 +417,15 @@ def add_shp(
import glob

if filename.startswith("http"):
filename = github_raw_url(filename)
filename = common.github_raw_url(filename)

if filename.startswith("http") and filename.endswith(".zip"):
out_dir = os.path.abspath("./cache/shp")
if not os.path.exists(out_dir):
os.makedirs(out_dir)
basename = os.path.basename(filename)
output = os.path.join(out_dir, basename)
download_file(filename, output)
common.download_file(filename, output)
files = list(glob.glob(os.path.join(out_dir, "*.shp")))
if len(files) > 0:
filename = files[0]
Expand Down Expand Up @@ -425,7 +468,7 @@ def add_vector(
import geopandas as gpd

if filename.startswith("http"):
filename = github_raw_url(filename)
filename = common.github_raw_url(filename)

if isinstance(filename, gpd.GeoDataFrame):
gdf = filename
Expand Down Expand Up @@ -455,7 +498,7 @@ def fit_bounds(self, bounds: List[float]):
bounds (list): A list of bounds in the form of [xmin, ymin, xmax, ymax].
"""

bounds = bounds_to_xy_range(bounds)
bounds = common.bounds_to_xy_range(bounds)

self.figure.x_range.start = bounds[0][0]
self.figure.x_range.end = bounds[0][1]
Expand Down
95 changes: 61 additions & 34 deletions leafmap/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import whitebox
import subprocess
from pathlib import Path
from typing import Union, List, Dict, Optional, Tuple, TYPE_CHECKING
from typing import Union, List, Dict, Optional, Tuple, TYPE_CHECKING, Any
from .stac import *

try:
Expand Down Expand Up @@ -1781,19 +1781,18 @@ def get_api_key(name: Optional[str] = None, key: Optional[str] = None) -> Option
Returns:
Optional[str]: The retrieved key, or None if no key was found.
"""

if key is not None:
return key
elif name is not None:
if _in_colab_shell():
from google.colab import userdata # pylint: disable=E0611
if name is not None:
try:
if _in_colab_shell():
from google.colab import userdata # pylint: disable=E0611

try:
return userdata.get(name)
except:
return os.environ.get(name)
else:
return os.environ.get(name)
except Exception:
pass
return os.environ.get(name)
return None


def set_api_key(key: str, name: str = "GOOGLE_MAPS_API_KEY"):
Expand Down Expand Up @@ -6297,7 +6296,6 @@ def meters_to_lnglat(x, y):
Returns:
tuple: A tuple of (longitude, latitude) in decimal degrees.
"""
import numpy as np

origin_shift = np.pi * 6378137
longitude = (x / origin_shift) * 180.0
Expand All @@ -6308,26 +6306,42 @@ def meters_to_lnglat(x, y):
return (longitude, latitude)


def bounds_to_xy_range(bounds):
"""Convert bounds to x and y range to be used as input to bokeh map.
def bounds_to_xy_range(
bounds: Union[
List[Union[Tuple[float, float], float]], Tuple[float, float, float, float]
]
) -> Tuple[Tuple[float, float], Tuple[float, float]]:
"""
Convert bounds to x and y range to be used as input to bokeh map.

Args:
bounds (list): A list of bounds in the form [(south, west), (north, east)] or [xmin, ymin, xmax, ymax].
bounds (Union[List[Union[Tuple[float, float], float]], Tuple[float, float, float, float]]):
A list of bounds in the form [(south, west), (north, east)] or [xmin, ymin, xmax, ymax].

Returns:
tuple: A tuple of (x_range, y_range).
Tuple[Tuple[float, float], Tuple[float, float]]: A tuple of (x_range, y_range).
"""

if isinstance(bounds, tuple):
bounds = list(bounds)
elif not isinstance(bounds, list):
raise TypeError("bounds must be a list")

if len(bounds) == 4:
if len(bounds) != 4:
raise ValueError(
"Tuple bounds must have exactly 4 elements (xmin, ymin, xmax, ymax)."
)
west, south, east, north = bounds
elif len(bounds) == 2:
south, west = bounds[0]
north, east = bounds[1]
elif isinstance(bounds, list):
if len(bounds) == 2 and all(
isinstance(coord, tuple) and len(coord) == 2 for coord in bounds
):
(south, west), (north, east) = bounds
elif len(bounds) == 4 and all(
isinstance(coord, (int, float)) for coord in bounds
):
west, south, east, north = bounds
else:
raise ValueError(
"List bounds must be in the form [(south, west), (north, east)] or [xmin, ymin, xmax, ymax]."
)
else:
raise TypeError("bounds must be a list or tuple")

xmin, ymin = lnglat_to_meters(west, south)
xmax, ymax = lnglat_to_meters(east, north)
Expand Down Expand Up @@ -6649,6 +6663,9 @@ def vector_area(vector, unit="m2", crs="epsg:3857"):
gdf = gpd.read_file(vector)
elif isinstance(vector, gpd.GeoDataFrame):
gdf = vector
else:
gdf = None
raise ValueError("Invalid input vector.")

area = gdf.to_crs(crs).area.sum()

Expand Down Expand Up @@ -10096,6 +10113,8 @@ def split_raster(filename, out_dir, tile_size=256, overlap=0, prefix="tile"):
elif isinstance(tile_size, tuple):
tile_width = tile_size[0]
tile_height = tile_size[1]
else:
raise ValueError("tile_size must be an integer or a tuple of (width, height)")

# Get the size of the input raster
width = ds.RasterXSize
Expand Down Expand Up @@ -10376,6 +10395,8 @@ def install_package(package):

if isinstance(package, str):
packages = [package]
elif isinstance(package, list):
packages = package

for package in packages:
if package.startswith("https"):
Expand Down Expand Up @@ -10875,7 +10896,7 @@ def merge_vector(
quiet: bool = False,
return_gdf: bool = False,
**kwargs,
):
) -> Optional["gpd.GeoDataFrame"]:
"""
Merge vector files into a single GeoDataFrame.

Expand Down Expand Up @@ -11458,8 +11479,6 @@ def mbtiles_to_pmtiles(
Returns:
None: The function returns None either upon successful completion or when the pmtiles package is not installed.

Raises:
Any exception raised by pmtiles.convert.mbtiles_to_pmtiles will be propagated up.
"""

import pmtiles.convert as convert
Expand Down Expand Up @@ -11984,10 +12003,14 @@ def blend_images(
Returns:
numpy.ndarray: The blended image as a NumPy array.
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt

try:
import cv2
except ImportError:
raise ImportError("The blend_images function requires the OpenCV library.")

# Resize the images to have the same dimensions
if isinstance(img1, str):
if img1.startswith("http"):
Expand Down Expand Up @@ -13183,11 +13206,11 @@ def nasa_data_login(strategy: str = "all", persist: bool = False, **kwargs) -> N

Args:
strategy (str, optional): The authentication method.
"all": (default) try all methods until one works
"interactive": enter username and password.
"netrc": retrieve username and password from ~/.netrc.
"environment": retrieve username and password from $EARTHDATA_USERNAME and $EARTHDATA_PASSWORD.
persist (bool, optional): Whether to persist credentials in a .netrc file. Defaults to False.
"all": (default) try all methods until one works
"interactive": enter username and password.
"netrc": retrieve username and password from ~/.netrc.
"environment": retrieve username and password from $EARTHDATA_USERNAME and $EARTHDATA_PASSWORD.
persist (bool, optional): Whether to persist credentials in a .netrc file. Defaults to False.
**kwargs: Additional keyword arguments for the earthaccess.login() function.
"""
try:
Expand Down Expand Up @@ -13299,7 +13322,10 @@ def nasa_data_search(
Returns:
Union[List[dict], tuple]: The retrieved granules. If return_gdf is True, also returns the resulting GeoDataFrame.
"""
import earthaccess
try:
import earthaccess
except ImportError:
install_package("earthaccess")

if short_name is not None:
kwargs["short_name"] = short_name
Expand Down Expand Up @@ -14551,6 +14577,7 @@ def detect_geometry_type(geometry):
raise ValueError("Unsupported geometry type or invalid geometry structure.")

# Convert GeoDataFrame to a dictionary if needed
geometry_type = None
if isinstance(geometry, gpd.GeoDataFrame):
geometry_dict = _convert_geodataframe_to_esri_format(geometry)[0]
geometry_type = detect_geometry_type(geometry_dict)
Expand Down
Loading

0 comments on commit d6de523

Please sign in to comment.