KML 핵심가이드
구글맵에 트렉정보를 표시하고 싶다면, 어떤 방법이 있을까?
구글 API 에서는 kml 파일을 지원하고 이걸 읽어들여서 표시할 수 있도록 지원한다.
kml 파일을 어떻게 만드나
보통 GPS 기기나 휴대폰 앱을 통해 이동한 경로1)를 .gpx 라는 파일 포맷으로 저장한다. 궁극적으로 이 파일을 kml 파일로 바꿔야 한다.
먼저 여러개의 gpx 파일을 하나의 파일로 만든다. 이때 각각의 트렉데이터2)를 하나로 합쳐야 한다. 이때 필요한 스크립트 파일(b.sh)을 하나 만들고 아래 코드를 입력한다.
#!/bin/bash
output="merged.gpx"
files=(*.gpx)
if [ ! -e "${files[0]}" ]; then
echo "GPX 파일이 없습니다."
exit 1
fi
args=()
for file in "${files[@]}"; do
[ "$file" = "$output" ] && continue
args+=("-i" "gpx" "-f" "$file")
done
gpsbabel \
"${args[@]}" \
-x track,merge \
-o gpx \
-F "$output"
if [ $? -eq 0 ]; then
echo "완료: $output"
else
echo "GPX 병합 실패"
rm -f "$output"
exit 1
fi
b.sh 파일을 gpx 파일들이 있는 디렉토리로 옮긴다. 아래와 같이 실행하면, merged.gpx 파일이 생성된다.
#./b.sh
이제 구글드라이브에 접속해서 '신규 - 구글 내지도' 를 선택한다. 레이어를 추가하고 앞서 만든 파일을 올린다.
지도에 표시가 되고나면, 오른쪽 상단의 메뉴(점 3개)에서 KML/KMZ 내보내기를 선택하고, 'KMZ 대신 KML로 내보냅니다. 모든 아이콘을 지원하지는 않습니다' 체크 후 다운로드한다. 이제 확장자가 kml 인 파일(source.kml)을 얻었다.
필요에 맞게 수정하기
앞서 만든 kml 파일을 올리기에는 수정 사항이 필요하다.
- 시작 마커에는 '시작지점', 종료 마커에는 '도착지점' 이라는 문구로 수정
- 트랙정보를 클릭했을 때, 윈도우 창이 뜨고 썸네일 그림과 링크가 걸린 텍스트가 표시되도록 수정
이를 위해 스크립트 파일(con.sh)을 만들고 아래 내용을 입력한다.
#!/bin/bash
# 사용법:
# ./a.sh source.kml result.kml bulgaria:2017:38.jpg bulgaria:2017
#
# 예:
# ./a.sh source.kml result.kml bulgaria:2017:38.jpg bulgaria:2017
set -e
INPUT="${1:-source.kml}"
OUTPUT="${2:-bulgaria2.kml}"
IMAGE="${3}"
JOURNEY="${4}"
if [ ! -f "$INPUT" ]; then
echo "오류: 입력 파일을 찾을 수 없습니다: $INPUT"
exit 1
fi
if [ -z "$IMAGE" ]; then
echo "오류: 이미지 경로가 지정되지 않았습니다."
echo "사용법: ./a.sh source.kml result.kml bulgaria:2017:38.jpg bulgaria:2017"
exit 1
fi
if [ -z "$JOURNEY" ]; then
echo "오류: 여행 경로가 지정되지 않았습니다."
echo "사용법: ./a.sh source.kml result.kml bulgaria:2017:38.jpg bulgaria:2017"
exit 1
fi
python3 - "$INPUT" "$OUTPUT" "$IMAGE" "$JOURNEY" <<'PY'
import sys
import xml.etree.ElementTree as ET
input_file = sys.argv[1]
output_file = sys.argv[2]
image = sys.argv[3]
journey = sys.argv[4]
year = journey.split(":")[-1]
NS = "http://www.opengis.net/kml/2.2"
ET.register_namespace("", NS)
tree = ET.parse(input_file)
root = tree.getroot()
def tag(name):
return f"{{{NS}}}{name}"
document = root.find(tag("Document"))
if document is None:
raise SystemExit("오류: KML Document를 찾을 수 없습니다.")
folder = document.find(f".//{tag('Folder')}")
if folder is None:
raise SystemExit("오류: Folder를 찾을 수 없습니다.")
placemarks = folder.findall(tag("Placemark"))
if len(placemarks) < 3:
raise SystemExit("오류: Placemark가 3개 미만입니다.")
# --------------------------------------------------
# 1. Folder 이름 변경
# --------------------------------------------------
folder_name = folder.find(tag("name"))
if folder_name is not None:
folder_name.text = "all.gpx"
# --------------------------------------------------
# 2. 출발지점
# --------------------------------------------------
start = placemarks[0]
name = start.find(tag("name"))
if name is not None:
name.text = ""
description = start.find(tag("description"))
if description is not None:
description.text = (
'<h4 style="color : blue; font-family: RIDIBatang;">'
'출발지점'
'</h4>'
)
# --------------------------------------------------
# 3. 도착지점
# --------------------------------------------------
end = placemarks[1]
name = end.find(tag("name"))
if name is not None:
name.text = ""
description = end.find(tag("description"))
if description is not None:
description.text = (
'<h4 style="color : blue; font-family: RIDIBatang;">'
'도착지점'
'</h4>'
)
# --------------------------------------------------
# 4. 트랙
# --------------------------------------------------
track = placemarks[2]
name = track.find(tag("name"))
if name is not None:
name.text = "Cycling"
# 이미지 URL
image_url = (
"https://likewind.org/lib/exe/fetch.php?media=journey:"
+ image
)
# 여행 페이지 URL
journey_url = (
"https://likewind.org/doku.php?id=journey:"
+ journey
+ ":start"
)
description = track.find(tag("description"))
if description is not None:
description.text = (
'<img src="' + image_url + '" '
'height="200" width="auto" /><br><br>'
'<h4 style="color : blue; font-family: RIDIBatang; text-align: center;">'
'<a href="' + journey_url + '">'
'자전거여행(' + year + ')'
'</a></h4>'
)
# --------------------------------------------------
# 5. KML 저장
#
# 중요:
# 원본 KML의 좌표 데이터는 전혀 수정하지 않는다.
# --------------------------------------------------
tree.write(
output_file,
encoding="UTF-8",
xml_declaration=True
)
print(f"완료: {output_file}")
print(f"이미지: {image}")
print(f"여행: {journey}")
PY
앞서 만든 스크립트 실행하는 방법은 이렇다.
#./con.sh 원본kml파일명 결과파일명 썸네일사진명 링크주소
실행한다.
#./con.sh source.kml result.kml bulgaria:2017:38.jpg bulgaria:2017 완료: result.kml 이미지: bulgaria:2018:38.jpg 여행: bulgaria:2018
문제없이 실행되었다면, result.kml 이 보일 것이다.
확인하기
제대로 변환작업이 되었는지 확인해야 한다. result.kml 파일을 호스팅서버에 업로드하고, 각 국가 페이지에 표시된 kml 코드를 참고하여 체크한다.