mirror of
https://github.com/enzet/map-machine.git
synced 2025-06-05 04:12:08 +02:00
New tags for skip, write, and draw; options for parsing and drawing.
This commit is contained in:
parent
feb073032a
commit
e2cc8d8a14
4 changed files with 158 additions and 67 deletions
152
mapper.py
152
mapper.py
|
@ -26,18 +26,6 @@ sys.path.append('lib')
|
|||
import svg
|
||||
from vector import Vector
|
||||
|
||||
input_file_name = sys.argv[1]
|
||||
|
||||
if not os.path.isfile(input_file_name):
|
||||
print 'Fatal: no such file: ' + input_file_name + '.'
|
||||
sys.exit(1)
|
||||
|
||||
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 = 2650, 2650
|
||||
|
||||
background_color = 'EEEEEE'
|
||||
grass_color = 'C8DC94'
|
||||
sand_color = 'F0E0D0'
|
||||
|
@ -49,33 +37,39 @@ water_color = 'AACCFF'
|
|||
water_border_color = '6688BB'
|
||||
wood_color = 'B8CC84'
|
||||
|
||||
tags_to_write = ['operator', 'opening_hours', 'cuisine', 'network', 'website',
|
||||
tags_to_write = set(['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',
|
||||
'min_height', 'height', 'inscription', 'start_date']
|
||||
'min_height', 'height', 'inscription', 'start_date',
|
||||
'created_by', 'naptan:verified', 'url', 'naptan:AtcoCode',
|
||||
'naptan:Landmark', 'naptan:Indicator', 'collection_times',
|
||||
'naptan:Street', 'naptan:PlusbusZoneRef', 'naptan:Crossing',
|
||||
'local_ref', 'naptan:CommonName', 'survey:date',
|
||||
'naptan:NaptanCode', 'postal_code', 'uk_postcode_centroid',
|
||||
'fhrs:rating_date', 'fhrs:local_authority_id', 'destination',
|
||||
'fhrs:id', 'naptan:ShortCommonName', 'flickr', 'royal_cypher',
|
||||
'is_in', 'booth', 'naptan:AltStreet', 'media:commons',
|
||||
'ref_no', 'uri', 'fhrs:inspectiondate', 'telephone',
|
||||
'naptan:AltCommonName', 'end_date', 'facebook', 'naptan:Notes',
|
||||
'voltage', 'last_collection', 'twitter', 'ele', 'information',
|
||||
'phone_1', 'cyclestreets_id',
|
||||
# To draw
|
||||
'naptan:Bearing', 'species', 'taxon', 'seats', 'capacity',
|
||||
'fhrs:rating', 'fhrs:confidence_management', 'fhrs:hygiene',
|
||||
'genus', 'platforms', 'naptan:BusStopType'])
|
||||
|
||||
prefix_to_write = ['addr', 'contact', 'name', 'operator', 'wikipedia',
|
||||
prefix_to_write = set(['addr', 'contact', 'name', 'operator', 'wikipedia',
|
||||
'alt_name', 'description', 'old_name', 'inscription',
|
||||
'route_ref', 'is_in', 'website']
|
||||
'route_ref', 'is_in', 'website',
|
||||
# To draw
|
||||
'species', 'taxon'])
|
||||
|
||||
tags_to_skip = ['note', 'layer', 'source', 'building:part', 'fixme', 'comment']
|
||||
tags_to_skip = set(['note', 'layer', 'source', 'building:part', 'fixme', 'comment',
|
||||
'FIXME', 'source_ref', 'naptan:verified:note'])
|
||||
|
||||
prefix_to_skip = ['source']
|
||||
|
||||
output_file.begin(w, h)
|
||||
output_file.rect(0, 0, w, h, color=background_color)
|
||||
|
||||
minimum = Geo(180, 180)
|
||||
maximum = Geo(-180, -180)
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
min1 = Geo(float(sys.argv[5]), float(sys.argv[3]))
|
||||
max1 = Geo(float(sys.argv[6]), float(sys.argv[4]))
|
||||
|
||||
authors = {}
|
||||
missed_tags = {}
|
||||
prefix_to_skip = set(['source'])
|
||||
|
||||
def get_d_from_file(file_name):
|
||||
path, x, y = icons.get_path(file_name)
|
||||
|
@ -126,14 +120,6 @@ def get_min_max(node_map):
|
|||
return minimum, maximum
|
||||
|
||||
|
||||
minimum, maximum = get_min_max(node_map)
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
flinger = GeoFlinger(min1, max1, Vector(0, 0), Vector(w, h))
|
||||
else:
|
||||
flinger = GeoFlinger(minimum, maximum, Vector(25, 25), Vector(975, 975))
|
||||
|
||||
|
||||
def draw_path(nodes, style, shift=Vector()):
|
||||
prev_node = None
|
||||
for node_id in nodes:
|
||||
|
@ -185,10 +171,6 @@ def draw_text(text, x, y, fill):
|
|||
'" style="font-size:10;text-anchor:middle;font-family:Myriad Pro;fill:#' + fill + ';">' + text + '</text>')
|
||||
|
||||
def point(k, v, x, y, fill, text_y):
|
||||
if ('node ' + k + ': ' + v) in missed_tags:
|
||||
missed_tags['node ' + k + ': ' + v] += 1
|
||||
else:
|
||||
missed_tags['node ' + k + ': ' + v] = 1
|
||||
text = k + ': ' + v
|
||||
if type(text) == unicode:
|
||||
text = text.encode('utf-8')
|
||||
|
@ -206,11 +188,11 @@ def construct_layers():
|
|||
way = way_map[way_id]
|
||||
if not ('layer' in way['tags']):
|
||||
way['tags']['layer'] = 0
|
||||
if not (int(way['tags']['layer']) in layers):
|
||||
layers[int(way['tags']['layer'])] = \
|
||||
if not (float(way['tags']['layer']) in layers):
|
||||
layers[float(way['tags']['layer'])] = \
|
||||
{'b': [], 'h1': [], 'h2': [], 'r': [], 'n': [], 'l': [],
|
||||
'a': [], 'le': [], 'ba': [], 'bo': [], 'w': []}
|
||||
layer = layers[int(way['tags']['layer'])]
|
||||
layer = layers[float(way['tags']['layer'])]
|
||||
if 'building' in way['tags']:
|
||||
layer['b'].append(way)
|
||||
if 'natural' in way['tags']:
|
||||
|
@ -242,8 +224,6 @@ def construct_layers():
|
|||
return layers
|
||||
|
||||
|
||||
layers = construct_layers()
|
||||
|
||||
def draw_raw_ways():
|
||||
for way_id in way_map:
|
||||
way = way_map[way_id]
|
||||
|
@ -478,7 +458,7 @@ def draw_raw_nodes():
|
|||
def no_draw(key):
|
||||
if key in tags_to_write or key in tags_to_skip:
|
||||
return True
|
||||
for prefix in prefix_to_write + prefix_to_skip:
|
||||
for prefix in prefix_to_write.union(prefix_to_skip):
|
||||
if key[:len(prefix) + 1] == prefix + ':':
|
||||
return True
|
||||
return False
|
||||
|
@ -549,7 +529,7 @@ def get_icon(tags, scheme, fill='444444'):
|
|||
scheme['cache'][tags_hash] = returned
|
||||
return returned
|
||||
|
||||
def draw_nodes(show_missed_tags=False, overlap=14):
|
||||
def draw_nodes(show_missed_tags=False, overlap=14, draw=True):
|
||||
print 'Draw nodes...'
|
||||
|
||||
start_time = datetime.datetime.now()
|
||||
|
@ -579,14 +559,30 @@ def draw_nodes(show_missed_tags=False, overlap=14):
|
|||
p = {}
|
||||
|
||||
shapes, fill, processed = get_icon(p, scheme)
|
||||
processed_tags += len(processed)
|
||||
skipped_tags += len(p) - len(processed)
|
||||
|
||||
for k in p:
|
||||
if k in processed or no_draw(k):
|
||||
processed_tags += 1
|
||||
else:
|
||||
skipped_tags += 1
|
||||
|
||||
for k in []: # p:
|
||||
if to_write(k):
|
||||
draw_text(k + ': ' + p[k], x, y + 18 + text_y, '444444')
|
||||
text_y += 10
|
||||
|
||||
if show_missed_tags:
|
||||
for k in p:
|
||||
v = p[k]
|
||||
if not no_draw(k) and not k in processed:
|
||||
if ('node ' + k + ': ' + v) in missed_tags:
|
||||
missed_tags['node ' + k + ': ' + v] += 1
|
||||
else:
|
||||
missed_tags['node ' + k + ': ' + v] = 1
|
||||
|
||||
if not draw:
|
||||
continue
|
||||
|
||||
if show_missed_tags:
|
||||
for k in p:
|
||||
if not no_draw(k) and not k in processed:
|
||||
|
@ -617,20 +613,56 @@ def draw_nodes(show_missed_tags=False, overlap=14):
|
|||
str(skipped_tags) + ' (' + \
|
||||
str(processed_tags / float(processed_tags + skipped_tags) * 100) + ' %).'
|
||||
|
||||
# Actions
|
||||
|
||||
input_file_name = sys.argv[1]
|
||||
|
||||
if not os.path.isfile(input_file_name):
|
||||
print 'Fatal: no such file: ' + input_file_name + '.'
|
||||
sys.exit(1)
|
||||
|
||||
node_map, way_map, relation_map = osm_reader.parse_osm_file(input_file_name,
|
||||
parse_ways=False, parse_relations=False)
|
||||
|
||||
output_file = svg.SVG(open(sys.argv[2], 'w+'))
|
||||
|
||||
w, h = 2650, 2650
|
||||
|
||||
output_file.begin(w, h)
|
||||
output_file.rect(0, 0, w, h, color=background_color)
|
||||
|
||||
minimum = Geo(180, 180)
|
||||
maximum = Geo(-180, -180)
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
min1 = Geo(float(sys.argv[5]), float(sys.argv[3]))
|
||||
max1 = Geo(float(sys.argv[6]), float(sys.argv[4]))
|
||||
|
||||
authors = {}
|
||||
missed_tags = {}
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
flinger = GeoFlinger(min1, max1, Vector(0, 0), Vector(w, h))
|
||||
else:
|
||||
print 'Compute borders...'
|
||||
minimum, maximum = get_min_max(node_map)
|
||||
flinger = GeoFlinger(minimum, maximum, Vector(25, 25), Vector(975, 975))
|
||||
print 'Done.'
|
||||
|
||||
#layers = construct_layers()
|
||||
|
||||
#draw_raw_nodes()
|
||||
#draw_raw_ways()
|
||||
|
||||
text_y = 0
|
||||
|
||||
icons = extract_icon.IconExtractor('icons.svg')
|
||||
|
||||
#sys.exit(0)
|
||||
|
||||
#draw_ways()
|
||||
#draw_nodes(show_missed_tags=True, overlap=12)
|
||||
draw_nodes(show_missed_tags=False, overlap=12, draw=True)
|
||||
|
||||
#draw_ways()
|
||||
draw_nodes()
|
||||
#draw_nodes()
|
||||
|
||||
if flinger.space.x == 0:
|
||||
output_file.rect(0, 0, w, flinger.space.y, color='FFFFFF')
|
||||
|
@ -638,10 +670,12 @@ if flinger.space.x == 0:
|
|||
|
||||
output_file.end()
|
||||
|
||||
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]) + ')'
|
||||
missed_tags_file = open('missed_tags.yml', 'w+')
|
||||
for tag in top_missed_tags:
|
||||
missed_tags_file.write('- {tag: "' + tag + '", count: ' + \
|
||||
str(missed_tags[tag]) + '}\n')
|
||||
missed_tags_file.close()
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
|
|
@ -86,19 +86,26 @@ def parse_tag(text):
|
|||
v = text[v_index + 3:text.find('"', v_index + 4)]
|
||||
return k, v
|
||||
|
||||
def parse_osm_file(file_name):
|
||||
print 'Reading OSM file ' + file_name
|
||||
def parse_osm_file(file_name, parse_nodes=True, parse_ways=True,
|
||||
parse_relations=True):
|
||||
start_time = datetime.datetime.now()
|
||||
try:
|
||||
node_map, way_map, relation_map = parse_osm_file_fast(file_name)
|
||||
node_map, way_map, relation_map = parse_osm_file_fast(file_name,
|
||||
parse_nodes=parse_nodes, parse_ways=parse_ways,
|
||||
parse_relations=parse_relations)
|
||||
except Exception as e:
|
||||
print e
|
||||
print '\033[31mFast parsing failed.\033[0m'
|
||||
a = raw_input('Do you want to use slow but correct XML parsing? [y/n] ')
|
||||
if a in ['y', 'yes']:
|
||||
start_time = datetime.datetime.now()
|
||||
print 'Opening OSM file ' + file_name + '...'
|
||||
input_file = open(input_file_name)
|
||||
print 'Done.'
|
||||
print 'Parsing OSM file ' + file_name + '...'
|
||||
content = xml.dom.minidom.parse(input_file)
|
||||
input_file.close()
|
||||
print 'Done.'
|
||||
else:
|
||||
return None, None, None
|
||||
print 'File readed in ' + \
|
||||
|
@ -107,13 +114,17 @@ def parse_osm_file(file_name):
|
|||
str(len(way_map)) + ', relations: ' + str(len(relation_map)) + '.'
|
||||
return node_map, way_map, relation_map
|
||||
|
||||
def parse_osm_file_fast(file_name):
|
||||
def parse_osm_file_fast(file_name, parse_nodes=True, parse_ways=True,
|
||||
parse_relations=True):
|
||||
node_map = {}
|
||||
way_map = {}
|
||||
relation_map = {}
|
||||
print 'Line number counting for ' + file_name + '...'
|
||||
with open(file_name) as f:
|
||||
for lines_number, l in enumerate(f):
|
||||
pass
|
||||
print 'Done.'
|
||||
print 'Parsing OSM file ' + file_name + '...'
|
||||
input_file = open(file_name)
|
||||
line = input_file.readline()
|
||||
line_number = 0
|
||||
|
@ -124,6 +135,11 @@ def parse_osm_file_fast(file_name):
|
|||
# Node parsing.
|
||||
|
||||
if line[:6] in [' <node', '\t<node']:
|
||||
if not parse_nodes:
|
||||
if parse_ways or parse_relations:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
if line[-3] == '/':
|
||||
node = parse_node(line[7:-3])
|
||||
node_map[node['id']] = node
|
||||
|
@ -136,6 +152,11 @@ def parse_osm_file_fast(file_name):
|
|||
# Way parsing.
|
||||
|
||||
elif line[:5] in [' <way', '\t<way']:
|
||||
if not parse_ways:
|
||||
if parse_relations:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
if line[-3] == '/':
|
||||
way = parse_way(line[6:-3])
|
||||
way_map[node['id']] = way
|
||||
|
@ -149,6 +170,8 @@ def parse_osm_file_fast(file_name):
|
|||
# Relation parsing.
|
||||
|
||||
elif line[:10] in [' <relation', '\t<relation']:
|
||||
if not parse_relations:
|
||||
break
|
||||
if line[-3] == '/':
|
||||
relation = parse_relation(line[11:-3])
|
||||
relation_map[relation['id']] = relation
|
||||
|
|
29
tags.yml
29
tags.yml
|
@ -6,10 +6,12 @@ colors:
|
|||
'blue': '2233AA'
|
||||
'brown': '964B00'
|
||||
'darkgreen': '446722'
|
||||
'gold': 'FFD700' # Wikipedia
|
||||
'gray': '888888'
|
||||
'green': '4E9A06'
|
||||
'grey': '888888'
|
||||
'lightblue': '2288CC'
|
||||
'slate_blue': '2288CC' # The same
|
||||
'lightgreen': '73D216'
|
||||
'maroon': '800000'
|
||||
'orange': 'FCAF3E'
|
||||
|
@ -28,6 +30,7 @@ colors:
|
|||
'grass': 'C8DC94'
|
||||
'sand': 'F0E0D0'
|
||||
'beach': 'F0E0C0'
|
||||
'deciduous': 'FCAF3E'
|
||||
'desert': 'F0E0D0'
|
||||
'playground': '884400'
|
||||
'parking': 'DDCC99'
|
||||
|
@ -57,10 +60,14 @@ tags:
|
|||
icon: [restaurant]
|
||||
- tags: {amenity: pharmacy}
|
||||
icon: [pharmacy]
|
||||
- tags: {amenity: post_box}
|
||||
icon: [post_box]
|
||||
- tags: {amenity: drinking_water}
|
||||
icon: [drinking_water]
|
||||
- tags: {amenity: toilets}
|
||||
icon: [toilets]
|
||||
- tags: {amenity: telephone}
|
||||
icon: [telephone]
|
||||
- tags: {amenity: theatre}
|
||||
icon: [theatre]
|
||||
- tags: {amenity: bar}
|
||||
|
@ -90,6 +97,9 @@ tags:
|
|||
add_icon: [microphone]
|
||||
- tags: {building: '*', 'roof:material': metal}
|
||||
icon: [metal_roof]
|
||||
|
||||
# Trees
|
||||
|
||||
- tags: {natural: tree}
|
||||
icon: [tree]
|
||||
color: wood
|
||||
|
@ -102,6 +112,8 @@ tags:
|
|||
- tags: {natural: tree, type: conifer}
|
||||
icon: [needleleaved]
|
||||
color: wood
|
||||
- tags: {natural: tree, leaf_cycle: deciduous}
|
||||
color: deciduous
|
||||
- tags: {natural: tree, denotation: urban}
|
||||
over_icon: [urban_tree_pot]
|
||||
under_icon: [tree, broadleaved, needleleaved]
|
||||
|
@ -110,6 +122,7 @@ tags:
|
|||
under_icon: [tree, broadleaved, needleleaved]
|
||||
|
||||
# Entrance
|
||||
|
||||
- tags: {entrance: 'yes'}
|
||||
icon: [entrance]
|
||||
- tags: {entrance: main}
|
||||
|
@ -141,6 +154,10 @@ tags:
|
|||
add_icon: [no_traffic_signals]
|
||||
- tags: {highway: crossing, crossing: traffic_signals}
|
||||
add_icon: [traffic_signals]
|
||||
- tags: {highway: mini_roundabout}
|
||||
icon: [mini_roundabout]
|
||||
- tags: {highway: turning_circle}
|
||||
icon: [turning_circle]
|
||||
- tags: {highway: traffic_signals}
|
||||
icon: [traffic_signals]
|
||||
- tags: {traffic_calming: bump}
|
||||
|
@ -163,12 +180,20 @@ tags:
|
|||
icon: [mausoleum]
|
||||
- tags: {barrier: gate}
|
||||
icon: [gate]
|
||||
- tags: {barrier: bollard}
|
||||
icon: [bollard]
|
||||
- tags: {barrier: lift_gate}
|
||||
icon: [lift_gate]
|
||||
- tags: {barrier: turnstile}
|
||||
icon: [turnstile]
|
||||
- tags: {barrier: stile}
|
||||
icon: [stile]
|
||||
- tags: {man_made: pole}
|
||||
icon: [pole]
|
||||
- tags: {power: pole}
|
||||
icon: [pole]
|
||||
- tags: {power: tower}
|
||||
icon: [power_tower]
|
||||
- tags: {man_made: pole, highway: street_lamp}
|
||||
icon: [pole_lamp]
|
||||
- tags: {man_made: flagpole}
|
||||
|
@ -209,3 +234,7 @@ tags:
|
|||
add_icon: [trolleybus]
|
||||
- tags: {access: private}
|
||||
add_icon: [private]
|
||||
- tags: {direction: clockwise}
|
||||
add_icon: [clockwise]
|
||||
- tags: {smoking: 'no'}
|
||||
add_icon: [no_smoking]
|
||||
|
|
13
ui.py
13
ui.py
|
@ -6,15 +6,20 @@ Author: Sergey Vartanov (me@enzet.ru).
|
|||
|
||||
import sys
|
||||
|
||||
|
||||
def write_line(number, total):
|
||||
length = 20
|
||||
parts = length * 8
|
||||
boxes = [' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉']
|
||||
|
||||
if number == -1:
|
||||
print ('%3s' % '100') + ' % ░' + (length * '░') + '░'
|
||||
print ('%3s' % '100') + ' % █' + (length * '█') + '█'
|
||||
elif number % 1000 == 0:
|
||||
p = number / float(total)
|
||||
l = int(p * length)
|
||||
print ('%3s' % str(int(p * 1000) / 10)) + ' % ░' + (l * '░') + \
|
||||
((length - l) * ' ') + '░'
|
||||
l = int(p * parts)
|
||||
fl = l / 8
|
||||
pr = int(l - fl * 8)
|
||||
print ('%3s' % str(int(p * 1000) / 10)) + ' % █' + (fl * '█') + \
|
||||
boxes[pr] + ((length - fl - 1) * ' ') + '█'
|
||||
sys.stdout.write("\033[F")
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue