百度地图 自定义图层 工具 原理 参考地址 百度地图自定义图层----BMapTileCutterJava切图工具网络版
最近做百度 地图api相关应用开发,需要将自己的地图叠加到百度 地图上面,查看了百度 官方的api说明javascript部分,不没有很好的解释如何覆盖接口。
在网上找了相关的文章看了下,(http://www.makaidong.com/jz1108/archive/2011/10/08/2202239.html)这篇文章实现了这个切图的功能,但是最新的百度 最高缩放等级达到19级,项目需要,无奈只能自己写个切图开发工具。
参考了同样作者的另一篇文章(http://www.makaidong.com/jz1108/archive/2011/07/02/2095376.html),专门讲百度 坐标系统开发的。
程序是用java web实现, struts 2文件标签和简单js 调用。
实现核心代码
1.tileutils.java
1 package com.xiefei.core; 2 3 import java.awt.graphics2d; 4 import java.awt.image; 5 import java.awt.toolkit; 6 import java.awt.transparency; 7 import java.awt.image.bufferedimage; 8 import java.awt.image.cropimagefilter; 9 import java.awt.image.filteredimagesource; 10 import java.awt.image.imagefilter; 11 import java.io.file; 12 13 import javax.imageio.imageio; 14 15 public class tileutils { 16 private int minlevel; 17 private int maxlevel; 18 private int piclevel; 19 private double mercatorx; 20 private double mercatory; 21 private string pic; 22 private string savepath; 23 24 public tileutils(string pic, double mercatorx, double mercatory, 25 string savepath) { 26 this.pic = pic; 27 this.mercatorx = mercatorx; 28 this.mercatory = mercatory; 29 this.savepath = savepath; 30 } 31 32 public tileutils(string pic, int minlevel, int maxlevel, int piclevel, double mercatorx, 33 double mercatory, string savepath) { 34 this.pic = pic; 35 this.minlevel = minlevel; 36 this.maxlevel = maxlevel; 37 this.mercatorx = mercatorx; 38 this.mercatory = mercatory; 39 this.savepath = savepath; 40 this.piclevel = piclevel; 41 } 42 43 public void cutterall() throws exception { 44 for (int i = minlevel; i <= maxlevel; i++) { 45 cutterone(i); 46 } 47 } 48 49 public void cutterone(int level) throws exception { 50 //图片中心的像素坐标(pixelx,pixely),图片中心的平面坐标即魔卡托坐标(mercatorx, mercatory) 51 //像素坐标 = 平面坐标 * math.pow(2, level - 18) 52 double pixelx = mercatorx * math.pow(2, level - 18); 53 double pixely = mercatory * math.pow(2, level - 18); 54 system.out.println("pixelx : " + pixelx); 55 system.out.println("pixely : " + pixely); 56 bufferedimage bi = imageio.read(new file(pic)); 57 int width = bi.getwidth(); 58 int height = bi.getheight(); 59 //图片遵循原则:当前图片所属级别piclevel不缩放即像素级别相等。 60 //按照公式缩放:当前级别图片长度 = 原图片长度 * math.pow(2, level - piclevel) 61 //minx: 图片左下角x坐标 62 //miny: 图片左下角y坐标 63 //maxx: 图片右上角x坐标 64 //maxy: 图片右上角y坐标 65 double minx = pixelx - width * math.pow(2, level - piclevel) / 2; 66 double miny = pixely - height * math.pow(2, level - piclevel) / 2; 67 double maxx = pixelx + width * math.pow(2, level - piclevel) / 2; 68 double maxy = pixely + height * math.pow(2, level - piclevel) / 2; 69 system.out.println("(minx,miny) = (" + minx + ", " + miny + ")" ); 70 system.out.println("(maxx,maxy) = (" + maxx + ", " + maxy + ")" ); 71 int neatminx = (int) minx / 256; 72 int remminx = (int) minx % 256; 73 int neatminy = (int) miny / 256; 74 int remminy = (int) miny % 256 ; 75 76 int neatmaxx = (int) maxx / 256; 77 int remmaxx = 256 - (int) maxx % 256; 78 int neatmaxy = (int) maxy / 256; 79 int remmaxy = 256 - (int) maxy % 256; 80 //(neatminx,neatminy)为图片左下角最近的整数图块坐标,neatminx到neatmaxx即当前级别下切割图块的图块坐标x 81 //(neatmaxx,neatmaxy)为图片右上角最近的整数图块坐标,neatminy到neatmaxy即当前级别下切割图块的图块坐标y 82 system.out.println("neatminx: " + neatminx); 83 system.out.println("neatmaxx: " + neatmaxx); 84 system.out.println("neatminy: " + neatminy); 85 system.out.println("neatmaxy: " + neatmaxy); 86 system.out.println("remminx width remmaxx : " + remminx + " "+ width + " "+ remmaxx ); 87 system.out.println("remminy height remmaxy : " + remminy + " " + height +" " + remmaxy ); 88 89 // 扩充原图片为width * height --- > (remminx + width + remmaxx ) * (remminy + 90 // height +remmaxy) 91 int extendwidth = (neatmaxx - neatminx + 1 ) * 256; 92 int extendheight = (neatmaxy - neatminy + 1 ) * 256; 93 system.out.println("extendwidth: " + extendwidth); 94 system.out.println("extendheight: " + extendheight); 95 96 bufferedimage outputimage = null; 97 graphics2d g = bi.creategraphics(); 98 bufferedimage extend = g.getdeviceconfiguration().createcompatibleimage(extendwidth, extendheight, transparency.translucent); 99 g.dispose();100 g = extend.creategraphics();101 g.drawimage(extend, 0, 0, extendwidth, extendheight, null);102 g.drawimage(bi, remminx, remmaxy, (int) (width * math.pow(2, level - piclevel)), (int)(height * math.pow(2, level - piclevel)), null);103 outputimage = extend;104 105 //切割图片,共( neatmaxx - neatminx + 1) * (neatmaxy - neatminy + 1)份 256*256图片106 string dirname = savepath.substring(0, savepath.lastindexof("\\")) + "\\tiles\\" + level;107 system.out.println("dirname : " + dirname);108 109 110 file dir = new file(dirname);111 image image = extend.getscaledinstance(extendwidth, extendheight, image.scale_default);112 if(dir.exists()) {113 system.out.println("创建目录失败!, 目录已存在!");114 } else {115 if(dir.mkdirs()) {116 imageio.write(extend, "png", new file(dirname + savepath.substring(savepath.lastindexof("\\"))));117 system.out.println("savepath : " + dirname + savepath.substring(savepath.lastindexof("\\")));118 system.out.println("extend success!");119 int w = neatmaxx - neatminx + 1;120 int h = neatmaxy - neatminy + 1;121 for(int i = 0; i < w; i++) {122 for(int j = 1; j <= h; j++) {123 imagefilter cropfilter = new cropimagefilter(256 * i, 256* (h - j), 256, 256);124 image img = toolkit.getdefaulttoolkit().createimage(new filteredimagesource(image.getsource(),cropfilter));125 bufferedimage tag = new bufferedimage(256, 256 , bufferedimage.type_int_bgr);126 graphics2d gs = tag.creategraphics();127 tag = gs.getdeviceconfiguration().createcompatibleimage(256, 256, transparency.translucent);128 gs.dispose();129 gs = tag.creategraphics();130 gs.drawimage(img, 0, 0, null);131 g.dispose();132 string croppicname = dirname + "\\tile" + (neatminx + i) + "_" + (neatminy + j - 1) + ".png"; 133 imageio.write(tag, "png", new file(croppicname));134 }135 }136 system.out.println("切割图片成功!");137 } else {138 system.out.println("创建目录失败!");139 }140 }141 }142 143 }
代码的核心思想是将原图片
<iframe id="cproIframe_u1513126_3" width="640" height="60" src="http://release.baidu.com/acom?adn=4&at=231&aurl=&cad=1&ccd=24&cec=UTF-8&cfv=0&ch=0&col=zh-CN&conBW=0&conOP=1&cpa=1&dai=3&dis=0&layout_filter=image&ltr=http%3A%2F%2Fwww.makaidong.com%2F%25E5%258D%259A%25E5%25AE%25A2%25E5%259B%25AD%25E7%2589%259B%2F31781.shtml&ltu=http%3A%2F%2Fwww.makaidong.com%2F%25E5%258D%259A%25E5%25AE%25A2%25E5%259B%25AD%25E7%2589%259B%2F31781.shtml&lu_161=6&lunum=6&n=00057180_cpr&pcs=1903x945&pis=10000x10000&ps=4368x426&psr=1920x1080&pss=1903x4368&qn=42dc7683add112f1&rad=&rsi0=640&rsi1=60&rsi5=4&rss0=%23FFFFFF&rss1=%23FFFFFF&rss2=%230000ff&rss3=%23000000&rss4=%23000000&rss5=&rss6=%23e10900&rss7=&scale=&skin=tabcloud_skin_3&stid=5&td_id=1513126&titFF=%E5%AE%8B%E4%BD%93&titFS=12&titTA=left&tn=text_default_640_60&tpr=1449574716094&ts=1&version=2.0&xuanting=0&exps=113013&dtm=BAIDU_DUP2_SETJSONADSLOT&dc=2&di=u1513126&ti=%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BE%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9B%BE%E5%B1%82----BMapTileCutterJava%E5%88%87%E5%9B%BE%E5%B7%A5%E5%85%B7%E7%BD%91%E7%BB%9C%E7%89%88%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD&tt=1449574716148.-1449574716148.22.23&feid=113013" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; list-style: none; border-width: 0px; border-style: initial; outline: 0px; background: transparent;"></iframe>