osmdroid绘制点线面(比例尺,缩小放大,导航图标等),地图的基本用法都有。需要注意就是自已位置的图标出现,一定要有打开gps,打开gps之后,获取屏幕地图的坐标也是能获取的。这次的项目代码打包,在之前两篇的osmdroid 相关博客基础上扩展的。所以有更加全面的介绍。
1,图片介绍
这就是项目整体功能了。
2,绘制5万个点
这是
5万个点用一个图层来绘制,当然你也可以使用ondraw 一个个点换算屏幕坐标的绘制。
package com.osmdroid.sample.overlay;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import android.widget.Toast;
import com.osmdroid.sample.util.BaseSampleFragment;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.simplefastpoint.LabelledGeoPoint;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlayOptions;
import org.osmdroid.views.overlay.simplefastpoint.SimplePointTheme;
import java.util.ArrayList;
import java.util.List;
/**
* Example of SimpleFastPointOverlay
* Created by Miguel Porto on 12-11-2016.
*/
public class SampleSimpleFastPointOverlay extends BaseSampleFragment {
@Override
public String getSampleTitle() {
return "Simple Fast Point Overlay with 10k points";
}
@Override
protected void addOverlays() {
super.addOverlays();
// create 10k labelled points
// in most cases, there will be no problems of displaying >100k points, feel free to try
List<IGeoPoint> points = new ArrayList<>();
for (int i = 0; i < 50000; i++) {
points.add(new LabelledGeoPoint(37 + Math.random() * 5, -8 + Math.random() * 5
, "Point #" + i));
}
// wrap them in a theme
SimplePointTheme pt = new SimplePointTheme(points, true);
// create label style
Paint textStyle = new Paint();
textStyle.setStyle(Paint.Style.FILL);
textStyle.setColor(Color.parseColor("#0000ff"));
textStyle.setTextAlign(Paint.Align.CENTER);
textStyle.setTextSize(24);
// set some visual options for the overlay
// we use here MAXIMUM_OPTIMIZATION algorithm, which works well with >100k points
SimpleFastPointOverlayOptions opt = SimpleFastPointOverlayOptions.getDefaultStyle()
.setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION)
.setRadius(7).setIsClickable(true).setCellSize(15).setTextStyle(textStyle);
// create the overlay with the theme
final SimpleFastPointOverlay sfpo = new SimpleFastPointOverlay(pt, opt);
// onClick callback
sfpo.setOnClickListener(new SimpleFastPointOverlay.OnClickListener() {
@Override
public void onClick(SimpleFastPointOverlay.PointAdapter points, Integer point) {
Toast.makeText(mMapView.getContext()
, "You clicked " + ((LabelledGeoPoint) points.get(point)).getLabel()
, Toast.LENGTH_SHORT).show();
}
});
// add overlay
mMapView.getOverlays().add(sfpo);
// zoom to its bounding box
mMapView.addOnFirstLayoutListener(new MapView.OnFirstLayoutListener() {
@Override
public void onFirstLayout(View v, int left, int top, int right, int bottom) {
if(mMapView != null && mMapView.getController() != null) {
mMapView.getController().zoomTo(6);
mMapView.zoomToBoundingBox(sfpo.getBoundingBox(), true);
}
}
});
}
}
另外一种绘制的形式
package com.osmdroid.sample.overlay;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
import org.osmdroid.views.overlay.Overlay;
/**
* 自定义绘制的地图坐标
*/
public class CustomPointOverlay extends Overlay {
private final Point mMapCoordsProjected = new Point();
private final Point mMapCoordsTranslated = new Point();
protected Paint mCirclePaint = new Paint();
public CustomPointOverlay() {
}
static CustomPointOverlay mGisOverlay = null;
public static CustomPointOverlay GetInstance() {
if (mGisOverlay == null) {
synchronized (CustomPointOverlay.class) {
if (mGisOverlay == null) {
mGisOverlay = new CustomPointOverlay();
}
}
}
return mGisOverlay;
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
//经纬度坐标到屏幕坐标的转换
mapView.getProjection().toProjectedPixels(23.12658183, 113.365588756, mMapCoordsProjected);
Projection pj = mapView.getProjection();
pj.toPixelsFromProjected(mMapCoordsProjected, mMapCoordsTranslated);
// final float radius = lastFix.getAccuracy()
// / (float) TileSystem.GroundResolution(lastFix.getLatitude(),
// mapView.getZoomLevel());
final float radius = 10L;
mCirclePaint.setColor(Color.BLUE);
mCirclePaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(mMapCoordsTranslated.x, mMapCoordsTranslated.y, radius, mCirclePaint);
}
}
3,绘制线
绘制线也是一样啦。使用这个类就行,Polyline
// create 10k labelled points
// in most cases, there will be no problems of displaying >100k points, feel free to try
List<org.osmdroid.util.GeoPoint> points = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
points.add(new GeoPoint(37 + Math.random() * 5, -8 + Math.random() * 5, 0));
}
//随机产生的1000个点并连成线
if(points.size()>0){
org.osmdroid.views.overlay.Polyline Polyline=new org.osmdroid.views.overlay.Polyline();
Polyline.setWidth(2);
Polyline.setColor(0xFF1B7BCD);
Polyline.setPoints(points);
mapView.getOverlays().add(Polyline);
}
//计算边界值,定位边界
final BoundingBox box = new BoundingBox(37,-8,42,-3);
// zoom to its bounding box
mapView.addOnFirstLayoutListener(new MapView.OnFirstLayoutListener() {
@Override
public void onFirstLayout(View v, int left, int top, int right, int bottom) {
if(mapView != null && mapView.getController() != null) {
mapView.getController().zoomTo(6);
mapView.zoomToBoundingBox(box, true);
}
}
});
}
//如果线的绘制,要实时绘制,可采用类似格网绘图,及时地图增加移动,放大,缩小里面监听
//进行图层的重绘
4,绘制面
使用 polygon
// create 10k labelled points
// in most cases, there will be no problems of displaying >100k points, feel free to try
List<GeoPoint> points = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
points.add(new GeoPoint(37 + Math.random() * 5, -8 + Math.random() * 5, 0));
}
//随机产生的1000个点并连成面
if(points.size()>0){
org.osmdroid.views.overlay.Polygon polygon=new org.osmdroid.views.overlay.Polygon();
polygon.setStrokeWidth(1);
polygon.setFillColor(0x8032B5EB);
polygon.setStrokeColor(Color.BLUE);
polygon.setPoints(points);
mapView.getOverlays().add(polygon);
}
//计算边界值,定位边界
final BoundingBox box = new BoundingBox(37,-8,42,-3);
// zoom to its bounding box
mapView.addOnFirstLayoutListener(new MapView.OnFirstLayoutListener() {
@Override
public void onFirstLayout(View v, int left, int top, int right, int bottom) {
if(mapView != null && mapView.getController() != null) {
mapView.getController().zoomTo(6);
mapView.zoomToBoundingBox(box, true);
}
}
});
5,基本配置,比例尺,缩小,放大
package com.osmdroid.sample;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Toast;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
import org.osmdroid.views.overlay.simplefastpoint.LabelledGeoPoint;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay;
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlayOptions;
import org.osmdroid.views.overlay.simplefastpoint.SimplePointTheme;
import java.util.ArrayList;
import java.util.List;
public class BasicMapTestActivity extends AppCompatActivity implements View.OnClickListener {
private MapView mapView;
//地图旋转
private RotationGestureOverlay mRotationGestureOverlay;
//比例尺
private ScaleBarOverlay mScaleBarOverlay;
//指南针方向
private CompassOverlay mCompassOverlay = null;
//设置导航图标的位置
private MyLocationNewOverlay mLocationOverlay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basic_test);
initView();
}
private void initView() {
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
mapView = (MapView) findViewById(R.id.mymapview);
mapView.setDrawingCacheEnabled(true);
mapView.setMaxZoomLevel(20);
mapView.setMinZoomLevel(6);
mapView.getController().setZoom(12);
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.setUseDataConnection(true);
mapView.setMultiTouchControls(true);// 触控放大缩小
//是否显示地图数据源
mapView.getOverlayManager().getTilesOverlay().setEnabled(true);
//地图自由旋转
mRotationGestureOverlay = new RotationGestureOverlay(mapView);
mRotationGestureOverlay.setEnabled(true);
mapView.getOverlays().add(this.mRotationGestureOverlay);
//比例尺配置
final DisplayMetrics dm = getResources().getDisplayMetrics();
mScaleBarOverlay = new ScaleBarOverlay(mapView);
mScaleBarOverlay.setCentred(true);
mScaleBarOverlay.setAlignBottom(true); //底部显示
mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);
mapView.getOverlays().add(this.mScaleBarOverlay);
//指南针方向
mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
mapView);
mCompassOverlay.enableCompass();
mapView.getOverlays().add(this.mCompassOverlay);
//设置导航图标
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),
mapView);
mapView.getOverlays().add(this.mLocationOverlay);
mLocationOverlay.enableMyLocation(); //设置可视
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
//定位当前的位置,并设置缩放级别
mapView.getController().setZoom(18);
mapView.getController().setCenter(new GeoPoint(23.12648183, 113.365548756));
break;
case R.id.button2: //绘制点
List<IGeoPoint> points = new ArrayList<>();
points.add(new LabelledGeoPoint(23.12658183, 113.365588756 , "Point #" + 1));
points.add(new LabelledGeoPoint(23.12647183, 113.365558756 , "Point #" + 2));
// wrap them in a theme
SimplePointTheme pt = new SimplePointTheme(points, true);
// create label style
Paint textStyle = new Paint();
textStyle.setStyle(Paint.Style.FILL);
textStyle.setColor(Color.parseColor("#0000ff"));
textStyle.setTextAlign(Paint.Align.CENTER);
textStyle.setTextSize(24);
// set some visual options for the overlay
// we use here MAXIMUM_OPTIMIZATION algorithm, which works well with >100k points
SimpleFastPointOverlayOptions opt = SimpleFastPointOverlayOptions.getDefaultStyle()
.setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION)
.setRadius(7).setIsClickable(true).setCellSize(15).setTextStyle(textStyle);
// create the overlay with the theme
final SimpleFastPointOverlay sfpo = new SimpleFastPointOverlay(pt, opt);
// onClick callback
sfpo.setOnClickListener(new SimpleFastPointOverlay.OnClickListener() {
@Override
public void onClick(SimpleFastPointOverlay.PointAdapter points, Integer point) {
Toast.makeText(mapView.getContext()
, "You clicked " + ((LabelledGeoPoint) points.get(point)).getLabel()
, Toast.LENGTH_SHORT).show();
}
});
// add overlay
mapView.getOverlays().add(sfpo);
break;
case R.id.button3://缩小
mapView.getController().zoomOut();
break;
case R.id.button4://放大
mapView.getController().zoomIn();
break;
}
}
@Override
public void onPause() {
this.mLocationOverlay.disableMyLocation();
super.onPause();
}
@Override
public void onResume() {
super.onResume();
}
}
package com.osmdroid.sample;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
public class BasicMapTestActivity3 extends AppCompatActivity implements View.OnClickListener ,LocationListener {
private MapView mapView;
//地图旋转
private RotationGestureOverlay mRotationGestureOverlay;
//比例尺
private ScaleBarOverlay mScaleBarOverlay;
//指南针方向
private CompassOverlay mCompassOverlay = null;
//设置导航图标的位置
private MyLocationNewOverlay mLocationOverlay;
private LocationManager lm;
private Location currentLocation = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basic_test_3);
initView();
}
private void initView() {
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
mapView = (MapView) findViewById(R.id.mymapview);
mapView.setDrawingCacheEnabled(true);
mapView.setMaxZoomLevel(20);
mapView.setMinZoomLevel(6);
mapView.getController().setZoom(12);
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.setUseDataConnection(true);
mapView.setMultiTouchControls(true);// 触控放大缩小
//是否显示地图数据源
mapView.getOverlayManager().getTilesOverlay().setEnabled(true);
//地图自由旋转
mRotationGestureOverlay = new RotationGestureOverlay(mapView);
mRotationGestureOverlay.setEnabled(true);
mapView.getOverlays().add(this.mRotationGestureOverlay);
//比例尺配置
final DisplayMetrics dm = getResources().getDisplayMetrics();
mScaleBarOverlay = new ScaleBarOverlay(mapView);
mScaleBarOverlay.setCentred(true);
mScaleBarOverlay.setAlignBottom(true); //底部显示
mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);
mapView.getOverlays().add(this.mScaleBarOverlay);
//指南针方向
mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
mapView);
mCompassOverlay.enableCompass();
mapView.getOverlays().add(this.mCompassOverlay);
//设置导航图标
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),
mapView);
mapView.getOverlays().add(this.mLocationOverlay);
mLocationOverlay.enableMyLocation(); //设置可视
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
if (currentLocation != null) {
GeoPoint myPosition = new GeoPoint(currentLocation.getLatitude(), currentLocation.getLongitude());
mapView.getController().animateTo(myPosition);
}
break;
case R.id.button2:
if (!mLocationOverlay.isFollowLocationEnabled()) {
mLocationOverlay.enableFollowLocation();
} else {
mLocationOverlay.disableFollowLocation();
}
break;
}
}
@Override
public void onLocationChanged(Location location) {
currentLocation=location;
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onPause() {
super.onPause();
try{
lm.removeUpdates(this);
}catch (Exception ex){}
mCompassOverlay.disableCompass();
mLocationOverlay.disableFollowLocation();
mLocationOverlay.disableMyLocation();
mScaleBarOverlay.enableScaleBar();
}
@Override
public void onResume(){
super.onResume();
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
try{
//this fails on AVD 19s, even with the appcompat check, says no provided named gps is available
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0l,0f,this);
}catch (Exception ex){}
try{
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0l,0f,this);
}catch (Exception ex){}
mLocationOverlay.enableFollowLocation();
mLocationOverlay.enableMyLocation();
mScaleBarOverlay.disableScaleBar();
}
}
package com.osmdroid.sample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import com.osmdroid.sample.overlay.CustomPointOverlay;
import com.osmdroid.sample.util.SomeDataMapManger;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.compass.CompassOverlay;
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
public class BasicMapTestActivity2 extends AppCompatActivity implements View.OnClickListener {
private MapView mapView;
//地图旋转
private RotationGestureOverlay mRotationGestureOverlay;
//比例尺
private ScaleBarOverlay mScaleBarOverlay;
//指南针方向
private CompassOverlay mCompassOverlay = null;
//设置导航图标的位置
private MyLocationNewOverlay mLocationOverlay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basic_test_2);
initView();
}
private void initView() {
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
mapView = (MapView) findViewById(R.id.mymapview);
mapView.setDrawingCacheEnabled(true);
mapView.setMaxZoomLevel(20);
mapView.setMinZoomLevel(6);
mapView.getController().setZoom(12);
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.setUseDataConnection(true);
mapView.setMultiTouchControls(true);// 触控放大缩小
//是否显示地图数据源
mapView.getOverlayManager().getTilesOverlay().setEnabled(true);
//地图自由旋转
mRotationGestureOverlay = new RotationGestureOverlay(mapView);
mRotationGestureOverlay.setEnabled(true);
mapView.getOverlays().add(this.mRotationGestureOverlay);
//比例尺配置
final DisplayMetrics dm = getResources().getDisplayMetrics();
mScaleBarOverlay = new ScaleBarOverlay(mapView);
mScaleBarOverlay.setCentred(true);
mScaleBarOverlay.setAlignBottom(true); //底部显示
mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);
mapView.getOverlays().add(this.mScaleBarOverlay);
//指南针方向
mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
mapView);
mCompassOverlay.enableCompass();
mapView.getOverlays().add(this.mCompassOverlay);
//设置导航图标
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),
mapView);
mapView.getOverlays().add(this.mLocationOverlay);
mLocationOverlay.enableMyLocation(); //设置可视
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
//定位当前的位置,并设置缩放级别
mapView.getController().setZoom(18);
mapView.getController().setCenter(new GeoPoint(23.12648183, 113.365548756));
break;
case R.id.button2: //绘制点
// add overlay
mapView.getOverlays().add(CustomPointOverlay.GetInstance());
break;
case R.id.button3://屏幕点击的坐标
//这个功能的使用,需要打开gps,就是说gps有数据
MyLocationOverlayWithClick overlay = new MyLocationOverlayWithClick(mapView);
overlay.enableFollowLocation();
overlay.enableMyLocation();
mapView.getOverlayManager().add(overlay);
break;
case R.id.button4:
SomeDataMapManger.initGeoJsonData(mapView,this);
mapView.getController().setZoom(12);
mapView.getController().setCenter(new GeoPoint(23.12648183, 113.365548756));
break;
}
}
public static class MyLocationOverlayWithClick extends MyLocationNewOverlay{
public MyLocationOverlayWithClick(MapView mapView) {
super(mapView);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e, MapView map) {
if (getLastFix() != null)
Toast.makeText(map.getContext(), "Tap! I am at " + getLastFix().getLatitude() + "," + getLastFix().getLongitude(), Toast.LENGTH_LONG).show();
return true;
}
}
@Override
public void onPause() {
this.mLocationOverlay.disableMyLocation();
super.onPause();
}
@Override
public void onResume() {
super.onResume();
}
}