Как проверить, если позиция действительна в StreetView в Android

У меня есть приложение, которое случайным образом генерирует позиции в 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. Мне нужно, чтобы и там оно было действительным.

Мне известно, что вы можете сделать это с помощью JavaScript API v3, перейдя по этой ссылке: https://developers.google.com/maps/documentation/javascript/reference

Вы бы сделали что-то вроде этого:

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. Кстати, я использую API служб Google Play, а не Google Maps v2 Android.

Кто-нибудь может пролить свет?

РЕДАКТИРОВАТЬ: Следуя совету Ратаны, это то, что я до сих пор:

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());
            }
        });

4 ответа

Решение
@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-апи-вопросы / вопросы / детали? ID = 4823

Официальное решение предполагает использование официального API-интерфейса Google Street View Image (бесплатно, без ограничений - https://developers.google.com/maps/documentation/streetview/metadata) через HTTPS.

СТАРЫЙ (УСТАРЕВШИЙ) ОТВЕТ:

Я взломал обходной путь для этого, который уродлив, но остается в API, пока Google не обновит его, чтобы позволить запрашивать панорамы, как это делает iOS SDK.

Это включает в себя созданиеStreetViewPanoramaView, но не прикрепляя его к макету, а устанавливая его положение в текущем местоположении. И затем тестирование, если у этого есть местоположение панорамы после этого.

Это, кажется, работает, но будет добавлять запрос на трекер Android Google Maps API V2 (который является частью API сервисов Google Play), чтобы добавить это, поскольку 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);

РЕДАКТИРОВАТЬ: использовать новый вызов API Async:

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);

Я много гуглю по этому вопросу. Наконец-то я получил одну полезную ссылку. Смотрите, нет прямого способа использовать функцию JavaScript getPanoramaByLocation() в Android API. Но есть обходной путь к этому.

Здесь я предоставляю URL:

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

Смотрите случаи:

  1. Когда вы нажмете этот URL, указав действительный лат / лнг. Вы получите вид с улицы. Таким образом, вы можете использовать размер или содержание этого изображения для проверки, является ли оно пустым изображением или действительным изображением.

Смотрите этот URL:

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

  1. В вышеупомянутом URL я передал недопустимый lat / lng, что означает, что для этого lat / lng нет просмотра улиц, поэтому вы можете использовать "библиотеку извлечения текста" или проверить размер файла. Вы узнаете, доступен ли просмотр улиц на данный момент

Проверьте эту ссылку для ответа, когда вы нажимаете URL для получения просмотра улиц:

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

Я создал небольшую библиотеку (на основе ответа VVB), которая позволяет (довольно надежно) проверить, доступен ли StreetView для определенного местоположения.

Не стесняйтесь проверить это.

StreetViewProbe

  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");                            
                    }
                }
            });
        }
    });
    

Для моего приложения StreetView я создал вспомогательное приложение в качестве компаньона, которое просматривает все местоположения широты и ширины на заданном радиусе и запрашивает у StreetView панораму.

Результатом этого приложения является небольшой текстовый файл с координатами широта / долгота в разрешении, подходящем для моих нужд (5 градусов). Затем я использую этот файл данных в своем главном приложении в качестве источника местоположений StreetView.

Используя метод setPostion(LatLng, radius), я гарантированно получаю результат каждый раз. Размер этого файла также довольно мал < 500 КБ.

Я сомневаюсь, что Google когда-либо выпустит набор данных о том, где находился StreetView (я запускаю свое приложение для очистки непосредственно перед каждым обновлением основного приложения, чтобы убедиться, что у меня есть актуальные значения). Я не уверен, что они предоставят метод, который имеет следующую подпись, либо boolean hasStreetView(LatLng, radius).

Другие вопросы по тегам