如何在Android中的StreetView中检查位置是否有效

时间:2013-06-20 16:15:39

标签: android google-maps-api-3

我有一个应用程序,它根据定义的边界在GoogleMaps中随机生成位置。所以我首先生成一个随机LatLng,然后我验证这个点是否在我的边界内。如果是,则有效。

Builder builder = new LatLngBounds.Builder();

        double antartica[] = {-62.5670958528642, -59.92767333984375, -62.584805850293485, -59.98260498046875, -62.61450963659083};
        for (int i = 0; i < antartica.length; i++) {
            builder.include(new LatLng(antartica[i],antartica[++i]));
        }
        pAntarctica = builder.build();

LatLng point = generateRandomPosition();
    if(isWithinBoundaries(point))
        return point;
    else
        return getValidPoint();

所以在此之后,我最终得到了有效点。我的问题是,Google地图中的有效点在StreetView中不一定有效。

可能会发生这个随机点在地球上尚未映射到StreetView中的某个位置。我也需要它在那里有效。

我知道您可以使用此link之后的JavaScript API v3来完成此操作。

你会做这样的事情:

var latLng = new google.maps.LatLng(12.121221, 78.121212);
            streetViewService.getPanoramaByLocation(latLng, STREETVIEW_MAX_DISTANCE, function (streetViewPanoramaData, status) {
                if (status === google.maps.StreetViewStatus.OK) {
                    //ok
                } else {
                    //no ok
                }
            });

但我希望只使用Android来做到这一点。我顺便使用Google Play Services API, Google Maps v2 Android。

任何人都能解释一下吗?

修改 按照ratana的建议,这是我到目前为止所做的:

svpView.getStreetViewPanoramaAsync(new OnStreetViewPanoramaReadyCallback() {
            @Override
            public void onStreetViewPanoramaReady(final StreetViewPanorama panorama) {
                for(final LatLng point : points) {
                    System.out.println(point.latitude + " " + point.longitude);     
                    panorama.setPosition(point, 1000);

                    final CountDownLatch latch = new CountDownLatch(1);

                    mHandlerMaps.post(new Runnable() {
                        @Override
                        public void run() {
                            if (panorama.getLocation() != null) {
                                System.out.println("not null " + panorama.getLocation().position);
                                writeToFile(panorama.getLocation().position.toString());
                                l.add(point);
                            }
                            latch.countDown();
                        }
                    });

                    try {
                        latch.await(4, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(l.toString());
            }
        });

5 个答案:

答案 0 :(得分:7)

@Override
public void onStreetViewPanoramaReady(StreetViewPanorama streetViewPanorama) {
    mPanorama.setOnStreetViewPanoramaChangeListener(new StreetViewPanorama.OnStreetViewPanoramaChangeListener() {
@Override
public void onStreetViewPanoramaChange(StreetViewPanoramaLocation streetViewPanoramaLocation) {
    if (streetViewPanoramaLocation != null && streetViewPanoramaLocation.links != null) {
        // location is present
    } else {
        // location not available
    }
}
 });

编辑:Google的官方答案在这里(https://code.google.com/p/gmaps-api-issues/issues/detail?id=7033),其中指出: https://code.google.com/p/gmaps-api-issues/issues/detail?id=4823

官方解决方案涉及通过HTTPS使用官方Google街景图片API(免费,无限制 - https://developers.google.com/maps/documentation/streetview/metadata)。

旧(弃用)答案:

我已经将这种难以处理的解决方法整合在一起,但仍保留在API中,直到Google更新它以允许以iOS SDK的方式查询全景图。

这涉及创建StreetViewPanoramaView,但不将其附加到布局,并将其位置设置为当前位置。然后测试它后面是否有全景位置。

这似乎有效,但是会在Android Google Maps API V2(这是Google Play服务API的一部分)跟踪器上提交请求,因为iOS SDK具有此功能。

// Handle on the panorama view
private StreetViewPanoramaView svpView;

...

// create a StreetViewPanoramaView in your fragment onCreateView or activity onCreate method
// make sure to handle its lifecycle methods with the fragment or activity's as per the documentation - onResume, onPause, onDestroy, onSaveInstanceState, etc.
StreetViewPanoramaOptions options = new StreetViewPanoramaOptions();
svpView = new StreetViewPanoramaView(getActivity(), options);
svpView.onCreate(savedInstanceState);

...

// Snippet for when the map's location changes, query for street view panorama existence
private Handler mHandler = new Handler();
private static final int QUERY_DELAY_MS = 500;

// When the map's location changes, set the panorama position to the map location
svpView.getStreetViewPanorama().setPosition(mapLocationLatLng);

mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        if (svpView.getStreetViewPanorama().getLocation() != null) {
            // YOUR DESIRED ACTION HERE -- get the panoramaID, etc..
            // getLocation() -- a StreetViewPanoramaLocation -- will be null if there is no panorama
            // We have to delay this a bit because it may take some time before it loads
            // Note that adding an OnStreetViewPanoramaChangeListener doesn't seem to be reliably called after setPosition is called and there is a panorama -- possibly because it's not been added to the layout?
        }
    }
}, QUERY_DELAY_MS);

编辑:使用新的Async API调用:

svpView.getStreetViewPanoramaAsync(new OnStreetViewPanoramaReadyCallback() {
    @Override
    public void onStreetViewPanoramaReady(final StreetViewPanorama panorama) {
        panorama.setPosition(mapLocationLatLng, DEFAULT_SEARCH_RADIUS);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (panorama.getLocation() != null) {
                    // your actions here
                }
            }
        }, QUERY_DELAY_MS);

答案 1 :(得分:6)

我为这个问题写了很多东西。最后我得到了一个有用的链接。看到没有直接的方法在android api中使用getPanoramaByLocation()javascript函数。但是有一个工作要做。

我在这里提供网址:

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

见案例:

  1. 当您通过提供有效的lat / lng来点击此网址时。你会得到街景。因此,您可以使用该图像大小或内容来检查其是空白图像还是有效图像。
  2. 请参阅此网址:

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

    1. 在上面的网址中我通过了无效的lat / lng意味着这个lat / lng没有街景,所以你可以使用&#34;文本提取库&#34;或通过检查文件大小。您将了解街景是否可用
    2. 点击获取街景的网址时,请检查此链接以获取响应:

      https://developers.google.com/maps/documentation/geocoding/?hl=nl

答案 2 :(得分:3)

我创建了一个小型库(基于VVB's answer),可让您(非常可靠地)检查StreetView是否适用于特定位置。

Feel free to check it out.

StreetViewProbe

答案 3 :(得分:0)

对于我的StreetView应用程序,我构建了一个抓取应用程序作为伴侣,这个抓取应用程序遍历给定半径的所有lat / lng位置,并查询StreetView以获取全景图。

这个应用程序的输出是一个lat / lng位置的小文本文件,其分辨率适合我的需要(5度)。然后,我在主应用程序中使用此数据文件作为StreetView位置的源。

使用setPostion(LatLng,radius)方法,我保证每次都能得到一个结果。该文件的大小也非常小&lt; 500KB。

我怀疑谷歌是否会发布StreetView所在的数据集(我在每次更新主播应用程序之前运行我的抓取应用程序,以确保我拥有最新值)。我不确定他们是否提供了具有以下签名的方法:boolean hasStreetView(LatLng,radius)。

答案 4 :(得分:0)

  1. 验证可用的全景视图

    mStreetViewPanoramaView.getStreetViewPanoramaAsync(new OnStreetViewPanoramaReadyCallback() {
        @Override
        public void onStreetViewPanoramaReady(StreetViewPanorama streetViewPanorama) {
            //Using setPositionWithRadius
            streetViewPanorama.setPosition(new LatLng(latitud, longitud), 200);
            mPanorama = streetViewPanorama;
    
            mPanorama.setOnStreetViewPanoramaChangeListener(new StreetViewPanorama.OnStreetViewPanoramaChangeListener() {
                @Override
                public void onStreetViewPanoramaChange(StreetViewPanoramaLocation streetViewPanoramaLocation) {
                    if (streetViewPanoramaLocation == null) {                            
                        Log.e("StreetViewActivity","Panoramic view not available");                            
                    }
                }
            });
        }
    });