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

Revision 27545, 16.3 KB checked in by kdrangmeister, 2 years ago (diff)

Removed CssParameters? for mapnik 2.0

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