<s> import xml . dom . minidom as md <EOL> import re <EOL> import pathlib <EOL> import json <EOL> import click <EOL> GEOTYPES = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> STYLE_TYPES = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> SPACE = re . compile ( r'<STR_LIT>' ) <EOL> def get ( node , name ) : <EOL> """<STR_LIT>""" <EOL> return node . getElementsByTagName ( name ) <EOL> def get1 ( node , name ) : <EOL> """<STR_LIT>""" <EOL> s = get ( node , name ) <EOL> if s : <EOL> return s [ <NUM_LIT:0> ] <EOL> else : <EOL> return None <EOL> def attr ( node , name ) : <EOL> """<STR_LIT>""" <EOL> return node . getAttribute ( name ) <EOL> def val ( node ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> node . normalize ( ) <EOL> return node . firstChild . wholeText <EOL> except AttributeError : <EOL> return '<STR_LIT>' <EOL> def valf ( node ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return float ( val ( node ) ) <EOL> except ValueError : <EOL> return None <EOL> def numarray ( a ) : <EOL> """<STR_LIT>""" <EOL> return [ float ( aa ) for aa in a ] <EOL> def coords1 ( s ) : <EOL> """<STR_LIT>""" <EOL> return numarray ( re . sub ( SPACE , '<STR_LIT>' , s ) . split ( '<STR_LIT:U+002C>' ) ) <EOL> def coords ( s ) : <EOL> """<STR_LIT>""" <EOL> s = s . split ( ) <EOL> return [ coords1 ( ss ) for ss in s ] <EOL> def gx_coords1 ( s ) : <EOL> """<STR_LIT>""" <EOL> return numarray ( s . split ( '<STR_LIT:U+0020>' ) ) <EOL> def gx_coords ( node ) : <EOL> """<STR_LIT>""" <EOL> els = get ( node , '<STR_LIT>' ) <EOL> coordinates = [ ] <EOL> times = [ ] <EOL> coordinates = [ gx_coords1 ( val ( el ) ) for el in els ] <EOL> time_els = get ( node , '<STR_LIT>' ) <EOL> times = [ val ( t ) for t in time_els ] <EOL> return { <EOL> '<STR_LIT>' : coordinates , <EOL> '<STR_LIT>' : times , <EOL> } <EOL> def disambiguate ( names , mark = '<STR_LIT:1>' ) : <EOL> """<STR_LIT>""" <EOL> names_seen = set ( ) <EOL> new_names = [ ] <EOL> for name in names : <EOL> new_name = name <EOL> while new_name in names_seen : <EOL> new_name += mark <EOL> new_names . append ( new_name ) <EOL> names_seen . add ( new_name ) <EOL> return new_names <EOL> def to_filename ( s ) : <EOL> """<STR_LIT>""" <EOL> s = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , s ) <EOL> s = s . strip ( ) . replace ( '<STR_LIT:U+0020>' , '<STR_LIT:_>' ) <EOL> return s <EOL> def build_rgb_and_opacity ( s ) : <EOL> """<STR_LIT>""" <EOL> color = '<STR_LIT>' <EOL> opacity = <NUM_LIT:1> <EOL> if s . startswith ( '<STR_LIT:#>' ) : <EOL> s = s [ <NUM_LIT:1> : ] <EOL> if len ( s ) == <NUM_LIT:8> : <EOL> color = s [ <NUM_LIT:6> : <NUM_LIT:8> ] + s [ <NUM_LIT:4> : <NUM_LIT:6> ] + s [ <NUM_LIT:2> : <NUM_LIT:4> ] <EOL> opacity = round ( int ( s [ <NUM_LIT:0> : <NUM_LIT:2> ] , <NUM_LIT:16> ) / <NUM_LIT> , <NUM_LIT:2> ) <EOL> elif len ( s ) == <NUM_LIT:6> : <EOL> color = s [ <NUM_LIT:4> : <NUM_LIT:6> ] + s [ <NUM_LIT:2> : <NUM_LIT:4> ] + s [ <NUM_LIT:0> : <NUM_LIT:2> ] <EOL> elif len ( s ) == <NUM_LIT:3> : <EOL> color = s [ : : - <NUM_LIT:1> ] <EOL> return '<STR_LIT:#>' + color , opacity <EOL> def build_svg_style ( node ) : <EOL> """<STR_LIT>""" <EOL> d = { } <EOL> for item in get ( node , '<STR_LIT>' ) : <EOL> style_id = '<STR_LIT:#>' + attr ( item , '<STR_LIT:id>' ) <EOL> props = { } <EOL> for x in get ( item , '<STR_LIT>' ) : <EOL> color = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> if color : <EOL> rgb , opacity = build_rgb_and_opacity ( color ) <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> props [ '<STR_LIT>' ] = <NUM_LIT:1> <EOL> fill = valf ( get1 ( x , '<STR_LIT>' ) ) <EOL> if fill == <NUM_LIT:0> : <EOL> props [ '<STR_LIT>' ] = fill <EOL> elif fill == <NUM_LIT:1> and '<STR_LIT>' not in props : <EOL> props [ '<STR_LIT>' ] = fill <EOL> outline = valf ( get1 ( x , '<STR_LIT>' ) ) <EOL> if outline == <NUM_LIT:0> : <EOL> props [ '<STR_LIT>' ] = outline <EOL> elif outline == <NUM_LIT:1> and '<STR_LIT>' not in props : <EOL> props [ '<STR_LIT>' ] = outline <EOL> for x in get ( item , '<STR_LIT>' ) : <EOL> color = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> if color : <EOL> rgb , opacity = build_rgb_and_opacity ( color ) <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> width = valf ( get1 ( x , '<STR_LIT:width>' ) ) <EOL> if width is not None : <EOL> props [ '<STR_LIT>' ] = width <EOL> for x in get ( item , '<STR_LIT>' ) : <EOL> icon = get1 ( x , '<STR_LIT>' ) <EOL> if not icon : <EOL> continue <EOL> props = { } <EOL> props [ '<STR_LIT>' ] = val ( get1 ( icon , '<STR_LIT>' ) ) <EOL> d [ style_id ] = props <EOL> return d <EOL> def build_leaflet_style ( node ) : <EOL> """<STR_LIT>""" <EOL> d = { } <EOL> for item in get ( node , '<STR_LIT>' ) : <EOL> style_id = '<STR_LIT:#>' + attr ( item , '<STR_LIT:id>' ) <EOL> props = { } <EOL> for x in get ( item , '<STR_LIT>' ) : <EOL> color = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> if color : <EOL> rgb , opacity = build_rgb_and_opacity ( color ) <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> props [ '<STR_LIT>' ] = <NUM_LIT:1> <EOL> fill = valf ( get1 ( x , '<STR_LIT>' ) ) <EOL> if fill == <NUM_LIT:0> : <EOL> props [ '<STR_LIT>' ] = fill <EOL> elif fill == <NUM_LIT:1> and '<STR_LIT>' not in props : <EOL> props [ '<STR_LIT>' ] = fill <EOL> outline = valf ( get1 ( x , '<STR_LIT>' ) ) <EOL> if outline == <NUM_LIT:0> : <EOL> props [ '<STR_LIT>' ] = outline <EOL> elif outline == <NUM_LIT:1> and '<STR_LIT>' not in props : <EOL> props [ '<STR_LIT>' ] = outline <EOL> for x in get ( item , '<STR_LIT>' ) : <EOL> color = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> if color : <EOL> rgb , opacity = build_rgb_and_opacity ( color ) <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> width = valf ( get1 ( x , '<STR_LIT:width>' ) ) <EOL> if width is not None : <EOL> props [ '<STR_LIT>' ] = width <EOL> for x in get ( item , '<STR_LIT>' ) : <EOL> icon = get1 ( x , '<STR_LIT>' ) <EOL> if not icon : <EOL> continue <EOL> props = { } <EOL> props [ '<STR_LIT>' ] = val ( get1 ( icon , '<STR_LIT>' ) ) <EOL> d [ style_id ] = props <EOL> return d <EOL> def build_geometry ( node ) : <EOL> """<STR_LIT>""" <EOL> geoms = [ ] <EOL> times = [ ] <EOL> if get1 ( node , '<STR_LIT>' ) : <EOL> return build_geometry ( get1 ( node , '<STR_LIT>' ) ) <EOL> if get1 ( node , '<STR_LIT>' ) : <EOL> return build_geometry ( get1 ( node , '<STR_LIT>' ) ) <EOL> if get1 ( node , '<STR_LIT>' ) : <EOL> return build_geometry ( get1 ( node , '<STR_LIT>' ) ) <EOL> for geotype in GEOTYPES : <EOL> geonodes = get ( node , geotype ) <EOL> if not geonodes : <EOL> continue <EOL> for geonode in geonodes : <EOL> if geotype == '<STR_LIT>' : <EOL> geoms . append ( { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : coords1 ( val ( get1 ( <EOL> geonode , '<STR_LIT>' ) ) ) <EOL> } ) <EOL> elif geotype == '<STR_LIT>' : <EOL> geoms . append ( { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : coords ( val ( get1 ( <EOL> geonode , '<STR_LIT>' ) ) ) <EOL> } ) <EOL> elif geotype == '<STR_LIT>' : <EOL> rings = get ( geonode , '<STR_LIT>' ) <EOL> coordinates = [ coords ( val ( get1 ( ring , '<STR_LIT>' ) ) ) <EOL> for ring in rings ] <EOL> geoms . append ( { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : coordinates , <EOL> } ) <EOL> elif geotype in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> track = gx_coords ( geonode ) <EOL> geoms . append ( { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : track [ '<STR_LIT>' ] , <EOL> } ) <EOL> if track [ '<STR_LIT>' ] : <EOL> times . append ( track [ '<STR_LIT>' ] ) <EOL> return { '<STR_LIT>' : geoms , '<STR_LIT>' : times } <EOL> def build_feature ( node ) : <EOL> """<STR_LIT>""" <EOL> geoms_and_times = build_geometry ( node ) <EOL> if not geoms_and_times [ '<STR_LIT>' ] : <EOL> return None <EOL> props = { } <EOL> for x in get ( node , '<STR_LIT:name>' ) [ : <NUM_LIT:1> ] : <EOL> props [ '<STR_LIT:name>' ] = val ( x ) <EOL> for x in get ( node , '<STR_LIT:description>' ) [ : <NUM_LIT:1> ] : <EOL> description = val ( x ) <EOL> if description : <EOL> props [ '<STR_LIT:description>' ] = description <EOL> for x in get ( node , '<STR_LIT>' ) [ : <NUM_LIT:1> ] : <EOL> style_url = val ( x ) <EOL> if style_url [ <NUM_LIT:0> ] != '<STR_LIT:#>' : <EOL> style_url = '<STR_LIT:#>' + style_url <EOL> props [ '<STR_LIT>' ] = style_url <EOL> for x in get ( node , '<STR_LIT>' ) [ : <NUM_LIT:1> ] : <EOL> color = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> if color : <EOL> rgb , opacity = build_rgb_and_opacity ( color ) <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> props [ '<STR_LIT>' ] = <NUM_LIT:1> <EOL> fill = valf ( get1 ( x , '<STR_LIT>' ) ) <EOL> if fill == <NUM_LIT:0> : <EOL> props [ '<STR_LIT>' ] = fill <EOL> elif fill == <NUM_LIT:1> and '<STR_LIT>' not in props : <EOL> props [ '<STR_LIT>' ] = fill <EOL> outline = valf ( get1 ( x , '<STR_LIT>' ) ) <EOL> if outline == <NUM_LIT:0> : <EOL> props [ '<STR_LIT>' ] = outline <EOL> elif outline == <NUM_LIT:1> and '<STR_LIT>' not in props : <EOL> props [ '<STR_LIT>' ] = outline <EOL> for x in get ( node , '<STR_LIT>' ) [ : <NUM_LIT:1> ] : <EOL> color = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> if color : <EOL> rgb , opacity = build_rgb_and_opacity ( color ) <EOL> props [ '<STR_LIT>' ] = rgb <EOL> props [ '<STR_LIT>' ] = opacity <EOL> width = valf ( get1 ( x , '<STR_LIT:width>' ) ) <EOL> if width : <EOL> props [ '<STR_LIT>' ] = width <EOL> for x in get ( node , '<STR_LIT>' ) [ : <NUM_LIT:1> ] : <EOL> datas = get ( x , '<STR_LIT>' ) <EOL> for data in datas : <EOL> props [ attr ( data , '<STR_LIT:name>' ) ] = val ( get1 ( <EOL> data , '<STR_LIT:value>' ) ) <EOL> simple_datas = get ( x , '<STR_LIT>' ) <EOL> for simple_data in simple_datas : <EOL> props [ attr ( simple_data , '<STR_LIT:name>' ) ] = val ( simple_data ) <EOL> for x in get ( node , '<STR_LIT>' ) [ : <NUM_LIT:1> ] : <EOL> begin = val ( get1 ( x , '<STR_LIT>' ) ) <EOL> end = val ( get1 ( x , '<STR_LIT:end>' ) ) <EOL> props [ '<STR_LIT>' ] = { '<STR_LIT>' : begin , '<STR_LIT:end>' : end } <EOL> if geoms_and_times [ '<STR_LIT>' ] : <EOL> times = geoms_and_times [ '<STR_LIT>' ] <EOL> if len ( times ) == <NUM_LIT:1> : <EOL> props [ '<STR_LIT>' ] = times [ <NUM_LIT:0> ] <EOL> else : <EOL> props [ '<STR_LIT>' ] = times <EOL> feature = { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : props , <EOL> } <EOL> geoms = geoms_and_times [ '<STR_LIT>' ] <EOL> if len ( geoms ) == <NUM_LIT:1> : <EOL> feature [ '<STR_LIT>' ] = geoms [ <NUM_LIT:0> ] <EOL> else : <EOL> feature [ '<STR_LIT>' ] = { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : geoms , <EOL> } <EOL> if attr ( node , '<STR_LIT:id>' ) : <EOL> feature [ '<STR_LIT:id>' ] = attr ( node , '<STR_LIT:id>' ) <EOL> return feature <EOL> def build_feature_collection ( node , name = None ) : <EOL> """<STR_LIT>""" <EOL> geojson = { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : [ ] , <EOL> } <EOL> for placemark in get ( node , '<STR_LIT>' ) : <EOL> feature = build_feature ( placemark ) <EOL> if feature is not None : <EOL> geojson [ '<STR_LIT>' ] . append ( feature ) <EOL> if name is not None : <EOL> geojson [ '<STR_LIT>' ] = { '<STR_LIT:name>' : name } <EOL> return geojson <EOL> def build_layers ( node , disambiguate_names = True ) : <EOL> """<STR_LIT>""" <EOL> layers = [ ] <EOL> names = [ ] <EOL> for i , folder in enumerate ( get ( node , '<STR_LIT>' ) ) : <EOL> geojson = build_feature_collection ( folder ) <EOL> if not geojson [ '<STR_LIT>' ] : <EOL> continue <EOL> layers . append ( geojson ) <EOL> name = val ( get1 ( folder , '<STR_LIT:name>' ) ) <EOL> names . append ( name ) <EOL> if not layers : <EOL> geojson = build_feature_collection ( node ) <EOL> if geojson [ '<STR_LIT>' ] : <EOL> layers . append ( geojson ) <EOL> name = val ( get1 ( node , '<STR_LIT:name>' ) ) <EOL> names . append ( name ) <EOL> if disambiguate_names : <EOL> new_names = disambiguate ( names ) <EOL> new_layers = [ ] <EOL> for i , layer in enumerate ( layers ) : <EOL> layer [ '<STR_LIT>' ] = { '<STR_LIT:name>' : new_names [ i ] } <EOL> new_layers . append ( layer ) <EOL> layers = new_layers <EOL> return layers <EOL> @ click . command ( ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , is_flag = True , <EOL> default = False ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , type = click . Choice ( STYLE_TYPES ) , <EOL> default = None ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , <EOL> default = '<STR_LIT>' ) <EOL> @ click . argument ( '<STR_LIT>' ) <EOL> @ click . argument ( '<STR_LIT>' ) <EOL> def main ( kml_path , output_dir , separate_folders = False , <EOL> style_type = None , style_filename = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> kml_path = pathlib . Path ( kml_path ) . resolve ( ) <EOL> if output_dir is None : <EOL> output_dir = kml_path . parent <EOL> else : <EOL> output_dir = pathlib . Path ( output_dir ) <EOL> if not output_dir . exists ( ) : <EOL> output_dir . mkdir ( ) <EOL> output_dir = output_dir . resolve ( ) <EOL> with kml_path . open ( '<STR_LIT:r>' ) as src : <EOL> kml_str = src . read ( ) <EOL> root = md . parseString ( kml_str ) <EOL> if separate_folders : <EOL> layers = build_layers ( root ) <EOL> else : <EOL> name = kml_path . name . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> layers = [ build_feature_collection ( root , name = name ) ] <EOL> filenames = disambiguate ( <EOL> [ to_filename ( layer [ '<STR_LIT>' ] [ '<STR_LIT:name>' ] ) <EOL> for layer in layers ] ) <EOL> filenames = [ name + '<STR_LIT>' for name in filenames ] <EOL> for i in range ( len ( layers ) ) : <EOL> path = pathlib . Path ( output_dir , filenames [ i ] ) <EOL> with path . open ( '<STR_LIT:w>' ) as tgt : <EOL> json . dump ( layers [ i ] , tgt ) <EOL> if style_type in STYLE_TYPES : <EOL> builder_name = '<STR_LIT>' . format ( style_type ) <EOL> style_dict = globals ( ) [ builder_name ] ( root ) <EOL> path = pathlib . Path ( output_dir , style_filename ) <EOL> with path . open ( '<STR_LIT:w>' ) as tgt : <EOL> json . dump ( style_dict , tgt ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
