123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <?php
- namespace Workerman\Protocols;
- class Jytgps {
-
-
- const LOCATION_FORMAT_FLOAT = 0;
-
- const LOCATION_FORMAT_RAW = 1;
- private static $locationFormat ;
-
-
- public static function str2bin( $text ){
- if (!is_string($text))
- return null;
- $arr = explode(' ',$text);
- $bin = '';
- foreach($arr as $hex){
- if(strlen($hex) == 2){
- $bin .= chr( hexdec($hex) );
- }
- }
- return $bin;
- }
-
-
- public static function input( $buffer, $connection ){
- $end = substr($buffer,-1);
- if($end != '#'){
- return 0;
- }
- return strlen($buffer);
- }
-
-
- public static function encode( $value ){
- //echo 'encode:'.PHP_EOL;
- //var_dump($value);
-
- return $value['head_char'].$value['identify'].$value['version'].'Y'.$value['function_code'].$value['function_keyword'].$value['end_char'];
-
- }
-
-
- public static function decode( $buffer ){
- /*
- function_code(终端--功能类指令): A-上传状态类信息 B-上传定位类信息
- function_keyword(功能项):
- */
- $length = strlen($buffer);
- $str = rtrim($buffer,"#");
- $arr = explode('#',$str);
- $decode = array();
- foreach($arr as $key=>$row){
- $buffer = $row.'#';
- $data = array();
- $data['head_char'] = substr($buffer,0,1);
- $data['identify'] = substr($buffer,1,2);
- $data['version'] = substr($buffer,3,2);
- $data['reply'] = substr($buffer,5,1);
- $index = strpos($buffer,',')+1;
- $data['device_id'] = substr($buffer,6,$index-1-6);
- $re = substr($buffer,$index,1);
- if($re == 'Y'){ //Y回应的数据包,功能码和关键词的起始位置和非回应的不一样
- $data['function_code'] = substr($buffer,$index+1,1);
- $data['function_keyword'] = substr($buffer,$index+2,1);
- $data['end_char'] = substr($buffer,$index+3,1);
- }else{
- $data['function_code'] = substr($buffer,$index,1);
- $data['function_keyword'] = substr($buffer,$index+1,1);
- $data['order_data'] = substr($buffer,$index+2,$length-1);
- $data['end_char'] = substr($buffer,-1);
- //解析指令数据
- $data['method'] = 'method000'.$data['function_code'];
- if($data['function_code'] == 'A'){ //上报状态
- array_push($decode, $data);
- }
- elseif($data['function_code'] == 'B'){ //上报定位
- if($data['function_keyword'] == 'A'){
- $data = self::decodeLocation($data);
- if($data['lat'] !== false)
- array_push($decode, $data);
- else
- echo 'lat empty ' . PHP_EOL;
- }
- else{
- //....跳过
- }
- }
- else{
- //....跳过
- }
- }
- }
-
- return $decode;
- }
-
-
- public static function bin2str( $hex, $space ){
- $data = unpack("C*chars",$hex);
- $bin = '';
- foreach($data as $key=>$value){
- $bin .= sprintf('%02X',$value);
- if($space)
- $bin .= ' ';
- }
- return trim($bin);
- }
-
-
- private function decodeLocation( $data ){
- $orders = explode('&',$data['order_data']);
- $data['lat'] = false;
- $data['lng'] = false;
- foreach ($orders as $order) {
- $code = substr($order,0,1);
- //解析定位数据
- if($code=='A'){
- //A0732142233550011405829060520190600
- //时分秒
- $times = substr($order,1,2).':'.substr($order,3,2).':'.substr($order,5,2);
- //定位纠偏 纠偏公式 abcde.fghi abc+de/60+fghi/600000
- $lat1 = substr($order,7,4);
- $lat2 = substr($order,11,4);
- $lng1 = substr($order,15,5);
- $lng2 = substr($order,20,4);
- if(self::locationFormat == self::LACATION_FORMAT_FLOAT){
- $lat_a = floor($lat1/100);
- $lat_b = (($lat1 - $lat_a*100).'.'.$lat2 )/60;
- $data['lat'] = $lat_a + $lat_b;
- $lng_a = floor($lng1/100);
- $lng_b = (($lng1 - $lng_a*100).'.'.$lng2 )/60;
- $data['lng'] = $lng_a + $lng_b;
- }else{
- $data['lat'] = $lat1 .'.'. $lat2;
- $data['lng'] = $lng1 .'.'. $lng2;
- }
-
- /*
- $lat_0 = substr($order,7,4).'.'.substr($order,11,4);
- $lng_0 = substr($order,15,5).'.'.substr($order,20,4);
- $data['lat_0'] = $lat_0;
- $data['lng_0'] = $lng_0;
- */
- $f = ord(substr($order,24,1));
- $data['f'] = $f;
- $data['type'] = 1;//1-表示取GPS坐标数据,2-表示取基站坐标
- switch ($f) {
- case 48://0x0011 0000 西经、南纬、定位
- $data['ew']='W';
- $data['ns']='S';
- $data['location']=true;
- break;
- case 49://0x0011 0001 西经、南纬、非定位
- $data['ew']='W';
- $data['ns']='S';
- $data['location']=false;
- break;
- case 50://0x0011 0010 西经、北纬、定位
- $data['ew']='W';
- $data['ns']='N';
- $data['location']=true;
- break;
- case 51://0x0011 0011 西经、北纬、非定位
- $data['ew']='W';
- $data['ns']='N';
- $data['location']=false;
- break;
- case 52://0x0011 0100 东经、南纬、定位
- $data['ew']='E';
- $data['ns']='S';
- $data['location']=true;
- break;
- case 53://0x0011 0101东经、南纬、非定位
- $data['ew']='E';
- $data['ns']='S';
- $data['location']=false;
- break;
- case 54://0x0011 0110东经、北纬、定位
- $data['ew']='E';
- $data['ns']='N';
- $data['location']=true;
- break;
- case 55://0x0011 0111 东经、北纬、非定位
- $data['ew']='E';
- $data['ns']='N';
- $data['location']=false;
- break;
- case 63://0x0011 1111 表示设备直接调用第三方的基站位置解析接口成经纬度信息上传,该标志位用来区分正常的GPS 定位经纬度信息
- $data['ew']=null;
- $data['ns']=null;
- $data['type']=2;
- break;
-
- default:
- break;
- }
-
- $data['speed'] = substr($order,25,2);
- $data['direction'] = substr($order,27,2);
- $dates = '20'.substr($order,33,2).'-'.substr($order,31,2).'-'.substr($order,29,2); //年月日
- $data['device_time'] = $dates.' '.$times;
- }
- }
- return $data;
- }
-
-
- public function setLocationFormat( $format ){
- self::locationFormat = $format;
- }
-
- }
|