shithub: map

Download patch

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:
--