# Draw polygon on LCD from GPS latitude and longitude

I'm working on a personal project (a usefully tool based on ublox GPS and Arduino Mega that can measure distance between 2 points, compute area, speed, save data on SD card)

Now I want to add new feature and when I show the area(in m^2) on LCD, I want to show the polygon built by more coordinates.

I tried all I know, I searched for solutions but without success.

How can I "scale down" coordinates to make them fit in a x,y system with max size (320*480, LCD size) ? • It's called "division"...? Surely you did it at school? Apr 23, 2016 at 0:21
• @majenko : I did the dividion at school. But there is a problem, eg: Lat1 = 44.456798, Lng1 = 25.563478 Lat2 = 44.672323, Lng2 = 25.894578 Let say with this 2 points I want to draw a line on the LCD, I can draw it but on the display will be almost a single pixel, and If i want to scale it up, I will obtain every time a small one ... because there are changed only decimals ... Apr 23, 2016 at 6:41
• @ChrisStratton i did the math myself. The map function is amazing and I think I will convert actual code to on that use map function. Thanks for suggestion! Apr 23, 2016 at 7:47

Over a small area lat and long are just simple Y and X coordinates respectively.

Dynamic scaling of the points is a very simple matter. All you need to do is work out the range of each dimension - so subtract the lowest latitude from the highest, and the lowest longitude from the highest.

That gives the full X and Y dimension of your area. Then just divide those by the dimensions of your screen. That gives you a scaling factor for each direction.

For each point, subtract the lowest longitude and latitude, and divide by the scaling factor for each direction.

If you want to be more fancy and retain the aspect ratio then you just need to work out which of the two scaling factors will allow all the polygon to remain on the screen - that is, divide and offset all your points by one factor, then by the other, and pick the smallest factor where all the points are within the area of your screen.

• I'm trying now to do your method, I think is what I want ... Apr 23, 2016 at 6:49

I did the code for Arduino and it works really nice. I added an dynamic X offset to center it on the screen.

``````// lat = coordinatesForArea[i]
// lng = coordinatesForArea[i]
// cntr is the count of points

float newPoints;
float maxLat = 0;
float maxLng = 0;
float minLat = 180;
float minLng = 180;

for (int i = 0; i < cntr; i++) {
maxLat = max(maxLat, coordinatesForArea[i]);
maxLng = max(maxLng, coordinatesForArea[i]);
minLat = min(minLat, coordinatesForArea[i]);
minLng = min(minLng, coordinatesForArea[i]);
}

float ySize = maxLat - minLat;
float xSize = maxLng - minLng;

float scaleFactor = ySize / 300;

float maxY = 0;
float maxX = 0;

for (int i = 0; i < cntr; i++) {
newPoints[i] = (coordinatesForArea[i] - minLng) / scaleFactor;
newPoints[i] = (coordinatesForArea[i] - minLat) / scaleFactor;
maxX = max(maxX, newPoints[i]);
maxY = max(maxY, newPoints[i]);
}

float newScaleFactor = maxY > maxX ? maxY / 300 : maxX / 300;

float newMaxX = 0;

for (int i = 0; i < cntr; i++) {
newPoints[i] = newPoints[i] / newScaleFactor;
newPoints[i] = newPoints[i] / newScaleFactor;

newMaxX = max(newMaxX, newPoints[i]);
}

float newOffsetX = (320 - newMaxX) / 2;
float newOffsetY = 100;

for (int i = 0; i < cntr; i++) {
newPoints[i] = newPoints[i] + newOffsetY;
newPoints[i] = newPoints[i] + newOffsetX;
}

for (int i = 0; i < cntr-1; i++) {
myGLCD.drawLine(newPoints[i], newPoints[i], newPoints[i+1], newPoints[i+1]);
}

myGLCD.drawLine(newPoints, newPoints, newPoints[cntr-1], newPoints[cntr-1]);
``````

Thank you Majenko