Module: GD::GIS::Projection

Defined in:
lib/gd/gis/projection.rb

Overview

Projection helpers for Web Mercator–based maps.

This module provides low-level projection utilities used throughout the rendering pipeline to convert geographic coordinates (longitude, latitude) into projected and pixel coordinates.

All longitude and latitude values are assumed to be in WGS84 (EPSG:4326).

Constant Summary collapse

R =

Earth radius used for Web Mercator (meters)

6378137.0
TILE_SIZE =

Web Mercator tile size in pixels

256

Class Method Summary collapse

Class Method Details

.lonlat_to_global_px(lon, lat, zoom) ⇒ Array<Float>

Converts geographic coordinates to global pixel coordinates.

This method implements the standard XYZ / Web Mercator tiling scheme used by most web map providers.

Latitude values are clamped to the valid Web Mercator range.

Parameters:

  • lon (Float)

    longitude in degrees

  • lat (Float)

    latitude in degrees

  • zoom (Integer)

    zoom level

Returns:

  • (Array<Float>)

    global pixel coordinates [x, y]



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/gd/gis/projection.rb', line 76

def self.lonlat_to_global_px(lon, lat, zoom)
  lat = lat.clamp(-85.05112878, 85.05112878)
  n = 2.0**zoom

  x = (lon + 180.0) / 360.0 * n * TILE_SIZE

  lat_rad = lat * Math::PI / 180.0
  y = (1.0 - (Math.log(Math.tan(lat_rad) + (1.0 / Math.cos(lat_rad))) / Math::PI)) / 2.0 * n * TILE_SIZE

  [x, y]
end

.lonlat_to_pixel(lon, lat, min_x, max_x, min_y, max_y, width, height) ⇒ Array<Integer>

Projects geographic coordinates into pixel space relative to a bounding box.

This method is typically used for viewport-based rendering where a fixed image size is mapped to a geographic extent.

Parameters:

  • lon (Float)

    longitude in degrees

  • lat (Float)

    latitude in degrees

  • min_x (Float)

    minimum Web Mercator X (meters)

  • max_x (Float)

    maximum Web Mercator X (meters)

  • min_y (Float)

    minimum Web Mercator Y (meters)

  • max_y (Float)

    maximum Web Mercator Y (meters)

  • width (Integer)

    image width in pixels

  • height (Integer)

    image height in pixels

Returns:

  • (Array<Integer>)

    pixel coordinates [x, y]



51
52
53
54
55
56
57
58
59
# File 'lib/gd/gis/projection.rb', line 51

def self.lonlat_to_pixel(lon, lat, min_x, max_x, min_y, max_y, width, height)
  x = mercator_x(lon)
  y = mercator_y(lat)

  px = (x - min_x) / (max_x - min_x) * width
  py = height - ((y - min_y) / (max_y - min_y) * height)

  [px.to_i, py.to_i]
end

.mercator_x(lon) ⇒ Float

Converts longitude to Web Mercator X coordinate.

Parameters:

  • lon (Float)

    longitude in degrees

Returns:

  • (Float)

    X coordinate in meters



23
24
25
# File 'lib/gd/gis/projection.rb', line 23

def self.mercator_x(lon)
  lon * Math::PI / 180.0 * R
end

.mercator_y(lat) ⇒ Float

Converts latitude to Web Mercator Y coordinate.

Parameters:

  • lat (Float)

    latitude in degrees

Returns:

  • (Float)

    Y coordinate in meters



31
32
33
# File 'lib/gd/gis/projection.rb', line 31

def self.mercator_y(lat)
  Math.log(Math.tan((Math::PI / 4) + (lat * Math::PI / 360.0))) * R
end