Class: GD::GIS::Feature
- Inherits:
-
Object
- Object
- GD::GIS::Feature
- Defined in:
- lib/gd/gis/feature.rb
Overview
Represents a single geographic feature with geometry and properties.
A Feature acts as the rendering bridge between:
-
GeoJSON-like geometry data
-
Attribute properties
-
GD drawing primitives
Features are responsible for drawing themselves onto a GD image using a provided projection and styling information.
Instance Attribute Summary collapse
-
#geometry ⇒ Hash
readonly
GeoJSON geometry object.
-
#layer ⇒ Symbol?
readonly
Logical layer identifier.
-
#properties ⇒ Hash
readonly
Feature properties (tags).
Instance Method Summary collapse
-
#centroid ⇒ Array<Float>?
Computes a simple centroid for line-based geometries.
-
#draw(img, projection, color, width, layer = nil) ⇒ void
Draws the feature onto a GD image.
-
#draw_line(img, projection, coords, color, width) ⇒ void
Draws a single line geometry.
-
#draw_lines(img, projection, coords, color, width) ⇒ void
Draws line or multiline geometries.
-
#draw_polygon(img, projection, rings, color) ⇒ void
Draws a filled polygon using a single color.
-
#draw_polygon_outline(img, projection, rings, color, width) ⇒ void
Draws only the outline of a polygon.
-
#draw_polygon_styled(img, projection, rings, style) ⇒ void
Draws a polygon with fill and stroke styling.
-
#initialize(geometry, properties, layer = nil) ⇒ Feature
constructor
Creates a new feature.
-
#label ⇒ String?
Returns the display label for the feature.
Constructor Details
#initialize(geometry, properties, layer = nil) ⇒ Feature
Creates a new feature.
33 34 35 36 37 |
# File 'lib/gd/gis/feature.rb', line 33 def initialize(geometry, properties, layer = nil) @geometry = geometry @properties = properties || {} @layer = layer end |
Instance Attribute Details
#geometry ⇒ Hash (readonly)
Returns GeoJSON geometry object.
17 18 19 |
# File 'lib/gd/gis/feature.rb', line 17 def geometry @geometry end |
#layer ⇒ Symbol? (readonly)
Returns logical layer identifier.
23 24 25 |
# File 'lib/gd/gis/feature.rb', line 23 def layer @layer end |
#properties ⇒ Hash (readonly)
Returns feature properties (tags).
20 21 22 |
# File 'lib/gd/gis/feature.rb', line 20 def properties @properties end |
Instance Method Details
#centroid ⇒ Array<Float>?
Computes a simple centroid for line-based geometries.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/gd/gis/feature.rb', line 217 def centroid pts = [] case geometry["type"] when "LineString" pts = geometry["coordinates"] when "MultiLineString" pts = geometry["coordinates"].flatten(1) end return nil if pts.empty? lon = pts.sum(&:first) / pts.size lat = pts.sum(&:last) / pts.size [lon, lat] end |
#draw(img, projection, color, width, layer = nil) ⇒ void
This method returns an undefined value.
Draws the feature onto a GD image.
This is the main rendering entry point and dispatches to the appropriate drawing method based on geometry type and layer styling.
Supported geometry types:
-
Polygon
-
MultiPolygon
-
LineString
-
MultiLineString
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/gd/gis/feature.rb', line 60 def draw(img, projection, color, width, layer = nil) case geometry["type"] when "Polygon" if layer == :water draw_polygon_outline(img, projection, geometry["coordinates"], color, width) elsif layer.is_a?(Hash) draw_polygon_styled(img, projection, geometry["coordinates"], layer) else draw_polygon(img, projection, geometry["coordinates"], color) end when "MultiPolygon" geometry["coordinates"].each do |poly| if layer == :water draw_polygon_outline(img, projection, poly, color, width) elsif layer.is_a?(Hash) draw_polygon_styled(img, projection, poly, layer) else draw_polygon(img, projection, poly, color) end end when "LineString", "MultiLineString" draw_lines(img, projection, geometry["coordinates"], color, width) end end |
#draw_line(img, projection, coords, color, width) ⇒ void
This method returns an undefined value.
Draws a single line geometry.
195 196 197 198 199 200 201 202 203 |
# File 'lib/gd/gis/feature.rb', line 195 def draw_line(img, projection, coords, color, width) return if color.nil? coords.each_cons(2) do |(lon1, lat1), (lon2, lat2)| x1, y1 = projection.call(lon1, lat1) x2, y2 = projection.call(lon2, lat2) img.line(x1, y1, x2, y2, color, thickness: width) end end |
#draw_lines(img, projection, coords, color, width) ⇒ void
This method returns an undefined value.
Draws line or multiline geometries.
177 178 179 180 181 182 183 184 185 |
# File 'lib/gd/gis/feature.rb', line 177 def draw_lines(img, projection, coords, color, width) return if color.nil? if coords.first.is_a?(Array) && coords.first.first.is_a?(Array) coords.each { |line| draw_line(img, projection, line, color, width) } else draw_line(img, projection, coords, color, width) end end |
#draw_polygon(img, projection, rings, color) ⇒ void
This method returns an undefined value.
Draws a filled polygon using a single color.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/gd/gis/feature.rb', line 151 def draw_polygon(img, projection, rings, color) return if color.nil? rings.each do |ring| pts = ring.filter_map do |lon, lat| x, y = projection.call(lon, lat) next if x.nil? || y.nil? [x.to_i, y.to_i] end pts = pts.chunk_while { |a, b| a == b }.map(&:first) next if pts.length < 3 img.filled_polygon(pts, color) end end |
#draw_polygon_outline(img, projection, rings, color, width) ⇒ void
This method returns an undefined value.
Draws only the outline of a polygon.
Used primarily for water bodies.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/gd/gis/feature.rb', line 129 def draw_polygon_outline(img, projection, rings, color, width) return if color.nil? rings.each do |ring| pts = ring.filter_map do |lon, lat| x, y = projection.call(lon, lat) [x.to_i, y.to_i] if x && y end next if pts.size < 2 img.lines(pts, color, width) end end |
#draw_polygon_styled(img, projection, rings, style) ⇒ void
This method returns an undefined value.
Draws a polygon with fill and stroke styling.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/gd/gis/feature.rb', line 95 def draw_polygon_styled(img, projection, rings, style) fill = style[:fill] ? GD::Color.rgb(*style[:fill]) : nil stroke = style[:stroke] ? GD::Color.rgb(*style[:stroke]) : nil rings.each do |ring| pts = ring.filter_map do |lon, lat| x, y = projection.call(lon, lat) next if x.nil? || y.nil? [x.to_i, y.to_i] end pts = pts.chunk_while { |a, b| a == b }.map(&:first) next if pts.length < 3 img.filled_polygon(pts, fill) if fill if stroke pts.each_cons(2) { |a, b| img.line(a[0], a[1], b[0], b[1], stroke) } img.line(pts.last[0], pts.last[1], pts.first[0], pts.first[1], stroke) end end end |
#label ⇒ String?
Returns the display label for the feature.
Prefers Japanese names if present.
210 211 212 |
# File 'lib/gd/gis/feature.rb', line 210 def label properties["name:ja"] || properties["name"] end |