Convert $GPGGA sentence coords for Maps URL

Hi, I’m not using a typical GPS setup or any library…

I need to extract (easy) the lat & long strings from the $GPGGA sentence - then convert them to a numeric format suitable for Google Maps ‘&place=‘ syntax…

It’s just numbers, but I can’t see where the minutes and decimal minutes or fractions of a degree trip over themselves !

The easiest way to strip the individual data parts like latitude and longitude is to use a library like TinyGPS++.

Otherwise I have used strtok() to separate the data.

1 Like

Hi.
That can certainly be done and it doesn't require a GPS library. But we don't see what efforts you've made to date or exactly why the numerical format is a problem. I thought they could be entered into Google Maps in various formats.

What does "trip over themselves" mean?

1 Like

The strange DDMM.MMMMM format of NMEA coordinates is explained here https://www.gpsworld.com/what-exactly-is-gps-nmea-data/

Don't forget to apply negative N/S E/W signs (if applicable) to the result AFTER doing the numeric conversion, or you introduce large errors.

Libraries like TinyGPS and NeoGPS convert lat/lon into long integers, in millionths of a degree, to preserve full accuracy.

1 Like

Yeah... thanks.
I did it a few years ago, but can't find the code (!)
My confusion comes from the fractional minutes vs the decimal degrees.

I get the co-ords correctly. but when plotted - they are not correctly interpreted as parts of the lat/long.
I only seem to get the integer part - hence the plotted location is somewhat north and west of where it should be!

GPS returns...
*$GPGGA,072651.00,3754.559774,S,14510.604956,E,1,06,0.8,107.9,M,3.0,M,,45

Maps shows
https://www.google.com/maps/place/37°54'33.2"S+145°10'36.4"E/@-37.90921,145.174596
This is correct

Do you really need to be reminded to post the code?

This > 3754.559774,S,14510.604956,E,

is -37.909329, 145.176749

Near the Lum Reserve Playground in Melbourne.

1 Like

No code as such yet…
Just the incoming $GPGGA sentence.

The reason I can’t use a library off the shelf, is because on the SIMCOM modems, the onboard GPS data is interspersed with the modem operating data and SMS texts etc on the same port.

I simply parse each sentence as it arrives - on the leading characters of the message for command responses, sms text, time, rssi, or in this case the gps data.
.

just for the fun of it! :slight_smile:

it's based btw on this code previously posted here.

void setup() {
  char test_str[] = "$GPGGA,072651.00,3754.559774,S,14510.604956,E,1,06,0.8,107.9,M,3.0,M,,45";
  int i = 0;
  char *start_pch, *end_pch;
  char extracted_str[16];
  char temp_str[32];
  char map_str[100] = "https://www.google.com/maps/place/";

  float f_temp, latitude, longuitude;
  int i_temp;

  start_pch = test_str - 1;

  Serial.begin(115200);

  end_pch = strstr (test_str, ",");
  while ( end_pch != NULL ) {
    ++i;
    memset (extracted_str, 0, 16);
    strncpy (extracted_str, start_pch + 1, end_pch - start_pch - 1);
    if (i == 3) {
      f_temp = atof(extracted_str);
      i_temp = (int)f_temp;
      f_temp = (f_temp - i_temp) * 60;
      sprintf(temp_str, "%i°%i'%s\"", i_temp / 100, i_temp%100, String(f_temp, 1).c_str());
      strcat(map_str, temp_str);
      latitude =  (atof(&extracted_str[2]) / 60) + (i_temp / 100);
    }
    else if (i == 4) {
      strcat(map_str, extracted_str);
      if (extracted_str[0] == 'S') latitude *= -1;
    }
    else if (i == 5) {
      f_temp = atof(extracted_str);
      i_temp = (int)f_temp;
      f_temp = (f_temp - i_temp) * 60;
      sprintf(temp_str, "%c%i°%i'%s\"", (i_temp > 0) ? '+' : '-', i_temp / 100, i_temp%100, String(f_temp, 1).c_str());
      strcat(map_str, temp_str);
      longuitude =  (atof(&extracted_str[3]) / 60) + (i_temp / 100);
    }
    else if (i == 6) {
      strcat(map_str, extracted_str);
      if (extracted_str[0] == 'W') longuitude *= -1;
    }
    start_pch = end_pch;
    end_pch = strstr (end_pch + 1, ",");
  }

  //retrieve (checksum)
  memset (extracted_str, 0, 16);
  strncpy (extracted_str, start_pch + 1, strlen(start_pch));

  sprintf(temp_str, "/@%s,%s", String(latitude, 5).c_str(), String(longuitude, 5).c_str());
  strcat(map_str, temp_str);


  Serial.println(map_str);
}

void loop() {
  // put your main code here, to run repeatedly:

}

https://www.google.com/maps/place/37°54'33.6"S+145°10'36.3"E/@-37.90933,145.17674

1 Like

Hmmm ... seems like you could still use a library like TinyGPS++. As you're reading in characters, at some point you must know whether you're dealing with a NMEA sentence or something else. If the former, finish collecting the entire line into a char array and then "play" it to the library. Otherwise, process it as appropriate.

1 Like

@sherzaad - thanks! That’s more than I expected…
I’ll fire it up in the morning and send beer later, thanks.

@gfvalvo - thanks too…
I was thinking about that, but I’m quite low in resources, and was cautious about loading up, extra routines that may not be needed,

I’ll post back in my thoughts tomorrow - cheers.

Any functions (in your code or a library) that aren't actually called are not linked into the final object code and occupy no resources.

Just seems to me rolling your own NMEA sentence parser is unnecessary work (especially when there is established and well-debugged code available) and will require a fair amount of debugging to get the corner cases correct.

Also, if you're just starting this project then "low in resources" is not a good place to be. My go-to solution is to throw better hardware at the problem. Hardware is cheap. Pulling your hair out is painful.

I’m with you on all of that!
This project is almost five years old running well.

The GPS addon was a request from a friend.. I’d thought about doing it before, but always planned a major rewrite for other reasons… age and health got in the way

So i thought I’d see if I could tack it in without upsetting the apple cart.

It was a function already in the SIM7600 modem, so I just thought I’d try to roll it in. (it’s a LOT of code in a Mega1284)

I might look at tinygps again… I already have it installed…
Any thoughts how to use a port redirection, as it’s not on a separate set of pins…

Not really sure what you mean. What's "not on a separate set of pins…"?

The gps serial data arrives on the same tx/rx pins as the other serial comms data.
i can’t instantiate the tinygps on the same pins as my general comms…
the gps funcuptionslity is inside the same chip as the modem…

I hope I’m not making any wrong assumption.

I see both sets of data on the same tx pin - at different moments in time.

You don't associate the TinyGPSPlus object with a Stream object when you instantiate it. It doesn't handle the Serial I/O, it just acts as a NMEA sentence parser. So, just handle the the serial comms as usual.

I don't know how the serial data stream is formatted in your application, but for argument's sake let's say the records are delimited by new lines. So, collect an entire line in a char buffer. If you identify it as a NMEA sentence, then stream it to the TinyGPSPlus object. Otherwise, handle it as appropriate.

See how the Library's BasicExample works.

1 Like

ahhh ok, I usually write most of my own parsers, and seeing the forums, I just assumed that it was created with a link to the desired serial pins…

Just goes to show that making an ASSumption makes an ASS of ME :scream: (not U) !

When I consider using an unfamiliar library, my first stop is the source code on GitHub .... constructor(s) and public members - functions and variables. I study those even before heading to the examples.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.