1. 概述
1.1 版本
報表伺服器版本 | App版本 |
---|---|
11.0 | V11.0 |
1.2 應用場景
使用者希望一鍵獲取當前地理位置,或把當前地理位置實時展示在地圖上便於資訊確認。
1.3 功能簡介
本文介紹如何獲取當前地理位置。
注:以下範例僅示範如何獲取地理位置,如需進行填報,需要自行設定範本填報屬性,詳細步驟可參考:設定填報屬性 。
範例 | 實現思路 |
---|---|
範例一:普通報表獲取經緯度 | 在普通報表中新增按鈕,給按鈕新增 JS 事件。 在 JS 中使用 FR.location 方法,直接獲取當前位置的經緯度 |
範例二:決策報表獲取經緯度 | 在決策報表中新增正文元件,給元件新增 JS 事件。 在 JS 中使用 FR.location 方法,直接獲取當前位置的經緯度 |
範例三:FVS 獲取經緯度及地理位置名稱 | 在 FVS 中新增標題組件,給組件新增 JS 事件。 在 JS 中實現以下步驟: 1)使用 FR.location 方法獲取當前位置的經緯度。 2)由於 ios 端和Android端傳回的經緯度座標系不同,呼叫高德的座標轉換 API API,根據裝置類型,將經緯度統一轉換成火星座標系。 3)呼叫高德逆地理編碼 API API將經緯度轉換成實際的地理位置名稱。 |
範例四:普通報表獲取經緯度、地理位置名稱及重新整理地圖 | 在普通報表中新增按鈕,給按鈕新增 JS 事件。 在 JS 中實現以下步驟: 1)使用 FR.location 方法獲取當前位置的經緯度。 2)由於 ios 端和Android端傳回的經緯度座標系不同,呼叫高德的座標轉換 API API,根據裝置類型,將經緯度統一轉換成火星座標系。 3)呼叫高德逆地理編碼 API API將經緯度轉換成實際的地理位置名稱。 4)點地圖綁定經緯度,使用圖表重新整理API重新整理地圖,快速定位到準確位置。 |
2. 範例一:普通報表獲取經緯度
本節範例:製作一張簽到範本,點選「地理位置」按鈕獲取當前位置的經緯度,並填入下方對應的儲存格中。如下圖所示:
2.1 準備範本
1)設定主體內容
開啟設計器,建立一張普通報表,範本樣式如下圖所示。
2)新增元件
設定 E2 儲存格為按鈕元件,元件名稱為「地理位置」。
設定 C5 儲存格為下拉框元件,E5 儲存格為時間元件。如下圖所示:
2.2 JS 獲取經緯度
選中 E2 儲存格,在右側屬性面板中點選「元件設定>事件」,給按鈕元件新增一個點選事件。
在 JavaScript 腳本中,透過 FR.location 方法獲取地理位置的經緯度,如果 status 值為 success,則表示獲取地理位置成功,否則定位失敗。
如果定位成功,則將傳回的地理位置資訊透過 setCellValue 指派給 C4 儲存格。如下圖所示:
注:該方法只適用於行動端,如果在 Web 點選該按鈕事件獲取地理位置,則直接提示定位失敗。
JavaScript 程式碼如下所示:
2.3 JS 獲取當前時間
選中 E2 儲存格,在右側屬性面板中點選「元件設定>事件」,給按鈕元件再新增一個點選事件。
在 JavaScript 腳本中, 將獲取到的當前簽到時間指派給 E4 儲存格。如下圖所示:
JavaScript 程式碼如下:
2.4 效果查看
App 直接掃碼填報預覽或將製作完成的範本掛載至數據決策系統,類型選擇「填報」,即在 App 目錄中查看,詳細掛載步驟請查看 新增範本,如下圖所示:
App 預覽效果如下圖所示:
3. 範例二:決策報表獲取經緯度
本節範例:製作一張決策報表,預覽時自動獲取當前位置的經緯度。
3.1 準備範本
建立一張決策報表,在表單內新增 2 個「正文元件」,元件名稱分別為 jingdu、weidu 。如下圖所示:
3.2 新增事件
選中一個正文元件,如 jingdu ,為其新增一個「初始化後事件」。如下圖所示:
JavaScript 程式碼如下:
3.3 效果預覽
App 直接掃碼預覽或將製作完成的範本掛載至數據決策系統,即可在 App 目錄中查看,詳細掛載步驟請查看 新增範本 。
App 預覽效果如下圖所示:
4. 範例三:FVS 獲取經緯度及地理位置名稱
本節範例:製作一張 FVS 範本,點選「點我獲取經緯度及地理位置名稱」獲取當前位置的經緯度及地理位置名稱。
4.1 環境準備
本節方案需要使用到高德的座標轉換 API API和逆地理編碼 API API,在使用API前需前往高德開放平台申請 Web 服務 API 類型 Key 。
範例程式碼中使用的高德 KEY 僅用於方案展示,不可在正式環境中使用。
注1:如需在正式環境中使用該方案,需自行前往高德官網申請免費/付費 key,請前往:高德開放平台 。
注2:如只需獲取經緯度,不需獲取地理位置名稱,則不需要進行此節環境準備操作。
4.2 準備範本
1)開啟 FineReport 設計器,點選菜單欄「檔案>建立視覺化看板」。
2)點選「建立看板」,如下圖所示:
3)點選左側組件列表欄的「文字」組件,將「標題」拖入畫布中,如下圖所示:
4)選中「標題」組件,在右側配置欄「內容」中設定標題內容為「點我獲取經緯度及地理位置名稱」,如下圖所示:
4.3 新增事件
1)選中「標題」組件,點選右側配置欄「交互>點選事件>新增點選事件>JavaScript」。
2)設定事件名稱為「獲取經緯度及地理位置名稱」,輸入 JavaScript 程式碼,點選「確定」,如下圖所示:
JavaScript 程式碼如下:
duchamp.location(function(status, message, coordinate) { //三個參數,status是狀態(success,fail),message是經緯度(如31.590668,120.457507),coordinate是座標系資訊(ios傳回WGS84,Android傳回GCJ02)。
if (status == "success") { //獲取經緯度成功時執行此函式
var aa = message.split(','); //message是一個,分割的字串,轉換成陣列
weidu = aa[0]; //獲取資料分析app、企業微信、釘釘傳回的緯度
jingdu = aa[1]; //獲取資料分析app、企業微信、釘釘傳回的經度
if (coordinate == "WGS84") { //根據座標系判斷當前裝置是Android還是ios,Android傳回GCJ02,ios傳回WGS84,當手機是ios時執行以下程式碼
var url1 = "https://restapi.amap.com/v3/assistant/coordinate/convert?locations=" + jingdu + "," + weidu + "&coordsys=gps&output=json&key=4eff2ee8c07f35b8702722abc8f35bf2"; //呼叫高德API將ios傳回的地球座標系經緯度轉換為火星座標系
duchamp.ajax({
url: url1,
type: "get", //高德api要求使用get方式請求
dataType: "jsonp", //跨域使用jsonp方式
success: function(data) { //請求成功時呼叫此函式
if (data.status == "1") { //高德apiAPI傳回的狀態碼是1(請求成功)
jingdu = data.locations.split(',')[0]; //獲取轉換後的經度
weidu = data.locations.split(',')[1]; //獲取轉換後的緯度
var url2 = "https://restapi.amap.com/v3/geocode/regeo?output=json&location=" + jingdu + "," + weidu + "&key=4eff2ee8c07f35b8702722abc8f35bf2&radius=10&extensions=all"; //呼叫高德API根據經緯度進行逆地理編碼
duchamp.ajax({
url: url2,
type: "get", //高德api要求使用get方式請求
dataType: "jsonp", //跨域使用jsonp方式
success: function(msg) { //請求成功時呼叫此函式
if (msg.status == "1") { //高德apiAPI傳回的狀態碼是1(請求成功)
var address = msg.regeocode.formatted_address; //從高德API傳回的結果中,取出結構化地址,即地理位置名稱
if (address != null && address != "" && address != "null") { //判斷地址是否為空
duchamp.Msg.alert({title:"當前經緯度和地址:",message:jingdu+","+weidu+","+address});//地址不為空,則彈出當前經緯度和地址
} else {
duchamp.Msg.alert({title:"警告:",message:"無法獲取當前地址"});//地址為空,則彈出警告
}
};
if (msg.status == "0") { //高德apiAPI傳回的狀態碼是0(請求失敗)
duchamp.Msg.alert({title:"警告:",message:"經緯度轉換地址出錯:錯誤資訊是" + msg.info + ",錯誤碼是:" + msg.infocode + ",詳情請存取:https://lbs.amap.com/api/webservice/guide/tools/info/"}); //如果出錯,彈出高德api傳回的報錯
}
},
error: function(info) { //請求失敗時呼叫此函式
duchamp.Msg.alert({title:"警告:",message:"請求失敗,請聯絡管理者。"});
},
complete: function(XMLHttpRequest, status) { //請求完成後最終執行回呼函式
if (status == 'timeout') { //逾時,status還有success,error等值的情況
duchamp.Msg.alert({title:"警告:",message:"請求逾時,請檢查網路。"});
}
},
timeout: 3000, //逾時時間為3S
async: "false" //同步請求,和上面的ajax請求不是非同步的,需要順序執行
});
};
if (data.status == "0") { //高德apiAPI傳回的狀態碼是0(請求失敗)
duchamp.Msg.alert({title:"警告:",message:"經緯度轉換座標系出錯:錯誤資訊是" + data.info + ",錯誤碼是:" + data.infocode + ",詳情請存取:https://lbs.amap.com/api/webservice/guide/tools/info/"}); //如果出錯,彈出高德api傳回的報錯
}
},
error: function(info) { //請求失敗時呼叫此函式
duchamp.Msg.alert({title:"警告:",message:"請求失敗,請聯絡管理者。"});
},
complete: function(XMLHttpRequest, status) { //請求完成後最終執行回呼函式
if (status == 'timeout') { //判斷是否逾時,status還有success,error等值的情況
duchamp.Msg.alert({title:"警告:",message:"請求逾時"});
}
},
timeout: 3000, //逾時時間為3s
async: "false" //同步請求,和下面的ajax請求不是非同步的,需要順序執行
});
} else { //當手機是Android時,執行以下程式碼
var url3 = "https://restapi.amap.com/v3/geocode/regeo?output=json&location=" + jingdu + "," + weidu + "&key=4eff2ee8c07f35b8702722abc8f35bf2&radius=10&extensions=all"; //呼叫高德API根據經緯度進行逆地理編碼
duchamp.ajax({
url: url3,
type: "get", //高德api要求使用get方式請求
dataType: "jsonp", //跨域使用jsonp方式
success: function(msg) { //請求成功時呼叫此函式
if (msg.status == "1") { //高德apiAPI傳回的狀態碼是1(請求成功)
var address = msg.regeocode.formatted_address; //從高德API傳回的結果中,取出結構化地址,即地理位置名稱
if (address != null && address != "" && address != "null") { //判斷地址是否為空
duchamp.Msg.alert({title:"當前經緯度和地址:", message:jingdu+","+weidu+","+address});//地址不為空,則彈出當前經緯度和地址
} else {
duchamp.Msg.alert({title:"警告:",message:"無法獲取當前地址"});//地址為空,則彈出警告
}
};
if (msg.status == "0") { //高德apiAPI傳回的狀態碼是0(請求失敗)
duchamp.Msg.alert({title:"警告:",message:"經緯度轉換地址出錯:錯誤資訊是" + msg.info + ",錯誤碼是:" + msg.infocode + ",詳情請存取:https://lbs.amap.com/api/webservice/guide/tools/info/"}); //如果出錯,彈出高德api傳回的報錯
}
},
error: function(info) { //請求失敗時呼叫此函式
duchamp.Msg.alert({title:"警告:",message:"請求失敗,請聯絡管理者。"});
},
complete: function(XMLHttpRequest, status) { //請求完成後最終執行回呼函式
if (status == 'timeout') { //逾時,status還有success,error等值的情況
duchamp.Msg.alert({title:"警告:",message:"請求逾時,請檢查網路。"});
}
},
timeout: 3000, //逾時時間為3S
async: "false" //同步請求,和上面的ajax請求不是非同步的,需要順序執行
});
}
} else { //獲取經緯度失敗時執行此函式
duchamp.Msg.alert({title:"警告:",message:"錯誤:請檢查手機網路和定位服務開關及權限,或聯絡管理者。" + "\n" + "狀態碼:" + status + "\n" + "錯誤資訊:" + JSON.stringify(message)}); //資料分析app、企業微信、釘釘獲取經緯度失敗時傳回報錯資訊
}
});
4.4 效果預覽
App 直接掃碼預覽或將製作完成的範本掛載至數據決策系統,即可在 App 目錄中查看,詳細掛載步驟請查看 新增範本 。
App 預覽效果如下圖所示:
5. 範例四:普通報表獲取經緯度、地理位置名稱及重新整理地圖
範例:製作一張普通報表,點選「地理位置」按鈕獲取當前位置資訊,並填入相應的儲存格中,同時自動重新整理地圖,把當前地理位置展示在地圖上方便使用者確認。
注:該方案支援行動端app、企業微信整合、釘釘整合。
5.1 環境準備
本節方案需要使用到高德的座標轉換 API API和逆地理編碼 API API,在使用API前需前往高德開放平台申請 Web 服務 API 類型 Key 。
範例程式碼中使用的高德 KEY 僅用於方案展示,不可在正式環境中使用。
注:如需在正式環境中使用該方案,需自行前往高德官網申請免費/付費 key,請前往:高德開放平台 。
注2:如只需獲取經緯度,不需獲取地理位置名稱,則不需要進行此節環境準備操作。
5.2 準備範本
1)設定主體內容
開啟設計器,建立一張普通報表,範本樣式如下圖所示。
注:需確定經度、緯度、地名存放在固定的儲存格中,便於後續點地圖綁定儲存格資料。
2)設計地圖
合併 B1~H21 儲存格區域,被選儲存格,點選工具欄 插入圖表,選擇「地圖>點地圖」。如下圖所示:
選中地圖所在儲存格,點選右側屬性面板「儲存格元素」,選擇「類型」, 地圖點選擇「中國」,GIS 圖層選擇「高德地圖」。
選擇「資料」, 資料集來源為「儲存格資料」,使用「經緯度定位」,綁定儲存格內的經緯度和位置資訊。具體設定如下圖所示:
3)新增元件
合併 J3~L3儲存格,設定 J3 儲存格為按鈕元件,如下圖所示:
5.3 新增事件
選中 J3 儲存格,在右側屬性面板中點選「元件設定>事件」,給按鈕元件新增一個「點選」事件,事件需要設定一個地圖位置參數。如下圖所示:
JavaScript 程式碼如下:
FR.location(function(status, message, coordinate) { //三個參數,status是狀態(success,fail),message是經緯度(如31.590668,120.457507),coordinate是座標系資訊(ios傳回WGS84,Android傳回GCJ02)。
if (status == "success") { //獲取經緯度成功時執行此函式
var aa = message.split(','); //message是一個,分割的字串,轉換成陣列
weidu = aa[0]; //獲取資料分析app、企業微信、釘釘傳回的緯度
jingdu = aa[1]; //獲取資料分析app、企業微信、釘釘傳回的經度
if (coordinate == "WGS84") { //根據座標系判斷當前裝置是Android還是ios,Android傳回GCJ02,ios傳回WGS84,當手機是ios時執行以下程式碼
var url1 = "https://restapi.amap.com/v3/assistant/coordinate/convert?locations=" + jingdu + "," + weidu + "&coordsys=gps&output=json&key=47b4db70b1259b4722957d991202f66d"; //呼叫高德API將ios傳回的地球座標系經緯度轉換為火星座標系
FR.ajax({
url: url1,
type: "get", //高德api要求使用get方式請求
dataType: "jsonp", //跨域使用jsonp方式
success: function(data) { //請求成功時呼叫此函式
if (data.status == "1") { //高德apiAPI傳回的狀態碼是1(請求成功)
jingdu = data.locations.split(',')[0]; //獲取轉換後的經度
weidu = data.locations.split(',')[1]; //獲取轉換後的緯度
var url2 = "https://restapi.amap.com/v3/geocode/regeo?output=json&location=" + jingdu + "," + weidu + "&key=47b4db70b1259b4722957d991202f66d&radius=10&extensions=all"; //呼叫高德API根據經緯度進行逆地理編碼
FR.ajax({
url: url2,
type: "get", //高德api要求使用get方式請求
dataType: "jsonp", //跨域使用jsonp方式
success: function(msg) { //請求成功時呼叫此函式
if (msg.status == "1") { //高德apiAPI傳回的狀態碼是1(請求成功)
var address = msg.regeocode.formatted_address; //從高德API傳回的結果中,取出結構化地址,即地理位置名稱
if (address != null && address != "" && address != "null") { //判斷地址是否為空
contentPane.setCellValue(9, 1, jingdu);
contentPane.setCellValue(10, 1, weidu);
contentPane.setCellValue(11, 1, address); //給地圖綁定的三個儲存格指派
setTimeout(function() {
FR.Chart.WebUtils.getChart(b).dataRefresh(); //重新整理地圖
}, 1000);
FR.Msg.alert("當前地址是:" + address);
} else {
FR.Msg.alert("無法獲取當前地址");
}
};
if (msg.status == "0") { //高德apiAPI傳回的狀態碼是0(請求失敗)
FR.Msg.alert("經緯度轉換地址出錯:錯誤資訊是" + msg.info + ",錯誤碼是:" + msg.infocode + ",詳情請存取:https://lbs.amap.com/api/webservice/guide/tools/info/"); //如果出錯,彈出高德api傳回的報錯
}
},
error: function(info) { //請求失敗時呼叫此函式
FR.Msg.alert("請求失敗,請聯絡管理者。");
},
complete: function(XMLHttpRequest, status) { //請求完成後最終執行回呼函式
if (status == 'timeout') { //逾時,status還有success,error等值的情況
FR.Msg.alert("請求逾時,請檢查網路。");
}
},
timeout: 3000, //逾時時間為3S
async: "false" //同步請求,和上面的ajax請求不是非同步的,需要順序執行
});
};
if (data.status == "0") { //高德apiAPI傳回的狀態碼是0(請求失敗)
FR.Msg.alert("經緯度轉換座標系出錯:錯誤資訊是" + data.info + ",錯誤碼是:" + data.infocode + ",詳情請存取:https://lbs.amap.com/api/webservice/guide/tools/info/"); //如果出錯,彈出高德api傳回的報錯
}
},
error: function(info) { //請求失敗時呼叫此函式
FR.Msg.alert("請求失敗,請聯絡管理者。");
},
complete: function(XMLHttpRequest, status) { //請求完成後最終執行回呼函式
if (status == 'timeout') { //判斷是否逾時,status還有success,error等值的情況
FR.Msg.alert("請求逾時");
}
},
timeout: 3000, //逾時時間為3s
async: "false" //同步請求,和下面的ajax請求不是非同步的,需要順序執行
});
} else { //當手機是Android時,執行以下程式碼
var url3 = "https://restapi.amap.com/v3/geocode/regeo?output=json&location=" + jingdu + "," + weidu + "&key=47b4db70b1259b4722957d991202f66d&radius=10&extensions=all"; //呼叫高德API根據經緯度進行逆地理編碼
FR.ajax({
url: url3,
type: "get", //高德api要求使用get方式請求
dataType: "jsonp", //跨域使用jsonp方式
success: function(msg) { //請求成功時呼叫此函式
if (msg.status == "1") { //高德apiAPI傳回的狀態碼是1(請求成功)
var address = msg.regeocode.formatted_address; //從高德API傳回的結果中,取出結構化地址,即地理位置名稱
if (address != null && address != "" && address != "null") { //判斷地址是否為空
contentPane.setCellValue(9, 1, jingdu);
contentPane.setCellValue(10, 1, weidu);
contentPane.setCellValue(11, 1, address); //給地圖綁定的三個儲存格指派
setTimeout(function() {
FR.Chart.WebUtils.getChart(b).dataRefresh(); //重新整理地圖
}, 1000);
FR.Msg.alert("當前地址是:" + address);
} else {
FR.Msg.alert("無法獲取當前地址");
}
};
if (msg.status == "0") { //高德apiAPI傳回的狀態碼是0(請求失敗)
FR.Msg.alert("經緯度轉換地址出錯:錯誤資訊是" + msg.info + ",錯誤碼是:" + msg.infocode + ",詳情請存取:https://lbs.amap.com/api/webservice/guide/tools/info/"); //如果出錯,彈出高德api傳回的報錯
}
},
error: function(info) { //請求失敗時呼叫此函式
FR.Msg.alert("請求失敗,請聯絡管理者。");
},
complete: function(XMLHttpRequest, status) { //請求完成後最終執行回呼函式
if (status == 'timeout') { //逾時,status還有success,error等值的情況
FR.Msg.alert("請求逾時,請檢查網路。");
}
},
timeout: 3000, //逾時時間為3S
async: "false" //同步請求,和上面的ajax請求不是非同步的,需要順序執行
});
}
} else { //獲取經緯度失敗時執行此函式
FR.Msg.alert("錯誤:請檢查手機網路和定位服務開關及權限,或聯絡管理者。" + "\n" + "狀態碼:" + status + "\n" + "錯誤資訊:" + JSON.stringify(message)); //資料分析app、企業微信、釘釘獲取經緯度失敗時傳回報錯資訊
}
});
5.4 效果預覽
App 直接掃碼查看或將製作完成的範本掛載至數據決策系統,類型選擇「填報」,即可在 App 目錄中查看,詳細掛載步驟請查看 新增範本,如下圖所示:
行動端預覽效果如下圖所示:
6. 注意事項
問題描述:
製作決策報表時,想調節元件大小,出現如下圖的提示:
解決方案:
在「元件設定」裏面將「body」的佈局方式改為「絕對佈局」,就能夠自訂元件大小了。
7. 範本下載
1)範例一已完成範本:普通報表獲取經緯度.cpt
2)範例二已完成範本:決策報表獲取經緯度.frm
3)範例三已完成範本:FVS獲取經緯度及地理位置名稱.fvs
4)範例四已完成範本:普通報表獲取經緯度、地理位置名稱及重新整理地圖.cpt