要使车辆图标的大小随地图缩放而变化,可以在 VehicleOverlay
类的 draw
方法中根据当前的缩放级别动态调整车辆图标的大小。以下是如何实现这种功能的示例代码:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Overlay;
public class MainActivity extends AppCompatActivity {
private MapView map = null;
private VehicleOverlay vehicleOverlay;
private GeoPoint vehiclePosition;
private float vehicleBearing = 0.0f; // 初始化航向角
private Handler handler;
private Runnable updateVehicleRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Configuration.getInstance().setUserAgentValue(BuildConfig.APPLICATION_ID);
setContentView(R.layout.activity_main);
map = (MapView) findViewById(R.id.map);
map.setMultiTouchControls(true);
// 初始化地图控制器
IMapController mapController = map.getController();
mapController.setZoom(15.0);
GeoPoint startPoint = new GeoPoint(88.888, 88.888); // 示例:埃菲尔铁塔
mapController.setCenter(startPoint);
// 初始化车辆位置
vehiclePosition = new GeoPoint(88.888, 88.888);
// 创建并添加车辆覆盖物
Bitmap vehicleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.vehicle_icon);
vehicleOverlay = new VehicleOverlay(vehicleBitmap, vehiclePosition, vehicleBearing);
map.getOverlayManager().add(vehicleOverlay);
// 定义定时任务
handler = new Handler();
updateVehicleRunnable = new Runnable() {
@Override
public void run() {
// 模拟车辆位置和航向更新
updateVehicleMovement(new GeoPoint(vehiclePosition.getLatitude() + 0.0001, vehiclePosition.getLongitude() + 0.0001), vehicleBearing + 10.0f);
handler.postDelayed(this, 1000); // 每1秒更新一次
}
};
handler.postDelayed(updateVehicleRunnable, 1000); // 启动定时任务
}
@Override
public void onResume() {
super.onResume();
map.onResume(); // 需要用于指南针、当前位置覆盖物等
}
@Override
public void onPause() {
super.onPause();
handler.removeCallbacks(updateVehicleRunnable); // 停止定时任务
map.onPause(); // 需要用于指南针、当前位置覆盖物等
}
// 更新车辆位置和航向的方法
private void updateVehicleMovement(GeoPoint newPosition, float newBearing) {
vehiclePosition.setCoords(newPosition.getLatitude(), newPosition.getLongitude());
vehicleBearing = newBearing;
vehicleOverlay.setPositionAndBearing(vehiclePosition, vehicleBearing);
map.invalidate(); // 刷新地图
}
}
// 自定义车辆覆盖物类
class VehicleOverlay extends Overlay {
private Bitmap vehicleBitmap;
private GeoPoint position;
private float bearing;
public VehicleOverlay(Bitmap vehicleBitmap, GeoPoint position, float bearing) {
this.vehicleBitmap = vehicleBitmap;
this.position = position;
this.bearing = bearing;
}
public void setPositionAndBearing(GeoPoint position, float bearing) {
this.position = position;
this.bearing = bearing;
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (shadow) {
return; // 不绘制阴影
}
// 将地理坐标转为屏幕坐标
Point screenPoint = new Point();
mapView.getProjection().toPixels(position, screenPoint);
// 获取当前缩放级别
float currentZoomLevel = mapView.getZoomLevelDouble();
float scale = (float) Math.pow(2, currentZoomLevel - 15); // 15是车辆图标的基准缩放级别
// 缩放车辆图标
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
matrix.postRotate(bearing, vehicleBitmap.getWidth() / 2, vehicleBitmap.getHeight() / 2);
matrix.postTranslate(screenPoint.x - (vehicleBitmap.getWidth() * scale) / 2, screenPoint.y - (vehicleBitmap.getHeight() * scale) / 2);
// 创建缩放和旋转后的车辆图标
Bitmap scaledAndRotatedBitmap = Bitmap.createBitmap(vehicleBitmap, 0, 0, vehicleBitmap.getWidth(), vehicleBitmap.getHeight(), matrix, true);
// 绘制缩放和旋转后的车辆图标
canvas.drawBitmap(scaledAndRotatedBitmap, matrix, null);
}
}
在这个示例中,车辆图标在地图缩放时自动调整大小。Overlay
类的 draw
方法使用当前的地图缩放级别来计算图标的缩放比例,并通过 Matrix
对象进行缩放和旋转操作。具体步骤如下:
- 获取当前的缩放级别
currentZoomLevel
。 - 计算图标的缩放比例
scale
。 - 使用
Matrix
对象对车辆图标进行缩放 (postScale
) 和旋转 (postRotate
)。 - 将缩放和旋转后的图标绘制到画布上。
注意:
-
scale
的计算假定基准缩放级别为 15(即图标在缩放级别 15 时为原始大小),根据需求调整该基准缩放级别。