ZhuDongming
2019-09-02 321a114af75d62f66bd5d46f01a44c955cbde286
更新污染传播接口
4 files modified
274 ■■■■ changed files
src/main/java/com/moral/controller/ScreenController.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/moral/service/impl/HistoryHourlyServiceImpl.java 51 ●●●●● patch | view | raw | blame | history
src/main/java/com/moral/service/impl/HistoryMinutelyServiceImpl.java 10 ●●●●● patch | view | raw | blame | history
src/main/webapp/view/pollutionsource.jsp 187 ●●●● patch | view | raw | blame | history
src/main/java/com/moral/controller/ScreenController.java
@@ -1,16 +1,11 @@
package com.moral.controller;
import static com.moral.common.util.ResourceUtil.getValue;
import static com.moral.common.util.WebUtils.getParametersStartingWith;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -21,9 +16,6 @@
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.net.ftp.FTPClient;
@@ -98,11 +90,15 @@
import com.moral.service.WeatherService;
import com.moral.util.AQICalculation;
import com.moral.util.TempAllocationUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import static com.moral.common.util.ResourceUtil.getValue;
import static com.moral.common.util.WebUtils.getParametersStartingWith;
/**
 * The Class ScreenController.大屏接口
@@ -1225,7 +1221,7 @@
    @GetMapping("/pollutionSource")
    @ApiOperation(value = "污染传播来源", notes = "污染传播来源")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "mac", value = "设备mac地址(如:898607b0101730392254)", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "mac", value = "设备mac地址(如:898607b0101730392251)", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "sensorKey", value = "查询的监测因子的key(格式:e1)", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "time", value = "查询时间(格式:2019-09-01-10)", required = true, paramType = "query", dataType = "String")})
    public ModelAndView pollutionSource(ModelAndView model, HttpServletRequest request) throws Exception {
@@ -1238,17 +1234,17 @@
        LocalDateTime timeLocalDateTime = LocalDateTime.parse(time, dateTimeFormatter);
        System.out.println(timeLocalDateTime);
        int month = timeLocalDateTime.getMonth().getValue();
        Point dirPoint= historyHourlyService.getDirPoint(parameters);
        Map<String,Object> getPollutionSourceData=historyHourlyService.getPollutionSourceData(parameters);
        Point dirPoint = historyHourlyService.getDirPoint(parameters);
        Map<String, Object> getPollutionSourceData = historyHourlyService.getPollutionSourceData(parameters);
        System.out.println(dirPoint.toString());
        System.out.println("getPollutionSourceData:"+getPollutionSourceData);
        System.out.println("getPollutionSourceData:" + getPollutionSourceData);
        String mac = parameters.get("mac").toString();
        Device device = deviceService.getDeviceByMac(mac, false);
        JSONObject params = new JSONObject();
        params.put("device", device);
        params.put("month", month);
        params.put("dirPoint",dirPoint);
        params.put("getPollutionSourceData",getPollutionSourceData);
        params.put("dirPoint", dirPoint);
        params.put("getPollutionSourceData", getPollutionSourceData);
        String paramsJson = params.toJSONString();
        model.addObject("pollutionSourceParams", paramsJson);
        model.setViewName("pollutionsource");
src/main/java/com/moral/service/impl/HistoryHourlyServiceImpl.java
@@ -5,8 +5,6 @@
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Service;
@@ -17,6 +15,7 @@
import com.moral.mapper.SensorMapper;
import com.moral.service.DeviceService;
import com.moral.service.HistoryHourlyService;
import javax.annotation.Resource;
@Service
public class HistoryHourlyServiceImpl implements HistoryHourlyService {
@@ -37,31 +36,23 @@
            sensorKeys.add(sensor.getSensorKey());
        }
        parameters.put("sensorKeys", sensorKeys);
       /* if(pollutionSourceData.get("e6")!=null&&pollutionSourceData.get("e18")!=null){
            pollutionSourceData=historyHourlyMapper.getPollutionSourceData(parameters);
        }
        return pollutionSourceData;*/
        System.out.println("----"+historyHourlyMapper.getPollutionSourceData(parameters));
       return historyHourlyMapper.getPollutionSourceData(parameters);
        return historyHourlyMapper.getPollutionSourceData(parameters);
    }
    @Override
    public Point getDirPoint(Map<String, Object> parameters) throws Exception{
        Map<String,Object> pollutionSourceData=getPollutionSourceData(parameters);
    public Point getDirPoint(Map<String, Object> parameters) throws Exception {
        Map<String, Object> pollutionSourceData = getPollutionSourceData(parameters);
        String mac = parameters.get("mac").toString();
        Device device = deviceService.getDeviceByMac(mac, false);
        Point pointEnd=new Point();
        if(MapUtils.isNotEmpty(pollutionSourceData)){
            System.out.println("pollutionSourceData"+pollutionSourceData);
            if(pollutionSourceData.get("e18")!=null&&pollutionSourceData.get("e23")!=null&&pollutionSourceData.get("e6")!=null){
                double windSpeed=Double.valueOf(pollutionSourceData.get("e18").toString());
                double winDir=Double.valueOf(pollutionSourceData.get("e23").toString());
                double distance=windSpeed*3600;
                double long1=device.getLongitude();
                double lat1=device.getLatitude();
                System.out.println("windSpeed:"+windSpeed+"---winDir:"+winDir+"---distance:"+distance+"--long1:"+long1+"--lat1:"+lat1);
                String[] result=calLocationByDistanceAndLocationAndDirection(winDir,long1,lat1,distance);
                System.out.println("result1:"+Double.valueOf(result[0])+"result2:"+Double.valueOf(result[1]));
        Point pointEnd = new Point();
        if (MapUtils.isNotEmpty(pollutionSourceData)) {
            if (pollutionSourceData.get("e18") != null && pollutionSourceData.get("e23") != null && pollutionSourceData.get("e6") != null) {
                double windSpeed = Double.valueOf(pollutionSourceData.get("e18").toString());
                double winDir = Double.valueOf(pollutionSourceData.get("e23").toString());
                double distance = windSpeed * 3600;
                double long1 = device.getLongitude();
                double lat1 = device.getLatitude();
                String[] result = calLocationByDistanceAndLocationAndDirection(winDir, long1, lat1, distance);
                pointEnd.setLng(Double.valueOf(result[0]));
                pointEnd.setLat(Double.valueOf(result[1]));
            }
@@ -70,29 +61,29 @@
    }
    /**
     * 根据一点的坐标与距离,以及方向,计算另外一点的位置
     * @param angle 角度,从正北顺时针方向开始计算
     *
     * @param angle     角度,从正北顺时针方向开始计算
     * @param startLong 起始点经度
     * @param startLat 起始点纬度
     * @param distance 距离,单位m
     * @param startLat  起始点纬度
     * @param distance  距离,单位m
     * @return
     */
    private String[] calLocationByDistanceAndLocationAndDirection(double angle, double startLong,double startLat, double distance){
    private String[] calLocationByDistanceAndLocationAndDirection(double angle, double startLong, double startLat, double distance) {
        /** 地球半径 **/
        final double R = 6371e3;
        /** 180° **/
        final DecimalFormat df = new DecimalFormat("0.000000");
        String[] result = new String[2];
        //将距离转换成经度的计算公式
        double δ = distance/R;
        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 lng = startLong + Math.atan2(Math.sin(angle)*Math.sin(δ)*Math.cos(startLat),Math.cos(δ)-Math.sin(startLat)*Math.sin(lat));
        double lat = Math.asin(Math.sin(startLat) * Math.cos(δ) + Math.cos(startLat) * Math.sin(δ) * Math.cos(angle));
        double lng = startLong + Math.atan2(Math.sin(angle) * Math.sin(δ) * Math.cos(startLat), Math.cos(δ) - Math.sin(startLat) * Math.sin(lat));
        // 转为正常的10进制经纬度
        lng = Math.toDegrees(lng);
        lat = Math.toDegrees(lat);
src/main/java/com/moral/service/impl/HistoryMinutelyServiceImpl.java
@@ -1,11 +1,7 @@
package com.moral.service.impl;
import static com.moral.common.bean.Constants.NULL_VALUE;
import static org.springframework.util.ObjectUtils.isEmpty;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -31,8 +27,6 @@
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
@@ -55,6 +49,10 @@
import com.moral.mapper.HistoryMinutelyMapper;
import com.moral.mapper.SensorMapper;
import com.moral.service.HistoryMinutelyService;
import javax.annotation.Resource;
import static com.moral.common.bean.Constants.NULL_VALUE;
import static org.springframework.util.ObjectUtils.isEmpty;
@Service
@SuppressWarnings({"unchecked", "unused", "rawtypes"})
src/main/webapp/view/pollutionsource.jsp
@@ -120,10 +120,9 @@
    var params = $.parseJSON($("#pollutionSourceParams").html());
    var month = params["month"];
    var device = params["device"];
    var dirPoint=params["dirPoint"];
    console.log(dirPoint.lng);
    console.log(dirPoint.lat);
    var getPollutionSourceData=params["getPollutionSourceData"];
    var dirPoint = new BMap.Point(params["dirPoint"].lng, params["dirPoint"].lat);
    var getPollutionSourceData = params["getPollutionSourceData"];
    var windSpeed = parseFloat(getPollutionSourceData["e18"]);
    var map = new BMap.Map("mapCanvas", {enableMapClick: false});
    map.setMapStyle(mapStyle);
    map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
@@ -133,74 +132,86 @@
    });
    map.addControl(navigation);
    map.addControl(new BMap.ScaleControl());
    if ($.isEmptyObject(dirPoint)||$.isEmptyObject(getPollutionSourceData)||getPollutionSourceData["e18"]==0) {
    if ($.isEmptyObject(dirPoint) || $.isEmptyObject(getPollutionSourceData) || getPollutionSourceData["e6"] == 0 || getPollutionSourceData["e18"] == 0 || getPollutionSourceData["e23"] == 0 || windSpeed <= 0.03) {
        showNoData();
    }else{
        var humidity=getPollutionSourceData["e6"];
        var windSpeed=getPollutionSourceData["e18"];
    } else {
        var humidity = parseFloat(getPollutionSourceData["e6"]);
        var windDir = parseFloat(getPollutionSourceData["e23"]);
        var longitude = params["device"]["longitude"];
        var latitude = params["device"]["latitude"];
        var point = new BMap.Point(longitude, latitude);
        var icon = new BMap.Icon("/img/ico00.png", new BMap.Size(50, 50));
        var marker = new BMap.Marker(point, {icon: icon, offset: new BMap.Size(0, -20)});
        map.addOverlay(marker);
        map.centerAndZoom(point, 17);
        var polyline1 = new BMap.Polyline([
                dirPoint,
                new BMap.Point(point.lng+0.01, point.lat+0.01)
            ],
            {strokeColor: "#5298FF", strokeWeight: 4, strokeOpacity: 1}
        );
        var polyline2 = new BMap.Polyline([
                dirPoint,
                new BMap.Point( point.lng-0.02,  point.lat-0.01)
            ],
            {strokeColor: "#5298FF", strokeWeight: 4, strokeOpacity: 1}
        );
        var distance=windSpeed*3600;
        console.log(distance);
        var arrowLength;//两点间箭头长度
        if (distance <= 5) {
            arrowLength = 0;
        } else if (distance > 5 && distance <= 20) {
            arrowLength = 2;
        } else if (distance > 20 && distance <= 50) {
            arrowLength = 3;
        } else if (distance > 50 && distance <= 100) {
            arrowLength = 5;
        } else if (distance > 100 && distance <= 200) {
            arrowLength = 10;
        } else if (distance > 200 && distance <= 500) {
            arrowLength = 20;
        } else if (distance > 500 && distance <= 1000) {
            arrowLength = 40;
        } else if (distance > 1000 && distance <= 2000) {
            arrowLength = 80;
        } else if (distance > 2000 && distance <= 3000) {
            arrowLength = 120;
        } else if (distance > 3000 && distance <= 10000) {
            arrowLength = 500;
        } else if (distance > 10000 && distance <= 20000) {
            arrowLength = 1000;
        } else if (distance > 20000 && distance <= 50000) {
            arrowLength = 2500;
        } else if (distance > 50000 && distance <= 100000) {
            arrowLength = 5000;
        } else if (distance > 100000 && distance <= 200000) {
            arrowLength = 10000;
        } else if (distance > 200000 && distance <= 500000) {
            arrowLength = 25000;
        } else if (distance > 500000 && distance <= 1000000) {
            arrowLength = 50000;
        } else if (distance > 1000000 && distance <= 2000000) {
            arrowLength = 100000;
        } else {
            arrowLength = 150000;
        map.centerAndZoom(point, 16);
        //centre:椭圆中心点,X:横向经度,Y:纵向纬度
        function add_oval(centre, x, y) {
            var assemble = new Array();
            var angle;
            var dot;
            var tangent = x / y;
            for (i = 0; i < 36; i++) {
                angle = (2 * Math.PI / 36) * i;
                dot = new BMap.Point(centre.lng + Math.sin(angle) * y * tangent, centre.lat + Math.cos(angle) * y);
                assemble.push(dot);
            }
            return assemble;
        }
        map.addOverlay(polyline1);// 画两点间线
        addArrow(polyline1, arrowLength, Math.PI / 7,windSpeed);
        map.addOverlay(polyline2);// 画两点间线
        addArrow(polyline2, arrowLength, Math.PI / 7,windSpeed);
        //以画多边形区域的方法画扇形区域 画出以point点为圆心,半径为radius,夹角从sDegree到eDegree的扇形
        function Sector(point, radius, sDegree, eDegree) {
            var points = []; //创建构成多边形的点数组
            var step = ((eDegree - sDegree) / 10) || 10; //根据扇形的总夹角确定每步夹角度数,最大为10
            points.push(point);
            for (var i = sDegree; i < eDegree + 0.001; i += step) { //循环获取每步的圆弧上点的坐标,存入点数组
                points.push(EOffsetBearing(point, radius, i));
            }
            points.push(point);
            return points;
        }
        //使用数学的方法计算需要画扇形的圆弧上的点坐标
        function EOffsetBearing(point, dist, bearing) {
            var lngConv = map.getDistance(point, new BMap.Point(point.lng + 0.1, point.lat)) * 10; //计算经度与原点的距离
            var latConv = map.getDistance(point, new BMap.Point(point.lng, point.lat + 0.1)) * 10; //计算纬度与原点的距离
            var lat = dist * Math.sin(bearing * Math.PI / 180) / latConv; //正弦计算待获取的点的纬度与原点纬度差
            var lng = dist * Math.cos(bearing * Math.PI / 180) / lngConv; //余弦计算待获取的点的经度与原点经度差
            return new BMap.Point(point.lng + lng, point.lat + lat);
        }
        var distance = windSpeed * 3600;
        var winDirStart = 240 - windDir;
        var winDirEnd = 300 - windDir;
        var oval = new BMap.Polygon(Sector(dirPoint, distance, winDirStart, winDirEnd), {
            strokeColor: "grey",
            strokeWeight: 1,
            strokeOpacity: 0.8,
            fillColor: "grey"
        });
        map.addOverlay(oval);
        var oval = new BMap.Polygon(Sector(dirPoint, distance * 0.66, winDirStart, winDirEnd), {
            strokeColor: "grey",
            strokeWeight: 1,
            strokeOpacity: 0.6,
            fillColor: "grey"
        });
        map.addOverlay(oval);
        var oval = new BMap.Polygon(Sector(dirPoint, distance * 0.33, winDirStart, winDirEnd), {
            strokeColor: "grey",
            strokeWeight: 1,
            strokeOpacity: 0.4,
            fillColor: "grey"
        });
        map.addOverlay(oval);
        var polyline = new BMap.Polyline([
                dirPoint,
                point
            ],
            {strokeColor: "#5298FF", strokeWeight: 4, strokeOpacity: 1}
        );
        addArrow(polyline, 0, Math.PI / 7, windSpeed, humidity);
        var winfowTextCause = "<p style='height: 44px;line-height: 22px'>汽车尾气,工厂废气,以及周边地区农田秸秆焚烧,污染传播途径是根据风向来做出调整</p>";
        var winfowTextSource;
        var supplement;
@@ -208,40 +219,40 @@
            if (windSpeed >= 3.4) {
                supplement = ",但风速较大,大气扩散条件较有利,空气质量相对提升";
            }
            if (humidity>=90.0) {
            if (humidity >= 90.0) {
                supplement = ",但降雨有利于对颗粒物的沉降、冲刷,改善污染状况";
            }else{
                supplement ="";
            } else {
                supplement = "";
            }
            winfowTextSource = "<p style='height: 22px;line-height: 22px'>压强升高气温降低,会因冷空气带来的颗粒物,导致污染上升" + supplement + "</p>";
        } else if (month == 3 || month == 4 || month == 5) {
            if (windSpeed >= 3.4) {
                supplement = ",但风速较大,大气扩散条件较有利,空气质量相对提升";
            }
            if (humidity>=90.0) {
            if (humidity >= 90.0) {
                supplement = ",但降雨有利于对颗粒物的沉降、冲刷,改善污染状况";
            }else{
                supplement ="";
            } else {
                supplement = "";
            }
            winfowTextSource = "<p style='height: 22px;line-height: 22px'>地面逆温频率的增加使污染物在近地层不断积累" + supplement + "</p>";
        } else if (month == 6 || month == 7) {
            if (windSpeed >= 3.4) {
                supplement = ",同时风速较大,加速扩散";
            }
            if (humidity>=90.0) {
            if (humidity >= 90.0) {
                supplement = ",同时降雨有利于对颗粒物的沉降、冲刷,改善污染状况";
            }else{
                supplement ="";
            } else {
                supplement = "";
            }
            winfowTextSource = "<p style='height: 22px;line-height: 22px'>夏季的气温条件不易发生逆温,利于污染物扩散" + supplement + "</p>";
        } else if (month == 8 || month == 9 || month == 10 || month == 11) {
            if (windSpeed >= 3.4) {
                supplement = ",但风速较大,利于污染物扩散";
            }
            if (humidity>=90.0) {
            if (humidity >= 90.0) {
                supplement = ",但降雨有利于对颗粒物的沉降、冲刷,改善污染状况";
            }else{
                supplement ="";
            } else {
                supplement = "";
            }
            winfowTextSource = "<p style='height: 22px;line-height: 22px'>大气扩散条件不好使污染物聚集,增大了气态污染物向二次颗粒物转化的机会" + supplement + "</p>";
        }
@@ -263,9 +274,7 @@
        });
    }
    function addArrow(polyline, length, angleValue,windSpeed) {
    function addArrow(polyline, length, angleValue, windSpeed, humidity) {
        var linePoint = polyline.getPath();// 线的坐标串
        var arrowCount = linePoint.length;
        for (var i = 1; i < arrowCount; i++) { // 在拐点处绘制箭头
@@ -276,7 +285,7 @@
            var delta = 0; // 主线斜率,垂直时无斜率
            var param = 0; // 代码简洁考虑
            var pixelTemX, pixelTemY, poMiddleX, poMiddleY;// 临时点坐标
            var pixelX, pixelY, pixelX1, pixelY1;// 箭头两个点
            var pixelX, pixelY;// 箭头两个点
            poMiddleX = (pixelEnd.x + pixelStart.x) / 2;
            poMiddleY = (pixelEnd.y + pixelStart.y) / 2;
            if (poMiddleX - pixelStart.x == 0) { // 斜率不存在时
@@ -288,8 +297,7 @@
                }
                // 已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法
                pixelX = pixelTemX - r * Math.tan(angle);
                pixelX1 = pixelTemX + r * Math.tan(angle);
                pixelY = pixelY1 = pixelTemY;
                pixelY = pixelTemY;
            } else { // 斜率存在时
                delta = (poMiddleY - pixelStart.y) / (poMiddleX - pixelStart.x);
                param = Math.sqrt(delta * delta + 1);
@@ -303,24 +311,20 @@
                // 已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法
                pixelX = pixelTemX + Math.tan(angle) * r * delta / param;
                pixelY = pixelTemY - Math.tan(angle) * r / param;
                pixelX1 = pixelTemX - Math.tan(angle) * r * delta / param;
                pixelY1 = pixelTemY + Math.tan(angle) * r / param;
            }
            var pointArrow = map.pixelToPoint(new BMap.Pixel(pixelX, pixelY));
            var pointArrow1 = map.pixelToPoint(new BMap.Pixel(pixelX1, pixelY1));
            var pointMiddle = map.pixelToPoint(new BMap.Pixel(poMiddleX, poMiddleY));
            lab = new BMap.Label("风速:"+windSpeed+"m/s", {position: pointMiddle, offset: new BMap.Size(0, -30)});
            lab = new BMap.Label("<P>风速:" + windSpeed + "m/s</p><P>湿度:" + humidity + "°</p>", {
                position: pointMiddle,
                offset: new BMap.Size(-50, -20)
            });
            lab.setStyle({
                color: "red",
                color: "#FFFFFF",
                fontSize: "16px",
                backgroundColor: "1",
                border: "0",
                fontWeight: "bold"
            });
            map.addOverlay(lab);
            var Arrow = new BMap.Polyline([pointArrow, pointMiddle, pointArrow1],
                {strokeColor: "#5298FF", strokeWeight: 4, strokeOpacity: 1});
            map.addOverlay(Arrow);
        }
    };
@@ -333,4 +337,5 @@
            document.getElementById("cpm").style.display = 'block';
        }, 250);
    };
</script>