Upload 2 files
Browse files- 10.11_draw_query_indicators_v10_HF.R +176 -73
- helpers.R +5 -0
10.11_draw_query_indicators_v10_HF.R
CHANGED
|
@@ -1386,6 +1386,15 @@ server <- function(input, output, session) {
|
|
| 1386 |
is_3d <- reactiveVal(FALSE)
|
| 1387 |
is_grid_on <- reactiveVal(FALSE)
|
| 1388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1389 |
rv <- reactiveValues(
|
| 1390 |
n_incidents = "---", n_fatalities = "---",
|
| 1391 |
n_graves = "---", n_facilities = "---",
|
|
@@ -1481,19 +1490,42 @@ server <- function(input, output, session) {
|
|
| 1481 |
)
|
| 1482 |
}
|
| 1483 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1484 |
# Central visibility updater
|
| 1485 |
apply_visibility <- function(active, grid_on, crime_type, nivel, envipe_type, fosas_type = "fosas") {
|
| 1486 |
prx <- maplibre_proxy("map")
|
| 1487 |
|
| 1488 |
for (orig_lid in names(GRID_LAYER_CFG)) {
|
| 1489 |
if (orig_lid == "fosas-choro" && !has_fosas_tbl) next
|
|
|
|
| 1490 |
vis <- if (!grid_on && orig_lid %in% active) "visible" else "none"
|
| 1491 |
prx <- prx |> set_layout_property(orig_lid, "visibility", vis)
|
| 1492 |
}
|
| 1493 |
-
|
| 1494 |
-
|
| 1495 |
-
|
| 1496 |
-
|
|
|
|
| 1497 |
|
| 1498 |
# Sync crime fill color to selected type when grid is OFF
|
| 1499 |
if (!grid_on && "crime-choro" %in% active) {
|
|
@@ -1504,7 +1536,7 @@ server <- function(input, output, session) {
|
|
| 1504 |
}
|
| 1505 |
|
| 1506 |
# Sync fosas fill color to selected sub-type when grid is OFF
|
| 1507 |
-
if (has_fosas_tbl && !grid_on && "fosas-choro" %in% active) {
|
| 1508 |
prx <- prx |> set_paint_property(
|
| 1509 |
"fosas-choro", "fill-color",
|
| 1510 |
fosas_step_expr(fosas_type)
|
|
@@ -1512,6 +1544,7 @@ server <- function(input, output, session) {
|
|
| 1512 |
}
|
| 1513 |
|
| 1514 |
for (lid in NON_GRID_LAYERS) {
|
|
|
|
| 1515 |
prx <- prx |> set_layout_property(
|
| 1516 |
lid, "visibility",
|
| 1517 |
if (lid %in% active) "visible" else "none"
|
|
@@ -1527,9 +1560,15 @@ server <- function(input, output, session) {
|
|
| 1527 |
)
|
| 1528 |
}
|
| 1529 |
|
| 1530 |
-
# Grid fill layers (opacity-based to avoid always-visible init bug)
|
| 1531 |
-
|
| 1532 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1533 |
for (orig_lid in names(GRID_LAYER_CFG)) {
|
| 1534 |
if (orig_lid == "fosas-choro" && !has_fosas_tbl) next
|
| 1535 |
key <- GRID_LAYER_CFG[[orig_lid]]
|
|
@@ -1748,63 +1787,12 @@ server <- function(input, output, session) {
|
|
| 1748 |
}, error = function(e) { message("grid_nivel", niv, ": ", e$message); NULL })
|
| 1749 |
}
|
| 1750 |
|
| 1751 |
-
#
|
| 1752 |
-
|
| 1753 |
-
|
| 1754 |
-
|
| 1755 |
-
|
| 1756 |
-
|
| 1757 |
-
grid4_sf <- grid_sf_list[["4"]]
|
| 1758 |
-
grid5_sf <- grid_sf_list[["5"]]
|
| 1759 |
-
grid6_sf <- grid_sf_list[["6"]]
|
| 1760 |
-
# grid7_sf stays NULL until user first selects N7 (see lazy observer below)
|
| 1761 |
-
desap_sf <- tryCatch({
|
| 1762 |
-
DBI::dbGetQuery(con, web_sql("src_desap")) |>
|
| 1763 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1764 |
-
dplyr::select(-wkt)
|
| 1765 |
-
}, error = function(e) { message("desap: ", e$message); NULL })
|
| 1766 |
-
|
| 1767 |
-
remesas_sf <- tryCatch({
|
| 1768 |
-
DBI::dbGetQuery(con, web_sql("src_remesas")) |>
|
| 1769 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1770 |
-
dplyr::select(-wkt)
|
| 1771 |
-
}, error = function(e) { message("remesas: ", e$message); NULL })
|
| 1772 |
-
|
| 1773 |
-
pam_sf <- tryCatch({
|
| 1774 |
-
DBI::dbGetQuery(con, web_sql("src_pam")) |>
|
| 1775 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1776 |
-
dplyr::select(-wkt)
|
| 1777 |
-
}, error = function(e) { message("pam: ", e$message); NULL })
|
| 1778 |
-
|
| 1779 |
-
fosas_sf <- tryCatch({
|
| 1780 |
-
DBI::dbGetQuery(con, web_sql("src_fosas")) |>
|
| 1781 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1782 |
-
dplyr::select(-wkt)
|
| 1783 |
-
}, error = function(e) { message("dim_fosas_mun: ", e$message); NULL })
|
| 1784 |
-
|
| 1785 |
-
state_sf <- tryCatch({
|
| 1786 |
-
DBI::dbGetQuery(con, web_sql("src_state")) |>
|
| 1787 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1788 |
-
dplyr::select(-wkt)
|
| 1789 |
-
}, error = function(e) { message("state_polygons: ", e$message); NULL })
|
| 1790 |
-
|
| 1791 |
-
routes_sf <- tryCatch({
|
| 1792 |
-
DBI::dbGetQuery(con, web_sql("src_routes")) |>
|
| 1793 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1794 |
-
dplyr::select(-wkt)
|
| 1795 |
-
}, error = function(e) { message("routes: ", e$message); NULL })
|
| 1796 |
-
|
| 1797 |
-
via_sf <- tryCatch({
|
| 1798 |
-
DBI::dbGetQuery(con, web_sql("src_via")) |>
|
| 1799 |
-
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1800 |
-
dplyr::select(-wkt)
|
| 1801 |
-
}, error = function(e) { message("viaferrea: ", e$message); NULL })
|
| 1802 |
-
|
| 1803 |
-
migrants_pts <- load_pts("migrants", 8000)
|
| 1804 |
-
graves_pts <- load_pts("graves", 5000)
|
| 1805 |
-
infra_pts <- load_pts("support_infrastructure", 5000)
|
| 1806 |
-
ocved_pts <- load_pts("ocved_events", 80000)
|
| 1807 |
-
ged_pts <- load_pts("ged_events", 80000)
|
| 1808 |
|
| 1809 |
m <- maplibre(
|
| 1810 |
style = carto_style("positron"),
|
|
@@ -1927,9 +1915,8 @@ server <- function(input, output, session) {
|
|
| 1927 |
)
|
| 1928 |
}
|
| 1929 |
|
| 1930 |
-
#
|
| 1931 |
-
|
| 1932 |
-
m <- add_typed_grid_layers(m, grid_sf_list[[nv]], nv)
|
| 1933 |
|
| 1934 |
# --- Line layers ------------------------------------------------------------
|
| 1935 |
if (!is.null(routes_sf)) {
|
|
@@ -1999,14 +1986,129 @@ server <- function(input, output, session) {
|
|
| 1999 |
}
|
| 2000 |
}, ignoreNULL = TRUE, ignoreInit = TRUE)
|
| 2001 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2002 |
observeEvent(input$clear_btn, {
|
| 2003 |
clear_drawn_features(maplibre_proxy("map"))
|
| 2004 |
load_national_totals()
|
| 2005 |
})
|
| 2006 |
|
| 2007 |
-
|
|
|
|
|
|
|
|
|
|
| 2008 |
load_national_totals()
|
| 2009 |
-
# Populate state filter at startup — avoids renderUI lifecycle issues
|
| 2010 |
tbl_cols <- tryCatch(
|
| 2011 |
DBI::dbGetQuery(con, "DESCRIBE state_polygons")$column_name,
|
| 2012 |
error = function(e) character(0)
|
|
@@ -2022,7 +2124,7 @@ server <- function(input, output, session) {
|
|
| 2022 |
)
|
| 2023 |
updateSelectInput(session, "state_select",
|
| 2024 |
choices = c("Choose a state..." = "", state_ch))
|
| 2025 |
-
}
|
| 2026 |
|
| 2027 |
observeEvent(input$grid_icon_click, {
|
| 2028 |
new_on <- !is_grid_on()
|
|
@@ -2173,8 +2275,9 @@ server <- function(input, output, session) {
|
|
| 2173 |
df <- rv$mun_df
|
| 2174 |
if (is.null(df) || nrow(df) == 0)
|
| 2175 |
return(div(class = "dp-empty", "Draw a polygon or click a municipality to filter."))
|
| 2176 |
-
col_name <- CRIME_COLS[[input$crime_type]]
|
| 2177 |
-
|
|
|
|
| 2178 |
df_sorted <- df[order(df[[col_name]], decreasing = TRUE, na.last = TRUE), ]
|
| 2179 |
top <- head(df_sorted, 5L)
|
| 2180 |
mx <- max(top[[col_name]], na.rm = TRUE)
|
|
|
|
| 1386 |
is_3d <- reactiveVal(FALSE)
|
| 1387 |
is_grid_on <- reactiveVal(FALSE)
|
| 1388 |
|
| 1389 |
+
# Lazy-load flags: each flips to TRUE the first time the layer is added via proxy.
|
| 1390 |
+
lazy_added <- reactiveValues(
|
| 1391 |
+
desap = FALSE, remesas = FALSE, pam = FALSE, fosas = FALSE,
|
| 1392 |
+
state = FALSE, routes = FALSE, via = FALSE,
|
| 1393 |
+
migrants = FALSE, graves = FALSE, infra = FALSE,
|
| 1394 |
+
ocved = FALSE, ged = FALSE,
|
| 1395 |
+
grid4 = FALSE, grid5 = FALSE, grid6 = FALSE
|
| 1396 |
+
)
|
| 1397 |
+
|
| 1398 |
rv <- reactiveValues(
|
| 1399 |
n_incidents = "---", n_fatalities = "---",
|
| 1400 |
n_graves = "---", n_facilities = "---",
|
|
|
|
| 1490 |
)
|
| 1491 |
}
|
| 1492 |
|
| 1493 |
+
# Returns TRUE if the layer has been added to the map (either at render time
|
| 1494 |
+
# or via a lazy proxy call). Prevents set_layout_property on absent layers.
|
| 1495 |
+
layer_ready <- function(id) {
|
| 1496 |
+
switch(id,
|
| 1497 |
+
"crime-choro" = TRUE, "crime-border" = TRUE,
|
| 1498 |
+
"desap-choro" = isTRUE(lazy_added$desap),
|
| 1499 |
+
"remesas-choro" = isTRUE(lazy_added$remesas),
|
| 1500 |
+
"pam-choro" = isTRUE(lazy_added$pam),
|
| 1501 |
+
"fosas-choro" = isTRUE(lazy_added$fosas),
|
| 1502 |
+
"envipe-state" = isTRUE(lazy_added$state),
|
| 1503 |
+
"routes-lines" = isTRUE(lazy_added$routes),
|
| 1504 |
+
"viaferrea-lines"= isTRUE(lazy_added$via),
|
| 1505 |
+
"migrants-pts" = isTRUE(lazy_added$migrants),
|
| 1506 |
+
"graves-pts" = isTRUE(lazy_added$graves),
|
| 1507 |
+
"infra-pts" = isTRUE(lazy_added$infra),
|
| 1508 |
+
"ocved-pts" = isTRUE(lazy_added$ocved),
|
| 1509 |
+
"ged-pts" = isTRUE(lazy_added$ged),
|
| 1510 |
+
grepl("^grid-", id)
|
| 1511 |
+
)
|
| 1512 |
+
}
|
| 1513 |
+
|
| 1514 |
# Central visibility updater
|
| 1515 |
apply_visibility <- function(active, grid_on, crime_type, nivel, envipe_type, fosas_type = "fosas") {
|
| 1516 |
prx <- maplibre_proxy("map")
|
| 1517 |
|
| 1518 |
for (orig_lid in names(GRID_LAYER_CFG)) {
|
| 1519 |
if (orig_lid == "fosas-choro" && !has_fosas_tbl) next
|
| 1520 |
+
if (!layer_ready(orig_lid)) next
|
| 1521 |
vis <- if (!grid_on && orig_lid %in% active) "visible" else "none"
|
| 1522 |
prx <- prx |> set_layout_property(orig_lid, "visibility", vis)
|
| 1523 |
}
|
| 1524 |
+
if (layer_ready("crime-border"))
|
| 1525 |
+
prx <- prx |> set_layout_property(
|
| 1526 |
+
"crime-border", "visibility",
|
| 1527 |
+
if (!grid_on && "crime-choro" %in% active) "visible" else "none"
|
| 1528 |
+
)
|
| 1529 |
|
| 1530 |
# Sync crime fill color to selected type when grid is OFF
|
| 1531 |
if (!grid_on && "crime-choro" %in% active) {
|
|
|
|
| 1536 |
}
|
| 1537 |
|
| 1538 |
# Sync fosas fill color to selected sub-type when grid is OFF
|
| 1539 |
+
if (has_fosas_tbl && !grid_on && "fosas-choro" %in% active && layer_ready("fosas-choro")) {
|
| 1540 |
prx <- prx |> set_paint_property(
|
| 1541 |
"fosas-choro", "fill-color",
|
| 1542 |
fosas_step_expr(fosas_type)
|
|
|
|
| 1544 |
}
|
| 1545 |
|
| 1546 |
for (lid in NON_GRID_LAYERS) {
|
| 1547 |
+
if (!layer_ready(lid)) next
|
| 1548 |
prx <- prx |> set_layout_property(
|
| 1549 |
lid, "visibility",
|
| 1550 |
if (lid %in% active) "visible" else "none"
|
|
|
|
| 1560 |
)
|
| 1561 |
}
|
| 1562 |
|
| 1563 |
+
# Grid fill layers (opacity-based to avoid always-visible init bug).
|
| 1564 |
+
# Skip niveles that haven't been lazy-loaded yet.
|
| 1565 |
+
loaded_niv <- c(
|
| 1566 |
+
if (isTRUE(lazy_added$grid4)) "4",
|
| 1567 |
+
if (isTRUE(lazy_added$grid5)) "5",
|
| 1568 |
+
if (isTRUE(lazy_added$grid6)) "6",
|
| 1569 |
+
if (grid7_loaded()) "7"
|
| 1570 |
+
)
|
| 1571 |
+
for (niv in loaded_niv) {
|
| 1572 |
for (orig_lid in names(GRID_LAYER_CFG)) {
|
| 1573 |
if (orig_lid == "fosas-choro" && !has_fosas_tbl) next
|
| 1574 |
key <- GRID_LAYER_CFG[[orig_lid]]
|
|
|
|
| 1787 |
}, error = function(e) { message("grid_nivel", niv, ": ", e$message); NULL })
|
| 1788 |
}
|
| 1789 |
|
| 1790 |
+
# Only crime_sf is loaded at render time (the only visible-by-default layer).
|
| 1791 |
+
# All other layers load lazily the first time the user enables them.
|
| 1792 |
+
desap_sf <- NULL; remesas_sf <- NULL; pam_sf <- NULL
|
| 1793 |
+
fosas_sf <- NULL; state_sf <- NULL; routes_sf <- NULL; via_sf <- NULL
|
| 1794 |
+
migrants_pts <- NULL; graves_pts <- NULL; infra_pts <- NULL
|
| 1795 |
+
ocved_pts <- NULL; ged_pts <- NULL
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1796 |
|
| 1797 |
m <- maplibre(
|
| 1798 |
style = carto_style("positron"),
|
|
|
|
| 1915 |
)
|
| 1916 |
}
|
| 1917 |
|
| 1918 |
+
# Grid N4-6 load lazily on first user interaction (see lazy_add_grid observer).
|
| 1919 |
+
# Nothing added here at render time.
|
|
|
|
| 1920 |
|
| 1921 |
# --- Line layers ------------------------------------------------------------
|
| 1922 |
if (!is.null(routes_sf)) {
|
|
|
|
| 1986 |
}
|
| 1987 |
}, ignoreNULL = TRUE, ignoreInit = TRUE)
|
| 1988 |
|
| 1989 |
+
# Lazy layer loader helpers — load on first use via proxy.
|
| 1990 |
+
lazy_add_fill <- function(key, sql_name, id, make_layer_fn) {
|
| 1991 |
+
if (isTRUE(lazy_added[[key]]) || is.null(con)) return()
|
| 1992 |
+
sf_data <- tryCatch({
|
| 1993 |
+
DBI::dbGetQuery(con, web_sql(sql_name)) |>
|
| 1994 |
+
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 1995 |
+
dplyr::select(-wkt)
|
| 1996 |
+
}, error = function(e) { message("lazy ", id, ": ", e$message); NULL })
|
| 1997 |
+
if (!is.null(sf_data)) {
|
| 1998 |
+
make_layer_fn(maplibre_proxy("map"), sf_data)
|
| 1999 |
+
lazy_added[[key]] <<- TRUE
|
| 2000 |
+
}
|
| 2001 |
+
}
|
| 2002 |
+
lazy_add_pts <- function(key, tbl, id, color, radius = 2, limit = 80000) {
|
| 2003 |
+
if (isTRUE(lazy_added[[key]]) || is.null(con)) return()
|
| 2004 |
+
pts <- load_pts(tbl, limit)
|
| 2005 |
+
if (!is.null(pts)) {
|
| 2006 |
+
maplibre_proxy("map") |>
|
| 2007 |
+
add_circle_layer(
|
| 2008 |
+
id = id, source = pts,
|
| 2009 |
+
circle_color = color, circle_radius = radius,
|
| 2010 |
+
circle_opacity = 0.75,
|
| 2011 |
+
circle_stroke_color = "rgba(0,0,0,0.4)",
|
| 2012 |
+
circle_stroke_width = 0.7,
|
| 2013 |
+
visibility = if (id %in% (input$active_layers %||% "")) "visible" else "none"
|
| 2014 |
+
)
|
| 2015 |
+
lazy_added[[key]] <<- TRUE
|
| 2016 |
+
}
|
| 2017 |
+
}
|
| 2018 |
+
lazy_add_grid <- function(nv_chr) {
|
| 2019 |
+
key <- paste0("grid", nv_chr)
|
| 2020 |
+
if (isTRUE(lazy_added[[key]]) || is.null(con)) return()
|
| 2021 |
+
sf_data <- tryCatch({
|
| 2022 |
+
DBI::dbGetQuery(con, web_sql_grid_unified(as.integer(nv_chr), has_fosas_tbl)) |>
|
| 2023 |
+
sf::st_as_sf(wkt = "wkt", crs = 4326) |>
|
| 2024 |
+
dplyr::select(-wkt)
|
| 2025 |
+
}, error = function(e) { message("lazy grid n", nv_chr, ": ", e$message); NULL })
|
| 2026 |
+
if (!is.null(sf_data)) {
|
| 2027 |
+
maplibre_proxy("map") |> add_typed_grid_layers(sf_data, nv_chr)
|
| 2028 |
+
lazy_added[[key]] <<- TRUE
|
| 2029 |
+
}
|
| 2030 |
+
}
|
| 2031 |
+
|
| 2032 |
+
# Observer fires when any layer toggle or grid state changes.
|
| 2033 |
+
# Loads each dataset the first time its layer becomes potentially visible.
|
| 2034 |
+
observeEvent(
|
| 2035 |
+
eventExpr = list(input$active_layers, is_grid_on(), input$grid_nivel),
|
| 2036 |
+
handlerExpr = {
|
| 2037 |
+
active <- input$active_layers %||% character(0)
|
| 2038 |
+
grid_on <- is_grid_on()
|
| 2039 |
+
nivel <- input$grid_nivel %||% "6"
|
| 2040 |
+
|
| 2041 |
+
# Choropleth / line layers (all hidden by default)
|
| 2042 |
+
if (!grid_on && "desap-choro" %in% active)
|
| 2043 |
+
lazy_add_fill("desap", "src_desap", "desap-choro", function(prx, d)
|
| 2044 |
+
prx |> add_fill_layer("desap-choro", source = d,
|
| 2045 |
+
fill_color = desap_qstep_expr(), fill_opacity = 0.6,
|
| 2046 |
+
tooltip = list("concat", "<b>", list("get","municipio"), "</b>",
|
| 2047 |
+
"<br>Disappearances: ", list("to-string", list("get","desap_per_100k")), " /100k")))
|
| 2048 |
+
if (!grid_on && "remesas-choro" %in% active)
|
| 2049 |
+
lazy_add_fill("remesas", "src_remesas", "remesas-choro", function(prx, d)
|
| 2050 |
+
prx |> add_fill_layer("remesas-choro", source = d,
|
| 2051 |
+
fill_color = giim_match_expr(), fill_opacity = 0.75,
|
| 2052 |
+
tooltip = list("concat", "<b>", list("get","municipio"), "</b>",
|
| 2053 |
+
"<br>Migration intensity: <b>", list("get","giim_mun"), "</b>")))
|
| 2054 |
+
if (!grid_on && "pam-choro" %in% active)
|
| 2055 |
+
lazy_add_fill("pam", "src_pam", "pam-choro", function(prx, d)
|
| 2056 |
+
prx |> add_fill_layer("pam-choro", source = d,
|
| 2057 |
+
fill_color = pam_qstep_expr(), fill_opacity = 0.7,
|
| 2058 |
+
tooltip = list("concat", "<b>", list("get","municipio"), "</b>",
|
| 2059 |
+
"<br>Irregular migration events: ", list("to-string", list("get","pam_n")))))
|
| 2060 |
+
if (!grid_on && "fosas-choro" %in% active && has_fosas_tbl)
|
| 2061 |
+
lazy_add_fill("fosas", "src_fosas", "fosas-choro", function(prx, d)
|
| 2062 |
+
prx |> add_fill_layer("fosas-choro", source = d,
|
| 2063 |
+
fill_color = fosas_step_expr("fosas"), fill_opacity = 0.65,
|
| 2064 |
+
tooltip = list("concat", "<b>", list("get","municipio"), "</b>",
|
| 2065 |
+
"<br>Burial pits: ", list("to-string", list("get","fosas_total")),
|
| 2066 |
+
"<br>Bodies: ", list("to-string", list("get","cuerpos_total")))))
|
| 2067 |
+
if ("envipe-state" %in% active)
|
| 2068 |
+
lazy_add_fill("state", "src_state", "envipe-state", function(prx, d)
|
| 2069 |
+
prx |> add_fill_layer("envipe-state", source = d,
|
| 2070 |
+
fill_color = step_expr("insecurity_perc", c(40,55,65,75,85), ENVIPE_PAL),
|
| 2071 |
+
fill_opacity = 0.6,
|
| 2072 |
+
tooltip = list("concat", "<b>", list("get","desc_entidad"), "</b>",
|
| 2073 |
+
"<br>Insecurity: ", list("to-string", list("get","insecurity_perc")), "%",
|
| 2074 |
+
"<br>Dark figures: ", list("to-string", list("get","dark_figures_perc")), "%")))
|
| 2075 |
+
if ("routes-lines" %in% active)
|
| 2076 |
+
lazy_add_fill("routes", "src_routes", "routes-lines", function(prx, d)
|
| 2077 |
+
prx |> add_line_layer("routes-lines", source = d,
|
| 2078 |
+
line_color = COL_AMBER,
|
| 2079 |
+
line_width = list("interpolate", list("linear"), list("zoom"), 5, 0.5, 10, 2.0),
|
| 2080 |
+
line_opacity = 0.1))
|
| 2081 |
+
if ("viaferrea-lines" %in% active)
|
| 2082 |
+
lazy_add_fill("via", "src_via", "viaferrea-lines", function(prx, d)
|
| 2083 |
+
prx |> add_line_layer("viaferrea-lines", source = d,
|
| 2084 |
+
line_color = "#990f0f", line_width = 1.5, line_opacity = 0.9,
|
| 2085 |
+
line_dasharray = c(4, 2)))
|
| 2086 |
+
|
| 2087 |
+
# Point layers
|
| 2088 |
+
if ("migrants-pts" %in% active) lazy_add_pts("migrants", "migrants", "migrants-pts", COL_YEL, 2, 8000)
|
| 2089 |
+
if ("graves-pts" %in% active) lazy_add_pts("graves", "graves", "graves-pts", COL_RED, 2, 5000)
|
| 2090 |
+
if ("infra-pts" %in% active) lazy_add_pts("infra", "support_infrastructure", "infra-pts", COL_GREEN, 2, 5000)
|
| 2091 |
+
if ("ocved-pts" %in% active) lazy_add_pts("ocved", "ocved_events", "ocved-pts", COL_AMBER, 1, 80000)
|
| 2092 |
+
if ("ged-pts" %in% active) lazy_add_pts("ged", "ged_events", "ged-pts", COL_LIGHT_BLUE, 1, 80000)
|
| 2093 |
+
|
| 2094 |
+
# Grid niveles N4-N6 load the first time the user enables grid mode
|
| 2095 |
+
if (grid_on) {
|
| 2096 |
+
for (nv in c("4", "5", "6")) lazy_add_grid(nv)
|
| 2097 |
+
}
|
| 2098 |
+
},
|
| 2099 |
+
ignoreNULL = TRUE, ignoreInit = TRUE
|
| 2100 |
+
)
|
| 2101 |
+
|
| 2102 |
observeEvent(input$clear_btn, {
|
| 2103 |
clear_drawn_features(maplibre_proxy("map"))
|
| 2104 |
load_national_totals()
|
| 2105 |
})
|
| 2106 |
|
| 2107 |
+
# Defer sidebar data queries to after the first UI flush so the map renders
|
| 2108 |
+
# immediately and the user sees the interface before numbers arrive.
|
| 2109 |
+
session$onFlushed(function() {
|
| 2110 |
+
if (is.null(con)) return()
|
| 2111 |
load_national_totals()
|
|
|
|
| 2112 |
tbl_cols <- tryCatch(
|
| 2113 |
DBI::dbGetQuery(con, "DESCRIBE state_polygons")$column_name,
|
| 2114 |
error = function(e) character(0)
|
|
|
|
| 2124 |
)
|
| 2125 |
updateSelectInput(session, "state_select",
|
| 2126 |
choices = c("Choose a state..." = "", state_ch))
|
| 2127 |
+
}, once = TRUE)
|
| 2128 |
|
| 2129 |
observeEvent(input$grid_icon_click, {
|
| 2130 |
new_on <- !is_grid_on()
|
|
|
|
| 2275 |
df <- rv$mun_df
|
| 2276 |
if (is.null(df) || nrow(df) == 0)
|
| 2277 |
return(div(class = "dp-empty", "Draw a polygon or click a municipality to filter."))
|
| 2278 |
+
col_name <- (CRIME_COLS[[input$crime_type %||% ""]] %||%
|
| 2279 |
+
CRIME_COLS[["Homicide rate"]])$col
|
| 2280 |
+
if (is.null(col_name) || !col_name %in% names(df)) col_name <- "homicidio"
|
| 2281 |
df_sorted <- df[order(df[[col_name]], decreasing = TRUE, na.last = TRUE), ]
|
| 2282 |
top <- head(df_sorted, 5L)
|
| 2283 |
mx <- max(top[[col_name]], na.rm = TRUE)
|
helpers.R
CHANGED
|
@@ -54,6 +54,11 @@ ddb_connect <- function(path = ":memory:", remote = FALSE, read_only = FALSE) {
|
|
| 54 |
DBI::dbExecute(con, "LOAD httpfs")
|
| 55 |
}
|
| 56 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
}
|
| 58 |
con
|
| 59 |
}
|
|
|
|
| 54 |
DBI::dbExecute(con, "LOAD httpfs")
|
| 55 |
}
|
| 56 |
)
|
| 57 |
+
# Cache parquet footers and keep TCP connections alive across queries.
|
| 58 |
+
tryCatch({
|
| 59 |
+
DBI::dbExecute(con, "SET enable_http_metadata_cache = true")
|
| 60 |
+
DBI::dbExecute(con, "SET http_keep_alive = true")
|
| 61 |
+
}, error = function(e) invisible(NULL))
|
| 62 |
}
|
| 63 |
con
|
| 64 |
}
|