由于需求,许多时候需要用到离线地图。
参考了如下:
离线地图的制作 https://blog.csdn.net/bobantangzlt/article/details/22403817
在线开发文档:https://www.jianshu.com/p/0075bc78e4f0
osmdroid github:https://link.jianshu.com/?t=https://github.com/osmdroid/osmdroid
因为我是使用的是ecplise 所以引用jar包
adnroid studio :看看这个https://www.jianshu.com/p/0075bc78e4f0
资源:地图工具与jar包链接:链接:https://pan.baidu.com/s/1FkrcJbURn66KMZ2WOIhmUQ 密码:bz8a,
一 Mobile_Atlas_Creator_1.8的使用
1.Map source
选择Microsoft Maps China(因为其他地图源都不怎么行,没开APN的问题?)
2.zoom levels
选择你需要的发大比例,可以多选,放数值越大下载的地图瓦块也多,离线地图包就越大。自行选择。
3.地图的选择
选择所要制作离线地图的区域,可以通过长按鼠标左键并且拖拽选择,也可以在软件左侧-坐标信息填写经纬度范围去选择,选择好之后记得点击“选择该区域”按钮;
,
4点击Atlas Content下的Mapnik,确定好自己勾选的zoom levels,点击Add selection,再点击create atlas 开始下载
好了,离线地图就下载好了。地图路径:Mobile_Atlas_Creator_1.8\Mobile_Atlas_Creator_1.8\atlases
二 离线地图的加载
权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
提示:编译版本为23或以上版本,要注意动态获取读写存储空间权限,否则地图可能不显示
布局:
<org.osmdroid.views.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
读取离线地图方法
private void readMap(File f) {
//f是离线地图的压缩包(Mapnik .zip的路径获取的file)
if (f.exists()) {
File[] list = f.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
continue;
}
String name = list[i].getName().toLowerCase();
if (!name.contains(".")) {
continue; // 跳过没有扩展名的文件
}
name = name.substring(name.lastIndexOf(".") + 1);
if (name.length() == 0) {
continue;
}
if (ArchiveFileFactory.isFileExtensionRegistered(name)) {
try {
// ok found a file we support and have a driver for
// the format, for this demo, we'll just use the
// first one
// 离线创建的provider瓦,它只会做
// 离线文件archives
// 一次使用的第一个文件
OfflineTileProvider tileProvider = new OfflineTileProvider(
new SimpleRegisterReceiver(getActivity()),
new File[] { list[i] });
// tell osmdroid to use that provider instead of the
// default rig which is (asserts, cache,
// files/archives, online
mMapView.setTileProvider(tileProvider);
// this bit enables us to find out what tiles
// sources are available. note, that this action may
// take some time to run
// and should be ran asynchronously. we've put it
// inline for simplicity
String source = "";
IArchiveFile[] archives = tileProvider
.getArchives();
if (archives.length > 0) {
// cheating a bit here, get the first archive
// file and ask for the tile sources names it
// contains
Set<String> tileSources = archives[0]
.getTileSources();
// presumably, this would be a great place to
// tell your users which tiles sources are
// available
if (!tileSources.isEmpty()) {
// ok good, we found at least one tile
// source, create a basic file based tile
// source using that name
// and set it. If we don't set it, osmdroid
// will attempt to use the default source,
// which is "MAPNIK",
// which probably won't match your offline
// tile source, unless it's MAPNIK
source = tileSources.iterator().next();
this.mMapView
.setTileSource(FileBasedTileSource
.getSource(source));
} else {
this.mMapView
.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
} else {
this.mMapView
.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
// Toast.makeText(
// this,
// "Using " + list[i].getAbsolutePath() + " "
// + source, Toast.LENGTH_SHORT)
// .show();
this.mMapView.invalidate();
return;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
// Toast.makeText(
// this,
// f.getAbsolutePath()
// + " did not have any files I can open! Try using MOBAC",
// Toast.LENGTH_SHORT).show();
} else {
// Toast.makeText(this, f.getAbsolutePath() + " dir not found!",
// Toast.LENGTH_SHORT).show();
}
}
地图初始化
private MapView mMapView;
private IMapController mapControl;
public View CreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_national_weather,
container, false);
mMapView = (MapView) view.findViewById(R.id.mapView);
mMapView.setUseDataConnection(false); // 设置取消通过网络加载
readMap(China);//加载离线地图
mMapView.setClickable(true);//设置可点击
mMapView.setBuiltInZoomControls(true);//放大缩小功能开启
mapControl = mMapView.getController();//获得控制器
mMapView.setMultiTouchControls(true);// 设置多指触控可用
mMapView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);// 关闭硬件加速(绘制轨迹时需要)
mMapView.getOverlays().clear();//清空地图上的标记
GeoPoint cententGeo=new GeoPoint(37.926868, 112.543945);
mapControl.setCenter(cententGeo);//设置地图中心点,注意中心点请根据自己截取的地图,获取其中点的经纬度
mMapView.setMinZoomLevel(6); //设置最小放大级别
mMapView.setMaxZoomLevel(7);//设置最大放大级别
mapControl.setZoom(6);//设置缩放级别
}
//添加maker
private void addPointe(GeoPoint dian, Drawable draw) {
Marker marker = new Marker(mMapView);
marker.setIcon(draw);// 设置图标
marker.setPosition(dian);// 设置位置
marker.setAnchor(0.5f, 1f);// 设置偏移量
// marker.setTitle("我是Titile");//设置标题
// marker.setSubDescription("我是SubDescription");//设置说明
mMapView.getOverlays().add(marker);// 添加marker到MapView
}