简介
osmdroid 是一个用于在 Android 应用中显示地图的开源库。它提供了在 Android 应用中加载 OpenStreetMap(OSM)地图数据的功能,允许开发者在自己的应用中实现地图浏览、标注、交互等功能。
地图库地址
https://github.com/osmdroid/osmdroid
使用方式
引入依赖
implementation 'org.osmdroid:osmdroid-android:6.0.2'
创建布局
<?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=".MainActivity">
<org.osmdroid.views.MapView
android:id="@+id/map"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
项目中使用
首先需要申请定位权限
class MainActivity : AppCompatActivity() {
private val LOCATION_PERMISSION_REQUEST_CODE = 1001
private lateinit var mapView: MapView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mapView = findViewById(R.id.map)
// 检查定位权限是否已经被授予
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
) {
// 如果权限未被授予,则请求权限
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
LOCATION_PERMISSION_REQUEST_CODE
);
} else {
// 如果权限已经被授予,则执行你需要的操作
// 例如,初始化定位服务等
val points: MutableList<GeoPoint> = mutableListOf()
points.add(GeoPoint(40.7128, -74.0060)) //
points.add(GeoPoint(34.0522, -118.2437)); //
points.add(GeoPoint(80.8781, -87.6298)); //
// points.add(GeoPoint(60.8781, 100.6298)); //
val polyline = Polyline(mapView)
polyline.setPoints(points);
mapView.getOverlayManager().add(polyline);
mapView.invalidate()
//画一个标记
// val marker = Marker(mapView)
// marker.position = GeoPoint(60.8781, 100.6298)
// marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
// marker.icon = resources.getDrawable(R.mipmap.ic_launcher_round)
// marker.title = "障碍物"
// mapView.getOverlays().add(0, marker)
// mapView.invalidate()
val items = ArrayList<OverlayItem>()
items.add(
OverlayItem(
"Title",
"Description",
GeoPoint(60.8781, 100.6298)
)
) // Lat/Lon decimal degrees
val mOverlay = ItemizedOverlayWithFocus<OverlayItem>(
items,
object : OnItemGestureListener<OverlayItem> {
override fun onItemSingleTapUp(index: Int, item: OverlayItem?): Boolean {
return true
}
override fun onItemLongPress(index: Int, item: OverlayItem?): Boolean {
return true
}
}, this
)
mOverlay.setFocusItemsOnTap(true)
mapView.getOverlays().add(mOverlay)
}
}
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
// 检查用户是否授予了定位权限
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授予了定位权限,执行你需要的操作
// 例如,初始化定位服务等
} else {
// 用户拒绝了定位权限,可以提示用户手动授权或执行其他操作
}
}
}
}
显示
这是显示折线和标记的方法
但是有时候如果我们需要添加一个标记,但是我们不需要图片,只是单纯的显示一个文字的话,我们可以使用自定义Overlay
TextOverlay
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.util.GeoPoint;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
public class TextOverlay extends Overlay {
private GeoPoint geoPoint;
private String text;
private Paint textPaint;
public TextOverlay(MapView mapView, GeoPoint geoPoint, String text) {
super();
this.geoPoint = geoPoint;
this.text = text;
// 设置文本画笔样式
textPaint = new Paint();
textPaint.setColor(Color.RED);
textPaint.setTextSize(40);
textPaint.setTextAlign(Paint.Align.CENTER);
// 将覆盖物添加到地图上
mapView.getOverlays().add(this);
}
@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);
}
}
}
Activity 中使用这个自定义的 Overlay 类来显示文本标签
// 创建一个地图上的 GeoPoint
GeoPoint point = new GeoPoint(0d, 0d);
// 创建一个文本覆盖物
TextOverlay textOverlay = new TextOverlay(mapView, point, "Text");