前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >下载谷歌离线地图瓦片图「建议收藏」

下载谷歌离线地图瓦片图「建议收藏」

作者头像
全栈程序员站长
发布2022-11-08 11:26:08
2.4K1
发布2022-11-08 11:26:08
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

项目中遇到一个需求,需要将某个地图区域的离线地图下载下来,整理很多网上的资料自己实现根据起始点的经纬度下载离线地图,代码如下

代码语言:javascript
复制
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Test {
private static final int  BUFFER_SIZE = 2 * 1024;
public static void main(String[] args) throws Exception {
double [] start = new double[]{36.03267263,103.480619123};//最大纬度 最小精度 起点
double [] end = new double[]{35.522920921,103.520211928};//最小纬度  最大精度  终点
// 36.03267263 103.480619123 35.522920921 103.520211928
int [] z = new int[] {8,9};
/**
* 谷歌地图地址参数
* lyrs = 类型
*
* h = roads only 路线图
* m = standard roadmap
* p = terrain 地形图
* r = somehow altered roadmap
* s = satellite only 卫星图
* t = terrain only
* y = hybrid 混合
*/
String src = "http://mt0.google.cn/vt/lyrs=m@180000000&hl=zh-CN&gl=cn&x=%s&y=%s&z=%s&s=Ga";
String targetDir  ="D:\\map";
//getGoogleMap(start,end,z,src,targetDir); //获取谷歌地图瓦片图
getFileInfo(targetDir);//获取下载之后的文件信息
toZip(targetDir, "D:/map.zip",true);//压缩下载的文件
}
/**
* 获取下载之后的文件信息
* @param targetDir
*/
public static  void getFileInfo(String targetDir){
File file = new File(targetDir);
System.out.println("下载后的文件大小:"+file.length()/1024+"M");
File[] files = file.listFiles();
for (File f : files){
String level = f.getName();
int count =0;
File[] cfiles = f.listFiles();
for (File cf : cfiles){
count+=cf.list().length;
}
System.out.println("L"+level+"文件数量: "+count);
}
}
/**
* 根据起始点经纬度获取地图信息
* @param startPoint 数组 如:new double[]{35.522920921,103.480619123};
* @param endPoint 数组 如:new double[]{36.033726441,103.520211928};
* @param z 地图级别 new int[] {8,9}; 0-17
* @param src 地图下载地址
* @param targetDir 本地保存的路径
* @throws IOException
*/
public static void getGoogleMap(double [] startPoint,double [] endPoint,int [] z,String src,String targetDir) throws IOException {
// int zoom = 15;
double minlat = startPoint[0]; //35.522920921
double minlon = startPoint[1];//103.480619123
double maxlat = endPoint[0];//36.033726441
double maxlon = endPoint[1];//103.520211928
for (int k = z[0]; k <= z[1]; k ++){
Map<String, Integer> minMap = getTileNumber(minlat, minlon, k);
Map<String, Integer> maxMap = getTileNumber(maxlat, maxlon, k);
int minX = minMap.get("x");
int minY = minMap.get("y") ;
int maxX = maxMap.get("x");
int maxY = maxMap.get("y");
//
for (int i = minX; i <= maxX; i++) {
for (int j = minY; j <= maxY; j++) {
String url = String.format(src, i, j, k);
System.out.println(url);
downLaodImages(url, i, j, k,targetDir);
}
}
}
}
/**
* 根据经纬度获取瓦片坐标 算法请参考
* https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
* @param lat
* @param lon
* @param zoom
* @return
*/
public static Map getTileNumber(final double lat, final double lon, final int zoom) {
Map<String,Integer> map = new HashMap<>();
int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
if (xtile < 0)
xtile=0;
if (xtile >= (1<<zoom))
xtile=((1<<zoom)-1);
if (ytile < 0)
ytile=0;
if (ytile >= (1<<zoom))
ytile=((1<<zoom)-1);
map.put("z",zoom);
map.put("x",xtile);
map.put("y",ytile);
return map;
}
/**
*
* @param url 下载图片的url
* @param x
* @param y
* @param z
* @throws IOException
*/
public static void downLaodImages(String url,int x,int y, int z,String targetDir) throws IOException {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
File zFile = new File(targetDir+"\\"+z);
if(!zFile.exists()){
zFile.mkdir();
}
File xFile = new File(targetDir+"\\"+z+"\\"+x);
if(!xFile.exists()){
xFile.mkdir();
}
DataInputStream dataInputStream = new DataInputStream(conn.getInputStream()) ;;
FileOutputStream fileOutputStream = null;
//根据坐标 x y z生成文件名 下载png无损图片
String imageName =  targetDir+"\\"+z+"\\"+x+"\\"+y+".png";
fileOutputStream = new FileOutputStream(new File(imageName));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = dataInputStream.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
fileOutputStream.write(output.toByteArray());
dataInputStream.close();
fileOutputStream.close();
output.close();
System.out.println("已完成下载!");
}
/**
* 压缩
*/
public static void toZip(String srcDir, String outName, boolean KeepDirStructure)
throws RuntimeException{
long start = System.currentTimeMillis();ZipOutputStream zos = null ;
try {
FileOutputStream out= new FileOutputStream(new File(outName));
zos = new ZipOutputStream(out);
File sourceFile = new File(srcDir);
compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("zip error",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void compress(File sourceFile, ZipOutputStream zos, String name,
boolean KeepDirStructure) throws Exception{
byte[] buf = new byte[BUFFER_SIZE];
if(sourceFile.isFile()){
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
} else {
//是文件夹
File[] listFiles = sourceFile.listFiles();
if(listFiles == null || listFiles.length == 0){
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if(KeepDirStructure){
// 空文件夹的处理
zos.putNextEntry(new ZipEntry(name + "/"));
// 没有文件,不需要文件的copy
zos.closeEntry();
}
}else {
for (File file : listFiles) {
// 判断是否需要保留原来的文件结构
if (KeepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
} else {
compress(file, zos, file.getName(),KeepDirStructure);
}
}
}
}
}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/191235.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月20日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档