在不使用浏览器的情况下使用 Python 捕获嵌入式谷歌地图图像

新手上路,请多包涵

我注意到,从 Google 地图页面,您可以获得一个“嵌入”链接以放入 iframe 并在浏览器中加载地图。 (这里没有消息)

图像大小可以调整到非常大,所以我有兴趣将一些大图像作为单个 .PNG 格式获取。

更具体地说,我想从边界框(右上角和左下角坐标)定义一个矩形区域,并使用适当的缩放系数获取相应的图像。

但我的问题是:如何使用 Python 将此地图的“像素内容”作为图像对象获取?

(我的理由是:如果浏览器可以获取并呈现此类图像内容,那么 Python 也应该能够做到这一点)。

编辑:这是显示我的示例地图的 HTML 文件的内容:

 <iframe
    width="2000"
    height="1500"
    frameborder="0"
    scrolling="yes"
    marginheight="0"
    marginwidth="0"
    src="http://maps.google.com.br/maps?hl=pt-BR&amp;ll=-30.027489,-51.229248&amp;spn=1.783415,2.745209&amp;z=10&amp;output=embed"/>

编辑:我按照 Ned Batchelder 的建议做了,并使用从上面的 iframe 中获取的 src 地址读取了 urllib.urlopen() 调用的内容。结果是出现了很多 javascript 代码,我认为这与 Google Maps JavaScript API 有关。所以,问题仍然存在:我如何才能从 Python 中的所有这些东西中做一些有用的东西来获得地图图像?

编辑:这个链接似乎包含一些关于谷歌地图如何平铺他们的地图的非常相关的信息:http: //www.codeproject.com/KB/scrapbook/googlemap.aspx

还有: http ://econym.org.uk/gmap/howitworks.htm

原文由 heltonbiker 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 714
2 个回答

我感谢所有的答案。我最终以另一种方式解决了这个问题,使用 Google Maps Static API 和一些公式将坐标空间转换为像素空间,这样我就可以获得可以很好地“拼接”在一起的精确图像。

对于任何感兴趣的人,这里是代码。如果它对某人有帮助,请发表评论!

=============================

 import Image, urllib, StringIO
from math import log, exp, tan, atan, pi, ceil

EARTH_RADIUS = 6378137
EQUATOR_CIRCUMFERENCE = 2 * pi * EARTH_RADIUS
INITIAL_RESOLUTION = EQUATOR_CIRCUMFERENCE / 256.0
ORIGIN_SHIFT = EQUATOR_CIRCUMFERENCE / 2.0

def latlontopixels(lat, lon, zoom):
    mx = (lon * ORIGIN_SHIFT) / 180.0
    my = log(tan((90 + lat) * pi/360.0))/(pi/180.0)
    my = (my * ORIGIN_SHIFT) /180.0
    res = INITIAL_RESOLUTION / (2**zoom)
    px = (mx + ORIGIN_SHIFT) / res
    py = (my + ORIGIN_SHIFT) / res
    return px, py

def pixelstolatlon(px, py, zoom):
    res = INITIAL_RESOLUTION / (2**zoom)
    mx = px * res - ORIGIN_SHIFT
    my = py * res - ORIGIN_SHIFT
    lat = (my / ORIGIN_SHIFT) * 180.0
    lat = 180 / pi * (2*atan(exp(lat*pi/180.0)) - pi/2.0)
    lon = (mx / ORIGIN_SHIFT) * 180.0
    return lat, lon

############################################

# a neighbourhood in Lajeado, Brazil:

upperleft =  '-29.44,-52.0'
lowerright = '-29.45,-51.98'

zoom = 18   # be careful not to get too many images!

############################################

ullat, ullon = map(float, upperleft.split(','))
lrlat, lrlon = map(float, lowerright.split(','))

# Set some important parameters
scale = 1
maxsize = 640

# convert all these coordinates to pixels
ulx, uly = latlontopixels(ullat, ullon, zoom)
lrx, lry = latlontopixels(lrlat, lrlon, zoom)

# calculate total pixel dimensions of final image
dx, dy = lrx - ulx, uly - lry

# calculate rows and columns
cols, rows = int(ceil(dx/maxsize)), int(ceil(dy/maxsize))

# calculate pixel dimensions of each small image
bottom = 120
largura = int(ceil(dx/cols))
altura = int(ceil(dy/rows))
alturaplus = altura + bottom

final = Image.new("RGB", (int(dx), int(dy)))
for x in range(cols):
    for y in range(rows):
        dxn = largura * (0.5 + x)
        dyn = altura * (0.5 + y)
        latn, lonn = pixelstolatlon(ulx + dxn, uly - dyn - bottom/2, zoom)
        position = ','.join((str(latn), str(lonn)))
        print x, y, position
        urlparams = urllib.urlencode({'center': position,
                                      'zoom': str(zoom),
                                      'size': '%dx%d' % (largura, alturaplus),
                                      'maptype': 'satellite',
                                      'sensor': 'false',
                                      'scale': scale})
        url = 'http://maps.google.com/maps/api/staticmap?' + urlparams
        f=urllib.urlopen(url)
        im=Image.open(StringIO.StringIO(f.read()))
        final.paste(im, (int(x*largura), int(y*altura)))
final.show()

原文由 heltonbiker 发布,翻译遵循 CC BY-SA 3.0 许可协议

与其尝试使用嵌入链接,不如直接访问 Google API 以获取静态图片形式的图像。这是 Google Maps 静态图像 API 的链接 - 看起来您只需在 URL 中传递 long/lat 参数,就像您对普通可嵌入的那样。例如:

 http://maps.googleapis.com/maps/api/staticmap?center=-30.027489,-51.229248&size=600x600&zoom=14&sensor=false

以您在上面给出的坐标为中心,为您提供 600x600 的街道级概览,这似乎是巴西的阿雷格里港。现在您可以使用 urlopenPIL 正如 Ned 所建议的:

 from cStringIO import StringIO
import Image
import urllib

url = "http://maps.googleapis.com/maps/api/staticmap?center=-30.027489,-51.229248&size=800x800&zoom=14&sensor=false"
buffer = StringIO(urllib.urlopen(url).read())
image = Image.open(buffer)

原文由 Daniel Roseman 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题