Objetivo

💡 Atualmente, estou desenvolvendo um projeto voltado para o mapeamento de congestionamentos urbanos, analisando seus padrões de origem e propagação. Para isso, levo em consideração tanto os elementos da rede viária quanto aspectos do ambiente construído, buscando compreender os fatores que influenciam a formação e dispersão do tráfego intenso.

🔍 Com isso pretendo elaborar uma análise multidimensional através da união de estrutura (grafos), complexidade (fractais) e contexto (ambiente construído) para modelagem da estrutura urbana de mobilidade.

Com esses três aspectos posso implementar camadas de contexto urbano e integrar dados do ambiente construído, como:

Grafos

✨ Como muitos congestionamentos têm origem nas interseções, pretendo avaliá-los por meio de métricas da teoria dos grafos, identificando padrões estruturais que podem impactar diretamente a fluidez do trânsito e a mobilidade urbana

🔹 Por que usar grafos para entender congestionamentos?
📌 Interseções como vértices: As interseções rodoviárias funcionam como nós da rede, sendo pontos cruciais na propagação do congestionamento.
📌 Ruas como arestas: As conexões entre interseções formam as arestas, determinando como o fluxo de tráfego se desloca.
📌 Centralidade de intermediação (betweenness): Identifica nós estratégicos que atuam como gargalos—pontos onde o congestionamento tende a se formar.
📌 Centralidade de proximidade (closeness): Mostra quais interseções estão mais acessíveis, podendo afetar a dispersão do tráfego.
📌 Centralidade de grau (degree): Avalia o número de conexões de uma interseção, indicando se ela tem muitas entradas e saídas e como isso pode impactar a fluidez.
📌 Propagação do congestionamento: Usando propriedades do grafo, é possível analisar como os padrões de trânsito evoluem e prever zonas críticas antes que se tornem problemáticas.
🔹 Vantagens da abordagem com grafos
✅ Permite uma visualização estruturada da rede viária e dos padrões de tráfego.
✅ Quantifica impactos de cruzamentos críticos no fluxo geral.
✅ Ajuda no planejamento urbano, permitindo ajustes estratégicos para reduzir congestionamentos.
✅ Pode ser combinado com dados de ambiente construído, como largura das ruas e presença de semáforos, para análises mais precisas.

Fractais

🔹 Por que usar fractais para entender congestionamentos urbanos?

📌 Auto-semelhança urbana:
Cidades crescem de forma desigual, mas com padrões que se repetem em várias escalas — bairros, ruas e cruzamentos muitas vezes refletem estruturas maiores. Fractais ajudam a captar essa auto-organização espacial.
📌 Complexidade da malha viária:
Redes de tráfego apresentam ramificações, aglomerações e zonas periféricas que não são bem descritas por geometria tradicional. Já a geometria fractal abraça essa complexidade.
📌 Medição da rugosidade e dispersão:
A dimensão fractal permite quantificar a irregularidade e fragmentação da malha viária, o que afeta diretamente como o tráfego se espalha e onde ele tende a se acumular.
📌 Previsibilidade da propagação:
Sistemas com estrutura fractal costumam ter zonas críticas recorrentes. Ao entender a estrutura fractal, é possível prever como um congestionamento pode se espalhar de forma não-linear.
📌 Escalas múltiplas de análise:
Fractais funcionam bem desde o nível macro (zonas inteiras de uma cidade) até o micro (interseções locais), permitindo integrar diferentes camadas de análise — inclusive o ambiente construído.

✅ Vantagens da abordagem fractal
- Mensuração objetiva da complexidade urbana
- Integração com modelos dinâmicos de propagação (como SIR, percolação ou CA)
- Complementaridade com as métricas de centralidade do grafo
- Aplicável a dados espaciais vetoriais ou raster
- Base para simulações de cenários urbanos com alta fidelidad

Objetivo específico

Criar um grafo que incorpore dados da rede viária permitindo que análises de grafos e fractais possam ser realizadas sobre a rede viária em nós de interesse.

Na figura abaixo podemos ver que o objeto no mapa e o grafo compartilham um mesmo valor de atributo que se chama osm_id, esse atributo é a ID do link fornecida pelo Open Street Maps (OSM).

Resultado esperado: Grafo com arestas de mesmo ID das Ruas do arquivo shape

Resultado esperado: Grafo com arestas de mesmo ID das Ruas do arquivo shape

Pipeline

Carregar bibliotecas

library(sf)
library(igraph)
library(visNetwork)
library(dplyr)
library(mapview)

🏙 1. Importar e preparar a rede viária

ruas <- st_read("C:/Users/fagne/OneDrive/SIG/sul-latest-free.shp/OSM_POA/OSM_PoA/OSM_PoA.shp")
## Reading layer `OSM_PoA' from data source 
##   `C:\Users\fagne\OneDrive\SIG\sul-latest-free.shp\OSM_POA\OSM_PoA\OSM_PoA.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 42439 features and 10 fields
## Geometry type: MULTILINESTRING
## Dimension:     XY
## Bounding box:  xmin: -51.29933 ymin: -30.26926 xmax: -51.01163 ymax: -29.94017
## Geodetic CRS:  WGS 84

Nesse caso estou trabalhando apenas com vias arteriais

ruas <- ruas[ruas$highway %in% c("primary", "primary_link", "secondary", "secondary_link"), ]
ruas <- st_transform(ruas, 4326)

Recortar para uma área específica

Aqui criamos um bounding box para definir uma área específica para análise dentro da rede de arteriais que carregamos.

bbox <- st_bbox(c(xmin = -51.13754, ymin = -30.03429, xmax = -51.12969, ymax = -30.02931), 
                crs = st_crs(4326))


# plinio
bbox <- st_bbox(c(xmin = -51.186075, ymin = -30.022909, xmax = -51.183189, ymax = -30.020670),                 crs = st_crs(4326))# WGS 84

# Converter para um objeto sf (polígono)
bbox_sf <- st_as_sfc(bbox)

# Visualizar com mapview
mapview(bbox_sf, col.regions = "red", alpha = 0.3)

Visualizar o subset

Aqui já é possível visualizar a rede compreendida no bounding box.

ruas <- st_crop(ruas, bbox)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
mapview(ruas)

🌍 2. Garantir que cada rua seja um único segmento e preservar osm_id

ruas_segmentadas <- ruas %>%
  st_cast("LINESTRING") %>%
  group_by(osm_id) %>%
  summarise(geometry = st_union(geometry), .groups = "drop") %>%
  mutate(osm_id = as.character(osm_id), edge_id = row_number())  # Criar um ID único para cada segmento

📌 3. Extrair coordenadas corretamente

coords <- st_coordinates(ruas_segmentadas)

🔗 4. Criar lista única de nós com base nas coordenadas

nodes <- data.frame(
  X = coords[, "X"], 
  Y = coords[, "Y"]
) %>%
  distinct() %>%
  mutate(id = row_number())  # Atribuir um ID único para cada nó

🔗 5. Criar arestas e manter correspondência correta com osm_id

coords <- st_coordinates(ruas_segmentadas)  # Extrair coordenadas corretamente

Criar edges

edges_temp <- data.frame(
  osm_id = rep(ruas_segmentadas$osm_id, sapply(st_geometry(ruas_segmentadas), function(g) nrow(st_coordinates(g)))),
  X = coords[, "X"],
  Y = coords[, "Y"]
)

Ajustar edges corretamente

edges <- edges_temp %>%
  group_by(osm_id) %>%
  summarise(from.X = first(X), from.Y = first(Y),  
            to.X = last(X), to.Y = last(Y)) %>%
  left_join(nodes, by = c("from.X" = "X", "from.Y" = "Y")) %>%
  rename(from = id) %>%
  left_join(nodes, by = c("to.X" = "X", "to.Y" = "Y")) %>%
  rename(to = id) %>%
  left_join(ruas_segmentadas %>% select(osm_id, edge_id, geometry), by = "osm_id") %>%
  mutate(original_id = osm_id)  # Agora `osm_id` será corretamente preservado

edges <- edges %>%
  dplyr::select(from, to, original_id, edge_id)

nodes <- nodes %>%
  filter(id %in% c(edges$from, edges$to))

🔎 6. Verificar correspondência entre edges e ruas

print(nrow(ruas_segmentadas))  # Deve ser igual ao número de edges
## [1] 18
print(nrow(edges))  # Deve ser igual ao número de ruas
## [1] 18

🗺 7. Visualizar edges_temp no mapview

edges_sf <- edges_temp %>%
  st_as_sf(coords = c("X", "Y"), crs = 4326)  # Converter para spatial dataframe

mapview(edges_sf, zcol="osm_id") + mapview(ruas, zcol="osm_id")

🏗 8. Criar grafo com igraph

grafo <- graph_from_data_frame(edges, directed = TRUE)
plot(grafo, vertex.label = NA, main = "Grafo da Rede Viaria")

📊 9. Obter métricas do grafo

Número de vértices

Os vértices representam os nós da rede—no seu caso, podem ser interseções de ruas ou pontos específicos no mapa.
- Vértices altos: Indica uma rede viária complexa, com muitas interseções.
- Vértices baixos: Pode representar caminhos mais diretos, com menos pontos de decisão.

print(vcount(grafo))  
## [1] 17

Número de arestas

As arestas representam conexões entre os vértices—ou seja, as ruas ou caminhos entre interseções.
- Arestas altas: Indica uma rede viária bem interligada, com múltiplas rotas possíveis.
- Arestas baixas: Pode significar poucas alternativas, o que pode afetar o fluxo de tráfego.

print(ecount(grafo))  
## [1] 18

Densidade do grafo ou Densidade da rede

Mede quão conectada está a rede.
- Densidade alta: Muitas conexões entre nós, indicando um centro urbano compacto.
- Densidade baixa: Rede mais espalhada, típica de áreas suburbanas.

print(edge_density(grafo))  
## [1] 0.06617647

Grau dos nós ou Centralidade de Grau

O grau de um nó é o número de conexões que ele possui.
- Nó de alto grau: Muito conectado, pode ser um ponto central na rede viária.
- Nó de baixo grau: Poucas conexões, pode ser um cul-de-sac ou um cruzamento menos utilizado.

Essa métrica indica quantos vizinhos imediatos um nó possui.
- Nó com alto grau: Muito conectado, pode ser um ponto de grande fluxo na rede viária.
- Nó com baixo grau: Poucas conexões, pode representar um beco sem saída ou um cruzamento menos movimentado.

print(degree(grafo))  
##  1  3  8 13 15 17 23 25 28 30 35 29 12  7 22 34 43 
##  1  4  3  4  1  4  2  1  1  4  2  2  3  1  1  1  1

Centralidade de intermediação

Mede quantas vezes um nó é usado como “ponte” entre outros.
- Nó com alta betweenness: Crucial para conectar diferentes partes da rede.
- Nó com baixa betweenness: Menos importante para a conectividade global.

print(betweenness(grafo))  
##  1  3  8 13 15 17 23 25 28 30 35 29 12  7 22 34 43 
##  0 44  9 46  0 47  9  0  0 50 18 10 12  0  0  0  0

Centralidade de proximidade

A centralidade de proximidade (closeness) mede o quão rapidamente um nó pode alcançar todos os outros na rede. Ela ajuda a identificar pontos estratégicos para navegação e mobilidade. 🚀
- Um nó com alta proximidade pode chegar rapidamente a todos os outros pontos da rede.
- Um nó com baixa proximidade está mais isolado, levando mais tempo para alcançar os demais.
Isso é útil, por exemplo, para planejamento urbano, indicando interseções centrais que facilitam o tráfego.
Fórmula matemática
A proximidade de um nó ( u ) é calculada como:
\[C(u) = \frac{1}{\sum d(u, v)}\]
onde ( d(u, v) ) representa a distância mais curta entre o nó ( u ) e todos os outros ( v ).
Quanto menor a soma das distâncias, maior a proximidade!

print(closeness(grafo))  
##          1          3          8         13         15         17         23 
## 0.03448276 0.05000000 0.04000000 0.05555556 0.02857143 0.05263158 0.03571429 
##         25         28         30         35         29         12          7 
## 0.02631579 0.01960784 0.04761905 0.03333333 0.02500000 1.00000000        NaN 
##         22         34         43 
##        NaN        NaN        NaN

Diâmetro do grafo

Representa a maior distância entre dois nós da rede.
- Diâmetro grande: Cidade extensa, onde os extremos estão longe.
- Diâmetro pequeno: Cidade compacta, tudo está perto.

print(diameter(grafo))  
## [1] 8

Atribuir comunidades aos nós

# comunidades <- cluster_louvain(grafo)
# V(grafo)$comunidade <- membership(comunidades)  

🌐 10. Criar visualização interativa com visNetwork

Primeiro criamos o identificador de ID dos vértices

nodes_vis <- data.frame(
  id = nodes$id, 
  label = nodes$id, 
  title = paste("ID:", nodes$id)  # Exibir ID ao passar o mouse
)

Depois o identificador de ID das arestas

edges_vis <- edges %>%
  mutate(
    title = paste("Rua OSM ID:", original_id),  # Exibir ao passar o mouse
   # osm =   original_id,  # Exibir ao passar o mouse
    label = original_id  # Exibir diretamente no grafo
  ) %>%
  dplyr::select(from, to, title, label)  # Removido erro de texto extra
#edges_vis$title <- as.character(edges_vis$original_id)  # Converter para texto legível

Por fim, mantemos apenas vértices ligados efetivamente Às arestas

nodes_vis <- nodes_vis %>%
  filter(id %in% c(edges_vis$from, edges_vis$to))

Então, exibimos a rede

 visNetwork(nodes_vis, edges_vis) %>%
   visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
   visLegend(position = "right")
edges_vis <- edges_vis %>%
  mutate(
    comprimento_km = 1,#as.numeric(st_length(geometry)) / 1000,  # exemplo com comprimento da rua
    peso_congestionamento = 2,#1 / (faixas + 1) + as.numeric(tem_semaforo) + densidade_edif,
    info_tooltip = paste("Comprimento",comprimento_km, "<br>Peso:", peso_congestionamento,"<br>Faixas:", NA, "<br>Semáforo:", NA, "<br>Densidade:", NA)
  )

edges_vis$title <- edges_vis$info_tooltip

edges_vis$label <- paste0("ID: ", edges_vis$label)
visNetwork(nodes_vis, edges_vis) 

Grupamento de vértices por comunidades

nodes_vis <- data.frame(
  id = nodes$id, 
  label = nodes$id, 
  title = paste("ID:", nodes$id),  # Exibir ID ao passar o mouse
  group = nodes$id  # Atribuir o grupo baseado na comunidade
 #group = V(grafo)$comunidade  # Atribuir o grupo baseado na comunidade
)

Customizamos as cores de exibição das comunidades

nodes_vis$color <- rainbow(length(unique(nodes_vis$group)))[nodes_vis$group]

edges_vis <- edges %>%
  mutate(title = paste("Rua OSM ID:", original_id), label = original_id) %>%
  dplyr::select(from, to, original_id)

Geramos o grafo de comunidades

visNetwork(nodes_vis, edges_vis) %>%
  visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
  visGroups(groupname = unique(nodes_vis$group)) %>%
  visLegend(position = "right")

Fractais

Ah, os fractais… uma beleza caótica que ainda está no forno! 🔥

A análise fractal pode revelar padrões ocultos na estrutura da sua rede viária e ajudar a entender sua complexidade. Aqui estão alguns passos para transformar sua rede em um fractal e realizar a análise:

1️⃣ Converter a Rede em um Fractal Método de Box-Counting: Uma abordagem comum para medir a dimensão fractal de redes espaciais. Você pode dividir sua rede em uma grade de diferentes tamanhos e contar quantas células contêm partes da rede.

Método de Similaridade: Algumas redes viárias apresentam padrões de auto-semelhança, onde segmentos menores se parecem com a estrutura maior. Você pode testar isso aplicando subdivisões iterativas.

2️⃣ Calcular a Dimensão Fractal Use a função fractaldim() do pacote fractal no R para calcular a dimensão fractal da rede.

Outra opção é usar boxcount() do pacote pracma, que implementa o método de contagem de caixas.

3️⃣ Analisar Propriedades Fractais Distribuição de Grau: Redes fractais muitas vezes seguem distribuições de potência. Você pode verificar isso com fit_power_law() do pacote igraph.

Centralidade e Caminhos: A análise de betweenness e closeness pode revelar padrões fractais na conectividade da rede.

4️⃣ Visualização Fractal Você pode usar ggplot2 para criar gráficos que mostram a estrutura fractal da rede.

O pacote tidygraph pode ajudar a visualizar padrões de auto-semelhança.

1️⃣ Cálculo da Dimensão Fractal com Box-Counting Este método divide a rede em uma grade e conta quantas células contêm partes da rede.

🧠 O que é a Dimensão Fractal? - É uma medida da complexidade espacial de um objeto irregular — como uma rede de ruas ou o contorno de uma cidade. - A dimensão fractal indica o grau em que o padrão “enche” o espaço: quanto mais fragmentado ou ramificado, maior a dimensão (embora nunca exceda o valor inteiro do espaço: em 2D, nunca passa de 2).

📦 Box-Counting: Como funciona a técnica? A ideia do método é: - Cobrir o conjunto de pontos com uma malha de quadrados de tamanho size - Contar quantos quadrados contêm pelo menos um ponto - Repetir com diferentes tamanhos de quadrado - Plotar o resultado em escala log-log para estimar a dimensão fractal com uma regressão

📊 Interpretação - Uma rede viária mais orgânica, como em centros históricos, tende a ter dimensão fractal mais alta - Redes muito regulares ou planejadas (como malhas retangulares) têm dimensões mais próximas de 1

library(pracma)

# Função para calcular a dimensão fractal usando Box-Counting
box_counting <- function(points, sizes) {
  counts <- sapply(sizes, function(size) {
    grid_x <- seq(min(points$X), max(points$X), by = size)
    grid_y <- seq(min(points$Y), max(points$Y), by = size)
    count <- sum(sapply(grid_x, function(x) {
      sum(sapply(grid_y, function(y) {
        any(points$X >= x & points$X < x + size & points$Y >= y & points$Y < y + size)
      }))
    }))
    return(count)
  })
  return(data.frame(size = sizes, count = counts))
}

# Aplicação sobre os nós da rede
#- Varia o tamanho das caixas de 0.001 a 0.01 (em unidades do espaço — pode ser km, graus, etc.)
sizes <- seq(0.001, 0.01, by = 0.001)
sizes <- seq(10, 1000, by = 10)  # tamanhos das caixas em metros
result <- box_counting(nodes, sizes)



# Ajuste log-log para estimar a dimensão fractal
#plot(log(result$size), log(result$count), type = "b", main = "Dimensão Fractal da Rede Viária")
plot(log(result$size / 1000), log(result$count), type = "b",
     xlab = "Log(Tamanho da caixa em km)", ylab = "Log(Contagem)",
     main = "Dimensão Fractal da Rede Viária")

2️⃣ Distribuição de Grau e Ajuste de Lei de Potência Redes fractais frequentemente seguem distribuições de potência.

library(igraph)

# Ajuste de Lei de Potência
fit <- fit_power_law(degree(grafo))
print(fit)
## $continuous
## [1] FALSE
## 
## $alpha
## [1] 1.932962
## 
## $xmin
## [1] 1
## 
## $logLik
## [1] -28.13125
## 
## $KS.stat
## [1] 0.1343017

3️⃣ Visualização Fractal Podemos visualizar padrões fractais na rede.

library(ggplot2)

ggplot(nodes, aes(x = X, y = Y)) +
  geom_point(color = "blue", alpha = 0.5) +
  theme_minimal() +
  ggtitle("Visualização Fractal da Rede Viária")

library(igraph)

# Criar o grafo a partir das arestas
grafo <- graph_from_data_frame(edges, directed = FALSE)
# Calcular betweenness centrality
betweenness_values <- betweenness(grafo, normalized = TRUE)
betweenness_values
##         1         3         8        13        15        17        23        25 
## 0.0000000 0.3250000 0.1250000 0.4833333 0.0000000 0.4041667 0.1250000 0.0000000 
##        28        30        35        29        12         7        22        34 
## 0.0000000 0.4875000 0.2333333 0.1250000 0.1250000 0.0000000 0.0000000 0.0000000 
##        43 
## 0.0000000
# Calcular closeness centrality
closeness_values <- closeness(grafo, normalized = TRUE)
closeness_values
##         1         3         8        13        15        17        23        25 
## 0.3018868 0.4210526 0.3555556 0.4705882 0.2666667 0.4324324 0.3200000 0.2461538 
##        28        30        35        29        12         7        22        34 
## 0.2162162 0.4571429 0.3478261 0.2711864 0.3555556 0.3018868 0.3076923 0.3200000 
##        43 
## 0.2666667
# Adicionar os valores aos nós
nodes$betweenness <- betweenness_values[nodes$id]
nodes$closeness <- closeness_values[nodes$id]
# Visualizar os resultados
print(summary(nodes$betweenness))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##  0.0000  0.0000  0.0625  0.0625  0.1250  0.1250       9
print(summary(nodes$closeness))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##  0.2462  0.2701  0.3048  0.3031  0.3289  0.3556       9
# Visualizar graficamente
library(ggplot2)

ggplot(nodes, aes(x = betweenness)) +
  geom_histogram(bins = 30, fill = "blue", alpha = 0.7) +
  theme_minimal() +
  ggtitle("Distribuição da Centralidade Betweenness")
## Warning: Removed 9 rows containing non-finite outside the scale range
## (`stat_bin()`).

ggplot(nodes, aes(x = closeness)) +
  geom_histogram(bins = 30, fill = "red", alpha = 0.7) +
  theme_minimal() +
  ggtitle("Distribuição da Centralidade Closeness")
## Warning: Removed 9 rows containing non-finite outside the scale range
## (`stat_bin()`).

1️⃣ Dimensão de Hausdorff Este método mede a complexidade da rede considerando sua auto-semelhança.

Uma dimensão alta como essa pode indicar que o conjunto ocupa muito espaço (ou grau de liberdade) dentro do espaço de origem.

Em análise fractal: seria um objeto extremamente intricado em múltiplas escalas.

A dimensão de Hausdorff, nesse contexto, quantifica como o número de vizinhos acessíveis cresce com a escala.

Em redes rodoviárias, ela pode indicar densidade de conexões e redundância geográfica (por exemplo, número de caminhos alternativos entre regiões).

Uma dimensão alta, como 31.7, sugere que o grafo é extremamente ramificado, com muitas possibilidades de movimento, rotas e interconexões — talvez até que os dados estejam em um espaço de atributos muito rico (tempo, fluxo, tipo de via, etc.).

library(geometry)
## 
## Attaching package: 'geometry'
## The following objects are masked from 'package:pracma':
## 
##     cart2pol, cart2sph, dot, pol2cart, polyarea, sph2cart
# Função para calcular a dimensão de Hausdorff
hausdorff_dim <- function(points) {
  dist_matrix <- dist(points)
  return(max(dist_matrix) / min(dist_matrix))
}

# Aplicação sobre os nós da rede
hausdorff_value <- hausdorff_dim(nodes[, c("X", "Y")])
print(paste("Dimensão de Hausdorff:", hausdorff_value))
## [1] "Dimensão de Hausdorff: 31.7283359883424"

2️⃣ Análise de Percolação Estuda a conectividade da rede e como ela se fragmenta.

library(igraph)

# Remover aleatoriamente 10% das arestas e verificar conectividade
grafo_removido <- delete_edges(grafo, sample(E(grafo), length(E(grafo)) * 0.1))
components <- components(grafo_removido)

print(paste("Número de componentes após remoção:", components$no))
## [1] "Número de componentes após remoção: 2"

3️⃣ Distribuição de Lei de Potência Verifica se a rede segue uma distribuição fractal.

library(igraph)

# Ajuste de Lei de Potência
fit <- fit_power_law(degree(grafo))
print(fit)
## $continuous
## [1] FALSE
## 
## $alpha
## [1] 1.932962
## 
## $xmin
## [1] 1
## 
## $logLik
## [1] -28.13125
## 
## $KS.stat
## [1] 0.1343017

4️⃣ Dimensão Fractal da Fronteira Mede a irregularidade das bordas da rede.

#devtools::install_github ("mariodosreis/fractal")
#https://github.com/mariodosreis/fractal
library(fractal)
library(Rdimtools)
## ** ------------------------------------------------------- **
## ** Rdimtools || Dimension Reduction and Estimation Toolbox
## **
## ** Version    : 1.1.2       (2025)
## ** Maintainer : Kisung You  (kisungyou@outlook.com)
## ** Website    : https://kisungyou.com/Rdimtools/
## **
## ** Please see 'citation('Rdimtools)' to cite the package.
## ** ------------------------------------------------------- **
# Aplicação do método de Box-Counting na fronteira
border_points <- nodes[nodes$id %in% c(edges$from, edges$to), ]

# Definir um número adequado de níveis para a análise fractal
nlevel_value <- 50  # Ajuste conforme necessário

# Executar a análise de Box-Counting
result <- est.boxcount(as.matrix(border_points[, c("X", "Y")]), nlevel = nlevel_value)

# Visualizar os resultados
plot(log(1 / result$r), log(result$Nr), type = "b", 
     main = "Dimensão Fractal da Fronteira", 
     xlab = "Log(1/Escala)", ylab = "Log(Número de caixas)")

5️⃣ Análise de Auto-Similaridade

Verifica padrões de auto-semelhança na rede.

library(igraph)
library(Rdimtools)
library(ggplot2)

# Criar o grafo
grafo <- graph_from_data_frame(edges, directed = FALSE)

# **1. Corrigir erro na extração de comunidades**
comunidades <- cluster_louvain(grafo)
membership_df <- data.frame(id = as.numeric(names(membership(comunidades))), 
                            comunidade = as.numeric(membership(comunidades)))

Geramos o grafo de comunidades

visNetwork(nodes_vis, edges_vis) %>%
  visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
  visGroups(groupname = unique(nodes_vis$comunidade)) %>%
  visLegend(position = "right")
# **5. Corrigir a análise fractal**
nlevel_value <- 50
result <- est.boxcount(as.matrix(nodes[, c("X", "Y")]), nlevel = nlevel_value)
# **6. Ajustar gráfico para evitar NA values**
ggplot(na.omit(nodes), aes(x = betweenness)) +
  geom_histogram(bins = 30, fill = "blue", alpha = 0.7) +
  theme_minimal() +
  ggtitle("Distribuição da Centralidade Betweenness")