腾讯地图SDK Android版开发 11 覆盖物示例 4 线
- 前言
- 线的属性介绍
- ColorType 和 LineType
- ColorType
- LineType
- 与颜色有关的属性
- 填充色和线宽
- 描边颜色和描边的宽度
- 分段颜色
- 渐变色
- 擦除颜色
- 与纹理相关属性
- 内置纹理
- 自定义颜色纹理
- 线上叠加纹理
- 虚线
- 界面布局
- MapPolyline类
- 常量
- 成员变量
- 初始值
- 创建覆盖物
- 移除覆盖物
- 设置属性
- 加载地图和释放地图
- MapPolylineActivity类
- 控件响应事件
- 运行效果图
前言
文本通过创建多个不同线宽的折线,介绍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_DOTTEDLINE | 点 | 2 |
与颜色有关的属性
填充色和线宽
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_BLUE | 19 | |
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 类
类型 | 方法 | 说明 |
---|---|---|
PolylineOptions | arrow(boolean flag) | 导航用接口,开发都不要用 |
PolylineOptions | arrowSpacing(int arrowSpacing) | 设置方向箭头的间距,单位(px),默认是100px |
PolylineOptions | arrowTexture(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);
}