import gradio as gr import folium from geopy.distance import geodesic import numpy as np import matplotlib.pyplot as plt # def calculate_line_of_sight(site1, site2): distance = geodesic(site1[:2], site2[:2]).km return distance # def calculate_propagation_loss(distance, frequency, model): if model == "Okumura-Hata-Davidson": loss = 69.55 + 26.16 * np.log10(frequency) - 13.82 * np.log10(30) + (44.9 - 6.55 * np.log10(30)) * np.log10(distance) elif model == "ITU-R P.1546": loss = 20 * np.log10(distance) + 20 * np.log10(frequency) + 92.45 elif model == "ITU-R 525/526": loss = 20 * np.log10(distance * 1e3) + 20 * np.log10(frequency) + 92.45 elif model == "Longley Rice": loss = 32.45 + 20 * np.log10(distance) + 20 * np.log10(frequency) else: loss = None return loss # def calculate_link_budget(tx_power, rx_sensitivity, propagation_loss): return tx_power - propagation_loss - rx_sensitivity # def create_map(): m = folium.Map(location=[-27.595, -48.558], zoom_start=15) site1 = folium.Marker(location=[-27.5968, -48.5686], tooltip='Site 1', draggable=True, icon=folium.Icon(color='red')) site2 = folium.Marker(location=[-27.5970, -48.5613], tooltip='Site 2', draggable=True, icon=folium.Icon(color='blue')) site1.add_to(m) site2.add_to(m) folium.LatLngPopup().add_to(m) return m._repr_html_() # def draw_fresnel(site1, site2, distance): frequency = 2400 # wavelength = 300 / frequency # d1 = np.linspace(0, distance, 500) r1 = np.sqrt((wavelength * d1 * (distance - d1)) / distance) r2 = np.sqrt((2 * wavelength * d1 * (distance - d1)) / distance) r3 = np.sqrt((3 * wavelength * d1 * (distance - d1)) / distance) r4 = np.sqrt((4 * wavelength * d1 * (distance - d1)) / distance) fig, ax = plt.subplots() ax.plot(d1, r1, label='1ª Zona de Fresnel') ax.plot(d1, r2, label='2ª Zona de Fresnel', linestyle='--') ax.plot(d1, r3, label='3ª Zona de Fresnel', linestyle=':') ax.plot(d1, r4, label='4ª Zona de Fresnel', linestyle='-.') ax.fill_between(d1, 0, r1, color='lightblue', alpha=0.5) ax.set_title('Diagrama de Fresnel') ax.set_xlabel('Distância (km)') ax.set_ylabel('Raio da Zona de Fresnel (m)') ax.legend() ax.grid(True) return fig # def draw_line_of_sight(site1, site2, distance, site1_height, site2_height): d1 = np.linspace(0, distance, 500) # los = np.linspace(site1_height, site2_height, 500) fig, ax = plt.subplots() ax.plot(d1, los, label='Linha de Visada', color='magenta') ax.set_title('Linha de Visada') ax.set_xlabel('Distância (km)') ax.set_ylabel('Elevação (m)') ax.legend() ax.grid(True) return fig # def interactive_propagation_map(site1_coords, site2_coords, site1_height, site2_height, frequency, model, tx_power1, rx_sensitivity1, tx_power2, rx_sensitivity2): try: site1_lat, site1_lon = map(float, site1_coords.split(',')) site2_lat, site2_lon = map(float, site2_coords.split(',')) except ValueError: return "Erro: Coordenadas inválidas.", "Erro: Coordenadas inválidas.", "Erro: Coordenadas inválidas.", None, None, None site1 = (site1_lat, site1_lon, site1_height) site2 = (site2_lat, site2_lon, site2_height) # distance = calculate_line_of_sight(site1, site2) # propagation_loss = calculate_propagation_loss(distance, frequency, model) # link_budget1 = calculate_link_budget(tx_power1, rx_sensitivity2, propagation_loss) link_budget2 = calculate_link_budget(tx_power2, rx_sensitivity1, propagation_loss) # m = folium.Map(location=[(site1_lat + site2_lat) / 2, (site1_lon + site2_lon) / 2], zoom_start=15) folium.Marker(location=[site1_lat, site1_lon], popup='Site 1 Coordenadas: {:.6f}, {:.6f}'.format(site1_lat, site1_lon), tooltip='Site 1', draggable=True, icon=folium.Icon(color='red')).add_to(m) folium.Marker(location=[site2_lat, site2_lon], popup='Site 2 Coordenadas: {:.6f}, {:.6f}'.format(site2_lat, site2_lon), tooltip='Site 2', draggable=True, icon=folium.Icon(color='blue')).add_to(m) folium.PolyLine(locations=[[site1_lat, site1_lon], [site2_lat, site2_lon]], color='blue', weight=2.5).add_to(m) m.add_child(folium.LatLngPopup()) map_html = m._repr_html_() # fresnel_plot = draw_fresnel(site1, site2, distance) # los_plot = draw_line_of_sight(site1, site2, distance, site1_height, site2_height) return map_html, f"Distância: {distance:.2f} km", f"Perda de propagação: {propagation_loss:.2f} dB", fresnel_plot, f"Link Budget (Site 1 -> Site 2): {link_budget1:.2f} dB", f"Link Budget (Site 2 -> Site 1): {link_budget2:.2f} dB", los_plot with gr.Blocks() as interface: gr.Markdown("# RF-Radio") gr.Markdown("## Calculate the line of sight and propagation loss between two points.") gr.Markdown("### Version 1 developed by Ramon Mayor Martins, 2024 | [Personal](https://rmayormartins.github.io/) | [Spaces](https://huggingface.co/rmayormartins)") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### Mapa") map_display = gr.HTML(create_map(), label="Clique no mapa para marcar os sites e arraste os marcadores para ajustar a posição. Copie e cole as coordenadas nos campos abaixo.") with gr.Column(scale=1): gr.Markdown("### Coordenadas") site1_coords = gr.Textbox(label="Coordenadas do Site 1", placeholder="-27.5968, -48.5686", value="-27.5968, -48.5686") site2_coords = gr.Textbox(label="Coordenadas do Site 2", placeholder="-27.5970, -48.5613", value="-27.5970, -48.5613") site1_height = gr.Number(label="Altura do Site 1 (m)", value=30) site2_height = gr.Number(label="Altura do Site 2 (m)", value=30) with gr.Row(): with gr.Column(scale=1): gr.Markdown("### Modelo de Propagação") frequency = gr.Slider(minimum=30, maximum=3000, label="Frequência (MHz)") model = gr.Radio(choices=["Okumura-Hata-Davidson", "ITU-R P.1546", "ITU-R 525/526", "Longley Rice"], label="Modelo de Propagação") with gr.Column(scale=1): gr.Markdown("### Link Budget") tx_power1 = gr.Number(label="Potência Tx do Site 1 (dBm)", value=20) rx_sensitivity1 = gr.Number(label="Sensibilidade Rx do Site 1 (dBm)", value=-90) tx_power2 = gr.Number(label="Potência Tx do Site 2 (dBm)", value=20) rx_sensitivity2 = gr.Number(label="Sensibilidade Rx do Site 2 (dBm)", value=-90) with gr.Row(): calculate_button = gr.Button("Calcular") gr.Markdown("### Resultados:") with gr.Row(): with gr.Column(scale=1): distance_output = gr.Textbox(label="Distância", interactive=False) loss_output = gr.Textbox(label="Perda de Propagação", interactive=False) with gr.Column(scale=1): link_budget1_output = gr.Textbox(label="Link Budget (Site 1 -> Site 2)", interactive=False) link_budget2_output = gr.Textbox(label="Link Budget (Site 2 -> Site 1)", interactive=False) with gr.Row(): with gr.Column(scale=1): fresnel_plot = gr.Plot(label="Diagrama de Fresnel") with gr.Column(scale=1): terrain_plot = gr.Plot(label="Linha de Visada") calculate_button.click(fn=interactive_propagation_map, inputs=[site1_coords, site2_coords, site1_height, site2_height, frequency, model, tx_power1, rx_sensitivity1, tx_power2, rx_sensitivity2], outputs=[map_display, distance_output, loss_output, fresnel_plot, link_budget1_output, link_budget2_output, terrain_plot]) # interface.launch() # JavaScript campo (voltar) js_code = ''' document.addEventListener('DOMContentLoaded', function() { var iframe = document.querySelector('iframe'); iframe.addEventListener('load', function() { var iframeDocument = iframe.contentDocument || iframe.contentWindow.document; function addDragEndListener(marker, siteLabel) { marker.on('moveend', function(e) { var lat = e.target.getLatLng().lat.toFixed(6); var lon = e.target.getLatLng().lng.toFixed(6); var popupContent = siteLabel + ' Coordenadas: ' + lat + ',' + lon; marker.bindPopup(popupContent).openPopup(); console.log(popupContent); }); // Atualizar o popup imediatamente com a posição inicial var lat = marker.getLatLng().lat.toFixed(6); var lon = marker.getLatLng().lng.toFixed(6); var popupContent = siteLabel + ' Coordenadas: ' + lat + ',' + lon; marker.bindPopup(popupContent).openPopup(); console.log(popupContent); } var markers = iframeDocument.querySelectorAll('.leaflet-marker-icon'); console.log('Markers found:', markers.length); var siteLabels = ['Site 1', 'Site 2']; markers.forEach((marker, index) => { console.log('Adding event listener to marker', index); addDragEndListener(marker, siteLabels[index]); }); }); }); ''' display(gr.HTML(f""))