于紫祥_1901
2020-07-13 9e4480300d1285a574d52451206c5adc81396be4
无组织排放实时
2 files added
7 files modified
732 ■■■■■ changed files
src/main/java/com/moral/config/WebSocketConfig.java 7 ●●●● patch | view | raw | blame | history
src/main/java/com/moral/controller/ScreenController.java 105 ●●●●● patch | view | raw | blame | history
src/main/java/com/moral/mapper/MonitorPointMapper.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/moral/service/MonitorPointService.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java 21 ●●●●● patch | view | raw | blame | history
src/main/java/com/moral/webSocketServer/WebSocketServerNew.java 177 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/MonitorPointMapper.xml 7 ●●●●● patch | view | raw | blame | history
src/main/webapp/view/newUnorganizedMap.jsp 407 ●●●●● patch | view | raw | blame | history
src/main/webapp/view/unorganizedMap.jsp 2 ●●● patch | view | raw | blame | history
src/main/java/com/moral/config/WebSocketConfig.java
@@ -3,19 +3,21 @@
import com.moral.service.DeviceService;
import com.moral.webSocketServer.WebSocketServer;
import com.moral.webSocketServer.WebSocketServerNew;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
   /* @Bean
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }*/
    }
    @Bean
    public MessageConverter jsonMessageConverter() {
@@ -25,6 +27,7 @@
    @Autowired
    public void setMessageService(DeviceService deviceService){
        WebSocketServer.deviceService=deviceService;
        WebSocketServerNew.deviceService=deviceService;
    }
}
src/main/java/com/moral/controller/ScreenController.java
@@ -73,15 +73,19 @@
import com.moral.service.SensorUnitService;
import com.moral.service.WeatherService;
import com.moral.util.AQICalculation;
import com.moral.util.MyLatLng;
import com.moral.util.TempAllocationUtils;
import com.moral.util.mapUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONString;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.ibatis.annotations.Param;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
@@ -1201,9 +1205,7 @@
    public ResultBean<Map<String, Object>> getSensor(HttpServletRequest request) throws Exception {
        Map<String, Object> parameters = WebUtils.getParametersStartingWith(request, null);
        String mac = (String) parameters.get("mac");
        //System.out.println("ScreenController-----getSensor-----mac:"+mac);
        Map<String, Object> map = sensorUnitService.getSensorByMac(mac);
        System.out.println("ScreenController-----getSensor-----map:"+map);
        return new ResultBean<Map<String, Object>>(map);
    }*/
@@ -1271,7 +1273,6 @@
    })
    public ResultBean<List<Map<String, Object>>> AIForecast(HttpServletRequest request) throws Exception {
        Map<String, Object> parameters = getParametersStartingWith(request, null);
        //System.out.println(parameters);
        String monitorPoint = (String) parameters.get("monitorPoint");
        String intoTime = parameters.get("time").toString();
        Date date = new SimpleDateFormat("yy-MM-dd").parse(intoTime);
@@ -1629,7 +1630,9 @@
    public ModelAndView newMap(ModelAndView model, @RequestParam("areaCode") long code,
                            @RequestParam("accountId") int accountId) {
        Account account = accountService.getAccountById(accountId);
        List<MonitorPoint> monitorPointList = monitorPointService.getMonitorPointListByAccountId(accountId);
        String regionName = areaService.queryFullNameByCode(code);
        if (account != null && regionName != null) {
            Object sensors = sensorService.queryAll();
            JSONObject params = new JSONObject();
@@ -1843,7 +1846,6 @@
    }
    @GetMapping("/unorganizedEmissions")
    @ApiOperation(value = "无组织排放", notes = "无组织排放")
    @ApiImplicitParams(value = {
@@ -1867,4 +1869,99 @@
        return model;
    }
    @GetMapping("/unorganizedEmissionsRealTime")
    @ApiOperation(value = "无组织排放实时", notes = "无组织排放实时")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "monitorPointId", value = "公司Id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "sensorKey", value = "因子", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "accountId", value = "用户id", required = false, paramType = "query", dataType = "String")})
    public ModelAndView unorganizedEmissionsBackups(HttpServletRequest request, ModelAndView model) {
        Map<String, Object> parameters = WebUtils.getParametersStartingWith(request, null);
        String monitPointIdS = (String) parameters.get("monitorPointId");
        String sensor = (String) parameters.get("sensorKey");
        String accountId = (String) parameters.get("accountId");
        Account account = accountService.getAccountById(Integer.parseInt(accountId));
        int monitPointId = Integer.parseInt(monitPointIdS);
        JSONObject params = monitorPointService.getMacList(monitPointId);
        params.put("accountId", accountId);
        params.put("orgId", account.getOrganizationId());
        params.put("sensor", sensor);
        //获取公司信息
        //JSONObject params=monitorPointService.getMonitorPointById(monitPointId,Time,3,sensor);
        // model.addObject("params",params);
        model.addObject("params", params);
        model.setViewName("newUnorganizedMap");
        return model;
    }
    @GetMapping("/chooseDevice")
    @ResponseBody
    public Object unorganizedEmissionsBackups(String wind, String monitPointId) {
        JSONObject params = new JSONObject();
        Double windDir = Double.parseDouble(wind);
        List<Device> deviceList = deviceService.getDeviceById2(Integer.parseInt(monitPointId));
        Map<String, Object> longAndLatiMap;
        List<Map> longAndLatiList = new ArrayList<>();//经纬度夹角集合,存放的是windList中两台设备的下标和两台设备夹角与风向角的差值
        List<Device> preAngleDeviceList = new ArrayList<Device>(); //角度减去风向最小的两台设备
        for (int f = 0; f < deviceList.size(); f++) {
            for (int h = 0; h < deviceList.size(); h++) {
                if (f != h) {
                    longAndLatiMap = new HashMap<String, Object>();
                    longAndLatiMap.put("h", h);
                    longAndLatiMap.put("f", f);
                    Double angle = mapUtils.getAngle(
                            new MyLatLng((Double) deviceList.get(h).getLongitude(),
                                    (Double) deviceList.get(h).getLatitude()),
                            new MyLatLng((Double) deviceList.get(f).getLongitude(),
                                    (Double) deviceList.get(f).getLatitude()));
                    Double angleDiff = Math.abs(angle - windDir);
                    longAndLatiMap.put("angle", angleDiff);
                    longAndLatiList.add(longAndLatiMap);
                }
            }
        }
        Double minAngle = (Double) longAndLatiList.get(0).get("angle");
        int indexAngle = 0;
        for (int j = 1; j < longAndLatiList.size(); j++) {
            if (minAngle > (Double) longAndLatiList.get(j).get("angle")) {
                minAngle = (Double) longAndLatiList.get(j).get("angle");
                indexAngle = j;
            }else {
                indexAngle=indexAngle;
            }
        }
        preAngleDeviceList.add(deviceList.get((Integer) longAndLatiList.get(indexAngle).get("h")));
        preAngleDeviceList.add(deviceList.get((Integer) longAndLatiList.get(indexAngle).get("f")));
        Double length = mapUtils.getDistance((Double) preAngleDeviceList.get(0).getLongitude(), (Double) preAngleDeviceList.get(0).getLatitude(),
                (Double) preAngleDeviceList.get(1).getLongitude(), (Double) preAngleDeviceList.get(1).getLatitude());
        Double subLength = length / 5;
        Double subLength1 = length / 6.1;
        Double angle = mapUtils.getAngle(
                new MyLatLng((Double) preAngleDeviceList.get(0).getLongitude(),
                        (Double) preAngleDeviceList.get(0).getLatitude()),
                new MyLatLng((Double) preAngleDeviceList.get(1).getLongitude(),
                        (Double) preAngleDeviceList.get(1).getLatitude()));
        List locationList = new ArrayList();
        String[] firstLocation = mapUtils.calLocationByDistanceAndLocationAndDirection(angle, (Double) preAngleDeviceList.get(0).getLongitude(),
                (Double) preAngleDeviceList.get(0).getLatitude(), subLength);
        String[] secondLoction = mapUtils.calLocationByDistanceAndLocationAndDirection(angle, Double.parseDouble(firstLocation[0]),
                Double.parseDouble(firstLocation[1]), subLength);
        String[] thirdLocation = mapUtils.calLocationByDistanceAndLocationAndDirection(angle, Double.parseDouble(secondLoction[0]),
                Double.parseDouble(secondLoction[1]), subLength);
        String[] fourthLoction = mapUtils.calLocationByDistanceAndLocationAndDirection(angle, Double.parseDouble(thirdLocation[0]),
                Double.parseDouble(thirdLocation[1]), subLength);
        String[] fivethLoction = mapUtils.calLocationByDistanceAndLocationAndDirection(angle, Double.parseDouble(fourthLoction[0]),
                Double.parseDouble(fourthLoction[1]), subLength1);
        locationList.add(firstLocation);
        locationList.add(secondLoction);
        locationList.add(thirdLocation);
        locationList.add(fourthLoction);
        locationList.add(fivethLoction);
        String preAngleDeviceString = JSON.toJSON(preAngleDeviceList).toString();
        params.put("preAngleDeviceString", preAngleDeviceString);//两台添加箭头的设备
        params.put("locationList",locationList);
        return params;
    }
}
src/main/java/com/moral/mapper/MonitorPointMapper.java
@@ -22,4 +22,6 @@
    List<Device> getDeviceList(@Param("id") int id);
    //获取公司信息,通过id
    MonitorPoint getMonitorPointById(@Param("id") int id);
    List<MonitorPoint> getMonitorPointListByAccountId(@Param("id") int id);
}
src/main/java/com/moral/service/MonitorPointService.java
@@ -49,4 +49,8 @@
    //获取公司信息,通过id
    JSONObject getMonitorPointById(int id, String Time, int i, String sensor);
    JSONObject getMacList(int id);
    List<MonitorPoint> getMonitorPointListByAccountId(int id);
}
src/main/java/com/moral/service/impl/MonitorPointServiceImpl.java
@@ -796,5 +796,26 @@
        return params;
    }
    @Override
    public JSONObject getMacList(int monitPointId) {
        JSONObject params = new JSONObject();
        MonitorPoint monitorPoint = monitorPointMapper.getMonitorPointById(monitPointId);
        //获取厂界所有设备
        List<Device> deviceList = deviceService.getDeviceById2(monitPointId);
        params.put("longitudeCompany",monitorPoint.getLongitude());
        params.put("latitudeCompany",monitorPoint.getLatitude());
        params.put("latitudeCompany",monitorPoint.getLatitude());
        params.put("monitPointId",monitPointId);
        params.put("deviceList",deviceList);
        return params;
    }
    @Override
    public List<MonitorPoint> getMonitorPointListByAccountId(int id) {
        return monitorPointMapper.getMonitorPointListByAccountId(id);
    }
}
src/main/java/com/moral/webSocketServer/WebSocketServerNew.java
New file
@@ -0,0 +1,177 @@
package com.moral.webSocketServer;
import com.moral.common.util.ParameterUtils;
import com.moral.entity.Device;
import com.moral.service.DeviceService;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
/**
 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@Slf4j
@ServerEndpoint("/screen/webSocketNew/{param}")
@Component
public class WebSocketServerNew {
    public static DeviceService deviceService;
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    private String orgId;
    private String accountId;
    private Connection connection;
    private Channel channel;
    // 存放session的集合,很重要!!
    private static CopyOnWriteArraySet<WebSocketServerNew> webSocketSet = new CopyOnWriteArraySet<WebSocketServerNew>();
    /**
     * 连接建立成功调用的方法
     *
     * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("param") String param) {
        this.session = session;
        //这个一定要写,第一次很容易忽略!
        webSocketSet.add(this);
        String[] flag=param.split("&");
        String orgId = flag[0];
        String accountId = flag[1];
        String monitPointId = flag[2];
        String p=flag[3];
        String QUEUE_NAME = "deviceData_" + accountId;
        Map<String, Object> paramMap = new HashMap<String, Object>();
        List<Device> deviceList = deviceService.getDeviceById2(Integer.parseInt(monitPointId));
        try {
            //打开连接和创建频道,与发送端一样
            ConnectionFactory factory = new ConnectionFactory();
            //设置MabbitMQ所在主机ip或者主机名
            factory.setHost("47.96.15.25");
            factory.setPort(5672);
            factory.setUsername("guest");
            factory.setPassword("guest_pass");
            String routingKey;
            connection = factory.newConnection();
            channel = connection.createChannel();
            //声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。
            channel.queueDeclare(QUEUE_NAME, false, false, true, null);
            for (Device d : deviceList) {
                routingKey = orgId + "." + d.getMac();
                channel.queueBind(QUEUE_NAME, "screens_data", routingKey);
            }
            //创建队列消费者
            QueueingConsumer consumer = new QueueingConsumer(channel);
            //指定消费队列
            channel.basicConsume(QUEUE_NAME, true, consumer);
            int i=Integer.parseInt(p);
            while (true) {
                if (i<=12){
                    QueueingConsumer.Delivery delivery = consumer.nextDelivery();
                    String message = new String(delivery.getBody());
                    sendMessage(message);
                    i++;
                }else {
                    //Thread.sleep(1* 1000);
                    QueueingConsumer.Delivery delivery = consumer.nextDelivery();
                    String message = new String(delivery.getBody());
                    sendMessage(message);
                    i++;
                }
                //nextDelivery是一个阻塞方法(内部实现其实是阻塞队列的take方法)
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
//**从安全Set中 移除当前连接对象*//**//**//**//**//**//**//**//*
        webSocketSet.remove(this);
        try {
            connection.close();
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
    @OnMessage
    public void onMessage(String message) {
        System.out.println(message);
        for (WebSocketServerNew webSocketServer : webSocketSet) {
            webSocketServer.sendMessage(message);
        }
    }
   /* @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "deviceInfo", durable = "false", autoDelete = "true"),
            exchange = @Exchange(value = "screens_data", durable = "true", type = "topic"),
            key = "99.*"
    ))
    @RabbitHandler //注解意思:如果有消息过来 需要消费的时候才会调用该方法
    public void receiveMessage(@Payload String message, @Headers Map<String, Object> headers, Channel channel) throws IOException {
        //sendMessage(message.toString());
        onMessage(message);
       *//* Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        //手动接受并告诉rabbitmq消息已经接受了  deliverTag记录接受消息 false不批量接受
        channel.basicAck(deliveryTag, true);*//*
    }*/
    /**
     * 服务器端推送消息
     */
    public void sendMessage(String message) {
        try {
            if (session.isOpen()) {
                this.session.getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error(error.getMessage());
    }
}
src/main/resources/mapper/MonitorPointMapper.xml
@@ -165,4 +165,11 @@
    <select id="getMonitorPointById" resultType="com.moral.entity.MonitorPoint">
        select * from monitor_point where id=#{id}
    </select>
    <select id="getMonitorPointListByAccountId" resultType="com.moral.entity.MonitorPoint">
        SELECT mp.* FROM account a,`monitor_point` mp,organization o
        where a.organization_id=o.id
        and o.id=mp.organization_id
        and a.id=#{id};
    </select>
</mapper>
src/main/webapp/view/newUnorganizedMap.jsp
New file
@@ -0,0 +1,407 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <style type="text/css">
        body, html, #allmap {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }
        #box {
            width: 300px;
            height: 400px;
            top: 220px;
            right: 30px;
            position: absolute;
            z-index: 1;
            border: 2px solid red;
            background-color: gainsboro;
            opacity: 0.8;
        }
        #cpm, #cpm1 {
            width: 300px;
            height: 100px;
            position: absolute;
            background-color: #ffffff;
            display: none;
            left: 50%;
            top: 50%;
            margin-left: -150px;
            margin-top: -50px;
            z-index: 11;
            color: #000000;
            border: 2px solid #FF7F50;
            font-size: 14px;
            line-height: 100px;
            text-align: center;
        }
    </style>
    <script type="text/javascript"
            src="http://api.map.baidu.com/api?v=2.0&ak=rER1sgBIcQxkfNSlm2wmBGZGgEERrooM"></script>
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/utils.js"></script>
    <script type="text/javascript">
        if (typeof (JSON) == 'undefined') {
            $.getScript("js/json2.js");
        }
    </script>
    <script type="text/javascript" src="/js/paging.js"></script>
    <title>地图展示</title>
</head>
<body>
<div id="cpm">该时间存在设备无风向数据,数据不能作为参考</div>
<div id="cpm1">该时间在线设备小于两台,数据不能作为参考</div>
<div id="allmap" style="z-index: 0">
</div>
<div id="box">
    <p>
        <img src="/img/wind_dir02.png" style="width: 30px;height: 45px;margin-left: 20px;"/> <span
            style="position: relative;top: -9px;">&nbsp;&nbsp;:风向(尖头向上代表正北方向)</span>
    </p>
    <p>
        <img src="/img/arrows01.png" style="margin-left: 20px;transform:rotate(90deg);width: 30px;height: 60px;"/> <span
            style="position: relative;top: -25px;">&nbsp;&nbsp;:浓度由高到低</span>
    </p>
    <p>
        <img src="/img/arrows02.png" style="width: 30px;height: 60px;margin-left: 20px;transform:rotate(90deg);"/> <span
            style="position: relative;top: -25px;">&nbsp;&nbsp;:浓度由低到高</span>
    </p>
    <p style="text-indent: 1em;line-height: 25px;color: red" id="alarm">浓度变化:<span id="diff"></span></br></br>&nbsp;&nbsp;&nbsp;
        注:浓度变化为下风向因子浓度减去上风向因子浓度</p>
</div>
<div id="mapParams" style="display: none;">
    ${requestScope.params}
</div>
</body>
</html>
<script type="text/javascript">
    var hostAndPort = document.location.host;
    // 百度地图API功能
    var map = new BMap.Map("allmap", {minZoom: 14, maxZoom: 19});    // 创建Map实例
    map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
    var params = $.parseJSON($("#mapParams").html());
    var longitude = params["longitudeCompany"];
    var latitude = params["latitudeCompany"];
    var point = new BMap.Point(longitude, latitude);
    map.centerAndZoom(point, 18.5);  // 初始化地图,设置中心点坐标和地图级别
    var devices = [];
    var deviceList = params["deviceList"];
    var sensor = params["sensor"];
    var accountId = params["accountId"];
    var orgId = params["orgId"];
    var monitPointId = params["monitPointId"];
    var arrows=[];
    //添加地图类型控件
    map.addControl(new BMap.MapTypeControl({
        mapTypes: [
            BMAP_HYBRID_MAP,
            BMAP_NORMAL_MAP
        ]
    }));
    map.setMapType(BMAP_HYBRID_MAP);
    if (deviceList != null) {
        if (deviceList.length > 1) {
            for (var i = 0; i < deviceList.length; i++) {
                var icon = new BMap.Icon("/img/ico00.png", new BMap.Size(48, 48));
                var mark = new BMap.Marker(new BMap.Point(deviceList[i].longitude, deviceList[i].latitude), {icon: icon});
                devices.push(new BMap.Point(deviceList[i].longitude, deviceList[i].latitude));
                map.addOverlay(mark);
            }
        } else {
            var icon1 = new BMap.Icon("/img/ico00.png", new BMap.Size(48, 48));
            var mark1 = new BMap.Marker(new BMap.Point(deviceList.longitude, deviceList.latitude), {icon: icon1});
            devices.push(new BMap.Point(deviceList.longitude, deviceList.latitude));
            map.addOverlay(mark1);
            $("#alarm").css("visibility", "hidden");
        }
    }
    var ws;
    if (typeof (WebSocket) === "undefined") {
        alert("您的浏览器不支持WebSocket");
    } else {
        var p=0;
        ws = new WebSocket('ws://' + hostAndPort + '/screen/webSocketNew/' + orgId + '&' + accountId + '&' + monitPointId+ '&' +p);
        ws.onopen = function () {
        };
        //获得消息事件
        ws.onmessage = function (msg) {
            // $("#searchParam").val(JSON.parse(msg.data));
            if(deviceList.length>=2){
                realTimeData(JSON.parse(JSON.parse(msg.data)), deviceList,monitPointId);
            }else{
                if(deviceList.length==0){
                    $("#box").css("visibility","hidden");
                    document.getElementById("cpm").style.display = 'block';
                }
                if(deviceList.length==1){
                    $("#box").css("visibility","hidden");
                    document.getElementById("cpm1").style.display = 'block';
                }
            }
            /*  if (moralMap.showSensors && typeof (moralMap.showSensors) == "function") {
                  moralMap.showSensors(JSON.parse(JSON.parse(msg.data)));
              }*/
        };
        //关闭事件
        ws.onclose = function () {
        };
        //发生了错误事件
        ws.onerror = function () {
        };
    }
    var marks = [];
    function realTimeData(data, deviceList,monitPointId) {
        for (var j = 0; j < marks.length; j++) {
            map.removeOverlay(marks[j]);
        }
        var diffArr=[];
        for (var i = 0; i < deviceList.length; i++) {
            var deviceInfo = data;
            var mac = deviceInfo["mac"];
            if (mac == deviceList[i].mac) {
                deviceList[i]["deviceInfo"] = deviceInfo;
            }
            }
        for (var i = 0; i < deviceList.length; i++) {
            for (var j = 0; j <deviceList.length ; j++) {
                if (j != i) {
                        var maps={};
                        var windNumj=deviceList[j]["deviceInfo"]["e23"];
                        var windNumi=deviceList[i]["deviceInfo"]["e23"];
                        var diff=windNumj-windNumi;
                        if (diff > 180) {
                            diff = 360 - diff;
                        }
                        maps["j"]=j;
                        maps["i"]=i;
                        maps["diff"]=Math.abs(diff);
                        diffArr.push(maps);
                }
        }
            var icon = new BMap.Icon("/img/wind_dir02.png", new BMap.Size(25, 25), {anchor: new BMap.Size(11, 21.5)});
            var mark = new BMap.Marker(new BMap.Point(deviceList[i].longitude, deviceList[i].latitude), {icon: icon});
            devices.push(new BMap.Point(deviceList[i].longitude, deviceList[i].latitude));
            var dirWind=0;
            if (deviceList[i]["deviceInfo"]["e23"]<=180){
                dirWind=180+parseInt(deviceList[i]["deviceInfo"]["e23"]);
            }else {
                dirWind=deviceList[i]["deviceInfo"]["e23"].valueOf()-180
            }
            mark.setRotation(dirWind);
            marks.push(mark);
            map.addOverlay(mark);
        }
        var minIndex=0;
        var minWindDir=0.0;
        minWindDir=diffArr[0]["diff"];
        for (var i = 1; i <diffArr.length ; i++) {
            if (minWindDir>diffArr[i]["diff"]){
                minWindDir=diffArr[i]["diff"];
                minIndex=i;
            }else {
                minIndex=minIndex;
            }
        }
        var firstDevice=deviceList[diffArr[minIndex]["j"]];
        var secondDevice=deviceList[diffArr[minIndex]["i"]];
        var fNum=Number(firstDevice["deviceInfo"]["e23"]);
        var sNum=Number(secondDevice["deviceInfo"]["e23"]);
        var wind=0;
        if(Math.abs(fNum-secondDevice)>180){
            wind=(fNum+sNum)/2+180;
            if (wind>360){
                wind=wind-360;
            }
        }else {
            wind=(fNum+sNum)/2
        }
        $.ajax({
            url: "/screen/chooseDevice",
            type: "get",
            dataType: "json",
            data:{"wind":wind,"monitPointId":monitPointId},
            success: function (info) {
                var locationList=info["locationList"];
                var preAngleDeviceString = info["preAngleDeviceString"];
                var preAngleDeviceList="";
                if (preAngleDeviceString!=0 &&preAngleDeviceString!=1){
                    var arrow="";
                    preAngleDeviceList=JSON.parse(preAngleDeviceString);
                    var mac0=preAngleDeviceList[0]["mac"];
                    var mac1=preAngleDeviceList[1]["mac"];
                    for (var i = 0; i <deviceList.length ; i++) {
                        if (mac0==deviceList[i]["mac"]){
                            preAngleDeviceList[0]["sensors"]=deviceList[i]["deviceInfo"];
                        }else if (mac1==deviceList[i]["mac"]){
                            preAngleDeviceList[1]["sensors"]=deviceList[i]["deviceInfo"];
                        }else {
                            continue;
                        }
                    }
                    var diff=preAngleDeviceList[0]["sensors"][sensor]-preAngleDeviceList[1]["sensors"][sensor];
                    var diffSensor=preAngleDeviceList[1]["sensors"][sensor]-preAngleDeviceList[0]["sensors"][sensor];
                    diffSensor=String(diffSensor).replace(/^(.*\..{4}).*$/,"$1");
                    connectionDoublePoint(diff,preAngleDeviceList,locationList,diffSensor);
            }}}
        );
    }
function connectionDoublePoint(diff,preAngleDeviceList,locationList,diffSensor) {
    for (var i = 0; i <arrows.length ; i++) {
        map.removeOverlay(arrows[i]);
    }
    var info="";
    if (diff>0){
        info="厂区内无排放";
        var polyline = new BMap.Polyline([
            new BMap.Point(preAngleDeviceList[0].longitude, preAngleDeviceList[0].latitude),
            new BMap.Point(locationList[0][0],locationList[0][1])
        ], {strokeColor:"red", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline);   //增加折线
        var polyline1 = new BMap.Polyline([
            new BMap.Point(locationList[0][0],locationList[0][1]),
            new BMap.Point(locationList[1][0],locationList[1][1])
        ], {strokeColor:"Tomato", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline1);   //增加折线
        var polyline2 = new BMap.Polyline([
            new BMap.Point(locationList[1][0],locationList[1][1]),
            new BMap.Point(locationList[2][0],locationList[2 ][1])
        ], {strokeColor:"Coral", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline2);   //增加折线
        var polyline3 = new BMap.Polyline([
            new BMap.Point(locationList[2][0],locationList[2][1]),
            new BMap.Point(locationList[3][0],locationList[3][1])
        ], {strokeColor:"Orange", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline3);   //增加折线
        var polyline4 = new BMap.Polyline([
            new BMap.Point(locationList[3][0],locationList[3][1]),
            new BMap.Point(locationList[4][0],locationList[4][1])
        ], {strokeColor:"Gold", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline4);   //增加折线
        var arrowLineList = new Array();//记录绘制的箭头线
        arrows.push(polyline);
        arrows.push(polyline1);
        arrows.push(polyline2);
        arrows.push(polyline3);
        arrows.push(polyline4);
        color="Gold";
        arrowLineList[arrowLineList.length] = addArrow(polyline4,30,Math.PI/7,color);//记录绘制的箭头线
    } else {
        info="厂区内有排放";
        var polyline = new BMap.Polyline([
            new BMap.Point(preAngleDeviceList[0].longitude, preAngleDeviceList[0].latitude),
            new BMap.Point(locationList[0][0],locationList[0][1])
        ], {strokeColor:"Gold", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline);   //增加折线
        var polyline1 = new BMap.Polyline([
            new BMap.Point(locationList[0][0],locationList[0][1]),
            new BMap.Point(locationList[1][0],locationList[1][1])
        ], {strokeColor:"Orange", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline1);   //增加折线
        var polyline2 = new BMap.Polyline([
            new BMap.Point(locationList[1][0],locationList[1][1]),
            new BMap.Point(locationList[2][0],locationList[2 ][1])
        ], {strokeColor:"Coral", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline2);   //增加折线
        var polyline3 = new BMap.Polyline([
            new BMap.Point(locationList[2][0],locationList[2][1]),
            new BMap.Point(locationList[3][0],locationList[3][1])
        ], {strokeColor:"Tomato", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline3);   //增加折线
        var polyline4 = new BMap.Polyline([
            new BMap.Point(locationList[3][0],locationList[3][1]),
            new BMap.Point(locationList[4][0],locationList[4][1])
        ], {strokeColor:"red", strokeWeight:8, strokeOpacity:0.5});   //创建折线
        map.addOverlay(polyline4);   //增加折线
        arrows.push(polyline);
        arrows.push(polyline1);
        arrows.push(polyline2);
        arrows.push(polyline3);
        arrows.push(polyline4);
        var arrowLineList = new Array();//记录绘制的箭头线
        color="red";
        arrowLineList[arrowLineList.length] = addArrow(polyline4,28,Math.PI/7,color);//记录绘制的箭头线
    }
    $("#diff").html(diffSensor+" ("+info+")");
}
    function addArrow(polyline, length, angleValue, color) { //绘制箭头的函数
        var linePoint = polyline.getPath();//线的坐标串
        var arrowCount = linePoint.length;
        for (var i = 1; i < arrowCount; i++) { //在拐点处绘制箭头
            var pixelStart = map.pointToPixel(linePoint[i - 1]);
            var pixelEnd = map.pointToPixel(linePoint[i]);
            var angle = angleValue;//箭头和主线的夹角
            var r = length; // r/Math.sin(angle)代表箭头长度
            var delta = 0; //主线斜率,垂直时无斜率
            var param = 0; //代码简洁考虑
            var pixelTemX, pixelTemY;//临时点坐标
            var pixelX, pixelY, pixelX1, pixelY1;//箭头两个点
            if (pixelEnd.x - pixelStart.x == 0) { //斜率不存在是时
                pixelTemX = pixelEnd.x;
                if (pixelEnd.y > pixelStart.y) {
                    pixelTemY = pixelEnd.y - r;
                } else {
                    pixelTemY = pixelEnd.y + r;
                }
                //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法
                pixelX = pixelTemX - r * Math.tan(angle);
                pixelX1 = pixelTemX + r * Math.tan(angle);
                pixelY = pixelY1 = pixelTemY;
            } else  //斜率存在时
            {
                delta = (pixelEnd.y - pixelStart.y) / (pixelEnd.x - pixelStart.x);
                param = Math.sqrt(delta * delta + 1);
                if ((pixelEnd.x - pixelStart.x) < 0) //第二、三象限
                {
                    pixelTemX = pixelEnd.x + r / param;
                    pixelTemY = pixelEnd.y + delta * r / param;
                } else//第一、四象限
                {
                    pixelTemX = pixelEnd.x - r / param;
                    pixelTemY = pixelEnd.y - delta * r / param;
                }
                //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法
                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));
            arrow = new BMap.Polyline([
                pointArrow,
                linePoint[i],
                pointArrow1
            ], {strokeColor: color, strokeWeight: 6, strokeOpacity: 0.5});
            arrows.push(arrow);
            map.addOverlay(arrow);
            return arrow;
        }
    }
</script>
src/main/webapp/view/unorganizedMap.jsp
@@ -18,7 +18,7 @@
        #box {
            width:300px;
            height:400px;
            top:520px;
            top:220px;
            right:30px;
            position:absolute;
            z-index:1;