libgd-gis 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/gd/gis/layer_points.rb +95 -10
- data/lib/gd/gis/map.rb +100 -6
- data/lib/gd/gis/style.rb +5 -0
- metadata +2 -3
- data/lib/test.rb +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 853349ea776badb5542429302596948e10214ccd5dd3eb75c31e075bfde0e45e
|
|
4
|
+
data.tar.gz: 51a6d88d8f49e6e14a363c68fbd9a0837aae91aef028b456f4df20865831fce8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e3430de5b4a01574ccb741d0948de4458b07cae11e196835282c71c88edf2e69f3f6a53f5d35cdaa3195423f0e9bf845324919b233f3aeec68af5719da752173
|
|
7
|
+
data.tar.gz: e2a9b4e8149839b5b9d7b834757e304979a81e3879a4332f97159e75236be79ea4c4e179a54ed3efd94231c24d290edc83812793b2962ffdbd40ae12549bf40a
|
data/lib/gd/gis/layer_points.rb
CHANGED
|
@@ -38,27 +38,35 @@ module GD
|
|
|
38
38
|
label: nil,
|
|
39
39
|
font: nil,
|
|
40
40
|
size: 12,
|
|
41
|
-
color: [0, 0, 0]
|
|
41
|
+
color: [0, 0, 0],
|
|
42
|
+
font_color: nil,
|
|
43
|
+
symbol: 0
|
|
42
44
|
)
|
|
43
45
|
@data = data
|
|
44
46
|
@lon = lon
|
|
45
47
|
@lat = lat
|
|
48
|
+
@color = color
|
|
49
|
+
@font_color = font_color
|
|
46
50
|
|
|
47
51
|
if icon.is_a?(Array) || icon.nil?
|
|
48
52
|
fill, stroke = icon || [GD::GIS::ColorHelpers.random_rgb, GD::GIS::ColorHelpers.random_rgb]
|
|
49
53
|
@icon = build_default_marker(fill, stroke)
|
|
54
|
+
elsif %w[numeric alphabetic symbol].include?(icon)
|
|
55
|
+
@icon = icon
|
|
50
56
|
else
|
|
51
57
|
@icon = GD::Image.open(icon)
|
|
58
|
+
@icon.alpha_blending = true
|
|
59
|
+
@icon.save_alpha = true
|
|
52
60
|
end
|
|
53
61
|
|
|
54
62
|
@label = label
|
|
55
63
|
@font = font
|
|
56
64
|
@size = size
|
|
65
|
+
|
|
57
66
|
@r, @g, @b, @a = color
|
|
58
67
|
@a = 0 if @a.nil?
|
|
59
68
|
|
|
60
|
-
@
|
|
61
|
-
@icon.save_alpha = true
|
|
69
|
+
@symbol = symbol
|
|
62
70
|
end
|
|
63
71
|
|
|
64
72
|
# Builds a default circular marker icon.
|
|
@@ -93,8 +101,23 @@ module GD
|
|
|
93
101
|
#
|
|
94
102
|
# @return [void]
|
|
95
103
|
def render!(img, projector)
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
value = case @icon
|
|
105
|
+
when "numeric"
|
|
106
|
+
@symbol
|
|
107
|
+
when "alphabetic"
|
|
108
|
+
(@symbol + 96).chr
|
|
109
|
+
when "symbol"
|
|
110
|
+
@symbol
|
|
111
|
+
else
|
|
112
|
+
@icon
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
if @icon.is_a?(GD::Image)
|
|
116
|
+
w = @icon.width
|
|
117
|
+
h = @icon.height
|
|
118
|
+
else
|
|
119
|
+
w = radius_from_text(img, value, font: @font, size: @size) * 2
|
|
120
|
+
end
|
|
98
121
|
|
|
99
122
|
@data.each do |row|
|
|
100
123
|
lon = @lon.call(row)
|
|
@@ -102,10 +125,6 @@ module GD
|
|
|
102
125
|
|
|
103
126
|
x, y = projector.call(lon, lat)
|
|
104
127
|
|
|
105
|
-
# icono
|
|
106
|
-
img.copy(@icon, x - (w / 2), y - (h / 2), 0, 0, w, h)
|
|
107
|
-
|
|
108
|
-
# etiqueta opcional
|
|
109
128
|
next unless @label && @font
|
|
110
129
|
|
|
111
130
|
text = @label.call(row)
|
|
@@ -113,14 +132,80 @@ module GD
|
|
|
113
132
|
|
|
114
133
|
font_h = @size * 1.1
|
|
115
134
|
|
|
135
|
+
if @icon == "numeric" || @icon == "alphabetic" || @icon == "symbol"
|
|
136
|
+
draw_symbol_circle!(
|
|
137
|
+
img: img,
|
|
138
|
+
x: x,
|
|
139
|
+
y: y,
|
|
140
|
+
symbol: value,
|
|
141
|
+
bg_color: @color,
|
|
142
|
+
font_color: @font_color,
|
|
143
|
+
font: @font,
|
|
144
|
+
font_size: @size
|
|
145
|
+
)
|
|
146
|
+
else
|
|
147
|
+
img.copy(@icon, x - (w / 2), y - (h / 2), 0, 0, w, h)
|
|
148
|
+
end
|
|
149
|
+
|
|
116
150
|
img.text(text,
|
|
117
151
|
x: x + (w / 2) + 4,
|
|
118
152
|
y: y + (font_h / 2),
|
|
119
153
|
size: @size,
|
|
120
|
-
color:
|
|
154
|
+
color: @font_color,
|
|
121
155
|
font: @font)
|
|
122
156
|
end
|
|
123
157
|
end
|
|
158
|
+
|
|
159
|
+
# Draws a filled circle (bullet) with a centered numeric label.
|
|
160
|
+
#
|
|
161
|
+
# - x, y: circle center in pixels
|
|
162
|
+
# - y for text() is BASELINE (not top). We compute baseline to center the text.
|
|
163
|
+
def draw_symbol_circle!(img:, x:, y:, symbol:, bg_color:, font_color:, font:, font_size:, angle: 0.0)
|
|
164
|
+
diameter = radius_from_text(img, symbol, font: font, size: font_size) * 2
|
|
165
|
+
|
|
166
|
+
# 1) Bullet background
|
|
167
|
+
img.filled_ellipse(x, y, diameter, diameter, bg_color)
|
|
168
|
+
|
|
169
|
+
# 2) Measure text in pixels (matches rendering)
|
|
170
|
+
text = symbol.to_s
|
|
171
|
+
w, h = img.text_bbox(text, font: font, size: font_size, angle: angle)
|
|
172
|
+
|
|
173
|
+
# 3) Compute centered position:
|
|
174
|
+
# text() uses baseline Y, so:
|
|
175
|
+
# top_y = y - h/2
|
|
176
|
+
# baseline = top_y + h = y + h/2
|
|
177
|
+
text_x = (x - (w / 2.0)).round
|
|
178
|
+
text_y = (y + (h / 2.0)).round
|
|
179
|
+
|
|
180
|
+
# 4) Draw number
|
|
181
|
+
img.text(
|
|
182
|
+
text,
|
|
183
|
+
x: text_x,
|
|
184
|
+
y: text_y,
|
|
185
|
+
font: font,
|
|
186
|
+
size: font_size,
|
|
187
|
+
color: font_color
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Calculates a circle radius that fully contains the rendered text.
|
|
192
|
+
#
|
|
193
|
+
# img : GD::Image
|
|
194
|
+
# text : String (number, letters, etc.)
|
|
195
|
+
# font : path to .ttf
|
|
196
|
+
# size : font size in points
|
|
197
|
+
# padding : extra pixels around text (visual breathing room)
|
|
198
|
+
#
|
|
199
|
+
def radius_from_text(img, text, font:, size:, padding: 4)
|
|
200
|
+
w, h = img.text_bbox(
|
|
201
|
+
text.to_s,
|
|
202
|
+
font: font,
|
|
203
|
+
size: size
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Use the larger dimension to ensure the text fits
|
|
207
|
+
([w, h].max / 2.0).ceil + padding
|
|
208
|
+
end
|
|
124
209
|
end
|
|
125
210
|
end
|
|
126
211
|
end
|
data/lib/gd/gis/map.rb
CHANGED
|
@@ -133,6 +133,7 @@ module GD
|
|
|
133
133
|
|
|
134
134
|
@debug = false
|
|
135
135
|
@used_labels = {}
|
|
136
|
+
@count = 1
|
|
136
137
|
end
|
|
137
138
|
|
|
138
139
|
# Returns all features belonging to a given semantic layer.
|
|
@@ -258,20 +259,20 @@ module GD
|
|
|
258
259
|
warn "Style error: missing 'points' section"
|
|
259
260
|
end
|
|
260
261
|
|
|
261
|
-
font =
|
|
262
|
+
font = @style.points[:font] || begin
|
|
262
263
|
warn "[libgd-gis] points.font not defined in style, using random system font"
|
|
263
264
|
GD::GIS::FontHelper.random
|
|
264
265
|
end
|
|
265
266
|
|
|
266
|
-
size =
|
|
267
|
+
size = @style.points[:size] || begin
|
|
267
268
|
warn "[libgd-gis] points.font size not defined in style, using random system font size"
|
|
268
269
|
(6..14).to_a.sample
|
|
269
270
|
end
|
|
270
271
|
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
color = @style.points[:color] ? @style.normalize_color(@style.points[:color]) : GD::GIS::ColorHelpers.random_vivid
|
|
273
|
+
font_color = @style.points[:font_color] ? @style.normalize_color(@style.points[:font_color]) : [250, 250, 250, 0]
|
|
273
274
|
|
|
274
|
-
icon = if
|
|
275
|
+
icon = if @style.points.key?(:icon_fill) && @style.points.key?(:icon_stroke)
|
|
275
276
|
[points_style[:icon_stroke],
|
|
276
277
|
points_style[:icon_stroke]]
|
|
277
278
|
end
|
|
@@ -285,8 +286,11 @@ module GD
|
|
|
285
286
|
label: ->(f) { f.properties["name"] },
|
|
286
287
|
font: font,
|
|
287
288
|
size: size,
|
|
288
|
-
color: color
|
|
289
|
+
color: color,
|
|
290
|
+
font_color: font_color,
|
|
291
|
+
symbol: @count
|
|
289
292
|
)
|
|
293
|
+
@count += 1
|
|
290
294
|
elsif LINE_GEOMS.include?(geom_type)
|
|
291
295
|
@layers[:minor] << feature
|
|
292
296
|
end
|
|
@@ -294,6 +298,96 @@ module GD
|
|
|
294
298
|
end
|
|
295
299
|
end
|
|
296
300
|
|
|
301
|
+
# Adds a single point (marker) to the map.
|
|
302
|
+
#
|
|
303
|
+
# This is a convenience helper for the most common use case: rendering
|
|
304
|
+
# one point with an optional label and icon, without having to build
|
|
305
|
+
# a full collection or manually configure a PointsLayer.
|
|
306
|
+
#
|
|
307
|
+
# Internally, this method wraps the given coordinates into a one-element
|
|
308
|
+
# data collection and delegates rendering to {GD::GIS::PointsLayer},
|
|
309
|
+
# preserving the same rendering behavior and options.
|
|
310
|
+
#
|
|
311
|
+
# This method is intended for annotations, markers, alerts, cities,
|
|
312
|
+
# or any scenario where only one point needs to be rendered.
|
|
313
|
+
#
|
|
314
|
+
# @param lon [Numeric]
|
|
315
|
+
# Longitude of the point.
|
|
316
|
+
# @param lat [Numeric]
|
|
317
|
+
# Latitude of the point.
|
|
318
|
+
# @param label [String, nil]
|
|
319
|
+
# Optional text label rendered next to the point.
|
|
320
|
+
# @param icon [String, Array<GD::Color>, nil]
|
|
321
|
+
# Marker representation. Can be:
|
|
322
|
+
# - a path to an image file
|
|
323
|
+
# - :numeric or :alphabetic symbol styles
|
|
324
|
+
# - an array of [fill, stroke] colors
|
|
325
|
+
# - nil to generate a default marker
|
|
326
|
+
# @param font [String, nil]
|
|
327
|
+
# Font path used to render the label or symbol.
|
|
328
|
+
# @param size [Integer]
|
|
329
|
+
# Font size in pixels (default: 12).
|
|
330
|
+
# @param color [Array<Integer>]
|
|
331
|
+
# Label or symbol background color as an RGB(A) array.
|
|
332
|
+
# @param font_color [GD::Color, nil]
|
|
333
|
+
# Text color for numeric or alphabetic symbols.
|
|
334
|
+
#
|
|
335
|
+
# @return [void]
|
|
336
|
+
#
|
|
337
|
+
# @example Render a simple point
|
|
338
|
+
# map.add_point(
|
|
339
|
+
# lon: -58.3816,
|
|
340
|
+
# lat: -34.6037
|
|
341
|
+
# )
|
|
342
|
+
#
|
|
343
|
+
# @example Point with label
|
|
344
|
+
# map.add_point(
|
|
345
|
+
# lon: -58.3816,
|
|
346
|
+
# lat: -34.6037,
|
|
347
|
+
# label: "Buenos Aires"
|
|
348
|
+
# )
|
|
349
|
+
#
|
|
350
|
+
# @example Point with numeric marker
|
|
351
|
+
# map.add_point(
|
|
352
|
+
# lon: -58.3816,
|
|
353
|
+
# lat: -34.6037,
|
|
354
|
+
# icon: "numeric",
|
|
355
|
+
# label: "1",
|
|
356
|
+
# font: "/usr/share/fonts/DejaVuSans.ttf"
|
|
357
|
+
# )
|
|
358
|
+
#
|
|
359
|
+
|
|
360
|
+
def add_point(
|
|
361
|
+
lon:,
|
|
362
|
+
lat:,
|
|
363
|
+
label: nil,
|
|
364
|
+
icon: nil,
|
|
365
|
+
font: nil,
|
|
366
|
+
size: nil,
|
|
367
|
+
color: nil,
|
|
368
|
+
font_color: nil,
|
|
369
|
+
symbol: nil
|
|
370
|
+
)
|
|
371
|
+
row = {
|
|
372
|
+
lon: lon,
|
|
373
|
+
lat: lat,
|
|
374
|
+
label: label
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
@points_layers << GD::GIS::PointsLayer.new(
|
|
378
|
+
[row],
|
|
379
|
+
lon: -> r { r[:lon] },
|
|
380
|
+
lat: -> r { r[:lat] },
|
|
381
|
+
icon: icon || @style.point[:icon],
|
|
382
|
+
label: label ? -> r { r[:label] } : nil,
|
|
383
|
+
font: font || @style.point[:font],
|
|
384
|
+
size: size || @style.point[:size],
|
|
385
|
+
color: color || @style.point[:color],
|
|
386
|
+
font_color: font_color || @style.point[:font_color],
|
|
387
|
+
symbol: symbol
|
|
388
|
+
)
|
|
389
|
+
end
|
|
390
|
+
|
|
297
391
|
# Adds a generic points overlay layer.
|
|
298
392
|
#
|
|
299
393
|
# @param data [Enumerable]
|
data/lib/gd/gis/style.rb
CHANGED
|
@@ -17,6 +17,9 @@ module GD
|
|
|
17
17
|
# @return [Hash] global styling rules
|
|
18
18
|
attr_reader :global
|
|
19
19
|
|
|
20
|
+
# @return [Hash] point styling rules
|
|
21
|
+
attr_reader :point
|
|
22
|
+
|
|
20
23
|
# @return [Hash] road styling rules
|
|
21
24
|
attr_reader :roads
|
|
22
25
|
|
|
@@ -45,6 +48,7 @@ module GD
|
|
|
45
48
|
# :global, :roads, :rails, :water, :parks, :points, :order, :track
|
|
46
49
|
def initialize(definition)
|
|
47
50
|
@global = definition[:global] || {}
|
|
51
|
+
@point = definition[:point] || {}
|
|
48
52
|
@roads = definition[:roads] || {}
|
|
49
53
|
@rails = definition[:rails] || {}
|
|
50
54
|
@water = definition[:water] || {}
|
|
@@ -79,6 +83,7 @@ module GD
|
|
|
79
83
|
|
|
80
84
|
new(
|
|
81
85
|
global: data[:global],
|
|
86
|
+
point: data[:point],
|
|
82
87
|
roads: data[:roads],
|
|
83
88
|
rails: data[:rail] || data[:rails],
|
|
84
89
|
track: data[:track],
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: libgd-gis
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Germán Alberto Giménez Silva
|
|
@@ -57,7 +57,6 @@ files:
|
|
|
57
57
|
- lib/gd/gis/projection.rb
|
|
58
58
|
- lib/gd/gis/style.rb
|
|
59
59
|
- lib/libgd_gis.rb
|
|
60
|
-
- lib/test.rb
|
|
61
60
|
homepage: https://github.com/ggerman/libgd-gis
|
|
62
61
|
licenses:
|
|
63
62
|
- MIT
|
|
@@ -77,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
76
|
- !ruby/object:Gem::Version
|
|
78
77
|
version: '0'
|
|
79
78
|
requirements: []
|
|
80
|
-
rubygems_version: 4.0.
|
|
79
|
+
rubygems_version: 4.0.5
|
|
81
80
|
specification_version: 4
|
|
82
81
|
summary: Geospatial raster rendering for Ruby using libgd
|
|
83
82
|
test_files: []
|
data/lib/test.rb
DELETED