Gadget Webview et Javascript

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
vertexview
Messages : 10
Inscription : mer. 24/janv./2024 16:02

Gadget Webview et Javascript

Message par vertexview »

Bonjour,
J'expérimente actuellement une librairie Javascript très intéressante, avec le nouveau gadget webview PB 6.10, pour des fonctions de geomapping.
Cette librairie utilise la cartographie d'Openstreetmap (https://www.openstreetmap.org).

Le test local avec un fichier index.html est assez simple, et concluant.
J'ai fait un essai également avec un code html converti et passé dans un String au gadget Webview,... sans succès.

Voici la documentation Leaflet Javascript library: https://leafletjs.com/index.html
Javascript et code CSS: https://leafletjs-cdn.s3.amazonaws.com/ ... eaflet.zip

La visualisation est réalisée sans anomalie dans le gadget webview avec un fichier html local appelé avec ce code:

Code : Tout sélectionner

Global URL_leaflet.s=ProgDirectory.s+"/html/index.html"
SetGadgetText(#WebView_OSM, URL_leaflet.s)
Ces fichiers Leaflet sont placés dans le répertoire /js du projet:
leaflet.js - Code Leaflet JavaScript
leaflet.css - Feuille de style Leaflet
images - Ce répertoire, à l'emplacement de leaflet.css, contient des images référencées par la feuille de style.

Le fichier Index.html est placé dans le répertoire /html du projet:

Code : Tout sélectionner

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Leaflet</title>
<link rel="stylesheet" href="js/leaflet.css" />
<script src="js/leaflet.js"></script>
<style>
  body{
    margin: 0;
    padding: 0;
  }
  #map {
    width: 100vw;
    height: 100vh;
  }
</style>
</head>
<body>
<div id="map"></div>
<script>
  const map = L.map('map', {center: [48.863, 2.329], zoom: 12});
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' 
    }).addTo(map);
  function onMapClick(e) {
    alert("You clicked the map at " + e.latlng);
  }
  var marker1 = L.marker([48.863, 2.329]).addTo(map);
  map.on('click', onMapClick);  
</script>
</body>
</html>

Voici la définition Purebasic du String correspondant au code HTML précedent, passé au gadget Webview avec:
SetGadgetItemText(#WebView_1, #PB_Web_HtmlCode, HTML.s)

Code : Tout sélectionner

Global HTML.s
HTML.s="<!DOCTYPE html>\n"+
       ~"<html lang=\"en\">\n"+
       ~"<head>\n"+
       ~"<meta charset=\"UTF-8\">\n"+
       ~"<title>Leaflet</title>\n"+
       ~"<link rel=\"stylesheet\" href=\"js/leaflet.css\" />\n"+
       ~"<script src=\"js/leaflet.js\"></script>\n"+
       ~"<style>\n"+
       ~"  body{\n"+
       ~"    margin: 0;\n"+
       ~"    padding: 0;\n"+
       ~"  }\n"+
       ~"  #map {\n"+
       ~"    width: 100vw;\n"+
       ~"    height: 100vh;\n"+
       ~"  }\n"+
       ~"</style>\n"+
       ~"</head>\n"+
       ~"<body>\n"+
       ~"<div id=\"Map\"></div>\n"+
       ~"<script>\n"+
       ~"  const Map = L.Map('map', {center: [48.86, 2.29], zoom: 12});\n"+
       ~"  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n"+
       ~"  attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors'\n"+
       ~"  }).addTo(Map);\n"+
       ~"function onMapClick(e) {\n"+
       ~"alert(\"You clicked the Map at \" + e.latlng);\n"+
       ~"}\n"+
       ~"var marker1 = L.marker([48.863, 2.329]).addTo(Map);\n"+
       ~"Map.on('click', onMapClick);\n"+
       ~"</script>\n"+
       ~"</body>\n"+
       ~"</html>"
Mon premier objectif est de visualiser une cartographie avec un code HTML passé au gadget Webview sous forme de String...
Ensuite, le but sera d'interagir avec le gadget Webview et Javascript (ajout de marqueurs, actualisation de positions avec des coordonnées GPS).

Je suis preneur de toute idée pour faire avancer ces tests.
Merci pour votre aide.
Dernière modification par vertexview le sam. 20/avr./2024 15:28, modifié 1 fois.
Avatar de l’utilisateur
vertexview
Messages : 10
Inscription : mer. 24/janv./2024 16:02

Re: Gadget Webview et Javascript

Message par vertexview »

J'ai modifié ma définition de String pour un code opérationnel.
La solution la plus simple a été de remplacer les deux lignes contenant un référencement local des fichiers leaflet (leaflet.css and leaflet.js) avec les liens réseaux associés.

Non opérationnel

Code : Tout sélectionner

~"<link rel=\"stylesheet\" href=\"js/leaflet.css\" />\n"+
~"<script src=\"js/leaflet.js\"></script>\n"+
Fonctionnement correct

Code : Tout sélectionner

~"<link rel='stylesheet' href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' integrity='sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=' crossorigin=''/> \n" +
~"<script src='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' integrity='sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=' crossorigin=''></script> \n" + 
Voici le nouveau string passé au gadget Webview permettant l'affichage de la cartographie.

Code : Tout sélectionner

Global HTML.s=""
HTML+  ~"<!DOCTYPE html> \n"+
       ~"<html lang='en'> \n"+
       ~"<head> \n"+
       ~"<meta charset='UTF-8'> \n"+
       ~"<title>Leaflet</title> \n"+
       ~"<link rel='stylesheet' href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' integrity='sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=' crossorigin=''/> \n" +
       ~"<script src='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' integrity='sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=' crossorigin=''></script> \n" +
       ~"<style> \n"+
       ~"  body{ \n"+
       ~"    margin: 0; \n"+
       ~"    padding: 0; \n"+
       ~"  } \n"+
       ~"  #map { \n"+
       ~"    width: 100vw; \n"+
       ~"    height: 100vh; \n"+
       ~"  } \n"+
       ~"</style> \n"+
       ~"</head> \n"+
       ~"<body> \n"+
       ~"<div id='map'></div> \n"+
       ~"<script>\n"+
       ~"  const map = L.map('map', {center: [48.86, 2.29], zoom: 12}); \n"+
       ~"  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { \n"+
       ~"  attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors' \n"+
       ~"  }).addTo(map); \n"+
       ~"function onMapClick(e) { \n"+
       ~"alert('You clicked the Map at ' + e.latlng); \n"+
       ~"} \n"+
       ~"var marker1 = L.marker([48.863, 2.329]).addTo(map); \n"+
       ~"map.on('click', onMapClick); \n"+
       ~"</script> \n"+
       ~"</body> \n"+
       ~"</html>"
Un code de démonstration réalisé par Kiffi est également disponible sur le forum Purebasic anglais.
https://www.purebasic.fr/english/viewto ... 55#p619755

Il reprend l'exemple générique du Quickstart Guide Leaflet.
https://leafletjs.com/examples/quick-start/
Avatar de l’utilisateur
vertexview
Messages : 10
Inscription : mer. 24/janv./2024 16:02

Re: Gadget Webview et Javascript

Message par vertexview »

Bonjour,
Je cherche un moyen simple d'interaction entre un programme Purebasic de cartographie et la librairie JS Leaflet chargée dans un Webview gadget.
Voici un code partiel de test qui présente le sujet.

Le premier besoin est de pouvoir changer le centre de la carte (nouvelles coordonnées GPS de référence) dynamiquement en cliquant sur un objet bouton défini en Purebasic.

Le principe actuellement envisagé est de modifier la variable Javascript concernée dans le code HTML (homeRef défini dans une partie script JS avec Tag) via une procédure utilisant WebViewExecuteScript.
Le code Purebasic, avec sa partie définition Javascript, doit être compatible avec les bases de structuration DOM HTML.
Si vous avez une idée pour compléter le code, je suis preneur...

Code : Tout sélectionner

Global HTML.s=""
HTML+  ~"<!DOCTYPE html> \n"+
       ~"<html lang='en'> \n"+
       ~"<head> \n"+
       ~"<meta charset='UTF-8'> \n"+
       ~"<title>Leaflet</title> \n"+
       ~"<link rel='stylesheet' href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' integrity='sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=' crossorigin=''/> \n" +
       ~"<script src='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' integrity='sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=' crossorigin=''></script> \n" +
       ~"<style> \n"+
       ~"  body{ \n"+
       ~"    margin: 0; \n"+
       ~"    padding: 0; \n"+
       ~"  } \n"+
       ~"  #map { \n"+
       ~"    width: 100vw; \n"+
       ~"    height: 100vh; \n"+
       ~"  } \n"+
       ~"</style> \n"+
       ~"</head> \n"+
       ~"<body> \n"+
       ~"<div id='map'></div> \n"+
       ~"<script id=\"homeValue\">let homeRef = [48.850, 2.350]</script>\n"+       
       ~"<script>\n"+
       ~"  const map = L.map('map', {center: homeRef, zoom: 12}); \n"+
       ~"  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { \n"+
       ~"  attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors' \n"+
       ~"  }).addTo(map); \n"+
       ~" const circle1 = L.circle(homeRef, {radius: 5000}).addTo(map); \n"+
       ~" const circle2 = L.circle(homeRef, {radius: 10000}).addTo(map); \n"+
       ~" circle1.setStyle({color: 'red'}); \n"+
       ~" circle1.setStyle({weight:1.0}); \n"+
       ~" circle1.setStyle({fillOpacity:0.01}); \n"+
       ~" circle2.setStyle({color: 'blue'}); \n"+
       ~" circle2.setStyle({weight:1.0}); \n"+
       ~" circle2.setStyle({fillOpacity:0.01}); \n"+
       ~"function onMapClick(e) { \n"+
       ~"alert('You clicked the Map at ' + e.latlng); \n"+
       ~"} \n"+
       ~"var marker1 = L.marker([48.84, 2.32]).addTo(map); \n"+
       ~"var marker2 = L.marker([48.88, 2.36]).addTo(map); \n"+
       ~"map.on('click', onMapClick); \n"+
       ~"</script> \n"+
       ~"</body> \n"+
       ~"</html>"
    
 
  Procedure HomeValueCallback(ParametreJSON$)
    ; Change JS variable value in script
    WebViewExecuteScript(0, ~"const element=document.getElementById(\"homeValue\"); element.textContent=\"let homeRef = [48.874, 2.295]\";");
  EndProcedure
  
  Procedure ChangeMapCenter(Eventype)
     BindWebViewCallback(0, "homeValue", @HomeValueCallback())
  EndProcedure  

  OpenWindow(0, 100, 100, 1200, 768, "Webview Callback Test", #PB_Window_SystemMenu)

  WebViewGadget(0, 0, 0, 1024, 768, #PB_WebView_Debug)
  SetGadgetItemText(0, #PB_WebView_HtmlCode, HTML.s)
  ButtonGadget(#PB_Any, 1040,  200, 140, 40, "Change Map Center")
  
  ; Call ChangeMapCenter procedure

  Repeat 
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget
      ChangeMapCenter(Eventype)
    EndIf
    
  Until Event = #PB_Event_CloseWindow
  End
Avatar de l’utilisateur
vertexview
Messages : 10
Inscription : mer. 24/janv./2024 16:02

Re: Gadget Webview et Javascript

Message par vertexview »

Bonjour,
Voici un code fonctionnel et compact, ceci après plusieurs échanges fructueux sur le forum anglais avec Kiffi et JHPJHP.
https://www.purebasic.fr/english/viewtopic.php?t=84085

Code : Tout sélectionner

EnableExplicit

Enumeration
  #Window
  #WebViewGadget
  #ButtonGadgetParis
  #ButtonGadgetLondon
  #ButtonGadgetMadrid
  #ButtonGadgetBerlin
EndEnumeration

Define HTML.s= ~"<!DOCTYPE html> \n"+
               ~"<html lang='en'> \n"+
               ~"<head> \n"+
               ~"<meta charset='UTF-8'> \n"+
               ~"<title>Leaflet</title> \n"+
               ~"<link rel='stylesheet' href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' integrity='sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=' crossorigin=''/> \n" +
               ~"<script src='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' integrity='sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=' crossorigin=''></script> \n" +
               ~"<style> \n"+
               ~"  body{ \n"+
               ~"    margin: 0; \n"+
               ~"    padding: 0; \n"+
               ~"  } \n"+
               ~"  #map { \n"+
               ~"    width: 100vw; \n"+
               ~"    height: 100vh; \n"+
               ~"  } \n"+
               ~"</style> \n"+
               ~"</head> \n"+
               ~"<body> \n"+
               ~"<div id='map'></div> \n"+
               ~"<script>\n"+
               ~"  let homeRef = [48.850, 2.350]; \n"+
               ~"  const map = L.map('map', {center: homeRef, zoom: 12}); \n"+
               ~"  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { \n"+
               ~"  attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors' \n"+
               ~"  }).addTo(map); \n"+
               ~" const circle1 = L.circle(homeRef, {radius: 5000}).addTo(map); \n"+
               ~" const circle2 = L.circle(homeRef, {radius: 10000}).addTo(map); \n"+
               ~" circle1.setStyle({color: 'red'}); \n"+
               ~" circle1.setStyle({weight:1.0}); \n"+
               ~" circle1.setStyle({fillOpacity:0.01}); \n"+
               ~" circle2.setStyle({color: 'blue'}); \n"+
               ~" circle2.setStyle({weight:1.0}); \n"+
               ~" circle2.setStyle({fillOpacity:0.01}); \n"+
               ~"\n"+
               ~"function goTo(lat, lng) { \n"+
               ~"  map.flyTo(new L.LatLng(lat, lng)); \n"+
               ~"} \n"+
               ~"\n"+
               ~"</script> \n"+
               ~"</body> \n"+
               ~"</html>"

Procedure ButtonGadgetParisEvent()
  WebViewExecuteScript(#WebViewGadget, "goTo(48.850, 2.350);")
EndProcedure

Procedure ButtonGadgetLondonEvent()
  WebViewExecuteScript(#WebViewGadget, "goTo(51.509865, -0.118092);")
EndProcedure

Procedure ButtonGadgetMadridEvent()
  WebViewExecuteScript(#WebViewGadget, "goTo(40.416775, -3.703790);")
EndProcedure

Procedure ButtonGadgetBerlinEvent()
  WebViewExecuteScript(#WebViewGadget, "goTo(52.520007, 13.404954);")
EndProcedure


OpenWindow(#Window, 100, 100, 1200, 768, "Webview Callback Test", #PB_Window_SystemMenu)
WebViewGadget(#WebViewGadget, 0, 0, 1024, 768, #PB_WebView_Debug)
SetGadgetItemText(#WebViewGadget, #PB_WebView_HtmlCode, HTML.s)
ButtonGadget(#ButtonGadgetParis, 1040,  200, 140, 40, "Aller à Paris")
ButtonGadget(#ButtonGadgetLondon, 1040,  300, 140, 40, "Aller à Londres")
ButtonGadget(#ButtonGadgetMadrid, 1040,  400, 140, 40, "Aller à Madrid")
ButtonGadget(#ButtonGadgetBerlin, 1040,  500, 140, 40, "Aller à Berlin")

BindGadgetEvent(#ButtonGadgetParis, @ButtonGadgetParisEvent())
BindGadgetEvent(#ButtonGadgetLondon, @ButtonGadgetLondonEvent())
BindGadgetEvent(#ButtonGadgetMadrid, @ButtonGadgetMadridEvent())
BindGadgetEvent(#ButtonGadgetBerlin, @ButtonGadgetBerlinEvent())

Repeat 
Until WaitWindowEvent() = #PB_Event_CloseWindow 
Dernière modification par vertexview le mer. 09/juil./2025 17:43, modifié 1 fois.
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: Gadget Webview et Javascript

Message par SPH »

Waouw, impressionnant !! :!:

Merci pour ce code. :o

Tu veux coder quoi sur cette base ? :?:

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Gadget Webview et Javascript

Message par Ar-S »

C'est très fluide bravo.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
vertexview
Messages : 10
Inscription : mer. 24/janv./2024 16:02

Re: Gadget Webview et Javascript

Message par vertexview »

Bonjour,
Les utilisations possibles concernant des cartographies interactives semblent nombreuses, ceci en prenant en compte les fonctions disponibles dans la librairie Leaflet et ses possibilités graphiques.
Détail de l'API: https://leafletjs.com/reference.html

Le point délicat était d'avoir un moyen d'interaction simple entre un code Purebasic et cette librairie JS.
A priori, le composant WebView associé à WebViewExecuteScript semble répondre aux besoins.

Pour le fun, j'ai poursuivi le développement du code associé au décodage ADS-B sur clef RTL-SDR (voir viewtopic.php?p=218980#p218980).
J'ai maintenant un code qui me permet de déterminer les coordonnées des avions reçus (codage CPR ADS-B), l'altitude, l'identifiant de vol, et d'interroger des bases de données spécialisées en mode HTTP pour obtenir des informations JSON complémentaires (récupération du modèle d'avion, compagnie, propriétaire,...).
Un onglet avec la vue cartographique des avions locaux, comme sur le site https://globe.adsbexchange.com/, ne semble pas irréaliste...
Répondre