Salut, Il y a quelques temps, j'avais proposé 2 scripts python pour améliorer les fichiers Cléo. http://lists.openstreetmap.org/pipermail/talk-fr/2011-August/035156.html
Ca n'avait pas eu un grand succès à l'époque je retente ce soir: si des testeurs pouvaient faire un retour sur la qualité des fiabilisations. Pas la peine de faire un import, un petit coup de validator avant/apres, une superposition des couches pour vérifier que l'on respecte la géométrie, qu'on perd pas les relations multipolygone.... Et on pourrait mettre ça dans la chaîne de génération Cléo, et (presque) fermer le robinet. L'étape suivante c'est l'automate évoqué par sly : appliquer l'équivalent au bâti OSM détecté en ano par Osmose. A+ Bruno
#!/usr/bin/python # -*- coding: utf8 -*- from rtree import Rtree import OsmSax, sys DIST_MIN = 1.0e-12 def coords(n): return (n.lat, n.lon) def distance2(a,b): xa, ya = coords(a) xb, yb = coords(b) return (xa-xb)**2 + (ya-yb)**2 class Node(object): def __init__(self, id=None, lon=None, lat=None, tags=None): self.id = id if lon != None: self.lon, self.lat = float(lon), float(lat) if tags: self.tags = tags else: self.tags = {} self.inWay = set() self.inRel = set() class Way(object): def __init__(self, id=None, nodes=None, tags=None): self.id = id if nodes: self.nodes = nodes else: self.nodes = [] if tags: self.tags = tags else: self.tags = {} class Relation(object): def __init__(self, id, members=None, tags=None): self.id = id if members: self.members = members else: self.members = [] if tags: self.tags = tags else: self.tags = {} def __repr__(self): return "Relation(id=%r, members=%r, tags=%r)" % (self.id, self.members, self.tags) class Cache: def __init__(self): self.nods = {} self.ways = {} self.rels = {} def NodeCreate(self, data): self.nods[data["id"]] = Node(id=data["id"],lon=data["lon"],lat=data["lat"],tags=data["tag"]) def WayCreate(self, data): self.ways[data["id"]] = Way(id=data["id"],nodes=data["nd"],tags=data["tag"]) def RelationCreate(self, data): self.rels[data["id"]] = Relation(id=data["id"],tags=data["tag"],members=data["member"]) ########################################################################### fout = sys.argv[2] data = OsmSax.OsmSaxReader(sys.argv[1]) cache = Cache() print 'Parse du fichier...' data.CopyTo(cache) idxNode = Rtree() tabindx = {} print 'Indexation...' i = 0 for k in cache.nods.keys(): i += 1 idxNode.insert(i, coords(cache.nods[k])) tabindx[i] = cache.nods[k] # set des chemins utilisant un noeud for w in cache.ways.values(): for nid in w.nodes: cache.nods[nid].inWay.add(w) # set des relations utilisant un noeud for r in cache.rels.values(): for m in r.members: if m['type'] == 'node': cache.nodes[m['ref']].inRel.add(r) print 'Simplification des noeuds...' # balayage des noeuds à simplifier for noeud in cache.nods.values(): # print 'traitment', noeud.id # le noeud a-t-il déjà été supprimé if not cache.nods.has_key(noeud.id): continue # recherche des noeuds proches for i in idxNode.nearest(coords(noeud),4): np = tabindx[i] if np == noeud: continue if distance2(noeud, np) < DIST_MIN: noeud.tags['fixme']='simplify' #remplacement du np par noeud dans les ways for w in np.inWay: while np.id in w.nodes : ind = w.nodes.index(np.id) w.nodes[ind]=noeud.id #suppression np de l'index idxNode.delete(i,coords(np)) #suppression de la liste des noeuds del cache.nods[np.id] print 'Nettoyage des chemins...' for w in cache.ways.values(): i = 1 # balayage des segments d'un way while (len(w.nodes) > 1) & (i < len(w.nodes)): if w.nodes[i-1] == w.nodes[i]: w.nodes.pop(i) continue i += 1 print 'Ecriture...' out = OsmSax.OsmSaxWriter(fout, "UTF-8") out.startDocument() out.startElement("osm", {'version':'0.6'}) for n in cache.nods.values(): out.NodeCreate({'id':n.id,'lon':n.lon,'lat':n.lat,'tag':n.tags}) for w in cache.ways.values(): out.WayCreate({'id':w.id,'nd':w.nodes,'tag':w.tags}) for r in cache.rels.values(): out.RelationCreate({'id':r.id,'member':r.members,'tag':r.tags}) out.endElement("osm")
#!/usr/bin/python # -*- coding: utf8 -*- from rtree import Rtree import OsmSax, sys from shapely.geometry import Point, LineString DIST_MIN = 2.0e-6 def coords(n): return (n.lat, n.lon) def procheWay(nd, p1, p2): #renvoie vrai si node est pres du segment formé par p1,p2 no=Point(coords(nd)) no1=Point(coords(p1)) no2=Point(coords(p2)) seg = LineString([coords(p1), coords(p2)]) d = no.distance(seg) d1 = no.distance(no1) d2 = no.distance(no2) if (d < DIST_MIN) & (d < d1) & (d < d2) : return True else: return False class Node(object): def __init__(self, id=None, lon=None, lat=None, tags=None): self.id = id if lon != None: self.lon, self.lat = float(lon), float(lat) if tags: self.tags = tags else: self.tags = {} self.inWay = set() self.inRel = set() class Way(object): def __init__(self, id=None, nodes=None, tags=None): self.id = id if nodes: self.nodes = nodes else: self.nodes = [] if tags: self.tags = tags else: self.tags = {} class Relation(object): def __init__(self, id, members=None, tags=None): self.id = id if members: self.members = members else: self.members = [] if tags: self.tags = tags else: self.tags = {} def __repr__(self): return "Relation(id=%r, members=%r, tags=%r)" % (self.id, self.members, self.tags) class Cache: def __init__(self): self.nods = {} self.ways = {} self.rels = {} def NodeCreate(self, data): self.nods[data["id"]] = Node(id=data["id"],lon=data["lon"],lat=data["lat"],tags=data["tag"]) def WayCreate(self, data): self.ways[data["id"]] = Way(id=data["id"],nodes=data["nd"],tags=data["tag"]) def RelationCreate(self, data): self.rels[data["id"]] = Relation(id=data["id"],tags=data["tag"],members=data["member"]) ########################################################################### fout = sys.argv[2] data = OsmSax.OsmSaxReader(sys.argv[1]) cache = Cache() print 'Parse du fichier...' data.CopyTo(cache) idxNode = Rtree() tabindx = {} print 'Indexation...' i = 0 for k in cache.nods.keys(): i += 1 idxNode.insert(i, coords(cache.nods[k])) tabindx[i] = cache.nods[k] print 'Snap...' # balayage des ways for w in cache.ways.values(): i = 1 # balayage des segments d'un way while i < len(w.nodes): # print w.id , ' ',len(w.nodes), ' ', i # recherche des noeuds proches du segment seg = LineString( [ coords(cache.nods[w.nodes[i-1]]), coords(cache.nods[w.nodes[i]]) ] ) for idx in idxNode.nearest(seg.bounds,10): np = tabindx[idx] # si le noeud est déjà dans le way on ne fait rien # print 'id point: ', np.id if np.id in w.nodes: continue # print 'id point: ', np.id, ' ', no.distance(seg) if procheWay(np, cache.nods[w.nodes[i-1]], cache.nods[w.nodes[i]]): np.tags['fixme'] = 'Snaper' w.nodes.insert(i, np.id) i-=1 break i += 1 print 'Ecriture...' out = OsmSax.OsmSaxWriter(fout, "UTF-8") out.startDocument() out.startElement("osm", {'version':'0.6'}) for n in cache.nods.values(): out.NodeCreate({'id':n.id,'lon':n.lon,'lat':n.lat,'tag':n.tags}) for w in cache.ways.values(): out.WayCreate({'id':w.id,'nd':w.nodes,'tag':w.tags}) for r in cache.rels.values(): out.RelationCreate({'id':r.id,'member':r.members,'tag':r.tags}) out.endElement("osm")
_______________________________________________ Talk-fr mailing list Talk-fr@openstreetmap.org http://lists.openstreetmap.org/listinfo/talk-fr