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 */
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* August-September 2019 * August-September 2019
*/ */
/* global baseFileSize, formatBytes, Promise, omnivore, JSZip, map, layerControl, updateCharts */ /* global baseFileSize, formatBytes, Promise, omnivore, JSZip, map, layerControl, intervals, updateCharts, odClick*/
/* exported makeBaseMap, baseLayerPromises, drawnItems */ /* exported makeBaseMap, baseLayerPromises, drawnItems */
/* Lines related to displaying loading bar are commented */ /* Lines related to displaying loading bar are commented */
...@@ -19,7 +19,7 @@ let baseLayerPromises = []; ...@@ -19,7 +19,7 @@ let baseLayerPromises = [];
currentBaseLayer = 1;*/ currentBaseLayer = 1;*/
let drawnItems; let drawnItems;
let od, flowMapLayer; let od, flowMapsArray = [];
/*Object.keys(baseFileSize).forEach((name) => { /*Object.keys(baseFileSize).forEach((name) => {
if (name.split(".")[1] == "zip") { if (name.split(".")[1] == "zip") {
...@@ -888,7 +888,119 @@ const toggleButtons = () => { ...@@ -888,7 +888,119 @@ const toggleButtons = () => {
}) })
}*/ }*/
let canvasPointRenderer = L.canvas({ pane: 'pane_flujos' });
const createFlowLayer = (geojson, type, addOnCreate) => {
return new Promise(resolve => {
let canvasBezierStyle = [],
animatedCanvasBezierStyle = [];
// define styles based on properties and values
intervals[type].values.forEach( (val, idx) => {
canvasBezierStyle.push({
classMinValue: idx == 0 ? 0 : intervals[type].values[idx-1] + 1,
classMaxValue: val,
symbol: {
strokeStyle: intervals[type].colors[idx],
lineWidth: intervals[type].thickness[idx],
lineCap: "round",
shadowColor: intervals[type].colors[idx],
shadowBlur: 1.5
}
});
animatedCanvasBezierStyle.push({
classMinValue: idx == 0 ? 0 : intervals[type].values[idx-1] + 1,
classMaxValue: val,
symbol: {
strokeStyle: intervals[type].colors[idx],
lineWidth: intervals[type].animThickness[idx],
lineDashOffsetSize: 4,
lineCap: "round",
shadowColor: intervals[type].colors[idx],
shadowBlur: 1.5
}
})
});
$.getJSON(geojson, data => {
let flowMapLayer = L.canvasFlowmapLayer(data, {
// Define origins and destination from json values
originAndDestinationFieldIds: {
originUniqueIdField: "id_origen",
originGeometry: {
x: "xo",
y: "yo"
},
destinationUniqueIdField: "id_destino",
destinationGeometry: {
x: "xd",
y: "yd"
}
},
// Line styles
canvasBezierStyle: {
type: "classBreaks",
field: "viajes",
classBreakInfos: canvasBezierStyle
},
// Animated line styles
animatedCanvasBezierStyle: {
type: "classBreaks",
field: "viajes",
classBreakInfos: animatedCanvasBezierStyle
},
// dot styles
style: function (geoJsonFeature) {
if (geoJsonFeature.properties.isOrigin) {
return {
renderer: canvasPointRenderer,
radius: 5,
weight: 1,
color: 'rgb(195, 255, 62)',
fillColor: 'rgba(195, 255, 62, 0.6)',
fillOpacity: 0.6
};
} else {
return {
renderer: canvasPointRenderer,
radius: 2.5,
weight: 0.25,
color: 'rgb(17, 142, 170)',
fillColor: 'rgb(17, 142, 170)',
fillOpacity: 0.7
};
}
},
// some custom options
pathDisplayMode: "all",
animationStarted: true,
//animationEasingFamily: "Cubic",
//animationEasingType: "In",
animationEasingFamily: "Linear",
animationEasingType: "None",
animationDuration: 2000,
customLayerId: type,
pane: "pane_flujos"
}).bindTooltip( layer => { // what to display on hover
let coords = layer.getLatLng();
let label = od.features.filter( f => f.properties.lng == coords.lng && f.properties.lat == coords.lat);
return label[0].properties.nombre;
})
// if layer is to be added to on creation, add click funcionality
if (addOnCreate) {
flowMapLayer.addTo(map).on('click', odClick);
}
flowMapsArray.push(flowMapLayer);
resolve(flowMapsArray);
});
});
}
const makeBaseMap = () => { const makeBaseMap = () => {
//return new Promise( resolve=> {
createPane("pane_munis", 402); createPane("pane_munis", 402);
createPane("pane_munis_contexto", 402); createPane("pane_munis_contexto", 402);
createPane("pane_ZMs", 403); createPane("pane_ZMs", 403);
...@@ -981,194 +1093,25 @@ const makeBaseMap = () => { ...@@ -981,194 +1093,25 @@ const makeBaseMap = () => {
od = data; od = data;
}); });
let canvasPointRenderer = L.canvas({ pane: 'pane_flujos' }); // create one flow, then another, then another...
// and finally set reset control funcionality
$.getJSON("data/viajes_ocupados_desde.geojson", data => { createFlowLayer("data/viajes_ocupados_desde.geojson", "ocupadosDesde", true)
flowMapLayer = L.canvasFlowmapLayer(data, { .then( () => createFlowLayer("data/viajes_ocupados_hacia.geojson", "ocupadosHacia") )
// Define origins and destination from json values .then( layers => {
originAndDestinationFieldIds: {
originUniqueIdField: "id_origen",
originGeometry: {
x: "xo",
y: "yo"
},
destinationUniqueIdField: "id_destino",
destinationGeometry: {
x: "xd",
y: "yd"
}
},
// Line styles
canvasBezierStyle: {
type: "classBreaks",
field: "viajes",
classBreakInfos: [{
classMinValue: 0,
classMaxValue: 1000,
symbol: {
strokeStyle: "#00c5ff",
lineWidth: 0.5,
lineCap: "round",
shadowColor: "#00c5ff",
shadowBlur: 1.5
}
}, {
classMinValue: 1001,
classMaxValue: 2000,
symbol: {
strokeStyle: "#008fdc",
lineWidth: 1.5,
lineCap: "round",
shadowColor: "#008fdc",
shadowBlur: 1.5
}
}, {
classMinValue: 2001,
classMaxValue: 6000,
symbol: {
strokeStyle: "#005ce6",
lineWidth: 2,
lineCap: "round",
shadowColor: "#005ce6",
shadowBlur: 1.5
}
}, {
classMinValue: 6001,
classMaxValue: 7200,
symbol: {
strokeStyle: "#4c0073",
lineWidth: 10,
lineCap: "round",
shadowColor: "#4c0073",
shadowBlur: 1.5
}
}]
},
// Animated line styles
animatedCanvasBezierStyle: {
type: "classBreaks",
field: "viajes",
classBreakInfos: [{
classMinValue: 0,
classMaxValue: 1000,
symbol: {
strokeStyle: "#00c5ff",
lineWidth: 0.5,
lineDashOffsetSize: 4,
lineCap: "round",
shadowColor: "#00c5ff",
shadowBlur: 1.5
}
}, {
classMinValue: 1001,
classMaxValue: 2000,
symbol: {
strokeStyle: "#008fdc",
lineWidth: 1.5,
lineDashOffsetSize: 4,
lineCap: "round",
shadowColor: "#008fdc",
shadowBlur: 1.5
}
}, {
classMinValue: 2001,
classMaxValue: 6000,
symbol: {
strokeStyle: "#005ce6",
lineWidth: 4,
lineDashOffsetSize: 4,
lineCap: "round",
shadowColor: "#005ce6",
shadowBlur: 1.5
}
}, {
classMinValue: 6001,
classMaxValue: 7200,
symbol: {
strokeStyle: "#4c0073",
lineWidth: 15,
lineDashOffsetSize: 4,
lineCap: "round",
shadowColor: "#4c0073",
shadowBlur: 1.5
}
}]
},
// dot styles
style: function (geoJsonFeature) {
if (geoJsonFeature.properties.isOrigin) {
return {
renderer: canvasPointRenderer,
radius: 5,
weight: 1,
color: 'rgb(195, 255, 62)',
fillColor: 'rgba(195, 255, 62, 0.6)',
fillOpacity: 0.6
};
} else {
return {
renderer: canvasPointRenderer,
radius: 2.5,
weight: 0.25,
color: 'rgb(17, 142, 170)',
fillColor: 'rgb(17, 142, 170)',
fillOpacity: 0.7
};
}
},
// some custom options
pathDisplayMode: "all",
animationStarted: true,
//animationEasingFamily: "Cubic",
//animationEasingType: "In",
animationEasingFamily: "Linear",
animationEasingType: "None",
animationDuration: 2000,
pane: "pane_flujos"
}).bindTooltip( layer => { // what to display on hover
let coords = layer.getLatLng();
let label = od.features.filter( f => f.properties.lng == coords.lng && f.properties.lat == coords.lat);
return label[0].properties.nombre;
});
flowMapLayer.addTo(map);
// hack to get origins and destinations in desired map pane
//$(".leaflet-pane.leaflet-overlay-pane canvas").detach().appendTo($(".leaflet-pane_flujos-pane"));
// Define what happens when user clicks dots
flowMapLayer.on("click", e => {
// clear paths
flowMapLayer.clearAllPathSelections();
let origins = "";
// select and draw flows from origins
if (e.sharedOriginFeatures.length) {
flowMapLayer.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 = flowMapLayer.originAndDestinationGeoJsonPoints.features.filter( f => f.geometry.coordinates[0] === e.latlng.lng && f.geometry.coordinates[1] === e.latlng.lat);
flowMapLayer.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 dots are only destinations, add paths when clicked on
/*if (e.sharedDestinationFeatures.length) {
flowMapLayer.selectFeaturesForPathDisplay(e.sharedDestinationFeatures, "SELECTION_NEW");
}*/
});
// reset to all flows displayed // reset to all flows displayed
$("#resetFlows").on("click", () => { $("#resetFlows").on("click", () => {
flowMapLayer.selectFeaturesForPathDisplay(flowMapLayer.originAndDestinationGeoJsonPoints.features, "SELECTION_NEW"); layers.forEach( layer => {
if (map.hasLayer(layer)) {
layer.selectFeaturesForPathDisplay(layer.originAndDestinationGeoJsonPoints.features, "SELECTION_NEW");
$("#tblViajesDesde tbody").html(""); $("#tblViajesDesde tbody").html("");
}
});
}); });
//resolve(layers);
}); });
//});
/* // Localize Leaflet.Draw texts /* // Localize Leaflet.Draw texts
L.drawLocal = { L.drawLocal = {
draw: { draw: {
toolbar: { toolbar: {
......
...@@ -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;
}; };
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