mirror of
https://github.com/owntracks/recorder.git
synced 2026-04-09 00:36:50 +00:00
Add support for CSV in ocat and GeoJSON in backend
This commit is contained in:
89
ocat.c
89
ocat.c
@@ -5,6 +5,48 @@
|
||||
#include <time.h>
|
||||
#include "json.h"
|
||||
#include "storage.h"
|
||||
#include "util.h"
|
||||
|
||||
void csv_output(JsonNode *json)
|
||||
{
|
||||
JsonNode *arr, *one, *j;
|
||||
time_t tst = 0L;
|
||||
double lat = 0.0, lon = 0.0;
|
||||
char *tid = "", *addr;
|
||||
|
||||
arr = json_find_member(json, "locations");
|
||||
json_foreach(one, arr) {
|
||||
tid = addr = "";
|
||||
lat = lon = 0.0;
|
||||
|
||||
if ((j = json_find_member(one, "tid")) != NULL) {
|
||||
tid = j->string_;
|
||||
}
|
||||
|
||||
if ((j = json_find_member(one, "addr")) != NULL) {
|
||||
addr = j->string_;
|
||||
}
|
||||
|
||||
if ((j = json_find_member(one, "tst")) != NULL) {
|
||||
tst = j->number_;
|
||||
}
|
||||
|
||||
if ((j = json_find_member(one, "lat")) != NULL) {
|
||||
lat = j->number_;
|
||||
}
|
||||
|
||||
if ((j = json_find_member(one, "lon")) != NULL) {
|
||||
lon = j->number_;
|
||||
}
|
||||
|
||||
printf("%s,%s,%lf,%lf,%s\n",
|
||||
isotime(tst),
|
||||
tid,
|
||||
lat,
|
||||
lon,
|
||||
addr);
|
||||
}
|
||||
}
|
||||
|
||||
void usage(char *prog)
|
||||
{
|
||||
@@ -20,6 +62,7 @@ void usage(char *prog)
|
||||
printf(" YYYY-MM-DDTHH\n");
|
||||
printf(" YYYY-MM-DD\n");
|
||||
printf(" YYYY-MM\n");
|
||||
printf(" --format json|csv -f output format (default: JSON)\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
@@ -32,6 +75,14 @@ int main(int argc, char **argv)
|
||||
char *username = NULL, *device = NULL, *time_from = NULL, *time_to = NULL;
|
||||
JsonNode *json, *obj, *locs;
|
||||
time_t now, s_lo, s_hi;
|
||||
typedef enum {
|
||||
PLAIN = 0,
|
||||
GEOJSON,
|
||||
CSV,
|
||||
JSON,
|
||||
} output_type;
|
||||
output_type otype = JSON;
|
||||
|
||||
|
||||
time(&now);
|
||||
|
||||
@@ -43,11 +94,12 @@ int main(int argc, char **argv)
|
||||
{ "device", required_argument, 0, 'd'},
|
||||
{ "from", required_argument, 0, 'F'},
|
||||
{ "to", required_argument, 0, 'T'},
|
||||
{ "format", required_argument, 0, 'f'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int optindex = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "hlu:d:F:T:", long_options, &optindex);
|
||||
c = getopt_long(argc, argv, "hlu:d:F:T:f:", long_options, &optindex);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
@@ -67,6 +119,18 @@ int main(int argc, char **argv)
|
||||
case 'T':
|
||||
time_to = strdup(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
if (!strcmp(optarg, "json"))
|
||||
otype = JSON;
|
||||
else if (!strcmp(optarg, "geojson"))
|
||||
otype = GEOJSON;
|
||||
else if (!strcmp(optarg, "csv"))
|
||||
otype = CSV;
|
||||
else {
|
||||
fprintf(stderr, "%s: unrecognized output format\n", progname);
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
/* getopt_long already printed message */
|
||||
@@ -151,7 +215,28 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
json_append_member(obj, "locations", locs);
|
||||
printf("%s\n", json_stringify(obj, " "));
|
||||
|
||||
|
||||
if (otype == JSON) {
|
||||
char *js = json_stringify(obj, " ");
|
||||
|
||||
if (js != NULL) {
|
||||
printf("%s\n", js);
|
||||
free(js);
|
||||
}
|
||||
|
||||
} else if (otype == CSV) {
|
||||
csv_output(obj);
|
||||
} else if (otype == GEOJSON) {
|
||||
JsonNode *geojson = geo_json(locs);
|
||||
char *js;
|
||||
|
||||
js = json_stringify(geojson, " ");
|
||||
if (js != NULL) {
|
||||
printf("%s\n", js);
|
||||
free(js);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
99
storage.c
99
storage.c
@@ -381,3 +381,102 @@ void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t
|
||||
fclose(fp);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* We're being passed an array of location objects created in
|
||||
* locations(). Produce a Geo JSON tree.
|
||||
*/
|
||||
/*
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [-80.83775386582222,35.24980190252168]
|
||||
},
|
||||
"properties": {
|
||||
"name": "DOUBLE OAKS CENTER",
|
||||
"address": "1326 WOODWARD AV"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [-80.83827000459532,35.25674709224663]
|
||||
},
|
||||
"properties": {
|
||||
"name": "DOUBLE OAKS NEIGHBORHOOD PARK",
|
||||
"address": "2605 DOUBLE OAKS RD"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
static void geo_f_array(JsonNode *features, double lat, double lon, char *tid, char *addr)
|
||||
{
|
||||
// JsonNode *features = json_mkarray();
|
||||
JsonNode *f;
|
||||
|
||||
JsonNode *geom, *props;
|
||||
f = json_mkobject();
|
||||
|
||||
json_append_member(f, "type", json_mkstring("Feature"));
|
||||
|
||||
geom = json_mkobject();
|
||||
json_append_member(geom, "type", json_mkstring("Point"));
|
||||
JsonNode *coords = json_mkarray();
|
||||
json_append_element(coords, json_mknumber(lon)); /* first LON! */
|
||||
json_append_element(coords, json_mknumber(lat));
|
||||
json_append_member(geom, "coordinates", coords);
|
||||
|
||||
|
||||
|
||||
props = json_mkobject();
|
||||
json_append_member(props, "name", json_mkstring(tid));
|
||||
json_append_member(props, "address", json_mkstring(addr));
|
||||
|
||||
|
||||
json_append_member(f, "geometry", geom);
|
||||
json_append_member(f, "properties", props);
|
||||
|
||||
json_append_element(features, f);
|
||||
}
|
||||
JsonNode *geo_json(JsonNode *location_array)
|
||||
{
|
||||
JsonNode *one, *j;
|
||||
JsonNode *feature_array, *fcollection;
|
||||
|
||||
fcollection = json_mkobject();
|
||||
json_append_member(fcollection, "type", json_mkstring("FeatureCollection"));
|
||||
|
||||
feature_array = json_mkarray();
|
||||
|
||||
json_foreach(one, location_array) {
|
||||
double lat = 0.0, lon = 0.0;
|
||||
char *addr = "", *tid = "";
|
||||
|
||||
if ((j = json_find_member(one, "lat")) != NULL) {
|
||||
lat = j->number_;
|
||||
}
|
||||
|
||||
if ((j = json_find_member(one, "lon")) != NULL) {
|
||||
lon = j->number_;
|
||||
}
|
||||
if ((j = json_find_member(one, "tid")) != NULL) {
|
||||
tid = j->string_;
|
||||
}
|
||||
if ((j = json_find_member(one, "addr")) != NULL) {
|
||||
addr = j->string_;
|
||||
}
|
||||
|
||||
geo_f_array(feature_array, lat, lon, tid, addr);
|
||||
}
|
||||
|
||||
json_append_member(fcollection, "features", feature_array);
|
||||
|
||||
return (fcollection);
|
||||
}
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
JsonNode *lister(char *username, char *device, time_t s_lo, time_t s_hi);
|
||||
void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi);
|
||||
int make_times(char *time_from, time_t *s_lo, char *time_to, time_t *s_to);
|
||||
JsonNode *geo_json(JsonNode *json);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user