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
*
* November-December 2020
* November 2020 - January 2021
*/
/* global mapboxgl, turf */
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" }}],
selectedIDs = selectedMunis.map(m => m.id);
//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);
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
//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"
let pbfSource = {
type: "vector",
tiles: [`${baseUrl}/${mbtiles}/mbtiles/{z}/{x}/{y}.pbf`],
maxzoom: 14,
minzoom: 8
"type": "vector",
"tiles": [`${baseUrl}/${mbtiles}/mbtiles/{z}/{x}/{y}.pbf`],
"minzoom": minZoom,
"maxzoom": maxZoom,
/*"type": "symbol",
"paint": {
"icon-opacity": 0.8,
......@@ -34,7 +39,7 @@ const tileSource = (mbtiles) => {
"icon-allow-overlap": true,
"icon-ignore-placement": true
}/
type: "heatmap",
"type": "heatmap",
"paint": {
//"heatmap-opacity": ["case", ["within", polygon], 0.1, 0],
"heatmap-intensity": 0.1,
......@@ -46,12 +51,12 @@ const tileSource = (mbtiles) => {
}
let map = new mapboxgl.Map({
container: "mexmap",
accessToken: "pk.eyJ1IjoiZGV2ZWxvcGdlbyIsImEiOiJja2dwcXFic20wYnJnMzBrbG11d3dwYTkyIn0.4WwFOH6C7hDQXV9obU6mAw",
style: "mapbox://styles/mapbox/dark-v10",
center: [-99.17, 19.36],
zoom: 9,
maxZoom: 20
"container": "mexmap",
"accessToken": "pk.eyJ1IjoiZGV2ZWxvcGdlbyIsImEiOiJja2dwcXFic20wYnJnMzBrbG11d3dwYTkyIn0.4WwFOH6C7hDQXV9obU6mAw",
"style": "mapbox://styles/mapbox/dark-v10",
"center": [-99.17, 19.36],
"zoom": 9,
"maxZoom": 20
});
map.addControl(new mapboxgl.NavigationControl());
......@@ -60,23 +65,23 @@ map.on("style.load", async () => {
// add municipios source
map.addSource("dim_municipio", {
type: "vector",
tiles: [`${baseUrl}/dim_municipio/mvt/{z}/{x}/{y}?geom_column=municipio_geom_4326&columns=municipio_cvegeo`],
maxzoom: 14,
minzoom: 8,
"type": "vector",
"tiles": [`${baseUrl}/dim_municipio/mvt/{z}/{x}/{y}?geom_column=municipio_geom_4326&columns=municipio_cvegeo`],
"maxzoom": 14,
"minzoom": 8,
"promoteId": {"dim_municipio": "municipio_cvegeo"}
});
// create and add denue source
let denueSource = tileSource("denueC");
let denueSource = tileSource("denueC", 8, 14);
map.addSource("denueC", denueSource);
// add municipios line layer
map.addLayer({
id: "muni_lines",
"id": "muni_lines",
"source-layer": "dim_municipio",
source: "dim_municipio",
type: "line",
"source": "dim_municipio",
"type": "line",
"paint": {
"line-opacity": [
"interpolate",
......@@ -97,10 +102,10 @@ map.on("style.load", async () => {
});
// add municipios polygon layer
map.addLayer({
id: "muni_polygon",
"id": "muni_polygon",
"source-layer": "dim_municipio",
source: "dim_municipio",
type: "fill",
"source": "dim_municipio",
"type": "fill",
"paint": {
"fill-color": "rgb(150,150,150)",
"fill-opacity": [
......@@ -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({
id: "denue",
"id": "denue",
"source-layer": "denue",
source: denueSource,
filter: [
"source": denueSource,
"filter": [
"all",
[
"match",
["get", "municipio_cvegeo"],
selectedIDs,
selectedIDs.length > 0 ? selectedIDs : ["sin-clave"],
true,
false
]
],
type: "circle",
"type": "circle",
"paint": {
"circle-opacity": 0.5,
"circle-radius": [
......@@ -172,34 +193,41 @@ map.on("style.load", async () => {
});
selectedIDs.forEach( muniID => {
// set fesature state for each initially selected id
map.setFeatureState({
source: "dim_municipio",
sourceLayer: "dim_municipio",
id: muniID
"source": "dim_municipio",
"sourceLayer": "dim_municipio",
"id": muniID
}, {
selected: true
"selected": true
});
});
map.addSource("circle", {
"type": "geojson",
//"data": "http://localhost:8090/circle.geojson"
"data": new URL(`/circle.geojson`, window.location.href).href
});
let clusterSource = tileSource("clusters", 8, 10);
map.addSource("clusters", clusterSource);
map.addLayer({
"id": "circle",
"type": "fill",
"source": "circle",
"layout": {},
"id": "clusterLayer",
"source-layer": "denue_cdmx",
"type": "circle",
"source": clusterSource,
"maxZoom": 10,
"paint": {
"fill-color": "#088",
"fill-opacity": 0.56
//"circle-radius": ["interpolate", ["linear"], ["zoom"], 8, 2, 10, 5],
"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
muniGeoms = [];
let muniID = null;
map.on("click", "denue", async e => {
// flag we're only clicking denue points
......@@ -234,32 +262,39 @@ map.on("click", "muni_polygon", e => {
let muniGeom = e.features[0].geometry;
if (selectedMunis.some(e => e.id === muniID)) { // if muni was clicked before
map.removeFeatureState({
source: "dim_municipio",
sourceLayer: "dim_municipio",
id: muniID
"source": "dim_municipio",
"sourceLayer": "dim_municipio",
"id": muniID
});
// remove clicked polygon from array
selectedMunis = selectedMunis.filter( el => el.id !== muniID );
} else { // if first time clicking muni
map.setFeatureState({
source: "dim_municipio",
sourceLayer: "dim_municipio",
id: muniID
"source": "dim_municipio",
"sourceLayer": "dim_municipio",
"id": muniID
}, {
selected: true
"selected": true
});
// add clicked polygon to array
selectedMunis.push({id: muniID, geom: muniGeom});
}
// get array of ids and geoms
selectedIDs = selectedMunis.map(a => a.id);
muniGeoms = selectedMunis.map(a => a.geom);
//let muniGeoms = selectedMunis.map(a => a.geom);
// check if selectedMunis intersect circle
let circleLayer = map.queryRenderedFeatures( {layers: ["circle"] });
let circleGeom = circleLayer[0].geometry;
let muniInteresects = selectedMunis.filter( el => turf.intersect(el.geom, circleGeom));
let intersectedIDs = muniInteresects.map(a => a.id);
// check if circle is rendered
let circleLayer = map.queryRenderedFeatures( {layers: ["circle"] }),
circleGeom = null,
muniInteresects = [],
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
// ids not intersecting circle
......@@ -305,7 +340,6 @@ map.on("click", "muni_polygon", e => {
// Change the cursor to a pointer when the mouse is over the denue layer.
map.on("mouseenter", "denue", () => {
map.getCanvas().style.cursor = "pointer";
//}
});
// 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