|  |  |  | 
|---|
|  |  |  | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; | 
|---|
|  |  |  | import com.moral.api.entity.HistorySecondUav; | 
|---|
|  |  |  | import com.moral.api.mapper.HistorySecondUavMapper; | 
|---|
|  |  |  | import com.moral.api.pojo.dto.uav.UAVGetBD; | 
|---|
|  |  |  | import com.moral.api.pojo.dto.uav.UAVGteForDTO; | 
|---|
|  |  |  | import com.moral.api.pojo.dto.uav.UAVQueryTimeSlotDTO; | 
|---|
|  |  |  | import com.moral.api.pojo.dto.uav.UAVResultDTO; | 
|---|
|  |  |  | 
|---|
|  |  |  | import com.moral.api.pojo.vo.uav.UAVQueryTimeSlotVO; | 
|---|
|  |  |  | import com.moral.api.pojo.vo.uav.UAVQueryTimeSlotVOs; | 
|---|
|  |  |  | import com.moral.api.service.HistorySecondUavService; | 
|---|
|  |  |  | import com.moral.api.service.UAVService; | 
|---|
|  |  |  | import com.moral.constant.ResponseCodeEnum; | 
|---|
|  |  |  | import com.moral.constant.ResultMessage; | 
|---|
|  |  |  | import com.moral.util.DateUtils; | 
|---|
|  |  |  | 
|---|
|  |  |  | HistorySecondUavService historySecondUavService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | HistorySecondUavMapper historySecondUavMapper; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | UAVService uavService; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * @Description: 根据批次号查询无人机飞行数据 | 
|---|
|  |  |  | 
|---|
|  |  |  | return new ResultMessage(ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getMsg(),vo); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PostMapping("test") | 
|---|
|  |  |  | @PostMapping("getUav") | 
|---|
|  |  |  | public ResultMessage test(@RequestBody Map<String, Object> params){ | 
|---|
|  |  |  | //判断是否缺少参数 | 
|---|
|  |  |  | if (!params.containsKey("mac") || !params.containsKey("batch") || !params.containsKey("height")|| !params.containsKey("uvasize")) { | 
|---|
|  |  |  | if (!params.containsKey("mac") || !params.containsKey("batch") || !params.containsKey("height1")|| !params.containsKey("uvasize")|| !params.containsKey("height2")) { | 
|---|
|  |  |  | return ResultMessage.fail(ResponseCodeEnum.PARAMETERS_IS_MISSING.getCode(), ResponseCodeEnum.PARAMETERS_IS_MISSING.getMsg()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String uvasize = params.get("uvasize").toString(); | 
|---|
|  |  |  | int size = Integer.parseInt(uvasize); | 
|---|
|  |  |  | //纬度 | 
|---|
|  |  |  | ArrayList<Double> flyLatList = new ArrayList<>(); | 
|---|
|  |  |  | //经度 | 
|---|
|  |  |  | ArrayList<Double> flyLonList = new ArrayList<>(); | 
|---|
|  |  |  | //        String mac ="p5dnd7a0243591"; | 
|---|
|  |  |  | //        String time1 ="2023-07-19 14:14:08"; | 
|---|
|  |  |  | //        String time2 ="2023-07-19 14:35:29"; | 
|---|
|  |  |  | // | 
|---|
|  |  |  | ////        List<UAVResultDTO> uavResultDTOS = historySecondUavMapper.reList(map); | 
|---|
|  |  |  | //        QueryWrapper<HistorySecondUav> queryWrapper = new QueryWrapper<>(); | 
|---|
|  |  |  | //        queryWrapper.select("value"); | 
|---|
|  |  |  | //        queryWrapper.eq("mac",mac); | 
|---|
|  |  |  | //        queryWrapper.between("time",time1,time2); | 
|---|
|  |  |  | //        List<HistorySecondUav> historySecondUavs = historySecondUavMapper.selectList(queryWrapper); | 
|---|
|  |  |  | List<HistorySecondUav> historySecondUavs = historySecondUavMapper.reList(params); | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(historySecondUavs)){ | 
|---|
|  |  |  | return new ResultMessage(ResponseCodeEnum.TARGET_IS_NULL,"null"); | 
|---|
|  |  |  | List<UAVResultDTO> uavResultDTOS = uavService.getUav(params); | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(uavResultDTOS)){ | 
|---|
|  |  |  | return new ResultMessage(ResponseCodeEnum.SENSOR_IS_NOT_EXIST,"null"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | int ik=1; | 
|---|
|  |  |  | for (HistorySecondUav historySecondUav : historySecondUavs) { | 
|---|
|  |  |  | String value = historySecondUav.getValue(); | 
|---|
|  |  |  | Map map1 = JSON.parseObject(value, Map.class); | 
|---|
|  |  |  | flyLatList.add(Double.parseDouble(map1.get("flylat").toString())); | 
|---|
|  |  |  | flyLonList.add(Double.parseDouble(map1.get("flylon").toString())); | 
|---|
|  |  |  | historySecondUav.setId(ik++); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Double maxLat = Collections.max(flyLatList); | 
|---|
|  |  |  | Double maxLon = Collections.max(flyLonList); | 
|---|
|  |  |  | Double minLat = Collections.min(flyLatList); | 
|---|
|  |  |  | Double minLon = Collections.min(flyLonList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //大四边形右下 | 
|---|
|  |  |  | String leftTop =  minLat +";"+ maxLon; | 
|---|
|  |  |  | //右上 | 
|---|
|  |  |  | String rightTop =  maxLat +";"+ maxLon; | 
|---|
|  |  |  | //左下 | 
|---|
|  |  |  | String leftBottom = minLat +";" + minLon; | 
|---|
|  |  |  | //左上 | 
|---|
|  |  |  | String rightBottom = maxLat +";" + minLon; | 
|---|
|  |  |  | //计算纬度的距离 | 
|---|
|  |  |  | double distance1 = getDistance(maxLon, minLat, maxLon, maxLat); | 
|---|
|  |  |  | //计算经度的距离 | 
|---|
|  |  |  | double distance2 = getDistance(maxLon, minLat, minLon, minLat); | 
|---|
|  |  |  | ArrayList<UAVGteForDTO> list = new ArrayList<>(); | 
|---|
|  |  |  | //小四边形 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String [] lefts =new String[]{maxLon.toString(),minLat.toString()}; | 
|---|
|  |  |  | //右上2 | 
|---|
|  |  |  | String[] youshang = calLocationByDistanceAndLocationAndDirection(90, minLon, maxLat, 50); | 
|---|
|  |  |  | //右下2 | 
|---|
|  |  |  | String[] youxia = calLocationByDistanceAndLocationAndDirection(180, Double.parseDouble(youshang[0]), Double.parseDouble(youshang[1]), 50); | 
|---|
|  |  |  | //左下2 | 
|---|
|  |  |  | String[] zuoxia = calLocationByDistanceAndLocationAndDirection(180, minLon, maxLat, 50); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (int i = 0; i <distance2 ; i+=size) { | 
|---|
|  |  |  | UAVGteForDTO dto1 = new UAVGteForDTO(); | 
|---|
|  |  |  | String[] strings2 = calLocationByDistanceAndLocationAndDirection(90, minLon, maxLat, i); | 
|---|
|  |  |  | String[] strings3 = calLocationByDistanceAndLocationAndDirection(90, Double.parseDouble(youshang[0].toString()), Double.parseDouble(youshang[1].toString()), i); | 
|---|
|  |  |  | String[] strings4 = calLocationByDistanceAndLocationAndDirection(90, Double.parseDouble(youxia[0].toString()), Double.parseDouble(youxia[1].toString()), i); | 
|---|
|  |  |  | String[] strings5 = calLocationByDistanceAndLocationAndDirection(90, Double.parseDouble(zuoxia[0].toString()), Double.parseDouble(zuoxia[1].toString()), i); | 
|---|
|  |  |  | dto1.setLeftTop(strings2); | 
|---|
|  |  |  | dto1.setRightTop(strings3); | 
|---|
|  |  |  | dto1.setRightBottom(strings4); | 
|---|
|  |  |  | dto1.setLeftBottom(strings5); | 
|---|
|  |  |  | list.add(dto1); | 
|---|
|  |  |  | for (int j = 0; j < distance1; j+=size) { | 
|---|
|  |  |  | UAVGteForDTO dto2 = new UAVGteForDTO(); | 
|---|
|  |  |  | String[] strings6 = calLocationByDistanceAndLocationAndDirection(180, Double.parseDouble(strings2[0].toString()), Double.parseDouble(strings2[1].toString()), j); | 
|---|
|  |  |  | String[] strings7 = calLocationByDistanceAndLocationAndDirection(180, Double.parseDouble(strings3[0].toString()), Double.parseDouble(strings3[1].toString()), j); | 
|---|
|  |  |  | String[] strings8 = calLocationByDistanceAndLocationAndDirection(180, Double.parseDouble(strings4[0].toString()), Double.parseDouble(strings4[1].toString()), j); | 
|---|
|  |  |  | String[] strings9 = calLocationByDistanceAndLocationAndDirection(180, Double.parseDouble(strings5[0].toString()), Double.parseDouble(strings5[1].toString()), j); | 
|---|
|  |  |  | dto2.setLeftTop(strings6); | 
|---|
|  |  |  | dto2.setRightTop(strings7); | 
|---|
|  |  |  | dto2.setRightBottom(strings8); | 
|---|
|  |  |  | dto2.setLeftBottom(strings9); | 
|---|
|  |  |  | if (j!=0){ | 
|---|
|  |  |  | list.add(dto2); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | HashMap<String,List<String>> rsMap = new HashMap<>(); | 
|---|
|  |  |  | List<String>  stringList = new ArrayList<>(); | 
|---|
|  |  |  | for (UAVGteForDTO uavGteForDTO : list) { | 
|---|
|  |  |  | ArrayList<String> list1 = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<String[]> doubleArrayList = new ArrayList<>(); | 
|---|
|  |  |  | doubleArrayList.add(uavGteForDTO.getLeftTop()); | 
|---|
|  |  |  | doubleArrayList.add(uavGteForDTO.getLeftBottom()); | 
|---|
|  |  |  | doubleArrayList.add(uavGteForDTO.getRightTop()); | 
|---|
|  |  |  | doubleArrayList.add(uavGteForDTO.getRightBottom()); | 
|---|
|  |  |  | String[] leftTops = uavGteForDTO.getLeftTop(); | 
|---|
|  |  |  | String[] rightBottoms = uavGteForDTO.getRightBottom(); | 
|---|
|  |  |  | Double x1 = Double.parseDouble(leftTops[0]); | 
|---|
|  |  |  | Double x2 = Double.parseDouble(rightBottoms[0]); | 
|---|
|  |  |  | Double y1 = Double.parseDouble(leftTops[1]); | 
|---|
|  |  |  | Double y2 = Double.parseDouble(rightBottoms[1]); | 
|---|
|  |  |  | //获取区域对象 | 
|---|
|  |  |  | for (int i = 0; i < historySecondUavs.size(); i++) { | 
|---|
|  |  |  | HistorySecondUav historySecondUav = historySecondUavs.get(i); | 
|---|
|  |  |  | String value = historySecondUav.getValue(); | 
|---|
|  |  |  | Map map1 = JSON.parseObject(value, Map.class); | 
|---|
|  |  |  | String flylat = map1.get("flylat").toString(); | 
|---|
|  |  |  | String flylon = map1.get("flylon").toString(); | 
|---|
|  |  |  | //判断点是否在区域内 | 
|---|
|  |  |  | boolean flag = isInPolygon(flylon,flylat,x1,x2,y1,y2); | 
|---|
|  |  |  | if (flag){ | 
|---|
|  |  |  | String time = DateUtils.dateToDateString(historySecondUav.getTime()); | 
|---|
|  |  |  | //historySecondUavs.remove(i); | 
|---|
|  |  |  | if(!stringList.contains(time)){ | 
|---|
|  |  |  | list1.add(historySecondUav.getValue()); | 
|---|
|  |  |  | stringList.add(time); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //获取中心点坐标 | 
|---|
|  |  |  | String result = getResult(doubleArrayList); | 
|---|
|  |  |  | rsMap.put(result,list1); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //计算区域类所有因子的平均数 | 
|---|
|  |  |  | ArrayList<UAVResultDTO> uavResultDTOS = new ArrayList<>(); | 
|---|
|  |  |  | Set<String> strings = rsMap.keySet(); | 
|---|
|  |  |  | for (String string : strings) { | 
|---|
|  |  |  | UAVResultDTO dto = new UAVResultDTO(); | 
|---|
|  |  |  | List<String> list1 = rsMap.get(string); | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(list1)){ | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | ArrayList<Double> TVOCArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> PM10ArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> PM25ArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> SOArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> NOArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> QYArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> COArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> WDArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> SHArrayList = new ArrayList<>(); | 
|---|
|  |  |  | ArrayList<Double> O3ArrayList = new ArrayList<>(); | 
|---|
|  |  |  | for (String s : list1) { | 
|---|
|  |  |  | JSONObject jsonObject = JSON.parseObject(s); | 
|---|
|  |  |  | //tvoc | 
|---|
|  |  |  | Object a99054 = jsonObject.get("a99054"); | 
|---|
|  |  |  | if (!Objects.isNull(a99054)){ | 
|---|
|  |  |  | TVOCArrayList.add(Double.parseDouble(a99054.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //pm2.5 | 
|---|
|  |  |  | Object a34004 = jsonObject.get("a34004"); | 
|---|
|  |  |  | if (!Objects.isNull(a34004)){ | 
|---|
|  |  |  | PM25ArrayList.add(Double.parseDouble(a34004.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //二氧化硫 | 
|---|
|  |  |  | Object a21026 = jsonObject.get("a21026"); | 
|---|
|  |  |  | if (!Objects.isNull(a21026)){ | 
|---|
|  |  |  | SOArrayList.add(Double.parseDouble(a21026.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //二氧化氮 | 
|---|
|  |  |  | Object a21004 = jsonObject.get("a21004"); | 
|---|
|  |  |  | if (!Objects.isNull(a21004)){ | 
|---|
|  |  |  | NOArrayList.add(Double.parseDouble(a21004.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //气压 | 
|---|
|  |  |  | Object a01006 = jsonObject.get("a01006"); | 
|---|
|  |  |  | if (!Objects.isNull(a01006)){ | 
|---|
|  |  |  | QYArrayList.add(Double.parseDouble(a01006.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //pm10 | 
|---|
|  |  |  | Object a34002 = jsonObject.get("a34002"); | 
|---|
|  |  |  | if (!Objects.isNull(a34002)){ | 
|---|
|  |  |  | PM10ArrayList.add(Double.parseDouble(a34002.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //co | 
|---|
|  |  |  | Object a21005 = jsonObject.get("a21005"); | 
|---|
|  |  |  | if (!Objects.isNull(a21005)){ | 
|---|
|  |  |  | COArrayList.add(Double.parseDouble(a21005.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //湿度 | 
|---|
|  |  |  | Object a01002 = jsonObject.get("a01002"); | 
|---|
|  |  |  | if (!Objects.isNull(a01002)){ | 
|---|
|  |  |  | QYArrayList.add(Double.parseDouble(a01002.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //温度 | 
|---|
|  |  |  | Object a01001 = jsonObject.get("a01001"); | 
|---|
|  |  |  | if (!Objects.isNull(a01001)){ | 
|---|
|  |  |  | QYArrayList.add(Double.parseDouble(a01001.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //臭氧 | 
|---|
|  |  |  | Object a05024 = jsonObject.get("a05024"); | 
|---|
|  |  |  | if (!Objects.isNull(a05024)){ | 
|---|
|  |  |  | O3ArrayList.add(Double.parseDouble(a05024.toString())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | double WDDouble =0.0; | 
|---|
|  |  |  | double SHDouble =0.0; | 
|---|
|  |  |  | double QYDouble =0.0; | 
|---|
|  |  |  | double CODouble =0.0; | 
|---|
|  |  |  | double TVODouble =0.0; | 
|---|
|  |  |  | double PM10Double =0.0; | 
|---|
|  |  |  | double PM25Double =0.0; | 
|---|
|  |  |  | double SODouble =0.0; | 
|---|
|  |  |  | double NODouble =0.0; | 
|---|
|  |  |  | double O3Double =0.0; | 
|---|
|  |  |  | if (COArrayList.size()>0){ | 
|---|
|  |  |  | CODouble = COArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (TVOCArrayList.size()>0){ | 
|---|
|  |  |  | TVODouble = TVOCArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (PM10ArrayList.size()>0){ | 
|---|
|  |  |  | PM10Double = PM10ArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (PM25ArrayList.size()>0){ | 
|---|
|  |  |  | PM25Double = PM25ArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (SOArrayList.size()>0){ | 
|---|
|  |  |  | SODouble = SOArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (NOArrayList.size()>0){ | 
|---|
|  |  |  | NODouble = NOArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (WDArrayList.size()>0){ | 
|---|
|  |  |  | WDDouble = WDArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (SHArrayList.size()>0){ | 
|---|
|  |  |  | SHDouble = SHArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (QYArrayList.size()>0){ | 
|---|
|  |  |  | QYDouble = QYArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (O3ArrayList.size()>0){ | 
|---|
|  |  |  | O3Double = O3ArrayList.stream().mapToDouble(Double::doubleValue).average().getAsDouble(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //            dto.setCoAvg(CODouble); | 
|---|
|  |  |  | //            dto.setNO2Avg(NODouble); | 
|---|
|  |  |  | //            dto.setO3Avg(O3Double); | 
|---|
|  |  |  | //            dto.setTVOCAvg(TVODouble); | 
|---|
|  |  |  | //            dto.setPM10Avg(PM10Double); | 
|---|
|  |  |  | //            dto.setPM25Avg(PM25Double); | 
|---|
|  |  |  | //            dto.setSO2Avg(SODouble); | 
|---|
|  |  |  | //            dto.setWDAvg(WDDouble); | 
|---|
|  |  |  | //            dto.setSHAvg(SHDouble); | 
|---|
|  |  |  | //            dto.setQYAvg(QYDouble); | 
|---|
|  |  |  | dto.setA21005(CODouble); | 
|---|
|  |  |  | dto.setA21004(NODouble); | 
|---|
|  |  |  | dto.setA05024(O3Double); | 
|---|
|  |  |  | dto.setA99054(TVODouble); | 
|---|
|  |  |  | dto.setA34002(PM10Double); | 
|---|
|  |  |  | dto.setA34004(PM25Double); | 
|---|
|  |  |  | dto.setA21026(SODouble); | 
|---|
|  |  |  | dto.setA01001(WDDouble); | 
|---|
|  |  |  | dto.setA01002(SHDouble); | 
|---|
|  |  |  | dto.setA01006(QYDouble); | 
|---|
|  |  |  | String[] s = string.split("_"); | 
|---|
|  |  |  | dto.setFlyLat(Double.parseDouble(s[1])); | 
|---|
|  |  |  | dto.setFlyLon(Double.parseDouble(s[0])); | 
|---|
|  |  |  | uavResultDTOS.add(dto); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return new ResultMessage(ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getMsg(),uavResultDTOS); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | return new ResultMessage(ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getMsg(),vo); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static final double EARTH_RADIUS = 6378137; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static final double R = 6371e3; | 
|---|
|  |  |  | /** 180° **/ | 
|---|
|  |  |  | private static final DecimalFormat df = new DecimalFormat("0.00000000"); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 根据一点的坐标与距离,以及方向,计算另外一点的位置 | 
|---|
|  |  |  | * @param angle 角度,从正北顺时针方向开始计算 | 
|---|
|  |  |  | * @param startLong 起始点经度 | 
|---|
|  |  |  | * @param startLat 起始点纬度 | 
|---|
|  |  |  | * @param distance 距离,单位m | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static String[] calLocationByDistanceAndLocationAndDirection(double angle, double startLong,double startLat, double distance){ | 
|---|
|  |  |  | String[] result = new String[2]; | 
|---|
|  |  |  | //将距离转换成经度的计算公式 | 
|---|
|  |  |  | double δ = distance/R; | 
|---|
|  |  |  | // 转换为radian,否则结果会不正确 | 
|---|
|  |  |  | angle = Math.toRadians(angle); | 
|---|
|  |  |  | startLong = Math.toRadians(startLong); | 
|---|
|  |  |  | startLat = Math.toRadians(startLat); | 
|---|
|  |  |  | double lat = Math.asin(Math.sin(startLat)*Math.cos(δ)+Math.cos(startLat)*Math.sin(δ)*Math.cos(angle)); | 
|---|
|  |  |  | double lon = startLong + Math.atan2(Math.sin(angle)*Math.sin(δ)*Math.cos(startLat),Math.cos(δ)-Math.sin(startLat)*Math.sin(lat)); | 
|---|
|  |  |  | // 转为正常的10进制经纬度 | 
|---|
|  |  |  | lon = Math.toDegrees(lon); | 
|---|
|  |  |  | lat = Math.toDegrees(lat); | 
|---|
|  |  |  | result[0] = df.format(lon); | 
|---|
|  |  |  | result[1] = df.format(lat); | 
|---|
|  |  |  | return result; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 根据经纬度,计算两点间的距离 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param longitude1 第一个点的经度 | 
|---|
|  |  |  | * @param latitude1  第一个点的纬度 | 
|---|
|  |  |  | * @param longitude2 第二个点的经度 | 
|---|
|  |  |  | * @param latitude2  第二个点的纬度 | 
|---|
|  |  |  | * @return 返回距离 单位米 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) { | 
|---|
|  |  |  | // 纬度 | 
|---|
|  |  |  | double lat1 = Math.toRadians(latitude1); | 
|---|
|  |  |  | double lat2 = Math.toRadians(latitude2); | 
|---|
|  |  |  | // 经度 | 
|---|
|  |  |  | double lng1 = Math.toRadians(longitude1); | 
|---|
|  |  |  | double lng2 = Math.toRadians(longitude2); | 
|---|
|  |  |  | // 纬度之差 | 
|---|
|  |  |  | double a = lat1 - lat2; | 
|---|
|  |  |  | // 经度之差 | 
|---|
|  |  |  | double b = lng1 - lng2; | 
|---|
|  |  |  | // 计算两点距离的公式 | 
|---|
|  |  |  | double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + | 
|---|
|  |  |  | Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2))); | 
|---|
|  |  |  | // 弧长乘地球半径, 返回单位: 米 | 
|---|
|  |  |  | s =  s * EARTH_RADIUS; | 
|---|
|  |  |  | return s; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取中心点 | 
|---|
|  |  |  | public static String getResult(ArrayList<String[]> doubleArrayList){ | 
|---|
|  |  |  | //        UAVResultDTO uavResultDTO = new UAVResultDTO(); | 
|---|
|  |  |  | int total = doubleArrayList.size(); | 
|---|
|  |  |  | double X = 0, Y = 0, Z = 0; | 
|---|
|  |  |  | for (int i = 0; i < total; i++) { | 
|---|
|  |  |  | double lat, lon, x, y, z; | 
|---|
|  |  |  | String[] strings = doubleArrayList.get(i); | 
|---|
|  |  |  | lon = Double.parseDouble(strings[0]) * Math.PI / 180; | 
|---|
|  |  |  | lat = Double.parseDouble(strings[1]) * Math.PI / 180; | 
|---|
|  |  |  | x = Math.cos(lat) * Math.cos(lon); | 
|---|
|  |  |  | y = Math.cos(lat) * Math.sin(lon); | 
|---|
|  |  |  | z = Math.sin(lat); | 
|---|
|  |  |  | X += x; | 
|---|
|  |  |  | Y += y; | 
|---|
|  |  |  | Z += z; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | X = X / total; | 
|---|
|  |  |  | Y = Y / total; | 
|---|
|  |  |  | Z = Z / total; | 
|---|
|  |  |  | double Lon = Math.atan2(Y, X); | 
|---|
|  |  |  | double Hyp = Math.sqrt(X * X + Y * Y); | 
|---|
|  |  |  | double Lat = Math.atan2(Z, Hyp); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | double rsLon = Lon * 180 / Math.PI; | 
|---|
|  |  |  | double rsLat = Lat * 180 / Math.PI; | 
|---|
|  |  |  | //        uavResultDTO.setFlyLon(rsLon); | 
|---|
|  |  |  | //        uavResultDTO.setFlyLat(rsLat); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return rsLon+"_"+rsLat; | 
|---|
|  |  |  | //        return uavResultDTO; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取中心点 | 
|---|
|  |  |  | public static UAVResultDTO getResults(ArrayList<String[]> doubleArrayList){ | 
|---|
|  |  |  | UAVResultDTO uavResultDTO = new UAVResultDTO(); | 
|---|
|  |  |  | int total = doubleArrayList.size(); | 
|---|
|  |  |  | double X = 0, Y = 0, Z = 0; | 
|---|
|  |  |  | for (int i = 0; i < total; i++) { | 
|---|
|  |  |  | double lat, lon, x, y, z; | 
|---|
|  |  |  | String[] strings = doubleArrayList.get(i); | 
|---|
|  |  |  | lon = Double.parseDouble(strings[0]) * Math.PI / 180; | 
|---|
|  |  |  | lat = Double.parseDouble(strings[1]) * Math.PI / 180; | 
|---|
|  |  |  | x = Math.cos(lat) * Math.cos(lon); | 
|---|
|  |  |  | y = Math.cos(lat) * Math.sin(lon); | 
|---|
|  |  |  | z = Math.sin(lat); | 
|---|
|  |  |  | X += x; | 
|---|
|  |  |  | Y += y; | 
|---|
|  |  |  | Z += z; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | X = X / total; | 
|---|
|  |  |  | Y = Y / total; | 
|---|
|  |  |  | Z = Z / total; | 
|---|
|  |  |  | double Lon = Math.atan2(Y, X); | 
|---|
|  |  |  | double Hyp = Math.sqrt(X * X + Y * Y); | 
|---|
|  |  |  | double Lat = Math.atan2(Z, Hyp); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | double rsLon = Lon * 180 / Math.PI; | 
|---|
|  |  |  | double rsLat = Lat * 180 / Math.PI; | 
|---|
|  |  |  | uavResultDTO.setFlyLon(rsLon); | 
|---|
|  |  |  | uavResultDTO.setFlyLat(rsLat); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //        return rsLon+"_"+rsLat; | 
|---|
|  |  |  | return uavResultDTO; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 将经纬度点集合转换为GeneralPath对象 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param points 点集合(有序) | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @return GeneralPath对象 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static GeneralPath genGeneralPath(ArrayList<Point2D.Double> points) { | 
|---|
|  |  |  | GeneralPath path = new GeneralPath(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (points.size() < 3) { | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | path.moveTo((float) points.get(0).getX(), (float) points.get(0).getY()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (Iterator<Point2D.Double> it = points.iterator(); it.hasNext();) { | 
|---|
|  |  |  | Point2D.Double point = (Point2D.Double) it.next(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | path.lineTo((float) point.getX(), (float) point.getY()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | path.closePath(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return path; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true | 
|---|
|  |  |  | * @param point 检测点 | 
|---|
|  |  |  | * @param pts   多边形的顶点 | 
|---|
|  |  |  | * @return      点在多边形内返回true,否则返回false | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int N = pts.size(); | 
|---|
|  |  |  | boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true | 
|---|
|  |  |  | int intersectCount = 0;//cross points count of x | 
|---|
|  |  |  | double precision = 2e-10; //浮点类型计算时候与0比较时候的容差 | 
|---|
|  |  |  | Point2D.Double p1, p2;//neighbour bound vertices | 
|---|
|  |  |  | Point2D.Double p = point; //当前点 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | p1 = pts.get(0);//left vertex | 
|---|
|  |  |  | for(int i = 1; i <= N; ++i){//check all rays | 
|---|
|  |  |  | if(p.equals(p1)){ | 
|---|
|  |  |  | return boundOrVertex;//p is an vertex | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | p2 = pts.get(i % N); | 
|---|
|  |  |  | if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){ | 
|---|
|  |  |  | p1 = p2; | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){ | 
|---|
|  |  |  | if(p.y <= Math.max(p1.y, p2.y)){ | 
|---|
|  |  |  | if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){ | 
|---|
|  |  |  | return boundOrVertex; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(p1.y == p2.y){ | 
|---|
|  |  |  | if(p1.y == p.y){ | 
|---|
|  |  |  | return boundOrVertex; | 
|---|
|  |  |  | }else{//before ray | 
|---|
|  |  |  | ++intersectCount; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; | 
|---|
|  |  |  | if(Math.abs(p.y - xinters) < precision){ | 
|---|
|  |  |  | return boundOrVertex; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(p.y < xinters){ | 
|---|
|  |  |  | ++intersectCount; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | if(p.x == p2.x && p.y <= p2.y){ | 
|---|
|  |  |  | Point2D.Double p3 = pts.get((i+1) % N); | 
|---|
|  |  |  | if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){ | 
|---|
|  |  |  | ++intersectCount; | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | intersectCount += 2; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | p1 = p2; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(intersectCount % 2 == 0){//偶数在多边形外 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } else { //奇数在多边形内 | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 判断当前位置是否在多边形区域内 | 
|---|
|  |  |  | * @param | 
|---|
|  |  |  | * @param doubleArrayList 区域顶点 | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static boolean isInPolygon(String X,String Y,ArrayList<String[]> doubleArrayList){ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | double p_x =Double.parseDouble(X); | 
|---|
|  |  |  | double p_y =Double.parseDouble(Y); | 
|---|
|  |  |  | Point2D.Double point = new Point2D.Double(p_x, p_y); | 
|---|
|  |  |  | List<Point2D.Double> pointList= new ArrayList<Point2D.Double>(); | 
|---|
|  |  |  | for (String[] strings : doubleArrayList) { | 
|---|
|  |  |  | double polygonPoint_x=Double.parseDouble(strings[0]); | 
|---|
|  |  |  | double polygonPoint_y=Double.parseDouble(strings[1]); | 
|---|
|  |  |  | Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x,polygonPoint_y); | 
|---|
|  |  |  | pointList.add(polygonPoint); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return IsPtInPoly(point,pointList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public boolean isInPolygon(String X,String Y,double x1,double x2,double y1,double y2){ | 
|---|
|  |  |  | boolean result = false; | 
|---|
|  |  |  | double x =Double.parseDouble(X); | 
|---|
|  |  |  | double y =Double.parseDouble(Y); | 
|---|
|  |  |  | if(x >= Math.min(x1, x2) && x <= Math.max(x1, x2) ){ | 
|---|
|  |  |  | if(y >= Math.min(y1, y2) && y <= Math.max(y1, y2)){ | 
|---|
|  |  |  | result = true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return result; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|