反馈已提交

网络繁忙

[App]JS获取当前地理位置

  • 文档创建者:文档助手1
  • 历史版本:48
  • 最近更新:Fairy.Zhang 于 2024-12-06
  • 1. 概述

    1.1 版本

    报表服务器版本
    App版本
    11.0V11.0

    1.2 应用场景

    用户希望一键获取当前地理位置,或把当前地理位置实时展示在地图上便于信息确认。

    1.3 功能简介

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

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

    示例
    实现思路

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

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

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

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

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

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

    示例三:FVS 获取经纬度及地理位置名称

    在 FVS 中添加标题组件,给组件添加 JS 事件。

    在 JS 中实现以下步骤:

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

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

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

    示例四:普通报表获取经纬度、地理位置名称及刷新地图


    在普通报表中添加按钮,给按钮添加 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 效果查看

    App 直接扫码填报预览或将制作完成的模板挂载至数据决策系统,类型选择「填报」,即在 App 目录中查看,详细挂载步骤请查看 添加模板,如下图所示:

    222

    App 预览效果如下图所示:


    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 效果预览

    App 直接扫码预览或将制作完成的模板挂载至数据决策系统,即可在 App 目录中查看,详细挂载步骤请查看 添加模板 。

    App 预览效果如下图所示:

    4. 示例三:FVS 获取经纬度及地理位置名称

    本节示例:制作一张 FVS 模板,点击「点我获取经纬度及地理位置名称」获取当前位置的经纬度及地理位置名称。

    4.1 环境准备

    本节方案需要使用到高德的坐标转换 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") { //高德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=4eff2ee8c07f35b8702722abc8f35bf2&radius=10&extensions=all"; //调用高德API根据经纬度进行逆地理编码
                            duchamp.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") { //判断地址是否为空
                                            
                                            duchamp.Msg.alert({title:"当前经纬度和地址:",message:jingdu+","+weidu+","+address});//地址不为空,则弹出当前经纬度和地址
                                        } else {
                                            duchamp.Msg.alert({title:"警告:",message:"无法获取当前地址"});//地址为空,则弹出警告
                                        }
                                    };
                                    if (msg.status == "0") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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") { //高德api接口返回的状态码是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 预览效果如下图所示:

    动画1.gif

    5. 示例四:普通报表获取经纬度、地理位置名称及刷新地图

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

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

    5.1 环境准备

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

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

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

    注2:如只需获取经纬度,不需获取地理位置名称,则不需要进行此节环境准备操作。


    5.2 准备模板

    1)设置主体内容

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

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

     

    2)设计地图

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

    选中地图所在单元格,点击右侧属性面板「单元格元素」,选择「类型」, 地图点选择「中国」,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") { //高德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、企业微信、钉钉获取经纬度失败时返回报错信息
    }
    });

    5.4 效果预览

    App 直接扫码查看或将制作完成的模板挂载至数据决策系统,类型选择「填报」,即可在 App 目录中查看,详细挂载步骤请查看 添加模板,如下图所示:

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

    6. 注意事项

    问题描述:

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

    13.png

    解决方案:

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

    14.png

    7. 模板下载

    1)示例一已完成模板:普通报表获取经纬度.cpt

    2)示例二已完成模板:决策报表获取经纬度.frm

    3)示例三已完成模板:FVS获取经纬度及地理位置名称.fvs

    4)示例四已完成模板:普通报表获取经纬度、地理位置名称及刷新地图.cpt

    附件列表


    主题: 移动端应用
    已经是第一篇
    已经是最后一篇
    • 有帮助
    • 没帮助
    • 只是浏览
    中文(简体)

    鼠标选中内容,快速反馈问题

    鼠标选中存在疑惑的内容,即可快速反馈问题,我们将会跟进处理。

    不再提示

    10s后关闭



    AI

    联系我们
    在线支持
    获取专业技术支持,快速帮助您解决问题
    工作日9:00-12:00,13:30-17:30在线
    页面反馈
    针对当前网页的建议、问题反馈
    售前咨询
    采购需求/获取报价/预约演示
    或拨打: 400-811-8890 转1
    qr
    热线电话
    咨询/故障救援热线:400-811-8890转2
    总裁办24H投诉:17312781526
    提交页面反馈
    仅适用于当前网页的意见收集,帆软产品问题请在 问答板块提问前往服务平台 获取技术支持