ref: 85447376e6315272dda68941ced6167d88a0a858
parent: f900d290324a70af335cfe62fec24af726851d35
author: sirjofri <sirjofri@sirjofri.de>
date: Sun Apr 6 12:05:26 EDT 2025
theoretically implements all geojson types. redraw map on geojson plumb
--- a/geojson.c
+++ b/geojson.c
@@ -10,10 +10,16 @@
static char *Tfeature = "Feature";
static char *Tfeatures = "features";
static char *Tgeometry = "geometry";
+static char *Tgeometries = "geometries";
static char *Tfeaturecollection = "FeatureCollection";
+
static char *Tpoint = "Point";
+static char *Tmultipoint = "MultiPoint";
static char *Tlinestring = "LineString";
+static char *Tmultilinestring = "MultiLineString";
static char *Tpolygon = "Polygon";
+static char *Tmultipolygon = "MultiPolygon";
+static char *Tgeocollection = "GeometryCollection";
static char *Enumber = "expected number";
static char *Earray = "expected array";
@@ -21,6 +27,46 @@
static char *Eobject = "expected object";
static char *Estring = "expected string";
+static int
+jisarray(JSON *j)
+{
+ if (!(j && j->t == JSONArray)) {
+ werrstr(Earray);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+jisnumber(JSON *j)
+{
+ if (!(j && j->t == JSONNumber)) {
+ werrstr(Earray);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+jisobject(JSON *j)
+{
+ if (!(j && j->t == JSONObject)) {
+ werrstr(Eobject);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+jisstring(JSON *j)
+{
+ if (!(j && j->t == JSONString)) {
+ werrstr(Estring);
+ return 0;
+ }
+ return 1;
+}
+
extern Image *mapimage;
extern int tilesize;
@@ -32,10 +78,8 @@
static int
jsonnum(JSON *j, double *n)
{
- if (!(j && j->t == JSONNumber)) {
- werrstr(Enumber);
+ if (!jisnumber(j))
return 0;
- }
*n = j->n;
return 1;
}
@@ -46,10 +90,8 @@
JSONEl *el;
assert(x && y);
- if (j->t != JSONArray) {
- werrstr(Earray);
+ if (!jisarray(j))
return 0;
- }
el = j->first;
if (el && el->val) {
@@ -94,10 +136,8 @@
{
JSONEl *el;
int n;
- if (!(j && j->t == JSONArray)) {
- werrstr(Earray);
+ if (!jisarray(j))
return 0;
- }
*np = 0;
for (el = j->first; el; el = el->next)
@@ -157,10 +197,8 @@
JSONEl *el;
int ret;
- if (!(j && j->t == JSONArray)) {
- werrstr(Earray);
+ if (!jisarray(j))
return 0;
- }
ret = 1;
for (el = j->first; el; el = el->next)
@@ -175,10 +213,8 @@
GBundle b;
Point off;
- if (!(j && j->t == JSONArray)) {
- werrstr(Earray);
+ if (!jisarray(j))
return 0;
- }
if (!jsoncoords(j, &p.lon, &p.lat))
return 0;
@@ -203,6 +239,20 @@
}
static int
+rendermpoint(JSON *j)
+{
+ JSONEl *el;
+ if (!jisarray(j))
+ return 0;
+
+ for (el = j->first; el; el = el->next) {
+ if (!renderpoint(el->val))
+ return 0;
+ }
+ return 1;
+}
+
+static int
renderlinestring(JSON *j)
{
JSONEl *el;
@@ -210,10 +260,8 @@
double x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
GPos f, t;
- if (!(j && j->t == JSONArray)) {
- werrstr(Earray);
+ if (!jisarray(j))
return 0;
- }
debugprint("LINESTRING\n");
for (el = j->first; el; el = el->next) {
@@ -239,6 +287,20 @@
}
static int
+rendermlinestring(JSON *j)
+{
+ JSONEl *el;
+ if (!jisarray(j))
+ return 0;
+
+ for (el = j->first; el; el = el->next) {
+ if (!renderlinestring(el->val))
+ return 0;
+ }
+ return 1;
+}
+
+static int
renderpolygon(JSON *j)
{
JSONEl *el;
@@ -246,10 +308,8 @@
Point *pts;
int np;
- if (!(j && j->t == JSONArray)) {
- werrstr(Earray);
+ if (!jisarray(j))
return 0;
- }
img = allocimage(display, mapimage->r, GREY1, 0, DBlack);
if (!img)
@@ -263,39 +323,34 @@
pts = nil;
}
draw(mapimage, img->r, cgreen, img, ZP);
+ freeimage(img);
return 1;
}
static int
-renderfeaturegeometry(JSON *j)
+rendermpolygon(JSON *j)
{
- char *s;
- JSON *type;
-
- if (!(j && j->t == JSONObject)) {
- werrstr(Eobject);
+ JSONEl *el;
+ if (!jisarray(j))
return 0;
+ for (el = j->first; el; el = el->next) {
+ if (!renderpolygon(el->val))
+ return 0;
}
-
- type = jsonbyname(j, Ttype);
- if (!(type && type->t == JSONString)) {
- werrstr(Estring);
+ return 1;
+}
+
+static int
+rendergeocollection(JSON *j)
+{
+ JSONEl *el;
+ if (!jisarray(j))
return 0;
+ for (el = j->first; el; el = el->next) {
+ if (!renderjsontype(el->val))
+ return 0;
}
-
- s = jsonstr(type);
- if (!s) {
- werrstr("empty type");
- return 0;
- }
- if (strcmp(s, Tpoint) == 0)
- return renderpoint(jsonbyname(j, Tcoords));
- if (strcmp(s, Tlinestring) == 0)
- return renderlinestring(jsonbyname(j, Tcoords));
- if (strcmp(s, Tpolygon) == 0)
- return renderpolygon(jsonbyname(j, Tcoords));
- werrstr("invalid type: %s", s);
- return 0;
+ return 1;
}
static int
@@ -305,10 +360,8 @@
char *s;
type = jsonbyname(j, Ttype);
- if (!(type && type->t == JSONString)) {
- werrstr(Estring);
+ if (!jisstring(type))
return 0;
- }
s = jsonstr(type);
if (!s) {
@@ -318,7 +371,22 @@
if (strcmp(s, Tfeaturecollection) == 0)
return renderfeaturecollection(jsonbyname(j, Tfeatures));
if (strcmp(s, Tfeature) == 0)
- return renderfeaturegeometry(jsonbyname(j, Tgeometry));
+ return renderjsontype(jsonbyname(j, Tgeometry));
+
+ if (strcmp(s, Tpoint) == 0)
+ return renderpoint(jsonbyname(j, Tcoords));
+ if (strcmp(s, Tmultipoint) == 0)
+ return rendermpoint(jsonbyname(j, Tcoords));
+ if (strcmp(s, Tlinestring) == 0)
+ return renderlinestring(jsonbyname(j, Tcoords));
+ if (strcmp(s, Tmultilinestring) == 0)
+ return rendermlinestring(jsonbyname(j, Tcoords));
+ if (strcmp(s, Tpolygon) == 0)
+ return renderpolygon(jsonbyname(j, Tcoords));
+ if (strcmp(s, Tmultipolygon) == 0)
+ return rendermpolygon(jsonbyname(j, Tcoords));
+ if (strcmp(s, Tgeocollection) == 0)
+ return rendergeocollection(jsonbyname(j, Tgeometries));
werrstr("invalid type: %s", s);
return 0;
}
--- a/map.c
+++ b/map.c
@@ -404,11 +404,10 @@
if (pm->ndata < 0)
goto Backout;
- if (!parsepos(pm->data, pm->ndata, &pos, &zoom))
+ if (!parsepos(pm->data, pm->ndata, &pos, &z))
goto Out;
gpsloc = pos;
- z = zoom;
if (z >= 0 && z <= maxzoom)
currentloc.z = zoom = z;
locupdated();
@@ -416,7 +415,9 @@
goto Backout;
Out:
- if (!handlegeojson(pm->data, pm->ndata))
+ if (handlegeojson(pm->data, pm->ndata))
+ handlecmd(Credraw);
+ else
debugprint("geojson: %r\n");
Backout:
--
⑨