2010-11-22 10 views
14

¿Hay alguna manera de determinar si un panorama de Google Streetview está disponible desde una aplicación de Android (es decir, utilizando Java)?Comprobar la existencia de la función Streetview de Google

No parece que existan alternativas para PHP o Python u otras tecnologías del lado del servidor.

El impacto de llamar a Google Streetview donde no existe panorama es simplemente una pantalla negra y una "cosa giratoria".

Respuesta

7

Creé un pequeño truco para esto. :)

strings.xml

<string name="html_streetview"> <![CDATA[ 
<html> 
<head> 
    <script src="http://maps.google.com/maps/api/js?v=3&amp;sensor=false" type="text/javascript"></script> 
</head> 
<body> 
<script type="text/javascript"> 
Android.echo(); 
var testPoint = new google.maps.LatLng(%1$s, %2$s,true); 
var svClient = new google.maps.StreetViewService(); 
svClient.getPanoramaByLocation(testPoint, 50,function (panoramaData, status) { 
    if (status == google.maps.StreetViewStatus.OK) { 
    Android.hasStreetview(); 
    } else { 
    Android.hasNotStreetview(); 
    } 
}); 
</script> 
</body> 
</html> 
]]> 
</string> 

ahora añadir un botón de vista calle de la actividad y poner este siguiente código en el método onclick:

if (webView == null) { 
     webView = new WebView(this); 
     webView.setVisibility(View.INVISIBLE); 
     webView.getSettings().setJavaScriptEnabled(true); 
     webView.addJavascriptInterface(new JavascriptCheck(this), "Android"); 
     webView.setWebViewClient(new WebViewClient() { 
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { 
       Toast.makeText(this, "Streetview loading", Toast.LENGTH_SHORT).show(); 
       super.onReceivedError(view, errorCode, description, failingUrl); 
       } 
     }); 
    } 

    Toast.makeText(this, "Streetview loading", Toast.LENGTH_SHORT).show(); 

    webView.loadDataWithBaseURL(baseurl, 
     getString(R.string.html_streetview, latitude, longitude), "text/html", "UTF-8", baseurl); 

Y ahora la clase interna de la actividad :

public class JavascriptCheck { 
    private final Context context; 

    public JavascriptCheck(Context context) { 
     this.context = context; 
    } 

    public void echo() { 
     Log.d("JavascriptChecker", "javascript called"); 
    } 

    public void hasStreetview() { 
     pushStreetviewState(true); 
    } 

    public void hasNotStreetview() { 
     pushStreetviewState(false); 
    } 

    private void pushStreetviewState(final boolean hasStreetview) { 
     Log.d("JavascriptChecker", hasStreetview); 
     // TODO do your stuff needed here 
    } 
} 

esto es una solución bastante mala, pero probablemente puede ayudar. :)

+0

Brilliant! - ¡Intentaré esto tonite! – alshapton

+0

con honeycomb debes hacer algunos cambios en el javascript y también en el javascript checker. – alosdev

+0

¿Qué es básico que esté aquí? webView.loadDataWithBaseURL (baseurl, getString (R.string.html_streetview, latitud, longitud), "text/html", "UTF-8", baseurl); – Nick

1

Sólo para más adelante la excelente respuesta de los alos, aquí es un script que le devuelva el ángulo necesario para que Streetview lanzará señalado en las coordenadas correctas:

<string name="html_streetview_bearing"> <![CDATA[ 
<html> 
<head> 
<script src="http://maps.google.com/maps/api/js?v=3&amp;sensor=false" type="text/javascript"></script> 
</head> 
<body> 
<script type=\"text/javascript\"> 
    var testPoint = new google.maps.LatLng(%1$s, %2$s,true); 
    var svClient = new google.maps.StreetViewService(); 


    svClient.getPanoramaByLocation(testPoint,100,function (camera, status) { 

    if(camera!=null) { 

    var location = camera.location; 
    var latLng = location.latLng; 
    lat2 = latLng.lat(); 
    lon2 = latLng.lng(); 
    lat1 = testPoint.lat(); 
    lon1 = testPoint.lng(); 

    var dLon = lon1 - lon2; 
    var y = Math.sin(dLon) * Math.cos(lat2); 
    var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); 
    var bearing = Math.atan2(y, x) * (180/Math.PI); 
    Android.setStreetviewAngle(bearing); 

    } 


    } 
); 
</script> 
</body> 
</html> 
]]> 
</string> 

Nota: El valor de retorno necesita ser alterado para que

bearing = (bearing + 180) % 360; 

para darle el valor final correcto. Lo hago en código nativo.

RESPUESTA ACTUALIZADA: Ahora funciona en Android 3.0 y superior.

1

Gracias un montón Alos y steemcb, me quedé atrapado con la vista de la calle que muestra la propiedad incorrecta o una pantalla en blanco. Espero que Google salga con un SDK nativo de Android, ¡hasta entonces ambos códigos ROX!

Tuve que hacer algunos ajustes antes de poder usar el código. Aquí está mi implementación.

strings.xml

<string formatted="false" name="html_streetview"> 
&lt;html> 
    &lt;head> 
    &lt;script src=\"http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;sensor=false\" type=\"text/javascript\"/> 
    &lt;/head> 
    &lt;body> 
    &lt;script type=\"text/javascript\"> 
     var testPoint = new GLatLng(%1$s, %2$s); 
     var svClient = new GStreetviewClient(); 

     svClient.getNearestPanoramaLatLng(testPoint,function(camera){ 
      if (camera !== null){ 
       lat2 = camera.lat(); 
       lon2 = camera.lng(); 
       lat1 = testPoint.lat(); 
       lon1 = testPoint.lng(); 

       dLon = lon1 - lon2; 
       y = Math.sin(dLon) * Math.cos(lat2); 
       x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); 
       var bearing = Math.atan2(y, x) * (180/Math.PI); 
       //had to get rid of this line it was causing formatting exceptions 
       // I moved this logic to the inner class 
       //bearing = (bearing + 180) % 360; 
       Android.setStreetViewAngle(bearing);    
      } 
      //had trouble with bearing taking long to calculate and end up with 0.0 value in the uri. So I put it in here after when bearing is calculated. Not pretty.. but it works for me 
      svClient.getNearestPanoramaLatLng(testPoint, function (nearest) { 
      if ((nearest !== null) &amp;&amp; (testPoint.distanceFrom(nearest) &lt;= 100)) { 
       Android.hasStreetview(true); 
      } 
      else { 
       Android.hasStreetview(false); 
      }   
      }); 
     });  

&lt;/script> 
    &lt;/body> 
&lt;/html> 
</string>  

clase interna privada

private final Context context; 
     private double bearing; 


     public JavascriptCheck(Context context) { 
      this.context = context; 

     } 

     public void hasStreetview(boolean hasStreetview) { 
      if (hasStreetview) {    
      String uri = "google.streetview:cbll=" + propDetailInfo.getLatitude() + "," + propDetailInfo.getLongitude() + 
       "&cbp=1,"+ bearing + ",,1,1.0&mz=14"; 

      Utils.printDebug("URI: " + uri); 
      Intent streetView = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); 
      startActivity(streetView); 
      } else { 
      Toast.makeText(context, "Sorry Streetview not available for this address", Toast.LENGTH_LONG).show(); 
      } 
     } 
     public void setStreetViewAngle(double bearing){ 
      bearing = (bearing + 180) % 360; 
      this.bearing = bearing; 
     } 

     public void toast(String part) { 
      Toast.makeText(context, part, Toast.LENGTH_SHORT).show(); 
     } 

     } 
+0

Ya no funciona en ICS. – naqi

0

Una manera de hacerlo sería utilizar Google Street View API de imagen para comprobar si Google Street View existe o no.

https://developers.google.com/maps/documentation/streetview/

devuelve una imagen con un tamaño de archivo diferente cuando Street View en un determinado coordina existe, que cuando no lo hace

http://maps.googleapis.com/maps/api/streetview?size=400x400&location=40.720032,%20-73.988354&fov=90&heading=235&pitch=10&sensor=false 

Puede comparar estas imágenes y comprobar si existe o no

Cuestiones relacionadas