source: subversion/applications/rendering/parking/mapnik/mapnik-to-bw.py @ 26204

Last change on this file since 26204 was 24156, checked in by kdrangmeister, 9 years ago

added afa-30100, removed power-lines

File size: 11.1 KB
Line 
1# -*- coding: utf-8 -*-
2# by kay
3
4import sys,os,subprocess
5from optparse import OptionParser
6#from xml.dom.minidom import parse, parseString
7import pxdom
8import colorsys
9
10simple_colors = {
11    'aliceblue': 'f0f8ff',
12    'antiquewhite': 'faebd7',
13    'aqua': '00ffff',
14    'aquamarine': '7fffd4',
15    'azure': 'f0ffff',
16    'beige': 'f5f5dc',
17    'bisque': 'ffe4c4',
18    'black': '000000',
19    'blanchedalmond': 'ffebcd',
20    'blue': '0000ff',
21    'blueviolet': '8a2be2',
22    'brown': 'a52a2a',
23    'burlywood': 'deb887',
24    'cadetblue': '5f9ea0',
25    'chartreuse': '7fff00',
26    'chocolate': 'd2691e',
27    'coral': 'ff7f50',
28    'cornflowerblue': '6495ed',
29    'cornsilk': 'fff8dc',
30    'crimson': 'dc143c',
31    'cyan': '00ffff',
32    'darkblue': '00008b',
33    'darkcyan': '008b8b',
34    'darkgoldenrod': 'b8860b',
35    'darkgray': 'a9a9a9',
36    'darkgreen': '006400',
37    'darkkhaki': 'bdb76b',
38    'darkmagenta': '8b008b',
39    'darkolivegreen': '556b2f',
40    'darkorange': 'ff8c00',
41    'darkorchid': '9932cc',
42    'darkred': '8b0000',
43    'darksalmon': 'e9967a',
44    'darkseagreen': '8fbc8f',
45    'darkslateblue': '483d8b',
46    'darkslategray': '2f4f4f',
47    'darkturquoise': '00ced1',
48    'darkviolet': '9400d3',
49    'deeppink': 'ff1493',
50    'deepskyblue': '00bfff',
51    'dimgray': '696969',
52    'dodgerblue': '1e90ff',
53    'feldspar': 'd19275',
54    'firebrick': 'b22222',
55    'floralwhite': 'fffaf0',
56    'forestgreen': '228b22',
57    'fuchsia': 'ff00ff',
58    'gainsboro': 'dcdcdc',
59    'ghostwhite': 'f8f8ff',
60    'gold': 'ffd700',
61    'goldenrod': 'daa520',
62    'gray': '808080',
63    'green': '008000',
64    'greenyellow': 'adff2f',
65    'grey': '808080',
66    'honeydew': 'f0fff0',
67    'hotpink': 'ff69b4',
68    'indianred ': 'cd5c5c',
69    'indigo ': '4b0082',
70    'ivory': 'fffff0',
71    'khaki': 'f0e68c',
72    'lavender': 'e6e6fa',
73    'lavenderblush': 'fff0f5',
74    'lawngreen': '7cfc00',
75    'lemonchiffon': 'fffacd',
76    'lightblue': 'add8e6',
77    'lightcoral': 'f08080',
78    'lightcyan': 'e0ffff',
79    'lightgoldenrodyellow': 'fafad2',
80    'lightgrey': 'd3d3d3',
81    'lightgreen': '90ee90',
82    'lightpink': 'ffb6c1',
83    'lightsalmon': 'ffa07a',
84    'lightseagreen': '20b2aa',
85    'lightskyblue': '87cefa',
86    'lightslateblue': '8470ff',
87    'lightslategray': '778899',
88    'lightsteelblue': 'b0c4de',
89    'lightyellow': 'ffffe0',
90    'lime': '00ff00',
91    'limegreen': '32cd32',
92    'linen': 'faf0e6',
93    'magenta': 'ff00ff',
94    'maroon': '800000',
95    'mediumaquamarine': '66cdaa',
96    'mediumblue': '0000cd',
97    'mediumorchid': 'ba55d3',
98    'mediumpurple': '9370d8',
99    'mediumseagreen': '3cb371',
100    'mediumslateblue': '7b68ee',
101    'mediumspringgreen': '00fa9a',
102    'mediumturquoise': '48d1cc',
103    'mediumvioletred': 'c71585',
104    'midnightblue': '191970',
105    'mintcream': 'f5fffa',
106    'mistyrose': 'ffe4e1',
107    'moccasin': 'ffe4b5',
108    'navajowhite': 'ffdead',
109    'navy': '000080',
110    'oldlace': 'fdf5e6',
111    'olive': '808000',
112    'olivedrab': '6b8e23',
113    'orange': 'ffa500',
114    'orangered': 'ff4500',
115    'orchid': 'da70d6',
116    'palegoldenrod': 'eee8aa',
117    'palegreen': '98fb98',
118    'paleturquoise': 'afeeee',
119    'palevioletred': 'd87093',
120    'papayawhip': 'ffefd5',
121    'peachpuff': 'ffdab9',
122    'peru': 'cd853f',
123    'pink': 'ffc0cb',
124    'plum': 'dda0dd',
125    'powderblue': 'b0e0e6',
126    'purple': '800080',
127    'red': 'ff0000',
128    'rosybrown': 'bc8f8f',
129    'royalblue': '4169e1',
130    'saddlebrown': '8b4513',
131    'salmon': 'fa8072',
132    'sandybrown': 'f4a460',
133    'seagreen': '2e8b57',
134    'seashell': 'fff5ee',
135    'sienna': 'a0522d',
136    'silver': 'c0c0c0',
137    'skyblue': '87ceeb',
138    'slateblue': '6a5acd',
139    'slategray': '708090',
140    'snow': 'fffafa',
141    'springgreen': '00ff7f',
142    'steelblue': '4682b4',
143    'tan': 'd2b48c',
144    'teal': '008080',
145    'thistle': 'd8bfd8',
146    'tomato': 'ff6347',
147    'turquoise': '40e0d0',
148    'violet': 'ee82ee',
149    'violetred': 'd02090',
150    'wheat': 'f5deb3',
151    'white': 'ffffff',
152    'whitesmoke': 'f5f5f5',
153    'yellow': 'ffff00',
154    'yellowgreen': '9acd32'
155    }
156
157def color_to_bw(rgb):
158    r,g,b=rgb
159    #method 1:
160    #y = 0.229*r + 0.587*g + 0.114*b
161    y = 0.25*r + 0.62*g + 0.13*b
162    return (y,y,y)
163    #method 2:
164    h,l,s = colorsys.rgb_to_hls(r, g, b)
165    s = 0
166    return colorsys.hls_to_rgb(h,l,s)
167
168def parse_color(s):
169    """ Parses color string in format #ABC or #AABBCC to RGB tuple. """
170    s = s.lower()
171    if simple_colors.has_key(s):  # translate color names to rgb
172        s = '#'+simple_colors.get(s)
173    l = len(s)
174    assert(l in (4,7))
175#    print "s=",s
176    if l==4:
177        return tuple(int(ch * 2, 16)/255.0 for ch in s[1:])
178    else:
179        return tuple(int(ch1 + ch2, 16)/255.0 for ch1, ch2 in \
180                     zip(
181                        (ch1 for ch1 in s[1::2]),
182                        (ch2 for ch2 in s[2::2])
183                        )
184                    )
185
186def rgb_to_css(rgb):
187    r,g,b=rgb
188    return "#{r:02x}{g:02x}{b:02x}".format(r=int(r*255.0),g=int(g*255.0),b=int(b*255.0))
189
190def dom_convert_to_grey(document):
191    els = document.getElementsByTagName("CssParameter")
192    #print "els=",els
193    for el in els:
194        at = el.getAttribute("name")
195        if at=="stroke" or at=="fill":
196            col=el.firstChild.nodeValue
197            bw=rgb_to_css(color_to_bw(parse_color(col)))
198            print "converted {typ} from {a} to {bw}." .format(typ=at,a=col,bw=bw)
199            el.firstChild.nodeValue=bw
200
201    #<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">
202    els = document.getElementsByTagName("Map")
203    for el in els:
204        col = el.getAttribute("bgcolor")
205        assert(col!='')
206        assert(col!=None)
207        bw=rgb_to_css(color_to_bw(parse_color(col)))
208        print "converted {typ} from {a} to {bw}." .format(typ='bgcolor',a=col,bw=bw)
209        el.setAttribute("bgcolor",bw)
210
211    #<TextSymbolizer ... fill="#6699cc"/>
212    els = document.getElementsByTagName("TextSymbolizer")
213    for el in els:
214        col = el.getAttribute("fill")
215        assert(col!='')
216        assert(col!=None)
217        bw=rgb_to_css(color_to_bw(parse_color(col)))
218        print "converted {typ} from {a} to {bw}." .format(typ='TS-fill',a=col,bw=bw)
219        el.setAttribute("fill",bw)
220        #<TextSymbolizer halo_fill="#fed7a5"/> (optional)
221        col = el.getAttribute("halo_fill")
222        assert(col!=None)
223        if col!='':
224            bw=rgb_to_css(color_to_bw(parse_color(col)))
225            print "converted {typ} from {a} to {bw}." .format(typ='TS-halo_fill',a=col,bw=bw)
226            el.setAttribute("halo_fill",bw)
227
228
229def dom_strip_style_and_layer(document,stylename,layername):
230    removeElements=[]
231    # remove <Style name="points"> and <Layer name="amenity-points">
232    els = document.getElementsByTagName("Style")
233    for el in els:
234        if el.getAttribute("name")==stylename:
235            removeElements.append(el)
236    els = document.getElementsByTagName("Layer")
237    for el in els:
238        if el.getAttribute("name")==layername:
239            removeElements.append(el)
240    print removeElements
241    for el in removeElements:
242        parent = el.parentNode
243        parent.removeChild(el)
244
245def dom_strip_icons(document):
246    dom_strip_style_and_layer(document,"points","amenity-points")
247    dom_strip_style_and_layer(document,"power_line","power_line")
248    dom_strip_style_and_layer(document,"power_minorline","power_minorline")
249    dom_strip_style_and_layer(document,"power_towers","power_towers")
250    dom_strip_style_and_layer(document,"power_poles","power_poles")
251
252def transmogrify_file(sf,dfgrey,dfnoicons):
253    dom= pxdom.getDOMImplementation('') 
254    parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
255    parser.domConfig.setParameter('entities', 0) # 1 -> exception if attribute values is set
256    #parser.domConfig.setParameter('disallow-doctype', 1)
257    parser.domConfig.setParameter('pxdom-resolve-resources', 1) # 1 -> replace &xyz; with text
258    document = parser.parseURI(sf)
259
260    dom_convert_to_grey(document)
261   
262    output= document.implementation.createLSOutput() 
263    output.systemId= dfgrey
264    output.encoding= 'utf-8' 
265    serialiser= document.implementation.createLSSerializer() 
266    serialiser.write(document, output)
267
268    dom_strip_icons(document)
269   
270    output= document.implementation.createLSOutput() 
271    output.systemId= dfnoicons
272    output.encoding= 'utf-8' 
273    serialiser= document.implementation.createLSSerializer() 
274    serialiser.write(document, output)
275
276def strip_doctype(f):
277    p = subprocess.Popen(['sed','-i','2,5 d',f]) # -i means 'in place'
278    p.wait()
279
280def convert_icons_to_bw(source_symbols_dir,dest_symbols_dir):
281    image_files = os.listdir(source_symbols_dir)
282    image_files = [f for f in image_files if f.endswith('png')]
283    for f in image_files:
284        # convert ./original-mapnik/symbols/*.png -fx '0.25*r + 0.62*g + 0.13*b' ./bw-mapnik/symbols/*.png
285        sf = os.path.join(source_symbols_dir,f)
286        df = os.path.join(dest_symbols_dir,f)
287        p = subprocess.Popen(['convert',sf,'-fx','0.25*r + 0.62*g + 0.13*b',df])
288        p.wait()
289
290def add_license_files(dirname):
291    f = open(os.path.join(dirname,"CONTACT"), 'w')
292    f.write("This style is created by kayd@toolserver.org")
293    f.close
294    f = open(os.path.join(dirname,"LICENSE"), 'w')
295    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)")
296    f.close
297
298def main(options):
299    source_dir = options['sourcedir']
300    source_file = options['sourcefile']
301    source_symbols_dir = os.path.join(source_dir,"symbols")
302    dest_dir = options['destdir']
303
304    dest_dir_bw = os.path.join(dest_dir,"bw-mapnik")
305    dest_dir_bw_symbols = os.path.join(dest_dir_bw,"symbols")
306    dest_file_bw = 'osm-bw.xml'
307    bw_file = os.path.join(dest_dir_bw,dest_file_bw)
308    if not os.path.exists(dest_dir_bw_symbols):
309        os.makedirs(dest_dir_bw_symbols)
310
311    dest_dir_bw_noicons = os.path.join(dest_dir,"bw-noicons")
312    dest_dir_bw_noicons_symbols = os.path.join(dest_dir_bw_noicons,"symbols")
313    dest_file_bw_noicons = 'osm-bw-noicons.xml'
314    bw_noicons_file = os.path.join(dest_dir_bw_noicons,dest_file_bw_noicons)
315    if not os.path.exists(dest_dir_bw_noicons_symbols):
316        os.makedirs(dest_dir_bw_noicons_symbols)
317
318    convert_icons_to_bw(source_symbols_dir,dest_dir_bw_symbols)
319    convert_icons_to_bw(source_symbols_dir,dest_dir_bw_noicons_symbols)
320    transmogrify_file(os.path.join(source_dir,source_file),bw_file,bw_noicons_file)
321    strip_doctype(bw_file)
322    strip_doctype(bw_noicons_file)
323    add_license_files(dest_dir_bw)
324    add_license_files(dest_dir_bw_noicons)
325
326if __name__ == '__main__':
327    parser = OptionParser()
328    parser.add_option("-s", "--sourcedir", dest="sourcedir", help="path to the source directory", default=".")
329    parser.add_option("-f", "--sourcefile", dest="sourcefile", help="source filename, default is 'osm.xml')", default="osm.xml")
330    parser.add_option("-d", "--destdir", dest="destdir", help="path to the destination directory, further dirs are created within. default is '/tmp'", default="/tmp")
331    (options, args) = parser.parse_args()
332    print options
333    main(options.__dict__)
334    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.