2011-09-20 23 views
10

मैंने देखा है कि, Google मानचित्र पेज से, आप एक आईफ़्रेम के अंदर डालने के लिए "एम्बेड" लिंक प्राप्त कर सकते हैं और ब्राउज़र को मानचित्र में लोड कर सकते हैं। (यहां कोई समाचार नहीं)ब्राउज़र का उपयोग किए बिना पाइथन के साथ एम्बेडेड Google मानचित्र छवि को कैप्चर करें

छवि का आकार बहुत बड़ा होने के लिए समायोजित किया जा सकता है, इसलिए मुझे कुछ बड़ी छवियां एकल पीएनजी के रूप में प्राप्त करने में रूचि है।

अधिक विशेष रूप से, मैं एक आयताकार क्षेत्र को एक बाउंडिंग बॉक्स (ऊपरी-दाएं और निचले बाएं निर्देशांक) से परिभाषित करना चाहता हूं, और उपयुक्त ज़ूम कारक के साथ संबंधित छवि प्राप्त करना चाहता हूं।

लेकिन मेरा सवाल है: मैं इस मानचित्र के "पिक्सेल सामग्री" को छवि ऑब्जेक्ट के रूप में प्राप्त करने के लिए पायथन का उपयोग कैसे कर सकता हूं?

(मेरा तर्क यह है कि: यदि ब्राउज़र ऐसी छवि सामग्री प्राप्त और प्रस्तुत कर सकता है, तो पाइथन भी ऐसा करने में सक्षम होना चाहिए)।

संपादित करें:

<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"/> 

संपादित करें: इस है कि मेरे नमूना नक्शा दिखाता है HTML फ़ाइल की सामग्री है मैं के रूप में नेड Batchelder ने सुझाव दिया था, और src पता ले लिया का उपयोग कर एक urllib.urlopen() कॉल की सामग्री पढ़ने उपरोक्त आईफ्रेम से। नतीजा बहुत सारे जावास्क्रिप्ट कोड था, जो मुझे लगता है कि Google मानचित्र जावास्क्रिप्ट एपीआई के साथ करना है। तो, प्रश्न लिंग: नक्शा छवि प्राप्त करने के लिए मैं पाइथन में इन सभी चीजों से कुछ उपयोगी सामान कैसे कर सकता हूं?

संपादित करें: http://www.codeproject.com/KB/scrapbook/googlemap.aspx

भी

: इस लिंक कैसे गूगल मैप्स उनके नक्शे टाइल पर कुछ बहुत प्रासंगिक जानकारी ऐसा प्रतीत होता है http://econym.org.uk/gmap/howitworks.htm

उत्तर

18

मैं सभी प्रश्नों के उत्तर के लिए धन्यवाद देता हूं। मैंने Google मानचित्र स्टेटिक एपीआई और कोऑर्डिनेट स्पेस से पिक्सेल स्पेस में कनवर्ट करने के लिए कुछ सूत्रों का उपयोग करके समस्या को हल करने का अंत किया, ताकि मैं सटीक छवियां प्राप्त कर सकूं जो अच्छी तरह से "सिलाई" कर सकें।

रुचि रखने वाले किसी भी व्यक्ति के लिए, यहां कोड है। अगर यह किसी की मदद करता है, तो कृपया टिप्पणी करें!

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

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

बहुत अच्छा! मुझे यह काम करने के लिए मिला लेकिन यहां कुछ छोटे बदलाव करने की आवश्यकता है: https://gist.github.com/BenElgar/0d5b3e7cc89cb2180c6e। ध्यान दें कि यह पाइथन 2 है लेकिन इसे पायथन 3 में काम करने के लिए बहुत मुश्किल नहीं होना चाहिए। यह भी ध्यान रखें कि यह स्थिर नक्शा एपीआई के लिए उपयोग की शर्तों को तकनीकी रूप से तोड़ रहा है जैसा कि यहां विस्तृत किया गया है: https: // डेवलपर्स। google.com/maps/terms#section_10_1_3 –

+0

पायथन 3 के लिए अपडेट किया गया: https://stackoverflow.com/a/47776466/5859283 – 4Oh4

0

urllib.urlopen एक यूआरएल खुल जाएगा, परिणाम एक .read() विधि होगा आप छवि बाइट्स प्राप्त करने के लिए उपयोग कर सकते हैं। cStringIO में स्मृति-सारणी के आधार पर एक फ़ाइल-जैसी वस्तु है। पीआईएल में Image.open फ़ंक्शन है जो आपको एक छवि वस्तु देने के लिए फ़ाइल जैसी चीज़ खोलता है। छवि वस्तुओं को उनके पिक्सेल मानों के बारे में पूछा जा सकता है।

+0

जैसा कि आपने कहा है, urllib का उपयोग करके मुझे जावास्क्रिप्ट कोड (मुझे लगता है), एक छवि वस्तु नहीं है। यह समझ में आता है, क्योंकि एम्बेडेड नक्शा नेविगेशन की अनुमति देता है (यह Google मानचित्र स्टेटिक एपीआई का उपयोग करके उत्पन्न नहीं होता है, जिसकी छवि आकार पर कुछ गंभीर सीमाएं हैं)। – heltonbiker

+0

@heltonbiker: क्षमा करें, मुझे नहीं पता कि अधिक जटिल समस्या के साथ कैसे मदद करें। मूल विवरण अधिक सरल लग रहा था। –

+0

मैं आपकी अंतर्दृष्टि और रुचि के लिए बहुत आभारी हूं। असल में, मैं Google मानचित्र स्टेटिक एपीआई के साथ आपके सुझाव का उपयोग करता हूं। समस्या पूछा, हालांकि, शायद कुछ जावास्क्रिप्ट का उपयोग कर शायद अधिक आसानी से हल किया गया है। अगर मुझे कोई अच्छा जवाब मिल जाए, तो मैं इसे यहां पोस्ट करूंगा। एक बार फिर धन्यवाद! – heltonbiker

13

एम्बेड लिंक का उपयोग करने की कोशिश करने के बजाय, आपको छवियों को स्थैतिक ग्राफिक्स के रूप में प्राप्त करने के लिए सीधे Google API पर जाना चाहिए। यहां Google Maps static image API का लिंक दिया गया है - ऐसा लगता है कि आप यूआरएल में लंबे/लेट पैरामीटर में बस पास कर सकते हैं जैसे कि आप सामान्य एम्बेड करने योग्य के लिए करते हैं। उदाहरण के लिए:

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

आप एक 600x600 सड़क-स्तरीय अवलोकन समन्वय आप ऊपर देना है, जो ब्राजील में पोर्टो एलेग्रे हो रहा है पर केंद्रित देता है। अब आप urlopen और PIL उपयोग कर सकते हैं के रूप में नेड पता चलता है:

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) 
+0

यह अभी मेरा विकल्प है, लेकिन मैं अभी भी इसे "प्लान बी" बनाने की कोशिश करना चाहता हूं, क्योंकि उन मेगापिक्सेल आकार वाली छवियों को उत्पन्न करने के लिए छवि सिलाई आवश्यक होगी, जिसका लक्ष्य मैं कर रहा हूं। छवि कोनों के लिए निर्देशांक प्राप्त करना आवश्यक रूप से आसान या स्पष्ट नहीं है, और चूंकि एम्बेडेड मानचित्र स्वचालित रूप से एक साथ सिलाई करते हैं, शायद जावास्क्रिप्ट एपीआई का अध्ययन करने के लिए कुछ अंतर्दृष्टि मिल सकती है। आपकी युक्तियों के लिए धन्यवाद और आपके अच्छे कोड स्निपेट के लिए धन्यवाद! – heltonbiker

5

यह लोगों को है कि अजगर 3 का उपयोग के लिए Daniel Roseman's answer है। एक्स:

अजगर 3.x कोड:

from io import BytesIO 
from PIL import Image 
from urllib import request 
import matplotlib.pyplot as plt # this is if you want to plot the map using pyplot 

url = "http://maps.googleapis.com/maps/api/staticmap?center=-30.027489,-51.229248&size=800x800&zoom=14&sensor=false" 

buffer = BytesIO(request.urlopen(url).read()) 
image = Image.open(buffer) 

# Show Using PIL 
image.show() 

# Or using pyplot 
plt.imshow(image) 
plt.show() 
3

एक अधिक संक्षिप्त पायथन 2.x संगत विधि

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") 
1

गूगल स्थिर मानचित्र छवि पर कब्जा कर लिया/बचाया है करने के लिए (एक PNG के रूप में) सबसे आसान तरीका है:

import requests 

img = open('tmp.png','wb') 
img.write(requests.get('https://maps.googleapis.com/maps/api/staticmap?center=33.0456,131.3009&zoom=12&size=320x385&key=YOUR_API_KEY').content) 
img.close() 
+0

काम नहीं करता है: / – rvcristiand

5

के आधार पर BenElgar से परिवर्तन के साथ heltonbiker से उत्कृष्ट जवाब नीचे दिए गए, अजगर 3 के लिए कुछ अद्यतन कोड और एपीआई कुंजी के लिए उपयोग की है उम्मीद है कि अपनी किसी के लिए उपयोगी:

""" 
Stitch together Google Maps images from lat, long coordinates 
Based on work by heltonbiker and BenElgar 
Changes: 
    * updated for Python 3 
    * added Google Maps API key (compliance with T&C, although can set to None) 
    * handle http request exceptions 
""" 

import requests 
from io import BytesIO 
from math import log, exp, tan, atan, pi, ceil 
from PIL import Image 
import sys 

EARTH_RADIUS = 6378137 
EQUATOR_CIRCUMFERENCE = 2 * pi * EARTH_RADIUS 
INITIAL_RESOLUTION = EQUATOR_CIRCUMFERENCE/256.0 
ORIGIN_SHIFT = EQUATOR_CIRCUMFERENCE/2.0 
GOOGLE_MAPS_API_KEY = None # set to 'your_API_key' 

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 


def get_maps_image(NW_lat_long, SE_lat_long, zoom=18): 

    ullat, ullon = NW_lat_long 
    lrlat, lrlon = SE_lat_long 

    # 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 

    # assemble the image from stitched 
    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 = {'center': position, 
         'zoom': str(zoom), 
         'size': '%dx%d' % (largura, alturaplus), 
         'maptype': 'satellite', 
         'sensor': 'false', 
         'scale': scale} 
      if GOOGLE_MAPS_API_KEY is not None: 
      urlparams['key'] = GOOGLE_MAPS_API_KEY 

      url = 'http://maps.google.com/maps/api/staticmap' 
      try:     
      response = requests.get(url, params=urlparams) 
      response.raise_for_status() 
      except requests.exceptions.RequestException as e: 
      print(e) 
      sys.exit(1) 

      im = Image.open(BytesIO(response.content))     
      final.paste(im, (int(x*largura), int(y*altura))) 

    return final 

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

if __name__ == '__main__': 

    # a neighbourhood in Lajeado, Brazil: 
    NW_lat_long = (-29.44,-52.0) 
    SE_lat_long = (-29.45,-51.98) 

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

    result = get_maps_image(NW_lat_long, SE_lat_long, zoom=18) 
    result.show() 
संबंधित मुद्दे