Commit 1e2acdbf authored by Rodrigo Tapia-McClung's avatar Rodrigo Tapia-McClung

Start with empty selection. Add clustered tiles. Tile layers with zooms as...

Start with empty selection. Add clustered  tiles. Tile layers with zooms as parameter. Move circle layer up. Check circle interesection logic.
parent e2441e39
/* /*
* Copyright 2020 - All rights reserved. * Copyright 2020-2021 - All rights reserved.
* Rodrigo Tapia-McClung * Rodrigo Tapia-McClung
* *
* November-December 2020 * November 2020 - January 2021
*/ */
/* global mapboxgl, turf */ /* global mapboxgl, turf */
const baseUrl = new URL(`/data`, window.location.href).href; const baseUrl = new URL(`/data`, window.location.href).href;
let selectedMunis = [{id: "09002", geom: { coordinates: [[ -99.25958633422852, 19.34791392861453 ]], type: "Polygon" }}, {id: "09012", geom: { coordinates: [[ -99.25958633422852, 19.34791392861453 ]], type: "Polygon" }}], //let selectedMunis = [{id: "09002", geom: { coordinates: [[ -99.25958633422852, 19.34791392861453 ]], type: "Polygon" }}, {id: "09012", geom: { coordinates: [[ -99.25958633422852, 19.34791392861453 ]], type: "Polygon" }}],
selectedIDs = selectedMunis.map(m => m.id); // selectedIDs = selectedMunis.map(m => m.id);
let selectedMunis = [],
selectedIDs = [];
//TODO: pass a non-empty selectedIDs array and fetch their corresponding geometries to build the object
// selectedMunis = [{id: "id", geom: geometry}]
// define MVT layer for given table and some attributes // define MVT layer for given table and some attributes
//const mapboxLayer = (table, n, polygon, box) => { //const mapboxLayer = (table, n, polygon, box) => {
const tileSource = (mbtiles) => { const tileSource = (mbtiles, minZoom, maxZoom) => {
// if serving directly from PostGIS, use "source-layer": table, if using mbtiles, use "source-layer": "denue" // if serving directly from PostGIS, use "source-layer": table, if using mbtiles, use "source-layer": "denue"
let pbfSource = { let pbfSource = {
type: "vector", "type": "vector",
tiles: [`${baseUrl}/${mbtiles}/mbtiles/{z}/{x}/{y}.pbf`], "tiles": [`${baseUrl}/${mbtiles}/mbtiles/{z}/{x}/{y}.pbf`],
maxzoom: 14, "minzoom": minZoom,
minzoom: 8 "maxzoom": maxZoom,
/*"type": "symbol", /*"type": "symbol",
"paint": { "paint": {
"icon-opacity": 0.8, "icon-opacity": 0.8,
...@@ -34,7 +39,7 @@ const tileSource = (mbtiles) => { ...@@ -34,7 +39,7 @@ const tileSource = (mbtiles) => {
"icon-allow-overlap": true, "icon-allow-overlap": true,
"icon-ignore-placement": true "icon-ignore-placement": true
}/ }/
type: "heatmap", "type": "heatmap",
"paint": { "paint": {
//"heatmap-opacity": ["case", ["within", polygon], 0.1, 0], //"heatmap-opacity": ["case", ["within", polygon], 0.1, 0],
"heatmap-intensity": 0.1, "heatmap-intensity": 0.1,
...@@ -46,12 +51,12 @@ const tileSource = (mbtiles) => { ...@@ -46,12 +51,12 @@ const tileSource = (mbtiles) => {
} }
let map = new mapboxgl.Map({ let map = new mapboxgl.Map({
container: "mexmap", "container": "mexmap",
accessToken: "pk.eyJ1IjoiZGV2ZWxvcGdlbyIsImEiOiJja2dwcXFic20wYnJnMzBrbG11d3dwYTkyIn0.4WwFOH6C7hDQXV9obU6mAw", "accessToken": "pk.eyJ1IjoiZGV2ZWxvcGdlbyIsImEiOiJja2dwcXFic20wYnJnMzBrbG11d3dwYTkyIn0.4WwFOH6C7hDQXV9obU6mAw",
style: "mapbox://styles/mapbox/dark-v10", "style": "mapbox://styles/mapbox/dark-v10",
center: [-99.17, 19.36], "center": [-99.17, 19.36],
zoom: 9, "zoom": 9,
maxZoom: 20 "maxZoom": 20
}); });
map.addControl(new mapboxgl.NavigationControl()); map.addControl(new mapboxgl.NavigationControl());
...@@ -60,23 +65,23 @@ map.on("style.load", async () => { ...@@ -60,23 +65,23 @@ map.on("style.load", async () => {
// add municipios source // add municipios source
map.addSource("dim_municipio", { map.addSource("dim_municipio", {
type: "vector", "type": "vector",
tiles: [`${baseUrl}/dim_municipio/mvt/{z}/{x}/{y}?geom_column=municipio_geom_4326&columns=municipio_cvegeo`], "tiles": [`${baseUrl}/dim_municipio/mvt/{z}/{x}/{y}?geom_column=municipio_geom_4326&columns=municipio_cvegeo`],
maxzoom: 14, "maxzoom": 14,
minzoom: 8, "minzoom": 8,
"promoteId": {"dim_municipio": "municipio_cvegeo"} "promoteId": {"dim_municipio": "municipio_cvegeo"}
}); });
// create and add denue source // create and add denue source
let denueSource = tileSource("denueC"); let denueSource = tileSource("denueC", 8, 14);
map.addSource("denueC", denueSource); map.addSource("denueC", denueSource);
// add municipios line layer // add municipios line layer
map.addLayer({ map.addLayer({
id: "muni_lines", "id": "muni_lines",
"source-layer": "dim_municipio", "source-layer": "dim_municipio",
source: "dim_municipio", "source": "dim_municipio",
type: "line", "type": "line",
"paint": { "paint": {
"line-opacity": [ "line-opacity": [
"interpolate", "interpolate",
...@@ -97,10 +102,10 @@ map.on("style.load", async () => { ...@@ -97,10 +102,10 @@ map.on("style.load", async () => {
}); });
// add municipios polygon layer // add municipios polygon layer
map.addLayer({ map.addLayer({
id: "muni_polygon", "id": "muni_polygon",
"source-layer": "dim_municipio", "source-layer": "dim_municipio",
source: "dim_municipio", "source": "dim_municipio",
type: "fill", "type": "fill",
"paint": { "paint": {
"fill-color": "rgb(150,150,150)", "fill-color": "rgb(150,150,150)",
"fill-opacity": [ "fill-opacity": [
...@@ -112,22 +117,38 @@ map.on("style.load", async () => { ...@@ -112,22 +117,38 @@ map.on("style.load", async () => {
} }
}); });
// add denue cirle layer filtered by municipios in selectedMunis array map.addSource("circle", {
"type": "geojson",
//"data": "http://localhost:8090/circle.geojson"
"data": new URL(`/circle.geojson`, window.location.href).href
});
map.addLayer({
"id": "circle",
"type": "fill",
"source": "circle",
"layout": {},
"paint": {
"fill-color": "#088",
"fill-opacity": 0.56
}
});
// add denue circle layer filtered by municipios in selectedMunis array
map.addLayer({ map.addLayer({
id: "denue", "id": "denue",
"source-layer": "denue", "source-layer": "denue",
source: denueSource, "source": denueSource,
filter: [ "filter": [
"all", "all",
[ [
"match", "match",
["get", "municipio_cvegeo"], ["get", "municipio_cvegeo"],
selectedIDs, selectedIDs.length > 0 ? selectedIDs : ["sin-clave"],
true, true,
false false
] ]
], ],
type: "circle", "type": "circle",
"paint": { "paint": {
"circle-opacity": 0.5, "circle-opacity": 0.5,
"circle-radius": [ "circle-radius": [
...@@ -172,34 +193,41 @@ map.on("style.load", async () => { ...@@ -172,34 +193,41 @@ map.on("style.load", async () => {
}); });
selectedIDs.forEach( muniID => { selectedIDs.forEach( muniID => {
// set fesature state for each initially selected id
map.setFeatureState({ map.setFeatureState({
source: "dim_municipio", "source": "dim_municipio",
sourceLayer: "dim_municipio", "sourceLayer": "dim_municipio",
id: muniID "id": muniID
}, { }, {
selected: true "selected": true
}); });
}); });
map.addSource("circle", { let clusterSource = tileSource("clusters", 8, 10);
"type": "geojson", map.addSource("clusters", clusterSource);
//"data": "http://localhost:8090/circle.geojson"
"data": new URL(`/circle.geojson`, window.location.href).href
});
map.addLayer({ map.addLayer({
"id": "circle", "id": "clusterLayer",
"type": "fill", "source-layer": "denue_cdmx",
"source": "circle", "type": "circle",
"layout": {}, "source": clusterSource,
"maxZoom": 10,
"paint": { "paint": {
"fill-color": "#088", //"circle-radius": ["interpolate", ["linear"], ["zoom"], 8, 2, 10, 5],
"fill-opacity": 0.56 "circle-radius": ["interpolate", ["linear"], ["get", "point_count"], 10, 2, 10000, 10],
"circle-color": ["match", ["get", "municipio_cvegeo"],
"09002", "#764622",
"09003", "#da5475",
"09004", "#4935ff",
"09005", "#fd9846",
"09006", "#41bd22",
"#676345" //other
]
} }
}); });
}); });
let muniID = null let muniID = null;
muniGeoms = [];
map.on("click", "denue", async e => { map.on("click", "denue", async e => {
// flag we're only clicking denue points // flag we're only clicking denue points
...@@ -234,32 +262,39 @@ map.on("click", "muni_polygon", e => { ...@@ -234,32 +262,39 @@ map.on("click", "muni_polygon", e => {
let muniGeom = e.features[0].geometry; let muniGeom = e.features[0].geometry;
if (selectedMunis.some(e => e.id === muniID)) { // if muni was clicked before if (selectedMunis.some(e => e.id === muniID)) { // if muni was clicked before
map.removeFeatureState({ map.removeFeatureState({
source: "dim_municipio", "source": "dim_municipio",
sourceLayer: "dim_municipio", "sourceLayer": "dim_municipio",
id: muniID "id": muniID
}); });
// remove clicked polygon from array // remove clicked polygon from array
selectedMunis = selectedMunis.filter( el => el.id !== muniID ); selectedMunis = selectedMunis.filter( el => el.id !== muniID );
} else { // if first time clicking muni } else { // if first time clicking muni
map.setFeatureState({ map.setFeatureState({
source: "dim_municipio", "source": "dim_municipio",
sourceLayer: "dim_municipio", "sourceLayer": "dim_municipio",
id: muniID "id": muniID
}, { }, {
selected: true "selected": true
}); });
// add clicked polygon to array // add clicked polygon to array
selectedMunis.push({id: muniID, geom: muniGeom}); selectedMunis.push({id: muniID, geom: muniGeom});
} }
// get array of ids and geoms // get array of ids and geoms
selectedIDs = selectedMunis.map(a => a.id); selectedIDs = selectedMunis.map(a => a.id);
muniGeoms = selectedMunis.map(a => a.geom); //let muniGeoms = selectedMunis.map(a => a.geom);
// check if selectedMunis intersect circle // check if circle is rendered
let circleLayer = map.queryRenderedFeatures( {layers: ["circle"] }); let circleLayer = map.queryRenderedFeatures( {layers: ["circle"] }),
let circleGeom = circleLayer[0].geometry; circleGeom = null,
let muniInteresects = selectedMunis.filter( el => turf.intersect(el.geom, circleGeom)); muniInteresects = [],
let intersectedIDs = muniInteresects.map(a => a.id); intersectedIDs = [];
// if it is, check if selectedMunis intersect circle
if (circleLayer.length > 0) {
circleGeom = circleLayer[0].geometry;
muniInteresects = selectedMunis.filter( el => turf.intersect(el.geom, circleGeom));
intersectedIDs = muniInteresects.map(a => a.id);
}
if (intersectedIDs.length > 0 ) { // if at least one polygons intersects circle geom if (intersectedIDs.length > 0 ) { // if at least one polygons intersects circle geom
// ids not intersecting circle // ids not intersecting circle
...@@ -305,7 +340,6 @@ map.on("click", "muni_polygon", e => { ...@@ -305,7 +340,6 @@ map.on("click", "muni_polygon", e => {
// Change the cursor to a pointer when the mouse is over the denue layer. // Change the cursor to a pointer when the mouse is over the denue layer.
map.on("mouseenter", "denue", () => { map.on("mouseenter", "denue", () => {
map.getCanvas().style.cursor = "pointer"; map.getCanvas().style.cursor = "pointer";
//}
}); });
// Change it back to a pointer when it leaves. // Change it back to a pointer when it leaves.
......
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