腾讯地图SDK Android版开发 11 覆盖物示例 4 线

前言

文本通过创建多个不同线宽的折线,介绍Polyline的使用方法。

线的属性包括是否可点击、透明度、描边属性、是否虚线、填充属性和擦除颜色。

  • 填充属性包括分段颜色内置纹理颜色纹理箭头纹理渐变色。只能选一或不选。

为了直观显示线的属性,仅使用了CheckBox控件,多种属性只能选一通过代码实现。

说明:官方指南中还介绍了线的更多用法,如动态路名、折线动画、线的动态更新

线的属性介绍

线是由一组经纬度点按照一定的顺序连接而成,在地图上绘制线由 Polyline 类定义实现。通常用来表示一段路、轨迹等线型场景。

添加折线的同时可以设置线的颜色、宽度等属性。

ColorType 和 LineType

ColorType

  • 枚举 PolylineOptions.ColorType 定义了通过纹理和颜色两种填充线的方式。
枚举常量说明
LINE_COLOR_NONE未设置颜色类型 (默认值)
LINE_COLOR_TEXTURE纹理图片里的颜色索引
LINE_COLOR_ARGB纯色线 32bit ARGB颜色

LineType

  • 类PolylineOptions.LineType 定义了线的绘制类型。
常量说明
LINE_TYPE_MULTICOLORLINE彩虹蚯蚓**(默认值)**0
LINE_TYPE_IMAGEINARYLINE虚线1
LINE_TYPE_DOTTEDLINE2

与颜色有关的属性

填充色和线宽

  • color(int i) 设置线的颜色
  • width(float width) 设置线宽度

描边颜色和描边的宽度

  • borderColor 设置ARGB线的描边颜色。

  • borderWidth 设置ARGB线描边的宽度。

    • 设置描边颜色的宽度后,填充的部分宽度为 width - 2 * borderWidth
  • borderColors 设置描边分段颜色。

    • 颜色数量应该与 colors(int[]colors, int[]indexes)接口中的colors的长度保持一致。

分段颜色

// 设置分段线的顶点索引,这个索引值的数量必须和下面的颜色列表数量相同
int[] indexes = {0,1,2,3,4};
// 设置每段索引之间的颜色,这个颜色同样支持纹理颜色,即 PolylineOptions.Colors 中定义的 [0, 10] 值
int[] colors = {0xff00ff00, // 线上点 [0, 1] 之间为绿色
                0xffffff00, // 线上点 [1, 2] 之间为黄色
                0xffff0000, // 线上点 [2, 3] 之间为红色
                0xffffff00, // 线上点 [3, 4] 之间为黄色
                0xff00ff00  // 线上点 [4, 最后一个点] 之间为绿色
};
polylineOptions.width(15f);
//设置彩虹线的颜色
polylineOptions.colors(colors, indexes);

渐变色

注意:设置渐变开关 只有线类型是PolylineOptions.LineType.LINE_TYPE_MULTICOLORLINE 且 PolylineOptions.isRoad() 为 true才生效

(备注:isRoad默认为true)

// 设置线的类型
polylineOptions.lineType(PolylineOptions.LineType.LINE_TYPE_MULTICOLORLINE);
// 渐变色折线
polylineOptions.gradient(true);
polylineOptions.colors(colors, indexes);

擦除颜色

支持线从 Polyline 中索引为 0 的坐标点开始擦除到用户指定的坐标点。以上面的线为例,从第一段中擦除一部分:

Polyline polyline = tencentMap.addPolyline(polylineOptions);
// 必须设置 `true`,默认为 `false`
polyline.setEraseable(true);
// 其中第一个参数表示要擦除到的坐标索引 `index`
// 第二个参数表示从 [`index -1`, `index`] 之间的坐标
// 如果这个坐标不在擦除的索引范围内,会一直擦除到 `index`
polyline.eraseTo(1, new LatLng(39.983919,116.305722));

与纹理相关属性

通常用用 ARGB 颜色值直接设置线的颜色,这能满足大部分场景,但对于希望有阴影效果的线就无法满足了。

地图 SDK 支持用纹理填充线来实现阴影等效果,这个纹理可以理解为线的截面纹理,地图把这个截面的纹理沿线绘制的方向填充到整条线。

内置纹理

地图 SDK 内置一份纹理填充颜色,用户只需要通过 PolylineOptions.color(int i) 接口设置 PolylineOptions.Colors 中定义的 [0, 10] 号对应的颜色就能展示对应的效果。

  • 示例
// 纹理颜色
polylineOptions.color(PolylineOptions.Colors.GRAYBLUE)
  • PolylineOptions.Colors 类
常量说明
GREY灰色0
LIGHT_BLUE淡蓝1
RED红色2
YELLOW黄色3
GREEN绿色4
MID_BLUE中蓝5
DARK_BLUE深蓝6
TRANSPARENT透明色7
GRAYBLUE灰蓝8
LIVER_RED猪肝红9
DASHED虚线(绘制步行时使用到)33
WHITE_BLUE19
LAST_BLUE最后一条蓝色的线20

自定义颜色纹理

  • 使用自定义纹理填充。
// 设置自定义纹理,纹理在工程的 assets 目录
polylineOptions.colorTexture(BitmapDescriptorFactory.fromAsset("color_texture.png"))
// 使用纹理图片的第三行像素填充线的每个像素截面
polylineOptions.color(2);

线上叠加纹理

  • 示例:线上绘制箭头
// 折线的颜色为绿色
polylineOptions.color(0xff00ff00);
// 折线宽度为25像素
polylineOptions.width(25);
// 必须打开这个开关,允许在线上绘制纹理
polylineOptions.arrow(true);
// 支持设置纹理的间距
polylineOptions.arrowSpacing(30);
// 设置纹理图片
polylineOptions.arrowTexture(BitmapDescriptorFactory.fromAsset("color_arrow_texture.png"));
  • PolylineOptions 类
类型方法说明
PolylineOptionsarrow(boolean flag)导航用接口,开发都不要用
PolylineOptionsarrowSpacing(int arrowSpacing)设置方向箭头的间距,单位(px),默认是100px
PolylineOptionsarrowTexture(BitmapDescriptor arrowTexture)设置方向箭头的自定义纹理

虚线

  • pattern(List< Integer > pattern)设置ARGB虚线的样式
  • 虚线属性pattern的元素数量必须是偶数个,每对元素分别表示虚线中实线区域的长度,以及空白区域的长度(单位px)。
// 设置虚线模式
List<Integer> pattern = new ArrayList<>();
pattern.add(35);
pattern.add(20);
polylineOptions.pattern(list);

界面布局

在这里插入图片描述

  • 布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapPolylineActivity">

    <com.tencent.tencentmap.mapsdk.maps.TextureMapView
        android:id="@+id/mapview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/bottomView"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.LinearLayoutCompat
        android:id="@+id/bottomView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/mapview">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/background_dark"
            android:gravity="center_horizontal"
            android:orientation="horizontal">

            <CheckBox
                android:id="@+id/clickable"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:checked="true"
                android:onClick="setMarkerFlag"
                android:text="点击"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/alpha"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setMarkerFlag"
                android:text="透明"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/colors"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.3"
                android:onClick="setMarkerFlag"
                android:text="分段颜色"
                android:textColor="@color/yellow_800"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/defaultTexture"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.3"
                android:onClick="setMarkerFlag"
                android:text="内置纹理"
                android:textColor="@color/yellow_800"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/colorTextures"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.3"
                android:onClick="setMarkerFlag"
                android:text="颜色纹理"
                android:textColor="@color/yellow_800"
                android:textStyle="bold" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center"
            android:background="@android:color/background_dark"
            android:orientation="horizontal">

            <CheckBox
                android:id="@+id/border"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setMarkerFlag"
                android:text="描边"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/dottedLine"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setMarkerFlag"
                android:text="虚线"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/arrowTexture"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.3"
                android:onClick="setMarkerFlag"
                android:text="箭头纹理"
                android:textColor="@color/yellow_800"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/gradient"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.3"
                android:onClick="setMarkerFlag"
                android:text="渐变色"
                android:textColor="@color/yellow_800"
                android:textStyle="bold" />

            <CheckBox
                android:id="@+id/eraseColor"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.3"
                android:onClick="setMarkerFlag"
                android:text="擦除颜色"
                android:textColor="@color/white"
                android:textStyle="bold" />

        </LinearLayout>
    </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

MapPolyline类

以下为MapPolyline类部分代码。

常量

public static final String CLICKABLE = "clickable"; // 点击
public static final String ALPHA = "alpha"; // 透明
public static final String BORDER = "border"; // 描边
public static final String DOTTED_LINE = "DottedLine"; // 虚线
public static final String COLORS = "Colors"; // 分段颜色
public static final String DEFAULT_TEXTURES = "DefaultTextures"; // 内置纹理
public static final String COLOR_TEXTURES = "ColorTextures"; // 分段纹理
public static final String ARROW_TEXTURES = "ArrowTextures"; // 箭头纹理
public static final String GRADIENT = "Gradient"; // 渐变色
public static final String ERASE_COLOR = "EraseColor"; // 擦除颜色
  • 渐变色
final static int COLOR_RED = 0xAAD50000;
final static int COLOR_YELLOW = 0xAAF57F17;
final static int COLOR_BLUE = 0xAA0D47A1;
final static int COLOR_GREEN = 0xAA33691E;
final static int COLOR_GRAY = 0xAA999999;
  • 折线线宽:多个折线的宽度依次为5,10, 15, ……
final static int LINE_WIDTH_MIN = 5;
final static int LINE_WIDTH_STEP = 5;
  • 描边宽度和颜色
final static int LINE_BORDER_WIDTH = 2;
final static int LINE_BORDER_COLOR = 0xFFFFFF00; // 描边颜色 黄色
  • 擦除颜色
final static int LINE_ERASE_COLOR = COLOR_GRAY; // 擦除颜色

成员变量

// 覆盖物列表
List<Removable> overlays = new ArrayList<>();
// 选中的状态
List<String> selectedFlags = new ArrayList<>();

List<List<LatLng>> lines = new ArrayList<>(); // 多个折线
BitmapDescriptor colorBitmap;
BitmapDescriptor arrowBitmap;
int[] colorValues; // 渐变色
int[] borderValues; // 描边渐变色

初始值

  • 默认选中选项
selectedFlags.add(CLICKABLE);
  • 多个折线
double latSpan = 0.05;
for (int i = 0; i < 5; ++i) {
    List<LatLng> points = new ArrayList<>();
    points.add(new LatLng(39.865 + latSpan * i, 116.254));
    points.add(new LatLng(39.865 + latSpan * i, 116.304));
    points.add(new LatLng(39.825 + latSpan * i, 116.354));
    points.add(new LatLng(39.855 + latSpan * i, 116.394));
    points.add(new LatLng(39.805 + latSpan * i, 116.454));
    points.add(new LatLng(39.865 + latSpan * i, 116.504));
    points.add(new LatLng(39.805 + latSpan * i, 116.544));
    lines.add(points);
}
  • 纹理和颜色(纹理图来自官方Demo)
colorBitmap = BitmapDescriptorFactory.fromAsset("color_texture.png");
arrowBitmap = BitmapDescriptorFactory.fromAsset("color_arrow_texture.png");

colorValues = new int[]{COLOR_RED, COLOR_YELLOW, COLOR_BLUE, COLOR_GREEN};
borderValues = new int[]{COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_RED};
  • 点击事件
initEvent();
private void initEvent() {
    map.setOnPolylineClickListener(new TencentMap.OnPolylineClickListener() {
        @Override
        public void onPolylineClick(Polyline polyline, LatLng point) {
            showToast("click polyline");
        }
    });
}

创建覆盖物

  • 创建大地曲线或创建多个折线
public void addOverlays() {
    // 创建多个折线
    int width = LINE_WIDTH_MIN;
    for (List<LatLng> points : lines) {
        PolylineOptions polylineOptions = new PolylineOptions()
                // 设置线宽度
                .width(width)
                // 设置线的颜色
                .color(COLOR_RED)
                // 设置路线是否显示半圆端点
                .lineCap(true)
                .addAll(points);

        setOption(polylineOptions, selectedFlags);

        // 在地图上绘制折线
        Polyline polyline = map.addPolyline(polylineOptions);
        if (selectedFlags.contains(ERASE_COLOR)) {
            // 必须设置 `false`,默认为 `true`
            // polyline.setEraseable(false);
            // 其中第一个参数表示要擦除到的坐标索引 index
            // 第二个参数表示从 [index -1, index] 之间的坐标
            // 如果这个坐标不在擦除的索引范围内,会一直擦除到 index
            final int index = 2;
            polyline.eraseTo(index, points.get(index - 1));
        }
        overlays.add(polyline);

        width += LINE_WIDTH_STEP;
    }
}
  • 设置折线属性
private void setOption(PolylineOptions option, List<String> flags) {
    if (flags.contains(CLICKABLE))
        option.clickable(true);
    else
        option.clickable(false);

    if (flags.contains(ALPHA)) {
        final float alpha = 0.5f;
        // 设置透明度
        option.alpha(alpha);
    }

    if (flags.contains(BORDER)) {
        if (flags.contains(COLORS) || flags.contains(GRADIENT)) {
            // 分段描边
            option.borderColors(borderValues);
        } else {
            // 设置线ARGB的描边颜色
            // 当线是纯色线的时候,设置border的颜色可用此接口
            option.borderColor(LINE_BORDER_COLOR);
        }
        // 设置ARGB线 描边的宽度
        // 描边颜色的宽度,不过填充的部分宽度为 width - 2 * borderWidth
        option.borderWidth(LINE_BORDER_WIDTH);
    }

    if (flags.contains(DOTTED_LINE)) {
        // 设置虚线模式
        List<Integer> pattern = new ArrayList<>();
        pattern.add(35);
        pattern.add(20);
        option.pattern(pattern);
        // 设置路线是否显示半圆端点
        option.lineCap(true);
    }

    if (flags.contains(COLORS)) {
        int[] indexes = new int[colorValues.length];
        for (int i = 0; i < indexes.length; ++i)
            indexes[i] = i;

        option.lineType(PolylineOptions.LineType.LINE_TYPE_MULTICOLORLINE);
        option.colors(colorValues, indexes);
    }

    if (flags.contains(DEFAULT_TEXTURES)) {
        option.color(PolylineOptions.Colors.GRAYBLUE);
    }

    if (flags.contains(COLOR_TEXTURES)) {
        // 设置图片作为线的填充纹理
        // 注意:
        // 1、当调用此接口,且LineType不为 LINE_TYPE_DOTTEDLINE 时,
        //  color和colors接口指定的值代表用此接口设置纹理的第几像素行,以绘制纹理线。
        // 2、当调用此接口,且LineType设置为 LINE_TYPE_DOTTEDLINE 时,
        //  绘制线时会连续绘制此接口设置的纹理。
        option.colorTexture(colorBitmap);

        // 设置线的颜色
        // final int color = 1;
        // option.color(color);
        // 设置线的分段颜色 红,黄,蓝,绿,浅蓝
        final int[] colors = new int[]{2, 3, 1, 4, 8};
        final int[] indexes = new int[]{0, 1, 2, 4, 5};
        option.colors(colors, indexes);
    }

    if (flags.contains(ARROW_TEXTURES)) {
        // 必须打开这个开关,允许在线上绘制纹理
        option.arrow(true);
        // 支持设置纹理的间距
        option.arrowSpacing(30);
        // 设置纹理图片
        option.arrowTexture(arrowBitmap);
    }

    if (flags.contains(GRADIENT)) {
        int[] indexes = new int[colorValues.length];
        for (int i = 0; i < indexes.length; ++i)
            indexes[i] = i;

        // 渐变色折线
        option.gradient(true);
        // 设置线的类型
        option.lineType(PolylineOptions.LineType.LINE_TYPE_MULTICOLORLINE);
        option.colors(colorValues, indexes);
    }

    if (flags.contains(ERASE_COLOR)) {
        option.eraseColor(LINE_ERASE_COLOR);
    }
}

移除覆盖物

public void removeOverlay() {
    // 清除地图上所有的标注类(Marker、Polyline、Polygon,TileOverlay除外)
    // map.clearAllOverlays();

    // 从地图移除覆盖物
    for (Removable overlay : overlays) {
        if (!overlay.isRemoved())
            overlay.remove();
    }
    overlays.clear();
}

设置属性

public void setFlags(List<String> flags) {
    selectedFlags.clear();
    selectedFlags.addAll(flags);

    removeOverlay();
    addOverlays();
}

加载地图和释放地图

public void onMapLoaded() {
    addOverlays();
}

public void onMapDestroy() {
    removeOverlay();
}

MapPolylineActivity类

以下是MapPolylineActivity类部分代码

控件响应事件

说明:为了直观显示线的属性,仅使用了CheckBox控件,多种属性只能选一通过代码实现。

public void setMarkerFlag(View view) {
    List<Integer> group = Arrays.asList(
            R.id.colors,
            R.id.defaultTexture,
            R.id.colorTextures,
            R.id.arrowTexture,
            R.id.gradient);

    boolean checked = ((CheckBox) view).isChecked();
    int id = view.getId();
    if (checked) {
        if (group.contains(id)) {
            for (int checkBoxId : group) {
                if (checkBoxId != id) {
                    ((CheckBox) findViewById(checkBoxId)).setChecked(false);
                }
            }
        }
    }

    update();
}
private void update() {
    final int[] ids = {
            R.id.clickable,
            R.id.alpha,
            R.id.border,
            R.id.dottedLine,
            R.id.colors,
            R.id.defaultTexture,
            R.id.colorTextures,
            R.id.arrowTexture,
            R.id.gradient,
            R.id.eraseColor,
    };
    final String[] options = {
            MapPolyline.CLICKABLE,
            MapPolyline.ALPHA,
            MapPolyline.BORDER,
            MapPolyline.DOTTED_LINE,
            MapPolyline.COLORS,
            MapPolyline.DEFAULT_TEXTURES,
            MapPolyline.COLOR_TEXTURES,
            MapPolyline.ARROW_TEXTURES,
            MapPolyline.GRADIENT,
            MapPolyline.ERASE_COLOR,
    };
    List<String> flags = new ArrayList<>();
    for (int i = 0; i < ids.length; ++i) {
        CheckBox checkBox = findViewById(ids[i]);
        if (checkBox.isChecked())
            flags.add(options[i]);
    }
    mapPolyline.setFlags(flags);
}

运行效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值