diff --git a/icons.svg b/icons.svg index 69e6814..42163eb 100644 --- a/icons.svg +++ b/icons.svg @@ -13,7 +13,7 @@ height="600px" id="svg2987" version="1.1" - inkscape:version="0.48.3.1 r9886" + inkscape:version="0.48.5 r10040" sodipodi:docname="icons.svg"> @@ -24,13 +24,13 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1" - inkscape:cx="306.0879" - inkscape:cy="579.54088" + inkscape:zoom="16" + inkscape:cx="85.77483" + inkscape:cy="361.94213" inkscape:current-layer="layer1" inkscape:document-units="px" - showgrid="false" - showguides="false" + showgrid="true" + showguides="true" inkscape:guide-bbox="true" inkscape:object-paths="true" inkscape:snap-bbox="true" @@ -262,6 +262,22 @@ orientation="0,1" position="0,152" id="guide4093" /> + + + + @@ -279,13 +295,26 @@ id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer"> + + @@ -293,13 +322,13 @@ sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" id="bench" - d="m 19,74 0,1 2,0 -1,3 1,0 1,-3 4,0 1,3 1,0 -1,-3 2,0 0,-1 z" + d="m 19,218 0,1 2,0 -1,3 1,0 1,-3 4,0 1,3 1,0 -1,-3 2,0 0,-1 z" style="fill:#000000;stroke:none" inkscape:label="#path3043" /> @@ -319,7 +348,7 @@ - @@ -409,12 +433,6 @@ id="path3071" d="m 82,56 -1,1 1,1 1,-1 10.5,0 0.5,1 1,-1 -1,-1 z" style="color:#000000;fill:#a52a2a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> - @@ -454,11 +472,6 @@ id="path3087" inkscape:connector-curvature="0" style="fill:#a52a2a" /> - @@ -766,10 +779,11 @@ sodipodi:nodetypes="cccccccc" inkscape:label="#path3188" /> + inkscape:label="#path3190" + inkscape:connector-curvature="0" /> + inkscape:label="#path3953" + sodipodi:nodetypes="ccccc" /> - - - - + d="m 181.5,99 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,1 c 0,0.277 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-1 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 2,0 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,1 c 0,0.277 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-1 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 2,0 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,1 c 0,0.277 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-1 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m -3.5,3 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 0.55228,0 1,0.44772 1,1 l 0,2 c 0,0.55228 -0.44772,1 -1,1 l 0,1 c 0,0.554 0.446,1 1,1 l 2,0 c 0.554,0 1,-0.446 1,-1 l 0,-6 c 0,-0.554 -0.446,-1 -1,-1 l -3,0 z" + id="foot" + inkscape:connector-curvature="0" /> + inkscape:label="#rect4296" + inkscape:connector-curvature="0" /> + inkscape:label="#rect4343" + inkscape:connector-curvature="0" /> + style="color:#000000;fill:#000000;stroke:none;stroke-width:0.30000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 99.5,178 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,5 0,1 c 0,0.277 0.223,0.5 0.5,0.5 0.82843,0 1.5,0.67157 1.5,1.5 l 0,3 c 0,0.277 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-3 c 0,-0.82843 0.67157,-1.5 1.5,-1.5 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-1 0,-5 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 -0.277,0 -0.5,0.223 -0.5,0.5 l 0,4.5 -1,0 0,-4.5 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 -0.277,0 -0.5,0.223 -0.5,0.5 l 0,4.5 -1,0 0,-4.5 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z" + id="rect3276" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sscssssssssscsssccsssccss" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mapper.py b/mapper.py index ad4c2d0..cf1e13b 100644 --- a/mapper.py +++ b/mapper.py @@ -7,14 +7,17 @@ Simple tool for working with OpenStreetMap data. Author: Sergey Vartanov (me@enzet.ru). """ +import copy import datetime import os import re import sys import xml.dom.minidom +import yaml import extract_icon import osm_reader +import ui from flinger import GeoFlinger, Geo @@ -39,7 +42,7 @@ node_map, way_map, relation_map = osm_reader.parse_osm_file(input_file_name) output_file = svg.SVG(open(sys.argv[2], 'w+')) -w, h = 2000, 2000 +w, h = 2650, 2650 background_color = 'EEEEEE' grass_color = 'C8DC94' @@ -56,7 +59,8 @@ tags_to_write = ['operator', 'opening_hours', 'cuisine', 'network', 'website', 'phone', 'branch', 'route_ref', 'brand', 'ref', 'wikipedia', 'description', 'level', 'wikidata', 'name', 'alt_name', 'image', 'fax', 'old_name', 'artist_name', 'int_name', - 'official_name', 'full_name', 'email', 'designation'] + 'official_name', 'full_name', 'email', 'designation', + 'min_height', 'height'] prefix_to_write = ['addr', 'contact', 'name', 'operator', 'wikipedia', 'alt_name', 'description', 'old_name', 'inscription', @@ -280,7 +284,10 @@ def draw_ways(): # Post part. + way_number = 0 for way in layer['l']: + way_number += 1 + ui.write_line(way_number, len(layer['l'])) text_y = 0 c = line_center(way['nodes']) if way['tags']['landuse'] == 'grass': @@ -466,8 +473,6 @@ def draw_ways(): style += 'fill:none;stroke:#FF0000;stroke-width:0.5;stroke-dahsarray:10,20;' draw_path(way['nodes'], style) -print 'Done.' - # Nodes drawing def draw_raw_nodes(): @@ -492,12 +497,59 @@ def to_write(key): return True return False +def get_icon(tags, scheme, fill='444444'): + main_icon = None + extra_icons = [] + processed = set() + for element in scheme['tags']: + matched = True + for tag in element['tags']: + if not tag in tags: + matched = False + break + if element['tags'][tag] != '*' and element['tags'][tag] != tags[tag]: + matched = False + break + if 'no_tags' in element: + for no_tag in element['no_tags']: + if no_tag in tags.keys(): + matched = False + break + if matched: + if 'draw' in element and not element['draw']: + processed = set(element['tags'].keys()) + if 'icon' in element: + main_icon = copy.deepcopy(element['icon']) + processed = set(element['tags'].keys()) + if 'over_icon' in element: + main_icon += element['over_icon'] + for key in element['tags'].keys(): + processed.add(key) + if 'add_icon' in element: + extra_icons += element['add_icon'] + for key in element['tags'].keys(): + processed.add(key) + if 'color' in element: + fill = scheme['colors'][element['color']] + for key in element['tags'].keys(): + processed.add(key) + if main_icon: + return [main_icon] + extra_icons, fill, processed + else: + return [], fill, processed + def draw_nodes(): print 'Draw nodes...' - # yaml.load(open('tags.yml')) + scheme = yaml.load(open('tags.yml')) - for node_id in node_map: + node_number = 0 + + s = sorted(node_map.keys(), key=lambda x: -node_map[x]['lat']) + + for node_id in s: + node_number += 1 + ui.write_line(node_number, len(node_map)) node = node_map[node_id] flinged = flinger.fling(Geo(node['lat'], node['lon'])) x = flinged.x @@ -507,205 +559,8 @@ def draw_nodes(): p = node['tags'] else: p = {} - fill = '444444' - processed = set([]) - if 'colour' in p or 'color' in p: - k = 'color' if 'color' in p else 'colour' - v = p[k] - processed.add(k) - if v == 'blue': - fill='2233AA' - elif v == 'lightblue': - fill='2288CC' - elif v == 'red': - fill='CC0000' - elif v == 'violet': - fill='75507B' - elif v == 'green': - fill='4E9A06' - elif v == 'yellow': - fill='EDD400' - else: - processed.remove(k) - - shapes = [] - - if p == {}: - pass - elif 'amenity' in p: - k = 'amenity' - v = p['amenity'] - processed.add(k) - if v in ['bench', 'bicycle_parking', 'cafe', 'waste_basket', - 'clinic', 'restaurant', 'pharmacy', 'drinking_water', - 'toilets', 'theatre', 'bar', 'bank', 'pub', 'post_office']: - shapes.append(v) - elif v == 'fast_food': - shape = 'fast_food' - if 'operator' in p: - if p['operator'] == "McDonald's": - shape = 'mcdonalds' - processed.add('operator') - if 'operator:en' in p: - if p['operator:en'] == "McDonald's": - shape = 'mcdonalds' - processed.add('operator:en') - shapes.append(shape) - elif v == 'shop': - if 'shop' in p: - if p['shop'] in ['fishing']: - draw_point_shape('shop_' + p['shop'], x, y, fill) - elif v == 'fountain': - shapes.append('fountain') - fill = water_border_color - elif v == 'recycling': - if not 'recycling_type' in p: - shapes.append('recycling') - else: - processed.remove(k) - for k in p: - if 'karaoke' in p and p['karaoke'] == 'yes': - draw_point_shape('microphone', flinged.x + 16, y, fill) - processed.add('karaoke') - elif 'building' in p: - k = 'building' - v = p['building'] - for k in p: - if 'roof:material' in p and p['roof:material'] == 'metal': - draw_point_shape('metal_roof', flinged.x + 16, y, fill) - processed.add('roof:material') - elif 'railway' in p: - k = 'railway' - v = p['railway'] - processed.add(k) - if v == 'subway_entrance': - shapes.append('train') - else: - processed.remove(k) - elif 'natural' in p: - k = 'natural' - v = p['natural'] - processed.add(k) - if v == 'tree': - shape = 'tree' - if 'leaf_type' in p and p['leaf_type'] in ['broadleaved', 'needleleaved']: - shape = p['leaf_type'] - processed.add('leaf_type') - if 'type' in p and p['type'] == 'conifer': - shape = 'needleleaved' - processed.add('type') - if 'denotation' in p: - if p['denotation'] == 'urban': - draw_point_shape([shape, 'urban_tree_pot'], x, y, wood_color) - processed.add('denotation') - elif p['denotation'] == 'avenue': - draw_point_shape([shape, 'avenue_tree'], x, y, wood_color) - processed.add('denotation') - elif v == 'cave_entrance': - shapes.append('cave') - elif v == 'bush': - shapes.append('bush') - fill = wood_color - else: - processed.remove(k) - elif 'entrance' in p: - k = 'entrance' - v = p['entrance'] - processed.add(k) - if v == 'yes': - shapes.append('entrance') - elif v == 'main': - shapes.append('main_entrance') - elif v == 'staircase': - shapes.append('staircase') - else: - processed.remove(k) - elif 'highway' in p: - k = 'highway' - v = p['highway'] - processed.add(k) - if v == 'crossing': - shape = 'crossing' - if 'crossing' in p: - if p['crossing'] == 'zebra': - shape = 'zebra' - processed.add('crossing') - elif p['crossing'] == 'uncontrolled': - draw_point_shape('no_traffic_signals', x + 16, y, fill) - processed.add('crossing') - elif p['crossing'] == 'traffic_signals': - draw_point_shape('traffic_signals', x + 16, y, fill) - processed.add('crossing') - elif 'crossing_ref' in p: - if p['crossing_ref'] == 'zebra': - shape = 'zebra' - processed.add('crossing_ref') - shapes.append(shape) - elif v == 'traffic_signals': - shapes.append('traffic_signals') - elif v == 'street_lamp': - shapes.append('street_lamp') - else: - processed.remove(k) - elif 'historic' in p: - k = 'historic' - v = p['historic'] - processed.add(k) - if v == 'memorial': - shape = v - if v in p: - if p[v] == 'statue': - shape = p[v] - processed.add(v) - elif p[v] == 'plaque': - shape = p[v] - processed.add(v) - shapes.append(shape) - elif v == 'tomb': - shape = v - if v in p: - if p[v] == 'mausoleum': - shape = p[v] - processed.add(v) - shapes.append(shape) - else: - processed.remove(k) - elif 'barrier' in p: - k = 'barrier' - v = p['barrier'] - processed.add(k) - if v == 'gate': - shapes.append('gate') - elif v == 'lift_gate': - shapes.append('lift_gate') - elif v == 'turnstile': - shapes.append('turnstile') - else: - processed.remove(k) - elif 'man_made' in p: - k = 'man_made' - v = p['man_made'] - processed.add(k) - if v == 'pole': - shapes.append('pole') - elif v == 'flagpole': - shapes.append('flagpole') - else: - processed.remove(k) - elif 'tourism' in p: - k = 'tourism' - v = p['tourism'] - processed.add(k) - if v == 'attraction': - shape = v - if v in p: - if p[v] == 'amusement_ride': - shape = p[v] - processed.add(v) - shapes.append(shape) - else: - processed.remove(k) + shapes, fill, processed = get_icon(p, scheme) for k in []: # p: if to_write(k): @@ -713,25 +568,15 @@ def draw_nodes(): text_y += 10 for k in p: - if k == 'foot' and p[k] == 'yes': - shapes.append('foot') - processed.add(k) - elif k == 'bicycle' and p[k] == 'yes': - shapes.append('bicycle') - processed.add(k) - elif k == 'internet_access' and p[k] == 'wlan': - shapes.append('wlan') - processed.add(k) - elif not no_draw(k) and not k in processed: + if not no_draw(k) and not k in processed: point(k, p[k], x, y, fill, text_y) text_y += 10 - + xxx = -(len(shapes) - 1) * 8 for shape in shapes: draw_point_shape(shape, x + xxx, y, fill) xxx += 16 - -print 'Done.' + ui.write_line(-1, len(node_map)) #draw_raw_nodes() #draw_raw_ways() @@ -742,7 +587,7 @@ icons = extract_icon.IconExtractor('icons.svg') #sys.exit(0) -draw_ways() +#draw_ways() draw_nodes() if flinger.space.x == 0: @@ -751,11 +596,10 @@ if flinger.space.x == 0: output_file.end() -print '\nMissing tags:\n' -top_missed_tags = reversed(sorted(missed_tags.keys(), key=lambda x: -missed_tags[x])) -for tag in top_missed_tags: - if tag[:4] == 'node': - print tag + ' (' + str(missed_tags[tag]) + ')' +print '\nTop missed tags:\n' +top_missed_tags = sorted(missed_tags.keys(), key=lambda x: -missed_tags[x]) +for tag in top_missed_tags[:10]: + print tag + ' (' + str(missed_tags[tag]) + ')' sys.exit(0) diff --git a/osm_reader.py b/osm_reader.py index 04c6968..b15fa32 100644 --- a/osm_reader.py +++ b/osm_reader.py @@ -5,6 +5,7 @@ Author: Sergey Vartanov """ import datetime +import ui import sys @@ -102,11 +103,7 @@ def parse_osm_file(file_name, silent=False): line_number = 0 while line != '': line_number += 1 - if line_number % 10000 == 0: - p = line_number / float(lines_number) - l = int(p * 100) - print 'Line ' + str(int(p * 1000) / 10) + ' %: [' + (l * '=') + ((100 - l) * ' ') + '].' - sys.stdout.write("\033[F") + ui.write_line(line_number, lines_number) # Node parsing. @@ -158,11 +155,12 @@ def parse_osm_file(file_name, silent=False): element['members'].append(member) line = input_file.readline() input_file.close() + + ui.write_line(-1, lines_number) # Complete progress bar. + if not silent: print 'File readed in ' + \ str(datetime.datetime.now() - start_time) + '.' print 'Nodes: ' + str(len(node_map)) + ', ways: ' + \ str(len(way_map)) + ', relations: ' + str(len(relation_map)) + '.' return node_map, way_map, relation_map - - diff --git a/tags.yml b/tags.yml index c759484..77bf08a 100644 --- a/tags.yml +++ b/tags.yml @@ -3,10 +3,12 @@ colors: # Color names 'blue': '2233AA' + 'gray': '888888' + 'green': '4E9A06' + 'grey': '888888' 'lightblue': '2288CC' 'red': 'CC0000' 'violet': '75507B' - 'green': '4E9A06' 'yellow': 'EDD400' # Entity @@ -20,10 +22,18 @@ colors: 'parking': 'DDCC99' 'water': 'AACCFF' 'water_border': '6688BB' + 'wood': 'B8CC84' tags: + +- tags: {place: quarter} + draw: false - tags: {amenity: bench} icon: [bench] +- tags: {amenity: bench, backrest: 'yes'} + icon: [bench_backrest] +- tags: {amenity: bench, backrest: 'no'} + icon: [bench_no_backrest] - tags: {amenity: bicycle_parking} icon: [bicycle_parking] - tags: {amenity: cafe} @@ -50,16 +60,18 @@ tags: icon: [pub] - tags: {amenity: post_office} icon: [post_office] -- tags: {amenity: fast_food, 'operator:en': McDonald's} +- tags: {amenity: fast_food, 'operator:en': "McDonald's"} icon: [mcdonalds] - tags: {amenity: fast_food} icon: [fast_food] - tags: {amenity: shop, shop: fishing} icon: [fishing] +- tags: {shop: gift} + icon: [gift] - tags: {amenity: fountain} - icon: [fontain] + icon: [fountain] color: water_border -- tags: {amenity: '*', karaoke: yes} +- tags: {amenity: '*', karaoke: 'yes'} add_icon: [microphone] - tags: {building: '*', 'roof:material': metal} icon: [metal_roof] @@ -67,24 +79,30 @@ tags: icon: [train] - tags: {natural: tree} icon: [tree] + color: wood - tags: {natural: tree, leaf_type: broadleaved} icon: [broadleaved] + color: wood - tags: {natural: tree, leaf_type: needleleaved} icon: [needleleaved] + color: wood - tags: {natural: tree, type: conifer} icon: [needleleaved] + color: wood - tags: {natural: tree, denotation: urban} over_icon: [urban_tree_pot] under_icon: [tree, broadleaved, needleleaved] -- tags: {natural: tree, denotation: avenue_tree} +- tags: {natural: tree, denotation: avenue} over_icon: [avenue_tree] under_icon: [tree, broadleaved, needleleaved] -- tags: {entrance: yes} +- tags: {entrance: 'yes'} icon: [entrance] - tags: {entrance: main} icon: [main_entrance] - tags: {entrance: staircase} icon: [staircase] +- tags: {highway: bus_stop} + icon: [bus_stop] - tags: {highway: crossing} icon: [crossing] - tags: {highway: crossing, crossing: uncontrolled} @@ -99,6 +117,8 @@ tags: icon: [memorial] - tags: {historic: memorial, memorial: statue} icon: [statue] +- tags: {tourism: artwork, artwork_type: statue} + icon: [statue] - tags: {historic: memorial, memorial: plaque} icon: [plaque] - tags: {historic: tomb} @@ -113,15 +133,58 @@ tags: icon: [turnstile] - tags: {man_made: pole} icon: [pole] +- tags: {man_made: pole, highway: street_lamp} + icon: [pole_lamp] - tags: {man_made: flagpole} icon: [flagpole] - tags: {tourism: attraction} icon: [attraction] - tags: {tourism: attraction, attraction: amusement_ride} icon: [amusement_ride] -- tags: {foot: yes} - icon: [foot] -- tags: {bicycle: yes} - icon: [bicycle] + +- tags: {foot: 'yes'} + add_icon: [foot] +- tags: {foot: 'no'} + add_icon: [no_foot] +- tags: {bicycle: 'yes'} + add_icon: [bicycle] +- tags: {bicycle: 'no'} + add_icon: [no_bicycle] +- tags: {internet_access: wlan, 'internet_access:fee': 'no'} + add_icon: [free_wlan] - tags: {internet_access: wlan} - icon: [wlan] + no_tags: {'internet_access:fee'} + add_icon: [wlan] +- tags: {material: wood} + add_icon: [wood] +- tags: {bus: 'yes'} + add_icon: [bus] +- tags: {trolleybus: 'yes'} + add_icon: [trolleybus] +- tags: {access: private} + add_icon: [private] + +- tags: {color: blue} + color: blue +- tags: {colour: blue} + color: blue +- tags: {color: lightblue} + color: lightblue +- tags: {colour: lightblue} + color: lightblue +- tags: {color: red} + color: red +- tags: {colour: red} + color: red +- tags: {color: violet} + color: violet +- tags: {colour: violet} + color: violet +- tags: {color: green} + color: green +- tags: {colour: green} + color: green +- tags: {color: yellow} + color: yellow +- tags: {colour: yellow} + color: yellow