mirror of
https://github.com/owntracks/recorder.git
synced 2026-08-27 16:57:21 +00:00
Add support for GeoJSON POI only
addresses https://github.com/owntracks/recorder/issues/439
This commit is contained in:
@@ -31,7 +31,7 @@ List users. If _user_ is specified, lists that user's devices. If both _user_ an
|
||||
|
||||
## `locations`
|
||||
|
||||
Here comes the actual data. This lists users' locations and requires both _user_ and _device_. Output format is JSON unless a different _format_ is given (`csv`, `json`, `geojson`, `xml`, and `linestring` are supported).
|
||||
Here comes the actual data. This lists users' locations and requires both _user_ and _device_. Output format is JSON unless a different _format_ is given (`csv`, `json`, `geojson`, `geojsonpoi`, `xml`, and `linestring` are supported).
|
||||
|
||||
In order to limit the number of records returned, use _limit_ which causes a reverse search through the `.rec` files; this can be used to find the last N positions.
|
||||
|
||||
|
||||
@@ -508,6 +508,7 @@ The Recorder's built-in WebSocket server updates a map as it receives publishes
|
||||
|
||||
* JSON
|
||||
* GeoJSON (points)
|
||||
* GeoJSON (points) for Points of Interest only
|
||||
* GeoJSON (line string)
|
||||
* CSV
|
||||
* GPX
|
||||
|
||||
@@ -1186,6 +1186,8 @@ static int dispatch(struct mg_connection *conn, const char *uri)
|
||||
if ((ret = mg_get_var(conn, "format", buf, sizeof(buf))) > 0) {
|
||||
if (!strcmp(buf, "geojson"))
|
||||
otype = GEOJSON;
|
||||
else if (!strcmp(buf, "geojsonpoi"))
|
||||
otype = GEOJSONPOI;
|
||||
else if (!strcmp(buf, "json"))
|
||||
otype = JSON;
|
||||
else if (!strcmp(buf, "linestring"))
|
||||
@@ -1290,7 +1292,17 @@ static int dispatch(struct mg_connection *conn, const char *uri)
|
||||
return (json_response(conn, geoline));
|
||||
|
||||
} else if (otype == GEOJSON) {
|
||||
JsonNode *geojson = geo_json(locs);
|
||||
JsonNode *geojson = geo_json(locs, false);
|
||||
|
||||
json_delete(obj);
|
||||
if (geojson != NULL) {
|
||||
return (json_response(conn, geojson));
|
||||
}
|
||||
json_delete(obj);
|
||||
return send_status(conn, 422, "geojson failed");
|
||||
|
||||
} else if (otype == GEOJSONPOI) { // POI only
|
||||
JsonNode *geojson = geo_json(locs, true);
|
||||
|
||||
json_delete(obj);
|
||||
if (geojson != NULL) {
|
||||
|
||||
@@ -63,6 +63,7 @@ void usage(char *prog)
|
||||
printf(" --format json -f output format (default: JSON)\n");
|
||||
printf(" csv (overrides $OCAT_FORMAT\n");
|
||||
printf(" geojson Geo-JSON points\n");
|
||||
printf(" geojsonpoi Geo-JSON points, POI only\n");
|
||||
printf(" linestring Geo-JSON LineString\n");
|
||||
printf(" gpx\n");
|
||||
printf(" xml\n");
|
||||
@@ -261,6 +262,8 @@ int main(int argc, char **argv)
|
||||
otype = JSON;
|
||||
else if (!strcmp(optarg, "geojson"))
|
||||
otype = GEOJSON;
|
||||
else if (!strcmp(optarg, "geojsonpoi"))
|
||||
otype = GEOJSONPOI;
|
||||
else if (!strcmp(optarg, "linestring"))
|
||||
otype = LINESTRING;
|
||||
else if (!strcmp(optarg, "raw"))
|
||||
@@ -498,7 +501,19 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
} else if (otype == GEOJSON) {
|
||||
JsonNode *geojson = geo_json(locs);
|
||||
JsonNode *geojson = geo_json(locs, false);
|
||||
char *js;
|
||||
|
||||
if (geojson != NULL) {
|
||||
js = json_stringify(geojson, JSON_INDENT);
|
||||
if (js != NULL) {
|
||||
printf("%s\n", js);
|
||||
free(js);
|
||||
}
|
||||
json_delete(geojson);
|
||||
}
|
||||
} else if (otype == GEOJSONPOI) { // POI only
|
||||
JsonNode *geojson = geo_json(locs, true);
|
||||
char *js;
|
||||
|
||||
if (geojson != NULL) {
|
||||
|
||||
@@ -919,7 +919,7 @@ void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t
|
||||
*
|
||||
*/
|
||||
|
||||
static void append_to_feature_array(JsonNode *features, double lat, double lon, char *tid, char *addr, long tst, long vel, long acc)
|
||||
static void append_to_feature_array(JsonNode *features, double lat, double lon, char *tid, char *addr, long tst, long vel, long acc, char *poi, char *isotst)
|
||||
{
|
||||
JsonNode *geom, *props, *f = json_mkobject();
|
||||
|
||||
@@ -933,11 +933,16 @@ static void append_to_feature_array(JsonNode *features, double lat, double lon,
|
||||
json_append_member(geom, "coordinates", coords);
|
||||
|
||||
props = json_mkobject();
|
||||
json_append_member(props, "name", json_mkstring(tid));
|
||||
if (poi && *poi) {
|
||||
json_append_member(props, "name", json_mkstring(poi));
|
||||
} else {
|
||||
json_append_member(props, "name", json_mkstring(tid));
|
||||
json_append_member(props, "vel", json_mknumber(vel));
|
||||
json_append_member(props, "tst", json_mknumber(tst));
|
||||
json_append_member(props, "acc", json_mknumber(acc));
|
||||
}
|
||||
json_append_member(props, "address", json_mkstring(addr));
|
||||
json_append_member(props, "vel", json_mknumber(vel));
|
||||
json_append_member(props, "tst", json_mknumber(tst));
|
||||
json_append_member(props, "acc", json_mknumber(acc));
|
||||
json_append_member(props, "isotst", json_mkstring(isotst));
|
||||
|
||||
json_append_member(f, "geometry", geom);
|
||||
json_append_member(f, "properties", props);
|
||||
@@ -945,7 +950,7 @@ static void append_to_feature_array(JsonNode *features, double lat, double lon,
|
||||
json_append_element(features, f);
|
||||
}
|
||||
|
||||
JsonNode *geo_json(JsonNode *location_array)
|
||||
JsonNode *geo_json(JsonNode *location_array, bool poi_only)
|
||||
{
|
||||
JsonNode *one, *j;
|
||||
JsonNode *feature_array, *fcollection;
|
||||
@@ -959,9 +964,15 @@ JsonNode *geo_json(JsonNode *location_array)
|
||||
|
||||
json_foreach(one, location_array) {
|
||||
double lat = 0.0, lon = 0.0;
|
||||
char *addr = "", *tid = "";
|
||||
char *addr = "", *tid = "", *poi = "", *isotst = "";
|
||||
long tst = 0, vel = 0, acc = 0;
|
||||
|
||||
if (poi_only) {
|
||||
if ((j = json_find_member(one, "poi")) == NULL) {
|
||||
continue;
|
||||
}
|
||||
poi = j->string_;
|
||||
}
|
||||
if ((j = json_find_member(one, "lat")) != NULL) {
|
||||
lat = j->number_;
|
||||
}
|
||||
@@ -974,6 +985,9 @@ JsonNode *geo_json(JsonNode *location_array)
|
||||
if ((j = json_find_member(one, "addr")) != NULL) {
|
||||
addr = j->string_;
|
||||
}
|
||||
if ((j = json_find_member(one, "isotst")) != NULL) {
|
||||
isotst = j->string_;
|
||||
}
|
||||
if ((j = json_find_member(one, "tst")) != NULL) {
|
||||
tst = j->number_;
|
||||
}
|
||||
@@ -984,7 +998,7 @@ JsonNode *geo_json(JsonNode *location_array)
|
||||
acc = j->number_;
|
||||
}
|
||||
|
||||
append_to_feature_array(feature_array, lat, lon, tid, addr, tst, vel, acc);
|
||||
append_to_feature_array(feature_array, lat, lon, tid, addr, tst, vel, acc, poi, isotst);
|
||||
}
|
||||
|
||||
json_append_member(fcollection, "features", feature_array);
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef enum {
|
||||
RAWPAYLOAD,
|
||||
LINESTRING,
|
||||
XML,
|
||||
GEOJSONPOI,
|
||||
} output_type;
|
||||
|
||||
/* JSON payload types */
|
||||
@@ -45,7 +46,7 @@ JsonNode *lister(char *username, char *device, time_t s_lo, time_t s_hi, int rev
|
||||
JsonNode *multilister(JsonNode *udpairs, time_t s_lo, time_t s_hi, int reverse);
|
||||
void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi, output_type otype, int limit, JsonNode *fields, char *username, char *device);
|
||||
int make_times(char *time_from, time_t *s_lo, char *time_to, time_t *s_to, int hours);
|
||||
JsonNode *geo_json(JsonNode *json);
|
||||
JsonNode *geo_json(JsonNode *json, bool poi_only);
|
||||
JsonNode *geo_linestring(JsonNode *location_array);
|
||||
JsonNode *kill_datastore(char *username, char *device);
|
||||
JsonNode *last_users(char *user, char *device, JsonNode *fields);
|
||||
|
||||
Reference in New Issue
Block a user