Анимировать камеру, чтобы позиционировать и установить панорамирование в Google Maps - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь добиться аналогичного тому, как работает навигация в Google Maps, проверьте изображение ниже для справки. На картах Google маркер выглядит в статическом положении, за исключением изменения камеры


.

enter image description here

Чтобы добиться этого, я анимирую маркер каждый раз, когда меняется мое местоположение, и позже я размещаю его в нижней части экрана, перемещая его на -300px по координате Y.

Но я не могу анимировать камеру для изменения местоположения, одновременно перемещая экран на 300 пикселей вниз.

Когда я анимирую камеру для изменения местоположения, маркер перемещается точно в центр экрана, и позже, когда я перемещаю камеру на 300 пикселей ниже, происходит другая анимация, которая выглядит очень раздражающей.

Есть ли способ, которым я могу добиться того, что делают карты Google? Любая ссылка или помощь приветствуется.

1 Ответ

0 голосов
/ 11 сентября 2018

Код полностью реализован в onLocationChanged, но как документировано, некоторые из них могут быть извлечены во время инициализации.

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

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

Вот краткое изложение концепции:

enter image description here

И код (с записью экрана ниже):

@Override
public void onLocationChanged(Location location) {

    // First point processing
    if (lastLocation == null) {

        // save last location
        lastLocation = location;

        // initial camera
        CameraPosition.Builder b = CameraPosition.builder().
                zoom(15.0F).
                target(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()));
        CameraUpdate cu = CameraUpdateFactory.newCameraPosition(b.build());
        mMap.animateCamera(cu);
        return;
    }

    // subsequent updates

    LatLng oldPos = new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude());
    LatLng newPos = new LatLng(location.getLatitude(), location.getLongitude());

    // ignore very small position deviations (prevents wild swinging)
    double d = SphericalUtil.computeDistanceBetween(oldPos, newPos);
    if (d < 10) {
        return;
    }


    // compute our own bearing (do not use location bearing)
    double bearing = SphericalUtil.computeHeading(oldPos, newPos);

    //-----------------------------------------------
    // Next section really only needs to be done once

    // Compute distance of pixels on screen using some desirable "offset"

    Projection p = mMap.getProjection();
    Point  bottomRightPoint = p.toScreenLocation(p.getVisibleRegion().nearRight);
    Point center = new Point(bottomRightPoint.x/2,bottomRightPoint.y/2);
    Point offset = new Point(center.x, (center.y + 300));

    LatLng centerLoc = p.fromScreenLocation(center);
    LatLng offsetNewLoc = p.fromScreenLocation(offset);

    // this computed value only changes on zoom
    double offsetDistance = SphericalUtil.computeDistanceBetween(centerLoc, offsetNewLoc);
    //-----------------------------------------------


    // Compute shadow target position from current position (see diagram)
    LatLng shadowTgt = SphericalUtil.computeOffset(newPos,offsetDistance,bearing);

    // update circles
    if (centerCircle != null) {
        centerCircle.setCenter(shadowTgt);
    } else {
        centerCircle = mMap.addCircle(new CircleOptions().strokeColor(Color.BLUE).center(shadowTgt).radius(50));
    }
    if (carCircle != null) {
        carCircle.setCenter(newPos);
    } else {
        carCircle = mMap.addCircle(new CircleOptions().strokeColor(Color.GREEN).center(newPos).radius(50));
    }


    // update camera

    CameraPosition.Builder b = CameraPosition.builder();
    b.zoom(15.0F);
    b.bearing((float)(bearing));
    b.target(shadowTgt);
    CameraUpdate cu = CameraUpdateFactory.newCameraPosition(b.build());
    mMap.animateCamera(cu);

    // save location as last for next update
    lastLocation = location;
}

Примечания:

  • При изменении масштаба необходимо offsetDistance пересчитать. (Но, как уже отмечалось, это не обязательно делать при каждом изменении места.)
  • На концептуальной диаграмме подшипник обозначен как 0-360, но на самом деле -180-180.
  • Как видите, большая часть работы выполняется в классе SphericalUtil.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...