การเข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่เพื่อใช้ใน KML

Mano Marks, ทีม Google Geo
เขียน: ธันวาคม 2007
อัปเดต: ธันวาคม 2013

วัตถุประสงค์

บทแนะนำนี้มีไว้สำหรับนักพัฒนาซอฟต์แวร์ที่คุ้นเคยกับ ภาษาการเขียนสคริปต์และต้องการเรียนรู้วิธีใช้ Google Geocoding API เพื่อแปลงที่อยู่เป็นพิกัดทางภูมิศาสตร์และรวมไว้ในไฟล์ KML แม้ว่าตัวอย่างโค้ด จะแสดงใน Python แต่ก็สามารถปรับให้เข้ากับภาษาโปรแกรมอื่นๆ ส่วนใหญ่ได้ค่อนข้างง่าย

การแปลงพิกัดภูมิศาสตร์คือกระบวนการแปลงที่อยู่เป็นชุดพิกัดละติจูด/ลองจิจูด ซึ่งทำให้ระบุที่อยู่บนแผนที่ได้ คุณอาจต้องการเข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่ และใส่ลงในไฟล์ KML โดยตรง ซึ่งเป็นเรื่องปกติ เช่น เมื่อป้อนข้อมูลลงใน แบบฟอร์มและคุณสร้างไฟล์ KML เพื่อตอบสนองต่อคำขอ ไฟล์ KML เหล่านี้อาจ จัดเก็บไว้ในฐานข้อมูล ในระบบไฟล์ หรือส่งคืนไปยัง NetworkLink ที่เชื่อมต่อกับไฟล์ของคุณ โปรดทราบว่าเมื่อใช้เทคนิคนี้ คุณต้องปฏิบัติตามข้อกำหนดในการให้บริการ สำหรับ Geocoding API เนื่องจากมีข้อจำกัดบางอย่างเกี่ยวกับระยะเวลาที่จัดเก็บผลลัพธ์ได้ รวมถึง จำนวนองค์ประกอบที่คุณจะแปลงเป็นพิกัดทางภูมิศาสตร์ได้ในแต่ละวัน

บทแนะนำนี้จะแสดงวิธีใช้ Python เพื่อเปลี่ยนสตริง "1600 Amphitheatre Pkwy, Mountain View, CA 94043" ให้เป็นสตริงต่อไปนี้

<?xml version='1.0' encoding='UTF-8'?> 
<kml xmlns='http://earth.google.com/kml/2.2'>
<Document>
<Placemark>
<description>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA</description>
<Point>
<coordinates>-122.081783,37.423111,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>

สร้างเอกสาร KML

KML เป็นภาษาการมาร์กอัป XML ดังนั้นเราจึงใช้ฟังก์ชัน xml.dom.minidom ในตัวของ Python เพื่อสร้างเอกสาร KML ได้ minidom ของ Python เป็นการใช้งาน DOM และภาษาโปรแกรมส่วนใหญ่รองรับ DOM จึงควรย้ายข้อมูลกระบวนการนี้ไปยังภาษาโปรแกรมอื่นได้ง่าย มีขั้นตอนดังนี้

  1. สร้างเอกสารโดยใช้ xml.dom.minidom.Document() ของ Python
  2. สร้างองค์ประกอบราก <kml> โดยใช้ createElementNS.
  3. ผนวกเข้ากับเอกสารโดยใช้ appendChild
  4. สร้างองค์ประกอบเอกสารโดยใช้ createElement
  5. เพิ่มลงในองค์ประกอบ <kml> โดยใช้ appendChild
  6. สำหรับที่อยู่แต่ละรายการ ให้สร้างองค์ประกอบ <Placemark> โดยใช้ createElement แล้วต่อท้ายองค์ประกอบ Document จากนั้นสร้างองค์ประกอบ <description> มอบหมายค่าของที่อยู่ให้ และต่อท้ายองค์ประกอบ <Placemark>
  7. สร้างองค์ประกอบ <Point> เพิ่มองค์ประกอบย่อย <coordinates> และต่อท้ายองค์ประกอบ <Placemark>
  8. ส่งที่อยู่ไปยัง Geocoder ของ Maps API ซึ่งจะส่งการตอบกลับในรูปแบบ JSON หรือ XML ใช้ urllib.urlopen() เพื่อดึงข้อมูลไฟล์และอ่านเป็นสตริง
  9. แยกวิเคราะห์การตอบกลับและดึงองค์ประกอบลองจิจูดและละติจูด
  10. สร้างโหนดข้อความในองค์ประกอบ <coordinates> และกำหนดสตริงละติจูด/ลองจิจูดเป็นค่าของโหนด
  11. เขียนเอกสาร KML ลงในไฟล์ข้อความ

โค้ด Python ตัวอย่าง

โปรดทราบว่าโค้ดตัวอย่างด้านล่างใช้ตัวแปร mapsKey แบบจำลอง คุณจะต้องแทนที่คีย์นี้ด้วยคีย์ของคุณเอง

โค้ดตัวอย่างสำหรับการแปลงรหัสพิกัดภูมิศาสตร์ด้วย Python 2.7 และเอาต์พุต JSON แสดงอยู่ด้านล่าง

import urllib
import xml.dom.minidom
import json 

def geocode(address, sensor=False):
 # This function queries the Google Maps API geocoder with an
 # address. It gets back a csv file, which it then parses and
 # returns a string with the longitude and latitude of the address.

 # This isn't an actual maps key, you'll have to get one yourself.
 # Sign up for one here: https://code.google.com/apis/console/
  mapsKey = 'abcdefgh'
  mapsUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address='
     
 # This joins the parts of the URL together into one string.
  url = ''.join([mapsUrl,urllib.quote(address),'&sensor=',str(sensor).lower()])
#'&key=',mapsKey])
  jsonOutput = str(urllib.urlopen(url).read ()) # get the response 
  # fix the output so that the json.loads function will handle it correctly
  jsonOutput=jsonOutput.replace ("\\n", "")
  result = json.loads(jsonOutput) # converts jsonOutput into a dictionary 
  # check status is ok i.e. we have results (don't want to get exceptions)
  if result['status'] != "OK": 
    return ""
  coordinates=result['results'][0]['geometry']['location'] # extract the geometry 
  return str(coordinates['lat'])+','+str(coordinates['lng'])

def createKML(address, fileName):
 # This function creates an XML document and adds the necessary
 # KML elements.

  kmlDoc = xml.dom.minidom.Document()
  
  kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2','kml')

  kmlElement = kmlDoc.appendChild(kmlElement)

  documentElement = kmlDoc.createElement('Document')
  documentElement = kmlElement.appendChild(documentElement)

  placemarkElement = kmlDoc.createElement('Placemark')
  
  descriptionElement = kmlDoc.createElement('description')
  descriptionText = kmlDoc.createTextNode(address)
  descriptionElement.appendChild(descriptionText)
  placemarkElement.appendChild(descriptionElement)
  pointElement = kmlDoc.createElement('Point')
  placemarkElement.appendChild(pointElement)
  coorElement = kmlDoc.createElement('coordinates')

  # This geocodes the address and adds it to a  element.
  coordinates = geocode(address)
  coorElement.appendChild(kmlDoc.createTextNode(coordinates))
  pointElement.appendChild(coorElement)

  documentElement.appendChild(placemarkElement)

  # This writes the KML Document to a file.
  kmlFile = open(fileName, 'w')
  kmlFile.write(kmlDoc.toprettyxml(' '))  
  kmlFile.close()

if __name__ == '__main__':
  createKML('1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA', 'google.kml')

สิ่งอื่นๆ ที่ควรพิจารณา

การกำหนดเวลาคำขอเข้ารหัสพิกัดภูมิศาสตร์

คำขอเข้ารหัสพิกัดภูมิศาสตร์จะขึ้นอยู่กับขีดจำกัดอัตราการค้นหาสูงสุดต่อวันของ Geocoder โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับขีดจำกัดเหล่านี้ในเอกสารประกอบของ Google Geocoding API คุณระบุการหน่วงเวลาระหว่างคำขอ Geocode แต่ละรายการได้เพื่อให้มั่นใจว่าคุณจะไม่ส่งคำค้นหาไปยัง Geocoder เร็วเกินไป คุณสามารถเพิ่มการหน่วงเวลานี้ได้ทุกครั้งที่ได้รับสถานะOVER_QUERY_LIMIT และใช้ลูปwhileเพื่อให้แน่ใจว่าคุณได้เข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่เรียบร้อยแล้วก่อนที่จะไปยังที่อยู่ถัดไป

การเปลี่ยนประเทศฐาน

โปรแกรม Geocoder ได้รับการตั้งโปรแกรมให้ลำเอียงผลลัพธ์ตามโดเมนต้นทาง ตัวอย่างเช่น การป้อน "syracuse" ในช่องค้นหาบน maps.google.com จะทำการเข้ารหัสพิกัดภูมิศาสตร์เมือง "Syracuse, NY" ขณะที่การป้อนคำค้นหาเดียวกันใน maps.google.it (โดเมนของอิตาลี) จะ ค้นหาเมือง "Siracusa" ในซิซิลี คุณจะได้รับผลลัพธ์เดียวกันโดยการส่งคำค้นหานั้นผ่านการเข้ารหัสพิกัดภูมิศาสตร์ HTTP ไปยัง maps.google.it แทน maps.google.com ซึ่งทำได้โดยการแก้ไขตัวแปร mapsUrl ในโค้ดตัวอย่างด้านบน ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดภูมิภาคได้ในเอกสารประกอบของ Geocoding API

หมายเหตุ: คุณจะส่งคำขอไปยังเซิร์ฟเวอร์ maps.google.* ที่ไม่มีอยู่ไม่ได้ ดังนั้นโปรดตรวจสอบว่ามีโดเมนประเทศอยู่ก่อนที่จะเปลี่ยนเส้นทางการค้นหา Geocoding ไปยังเซิร์ฟเวอร์ดังกล่าว หากต้องการดูการรองรับ Geocode ตามประเทศ โปรดดูโพสต์นี้

บทสรุป

เมื่อใช้โค้ดด้านบน ตอนนี้คุณสามารถเข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่โดยใช้ Python สร้าง KML <Placemark> จากที่อยู่ดังกล่าว และบันทึกลงในดิสก์ได้แล้ว หากพบว่าคุณต้อง เข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่ต่อวันมากกว่าที่ขีดจํากัดอนุญาต หรือว่าเครื่องมือเข้ารหัสพิกัดภูมิศาสตร์ของ Google ไม่ครอบคลุม ภูมิภาคที่คุณสนใจ ให้พิจารณาใช้บริการเว็บเข้ารหัสพิกัดภูมิศาสตร์เพิ่มเติม

เมื่อทราบวิธีเข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่แล้ว โปรดดูบทความเกี่ยวกับ การใช้ KML ใน Google Mashup Editor และ การใช้ PHP และ MySQL เพื่อสร้าง KML หากพบปัญหาหรือมีข้อสงสัยเกี่ยวกับบทแนะนำนี้ โปรดโพสต์ในฟอรัม Stack Overflow