SotM-US 2015
Osmose QA
Issue reported
at NYC on 2015-06-07
Frédéric Rodrigo <frederic@carte-libre.fr>
(c)left 2015 - CC-BY-SA v3.0
http://osmose.openstreetmap.fr
Osmose QA ?
Quality tool
Data analysis
Issues detection with rules
Missing data from OpenData
Integration suggestions
Osmose QA way
No duplicate analyses with other tools
No force mapping way
– Adapt to local mapping approach
– No choose one alternative among others
Frontend - Interface
1 ligne 2 ligne 3 ligne 4 ligne
0
2
4
6
8
10
12
1 colonne
2 colonne
3 colonne
Frontend
Issues map
Filter: severity, topic, fixable, items
– Responsive, filter for survey
Coverage map, heatmap
Connection Oauth via osm.org
Export issues: GPX, remote JOSM, Json, RSS…
Issues dumps: SQL, CSV
Frontend - Popup
1. Description
2. Suspects elements
3. Tags
4. Zone links
5. Buttons
6. Suggested fixs
7. Status change: corrected, false positive
Frontend – Tags Editor
Make change into OSM from Osmose QA
Edit only tags
Can apply « fix »
– A nice differential
tags editor
Backend - Frontend
Backend Frontend
OSM Data
API
Backend - Countries
Split : specifics analyser
– Languages, Country, Projection
→ allow statistics
Sublevels split : France, Italy, Belgium, USA, Canada...
70% of planet data
→ Need more servers
→ Aim self support from local community: mapping practice,
knowledge, OpenData
Backend - Analysers
Analysers
– Rules on one object tags
● Capitals, ref...
– SQL spatial rules or multi-objects check
● Reverse roundabout, unconnected highway...
– OpenData features checking
● Schools, post offices, bus stops...
More than 200 analysers
Sax analyser
class Name_Spaces(Plugin):
def init(self, logger):
self.errors[903] = { "item": 5010, "level": 2, "tag": ["name", "fix:chair"], "desc": T_(u"Too
many spaces") }
def node(self, data, tags):
name = tags[u"name"]
if u" " in name:
err.append({"class": 903, "subclass": 0, "text": T_("Name contains successive
spaces")})
if len(err) > 0:
name = re.sub(r' +', ' ', name.strip())
for e in err:
e["fix"] = {"name": name}
issue definition
issue detection
issue possible fix
Osmosis analyserSql10 = """
SELECT
id,
ST_AsText(way_locate(linestring))
FROM
ways
WHERE
tags ? 'junction' AND tags->'junction' = 'roundabout' AND
is_polygon AND ST_IsSimple(linestring) AND
{1} ST_OrderingEquals(ST_Makepolygon(linestring), st_forceRHR(ST_Makepolygon(linestring)))"""
class Analyser_Osmosis_Roundabout_Reverse(Analyser_Osmosis):
def __init__(self, config, logger = None):
Analyser_Osmosis.__init__(self, config, logger)
self.classs_change[1] = {"item":"1050", "level": 1, "tag": ["highway", "roundabout", "fix:chair"], "desc": T_(u"Reverse
roundabout") }
self.callback10 = lambda res: {"class":1, "data":[self.way_full, self.positionAsText]}
if self.config.options.get("driving_side") == "left":
self.driving_side = "NOT "
else:
self.driving_side = ""
def analyser_osmosis_all(self):
self.run(sql10.format("", self.driving_side), self.callback10)
issue detection
issue definition
OpenData analyser
class Analyser_Merge_Poste_FR(Analyser_Merge):
def __init__(self, config, logger = None):
self.missing_official = {"item":"8020", "class": 1, "level": 3, "tag": ["merge", "post"], "desc": T_(u"Post office not integrated") }
self.missing_osm = {"item":"7050", "class": 2, "level": 3, "tag": ["merge", "post"], "desc": T_(u"Post office without ref:FR:LaPoste") }
self.possible_merge = {"item":"8021", "class": 3, "level": 3, "tag": ["merge", "post"], "desc": T_(u"Post office, integration suggestion") }
Analyser_Merge.__init__(self, config, logger,
Source(
name = u"points de contact du réseau postal français",
file = "poste_FR.csv.bz2",
encoding = "ISO-8859-15",
csv = CSV(separator = ";")),
Load("Longitude", "Latitude", table = "poste_fr"),
Mapping(
select = Select(
types = ["nodes", "ways"],
tags = {"amenity": "post_office"}),
osmRef = "ref:FR:LaPoste",
conflationDistance = 1000,
generate = Generate(
static = {
"amenity": "post_office",
"operator": "La Poste",
"source": "data.gouv.fr:LaPoste - 01/2013"},
mapping = {
"ref:FR:LaPoste": "Identifiant",
"name": lambda res: re.sub(self.Principal, " Principal", res[u"Libellé du site"]),
"addr:postcode": "Code postal"} )))
issue definitions
OpenData source file description
OSM data pick-up
Join OpenData & OSM
Map OpenData columns to OSM tags
15 Millions of issues
USA
Germany
World, level=1
France, level=1
Corrections
Errors
New
Rules
USA, level=1
Germany, level=1
Stats
15 millions of issues
– 850 000 of level=1
3 700 000 executed analyses
– 12 000 analysis / 2 days
15 virtuals serveurs
500 rules checked
19,8 / 28 Go : 70 % of planet
352 area (countries or sub areas)
Maproulette
Bridge to Maproulette
Reports choose:
– [world] Highway intersecting building
– [world] Object tagged twice as node or way
– [france] Missing soccer pitch
– [world] Broken highway level continuity
→ OSM as a Marathon
Osmose
http://osmose.openstreetmap.fr
http://wiki.osm.org/Osmose
@osmose_qa

20150607 sotm-us-osmose-qa

  • 1.
    SotM-US 2015 Osmose QA Issuereported at NYC on 2015-06-07 Frédéric Rodrigo <frederic@carte-libre.fr> (c)left 2015 - CC-BY-SA v3.0 http://osmose.openstreetmap.fr
  • 2.
    Osmose QA ? Qualitytool Data analysis Issues detection with rules Missing data from OpenData Integration suggestions
  • 3.
    Osmose QA way Noduplicate analyses with other tools No force mapping way – Adapt to local mapping approach – No choose one alternative among others
  • 4.
    Frontend - Interface 1ligne 2 ligne 3 ligne 4 ligne 0 2 4 6 8 10 12 1 colonne 2 colonne 3 colonne
  • 5.
    Frontend Issues map Filter: severity,topic, fixable, items – Responsive, filter for survey Coverage map, heatmap Connection Oauth via osm.org Export issues: GPX, remote JOSM, Json, RSS… Issues dumps: SQL, CSV
  • 6.
    Frontend - Popup 1.Description 2. Suspects elements 3. Tags 4. Zone links 5. Buttons 6. Suggested fixs 7. Status change: corrected, false positive
  • 7.
    Frontend – TagsEditor Make change into OSM from Osmose QA Edit only tags Can apply « fix » – A nice differential tags editor
  • 9.
    Backend - Frontend BackendFrontend OSM Data API
  • 10.
    Backend - Countries Split: specifics analyser – Languages, Country, Projection → allow statistics Sublevels split : France, Italy, Belgium, USA, Canada... 70% of planet data → Need more servers → Aim self support from local community: mapping practice, knowledge, OpenData
  • 11.
    Backend - Analysers Analysers –Rules on one object tags ● Capitals, ref... – SQL spatial rules or multi-objects check ● Reverse roundabout, unconnected highway... – OpenData features checking ● Schools, post offices, bus stops... More than 200 analysers
  • 12.
    Sax analyser class Name_Spaces(Plugin): definit(self, logger): self.errors[903] = { "item": 5010, "level": 2, "tag": ["name", "fix:chair"], "desc": T_(u"Too many spaces") } def node(self, data, tags): name = tags[u"name"] if u" " in name: err.append({"class": 903, "subclass": 0, "text": T_("Name contains successive spaces")}) if len(err) > 0: name = re.sub(r' +', ' ', name.strip()) for e in err: e["fix"] = {"name": name} issue definition issue detection issue possible fix
  • 13.
    Osmosis analyserSql10 =""" SELECT id, ST_AsText(way_locate(linestring)) FROM ways WHERE tags ? 'junction' AND tags->'junction' = 'roundabout' AND is_polygon AND ST_IsSimple(linestring) AND {1} ST_OrderingEquals(ST_Makepolygon(linestring), st_forceRHR(ST_Makepolygon(linestring)))""" class Analyser_Osmosis_Roundabout_Reverse(Analyser_Osmosis): def __init__(self, config, logger = None): Analyser_Osmosis.__init__(self, config, logger) self.classs_change[1] = {"item":"1050", "level": 1, "tag": ["highway", "roundabout", "fix:chair"], "desc": T_(u"Reverse roundabout") } self.callback10 = lambda res: {"class":1, "data":[self.way_full, self.positionAsText]} if self.config.options.get("driving_side") == "left": self.driving_side = "NOT " else: self.driving_side = "" def analyser_osmosis_all(self): self.run(sql10.format("", self.driving_side), self.callback10) issue detection issue definition
  • 14.
    OpenData analyser class Analyser_Merge_Poste_FR(Analyser_Merge): def__init__(self, config, logger = None): self.missing_official = {"item":"8020", "class": 1, "level": 3, "tag": ["merge", "post"], "desc": T_(u"Post office not integrated") } self.missing_osm = {"item":"7050", "class": 2, "level": 3, "tag": ["merge", "post"], "desc": T_(u"Post office without ref:FR:LaPoste") } self.possible_merge = {"item":"8021", "class": 3, "level": 3, "tag": ["merge", "post"], "desc": T_(u"Post office, integration suggestion") } Analyser_Merge.__init__(self, config, logger, Source( name = u"points de contact du réseau postal français", file = "poste_FR.csv.bz2", encoding = "ISO-8859-15", csv = CSV(separator = ";")), Load("Longitude", "Latitude", table = "poste_fr"), Mapping( select = Select( types = ["nodes", "ways"], tags = {"amenity": "post_office"}), osmRef = "ref:FR:LaPoste", conflationDistance = 1000, generate = Generate( static = { "amenity": "post_office", "operator": "La Poste", "source": "data.gouv.fr:LaPoste - 01/2013"}, mapping = { "ref:FR:LaPoste": "Identifiant", "name": lambda res: re.sub(self.Principal, " Principal", res[u"Libellé du site"]), "addr:postcode": "Code postal"} ))) issue definitions OpenData source file description OSM data pick-up Join OpenData & OSM Map OpenData columns to OSM tags
  • 15.
    15 Millions ofissues USA Germany
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    Stats 15 millions ofissues – 850 000 of level=1 3 700 000 executed analyses – 12 000 analysis / 2 days 15 virtuals serveurs 500 rules checked 19,8 / 28 Go : 70 % of planet 352 area (countries or sub areas)
  • 21.
    Maproulette Bridge to Maproulette Reportschoose: – [world] Highway intersecting building – [world] Object tagged twice as node or way – [france] Missing soccer pitch – [world] Broken highway level continuity → OSM as a Marathon
  • 22.

Editor's Notes

  • #22 http://osmose.openstreetmap.fr/fr/errors/graph.png?item=1070