+
+Once at the Javascript module level, all Leaflet based map widgets
+should use the `ckan.commonLeafletMap` constructor to initialize the
+map. It accepts the following parameters:
+
+- `container`: HTML element or id of the map container
+- `mapConfig`: (Optional) CKAN config related to the common base layer
+- `leafletMapOptions`: (Optional) Options to pass to the Leaflet Map
+ constructor
+- `leafletBaseLayerOptions`: (Optional) Options to pass to the Leaflet
+ TileLayer constructor
+
+Most of the times you will want to do something like this for a sidebar
+map:
+
+ var map = ckan.commonLeafletMap('dataset-map-container', this.options.map_config, {attributionControl: false});
+
+And this for a primary content map:
+
+ var map = ckan.commonLeafletMap('map', this.options.map_config);
diff --git a/doc/map-widgets.rst b/doc/map-widgets.rst
deleted file mode 100644
index fc67d851..00000000
--- a/doc/map-widgets.rst
+++ /dev/null
@@ -1,135 +0,0 @@
-Common base layers for Map Widgets
-==================================
-
-To provide a consistent look and feel and avoiding code duplication, the map
-widgets (at least the ones based on `Leaflet`_) can use a common function to
-create the map. The base layer that the map will use can be configured via
-configuration options.
-
-.. image:: _static/base-map-stamen.png
-
-Configuring the base layer
---------------------------
-
-The map widgets use the `Leaflet-providers`_ library to make easy to choose the
-base tile layer that the map widgets will use. You can use any of the supported
-providers, which are listed in the `preview page`_.
-
-.. note:: As of October 2023, most if not all of the tile providers require at
- least some form of registration and / or domain registering. They also have
- terms of use and will most likely require proper attribution (which should be
- handled automatically for you when choosing a provider).
-
-If you haven't configured a map provider you will see the following notice in the
-map widgets:
-
-.. image:: _static/no-map-provider.png
-
-The main configuration option to manage the base layer used is
-``ckanext.spatial.common_map.type``. The value of this setting should be one of the
-provider names supported by Leaflet-providers, e.g. ``Stadia.StamenTerrain``, ``Stadia``,
-``MapBox``, ``Herev3.terrainDay``, ``Esri.WorldImagery``, ``USGS.USImagery`` etc. Note
-that these values are **case-sensitive**.
-
-Any additional configuration options required by Leaflet-providers should be set prefixed
-with ``ckanext.spatial.common_map.``, for instance to configure the Stamen Terrain map that
-was used in previous versions of ckanext-spatial::
-
- # Stadia / Stamen Terrain
- ckanext.spatial.common_map.type = Stadia.StamenTerrain
- ckanext.spatial.common_map.apikey =
-
-To use MapBox tiles::
-
- # MapBox
- ckanext.spatial.common_map.type = MapBox
- ckanext.spatial.common_map.mapbox.id =
- ckanext.spatial.common_map.mapbox.accessToken =
-
-
-Custom layers
-+++++++++++++
-
-You can use any tileset that follows the `XYZ convention`_ using the ``custom``
-type::
-
- ckanext.spatial.common_map.type = custom
-
-You will need to define the tileset URL using
-``ckanext.spatial.common_map.custom_url``. This follows the `Leaflet URL
-template`_ format (ie {s} for subdomains if any, {z} for zoom and {x} {y} for
-tile coordinates). Additionally you can use
-``ckanext.spatial.common_map.subdomains`` and
-``ckanext.spatial.common_map.attribution`` if needed (this one will also work
-for Leaflet-provider layers if you want to tweak the default attribution).
-
-For example::
-
- ckanext.spatial.common_map.type = custom
- ckanext.spatial.common_map.custom_url = https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}
- ckanext.spatial.common_map.attribution = Tiles courtesy of the U.S. Geological Survey
-
-Old Stamen tiles
-++++++++++++++++
-
-Previous versions of ckanext-spatial defaulted to using the `Stamen`_ terrain tiles as they
-not require registration. These were deprecated and stopped working on October 2023. If you see
-this error displayed in your map widgets, you need to configure an alternative provider using the
-methods described in the sections above:
-
-.. image:: _static/stamen-map-provider-error.png
-
-
-
-For developers
---------------
-
-To pass the base map configuration options to the relevant Javascript module
-that will initialize the map widget, use the ``h.get_common_map_config()``
-helper function. This is available when loading the ``spatial_metadata``
-plugin. If you don't want to require this plugin, create a new helper function
-that points to it to avoid duplicating the names, which CKAN won't allow (see
-for instance how the GeoJSON preview plugin does it).
-
-The function will return a dictionary with all configuration options that
-relate to the common base layer (that's all that start with
-``ckanext.spatial.common_map.``)
-
-You will need to dump the dict as JSON on the ``data-module-map_config``
-attribute (see for instance the ``dataset_map_base.html`` and
-``spatial_query.html`` snippets)::
-
- {% set map_config = h.get_common_map_config() %}
-
-
-
-
-Once at the Javascript module level, all Leaflet based map widgets should use
-the ``ckan.commonLeafletMap`` constructor to initialize the map. It accepts the
-following parameters:
-
-* ``container``: HTML element or id of the map container
-* ``mapConfig``: (Optional) CKAN config related to the common base layer
-* ``leafletMapOptions``: (Optional) Options to pass to the Leaflet Map constructor
-* ``leafletBaseLayerOptions``: (Optional) Options to pass to the Leaflet TileLayer
- constructor
-
-Most of the times you will want to do something like this for a sidebar map::
-
- var map = ckan.commonLeafletMap('dataset-map-container', this.options.map_config, {attributionControl: false});
-
-And this for a primary content map::
-
- var map = ckan.commonLeafletMap('map', this.options.map_config);
-
-
-.. _Leaflet: http://leafletjs.com
-.. _OpenStreetMap: http://openstreetmap.org
-.. _`XYZ convention`: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
-.. _MapBox: http://www.mapbox.com/
-.. _MapBox Studio: https://www.mapbox.com/mapbox-studio
-.. _here: http://www.mapbox.com/developers/api-overview/
-.. _`Leaflet URL template`: http://leafletjs.com/reference.html#url-template
-.. _Stamen: http://maps.stamen.com/
-.. _`Leaflet-providers`: https://github.com/leaflet-extras/leaflet-providers
-.. _`preview page`: http://leaflet-extras.github.io/leaflet-providers/preview/index.html
diff --git a/doc/previews.md b/doc/previews.md
new file mode 100644
index 00000000..a15e132f
--- /dev/null
+++ b/doc/previews.md
@@ -0,0 +1,8 @@
+# Previews for Spatial Formats
+
+!!! Note
+ The view plugins for rendering spatial formats can be found in
+ [ckanext-geoview](https://github.com/ckan/ckanext-geoview), which
+ contains view plugins based on [OpenLayers](http://openlayers.org) and
+ [Leaflet](http://leafletjs.org) to display several geospatial files and
+ services in CKAN.
diff --git a/doc/previews.rst b/doc/previews.rst
deleted file mode 100644
index 274e57b0..00000000
--- a/doc/previews.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-============================
-Previews for Spatial Formats
-============================
-
-.. note:: The view plugins for rendering spatial formats have
- been moved to ckanext-geoview_, which contains view plugins
- based on OpenLayers_ and Leaflet_ to display several geospatial files
- and services in CKAN.
-
-.. _Leaflet: http://leafletjs.org
-.. _OpenLayers: http://openlayers.org
-.. _ckanext-geoview: https://github.com/ckan/ckanext-geoview
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 00000000..4c8f017d
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1 @@
+mkdocs-material
diff --git a/doc/spatial-search.md b/doc/spatial-search.md
new file mode 100644
index 00000000..f3d76fcc
--- /dev/null
+++ b/doc/spatial-search.md
@@ -0,0 +1,297 @@
+# Spatial Search
+
+The spatial extension allows to index datasets with spatial information
+so they can be filtered via a spatial search query. This includes both
+via the web interface (see the [Spatial Search
+Widget](#spatial-search-widget)) or via the [action
+API](https://docs.ckan.org/en/latest/api/), e.g.:
+
+ http://localhost:5000/api/3/action/package_search?q=Pollution&ext_bbox=-7.535093,49.208494,3.890688,57.372349
+
+The `ext_bbox` parameter must be provided in the form
+`ext_bbox={minx},{miny},{maxx},{maxy}`
+
+## Setup
+
+To enable the spatial search you need to add the `spatial_query` plugin
+to your ini file. This plugin in turn requires the `spatial_metadata`
+plugin, eg:
+
+ ckan.plugins = ... spatial_metadata spatial_query
+
+To define which backend to use for the spatial search use the following
+configuration option (see [Choosing a backend for the spatial
+search](#choosing-a-backend-for-the-spatial-search)):
+
+ ckanext.spatial.search_backend = solr-bbox
+
+## Geo-Indexing your datasets
+
+Regardless of the backend that you are using, in order to make a dataset
+searchable by location, it must have a the location information (a
+geometry), indexed in Solr. You can provide this information in two
+ways.
+
+### The `spatial` extra field
+
+The easiest way to get your geometries indexed is to use an extra field
+named `spatial`. The value of this extra should be a valid
+[GeoJSON](http://geojson.org) geometry, for example:
+
+ {
+ "type":"Polygon",
+ "coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]
+ }
+
+or:
+
+ {
+ "type": "Point",
+ "coordinates": [-3.145,53.078]
+ }
+
+Every time a dataset is created, updated or deleted, the extension will
+index the information stored in the `spatial` in Solr, so it can be
+reflected on spatial searches.
+
+If you already have datasets when you enable Spatial Search then you'll
+need to [rebuild the search
+index](https://docs.ckan.org/en/latest/maintaining/cli.html?#search-index-rebuild-search-index).
+
+### Custom indexing logic
+
+You might not want to use the `spatial` extra field. Perhaps you don't
+want to store the geometries in the dataset metadata but prefer to do so
+in a separate table, or you simply want to perform a different
+processing on the geometries before indexing.
+
+In this case you need to implement the `before_dataset_index()` method
+of the
+[IPackageController](https://docs.ckan.org/en/latest/extensions/plugin-interfaces.html#ckan.plugins.interfaces.IPackageController.before_dataset_index)
+interface:
+
+```python
+def before_dataset_index(self, dataset_dict):
+
+ # When using the default `solr-bbox` backend (based on bounding boxes), you need to
+ # include the following fields in the returned dataset_dict:
+
+ dataset_dict["minx"] = minx
+ dataset_dict["maxx"] = maxx
+ dataset_dict["miny"] = miny
+ dataset_dict["maxy"] = maxy
+
+ # When using the `solr-spatial-field` backend, you need to include the `spatial_geom`
+ # field in the returned dataset_dict. This should be a valid geometry in WKT format.
+ # Shapely can help you get the WKT representation of your gemetry if you have it in GeoJSON:
+
+ shape = shapely.geometry.shape(geometry)
+ wkt = shape.wkt
+
+ dataset_dict["spatial_geom"] = wkt
+
+ # Don't forget to actually return the dict!
+
+ return dataset_dict
+```
+
+Some things to keep in mind:
+
+- Remember, you only need to provide one field, either `spatial_bbox`
+ or `spatial_geom`, depending on the backend chosen.
+
+- All indexed geometries should fall within the -180, -90, 180, 90
+ bounds. If you have polygons crossing the antimeridian (i.e. with
+ longituded lower than -180 or bigger than 180) you'll have to split
+ them across the antimeridian.
+
+- Check the default implementation of `before_dataset_index()` in
+ [ckanext/spatial/plugins/\_\_init\_\_.py](https://github.com/ckan/ckanext-spatial/blob/master/ckanext/spatial/plugin/__init__.py)
+ for extra useful checks and validations.
+
+- If you want to store the geometry in the `spatial` field but don't
+ want to apply the default automatic indexing logic applied by
+ ckanext-spatial just remove the field from the dict (this won't
+ remove it from the dataset metadata, just from the indexed data):
+
+ ```python
+ def before_dataset_search(self, dataset_dict):
+
+ dataset_dict.pop("spatial", None)
+
+ return dataset_dict
+ ```
+
+### Choosing a backend for the spatial search
+
+Ckanext-spatial uses Solr to power the spatial search. The current
+implementation is tested on Solr 9, which is the supported version,
+although it might work on previous Solr versions.
+
+!!! Note
+ The are official [Docker images for
+ Solr](https://github.com/ckan/ckan-solr) that have all the configuration
+ needed to perform spatial searches (look for the ones with a `-spatial`
+ suffix). This is the easiest way to get started but if you need to
+ customize Solr yourself see below for the modifications needed.
+
+There are different backends supported for the spatial search, it is
+important to understand their differences and the necessary setup
+required when choosing which one to use. To configure the search backend
+use the following configuration option:
+
+ ckanext.spatial.search_backend = solr-bbox | solr-spatial-field
+
+The following table summarizes the different spatial search backends:
+
+ | Backend | Supported geometries indexed in Solr | Solr setup needed |
+ |-----------------------|- ------------------------------- ----|---------------------|
+ | `solr-bbox` (default) | Bounding Box, Polygon (extents only) | Custom fields |
+ | `solr-spatial-field` | Bounding Box, Point and Polygon | Custom field + JTS |
+
+!!! Note
+ The default `solr-bbox` search backend was previously known as `solr`.
+ Please update your configuration if using this version as it will be
+ removed in the future.
+
+The `solr-bbox` backend is probably a good starting point. Here are more
+details about the available options (again, you don't need to modify
+Solr if you are using one of the spatially enabled official Docker
+images):
+
+- `solr-bbox`:
+ This option always indexes just the extent of the provided
+ geometries, whether if it's an actual bounding box or not. It
+ supports spatial sorting of the returned results (based on the
+ closeness of their bounding box to the query bounding box). It
+ uses standard Solr float fields so you just need to add the
+ following to your Solr schema:
+ ```xml
+
+
+
+
+
+
+
+ ```
+- `solr-spatial-field`:
+ This option uses the [RPT](https://solr.apache.org/guide/8_11/spatial-search.html#rpt)
+ Solr field, which allows to index points, rectangles and more
+ complex geometries like polygons. This requires the install of
+ the [JTS](https://github.com/locationtech/jts) library. See the
+ linked Solr documentation for details on this. Note that it does
+ not support spatial sorting of the returned results. You will
+ need to add the following field type and field to your Solr
+ schema file to enable it :
+ ```xml
+
+
+
+
+
+
+
+
+
+ ```
+ By default, the `solr-sptatial-field` backend uses the following
+ query. This can be customized by setting the
+ `ckanext.spatial.solr_query` configuration option, but note that
+ all placeholders must be included:
+ ```
+ {{!field f=spatial_geom}}Intersects(ENVELOPE({minx}, {maxx}, {maxy}, {miny}))
+ ```
+
+!!! Note
+ The old `postgis` search backend is no longer supported. You should
+ migrate to one of the other backends instead.
+
+## Spatial Search Widget
+
+![image](_static/spatial-search-widget.png)
+
+The extension provides a snippet to add a map widget to the search form,
+which allows filtering results by an area of interest.
+
+To add the map widget to the sidebar of the search page, add the
+following block to the dataset search page template
+(`myproj/ckanext/myproj/templates/package/search.html`). If your custom
+theme is simply extending the CKAN default theme, you will need to add
+`{% ckan_extends %}` to the start of your custom search.html, then
+continue with this:
+
+ {% block secondary_content %}
+
+ {% snippet "spatial/snippets/spatial_query.html" %}
+
+ {% endblock %}
+
+By default the map widget will show the whole world. If you want to set
+up a different default extent, you can pass an extra `default_extent` to
+the snippet, either with a pair of coordinates like this:
+
+ {% snippet "spatial/snippets/spatial_query.html", default_extent="[[15.62,
+ -139.21], [64.92, -61.87]]" %}
+
+or with a GeoJSON object describing a bounding box (note the escaped
+quotes):
+
+ {% snippet "spatial/snippets/spatial_query.html", default_extent="{ \"type\":
+ \"Polygon\", \"coordinates\": [[[74.89, 29.39],[74.89, 38.45], [60.50,
+ 38.45], [60.50, 29.39], [74.89, 29.39]]]}" %}
+
+You need to load the `spatial_metadata` and `spatial_query` plugins to
+use this snippet.
+
+## Dataset Extent Map
+
+![image](_static/dataset-extent-map.png)
+
+Using the snippets provided, if datasets contain a `spatial` extra like
+the one described in the previous section, a map will be shown on the
+dataset details page.
+
+There are snippets already created to load the map on the left sidebar
+or in the main body of the dataset details page, but these can be easily
+modified to suit your project needs
+
+To add a map to the sidebar, add the following block to the dataset page
+template (eg
+`ckanext-myproj/ckanext/myproj/templates/package/read_base.html`). If
+your custom theme is simply extending the CKAN default theme, you will
+need to add `{% ckan_extends %}` to the start of your custom read.html,
+then continue with this:
+
+ {% block secondary_content %}
+ {{ super() }}
+
+ {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %}
+ {% if dataset_extent %}
+ {% snippet "spatial/snippets/dataset_map_sidebar.html", extent=dataset_extent %}
+ {% endif %}
+
+ {% endblock %}
+
+For adding the map to the main body, add this to the main dataset page
+template (eg
+`ckanext-myproj/ckanext/myproj/templates/package/read.html`):
+
+ {% block primary_content_inner %}
+
+ {{ super() }}
+
+ {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %}
+ {% if dataset_extent %}
+ {% snippet "spatial/snippets/dataset_map.html", extent=dataset_extent %}
+ {% endif %}
+
+ {% endblock %}
+
+You need to load the `spatial_metadata` plugin to use these snippets.
diff --git a/doc/spatial-search.rst b/doc/spatial-search.rst
deleted file mode 100644
index a64fec78..00000000
--- a/doc/spatial-search.rst
+++ /dev/null
@@ -1,264 +0,0 @@
-==============
-Spatial Search
-==============
-
-The spatial extension allows to index datasets with spatial information so they
-can be filtered via a spatial search query. This includes both via the web
-interface (see the `Spatial Search Widget`_) or via the `action API`_, e.g.::
-
- http://localhost:5000/api/action/package_search?q=Pollution&ext_bbox=-7.535093,49.208494,3.890688,57.372349
-
-The ``ext_bbox`` parameter must be provided in the form ``ext_bbox={minx},{miny},{maxx},{maxy}``
-
-
-Setup
------
-
-To enable the spatial search you need to add the ``spatial_query`` plugin to
-your ini file. This plugin in turn requires the ``spatial_metadata`` plugin, eg::
-
- ckan.plugins = ... spatial_metadata spatial_query
-
-To define which backend to use for the spatial search use the following
-configuration option (see `Choosing a backend for the spatial search`_)::
-
- ckanext.spatial.search_backend = solr-bbox
-
-
-Geo-Indexing your datasets
---------------------------
-
-Regardless of the backend that you are using, in order to make a dataset
-searchable by location, it must have a the location information (a geometry), indexed in
-Solr. You can provide this information in two ways.
-
-The ``spatial`` extra field
-+++++++++++++++++++++++++++
-
-The easiest way to get your geometries indexed is to use an extra field named ``spatial``.
-The value of this extra should be a valid GeoJSON_ geometry, for example::
-
- {
- "type":"Polygon",
- "coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]
- }
-
-or::
-
- {
- "type": "Point",
- "coordinates": [-3.145,53.078]
- }
-
-
-Every time a dataset is created, updated or deleted, the extension will
-index the information stored in the ``spatial`` in Solr, so it can be reflected on spatial searches.
-
-If you already have datasets when you enable Spatial Search then you'll need to
-`rebuild the search index `_.
-
-
-Custom indexing logic
-+++++++++++++++++++++
-
-You might not want to use the ``spatial`` extra field. Perhaps you don't want to store the geometries
-in the dataset metadata but prefer to do so in a separate table, or you simply want to perform a different
-processing on the geometries before indexing.
-
-In this case you need to implement the ``before_dataset_index()`` method of the `IPackageController `_ interface::
-
- def before_dataset_index(self, dataset_dict):
-
- # When using the default `solr-bbox` backend (based on bounding boxes), you need to
- # include the following fields in the returned dataset_dict:
-
- dataset_dict["minx"] = minx
- dataset_dict["maxx"] = maxx
- dataset_dict["miny"] = miny
- dataset_dict["maxy"] = maxy
-
- # When using the `solr-spatial-field` backend, you need to include the `spatial_geom`
- # field in the returned dataset_dict. This should be a valid geometry in WKT format.
- # Shapely can help you get the WKT representation of your gemetry if you have it in GeoJSON:
-
- shape = shapely.geometry.shape(geometry)
- wkt = shape.wkt
-
- dataset_dict["spatial_geom"] = wkt
-
- # Don't forget to actually return the dict!
-
- return dataset_dict
-
-Some things to keep in mind:
-
-* Remember, you only need to provide one field, either ``spatial_bbox`` or ``spatial_geom``, depending on
- the backend chosen.
-* All indexed geometries should fall within the -180, -90, 180, 90 bounds. If you have polygons crossing the antimeridian (i.e. with longituded lower than -180 or bigger than 180) you'll have to split them across the antimeridian.
-* Check the default implementation of ``before_dataset_index()`` in `ckanext/spatial/plugins/__init__.py `_ for extra useful checks and validations.
-* If you want to store the geometry in the ``spatial`` field but don't want to apply the default automatic indexing logic applied by ckanext-spatial just remove the field from the dict (this won't remove it from the dataset metadata, just from the indexed data)::
-
- def before_dataset_search(self, dataset_dict):
-
- dataset_dict.pop("spatial", None)
-
- return dataset_dict
-
-Choosing a backend for the spatial search
-+++++++++++++++++++++++++++++++++++++++++
-
-Ckanext-spatial uses Solr to power the spatial search. The current implementation is tested on Solr 8, which is the supported version, although it might work on previous Solr versions.
-
-.. note:: The are official `Docker images for Solr `_ that have all the configuration needed to perform spatial searches (look for the ones with a ``-spatial`` suffix). This is the easiest way to get started but if you need to customize Solr yourself see below for the modifications needed.
-
-There are different backends supported for the spatial search, it is important
-to understand their differences and the necessary setup required when choosing
-which one to use. To configure the search backend use the following configuration option::
-
- ckanext.spatial.search_backend = solr-bbox | solr-spatial-field
-
-The following table summarizes the different spatial search backends:
-
-+-------------------------+--------------------------------------+--------------------+
-| Backend | Supported geometries indexed in Solr | Solr setup needed |
-+=========================+======================================+====================+
-| ``solr-bbox`` (default) | Bounding Box, Polygon (extents only) | Custom fields |
-+-------------------------+--------------------------------------+--------------------+
-| ``solr-spatial-field`` | Bounding Box, Point and Polygon | Custom field + JTS |
-+-------------------------+--------------------------------------+--------------------+
-
-.. note:: The default ``solr-bbox`` search backend was previously known as ``solr``. Please update
- your configuration if using this version as it will be removed in the future.
-
-
-The ``solr-bbox`` backend is probably a good starting point. Here are more
-details about the available options (again, you don't need to modify Solr if you are using one of the spatially enabled official Docker images):
-
-* ``solr-bbox``
- This option always indexes just the extent of the provided geometries, whether if it's an
- actual bounding box or not. It supports spatial sorting of the returned results (based on the closeness of their bounding box to the query bounding box). It uses standard Solr float fields so you just need to add the following to your Solr schema::
-
-
-
-
-
-
-
-
-
-* ``solr-spatial-field``
- This option uses the `RPT `_ Solr field, which allows
- to index points, rectangles and more complex geometries like polygons. This requires the install of the `JTS`_ library. See the linked Solr documentation for details on this. Note that it does not support spatial sorting of the returned results.
- You will need to add the following field type and field to your Solr
- schema file to enable it ::
-
-
-
-
-
-
-
-
-
-
-
- By default, the ``solr-sptatial-field`` backend uses the following query. This can be customized by setting the ``ckanext.spatial.solr_query`` configuration option, but note that all placeholders must be included::
-
- "{{!field f=spatial_geom}}Intersects(ENVELOPE({minx}, {maxx}, {maxy}, {miny}))"
-
-.. note:: The old ``postgis`` search backend is no longer supported. You should migrate to one of the other backends instead.
-
-
-
-Spatial Search Widget
----------------------
-
-
-.. image:: _static/spatial-search-widget.png
-
-The extension provides a snippet to add a map widget to the search form, which
-allows filtering results by an area of interest.
-
-To add the map widget to the sidebar of the search page, add the following
-block to the dataset search page template
-(``myproj/ckanext/myproj/templates/package/search.html``). If your custom
-theme is simply extending the CKAN default theme, you will need to add ``{% ckan_extends %}``
-to the start of your custom search.html, then continue with this::
-
- {% block secondary_content %}
-
- {% snippet "spatial/snippets/spatial_query.html" %}
-
- {% endblock %}
-
-By default the map widget will show the whole world. If you want to set up a
-different default extent, you can pass an extra ``default_extent`` to the
-snippet, either with a pair of coordinates like this::
-
- {% snippet "spatial/snippets/spatial_query.html", default_extent="[[15.62,
- -139.21], [64.92, -61.87]]" %}
-
-or with a GeoJSON object describing a bounding box (note the escaped quotes)::
-
- {% snippet "spatial/snippets/spatial_query.html", default_extent="{ \"type\":
- \"Polygon\", \"coordinates\": [[[74.89, 29.39],[74.89, 38.45], [60.50,
- 38.45], [60.50, 29.39], [74.89, 29.39]]]}" %}
-
-You need to load the ``spatial_metadata`` and ``spatial_query`` plugins to use this
-snippet.
-
-
-
-Dataset Extent Map
-------------------
-
-.. image:: _static/dataset-extent-map.png
-
-Using the snippets provided, if datasets contain a ``spatial`` extra like the
-one described in the previous section, a map will be shown on the dataset
-details page.
-
-There are snippets already created to load the map on the left sidebar or in
-the main body of the dataset details page, but these can be easily modified to
-suit your project needs
-
-To add a map to the sidebar, add the following block to the dataset page template (eg
-``ckanext-myproj/ckanext/myproj/templates/package/read_base.html``). If your custom
-theme is simply extending the CKAN default theme, you will need to add ``{% ckan_extends %}``
-to the start of your custom read.html, then continue with this::
-
- {% block secondary_content %}
- {{ super() }}
-
- {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %}
- {% if dataset_extent %}
- {% snippet "spatial/snippets/dataset_map_sidebar.html", extent=dataset_extent %}
- {% endif %}
-
- {% endblock %}
-
-For adding the map to the main body, add this to the main dataset page template (eg
-``ckanext-myproj/ckanext/myproj/templates/package/read.html``)::
-
- {% block primary_content_inner %}
-
- {{ super() }}
-
- {% set dataset_extent = h.get_pkg_dict_extra(c.pkg_dict, 'spatial', '') %}
- {% if dataset_extent %}
- {% snippet "spatial/snippets/dataset_map.html", extent=dataset_extent %}
- {% endif %}
-
- {% endblock %}
-
-You need to load the ``spatial_metadata`` plugin to use these snippets.
-
-.. _action API: http://docs.ckan.org/en/latest/apiv3.html
-.. _JTS: https://github.com/locationtech/jts
-.. _GeoJSON: http://geojson.org
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 00000000..f2eaf75d
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,75 @@
+site_name: ckanext-spatial
+#site_url: https://docs.ckan.org/projects/ckanext-spatial
+site_url: http://localhost:8000
+
+site_description: >-
+ The documentation of ckanext-spatial, a CKAN extension that
+ improves CKAN geospatial capabilities.
+
+
+repo_name: ckan/ckanext-spatial
+repo_url: https://github.com/ckan/ckanext-spatial
+
+docs_dir: doc
+
+theme:
+ name: material
+ palette:
+
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: ckan
+ toggle:
+ icon: material/toggle-switch
+ name: Switch to dark mode
+
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ toggle:
+ icon: material/toggle-switch-off
+ name: Switch to light mode
+
+ logo: _assets/logo.png
+ favicon: _assets/ckan.ico
+ features:
+ - navigation.expand
+ - navigation.footer
+ - navigation.instant
+ - navigation.instant.progress
+ - search.suggest
+ - search.highlight
+ - toc.integrate
+ - content.code.copy
+
+plugins:
+ - search
+
+markdown_extensions:
+ - toc:
+ permalink: true
+ - admonition
+ - pymdownx.highlight:
+ anchor_linenums: true
+ line_spans: __span
+ pygments_lang_class: true
+ - pymdownx.inlinehilite
+ - pymdownx.superfences
+ - pymdownx.tabbed:
+ alternate_style: true
+ - pymdownx.snippets
+
+
+extra_css:
+ - _css/extra.css
+
+nav:
+ - Home: 'index.md'
+ - Installation and setup: 'install.md'
+ - Spatial search: 'spatial-search.md'
+ - Spatial harvesters: 'harvesters.md'
+ - Other features:
+ - CSW: 'csw.md'
+ - Previews of spatial formats: 'previews.md'
+ - Common base layer for map widgets: 'map-widgets.md'
+ - CHANGELOG: 'changelog.md'