lifo-dijkstraserv/src/geojson.c

173 lines
4.1 KiB
C

#include "geojson.h"
#include "dijkstragraph.h"
#include "logging.h"
#include <stdlib.h>
#include <glib-object.h>
#include <json-glib/json-glib.h>
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
char *filename,
char *type)
{
JsonParser *parser;
JsonNode *root;
JsonArray *arr;
JsonNode *node;
JsonReader *reader;
GError *error;
int i, j;
int i_max, j_max;
char *name = NULL;
char *access = NULL;
int x, y, z;
int x_last, y_last, z_last;
enum dijkstra_net_type net_type;
struct dijkstra_net_meta *net_meta;
struct _stats {
int nodes;
int paths;
} stats = {.nodes = 0, .paths = 0};
report(LL_INFO, "Loading GeoJson '%s' data from %s...", type, filename);
if (!strcmp("street", type))
net_type = STREET;
else if (!strcmp("trainline", type))
net_type = TRAINLINE;
else if (!strcmp("access", type))
net_type = ACCESS;
else {
report(LL_ERROR, "Type '%s' not supported.\n", type);
return EXIT_FAILURE;
}
parser = json_parser_new ();
error = NULL;
json_parser_load_from_file(parser, filename, &error);
if (error)
{
report(LL_ERROR, "Unable to parse `%s': %s\n", filename, error->message);
g_error_free(error);
g_object_unref(parser);
return EXIT_FAILURE;
}
root = json_parser_get_root(parser);
arr = json_node_get_array(root);
if (arr) {
i_max = json_array_get_length(arr);
net_meta = NULL;
for (i = 0; i < i_max; i++)
{
node = json_array_get_element(arr, i);
if (node) {
reader = json_reader_new(node);
json_reader_read_member(reader, "properties");
if (json_reader_get_error(reader)) {
g_object_unref(reader);
continue;
}
json_reader_read_member(reader, "name");
name = strdup(json_reader_get_string_value(reader));
json_reader_end_member(reader); // name
json_reader_end_member(reader); // properties
switch (net_type) {
case STREET:
if (!net_meta)
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, NULL, NULL);
break;
case ACCESS:
access = name;
name = strchr(name, ':');
if (name == NULL) {
report(LL_ERROR,
"Invalid name for accesss. '%s'",
access);
g_object_unref(reader);
continue;
}
*name = '\0';
do
name++;
while (*name == ' ' && *name != '\0');
G_GNUC_FALLTHROUGH;
case TRAINLINE:
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, name, access);
break;
}
json_reader_read_member(reader, "geometry");
json_reader_read_member(reader, "coordinates");
z_last = 0; // By default, let's assume height 0
if (json_reader_is_array(reader)) {
j_max = json_reader_count_elements(reader);
for (j = 0; j < j_max; j++) {
json_reader_read_element(reader, j);
if (json_reader_is_array(reader)) {
stats.nodes++;
json_reader_read_element(reader, 0);
x = json_reader_get_int_value(reader);
json_reader_end_element(reader);
json_reader_read_element(reader, 1);
y = json_reader_get_int_value(reader);
json_reader_end_element(reader);
if (json_reader_count_elements(reader) > 2) {
json_reader_read_element(reader, 2);
z = json_reader_get_int_value(reader);
json_reader_end_element(reader);
} else {
z = z_last;
}
if (j > 0) {
stats.paths++;
dijkstra_path_new_to_list(solver,
x_last, y_last,
x, y,
z, z_last,
name,
net_meta,
DIJKSTRA_WEIGHT_AUTO);
}
x_last = x;
y_last = y;
z_last = z;
} else {
report(LL_WARNING, "err 1\n");
}
json_reader_end_element(reader);
}
} else {
report(LL_WARNING, "err 0\n");
}
json_reader_end_member(reader); // coordinates
json_reader_end_member(reader); // geometry
g_object_unref(reader);
} else {
report(LL_ERROR, "Invalid geojson file.\n");
}
}
} else {
report(LL_ERROR, "Invalid geojson file.\n");
}
report(LL_INFO, "Imported %d nodes and %d paths from GeoJson.",
stats.nodes,
stats.paths);
g_object_unref (parser);
return EXIT_SUCCESS;
}