private function checkAreaAlarm($device, $location, $rule)
 {
     //		Log::write("" .
     //				"\ncheckAreaAlarm\n" .$rule['id'].
     //				"\nRule:\n".print_r($rule, true)."" .
     //				"\nDevice\n".print_r($device, true)."" .
     //				"\nLocation\n".print_r($location, true) .
     //				"", Log::INFO);
     $polygon = $this->getPathAreaPoints($rule['path_area_id']);
     //将有关数字转成数字形式(否则是字符串形式,某些比较运算会有问题的)
     $rule['speed'] += 0;
     $location['speed'] += 0;
     $rule['long'] += 0;
     $rule['distance'] += 0;
     $speedMsg = $this->getSpeedLimitAlarmMsg($location['speed'], $rule['speed']);
     if ($rule['in_out'] == '进入') {
         if (Geometry::geoPointInPolygon2($location['baidu_lat'], $location['baidu_lng'], $polygon)) {
             if (empty($rule['long'])) {
                 $msg = '按照规则[' . $rule['label'] . '],' . $device['target_type'] . '[' . $device['target_name'] . '],' . '不允许在此时[' . date('Y-m-d H:i:s') . ']进入区域[' . $rule['path_area_label'] . '],' . "而现在检测到目标在区域内(坐标:{$location['baidu_lat']}, {$location['baidu_lng']})";
                 $msg .= empty($speedMsg) ? '' : ',并且' . $speedMsg;
                 return $this->startAlarm($device, $location, $rule, $msg);
             } else {
                 //允许进入时间 不为0
                 $longInSeconds = $rule['long'] * 60;
                 while ($previousLocation = $this->getPreviousLocation($device['id'], $location['id'])) {
                     if (!Geometry::geoPointInPolygon2($previousLocation['baidu_lat'], $previousLocation['baidu_lng'], $polygon)) {
                         return empty($speedMsg) ? null : $this->startSpeedAlarm($device, $location, $rule);
                         //历史轨迹点不在区域内,不用报警(如果不超速的话)
                     }
                     $timeDiff = $this->getTimeDifference('now', $previousLocation['time']);
                     if ($timeDiff >= $longInSeconds) {
                         $msg = '按照规则[' . $rule['label'] . '],' . $device['target_type'] . '[' . $device['target_name'] . '],' . '不允许在此时[' . date('Y-m-d H:i:s') . ']进入区域[' . $rule['path_area_label'] . ']' . '超过' . $rule['long'] . '分钟,' . "而现在检测到目标在区域内(坐标:{$location['baidu_lat']}, {$location['baidu_lng']})," . "并且时间已经超过" . floor($timeDiff / 60) . "分钟";
                         $msg .= empty($speedMsg) ? '' : ',并且' . $speedMsg;
                         return $this->startAlarm($device, $location, $rule, $msg);
                     }
                 }
                 return empty($speedMsg) ? null : $this->startSpeedAlarm($device, $location, $rule);
                 //已经 没有上一个定位了(时间仍不够长),不用报警
             }
         } else {
             //不允许进入,但是现在点不在区域内,仍有可能需要报警:如果当前点和上一个轨迹点的线段切割区域多边形的话。
             $previousLocation = $this->getPreviousLocation($device['id'], $location['id']);
             $timeDiff = floor($this->getTimeDifference('now', $previousLocation['time']) / 60);
             if ($timeDiff >= $rule['long'] && Geometry::geoSegmentCuttingPolygon($previousLocation['baidu_lat'], $previousLocation['baidu_lng'], $location['baidu_lat'], $location['baidu_lng'], $polygon)) {
                 $msg = '按照规则[' . $rule['label'] . '],' . $device['target_type'] . '[' . $device['target_name'] . '],' . '不允许在此时[' . date('Y-m-d H:i:s') . ']进入区域[' . $rule['path_area_label'] . ']' . (empty($rule['long']) ? '' : '超过' . $rule['long'] . '分钟') . ",而现在检测到目标的当前位置与上一个定位点的轨迹路线经过该区域" . (empty($rule['long']) ? '' : ',并且两轨迹点时间间隔已经超过' . $timeDiff . '分钟');
                 $msg .= empty($speedMsg) ? '' : ',并且' . $speedMsg;
                 return $this->startAlarm($device, $location, $rule, $msg);
             }
             return null;
         }
     } else {
         //离开区域报警
         $distance = round(Geometry::geoPointDistancePolygon($location['baidu_lat'], $location['baidu_lng'], $polygon));
         if (!Geometry::geoPointInPolygon2($location['baidu_lat'], $location['baidu_lng'], $polygon) && $distance >= $rule['distance']) {
             if (empty($rule['long'])) {
                 // 时长限制为0
                 $msg = '按照规则[' . $rule['label'] . '],' . $device['target_type'] . '[' . $device['target_name'] . '],' . '不允许在此时[' . date('Y-m-d H:i:s') . ']离开区域[' . $rule['path_area_label'] . ']' . $rule['distance'] . '米,' . "而现在检测到目标在区域外(坐标:{$location['baidu_lat']}, {$location['baidu_lng']}),距离区域" . $distance . '米';
                 $msg .= empty($speedMsg) ? '' : ',并且' . $speedMsg;
                 return $this->startAlarm($device, $location, $rule, $msg);
             } else {
                 //允许离开一段时间
                 $longInSeconds = $rule['long'] * 60;
                 $curLocationId = $location['id'];
                 while ($previousLocation = $this->getPreviousLocation($device['id'], $curLocationId)) {
                     $historyDist = Geometry::geoPointDistancePolygon($previousLocation['baidu_lat'], $previousLocation['baidu_lng'], $polygon);
                     if (Geometry::geoPointInPolygon2($previousLocation['baidu_lat'], $previousLocation['baidu_lng'], $polygon) || $historyDist < $rule['distance']) {
                         //历史轨迹点在区域内或者离开距离不够
                         return empty($speedMsg) || $distance < $rule['distance'] ? null : $this->startSpeedAlarm($device, $location, $rule);
                     }
                     $timeDiff = $this->getTimeDifference('now', $previousLocation['time']);
                     if ($timeDiff >= $longInSeconds) {
                         $msg = '按照规则[' . $rule['label'] . '],' . $device['target_type'] . '[' . $device['target_name'] . '],' . '不允许在此时[' . date('Y-m-d H:i:s') . ']离开区域[' . $rule['path_area_label'] . ']' . $rule['distance'] . '米,' . '超过' . $rule['long'] . '分钟,' . "而现在检测到目标在区域外(坐标:{$location['baidu_lat']}, {$location['baidu_lng']})," . "并且离开区域至少" . $rule['distance'] . '米' . "已经超过" . floor($timeDiff / 60) . "分钟";
                         $msg .= empty($speedMsg) ? '' : ',并且' . $speedMsg;
                         return $this->startAlarm($device, $location, $rule, $msg);
                     }
                     $curLocationId = $previousLocation['id'];
                 }
                 return empty($speedMsg) || $distance < $rule['distance'] ? null : $this->startSpeedAlarm($device, $location, $rule);
                 //已经 没有上一个定位了(时间仍不够长),不用报警
             }
         }
         return null;
         //轨迹点在区域里面,不用报警
     }
 }