Skip to content
Merged
3 changes: 3 additions & 0 deletions docs/images/recipes/component_apps/arcgis.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/recipes/component_apps/geojson.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/recipes/component_apps/overlay_popup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/recipes/component_apps/wms.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions docs/recipes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,14 @@ Databases
recipes/databases/persistent_service images/recipes/persistent_store_icon.png [database, persistent store, service]
recipes/databases/create_database_models images/recipes/database_model_icon.png [database, models, persistent store]
recipes/databases/working_with_database_models images/recipes/working_with_database_icon.png [database, models, persistent store]

Component Apps
++++++++++++++

.. recipe-gallery::
:layout: multi-row

recipes/component_apps/mapping_with_geojson images/recipes/component_apps/geojson.png [component, app, geojson, map, server]
recipes/component_apps/mapping_with_wms images/recipes/component_apps/wms.png [component, app, wms, map, service]
recipes/component_apps/mapping_with_arcgis_rest images/recipes/component_apps/arcgis.png [component, app, arcgis, rest, map, server, service]
recipes/component_apps/mapping_with_popups_and_overlays images/recipes/component_apps/overlay_popup.png [component, app, arcgis, rest, map, server, service]
89 changes: 89 additions & 0 deletions docs/recipes/component_apps/mapping_with_arcgis_rest.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
.. _component_app__mapping_with_argis_rest :



*************************************************
Component Apps: Mapping with ArcGIS REST Services
*************************************************

.. important::

These recipes only apply to Component App development and will not work for Standard Apps.

**Last Updated:** December 2025

Image ArcGIS MapServer
======================

.. code-block:: python

@App.page
def image_arcgis_mapserver(lib):
return lib.tethys.Display(
lib.tethys.Map(
center=[-10997148, 4569099],
zoom=4
)(
lib.ol.layer.Image(
lib.ol.source.ImageArcGISRest(
options=lib.Props(
ratio=1,
params={},
url="https://sampleserver6.arcgisonline.com/ArcGIS/rest/services/USA/MapServer"
)
)
)
)
)


Tile ArcGIS MapServer
=====================

.. code-block:: python

@App.page
def tile_arcgis_mapserver(lib):
return lib.tethys.Display(
lib.tethys.Map(
center=[-10997148, 4569099],
zoom=4
)(
lib.ol.layer.Tile(
extent=[-13884991, 2870341, -7455066, 6338219]
)(
lib.ol.source.TileArcGISRest(
url="https://sampleserver6.arcgisonline.com/ArcGIS/rest/services/USA/MapServer"
)
)
)
)

XYZ Esri
========

.. note::

This example sets ``default_basemap=None`` since the XYZ Esri layer is a basemap.

.. code-block:: python

@App.page
return lib.tethys.Display(
lib.tethys.Map(default_basemap=None)(
lib.ol.layer.WebGLTile(
lib.ol.source.ImageTile(
options=lib.Props(
attributions=(
'Tiles \u00A9 <a href="https://services.arcgisonline.com/ArcGIS/' +
'rest/services/World_Topo_Map/MapServer">ArcGIS</a>'
),
url=(
'https://server.arcgisonline.com/ArcGIS/rest/services/' +
'World_Topo_Map/MapServer/tile/{z}/{y}/{x}'
)
)
)
)
)
)
228 changes: 228 additions & 0 deletions docs/recipes/component_apps/mapping_with_geojson.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
.. _component_app__mapping_with_geojson :



************************************
Component Apps: Mapping with GeoJSON
************************************

.. important::

These recipes only apply to Component App development and will not work for Standard Apps.

**Last Updated:** December 2025

GeoJSON from a URL
==================

.. code-block:: python

@App.page
def geojson_from_url(lib):
return lib.tethys.Display(
lib.tethys.Map(
lib.ol.layer.Vector(
lib.ol.source.Vector(
options=lib.Props(
url="https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson",
format_="GeoJSON"
)
)
)
)
)

GeoJSON from explicit inline
============================

.. code-block:: python

@App.page
def geojson_from_inline(lib):
features, set_features = lib.hooks.use_state({
'type': 'FeatureCollection',
'crs': {
'type': 'name',
'properties': {
'name': 'EPSG:3857',
},
},
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [0, 0],
},
},
{
'type': 'Feature',
'geometry': {
'type': 'LineString',
'coordinates': [
[4e6, -2e6],
[8e6, 2e6],
],
},
},
{
'type': 'Feature',
'geometry': {
'type': 'LineString',
'coordinates': [
[4e6, 2e6],
[8e6, -2e6],
],
},
},
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[-5e6, -1e6],
[-3e6, -1e6],
[-4e6, 1e6],
[-5e6, -1e6],
],
],
},
},
{
'type': 'Feature',
'geometry': {
'type': 'MultiLineString',
'coordinates': [
[
[-1e6, -7.5e5],
[-1e6, 7.5e5],
],
[
[1e6, -7.5e5],
[1e6, 7.5e5],
],
[
[-7.5e5, -1e6],
[7.5e5, -1e6],
],
[
[-7.5e5, 1e6],
[7.5e5, 1e6],
],
],
},
},
{
'type': 'Feature',
'geometry': {
'type': 'MultiPolygon',
'coordinates': [
[
[
[-5e6, 6e6],
[-3e6, 6e6],
[-3e6, 8e6],
[-5e6, 8e6],
[-5e6, 6e6],
],
],
[
[
[-2e6, 6e6],
[0, 6e6],
[0, 8e6],
[-2e6, 8e6],
[-2e6, 6e6],
],
],
[
[
[1e6, 6e6],
[3e6, 6e6],
[3e6, 8e6],
[1e6, 8e6],
[1e6, 6e6],
],
],
],
},
},
{
'type': 'Feature',
'geometry': {
'type': 'GeometryCollection',
'geometries': [
{
'type': 'LineString',
'coordinates': [
[-5e6, -5e6],
[0, -5e6],
],
},
{
'type': 'Point',
'coordinates': [4e6, -5e6],
},
{
'type': 'Polygon',
'coordinates': [
[
[1e6, -6e6],
[3e6, -6e6],
[2e6, -4e6],
[1e6, -6e6],
],
],
},
],
},
},
],
})
return lib.tethys.Display(
lib.tethys.Map(
lib.ol.layer.Vector(
lib.ol.source.Vector(
options=lib.Props(
features=features,
format_="GeoJSON"
)
)
)
)
)


GeoJSON from File / Pandas Dataframe
====================================

.. code-block:: python

import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
from tethys_sdk.components.utils import transform_coordinate

def csv_to_geojson(csv_path):
df = pd.read_csv(csv_path)
geometry = [Point(transform_coordinate(xy, "EPSG:4326", "EPSG:3857")) for xy in zip(df['lat'], df['lon'])]
gdf = gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:3857")
return gdf.to_json()

@App.page
def geojson_from_csv(lib):
resources = lib.hooks.use_resources()
geojson = csv_to_geojson(resources.path / "points.csv")
return lib.tethys.Display(
lib.tethys.Map(
lib.ol.layer.Vector(
lib.ol.source.Vector(
options=lib.Props(
features=geojson,
format_="GeoJSON"
)
)
)
)
)
Loading