/** * 区域班列查询 */ public function inarea() { //先获取到参数 $starttime = $this->_get('starttime'); $endtime = $this->_get('endtime'); $points = json_decode($_GET['area']); if (empty($starttime)) { return_value_json(false, 'msg', '系统出错:开始时间为空'); } if (strlen($starttime) != 19 || strtotime($starttime) === false) { return_value_json(false, 'msg', '系统出错:开始时间格式不正确'); } if (!empty($endtime) && (strlen($endtime) != 19 || strtotime($endtime) === false)) { return_value_json(false, 'msg', '系统出错:结束时间格式不正确'); } if (empty($points) || !is_array($points) || count($points) < 2) { return_value_json(false, 'msg', '系统出错:多边形端点数量不够'); } foreach ($points as $index => $point) { $points[$index] = (array) $point; //把对象转成数组 } //首先查询数据库里指定时间内所有的定位信息 $Location = M('Location'); check_error($Location); $condition = array('_string' => " `location`.`time`>='{$starttime}' AND `train`.`number` IS NOT NULL "); if (!empty($endtime)) { $condition['_string'] .= " AND `location`.`time`<='{$endtime}' "; } $Location->join('`device` on `device`.`id`=`location`.`device_id`')->join("`train` on (`train`.`id`=`device`.`target_id` AND `device`.`target_type`='班列')")->join('`department` on `department`.`id`=`train`.`department_id`')->field(array('`location`.`id`', '`department`.`id`' => 'department_id', '`department`.`name`' => 'department', '`train`.`id`' => 'train_id', '`train`.`number`', '`train`.`due_date`', '`train`.`due_time`', '`location`.`device_id`', '`device`.`type`', '`device`.`label`', '`location`.`time`', 'state', 'online', '`location`.`address`', 'baidu_lat', 'baidu_lng', 'speed', 'direction', 'mcc', 'mnc', 'lac', 'cellid', '`location`.`range`'))->where($condition)->order('`department`.`sequence`, `train`.`id`, `time` ASC'); //先按班列id,然后按时间顺序 // $page = $_REQUEST['page'] + 0; // $limit = $_REQUEST['limit'] + 0; // if($page && $limit) $Location->limit($limit)->page($page); //这里不用数据库的分页,而是用我们自己的分页(目前没法分页了) $locations = $Location->select(); check_error($Location); $total = 0; $results = array(); $curTrain = null; //当前在区域内的班列 $alreadyIn = false; //目前是否已经在区域内 $lastLocation = null; foreach ($locations as $location) { $in = Geometry::geoPointInPolygon(array('lat' => $location['baidu_lat'], 'lng' => $location['baidu_lng']), $points); //TODO 考虑当前点与上一个定位点的轨迹线段是否切割多边形? if ($in) { if ($alreadyIn && $curTrain != $location['train_id']) { //已经在区域内,但是现在来了个不同的车(原来的车不知道跑哪里去了,这个车不知道是从哪里来的) //那么我们认为前车的离开点就是他轨迹的最后一个点,并且它现在离开区域了 $lastTrainLocationsCount = count($results[$total - 1]['locations']); if ($lastTrainLocationsCount > 0) { $results[$total - 1]['time_out'] = $results[$total - 1]['locations'][$lastTrainLocationsCount - 1]['time']; $results[$total - 1]['duration'] = $this->_getFriendlyDurationText($results[$total - 1]['time_in'], $results[$total - 1]['time_out']); $alreadyIn = false; $curTrain = null; } } if (!$alreadyIn && $curTrain === null) { //首次进入 $alreadyIn = true; $curTrain = $location['train_id']; $results[] = array('id' => $location['id'], 'department_id' => $location['department_id'], 'department' => $location['department'], 'train_id' => $location['train_id'], 'number' => $location['number'], 'device_id' => $location['device_id'], 'label' => $location['label'], 'time_in' => $location['time'], 'time_out' => '', 'duration' => '', 'locations' => array(), 'first_isout' => false, 'last_isout' => false); $total++; if ($lastLocation !== null && $lastLocation['train_id'] == $location['train_id']) { $results[$total - 1]['locations'][] = $lastLocation; $results[$total - 1]['first_isout'] = true; } } $results[$total - 1]['locations'][] = $location; } else { //出了区域 if ($alreadyIn) { if ($curTrain != $location['train_id']) { //原来的车不知道跑哪里去了 $lastTrainLocationsCount = count($results[$total - 1]['locations']); if ($lastTrainLocationsCount > 0) { $results[$total - 1]['time_out'] = $results[$total - 1]['locations'][$lastTrainLocationsCount - 1]['time']; } else { //这是不可能的。 $results[$total - 1]['time_out'] = $location['time']; } } else { //记录班列离开的点 $results[$total - 1]['time_out'] = $location['time']; $results[$total - 1]['locations'][] = $location; $results[$total - 1]['last_isout'] = true; } $results[$total - 1]['duration'] = $this->_getFriendlyDurationText($results[$total - 1]['time_in'], $results[$total - 1]['time_out']); $alreadyIn = false; $curTrain = null; } } $lastLocation = $location; } return_json(true, $total, 'results', $results); }