### Start Paraglidable Apache Server Source: https://github.com/antoinemeler/paraglidable/blob/master/README.md Starts the Apache HTTP server to serve the Paraglidable website locally. This allows visualization of the generated forecasts. ```bash /scripts/start_server.sh ``` -------------------------------- ### Clone Paraglidable Repository Source: https://github.com/antoinemeler/paraglidable/blob/master/README.md Clones the Paraglidable project repository from GitHub to your local machine. This is the first step in the installation process. ```bash git clone https://github.com/AntoineMeler/Paraglidable.git ``` -------------------------------- ### Load Datasets and Libraries - Python Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/README.md Loads necessary Python libraries and datasets for the Paraglidable project. It checks for the existence of required data files and raises an error if they are not found, guiding the user to download them. ```python import numpy as np, matplotlib.pyplot as plt, sys, os, calendar, glob, math, pickle, collections, logging, matplotlib.cm from dateutil import parser from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.basemap import Basemap sys.path.append("../") from inc.dataset import FlightsData weights_dir = "../bin/models/CLASSIFICATION_1.0.0/weights/" if not os.path.exists("../bin/data/flights_by_cell_day.pkl"): # Check data is downloaded raise FileNotFoundError("You must first download data by running 'cd "+ os.path.abspath("../../scripts/") +"'; python download_data.py'") with open("../bin/data/sorted_cells_latlon.pkl", "rb") as fin: sorted_cells_latlon = pickle.load(fin, encoding='latin1') with open("../bin/data/flights_by_cell_day.pkl", "rb") as fin: flights_by_cell_day = pickle.load(fin, encoding='latin1') with open("../bin/data/meteo_days.pkl", "rb") as fin: meteo_days = pickle.load(fin, encoding='latin1') with open("../bin/data/meteo_params.pkl", "rb") as fin: weather_params = pickle.load(fin, encoding='latin1') with open("../bin/data/meteo_days.pkl", "rb") as fin: meteo_days = pickle.load(fin, encoding='latin1') ``` -------------------------------- ### JavaScript AJAX Data Fetching Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This snippet demonstrates an AJAX GET request to fetch data from a specified API endpoint. It handles the response by updating an HTML element with pre-formatted JSON code. The request specifies the URL, HTTP method, data type, and success callback function. ```javascript $.ajax({ type: "GET", url: "/apps/api/get.php?key=be7b42f272ba686a&format=JSON&htmlentities=1", dataType: "text", success: function(data) { $("#apiJsonExample").html('
' + data + '
'); Prism.highlightElement($('#code-XML')[0]); }, error: function (result) {} }); ``` -------------------------------- ### JavaScript Date Formatting and Utility Functions Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This snippet includes JavaScript functions for formatting dates into 'YYYY-MM-DD' format, retrieving the current date in ISO format, and generating HTML for a calendar month view. It handles date calculations, weekend highlighting, and day-specific click events. ```javascript function formatDate(year, month, day) { return ('0000' + year).substr(-4) + '-' + ('00' + month).substr(-2) + '-' + ('00' + day).substr(-2); } function getTodayISO() { var today = new Date(); return formatDate(today.getFullYear(), today.getMonth() + 1, today.getDate()); } function getMonthHtml(year, month, settings) { var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var firstDay = 1; var monthHtml = '
'; monthHtml += '
' + monthNames[month - 1] + ' ' + year + '
'; var monthsFirstDayOfWeek = (new Date(formatDate(year, month, 1))).getUTCDay(), daysPerMonth = month == 4 || month == 6 || month == 9 || month == 11 ? 30 : (month == 2 ? (year & 3 || !(year % 25) && year & 15 ? 28 : 29) : 31); for (var i = 0; i < (monthsFirstDayOfWeek + 7 - firstDay)%7; i++) { monthHtml = monthHtml + '
'; } var today = getTodayISO(), dow = monthsFirstDayOfWeek; for (var d = 1; d <= daysPerMonth; d++) { var classes = [ 'datepicker-day' ], thisDate = formatDate(year, month, d); if (thisDate == today) { classes.push('datepicker-day-today'); } if (dow == 0 || dow == 6) { classes.push('datepicker-day-weekend'); } monthHtml = monthHtml + '
' + d + '
'; // Increase date of the week dow = dow + 1; if (dow == 7) { dow = 0; } } monthHtml = monthHtml + '
'; return monthHtml; } ``` -------------------------------- ### Visualize Training Area and Flights using Python Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb Visualizes the training area segmented into 1°x1°x100hPa cells and plots the takeoff coordinates of paragliding flights. It calculates the boundaries of the training area and uses Matplotlib with Basemap to render the map, grid, and flight data points. Dependencies include numpy, matplotlib, and mpl_toolkits.Basemap. ```python cell_reso = 1.0 min_lat, max_lat = min([c[0] for c in sorted_cells_latlon])-cell_reso/2., max([c[0] for c in sorted_cells_latlon])+cell_reso/2. min_lon, max_lon = min([c[1] for c in sorted_cells_latlon])-cell_reso/2., max([c[1] for c in sorted_cells_latlon])+cell_reso/2. plt.figure(figsize=((max_lon-min_lon)*.85, (max_lat-min_lat)*.85)) plt.title("Training cells and flights") m = Basemap(projection='mill', llcrnrlon=min_lon-2.5, llcrnrlat=min_lat-2.5, urcrnrlon=max_lon+2.5, urcrnrlat=max_lat+2.5, resolution='h') m.shadedrelief() # Draw training weather grid (GFS 1°x1°) for lat in range(1, round((max_lat-min_lat)/cell_reso)): m.plot([min_lon, max_lon], [min_lat + lat*cell_reso, min_lat + lat*cell_reso], '-', linewidth=1, color='r', alpha=0.325, latlon=True) for lon in range(1, round((max_lon-min_lon)/cell_reso)): m.plot([min_lon + lon*cell_reso, min_lon + lon*cell_reso], [min_lat, max_lat], '-', linewidth=1, color='r', alpha=0.325, latlon=True) m.plot([min_lon, max_lon, max_lon, min_lon, min_lon], [min_lat, min_lat, max_lat, max_lat, min_lat], '-', linewidth=2, color=(1., 0., 0.), latlon=True) # Draw flights m.scatter(np.array([f[1][4] for fd in flights_by_cell_day for f in fd]), # longitudes of training flights np.array([f[1][3] for fd in flights_by_cell_day for f in fd]), # latitudes of training flights marker='o', color='b', s=0.1, alpha=0.1, latlon=True) plt.show() ``` -------------------------------- ### Download and Load Paragliding Spots - JavaScript Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html Downloads spot prediction data from a JSON file for a given date and loads it onto the map. It manages the visibility of the spots layer, removing it if it exists before adding the new data. Dependencies include Leaflet.js and jQuery (for $.getJSON). ```javascript function callBackSpots(date) { return function(data) { loadSpots(date, data); } } function downloadSpotsPredictions() { if (g_spotsLayer != null) { if (map.hasLayer(g_spotsLayer)) map.removeLayer(g_spotsLayer); } if (g_mode != 'analysis') { $.getJSON("data/tiles/"+ g_strDate +"/spots.json", callBackSpots(g_strDate)); } } ``` -------------------------------- ### Load and Display Population Date Factor (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/README.md This script loads the 'population_date.npy' file, which contains a factor related to the date. It then prints this factor and its extrapolated percentage increase over the training interval, assuming a linear trend. This is useful for understanding how the population model's parameters change over time. ```python date_factor = np.load(weights_dir+"population_date.npy")[0] print("date_factor =", date_factor[0], "i.e. +%.1f%% in %.1f years, supposed linear."%(date_factor[0]*100., (meteo_days[-1]-meteo_days[0]).days/365.)) if False: dow_factor = np.load(weights_dir+"population_dow.npy")[0] plt.figure(figsize=(8, 3.5)) plt.bar(calendar.day_name, dow_factor) plt.title('dow_factor') plt.show() ``` -------------------------------- ### Fetch and Display JSON Data using AJAX Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This snippet demonstrates fetching JSON data from a server endpoint using jQuery's AJAX method. It then updates the HTML content of an element with the ID 'apiJsonExample' to display the fetched JSON data, applying syntax highlighting. ```javascript $.ajax({ type: "GET", url: "/apps/api/get.php?key=be7b42f272ba686a&format=JSON", dataType: "text", success: function(data) { $("#apiJsonExample").html('
' + data + '
'); Prism.highlightElement($('#code-JSON')[0]); }, error: function (result) {} }); ``` -------------------------------- ### Visualize Spot Population Distribution (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb This Python code visualizes the population distribution across different spots. It loads population data for spots from .npy files, concatenates them, sorts the populations in descending order, and displays them as a line plot. Dependencies include numpy and matplotlib. ```Python spot_population = np.concatenate([np.load(f)[0] for f in sorted(glob.glob(weights_dir+"population_0_spots__cell_*.npy"))]) plt.plot(np.sort(spot_population)[::-1]) plt.title("Spots population sorted by population") plt.show() ``` -------------------------------- ### Load and Print Date Factor (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb This Python code loads a 'date_factor' from a .npy file and prints its value along with an interpretation of its impact over time. It utilizes numpy for loading and standard printing. ```Python date_factor = np.load(weights_dir+"population_date.npy")[0] print("date_factor =", date_factor[0], "i.e. +%.1f%% in %.1f years, supposed linear."%(date_factor[0]*100., (meteo_days[-1]-meteo_days[0]).days/365.)) ``` -------------------------------- ### Initialize Leaflet Map and Set View (JavaScript) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This JavaScript code initializes a Leaflet map instance on an element with the ID 'map'. It configures map controls, sets the initial view center and zoom level, and retrieves these settings from URL parameters or cookies if available. It also handles the creation of different map layers for spots and flights. ```javascript var map = L.map('map', {attributionControl: false, zoomControl: false, minZoom: 4}).setView(viewCenter, viewZoom); var vignettesMaps = []; var g_spotsLayer = null; var g_flightsLayer = null; ``` -------------------------------- ### URL Generation for Map Sharing (JavaScript) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html Constructs a shareable URL for the map, including latitude, longitude, and zoom level. It formats the coordinates to three decimal places and appends date information. ```javascript link /?lat='+ newCenter.lat.toFixed(3) +"&lon="+ newCenter.lng.toFixed(3) +"&zoom="+ newZoom);// +"&day="+ strDate ``` -------------------------------- ### Handle Map View and User Input (JavaScript) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/mobileAndroid.html This JavaScript code retrieves map view parameters (latitude, longitude, zoom) from the URL query variables. It also handles cookies for view settings and initializes the map center and zoom level. It includes logic to pre-select a day based on URL parameters. ```javascript var inputLat = getQueryVariable("lat"); var inputLon = getQueryVariable("lon"); var inputVer = getQueryVariable("ver"); var inputDay = getQueryVariable("day"); var name = decodeURI(getQueryVariable("name")); if (inputVer == "1.0.0" || inputVer == "1.0.1") { $('#nameLink').css('display', 'none'); } var g_setPositionFunction = null; var viewCenter = [47, 8.5]; if (!(inputLat===false || inputLon===false)) { viewCenter = [parseFloat(inputLat), parseFloat(inputLon)]; } var viewZoom = 8; // On Android, get only the zoom part in cookie var strView = getCookie("view"); if (strView != "") { arView = strView.split(","); viewZoom = parseInt(arView[2]); } function setPosition_specific(lat, lon, spotId=-1) { Android.setLatLon(lat +","+ lon); // for Backward compatibility Android.setLatLon(lat +","+ lon +","+ spotId); // new version } g_setPositionFunction = setPosition_specific; setPositionMobile(viewCenter[0], viewCenter[1], viewZoom); // pre-select the clicked day if (!(inputDay === false)) { var day = parseInt(inputDay); if (day >= 0) { var momentDate = moment().add(day, 'days'); var strDate = momentDate.format("YYYY-MM-DD"); dayClick(strDate); if (day > 5) { // make the selected day visible $("#week").scrollTop(1000); } } } else { dayClick(moment().format("YYYY-MM-DD")); } applyLayersPreference(); ``` -------------------------------- ### Generate Paraglidable Forecast and Tiles Source: https://github.com/antoinemeler/paraglidable/blob/master/README.md Executes the script to generate +10 day forecasts and create map tiles based on the trained neural network. This script is part of the neural network functionality. ```python /neural_network/forecast.py ``` -------------------------------- ### Load and Print Mountainess Factor (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb Loads the mountainess factor from a .npy file and prints its value. This factor adjusts wind tolerance based on terrain. ```python mountainess_factor = np.load(weights_dir+"wind_block_cells_0.npy")[0] print("mountainess_factor =", mountainess_factor) ``` -------------------------------- ### Fetch Git Commit Hash Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This JavaScript code fetches the current Git commit hash from a 'data/commit.txt' file using AJAX. The fetched commit hash is then displayed in an HTML element with the ID 'version', linked to the commit on GitHub. ```javascript $.ajax({ type: "GET", url: "data/commit.txt", dataType: "text", success: function(commit) { $("div#version").html('commit ' + commit.substring(0, 8) + ""); } }); ``` -------------------------------- ### Google Analytics Configuration in JavaScript Source: https://github.com/antoinemeler/paraglidable/blob/master/www/mobile.html This JavaScript code snippet configures Google Analytics (gtag.js) for the web page. It initializes the dataLayer and sends the initial configuration and page view events to Google Analytics, using a specific tracking ID. ```javascript window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-127025208-1'); ``` -------------------------------- ### JavaScript: Generate Tile Layer URL with Transparency Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This function constructs the URL for map tiles based on the date and a transparency flag. It adjusts the directory path for analysis mode and includes transparency in the URL if the zoom level is high enough or explicitly requested. ```javascript function tilesUrl(date, transpa) { if (g_mode == 'analysis') { tilesdir = 'data/tiles_anl/'+date.substring(0,4); transpa = true; } else { tilesdir = 'data/tiles'; } if (transpa) return tilesdir +'/'+ date +'/256/{z}/{x}/{y}_transpa.{ext}'; else return tilesdir +'/'+ date +'/256/{z}/{x}/{y}.{ext}'; } ``` -------------------------------- ### Control Forward/Backward Movement - JavaScript Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html Manages the forward and backward movement logic based on the current application mode. In 'main' mode, it controls past data visibility; in 'analysis' mode, it navigates dates by a week. It interacts with `changePastMode` and `moveDay` functions. ```javascript function moveForward(forward) { if (g_mode == 'main') { var mode = !forward; if (g_modePast != mode) { g_modePast = mode; updateVignettes(); updatePrevNextButtons(); } } else if (g_mode == 'analysis') { moveDay(forward ? 7 : -7); } } ``` -------------------------------- ### Visualize Cell Population Distribution (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb This Python code calculates and visualizes the population distribution across different cells. It loads population data for each cell from .npy files, sums them, and displays the sorted populations as a bar chart. Dependencies include numpy, matplotlib, and glob. ```Python cell_population = [np.sum(np.load(f)) for f in sorted(glob.glob(weights_dir+"population_alt_cell_*.npy"))] plt.bar(range(len(cell_population)), sorted(cell_population)[::-1]) plt.title("Cells population summed over all the altitudes sorted by population") plt.show() ``` -------------------------------- ### Initialize and Populate Datepicker (JavaScript) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This JavaScript function, fillAnlDatepickerIfNeeded, is responsible for populating the calendar interface if it's currently empty. It iterates through years and months to generate HTML for each month and then calls disableMissingAnlDays to mark unavailable dates. Finally, it scrolls the calendar to a specific position. ```javascript function fillAnlDatepickerIfNeeded() { if ($("#calendar").html() == "") { for (y=2009; y<=2017; y++) for (m=1; m<=12; m++) $("#calendar").append(getMonthHtml(y, m)); disableMissingAnlDays(); $('#calendar').scrollLeft(143*12*4); } } ``` -------------------------------- ### Date Navigation and Validation - JavaScript Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html Provides functions to calculate the previous and next day's date strings and to determine if a given date is selectable based on the analysis mode and the number of days configured. It uses the Moment.js library for date manipulation. ```javascript //========================================= // Select day //========================================= function getStrDatePrevDay(strDate) { return moment(strDate, "YYYY-MM-DD").add(-1, 'days').format("YYYY-MM-DD"); } function getStrDateNextDay(strDate) { return moment(strDate, "YYYY-MM-DD").add(+1, 'days').format("YYYY-MM-DD"); } function isSelectableDate(strDate) { if (!strDate || !moment(strDate, "YYYY-MM-DD").isValid()) return false; if (g_mode == 'analysis') return true; var diffDays = getStrDateDiffDays(strDate); return (diffDays > -g_nbDays - 1 && diffDays < g_nbDays); } ``` -------------------------------- ### JavaScript: Display Keywords in Legend Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This function `displayKeyWords` dynamically generates and displays keywords in a legend section based on environmental factors like flyability, wind, and water. It sorts keywords by their calculated 'warning' value and updates the HTML to show visible keywords with their corresponding colored bars and wind direction arrows if applicable. ```javascript function displayKeyWords(val_flyability, val_wind, val_water, val_windAngle) { // keywords keywords = []; keywords.push(['Wind', warningLegendVal(val_wind), '#A00000']); keywords.push(['Humidity', warningLegendVal(val_water), '#A00000']); //keywords.push(['Plaf élevé (WIP fake)', Math.max(0.0, Math.sin(1.5*lon)), '#00A000']); keywords.sort(function(x, y) { return y[1] - x[1]; }); if ($('#legendSectionKeywords').html() == '') { keywordsHtml = ''; for (kw=0; kw \
\
\
\
\
' } $('#legendSectionKeywords').html(keywordsHtml); } nbVisibleKeywords = 0; for (kw=0; kw 0.0) { $('#keywordLineW'+ kw).html(keywords[kw][0]); $('#keyword'+ kw +'Val').css("width", Math.round(keywords[kw][1]*150)); $('#keyword'+ kw +'Val').css("background-color", keywords[kw][2]); $('#keywordLineW'+ kw).css("height", "14px"); $('#keywordLineV'+ kw).css("height", "12px"); $('#keywordLine' + kw).css("height", "14px"); $('#keywordLine' + kw).css("padding-bottom", "2px"); $('#keywordLineV'+ kw).css("visibility", "visible"); if(keywords[kw][0] == 'Wind') { var angleDeg = 180 - val_windAngle/Math.PI*180; $('#keywordLineW'+ kw).append(' '); } nbVisibleKeywords++; } else { $('#keywordLineW'+ kw).css("height", "0px"); $('#keywordLineV'+ kw).css("height", "0px"); $('#keywordLine' + kw).css("height", "0px"); $('#keywordLine' + kw).css("padding-bottom", "0px"); $('#keywordLineV'+ kw).css("visibility", "hidden"); } } if (nbVisibleKeywords==0) { $('#legendSectionKeywords').removeClass('active'); } } ``` -------------------------------- ### Map Interaction and Geolocation Handling (JavaScript) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html Handles user interactions with the map, including focusing search input, registering autocomplete callbacks, handling GPS location found and error events, and controlling map zoom. It also initiates a GPS location watch. ```javascript $("#searchInput").focusout(tryRetractSarch); var autocomplete = new kt.OsmNamesAutocomplete('searchInput', 'apps/search.php?q=', ''); autocomplete.registerCallback(function(item) { setPosition(item['lat'], item['lon'], true); }); function gpsLocationFound(e) { setPosition(e.latlng.lat, e.latlng.lng, true); $("#mapControlButtonGpsIcon").removeClass('searching'); $("#mapControlButtonGpsIcon").attr('src','imgs/icons/gps.svg'); $("#mapControlButtonGps").removeClass('disabled'); } function gpsLocationError(e) { $("#mapControlButtonGpsIcon").removeClass('searching'); $("#mapControlButtonGpsIcon").attr('src','imgs/icons/gps-disabled.svg'); $("#mapControlButtonGps").addClass('disabled'); } map.on('locationfound', gpsLocationFound) .on('locationerror', gpsLocationError); function mapZoom(direction) { map.setZoom(Math.max(map.getZoom() + direction, 0)); } function mapGps() { $("#mapControlButtonGpsIcon").addClass('searching'); map.locate({ enableHighAccuracy: true, watch: false, setView: false }); } ``` -------------------------------- ### Calculate and Visualize Population Probability (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb This Python code calculates the probability of at least one person going to fly based on flyability and population. It generates a 3D surface plot to visualize this relationship. Dependencies include numpy, matplotlib, and calendar. ```Python r = 200 in_proba = np.array([[1.*(float(x)/float(r-1))**2. for y in range(r)] for x in range(r)], np.float) population = np.array([[4.*(float(y)/float(r-1))**2. for y in range(r)] for x in range(r)], np.float) out_proba = np.array([[in_proba[x,y]*population[x,y] if population[x,y]<=1. else 1. - (1. - in_proba[x,y])**population[x,y] for y in range(r)] for x in range(r)], np.float) logging.getLogger().disabled = True ax = plt.figure(figsize=(9,5)).add_subplot(111, projection='3d') ax.view_init(35, 210) ax.set_xlim3d(0., np.amax(in_proba)) ax.set_ylim3d(0., np.amax(population)) ax.set_xlabel('Input probability') ax.set_ylabel('Population value') ax.set_zlabel('Output probability') ax.plot_surface(in_proba, population, out_proba, cmap=matplotlib.cm.jet) for p in [0.5*p for p in range(0,2)]: ax.plot([1.*(float(x)/float(r-1))**2. for x in range(r)], [p for x in range(r)], [p*(float(x)/float(r-1))**2. for x in range(r)], alpha=1, color='black', linewidth=1.5, zorder=10) for p in [0.5*p for p in range(2,9)]: ax.plot([1.*(float(x)/float(r-1))**2. for x in range(r)], [p for x in range(r)], [1. - (1. - 1.*(float(x)/float(r-1))**2.)**p for x in range(r)], alpha=1, color='black', linewidth=1.5, zorder=10) logging.getLogger().disabled = False ``` -------------------------------- ### JavaScript Mode Switching Function Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This function, `switchMode`, handles transitions between different application modes ('main', 'api', 'analysis'). It updates navigation bars, map tiles, legend visibility, zoom levels, date pickers, and API markers based on the selected mode. It also includes logic for handling date changes and removing specific map layers. ```javascript function switchMode(strMode) { idsNavigationBar = { 'main': 'mainNavigationBar', 'api': 'apiNavigationBar', 'analysis': 'analysisNavigationBar' }; oldMode = g_mode; if (strMode == 'main' || strMode == 'api' || strMode == 'analysis') { if ( (strMode != 'main' && switchNavigationBar(idsNavigationBar[strMode])) ) { g_mode = strMode; } else { switchNavigationBar(idsNavigationBar['main']); g_mode = 'main'; } // tiles if (g_mode == 'api' || showHideColorsVal == 0) { applyShowHideMapColors(false); } else { applyShowHideMapColors(true); } // legend hideShowLegend(g_mode=='main' || g_mode=='analysis', g_mode=='analysis', g_mode=='analysis'); // maxNativeZoom if (g_mode == 'analysis') { var maxAnlLevel = 6; paraglidableTiles.options.maxNativeZoom = L.Browser.retina ? maxAnlLevel-1 : maxAnlLevel; map.setZoom(L.Browser.retina ? maxAnlLevel-1 : maxAnlLevel); } else { paraglidableTiles.options.maxNativeZoom = g_switchZoom-1; } // prevNextDayContainer if (g_mode == 'main' || g_mode == 'analysis') { $("#prevNextDayContainer").css("visibility", "visible"); updatePrevNextButtons(); } else { $("#prevNextDayContainer").css("visibility", "hidden"); } // API markers if (g_mode != 'api') removeAllApiMarkers(); if (g_mode != 'analysis') { if (g_flightsLayer != null) { if (map.hasLayer(g_flightsLayer)) map.removeLayer(g_flightsLayer); } } // Calendar if (g_mode == 'analysis') fillAnlDatepickerIfNeeded(); // date if (g_mode == 'analysis') { changeDate('2013-05-13'); } else if (oldMode=='analysis') { changeDate(moment().format("YYYY-MM-DD")); } } } ``` -------------------------------- ### JavaScript: Handle Map Click Events Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This function, `mapClick`, determines the action to take when the map is clicked based on the current application mode ('main', 'api', or 'analysis'). It calls other functions like `setPosition` or `addApiMarker` accordingly. The map's click event listener is then set to use this function. ```javascript function mapClick(lat, lon) { hideAllModals(); if (g_mode == 'main') { setPosition(lat, lon, false); } else if (g_mode == 'api') { addApiMarker(lat, lon); } else if (g_mode == 'analysis') { setPosition(lat, lon, false, false); } } map.on('click', function(e) {mapClick(e.latlng.lat, e.latlng.lng);}); ``` -------------------------------- ### Desktop Mode Cookie Management (JavaScript) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This script checks for and sets a cookie to manage desktop mode preferences. It appends a style to hide the mobile version popup if desktop mode is enabled. It is designed to run client-side in a web browser. ```javascript if (getQueryVariable('forceDesktopMode') == '1' || getCookie('forceDesktopMode') == '1') { $('html > head').append($('')); setCookie('forceDesktopMode', '1'); } function stopAskingMobileVersion() { setCookie('forceDesktopMode', '1'); $('#popupMobileVersion').css('display','none'); } ``` -------------------------------- ### Count and Plot Flights by Time and Altitude (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/README.md This script counts paragliding flights by year, month, day of the week, and altitude using collections.Counter. It then generates bar plots to visualize these counts. The script iterates through flight data, aggregates counts, and uses matplotlib for plotting. Dependencies include 'collections', 'matplotlib.pyplot', and 'parser'. ```python counter_flights_by_year, counter_flights_by_month, counter_flights_by_alt, counter_flights_by_dow = collections.Counter(), collections.Counter(), collections.Counter(), collections.Counter() for cell_day in flights_by_cell_day: for flight in cell_day: counter_flights_by_alt[FlightsData.kAltitude(flight[1][5])] += 1 try: counter_flights_by_year [cell_day[0][0][0:4]] += len(cell_day) # counter[year] += nb_flights counter_flights_by_month[cell_day[0][0][5:7]] += len(cell_day) # counter[month] += nb_flights counter_flights_by_dow [parser.parse(cell_day[0][0]).strftime("%a")] += len(cell_day) # counter[dow] += nb_flights except IndexError: pass fig, axes = plt.subplots(nrows=3, ncols=2, figsize=(14, 10)) years, months, dow = sorted(list(counter_days)), sorted(list(counter_months)), ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] axes[0,0].set_title("nb days with available weather data") axes[0,0].bar(years, [counter_days[y] for y in years], color='#f07000') axes[0,1].set_title("nb flights in available days, by year") axes[0,1].bar(years, [counter_flights_by_year[y] for y in years]) axes[1,0].set_title("nb flights per days, by year") axes[1,0].bar(years, [counter_flights_by_year[y]/counter_days[y] for y in years]) axes[1,1].set_title("nb flights per days, by month") axes[1,1].bar(months, [counter_flights_by_month[m]/counter_months[m] for m in months]) axes[2,0].set_title("nb flights by day of week") axes[2,0].bar(dow, [counter_flights_by_dow[d] for d in dow]) print("Nb flights by day of week:", [counter_flights_by_dow[d] for d in dow]) # Flights by altitude axes[2,1].set_title("nb flights by altitude level") nb_alts = max(counter_flights_by_alt.keys())+1 axes[2,1].barh(["%d"%alt for alt in range(nb_alts)], [counter_flights_by_alt[alt] for alt in range(nb_alts)]) for alt in range(nb_alts): axes[2,1].text(counter_flights_by_alt[alt], alt-0.06, str(counter_flights_by_alt[alt]), fontsize=12) axes[2,1].set_xlim(0, 1.125*max(counter_flights_by_alt.values())) fig.tight_layout() ``` -------------------------------- ### Plot Flights by XC Score per Month (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/README.md This script generates a plot showing the number of flights for each XC score bin, broken down by month. It processes flight data to categorize flights by month and XC score, then uses numpy and matplotlib to create a line plot. Dependencies include 'numpy', 'calendar', and 'matplotlib.pyplot'. ```python max_score = 75 pts = [[] for m in range(0, 12)] for cell_day in flights_by_cell_day: try: pts[int(cell_day[0][0][5:7])-1] += [f[1][0] for f in cell_day] except IndexError: pass plt.figure(figsize=(12, 5)) plt.title("Number of flights by XC score for each month") for m in range(12): plt.plot(np.histogram(pts[m], bins=max_score, range=(0, max_score))[0], label=calendar.month_name[m+1]) plt.xlim(0., max_score-1) plt.ylim(ymin=0.) plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0) plt.show() ``` -------------------------------- ### Navigate Through Dates - JavaScript Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html Provides functionality to move between dates, either forward or backward by a specified number of days. It checks if the target date is selectable before attempting to change the date. Dependencies include moment.js. ```javascript function moveDay(deltaDay) { var newStrDate = moment(g_strDate, "YYYY-MM-DD").add(deltaDay, 'days').format("YYYY-MM-DD"); if (isSelectableDate(newStrDate)) changeDate(newStrDate); } ``` -------------------------------- ### Contact Form Submission (JavaScript/jQuery) Source: https://github.com/antoinemeler/paraglidable/blob/master/www/index.html This script handles the submission of a contact form using an AJAX POST request. It sends the user's name, email, and message to a server-side script for processing. It provides visual feedback on success or failure. ```javascript $('#send-message').click(function(){ var message_name = $("#message-name").val(); var message_email = $("#message-email").val(); var message_text = $("#message-text").val(); $.post( '/apps/sendMessage.php', { name: message_name, email: message_email, text: message_text }, function(data) { if(data == '1') { $("#send-message").val('✓'); } else { $("#send-message").val("Sorry there was en error, your e-mail could not be sent."); } }, 'text' ); }); ``` -------------------------------- ### Visualize Flight Score Distribution by Month (Python) Source: https://github.com/antoinemeler/paraglidable/blob/master/neural_network/docs/documentation.ipynb This script visualizes the distribution of flight scores for each month. It processes flight data to group flights by month and then plots the histogram of flight scores (up to a maximum score of 75) for each month using matplotlib and numpy. It assumes flight data is available in 'flights_by_cell_day' and uses the 'calendar' module for month names. ```python import matplotlib.pyplot as plt import numpy as np import calendar # Assuming flights_by_cell_day is a pre-defined list of flight data max_score = 75 pts = [[] for m in range(0, 12)] for cell_day in flights_by_cell_day: try: # Assuming cell_day[0][0] contains a date string and cell_day contains flight data month_index = int(cell_day[0][0][5:7])-1 if 0 <= month_index < 12: pts[month_index] += [f[1][0] for f in cell_day if len(f) > 1 and len(f[1]) > 0] except (IndexError, ValueError): pass plt.figure(figsize=(12, 5)) plt.title("Number of flights by XC score for each month") for m in range(12): # np.histogram returns counts and bin edges, we only need counts counts, _ = np.histogram(pts[m], bins=max_score, range=(0, max_score)) plt.plot(counts, label=calendar.month_name[m+1]) plt.xlim(0., max_score-1) plt.ylim(ymin=0.) plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0) plt.show() ```