Skip to content

Repository files navigation

what3words C++ Public API wrapper

A synchronous C++17 client for the hosted what3words Public API.

This project calls the normal what3words cloud API over HTTPS. It is not the offline C++ Core SDK, does not contain what3words address data, and does not require an Enterprise Suite installation or ESLA.

Status: 1.0.0 stable release.

Supported API operations

Method Public API operation
convert_to_3wa / convert_to_3wa_geojson Coordinates to a what3words address
convert_to_coordinates / convert_to_coordinates_geojson what3words address to coordinates
autosuggest AutoSuggest
autosuggest_with_coordinates AutoSuggest with coordinates
grid_section / grid_section_geojson Grid section
available_languages Available languages

The wrapper also provides is_possible_3wa, find_possible_3wa, did_you_mean, and the API-backed Client::is_valid_3wa helpers.

The public interface is based on the current public OpenAPI specification. /autosuggest-selection is intentionally not included because it is absent from that specification.

Requirements

  • C++17 compiler:
    • MSVC 2019 or newer;
    • GCC 9 or newer;
    • Clang 10 or newer;
    • a currently supported Apple Clang.
  • CMake 3.20 or newer.
  • libcurl.
  • nlohmann/json.
  • Catch2 when building tests.

Missing dependencies are fetched automatically for normal source builds. A vcpkg.json manifest is also provided for controlled dependency installation. When CMake fetches libcurl on Linux, install the platform's TLS development package first (for example, libssl-dev on Debian or Ubuntu).

Build

Automatic dependency fetching

cmake -S . -B build -DW3W_BUILD_TESTS=ON -DW3W_BUILD_EXAMPLES=ON
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failure

On single-configuration generators, omit -C Release from the ctest command and set -DCMAKE_BUILD_TYPE=Release while configuring. Static libraries are built by default. Pass -DBUILD_SHARED_LIBS=ON to build a shared library instead. On Windows, keep the wrapper and libcurl DLLs on PATH or beside the consuming executable.

Windows with vcpkg

Use a vcpkg toolchain and enable the manifest's tests feature:

cmake -S . -B build `
  -A x64 `
  -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
  -DVCPKG_MANIFEST_FEATURES=tests `
  -DW3W_BUILD_TESTS=ON `
  -DW3W_BUILD_EXAMPLES=ON
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failure

Use from CMake

FetchContent

include(FetchContent)
FetchContent_Declare(
    what3words_api
    GIT_REPOSITORY https://github.com/what3words/w3w-cpp-wrapper.git
    GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(what3words_api)

target_compile_features(your-target PRIVATE cxx_std_17)
target_link_libraries(your-target PRIVATE what3words::api)

Examples and tests are disabled by default when the project is consumed as a subdirectory.

Installed package

The fully system-resolved recipe below disables dependency fetching, so both libcurl and nlohmann/json must be supplied as installed CMake dependencies:

cmake -S . -B build-install \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/your/prefix \
  -DW3W_FETCH_DEPENDENCIES=OFF \
  -DW3W_BUILD_TESTS=OFF \
  -DW3W_BUILD_EXAMPLES=OFF
cmake --build build-install
cmake --install build-install

Consume it with:

find_package(what3words-api 1.0 CONFIG REQUIRED)
target_compile_features(your-target PRIVATE cxx_std_17)
target_link_libraries(your-target PRIVATE what3words::api)

When using a custom installation prefix, configure the consuming application with -DCMAKE_PREFIX_PATH=/your/prefix (or set what3words-api_DIR to the directory containing what3words-api-config.cmake).

When libcurl has to be fetched for a standalone build, install rules are disabled because a fetched dependency cannot form a relocatable exported package. add_subdirectory and FetchContent still work normally.

API key

Create an API key through the what3words developer portal and expose it to the example applications through W3W_API_KEY.

PowerShell:

$env:W3W_API_KEY = "your-api-key"

Command Prompt:

set W3W_API_KEY=your-api-key

bash or zsh:

export W3W_API_KEY="your-api-key"

Do not put production API keys in source files, CMake files, command-line arguments, logs, or commits. The wrapper sends the key only in the X-Api-Key header and prevents callers from overriding that header.

Quick start

The placeholder below keeps the first example focused on the API. Replace it only for a local trial, and never commit or distribute a real API key.

#include <iomanip>
#include <iostream>

#include <what3words/api.hpp>

int main() {
    try {
        const what3words::Client client("Your API Key here");

        const auto address =
            client.convert_to_coordinates("filled.count.soap");
        std::cout << std::fixed << std::setprecision(6)
                  << address.coordinates.lat << ", "
                  << address.coordinates.lng << '\n';
        return 0;
    } catch (const what3words::ApiError& error) {
        std::cerr << error.code() << ": " << error.api_message() << '\n';
    } catch (const what3words::Error& error) {
        std::cerr << error.what() << '\n';
    }

    return 2;
}

Expected output:

51.520847, -0.195521

An environment-based, production-safe runnable version is in examples/quickstart.cpp.

AutoSuggest

const auto options =
    what3words::AutosuggestOptions{}
        .focus({51.4243877, -0.3474524})
        .clip_to_countries({"GB", "DE"})
        .number_of_results(3)
        .prefer_land(true);

const auto response = client.autosuggest("filled.count.so", options);
for (const auto& suggestion : response.suggestions) {
    std::cout << "///" << suggestion.words << '\n';
}

Supported options are:

  • focus coordinates;
  • number of focus results;
  • clipping to countries, a circle, a bounding box, or a closed polygon;
  • language and locale;
  • text and supported voice input types;
  • number of results;
  • prefer-land.

Voice input requires an explicit language. Polygons must contain 4–25 points and repeat the first point as the last point.

GeoJSON

The conversion and grid operations have separate type-safe GeoJSON methods:

const auto geojson =
    client.convert_to_coordinates_geojson("filled.count.soap");

const auto& point = std::get<what3words::GeoJsonPoint>(
    geojson.features.front().geometry.coordinates);

GeoJsonCoordinates supports Point, LineString, and MultiLineString-style coordinate nesting without exposing the JSON library in public headers.

AutoSuggest is JSON-only in this wrapper. Although the public OpenAPI parameter currently lists format=geojson, both live AutoSuggest endpoints return their normal JSON suggestions envelope when it is requested. The wrapper therefore does not expose misleading AutoSuggest GeoJSON methods.

Helpers

what3words::is_possible_3wa("///filled.count.soap"); // local, true
what3words::find_possible_3wa("Meet at filled.count.soap");
what3words::did_you_mean("filled count soap");
client.is_valid_3wa("filled.count.soap"); // makes an AutoSuggest API call

is_possible_3wa checks only the address form. It does not prove that an address exists. Client::is_valid_3wa consumes an API request and can throw transport, authentication, quota, or API errors.

Error handling

Error Meaning
InvalidArgumentError Locally invalid coordinates, options, configuration, or headers
TransportError DNS, connection, timeout, or TLS failure
ApiError Structured what3words API error with HTTP status, code, and message
HttpError Non-success HTTP response without a structured API error
ParseError Successful response did not match the expected contract

The default transport verifies TLS certificates, follows only HTTP(S) redirects, sets finite connect/request timeouts, and does not automatically retry requests.

Custom configuration and testing

ClientConfig supports:

  • custom API-compatible base URL;
  • connect and request timeouts;
  • application user-agent/wrapper identifier;
  • additional non-authentication headers;
  • an injectable Transport.

The default client is safe to call concurrently because configuration is immutable after construction and each request uses its own libcurl easy handle. A custom transport defines its own thread-safety guarantees.

Plans, quotas, and cloud access

Endpoint availability and quotas depend on the API plan associated with the key. A 402 QuotaExceeded response is surfaced as ApiError. See the API documentation and plans.

This wrapper always calls an HTTP API. It does not add offline or on-premise functionality.

Versioning

  • 0.x: public C++ interface may change between minor versions.
  • 1.x: semantic versioning with a stable supported public interface.
  • Wrapper releases will record the Public API/OpenAPI contract they were tested against.

Licence

MIT. See LICENSE.

About

A what3words Public API wrapper for C++

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages