2020-05-02 16:27:44 +02:00
|
|
|
#include "geojson.h"
|
2020-05-02 17:02:26 +02:00
|
|
|
#include "dijkstragraph.h"
|
2020-05-02 16:27:44 +02:00
|
|
|
#include "logging.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <glib-object.h>
|
|
|
|
#include <json-glib/json-glib.h>
|
|
|
|
|
2020-05-02 16:51:12 +02:00
|
|
|
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
2021-02-26 19:15:48 +01:00
|
|
|
char *filename,
|
|
|
|
char *type)
|
2020-05-02 16:27:44 +02:00
|
|
|
{
|
|
|
|
JsonParser *parser;
|
|
|
|
JsonNode *root;
|
|
|
|
JsonArray *arr;
|
|
|
|
JsonNode *node;
|
|
|
|
JsonReader *reader;
|
|
|
|
GError *error;
|
|
|
|
|
|
|
|
int i, j;
|
|
|
|
int i_max, j_max;
|
|
|
|
|
|
|
|
char *name = NULL;
|
2021-02-26 19:15:48 +01:00
|
|
|
char *access = NULL;
|
2021-02-04 20:43:32 +01:00
|
|
|
int x, y, z;
|
|
|
|
int x_last, y_last, z_last;
|
2020-05-02 16:27:44 +02:00
|
|
|
|
2021-02-26 19:15:48 +01:00
|
|
|
enum dijkstra_net_type net_type;
|
|
|
|
struct dijkstra_net_meta *net_meta;
|
|
|
|
|
2020-05-02 16:27:44 +02:00
|
|
|
struct _stats {
|
|
|
|
int nodes;
|
|
|
|
int paths;
|
|
|
|
} stats = {.nodes = 0, .paths = 0};
|
|
|
|
|
2021-02-26 19:15:48 +01:00
|
|
|
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;
|
|
|
|
}
|
2020-05-02 16:27:44 +02:00
|
|
|
|
|
|
|
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);
|
2021-06-20 14:48:38 +02:00
|
|
|
net_meta = NULL;
|
2020-05-02 16:27:44 +02:00
|
|
|
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
|
|
|
|
|
2021-06-20 14:48:38 +02:00
|
|
|
switch (net_type) {
|
|
|
|
case STREET:
|
|
|
|
if (!net_meta)
|
|
|
|
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, NULL, NULL);
|
|
|
|
break;
|
|
|
|
case ACCESS:
|
2021-02-26 19:15:48 +01:00
|
|
|
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');
|
2021-06-20 14:48:38 +02:00
|
|
|
G_GNUC_FALLTHROUGH;
|
|
|
|
case TRAINLINE:
|
|
|
|
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, name, access);
|
|
|
|
break;
|
2021-02-26 19:15:48 +01:00
|
|
|
}
|
|
|
|
|
2020-05-02 16:27:44 +02:00
|
|
|
json_reader_read_member(reader, "geometry");
|
|
|
|
json_reader_read_member(reader, "coordinates");
|
2021-03-13 13:02:19 +01:00
|
|
|
z_last = 0; // By default, let's assume height 0
|
2020-05-02 16:27:44 +02:00
|
|
|
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);
|
2021-02-04 20:43:32 +01:00
|
|
|
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;
|
|
|
|
}
|
2020-05-02 16:27:44 +02:00
|
|
|
|
|
|
|
if (j > 0) {
|
|
|
|
stats.paths++;
|
2020-05-02 16:51:12 +02:00
|
|
|
dijkstra_path_new_to_list(solver,
|
2020-05-02 16:27:44 +02:00
|
|
|
x_last, y_last,
|
|
|
|
x, y,
|
2021-02-04 20:43:32 +01:00
|
|
|
z, z_last,
|
2020-05-02 17:13:27 +02:00
|
|
|
name,
|
2021-02-26 19:15:48 +01:00
|
|
|
net_meta,
|
2020-05-02 17:13:27 +02:00
|
|
|
DIJKSTRA_WEIGHT_AUTO);
|
2020-05-02 16:27:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
x_last = x;
|
|
|
|
y_last = y;
|
2021-02-04 20:43:32 +01:00
|
|
|
z_last = z;
|
2020-05-02 16:27:44 +02:00
|
|
|
} 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;
|
|
|
|
}
|