ref: 955586843da9b416a0ffbf00ac4fe3956f5cb560
parent: 825b1760ac8f5ec7930dedcd47199095f2634134
author: sirjofri <sirjofri@sirjofri.de>
date: Sat Mar 29 11:21:51 EDT 2025
fixes gpsfs read, adds copyright, fixes rendering
--- a/gps.c
+++ b/gps.c
@@ -40,8 +40,8 @@
return ret;
}
- ret.lon = strtod(fields[3], &nop);
- ret.lat = strtod(fields[4], &nop);
+ ret.lon = 180 + strtod(fields[3], &nop);
+ ret.lat = 90 + strtod(fields[4], &nop);
debugprint("GPS: %f %f\n", ret.lon, ret.lat);
return ret;
}
--- a/map.c
+++ b/map.c
@@ -39,7 +39,7 @@
GBundle currentloc;
Point drawoffset;
int maxzoom = 8;
-int zoom = 5;
+int zoom = 2;
int tilesize = 256;
@@ -47,8 +47,11 @@
Image *mapimage;
QLock mapimagelock;
-char statusline[512];
+char *copyright;
+char statusline[1024];
+static void handlecmd(int cmd);
+
static char*
getstatusline(void)
{
@@ -58,10 +61,12 @@
ns = gpsloc.lat > 90 ? 'N' : 'S';
we = gpsloc.lon > 180 ? 'E' : 'W';
- snprint(statusline, sizeof statusline, "Loc: %f%c %f%c Z: %d",
+ snprint(statusline, sizeof statusline, "Loc: %f%c %f%c Z: %d %c %s",
fabs(gpsloc.lon - 180), we,
fabs(gpsloc.lat - 90), ns,
- currentloc.z);
+ currentloc.z,
+ copyright ? ':' : ' ',
+ copyright ? copyright : "");
return statusline;
}
@@ -72,6 +77,7 @@
{
int fd, n;
char buf[32];
+ Dir *dir;
fd = open("/mnt/map/ctl", OREAD);
if (fd < 0)
@@ -85,6 +91,18 @@
maxzoom = atoi(buf);
+ fd = open("/mnt/map/copyright", OREAD);
+ if (fd >= 0) {
+ dir = dirfstat(fd);
+ n = dir->length;
+ copyright = mallocz(n + 1, 1);
+ free(dir);
+ n = read(fd, copyright, n);
+ if (n < 0)
+ sysfatal("mapfs error: read copyright: %r");
+ close(fd);
+ }
+
zoomsquared = mallocz(sizeof(ulong) * (maxzoom+1), 1);
for (int i = 0; i <= maxzoom; i++) {
@@ -103,11 +121,6 @@
NWindow *mainwindow;
NImage *nimage;
-enum {
- Cnil,
- Credraw,
-};
-
void
lockmapimage(void)
{
@@ -125,10 +138,16 @@
GPos p;
double x, y;
+ /* TODO: fix: "zoom point" should be centered properly */
+
if (gpsloc.lat > 180)
gpsloc.lat = 180;
if (gpsloc.lat < 0)
gpsloc.lat = 0;
+ if (gpsloc.lon > 360)
+ gpsloc.lon -= 360;
+ if (gpsloc.lon < 0)
+ gpsloc.lon = 360 - gpsloc.lon;
x = mapimagesize.x / 2. / (double)tilesize;
y = mapimagesize.y / 2. / (double)tilesize;
@@ -139,6 +158,17 @@
return p;
}
+enum {
+ Cnil,
+ Credraw,
+};
+
+static void
+locupdated(void)
+{
+ currentloc = getbundle(gpsoff(), currentloc.z, &drawoffset);
+}
+
int debug;
int shouldredraw = 0;
@@ -236,7 +266,7 @@
currentloc.z = cz;
cz = currentloc.z == zoom ? Cnil : Credraw;
zoom = currentloc.z;
- currentloc = getbundle(gpsoff(), currentloc.z, &drawoffset);
+ locupdated();
return cz;
}
@@ -288,7 +318,7 @@
return Cnil;
Loc:
- currentloc = getbundle(gpsoff(), currentloc.z, &drawoffset);
+ locupdated();
return Credraw;
}
@@ -319,8 +349,8 @@
gpsloc = pos;
if (zoom >= 0)
currentloc.z = zoom;
- currentloc = getbundle(gpsoff(), currentloc.z, &drawoffset);
- redrawmap();
+ locupdated();
+ handlecmd(Credraw);
Out:
plumbfree(pm);
@@ -348,7 +378,6 @@
traperrout();
initmapfs();
- gpsloc = getlocation();
if (initdraw(nil, nil, "map") < 0)
sysfatal("%r");
@@ -402,8 +431,11 @@
);
initimage();
- currentloc = getbundle(gpsoff(), zoom, &drawoffset);
- redrawmap();
+ gpsloc = getlocation();
+ currentloc.z = zoom;
+ locupdated();
+ handlecmd(Credraw);
+ imageupdated();
for (;;) {
switch (event(&ev)) {
@@ -414,10 +446,7 @@
handleplumb(ev.v);
break;
case Emouse:
- if (ev.mouse.buttons & 4)
- exits(nil);
- else
- natemouseevent(ev.mouse);
+ natemouseevent(ev.mouse);
break;
case Ekeyboard:
cmd = handlekeyboard(ev.kbdc);
--- /dev/null
+++ b/parse.c
@@ -1,0 +1,92 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+static double
+s2d(char *s, char **r)
+{
+ char buf[32];
+ char *bptr;
+
+ bptr = buf;
+ while ((*s >= '0' && *s <= '9') || *s == '.') {
+ *bptr = *s;
+ bptr++;
+ s++;
+ }
+ *bptr = 0; /* paranoid */
+ *r = s;
+ return atof(buf);
+}
+
+static int
+parseinto(char c, double n, double *lon, double *lat)
+{
+ switch (c) {
+ default:
+ return 0;
+ case 'N': case 'n':
+ *lat = n + 90;
+ break;
+ case 'S': case 's':
+ *lat = 90 - n;
+ break;
+ case 'W': case 'w':
+ *lon = 180 - n;
+ break;
+ case 'E': case 'e':
+ *lon = 180 + n;
+ break;
+ }
+ return 1;
+}
+
+int
+parsepos(char *data, int ndata, GPos *pos, int *zoom)
+{
+ char *str, *s;
+ int ret;
+ double num;
+ double lon, lat;
+
+ ret = 0;
+ *zoom = -1;
+
+ str = mallocz(sizeof(char) * (ndata + 1), 1);
+ memcpy(str, data, ndata);
+
+ /* invalid numbers for validation */
+ lon = -1.;
+ lat = -1.;
+
+ /* stage 1: first number */
+ num = s2d(str, &s);
+ if (!parseinto(*s, num, &lon, &lat))
+ goto Out;
+ s++;
+
+ /* stage 2: second number */
+ num = s2d(s, &s);
+ if (!parseinto(*s, num, &lon, &lat))
+ goto Out;
+ s++;
+
+ /* stage 3: zoom level (optional) */
+ if (*s)
+ *zoom = atoi(s);
+
+ /* stage 4: validate */
+ if (lon < 0. || lon > 360.)
+ goto Out;
+ if (lat < 0. || lat > 180.)
+ goto Out;
+
+ pos->lon = lon;
+ pos->lat = lat;
+ ret = 1;
+
+Out:
+ free(str);
+ return ret;
+}
\ No newline at end of file