天天看點

高德導航java_通過拼接實作高清地圖的下載下傳-高德-java實作

背景

地圖功能是每個系統必備的功能之一,通常可以使用百度地圖和高德地圖來實作線上地圖展示。

但是将展示的地圖下載下傳到本地則是一件有挑戰的事情。

運作環境

mac系統

java 1.8

其中标注的坐标原始資料是百度坐标,是以代碼中進行了轉換。

參考代碼

需求

某一天上司找我,說客戶提出需要将系統裡的線上地圖下載下傳到本地浏覽。利用搜尋引擎,找到一些思路,

前端思路: 線上地圖是canvas繪制的,可以将canvas轉圖檔存儲到本地。

後端思路: 高德和百度均提供靜态地圖接口,但是存在尺寸限制、标注限制。是以需要程式自己切割下載下傳,拼接地圖。

作為一名java後端開發,當然是選擇後端解決方案。

這裡先說下我的需求:我需要一份地圖,是杭州濱江地區的,地圖需要标注一些位置。這些位置超過10個。是以無法直接使用高德地圖接口下載下傳。

實作過程

以高德地圖為例,

首先請注冊高德開發者,申請密鑰,如此才可以調用接口

public final static String uurl = "http://restapi.amap.com/v3/staticmap?zoom=16&size=1024*1024&scale=1";// 高德地圖api

key = "你的密鑰";

解釋下這個接口的參數。

zoom 地圖的縮放比。

size 地圖的尺寸

scale 地圖清晰度 1表示非高清。2表示高清。如果設定值為2 則 zoom将自動成為17 size将變成 2048

由于下載下傳高清地圖,非常慢,以及記憶體容易溢出,是以這裡修改非高清的參數。

直接想要結果的,可以下載下傳一份代碼,自己跑一次

這裡先解釋下思路:

1、經緯度切割。 先确定你需要下載下傳地圖的經緯度範圍。需要2個點即可。

地圖左上角、地圖右下角。

例如這裡我的坐标是杭州濱江區。

String top = "120.123754,30.232441";

String end = "120.243745,30.141632";

你需要決定将你的地圖切割成多少塊。

這裡我設定步長是

// 按照0.01為步長,循環計算出所需獲得的圖檔中心位置坐标

int countX = (int) ((ex - sx) / 0.010999);// 如果ex - sx = 0,說明隻有一列

int countY = (int) ((sy - ey) / 0.00955);// 如果sy - ey = 0,說明隻有一行

其中0.010999 表示 橫向的地圖中心距離 0.00955 表示豎向的地圖中心距離。

這2個值 不能随意修改。和縮放比、清晰度存在關聯。

2、下載下傳地圖

設定了步長後即可運作程式,下載下傳地圖碎片。下載下傳有可能失敗,請多次執行,直到數目完整。

3、橫向切割圖檔

下載下傳的地圖碎片,多數情況存在重疊部分,是以需要切割。切割的規則是 第一張圖檔保持完整,從第二張圖檔開始切割重疊的部分,隻保留不重疊的圖檔。是以需要确定起點是關鍵。

for (int i = 1, j = 0; i <= allPng; i++) {

System.out.println("正在截取");

if (i == (j * count[1] + 1)) {

cutImage(path + "/getMaps/" + i + ".png", path + "/cuttedMaps/" + i + ".png", 0, 0, 1024, 1024);

j++;

} else {

cutImage(path + "/getMaps/" + i + ".png", path + "/cuttedMaps/" + i + ".png", 1024 - 1024, 0, 1024,

1024);

}

}

上圖中的 1024-1024 表示計算切割的起點位置。

這個重疊值如何确定,拿 1.png和2.png 對比确定。在打開ps工具手動數數偏差。 如果你重疊的像素是10 則這裡應當是 10

這裡因為我給的步長十分精确,重疊為0 是以切割的起點位置從0開始。

3、豎向切割

和橫向是同理的。需要人工通過ps确定 重疊的像素是多少.

橫向是比較第一張和第二張圖檔,但是豎向則需要 比較 第一列的第一張和 第二列的第一張圖檔。

System.out.println("開始對圖檔進行第二次截取...");

File f1 = new File(path + File.separator+"mergedMaps");

String[] mergedImgs = f1.list();

for (int i = 1; i <= mergedImgs.length; i++) {

if (i != mergedImgs.length) {

cutImage(path + File.separator+"mergedMaps"+File.separator + i + ".png", path + "/cutteddMaps/" + i + ".png", 0, 0,

(count[1] - 1) * 1024 + 1024, 1024);

} else {

cutImage(path + File.separator+"mergedMaps"+File.separator + i + ".png", path + "/cutteddMaps/" + i + ".png", 0, 0,

(count[1] - 1) * 1024 + 1024, 1024);

}

}

4、合成

正确設定步長、橫豎的切割起點,即可正确拼接出想要的圖檔了。

下載下傳圖檔可能不完整,可以重複多次執行,

以下是程式執行的效果。由于是16的縮放比,是以圖是很大的。大小是 28MB

高德導航java_通過拼接實作高清地圖的下載下傳-高德-java實作

image.png

問題

1、拼接的圖檔,出現錯位?

重疊值錯誤。請重新設定。

2、圖檔沒有重疊?

步長太大,請重新設定。

3、标注不完整,破碎

這個問題非常常見,本人也卡在這裡。主要原因是标注的點,正好處于分割線上,然後分割線存在重疊部分,切割的時候導緻标注不完整。

這裡解決方案主要是,不斷改變步長,確定地圖水準恰好無縫可以拼接。也就是0重疊,但是線條吻合。傳說中的完美分割,本人采用的就是該方案。

另外一個就是 ,位于标注上的點,坐标進行偏移,確定位于重疊的右側。這樣不會被切割。也需要多次人工嘗試。

4、高清版本

高清版本的參數和非高清的差異較大。主要是確定是 高清版本的地圖碎片尺寸是固定的 2048

而非高清的是 1024 是以需要注意修改參數。

5、切割和合并提示檔案不存在

下載下傳的地圖不完整,多次運作程式即可。因為高德的該接口似乎很奇怪,經常會失敗。

代碼下載下傳

提供2份代碼

濱江高清版本

稍後釋出,