235 lines
9.0 KiB
Python
235 lines
9.0 KiB
Python
|
|
import geopandas as gpd
|
||
|
|
import json
|
||
|
|
import sys
|
||
|
|
import folium
|
||
|
|
import requests
|
||
|
|
import re
|
||
|
|
import shutil
|
||
|
|
|
||
|
|
def internet_disponivel():
|
||
|
|
"""Verifica se há conexão com a internet."""
|
||
|
|
url = 'http://www.google.com/'
|
||
|
|
timeout = 5
|
||
|
|
try:
|
||
|
|
_ = requests.get(url, timeout=timeout)
|
||
|
|
return True
|
||
|
|
except requests.ConnectionError:
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Argumentos e configurações iniciais
|
||
|
|
pathFiles = sys.argv[1]
|
||
|
|
fileName = sys.argv[2]
|
||
|
|
outputName = sys.argv[3]
|
||
|
|
outputMapName = sys.argv[4]
|
||
|
|
topico_gps = sys.argv[5]
|
||
|
|
topico_ruas = sys.argv[6]
|
||
|
|
topico_trajeto_dinamico = sys.argv[7]
|
||
|
|
mapa_dados_json = sys.argv[8]
|
||
|
|
pastaSaida = 'Python/Output/'
|
||
|
|
|
||
|
|
|
||
|
|
if mapa_dados_json == "0":
|
||
|
|
# Carregar o arquivo shapefile contendo a geometria
|
||
|
|
input_shapefile = pathFiles + fileName + '.shp'
|
||
|
|
data_geometry = gpd.read_file(input_shapefile)
|
||
|
|
|
||
|
|
# Converter o GeoDataFrame para GeoJSON e adicionar ao mapa
|
||
|
|
geojson_data = data_geometry.to_json()
|
||
|
|
# Calcular os limites (bounds) da geometria
|
||
|
|
minx, miny, maxx, maxy = data_geometry.total_bounds
|
||
|
|
center = [(miny + maxy) / 2, (minx + maxx) / 2]
|
||
|
|
|
||
|
|
# Salvar GEOJson
|
||
|
|
data_geometry.to_file(pastaSaida + outputName, driver='GeoJSON')
|
||
|
|
else:
|
||
|
|
# Lendo os dados JSON
|
||
|
|
with open(pathFiles + fileName + '.json', 'r', encoding='utf-8-sig') as f:
|
||
|
|
geojson_data = json.load(f)
|
||
|
|
# Obter os limites (bounds) dos dados GeoJSON
|
||
|
|
bounds = folium.GeoJson(geojson_data).get_bounds()
|
||
|
|
center = [(bounds[0][0] + bounds[1][0]) / 2, (bounds[0][1] + bounds[1][1]) / 2]
|
||
|
|
|
||
|
|
# Adicionando um ID sequencial a cada Feature
|
||
|
|
for idx, feature in enumerate(geojson_data["features"]):
|
||
|
|
# Adicionar uma propriedade 'id' para cada Feature começando do índice zero
|
||
|
|
feature['id'] = idx
|
||
|
|
|
||
|
|
# Copiando o arquivo JSON para a pasta de saída
|
||
|
|
shutil.copy(pathFiles + fileName + '.json', pastaSaida + outputName)
|
||
|
|
|
||
|
|
# Verificar se há conexão com a internet
|
||
|
|
if internet_disponivel():
|
||
|
|
m = folium.Map(location=center, zoom_start=12)
|
||
|
|
else:
|
||
|
|
m = folium.Map(location=center, zoom_start=12, tiles=None)
|
||
|
|
|
||
|
|
|
||
|
|
folium.GeoJson(geojson_data).add_to(m)
|
||
|
|
|
||
|
|
# Salvar o mapa interativo em um arquivo HTML
|
||
|
|
m.save(pastaSaida + outputMapName)
|
||
|
|
|
||
|
|
|
||
|
|
# Caminho completo para o arquivo HTML gerado
|
||
|
|
caminho_completo_html = pastaSaida + outputMapName
|
||
|
|
|
||
|
|
# Abrir o arquivo HTML para leitura e escrita
|
||
|
|
with open(caminho_completo_html, 'r+') as arquivo_html:
|
||
|
|
# Ler o conteúdo do arquivo
|
||
|
|
conteudo_html = arquivo_html.read()
|
||
|
|
|
||
|
|
# Usar expressão regular para encontrar o ID do mapa
|
||
|
|
padrao_id_mapa = re.compile(r'id="map_(.*?)"')
|
||
|
|
resultado_busca = padrao_id_mapa.search(conteudo_html)
|
||
|
|
|
||
|
|
# Verificar se encontrou um ID de mapa
|
||
|
|
if resultado_busca:
|
||
|
|
id_mapa = 'map_' + resultado_busca.group(1)
|
||
|
|
else:
|
||
|
|
raise ValueError("Não foi possível encontrar o ID do mapa no arquivo HTML.")
|
||
|
|
|
||
|
|
# Script para desenhar o trajo percorrido no mapa
|
||
|
|
script_marcadores_dinamicos = f"""
|
||
|
|
<script src="folium/mqtt.min.js"></script>
|
||
|
|
<script src="folium/leaflet.rotatedMarker.js"></script>
|
||
|
|
<script>
|
||
|
|
var marcadores = {{}};
|
||
|
|
var trajetos = {{}};
|
||
|
|
|
||
|
|
function criarMarcador(id, coordenadas, orientacao) {{
|
||
|
|
var marcador;
|
||
|
|
|
||
|
|
if (id == 1) {{
|
||
|
|
marcador = L.marker(coordenadas, {{}}).addTo({id_mapa});
|
||
|
|
var icon = L.AwesomeMarkers.icon(
|
||
|
|
{{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}}
|
||
|
|
);
|
||
|
|
marcador.setIcon(icon);
|
||
|
|
}}
|
||
|
|
else {{
|
||
|
|
var customIcon = L.icon({{
|
||
|
|
iconUrl: 'folium/images/position_marker.png',
|
||
|
|
iconSize: [32, 32],
|
||
|
|
iconAnchor: [16, 16],
|
||
|
|
popupAnchor: [0, -16]
|
||
|
|
}});
|
||
|
|
marcador = L.marker(coordenadas, {{ icon: customIcon }}).addTo({id_mapa});
|
||
|
|
marcador.setRotationAngle(orientacao);
|
||
|
|
}}
|
||
|
|
|
||
|
|
var popup = L.popup({{"maxWidth": "100%"}});
|
||
|
|
var html = $(`<div id="html_${{id}}" style="width: 100.0%; height: 100.0%;">Endereco: ${{id}}</div>`)[0];
|
||
|
|
popup.setContent(html);
|
||
|
|
marcador.bindPopup(popup)
|
||
|
|
|
||
|
|
marcadores[id] = marcador;
|
||
|
|
}}
|
||
|
|
|
||
|
|
function criarTrajeto(id) {{
|
||
|
|
trajetos[id] = L.geoJson(null, {{
|
||
|
|
style: function(feature) {{
|
||
|
|
return {{ color: 'red' }};
|
||
|
|
}}
|
||
|
|
}}).addTo({id_mapa});
|
||
|
|
}}
|
||
|
|
|
||
|
|
function atualizarMarcador(id, coordenadas, orientacao) {{
|
||
|
|
var marcador = marcadores[id];
|
||
|
|
if (marcador) {{
|
||
|
|
marcador.setLatLng(coordenadas);
|
||
|
|
marcador.setRotationAngle(orientacao);
|
||
|
|
}}
|
||
|
|
}}
|
||
|
|
|
||
|
|
function atualizarTrajeto(id, coordenadas) {{
|
||
|
|
var trajeto = trajetos[id];
|
||
|
|
if (trajeto) {{
|
||
|
|
var feature = trajeto.toGeoJSON().features.find(f => f.id === id);
|
||
|
|
if (feature) {{
|
||
|
|
var ultima = [0.0, 0.0];
|
||
|
|
if (feature.geometry.coordinates.length > 0) {{
|
||
|
|
ultima = feature.geometry.coordinates[feature.geometry.coordinates.length - 1];
|
||
|
|
}}
|
||
|
|
if (!saoCoordenadasIguais(ultima, coordenadas, 0.000001)) {{
|
||
|
|
feature.geometry.coordinates.push(coordenadas);
|
||
|
|
trajeto.clearLayers();
|
||
|
|
trajeto.addData(feature);
|
||
|
|
}}
|
||
|
|
}}
|
||
|
|
}}
|
||
|
|
}}
|
||
|
|
|
||
|
|
function saoCoordenadasIguais(coord1, coord2, tolerancia) {{
|
||
|
|
return Math.abs(coord1[0] - coord2[0]) < tolerancia && Math.abs(coord1[1] - coord2[1]) < tolerancia;
|
||
|
|
}}
|
||
|
|
|
||
|
|
function adicionarDados(id, coordenadas, orientacao, foco) {{
|
||
|
|
if (!marcadores[id]) {{
|
||
|
|
criarMarcador(id, coordenadas, orientacao);
|
||
|
|
criarTrajeto(id);
|
||
|
|
trajetos[id].addData({{
|
||
|
|
"type": "Feature",
|
||
|
|
"geometry": {{
|
||
|
|
"type": "LineString",
|
||
|
|
"coordinates": []
|
||
|
|
}},
|
||
|
|
"properties": {{"Dist1": 0.0, "Dist2": 0.0, "Id": id, "Length": 0.0, "Name": "Trajeto"}},
|
||
|
|
"id": id
|
||
|
|
}});
|
||
|
|
}} else {{
|
||
|
|
atualizarMarcador(id, coordenadas, orientacao);
|
||
|
|
atualizarTrajeto(id, [coordenadas[1], coordenadas[0]]);
|
||
|
|
}}
|
||
|
|
if (foco) {{
|
||
|
|
{id_mapa}.setView(coordenadas, {id_mapa}.getZoom());
|
||
|
|
}}
|
||
|
|
}}
|
||
|
|
|
||
|
|
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexao segura
|
||
|
|
|
||
|
|
client.on('connect', function () {{
|
||
|
|
console.log('Conectado ao broker MQTT');
|
||
|
|
client.subscribe('{topico_gps}', function (err) {{
|
||
|
|
if (!err) {{
|
||
|
|
console.log("Inscricao bem-sucedida no topico");
|
||
|
|
}} else {{
|
||
|
|
console.error("Falha na inscricao do topico", err);
|
||
|
|
}}
|
||
|
|
}});
|
||
|
|
}});
|
||
|
|
|
||
|
|
client.on('message', function (topic, message) {{
|
||
|
|
var dados = JSON.parse(message);
|
||
|
|
if (topic === '{topico_gps}') {{
|
||
|
|
var id = dados.id;
|
||
|
|
var novaLatitude = dados.latitude;
|
||
|
|
var novaLongitude = dados.longitude;
|
||
|
|
var novaPosicao = [novaLatitude, novaLongitude];
|
||
|
|
var orientacao = dados.orientacao;
|
||
|
|
var foco = dados.foco;
|
||
|
|
|
||
|
|
adicionarDados(id, novaPosicao, orientacao, foco);
|
||
|
|
}}
|
||
|
|
}});
|
||
|
|
|
||
|
|
</script>
|
||
|
|
"""
|
||
|
|
|
||
|
|
# Importar arquivos localmente
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdn.jsdelivr.net/npm/leaflet@1.9.3/dist/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://code.jquery.com/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdn.jsdelivr.net/npm/leaflet@1.9.3/dist/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.2.0/css/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/', 'folium/')
|
||
|
|
conteudo_html = conteudo_html.replace('https://cdn.jsdelivr.net/gh/python-visualization/folium/folium/templates/', 'folium/')
|
||
|
|
|
||
|
|
# Inserir o script no conteúdo HTML
|
||
|
|
conteudo_atualizado = conteudo_html.replace('</html>', script_marcadores_dinamicos + '</html>')
|
||
|
|
|
||
|
|
# Agora, reabrir o arquivo para escrita e sobrescrever o conteúdo com a versão atualizada
|
||
|
|
with open(caminho_completo_html, 'w') as arquivo_html:
|
||
|
|
arquivo_html.write(conteudo_atualizado)
|