Commit 23d86a41 authored by Rodrigo Tapia-McClung's avatar Rodrigo Tapia-McClung

Add legend. Functions to create flows and handle funcionality

parent 0869d678
{
"type": "FeatureCollection",
"name": "viajes_ocupados_hacia",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id_origen": 24035, "muni_origen": "Soledad de Graciano Sánchez", "xo": -100.940833, "yo": 22.183056, "ocupados": "Secundario", "viajes": 53298, "id_destino": 24028, "muni_destino": "San Luis Potosí", "xd": -100.975, "yd": 22.149722, "personas": 53298 }, "geometry": { "type": "Point", "coordinates": [ -100.940833, 22.183056 ] } },
{ "type": "Feature", "properties": { "id_origen": 22006, "muni_origen": "Corregidora", "xo": -100.442, "yo": 20.531, "ocupados": "Primario", "viajes": 32663, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 32663 }, "geometry": { "type": "Point", "coordinates": [ -100.442, 20.531 ] } },
{ "type": "Feature", "properties": { "id_origen": 22011, "muni_origen": "El Marqués", "xo": -100.275248, "yo": 20.687706, "ocupados": "Primario", "viajes": 20108, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 20108 }, "geometry": { "type": "Point", "coordinates": [ -100.275248, 20.687706 ] } },
{ "type": "Feature", "properties": { "id_origen": 1005, "muni_origen": "Jesús María", "xo": -102.343333, "yo": 21.961111, "ocupados": "Secundario", "viajes": 16934, "id_destino": 1001, "muni_destino": "Aguascalientes", "xd": -102.296111, "yd": 21.880833, "personas": 16934 }, "geometry": { "type": "Point", "coordinates": [ -102.343333, 21.961111 ] } },
{ "type": "Feature", "properties": { "id_origen": 11004, "muni_origen": "Apaseo el Alto", "xo": -100.621667, "yo": 20.455556, "ocupados": "Primario", "viajes": 5586, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 5586 }, "geometry": { "type": "Point", "coordinates": [ -100.621667, 20.455556 ] } },
{ "type": "Feature", "properties": { "id_origen": 11037, "muni_origen": "Silao", "xo": -101.426667, "yo": 20.943611, "ocupados": "Primario", "viajes": 4993, "id_destino": 11020, "muni_destino": "León", "xd": -101.680556, "yd": 21.119722, "personas": 4993 }, "geometry": { "type": "Point", "coordinates": [ -101.426667, 20.943611 ] } },
{ "type": "Feature", "properties": { "id_origen": 11009, "muni_origen": "Comonfort", "xo": -100.791667, "yo": 20.716667, "ocupados": "Terciario", "viajes": 4755, "id_destino": 11007, "muni_destino": "Celaya", "xd": -100.815, "yd": 20.528889, "personas": 4755 }, "geometry": { "type": "Point", "coordinates": [ -100.791667, 20.716667 ] } },
{ "type": "Feature", "properties": { "id_origen": 1011, "muni_origen": "San Francisco de los Romo", "xo": -102.270278, "yo": 22.0725, "ocupados": "Secundario", "viajes": 4375, "id_destino": 1001, "muni_destino": "Aguascalientes", "xd": -102.296111, "yd": 21.880833, "personas": 4375 }, "geometry": { "type": "Point", "coordinates": [ -102.270278, 22.0725 ] } },
{ "type": "Feature", "properties": { "id_origen": 22008, "muni_origen": "Huimilpan", "xo": -100.283333, "yo": 20.366667, "ocupados": "Primario", "viajes": 3934, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 3934 }, "geometry": { "type": "Point", "coordinates": [ -100.283333, 20.366667 ] } },
{ "type": "Feature", "properties": { "id_origen": 11044, "muni_origen": "Villagrán", "xo": -100.996389, "yo": 20.511111, "ocupados": "Terciario", "viajes": 3916, "id_destino": 11007, "muni_destino": "Celaya", "xd": -100.815, "yd": 20.528889, "personas": 3916 }, "geometry": { "type": "Point", "coordinates": [ -100.996389, 20.511111 ] } },
{ "type": "Feature", "properties": { "id_origen": 24055, "muni_origen": "Zaragoza", "xo": -100.729722, "yo": 22.039722, "ocupados": "Secundario", "viajes": 3823, "id_destino": 24028, "muni_destino": "San Luis Potosí", "xd": -100.975, "yd": 22.149722, "personas": 3823 }, "geometry": { "type": "Point", "coordinates": [ -100.729722, 22.039722 ] } },
{ "type": "Feature", "properties": { "id_origen": 11031, "muni_origen": "San Francisco del Rincón", "xo": -101.857778, "yo": 21.018333, "ocupados": "Primario", "viajes": 1981, "id_destino": 11020, "muni_destino": "León", "xd": -101.680556, "yd": 21.119722, "personas": 1981 }, "geometry": { "type": "Point", "coordinates": [ -101.857778, 21.018333 ] } },
{ "type": "Feature", "properties": { "id_origen": 11027, "muni_origen": "Salamanca", "xo": -101.195717, "yo": 20.573931, "ocupados": "Terciario", "viajes": 1670, "id_destino": 11017, "muni_destino": "Irapuato", "xd": -101.3475, "yd": 20.674167, "personas": 1670 }, "geometry": { "type": "Point", "coordinates": [ -101.195717, 20.573931 ] } },
{ "type": "Feature", "properties": { "id_origen": 22016, "muni_origen": "San Juan del Río", "xo": -99.996389, "yo": 20.388889, "ocupados": "Primario", "viajes": 1636, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 1636 }, "geometry": { "type": "Point", "coordinates": [ -99.996389, 20.388889 ] } },
{ "type": "Feature", "properties": { "id_origen": 11007, "muni_origen": "Celaya", "xo": -100.815, "yo": 20.528889, "ocupados": "Primario", "viajes": 1301, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 1301 }, "geometry": { "type": "Point", "coordinates": [ -100.815, 20.528889 ] } },
{ "type": "Feature", "properties": { "id_origen": 11011, "muni_origen": "Cortazar", "xo": -100.941667, "yo": 20.433333, "ocupados": "Terciario", "viajes": 751, "id_destino": 11007, "muni_destino": "Celaya", "xd": -100.815, "yd": 20.528889, "personas": 751 }, "geometry": { "type": "Point", "coordinates": [ -100.941667, 20.433333 ] } },
{ "type": "Feature", "properties": { "id_origen": 11017, "muni_origen": "Irapuato", "xo": -101.3475, "yo": 20.674167, "ocupados": "Primario", "viajes": 729, "id_destino": 11020, "muni_destino": "León", "xd": -101.680556, "yd": 21.119722, "personas": 729 }, "geometry": { "type": "Point", "coordinates": [ -101.3475, 20.674167 ] } },
{ "type": "Feature", "properties": { "id_origen": 11009, "muni_origen": "Comonfort", "xo": -100.791667, "yo": 20.716667, "ocupados": "Primario", "viajes": 686, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 686 }, "geometry": { "type": "Point", "coordinates": [ -100.791667, 20.716667 ] } },
{ "type": "Feature", "properties": { "id_origen": 11020, "muni_origen": "León", "xo": -101.680556, "yo": 21.119722, "ocupados": "Terciario", "viajes": 643, "id_destino": 11017, "muni_destino": "Irapuato", "xd": -101.3475, "yd": 20.674167, "personas": 643 }, "geometry": { "type": "Point", "coordinates": [ -101.680556, 21.119722 ] } },
{ "type": "Feature", "properties": { "id_origen": 11003, "muni_origen": "San Miguel de Allende", "xo": -100.743889, "yo": 20.915278, "ocupados": "Primario", "viajes": 622, "id_destino": 22014, "muni_destino": "Querétaro", "xd": -100.391, "yd": 20.591, "personas": 622 }, "geometry": { "type": "Point", "coordinates": [ -100.743889, 20.915278 ] } },
{ "type": "Feature", "properties": { "id_origen": 11025, "muni_origen": "Purísima del Rincón", "xo": -101.879167, "yo": 21.030556, "ocupados": "Primario", "viajes": 506, "id_destino": 11020, "muni_destino": "León", "xd": -101.680556, "yd": 21.119722, "personas": 506 }, "geometry": { "type": "Point", "coordinates": [ -101.879167, 21.030556 ] } }
]
}
...@@ -194,6 +194,12 @@ body { ...@@ -194,6 +194,12 @@ body {
/*text-transform: capitalize;*/ /*text-transform: capitalize;*/
} }
.legendItem {
top: -25%;
position: relative;
padding-left: 10px;
}
/* Footer */ /* Footer */
img.grayscale { img.grayscale {
filter: gray; /* IE6-9 */ filter: gray; /* IE6-9 */
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*/ */
/* globals omnivore, Promise, chroma, makeBaseMap, makeIndicatorGraph, getData, getDataInSelection */ /* globals omnivore, Promise, chroma, makeBaseMap, makeIndicatorGraph, getData, getDataInSelection */
/* exported indicators. userFiles, userDates, timeParse, layerControl, updateCharts */ /* exported indicators. userFiles, userDates, timeParse, layerControl, updateCharts, intervals */
let timeParse, let timeParse,
timeFormat, timeFormat,
...@@ -30,9 +30,15 @@ let timeParse, ...@@ -30,9 +30,15 @@ let timeParse,
// define empty objects and indicators // define empty objects and indicators
let maxIndicators = {}, let maxIndicators = {},
minIndicators = {}, minIndicators = {},
indicators = ["area", "perimeter", "costa", "df"], //indicators = ["area", "perimeter", "costa", "df"],
indicatorsNames = ["Área", "Perímetro", "Desarrollo de la línea de costa", "Dimensión fractal"], indicators = ["ocupadosDesde", "ocupadosHacia", "poicDesde", "poicHacia", "ocupadosEntre", "poicEntre"],
indicatorsUnits = ["m\u00B2", "m", "", ""], indicatorsNames = ["Viajes de ocupados desde centros de mercado", "Viajes de ocupados hacia centros de mercado",
"Viajes de personas en OIC desde centros de mercado", "Viajes de personas en OIC hacia centros de mercado",
"Viajes de ocupados entre zonas", "Viajes de personas en OIC entre zonas"],
indicatorsShortNames = ["Ocupados desde <br/> centros de mercado", "Ocupados hacia <br/> centros de mercado",
"OIC desde centros <br/> de mercado", "OIC hacia centros <br/> de mercado",
"Ocupados entre zonas", "OIC entre zonas"],
//indicatorsUnits = ["m\u00B2", "m", "", ""],
indicatorsxAxisFormat = [".2s", ".2s", ".2f", ".2f"], indicatorsxAxisFormat = [".2s", ".2s", ".2f", ".2f"],
indicatorVars = {}, indicatorVars = {},
cols = []; cols = [];
...@@ -55,6 +61,24 @@ indicators.forEach((indicator, index) => { ...@@ -55,6 +61,24 @@ indicators.forEach((indicator, index) => {
}; };
}); });
let intervals = {
"ocupadosDesde": {
"classes": ["Menos de 1,000", "1,001 - 2,000", "2,001 - 6,000", "6,001 - 7,200"],
"values" : [1000, 2000, 6000, 7200],
"colors": ["#00c5ff", "#008fdc", "#005ce6", "#4c0073"],
"thickness": [0.5, 1.5, 2, 10],
"animThickness": [0.5, 1.5, 4, 15]
},
"ocupadosHacia": {
"classes": ["Menos de 1,000", "1,001 - 2,000", "2,001 - 6,000", "6,001 - 32,000", "32,001 - 53,300"],
"values" : [1000, 2000, 6000, 32000, 533000],
"colors": ["#ffbee8", "#ff73df", "#ff00c5", "#ad027d", "#80006b"],
"thickness": [0.5, 1.5, 2, 4, 10],
"animThickness": [0.5, 1.5, 4, 10, 15]
}
}
/*
indicatorVars.area.explanation = "Muestra la suma del &aacute;rea contenida en los pol&iacute;gonos dentro de la selecci&oacute;n o en toda la regi&oacute;n de estudio."; indicatorVars.area.explanation = "Muestra la suma del &aacute;rea contenida en los pol&iacute;gonos dentro de la selecci&oacute;n o en toda la regi&oacute;n de estudio.";
indicatorVars.perimeter.explanation = "Muestra la suma del per&iacute;metro de los pol&iacute;gonos dentro de la selecci&oacute;n o en toda la regi&oacute;n de estudio."; indicatorVars.perimeter.explanation = "Muestra la suma del per&iacute;metro de los pol&iacute;gonos dentro de la selecci&oacute;n o en toda la regi&oacute;n de estudio.";
indicatorVars.costa.explanation = "Relaciona el per&iacute;metro de un cuerpo de agua o longitud de l&iacute;nea de costa con el per&iacute;metro de un c&iacute;rculo de igual \ indicatorVars.costa.explanation = "Relaciona el per&iacute;metro de un cuerpo de agua o longitud de l&iacute;nea de costa con el per&iacute;metro de un c&iacute;rculo de igual \
...@@ -73,6 +97,7 @@ indicatorVars.df.explanation = "La geometr&iacute;a fractal se usa para hacer re ...@@ -73,6 +97,7 @@ indicatorVars.df.explanation = "La geometr&iacute;a fractal se usa para hacer re
Se calcula como \ Se calcula como \
<p class=\"equation\">DF = <span class=\"frac\"><sup>2 ln(P/4)</sup><span>&frasl;</span><sub>ln(A)</sub></span>,</p> \ <p class=\"equation\">DF = <span class=\"frac\"><sup>2 ln(P/4)</sup><span>&frasl;</span><sub>ln(A)</sub></span>,</p> \
donde P es el per&iacute;metro y A es el &aacute;rea."; donde P es el per&iacute;metro y A es el &aacute;rea.";
*/
let currentTiles = {}, let currentTiles = {},
allTiles = {}; allTiles = {};
...@@ -355,6 +380,35 @@ const getMinMax = table => { ...@@ -355,6 +380,35 @@ const getMinMax = table => {
}); });
} }
const odClick = (e) => {
e.target.clearAllPathSelections();
let origins = "";
// select and draw flows from origins
if (e.sharedOriginFeatures.length) {
e.target.selectFeaturesForPathDisplay(e.sharedOriginFeatures, "SELECTION_NEW");
/*e.sharedOriginFeatures.forEach( origin => {
/ origins += `${origin.properties.muni_origen} &rarr; ${origin.properties.muni_destino}: ${origin.properties.viajes} viajes <br>`;
});*/
}
// select and add flows toward those origins, i.e., for dots that are both origins and destinations
let dests = e.target.originAndDestinationGeoJsonPoints.features.filter( f => f.geometry.coordinates[0] === e.latlng.lng && f.geometry.coordinates[1] === e.latlng.lat);
e.target.selectFeaturesForPathDisplay(dests, "SELECTION_ADD");
dests.forEach( dest => {
//origins += `${dest.properties.muni_origen} &rarr; ${dest.properties.muni_destino}: ${dest.properties.viajes} viajes <br>`;
origins += `<tr><td>${dest.properties.muni_origen}</td><td>${dest.properties.muni_destino}</td><td>${dest.properties.viajes}</td></tr>`;
});
$("#tblViajesDesde tbody").html(origins);
if (e.sharedDestinationFeatures.length) {
e.target.selectFeaturesForPathDisplay(e.sharedDestinationFeatures, "SELECTION_ADD");
}
// if dots are only destinations, add paths when clicked on
/*if (e.sharedDestinationFeatures.length) {
e.target.selectFeaturesForPathDisplay(e.sharedDestinationFeatures, "SELECTION_NEW");
}*/
}
const populateMap = async(mapData) => { const populateMap = async(mapData) => {
// FIX: comment out to avoid DB calls // FIX: comment out to avoid DB calls
...@@ -462,7 +516,9 @@ const populateMap = async(mapData) => { ...@@ -462,7 +516,9 @@ const populateMap = async(mapData) => {
}; };
layerControl = L.control.layers(baseLayers, overlays).addTo(map); layerControl = L.control.layers(baseLayers, overlays).addTo(map);
makeBaseMap(); // basemap.js makeBaseMap() // basemap.js
//.then( flowLayers => { });
legend.addTo(map);
// fix for leaflet-mapbox-gl v. 0.0.11 that adds map's to tile pane: // fix for leaflet-mapbox-gl v. 0.0.11 that adds map's to tile pane:
// get children of map tile pane, create array from it and iterate // get children of map tile pane, create array from it and iterate
...@@ -705,6 +761,23 @@ L.timeDimension.layer.Tile = (layer, options) => { ...@@ -705,6 +761,23 @@ L.timeDimension.layer.Tile = (layer, options) => {
$("#indicatorSelect").on("change", function() { $("#indicatorSelect").on("change", function() {
// style currentTiles // style currentTiles
let option = this.value; // option selected from dropdrown let option = this.value; // option selected from dropdrown
flowMapsArray.forEach( layer => {
if (layer.options.customLayerId === option) {
map.addLayer(layer);
layer.on('click', odClick);
/*layer.getLayers().forEach(l => {
console.log(l.feature.properties._isSelectedForPathDisplay)
});*/
// TODO: Recover each layer state and populate table according to that
// layer._layers[i].feature.properties._isSelectedforPathDisplay
} else {
layer.off("click", odClick);
map.removeLayer(layer);
}
});
styleTiles(option, minIndicators, maxIndicators) styleTiles(option, minIndicators, maxIndicators)
.then(legend.addTo(map)); // add legend control -> it updates .then(legend.addTo(map)); // add legend control -> it updates
// FIXME: re-adding control updates its contents... why? // FIXME: re-adding control updates its contents... why?
...@@ -726,7 +799,7 @@ const styleTiles = (option, minIndicators, maxIndicators) => { ...@@ -726,7 +799,7 @@ const styleTiles = (option, minIndicators, maxIndicators) => {
minIndicators[option], scale(minIndicators[option]).hex(), minIndicators[option], scale(minIndicators[option]).hex(),
maxIndicators[option], scale(maxIndicators[option]).hex() maxIndicators[option], scale(maxIndicators[option]).hex()
]; ];
glmap.getMapboxMap().setPaintProperty(layer, "fill-color", color); //glmap.getMapboxMap().setPaintProperty(layer, "fill-color", color);
}); });
return Promise.resolve(scale); return Promise.resolve(scale);
} }
...@@ -735,20 +808,70 @@ let legend = L.control({ ...@@ -735,20 +808,70 @@ let legend = L.control({
position: "bottomright" position: "bottomright"
}); });
legend.onAdd = () => { legend.onAdd = function() {
let div = L.DomUtil.create("div", "info legend leaflet-bar"); let div = L.DomUtil.create("div", "info legend leaflet-bar");
let option = $("#indicatorSelect").val(); let option = $("#indicatorSelect").val();
let optionIndex = indicators.indexOf(option); let optionIndex = indicators.indexOf(option);
let legendText = indicatorsUnits[optionIndex] == "" ? indicatorsNames[optionIndex] : //let legendText = indicatorsUnits[optionIndex] == "" ? indicatorsNames[optionIndex] :
`${indicatorsNames[optionIndex]} (${indicatorsUnits[optionIndex]})`; // `${indicatorsNames[optionIndex]} (${indicatorsUnits[optionIndex]})`;
var html = `<h6>${legendText}</h6><ul>`;
let classes = scale.classes(); //title
classes.forEach((c, idx, array) => { let title = L.DomUtil.create("h6", "");
title.innerHTML = `${indicatorsShortNames[optionIndex]}`;
div.appendChild(title);
// list
let list = L.DomUtil.create("ul", "");
div.appendChild(list);
//var html = `<h6>${indicatorsShortNames[optionIndex]}</h6><ul>`;
//let domain =
//scale = chroma.scale("PuBu").padding([0.5, 0]).domain(domain).classes(5);
// data
let classes = intervals[option].classes;
//let classes = scale.classes();
/*classes.forEach((c, idx, array) => {
if (idx != array.length - 1) { if (idx != array.length - 1) {
html += `<li><i style="background: ${scale(c).hex()}"></i>${d3.format(",.4~s")(classes[idx])} - ${d3.format(",.4~s")(classes[idx+1])}</li>`; html += `<li><i style="background: ${scale(c).hex()}"></i>${d3.format(",.4~s")(classes[idx])} - ${d3.format(",.4~s")(classes[idx+1])}</li>`;
} }
});*/
// create stuff for each type of flow
classes.forEach( (c, idx) => {
// create list element
let item = L.DomUtil.create('li');
// create canvas element with arc of appropriate thickness ad color
let canvas = L.DomUtil.create('canvas');
let originProp = L.DomUtil.testProp(['transformOrigin', 'WebkitTransformOrigin', 'msTransformOrigin']);
canvas.style[originProp] = '50% 50%';
canvas.width = 18;
canvas.height = 18;
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(18, 18, 15, 1.5 * Math.PI, Math.PI, true);
ctx.lineWidth = intervals[option].thickness[idx];
ctx.lineCap = 'round';
// line color
ctx.strokeStyle = intervals[option].colors[idx];;
ctx.stroke();
// append canvas to list element
item.appendChild(canvas);
// create legend item text
let span = L.DomUtil.create("span", "legendItem");
span.innerText = c;
// append text to list item
item.appendChild(span)
// lastly, append item to list
list.appendChild(item);
}); });
html += "</ul>";
div.innerHTML = html;
return div; return div;
}; };
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment