2

我有一个 python 脚本,可以生成 kml 文件。现在我想将脚本中的这个 kml 文件(不是手动)上传到谷歌地图的“我的地图”部分。有人有python或其他脚本/代码吗?

4

1 回答 1

1

摘要:问题 2590修复之前,您无法解决问题,这可能需要一段时间,因为 Google 已将该问题作为 WontFix 关闭。您可以尝试一些变通方法来达到相同的最终结果,但就目前而言,您不能简单地使用 Google Maps Data API 上传 KML 文件。

长版:

没有任何 Python 代码来执行此操作,但Google Maps Data API允许您使用一系列 HTTP 请求来执行此操作。有关如何执行此操作的文档,请参阅开发人员指南的 HTTP 协议部分中的上传 KML 。因此,一种可能的 Python 解决方案是使用标准库中的httplib之类的东西来为您执行适当的 HTTP 请求。

经过各种编辑和您在评论中的反馈,这里有一个脚本,它通过命令行获取谷歌用户名和密码(小心你如何使用它!)authorization_token通过发出ClientLogin 身份验证请求来获取变量。使用有效的用户名和密码,身份验证令牌可用于Authorization将 KML 数据发布到地图数据 API 的标头中。

#!/usr/bin/env python
import httplib
import optparse
import sys
import urllib

class GoogleMaps(object):
    source = "daybarr.com-kmluploader-0.1"

    def __init__(self, email, passwd):
        self.email = email
        self.passwd = passwd
        self._conn = None
        self._auth_token = None

    def _get_connection(self):
        if not self._auth_token:
            conn = httplib.HTTPSConnection("www.google.com")
            params = urllib.urlencode({
                "accountType": "HOSTED_OR_GOOGLE",
                "Email": self.email,
                "Passwd": self.passwd,
                "service": "local",
                "source": self.source,
            })
            headers = {
                "Content-type": "application/x-www-form-urlencoded",
                "Accept": "text/plain",
            }
            conn.request("POST", "/accounts/ClientLogin", params, headers)
            response = conn.getresponse()
            if response.status != 200:
                raise Exception("Failed to login: %s %s" % (
                    response.status,
                    response.reason))
            body = response.read()
            for line in body.splitlines():
                if line.startswith("Auth="):
                    self._auth_token = line[5:]
                    break
            if not self._auth_token:
                raise Exception("Cannot find auth token in response %s" % body)
        if not self._conn:
            self._conn = httplib.HTTPConnection("maps.google.com")
        return self._conn

    connection = property(_get_connection)

    def upload(self, kml_data):
        conn = self.connection
        headers = {
            "GData-Version": "2.0",
            "Authorization": 'GoogleLogin auth=%s' % (self._auth_token,),
            "Content-Type": "application/vnd.google-earth.kml+xml",
        }
        conn.request("POST", "/maps/feeds/maps/default/full", kml_data, headers)
        response = conn.getresponse()
        if response.status != 200:
            raise Exception("Failed to upload kml: %s %s" % (
                response.status,
                response.reason))
        return response.read()

if __name__ == "__main__":
    parser = optparse.OptionParser()
    parser.add_option("-e", "--email", help="Email address for login")
    parser.add_option("-p", "--passwd", help="Password for login")
    options, args = parser.parse_args()
    if not (options.email and options.passwd):
        parser.error("email and passwd required")
    if args:
        kml_file = open(args[0], "r")
    else:
        kml_file = sys.stdin
    maps = GoogleMaps(options.email, options.passwd)
    print maps.upload(kml_file.read())

不幸的是,即使使用有效的登录凭据来获取有效的授权令牌并使用包含文档中给出的示例的有效 KML 文件,API 也会使用400 Bad Request. 显然这是一个已知问题( 2010 年 7 月 22 日报告了2590),因此如果您希望 Google 解决此问题,请投票并发表评论。

同时,如果没有修复该错误,您可以尝试

  1. 在不上传 KML 的情况下创建地图,然后根据谷歌关于该问题的评论 #9 中的建议上传适当的 KML 要素,当他们确认存在错误时。
  2. 如果这些方法支持您需要完成的工作,则上传 XML上传 CSV而不是 KML
  3. 摆弄 KML 数据的格式。Google Group for API 中的这篇文章表明这​​可能会有所帮助,但看起来很复杂。

祝你好运

于 2010-09-28T20:12:33.960 回答