Карты Google: Как нарисовать стрелки в середине каждого прямоугольника PolylineOptions? - PullRequest
0 голосов
/ 06 декабря 2018

Я отображаю маршрут, используя 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);

1 Ответ

0 голосов
/ 07 декабря 2018

Самый простой способ - использовать маркер с ориентацией на север (это важно из-за угла поворота маркера, начинающегося с севера). Стрелка (например, marker) - поместите ее в середину текущего сегмента полилинии, поверните это в соответствии с направлением и установить его свойство anchor() свойство на (0.5,0.5) и flat на true.Примерно так:

 ...
 // place first point of route (direction can't be calculated for it)
 LatLng prevLatLng = new LatLng(Double.parseDouble(routeInformation[0][0]),Double.parseDouble(routeInformation[0][1]));
 builder.include(prevLatLng);
 mMap.addCircle(new CircleOptions().center(prevLatLng).radius(15).strokeColor(Color.HSVToColor(255, prevHSV)).fillColor(Color.HSVToColor(255, prevHSV)).zIndex(7777));       

 // place other points
 for (int i=1; 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));

    // determine middle of segment
    LatLng middleLatLng = getMiddlePoint(prevLatLng, latlng);

    // determine direction
    float direction = bearingBetweenLocations(prevLatLng, latlng);

    // add marker with arrow      
    mMap.addMarker(new MarkerOptions()
    .position(middleLatLng)
    .anchor(0.5,0.5)
    .rotation(direction)
    .flat(true));       

    // move previous position to current
    prevLatLng = latlng;
}
...

В средней точке сегмента полилинии можно найти центр границ вшей:

private LatLng getMiddlePoint(LatLng latlng1, LatLng latlng2) {
    LatLngBounds.Builder builder = new LatLngBounds.Builder();
    builder.include(latlng1);
    builder.include(latlng2);  
    LatLngBounds bounds = builder.build();
    return bounds.getCenter();
}

или SphericalUtil.interpolate(LatLng from, LatLng to, double fraction) из Библиотека утилит Google Maps Android API :

LatLng middleLatLng = SphericalUtil.interpolate(prevLatLng, latlng, 0.5);

И направление можно определить в двух соседних точках маршрута, как в этом ответе satti8893 :

private double bearingBetweenLocations(LatLng latLng1,LatLng latLng2) {

    double PI = 3.14159;
    double lat1 = latLng1.latitude * PI / 180;
    double long1 = latLng1.longitude * PI / 180;
    double lat2 = latLng2.latitude * PI / 180;
    double long2 = latLng2.longitude * PI / 180;

    double dLon = (long2 - long1);

    double y = Math.sin(dLon) * Math.cos(lat2);
    double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
            * Math.cos(lat2) * Math.cos(dLon);

    double brng = Math.atan2(y, x);

    brng = Math.toDegrees(brng);
    brng = (brng + 360) % 360;

    return brng;
}

Внимание!Это не полный код, а просто идея.

Также взгляните на этот вопрос Scorpion .

Другой способ - создать MapView-на основе пользовательского вида и нарисуйте весь путь с помощью линий, окружностей и стрелок вручную в переопределенном dispatchDraw().

...