detecting “we have no imagery” of google maps stre

2020-06-09 04:13发布

问题:

I'm generating street view static images like so:

https://maps.googleapis.com/maps/api/streetview?size=1080x400&location=%s&fov=90&heading=235&pitch=0&key=%s

If you visit that link you see an image that says, "Sorry, we have no imagery for this..."

Is there any way to detect this "sorry" state so that I can fall back to another image?

回答1:

this situation is already build in in the 3.0 version due the boolean test status === streetviewStatus.Ok, here is a snippet from my situation solving

if (status === google.maps.StreetViewStatus.OK) {
            var img = document.createElement("IMG");
            img.src = 'http://maps.googleapis.com/maps/api/streetview?size=160x205&location='+ lat +','+ lng  +'&sensor=false&key=AIzaSyC_OXsfB8-03ZXcslwOiN9EXSLZgwRy94s';
            var oldImg = document.getElementById('streetViewImage');
            document.getElementById('streetViewContainerShow').replaceChild(img, streetViewImage);
        } else {
            var img = document.createElement("IMG");
            img.src = '../../images/ProfilnoProfilPicture.jpg';
            img.height = 205;
            img.width = 160;
            var oldImg = document.getElementById('streetViewImage');
            document.getElementById('streetViewContainerShow').replaceChild(img, streetViewImage);
        }


回答2:

One quick solution would be to load the image file using xmlrpc and check that its md5sum is 30234b543d5438e0a0614bf07f1ebd25, or that its size is 1717 bytes (it's unlikely that another image can have exactly the same size), but that's not very robust since I have seen Google change the position of the text in the image. Though it's a very good start for a prototype.

You could go for image processing instead. Note that it's still not perfectly robust since Google could decide to change the looks of the image anytime. You'll have to decide whether it's worth it.

Anyway, here is how I would do it using jQuery:

  • load the image and open a 2D context for direct pxiel access (see this question for how to do it)
  • analyse the image:
    • sample groups of 2×2 pixels at random locations; I recommend at least 30 groups
    • a group of 2×2 pixels is good if all the pixels have the same value and their R/G/B values do not differ by more than 10% (ie. they're grey)
    • count the ratio of good pixel groups in the image
  • if there are more than 70% good pixel groups, then we are pretty sure this is the “no imagery” version: replace it with another image of your choice.

The reason I do not recommend testing directly for an RGB value is because JPEG decompression may have slightly different behaviours on different browsers.



回答3:

You can use the getPanoramaByLocation function (see http://code.google.com/apis/maps/documentation/javascript/services.html#StreetViewService).

try something like this:

function handleMapClick()
{
 var ll= new google.maps.LatLng(latitude,longitude);
 sv.getPanoramaByLocation(ll, 50, processSVData);
}

function processSVData(data, status) {
 if (status==google.maps.StreetViewStatus.ZERO_RESULTS)
 {
   <DO SOMETHING>
 }
}


回答4:

As of 2016, you can use the new Street View Image Metadata API.

Now you just need the status field to know if a panorama is found.


Example requests:

https://maps.googleapis.com/maps/api/streetview/metadata?size=600x300&location=78.648401,14.194336&fov=90&heading=235&pitch=10&key=YOUR_API_KEY

{
   "status" : "ZERO_RESULTS"
}


https://maps.googleapis.com/maps/api/streetview/metadata?size=600x300&location=eiffel%20tower,%20paris,%20france&heading=-45&pitch=42&fov=110&key=YOUR_API_KEY

{
   ...
   "status" : "OK"
}


回答5:

Request a google street view image and if it has a specific file size it is a 'Not street view avaible'. I did the follwing:

var url = 'google street view url';

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';

xhr.onload = function (e) {
  if (this.status == 200) {
    try {
      var image = new Blob([this.response], {type: 'image/jpeg'});

      if (image.size) {
        if (url.indexOf('640x640') > -1 && image.size === 8410) {
          // Not street view
        }

        if (url.indexOf('400x300') > -1 && image.size === 3946) {
           // Not street view
        }
      }
    } catch (err) {
      // IE 9 doesn't support blob
    }
  }
};

xhr.send(); 


回答6:

Another way is to load the image and then compare some pixels colors. The "no streetview" image from google is always the same. Here is how you would compare 2 pixels:

var url = STREETVIEWURL
var img = new Image();
// Add some info to prevent cross origin tainting
img.src = url + '?' + new Date().getTime();
img.setAttribute('crossOrigin', '');
img.crossOrigin = "Anonymous";
img.onload = function() {
    var context = document.createElement('CANVAS').getContext('2d');
    context.drawImage(img, 0, 0);
    //load 2 pixels.  I chose the first one and the 5th row
    var data1 = context.getImageData(0, 0, 1, 1).data;
    var data2 = context.getImageData(0, 5, 1, 1).data;
    console.log(data1);
    // google unknown image is this pixel color [228,227,223,255]
    if(data1[0]==228 && data1[1]==227 && data1[2]==223 && data1[3]==255 && 
                     data2[0]==228 && data2[1]==227 && data2[2]==223 && data2[3]==255){
        console.log("NO StreetView Available");
    }else{
         console.log("StreetView is Available");
    }
};

Some potential issues: I've seen some errors with CrossOrigin tainting. Also, if google changes the image returned this code will break.