Capture embedded google map image with Python without using a browser

前端 未结 8 1095
心在旅途
心在旅途 2020-12-04 18:57

I have noticed that, from Google Maps page, you can get an \"embed\" link to put inside an iframe and load the map in a browser. (no news here)

The image size can be

相关标签:
8条回答
  • 2020-12-04 19:20

    A more concise Python 2.x compatible method is

    from io import BytesIO
    import Image
    import urllib
    
    url = "http://maps.googleapis.com/maps/api/staticmap?center=52.50058,13.31316&size=800x800&zoom=14"
    buffer = BytesIO(urllib.urlopen(url).read())
    image = Image.open(buffer)
    image.save("map.png")
    
    0 讨论(0)
  • 2020-12-04 19:35

    I thank for all the answers. I ended up solving the problem another way, using Google Maps Static API and some formulas to convert from Coordinate space to Pixel space, so that I can get precise images that "stitch" nicely together.

    For anyone interested, here is the code. If it helps someone, please comment!

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

    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()
    
    0 讨论(0)
提交回复
热议问题