source: subversion/applications/rendering/parking/mapnik/mapnik_to_bw.py @ 27538

Revision 27538, 11.2 KB checked in by kdrangmeister, 2 years ago (diff)

Changed font halo-fill for mapnik 2.0

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
8#import 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    """
164    #method 2:
165    h,l,s = colorsys.rgb_to_hls(r, g, b)
166    s *= 0   # desaturate
167    return colorsys.hls_to_rgb(h,l,s)
168    """
169
170def parse_color(s):
171    """ Parses color string in format #ABC or #AABBCC to RGB tuple. """
172    s = s.lower()
173    if simple_colors.has_key(s):  # translate color names to rgb
174        s = '#'+simple_colors.get(s)
175    l = len(s)
176    assert(l in (4,7))
177#    print "s=",s
178    if l==4:
179        return tuple(int(ch * 2, 16)/255.0 for ch in s[1:])
180    else:
181        return tuple(int(ch1 + ch2, 16)/255.0 for ch1, ch2 in \
182                     zip(
183                        (ch1 for ch1 in s[1::2]),
184                        (ch2 for ch2 in s[2::2])
185                        )
186                    )
187
188def rgb_to_css(rgb):
189    r,g,b=rgb
190    return "#{r:02x}{g:02x}{b:02x}".format(r=int(r*255.0),g=int(g*255.0),b=int(b*255.0))
191
192def dom_convert_to_grey(document):
193    els = document.getElementsByTagName("CssParameter")
194    #print "els=",els
195    for el in els:
196        at = el.getAttribute("name")
197        if at=="stroke" or at=="fill":
198            col=el.firstChild.nodeValue
199            bw=rgb_to_css(color_to_bw(parse_color(col)))
200            #print "converted {typ} from {a} to {bw}." .format(typ=at,a=col,bw=bw)
201            el.firstChild.nodeValue=bw
202
203    #<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">
204    els = document.getElementsByTagName("Map")
205    for el in els:
206        col = el.getAttribute("background-color")
207        assert(col!='')
208        assert(col!=None)
209        bw=rgb_to_css(color_to_bw(parse_color(col)))
210        #print "converted {typ} from {a} to {bw}." .format(typ='bgcolor',a=col,bw=bw)
211        el.setAttribute("background-color",bw)
212
213    #<TextSymbolizer ... fill="#6699cc"/>
214    els = document.getElementsByTagName("TextSymbolizer")
215    for el in els:
216        col = el.getAttribute("fill")
217        assert(col!='')
218        assert(col!=None)
219        bw=rgb_to_css(color_to_bw(parse_color(col)))
220        #print "converted {typ} from {a} to {bw}." .format(typ='TS-fill',a=col,bw=bw)
221        el.setAttribute("fill",bw)
222        #<TextSymbolizer halo-fill="#fed7a5"/> (optional)
223        col = el.getAttribute("halo-fill")
224        assert(col!=None)
225        if col!='':
226            bw=rgb_to_css(color_to_bw(parse_color(col)))
227            #print "converted {typ} from {a} to {bw}." .format(typ='TS-halo-fill',a=col,bw=bw)
228            el.setAttribute("halo-fill",bw)
229
230
231def dom_strip_style_and_layer(document,stylename,layername):
232    removeElements=[]
233    # remove <Style name="points"> and <Layer name="amenity-points">
234    els = document.getElementsByTagName("Style")
235    for el in els:
236        if el.getAttribute("name")==stylename:
237            removeElements.append(el)
238    els = document.getElementsByTagName("Layer")
239    for el in els:
240        if el.getAttribute("name")==layername:
241            removeElements.append(el)
242    print removeElements
243    for el in removeElements:
244        parent = el.parentNode
245        parent.removeChild(el)
246
247def dom_strip_icons(document):
248    dom_strip_style_and_layer(document,"points","amenity-points")
249    dom_strip_style_and_layer(document,"power_line","power_line")
250    dom_strip_style_and_layer(document,"power_minorline","power_minorline")
251    dom_strip_style_and_layer(document,"power_towers","power_towers")
252    dom_strip_style_and_layer(document,"power_poles","power_poles")
253
254def transmogrify_file(sf,dfgrey,dfnoicons):
255    dom= pxdom.getDOMImplementation('') 
256    parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
257    parser.domConfig.setParameter('entities', 0) # 1 -> exception if attribute values is set
258    #parser.domConfig.setParameter('disallow-doctype', 1)
259    parser.domConfig.setParameter('pxdom-resolve-resources', 1) # 1 -> replace &xyz; with text
260    document = parser.parseURI(sf)
261
262    dom_convert_to_grey(document)
263   
264    output= document.implementation.createLSOutput() 
265    output.systemId= dfgrey
266    output.encoding= 'utf-8' 
267    serialiser= document.implementation.createLSSerializer() 
268    serialiser.write(document, output)
269
270    dom_strip_icons(document)
271   
272    output= document.implementation.createLSOutput() 
273    output.systemId= dfnoicons
274    output.encoding= 'utf-8' 
275    serialiser= document.implementation.createLSSerializer() 
276    serialiser.write(document, output)
277
278def strip_doctype(f):
279    p = subprocess.Popen(['sed','-i','2,5 d',f]) # -i means 'in place'
280    p.wait()
281
282def convert_icons_to_bw(source_symbols_dir,dest_symbols_dir):
283    image_files = os.listdir(source_symbols_dir)
284    image_files = [f for f in image_files if f.endswith('png')]
285    for f in image_files:
286        # convert ./original-mapnik/symbols/*.png -fx '0.25*r + 0.62*g + 0.13*b' ./bw-mapnik/symbols/*.png
287        sf = os.path.join(source_symbols_dir,f)
288        df = os.path.join(dest_symbols_dir,f)
289        p = subprocess.Popen(['convert',sf,'-fx','0.25*r + 0.62*g + 0.13*b',df])
290        p.wait()
291
292def add_license_files(dirname):
293    f = open(os.path.join(dirname,"CONTACT"), 'w')
294    f.write("This style is created by kayd@toolserver.org")
295    f.close
296    f = open(os.path.join(dirname,"LICENSE"), 'w')
297    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)")
298    f.close
299
300def main(options):
301    source_dir = options['sourcedir']
302    source_file = options['sourcefile']
303    source_symbols_dir = os.path.join(source_dir,"symbols")
304    dest_dir = options['destdir']
305
306    dest_dir_bw = os.path.join(dest_dir,"bw-mapnik")
307    dest_dir_bw_symbols = os.path.join(dest_dir_bw,"symbols")
308    dest_file_bw = 'osm-bw.xml'
309    bw_file = os.path.join(dest_dir_bw,dest_file_bw)
310    if not os.path.exists(dest_dir_bw_symbols):
311        os.makedirs(dest_dir_bw_symbols)
312
313    dest_dir_bw_noicons = os.path.join(dest_dir,"bw-noicons")
314    dest_dir_bw_noicons_symbols = os.path.join(dest_dir_bw_noicons,"symbols")
315    dest_file_bw_noicons = 'osm-bw-noicons.xml'
316    bw_noicons_file = os.path.join(dest_dir_bw_noicons,dest_file_bw_noicons)
317    if not os.path.exists(dest_dir_bw_noicons_symbols):
318        os.makedirs(dest_dir_bw_noicons_symbols)
319
320    convert_icons_to_bw(source_symbols_dir,dest_dir_bw_symbols)
321    convert_icons_to_bw(source_symbols_dir,dest_dir_bw_noicons_symbols)
322    transmogrify_file(os.path.join(source_dir,source_file),bw_file,bw_noicons_file)
323    strip_doctype(bw_file)
324    strip_doctype(bw_noicons_file)
325    add_license_files(dest_dir_bw)
326    add_license_files(dest_dir_bw_noicons)
327
328if __name__ == '__main__':
329    parser = OptionParser()
330    parser.add_option("-s", "--sourcedir", dest="sourcedir", help="path to the source directory", default=".")
331    parser.add_option("-f", "--sourcefile", dest="sourcefile", help="source filename, default is 'osm.xml')", default="osm.xml")
332    parser.add_option("-d", "--destdir", dest="destdir", help="path to the destination directory, further dirs are created within. default is '/tmp'", default="/tmp")
333    (options, args) = parser.parse_args()
334    print options
335    main(options.__dict__)
336    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.