foliage 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +9 -0
- data/app/assets/images/.keep +0 -0
- data/app/assets/images/map/marker/icon-2x.png +0 -0
- data/app/assets/images/map/marker/icon.png +0 -0
- data/app/assets/images/map/marker/icon.svg +67 -0
- data/app/assets/images/map/marker/shadow.png +0 -0
- data/app/assets/javascripts/core_ext.js.coffee +61 -0
- data/app/assets/javascripts/foliage.js.coffee +23 -0
- data/app/assets/javascripts/foliage/band.js.coffee +99 -0
- data/app/assets/javascripts/foliage/bubbles.js.coffee +77 -0
- data/app/assets/javascripts/foliage/categories.js.coffee +70 -0
- data/app/assets/javascripts/foliage/choropleth.js.coffee +51 -0
- data/app/assets/javascripts/foliage/color.js.coffee +39 -0
- data/app/assets/javascripts/foliage/gradient.js.coffee +72 -0
- data/app/assets/javascripts/foliage/heatmap.js.coffee +49 -0
- data/app/assets/javascripts/foliage/leaf.js.coffee +422 -0
- data/app/assets/javascripts/foliage/path.js.coffee +76 -0
- data/app/assets/javascripts/foliage/paths.js.coffee +131 -0
- data/app/assets/javascripts/foliage/point_group.js.coffee +83 -0
- data/app/assets/javascripts/foliage/points.js.coffee +79 -0
- data/app/assets/javascripts/foliage/simple.js.coffee +35 -0
- data/app/assets/javascripts/leaflet/geographic_util.js.coffee +23 -0
- data/app/assets/javascripts/leaflet/ghost_label.js.coffee +100 -0
- data/app/assets/javascripts/leaflet/ghost_label_cluster.js.coffee +192 -0
- data/app/assets/javascripts/leaflet/layers_scheduler.js.coffee +57 -0
- data/app/assets/javascripts/leaflet/reactive_measure.js.coffee +414 -0
- data/app/assets/stylesheets/all.scss +16 -0
- data/app/assets/stylesheets/application.css +15 -0
- data/app/assets/stylesheets/compass/reset.scss +3 -0
- data/app/assets/stylesheets/compass/reset/utilities.scss +142 -0
- data/app/assets/stylesheets/leaflet.scss +1093 -0
- data/app/assets/stylesheets/leaflet/label.scss +40 -0
- data/app/assets/stylesheets/leaflet/tooltip.scss +42 -0
- data/app/assets/stylesheets/mixins.scss +131 -0
- data/app/assets/stylesheets/reset.scss +89 -0
- data/app/assets/stylesheets/variables.scss +47 -0
- data/app/helpers/foliage_helper.rb +23 -0
- data/lib/foliage.rb +9 -0
- data/lib/foliage/leaf.rb +235 -0
- data/lib/foliage/rails.rb +2 -0
- data/lib/foliage/rails/engine.rb +7 -0
- data/lib/foliage/rails/integration.rb +8 -0
- data/lib/foliage/version.rb +3 -0
- data/vendor/assets/javascripts/.keep +0 -0
- data/vendor/assets/javascripts/autosize.js +211 -0
- data/vendor/assets/javascripts/geographiclib.js +3074 -0
- data/vendor/assets/javascripts/leaflet.js.erb +9175 -0
- data/vendor/assets/javascripts/leaflet/draw.js +3573 -0
- data/vendor/assets/javascripts/leaflet/easy-button.js +366 -0
- data/vendor/assets/javascripts/leaflet/fullscreen.js +162 -0
- data/vendor/assets/javascripts/leaflet/heatmap.js +142 -0
- data/vendor/assets/javascripts/leaflet/label.js +545 -0
- data/vendor/assets/javascripts/leaflet/measure.js +6966 -0
- data/vendor/assets/javascripts/leaflet/modal.js +364 -0
- data/vendor/assets/javascripts/leaflet/providers.js +479 -0
- data/vendor/assets/javascripts/rbush.js +621 -0
- data/vendor/assets/stylesheets/.keep +0 -0
- data/vendor/assets/stylesheets/bootstrap/mixins.scss +55 -0
- data/vendor/assets/stylesheets/bootstrap/variables.scss +10 -0
- data/vendor/assets/stylesheets/leaflet.scss +479 -0
- data/vendor/assets/stylesheets/leaflet/draw.scss +282 -0
- data/vendor/assets/stylesheets/leaflet/easy-button.scss +56 -0
- data/vendor/assets/stylesheets/leaflet/fullscreen.scss +2 -0
- data/vendor/assets/stylesheets/leaflet/measure.scss +168 -0
- data/vendor/assets/stylesheets/leaflet/modal.scss +85 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ddfe5960094bf8bbd1f7250eea1b7470eb04dfe3
|
4
|
+
data.tar.gz: 233456b00d6ea184176015a33e739039a5358a68
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 29489a93eb3b3fba23d0769c825579911dbefe1317d3061a856ad484636179cf42a96789579e26c5eee90b5db280bec21734a330b118a45b097b823ac15daa0b
|
7
|
+
data.tar.gz: 221131a3db6c00fdd8d2331d50574f5aa5ce60746f037bf165e13c92074a832e65e0b1f0764ac2bec74049d374e47f95a7621ce4cf0188283913334b48a5d34e
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014-2016 Ekylibre, Jérémie Bonal
|
2
|
+
|
3
|
+
The MIT LICENSE
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# Foliage
|
2
|
+
|
3
|
+
Extracted from [Ekylibre's repo](http://github.com/ekylibre/ekylibre) as part of the [Osmosis](http://github.com/Aquaj/osmosis) fork, this gem provides convenient helpers, javascript and styles to quickly and easily display maps.
|
4
|
+
|
5
|
+
Based on [Leaflet.js](http://leafletjs.com).
|
6
|
+
|
7
|
+
## Dependencies
|
8
|
+
|
9
|
+
`// TODO`
|
File without changes
|
Binary file
|
Binary file
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
11
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
12
|
+
id="svg2"
|
13
|
+
version="1.1"
|
14
|
+
inkscape:version="0.91 r13725"
|
15
|
+
width="25"
|
16
|
+
height="41"
|
17
|
+
viewBox="0 0 25 41"
|
18
|
+
sodipodi:docname="icon.svg">
|
19
|
+
<metadata
|
20
|
+
id="metadata8">
|
21
|
+
<rdf:RDF>
|
22
|
+
<cc:Work
|
23
|
+
rdf:about="">
|
24
|
+
<dc:format>image/svg+xml</dc:format>
|
25
|
+
<dc:type
|
26
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
27
|
+
<dc:title></dc:title>
|
28
|
+
</cc:Work>
|
29
|
+
</rdf:RDF>
|
30
|
+
</metadata>
|
31
|
+
<defs
|
32
|
+
id="defs6" />
|
33
|
+
<sodipodi:namedview
|
34
|
+
pagecolor="#ffffff"
|
35
|
+
bordercolor="#666666"
|
36
|
+
borderopacity="1"
|
37
|
+
objecttolerance="10"
|
38
|
+
gridtolerance="10"
|
39
|
+
guidetolerance="10"
|
40
|
+
inkscape:pageopacity="0"
|
41
|
+
inkscape:pageshadow="2"
|
42
|
+
inkscape:window-width="1920"
|
43
|
+
inkscape:window-height="1057"
|
44
|
+
id="namedview4"
|
45
|
+
showgrid="false"
|
46
|
+
borderlayer="true"
|
47
|
+
inkscape:showpageshadow="false"
|
48
|
+
inkscape:zoom="5.7560976"
|
49
|
+
inkscape:cx="-82.783211"
|
50
|
+
inkscape:cy="-19.01566"
|
51
|
+
inkscape:window-x="0"
|
52
|
+
inkscape:window-y="0"
|
53
|
+
inkscape:window-maximized="1"
|
54
|
+
inkscape:current-layer="svg2" />
|
55
|
+
<path
|
56
|
+
style="fill:#187fce;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.75420874"
|
57
|
+
d="M 12.5,1 C 6.8467643,0.94037552 0.90011975,5.0932125 1,13 1.101235,21.014031 10.609264,28.121771 12.5,40 14.347762,28.312508 23.976551,21.962273 24,13 24.02093,5.0006739 18.153235,1.0596245 12.5,1 Z m 0.181641,7.3398438 c 2.494371,-3.473e-4 4.516847,2.0212542 4.517578,4.5156252 3.47e-4,2.495133 -2.022445,4.517925 -4.517578,4.517578 C 10.18727,17.372316 8.1656683,15.34984 8.1660156,12.855469 8.1667464,10.361861 10.188033,8.3405745 12.681641,8.3398438 Z"
|
58
|
+
id="path4138"
|
59
|
+
inkscape:connector-curvature="0"
|
60
|
+
sodipodi:nodetypes="sscssccccc" />
|
61
|
+
<path
|
62
|
+
style="fill:#1886d8;fill-opacity:0.85858583;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.53535354"
|
63
|
+
d="M 12.509053,0.90052064 C 6.855818,0.84089624 0.90917349,4.9937331 1.0090537,12.900521 c 0.101235,8.014031 9.6092633,15.121771 11.4999993,27 1.847762,-11.687492 11.476551,-18.037727 11.5,-27 0.02093,-7.9993265 -5.846765,-11.94037586 -11.5,-12.00000036 z m 0.181641,7.33984376 c 2.494371,-3.473e-4 4.516847,2.0212546 4.517578,4.5156256 3.47e-4,2.495133 -2.022445,4.517925 -4.517578,4.517578 C 10.196323,17.272837 8.174722,15.250361 8.1750693,12.75599 8.1758001,10.262382 10.197086,8.2410951 12.690694,8.2403644 Z"
|
64
|
+
id="path4138-3"
|
65
|
+
inkscape:connector-curvature="0"
|
66
|
+
sodipodi:nodetypes="sscssccccc" />
|
67
|
+
</svg>
|
Binary file
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Core extension for vizualisation
|
2
|
+
#
|
3
|
+
String.prototype.camelize = () ->
|
4
|
+
array = jQuery.map this.split("_"), (word)->
|
5
|
+
word.charAt(0).toUpperCase() + word.slice(1)
|
6
|
+
return array.join()
|
7
|
+
|
8
|
+
String.prototype.repeat = (count) ->
|
9
|
+
return new Array(count + 1).join(this)
|
10
|
+
|
11
|
+
Math.magnitude = (number, step = 1) ->
|
12
|
+
value = Math.abs(number)
|
13
|
+
power = 0
|
14
|
+
if value > 1
|
15
|
+
while Math.pow(10, power + step) < value
|
16
|
+
power += step
|
17
|
+
else
|
18
|
+
while Math.pow(10, power - step) > value
|
19
|
+
power -= step
|
20
|
+
mag = Math.pow(10, power)
|
21
|
+
result =
|
22
|
+
power: power
|
23
|
+
magnitude: mag
|
24
|
+
base: number / mag
|
25
|
+
|
26
|
+
Math.round2 = (number, round = 1) ->
|
27
|
+
return round * Math.round(number / round)
|
28
|
+
|
29
|
+
Math.humanize = (value, power = 0) ->
|
30
|
+
return Math.round(value)
|
31
|
+
# return Math.round(value / Math.pow(10, power)) + "e#{power}"
|
32
|
+
size = Math.round(power / 3)
|
33
|
+
return Math.round(value / Math.pow(10, 3 * size)) + "pnµm KMGTPE"[size + 4]
|
34
|
+
|
35
|
+
Math.ceil2 = (number, round = 1) ->
|
36
|
+
return round * Math.ceil(number / round)
|
37
|
+
|
38
|
+
Math.floor2 = (number, round = 1) ->
|
39
|
+
return round * Math.floor(number / round)
|
40
|
+
|
41
|
+
# Returns logarithm value in given base (10 by default)
|
42
|
+
Math.logg = (value, base = 10) ->
|
43
|
+
return Math.log(value) / Math.log(base)
|
44
|
+
|
45
|
+
# Compute number of decimal
|
46
|
+
# Negative value is return if trailing zero are found.
|
47
|
+
# Ex: 200 => -2
|
48
|
+
# 0.12500 => 3
|
49
|
+
# 0.125 => 3
|
50
|
+
# 125 => 0
|
51
|
+
Math.decimalCount = (value) ->
|
52
|
+
return 0 if value == 0
|
53
|
+
count = 0
|
54
|
+
integersCount = Math.ceil(Math.logg(Math.floor(value)))
|
55
|
+
value /= Math.pow(10, integersCount)
|
56
|
+
while (value != Math.floor(value))
|
57
|
+
count += 1
|
58
|
+
value *= 10
|
59
|
+
break if count > 100
|
60
|
+
return count - integersCount
|
61
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Add sprockets directives below:
|
2
|
+
|
3
|
+
#= require jquery
|
4
|
+
#= require jquery-ui
|
5
|
+
#= require jquery_ujs
|
6
|
+
#= require turbolinks
|
7
|
+
#= require_self
|
8
|
+
#= require geographiclib
|
9
|
+
#= require leaflet.js.erb
|
10
|
+
#= require leaflet/draw
|
11
|
+
#= require leaflet/fullscreen
|
12
|
+
#= require leaflet/providers
|
13
|
+
#= require leaflet/heatmap
|
14
|
+
#= require leaflet/measure
|
15
|
+
#= require leaflet/easy-button
|
16
|
+
#= require leaflet/modal
|
17
|
+
#= require leaflet/label
|
18
|
+
#= require rbush
|
19
|
+
#= require autosize
|
20
|
+
#= require_tree ./leaflet
|
21
|
+
#= require foliage/leaf
|
22
|
+
|
23
|
+
this.Foliage = {};
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class Foliage.Band
|
2
|
+
|
3
|
+
constructor: (@layer, @data, options = {}) ->
|
4
|
+
@items = []
|
5
|
+
property = @layer.reference
|
6
|
+
console.log "Property: ", property
|
7
|
+
previous = null
|
8
|
+
minValue = null
|
9
|
+
maxValue = null
|
10
|
+
for zone in @data
|
11
|
+
minValue ?= zone[property]
|
12
|
+
maxValue ?= zone[property]
|
13
|
+
minValue = zone[property] if minValue > zone[property]
|
14
|
+
maxValue = zone[property] if maxValue < zone[property]
|
15
|
+
if previous
|
16
|
+
@items.push
|
17
|
+
polygon: this.computeTrapez({x: previous.shape.coordinates[1], y: previous.shape.coordinates[0], w: previous.width}, {x: zone.shape.coordinates[1], y: zone.shape.coordinates[0], w: zone.width})
|
18
|
+
value: zone[property]
|
19
|
+
style:
|
20
|
+
stroke: false
|
21
|
+
fillOpacity: 1
|
22
|
+
previous = zone
|
23
|
+
if this.valid()
|
24
|
+
start = new Foliage.Color(options.startColor)
|
25
|
+
stop = new Foliage.Color(options.stopColor)
|
26
|
+
console.log(maxValue, minValue)
|
27
|
+
for item in @items
|
28
|
+
level = (item.value - minValue) / (maxValue - minValue)
|
29
|
+
item.style.fillColor = Foliage.Color.toString
|
30
|
+
red: start.red + (Math.round(stop.red - start.red) * level)
|
31
|
+
green: start.green + (Math.round(stop.green - start.green) * level)
|
32
|
+
blue: start.blue + (Math.round(stop.blue - start.blue) * level)
|
33
|
+
console.log "Bands computed"
|
34
|
+
else
|
35
|
+
console.warn "Invalid bands"
|
36
|
+
|
37
|
+
# Build layer as wanted
|
38
|
+
buildLayerGroup: (widget, globalStyle = {}) ->
|
39
|
+
group = []
|
40
|
+
for item in @items
|
41
|
+
edge = new L.polygon(item.polygon, item.style)
|
42
|
+
group.push(edge)
|
43
|
+
group
|
44
|
+
|
45
|
+
# Build HTML legend for given bands computed layer
|
46
|
+
buildLegend: () ->
|
47
|
+
html = "<div class='leaflet-legend-item' id='legend-#{@layer.name}'>"
|
48
|
+
html += "<h3>#{@layer.label}</h3>"
|
49
|
+
# html += "<div class='leaflet-legend-body leaflet-categories-scale'>"
|
50
|
+
# html += "<span class='leaflet-categories-items'>"
|
51
|
+
# html += "<span class='leaflet-categories-item'>"
|
52
|
+
# html += "<i class='leaflet-categories-sample' style='background-color: #{@items[0].fillColor};'></i>"
|
53
|
+
# html += " #{@layer.label}"
|
54
|
+
# html += "</span>"
|
55
|
+
# html += "</span>"
|
56
|
+
# html += "</div>"
|
57
|
+
html += "</div>"
|
58
|
+
return html
|
59
|
+
|
60
|
+
# Returns the item matching the given name
|
61
|
+
itemFor: (name) ->
|
62
|
+
back = null
|
63
|
+
@items.forEach (item, index, array) ->
|
64
|
+
back = item if item.name == name
|
65
|
+
return back
|
66
|
+
|
67
|
+
# Check if bands are valid
|
68
|
+
valid: () ->
|
69
|
+
@items.length > 0
|
70
|
+
|
71
|
+
# http://stackoverflow.com/questions/7854043/drawing-rectangle-between-two-points-with-arbitrary-width
|
72
|
+
computeTrapez: (a, b) ->
|
73
|
+
# Calculate a vector between start and end points
|
74
|
+
v =
|
75
|
+
x: b.x - a.x
|
76
|
+
y: b.y - a.y
|
77
|
+
|
78
|
+
# Then calculate a perpendicular to it (just swap X and Y coordinates)
|
79
|
+
p =
|
80
|
+
x: v.y # Use separate variable otherwise you overwrite X coordinate here
|
81
|
+
y: -v.x # Flip the sign of either the X or Y (edit by adam.wulf)
|
82
|
+
|
83
|
+
# Normalize that perpendicular
|
84
|
+
l = Math.sqrt(p.x * p.x + p.y * p.y); # That's length of perpendicular
|
85
|
+
n =
|
86
|
+
x: p.x / l
|
87
|
+
y: p.y / l # Now N is normalized perpendicular
|
88
|
+
|
89
|
+
# Calculate 4 points that form a rectangle by adding normalized perpendicular and multiplying it by half of the desired width
|
90
|
+
ar = (a.w / 2) * 9 / 1000000
|
91
|
+
br = (b.w / 2) * 9 / 1000000
|
92
|
+
r1 = new L.LatLng(a.x + n.x * ar, a.y + n.y * ar)
|
93
|
+
r2 = new L.LatLng(a.x - n.x * ar, a.y - n.y * ar)
|
94
|
+
r3 = new L.LatLng(b.x + n.x * br, b.y + n.y * br)
|
95
|
+
r4 = new L.LatLng(b.x - n.x * br, b.y - n.y * br)
|
96
|
+
return [r1, r2, r4, r3]
|
97
|
+
|
98
|
+
|
99
|
+
Foliage.registerLayerType "band", Foliage.Band
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Add sprockets directives below:
|
2
|
+
#= require foliage/gradient
|
3
|
+
#
|
4
|
+
|
5
|
+
class Foliage.Bubbles extends Foliage.Gradient
|
6
|
+
|
7
|
+
constructor: (@layer, @data, options = {}) ->
|
8
|
+
options.levelNumber ?= 5
|
9
|
+
|
10
|
+
super @data, @layer.reference, options
|
11
|
+
|
12
|
+
if this.valid()
|
13
|
+
|
14
|
+
# Compute radius
|
15
|
+
options.startRadius ?= 4
|
16
|
+
options.stopRadius ?= 24
|
17
|
+
start = options.startRadius
|
18
|
+
stop = options.stopRadius
|
19
|
+
for grade in @grades
|
20
|
+
level = grade.index / (@levelNumber - 1.0)
|
21
|
+
grade.radius = start + Math.round((stop - start) * level)
|
22
|
+
grade.fillColor = options.fillColor
|
23
|
+
grade.color = options.color
|
24
|
+
grade.weight = options.weight
|
25
|
+
grade.stroke = options.stroke
|
26
|
+
console.log "Radiuses computed"
|
27
|
+
else
|
28
|
+
console.warn "Invalid bubbles"
|
29
|
+
|
30
|
+
# Build layer as wanted
|
31
|
+
buildLayerGroup: (widget, globalStyle = {}) ->
|
32
|
+
group = []
|
33
|
+
# Shadow
|
34
|
+
for zone in @data
|
35
|
+
grade = this.gradeFor(zone[@layer.reference])
|
36
|
+
if grade.stroke
|
37
|
+
zoneStyle =
|
38
|
+
fillColor: grade.color
|
39
|
+
radius: grade.radius + grade.weight
|
40
|
+
stroke: false
|
41
|
+
fillOpacity: 0.8
|
42
|
+
group.push new L.CircleMarker(this._centroid(zone.shape), zoneStyle)
|
43
|
+
# Core
|
44
|
+
for zone in @data
|
45
|
+
grade = this.gradeFor(zone[@layer.reference])
|
46
|
+
zoneStyle =
|
47
|
+
fillColor: grade.fillColor
|
48
|
+
radius: grade.radius
|
49
|
+
stroke: false
|
50
|
+
fillOpacity: 1
|
51
|
+
zoneLayer = new L.CircleMarker(this._centroid(zone.shape), zoneStyle)
|
52
|
+
widget._bindPopup(zoneLayer, zone)
|
53
|
+
group.push(zoneLayer)
|
54
|
+
group
|
55
|
+
|
56
|
+
# Build HTML legend for given bubbles computed layer
|
57
|
+
buildLegend: () ->
|
58
|
+
html = "<div class='leaflet-legend-item' id='legend-#{@layer.name}'>"
|
59
|
+
html += "<h3>#{@layer.label}</h3>"
|
60
|
+
html += "<div class='leaflet-legend-body leaflet-bubbles-scale'>"
|
61
|
+
html += "<span class='min-value'>#{@grades[0].minLabel}</span>"
|
62
|
+
html += "<span class='leaflet-bubbles-grades'>"
|
63
|
+
for grade in @grades
|
64
|
+
html += "<i class='leaflet-bubbles-grade' style='width: #{2 * grade.radius}px; height: #{2 * grade.radius}px; background-color: #{grade.fillColor}; border-width: #{grade.weight}px; border-color: #{grade.color}' title='#{grade.minLabel} ~ #{grade.maxLabel}'></i>"
|
65
|
+
html += "</span>"
|
66
|
+
html += "<span class='max-value'>#{@grades[@levelNumber - 1].maxLabel}</span>"
|
67
|
+
html += "</div>"
|
68
|
+
html += "</div>"
|
69
|
+
return html
|
70
|
+
|
71
|
+
# Compute a centroid based on bounds
|
72
|
+
# The point can be out of the surface...
|
73
|
+
_centroid: (shape) ->
|
74
|
+
geojson = new L.GeoJSON(shape)
|
75
|
+
return geojson.getBounds().getCenter()
|
76
|
+
|
77
|
+
Foliage.registerLayerType "bubbles", Foliage.Bubbles
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class Foliage.Categories
|
2
|
+
|
3
|
+
constructor: (@layer, @data, options = {}) ->
|
4
|
+
@items = []
|
5
|
+
property = @layer.reference
|
6
|
+
for zone in @data
|
7
|
+
unless this.itemFor(zone[property])
|
8
|
+
@items.push
|
9
|
+
name: zone[property],
|
10
|
+
color: zone['shapeColor']
|
11
|
+
|
12
|
+
if this.valid()
|
13
|
+
@items = @items.sort (a, b) ->
|
14
|
+
a.name > b.name
|
15
|
+
@colors = options.colors ? []
|
16
|
+
if @items.length > @colors.length
|
17
|
+
for x in [@colors.length..@items.length]
|
18
|
+
@colors.push(options.parent.options.colors[x] ? "#000000")
|
19
|
+
for item, index in @items
|
20
|
+
if item.color?
|
21
|
+
item.fillColor = item.color
|
22
|
+
else
|
23
|
+
item.fillColor = @colors[index]
|
24
|
+
|
25
|
+
console.log "Categories computed"
|
26
|
+
else
|
27
|
+
console.warn "Invalid categories"
|
28
|
+
|
29
|
+
# Build layer as wanted
|
30
|
+
buildLayerGroup: (widget, globalStyle = {}) ->
|
31
|
+
group = []
|
32
|
+
for zone in @data
|
33
|
+
zoneStyle =
|
34
|
+
fillColor: this.itemFor(zone[@layer.reference]).fillColor
|
35
|
+
zoneLayer = new L.GeoJSON(zone.shape, $.extend(true, {}, globalStyle, zoneStyle))
|
36
|
+
widget._bindPopup(zoneLayer, zone)
|
37
|
+
unless @layer.withoutGhostLabel
|
38
|
+
label = new L.GhostLabel(className: 'leaflet-ghost-label', toBack: false).setContent(zone.name).toCentroidOfBounds(zoneLayer.getLayers()[0].getLatLngs())
|
39
|
+
widget.ghostLabelCluster.bind label, zoneLayer.getLayers()[0]
|
40
|
+
group.push(zoneLayer)
|
41
|
+
group
|
42
|
+
|
43
|
+
# Build HTML legend for given categories computed layer
|
44
|
+
buildLegend: () ->
|
45
|
+
html = "<div class='leaflet-legend-item' id='legend-#{@layer.name}'>"
|
46
|
+
html += "<h3>#{@layer.label}</h3>"
|
47
|
+
html += "<div class='leaflet-legend-body leaflet-categories-scale'>"
|
48
|
+
html += "<span class='leaflet-categories-items'>"
|
49
|
+
for name, item of @items
|
50
|
+
html += "<span class='leaflet-categories-item'>"
|
51
|
+
html += "<i class='leaflet-categories-sample' style='background-color: #{item.fillColor};'></i>"
|
52
|
+
html += " <span class='leaflet-categories-item_label'>#{item.name}</span>"
|
53
|
+
html += "</span>"
|
54
|
+
html += "</span>"
|
55
|
+
html += "</div>"
|
56
|
+
html += "</div>"
|
57
|
+
return html
|
58
|
+
|
59
|
+
# Returns the item matching the given name
|
60
|
+
itemFor: (name) ->
|
61
|
+
back = null
|
62
|
+
@items.forEach (item, index, array) ->
|
63
|
+
back = item if item.name == name
|
64
|
+
return back
|
65
|
+
|
66
|
+
# Check if categories are valid
|
67
|
+
valid: () ->
|
68
|
+
@items.length > 0
|
69
|
+
|
70
|
+
Foliage.registerLayerType "categories", Foliage.Categories
|