百度地图SDK Android版开发 11 覆盖物示例 4 线
- 前言
- 界面布局
- MapPolyline类
- 常量
- 成员变量
- 初始值
- 创建覆盖物
- 移除覆盖物
- 设置属性
- 加载地图和释放地图
- MapPolylineActivity类
- 控件响应事件
- 运行效果图
前言
文本通过创建多个不同线宽的折线和大地曲线,介绍Polyline的使用方法。
线的属性包括是否可点击、是否虚线、分段属性、发光属性和大地曲线。
- 分段属性包括
分段颜色
、分段纹理
、渐变色
。只能选一或不选。 - 发光属性包括
渐变发光
和模糊发光
。只能选一或不选。 - 分段属性、发光属性和大地曲线只能选一或不选。
为了直观显示线的属性,仅使用了CheckBox控件,多种属性只能选一通过代码实现。
界面布局
- 布局文件
<?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="com.example.baidudemo.MapMarkerActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
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/bmapView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/background_dark"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<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/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/colors"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="setMarkerFlag"
android:text="分段颜色"
android:textColor="@color/yellow_800"
android:textStyle="bold" />
<CheckBox
android:id="@+id/textures"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
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"
android:paddingHorizontal="10dp">
<CheckBox
android:id="@+id/gradient"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="false"
android:onClick="setMarkerFlag"
android:text="渐变色"
android:textColor="@color/yellow_800"
android:textStyle="bold" />
<CheckBox
android:id="@+id/bloomGradientA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="setMarkerFlag"
android:text="渐变发光"
android:textColor="@color/blue_500"
android:textStyle="bold" />
<CheckBox
android:id="@+id/bloomBlur"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="setMarkerFlag"
android:text="模糊发光"
android:textColor="@color/blue_500"
android:textStyle="bold" />
<CheckBox
android:id="@+id/geodesic"
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" />
</LinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
MapPolyline类
以下为MapPolyline类部分代码。
常量
public static final String CLICKABLE = "clickable"; // 点击
public static final String DOTTED_LINE = "DottedLine"; // 虚线
public static final String COLORS = "Colors"; // 分段颜色
public static final String TEXTURES = "Textures"; // 分段纹理
public static final String GRADIENT = "Gradient"; // 渐变色
public static final String BLOOM_GRADIENT_A = "BloomGradientA"; // 渐变发光
public static final String BLOOM_BLUR = "BloomBlur"; // 模糊发光
public static final String GEODESIC = "Geodesic"; // 大地曲线
- 渐变色
final static int COLOR_RED = 0xAAD50000;
final static int COLOR_YELLOW = 0xAAF57F17;
final static int COLOR_BLUE = 0xAA0D47A1;
final static int COLOR_GREEN = 0xAA33691E;
- 折线线宽:多个折线的宽度依次为5,10, 15, ……
关于折线宽度(来自API参考)
设置折线线宽, 默认为 5, 单位:像素 需要注意的是:Polyline的宽度适配地图当前缩放级别下的像素与地理范围的对应关系
final static int LINE_WIDTH_MIN = 5;
final static int LINE_WIDTH_STEP = 5;
成员变量
// 覆盖物列表
List<Overlay> overlays = new ArrayList<>();
// 选中的状态
List<String> selectedFlags = new ArrayList<>();
List<List<LatLng>> lines = new ArrayList<>(); // 多个折线
List<LatLng> geodesicLine = new ArrayList<>(); // 大地曲线坐标 仅两个点
ArrayList<BitmapDescriptor> bitmaps = new ArrayList<>(); // 纹理
List<Integer> colorValues = new ArrayList<>(); // 渐变色
初始值
- 默认选中选项
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);
}
geodesicLine.add(new LatLng(36.53, -121.47));
geodesicLine.add(new LatLng(22.33, 114));
- 纹理和颜色(纹理图来自官方Demo)
final String[] assetNames = {
"Icon_road_red_arrow.png",
"Icon_road_yellow_arrow.png",
"Icon_road_blue_arrow.png",
"Icon_road_green_arrow.png",
};
for (String name : assetNames) {
bitmaps.add(BitmapDescriptorFactory.fromAsset(name));
}
final int[] colors = {COLOR_RED, COLOR_YELLOW, COLOR_BLUE, COLOR_GREEN};
for (int color : colors)
colorValues.add(color);
- 点击事件
initEvent();
private void initEvent() {
map.setOnPolylineClickListener(new BaiduMap.OnPolylineClickListener() {
@Override
public boolean onPolylineClick(Polyline polyline) {
showToast("click polyline");
return true;
}
});
}
创建覆盖物
- 创建大地曲线或创建多个折线
public void addOverlays() {
if (selectedFlags.contains(GEODESIC)) {
// 创建大地曲线
PolylineOptions polylineOptions = new PolylineOptions()
.width(LINE_WIDTH_MIN)
.color(COLOR_RED)
// 设置Polyline头尾形状类型
.lineCapType(PolylineOptions.LineCapType.LineCapRound)
// 设置Polyline拐点衔接的形状类型
.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound)
.points(geodesicLine);
setOption(polylineOptions, selectedFlags);
// 在地图上绘制折线
Polyline polyline = (Polyline) map.addOverlay(polylineOptions);
overlays.add(polyline);
return;
}
// 创建多个折线
int width = LINE_WIDTH_MIN;
for (List<LatLng> points : lines) {
PolylineOptions polylineOptions = new PolylineOptions()
.width(width)
.color(COLOR_RED)
// 设置Polyline头尾形状类型
.lineCapType(PolylineOptions.LineCapType.LineCapRound)
// 设置Polyline拐点衔接的形状类型
.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound)
.points(points);
setOption(polylineOptions, selectedFlags);
// 在地图上绘制折线
Polyline polyline = (Polyline) map.addOverlay(polylineOptions);
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(DOTTED_LINE)) {
// 设置折线显示为虚线
option.dottedLine(true);
// 设置虚线形状
// PolylineDottedLineType.DOTTED_LINE_SQUARE
// PolylineDottedLineType.DOTTED_LINE_CIRCLE
option.dottedLineType(PolylineDottedLineType.DOTTED_LINE_SQUARE);
}
if (flags.contains(COLORS)) {
// 设置折线每个点的颜色值
// 每一个点带一个颜色值,绘制时按照索引依次取值 颜色个数 >= points的个数,
// 若colors越界大于点个数,则取最后一个颜色绘制
// 注意颜色值得格式为:0xAARRGGBB
option.colorsValues(colorValues);
}
if (flags.contains(TEXTURES)) {
// 添加纹理索引
List<Integer> indexList = new ArrayList<>();
for (int i = 0; i < bitmaps.size(); ++i)
indexList.add(i);
//
option.customTextureList(bitmaps);
// 设置纹理列表
option.textureIndex(indexList);
}
if (flags.contains(GRADIENT)) {
// 渐变色折线
option.isGradient(true);
option.colorsValues(colorValues);
}
if (flags.contains(BLOOM_GRADIENT_A)) {
// 设置发光模式
option.bloomType(PolylineOptions.LineBloomType.GradientA);
// 设置发光下的宽度
option.bloomWidth(option.getWidth() * 2);
// 设置发光透明度(0~255) 默认线段透明度
option.bloomAlpha(0xAA);
// 设置透明度渐变发光效果的渐变速率(1.0 ~ 10.0)默认5.0f
option.setBloomGradientASpeed(5.0f);
}
if (flags.contains(BLOOM_BLUR)) {
// 设置发光模式
option.bloomType(PolylineOptions.LineBloomType.BLUR);
// 设置发光下的宽度
option.bloomWidth(option.getWidth() * 2);
// 设置发光透明度(0~255) 默认线段透明度
option.bloomAlpha(0xAA);
// 设置模糊发光效果的模糊次数(1~10次) 默认1次
option.setBloomBlurTimes(2);
}
if (flags.contains(GEODESIC)) {
// 大地曲线
option.isGeodesic(true);
// 折线经度跨180需增加此字段
option.lineDirectionCross180(PolylineOptions.LineDirectionCross180.FROM_WEST_TO_EAST);
}
}
移除覆盖物
public void removeOverlay() {
//map.removeOverLays(overlays);
for (Overlay overlay : overlays)
overlay.remove();
overlays.clear();
}
设置属性
public void setFlags(List<String> flags) {
selectedFlags.clear();
selectedFlags.addAll(flags);
removeOverlay();
addOverlays();
}
加载地图和释放地图
public void onMapLoaded() {
initEvent();
addOverlays();
}
public void onMapDestroy() {
removeOverlay();
for (BitmapDescriptor bitmap : bitmaps) {
bitmap.recycle();
}
bitmaps = null;
}
MapPolylineActivity类
以下是MapPolylineActivity类部分代码
控件响应事件
**说明:**为了直观显示线的属性,仅使用了CheckBox控件,多种属性只能选一通过代码实现。
public void setMarkerFlag(View view) {
// 分段颜色、纹理、渐变、大地曲线
List<Integer> group1 = Arrays.asList(R.id.colors, R.id.textures, R.id.gradient, R.id.geodesic);
// 分段颜色、纹理、渐变
List<Integer> group2 = Arrays.asList(R.id.bloomGradientA, R.id.bloomBlur, R.id.geodesic);
boolean checked = ((CheckBox) view).isChecked();
int id = view.getId();
if (checked) {
if (group1.contains(id)) {
for (int checkBoxId : group1) {
if (checkBoxId != id) {
((CheckBox) findViewById(checkBoxId)).setChecked(false);
}
}
}
if (group2.contains(id)) {
for (int checkBoxId : group2) {
if (checkBoxId != id) {
((CheckBox) findViewById(checkBoxId)).setChecked(false);
}
}
}
}
update();
}
private void update() {
final int[] ids = {R.id.clickable,
R.id.dottedLine,
R.id.colors,
R.id.textures,
R.id.gradient,
R.id.bloomGradientA,
R.id.bloomBlur,
R.id.geodesic,
};
final String[] optins = {MapPolyline.CLICKABLE,
MapPolyline.DOTTED_LINE,
MapPolyline.COLORS,
MapPolyline.TEXTURES,
MapPolyline.GRADIENT,
MapPolyline.BLOOM_GRADIENT_A,
MapPolyline.BLOOM_BLUR,
MapPolyline.GEODESIC,
};
List<String> flags = new ArrayList<>();
for (int i = 0; i < ids.length; ++i) {
CheckBox checkBox = findViewById(ids[i]);
if (checkBox.isChecked())
flags.add(optins[i]);
}
mapPolyline.setFlags(flags);
}