Android 利用OSMdroid开发GIS 添加点、线、面和标记点

部署看这个:Android 利用OSMdroid开发GIS-CSDN博客

直接上代码

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <org.osmdroid.views.MapView
       android:id="@+id/mapView"
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>

   <LinearLayout
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_margin="10dp"
       android:layout_alignParentTop="true"
       android:orientation="vertical">
      <Button
          android:id="@+id/btnMarker"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="标记点" />

      <Button
          android:id="@+id/btnLine"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="线" />

      <Button
          android:id="@+id/btnPolygon"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="面" />

      <Button
          android:id="@+id/btnWord"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="文字" />
   </LinearLayout>

</RelativeLayout>

MainActivity.java:

package com.chy.osmdroid;


import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.text.TextPaint;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.chy.custom.TextOverlay;
import com.chy.layers.LayerTileSources;
import com.chy.permission.PermissionUtils;
import org.osmdroid.api.IMapController;
import org.osmdroid.tileprovider.MapTileProviderBasic;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.OverlayManager;
import org.osmdroid.views.overlay.Polygon;
import org.osmdroid.views.overlay.Polyline;
import org.osmdroid.views.overlay.TilesOverlay;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_PERMISSION_CODE = 0;// 权限所用
    // 动态申请权限
    private String[] permissions = {
            Manifest.permission.INTERNET,// 网络权限
            Manifest.permission.ACCESS_COARSE_LOCATION,// 精细定位
            Manifest.permission.ACCESS_FINE_LOCATION,// 粗定位
            Manifest.permission.ACCESS_WIFI_STATE,// 定位权限
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    private MapView mapView;
    private Button btnMarker;// 标记点
    private Button lineBtn;// 线
    private Button polygonBtn;// 面
    private Button wordBtn;// 文字

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getPermission();// 获取权限

        initControls();
    }

    /**
     * 权限
     * */
    private void getPermission(){
        if (PermissionUtils.hasPermissions(MainActivity.this, permissions)) {
            initMap();// 调用初始化地图
        } else {
            PermissionUtils.requestPermissions(MainActivity.this, REQUEST_PERMISSION_CODE, permissions);
            Toast.makeText(getApplicationContext(), "地图加载失败!", Toast.LENGTH_SHORT).show();
        }
    }

    // 地图初始化
    private void initMap(){
        // 获取mapView实例
        mapView = findViewById(R.id.mapView);
        mapView.setUseDataConnection(true);
        // 加载在线地图-高德地图
        //mapView.setTileSource(LayerTileSources.AutoNaviVector);
        // 加载天地图电子图
        mapView.setTileSource(LayerTileSources.TDTVEC_W);
        // 加载天地图标注图
        TilesOverlay tilesOverlay = new TilesOverlay(new MapTileProviderBasic(this,LayerTileSources.TDTCIA_W),this);
        mapView.getOverlayManager().add(tilesOverlay);




        // 设置最小缩放比例
        mapView.setMinZoomLevel(3.0);
        // 设置最大缩放比例
        mapView.setMaxZoomLevel(18.0);
        // 让瓦片适应不同像素密度:默认地图显示的字体小,图片像素高,可设置以下代码,使地图适应不同像素密度,更美观
        //mapView.setTilesScaledToDpi(true);

        IMapController mapController = mapView.getController();
        // 设置地图初始级别
        mapController.setZoom(11.0);

        // 设置初始中心点
        GeoPoint centerPoint = new GeoPoint(43.90, 125.33);
        mapController.setCenter(centerPoint);

        //启用缩放及滑动手势
        //mapView.setBuiltInZoomControls(true);// 废弃得方法,被下面方法所替代
        mapView.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
        mapView.setMultiTouchControls(true);
        mapView.getOverlayManager().getTilesOverlay().setEnabled(true);
        mapView.setSelected(true);

    }

    // 控件初始化
    private void initControls(){
        // 绘制点
        btnMarker = findViewById(R.id.btnMarker);
        btnMarker.setOnClickListener(markerClick);
        // 绘制线
        lineBtn = findViewById(R.id.btnLine);
        lineBtn.setOnClickListener(lineClick);
        // 绘制面
        polygonBtn = findViewById(R.id.btnPolygon);
        polygonBtn.setOnClickListener(polygonClick);
        // 绘制文字
        wordBtn = findViewById(R.id.btnWord);
        wordBtn.setOnClickListener(wordClick);

    }

    /**
     * 绘制标记点方法
     * */
    View.OnClickListener markerClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Marker marker = new Marker(mapView);
            GeoPoint point = new GeoPoint(43.90, 125.33);
            marker.setPosition(point);
            marker.setAnchor(Marker.ANCHOR_CENTER,Marker.ANCHOR_CENTER);
            // 设置图片
            marker.setIcon(getResources().getDrawable(R.mipmap.ic_launcher));
            marker.setTitle("测试点");
            /**
             * 添加标记到地图上
             * @param index 0控制标记点的在所有图层最下面;1控制标记点在所有图层最上面
             * */
            // 清除index为1的图层(绘制图层都在index为1中)
            OverlayManager overlayManager = mapView.getOverlayManager();
            if (overlayManager.size() > 1){
                mapView.getOverlayManager().remove(1);
            }
            // 添加标记点
            mapView.getOverlays().add(1,marker);
            // 刷新
            mapView.invalidate();
        }
    };

    /**
     * 绘制线方法
     * */
    View.OnClickListener lineClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 点集合
            List<GeoPoint> pointList = new ArrayList<GeoPoint>();
            pointList.add(new GeoPoint(43.90, 125.33));
            pointList.add(new GeoPoint(43.80, 125.23));
            pointList.add(new GeoPoint(43.70, 125.13));
            // 创建线实例
            Polyline polyline = new Polyline(mapView);
            // 设置点击图形,不弹出视图弹窗
            polyline.setInfoWindow(null);
            // 设置线颜色
            polyline.getOutlinePaint().setColor(Color.RED);
            // 设置线宽度
            polyline.getOutlinePaint().setStrokeWidth(20);
            // 赋值
            polyline.setPoints(pointList);
            /**
             * 添加线到地图上
             * @param index 0控制标记点的在所有图层最下面;1控制标记点在所有图层最上面
             * */
            // 清除index为1的图层(绘制图层都在index为1中)
            OverlayManager overlayManager = mapView.getOverlayManager();
            if (overlayManager.size() > 1){
                mapView.getOverlayManager().remove(1);
            }
            // 添加线
            mapView.getOverlayManager().add(1,polyline);
            // 刷新
            mapView.invalidate();

        }
    };

    /**
     * 绘制面方法
     * */
    View.OnClickListener polygonClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 点集合
            List<GeoPoint> pointList = new ArrayList<GeoPoint>();
            pointList.add(new GeoPoint(43.90, 125.33));
            pointList.add(new GeoPoint(43.80, 125.23));
            pointList.add(new GeoPoint(43.95, 125.53));
            // 创建线实例
            Polygon polygon = new Polygon(mapView);
            // 设置点击图形,不弹出视图弹窗
            polygon.setInfoWindow(null);
            // 设置线颜色
            polygon.getOutlinePaint().setColor(Color.GREEN);
            // 设置线宽度
            polygon.getOutlinePaint().setStrokeWidth(20);
            // 赋值
            polygon.setPoints(pointList);
            /**
             * 添加线到地图上
             * @param index 0控制标记点的在所有图层最下面;1控制标记点在所有图层最上面
             * */
            // 清除index为1的图层(绘制图层都在index为1中)
            OverlayManager overlayManager = mapView.getOverlayManager();
            if (overlayManager.size() > 1){
                mapView.getOverlayManager().remove(1);
            }
            // 添加面
            mapView.getOverlayManager().add(1,polygon);
            // 刷新
            mapView.invalidate();
        }
    };


    /**
     * 绘制文字方法
     * */
    View.OnClickListener wordClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 清除index为1的图层(绘制图层都在index为1中)
            OverlayManager overlayManager = mapView.getOverlayManager();
            if (overlayManager.size() > 1){
                mapView.getOverlayManager().remove(1);
            }

            GeoPoint wordPoint = new GeoPoint(43.95, 125.35);
            TextOverlay textOverlay = new TextOverlay(mapView);
            textOverlay.setPosition(wordPoint);
            // 设置文字
            textOverlay.setText("111111");
            // 设置文字颜色
            textOverlay.setWordColor(Color.RED);
            // 设置字体大小
            textOverlay.setTextSize(25);
        }
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}

自定义类TextOverlay.java:

package com.chy.custom;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Overlay;

/**
 * OSMdroid - 自定义文字Overlay
 * */
public class TextOverlay extends Overlay {

    private MapView mapView;
    private GeoPoint geoPoint;
    private String text;
    private Paint textPaint;

    /**
     * 构造函数
     * */
    public TextOverlay(MapView _mapView){
        super();
        this.mapView = _mapView;

        // 设置文本画笔样式
        textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(30);
        textPaint.setTextAlign(Paint.Align.CENTER);

        // 将覆盖物添加到地图上
        mapView.getOverlays().add(1,this);
        // 刷新
        mapView.invalidate();
    }

    public TextOverlay(MapView _mapView,GeoPoint _geoPoint,String _text){
        super();
        this.mapView = _mapView;
        this.geoPoint = _geoPoint;
        this.text = _text;

        // 设置文本画笔样式
        textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(30);
        textPaint.setTextAlign(Paint.Align.CENTER);

        // 将覆盖物添加到地图上
        mapView.getOverlays().add(1,this);
        // 刷新
        mapView.invalidate();
    }

    /**
     * 设置文字
     * */
    public void  setText(String text){
        this.text = text;
    }


    /**
     * 设置文字位置
     * */
    public void setPosition(GeoPoint geoPoint){
        this.geoPoint = geoPoint;
    }

    /**
     * 设置文字颜色
     * */
    public void setWordColor(int color){
        this.textPaint.setColor(color);
    }
    public void setWordARGB(int a, int r, int g, int b){
        this.textPaint.setARGB(a,r,g,b);
    }

    /**
     * 设置文字大小
     * */
    public void setTextSize(float textSize){
        textPaint.setTextSize(textSize);
    }

    /**
     * 设置文字位置
     * */
    public void setTextAlign(Paint.Align align){
        this.textPaint.setTextAlign(align);
    }

    @Override
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
        // 绘制文本标签
        //shadow 参数表示是否在绘制阴影层。在 OpenStreetMap (OSM) 中,阴影层通常用于在地图上显示阴影效果,例如地图上的建筑物或地形。通常情况下,我们只在 shadow 参数为 false 时绘制覆盖物,以避免在阴影层上绘制两次相同的内容。
        if (!shadow) {
            // 将地理坐标转换为屏幕坐标
            android.graphics.Point screenPoint = mapView.getProjection().toPixels(geoPoint, null);
            // 在屏幕上绘制文本标签
            canvas.drawText(text, screenPoint.x, screenPoint.y, textPaint);
        }
    }
}
相关推荐
诸神黄昏EX1 小时前
Android 分区相关介绍
android
大白要努力!2 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee2 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood2 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-5 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen8 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年15 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿17 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神19 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛19 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee