222

Mock LocationProvider - Structure/Explanation (NMEA, $GPRMC)


What is this: This tutorial shows how Mock LocationProviders are structured, so that you will be able to set up your own.

What you will learn: How a Mock LocationProvider (NMEA,$GPRMC) is built up.

Problems/Questions: post right below...

Difficulty: 2 of 5 

Description:
Basically a mock (~= fake) location provider is simply a textfile with a list of (gps-)locations within.

Each Mock LocationProvider to be created needs its own directory in the following path on the emulator: Quote:
/data/misc/location/<provider_name>.


When an LocationProvider is requested its directory is searched for the following files (in order):

class

kml

nmea <--- This is explained here

track


1.
If you pull the file ("/data/app/misc/location/gps/nmea")(which is a such a mock location provider, as no gps-device can be attached) via Eclipse' DDMS-View from the emulator to your pc , you see the following:

Java:
$GPRMC,.......
$GPRMC,003347.000,A,3725.3433,N,12205.7920,W,0.08,149.46,061007,,,D*70
$GPRMC,003348.000,A,3725.3433,N,12205.7921,W,0.05,142.51,061007,,,D*7E
$GPRMC,003349.000,A,3725.3432,N,12205.7921,W,0.08,159.56,061007,,,D*7E
$GPRMC,003350.000,A,3725.3432,N,12205.7921,W,0.06,151.59,061007,,,D*7F
$GPRMC,003351.000,A,3725.3432,N,12205.7921,W,0.20,120.57,061007,,,D*72
$GPRMC,.......


If you then lookup that "$GPRMC"-String on Google you will see, that it is a part of the NMEA-Protocol (who could expect that ):
Quote:
$GPRMC - Recommended Minimum Specific GPS/TRANSIT Data


So '$GPRMC' indicates a simple/minimalistic "partition" of the NMEA-Protocol.

So as the most gps-devices emit those GPRMC-'setences' (one line is one sentence) Android simply parses them line by line.

Fine, but what the heck do all those numbers/characters mean  :

If you really want to create you own Mock LocationProvider, take a look here for extensive explanation.

Quote:
* RMC
RMC = Recommended Minimum Specific GPS/TRANSIT Data

$GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh

1 = UTC(universal time, coordinated) of position fix
2 = Data status (A=good, V=navigation receiver warning)
3 = Current Latitude
4 = North/South in Latitude Hemisphere
5 = Current Longitude
6 = East/West in Longitude Hemisphere
7 = Speed over ground in knots
8 = (Direction of travel N:0°, E:90°, S:180°, W:270°)
9 = UT DateStamp
10 = Magnetic variation degrees (Easterly var. subtracts from true course)
11 = East/West
12 = Checksum


So lets parse one 'sentence' by hand to understand this:
XML:
$GPRMC,003347.000,A,3725.3433,N,12205.7920,W,0.08,149.46,061007,,,D*70

Parts:
1:   003347.000  -->   0:33 am 47 seconds 0 milliseconds (UTC(universal time, coordinated) of position fix)
2:   A           -->   Status is ok   (Data status (A=good, V=navigation receiver warning))
3:   3725.3433         (North/South in Latitude Hemisphere)
4:   N           -->   North   (North/South)
5:   12205.7920        (Current Longitude)
6:   W           -->   West   (East/West in Longitude Hemisphere)
7:   0.08        -->   0.08 knots/second (Direction: North/West)   (Speed over ground in knots)
8:   149.46      -->   sth. like SouthEast (Direction of travel  N:0°, E:90°, S:180°, W:270°)
9:   061007      -->   6th October, 2007  (UT(universal time) DateStamp)
10:  <empty>           (Magnetic variation degrees (Easterly var. subtracts from true course))
11:  <empty>           (East/West)
12:  D*70              (Checksum)


So if you want to create your own Mock LocationProvider, you will need to calculate the Checksum of each 'sentence'.

Example-Implementation in JAVA :
Java:
     /** Calculates the checksum for a sentence */
     public static String getChecksum(String sentence) {
          // Loop through all chars to get a checksum
          char character;
          int checksum = 0;
          int length = sentence.length();
          for (int i = 0; i < length; i++) {
               character = sentence.charAt(i);
               switch (character) {
                    case '$':
                         // Ignore the dollar sign
                         break;
                    case '*':
                         // Stop processing before the asterisk
                         break;
                    default:
                         // Is this the first value for the checksum?
                         if (checksum == 0) {
                              // Yes. Set the checksum to the value
                              checksum = (byte) character;
                         } else {
                              // No. XOR the checksum with this character's value
                              checksum = checksum ^ ((byte) character);
                         }
               }
          }
          // Return the checksum formatted as a two-character hexadecimal
          return Integer.toHexString(checksum);
     }

Example-Implementation in VB.NET :
VB.NET:
' Calculates the checksum for a sentence
  Public Function GetChecksum(ByVal sentence As String) As String
    ' Loop through all chars to get a checksum
    Dim Character As Char
    Dim Checksum As Integer
    For Each Character In sentence
      Select Case Character
        Case "$"c
          ' Ignore the dollar sign
        Case "*"c
          ' Stop processing before the asterisk
          Exit For
        Case Else
          ' Is this the first value for the checksum?
          If Checksum = 0 Then
            ' Yes. Set the checksum to the value
            Checksum = Convert.ToByte(Character)
          Else
            ' No. XOR the checksum with this character's value
            Checksum = Checksum Xor Convert.ToByte(Character)
          End If
      End Select
    Next
    ' Return the checksum formatted as a two-character hexadecimal
    Return Checksum.ToString("X2")
  End Function


Feel free to ask, if any question is still open 

你可能感兴趣的:(eclipse,android,UP,vb,VB.NET)