#include "geojson.h" #include "dijkstragraph.h" #include "logging.h" #include #include #include 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; }