diff options
-rwxr-xr-x | gk2kml.py | 114 | ||||
-rw-r--r-- | template.kml | 60 |
2 files changed, 174 insertions, 0 deletions
diff --git a/gk2kml.py b/gk2kml.py new file mode 100755 index 0000000..37d3521 --- /dev/null +++ b/gk2kml.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# +# gk2kml +# +# converts Gauss-Krueger coordinates to WGS84 +# and also output a .kml so we can easily +# load it up in Google Earth without copy-pasting +# +# 2022-04-27 Oliver Meckmann + +import argparse +from textwrap import dedent +from sys import exit + +from pyproj import CRS # Coordinate Reference System +from pyproj import Transformer + +# https://spatialreference.org/ref/epsg/wgs-84/ +# https://en.wikipedia.org/wiki/World_Geodetic_System +# https://epsg.io/?q=Gauss-Kruger%20kind%3APROJCRS + +def run_argparser(): + argparser = argparse.ArgumentParser(\ + formatter_class=argparse.RawTextHelpFormatter, + description=dedent(''' + Convert Gauss-Kru(e)ger Coordinates to WGS84 + ''')) + argparser.add_argument( + '-z', + '--zone', + default='3', + help=dedent(''' + Input Gauss-Kruger Zone (Default: 3) + 2 = 3deg Zone 2: Germany + 3 = 3deg Zone 3: Germany onshore between 7°30'E and 10°30'E + 4 = 3deg Zone 4: Germany onshore between 10°30'E and 13°30'E + 5 = 3deg Zone 5: Germany onshore east of 13°30'E + '''), + nargs='?', + ) + argparser.add_argument( + '-w', + '--write', + help='Write to file [filename] (.kml gets attached)', + type=str, + nargs='?' + ) + argparser.add_argument( + 'coord', + metavar='coord', + type=str, + help=dedent(''' + [easting northing] ([Rechtswert Hochwert]) + '''), + nargs=2) + + args = argparser.parse_args() + return args + +def main(): + args = run_argparser() + + if len(args.coord[0]) < 6 or len(args.coord[1]) < 6: + print('Error: coordinates too short/inaccurate!') + exit() + + easting = args.coord[0] + northing = args.coord[1] + # sometimes we don't have THAT accurate coords, we then fill up with a 0 + if len(easting) == 6: + easting += '0' + if len(northing) == 6: + northing += '0' + + # set zone + if args.zone == '2': + src_crs = 'EPSG:5682' + elif args.zone == '3': + src_crs = 'EPSG:5683' + elif args.zone == '4': + src_crs = 'EPSG:5684' + elif args.zone == '5': + src_crs = 'EPSG:5685' + else: + print('Error: Wrong zone!') + exit() + + transformer = Transformer.from_crs(src_crs, 'EPSG:4326') + result = transformer.transform(easting, northing) + + if(str(result[0]) != 'inf'): + print(str(result[0]) + ', ' + str(result[1])) + + if args.write: + print('Writing to kml file: ' + args.write + '.kml') + template = open('template.kml', 'r', encoding='utf-8') + outf = open(args.write + '.kml', 'w', encoding='utf-8', errors='ignore') + line = template.readline() + + while line: + line = line.replace('$NAME', args.write) + line = line.replace('$LON', str(result[1])) + line = line.replace('$LAT', str(result[0])) + #print(line, end='') + outf.write(line) + line = template.readline() + + outf.close() + + else: + print('Error: no valid result! Check input coords!') + +if __name__ == '__main__': + main() diff --git a/template.kml b/template.kml new file mode 100644 index 0000000..9469872 --- /dev/null +++ b/template.kml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> +<Document> + <name>$NAME.kml</name> + <Style id="s_ylw-pushpin_hl"> + <IconStyle> + <scale>1.4</scale> + <Icon> + <href>http://maps.google.com/mapfiles/kml/shapes/open-diamond.png</href> + </Icon> + </IconStyle> + <LabelStyle> + <scale>0.3</scale> + </LabelStyle> + <ListStyle> + </ListStyle> + </Style> + <StyleMap id="m_ylw-pushpin"> + <Pair> + <key>normal</key> + <styleUrl>#s_ylw-pushpin</styleUrl> + </Pair> + <Pair> + <key>highlight</key> + <styleUrl>#s_ylw-pushpin_hl</styleUrl> + </Pair> + </StyleMap> + <Style id="s_ylw-pushpin"> + <IconStyle> + <scale>1.2</scale> + <Icon> + <href>http://maps.google.com/mapfiles/kml/shapes/open-diamond.png</href> + </Icon> + </IconStyle> + <LabelStyle> + <scale>0.3</scale> + </LabelStyle> + <ListStyle> + </ListStyle> + </Style> + <Placemark> + <name>$NAME</name> + <description>$NAME</description> + <LookAt> + <longitude>$LON</longitude> + <latitude>$LAT</latitude> + <altitude>0</altitude> + <heading>0</heading> + <tilt>0</tilt> + <range>999.9998585735252</range> + <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode> + </LookAt> + <styleUrl>#m_ylw-pushpin</styleUrl> + <Point> + <gx:drawOrder>1</gx:drawOrder> + <coordinates>$LON,$LAT</coordinates> + </Point> + </Placemark> +</Document> +</kml> |