Comparing live GPS data from phone to database of coordinates

I am writing an arduino program to compare live gps coordinates (lat, long) to a database of coordinates which each have an associated ‘level of radioactivity’ variable. The program will calculate the distance between current position and the position of known data points (the position of radioactive materials on a beach) and if this distance is less than say 15m, the arduino will turn on an LED, the color of which depends on the level of radioactivity of the point.

Below is a more detailed description of the project including an example of the data that will be used and c++ code that I made implementing the distance comparison etc.

I will be using a nexus 4 as a virtual GPS shield through an app called sensoduino connected to arduino via bluetooth. This will provide live tracking of coordinates and data is sent to the arduino as .csv file (will this work?).

SUMMARY OF HELP I NEED:

Reading in the data from the ‘database’ which is a .txt file stored on (example outlined below). and storing it in a vector of classes (see c++ code below).
Where to store this database so that the arduino can access it to perform calculations without connection to internet or a computer.
Reading in csv data from sensoduino which uses the nexus 4 as a virtual GPS shield to collect ‘live’ latitude and longitude coordinates.
Using loop to determine distance from radioactive source and strength to turn on LED of particular color. (check c++ code below).

I have never used an Arduino before so I am not sure about how much the c++ language is compatible.

DATA AND C++ PROGRAM:

Below is a snippet of the data we will be using (there are 400-500 lines in the .txt file). The first column holds the latitude, the second the longitude and the third holds the level of radioactivity of the objects found at the location. The data has been ordered by level of radioactivity (from most radioactive to least) so that the program prioritizes warnings for strong radioactive points closer than 15m rather than the closest point.

latitude = 56.0349 longitude = -3.34267 radioactivity = 8690000

56.0328 -3.342 867289
56.0328 -3.342 867289
56.0348 -3.34242 404430
56.0348 -3.34247 295287
56.0338 -3.34122 221830
56.0346 -3.34242 193347
56.0337 -3.34118 182304
56.0342 -3.34141 155572
56.0337 -3.34173 145229
56.0347 -3.34239 125143
56.0336 -3.34134 120247
56.0345 -3.34251 115401

I have written some code in c++. It reads in the data from the above text file line by line and stores the data in the ‘radioactivityData’ struct and into a vector. There is also a function to calculate the distance between two sets of lat. lon. coordinates and a for loop that checks to see if you are <15m from one of the radioactive sources in the database. If you are, depending on the magnitude of the radioactivity, a different color LED will be lit up.

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <math.h>

using namespace std;

double distance(double lat1, double lon1, double lat2, double lon2);
double deg2rad(double deg);
double rad2deg(double rad);

struct radioactivityData
{
    double lat;
    double lon;
    int radioactivity;
};

int main()
{
    double myLat=56.035359; //I want these to be input from my android phone (Nexus 4) using a bluetooth receiver with the Arduino.
    double myLon=-3.3443385; //Also, this variable should be updated as the user continues walking and their position changes

    std::ifstream dataFile;
    dataFile.open("combinedorderedData.txt");

    std::string tmpLine;
    std::vector<radioactivityData> radioactivityTable;
    
    while(std::getline(dataFile, tmpLine))
    {
        std::stringstream inputLine(tmpLine);

        radioactivityData rad;
        if(!(inputLine >> rad.lat >> rad.lon >> rad.radioactivity))
        {
            // ... error parsing input. Report the error
            // or handle it in some other way.

            continue;   // keep going!
        }
        radioactivityTable.push_back(rad);
    }

    for(int i=0; i<radioactivityTable.size();)
    {
        if(distance(radioactivityTable[i].lat, radioactivityTable[i].lon, myLat, myLon)<15 && radioactivityTable[i].radioactivity > 10000)
        {
            cout << "Turn on RED LED" << endl;
            break;
        }
        else if(distance(radioactivityTable[i].lat, radioactivityTable[i].lon, myLat, myLon)<15 && radioactivityTable[i].radioactivity > 5000)
        {
            cout << "Turn on BLUE LED" << endl;
            break;
        }
        else if(distance(radioactivityTable[i].lat, radioactivityTable[i].lon, myLat, myLon)<15 && radioactivityTable[i].radioactivity > 2000)
        {
            cout << "Turn on GREEN LED" << endl;
            break;
        }
        else if(distance(radioactivityTable[i].lat, radioactivityTable[i].lon, myLat, myLon)<15 && radioactivityTable[i].radioactivity > 0)
        {
            cout << "Turn on YELLOW LED" << endl;
            break;
        }
        else
        {
            i++;
        }
    }

}

double distance(double lat1, double lon1, double lat2, double lon2) {
  double theta, dist;
  theta = lon1 - lon2;
  dist = sin(deg2rad(lat1)) * sin(deg2rad(lat2)) + cos(deg2rad(lat1)) * cos(deg2rad(lat2)) * cos(deg2rad(theta));
  dist = acos(dist);
  dist = rad2deg(dist);
  dist = dist * 60 * 1.1515;
  dist = dist * 1.609344 * 1000;

  return (dist);
}

double deg2rad(double deg) {
  return (deg * M_PI / 180);
}

double rad2deg(double rad) {
  return (rad * 180 / M_PI);
}

If your data is only around 500 records and can be represented as 2 floats and a long
value, that's 12 bytes per entry stored in internal format, about 6k of data. That could
be uploaded as a PROGMEM array of structs with the sketch.

However that can't be updated without reprogramming the Arduino.

Alternative storage could be an SDcard or microSD card, and using the SD library,
that requires a board with SD socket or a breakout board for an SDcard. Advantage
is that you have much more storage space and could simply copy the CSV file
to an SDcard. Code will be needed to parse the file though, and it would take more
time to iterate over the list than if it was in PROGMEM (that just means in the
chip's flash storage alongside the code).

Since your phone has far more processing power and storage than the arduino, consider doing all this work on the phone. Just send a message over bluetooth to the arduino to tell it what to do with the LEDs.

I have written some code in c++. It reads in the data from the above text file

Does it work on the Arduino?

wildbill:
Since your phone has far more processing power and storage than the arduino, consider doing all this work on the phone. Just send a message over bluetooth to the arduino to tell it what to do with the LEDs.

I have never made an android app before, how would I go about it?

PaulS:

I have written some code in c++. It reads in the data from the above text file

Does it work on the Arduino?

This is my first experience using arduino before. I know some c++ so I decided to write the program using that
as an indication of what I intended for the arduino. Would it not work?

Would it not work?

Does your Arduino have a place to store a file?

That code seems to be written for a machine that has unlimited amounts of memory. The Arduino does not.

Vectors that can dynamically grow? That's going to mangle memory something fierce.

PaulS:

Would it not work?

Does your Arduino have a place to store a file?

That code seems to be written for a machine that has unlimited amounts of memory. The Arduino does not.

Vectors that can dynamically grow? That's going to mangle memory something fierce.

I guess I could just get the size of the vector and make it a finite size. I will not be updating the database so I don't need a vector that dynamically grows.

See reply #1 for storing your data in program memory.

The Arduino performs only single precision floating point math (double is the same as float). If you use that to calculate the distance between waypoints, the accuracy is usually no better than +/- 100 meters.

so I don't need a vector that dynamically grows.

So, you only plan to read one record from the file?

Most arduinos have very little RAM and the space for your code (FLASH, progmem) is limited too. That kills your dynamic vector idea, but MarkT solved that for you in reply #1. However, as Jremington remarks, use of float doesn't give you the resolution you need.

One solution is to transform your data and work in different units - feet or meters perhaps depending on the size of the beach. Choose some arbitrary datum point and create your own "EsalaDE's" grid, doing the transform before you load it to the arduino's progmem. Then your coordinate data can simply be int. The arduino will need to be able to perform the same transformation on the incoming GPS data from the phone of course.

It's not necessary, but I'd also be tempted to change the radioactivity data to be byte - still overkill - you only need five different values to tell you which LED to turn on.