source: subversion/applications/rendering/parking/mapnik/generate_wifi_layer_xml.py @ 27717

Last change on this file since 27717 was 27682, checked in by kdrangmeister, 8 years ago

Added low-zoom 6x6 wifi icons

  • Property svn:mime-type set to text/plain
File size: 12.0 KB
Line 
1# -*- coding: utf-8 -*-
2# by kay
3
4import sys,os,subprocess,shutil
5from optparse import OptionParser
6#from xml.dom.minidom import parse, parseString
7import pxdom
8
9#import colorsys
10
11condition_colors = {
12    'free': '04c900',
13    'cust': 'c17223',
14    'none': '634e45',
15    'fee':  '037afe',
16    'unkn': 'a649b7'
17    }
18
19def dom_strip_style_and_layer(document,stylename,layername):
20    removeElements=[]
21    # remove <Style name="points"> and <Layer name="amenity-points">
22    els = document.getElementsByTagName("Style")
23    for el in els:
24        if el.getAttribute("name")==stylename:
25            removeElements.append(el)
26    els = document.getElementsByTagName("Layer")
27    for el in els:
28        if el.getAttribute("name")==layername:
29            removeElements.append(el)
30    print "removing the following elements:"
31    print removeElements
32    for el in removeElements:
33        parent = el.parentNode
34        parent.removeChild(el)
35
36def dom_strip_icons(document):
37    dom_strip_style_and_layer(document,"points","amenity-points")
38    dom_strip_style_and_layer(document,"power_line","power_line")
39    dom_strip_style_and_layer(document,"power_minorline","power_minorline")
40    dom_strip_style_and_layer(document,"power_towers","power_towers")
41    dom_strip_style_and_layer(document,"power_poles","power_poles")
42
43def transmogrify_file(sf,dfgrey,dfnoicons):
44    dom= pxdom.getDOMImplementation('')
45    parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
46    parser.domConfig.setParameter('entities', 0) # 1 -> exception if attribute values is set
47    #parser.domConfig.setParameter('disallow-doctype', 1)
48    parser.domConfig.setParameter('pxdom-resolve-resources', 1) # 1 -> replace &xyz; with text
49    document = parser.parseURI(sf)
50
51#    dom_convert_to_grey(document)
52   
53    output= document.implementation.createLSOutput()
54    output.systemId= dfgrey
55    output.encoding= 'utf-8'
56    serialiser= document.implementation.createLSSerializer()
57    serialiser.write(document, output)
58
59"""
60    dom_strip_icons(document)
61   
62    output= document.implementation.createLSOutput()
63    output.systemId= dfnoicons
64    output.encoding= 'utf-8'
65    serialiser= document.implementation.createLSSerializer()
66    serialiser.write(document, output)
67"""
68
69def strip_doctype(f):
70    p = subprocess.Popen(['sed','-i','2,9 d',f]) # -i means 'in place'
71    p.wait()
72
73def create_wifi_icons(source_symbols_dir,dest_symbols_dir):
74    create_wifi_area_icons(source_symbols_dir,dest_symbols_dir)
75    create_wifi_point_icons(source_symbols_dir,dest_symbols_dir)
76   
77def create_wifi_area_icons(source_symbols_dir,dest_symbols_dir):
78    return
79
80def create_wifi_point_icons(source_symbols_dir,dest_symbols_dir):
81    copy_files(source_symbols_dir,dest_symbols_dir,['wifi-vending.png'])
82    # wifi nodes
83    for condition in condition_colors.keys():
84        sf = os.path.join(source_symbols_dir,'wifi-source.png')
85        df = os.path.join(dest_symbols_dir,'wifi_node_{cond}.png'.format(cond=condition))
86        colorize_icon(sf,df,condition_colors.get(condition))
87    # wifi_6 nodes (lower zoom)
88    for condition in condition_colors.keys():
89        sf = os.path.join(source_symbols_dir,'wifi-6-source.png')
90        df = os.path.join(dest_symbols_dir,'wifi_node_6_{cond}.png'.format(cond=condition))
91        colorize_icon(sf,df,condition_colors.get(condition))
92
93def copy_files(src,dest,files):
94    for f in files:
95        if type(f) is tuple:
96            shutil.copy2(os.path.join(src,f[0]),os.path.join(dest,f[1]))
97        else:
98            shutil.copy2(os.path.join(src,f),os.path.join(dest,f))
99
100def colorize_icon(sf,df,color):
101    p = subprocess.Popen(['convert',sf,'-fill','#'+color,'-colorize','100',df])
102    p.wait()
103
104def hflip_icon(sf,df):
105    p = subprocess.Popen(['convert',sf,'-flip',df])
106    p.wait()
107
108def stamp_icon(sf,df,stampf):
109    p = subprocess.Popen(['convert',sf,stampf,'-compose','Darken','-composite',df])
110    p.wait()
111
112def add_license_files(dirname):
113    f = open(os.path.join(dirname,"CONTACT"), 'w')
114    f.write("This style is created by kayd@toolserver.org")
115    f.close
116    f = open(os.path.join(dirname,"LICENSE"), 'w')
117    f.write("This derived work is published by the author, Kay Drangmeister, under the same license as the original OSM mapnik style sheet (found here: http://svn.openstreetmap.org/applications/rendering/mapnik)")
118    f.close
119
120def main_wifitrans(options):
121    style_name = options['stylename']
122    source_dir = options['sourcedir']
123    source_file = options['sourcefile']
124    #source_symbols_dir_mapnik = os.path.join(source_dir,"symbols")
125    source_symbols_dir_style = os.path.join(source_dir,"wifi-symbols-src")
126    dest_dir = options['destdir']
127
128    # wifitrans - transparent layer to be put on top of mapnik or bw-noicons base layer
129   
130    dest_dir_style = os.path.join(dest_dir,style_name)
131    dest_dir_style_symbols = os.path.join(dest_dir_style,"symbols")
132    dest_file_style = 'osm-{style}.xml'.format(style=style_name)
133    style_file = os.path.join(dest_dir_style,dest_file_style)
134    if not os.path.exists(dest_dir_style_symbols):
135        os.makedirs(dest_dir_style_symbols)
136
137    create_wifi_icons(source_symbols_dir_style,dest_dir_style_symbols)
138    transmogrify_file(os.path.join(source_dir,source_file),style_file,"")
139    strip_doctype(style_file)
140    add_license_files(dest_dir_style)
141
142def main_wifi(options):
143    style_name = options['stylename']
144    source_bwn_dir = options['sourcebwndir']
145    source_bwn_file = options['sourcebwnfile']
146    source_p_dir = options['sourcepdir']
147    source_p_file = options['sourcepfile']
148    source_symbols_dir_style = os.path.join(source_p_dir,"wifi-symbols-src")
149    dest_dir = options['destdir']
150
151    dest_dir_style = os.path.join(dest_dir,style_name)
152    dest_dir_style_symbols = os.path.join(dest_dir_style,"symbols")
153    dest_file_style = 'osm-{style}.xml'.format(style=style_name)
154    style_file = os.path.join(dest_dir_style,dest_file_style)
155    if not os.path.exists(dest_dir_style_symbols):
156        os.makedirs(dest_dir_style_symbols)
157
158    create_wifi_icons(source_symbols_dir_style,dest_dir_style_symbols)
159    merge_bw_noicons_and_wifitrans_style(os.path.join(source_bwn_dir,source_bwn_file),os.path.join(source_p_dir,source_p_file),style_file)
160    #strip_doctype(style_file)
161    add_license_files(dest_dir_style)
162
163def merge_bw_noicons_and_wifitrans_style(bwnoicons_style_file,wifitrans_style_file,dest_wifi_style_file):
164    dom= pxdom.getDOMImplementation('')
165    parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
166    parser.domConfig.setParameter('entities', 0) # 1 -> exception if attribute values is set
167    #parser.domConfig.setParameter('disallow-doctype', 1)
168    parser.domConfig.setParameter('pxdom-resolve-resources', 1) # 1 -> replace &xyz; with text
169    dest_wifi_style_document = parser.parseURI(bwnoicons_style_file)
170    wifitrans_style_document = parser.parseURI(wifitrans_style_file)
171
172    wifi_area_style = dest_wifi_style_document.adoptNode(wifi_dom_cut_style(wifitrans_style_document,'wifi-area'))
173    wifi_area_layer = dest_wifi_style_document.adoptNode(wifi_dom_cut_layer(wifitrans_style_document,'wifi-area'))
174    things=[wifi_area_style,wifi_area_layer]
175    #better put wifi area layer earlier, before all roads
176    wifi_dom_insert_things_before_layer(dest_wifi_style_document,things,'turning_circle-casing')
177    # duplicate the wifi-area layer in order to make it less transparent
178    clone_of_wifi_area_layer = wifi_dom_clone_layer(dest_wifi_style_document,'wifi-area')
179    clone_of_wifi_area_layer.setAttribute('name','wifi-area-double')
180    wifi_dom_insert_things_before_layer(dest_wifi_style_document,clone_of_wifi_area_layer,'turning_circle-casing')
181
182    #add a second wifi area layer on top of the wifi-aisle roads.
183    wifi_area_top_layer = dest_wifi_style_document.adoptNode(wifi_dom_cut_layer(wifitrans_style_document,'wifi-area-top'))
184    things=[wifi_area_top_layer]
185    wifi_dom_insert_things_before_layer(dest_wifi_style_document,things,'direction_pre_bridges')
186
187    # handle the wifi points / nodes
188    wifi_points_style = dest_wifi_style_document.adoptNode(wifi_dom_cut_style(wifitrans_style_document,'wifi-points'))
189    wifi_points_layer = dest_wifi_style_document.adoptNode(wifi_dom_cut_layer(wifitrans_style_document,'wifi-points'))
190    things=[wifi_points_style,wifi_points_layer]
191    wifi_dom_insert_things_before_layer(dest_wifi_style_document,things,'direction_pre_bridges')
192
193    output= dest_wifi_style_document.implementation.createLSOutput()
194    output.systemId= dest_wifi_style_file
195    output.encoding= 'utf-8'
196    serialiser= dest_wifi_style_document.implementation.createLSSerializer()
197    serialiser.write(dest_wifi_style_document, output)
198
199    ''' write a "rest" file to check if everything has been cut out
200    output= wifitrans_style_document.implementation.createLSOutput()
201    output.systemId= 'rest.xml'
202    output.encoding= 'utf-8'
203    serialiser= wifitrans_style_document.implementation.createLSSerializer()
204    serialiser.write(wifitrans_style_document, output)
205    '''
206
207def wifi_dom_insert_things_before_layer(document,things,here):
208    # insert things after the "leisure" layer
209    els = document.getElementsByTagName("Layer")
210    #print "els="
211    #print els
212    for el in els:
213        #print "layername={ln}".format(ln=el.getAttribute("name"))
214        if el.getAttribute("name")==here:
215            #print "found it"
216            if type(things) is list:
217                for s in things:
218                    el.parentNode.insertBefore(s,el)
219            else:
220                el.parentNode.insertBefore(things,el)
221            return
222    raise 'Layer name not found'
223
224def wifi_dom_clone_layer(document,what):
225    els = document.getElementsByTagName("Layer")
226    for el in els:
227        #print "layername={ln}".format(ln=el.getAttribute("name"))
228        if el.getAttribute("name")==what:
229            #print "found it"
230            clone = el.cloneNode(True)
231            return clone
232    raise BaseException('Layer name {ln} not found'.format(ln=what))
233
234def wifi_dom_cut_layer(document,what):
235    els = document.getElementsByTagName("Layer")
236    for el in els:
237        #print "layername={ln}".format(ln=el.getAttribute("name"))
238        if el.getAttribute("name")==what:
239            #print "found it"
240            el.parentNode.removeChild(el)
241            return el
242    raise BaseException('Layer name {ln} not found'.format(ln=what))
243
244def wifi_dom_cut_style(document,what):
245    els = document.getElementsByTagName("Style")
246    for el in els:
247        #print "layername={ln}".format(ln=el.getAttribute("name"))
248        if el.getAttribute("name")==what:
249            #print "found it"
250            el.parentNode.removeChild(el)
251            return el
252    raise BaseException('Style name {sn} not found'.format(sn=what))
253
254"""
255./generate_xml.py osm-wifi-src.xml    osm-wifi.xml    --accept-none --host sql-mapnik --dbname osm_mapnik --prefix planet --inc ./wifi-inc --symbols ./wifi-symbols/ --world_boundaries /home/project/o/s/m/osm/data/world_boundaries/ --password ''
256./generate_xml.py osm-wifi-bw-src.xml osm-wifi-bw.xml --accept-none --host sql-mapnik --dbname osm_mapnik --prefix planet --inc ./wifi-inc --symbols ./wifi-symbols/ --world_boundaries /home/project/o/s/m/osm/data/world_boundaries/ --password ''
257./generate_xml.py osm-parkerr-src.xml    osm-parkerr.xml    --accept-none --host sql-mapnik --dbname osm_mapnik --prefix planet --inc ./wifi-inc --symbols ./wifi-symbols/ --world_boundaries /home/project/o/s/m/osm/data/world_boundaries/ --password ''
258"""
259
260if __name__ == '__main__':
261    parser = OptionParser()
262    parser.add_option("-s", "--sourcedir", dest="sourcedir", help="path to the source directory", default=".")
263    parser.add_option("-f", "--sourcefile", dest="sourcefile", help="source filename, default is 'osm.xml')", default="osm.xml")
264    parser.add_option("-d", "--destdir", dest="destdir", help="path to the destination directory, further dirs are created within. default is '/tmp'", default="/tmp")
265    (options, args) = parser.parse_args()
266    options['stylename'] = "wifitrans"
267    print options
268    main_wifitrans(options.__dict__)
269    options['sourcefile'] = "osm-wifi-src.xml"
270    options['stylename'] = "wifi"
271    main_wifi(options.__dict__)
272    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.