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);
        }
    }
}
相关推荐
消失的旧时光-19433 分钟前
kmp需要技能
android·设计模式·kotlin
帅得不敢出门1 小时前
Linux服务器编译android报no space left on device导致失败的定位解决
android·linux·服务器
雨白2 小时前
协程间的通信管道 —— Kotlin Channel 详解
android·kotlin
TimeFine3 小时前
kotlin协程 容易被忽视的CompletableDeferred
android
czhc11400756635 小时前
Linux1023 mysql 修改密码等
android·mysql·adb
GOATLong5 小时前
MySQL内置函数
android·数据库·c++·vscode·mysql
onthewaying7 小时前
Android SurfaceTexture 深度解析
android·opengl
茄子凉心7 小时前
Android Bluetooth 蓝牙通信
android·蓝牙通信·bluetooth通信
00后程序员张8 小时前
iOS 26 App 运行状况全面解析 多工具协同监控与调试实战指南
android·ios·小程序·https·uni-app·iphone·webview
2501_916007479 小时前
iOS 混淆实战,多工具组合完成 IPA 混淆、加固与发布治理(iOS混淆|IPA加固|无源码混淆|App 防反编译)
android·ios·小程序·https·uni-app·iphone·webview