Как изобразить направление в маршруте в гугл картах? - PullRequest
0 голосов
/ 03 апреля 2019

В проекте я отображаю маршрут, используя PolylineOptions для рисования ректов от одного POI до следующего POI.

Также в каждом POI я рисую круг.

Цель состоит в том, чтобы каким-то образом представить направление маршрута, например, нарисовав стрелку в середине каждого PolylineOptions прямоугольника. Проблема в том, что я не могу найти, как это сделать.

Это мой код:

    PolylineOptions rectOptions = new PolylineOptions();
    float[] prevHSV = new float[3];
    Color.colorToHSV(getResources().getColor(R.color.colorPrimary), prevHSV);
    rectOptions.color(Color.HSVToColor(255, prevHSV));

    String[][] routeInformation = ((MyApplication)getApplication()).getLineInformation(line);
    ArrayList<Double[]> routeStops = Util.getFullRouteFromLine(this, line);
    final LatLngBounds.Builder builder = new LatLngBounds.Builder();

    for (int i=0; i<routeInformation.length; i++){
        LatLng latlng = new LatLng(Double.parseDouble(routeInformation[i][0]),Double.parseDouble(routeInformation[i][1]));
        builder.include(latlng);
        mMap.addCircle(new CircleOptions().center(latlng).radius(15).strokeColor(Color.HSVToColor(255, prevHSV)).fillColor(Color.HSVToColor(255, prevHSV)).zIndex(7777));            
    }

    for (Double[] pos : routeStops){
        rectOptions.add(new LatLng(pos[0],pos[1])).width(5);
    }
    mMap.addPolyline(rectOptions);

Есть ли простой способ указать направление маршрута?

Что-то похожее на это, но это для веб-версии карт Google, а не для версии для Android: http://jsfiddle.net/nX8U8/2/

1 Ответ

1 голос
/ 04 апреля 2019

ИМХО самый простой способ - использовать плоский «ориентированный на север» маркер направления (стрелка), например:

Direction marker

, созданный с помощью векторного рисования ic_arrow_up.xml:

<vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportHeight="560"
    android:viewportWidth="560"
    android:height="24dp"
    android:width="24dp"
    >
    <path android:fillColor="#0000FF"
        android:pathData="M0,559.43C0,557.943 279.994,-0.561 280.458,0C282.014,1.884 560.512,559.569 559.999,559.776C559.665,559.911 496.562,532.823 419.77,499.581C419.77,499.581 280.15,439.14 280.15,439.14C280.15,439.14 140.756,499.57 140.756,499.57C64.089,532.807 1.056,560 0.681,560C0.307,560 0,559.743 0,559.43C0,559.43 0,559.43 0,559.43Z"
    />
</vector>

помещается на среднюю точку каждого отрезка полилинии с углом, рассчитанным на опоре сегмента.Как средний сегмент, так и направление сегмента полилинии можно определить с помощью SphericalUtil класса Утилита Google Maps Android API Utility Library .Направление можно найти через SphericalUtil.computeHeading() с первой и второй точками сегмента в качестве аргументов и LatLng средней точки сегмента - через SphericalUtil.interpolate() также с первой и второй точками сегментав качестве аргументов from и to и константы 0,5 (половина) в качестве fraction аргумента.

Итак, с таким источником:

...
@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;
    mGoogleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
        @Override
        public void onMapLoaded() {
            List<LatLng> sourcePoints = new ArrayList<>();
            PolylineOptions polyLineOptions;

            sourcePoints.add(new LatLng(-35.27801,149.12958));
            sourcePoints.add(new LatLng(-35.28032,149.12907));
            sourcePoints.add(new LatLng(-35.28099,149.12929));
            sourcePoints.add(new LatLng(-35.28144,149.12984));
            sourcePoints.add(new LatLng(-35.28194,149.13003));
            sourcePoints.add(new LatLng(-35.28282,149.12956));
            sourcePoints.add(new LatLng(-35.28302,149.12881));
            sourcePoints.add(new LatLng(-35.28473,149.12836));

            polyLineOptions = new PolylineOptions();
            polyLineOptions.addAll(sourcePoints);
            polyLineOptions.width(10);
            polyLineOptions.color(Color.BLUE);
            mGoogleMap.addPolyline(polyLineOptions);
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sourcePoints.get(0), 15));

            for (int i = 0; i < sourcePoints.size() - 1; i++) {
                // get first and second points of polyline segment
                LatLng segmentP1 = sourcePoints.get(i);
                LatLng segmentP2 = sourcePoints.get(i+1);

                // calculate middle point
                LatLng segmentMiddlePoint = SphericalUtil.interpolate(segmentP1, segmentP2, 0.5);
                // calculate bearing
                float segmentBearing = (float) SphericalUtil.computeHeading(segmentP1, segmentP2);

                // add flat marker at segment middle
                addDirectionMarker(segmentMiddlePoint, segmentBearing);
            }

    });

}
...
public void addDirectionMarker(LatLng latLng, float angle) {
    Drawable circleDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_arrow_up);
    BitmapDescriptor markerIcon = getMarkerIconFromDrawable(circleDrawable, 30, 30);

    mGoogleMap.addMarker(new MarkerOptions()
            .position(latLng)
            .anchor(0.5f, 0.5f)
            .rotation(angle)
            .flat(true)
            .icon(markerIcon)
    );
}

вы получите что-то подобное:

Path with direction markers

Также вы можете изменить размер маркеров стрелок, установив другие значения, отличные от 30, 30 в

BitmapDescriptor markerIcon = getMarkerIconFromDrawable(circleDrawable, 30, 30);

строка.

...