POC of a choropleth layer
This commit is contained in:
parent
31ea8d1a83
commit
8e12e6cf24
6 changed files with 98 additions and 4 deletions
|
@ -34,6 +34,7 @@
|
||||||
"homepage": "http://wiki.openstreetmap.org/wiki/UMap",
|
"homepage": "http://wiki.openstreetmap.org/wiki/UMap",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tmcw/togeojson": "^5.8.0",
|
"@tmcw/togeojson": "^5.8.0",
|
||||||
|
"chroma-js": "^2.4.2",
|
||||||
"csv2geojson": "5.1.1",
|
"csv2geojson": "5.1.1",
|
||||||
"dompurify": "^3.0.3",
|
"dompurify": "^3.0.3",
|
||||||
"georsstogeojson": "^0.1.0",
|
"georsstogeojson": "^0.1.0",
|
||||||
|
|
|
@ -26,5 +26,6 @@ mkdir -p umap/static/umap/vendors/tokml && cp -r node_modules/tokml/tokml.js uma
|
||||||
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css umap/static/umap/vendors/locatecontrol/
|
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css umap/static/umap/vendors/locatecontrol/
|
||||||
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/src/L.Control.Locate.js umap/static/umap/vendors/locatecontrol/
|
mkdir -p umap/static/umap/vendors/locatecontrol/ && cp -r node_modules/leaflet.locatecontrol/src/L.Control.Locate.js umap/static/umap/vendors/locatecontrol/
|
||||||
mkdir -p umap/static/umap/vendors/dompurify/ && cp -r node_modules/dompurify/dist/purify.js umap/static/umap/vendors/dompurify/
|
mkdir -p umap/static/umap/vendors/dompurify/ && cp -r node_modules/dompurify/dist/purify.js umap/static/umap/vendors/dompurify/
|
||||||
|
mkdir -p umap/static/umap/vendors/chroma/ && cp -r node_modules/chroma-js/chroma.min.js umap/static/umap/vendors/chroma/
|
||||||
|
|
||||||
echo 'Done!'
|
echo 'Done!'
|
||||||
|
|
|
@ -283,7 +283,7 @@ L.U.FeatureMixin = {
|
||||||
} else if (L.Util.usableOption(this.properties._umap_options, option)) {
|
} else if (L.Util.usableOption(this.properties._umap_options, option)) {
|
||||||
value = this.properties._umap_options[option]
|
value = this.properties._umap_options[option]
|
||||||
} else if (this.datalayer) {
|
} else if (this.datalayer) {
|
||||||
value = this.datalayer.getOption(option)
|
value = this.datalayer.getOption(option, this)
|
||||||
} else {
|
} else {
|
||||||
value = this.map.getOption(option)
|
value = this.map.getOption(option)
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,6 +379,7 @@ L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
|
||||||
['Default', L._('Default')],
|
['Default', L._('Default')],
|
||||||
['Cluster', L._('Clustered')],
|
['Cluster', L._('Clustered')],
|
||||||
['Heat', L._('Heatmap')],
|
['Heat', L._('Heatmap')],
|
||||||
|
['Choropleth', L._('Choropleth')],
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,94 @@ L.U.Layer.Cluster = L.MarkerClusterGroup.extend({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
||||||
|
_type: 'Choropleth',
|
||||||
|
includes: [L.U.Layer],
|
||||||
|
canBrowse: true,
|
||||||
|
|
||||||
|
initialize: function (datalayer) {
|
||||||
|
this.datalayer = datalayer
|
||||||
|
if (!L.Util.isObject(this.datalayer.options.choropleth)) {
|
||||||
|
this.datalayer.options.choropleth = {}
|
||||||
|
}
|
||||||
|
L.FeatureGroup.prototype.initialize.call(
|
||||||
|
this,
|
||||||
|
[],
|
||||||
|
this.datalayer.options.choropleth
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
computeLimits: function () {
|
||||||
|
const values = []
|
||||||
|
this.datalayer.eachLayer((layer) => values.push(layer.properties.density))
|
||||||
|
this.options.limits = chroma.limits(
|
||||||
|
values,
|
||||||
|
this.datalayer.options.choropleth.mode || 'q',
|
||||||
|
this.datalayer.options.choropleth.steps || 5
|
||||||
|
)
|
||||||
|
const color = this.datalayer.getOption('color')
|
||||||
|
this.options.colors = chroma
|
||||||
|
.scale(['white', color])
|
||||||
|
.colors(this.options.limits.length)
|
||||||
|
},
|
||||||
|
|
||||||
|
getColor: function (feature) {
|
||||||
|
if (!feature) return // FIXME shold not happen
|
||||||
|
const featureValue = feature.properties.density
|
||||||
|
// Find the bucket/step/limit that this value is less than and give it that color
|
||||||
|
for (let i = 0; i < this.options.limits.length; i++) {
|
||||||
|
if (featureValue <= this.options.limits[i]) {
|
||||||
|
return this.options.colors[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getOption: function (option, feature) {
|
||||||
|
if (option === 'fillColor' || option === 'color') return this.getColor(feature)
|
||||||
|
},
|
||||||
|
|
||||||
|
addLayer: function (layer) {
|
||||||
|
this.computeLimits()
|
||||||
|
L.FeatureGroup.prototype.addLayer.call(this, layer)
|
||||||
|
},
|
||||||
|
|
||||||
|
removeLayer: function (layer) {
|
||||||
|
this.computeLimits()
|
||||||
|
L.FeatureGroup.prototype.removeLayer.call(this, layer)
|
||||||
|
},
|
||||||
|
|
||||||
|
onAdd: function (map) {
|
||||||
|
this.computeLimits()
|
||||||
|
L.FeatureGroup.prototype.onAdd.call(this, map)
|
||||||
|
},
|
||||||
|
|
||||||
|
getEditableOptions: function () {
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'options.choropleth.steps',
|
||||||
|
{
|
||||||
|
handler: 'IntInput',
|
||||||
|
placeholder: L._('Choropleth steps'),
|
||||||
|
helpText: L._('Choropleth steps (default 5)'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'options.choropleth.mode',
|
||||||
|
{
|
||||||
|
handler: 'Select',
|
||||||
|
selectOptions: [
|
||||||
|
['q', L._('quantile')],
|
||||||
|
['e', L._('equidistant')],
|
||||||
|
['l', L._('logarithmic')],
|
||||||
|
['k', L._('k-mean')],
|
||||||
|
],
|
||||||
|
helpText: L._('Choropleth mode'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
L.U.Layer.Heat = L.HeatLayer.extend({
|
L.U.Layer.Heat = L.HeatLayer.extend({
|
||||||
_type: 'Heat',
|
_type: 'Heat',
|
||||||
includes: [L.U.Layer],
|
includes: [L.U.Layer],
|
||||||
|
@ -897,8 +985,6 @@ L.U.DataLayer = L.Evented.extend({
|
||||||
'options.fillOpacity',
|
'options.fillOpacity',
|
||||||
]
|
]
|
||||||
|
|
||||||
shapeOptions = shapeOptions.concat(this.layer.getEditableOptions())
|
|
||||||
|
|
||||||
const redrawCallback = function (field) {
|
const redrawCallback = function (field) {
|
||||||
this.hide()
|
this.hide()
|
||||||
this.layer.postUpdate(field)
|
this.layer.postUpdate(field)
|
||||||
|
@ -1050,7 +1136,11 @@ L.U.DataLayer = L.Evented.extend({
|
||||||
this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
|
this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
|
||||||
},
|
},
|
||||||
|
|
||||||
getOption: function (option) {
|
getOption: function (option, feature) {
|
||||||
|
if (this.layer && this.layer.getOption) {
|
||||||
|
const value = this.layer.getOption(option, feature)
|
||||||
|
if (value) return value
|
||||||
|
}
|
||||||
if (L.Util.usableOption(this.options, option)) return this.options[option]
|
if (L.Util.usableOption(this.options, option)) return this.options[option]
|
||||||
else return this.map.getOption(option)
|
else return this.map.getOption(option)
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/tokml/tokml.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/tokml/tokml.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/locatecontrol/L.Control.Locate.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/locatecontrol/L.Control.Locate.js"></script>
|
||||||
<script src="{{ STATIC_URL }}umap/vendors/dompurify/purify.js"></script>
|
<script src="{{ STATIC_URL }}umap/vendors/dompurify/purify.js"></script>
|
||||||
|
<script src="{{ STATIC_URL }}umap/vendors/chroma/chroma.min.js"></script>
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
{% if locale %}<script src="{{ STATIC_URL }}umap/locale/{{ locale }}.js"></script>{% endif %}
|
{% if locale %}<script src="{{ STATIC_URL }}umap/locale/{{ locale }}.js"></script>{% endif %}
|
||||||
{% compress js %}
|
{% compress js %}
|
||||||
|
|
Loading…
Reference in a new issue