天地图之添加覆盖物
最近多少还是会有一点焦虑,其实很大一部分原因是考虑的比较多罢了,适当的放弃一些东西,一切就会变的明朗起来。
接着上一篇天地图之定位信息详解,今天来继续来学习使用天地图 Android SDK 添加覆盖物标注,地图开发中除了常见的定位需求,还有就是覆盖物的添加,比如最近的项目是有关风险管控的,在地图上就要显示对应的风险点,下面的今天的内容:
单个覆盖物
多个覆盖物
集合覆盖物
文字覆盖物
总结
测试效果
单个覆盖物
这里单个覆盖物的添加使用资源文件夹里面的图片作为具体覆盖物,下面是自定义的一个 Overlay,具体如下:
1/**
2 * Powered by jzman.
3 * Created on 2018/6/25 0025.
4 */
5public class MOverlay extends Overlay{
6 private Drawable mDrawable;
7 private DrawableOption mDrawableOption;
8 private GeoPoint mGeoPoint;
9
10 public MOverlay(Context context) {
11 mDrawable = context.getResources().getDrawable(R.drawable.selected_marker);
12 mDrawableOption = new DrawableOption();
13 //设置锚点位置
14 mDrawableOption.setAnchor(0.5f,1.0f);
15 //设置旋转角度
16 mDrawableOption.setRotate(0);
17 //设置状态
18 mDrawableOption.setState(DrawableOption.STATE_NORMAL);
19 //设置多少帧刷新一次图片资源
20 mDrawableOption.setPeriod(200);
21 }
22
23
24 public boolean draw(GL10 gl, MapView mapView, boolean shadow, long when) {
25 MapViewRender render = mapView.getMapViewRender();
26 render.drawDrawable(gl,mDrawableOption,mDrawable,mGeoPoint);
27 return true;
28 }
29
30
31 public boolean onTap(GeoPoint p, MapView mapView) {
32 //指定当前点击的位置添加覆盖物,也可以自己指定
33 mGeoPoint = p;
34 return true;
35 }
36}
然后,将该 Overlay 添加到 MapVIew 中,具体如下:
1mapView.addOverlay(new MOverlay(this));
到此,添加单个覆盖物就完成了。
多个覆盖物
开发中经常需要在地图上标注一组数据相关的位置,此时就需要在地图上添加多个覆盖物了,添加一组相似类型的覆盖物使用到抽象类 ItemizedOverlay,下面是自定义多个覆盖物的一个 Overlay,具体如下:
1/**
2 * Powered by jzman.
3 * Created on 2018/6/25 0025.
4 */
5public class MItemOverlay2 extends ItemizedOverlay<OverlayItem> {
6
7 private MapView mapView;
8 private View view;
9 private TextView tvItemOverlay;
10 private ArrayList<OverlayItem> items;
11 private ArrayList<DefaultGeoPoint<MarkerBean>> points;
12
13 public MItemOverlay2(Drawable defaultMarker, ArrayList<DefaultGeoPoint<MarkerBean>> geoPoints, MapView mapView, View view) {
14 super(defaultMarker);
15 this.mapView = mapView;
16 this.view = view;
17 tvItemOverlay = view.findViewById(R.id.tvItemOverlayData);
18 items = new ArrayList<>();
19 points = geoPoints;
20 for (int i = 0; i < points.size(); i++) {
21 OverlayItem overlayItem = new OverlayItem(points.get(i),
22 points.get(i).getT().getTitle(),
23 points.get(i).getT().getSnippet());
24 overlayItem.setMarker(defaultMarker);
25 items.add(overlayItem);
26 }
27 populate();
28 }
29
30 /**
31 * 覆盖物条目总数
32 * @return
33 */
34
35 public int size() {
36 return items.size();
37 }
38
39 /**
40 * 创建覆盖物条目
41 * @param i
42 * @return
43 */
44
45 protected OverlayItem createItem(int i) {
46 return items.get(i);
47 }
48
49 /**
50 * 处理点击事件
51 * @param index
52 * @return
53 */
54
55 protected boolean onTap(int index) {
56 if (index == -1) return false;
57 mapView.updateViewLayout(view, new MapView.LayoutParams(
58 ViewGroup.LayoutParams.WRAP_CONTENT,
59 ViewGroup.LayoutParams.WRAP_CONTENT,
60 points.get(index),
61 MapView.LayoutParams.BOTTOM_CENTER));
62 tvItemOverlay.setText(points.get(index).getT().getTitle());
63 view.setVisibility(View.VISIBLE);
64 return true;
65 }
66}
设置点击每个覆盖物弹出的 View 必须已经被添加到 MapView 中,具体如下:
1mapView.addView(view, new MapView.LayoutParams(
2 ViewGroup.LayoutParams.WRAP_CONTENT,
3 ViewGroup.LayoutParams.WRAP_CONTENT,
4 null,
5 MapView.LayoutParams.TOP_LEFT));
如果没有出现添加,则会出错,出错信息如下:
1> java.lang.IllegalArgumentException: Given view not a child of com.tianditu.android.maps.MapView{ac3dbd7 V.E...... ........ 0,192-1080,1692 #7f070050 app:id/mapView}
然后,将该 Overlay 添加到 MapVIew 中,具体如下:
1Drawable drawable1 = getResources().getDrawable(R.drawable.selected_marker);
2MItemOverlay2 mItemOverlay2 = new MItemOverlay2(drawable1, markers, mapView, view);
3mapView.getOverlays().add(mItemOverlay2);
到此,添加多个覆盖物就完成了。
几何覆盖物
集合覆盖物主要就是使用几何图形标注相关位置点,下面自定义了一个 Overlay,通过点击地图位置添加几何覆盖物,效果可参考文末测试效果图,具体如下:
1/**
2 * Powered by jzman.
3 * Created on 2018/6/25 0025.
4 */
5public class GeometricOverlay extends Overlay{
6 private CircleArcOption mCircleArcOption;
7 private GeoPoint mGeoPoint;
8
9 public GeometricOverlay() {
10 mCircleArcOption = new CircleArcOption();
11 //设置覆盖物是否是虚线
12 mCircleArcOption.setDottedLine(true);
13 //设置填充颜色
14 mCircleArcOption.setFillColor(Color.GRAY);
15 //设置边框颜色
16 mCircleArcOption.setStrokeColor(Color.BLACK);
17 //设置边框宽度
18 mCircleArcOption.setStrokeWidth(5);
19 //是否使用中心点,设置true,绘制出的是扇形,反之则是圆弧
20 mCircleArcOption.setUseCenter(true);
21 //设置起始角度以及扫描角度
22 mCircleArcOption.setAngle(0,100);
23 }
24
25
26 public boolean draw(GL10 gl, MapView mapView, boolean shadow, long when) {
27 MapViewRender render = mapView.getMapViewRender();
28 render.drawCircleArc(gl,mCircleArcOption,mGeoPoint,1000);
29 return true;
30 }
31
32
33 public boolean onTap(GeoPoint p, MapView mapView) {
34 //指定当前点击的位置添加覆盖物,也可以自己指定
35 mGeoPoint = p;
36 return true;
37 }
38}
然后,将该 Overlay 添加到 MapVIew 中,具体如下:
1mapView.addOverlay(new GeometricOverlay());
到此,添加多个覆盖物就完成了。
文字覆盖物
文字覆盖物就是在相应的位置点添加文字,下面自定义了一个 Overlay,通过点击地图位置添加文字覆盖物,效果可参考文末测试效果图,具体如下:
1/**
2 * Powered by jzman.
3 * Created on 2018/6/25 0025.
4 */
5public class TextOverlay extends Overlay{
6 private FontOption mFontOption;
7 private GeoPoint mGeoPoint;
8
9 public TextOverlay(Context context) {
10 mFontOption = new FontOption();
11 //设置填充颜色
12 mFontOption.setFillColor(Color.RED);
13 //设置字体颜色、字体大小
14 mFontOption.setFontColor(Color.BLACK);
15 mFontOption.setFontSize(60);
16 //设置文字边框宽度、边框颜色
17 mFontOption.setStrokeWidth(4);
18 mFontOption.setStrokeColor(Color.GRAY);
19 //设置文字旋转角度
20 mFontOption.setTextRotate(60);
21 //设置字体
22 Typeface typeface = Typeface.createFromAsset(context.getAssets(), "font/font.ttf");
23 mFontOption.setFontTypeface(typeface);
24 }
25
26
27 public boolean draw(GL10 gl, MapView mapView, boolean shadow, long when) {
28 MapViewRender render = mapView.getMapViewRender();
29 if (mGeoPoint!=null){
30 render.drawText(gl,mFontOption,"这是文字覆盖物",mGeoPoint);
31 }
32 return true;
33 }
34
35
36 public boolean onTap(GeoPoint p, MapView mapView) {
37 //指定当前点击的位置添加覆盖物,也可以自己指定
38 mGeoPoint = p;
39 return true;
40 }
41}
然后,将该 Overlay 添加到 MapVIew 中,具体如下:
1mapView.addOverlay(new TextOverlay(this));
到此,添加多个覆盖物就完成了。
总结
综上所述,使用天地图添加覆盖物的一般步骤具体如下:
创建具体覆盖物的 Overlay
初始化覆盖物具体参数
重写 draw() 方法
将该 Overlay 添加到 MapView 中
开发中根据实际需求再做进一步的定制。