libgd-gis

A pure Ruby GIS rendering engine built on ruby-libgd. Render real maps, GeoJSON, labels and styles directly to PNG — no JS, no QGIS, no Mapbox.

Rendered Maps

Paraná Polygon
Argentina Museums
Argentina Cities
Tokyo Solarized
Paraná Carto Dark
World Peaks (Small)
Tokyo Water
Paraná Tokyo
Americas
Ice Cream Paraná
World Peaks
Europe
Avenida Ramírez
Museos Paraná
New York City
Argentina
Paris
Tanzania Hydro
Asia Peaks

Full Examples (Ruby)

tokyo.rb


require "pry"
require "gd/gis"

TOKYO = [139.68, 35.63, 139.82, 35.75]

map = GD::GIS::Map.new(
  bbox: TOKYO,
  zoom: 13,
  basemap: :carto_light
)

# map.style = GD::GIS::Style::DARK
# map.style = GD::GIS::Style::SOLARIZED
map.style = GD::GIS::Style.load("solarized")

# Roads
map.add_geojson("streets.geojson")
map.add_geojson("streets.geojson")
map.add_geojson("streets.geojson")

map.add_geojson("parks.geojson")

# Railways
# map.add_geojson("railways.geojson")
# map.add_geojson("railways.geojson")
# map.add_geojson("railways.geojson")

map.render

font = "../fonts/DejaVuSans-Bold.ttf"

bg = GD::Color.rgba(0, 0, 0, 80)
fg = GD::Color.rgb(255, 255, 255)

map.image.filled_rectangle(24, 24, 264, 88, bg)

map.image.text(
  "TOKYO",
  x: 48,
  y: 68,
  size: 32,
  color: fg,
  font: font
)

map.save("tokyo.png")

parana.rb


require "gd/gis"

BBOX = [-60.53, -31.77, -60.51, -31.74]

map = GD::GIS::Map.new(
  bbox: BBOX,
  zoom: 15,
  basemap: :carto_dark
)

polygon = [
  [-60.525, -31.750],
  [-60.520, -31.750],
  [-60.520, -31.755],
  [-60.525, -31.755],
  [-60.525, -31.750]
]

map.add_polygons(
  [polygon],
  fill:   [255, 140, 0, 120],
  stroke: [0, 0, 0, 200],
  width:  2
)

map.render
map.save("carto_dark.png")

puts "Generated carto_dark.png"

paris.rb


require "gd/gis"

PARIS = [2.25, 48.80, 2.42, 48.90]

map = GD::GIS::Map.new(
  bbox: PARIS,
  zoom: 13,
  basemap: :carto_light
)

map.style = GD::GIS::Style.load("solarized")


# Seine river
map.add_geojson("data/seine.geojson")

# Parks
map.add_geojson("data/parks.geojson")


pois = [
  { "name" => "Eiffel Tower", "lon" => 2.2945, "lat" => 48.8584 }
]

map.add_points(
  pois,
  lon:   ->(r){ r["lon"].to_f },
  lat:   ->(r){ r["lat"].to_f },
  icon:  "eiffel.jpg",
  label: ->(r){ r["name"] },
  font:  "./fonts/DejaVuSans-Bold.ttf",
  size:  14,
  color: [0,0,0]
)

map.render
map.image.antialias = true

# Title
font = "./fonts/DejaVuSans-Bold.ttf"
bg = GD::Color.rgba(0,0,0,100)
fg = GD::Color.rgb(255,255,255)

map.image.filled_rectangle(30, 30, 330, 100, bg)
map.image.text("PARIS", x: 60, y: 85, size: 36, color: fg, font: font)

map.save("paris.png")

nyc.rb


require "pry"
require "gd/gis"

MANHATTAN = [-74.05, 40.70, -73.93, 40.88]

map = GD::GIS::Map.new(
  bbox: MANHATTAN,
  zoom: 13,
  basemap: :carto_light
)

map.style = GD::GIS::Style.load("dark")

# capas
map.add_geojson("nyc_test.geojson")

# POIs
pois = [
  { "name" => "Manhattan",     "lon" => -73.97, "lat" => 40.78 },
  { "name" => "Brooklyn",      "lon" => -73.95, "lat" => 40.65 },
  { "name" => "Queens",        "lon" => -73.85, "lat" => 40.73 },
  { "name" => "Bronx",         "lon" => -73.86, "lat" => 40.85 },
  { "name" => "Staten Island", "lon" => -74.15, "lat" => 40.58 }
]

font = "./fonts/DejaVuSans-Bold.ttf"
map.add_points(
  pois,
  lon:   ->(r){ r["lon"] },
  lat:   ->(r){ r["lat"] },
  icon:  "icon.png",
  label: ->(r){ r["name"] },
  font:  font,
  size:  14,
  color: [0,0,0]
)

# UNA sola vez
map.render

map.image.antialias = true

bg = GD::Color.rgba(0,0,0,120)
fg = GD::Color.rgb(255,255,255)

map.image.filled_rectangle(30, 30, 520, 120, bg)
map.image.text("NEW YORK CITY", x: 60, y: 95, size: 36, color: fg, font: font)

map.save("nyc.png")

world_peaks.rb


require "json"
require "gd/gis"

EUROPE = [-15.0, 34.0, 40.0, 72.0]

map = GD::GIS::Map.new(
  bbox: EUROPE,
  zoom: 4,
  basemap: :carto_light
)


peaks = JSON.parse(File.read("picks.json"))

map.add_points(
  peaks,
  lon: ->(p) { p["longitude"] },
  lat: ->(p) { p["latitude"] },
  icon: "peak.png",
  label: ->(p) { p["name"] },
  font: "./fonts/DejaVuSans.ttf",
  size: 10,
  color: [0,0,0]
)

map.render
map.save("output/europe.png")

puts "Saved output/europe.png"

Animated Maps (Alpha)

libgd-gis is designed not only for static map rendering, but also for map manipulation and animated outputs such as route playback, simulated or real-time geolocation tracking.

Animated map generation is already possible, including GIF-based animations showing movement across cities. This feature is currently in alpha (alpha-1) and will be released as stable after extensive testing and API stabilization.

NYC — Multi-track Animation
Buenos Aires — Pac-Man Track
Manhattan — Pac-Man Path
Manhattan — Vehicle Tracking