上一篇我们讲了如何进行实现角度与弧度的互相转化。在该篇中我们会讲解如何进行实现坐标正算的程序。
目录
1.什么是坐标正算
2.代码实现
3.界面展示
侃侃而谈
从该篇开始程序就会慢慢的越往后越开始有点难度了,所以我想大家应该是蛮期待的,很高兴的是今天我终于把水准测量的程序写出来了,我每天会抽出两个小时来完善它,你会发现抽出再多的时间来做同一件事情会很低效,你也不可能一天就将程序设计出来。
我想让你知道的是尽量每天规划好做几样事情,而且每件事情都要有确定的时间点,比如该事情做两个小时,然后时间到立马再做另外一件事情,我发现这样是最高效的,至少现在是这样,你也可以试试。
水准计算这个程序是我开发这些程序中耗时最长的一个,因为它看起来的确很简单,然而你需要让用户自己添加任意个测站,因为你是不清楚用户会需要几个测站,所以你要动态的获取到用户输入的值然后在一个一个遍历后计算,听起来似乎是有点难的。
其实《工程测绘大师》这个小程序的代码优化的空间还很大,为什么这么说呢?上一个暑假为了能够快速上线很多东西是可以做成组件来进行复用,这样可以优化代码也增加了较好的可读性,为后期的代码维护和升级做一个铺垫。
组件的复用就是把相同的代码抽取出来,将其作为一个单独的模块组件,在哪个页面需要该组件引入即可。
什么时候应该将其作为组件?
当页面中需要很多地方需要用到该组件时,我们就应该把它封装成一个组件便于使用。比如目前的这个小程序头部导航用的就是一个独立的组件,因为它在每个页面中都要用到,所以这种情况就适合将其封装为一个组件。
组件的好处就是能够复用,而且我们还可以给组件传值提高组件的灵活性。比如说在坐标反算这个界面的头部,我们就需要把坐标正算 titleText="坐标正算"值传入进去给父组件,在组件中根据需要我们可以传很多所需值提高组件的灵活性。
<mynavbar back="true" home="true" tourl="../../../../../pageBar/component/index" color="rgba(0,0,0,.5)" titleText="坐标正算">mynavbar>
图0 头部组件
后期我会将代码进行优化,如果不进行优化随着程序的增加,代码变得异常的难以维护。
01、什么是坐标正算
坐标正算其实就是已知距离(两点间的距离)、方位角和该点的坐标,求另一个点坐标的过程。
图1-1 坐标正算图解
计算公式
Xb = Xa + Sab * CosαAB
Yb = Ya + Sab * SinαAB
我们可以从公式中发现坐标正算其实很简单,但是在测绘中他的用途特别广泛,如果你是从事传统测绘的测量,那么你很幸运,因为你天天都在和这个公式打交道。
02、代码实现
因为代码中都有相应注释,这里我不会做过多的说明。你只需要在微信中任意创建一个page页面就可以编写运行,以下文件的名字只是一个参考。其中样式还是与之前第七篇的样式(centralmeridianis.wxss)一致,由于篇幅有限样式不再做过多说明。
该篇主要的难点在于用split('.')来进行实现用户输入度分秒时要根据 . 来获取到度、 分、 秒的值,只有我们拿到了值才能进行后续的计算。(方法不止一种,这里我用的split('.')方法来实现)split(' ')函数方法主要是字符串方法,用于将字符串根据括号里面的符号进行分割成以该符号隔开的数组。
//例如:var str = '三/叶/雨';var arr = str.split('/')//通过查找到/来进行分割这里我们也可以是其他符号,根据要输入的值来确定。//输出数组:['三','叶','雨']//如果我们需要获取数组中的'三'就需要通过以下方式获取arr[0]//'三'arr[1]//'叶'arr[2]//'雨'//一般编程语言中下标都是从'0'开始
具体请看下面的代码
coordbeing.wxml
<mynavbar back="true" home="true" tourl="../../../../../pageBar/component/index" color="rgba(0,0,0,.5)" titleText="坐标正算">mynavbar><view class="header-text"> <image src="../../../../../icon/start.png">image>起点坐标view><block wx:for="{{list}}" wx:key="id"> <view class="centralmerid" id="{{item.id}}"> <view class="centralmerid-border {{item.border ? 'selected-border' : '' }}"> <view class="centralmerid-left-icon"> <image class="img-icon" src="{{item.url}}">image> <text class="left-text">{{item.text}}text> view> <input class="{{item.border ? 'selected-border' : '' }}" type="digit" value="{{cleantext}}" bindfocus="{{item.focous}}" bindblur="{{item.name}}" placeholder="{{item.tips}}">input> <view class="centralmerid-right-text">{{item.unit}}view> view> view>block><view class="result-btn" bindtap="multipleTap"> <view class="results"> <button type="primary" style="width:90%;">计算button> view>view><scroll-view class="footer" hidden="{{resultShow}}" scroll-y="true"> <view class="result-inner"> <view class="header-text close fixed-header"> <view class="close"> <image src="../../../../../icon/end.png">image>终点坐标 view> <image src="../../../../../icon/close.png" bindtap="myclose">image> view> <view class="result-inner-inner">Xb:<text class="resultColor"> {{xb}}text> ᴹview> <view class="result-inner-inner">Yb:<text class="resultColor">{{yb}}text> ᴹview> view>scroll-view><view class="footer-text" wx:if="{{resultShow}}"> <view class="footer-text-inner"> <view class="footer-inner">小贴士:单击为计算,双击则为清空。view> <view class="footer-inner">我国领土跨22个3度投影带,即第24~45带。view> view>view>
coordbeing.json
{ "usingComponents": { "mynavbar":"../../../../../common/resources/navbar/navbar" }}
coordbeing.js
Page({ /** * 页面的初始数据 */ data: { xValue: '', yValue: '', azimuthValue: '', twoValue: '', selecteBorder: false, resultShow: true, list: [{ id: 0, name: 'xValue', focous: 'xfocous', unit: 'ᴹ', url: '../../../../../icon/coordinate.png', text: "Xₐ", border: false }, { id: 1, name: 'yValue', focous: 'yfocous', unit: 'ᴹ', url: '../../../../../icon/coordinate.png', text: "Yₐ", border: false }, { id: 2, name: 'azimuthValue', focous: 'azimuthfocous', unit: '°′″', url: '../../../../../icon/angle.png', text: "α", tips: "请您以 度.分.秒 形式输入方位角", border: false }, { id: 3, name: 'twoValue', focous: 'twofocous', unit: 'ᴹ', url: '../../../../../icon/twopoint.png', text: "D", border: false } ] }, // 关闭答案 myclose() { this.setData({ resultShow: true }) }, // 获取焦点显示边框 xfocous() { this.setData({ 'list[0].border': true }) }, yfocous() { this.setData({ 'list[1].border': true }) }, azimuthfocous() { this.setData({ 'list[2].border': true }) }, twofocous() { this.setData({ 'list[3].border': true }) }, // 获得焦点当前选中的边框改变颜色 // 获取X xValue(e) { this.setData({ xValue: e.detail.value, 'list[0].border': false }) }, // 获取y yValue(e) { this.setData({ yValue: e.detail.value, 'list[1].border': false }) }, // 获取秒 azimuthValue(e) { this.setData({ azimuthValue: e.detail.value, 'list[2].border': false }) }, twoValue(e) { this.setData({ twoValue: e.detail.value, 'list[3].border': false }) }, // 失去焦点边框改变颜色 // 计算 calculations: function () { const PI = Math.PI var that = this var xa = Number(that.data.xValue) // x var ya = Number(that.data.yValue) //y var azimuthValue = that.data.azimuthValue //方位角 var d = Number(that.data.twoValue) //两点距离 var dufenmiao = azimuthValue.split('.'); //获取输入的数组 if (azimuthValue.indexOf(".") < 0) { var du = Number(dufenmiao[0]) var fen = 0 var miao = 0 } else { var du = Number(dufenmiao[0]) var fen = Number(dufenmiao[1]) var miao = Number(dufenmiao[2]) } var deg = du + fen / 60 + miao / 3600 var xb = getApp().fomatFloat((xa + d * Math.cos(deg * PI / 180)), 5) //保留5位小数 var yb = getApp().fomatFloat((ya + d * Math.sin(deg * PI / 180)), 5) if (that.data.xValue == '' || that.data.yValue == '' || that.data.azimuthValue == '' || that.data.twoValue == '') { wx.vibrateShort({}) //开启震动 wx.showModal({ title: '友情提示', content: '请您输入完整的值在进行计算!?', showCancel: false, cancelText: "确定" }) } else if (azimuthValue.indexOf(".") < 0) { wx.vibrateShort({}) //开启震动 wx.showModal({ title: '友情提示', content: '您当前没有以点号隔开,默认按 度.00.00 计算 ?', success(res) { if (res.confirm) { that.setData({ resultShow: false, xb: xb, yb: yb }) } } }) } else { if (azimuthValue.indexOf(".") == -1 || azimuthValue.split(".").length - 1 !== 2) { wx.vibrateShort({}) //开启震动 wx.showModal({ title: '友情提示!', content: '角度请您按照所给格式输入,如23.23.1中间必须以点隔开。!?', success(res) { if (res.confirm) { that.setData({ 'list[2].border': true, 'list[3].border': false }) } } }) } else { that.setData({ resultShow: false, xb: xb, yb: yb }) } } }, // 调用最终计算 //单击计算 multipleTap: function (e) { var that = this let curTime = e.timeStamp; let lastTime = that.lastTapDiffTime; that.lastTapDiffTime = curTime; //两次点击间隔小于300ms, 认为是双击 let diff = curTime - lastTime; if (diff < 300) { clearTimeout(that.lastTapTimeoutFunc); // 成功触发双击事件时,取消单击事件的执行 that.setData({ cleantext: '', xValue: '', yValue: '', azimuthValue: '', twoValue: '' }) } else { //双击清空 // 单击事件延时300毫秒执行,这和最初的浏览器的点击300ms延时有点像。 that.lastTapTimeoutFunc = setTimeout(function () { that.calculations() }, 300); } }})
其中最主要的部分为以下的部分这里实现了角度到度分秒的实现,小程序中都是用的JS代码实现,你也可以用各种编程语言去实现,此处仅作为抛砖引玉。
const PI = Math.PI var that = this var xa = Number(that.data.xValue) // x var ya = Number(that.data.yValue) //y var azimuthValue = that.data.azimuthValue //方位角 var d = Number(that.data.twoValue) //两点距离 var dufenmiao = azimuthValue.split('.'); //获取输入的数组 if (azimuthValue.indexOf(".") < 0) { var du = Number(dufenmiao[0]) var fen = 0 var miao = 0 } else { var du = Number(dufenmiao[0]) var fen = Number(dufenmiao[1]) var miao = Number(dufenmiao[2]) } var deg = du + fen / 60 + miao / 3600 var xb = getApp().fomatFloat((xa + d * Math.cos(deg * PI / 180)), 5) //保留5位小数 var yb = getApp().fomatFloat((ya + d * Math.sin(deg * PI / 180)), 5)
03、展示
图3-1 开发现场
图3-2 开发现场
自从回来雨似乎没有停止过它的呼吸,也许这个世界应该也需要晴女,让阳光温暖这片故土。
-END-
-预告-
以下小程序是本教程最终要开发的产品可以点击体验,下一篇为从0开发《工程测绘大师》小程序之坐标反算(十二)
●从0开发《工程测绘大师》小程序之6°带中央子午线计算篇(八)
●从0开发《工程测绘大师》小程序之玩转角度与度分秒相互转换篇(九)
●从0开发《工程测绘大师》小程序之玩转角度与弧度的互相转化篇(十)
我就知道你“在看”