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);
}
}
}