GPS(csv) to KML python - cchamchi/cansat GitHub Wiki
์บ์์ฑ์์ ๊ธฐ๋กํ GPS ๋ฐ์ดํฐ๋ฅผ ๊ตฌ๊ธ์ด์ค์ KMLํ์ผ๋ก ๋ณํํ๋ python ์ ์์๋ณด์
์์ ์ฝ๋๋ ์ฌ๊ธฐ์์ ๋ฐ์ทํ์๋ค.
์บ์์ฑ์์ ๊ธฐ๋กํ csv๋ก๊ทธ ํ์ผ์ ์๋์ ๊ฐ๋ค.
date,time,time_index,mode,longitude,latitude,altitude,numsat,speed,cource,bearing,distance,controlangle
90718,105851,563,1,127.10637,37.301155,81.8,12,0,166.32,251.2,3881.29,84.88
90718,105852,564,1,127.10637,37.301155,81.9,12,0,166.32,251.2,3881.29,84.88
90718,105853,565,1,127.10637,37.301155,81.9,12,0,166.32,251.2,3881.29,84.88
90718,105854,566,1,127.10637,37.301155,81.9,12,0,166.32,251.2,3881.29,84.88
90718,105855,567,1,127.10638,37.301155,82,12,0.01,166.32,251.2,3882.63,84.88
90718,105856,568,1,127.10638,37.301155,82.2,12,0.01,166.32,251.2,3882.63,84.88
90718,105857,569,1,127.10638,37.301151,82.3,12,0.02,166.32,251.21,3882.5,84.89
90718,105858,570,1,127.10638,37.301151,82.4,12,0.01,166.32,251.21,3882.5,84.89
๊ตฌ๊ธ ์ด์ค์ KML ํํ๋ ์ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ๊ธฐ ๋ฐ๋๋ค
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
๋ด์ฉ....
๋ด์ฉ....
</Document>
</kml>
ํ์ด์ ๋ผ์ด๋ธ๋ฌ์ค์ xml.dom.minidom ์ import ํ๋ค. DOM ํ์์ ๋ํ ์์ธํ ์ค๋ช ์ ์ฌ๊ธฐ์ฐธ๊ณ ํ๊ธฐ ๋ฐ๋๋ค.
import xml.dom.minidom
์ฐ์ xml ์ ์ฒด ๋คํ๋จผํธ๋ฅผ ํ๋ ๋ง๋ค๊ณ ๊ทธ์์ ํ๋์ฉ ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
kmlDoc = xml.dom.minidom.Document()
์ด์ kmlDoc ์ด๋ผ๋ ํฐ ๋ฐ๊ทธ๋ฆผ์ด ์๊ฒผ๋ค.
kmlElement = kmlDoc.createElementNS('http://www.opengis.net/kml/2.2', 'kml')
kmlElement.setAttribute('xmlns','http://www.opengis.net/kml/2.2')
kmlElement = kmlDoc.appendChild(kmlElement)
๋งจ์ฒ์ ์๋ kml ์์๋ฅผ ๋ง๋ค๊ณ kmlDoc์ append ์ํจ๋ค. ๋ค์์ Document ์์ ์ด๋ค.
documentElement = kmlDoc.createElement('Document')
documentElement = kmlElement.appendChild(documentElement)
๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก documentElement์ ์์ฑํ๊ณ ์ด๋ฒ์๋ kmlElement์ append์ํจ๋ค.
์ ์ฌ๊ธฐ ๊น์ง ์ดํด๊ฐ ๊ฐ๋๊ฐ?
์ด์ ๋ csv๋ฅผ ์ฝ๊ณ row ๋ง๋ค placemark๋ฅผ appendํด์ฃผ๋ฉด ๋๋ค.
placemark ์ ์์ ์ฝ๊ฐ์ ๊พธ๋ฏธ๊ธฐ ๊ณผ์ ์ ํด๋ณด์
<name>Cansat Flight path</name>
kml์ ์ด๋ฆ์ด ๋์ค๊ฒ ํ๋ค.
nameElement = kmlDoc.createElement('name')
nameElement.appendChild(kmlDoc.createTextNode('Cansat Flight path'))
documentElement.appendChild(nameElement)
์ฐธ ์ฝ์ฃ ์..
์ด ๋ฌธ๊ตฌ๋ฅผ ์ฐ์ง ์์ผ๋ฉด ์์ฒญ ํฐ ๋ ธ๋ ์์ ํ์ด ์ง๋์ ๊ทธ๋ ค์ง๋ค. ์์ด์ฝ์ ๋ฐ๊พธ๊ณ ์ถ์ผ๋ฉด ์๋ png ํ์ผ์ ์ด๋ฆ์ ๋ฐ๊พธ๋ฉด ๋๋ค.
์.. ๊ฐ์ฒด๊ฐ ์ข ๋ง์ฟค... ๊ทธ๋๋ ์ฐฌ์ฐฌํ ํ๋์ฉ ํด๋ณด์
<Style id="hiker-icon">
<IconStyle>
<Icon>
<href>http://maps.google.com/mapfiles/kml/pal4/icon49.png</href>
</Icon>
<hotSpot x="0" y=".5" xunits="fraction" yunits="fraction"/>
</IconStyle>
</Style>
์ฌ์ง ์ฌ์ด ์๋ํฐ๊ฐ ์์๊บผ ๊ฐ๋ค..
styleIdElement = kmlDoc.createElement('Style')
styleIdElement.setAttribute('id','hiker-icon')
documentElement.appendChild(styleIdElement)
iconStyleElement = kmlDoc.createElement('IconStyle')
styleIdElement.appendChild(iconStyleElement)
iconElement = kmlDoc.createElement('Icon')
iconStyleElement.appendChild(iconElement)
hrefElement = kmlDoc.createElement('href')
hrefElement.appendChild(kmlDoc.createTextNode('http://maps.google.com/mapfiles/kml/pal4/icon49.png'))
iconElement.appendChild(hrefElement)
hotSpotElement = kmlDoc.createElement('hotSpot')
hotSpotElement.setAttribute('x','0')
hotSpotElement.setAttribute('y','.5')
hotSpotElement.setAttribute('xunits','fraction')
hotSpotElement.setAttribute('yunits','fraction')
iconStyleElement.appendChild(hotSpotElement)
์ฌ๊ธฐ๊ฐ ๋ฉ์ธ ๋ฃจํ๋ผ ํ๊ฒ ๋ค. ์๋์ ํํ๋ก ๋ง๋ค์ด ๋ณด๋ค
<Placemark>
<styleUrl>#hiker-icon</styleUrl>
<Point>
<coordinates>127.10637,37.301155,81.8</coordinates>
</Point>
</Placemark>
placemark์์, styleUrl ์์, Point์์๋ฅผ ๋ง๋ค๊ณ csv์์ ์๋,๊ฒฝ๋,๊ณ ๋๋ฅผ ์ฝ์ด ๋ณด์
def extractCoord(row):
# This extracts an address from a row and returns it as a string. This requires knowing
# ahead of time what the columns are that hold the address information.
return '%s,%s,%s' % (row['longitude'], row['latitude'], row['altitude'])
def createPlacemark(kmlDoc, row, order):
# This creates a element for a row of data.
# A row is a dict.
placemarkElement = kmlDoc.createElement('Placemark')
#timeStampElement = kmlDoc.createElement('TimeStamp')
#placemarkElement.appendChild(timeStampElement)
styleUrlElement = kmlDoc.createElement('styleUrl')
styleUrlElement.appendChild(kmlDoc.createTextNode('#hiker-icon'))
placemarkElement.appendChild(styleUrlElement)
pointElement = kmlDoc.createElement('Point')
placemarkElement.appendChild(pointElement)
coordinates = extractCoord(row)
coorElement = kmlDoc.createElement('coordinates')
coorElement.appendChild(kmlDoc.createTextNode(coordinates))
pointElement.appendChild(coorElement)
return placemarkElement
์ต์ข ํ์ผ์ ์ฌ๊ธฐ์ ์ฌ๋ฆฐ๋ค. csv ํ์ผ python ํ์ผ
์์ ์์ ๋ ์ด๋ ๊ฒฝ๋ก๋ฅผ ํ์ ํ๋ ๋ฐฉ๋ฒ์ด ์ด๋ค. ์บ์์ฑ์ด ๋นํํ๋ 3์ฐจ์ ๊ฒฝ๋ก๋ฅผ ๋ณด๋ ค๋ฉด ์๋ก์ด kml์ ๋ง๋ค์ด ๋ณด์
document ์์ ์์ ์๋ ์์๋ฅผ ์ถ๊ฐ ํ์. ๋ ธ๋์ ๊ธฐ๋ฅ๊ณผ ๋ น์ ๊ธฐ๋ฅ์ผ๋ก ํ์๋๋ค.
<Style id="yellowLineGreenPoly">
<LineStyle>
<color>7f00ffff</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7f00ff00</color>
</PolyStyle>
</Style>
<Placemark>
<name>Absolute Extruded</name>
<description>Transparent green wall with yellow outlines</description>
<styleUrl>#yellowLineGreenPoly</styleUrl>
<LineString>
<extrude>1</extrude>
<tessellate>1</tessellate>
<altitudeMode>absolute</altitudeMode>
<coordinates> 127.0653457,37.2894706,162.2
127.0653686,37.2894783,150.5
127.0653991,37.2894821,140.4
127.0654373,37.289505,131.2
127.0654754,37.2895202,123.7
127.0654983,37.2895202,118
127.0655364,37.289505,113.3
127.0655593,37.289463,111.2
127.0655899,37.2894172,110.1
127.065628,37.2893867,108.3
127.0656661,37.2893524,107
127.0657043,37.2893257,105.7
127.0657577,37.2893066,104
127.0657958,37.289299,102.7
127.0658187,37.2893142,101
127.0657958,37.2893142,99.1
127.0659561,37.289257,72.3 </coordinates>
</LineString>
</Placemark>
ํ์ด์ ์ฝ๋๋ ์๋์ ๊ฐ๋ค ์ ์ฒด ์ฝ๋๋ ์ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ์
def createKML(csvReader, fileName, order):
# This constructs the KML document from the CSV file.
kmlDoc = xml.dom.minidom.Document()
kmlElement = kmlDoc.createElementNS('http://www.opengis.net/kml/2.2', 'kml')
kmlElement.setAttribute('xmlns','http://www.opengis.net/kml/2.2')
kmlElement = kmlDoc.appendChild(kmlElement)
documentElement = kmlDoc.createElement('Document')
documentElement = kmlElement.appendChild(documentElement)
nameElement = kmlDoc.createElement('name')
nameElement.appendChild(kmlDoc.createTextNode('Cansat Flight 3D path'))
documentElement.appendChild(nameElement)
styleIdElement = kmlDoc.createElement('Style')
styleIdElement.setAttribute('id',"yellowLineGreenPoly")
documentElement.appendChild(styleIdElement)
lineStyleElement = kmlDoc.createElement('LineStyle')
styleIdElement.appendChild(lineStyleElement)
colorElement = kmlDoc.createElement('color')
colorElement.appendChild(kmlDoc.createTextNode('7f00ffff'))
lineStyleElement.appendChild(colorElement)
widthElement = kmlDoc.createElement('width')
widthElement.appendChild(kmlDoc.createTextNode('4'))
lineStyleElement.appendChild(widthElement)
polyStyleElement = kmlDoc.createElement('PolyStyle')
styleIdElement.appendChild(polyStyleElement)
colorElement = kmlDoc.createElement('color')
colorElement.appendChild(kmlDoc.createTextNode('7f00ff00'))
polyStyleElement.appendChild(colorElement)
placemarkElement = kmlDoc.createElement('Placemark')
documentElement.appendChild(placemarkElement)
styleUrlElement = kmlDoc.createElement('styleUrl')
styleUrlElement.appendChild(kmlDoc.createTextNode('#yellowLineGreenPoly'))
placemarkElement.appendChild(styleUrlElement)
lineStringElement = kmlDoc.createElement('LineString')
placemarkElement.appendChild(lineStringElement)
extrudeElement = kmlDoc.createElement('extrude')
extrudeElement.appendChild(kmlDoc.createTextNode('1'))
lineStringElement.appendChild(extrudeElement)
tessellateElement = kmlDoc.createElement('tessellate')
tessellateElement.appendChild(kmlDoc.createTextNode('1'))
lineStringElement.appendChild(tessellateElement)
altitudeModeElement = kmlDoc.createElement('altitudeMode')
altitudeModeElement.appendChild(kmlDoc.createTextNode('absolute'))
lineStringElement.appendChild(altitudeModeElement)
# Skip the header line.
csvReader.next()
coordinatesElement = kmlDoc.createElement('coordinates')
for row in csvReader:
coordinatesElement.appendChild(kmlDoc.createTextNode(extractCoord(row)))
lineStringElement.appendChild(coordinatesElement)
kmlFile = open(fileName, 'w')
kmlFile.write(kmlDoc.toprettyxml(' ', newl = '\n', encoding = 'utf-8'))
์๋ ๋ก๊ทธ๋ฅผ ์ด์ฉํ์ฌ ๊ตฌ๊ธ ์ด์ค์์ ์ง์ ๊ทธ๋ ค ๋ณด์
๊ตฌ๊ธ ์ด์ค์์ ๋๊ฐ์ kml ํ์ผ์ ํจ๊ป ๊ทธ๋ฆฌ๋ฉด ์๋ ์ฒ๋ผ 3์ฐจ์ ๋นํ ๊ฒฝ๋ก๋ฅผ ๋ถ์ํ ์ ์๋ค.

๊ตฌ๊ธ ์ด์ค์ ๋๋ผ์ด ๊ธฐ๋ฅ์ด ๋ ์๋ค. ์๋, ๊ฒฝ๋, ๊ณ ๋, ๋ฐฉํฅ๊ฐ์ ๋ฃ์ด ์ฃผ๋ฉด ์บ์์ฑ์ด ๋ํํ๋ฉด์ ๋ณด๋ view๋ฅผ ๊ทธ๋๋ก ์๋ฎฌ๋ ์ด์ ๊ฐ๋ฅํ๋ค.