百度地图离线瓦片下载(java版)

注意改一下自己的ak

注意修改div的宽高、缩放比例、以及地图中心店经纬度      

 int width = 500;//地图div宽度
 int height = 500;//地图div高度
  int zoomLevel = 10;

package com.demo;




import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.net.URL;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;

public class BaiduMapDownloadDemo {
	public static int calcIdx = 1;
	public static int count = 0;
	private static String targetDir = "d:\\bMapImg\\beijing"; //下载目标文件夹
	private static String sourceDataFile = "d:\\bMapImgNew\\beijingMapData.txt"; //瓦片数据文件
	private static ExecutorService threadPool;
	
	private static Double EARTHRADIUS = 6370996.81;
	private static Double[] MCBAND = { 12890594.86, 8362377.87, 5591021d,
			3481989.83, 1678043.12, 0d };
	private static Double[] LLBAND = { 75d, 60d, 45d, 30d, 15d, 0d };
	private static Double[][] MC2LL = {
			{ 1.410526172116255e-8, 0.00000898305509648872, -1.9939833816331,
					200.9824383106796, -187.2403703815547, 91.6087516669843,
					-23.38765649603339, 2.57121317296198, -0.03801003308653,
					17337981.2 },
			{ -7.435856389565537e-9, 0.000008983055097726239,
					-0.78625201886289, 96.32687599759846, -1.85204757529826,
					-59.36935905485877, 47.40033549296737, -16.50741931063887,
					2.28786674699375, 10260144.86 },
			{ -3.030883460898826e-8, 0.00000898305509983578, 0.30071316287616,
					59.74293618442277, 7.357984074871, -25.38371002664745,
					13.45380521110908, -3.29883767235584, 0.32710905363475,
					6856817.37 },
			{ -1.981981304930552e-8, 0.000008983055099779535, 0.03278182852591,
					40.31678527705744, 0.65659298677277, -4.44255534477492,
					0.85341911805263, 0.12923347998204, -0.04625736007561,
					4482777.06 },
			{ 3.09191371068437e-9, 0.000008983055096812155, 0.00006995724062,
					23.10934304144901, -0.00023663490511, -0.6321817810242,
					-0.00663494467273, 0.03430082397953, -0.00466043876332,
					2555164.4 },
			{ 2.890871144776878e-9, 0.000008983055095805407, -3.068298e-8,
					7.47137025468032, -0.00000353937994, -0.02145144861037,
					-0.00001234426596, 0.00010322952773, -0.00000323890364,
					826088.5 } };
	private static Double[][] LL2MC = {
			{ -0.0015702102444, 111320.7020616939, 1704480524535203d,
					-10338987376042340d, 26112667856603880d,
					-35149669176653700d, 26595700718403920d,
					-10725012454188240d, 1800819912950474d, 82.5 },
			{ 0.0008277824516172526, 111320.7020463578, 647795574.6671607,
					-4082003173.641316, 10774905663.51142, -15171875531.51559,
					12053065338.62167, -5124939663.577472, 913311935.9512032,
					67.5 },
			{ 0.00337398766765, 111320.7020202162, 4481351.045890365,
					-23393751.19931662, 79682215.47186455, -115964993.2797253,
					97236711.15602145, -43661946.33752821, 8477230.501135234,
					52.5 },
			{ 0.00220636496208, 111320.7020209128, 51751.86112841131,
					3796837.749470245, 992013.7397791013, -1221952.21711287,
					1340652.697009075, -620943.6990984312, 144416.9293806241,
					37.5 },
			{ -0.0003441963504368392, 111320.7020576856, 278.2353980772752,
					2485758.690035394, 6070.750963243378, 54821.18345352118,
					9540.606633304236, -2710.55326746645, 1405.483844121726,
					22.5 },
			{ -0.0003218135878613132, 111320.7020701615, 0.00369383431289,
					823725.6402795718, 0.46104986909093, 2351.343141331292,
					1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45 } };
	
	public static void downloadBaiduMapPic(String dir,String dataFile){
		targetDir = dir;
		sourceDataFile = dataFile;
		threadPool = Executors.newFixedThreadPool(10);
		try {
			//2019-6-4发现百度地图增加SESSION校验,先获取SESSION
			//HttpClientDemo demo = new HttpClientDemo();
			String urlLogin = "http://lbsyun.baidu.com/custom/";
			DefaultHttpClient client = new DefaultHttpClient(
					new PoolingClientConnectionManager());

			HttpPost post = new HttpPost(urlLogin);
			HttpResponse response = client.execute(post);
			HttpEntity entity = response.getEntity();
			CookieStore cookieStore = client.getCookieStore();
			client.setCookieStore(cookieStore);
			//遍历数据
			LineNumberReader lnr = new LineNumberReader(new FileReader(sourceDataFile));
	        lnr.skip(Long.MAX_VALUE);
	        count = lnr.getLineNumber() + 1;
	        lnr.close();
            FileInputStream fileInputStream = new FileInputStream(new File(sourceDataFile));
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String text = null;
            while((text = bufferedReader.readLine()) != null){
            	String[] data = text.split(",");
//包含瓦片样式
            	String uri = "http://api1.map.bdimg.com/customimage/tile?&x="+data[1]+"&y="+data[2]+"&z="+data[0]+
            			"&udt=20190425&scale=1&ak=这里改成自己的AK&"
            			+ "styles=t%3Awater%7Ce%3Aall%7Cc%3A%230E69A7%2Ct%3Ahighway%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Ahighway%7Ce%3Ag.s%7Cc%3A%23147a92%2Ct%3Aarterial%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Alocal"
            			+ "%7Ce%3Ag%7Cc%3A%23000000%2Ct%3Aland%7Ce%3Aall%7Cc%3A%2308304b%2Ct%3Arailway%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Arailway%7Ce"
            			+ "%3Ag.s%7Cc%3A%2308304b%2Ct%3Aall%7Ce%3Al.t.f%7Cc%3A%23857f7f%2Ct%3Aall%7Ce%3Al.t.s%7Cc%3A%23000000%2Ct%3Agreen%7Ce%3Ag%7Cc"
            			+ "%3A%23062032%2Ct%3Aboundary%7Ce%3Aall%7Cc%3A%23AB101C%7Cw%3A1.5%2Ct%3Aall%7Ce%3Al.i%7Cv%3Aoff%2Ct%3Aall%7Ce%3Al.t.f%7Cv"
            			+ "%3Aon%7Cc%3A%232da0c6%2Ct%3Aroad%7Ce%3Al.t.f%7Cv%3Aoff%7Cc%3A%232da0c6";
            	//String uri = "http://api1.map.bdimg.com/customimage/tile?&x="+data[1]+"&y="+data[2]+"&z="+data[0]+"&udt=20171128&scale=1&ak=offlinekey&customid=midnight";
            	HttpGet get = new HttpGet(uri);
        		get.addHeader("Accept","image/webp,image/*,*/*;q=0.8");
        		get.addHeader("Accept-Encoding","gzip, deflate, sdch");
        		get.addHeader("Accept-Language","zh-CN,zh;q=0.8");
        		get.addHeader("Cache-Control","no-cache");
        		get.addHeader("Connection","keep-alive");
        		get.addHeader("Host","api1.map.bdimg.com");
        		get.addHeader("Pragma","no-cache");
        		get.addHeader("Referer","http://lbsyun.baidu.com/custom/");
        		get.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36");
            	DownLoadThread t = new DownLoadThread(data[1], ""+Math.abs(Integer.parseInt(data[2])), data[0], targetDir, 

get,response,client);
            	threadPool.execute(t);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
	}
	
	public static void main(String[] args) {
		//获取瓦片
		BaiduMapDownloadDemo.downloadBaiduMapPic("F:\\bMapImg3\\beijing", "F:\\bMapImgNew\\333.txt");
		
		//计算瓦片,将计算出的瓦片地址放入333.txt中
		 Map<String, Double> location = convertMC2LL(13372307.47, 3514145.00);
		 location = convertLL2MC(location.get("lng"),location.get("lat"));
		 System.out.println(location);
		 
		 int width = 500;//地图div宽度
		 int height = 500;//地图div高度
		 int zoomLevel = 10;
		 Map<String, Double> centerLL = new HashMap<String, Double>();
		 centerLL.put("lng", 116.3964D);
		 centerLL.put("lat", 39.9093D);
		 Map<String, Double> center = convertLL2MC(centerLL.get("lng"),centerLL.get("lat"));
		 System.out.println(location);
		 
		 
		 double cV = Math.pow(2, 18-zoomLevel);//现在直接计算这个数。理论不变,代码变了,我们直接计算好了。
		 double unitSize = cV * 256; //这个也只能自己计算了//mapType.getZoomFactor(zoomLevel);// 一个系数,=cV*256
		 double longitudeUnits = Math.ceil(center.get("x") / unitSize);// center.lng是一个很大的数
		 double latitudeUnits = Math.ceil(center.get("y") / unitSize);//这两个不用解释了吧
		 double tileSize = 256; //这个直接给常亮吧。要不得是mapType.k.Ob//mapType.getTileSize();
		 double[] cP = new double[]{ longitudeUnits,
		                 latitudeUnits,
		                 (center.get("x") - longitudeUnits * unitSize) / unitSize * tileSize,
		                 (center.get("y") - latitudeUnits * unitSize) / unitSize * tileSize };
		 double left = (cP[0] - Math.ceil((width / 2 - cP[2]) / tileSize));
		 double top =  (cP[1] - Math.ceil((height / 2 - cP[3]) / tileSize));
		 double right =  (cP[0] + Math.ceil((width / 2 + cP[2]) / tileSize));
		 double c0 = 0;
		    //if (mapType === BMAP_PERSPECTIVE_MAP && map.getZoom() == 15) {//这句应该不起作用
		    //    c0 = 1
		    //}
		 double bottom =  (cP[1] + Math.ceil((height / 2 + cP[3]) / tileSize) + c0);
		 List<String> xydata = new ArrayList<String>();
		    for (double i = left; i < right; i++) {
		        for (double j = top; j < bottom; j++) {
		        	System.out.println(zoomLevel+","+(int)i+","+ (int)j);
		            xydata.add(zoomLevel+","+(int)i+","+ (int)j);
		        }
		    }
		  //这个地方能直接获取瓦片地址的内部方法,挺好,省去了很多的代码移植。
//		    var getTilesUrl = map.getMapType().getTileLayer().getTilesUrl;
//		    //循环获取代码吧
//		    for (var i = 0, len = xydata.length; i < len; i++) {
//		        var url = getTilesUrl({x:xydata[i][0],y:xydata[i][1]}, zoomLevel, "normal");
//		        var path = zoomLevel+"/"+xydata[i][0]+"/"+xydata[i][1]+".png";
//		        if(!!callback){
//		            callback(path, url);
//		        }
//		    }        
		   
		 

		 
//		 根据百度经纬度计算出来墨卡托坐标后,将结果除以地图分辨率Math.Pow(2,18-zoom)即可得到平面像素坐标,然后将像素坐标除以256分别得到瓦片的行列号。
//		 
		 
//		String geo = "4|12928784.8679,4580889.0672;12928884.0335,4581026.05389|1-12928784.8679,4581018.53244,12928879.8193,4581026.05389,12928884.0335,4580966.20191,12928847.7346,4580961.14681,12928844.1937,4580957.53999,12928850.7314,4580891.67584,12928791.9678,4580889.0672,12928784.8679,4581018.53244;";
//		List<String> mocatorList = parseJeo(geo);
//		StringBuilder sb = new StringBuilder();
//		for (int i = 0; i < mocatorList.size(); i++) {
//			String[] coordinate = mocatorList.get(i).split("\\#");
//			Map<String, Double> location = convertMC2LL(
//					Double.parseDouble(coordinate[0]),
//					Double.parseDouble(coordinate[1]));
//			Double lng = location.get("lng");
//			Double lat = location.get("lat");
//			String coord = lng + "," + lat;
//			sb.append(coord);
//			if (i < mocatorList.size() - 1) {
//				sb.append(";");
//			}
//		}
//		System.out.println(sb.toString());
	}

	/**
	 * 解析Jeo数据
	 * 
	 * @param mocator
	 */
	public static List<String> parseJeo(String mocator) {
		List<String> mocatorList = new ArrayList<String>();

		if (null == mocator)
			return null;
		/* 拆分数据 */
		String[] geos = mocator.split("\\|");
		int n = Integer.parseInt(geos[0]);
		String center = geos[1];
		String polylineMoca = geos[2]; // 墨卡托坐标
		String[] plm = polylineMoca.split("\\;");

		/* 获取墨卡托边界 */
		String geo = null;
		if (n == 4) {
			for (int i = 0; i < plm.length; i++) {
				String[] geoPaths = plm[i].split("\\-");
				if (geoPaths[0].equals("1")) {
					geo = geoPaths[1];
				}
			}
		}
		// 墨卡托坐标解析
		String[] geoPolyline = geo.split("\\,");
		for (int i = 0; i < geoPolyline.length; i += 2) {
			mocatorList.add(geoPolyline[i] + "#" + geoPolyline[i + 1]);
		}

		return mocatorList;
	}

	/**
	 * 墨卡托坐标转经纬度坐标
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public static Map<String, Double> convertMC2LL(Double x, Double y) {
		Double[] cF = null;
		x = Math.abs(x);
		y = Math.abs(y);
		for (int cE = 0; cE < MCBAND.length; cE++) {
			if (y >= MCBAND[cE]) {
				cF = MC2LL[cE];
				break;
			}
		}
		Map<String, Double> location = converter(x, y, cF);
		location.put("lng", location.get("x"));
		location.remove("x");
		location.put("lat", location.get("y"));
		location.remove("y");
		return location;
	}

	/**
	 * 经纬度坐标转墨卡托坐标
	 * 
	 * @param lng
	 * @param lat
	 * @return
	 */
	public static Map<String, Double> convertLL2MC(Double lng, Double lat) {
		Double[] cE = null;
		lng = getLoop(lng, -180, 180);
		lat = getRange(lat, -74, 74);
		for (int i = 0; i < LLBAND.length; i++) {
			if (lat >= LLBAND[i]) {
				cE = LL2MC[i];
				break;
			}
		}
		if (cE != null) {
			for (int i = LLBAND.length - 1; i >= 0; i--) {
				if (lat <= -LLBAND[i]) {
					cE = LL2MC[i];
					break;
				}
			}
		}
		return converter(lng, lat, cE);
	}

	private static Map<String, Double> converter(Double x, Double y, Double[] cE) {
		Double xTemp = cE[0] + cE[1] * Math.abs(x);
		Double cC = Math.abs(y) / cE[9];
		Double yTemp = cE[2] + cE[3] * cC + cE[4] * cC * cC + cE[5] * cC * cC
				* cC + cE[6] * cC * cC * cC * cC + cE[7] * cC * cC * cC * cC
				* cC + cE[8] * cC * cC * cC * cC * cC * cC;
		xTemp *= (x < 0 ? -1 : 1);
		yTemp *= (y < 0 ? -1 : 1);
		Map<String, Double> location = new HashMap<String, Double>();
		location.put("x", xTemp);
		location.put("y", yTemp);
		return location;
	}

	private static Double getLoop(Double lng, Integer min, Integer max) {
		while (lng > max) {
			lng -= max - min;
		}
		while (lng < min) {
			lng += max - min;
		}
		return lng;
	}

	private static Double getRange(Double lat, Integer min, Integer max) {
		if (min != null) {
			lat = Math.max(lat, min);
		}
		if (max != null) {
			lat = Math.min(lat, max);
		}
		return lat;
	}
	public static void collectMapData(String sourceDir,String targetFile){
		try{
			File rootFile = new File(sourceDir);
			File[] zFiles = rootFile.listFiles();
			for(File zFile :zFiles){
				String zName = "";
				if(zFile.isDirectory()){
					zName = zFile.getName();
					File[] xFiles = zFile.listFiles();
					for(File xFile:xFiles){
						String xName = xFile.getName();
						File[] yFiles = xFile.listFiles();
						for(File yFile:yFiles){
							String yName = yFile.getName();
							yName = yName.substring(0,yName.indexOf("."));
							appendTofile(targetFile,zName+","+xName+","+yName);
						}
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	private static void appendTofile(String targetFile,String content) {
		FileWriter fw = null;
		try {
			File f = new File(targetFile);
			fw = new FileWriter(f, true);
		} catch (Exception e) {
			e.printStackTrace();
		}
		PrintWriter pw = new PrintWriter(fw);
		pw.println(content);
		pw.flush();
		try {
			fw.flush();
			pw.close();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private static void writeToFile(File file,String content){
        try {
            if(file.exists()){
                FileWriter fw = new FileWriter(file,true);
                BufferedWriter bw = new BufferedWriter(fw);
                bw.write(content);
                bw.close();
                fw.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class DownLoadThread implements Runnable{
	private String x;
	private String y;
	private String z;
	private String targetDir;
	private HttpGet get;
	private HttpResponse response;
	private DefaultHttpClient client;
	
	DownLoadThread(String x,String y,String z,String targetDir,HttpGet get,HttpResponse response,DefaultHttpClient 

client){
		this.x = x;
		this.y = y;
		this.z = z;
		this.targetDir = targetDir;
		this.get = get;
		this.response = response;
		this.client = client;
	}
	@Override
	public void run() {
        DataInputStream dataInputStream = null;
        FileOutputStream fileOutputStream = null;
        NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMinimumFractionDigits(2);
        try {
        	HttpEntity entity = response.getEntity();
        	response = client.execute(get);
    		entity = response.getEntity();
            dataInputStream = new DataInputStream(entity.getContent());
            //检查文件夹是否存在
            File zFile = new File(targetDir+"\\"+z);
            if(!zFile.exists()){
            	zFile.mkdir();
            }
            File xFile = new File(targetDir+"\\"+z+"\\"+x);
            if(!xFile.exists()){
            	xFile.mkdir();
            }
            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("已完成:"+BaiduMapDownloadDemo.calcIdx+"/"+BaiduMapDownloadDemo.count+"("+nf.format((BaiduMapDownloadDemo.calcIdx/(BaiduMapDownloadDemo.count*1.0))*100)+"%)");
            BaiduMapDownloadDemo.calcIdx++;
        }catch (Exception e) {
            e.printStackTrace();
        }
	}
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 百度地图webgl矢量下载是一项非常实用的功能,它可以方便用户下载百度地图中的矢量数据,使得用户可以将这些矢量数据用于自己的项目中。这项功能的实现基于webgl技术,将百度地图中的原始地图数据处理后,转化为矢量数据。 使用这项功能,用户可以先选择需要下载的区域,接着可以设置下载的矢量数据类型和输出格式,并设置矢量数据的分辨率等参数。下载完成后,用户可以获得一个zip文件,其中包含了转化后的矢量数据文件和相应的元数据。 该功能的应用范围非常广泛,包括但不限于地图制作、地理信息系统、城市规划等领域。对于科研人员和开发者来说尤为实用,因为他们可以自由定制矢量数据,并将其应用于自己的研究中。 总之,百度地图webgl矢量下载是一项非常实用的功能,它不仅丰富了百度地图的数据应用,也方便了用户下载矢量数据,满足了用户的个性化需求,同时也为相关领域的科研和开发提供了更多的数据资源。 ### 回答2: 在百度地图中,我们可以通过webgl矢量下载下载各种地图数据。这项功能提供了高质量、高精度的地图数据,可以帮助我们更好地了解和掌握地理信息。 使用百度地图 webgl矢量下载,用户只需在网上搜索相关地图信息之后,选择需要下载的地图数据,然后进行下载即可。下载的地图数据包含各种电子地图信息、交通信息、地形信息、建筑物信息等等,能够为用户提供全方位的地理信息,非常实用。 在下载过程中,用户还可以选择下载不同的地图数据类型,包括电子地图、卫星地图、交通地图、户外地图等等,从而满足不同用户的需求。同时,用户还可以根据自己的需求进行筛选和过滤,只下载需要的地图数据,避免下载过多无用的数据,更加方便快捷。 总之,百度地图的webgl矢量下载功能极大地方便了用户对地理信息的获取和处理,让我们更加便捷地获取最新的地图数据,掌握最全面的地理信息,为我们的出行和生活提供更多的便利。 ### 回答3: 百度地图推出的webgl矢量下载功能是一个非常实用的工具,可以让用户方便地下载各种地图数据,以便离线使用和定制地图。 首先,webgl矢量下载可以让用户下载各种矢量数据,如道路、建筑、河流、边界等,这些数据是非常有用的,可以让用户更加详细地了解所研究的地区和环境,也方便用户进行一些自定义的操作。 其次,webgl矢量下载的数据量也非常大,这意味着用户可以下载更加详细、更加丰富的地图数据,以满足各种不同的需求。用户可以根据自己的需要选择下载的数据类型和范围,这样可以避免不必要的下载和浪费。同时,百度地图还提供了离线导航功能,让用户能够在没有网络的情况下轻松使用地图。 总之,百度地图 webgl矢量下载是一个非常实用的工具,可以让用户获取更加详细和丰富的地图数据,方便大家进行各种研究和定制操作,值得广大用户使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牟云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值