2013-09-08 20:42:39 +02:00
|
|
|
==============
|
2013-04-10 18:37:33 +02:00
|
|
|
Spatial Search
|
|
|
|
==============
|
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
The spatial extension allows to index datasets with spatial information so they
|
|
|
|
can be filtered via a spatial query. This includes both via the web interface
|
|
|
|
(see the `Spatial Search Widget`_) or via the `action API`_, e.g.::
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
POST http://localhost:5000/api/action/package_search
|
|
|
|
{ "q": "Pollution",
|
|
|
|
"facet": "true",
|
|
|
|
"facet.field": "country",
|
|
|
|
"extras": {
|
|
|
|
"ext_bbox": "-7.535093,49.208494,3.890688,57.372349" }
|
|
|
|
}
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
.. versionchanged:: 2.0.1
|
|
|
|
Starting from this version the spatial filter it is also supported on GET
|
|
|
|
requests:
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
http://localhost:5000/api/action/package_search?q=Pollution&ext_bbox=-7.535093,49.208494,3.890688,57.372349
|
2013-04-10 18:37:33 +02:00
|
|
|
|
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
Setup
|
|
|
|
-----
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
To enable the spatial query you need to add the ``spatial_query`` plugin to
|
|
|
|
your ini file. This plugin requires the ``spatial_metadata`` plugin, eg::
|
|
|
|
|
|
|
|
ckan.plugins = [other 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
|
2013-04-10 18:37:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
Geo-Indexing your datasets
|
|
|
|
--------------------------
|
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
Regardless of the backend that you are using, in order to make a dataset
|
|
|
|
queryable by location, an special extra must be defined, with its key named
|
|
|
|
'spatial'. The value must be a valid GeoJSON_ geometry, for example::
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
{
|
|
|
|
"type":"Polygon",
|
|
|
|
"coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]
|
|
|
|
}
|
2013-04-10 18:37:33 +02:00
|
|
|
|
|
|
|
or::
|
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
{
|
|
|
|
"type": "Point",
|
|
|
|
"coordinates": [-3.145,53.078]
|
|
|
|
}
|
2013-04-10 18:37:33 +02:00
|
|
|
|
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
Every time a dataset is created, updated or deleted, the extension will
|
|
|
|
synchronize the information stored in the extra with the geometry table.
|
|
|
|
|
|
|
|
Choosing a backend for the spatial search
|
|
|
|
+++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
The following table summarizes the different spatial search backends:
|
|
|
|
|
|
|
|
+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+
|
|
|
|
| Backend | Solr Versions | Supported geometries | Sorting and relevance | Performance with large number of datasets |
|
|
|
|
+========================+===============+=====================================+===========================================================+===========================================+
|
|
|
|
| ``solr`` | 3.1 to 4.x | Bounding Box | Yes, spatial sorting combined with other query parameters | Good |
|
|
|
|
+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+
|
|
|
|
| ``solr-spatial-field`` | 4.x | Bounding Box, Point and Polygon [1] | Not implemented | Good |
|
|
|
|
+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+
|
|
|
|
| ``postgis`` | 1.3 to 4.x | Bounding Box | Partial, only spatial sorting supported [2] | Poor |
|
|
|
|
+------------------------+---------------+-------------------------------------+-----------------------------------------------------------+-------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
[1] Requires JTS
|
|
|
|
|
|
|
|
[2] Needs ``ckanext.spatial.use_postgis_sorting`` set to True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
We recommend to use the ``solr`` backend whenever possible. Here are more
|
|
|
|
details about the available options:
|
|
|
|
|
|
|
|
* ``solr`` (Recommended)
|
|
|
|
This option uses normal Solr fields to index the relevant bits of
|
|
|
|
information about the geometry and uses an algorithm function to sort
|
|
|
|
results by relevance, keeping any other non-spatial filtering. It only
|
|
|
|
supports bounding boxes both for the geometries to be indexed and the
|
|
|
|
input query shape. It requires `EDisMax`_ query parser, so it will only
|
|
|
|
work on versions of Solr greater than 3.1 (We recommend using Solr 4.x).
|
|
|
|
|
|
|
|
You will need to add the following fields to your Solr schema file to
|
|
|
|
enable it::
|
|
|
|
|
|
|
|
<fields>
|
|
|
|
<!-- ... -->
|
|
|
|
<field name="bbox_area" type="float" indexed="true" stored="true" />
|
|
|
|
<field name="maxx" type="float" indexed="true" stored="true" />
|
|
|
|
<field name="maxy" type="float" indexed="true" stored="true" />
|
|
|
|
<field name="minx" type="float" indexed="true" stored="true" />
|
|
|
|
<field name="miny" type="float" indexed="true" stored="true" />
|
|
|
|
</fields>
|
2014-06-13 13:52:33 +02:00
|
|
|
The solr schema file is typically located at: (..)/src/ckan/ckan/config/solr/schema.xml
|
2013-09-08 20:42:39 +02:00
|
|
|
|
|
|
|
* ``solr-spatial-field``
|
|
|
|
This option uses the `spatial field`_ introduced in Solr 4, which allows
|
|
|
|
to index points, rectangles and more complex geometries (complex geometries
|
|
|
|
will require `JTS`_, check the documentation).
|
|
|
|
Sorting has not yet been implemented, users willing to do so will need to
|
|
|
|
modify the query using the ``before_search`` extension point.
|
|
|
|
|
|
|
|
You will need to add the following field type and field to your Solr
|
|
|
|
schema file to enable it (Check the `Solr documentation`__ for more
|
|
|
|
information on the different parameters, note that you don't need
|
|
|
|
``spatialContextFactory`` if you are not using JTS)::
|
|
|
|
|
|
|
|
<types>
|
|
|
|
<!-- ... -->
|
|
|
|
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
|
|
|
|
spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory"
|
|
|
|
distErrPct="0.025"
|
|
|
|
maxDistErr="0.000009"
|
|
|
|
units="degrees" />
|
|
|
|
</types>
|
|
|
|
<fields>
|
|
|
|
<!-- ... -->
|
|
|
|
<field name="spatial_geom" type="location_rpt" indexed="true" stored="true" multiValued="true" />
|
|
|
|
</fields>
|
|
|
|
|
|
|
|
* ``postgis``
|
|
|
|
This is the original implementation of the spatial search. It
|
|
|
|
does not require any change in the Solr schema and can run on Solr 1.x,
|
|
|
|
but it is not as efficient as the previous ones. Basically the bounding
|
|
|
|
box based query is performed in PostGIS first, and the ids of the matched
|
|
|
|
datasets are added as a filter to the Solr request. This, apart from being
|
|
|
|
much less efficient, can led to issues on Solr due to size of the requests
|
|
|
|
(See `Solr configuration issues on legacy PostGIS backend`_). There is
|
|
|
|
support for a spatial ranking on this backend (setting
|
|
|
|
``ckanext.spatial.use_postgis_sorting`` to True on the ini file), but
|
|
|
|
it can not be combined with any other filtering.
|
2013-04-10 18:37:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
Spatial Search Widget
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
.. 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 to the sidebar of the search page, add this to the
|
|
|
|
dataset search page template
|
|
|
|
(``myproj/ckanext/myproj/templates/package/search.html``)::
|
|
|
|
|
|
|
|
{% 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]]]}" %}
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
You need to load the ``spatial_metadata`` and ``spatial_query`` plugins to use this
|
|
|
|
snippet.
|
2013-04-10 18:37:33 +02:00
|
|
|
|
2013-09-08 20:42:39 +02:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2014-06-14 04:43:20 +02:00
|
|
|
To add a map to the sidebar, add the following block to the dataset details page template (eg
|
|
|
|
``ckanext-myproj/ckanext/myproj/templates/package/read.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::
|
2013-09-08 20:42:39 +02:00
|
|
|
|
|
|
|
{% 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::
|
|
|
|
|
2014-01-09 18:46:45 +01:00
|
|
|
{% block primary_content_inner %}
|
2013-09-08 20:42:39 +02:00
|
|
|
|
2014-01-09 18:46:45 +01:00
|
|
|
{{ super() }}
|
2013-09-08 20:42:39 +02:00
|
|
|
|
2014-01-09 18:46:45 +01:00
|
|
|
{% 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 %}
|
2013-09-08 20:42:39 +02:00
|
|
|
|
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
You need to load the ``spatial_metadata`` plugin to use these snippets.
|
|
|
|
|
|
|
|
Legacy Search
|
|
|
|
-------------
|
|
|
|
|
|
|
|
Solr configuration issues on legacy PostGIS backend
|
|
|
|
+++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
|
|
|
|
If you find any of the issues described in this section it is strongly
|
|
|
|
recommended that you consider switching to one of the Solr based backends
|
|
|
|
which are much more efficient. These notes are just kept for informative
|
|
|
|
purposes.
|
|
|
|
|
|
|
|
|
|
|
|
If using Spatial Query functionality then there is an additional SOLR/Lucene
|
|
|
|
setting that should be used to set the limit on number of datasets searchable
|
|
|
|
with a spatial value.
|
|
|
|
|
|
|
|
The setting is ``maxBooleanClauses`` in the solrconfig.xml and the value is the
|
|
|
|
number of datasets spatially searchable. The default is ``1024`` and this could
|
|
|
|
be increased to say ``16384``. For a SOLR single core this will probably be at
|
|
|
|
`/etc/solr/conf/solrconfig.xml`. For a multiple core set-up, there will me
|
|
|
|
several solrconfig.xml files a couple of levels below `/etc/solr`. For that
|
|
|
|
case, *all* of the cores' `solrconfig.xml` should have this setting at the new
|
|
|
|
value.
|
|
|
|
|
|
|
|
Example::
|
|
|
|
|
|
|
|
<maxBooleanClauses>16384</maxBooleanClauses>
|
|
|
|
|
|
|
|
This setting is needed because PostGIS spatial query results are fed into SOLR
|
|
|
|
using a Boolean expression, and the parser for that has a limit. So if your
|
|
|
|
spatial area contains more than the limit (of which the default is 1024) then
|
|
|
|
you will get this error::
|
|
|
|
|
|
|
|
Dataset search error: ('SOLR returned an error running query...
|
|
|
|
|
|
|
|
and in the SOLR logs you see::
|
|
|
|
|
|
|
|
too many boolean clauses ... Caused by:
|
|
|
|
org.apache.lucene.search.BooleanQuery$TooManyClauses: maxClauseCount is set to
|
|
|
|
1024
|
|
|
|
|
|
|
|
|
|
|
|
Legacy API
|
|
|
|
++++++++++
|
|
|
|
|
|
|
|
The extension adds the following call to the CKAN search API, which returns
|
|
|
|
datasets with an extent that intersects with the bounding box provided::
|
|
|
|
|
|
|
|
/api/2/search/dataset/geo?bbox={minx,miny,maxx,maxy}[&crs={srid}]
|
|
|
|
|
|
|
|
If the bounding box coordinates are not in the same projection as the one
|
|
|
|
defined in the database, a CRS must be provided, in one of the following forms:
|
|
|
|
|
|
|
|
- `urn:ogc:def:crs:EPSG::4326`
|
|
|
|
- EPSG:4326
|
|
|
|
- 4326
|
|
|
|
|
|
|
|
.. _action API: http://docs.ckan.org/en/latest/apiv3.html
|
|
|
|
.. _edismax: http://wiki.apache.org/solr/ExtendedDisMax
|
|
|
|
.. _JTS: http://www.vividsolutions.com/jts/JTSHome.htm
|
|
|
|
.. _spatial field: http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4
|
|
|
|
__ `spatial field`_
|
|
|
|
.. _GeoJSON: http://geojson.org
|