geosdemo module¶
Main module.
Map (Map)
¶
Source code in geosdemo/geosdemo.py
class Map (ipyleaflet.Map): #we are going to build based on this
def __init__(self, center= [20, 0], zoom= 2, **kwargs) -> None: #needs to be passed back to the ipyleafclass this is why we put center and zoom in __init__
if "scroll_wheel_zoom" not in kwargs:
kwargs["scroll_wheel_zoom"] = True
print(f"this is what the user is providing:{kwargs}") #prints what the user provides
super().__init__(center=center, zoom=zoom, **kwargs) #super means upper label, the class you inherit from. This passes the parameters to geosdemo.py
print(kwargs) #AGAIN FOR DEBUGGING
#11a - adding the layers control as default
if "layers_control" not in kwargs:
kwargs["layers_control"] = True
print(kwargs) #AGAIN LINE FOR DEBUGGING or Checking things are going well
if kwargs["layers_control"]:
self.add_layers_control()
if "fullscreen_control" not in kwargs:
kwargs["fullscreen_control"] = True
if kwargs["fullscreen_control"]:
self.add_fullscreen_control()
print(kwargs)
def add_search_control(self, position="topleft", **kwargs): #based on control example
"""_summary_
Returns:
_type_: _description_
"""
if "url" not in kwargs:
kwargs["url"] = "https://nominatim.openstreetmap.org/search?format=json&q={s}"
search_control = ipyleaflet.SearchControl(position= position, **kwargs) #based on example in https://ipyleaflet.readthedocs.io/en/latest/controls/search_control.html
print(f"this is what the user is providing:{kwargs}")
self.add_control(search_control)
def add_draw_control(self, **kwargs): #based on control example
"""_summary_
"""
draw_control = ipyleaflet.DrawControl(**kwargs)
#customizing the draw control
draw_control.polyline = {
"shapeOptions": {
"color": "#6bc2e5",
"weight": 8,
"opacity": 1.0
}
}
draw_control.polygon = {
"shapeOptions": {
"fillColor": "#6be5c3",
"color": "#6be5c3",
"fillOpacity": 1.0
},
"drawError": {
"color": "#dd253b",
"message": "Oups!"
},
"allowIntersection": False
}
draw_control.circle = {
"shapeOptions": {
"fillColor": "#efed69",
"color": "#efed69",
"fillOpacity": 1.0
}
}
draw_control.rectangle = {
"shapeOptions": {
"fillColor": "#fca45d",
"color": "#fca45d",
"fillOpacity": 1.0
}
}
self.add_control(draw_control)
def add_layers_control(self, position='topright'):
"""_summary_ f
Args:
position (str, optional): _description_. Defaults to 'topright'.
"""
layers_control = ipyleaflet.LayersControl(position=position)
self.add_control(layers_control)
def add_fullscreen_control(self, position="topleft"):
"""Adds a fullscreen control to the map.
Args:
kwargs: Keyword arguments to pass to the fullscreen control.
"""
fullscreen_control = ipyleaflet.FullScreenControl(position=position)
self.add_control(fullscreen_control)
#adding a tile layer
def add_tile_layer(self, url, name, attribution="", **kwargs):
"""Adds a tile layer to the map.
Args:
url (str): The URL of the tile layer.
name (str): The name of the tile layer.
attribution (str, optional): The attribution of the tile layer. Defaults to "".
"""
tile_layer = ipyleaflet.TileLayer(
url=url,
name=name,
attribution=attribution,
**kwargs
)
self.add_layer(tile_layer)
#adding basemap
def add_basemap(self, basemap, **kwargs):
import xyzservices.providers as xyz #if a user wants another map is going tolook in xyz
if basemap.lower() == "roadmap": #the user can insert any form
url = 'http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}'
self.add_tile_layer(url, name=basemap, **kwargs) #name= basemap guarantess that gets the value of the selected
elif basemap.lower() == "satellite":
url = 'http://mt0.google.com/vt/lyrs=y&hl=en&x={x}&y={y}&z={z}'
self.add_tile_layer(url, name=basemap, **kwargs)
else:
try:
basemap = eval(f"xyz.{basemap}")
url = basemap.build_url()
attribution = basemap.attribution
self.add_tile_layer(url, name=basemap.name, attribution=attribution, **kwargs)
except:
raise ValueError(f"Basemap '{basemap}' not found.")
#adding vector data
def add_geojson(self, data, name='GeoJSON', **kwargs):
"""Adds a GeoJSON layer to the map.
Args:
data (dict): The GeoJSON data.
"""
if isinstance(data, str): #isinstance figures out the data type this allows to just read the data without worrying about how to load the geojson
import json
with open(data, "r") as f:
data = json.load(f)
geojson = ipyleaflet.GeoJSON(data=data,name=name, **kwargs)
self.add_layer(geojson)
#we neeed to add geopandas
def add_shp(self, data, name='Shapefile', **kwargs):
"""Adds a Shapefile layer to the map.
Args:
data (str): The path to the Shapefile.
"""
import geopandas as gpd
gdf = gpd.read_file(data)
geojson = gdf.__geo_interface__ #___geointerface___ if we use .tojson we would need to convet it back, thidsconverts to dictionary directly
self.add_geojson(geojson, name=name, **kwargs)
def add_raster(self, url, name='Raster', fit_bounds=True, **kwargs): #Week 12 adding the url using titiler
"""Adds a raster layer to the map. #fit_bounds assigned as True as default
Args:
url (str): The URL of the raster layer.
name (str, optional): The name of the raster layer. Defaults to 'Raster'.
fit_bounds (bool, optional): Whether to fit the map bounds to the raster layer. Defaults to True.
"""
import httpx
titiler_endpoint = "https://titiler.xyz"
r = httpx.get(
f"{titiler_endpoint}/cog/info",
params = {
"url": url,
}
).json()
bounds = r["bounds"]
r = httpx.get(
f"{titiler_endpoint}/cog/tilejson.json",
params = {
"url": url,
}
).json()
tile = r["tiles"][0]
self.add_tile_layer(url=tile, name=name, **kwargs)
if fit_bounds:
bbox = [[bounds[1], bounds[0]], [bounds[3], bounds[2]]]
self.fit_bounds(bbox)
#homework make some modifications to add the functionalities of the widgets
#copying material from toolbar.ipynb
def add_toolbar(self, position="topright"):
widget_width = "250px" #setting the widget width
padding = "0px 0px 0px 5px" # upper, right, bottom, left
#creating the tolbar button
toolbar_button = widgets.ToggleButton(
value=False,
tooltip="Toolbar", #user hover an displays text
icon="wrench", #https://fontawesome.com/v4/icons/
layout=widgets.Layout(width="28px", height="28px", padding=padding),
)
#creating the close button
close_button = widgets.ToggleButton(
value=False,
tooltip="Close the tool",
icon="times",
button_style="primary",
layout=widgets.Layout(height="28px", width="28px", padding=padding),
)
toolbar = widgets.HBox([toolbar_button])
def toolbar_click(change):
if change["new"]:
toolbar.children = [toolbar_button, close_button]
else:
toolbar.children = [toolbar_button]
toolbar_button.observe(toolbar_click, "value") #when is clicked we are going to observe the close button
#value is used in most of the time and means when we click is true and nclick is false
def close_click(change):
if change["new"]:
toolbar_button.close()
close_button.close()
toolbar.close()
close_button.observe(close_click, "value")
rows = 2
cols = 2
grid = widgets.GridspecLayout(rows, cols, grid_gap="0px", layout=widgets.Layout(width="62px"))
icons = ["folder-open", "map", "info", "question"] #names taken from the link above
for i in range(rows):
for j in range(cols):
grid[i, j] = widgets.Button(description="", button_style="primary", icon=icons[i*rows+j],
layout=widgets.Layout(width="28px", padding="0px"))
toolbar = widgets.VBox([toolbar_button])
def toolbar_click(change):
if change["new"]: #means once is clicked
toolbar.children = [widgets.HBox([close_button, toolbar_button]), grid]
else:
toolbar.children = [toolbar_button]
toolbar_button.observe(toolbar_click, "value")
#toolbar_ctrl = ipyleaflet.WidgetControl(widget=toolbar, position="topright") #here we need to addipyleaflet
toolbar_ctrl = ipyleaflet.WidgetControl(widget=toolbar, position=position) #to add flexibility and avoid hard coding of the position
self.add_control(toolbar_ctrl) #self instead of m in the notebook
# def add_local_raster(self, filename, name="Local raster", **kwargs):
# try:
# import localtileserver
# except ImportError:
# raise ImportError("loacltileserver not installed. Please install it with pip install ")
# self.add_tile_layer()
add_draw_control(self, **kwargs)
¶
summary
Source code in geosdemo/geosdemo.py
def add_draw_control(self, **kwargs): #based on control example
"""_summary_
"""
draw_control = ipyleaflet.DrawControl(**kwargs)
#customizing the draw control
draw_control.polyline = {
"shapeOptions": {
"color": "#6bc2e5",
"weight": 8,
"opacity": 1.0
}
}
draw_control.polygon = {
"shapeOptions": {
"fillColor": "#6be5c3",
"color": "#6be5c3",
"fillOpacity": 1.0
},
"drawError": {
"color": "#dd253b",
"message": "Oups!"
},
"allowIntersection": False
}
draw_control.circle = {
"shapeOptions": {
"fillColor": "#efed69",
"color": "#efed69",
"fillOpacity": 1.0
}
}
draw_control.rectangle = {
"shapeOptions": {
"fillColor": "#fca45d",
"color": "#fca45d",
"fillOpacity": 1.0
}
}
self.add_control(draw_control)
add_fullscreen_control(self, position='topleft')
¶
Adds a fullscreen control to the map.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
kwargs |
Keyword arguments to pass to the fullscreen control. |
required |
Source code in geosdemo/geosdemo.py
def add_fullscreen_control(self, position="topleft"):
"""Adds a fullscreen control to the map.
Args:
kwargs: Keyword arguments to pass to the fullscreen control.
"""
fullscreen_control = ipyleaflet.FullScreenControl(position=position)
self.add_control(fullscreen_control)
add_geojson(self, data, name='GeoJSON', **kwargs)
¶
Adds a GeoJSON layer to the map.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data |
dict |
The GeoJSON data. |
required |
Source code in geosdemo/geosdemo.py
def add_geojson(self, data, name='GeoJSON', **kwargs):
"""Adds a GeoJSON layer to the map.
Args:
data (dict): The GeoJSON data.
"""
if isinstance(data, str): #isinstance figures out the data type this allows to just read the data without worrying about how to load the geojson
import json
with open(data, "r") as f:
data = json.load(f)
geojson = ipyleaflet.GeoJSON(data=data,name=name, **kwargs)
self.add_layer(geojson)
add_layers_control(self, position='topright')
¶
summary f
Parameters:
Name | Type | Description | Default |
---|---|---|---|
position |
str |
description. Defaults to 'topright'. |
'topright' |
Source code in geosdemo/geosdemo.py
def add_layers_control(self, position='topright'):
"""_summary_ f
Args:
position (str, optional): _description_. Defaults to 'topright'.
"""
layers_control = ipyleaflet.LayersControl(position=position)
self.add_control(layers_control)
add_raster(self, url, name='Raster', fit_bounds=True, **kwargs)
¶
Adds a raster layer to the map. #fit_bounds assigned as True as default
Parameters:
Name | Type | Description | Default |
---|---|---|---|
url |
str |
The URL of the raster layer. |
required |
name |
str |
The name of the raster layer. Defaults to 'Raster'. |
'Raster' |
fit_bounds |
bool |
Whether to fit the map bounds to the raster layer. Defaults to True. |
True |
Source code in geosdemo/geosdemo.py
def add_raster(self, url, name='Raster', fit_bounds=True, **kwargs): #Week 12 adding the url using titiler
"""Adds a raster layer to the map. #fit_bounds assigned as True as default
Args:
url (str): The URL of the raster layer.
name (str, optional): The name of the raster layer. Defaults to 'Raster'.
fit_bounds (bool, optional): Whether to fit the map bounds to the raster layer. Defaults to True.
"""
import httpx
titiler_endpoint = "https://titiler.xyz"
r = httpx.get(
f"{titiler_endpoint}/cog/info",
params = {
"url": url,
}
).json()
bounds = r["bounds"]
r = httpx.get(
f"{titiler_endpoint}/cog/tilejson.json",
params = {
"url": url,
}
).json()
tile = r["tiles"][0]
self.add_tile_layer(url=tile, name=name, **kwargs)
if fit_bounds:
bbox = [[bounds[1], bounds[0]], [bounds[3], bounds[2]]]
self.fit_bounds(bbox)
add_search_control(self, position='topleft', **kwargs)
¶
summary
Returns:
Type | Description |
---|---|
_type_ |
description |
Source code in geosdemo/geosdemo.py
def add_search_control(self, position="topleft", **kwargs): #based on control example
"""_summary_
Returns:
_type_: _description_
"""
if "url" not in kwargs:
kwargs["url"] = "https://nominatim.openstreetmap.org/search?format=json&q={s}"
search_control = ipyleaflet.SearchControl(position= position, **kwargs) #based on example in https://ipyleaflet.readthedocs.io/en/latest/controls/search_control.html
print(f"this is what the user is providing:{kwargs}")
self.add_control(search_control)
add_shp(self, data, name='Shapefile', **kwargs)
¶
Adds a Shapefile layer to the map.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data |
str |
The path to the Shapefile. |
required |
Source code in geosdemo/geosdemo.py
def add_shp(self, data, name='Shapefile', **kwargs):
"""Adds a Shapefile layer to the map.
Args:
data (str): The path to the Shapefile.
"""
import geopandas as gpd
gdf = gpd.read_file(data)
geojson = gdf.__geo_interface__ #___geointerface___ if we use .tojson we would need to convet it back, thidsconverts to dictionary directly
self.add_geojson(geojson, name=name, **kwargs)
add_tile_layer(self, url, name, attribution='', **kwargs)
¶
Adds a tile layer to the map.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
url |
str |
The URL of the tile layer. |
required |
name |
str |
The name of the tile layer. |
required |
attribution |
str |
The attribution of the tile layer. Defaults to "". |
'' |
Source code in geosdemo/geosdemo.py
def add_tile_layer(self, url, name, attribution="", **kwargs):
"""Adds a tile layer to the map.
Args:
url (str): The URL of the tile layer.
name (str): The name of the tile layer.
attribution (str, optional): The attribution of the tile layer. Defaults to "".
"""
tile_layer = ipyleaflet.TileLayer(
url=url,
name=name,
attribution=attribution,
**kwargs
)
self.add_layer(tile_layer)
generate_lucky_number(length=1)
¶
summary
Parameters:
Name | Type | Description | Default |
---|---|---|---|
length |
int |
description. Defaults to 1. |
1 |
Returns:
Type | Description |
---|---|
_type_ |
description |
Source code in geosdemo/geosdemo.py
def generate_lucky_number(length= 1):
"""_summary_
Args:
length (int, optional): _description_. Defaults to 1.
Returns:
_type_: _description_
"""
result_str = ''.join(random.choice(string.digits) for i in range(length))
return int(result_str)
generate_random_string(length=10, upper=False, digits=False, punctuation=False)
¶
Generates a random string of a given length
Parameters:
Name | Type | Description | Default |
---|---|---|---|
length |
int |
Length of the string. Defaults to 10. |
10 |
upper |
bool |
Whether to include uppercase. Defaults to False. |
False |
digits |
bool |
description. Defaults to False. |
False |
punctuation |
bool |
description. Defaults to False. |
False |
Returns:
Type | Description |
---|---|
str |
The generated string |
Source code in geosdemo/geosdemo.py
def generate_random_string(length= 10, upper= False, digits = False, punctuation= False):
"""Generates a random string of a given length
Args:
length (int, optional): Length of the string. Defaults to 10.
upper (bool, optional): Whether to include uppercase. Defaults to False.
digits (bool, optional): _description_. Defaults to False.
punctuation (bool, optional): _description_. Defaults to False.
Returns:
str: The generated string
"""
letters = string.ascii_lowercase
if upper:
letters += string.ascii_uppercase
if digits:
letters += string.digits
if punctuation:
letters += string.pun
letters = string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str