Complete refactoring of location objectization (! ;-)

This commit is contained in:
Jan-Piet Mens
2015-08-29 18:49:54 +02:00
parent 2765063b7f
commit 9f04507f3f
4 changed files with 69 additions and 167 deletions
+1 -2
View File
@@ -66,7 +66,6 @@ void push_geojson(struct mg_connection *conn)
time_t s_lo, s_hi;
char *time_from = "2015-08-28", *time_to = NULL;
char *js;
output_type otype = GEOJSON;
char *username = "jpm", *device = "5s";
@@ -86,7 +85,7 @@ void push_geojson(struct mg_connection *conn)
if ((arr = json_find_member(json, "results")) != NULL) { // get array
json_foreach(f, arr) {
// fprintf(stderr, "%s\n", f->string_);
locations(f->string_, obj, locs, s_lo, s_hi, (otype == RAW) ? 1 : 0);
locations(f->string_, obj, locs, s_lo, s_hi, GEOJSON, 0);
}
}
json_delete(json);
+9 -23
View File
@@ -277,7 +277,9 @@ int main(int argc, char **argv)
/* If no from time specified but limit, set from to this month */
if (limit) {
time_from = strdup(yyyymm(now));
if (time_from == NULL) {
time_from = strdup(yyyymm(now));
}
}
if (make_times(time_from, &s_lo, time_to, &s_hi) != 1) {
@@ -338,7 +340,7 @@ int main(int argc, char **argv)
int n;
for (n = 0; n < argc; n++) {
locations(argv[n], obj, locs, s_lo, s_hi, (otype == RAW) ? 1 : 0);
locations(argv[n], obj, locs, s_lo, s_hi, otype, 0);
}
} else {
JsonNode *arr, *f;
@@ -348,29 +350,13 @@ int main(int argc, char **argv)
* process each and build the JSON `obj' with an array of locations.
*/
if (limit) {
/* get a list of .rec files from lister() without time limits,
* process them in reverse order */
if ((json = lister(username, device, s_lo, s_hi)) != NULL) {
if ((arr = json_find_member(json, "results")) != NULL) { // get array
json_foreach(f, arr) {
reverse_locations(f->string_, obj, locs, s_lo, s_hi, (otype == RAW) ? 1 : 0, limit);
}
if ((json = lister(username, device, s_lo, s_hi)) != NULL) {
if ((arr = json_find_member(json, "results")) != NULL) { // get array
json_foreach(f, arr) {
locations(f->string_, obj, locs, s_lo, s_hi, otype, limit);
}
json_delete(json);
}
} else {
if ((json = lister(username, device, s_lo, s_hi)) != NULL) {
if ((arr = json_find_member(json, "results")) != NULL) { // get array
json_foreach(f, arr) {
// fprintf(stderr, "%s\n", f->string_);
locations(f->string_, obj, locs, s_lo, s_hi, (otype == RAW) ? 1 : 0);
}
}
json_delete(json);
}
json_delete(json);
}
}
+58 -140
View File
@@ -399,6 +399,10 @@ JsonNode *lister(char *user, char *device, time_t s_lo, time_t s_hi)
struct jparam {
JsonNode *obj;
JsonNode *locs;
time_t s_lo;
time_t s_hi;
output_type otype;
int limit; /* if non-zero, we're searching backwards */
};
/*
@@ -457,22 +461,53 @@ static JsonNode *line_to_location(char *line)
* Invoked via tac() and cat(). Verify that line is indeed a location
* line from a .rec file. Then objectorize it and add to the locations
* JSON array and update the counter in our JSON object.
* Return 0 to tell caller to "ignore" the line, 1 to use it.
*/
static int candidate_line(char *line, void *param)
{
long counter = 0L;
JsonNode *j, *obj, *locs, *o;
JsonNode *j, *o;
struct jparam *jarg = (struct jparam*)param;
char *bp;
obj = jarg->obj;
locs = jarg->locs;
JsonNode *obj = jarg->obj;
JsonNode *locs = jarg->locs;
int limit = jarg->limit;
time_t s_lo = jarg->s_lo;
time_t s_hi = jarg->s_hi;
output_type otype = jarg->otype;
if (obj == NULL || obj->tag != JSON_OBJECT)
return (-1);
if (locs == NULL || locs->tag != JSON_ARRAY)
return (-1);
/* Do we have candidate lines? */
if (limit == 0) {
/* Reading forwards; account for time */
char *p;
struct tm tmline;
time_t secs;
if ((p = strptime(line, "%Y-%m-%dT%H:%M:%SZ", &tmline)) == NULL) {
fprintf(stderr, "no strptime on %s", line);
return (0);
}
secs = mktime(&tmline);
if (secs <= s_lo || secs >= s_hi) {
return (0);
}
if (otype == RAW) {
printf("%s\n", line);
return (0);
}
}
/* Do we have location line? */
if ((bp = strstr(line, "Z\t* ")) == NULL) { /* Not a location line */
return (0);
}
@@ -499,7 +534,14 @@ static int candidate_line(char *line, void *param)
return (1);
}
void reverse_locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi, int rawmode, int limit)
/*
* Read the file at `filename' (- is stdin) and store location
* objects at the JSON array `arr`. `obj' is a JSON object which
* contains `arr'.
* If limit is zero, we're going forward, else backwards.
*/
void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi, output_type otype, int limit)
{
int rc;
struct jparam jarg;
@@ -507,145 +549,21 @@ void reverse_locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo
if (obj == NULL || obj->tag != JSON_OBJECT)
return;
jarg.obj = obj;
jarg.locs = arr;
jarg.obj = obj;
jarg.locs = arr;
jarg.s_lo = s_lo;
jarg.s_hi = s_hi;
jarg.otype = otype;
jarg.limit = limit;
rc = tac(filename, limit, candidate_line, &jarg);
}
/*
* Read the file at `filename' (- is stdin) and store location
* objects at the JSON array `arr`. `obj' is a JSON object which
* contains `arr'.
*/
void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi, int rawmode)
{
JsonNode *o, *json, *j;
FILE *fp;
int doclose;
char buf[LINESIZE], **element;
long counter = 0L;
static char *numbers[] = { "lat", "lon", "batt", "vel", "cog", "tst", "alt", "dist", "trip", "p", NULL };
static char *strings[] = { "tid", "t", NULL };
static UT_string *tstamp = NULL;
if (obj == NULL || obj->tag != JSON_OBJECT)
return;
utstring_renew(tstamp);
if (!strcmp(filename, "-")) {
fp = stdin;
doclose = 0;
if (limit == 0) {
rc = cat(filename, candidate_line, &jarg);
} else {
if ((fp = fopen(filename, "r")) == NULL) {
fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno));
return;
}
doclose = 1;
rc = tac(filename, limit, candidate_line, &jarg);
}
/* Initialize our counter to what the JSON obj currently has */
if ((j = json_find_member(obj, "count")) != NULL) {
counter = j->number_;
json_delete(j);
}
while (fgets(buf, sizeof(buf)-1, fp) != NULL) {
char *bp, *ghash, *p;
double lat, lon;
struct tm tmline;
time_t secs, tst;
if ((p = strptime(buf, "%Y-%m-%dT%H:%M:%SZ", &tmline)) == NULL) {
fprintf(stderr, "no strptime on %s", buf);
continue;
}
utstring_clear(tstamp);
utstring_printf(tstamp, "%-20.20s", buf);
secs = mktime(&tmline);
if (secs <= s_lo || secs >= s_hi) {
continue;
}
if (rawmode) {
printf("%s", buf);
continue;
}
if ((bp = strstr(buf, "Z\t* ")) != NULL) {
if ((bp = strrchr(bp, '\t')) == NULL) {
continue;
}
++counter;
json = json_decode(bp + 1);
if (json == NULL) {
puts("Cannot decode JSON");
continue;
}
o = json_mkobject();
/* Start adding stuff to the object, then copy over the elements
* from the decoded original locations. */
for (element = numbers; element && *element; element++) {
if ((j = json_find_member(json, *element)) != NULL) {
if (j->tag == JSON_NUMBER) {
json_append_member(o, *element, json_mknumber(j->number_));
} else {
double d = atof(j->string_);
json_append_member(o, *element, json_mknumber(d));
}
}
}
for (element = strings; element && *element; element++) {
if ((j = json_find_member(json, *element)) != NULL) {
json_append_member(o, *element, json_mkstring(j->string_));
}
}
lat = lon = 0.0;
if ((j = json_find_member(o, "lat")) != NULL) {
lat = j->number_;
}
if ((j = json_find_member(o, "lon")) != NULL) {
lon = j->number_;
}
ghash = geohash_encode(lat, lon, GEOHASH_PREC);
json_append_member(o, "ghash", json_mkstring(ghash));
json_append_member(o, "isorcv", json_mkstring(utstring_body(tstamp)));
tst = 0L;
if ((j = json_find_member(o, "tst")) != NULL) {
tst = j->number_;
}
json_append_member(o, "isotst", json_mkstring(isotime(tst)));
get_geo(o, ghash);
json_append_element(arr, o);
}
}
/* Add the counter back into `obj' */
json_append_member(obj, "count", json_mknumber(counter));
if (doclose)
fclose(fp);
}
/*
* We're being passed an array of location objects created in
* locations(). Produce a Geo JSON tree.
+1 -2
View File
@@ -12,8 +12,7 @@ typedef enum {
} output_type;
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 rawmode);
void reverse_locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi, int rawmode, int limit);
void locations(char *filename, JsonNode *obj, JsonNode *arr, time_t s_lo, time_t s_hi, output_type otype, int limit);
int make_times(char *time_from, time_t *s_lo, char *time_to, time_t *s_to);
JsonNode *geo_json(JsonNode *json);
JsonNode *kill_datastore(char *username, char *device);