source: subversion/applications/rendering/parking/mapnik/generate_parking_layer_xml.py @ 26686

Revision 26686, 17.8 KB checked in by kdrangmeister, 3 years ago (diff)

Added parking nodes

  • Property svn:mime-type set to text/plain
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': '7fff00',
13    'disc': '50a100',
14    'cust': 'b68529',
15    'resi': '785534',
16    'priv': '3f2920',
17    'fee':  '67a1eb',
18    'unkn': 'bc73e2' # purple:'bc73e2' ; bluegreen:'6fc58a'
19    }
20
21forbidden_colors = {
22    'nopa': 'f8b81f',
23    'nost': 'f85b1f',
24    'fire': 'f81f1f'
25    }
26
27
28"""
29def dom_convert_to_grey(document):
30    els = document.getElementsByTagName("CssParameter")
31    #print "els=",els
32    for el in els:
33        at = el.getAttribute("name")
34        if at=="stroke" or at=="fill":
35            col=el.firstChild.nodeValue
36            bw=rgb_to_css(color_to_bw(parse_color(col)))
37            print "converted {typ} from {a} to {bw}." .format(typ=at,a=col,bw=bw)
38            el.firstChild.nodeValue=bw
39
40    #<Map bgcolor="---" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over" minimum_version="0.7.1">
41    els = document.getElementsByTagName("Map")
42    for el in els:
43        col = el.getAttribute("bgcolor")
44        assert(col!='')
45        assert(col!=None)
46        bw=rgb_to_css(color_to_bw(parse_color(col)))
47        print "converted {typ} from {a} to {bw}." .format(typ='bgcolor',a=col,bw=bw)
48        el.setAttribute("bgcolor",bw)
49
50    #<TextSymbolizer ... fill="#6699cc"/>
51    els = document.getElementsByTagName("TextSymbolizer")
52    for el in els:
53        col = el.getAttribute("fill")
54        assert(col!='')
55        assert(col!=None)
56        bw=rgb_to_css(color_to_bw(parse_color(col)))
57        print "converted {typ} from {a} to {bw}." .format(typ='TS-fill',a=col,bw=bw)
58        el.setAttribute("fill",bw)
59        #<TextSymbolizer halo_fill="#fed7a5"/> (optional)
60        col = el.getAttribute("halo_fill")
61        assert(col!=None)
62        if col!='':
63            bw=rgb_to_css(color_to_bw(parse_color(col)))
64            print "converted {typ} from {a} to {bw}." .format(typ='TS-halo_fill',a=col,bw=bw)
65            el.setAttribute("halo_fill",bw)
66"""
67
68def dom_strip_style_and_layer(document,stylename,layername):
69    removeElements=[]
70    # remove <Style name="points"> and <Layer name="amenity-points">
71    els = document.getElementsByTagName("Style")
72    for el in els:
73        if el.getAttribute("name")==stylename:
74            removeElements.append(el)
75    els = document.getElementsByTagName("Layer")
76    for el in els:
77        if el.getAttribute("name")==layername:
78            removeElements.append(el)
79    print "removing the following elements:"
80    print removeElements
81    for el in removeElements:
82        parent = el.parentNode
83        parent.removeChild(el)
84
85def dom_strip_icons(document):
86    dom_strip_style_and_layer(document,"points","amenity-points")
87    dom_strip_style_and_layer(document,"power_line","power_line")
88    dom_strip_style_and_layer(document,"power_minorline","power_minorline")
89    dom_strip_style_and_layer(document,"power_towers","power_towers")
90    dom_strip_style_and_layer(document,"power_poles","power_poles")
91
92def transmogrify_file(sf,dfgrey,dfnoicons):
93    dom= pxdom.getDOMImplementation('')
94    parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
95    parser.domConfig.setParameter('entities', 0) # 1 -> exception if attribute values is set
96    #parser.domConfig.setParameter('disallow-doctype', 1)
97    parser.domConfig.setParameter('pxdom-resolve-resources', 1) # 1 -> replace &xyz; with text
98    document = parser.parseURI(sf)
99
100#    dom_convert_to_grey(document)
101   
102    output= document.implementation.createLSOutput()
103    output.systemId= dfgrey
104    output.encoding= 'utf-8'
105    serialiser= document.implementation.createLSSerializer()
106    serialiser.write(document, output)
107
108"""
109    dom_strip_icons(document)
110   
111    output= document.implementation.createLSOutput()
112    output.systemId= dfnoicons
113    output.encoding= 'utf-8'
114    serialiser= document.implementation.createLSSerializer()
115    serialiser.write(document, output)
116"""
117
118def strip_doctype(f):
119    p = subprocess.Popen(['sed','-i','2,10 d',f]) # -i means 'in place'
120    p.wait()
121
122def create_parking_icons(source_symbols_dir,dest_symbols_dir):
123    create_parking_lane_icons(source_symbols_dir,dest_symbols_dir)
124    create_parking_area_icons(source_symbols_dir,dest_symbols_dir)
125    create_parking_point_icons(source_symbols_dir,dest_symbols_dir)
126   
127def create_parking_lane_icons(source_symbols_dir,dest_symbols_dir):
128    # first create mirror images (from left to right)
129    image_files = os.listdir(source_symbols_dir)
130    image_files = [f for f in image_files if f.startswith('park-l') and f.endswith('png')]
131    for f in image_files:
132        sf = os.path.join(source_symbols_dir,f)
133        df = os.path.join(source_symbols_dir,f) # this is changed so that we write in the source dir
134        hflip_icon(sf,df.replace('-l','-r'))
135
136    # then, create the colors
137    image_files = os.listdir(source_symbols_dir)
138    image_files = [f for f in image_files if f.endswith('source.png')]
139    for f in image_files:
140        # convert ./original-mapnik/symbols/*.png -fx '0.25*r + 0.62*g + 0.13*b' ./bw-mapnik/symbols/*.png
141        sf = os.path.join(source_symbols_dir,f)
142        df = os.path.join(dest_symbols_dir,f)
143        if 'n-' in f:      # then it's a non-parking thing
144            for c in forbidden_colors.iterkeys():
145                colorize_icon(sf,df.replace('source',c),forbidden_colors.get(c))
146        else:
147            for c in condition_colors.iterkeys():
148                colorize_icon(sf,df.replace('source',c),condition_colors.get(c))
149
150def create_parking_area_icons(source_symbols_dir,dest_symbols_dir):
151    tempf = "/tmp/2347856893476512873465.png"
152    df = os.path.join(dest_symbols_dir,"parking_area_source.png")
153    stampf = os.path.join(source_symbols_dir,"parking_area_stamp.png")
154    for c in condition_colors.iterkeys():
155        # step 1: colorize a "stamp" template image
156        p = subprocess.Popen(['convert','-size','16x16','xc:#'+condition_colors.get(c),stampf,'-compose','Darken','-composite',tempf])
157        p.wait()
158        # step 2: make it 50% transparent
159        # convert -size 16x16 parking_area_free.png xc:grey -alpha off -compose Copy_Opacity -composite  /tmp/a.png && gwenview /tmp/a.png
160        p = subprocess.Popen(['convert','-size','16x16',tempf,'xc:gray','-alpha','off','-compose','Copy_Opacity','-composite',df.replace('source',c)])
161        p.wait()
162
163
164def create_parking_point_icons(source_symbols_dir,dest_symbols_dir):
165    tempf = "/tmp/2347856893476512873465.png"
166    stampf = os.path.join(source_symbols_dir,"parking_node_stamp.png")
167    # for now there's only the parking-vending icon
168    copy_files(source_symbols_dir,dest_symbols_dir,['parking-vending.png'])
169    # parking nodes
170    image_files = ['parking_node_{cond}.png'.format(cond=f) for f in condition_colors.keys()]
171    for condition in condition_colors.keys():
172        # convert ./original-mapnik/symbols/*.png -fx '0.25*r + 0.62*g + 0.13*b' ./bw-mapnik/symbols/*.png
173        sf = os.path.join(source_symbols_dir,'parking_node_source.png')
174        df = os.path.join(dest_symbols_dir,'parking_node_{cond}.png'.format(cond=condition))
175        colorize_icon(sf,tempf,condition_colors.get(condition))
176        p = subprocess.Popen(['convert','-size','16x16',tempf,stampf,'-compose','Darken','-composite',df])
177        print (['convert','-size','16x16',tempf,stampf,'-compose','Darken','-composite',df])
178        p.wait()
179
180def copy_files(src,dest,files):
181    for f in files:
182        if type(f) is tuple:
183            shutil.copy2(os.path.join(src,f[0]),os.path.join(dest,f[1]))
184        else:
185            shutil.copy2(os.path.join(src,f),os.path.join(dest,f))
186
187def colorize_icon(sf,df,color):
188    p = subprocess.Popen(['convert',sf,'-fill','#'+color,'-colorize','100',df])
189    p.wait()
190
191def hflip_icon(sf,df):
192    p = subprocess.Popen(['convert',sf,'-flip',df])
193    p.wait()
194
195def stamp_icon(sf,df,stampf):
196    p = subprocess.Popen(['convert',sf,stampf,'-compose','Darken','-composite',df])
197    p.wait()
198
199def add_license_files(dirname):
200    f = open(os.path.join(dirname,"CONTACT"), 'w')
201    f.write("This style is created by kayd@toolserver.org")
202    f.close
203    f = open(os.path.join(dirname,"LICENSE"), 'w')
204    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)")
205    f.close
206
207def main_parktrans(options):
208    style_name = options['stylename']
209    source_dir = options['sourcedir']
210    source_file = options['sourcefile']
211    #source_symbols_dir_mapnik = os.path.join(source_dir,"symbols")
212    source_symbols_dir_style = os.path.join(source_dir,"parking-symbols-src")
213    dest_dir = options['destdir']
214
215    # parktrans - transparent layer to be put on top of mapnik or bw-noicons base layer
216   
217    dest_dir_style = os.path.join(dest_dir,style_name)
218    dest_dir_style_symbols = os.path.join(dest_dir_style,"symbols")
219    dest_file_style = 'osm-{style}.xml'.format(style=style_name)
220    style_file = os.path.join(dest_dir_style,dest_file_style)
221    if not os.path.exists(dest_dir_style_symbols):
222        os.makedirs(dest_dir_style_symbols)
223
224    create_parking_icons(source_symbols_dir_style,dest_dir_style_symbols)
225    transmogrify_file(os.path.join(source_dir,source_file),style_file,"")
226    strip_doctype(style_file)
227    add_license_files(dest_dir_style)
228
229def main_parking(options):
230    style_name = options['stylename']
231    source_bwn_dir = options['sourcebwndir']
232    source_bwn_file = options['sourcebwnfile']
233    source_p_dir = options['sourcepdir']
234    source_p_file = options['sourcepfile']
235    source_symbols_dir_style = os.path.join(source_p_dir,"parking-symbols-src")
236    dest_dir = options['destdir']
237
238    dest_dir_style = os.path.join(dest_dir,style_name)
239    dest_dir_style_symbols = os.path.join(dest_dir_style,"symbols")
240    dest_file_style = 'osm-{style}.xml'.format(style=style_name)
241    style_file = os.path.join(dest_dir_style,dest_file_style)
242    if not os.path.exists(dest_dir_style_symbols):
243        os.makedirs(dest_dir_style_symbols)
244
245    create_parking_icons(source_symbols_dir_style,dest_dir_style_symbols)
246    merge_bw_noicons_and_parktrans_style(os.path.join(source_bwn_dir,source_bwn_file),os.path.join(source_p_dir,source_p_file),style_file)
247    #strip_doctype(style_file)
248    add_license_files(dest_dir_style)
249
250def merge_bw_noicons_and_parktrans_style(bwnoicons_style_file,parktrans_style_file,dest_parking_style_file):
251    dom= pxdom.getDOMImplementation('')
252    parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
253    parser.domConfig.setParameter('entities', 0) # 1 -> exception if attribute values is set
254    #parser.domConfig.setParameter('disallow-doctype', 1)
255    parser.domConfig.setParameter('pxdom-resolve-resources', 1) # 1 -> replace &xyz; with text
256    dest_parking_style_document = parser.parseURI(bwnoicons_style_file)
257    parktrans_style_document = parser.parseURI(parktrans_style_file)
258
259#    dom_convert_to_grey(document)
260    parking_area_style = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parking-area'))
261    parking_area_layer = dest_parking_style_document.adoptNode(parking_dom_cut_layer(parktrans_style_document,'parking-area'))
262    #parking_dom_insert_things_before_layer(dest_parking_style_document,parking_area_style,'planet roads text osm low zoom')
263    #parking_dom_insert_things_before_layer(dest_parking_style_document,parking_area_layer,'planet roads text osm low zoom')
264    things=[parking_area_style,parking_area_layer]
265    #parking_dom_insert_things_before_layer(dest_parking_style_document,things,'planet roads text osm low zoom')
266    #better put parking area layer earlier, before all roads
267    parking_dom_insert_things_before_layer(dest_parking_style_document,things,'turning_circle-casing')
268    #add a second parking area layer on top of the parking-aisle roads.
269    parking_area_top_layer = dest_parking_style_document.adoptNode(parking_dom_cut_layer(parktrans_style_document,'parking-area-top'))
270    things=[parking_area_top_layer]
271    parking_dom_insert_things_before_layer(dest_parking_style_document,things,'direction_pre_bridges')
272
273    pllno = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-left-no'))
274    plrno = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-right-no'))
275    pllin = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-left-parallel'))
276    plrin = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-right-parallel'))
277    plldi = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-left-diagonal'))
278    plrdi = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-right-diagonal'))
279    pllor = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-left-perpendicular'))
280    plror = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parkinglane-right-perpendicular'))
281    pll = dest_parking_style_document.adoptNode(parking_dom_cut_layer(parktrans_style_document,'parkinglane-left'))
282    plr = dest_parking_style_document.adoptNode(parking_dom_cut_layer(parktrans_style_document,'parkinglane-right'))
283
284    things=[pllno,plrno,pllin,plrin,plldi,plrdi,pllor,plror,pll,plr]
285    parking_dom_insert_things_before_layer(dest_parking_style_document,things,'direction_pre_bridges')
286
287    parking_points_style = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parking-points'))
288    parking_points_layer = dest_parking_style_document.adoptNode(parking_dom_cut_layer(parktrans_style_document,'parking-points'))
289    parking_area_text_style = dest_parking_style_document.adoptNode(parking_dom_cut_style(parktrans_style_document,'parking-area-text'))
290    parking_area_text_layer = dest_parking_style_document.adoptNode(parking_dom_cut_layer(parktrans_style_document,'parking-area-text'))
291    #parking_dom_insert_things_before_layer(dest_parking_style_document,parking_area_style,'planet roads text osm low zoom')
292    #parking_dom_insert_things_before_layer(dest_parking_style_document,parking_area_layer,'planet roads text osm low zoom')
293    things=[parking_points_style,parking_points_layer,parking_area_text_style,parking_area_text_layer]
294    parking_dom_insert_things_before_layer(dest_parking_style_document,things,'direction_pre_bridges')
295
296    output= dest_parking_style_document.implementation.createLSOutput()
297    output.systemId= dest_parking_style_file
298    output.encoding= 'utf-8'
299    serialiser= dest_parking_style_document.implementation.createLSSerializer()
300    serialiser.write(dest_parking_style_document, output)
301
302    ''' write a "rest" file to check if everything has been cut out
303    output= parktrans_style_document.implementation.createLSOutput()
304    output.systemId= 'rest.xml'
305    output.encoding= 'utf-8'
306    serialiser= parktrans_style_document.implementation.createLSSerializer()
307    serialiser.write(parktrans_style_document, output)
308    '''
309
310def parking_dom_insert_things_before_layer(document,things,here):
311    # insert things after the "leisure" layer
312    els = document.getElementsByTagName("Layer")
313    #print "els="
314    #print els
315    for el in els:
316        #print "layername={ln}".format(ln=el.getAttribute("name"))
317        if el.getAttribute("name")==here:
318            #print "found it"
319            if type(things) is list:
320                for s in things:
321                    el.parentNode.insertBefore(s,el)
322            else:
323                el.parentNode.insertBefore(things,el)
324            return
325    raise 'Layer name not found'
326
327def parking_dom_cut_layer(document,what):
328    els = document.getElementsByTagName("Layer")
329    for el in els:
330        #print "layername={ln}".format(ln=el.getAttribute("name"))
331        if el.getAttribute("name")==what:
332            #print "found it"
333            el.parentNode.removeChild(el)
334            return el
335    raise BaseException('Layer name {ln} not found'.format(ln=what))
336
337def parking_dom_cut_style(document,what):
338    els = document.getElementsByTagName("Style")
339    for el in els:
340        #print "layername={ln}".format(ln=el.getAttribute("name"))
341        if el.getAttribute("name")==what:
342            #print "found it"
343            el.parentNode.removeChild(el)
344            return el
345    raise BaseException('Style name {sn} not found'.format(sn=what))
346
347"""
348./generate_xml.py osm-parking-src.xml    osm-parking.xml    --accept-none --host sql-mapnik --dbname osm_mapnik --prefix planet --inc ./parking-inc --symbols ./parking-symbols/ --world_boundaries /home/project/o/s/m/osm/data/world_boundaries/ --password ''
349./generate_xml.py osm-parking-bw-src.xml osm-parking-bw.xml --accept-none --host sql-mapnik --dbname osm_mapnik --prefix planet --inc ./parking-inc --symbols ./parking-symbols/ --world_boundaries /home/project/o/s/m/osm/data/world_boundaries/ --password ''
350./generate_xml.py osm-parkerr-src.xml    osm-parkerr.xml    --accept-none --host sql-mapnik --dbname osm_mapnik --prefix planet --inc ./parking-inc --symbols ./parking-symbols/ --world_boundaries /home/project/o/s/m/osm/data/world_boundaries/ --password ''
351"""
352
353if __name__ == '__main__':
354    parser = OptionParser()
355    parser.add_option("-s", "--sourcedir", dest="sourcedir", help="path to the source directory", default=".")
356    parser.add_option("-f", "--sourcefile", dest="sourcefile", help="source filename, default is 'osm.xml')", default="osm.xml")
357    parser.add_option("-d", "--destdir", dest="destdir", help="path to the destination directory, further dirs are created within. default is '/tmp'", default="/tmp")
358    (options, args) = parser.parse_args()
359    options['stylename'] = "parktrans"
360    print options
361    main_parktrans(options.__dict__)
362    options['sourcefile'] = "osm-parking-src.xml"
363    options['stylename'] = "parking"
364    main_parking(options.__dict__)
365    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.