Skip to main content

Overview

The Open Mobile Maps SDK supports multiple coordinate systems and provides seamless conversion between them. Understanding coordinate systems is essential for working with different data sources, rendering, and spatial calculations.

Coordinate Systems

The SDK supports several standard coordinate systems through CoordinateSystemIdentifiers:
RENDERSYSTEM
int32_t
Internal rendering coordinate system used by the map engine
EPSG3857
int32_t
WGS 84 / Pseudo-Mercator (Web Mercator) - Most common for web mapshttps://epsg.io/3857
EPSG4326
int32_t
WGS 84 - Standard GPS coordinates (latitude/longitude)https://epsg.io/4326
EPSG2056
int32_t
LV03+ - Swiss coordinate systemhttps://epsg.io/2056
EPSG21781
int32_t
CH1903 / LV03 - Legacy Swiss coordinate systemhttps://epsg.io/21781
UnitSphere
int32_t
Unit Sphere Polar coordinates (phi, theta, radius) with Earth as a unit sphere

Coord Structure

All coordinates are represented using the Coord struct:
struct Coord {
    int32_t systemIdentifier;  // Which coordinate system
    double x;                  // Longitude, easting, or phi
    double y;                  // Latitude, northing, or theta
    double z;                  // Elevation or radius
    
    Coord(int32_t system, double x, double y, double z)
        : systemIdentifier(system), x(x), y(y), z(z) {}
};

Common Coordinate Examples

// WGS84 (GPS coordinates) - New York City
Coord nyc_wgs84(
    CoordinateSystemIdentifiers::EPSG4326(),
    -74.006,  // longitude
    40.7128,  // latitude
    0.0       // elevation
);

// Web Mercator - Same location
Coord nyc_mercator(
    CoordinateSystemIdentifiers::EPSG3857(),
    -8238310.0,   // x in meters
    4970241.0,    // y in meters
    0.0
);

// Swiss LV03+ - Zurich
Coord zurich(
    CoordinateSystemIdentifiers::EPSG2056(),
    2683141.0,  // easting
    1247952.0,  // northing
    408.0       // elevation
);

CoordinateConversionHelperInterface

The main interface for coordinate conversion:
class CoordinateConversionHelperInterface {
public:
    // Create independent instance (not tied to map)
    static std::shared_ptr<CoordinateConversionHelperInterface> independentInstance();
    
    // Register custom coordinate converter
    virtual void registerConverter(
        const std::shared_ptr<CoordinateConverterInterface>& converter
    ) = 0;
    
    // Convert single coordinate
    virtual Coord convert(int32_t to, const Coord& coordinate) = 0;
    
    // Convert bounding box
    virtual RectCoord convertRect(int32_t to, const RectCoord& rect) = 0;
    
    // Convert to render system
    virtual Coord convertToRenderSystem(const Coord& coordinate) = 0;
    virtual RectCoord convertRectToRenderSystem(const RectCoord& rect) = 0;
    
    // Convert quadrilateral
    virtual QuadCoord convertQuad(int32_t to, const QuadCoord& quad) = 0;
    virtual QuadCoord convertQuadToRenderSystem(const QuadCoord& quad) = 0;
};

Basic Coordinate Conversion

Converting Between Systems

// Create conversion helper
auto converter = CoordinateConversionHelperInterface::independentInstance();

// Convert WGS84 to Web Mercator
Coord wgs84(-74.006, 40.7128, 0.0, CoordinateSystemIdentifiers::EPSG4326());
Coord mercator = converter->convert(
    CoordinateSystemIdentifiers::EPSG3857(),
    wgs84
);

// Convert back to WGS84
Coord backToWgs84 = converter->convert(
    CoordinateSystemIdentifiers::EPSG4326(),
    mercator
);

Converting to Render System

The render system is the internal coordinate space used by the map:
// Get conversion helper from map
auto mapConverter = mapInterface->getCoordinateConverterHelper();

// Convert to render coordinates
Coord worldCoord(CoordinateSystemIdentifiers::EPSG4326(), -74.006, 40.7128, 0.0);
Coord renderCoord = mapConverter->convertToRenderSystem(worldCoord);

// Use render coordinates for low-level rendering
The render system is map-specific and optimized for the map’s projection. Always use the map’s converter when converting to render coordinates.

Converting Rectangles

RectCoord Structure

struct RectCoord {
    Coord bottomLeft;   // Southwest corner
    Coord topRight;     // Northeast corner
};

Rectangle Conversion

// Define bounding box in WGS84
RectCoord bbox_wgs84(
    Coord(CoordinateSystemIdentifiers::EPSG4326(), -74.05, 40.68, 0.0),  // SW
    Coord(CoordinateSystemIdentifiers::EPSG4326(), -73.90, 40.85, 0.0)   // NE
);

// Convert to Web Mercator
RectCoord bbox_mercator = converter->convertRect(
    CoordinateSystemIdentifiers::EPSG3857(),
    bbox_wgs84
);

// Convert to render system
RectCoord renderBounds = mapConverter->convertRectToRenderSystem(bbox_wgs84);

Converting Quadrilaterals

QuadCoord Structure

struct QuadCoord {
    Coord topLeft;
    Coord topRight;
    Coord bottomRight;
    Coord bottomLeft;
};

Quad Conversion

QuadCoord quad_wgs84(
    Coord(CoordinateSystemIdentifiers::EPSG4326(), -74.0, 40.8, 0.0),   // TL
    Coord(CoordinateSystemIdentifiers::EPSG4326(), -73.9, 40.8, 0.0),   // TR
    Coord(CoordinateSystemIdentifiers::EPSG4326(), -73.9, 40.7, 0.0),   // BR
    Coord(CoordinateSystemIdentifiers::EPSG4326(), -74.0, 40.7, 0.0)    // BL
);

QuadCoord quad_mercator = converter->convertQuad(
    CoordinateSystemIdentifiers::EPSG3857(),
    quad_wgs84
);

Custom Coordinate Systems

From CRS Identifier

Parse coordinate system from URN identifier:
// Parse EPSG identifier
std::string crsUrn = "urn:ogc:def:crs:EPSG::4326";
int32_t systemId = CoordinateSystemIdentifiers::fromCrsIdentifier(crsUrn);

Coord coord(systemId, -74.006, 40.7128, 0.0);

Registering Custom Converters

Implement CoordinateConverterInterface for custom projections:
class CustomConverter : public CoordinateConverterInterface {
public:
    int32_t getFrom() override {
        return MY_CUSTOM_SYSTEM_ID;
    }
    
    int32_t getTo() override {
        return CoordinateSystemIdentifiers::EPSG3857();
    }
    
    Coord convert(const Coord& coordinate) override {
        // Implement conversion logic
        double newX = transformX(coordinate.x, coordinate.y);
        double newY = transformY(coordinate.x, coordinate.y);
        return Coord(getTo(), newX, newY, coordinate.z);
    }
};

// Register converter
auto customConverter = std::make_shared<CustomConverter>();
converter->registerConverter(customConverter);

Utility Functions

Unit Conversion

Get conversion factor from coordinate units to meters:
// Get meters per unit for a coordinate system
double factor = CoordinateSystemIdentifiers::unitToMeterFactor(
    CoordinateSystemIdentifiers::EPSG3857()
);

// Use for distance calculations
double distanceInUnits = 1000.0;
double distanceInMeters = distanceInUnits * factor;

Coordinate System Factory

Create coordinate system instances:
#include "CoordinateSystemFactory.h"

// Create coordinate system
auto coordSystem = CoordinateSystemFactory::createEpsg3857();
auto wgs84System = CoordinateSystemFactory::createEpsg4326();

Working with Map Coordinates

Getting Map’s Coordinate System

auto mapCoordSystem = mapInterface->getCoordinateSystem();
int32_t systemId = mapCoordSystem.identifier;

Converting User Input

// User provides GPS coordinates
double userLat = 40.7128;
double userLon = -74.006;

// Create coordinate in WGS84
Coord userCoord(
    CoordinateSystemIdentifiers::EPSG4326(),
    userLon,
    userLat,
    0.0
);

// Convert to map's coordinate system
auto mapConverter = mapInterface->getCoordinateConverterHelper();
Coord mapCoord = mapConverter->convert(
    mapInterface->getCoordinateSystem().identifier,
    userCoord
);

// Use with camera
camera->moveToCenterPosition(mapCoord, true);

Coordinate Utilities

The SDK provides CoordinatesUtil helper functions:
#include "CoordinatesUtil.h"

// Check if coordinates are valid
bool isValid = CoordinatesUtil::isValidCoordinate(coord);

// Normalize longitude to [-180, 180]
double normalized = CoordinatesUtil::normalizeLongitude(longitude);

// Calculate distance between coordinates (in same system)
double distance = CoordinatesUtil::distance(coord1, coord2);

Common Use Cases

GPS to Map Coordinates

void showGpsLocation(double latitude, double longitude) {
    Coord gpsCoord(
        CoordinateSystemIdentifiers::EPSG4326(),
        longitude,
        latitude,
        0.0
    );
    
    auto converter = mapInterface->getCoordinateConverterHelper();
    auto mapSystem = mapInterface->getCoordinateSystem().identifier;
    
    Coord mapCoord = converter->convert(mapSystem, gpsCoord);
    camera->moveToCenterPosition(mapCoord, true);
}

Converting Layer Data

void addPointsFromExternalSource(
    const std::vector<Point>& points,
    int32_t sourceSystem
) {
    auto converter = CoordinateConversionHelperInterface::independentInstance();
    auto targetSystem = mapInterface->getCoordinateSystem().identifier;
    
    for (const auto& point : points) {
        Coord sourceCoord(sourceSystem, point.x, point.y, 0.0);
        Coord mapCoord = converter->convert(targetSystem, sourceCoord);
        
        // Add to map layer
        layer->addPoint(mapCoord);
    }
}

Multi-System Data Sources

class MultiSourceLayer : public LayerInterface {
private:
    std::shared_ptr<CoordinateConversionHelperInterface> converter;
    int32_t targetSystem;
    
public:
    void onAdded(const std::shared_ptr<MapInterface>& map, int32_t index) override {
        converter = map->getCoordinateConverterHelper();
        targetSystem = map->getCoordinateSystem().identifier;
    }
    
    void addDataFromSource(const Data& data, int32_t sourceSystem) {
        // Convert all coordinates to map system
        for (const auto& item : data.items) {
            Coord sourceCoord(sourceSystem, item.x, item.y, item.z);
            Coord mapCoord = converter->convert(targetSystem, sourceCoord);
            processItem(mapCoord, item);
        }
    }
};

Best Practices

When converting coordinates outside of map context (e.g., preprocessing data), use independentInstance() instead of the map’s converter.
Coordinate conversion involves mathematical transformations. Cache results when the same coordinates are used multiple times.
Incorrect source coordinate system will produce wrong results. Double-check your data source’s coordinate system before converting.
Keep all coordinates within a layer in the same system to avoid repeated conversions during rendering.
Some systems use degrees (EPSG4326), others use meters (EPSG3857, EPSG2056). Use unitToMeterFactor() for distance calculations.

Common Pitfalls

  • Longitude/Latitude order: EPSG4326 uses (longitude, latitude), not (latitude, longitude)
  • Elevation handling: Z-coordinate may have different meanings in different systems
  • Polar regions: Some projections (like Web Mercator) don’t work well near poles
  • Antimeridian: Coordinates near ±180° longitude require special handling

Performance Tips

  • Convert coordinates once during data loading, not every frame
  • Batch conversions when possible to reduce function call overhead
  • Use render system coordinates for performance-critical rendering
  • Consider preprocessing data to the map’s coordinate system

Next Steps

Camera Controls

Use converted coordinates with camera navigation

Custom Layers

Build layers with multi-system coordinate support

Build docs developers (and LLMs) love