历史版本37 :[App]JS获取当前地理位置 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 概述编辑

1.1 版本

报表服务器版本
11.0

1.2 应用场景

用户希望在填报过程中,可以一键获取当前地理位置,并把当前地理位置实时展示在地图上便于信息确认。

1.3 功能简介

本文介绍如何获取当前地理位置。

注:以下示例仅演示如何获取地理位置,如需进行填报,需要自行设置模板填报属性,详细步骤可参考:设置填报属性

示例
实现思路

示例一:普通报表获取经纬度


在普通报表中添加按钮,给按钮添加 JS 事件。

在 JS 中使用 FR.location 方法,直接获取当前位置的经纬度

示例二:决策报表获取经纬度

在决策报表中添加文本控件,给控件添加 JS 事件。

在 JS 中使用 FR.location 方法,直接获取当前位置的经纬度

示例三:获取当前地理位置的名称

在普通报表中添加按钮,给按钮添加 JS 事件。

在 JS 中实现以下步骤:

1)使用 FR.location 方法获取当前位置的经纬度。

2)由于 ios 端和Android端返回的经纬度坐标系不同,调用高德的坐标转换 API 接口,根据设备类型,将经纬度统一转换成火星坐标系。

3)调用高德逆地理编码 API 接口将经纬度转换成实际的地理位置名称。

4)点地图绑定经纬度,使用图表刷新接口刷新地图,快速定位到准确位置。

2. 示例一:普通报表获取经纬度编辑

本节示例:制作一张签到模板,点击「地理位置」按钮获取当前位置的经纬度,并填入下方对应的单元格中。如下图所示:

222

2.1 准备模板

1)设置主体内容

打开设计器,新建一张普通报表,模板样式如下图所示。

2)添加控件

  • 设置 E2 单元格为按钮控件,控件名称为「地理位置」。

  • 设置 C5 单元格为下拉框控件,E5 单元格为时间控件。如下图所示:


2.2 JS 获取经纬度

选中 E2 单元格,在右侧属性面板中点击「控件设置>事件」,给按钮控件添加一个点击事件。

在 JavaScript 脚本中,通过 FR.location 方法获取地理位置的经纬度,如果 status 值为 success,则表示获取地理位置成功,否则定位失败。

如果定位成功,则将返回的地理位置信息通过 setCellValue 赋值给 C4 单元格。如下图所示:

注:该方法只适用于移动端,如果在 Web 点击该按钮事件获取地理位置,则直接提示定位失败。

JavaScript 代码如下所示:

FR.location(function(status, message){ //获取地理位置
if(status=="success") {
//定位成功,message返回经纬度值
FR.Msg.alert("当前位置是" + message);
contentPane.setCellValue(2, 3, message); 
} else {
//定位失败,message返回对应的错误信息
FR.Msg.alert(message); //定位失败
}
});

2.3 JS 获取当前时间

选中 E2 单元格,在右侧属性面板中点击「控件设置>事件」,给按钮控件添加一个点击事件。

在 JavaScript 脚本中, 将获取到的当前签到时间赋值给 E4 单元格。如下图所示:

JavaScript 代码如下:

var myDate = new Date();
var mytime=myDate.getFullYear()+"-"+(myDate.getMonth()+1)+"-"+myDate.getDate()+" "+myDate.getHours()+":"+myDate.getMinutes()+":"+myDate.getSeconds(); //获取当前时间
contentPane.setCellValue(4, 3, mytime);

2.4 效果查看

将制作完成的模板挂载至数据决策系统,类型选择「填报」,详细挂载步骤请查看 添加模板,如下图所示:

222

移动端预览效果如下图所示:


3. 示例二:决策报表获取经纬度编辑

本节示例:制作一张决策报表,预览时自动获取当前位置的经纬度。

3.1 准备模板

新建一张决策报表,在表单内添加 2 个「文本控件」,控件名称分别为 jingdu、weidu 。如下图所示:

3.2 添加事件

选中一个文本控件,如 jingdu ,为其添加一个「初始化后事件」。如下图所示:

JavaScript 代码如下:

var self = this;
FR.location(function(status, message){ 
if(status=="success") { 
var jingwei=message.split(",") ; 
self.options.form.getWidgetByName("jingdu").setValue(jingwei[1]);
self.options.form.getWidgetByName("weidu").setValue(jingwei[0]); } 
});

3.3 效果预览

将制作完成的模板挂载至数据决策系统,详细挂载步骤请查看 添加模板 。

移动端预览效果如下图所示:

4. 示例三:获取地理位置名称编辑

示例:制作一张普通报表,点击「地理位置」按钮获取当前位置信息,并填入相应的单元格中,同时自动刷新地图,把当前地理位置展示在地图上方便用户确认。

注:该方案支持移动端、企业微信集成、钉钉集成。

4.1 环境准备

本节方案需要使用到高德的坐标转换 API 接口和逆地理编码 API 接口,在使用接口前需前往高德开放平台申请 Web 服务 API 类型 Key 。

示例代码中使用的高德 KEY 仅用于方案展示,不可在正式环境中使用。

注:如需在正式环境中使用该方案,需自行前往高德官网申请免费/付费 key,请前往:高德开放平台 。


4.2 准备模板

1)设置主体内容

打开设计器,新建一张普通报表,模板样式如下图所示。

注:需确保经度、纬度、地名存放在固定的单元格中,便于后续点地图绑定单元格数据。

 

2)设计地图

合并 B1~H21 单元格区域,选中单元格,点击工具栏 Snag_194c381c.png 插入图表,选择「地图>点地图」。如下图所示:

选中地图所在单元格,点击右侧属性面板「单元格元素」,选择「类型」, 地图点选择「中国」,GIS 图层选择「高德地图」。

选择「数据」, 数据集来源为「单元格数据」,使用「经纬度定位」,绑定单元格内的经纬度和位置信息。具体设置如下图所示:

3)添加控件

合并 J3~L3单元格,设置 J3 单元格为按钮控件,如下图所示:

4.3 添加事件

选中 J3 单元格,在右侧属性面板中点击「控件设置>事件」,给按钮控件添加一个「点击」事件,事件需要设置一个地图位置参数。如下图所示:

JavaScript 代码如下:

FR.location(function(status, message, coordinate) { //三个参数,status是状态(success,fail),message是经纬度(如31.590668,120.457507),coordinate是坐标系信息(ios返回WGS84,安卓返回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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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、企业微信、钉钉获取经纬度失败时返回报错信息
}
});

4.4 效果预览

将制作完成的模板挂载至数据决策系统,类型选择「填报」,详细挂载步骤请查看 添加模板,如下图所示:

移动端预览效果如下图所示:

5. 注意事项编辑

问题描述:

制作决策报表时,想调节控件大小,出现如下图的提示:

13.png

解决方案:

在「控件设置」里面将「body」的布局方式改为「绝对布局」,就能够自定义控件大小了。

14.png

6. 模板下载编辑

1)示例一已完成模板:

获取地理位置经纬度.cpt

2)示例二已完成模板:

决策报表获经纬度.frm

3)示例三已完成模板:

点击按钮获取当前位置并刷新地图.cpt