I am at it again with using Google data. For a few projects I was interested in downloading street view imagery data. It has been used in criminal justice applications as a free source for second hand systematic social observation by having people code aspects of disorder from the imagery (instead of going in person) (Quinn et al., 2014), as estimates of the ambient walking around population (Yin et al., 2015), and examining criminogenic aspects of the built environment (Vandeviver, 2014).
I think it is just a cool source of data though to be honest. See for example Phil Cohen’s Family Inequality post in which he shows examples of auctioned houses in Detroit over time.
Using the Google Street View image API you can submit either a set of coordinates or an address and have the latest street view image returned locally. This ends up being abit simpler than my prior examples (such as the street distance API or the places API) because it just returns the image blob, no need to parse JSON.
Below is a simple example in python, using a set of addresses in Detroit that are part of a land bank. This function takes an address and a location to download the file, then saves the resulting jpeg to your folder of choice. I defaulted for the image to be 1200×800 pixels.
import urllib, os
myloc = r"C:\Users\andrew.wheeler\Dropbox\Public\ExampleStreetView" #replace with your own location
key = "&key=" + "" #got banned after ~100 requests with no key
def GetStreet(Add,SaveLoc):
base = "https://maps.googleapis.com/maps/api/streetview?size=1200x800&location="
MyUrl = base + urllib.quote_plus(Add) + key #added url encoding
fi = Add + ".jpg"
urllib.urlretrieve(MyUrl, os.path.join(SaveLoc,fi))
Tests = ["457 West Robinwood Street, Detroit, Michigan 48203",
"1520 West Philadelphia, Detroit, Michigan 48206",
"2292 Grand, Detroit, Michigan 48238",
"15414 Wabash Street, Detroit, Michigan 48238",
"15867 Log Cabin, Detroit, Michigan 48238",
"3317 Cody Street, Detroit, Michigan 48212",
"14214 Arlington Street, Detroit, Michigan 48212"]
for i in Tests:
GetStreet(Add=i,SaveLoc=myloc)
Dropbox has a nice mosaic view for a folder of pictures, you can view all seven photos here. Here is the 457 West Robinwood Street picture:
In my tests my IP got banned after around 100 images, but you can get a verified google account which allows 25,000 image downloads per day. Unfortunately the automatic API only returns the most recent image – there is no way to return older imagery nor know the date-stamp of the current image. (You technically could download the historical data if you know the pano id for the image. I don’t see any way though to know the available pano id’s though.) Update — as of 2018 there is now a Date associated with the image, specifically a Year-Month, but no more specific than that. Not being able to figure out historical pano id’s is still a problem as far as I can tell as well.
But this is definitely easier for social scientists wishing to code images as opposed to going into the online maps. Hopefully the API gets extended to have dates and a second API to return info. on what image dates are available. I’m not sure if Mike Bader’s software app is actually in the works, but for computer scientists there is a potential overlap with social scientists to do feature extraction of various social characteristics, in addition to manual coding of the images.
Update: here is a version that works for python 3+. Currently you need to have a key, no more getting a few free images before being cut off.
# For Python Versions 3+
# Tested V3.10 on 12/15/2021
import os
import urllib.parse
import urllib.request
myloc = r"??????????????" #replace with your own location
key = "&key=" + "????????????" #you need an actual key now!!
def GetStreet(Add,SaveLoc):
base = "https://maps.googleapis.com/maps/api/streetview?size=1200x800&location="
MyUrl = base + urllib.parse.quote_plus(Add) + key #added url encoding
fi = Add + ".jpg"
urllib.request.urlretrieve(MyUrl, os.path.join(SaveLoc,fi))
Tests = ["457 West Robinwood Street, Detroit, Michigan 48203",
"1520 West Philadelphia, Detroit, Michigan 48206",
"2292 Grand, Detroit, Michigan 48238",
"15414 Wabash Street, Detroit, Michigan 48238",
"15867 Log Cabin, Detroit, Michigan 48238",
"3317 Cody Street, Detroit, Michigan 48212",
"14214 Arlington Street, Detroit, Michigan 48212"]
for i in Tests:
GetStreet(Add=i,SaveLoc=myloc)
Joe Devlin
/ March 20, 2018Thanks for this, really useful! I initially got – AttributeError: module ‘urllib’ has no attribute ‘urlretrieve’ – so amended the code slightly to import urllib.request and also added request to – urllib.request.urlretrieve(MyUrl, os.path.join(SaveLoc,fi)) – but am now getting – HTTP Error 400: Bad Request – any ideas why that might be?
apwheele
/ March 20, 2018Sorry, not sure. Code works as is for me still (just ran it) — I am using V2.7 – are you using V3? Might be a good question for stackoverflow.
apwheele
/ March 21, 2018I see the ping-back someone answered your question — it needs to be encoded. I have updated the code snippet, as this is a good idea when passing arbitrary strings into the api, as other characters could cause problems as well.
Joe Devlin
/ March 23, 2018Thanks Andrew! I was thinking these images would be good to use for machine learning, maybe to try and identify certain stores/brands/signs or something like that. What do you think? Have you heard of anything like that being done? Also, do you know how I can remove the link to my facebook profile from these posts?
apwheele
/ March 23, 2018IANAL, so view the terms of service for your own application to see if you think you are OK. I cited a few applications that are similar to machine vision applications in this post already (Yin paper and work of Mike Bader), another I am familiar with is this Streetscore, http://ieeexplore.ieee.org/document/6910072/?tp=&arnumber=6910072&url=http:%2F%2Fieeexplore.ieee.org%2Fxpls%2Fabs_all.jsp%3Farnumber%3D6910072.
I just manually took out the link to your facebook profile from your comment.
Andrew Campbell
/ March 20, 2018This is great! I’m aware that Google Street View has a bunch of cameras that form the panoramas. I’m interested in getting the images for selected locations taken from the camera facing in the frontward direction. I’m relatively new to python so i’m wondering if you have any suggestions on whether it’s possible?
Thanks!
apwheele
/ March 21, 2018I’m not sure what you mean. Can you be more specific?
Andrew Campbell
/ March 21, 2018The images that download to the specified destination from the code are taken from a view looking at houses along a street. Is there a way in which the images can be oriented to face the road? I’m interested in looking at roadside assets in google street view imagery
apwheele
/ March 22, 2018Ok, to do that it takes alittle bit of GIS know-how. First you need to find the orientation of the street, then you can identify which direction to point the camera. If you submit a lat-lon (and orientation) you can get an image for anywhere in the panorama.
I did this for another project in which I needed to take running images of whole streets. What I did was generate a fine sample of points along the street (like every meter), in a GIS. From that data you can calculate the local orientation of the street. Then I sampled google street view images about every 40 meters (so there was little to no overlap between shots). But I requested images at 90 degrees to the street orientation (so I got the sidewalk), whereas here you would want to just look straight ahead (or backwards?).
Andrew Campbell
/ March 27, 2018Thanks for your response Andrew.
This is actually for a GIS project so my GIS know-how is solid. You’re correct in that I do want to look straight ahead (90 degrees, give or take accounting for optimal viewing) of the street. My question would be, where do i need to define the lat longs and orientation for each individual image location in the code?
apwheele
/ March 27, 2018Just using a street-centerline file I created sample points regularly along the segment. Is that your question? You can email and I can share code if you want (I just made the regularly sampled point in ArcGIS).
Simon Ghislain
/ May 12, 2018Hello,
i just installed python 3.5 and pyCharm, pasted the code, and got relatively same error at run as Joe Devlin:
AttributeError: module ‘urllib’ has no attribute ‘quote_plus’
Btw thank you very much for getting me on tracks…and sharing your code.
I’m trying to
1) define an itinerary from point A to point B
2) generate, like in your reply to Andrew Campbell, a set of points every 40m or so
3) use those points to calculate local direction of road
4) generate google street screenshots with your code
(I would like to make an animated GIF of that itinerary)
But i don’t know where to start…i would like NOT to use ArcGIS (i used to use it but i don’t have it anymore). Also i’m new to Python too, altough i have some background in programmation and coding.
Is it possible to use the Google itinerary tool to extract the set of points? (instead of a street-centerline file, whiwh I suppose is generated with ArcGIS?)
Could you please help me in telling me the main steps I should follow in order to achieve that?
I would be so thankful…
Thank you very much in advance for any help, and already for sharing your knowledge
Simon Ghislain
/ May 12, 2018Ok, the library urllib has been split into urllib.request, urllib.parse ans urllib.error from Python 2.x to Python 3.x
So only change is to write “urllib.parse.quote_plus” instead of “urllib.quote_plus”
and write
“urllib.request.urlretrieve” instead of “urllib.urlretrieve”
But then i got another error:
line 258, in urlretrieve
tfp = open(filename, ‘wb’)
FileNotFoundError: [Errno 2] No such file or directory: ‘C:\\tests\\ExampleStreetView\\457 West Robinwood Street, Detroit, Michigan 48203.jpg’
So looks like urlretrieve, instead of copying url content to a new file, tries to access the file beeing created?
Simon Ghislain
/ May 12, 2018Yeah it works!
Simply the destination directory didn’t exist yet…
Wow so magical…I tried with my own adress, get the .jpg in less than one second…
Now the last thing I would like to do is instead of a list of addresses, generate a set of coordinates and determine direction alongside road from a Google Map itinerary…with Direction aAPI? Is is possible?
ganesh
/ October 15, 2018am having this error could any one help me Error interpreting JPEG image file (Not a JPEG file: starts with 0x89 0x50)4
apwheele
/ October 15, 2018Sorry, not sure what the issue would be to cause this.
Valerio De Luca
/ January 4, 2019https://stackoverflow.com/questions/11310220/why-am-i-getting-the-error-not-a-jpeg-file-starts-with-0x89-0x50
john
/ April 4, 2019I am working on a project that requires me to gather aerial views of specific locations within larger developments. Due to the areas being located on the interior of the sites, street view images will not always give me the appropriate view. You mentioned in the article that you can use street addresses or coordinates. Is there a way to use the coordinates to gather aerial images as opposed to the street view?
apwheele
/ April 5, 2019Are you asking about oblique imagery? Or just plain old satellite photos?
For google I think you need to use javascript to get either, https://developers.google.com/maps/documentation/javascript/maptypes#45DegreeImagery.
If you just want satellite you should geocode the addresses, then I imagine there are a bunch of different options to grab the images beyond Google.
john
/ April 5, 2019Just satellite photos, thank you for your response and help!
apwheele
/ April 5, 2019Apparently there is a Google static map API that you can get just the overhead images with a URL (just inputting the address), https://developers.google.com/maps/documentation/maps-static/dev-guide, so that would work similar to here. Build the URL and save the image on your local machine.
Angel R
/ May 7, 2019Finally got this to work for me, however, the resulting jpegs cannot be opened by any of my photo/image viewer programs. All show to be 259 byte (1kb), JPG files. Not sure what is happening.
apwheele
/ May 7, 2019See some of the earlier comments, it may be the same problem (saved as a jpeg extension but is actually a PNG file).
Juan Marrugo
/ November 1, 2019I found out that you have to enable billing in the Google Cloud Console. If you enter the API key and run the program, you get those tiny files. Open any of the files using notepad, it should say “The Google Maps Platform server rejected your request. You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started“. On the other hand, if you do not enter an API key you get “The Google Maps Platform server rejected your request. You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account“.
apwheele
/ November 3, 2019Yes, to enable billing you need to provide a credit card for verification. But that does not mean you will actually be billed, you can set the API so it will cut off before the free limits run out (or just not submit that many requests).
If you have many more requests than the free billing allows, you should use a local geocoder or street centerlines to figure out the orientation stuff. But the streetview images are unique with no alternative that I am aware of.
Juan Marrugo
/ November 1, 2019Hi Andrew, hope you are doing fine. I searched for a way to grab Google Streetview images automatically and I was sent to your post. However I have a few questions:
1) Should I enable any specifics in the google console for it to work better on your script? I enabled Street View Static API, is that enough?
2) I have a set of randomly assorted points over a map, all set to fall in the center of a building. I need a photo of such building. Do you a way to batch reverse geocode the lat long coordinates into local directions? My main concern is that the pictures end up facing the wrong direction, and hence not showing the buildings.
3) If I were to use the Lat Long coordinates, what format should I use for it?
Thanks in advance,
Juan
apwheele
/ November 1, 2019For 1 yeah that is all that is needed. There are different tools to make sure you don’t go over your limit, but they don’t affect anything else.
For 2 yes I would reverse geocode the lat lon and then submit the address. (You can use another Google api to reverse geocode.) If you have the base centerlines files you could snap the lat lon to the nearest centerline, figure out orientation, and then figure out the lat/lon and orientation, but that is more work.
For 3 check out this other blog post I did, https://andrewpwheeler.wordpress.com/2018/04/02/drawing-google-streetview-images-down-an-entire-street-using-python/.
thejodyfall
/ November 18, 2021Hello, thanks for this post – really interesting. Is there a way to get a list of locations linked from an initial location in google maps/street view? So if I had a starting location, could I find out programmatically the linked locations, similar to the way street view works with the control arrows?
apwheele
/ November 18, 2021So two things you might be interested in. One is reverse geocoding, here you input a lat/lon pair and get back the addresses that are nearby, https://developers.google.com/maps/documentation/geocoding/overview#ReverseGeocoding.
The second will be the google places lookup. This is like reverse geocoding, except it will return googles listed businesses, https://andrewpwheeler.com/2014/05/15/using-the-google-places-api-in-python/.
I’m not 100% sure if this snippet is good for python3, https://dl.dropboxusercontent.com/s/f4ivwa7lif8fmrp/Grid_Googleplaces.py?dl=0, but that is closer to a full script for given a specify type of business, crawl over a whole city (given by a lat/lon bounding box).
apwheele
/ November 18, 2021Oh and here I have an example of using the reverse geocoding api, https://andrewpwheeler.com/2016/05/03/neighborhoods-in-albany-according-to-google/
thejodyfall
/ November 18, 2021Wow, that’s amazing! Will take a look through – thank you so much.
M
/ December 14, 2021I tried the code and I am using python 3.10 version and it gives me this error. raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
I am not sure what is causing this error.
Thank you for your help. If anyone has a new version of this code. I would be appreciated to share it with me.
Thanks.
apwheele
/ December 15, 2021See the update at the end of the post now.
Cristian
/ April 7, 2022Hi, nice post. I am trying to get every image on GSV from my city. As is saw on one of your replys, you said you take images every 30m. How did you do that? Is there another library for that?
apwheele
/ April 7, 2022See this post, https://andrewpwheeler.com/2018/04/02/drawing-google-streetview-images-down-an-entire-street-using-python/. You need to have a street file in a GIS and sample at regular points + calculate the orientation of the street.