百度地圖自定義圖層----BMapTileCutter(Java切圖工具網絡版)


最近做百度地圖API相關應用,需要將自己的地圖疊加到百度地圖上面,查看了百度官方的API說明Javascript部分,不沒有很好的解釋如何覆蓋接口。

在網上找了相關的文章看了下,(http://www.cnblogs.com/jz1108/archive/2011/10/08/2202239.html)這篇文章實現了這個切圖的功能,但是最新的百度最高縮放等級達到19級,項目需要,無奈只能自己寫個切圖工具。

參考了同樣作者的另一篇文章(http://www.cnblogs.com/jz1108/archive/2011/07/02/2095376.html),專門講百度坐標系統的。

程序是用Java Web實現, struts2文件標簽和簡單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 }

代碼的核心思想是將原圖片外圍拓展成256整數倍長度(最小包圍),即源代碼中的extendWidth * extendHeight圖片長度,然后再橫豎切割成多個256*256的瓦片圖塊。

2.index.jsp(切割圖片主頁)

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%
 3 String path = request.getContextPath();
 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
 5 %>
 6 <%@ taglib prefix="s" uri="/struts-tags" %> 
 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 8 <html>
 9   <head>
10     <base href="<%=basePath%>">
11     
12     <title>百度地圖切圖工具</title>
13     <meta http-equiv="pragma" content="no-cache">
14     <meta http-equiv="cache-control" content="no-cache">
15     <meta http-equiv="expires" content="0">    
16     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
17     <meta http-equiv="description" content="This is my page">
18     <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script>
19     <script type="text/javascript">
20         function getData(){
21             //var map = new BMap.Map("baiduMap");
22             var centerX = document.form1.centerX.value;
23             var centerY = document.form1.centerY.value;
24             //alert(centerX);
25             //alert(centerY);
26             var center = new BMap.Point(centerX, centerY);
27             /*獲取中心點的魔卡托坐標*/
28             var projection = new BMap.MercatorProjection();
29             var mercatorPoint = projection.lngLatToPoint(center);
30             document.form1.mercatorX.value = mercatorPoint.x;
31             document.form1.mercatorY.value = mercatorPoint.y;
32             document.form1.submit();
33             //alert(mercatorPoint.x+","+mercatorPoint.y);
34         }
35         function chooseDir(){
36             var savePath;
37             var objSrc = new ActiveXObject("Shell.Application").BrowseForFolder(0,"請選擇輸出文件夾路徑",0,"");
38             if(objSrc!=null){
39                 savePath = objSrc.Items().Item().Path;
40                 document.form1.savePath.value = savePath;
41                 //alert(savePath);
42             }
43         }
44     </script>
45   </head>
46   
47   <body>
48       <!--  
49       <div id="baiduMap" style="width:600px,height:800px"></div>
50     -->
51     
52     <form action="cutter" method="post" name="form1" id="form1" enctype="multipart/form-data">
53         請選擇需要切圖的圖片來源<s:file name="pic" label="Picture"/><br/>
54         圖片中心的經度坐標<input type="text" name="centerX" id="centerX" value="120.27628"/><br>
55         圖片中心的緯度坐標<input type="text" name="centerY"/ id="centerY" value="30.27554"><br>
56         <input type="text" name="mercatorX" id="mercatorX" value="" style="display:none"/>
57         <input type="text" name="mercatorY"/ id="mercatorY" value="" style="display:none">
58         最小級別
59         <select name="minLevel">
60             <option selected>16</option>
61             <option>17</option>
62             <option>18</option>
63             <option>19</option>
64         </select><br>
65         最大級別
66         <select name="maxLevel">
67             <option>16</option>
68             <option>17</option>
69             <option>18</option>
70             <option selected>19</option>
71         </select><br>
72         圖片所在級別
73         <select name="picLevel">
74             <option>16</option>
75             <option>17</option>
76             <option>18</option>
77             <option selected>19</option>
78         </select><br>
79         請選擇輸出目錄
80         <input type="text" name="savePath"/>
81         <input type="button" name="selectDir" onClick="chooseDir()" value="瀏覽"/><br/>
82         <input type="button" value="提交" onClick="getData()"/>
83     </form>
84   </body>
85 </html>

3.實現截圖

4.選擇輸出目錄,是查看本地目錄,用javascript調用ActiveX實現,只能在IE下運行,且需要把IE-->Internet選項-->安全中運行ActiveX控件運行才可以查看本地文件夾目錄。

源碼下載鏈接:http://files.cnblogs.com/thly1990/BaiduMapTileCutter.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM