package com.moral.api.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.ISqlSegment; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; import com.baomidou.mybatisplus.core.conditions.segments.NormalSegmentList; import com.moral.api.config.mybatis.MybatisPlusConfig; import com.moral.api.entity.Device; import com.moral.api.entity.HistoryFiveMinutely; import com.moral.api.entity.HistoryHourly; import com.moral.api.entity.MonitorPoint; import com.moral.api.mapper.HistoryFiveMinutelyMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.moral.api.pojo.dto.Wind.WindData; import com.moral.api.pojo.dto.historyFiveMinutely.DeviceAndFiveMinuteDataDTO; import com.moral.api.pojo.form.device.MonitorPointQueryForm; import com.moral.api.pojo.form.historyFiveMinutely.QueryDeviceAndFiveMinuteDataForm; import com.moral.api.service.HistoryFiveMinutelyService; import com.moral.api.service.MonitorPointService; import com.moral.constant.RedisConstants; import com.moral.constant.SeparateTableType; import com.moral.util.DateUtils; import com.moral.util.MybatisPLUSUtils; import io.lettuce.core.GeoCoordinates; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import java.util.*; /** *

* 5分钟数据表 服务实现类 *

* * @author moral * @since 2021-07-15 */ @Service public class HistoryFiveMinutelyServiceImpl extends ServiceImpl implements HistoryFiveMinutelyService { @Autowired MonitorPointService monitorPointService; @Autowired RedisTemplate redisTemplate; @Autowired HistoryFiveMinutelyMapper historyFiveMinutelyMapper; @Override public List queryDeviceAndFiveMinuteData(QueryDeviceAndFiveMinuteDataForm form) { //取参 Integer organizationId = form.getOrganizationId(); Integer regionCode = form.getRegionCode(); String sensorCode = form.getSensorCode(); //查询组织在对应地区下的站点以及设备 List monitorPoints = monitorPointService.queryByOrgIdAndRegionCode(new MonitorPointQueryForm(organizationId, regionCode)); List devices = new ArrayList<>(); for (MonitorPoint monitorPoint : monitorPoints) { List monitorPointDevices = monitorPoint.getDevices(); if (!ObjectUtils.isEmpty(monitorPointDevices)) devices.addAll(monitorPointDevices); } //查询所有设备对应的数据 List dtos = new ArrayList<>(); for (Device device : devices) { DeviceAndFiveMinuteDataDTO dto = new DeviceAndFiveMinuteDataDTO(); String mac = device.getMac(); //从缓存中获取 Map sensorValues = (Map) redisTemplate.opsForHash().get(RedisConstants.DATA_FIVE_MINUTES, mac); //如果没有数据从数据库查询 if (ObjectUtils.isEmpty(sensorValues)) { HistoryFiveMinutely dbHistoryFiveMinutely = queryLastDataByMac(mac); if (ObjectUtils.isEmpty(dbHistoryFiveMinutely)) continue; else sensorValues = JSON.parseObject(dbHistoryFiveMinutely.getValue(),Map.class); } String dbDataStr = JSON.toJSONString(sensorValues); sensorValues = JSON.parseObject(dbDataStr, HashMap.class); Map sensorValue = new HashMap<>(); if (sensorValues != null && sensorValues.get(sensorCode) != null) sensorValue.put(sensorCode, sensorValues.get(sensorCode)); else sensorValue.put(sensorCode, null); dto.setDevice(device); dto.setSensorValue(sensorValue); dtos.add(dto); } return dtos; } @Override public HistoryFiveMinutely queryLastDataByMac(String mac) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("mac", mac); queryWrapper.orderByDesc("time"); queryWrapper.last("limit 0,1"); //获取当月的表名 Date date = new Date(); List tableNames = MybatisPLUSUtils.getTableNamesByWrapper(date, date, SeparateTableType.MONTH); List datas = multiTableQuery(queryWrapper, tableNames); if (ObjectUtils.isEmpty(datas)) return null; return datas.get(0); } @Override public List getAreaWindData(Map params) { String timeUnits = DateUtils.dateToDateString(new Date(), DateUtils.yyyyMM_EN); params.put("timeUnits", timeUnits); //风场数据 List windData = historyFiveMinutelyMapper.getAreaWindData(params); return getWindData(windData); } /** * 根据输入的地点坐标计算中心点 * * @param geoCoordinateList * @return */ public Map getCenterPoint(List geoCoordinateList) { int total = geoCoordinateList.size(); double X = 0, Y = 0, Z = 0; for (GeoCoordinates g : geoCoordinateList) { double lat, lon, x, y, z; lat = (double) g.getY() * Math.PI / 180; lon = (double) g.getX() * 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); Map map = new HashMap<>(); map.put("lng", Lon * 180 / Math.PI); map.put("lat", Lat * 180 / Math.PI); return map; } public List getWindData(List windData) { List points = new ArrayList<>(); int length = 2000; int perdlen = 200; Double loma = 0d; Double lomi = 0d; Double lama = 0d; Double lami = 0d; List loList = new ArrayList<>(); List laList = new ArrayList<>(); Double U; Double V; //结果集 List list = new ArrayList<>(); List> mapList = new ArrayList<>(); for (WindData data : windData) { Double longitude = data.getLongitude(); Double latitude = data.getLatitude(); GeoCoordinates geoCoordinates = GeoCoordinates.create(longitude, latitude); points.add(geoCoordinates); loList.add(longitude); laList.add(latitude); Map map = new HashMap<>(); Double windDir = data.getWindDir(); Double windSpeed = data.getWindSpeed(); if (windDir == null) { windDir = 0d; windSpeed = 0d; } double dir = (360.0 - (windDir + 180.0) * Math.PI / 180.0); U = windSpeed * Math.cos(dir); V = windSpeed * Math.sin(dir); map.put("lo", longitude); map.put("la", latitude); map.put("U", U); map.put("V", V); mapList.add(map); } //根据所有多个站点经纬度获取中心点 Map centerPoint = getCenterPoint(points); if (loList.size() > 0) { loma = Collections.max(loList); lomi = Collections.min(loList); } if (laList.size() > 0) { lama = Collections.max(laList); lami = Collections.min(laList); } Map laLaMap = new HashMap<>(); laLaMap.put("maxLo", loma); laLaMap.put("minLo", lomi); laLaMap.put("maxLa", lama); laLaMap.put("minLa", lami); Double lo1 = lomi - length * 0.00001141; Double lo2 = loma + length * 0.00001141; Double la2 = lami - length * 0.00000899; Double la1 = lama + length * 0.00000899; double dx = 0.00001141 * perdlen; double dy = 0.00000899 * perdlen; int nx = (int) Math.floor((lo2 - lo1) / dx); int ny = (int) Math.floor((la1 - la2) / dy); List uList = new ArrayList<>(); List vList = new ArrayList<>(); int x; int y; for (int i = 0; i < mapList.size(); i++) { Double lo = (Double) mapList.get(i).get("lo"); Double la = (Double) mapList.get(i).get("la"); x = (int) Math.floor((lo - lo1) / dx); y = Math.abs((int) Math.floor((la - la1) / dy)); U = (Double) mapList.get(i).get("U"); V = (Double) mapList.get(i).get("V"); if (i == 0) { for (int j = 0; j < nx * ny; j++) { uList.add(0.0); vList.add(0.0); } } for (int j = 0; j < nx * ny; j++) { if (i == 0) { if ((y >= 2 && j == (y) * nx + x)) { int k; for (k = j - 2 * nx; k <= j + 2 * nx; k = k + nx) { uList.set(k, U); uList.set(k - 1, U); uList.set(k - 2, U); uList.set(k + 1, U); uList.set(k + 2, U); vList.set(k, V); vList.set(k - 1, V); vList.set(k - 2, V); vList.set(k + 1, V); vList.set(k + 2, V); } } } else { if (y >= 1 && j == y * nx + x) { int k; for (k = j - 2 * nx; k <= j + 2 * nx; ) { uList.set(k - 1, U); uList.set(k - 2, U); uList.set(k + 1, U); uList.set(k + 2, U); vList.set(k - 1, V); vList.set(k - 2, V); vList.set(k + 1, V); vList.set(k + 2, V); k = k + nx; } uList.set(j, U); vList.set(j, V); } } } } String uData = "\"" + "data" + "\"" + ": " + uList; String vData = "\"" + "data" + "\"" + ": " + vList; String header1 = "\"" + "header" + "\"" + ": " + "{" + "\"" + "parameterUnit" + "\"" + ": " + "\"" + "m/s" + "\"" + ", " + "\"" + "parameterNumber" + "\"" + ": " + 2 + ", " + "\"" + "dx" + "\"" + ": " + dx + ", " + "\"" + "dy" + "\"" + ": " + dy + ", " + "\"" + "parameterNumberName" + "\"" + ": " + "\"" + "eastward_wind" + "\"" + ", " + "\"" + "la1" + "\"" + ": " + la1 + ", " + "\"" + "la2" + "\"" + ": " + la2 + ", " + "\"" + "parameterCategory" + "\"" + ": " + 2 + ", " + "\"" + "lo1" + "\"" + ": " + lo1 + ", " + "\"" + "lo2" + "\"" + ": " + lo2 + ", " + "\"" + "nx" + "\"" + ": " + nx + ", " + "\"" + "ny" + "\"" + ": " + ny + ", " + "\"" + "refTime" + "\"" + ": " + "\"" + "2020-07-22 23:00:00" + "\"" + "}"; String header2 = "\"" + "header" + "\"" + ": " + "{" + "\"" + "parameterUnit" + "\"" + ": " + "\"" + "m/s" + "\"" + ", " + "\"" + "parameterNumber" + "\"" + ": " + 3 + ", " + "\"" + "dx" + "\"" + ": " + dx + ", " + "\"" + "dy" + "\"" + ": " + dy + ", " + "\"" + "parameterNumberName" + "\"" + ": " + "\"" + "eastward_wind" + "\"" + ", " + "\"" + "la1" + "\"" + ": " + la1 + ", " + "\"" + "la2" + "\"" + ": " + la2 + ", " + "\"" + "parameterCategory" + "\"" + ": " + 2 + ", " + "\"" + "lo1" + "\"" + ": " + lo1 + ", " + "\"" + "lo2" + "\"" + ": " + lo2 + ", " + "\"" + "nx" + "\"" + ": " + nx + ", " + "\"" + "ny" + "\"" + ": " + ny + ", " + "\"" + "refTime" + "\"" + ": " + "\"" + "2020-07-22 23:00:00" + "\"" + "}"; String s1 = "[" + "{" + header1 + ", " + uData + "}" + ", " + "{" + header2 + ", " + vData + "}" + "]"; JSONArray jsonArray = JSONArray.parseArray(s1); list.add(jsonArray); list.add(centerPoint.get("lng")); list.add(centerPoint.get("lat")); list.add(laLaMap); return list; } /** * @Description: 查询一段时间内某一mac的数据 * @Param: [mac, startDate, endDate] * @return: java.util.List * @Author: 陈凯裕 * @Date: 2021/9/23 */ public List getValueByMacAndTime(String mac, Date startDate, Date endDate) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("mac", mac); wrapper.between("time", startDate, endDate); List tableNames = MybatisPLUSUtils.getTableNamesByWrapper(startDate, endDate, SeparateTableType.MONTH); List datas = multiTableQuery(wrapper, tableNames); return datas; } /** * @Description: 多表查询,传入表名集合,以及条件wrapper,返回数据 * @Param: [wrapper, tableNames] * @return: java.util.List * @Author: 陈凯裕 * @Date: 2021/9/23 */ private List multiTableQuery(QueryWrapper wrapper, List tableNames) { List result = new ArrayList<>(); for (String tableName : tableNames) { MybatisPlusConfig.tableName.set(tableName); List datas = historyFiveMinutelyMapper.selectList(wrapper); result.addAll(datas); } MybatisPlusConfig.tableName.remove(); return result; } }