The kind of analyzer based on SQL query is relevant when want to check geometry or relation between multiple objects. The result of the query is used to fill the Osmose issue report.
For explenation purpose only, we just here make an analyzer that report pharmacy as node inside a building polygon, it is not looking for issue in the data.
SELECT
-- We report pharmacy nodes osm id and location
nodes.id,
ST_AsText(nodes.geom) AS geom
FROM
nodes
JOIN ways ON
-- Use the index on tags
ways.tags != ''::hstore AND
-- Look for ways with valid building tag
ways.tags?'building' AND ways.tags->'building' != 'no' AND
-- Look for way as valid polygon
is_polygon AND
-- Use the spatial index for ways bbox crossing the node location
ways.linestring && nodes.geom AND
-- Ensure the node is inside the polygon
-- (ST_Intersects call it self the spatial crossing with bbox, so in this case it not necessary)
ST_Intersects(ST_MakePolygon(ways.linestring), nodes.geom)
WHERE
-- Use the index on tags
nodes.tags != ''::hstore AND
-- Look for node with tag amenity=pharmacy
nodes.tags?'amenity' AND nodes.tags->'amenity' = 'pharmacy'
In [1]:
sql10 = """
SELECT
nodes.id,
ST_AsText(nodes.geom) AS geom
FROM
nodes
JOIN ways ON
ways.tags != ''::hstore AND
ways.tags?'building' AND ways.tags->'building' != 'no' AND
is_polygon AND
ST_Intersects(ST_MakePolygon(ways.linestring), nodes.geom)
WHERE
nodes.tags != ''::hstore AND
nodes.tags?'amenity' AND nodes.tags->'amenity' = 'pharmacy'
"""
We have to create an inherited class from Analyser_Osmosis
. The __init__()
setup the meta information of produced issues. It defines a class id for Osmose issues.
analyser_osmosis_common()
run the query and build the Osmose issues. For each row returned by the query, an Osmose issue is created using the lambda function. It should at least return:
class
refer to the class id definition,data
: must match the result row definition from the query.
In [2]:
%cd "/opt/osmose-backend/"
from analysers.Analyser_Osmosis import Analyser_Osmosis
class Analyser_Pharmacy_Building(Analyser_Osmosis):
def __init__(self, config, logger = None):
super().__init__(config, logger)
# Define Osmose issue class id 1
self.classs[1] = self.def_class(
item = 2010,
level = 1,
tags = ['building'],
title = T_('Pharmacy node in Building')
)
def analyser_osmosis_common(self):
# Run the SQL query
self.run(sql10, lambda res: {
# For each result, create an osmose issue of class 1
'class': 1,
# Explain how to interpret the returned fields from query
'data': [self.node_full, self.positionAsText]
})
To run the analyze we need a context of execution. Each country or area have a entry in the file osmose_config.py.
In [6]:
import osmose_config as config
country_conf = config.config['monaco']
country_conf.init()
country_conf.analyser_options
Out[6]:
In [7]:
from modules.jupyter import *
csv = run(country_conf, Analyser_Pharmacy_Building, format = 'csv')
print_csv(csv)
Out[7]:
In [8]:
geojson = run(country_conf, Analyser_Pharmacy_Building, format = 'geojson')
print_geojson(geojson, limit = 100)
In [ ]: