123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- <?php
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //class.nmea.parser.php
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // NmeaParser Class
- // Version: 1.0
- // Author: Terry Griffin
- // Based on Code written by: David Boardman
- // URL: http://cs.mwsu.edu/~griffin
- // Licensed: GNU General Public License (GNU GPL)
- //
- // Do what you want with the code.
- // Filtering not implemented yet....
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class NmeaParser{
- private $Nmea; //Nmea Array of data
- private $TimeStamp; //Unix time stamp
- private $maxHDOP; //max horizontal dilution of precision
- private $maxVDOP; //max horizontal dilution of precision
- private $CurrentUTC; //Current time stamp to coordinate sentences
-
- function __construct(){
- $this->Nmea = array();
- $this->TimeStamp= 0;
- $this->maxHDOP = 0.0;
- $this->maxVDOP = 0.0;
- $this->CurrentUTC = 0;
- $this->CurrentTime=0;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //SetMinSatellites - Set the minimum satellite parameter to remove / ignore sentences that don't have
- //enough satellites for a decent fix.
- //
- //@param - int $minSats - minimum satellites
- //@returns - void
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- public function SetMinSatellites($minSats=4){
- $this->minSats = $minSats;
- }
-
- //Dilution of precision:
- //1 Ideal This is the highest possible confidence level to be used for applications demanding the highest possible precision at all times.
- //1-2 Excellent At this confidence level, positional measurements are considered accurate enough to meet all but the most sensitive applications.
- //2-5 Good Represents a level that marks the minimum appropriate for making business decisions. Positional measurements could be used to make reliable in-route navigation suggestions to the user.
- //5-10 Moderate Positional measurements could be used for calculations, but the fix quality could still be improved. A more open view of the sky is recommended.
- //10-20 Fair Represents a low confidence level. Positional measurements should be discarded or used only to indicate a very rough estimate of the current location.
- //>20 Poor At this level, measurements are inaccurate by as much as 300 meters with a 6 meter accurate device (50 DOP × 6 meters) and should be discarded.
-
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //SetMaxHdop -
- //Set the maximum (smaller value = better) horizontal dilution of precision parameter to
- //remove / ignore sentences that don't have enough satellites in the correct location in the sky for a
- //decent fix.
- //
- //@param - int $maxHDOP - Hdop value
- //@returns - void
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- public function SetMaxHdop($maxHDOP=10){
- $this->maxHDOP = $maxHDOP;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //SetMaxVdop -
- //Set the maximum (smaller value = better) vertical dilution of precision parameter to
- //remove / ignore sentences that don't have enough satellites in the correct location in the sky for a
- //decent fix.
- //
- //@param - int $maxVDOP - Hdop value
- //@returns - void
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- public function SetMaxVdop($maxVDOP=10){
- $this->maxVDOP = $maxVDOP;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //NMEAtoUnixTime - Convert Date and Time to Linux Timestamp
- //
- //@param - string $time - current utc(hhmmss)
- //@param - int $date - current date (mmddyy)
- //@returns - int - timestamp
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- private function NMEAtoUnixTime($utc,$date){
- $h = substr($utc,0,2);
- $i = substr($utc,2,2);
- $s = substr($utc,4,2);
- $d = substr($date,0,2);
- $m = substr($date,2,2);
- $y = substr($date,4,2);
- //list($y,$m,$d) = explode('-',$date);
- return mktime($h,$i,$s,$m,$d,$y);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //ParseLine - Parse the current line
- //
- //@param - string $line - current nmea line
- //@returns - void
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- public function ParseLine($line){
- $this->NmeaType = $this->SetNmeaType($line);
- switch($this->type){
- case "GPGGA": $this->GPGGA($line);break;
- case "GPGLL": $this->GPGLL($line);break;
- case "GPGSA": $this->GPGSA($line);break;
- case "GPGSV": $this->GPGSV($line);break;
- case "GPRMC": $this->GPRMC($line);break;
- case "GPVTG": $this->GPVTG($line);break;
- default: return;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //DumpNmea - Returns current Nmea data
- //
- //@param - void
- //@returns - array - Nmea data
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- public function DumpNmea(){
- return $this->Nmea;
- }
-
-
- function GoodEnough(){
- return isset($this->Nmea[$this->CurrentUTC]['date']) && isset($this->Nmea[$this->CurrentUTC]['utc']) && isset($this->Nmea[$this->CurrentUTC]['lat']) && isset($this->Nmea[$this->CurrentUTC]['long']);
-
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- //NmeaType - GPGGA,GPGLL,GPGSA,GPGSV,GPRMC,GPVTG
- //
- //@param - int $NmeaType - what type of nmea sentence is it currently
- //@returns - void
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////
- private function SetNmeaType($line){
- $this->type = trim(strtoupper(substr($line,1,5)));
- return $this->type;
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //GGA - essential fix data which provide 3D location and accuracy data.
- //
- // $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
- //
- //Where:
- // GGA Global Positioning System Fix Data
- // 123519 Fix taken at 12:35:19 UTC
- // 4807.038,N Latitude 48 deg 07.038' N
- // 01131.000,E Longitude 11 deg 31.000' E
- // 1 Fix quality: 0 = invalid
- // 1 = GPS fix (SPS)
- // 2 = DGPS fix
- // 3 = PPS fix
- // 4 = Real Time Kinematic
- // 5 = Float RTK
- // 6 = estimated (dead reckoning) (2.3 feature)
- // 7 = Manual input mode
- // 8 = Simulation mode
- // 08 Number of satellites being tracked
- // 0.9 Horizontal dilution of position
- // 545.4,M Altitude, Meters, above mean sea level
- // 46.9,M Height of geoid (mean sea level) above WGS84
- // ellipsoid
- // (empty field) time in seconds since last DGPS update
- // (empty field) DGPS station ID number
- // *47 the checksum data, always begins with *
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function GPGGA($geostr){
- $split=explode(",",$geostr);
- $this->CurrentUTC = $this->fixUTC($split[1]);
- $this->Nmea[$this->CurrentUTC]['type']['GPGGA']=true;
- $this->Nmea[$this->CurrentUTC]['utc']=$this->fixUTC($split[1]);
- $this->Nmea[$this->CurrentUTC]['lat']=$this->degree2decimal($split[2],$split[3]);
- $this->Nmea[$this->CurrentUTC]['ns']=$split[3];
- $this->Nmea[$this->CurrentUTC]['long']=$this->degree2decimal($split[4],$split[5]);
- $this->Nmea[$this->CurrentUTC]['ew']=$split[5];
- $this->Nmea[$this->CurrentUTC]['gpsqual']=$split[6];
- $this->Nmea[$this->CurrentUTC]['numsat']=$split[7];
- $this->Nmea[$this->CurrentUTC]['hdp']=$split[8];
- $this->Nmea[$this->CurrentUTC]['alt']=$split[9];
- $this->Nmea[$this->CurrentUTC]['un_alt']=$split[10];
- $this->Nmea[$this->CurrentUTC]['geoidal']=$split[11];
- $this->Nmea[$this->CurrentUTC]['un_geoidal']=$split[12];
- $this->Nmea[$this->CurrentUTC]['dgps']=$split[13];
- $this->Nmea[$this->CurrentUTC]['diffstat']=trim($split[14]);
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // $GPGLL,4916.45,N,12311.12,W,225444,A,*1D
- //
- //Where:
- // GLL Geographic position, Latitude and Longitude
- // 4916.46,N Latitude 49 deg. 16.45 min. North
- // 12311.12,W Longitude 123 deg. 11.12 min. West
- // 225444 Fix taken at 22:54:44 UTC
- // A Data Active or V (void)
- // *iD checksum data
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function GPGLL($geostr){
- $split=explode(",",$geostr);
- $this->Nmea[$this->CurrentUTC]['type']['GPGLL']=true;
- $this->CurrentUTC = $this->fixUTC($split[3]);
- $this->Nmea[$this->CurrentUTC]['utc']=$this->fixUTC($split[3]);
- $this->Nmea[$this->CurrentUTC]['status']=$this->dataStatus($split[4]);
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
- //
- //Where:
- // GSA Satellite status
- // A Auto selection of 2D or 3D fix (M = manual)
- // 3 3D fix - values include: 1 = no fix
- // 2 = 2D fix
- // 3 = 3D fix
- // 04,05... PRNs of satellites used for fix (space for 12)
- // 2.5 PDOP (dilution of precision)
- // 1.3 Horizontal dilution of precision (HDOP)
- // 2.1 Vertical dilution of precision (VDOP)
- // *39 the checksum data, always begins with *
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function GPGSA($geostr){
- $split=explode(",",$geostr);
- $this->Nmea[$this->CurrentUTC]['type']['GPGSA']=true;
- $this->Nmea[$this->CurrentUTC]['selectmode']=$split[1];
- $this->Nmea[$this->CurrentUTC]['mode']=$split[2];
- $this->Nmea[$this->CurrentUTC]['sat1']=$split[3];
- $this->Nmea[$this->CurrentUTC]['sat2']=$split[4];
- $this->Nmea[$this->CurrentUTC]['sat3']=$split[5];
- $this->Nmea[$this->CurrentUTC]['sat4']=$split[6];
- $this->Nmea[$this->CurrentUTC]['sat5']=$split[7];
- $this->Nmea[$this->CurrentUTC]['sat6']=$split[8];
- $this->Nmea[$this->CurrentUTC]['sat7']=$split[9];
- $this->Nmea[$this->CurrentUTC]['sat8']=$split[10];
- $this->Nmea[$this->CurrentUTC]['sat9']=$split[11];
- $this->Nmea[$this->CurrentUTC]['sat10']=$split[12];
- $this->Nmea[$this->CurrentUTC]['sat11']=$split[13];
- $this->Nmea[$this->CurrentUTC]['sat12']=$split[14];
- $this->Nmea[$this->CurrentUTC]['pdop']=$split[15];
- $this->Nmea[$this->CurrentUTC]['hdop']=$split[16];
- $this->Nmea[$this->CurrentUTC]['vdop']=$split[17];
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- // $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75
- //
- //Where:
- // GSV Satellites in view
- // 2 Number of sentences for full data
- // 1 sentence 1 of 2
- // 08 Number of satellites in view
- //
- // 01 Satellite PRN number
- // 40 Elevation, degrees
- // 083 Azimuth, degrees
- // 46 SNR - higher is better
- // for up to 4 satellites per sentence
- // *75 the checksum data, always begins with *
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //*********needs fixing
- private function GPGSV($geostr){
- $split=explode(",",$geostr);
- $this->Nmea[$this->CurrentUTC]['type']['GPGSV']=true;
- $this->Nmea[$this->CurrentUTC]['satmessages']=$split[1];
- $this->Nmea[$this->CurrentUTC]['messnum']=$split[2];
- $this->Nmea[$this->CurrentUTC]['satview']=$split[3];
- $this->Nmea[$this->CurrentUTC]['satnum']=$split[4];
- $this->Nmea[$this->CurrentUTC]['elevdeg']=$split[5];
- $this->Nmea[$this->CurrentUTC]['azimuthdeg']=$split[6];
- $this->Nmea[$this->CurrentUTC]['snr']=$split[7];
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
- //
- //Where:
- // RMC Recommended Minimum sentence C
- // 123519 Fix taken at 12:35:19 UTC
- // A Status A=active or V=Void.
- // 4807.038,N Latitude 48 deg 07.038' N
- // 01131.000,E Longitude 11 deg 31.000' E
- // 022.4 Speed over the ground in knots
- // 084.4 Track angle in degrees True
- // 230394 Date - 23rd of March 1994
- // 003.1,W Magnetic Variation
- // *6A The checksum data, always begins with *
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function GPRMC($geostr){
- $split=explode(",",$geostr);
- $this->CurrentUTC = $this->fixUTC($split[1]);
- $this->Nmea[$this->CurrentUTC]['utc']=$this->fixUTC($split[1]);
- $this->Nmea[$this->CurrentUTC]['type']['GPRMC']=true;
- $this->Nmea[$this->CurrentUTC]['statusrmc']=$split[2];
- $this->Nmea[$this->CurrentUTC]['speed']=$split[7];
- $this->Nmea[$this->CurrentUTC]['track']=$split[8];
- $this->Nmea[$this->CurrentUTC]['date']=$split[9];
- $this->Nmea[$this->CurrentUTC]['magvar']=$split[10];
- $this->Nmea[$this->CurrentUTC]['mag_ew']=trim($split[11]);
- if($this->CurrentUTC && $split[9])
- $this->Nmea[$this->CurrentUTC]['Unix'] = $this->NMEAtoUnixTime($this->CurrentUTC,$split[9]);
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //VTG - Velocity made good. The gps receiver may use the LC prefix instead of GP if it is emulating Loran output.
- //
- // $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48
- //
- //where:
- // VTG Track made good and ground speed
- // 054.7,T True track made good (degrees)
- // 034.4,M Magnetic track made good
- // 005.5,N Ground speed, knots
- // 010.2,K Ground speed, Kilometers per hour
- // *48 Checksum
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function GPVTG($geostr){
- $split=explode(",",$geostr);
- $this->Nmea[$this->CurrentUTC]['type']['GPVTG']=true;
- $this->Nmea[$this->CurrentUTC]['trkdeg1']=$split[1];
- $this->Nmea[$this->CurrentUTC]['t']=$split[2];
- $this->Nmea[$this->CurrentUTC]['trkdeg2']=$split[3];
- $this->Nmea[$this->CurrentUTC]['m']=$split[4];
- $this->Nmea[$this->CurrentUTC]['spdknots']=$spdk=$split[5];
- $this->Nmea[$this->CurrentUTC]['knots']=$split[6];
- $this->Nmea[$this->CurrentUTC]['spdkmph']=$split[7];
- $this->Nmea[$this->CurrentUTC]['kph']=$split[8];
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //degree2decimal-
- //Convert latitude and longitude in degrees minutes seconds format to decimal format.
- //E.g. = 4807.038,N would be 48.12722
- //Formula is as follows
- // Degrees=Degrees
- // .d = M.m/60
- // Decimal Degrees=Degrees+.d
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function degree2decimal($deg_coord,$direction,$precision=6){
- $degree=(int)($deg_coord/100); //simple way
- $minutes= $deg_coord-($degree*100);
- $dotdegree=$minutes/60;
- $decimal=$degree+$dotdegree;
- //South latitudes and West longitudes need to return a negative result
- if (($direction=="S") or ($direction=="W"))
- {
- $decimal=$decimal*(-1);
- }
- $decimal=number_format($decimal,$precision,'.',''); //truncate decimal to $precision places
- return $decimal;
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //TimeChanged-
- //@param int $Time - time value
- //@return bool 0,1 (If both time are not equal, then we are processing new nmea data.)
- //
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function TimeChanged($Time){
- return $this->CurrentTime==$Time;
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //GetNmeaData-
- //@param void
- //@return array - nmea data array
- //
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- public function GetNmeaData(){
- return $this->Nmea;
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //fixUTCKey-
- //Replaces keys based on UTC with a linux time stamp.
- //@param int $UTC - UTC time (time only)
- //@param int $Unix - linux timestamp (has date)
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function fixUTCKey($UTC,$Unix){
- //Not done
- $arr[$newkey] = $arr[$oldkey];
- unset($arr[$oldkey]);
- }
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- //cleanUTC-
- //If UTC has a decimal in it, get rid of it.
- //@param int $UTC - UTC time (time only)
- //@return int $UTCfixed -
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- private function fixUTC($UTC){
- //list($Fixed,$Null) = explode('.',$UTC);
- return $UTC; //$Fixed;
- }
-
-
- }
- ?>
|