From 728957c73ac5c3a9f1b4c54eb84b40151abe1592 Mon Sep 17 00:00:00 2001 From: Arnaud Delcasse Date: Mon, 30 Dec 2024 11:51:25 +0100 Subject: [PATCH] Initial commit --- .gitea/workflows/build.yml | 65 +++++++++ Dockerfile | 64 +++++++++ bindings/valhalla_go.cpp | 194 +++++++++++++++++++++++++ bindings/valhalla_go.h | 36 +++++ build-config.go | 40 ++++++ default-config.go | 285 +++++++++++++++++++++++++++++++++++++ go.mod | 11 ++ go.sum | 15 ++ valhalla.go | 258 +++++++++++++++++++++++++++++++++ 9 files changed, 968 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 Dockerfile create mode 100644 bindings/valhalla_go.cpp create mode 100644 bindings/valhalla_go.h create mode 100644 build-config.go create mode 100644 default-config.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 valhalla.go diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..71380f7 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,65 @@ +name: Build and Push Docker Image + +on: + push: + tags: + - "*" + branches: + - main + - dev + +jobs: + build_and_push: + runs-on: ubuntu-latest + + steps: + - name: Install Docker + run: | + apt-get update + apt-get install -y docker.io + + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set Kubernetes Context + uses: azure/k8s-set-context@v4 + with: + method: kubeconfig + kubeconfig: ${{secrets.buildx_kubeconfig}} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: kubernetes + driver-opts: | + namespace=gitea + + - name: Login to Docker Registry + uses: docker/login-action@v3 + with: + registry: git.coopgo.io + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker image + id: metadata + uses: docker/metadata-action@v3 + with: + images: git.coopgo.io/${{gitea.repository}} + tags: | + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + flavor: | + latest=auto + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: | + ${{ steps.metadata.outputs.tags }} + build-args: | + ACCESS_TOKEN_USR=${{gitea.actor}} + ACCESS_TOKEN_PWD=${{gitea.token}} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..da0db8a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,64 @@ +FROM ghcr.io/valhalla/valhalla:latest + +COPY ./bindings/valhalla_go.* . + +RUN cp -r /usr/local/include/valhalla/third_party/* /usr/local/include/ + +RUN export DEBIAN_FRONTEND=noninteractive && apt update && apt install --yes --quiet \ + autoconf \ + automake \ + ccache \ + clang \ + clang-tidy \ + coreutils \ + curl \ + cmake \ + g++ \ + gcc \ + git \ + jq \ + lcov \ + libboost-all-dev \ + libcurl4-openssl-dev \ + libczmq-dev \ + libgdal-dev \ + libgeos++-dev \ + libgeos-dev \ + libluajit-5.1-dev \ + liblz4-dev \ + libprotobuf-dev \ + libspatialite-dev \ + libsqlite3-dev \ + libsqlite3-mod-spatialite \ + libtool \ + libzmq3-dev \ + lld \ + locales \ + luajit \ + make \ + osmium-tool \ + parallel \ + pkgconf \ + protobuf-compiler \ + python3-all-dev \ + python3-shapely \ + python3-requests \ + python3-pip \ + spatialite-bin \ + unzip \ + zlib1g-dev + +RUN g++ \ + valhalla_go.cpp \ + -fPIC \ + -shared \ + -o libvalhalla-go.so \ + -Wl,-Bstatic \ + -lvalhalla \ + -Wl,-Bdynamic \ + -lprotobuf-lite \ + -lz \ + -lpthread + +RUN cp libvalhalla-go.so /usr/local/lib/ + diff --git a/bindings/valhalla_go.cpp b/bindings/valhalla_go.cpp new file mode 100644 index 0000000..3134797 --- /dev/null +++ b/bindings/valhalla_go.cpp @@ -0,0 +1,194 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "valhalla_go.h" + +const boost::property_tree::ptree configure(boost::property_tree::ptree pt, const std::string& config) { + try { + boost::optional logging_subtree = + pt.get_child_optional("mjolnir.logging"); + if (logging_subtree) { + auto logging_config = valhalla::midgard::ToMap>( + logging_subtree.get()); + valhalla::midgard::logging::Configure(logging_config); + } + } catch (...) { throw std::runtime_error("Failed to load config from: " + config); } + + return pt; +} + +char* copy_str(const char * string) { + char *cstr = (char *) malloc(strlen(string) + 1); + strcpy(cstr, string); + return cstr; +} + +void* actor_init_from_file(const char* config, char * is_error) { + try { + boost::property_tree::ptree pt; + // parse the config and configure logging + rapidjson::read_json(config, pt); + auto actor = new valhalla::tyr::actor_t(configure(pt, config), true); + *is_error = 0; + return (void*) actor; + } catch (std::exception& ex) { + *is_error = 1; + return (void*) copy_str(ex.what()); + } +} + +void* actor_init_from_config(const char* config, char * is_error) { + try { + boost::property_tree::ptree pt; + std::istringstream is(config); + // parse the config and configure logging + rapidjson::read_json(is, pt); + auto actor = new valhalla::tyr::actor_t(configure(pt, config), true); + *is_error = 0; + return (void*) actor; + } catch (std::exception& ex) { + *is_error = 1; + return (void*) copy_str(ex.what()); + } +} + + +const char * actor_centroid(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->centroid(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_expansion(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->expansion(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_height(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->height(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_isochrone(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->isochrone(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_locate(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->locate(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_matrix(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->matrix(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_optimized_route(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->optimized_route(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_route(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->route(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_status(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->status(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_trace_attributes(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->trace_attributes(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_trace_route(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->trace_route(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} + +const char * actor_transit_available(Actor actor, const char * req, char * is_error) { + try { + std::string resp = ((valhalla::tyr::actor_t*) actor)->transit_available(req); + *is_error = 0; + return copy_str(resp.c_str()); + } catch (std::exception& ex) { + *is_error = 1; + return copy_str(ex.what()); + } +} diff --git a/bindings/valhalla_go.h b/bindings/valhalla_go.h new file mode 100644 index 0000000..fdf9cbb --- /dev/null +++ b/bindings/valhalla_go.h @@ -0,0 +1,36 @@ +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* Actor; +Actor actor_init_from_file(const char*, char *); +Actor actor_init_from_config(const char*, char *); + +const char * actor_centroid(Actor, const char *, char *); + +const char * actor_expansion(Actor, const char *, char *); + +const char * actor_height(Actor, const char *, char *); + +const char * actor_isochrone(Actor, const char *, char *); + +const char * actor_locate(Actor, const char *, char *); + +const char * actor_matrix(Actor, const char *, char *); + +const char * actor_optimized_route(Actor, const char *, char *); + +const char * actor_route(Actor, const char *, char *); + +const char * actor_status(Actor, const char *, char *); + +const char * actor_trace_attributes(Actor, const char *, char *); + +const char * actor_trace_route(Actor, const char *, char *); + +const char * actor_transit_available(Actor, const char *, char *); + + +#ifdef __cplusplus +} +#endif diff --git a/build-config.go b/build-config.go new file mode 100644 index 0000000..c64a09f --- /dev/null +++ b/build-config.go @@ -0,0 +1,40 @@ +package valhalla + +import "encoding/json" + +type Config struct { + Json map[string]interface{} +} + +func DefaultConfig() *Config { + var config map[string]interface{} + err := json.Unmarshal([]byte(defaultConfigString), &config) + if err != nil { + panic(err) + } + return &Config{Json: config} +} + +func (config *Config) String() string { + marshal, err := json.Marshal(config.Json) + if err != nil { + return err.Error() + } + return string(marshal) +} + +func (config *Config) SetTileDirPath(path string) { + mjolnir := config.Json["mjolnir"].(map[string]interface{}) + mjolnir["tile_dir"] = path +} + +func (config *Config) SetTileExtractPath(path string) { + mjolnir := config.Json["mjolnir"].(map[string]interface{}) + mjolnir["tile_extract"] = path +} + +func (config *Config) SetLoggingVerbosity(verbose bool) { + mjolnir := config.Json["mjolnir"].(map[string]interface{}) + logging := mjolnir["logging"].(map[string]interface{}) + logging["type"] = verbose +} diff --git a/default-config.go b/default-config.go new file mode 100644 index 0000000..dc36b78 --- /dev/null +++ b/default-config.go @@ -0,0 +1,285 @@ +package valhalla + +const defaultConfigString string = ` +{ + "additional_data": { + "elevation": "/data/valhalla/elevation/" + }, + "httpd": { + "service": { + "drain_seconds": 28, + "interrupt": "ipc:///tmp/interrupt", + "listen": "tcp://*:8002", + "loopback": "ipc:///tmp/loopback", + "shutdown_seconds": 1 + } + }, + "loki": { + "actions": [ + "locate", + "route", + "height", + "sources_to_targets", + "optimized_route", + "isochrone", + "trace_route", + "trace_attributes", + "transit_available", + "expansion", + "centroid", + "status" + ], + "logging": { + "color": true, + "file_name": "path_to_some_file.log", + "long_request": 100.0, + "type": "std_out" + }, + "service": { + "proxy": "ipc:///tmp/loki" + }, + "service_defaults": { + "heading_tolerance": 60, + "minimum_reachability": 50, + "node_snap_tolerance": 5, + "radius": 0, + "search_cutoff": 35000, + "street_side_max_distance": 1000, + "street_side_tolerance": 5 + }, + "use_connectivity": true + }, + "meili": { + "auto": { + "search_radius": 50, + "turn_penalty_factor": 200 + }, + "bicycle": { + "turn_penalty_factor": 140 + }, + "customizable": [ + "mode", + "search_radius", + "turn_penalty_factor", + "gps_accuracy", + "interpolation_distance", + "sigma_z", + "beta", + "max_route_distance_factor", + "max_route_time_factor" + ], + "default": { + "beta": 3, + "breakage_distance": 2000, + "geometry": false, + "gps_accuracy": 5.0, + "interpolation_distance": 10, + "max_route_distance_factor": 5, + "max_route_time_factor": 5, + "max_search_radius": 100, + "route": true, + "search_radius": 50, + "sigma_z": 4.07, + "turn_penalty_factor": 0 + }, + "grid": { + "cache_size": 100240, + "size": 500 + }, + "logging": { + "color": true, + "file_name": "path_to_some_file.log", + "type": "std_out" + }, + "mode": "auto", + "multimodal": { + "turn_penalty_factor": 70 + }, + "pedestrian": { + "search_radius": 50, + "turn_penalty_factor": 100 + }, + "service": { + "proxy": "ipc:///tmp/meili" + }, + "verbose": false + }, + "mjolnir": { + "admin": "/data/valhalla/admin.sqlite", + "data_processing": { + "allow_alt_name": false, + "apply_country_overrides": true, + "infer_internal_intersections": true, + "infer_turn_channels": true, + "scan_tar": false, + "use_admin_db": true, + "use_direction_on_ways": false, + "use_rest_area": false, + "use_urban_tag": false + }, + "global_synchronized_cache": false, + "hierarchy": true, + "id_table_size": 1300000000, + "import_bike_share_stations": false, + "include_bicycle": true, + "include_construction": false, + "include_driveways": true, + "include_driving": true, + "include_pedestrian": true, + "logging": { + "color": true, + "file_name": "path_to_some_file.log", + "type": "std_out" + }, + "lru_mem_cache_hard_control": false, + "max_cache_size": 1000000000, + "max_concurrent_reader_users": 1, + "reclassify_links": true, + "shortcuts": true, + "tile_dir": "/data/valhalla", + "tile_extract": "/data/valhalla/tiles.tar", + "timezone": "/data/valhalla/tz_world.sqlite", + "traffic_extract": "/data/valhalla/traffic.tar", + "transit_dir": "/data/valhalla/transit", + "transit_feeds_dir": "/data/valhalla/transit_feeds", + "use_lru_mem_cache": false, + "use_simple_mem_cache": false + }, + "odin": { + "logging": { + "color": true, + "file_name": "path_to_some_file.log", + "type": "std_out" + }, + "markup_formatter": { + "markup_enabled": false, + "phoneme_format": " (phoneme>//)" + }, + "service": { + "proxy": "ipc:///tmp/odin" + } + }, + "service_limits": { + "auto": { + "max_distance": 5000000.0, + "max_locations": 20, + "max_matrix_distance": 400000.0, + "max_matrix_location_pairs": 2500 + }, + "bicycle": { + "max_distance": 500000.0, + "max_locations": 50, + "max_matrix_distance": 200000.0, + "max_matrix_location_pairs": 2500 + }, + "bikeshare": { + "max_distance": 500000.0, + "max_locations": 50, + "max_matrix_distance": 200000.0, + "max_matrix_location_pairs": 2500 + }, + "bus": { + "max_distance": 5000000.0, + "max_locations": 50, + "max_matrix_distance": 400000.0, + "max_matrix_location_pairs": 2500 + }, + "centroid": { + "max_distance": 200000.0, + "max_locations": 5 + }, + "isochrone": { + "max_contours": 4, + "max_distance": 25000.0, + "max_distance_contour": 200, + "max_locations": 1, + "max_time_contour": 120 + }, + "max_alternates": 2, + "max_exclude_locations": 50, + "max_exclude_polygons_length": 10000, + "max_radius": 200, + "max_reachability": 100, + "max_timedep_distance": 500000, + "max_timedep_distance_matrix": 0, + "motor_scooter": { + "max_distance": 500000.0, + "max_locations": 50, + "max_matrix_distance": 200000.0, + "max_matrix_location_pairs": 2500 + }, + "motorcycle": { + "max_distance": 500000.0, + "max_locations": 50, + "max_matrix_distance": 200000.0, + "max_matrix_location_pairs": 2500 + }, + "multimodal": { + "max_distance": 500000.0, + "max_locations": 50, + "max_matrix_distance": 0.0, + "max_matrix_location_pairs": 0 + }, + "pedestrian": { + "max_distance": 250000.0, + "max_locations": 50, + "max_matrix_distance": 200000.0, + "max_matrix_location_pairs": 2500, + "max_transit_walking_distance": 10000, + "min_transit_walking_distance": 1 + }, + "skadi": { + "max_shape": 750000, + "min_resample": 10.0 + }, + "status": { + "allow_verbose": false + }, + "taxi": { + "max_distance": 5000000.0, + "max_locations": 20, + "max_matrix_distance": 400000.0, + "max_matrix_location_pairs": 2500 + }, + "trace": { + "max_alternates": 3, + "max_alternates_shape": 100, + "max_distance": 200000.0, + "max_gps_accuracy": 100.0, + "max_search_radius": 100.0, + "max_shape": 16000 + }, + "transit": { + "max_distance": 500000.0, + "max_locations": 50, + "max_matrix_distance": 200000.0, + "max_matrix_location_pairs": 2500 + }, + "truck": { + "max_distance": 5000000.0, + "max_locations": 20, + "max_matrix_distance": 400000.0, + "max_matrix_location_pairs": 2500 + } + }, + "statsd": { + "port": 8125, + "prefix": "valhalla" + }, + "thor": { + "clear_reserved_memory": false, + "extended_search": false, + "logging": { + "color": true, + "file_name": "path_to_some_file.log", + "long_request": 110.0, + "type": "std_out" + }, + "max_reserved_labels_count": 1000000, + "service": { + "proxy": "ipc:///tmp/thor" + }, + "source_to_target_algorithm": "select_optimal" + } +} +` diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..eabdc7e --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module git.coopgo.io/coopgo-platform/libvalhalla-go + +go 1.23.3 + +require github.com/rs/zerolog v1.33.0 + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + golang.org/x/sys v0.12.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..98afda4 --- /dev/null +++ b/go.sum @@ -0,0 +1,15 @@ +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/valhalla.go b/valhalla.go new file mode 100644 index 0000000..1db7754 --- /dev/null +++ b/valhalla.go @@ -0,0 +1,258 @@ +package valhalla + +// #cgo LDFLAGS: -L/usr/local/lib/ -lvalhalla-go +// #include +// #include +// #include "./bindings/valhalla_go.h" +import "C" + +import ( + "errors" + "unsafe" + + "github.com/rs/zerolog/log" +) + +type Actor struct { + ptr unsafe.Pointer +} + +func NewActorFromFile(configPath string) (*Actor, error) { + var isError uint8 = 0 + cs := C.CString(configPath) + resp := C.actor_init_from_file(cs, (*C.char)(unsafe.Pointer(&isError))) + C.free(unsafe.Pointer(cs)) + switch isError { + case 0: + return &Actor{ptr: unsafe.Pointer(resp)}, nil + case 1: + err := C.GoString((*C.char)(resp)) + C.free(unsafe.Pointer(resp)) + return nil, errors.New(err) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return nil, errors.New("Invalid error code from valhalla C binding") + } +} + +func NewActorFromConfig(config *Config) (*Actor, error) { + var isError uint8 = 0 + cs := C.CString(config.String()) + resp := C.actor_init_from_config(cs, (*C.char)(unsafe.Pointer(&isError))) + C.free(unsafe.Pointer(cs)) + switch isError { + case 0: + return &Actor{ptr: unsafe.Pointer(resp)}, nil + case 1: + err := C.GoString((*C.char)(resp)) + C.free(unsafe.Pointer(resp)) + return nil, errors.New(err) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return nil, errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Centroid(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_centroid((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Expansion(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_expansion((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Height(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_height((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Isochrone(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_isochrone((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Locate(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_locate((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Matrix(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_matrix((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) OptimizedRoute(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_optimized_route((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Route(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_route((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) Status(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_status((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) TraceAttributes(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_trace_attributes((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) TraceRoute(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_trace_route((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +} + +func (actor *Actor) TransitAvailable(request string) (string, error) { + var isError uint8 = 0 + cs := C.CString(request) + cresp := C.actor_transit_available((C.Actor)(actor.ptr), cs, (*C.char)(unsafe.Pointer(&isError))) + resp := C.GoString(cresp) + C.free(unsafe.Pointer(cresp)) + switch isError { + case 0: + return resp, nil + case 1: + return "", errors.New(resp) + default: + log.Panic().Msg("Invalid error code from valhalla C binding") + return "", errors.New("Invalid error code from valhalla C binding") + } +}