-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkml2htm.py
More file actions
executable file
·115 lines (88 loc) · 2.82 KB
/
Copy pathkml2htm.py
File metadata and controls
executable file
·115 lines (88 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env ./local/bin/python
# Standard:
import argparse
from argparse import RawTextHelpFormatter
from pathlib import Path
import html
# Third party:
# Own:
import config
def get_user_args():
parser = argparse.ArgumentParser(
description = (
"Creates a local tiles mesh viewer HTML file using OpenStreetMap\n\n"
"Author: https://github.com/andre-st/"
),
epilog = (
"Examples:\n"
" ./kml2htm.py\n"
" ./kml2htm.py routes.kml\n"
" ./kml2htm.py --htm-file=routes.html routes.kml\n"
"\n"
"License:\n"
" MIT License"
),
formatter_class = RawTextHelpFormatter
)
parser.add_argument( "kml_file", help=f"input KML file path with tiles, default: {config.DEFAULT_KML_FILE}", default=config.DEFAULT_KML_FILE, nargs="?" )
parser.add_argument( "-o", "--htm-file", help=f"output HTML file, default: {config.DEFAULT_HTM_FILE}", default=config.DEFAULT_HTM_FILE )
args = parser.parse_args()
return args
def main():
args = get_user_args()
kml_path = Path( args.kml_file )
if not kml_path.exists():
raise FileNotFoundError( f"{args.kml_file} not found" )
kml_content = kml_path.read_text( encoding="utf-8" )
# Escape safely for embedding in JS template string
kml_escaped = kml_content.replace( "`", "\\`" )
# HTML template to _embed_ KML code because browser
# forbid loading from local resource
#
html_content = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>OSM + Embedded KML</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
<style>
html, body {{
height: 100%;
margin: 0;
}}
#map {{
width: 100%;
height: 100%;
}}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-omnivore@0.3.4/leaflet-omnivore.min.js"></script>
<script>
const map = L.map('map').setView( [52.52, 13.405], 12 );
L.tileLayer( 'https://{{s}}.tile.openstreetmap.org/{{z}}/{{x}}/{{y}}.png', {{
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}}).addTo( map );
const kmlData = `{kml_escaped}`;
// Omnivore KML does not implement <Style>
const customStyler = L.geoJSON( null, {{
style: (feature) => {{
return {{ color: feature.properties.color, fillColor: feature.properties.color, fillOpacity: {config.TILE_OPACITY} }}
}}
}});
const kmlLayer = omnivore.kml.parse( kmlData, null, customStyler );
const bounds = kmlLayer.getBounds();
map.fitBounds( bounds );
kmlLayer.addTo( map );
</script>
</body>
</html>
"""
Path( args.htm_file ).write_text( html_content, encoding="utf-8" )
print( f"Generated {args.htm_file}" )
if __name__ == "__main__":
main()