Skip to content

Map Rendering

Geodetic provides a map adapter pattern (Geodetic::Map) for rendering coordinates, paths, areas, and features on maps. The adapter abstracts the rendering backend so the same Geodetic objects work with different map engines.

Architecture

Geodetic::Map::Base          # Abstract adapter interface
├── Geodetic::Map::LibGdGis  # Raster PNG output via libgd-gis
├── (future) Leaflet         # Interactive HTML/JS maps
├── (future) GoogleMaps      # Google Maps HTML or Static API
└── (future) KML             # KML XML output

MapMethods is a mixin applied to all coordinates, areas, paths, segments, and features, providing add_to_map(map, **style).

Usage

Adding objects to a map

Two equivalent APIs — use whichever reads better:

# Map-centric
map = Geodetic::Map::LibGdGis.new(bbox: bbox, zoom: 12, basemap: :carto_dark)
map.add(polygon, fill: [0, 200, 120, 170], stroke: [0, 200, 120, 30], width: 2)
map.add(path, color: [255, 220, 50], width: 3)
map.add(coordinate, color: [255, 0, 0], label: "Marker")

# Object-centric (via MapMethods mixin)
polygon.add_to_map(map, fill: [0, 200, 120, 170])
path.add_to_map(map, color: [255, 220, 50], width: 3)
coordinate.add_to_map(map, color: [255, 0, 0], label: "Marker")

The add method auto-detects the object type and dispatches to the appropriate handler. Supported types:

Object Layer type Notes
Any coordinate (18 systems) :point Converts to LLA automatically
Path :line Renders all waypoints as a line
Segment :line Two-point line
Polygon (and subclasses) :polygon Includes Triangle, Rectangle, Hexagon, etc.
Circle :polygon Approximated as N-gon (default 32 segments)
BoundingBox :polygon Four corners as a rectangle
Feature delegates Extracts geometry; merges label into style
ENU / NED rejected Raises ArgumentError (relative systems)

Rendering

# Simple render to file
map.render("output.png")

# Render with custom drawing block (LibGdGis-specific)
map.render("output.png") do |gd_map|
  img = gd_map.image
  # Use GD::Image primitives for custom markers, labels, arrows, etc.
end

# Render without saving (returns GD::GIS::Map)
gd_map = map.render

Bounding box

The LibGdGis adapter accepts bounding boxes as either:

# Geodetic BoundingBox object
bbox = Geodetic::Areas::BoundingBox.new(nw: nw_point, se: se_point)
map = Geodetic::Map::LibGdGis.new(bbox: bbox, zoom: 12)

# Raw [west, south, east, north] array
map = Geodetic::Map::LibGdGis.new(bbox: [-74.05, 40.65, -73.75, 40.82], zoom: 12)

LibGdGis Adapter

Color format

Colors are [r, g, b] or [r, g, b, alpha] arrays. The alpha channel follows libgd convention:

  • 0 = fully opaque
  • 255 = fully transparent

Style options

Option Point Line Polygon
color marker color stroke color
stroke stroke color outline color
fill fill color
width line width (px) outline width (px)
label text label
icon image path
font font path
size font size
font_color label color
symbol marker style
segments circle approximation (default 32)

Prerequisites

gem install libgd-gis
brew install gd   # macOS
# apt install libgd-dev   # Linux

Feature Class

Geodetic::Feature wraps a geometry (any coordinate or area) with a label and a metadata hash. It delegates distance_to and bearing_to to its geometry, using the centroid for area geometries. When added to a map, the label is automatically included in the style.

Examples