如何将带有脚本的 kml 文件上传到谷歌地图?

发布于 2024-09-24 23:57:27 字数 102 浏览 12 评论 0 原文

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

I have a python script, that generates kml files. Now I want to upload this kml file within the script (not per hand) to the "my maps" section of google maps. Does anybody have a python or other script/code to do so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

念三年u 2024-10-01 23:57:27

摘要问题 2590 已修复,这可能需要一段时间,因为 Google 将此问题作为 WontFix 关闭。您可以尝试使用一些解决方法来获得相同的最终结果,但就目前情况而言,您不能简单地使用 Google 地图数据 API 上传 KML 文件。

长版本:

没有任何Python代码来执行此操作,但是Google 地图数据 API 允许您通过一系列 HTTP 请求来完成此操作。请参阅 上传 KML(位于 <有关如何执行此操作的文档,请参阅 href="http://code.google.com/apis/maps/documentation/mapsdata/developers_guide.html" rel="nofollow">开发人员指南。因此,一种可能的 Python 解决方案是使用标准库中的 httplib 来执行以下操作:适合您的 HTTP 请求。

经过各种编辑和评论中的反馈后,这里有一个脚本,它通过命令行获取 Google 用户名和密码(请小心使用它!),通过创建 authorization_token 变量来获取 authorization_token 变量href="http://code.google.com/apis/maps/documentation/mapsdata/developers_guide_protocol.html#ClientLogin" rel="nofollow">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 响应 KML 帖子错误的请求。显然这是一个已知问题(已报告2590 2010 年 7 月 22 日)因此,如果您希望 Google 进行修复,请投票并发表评论。

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

  1. 在不上传 KML 的情况下创建地图,然后根据需要上传 KML 功能,如 当 Google 确认该错误存在时,对该问题发表评论 #9
  2. 上传 XML上传 CSV 而不是 KML(如果这些方法支持您需要完成的
  3. 格式调整)您的 KML 数据。 API 的 Google 网上论坛中的这篇文章建议:这可能会有所帮助,但看起来很复杂。

祝你好运

Summary: You can't until issue 2590 is fixed, which may be a while because Google have closed this issue as WontFix. There are workarounds you can try to achieve the same end result, but as it stands you cannot simply upload a KML file using the Google Maps Data API.

Long version:

I don't didn't have any Python code to do this, but the Google Maps Data API allows you to do this with a series of HTTP requests. See Uploading KML in the HTTP Protocol section of the Developers Guide for the documentation on how to do this. So one possible Python solution would be to use something like httplib in the standard library to do the appropriate HTTP requests for you.

After various edits and your feedback in the comments, here is a script that takes a Google username and password via the command line (be careful how you use it!) to obtain the authorization_token variable by making a ClientLogin authentication request. With a valid username and password, the auth token can be used in the Authorization header for POSTing the KML data to the Maps Data 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())

Unfortunately, even when using valid login credentials to obtain a valid authorization token and using a valid KML file containing exactly the example as given in the documentation, the API responds to the KML post with a 400 Bad Request. Apparently this is a known issue (2590 reported July 22nd 2010) so please vote for and comment on that if you'd like Google to fix.

In the meantime, without that bug fixed, you could try

  1. Create the map without uploading KML, and then upload KML features as appropriate, as suggested in comment #9 on the issue from Google, when they confirmed that the bug exists.
  2. uploading XML or uploading CSV instead of KML if these methods support what you need to get done
  3. fiddling with the format of your KML data. This post in the Google Group for the API suggests that this might help, but it looks complicated.

Good luck

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文