|
@@ -0,0 +1,264 @@
|
|
|
+package org.springblade.manager.formula.impl;
|
|
|
+
|
|
|
+import com.mixsmart.utils.CustomFunction;
|
|
|
+import com.mixsmart.utils.ListUtils;
|
|
|
+import com.mixsmart.utils.StringUtils;
|
|
|
+import org.springblade.manager.formula.ITurnPointCalculator;
|
|
|
+import org.springblade.manager.formula.LevelInfo;
|
|
|
+import org.springblade.manager.formula.NextPoint;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Random;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import static java.math.BigDecimal.ROUND_HALF_UP;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author yangyj
|
|
|
+ * @Date 2022/9/6 11:51
|
|
|
+ * @description TODO
|
|
|
+ */
|
|
|
+public class TurnPointCalculator implements ITurnPointCalculator {
|
|
|
+ public static Double FACTOR =0.46D;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<NextPoint> turnPoint(LevelInfo levelInfo, NextPoint nextPoint) {
|
|
|
+ double min=levelInfo.getMin();
|
|
|
+ List<NextPoint> list = new ArrayList<>();
|
|
|
+ double cD =levelInfo.getStep();
|
|
|
+ double bD= levelInfo.getBmh();
|
|
|
+ double npD=Double.parseDouble(nextPoint.getSc());
|
|
|
+ boolean existQ=StringUtils.isNumber(nextPoint.getQ());
|
|
|
+ double qD=existQ?Double.parseDouble(StringUtils.number2String(nextPoint.getQ(),3)):0;
|
|
|
+ /*默认保留三位小数*/
|
|
|
+ int scaleI = levelInfo.getScale();
|
|
|
+ /*前视后视的高差计算参数,趋高的时候前视小后视大,趋低的时候前视大后视小*/
|
|
|
+ double cut = BigDecimal.valueOf(cD*FACTOR).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ Random rd = new Random();
|
|
|
+ /*累计循环次数,循环上限是300*/
|
|
|
+ int count=0;
|
|
|
+ if(existQ){
|
|
|
+ if(npD+qD==bD){
|
|
|
+ /*已经得到正确的测量结果*/
|
|
|
+ list.add(new NextPoint(StringUtils.number2String(bD-npD,scaleI),StringUtils.number2String(npD,scaleI)));
|
|
|
+ }else{
|
|
|
+ /**
|
|
|
+ * target是当前测点的前一个转点仪器高*/
|
|
|
+ double target=npD+qD;
|
|
|
+ boolean higher=target>bD;
|
|
|
+ boolean loop=true;
|
|
|
+ do{
|
|
|
+ double big,small;
|
|
|
+ /*视高和目标视高的差值落在前后视最大差值内*/
|
|
|
+ /*bD可能从上下两个方向不断逼近target*/
|
|
|
+ if(Math.abs(bD-target)<cD-min){
|
|
|
+ loop=false;
|
|
|
+ double hd=Math.abs(bD-target);
|
|
|
+ big=BigDecimal.valueOf(rd.nextDouble()*(cD-cut)+cut).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ small=big-hd;
|
|
|
+ NextPoint lastZd =new NextPoint();
|
|
|
+ lastZd.setBmd(StringUtils.number2String(target,3));
|
|
|
+ if(higher){
|
|
|
+ /*前小后大*/
|
|
|
+ lastZd.setQ(StringUtils.number2String(small,3));
|
|
|
+ lastZd.setH(StringUtils.number2String(big,3));
|
|
|
+ }else{
|
|
|
+ /*前大后小*/
|
|
|
+ lastZd.setQ(StringUtils.number2String(big,3));
|
|
|
+ lastZd.setH(StringUtils.number2String(small,3));
|
|
|
+ }
|
|
|
+ lastZd.setZd(true);
|
|
|
+ list.add(lastZd);
|
|
|
+ list.add(new NextPoint(StringUtils.number2String(qD,3),StringUtils.number2String(npD,3)));
|
|
|
+ }else{
|
|
|
+ big=BigDecimal.valueOf(rd.nextDouble()*(cD-cut)+cut).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ small=BigDecimal.valueOf(rd.nextDouble()*(cut-0.6)+0.5).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ NextPoint p =createNextPoint(higher,big,small,bD,null,scaleI);
|
|
|
+ bD=Double.parseDouble(p.getBmd());
|
|
|
+ list.add(p);
|
|
|
+ }
|
|
|
+ count++;
|
|
|
+ }while (loop&&count<300);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ boolean loop=true;
|
|
|
+ do{
|
|
|
+ double big,small;
|
|
|
+ boolean higher=npD+min>bD;
|
|
|
+ NextPoint p;
|
|
|
+ if(bD-npD>min&&bD-npD<cD){
|
|
|
+ /*测点已经在仪器测量范围0.5<x<step*/
|
|
|
+ loop=false;
|
|
|
+ p=new NextPoint();
|
|
|
+ zd(bD-npD,0d,bD,npD,scaleI,p);
|
|
|
+ }else{
|
|
|
+ big=BigDecimal.valueOf(rd.nextDouble()*(cD-cut)+cut).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ small=BigDecimal.valueOf(rd.nextDouble()*(cut-0.6)+0.5).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ p =createNextPoint(higher,big,small,bD,npD,scaleI);
|
|
|
+ }
|
|
|
+ /*更新视高*/
|
|
|
+ if(StringUtils.isNotEmpty(p.getBmd())){
|
|
|
+ bD=Double.parseDouble(p.getBmd());
|
|
|
+ }
|
|
|
+ list.add(p);
|
|
|
+ count++;
|
|
|
+ }while (loop&&count<300);
|
|
|
+ }
|
|
|
+ if(list.size()>1){
|
|
|
+ levelInfo.setSightHeight(Double.parseDouble(list.get(list.size()-1).getBmd()));
|
|
|
+ levelInfo.getNextPointList().addAll(list.stream().limit(list.size()-1).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+ public NextPoint createNextPoint(Boolean higher,Double big,Double small ,Double bD,Double sc,Integer scaleI){
|
|
|
+ NextPoint p = new NextPoint();
|
|
|
+ if(higher){
|
|
|
+ /*测点大于仪器高0.5米*/
|
|
|
+ /*前视小后视大*/
|
|
|
+ zd(small, big, bD, sc, scaleI, p);
|
|
|
+ }else{
|
|
|
+ /*前视大后视小*/
|
|
|
+ zd(big, small, bD, sc, scaleI, p);
|
|
|
+ }
|
|
|
+ return p;
|
|
|
+ }
|
|
|
+ private void zd(Double q, Double h, Double bD, Double sc, Integer scaleI, NextPoint p) {
|
|
|
+ p.setQ(StringUtils.number2String(q,scaleI));
|
|
|
+ if(h!=0) {
|
|
|
+ p.setBmd(StringUtils.number2String(bD+h-q,scaleI));
|
|
|
+ p.setH(StringUtils.number2String(h, scaleI));
|
|
|
+ p.setZd(true);
|
|
|
+ }else{
|
|
|
+ p.setSc(StringUtils.number2String(sc,scaleI));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public static Random RD= new Random();
|
|
|
+ public static void jitter(NextPoint np){
|
|
|
+ if(np!=null&&StringUtils.isNotEmpty(np.getBmd())){
|
|
|
+ double dx = Math.random()*0.07*(RD.nextBoolean()?-1:1);
|
|
|
+ np.setBmd(StringUtils.number2String(Double.parseDouble(np.getBmd())+dx,3));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<NextPoint> closePoint(List<NextPoint> forward, LevelInfo levelInfo) {
|
|
|
+ List<NextPoint> result = new ArrayList<>();
|
|
|
+ Random rd = new Random();
|
|
|
+ /*默认保留三位小数*/
|
|
|
+ int scaleI=levelInfo.getScale();
|
|
|
+ /*当前实测点*/
|
|
|
+ Double[] DL=new Double[]{0.001,0.002,0.003,-0.001,-0.002,-0.003};
|
|
|
+ double ldx=DL[(int)Math.round(Math.random()*5)];
|
|
|
+ double scD= levelInfo.getBmh()+ldx;
|
|
|
+ /*当前仪器视线高*/
|
|
|
+ double bD=levelInfo.getSightHeight();
|
|
|
+ if(ListUtils.isNotEmpty(forward)){
|
|
|
+ /*每一个转点仪器视高之间最大高差*/
|
|
|
+ double cD =levelInfo.getStep();
|
|
|
+ /*必须保证转点视高最小高程大于0.5*/
|
|
|
+ String target=StringUtils.number2String(scD+0.5+rd.nextDouble()*(cD-0.5),scaleI);
|
|
|
+ List<NextPoint> backward = new ArrayList<>(forward);
|
|
|
+ /*反转转点得到闭合转点走势*/
|
|
|
+ Collections.reverse(backward);
|
|
|
+ backward=backward.stream().peek(TurnPointCalculator::jitter).collect(Collectors.toList());
|
|
|
+ backward.add(new NextPoint("0","0",target));
|
|
|
+ if(backward.size()>1){
|
|
|
+ /*去头*/
|
|
|
+ backward.remove(0);
|
|
|
+ }
|
|
|
+ for(NextPoint np:backward){
|
|
|
+ double dx = bD-Double.parseDouble(np.getBmd());
|
|
|
+ double dxx=Math.abs(dx);
|
|
|
+ double big=BigDecimal.valueOf(rd.nextDouble()*(cD-dxx-0.5)+dxx+0.5).setScale(scaleI,ROUND_HALF_UP).doubleValue();
|
|
|
+ double small=big-dxx;
|
|
|
+ if(dx<0){
|
|
|
+ /*后大前小,取高*/
|
|
|
+ np.setQ(StringUtils.number2String(small,3));
|
|
|
+ np.setH(StringUtils.number2String(big,3));
|
|
|
+
|
|
|
+ }else{
|
|
|
+ /*前大后小,趋低*/
|
|
|
+ np.setQ(StringUtils.number2String(big,3));
|
|
|
+ np.setH(StringUtils.number2String(small,3));
|
|
|
+ }
|
|
|
+ bD=Double.parseDouble(np.getBmd());
|
|
|
+ result.add(np);
|
|
|
+ }
|
|
|
+ result.add(new NextPoint(StringUtils.number2String(Double.parseDouble(target)-scD,scaleI),StringUtils.number2String(scD,scaleI)));
|
|
|
+ }else{
|
|
|
+ /*闭合点*/
|
|
|
+ result.add(new NextPoint(StringUtils.number2String(bD-scD,scaleI),StringUtils.number2String(scD,scaleI)));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public NextPoint vacancy(Object qs, Object gc, Object sj, Double bmd, String range, Object step){
|
|
|
+ NextPoint np = new NextPoint();
|
|
|
+ String dev="-6,6";
|
|
|
+ if(StringUtils.isNotEmpty(range)){
|
|
|
+ dev=range.replaceAll("[\\[\\]]","");
|
|
|
+ }
|
|
|
+ String dx;
|
|
|
+ double cD=Double.parseDouble(step.toString());
|
|
|
+ double min=0.5d;
|
|
|
+ do{
|
|
|
+ dx= CustomFunction.rangeList(1,0,dev,1,0,1).get(0).toString();
|
|
|
+ }while (StringUtils.isEquals(0,dx));
|
|
|
+ double hd;
|
|
|
+ boolean hasNp=true;
|
|
|
+ if(StringUtils.isNotEmpty(bmd,gc)){
|
|
|
+ hd=Double.parseDouble(bmd.toString())-Double.parseDouble(gc.toString());
|
|
|
+ if(hd>min&&hd<cD){
|
|
|
+ hasNp=false;
|
|
|
+ }
|
|
|
+ np.setSc(StringUtils.handleNull(gc));
|
|
|
+ }
|
|
|
+ if(StringUtils.isNotEmpty(gc)&&StringUtils.isEmpty(sj,qs)){
|
|
|
+ /*010*/
|
|
|
+ if(!hasNp){
|
|
|
+ np.setQ(CustomFunction.calculate(bmd,gc,3,2).toString());
|
|
|
+ }
|
|
|
+ }else if(StringUtils.isNotEmpty(gc,sj)&&StringUtils.isEmpty(qs)){
|
|
|
+ /*011*/
|
|
|
+ if(!hasNp){
|
|
|
+ np.setQ(CustomFunction.calculate(bmd,gc,3,2).toString());
|
|
|
+ }
|
|
|
+ np.setSj(sj.toString());
|
|
|
+ }else if(StringUtils.isNotEmpty(gc,qs)&&StringUtils.isEmpty(sj)){
|
|
|
+ /*110*/
|
|
|
+ np.setQ(qs.toString());
|
|
|
+ }else if(StringUtils.isNotEmpty(sj)&&StringUtils.isEmpty(gc,qs)){
|
|
|
+ /*001*/
|
|
|
+ np.setSj(sj.toString());
|
|
|
+ np.setSc(StringUtils.number2String(Double.parseDouble(np.getSj())+Double.parseDouble(dx)/1000,3));
|
|
|
+ hd=Double.parseDouble(bmd.toString())-Double.parseDouble(np.getSc());
|
|
|
+ if(hd>min&&hd<cD){
|
|
|
+ hasNp=false;
|
|
|
+ }
|
|
|
+ if(!hasNp){
|
|
|
+ np.setQ(CustomFunction.calculate(bmd,np.getSc(),3,2).toString());
|
|
|
+ }
|
|
|
+ }else if(StringUtils.isNotEmpty(qs,bmd)&&StringUtils.isEmpty(gc,sj)){
|
|
|
+ /*100*/
|
|
|
+ np.setQ(qs.toString());
|
|
|
+ np.setSc(StringUtils.number2String(bmd-Double.parseDouble(np.getQ()),3));
|
|
|
+ }else if(StringUtils.isNotEmpty(qs,sj)&&StringUtils.isEmpty(gc)){
|
|
|
+ /*101*/
|
|
|
+ np.setQ(qs.toString());
|
|
|
+ np.setSc(StringUtils.number2String(Double.parseDouble(sj.toString())+Double.parseDouble(dx)/1000,3));
|
|
|
+ }else if(StringUtils.isNotEmpty(qs,sj,gc)){
|
|
|
+ /*111*/
|
|
|
+ np.setQ(qs.toString());
|
|
|
+ np.setSc(gc.toString());
|
|
|
+ }
|
|
|
+ if(np.getSc()==null){
|
|
|
+ /*实测高程一定不能为空*/
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return np;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|