InitProcess - 29/03/2025 17:17:36

Capable de process préemptif

      ErrorNum:=0
ON ERR CALL(Formula(traceHandler).source)

// init variables des méthodes renvoyant $0 typé (pour le mode interprété)
dataTexte:=""
dataEntierLong:=0
dataDate:=!00-00-00!
dataBooléen:=False


    

Installer Cartographie - 06/02/2026 17:52:24

Capable de process préemptif

      #DECLARE($commande : Text)
// remarque : pour l'instant ne sert pas !!!

Case of 
	: (Count parameters=0)
		
		Installer Cartographie("Installer")
		
	: ($commande="IntégrationDansHôte")
		CALL WORKER("WK_Composant_CARTO"; Current method name; "IntégrerDansHôte")
		
	: ($commande="Installer")
		cs._Trace.me.EnvoyerMessages([msgk_event; msgk_log]; "Démarrage"; Current method name; "Installer Cartographie")
		
		// intégrer le composant dans la base hôte
		If (Storage.System.estExecuteDansHote)
			CALL WORKER("WK_Composant_CARTO"; Current method name; "IntégrerDansHôte")
		End if 
		
	: ($commande="IntégrerDansHôte")
		// à ce stade , la base n'est pas complètement ouverte ; boucler en attentant que les données à modifier soient présentes
		
		cs._Trace.me.EnvoyerMessages([msgk_event; msgk_log]; "Intégration"; Current method name; "Intégrer dans base hôte")
		
	: ($commande="ActualiserBarreMenus")
		// installer les menus dans la base hôte
		// ici rien
		
End case 

    

traceHandler - 22/12/2024 19:47:27

Capable de process préemptif

      cs._Trace.me.Intercepter()

    

COMPILER - 01/12/2024 12:18:33

      var ErrorNum : Integer
var ErrorDescription : Text

var dataEntierLong : Integer

var dataTexte : Text
var dataDate : Date
var dataBooléen : Boolean



    

Bac a sable CARTO - 28/05/2025 11:18:37

Partagée entre composants et base hôte

      var $o : Object

//$o:=cs.xSQL.Communes.new(92)
//ALERT(JSON Stringify($o; *))

//cs._Trace.me.EnvoyerMessages([msgk_event; msgk_log]; "toto"; Current method name; "ututut")

// ouvrir l'éditeur des traductions
cs.xSDK.TraductionsEditeur.new().ModifierTraductions()


    

[class]Lieux - 29/05/2025 14:04:46

      // attributs de la classe
property type : Integer
property latitude; longitude : Real

Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDentity de la BDD
	
	Super("Lieux"; $IDentity)
	
	
	// ----------------------
	//MARK:Wrappers
	// ----------------------
	
Function LesEvents()->$result : Collection
	// transformer .LesEvents en classe de de ce composant
	var $sélection : Collection
	var $ID : Integer
	
	$result:=New collection
	
	$sélection:=This.fct.LesEvents()
	// mettre au format du composant
	For each ($ID; $sélection)
		$result.push(cs.Events.new($ID))
	End for each 
	
	
Function LesMedias()->$result : Collection
	// transformer .LesMedias en classe de de ce composant
	var $sélection : Collection
	var $ID : Integer
	
	$result:=New collection
	
	$sélection:=This.fct.LesMedias()
	// mettre au format du composant
	For each ($ID; $sélection)
		$result.push(cs.Medias.new($ID))
	End for each 
	
	
	// ----------------------
	//MARK:Sélection
	// ----------------------
	
Function LesLiensPersonnels($params : Object)->$result : Collection
	// renvoie une collection de medias ou events liées à this par les personnes deQui
	var $sélection; $c : Collection
	var $entité : Object
	
	$result:=New collection
	
	// d'abord rechercher les events du lieu liés à .deQui
	$sélection:=This.LesEvents()
	Case of 
		: ($sélection.length=0)
		: (Not(OB Is defined($params; "deQui")))
		: (Not(OB Is defined($params.deQui; "sélection")))
		Else 
			// collection les ID des personnes liées à chaque event
			For each ($entité; $sélection)
				// ces personnes sont les protagonistes et les témoins
				$c:=$entité.LesProtagonistes()
				$c:=$c.combine($entité.LesTémoins("Groupe1"))
				$c:=$c.combine($entité.LesTémoins("Groupe2"))
				
				If (This.estLiéAdeQui($c; $params.deQui.sélection))
					// cet event est lié à deQui
					$result.push($entité)
				End if 
			End for each 
	End case 
	
	// puis rechercher les medias du lieu liés à deQui
	$sélection:=This.LesMedias()
	Case of 
		: ($sélection.length=0)
		: (Not(OB Is defined($params; "deQui")))
		: (Not(OB Is defined($params.deQui; "sélection")))
		Else 
			// collection les ID des personnes liées à chaque media
			For each ($entité; $sélection)
				// ces personnes sont les protagonistes et les témoins
				$c:=$entité.LesPersonnes()
				
				If (This.estLiéAdeQui($c; $params.deQui.sélection))
					// ce media lié à deQui
					$result.push($entité)
				End if 
			End for each 
	End case 
	
	
Function estLiéAdeQui($sélection : Collection; $deQui : Collection)->$result : Boolean
	var $c; $cc : Collection
	var $ID : Integer
	
	$c:=New collection
	For each ($ID; $sélection)
		$c.push(CodeEnreg($ID; [1]))
	End for each 
	$c:=$c.distinct()
	
	// est ce que $c contient .deQui
	// principe (autre ?) : unir les 2 collections, et chercher les valeurs distinctes : si $c augmente c'est que $nomProc n'affiche pas deQui demandé
	$cc:=$deQui.copy()
	$cc:=$cc.combine($c).distinct()
	$result:=($c.length=$cc.length)
	
	
	// ----------------------
	//MARK:Marker
	// ----------------------
	
Function getIconeURL($params : Object)->$result : Object
	// renvoyer les données de l'icone : 
	// .url : URL du fichier d'un icône standard ; créer le fichier si possible
	// .nomFichier : nom du fichier de l'icone
	// .image : l'image
	var $image : Picture
	
	$result:=New object
	
	// déjà en ressources
	$result.nomFichier:=String(This.type)+".png"
	If (OB Is defined($params.Apparence; "LieuxIconeURL"))
		$result.nomFichier:=$params.Apparence.LieuxIconeURL
	End if 
	
	// chemin du fichier
	$result.url:=$params.ressourcesURL+$params.sousDossierImages+"/"+$result.nomFichier
	// image
	READ PICTURE FILE(Folder(fk resources folder).folder("Images/ Cartographie").file($result.nomFichier).platformPath; $image)
	$result.image:=$image
	
	// ajouter à la collection
	$params.IconesData[$result.nomFichier]:=$result
	
	
Function PopUpContenu($params : Object)->$result : Text
	var $texte : Text
	
	// d'abord, le label de l'entité
	$texte:=Super.PopUpLabel()
	
	// la description
	$texte:=$texte+This.PopUpDescription($params)
	$result:=$texte
	
	
Function PopUpDescription($params : Object)->$result : Text
	// la description standard du popup
	var $texte : Text
	var $formats; $entité; $data : Object
	var $c; $cc : Collection
	
	If ($params.PopUpLiens)
		$params.label:=This.getIconeID()
		$formats:=New object
		
		// le label complet
		// premier bloc : label complet
		$texte:="<div id="+Char(Double quote)+"popUpLabel_"+This.getIconeID()+Char(Double quote)+">"
		$entité:=This.Le("Communes")
		$texte:=$texte+"<div class="+Char(Double quote)+"item"+Char(Double quote)+" src="+Char(Double quote)+$entité.getIconeURL($params).url+Char(Double quote)+">"
		$formats.Options:=$params.PopUpOptions[$entité.DataClassNom]
		$texte:=$texte+"<p>"+$entité.Libellé($formats)+"/br/"
		// le lieu
		$formats.Options:=$params.PopUpOptions[This.DataClassNom]
		$texte:=$texte+This.Libellé($formats)+"/br/"
		
		// puis la geolocalisation
		$texte:=$texte+Localized string("44")+" "+String(This.latitude; "^##.000000#°  Nord;-##.000000#°   Sud;0")+", "+Localized string("45")+" "+String(This.longitude; "^###.0000000#°   Est;-###.0000000#° Ouest;0")
		$texte:=$texte+"</p>"+"</div>"+"</div>"
		
		If (OB Is defined($params; "deQui"))
			// second bloc : liste de liens à ce lieu
			// chercher les liens (forcément event ou media)
			$c:=New collection
			$c:=This.LesLiensPersonnels(New object("deQui"; $params.deQui))
			// trier la collection d'entités par date
			$c:=$c.orderBy(New collection(New object("propertyPath"; "dateNum"; "descending"; False)))
			
			// ajouter au contenu de l'info-bulle
			// - le lien : il appelle le diaporama, paramètre = collection JSONnée de IDlieu et des IDobjets du lieu
			$cc:=New collection
			For each ($data; $c)
				$cc.push($data.IDcodé())
			End for each 
			
			Case of 
				: (True)
					// BDDmère
					$texte:=$texte+"<p id ="+Char(Double quote)+"popUp4Dparams_"+This.getIconeID()+Char(Double quote)+">,"+String($entité.IDcodé())+","+JSON Stringify($cc)+"</p>"
					
				Else 
					// page Web
					$texte:=$texte+"<a href="+Char(Double quote)+"/4DCGI/HTTP/wwwTraiterActionCarto"+Char(Double quote)+">"
			End case 
			
			// - la liste des entités liées à ce lieu (media ou events)
			// rappel : en ALVclient, le libellé est calculé sur le serveur où les userPrefs ne sont pas connues. Les fixer ici
			$formats:=$params.formats
			$texte:=$texte+"<div id="+Char(Double quote)+"popUpTab_"+This.getIconeID()+Char(Double quote)+">"
			For each ($data; $c)
				// écrire l'icone
				$texte:=$texte+"<div class="+Char(Double quote)+"item"+Char(Double quote)+" src="+Char(Double quote)+$data.getIconeURL($params).url+Char(Double quote)+">"
				// écrire le libellé
				$formats.Options:=$params.PopUpOptions[$data.DataClassNom]
				$texte:=$texte+"<p>"+$data.Libellé($formats)+"</p>"
				$texte:=$texte+"</div>"
			End for each 
			
			// c'est fini, fermer les balises
			$texte:=$texte+"</div>"
		End if 
		
	Else 
		$texte:=""
	End if 
	$result:=$texte
	
	
    

[class]Departements - 14/12/2024 11:05:13

      Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDunique de la BDD
	
	Super("Departements"; $IDentity)
	
	
Function PopUpContenu($params : Object)->$result : Text
	var $texte : Text
	
	// d'abord, le label de l'entité
	$texte:=Super.PopUpLabel()
	
	// la description
	$texte:=$texte+This.PopUpDescription($params)
	
	$result:=$texte
	
    

[class]_Trace - 30/12/2024 13:46:37

      property cible : cs.xSDK.Traces
property success : Boolean

singleton Class constructor()
	
	This.cible:=cs.xSDK.Traces.new()
	This.success:=False
	
	
Function set Error($numError : Integer)
	This.cible.Error:=$numError
	
Function get Error()->$result : Integer
	$result:=This.cible.Error
	
	
Function set ErrorDescription($description : Text)
	This.cible.ErrorDescription:=$description
	
Function get ErrorDescription()->$result : Text
	$result:=This.cible.ErrorDescription
	
	
Function Intercepter()
	ErrorNum:=This.cible.Intercepter("CARTO"; Error; Error method; Error line; Error formula)
	
	
Function Initialiser($nomMethode : Text)->$result : Object
	This.cible.CréerErreur("CARTO"; 0; $nomMethode; "")
	$result:=This
	
	
Function Créer($Error : Integer; $nomMethode : Text; $ErrorDescription : Text)->$result : Object
	This.cible.CréerErreur("CARTO"; $Error; $nomMethode; $ErrorDescription)
	$result:=This
	
	
Function FixerSuccess()
	This.cible.FixerSuccess()
	This.success:=This.cible.success
	
	
Function LeverException($options : Collection)
	// renseigner le label de l'erreur
	This.cible.ErrorLabel:=Localized string(String(This.cible.Error))
	// lancer le traitement de l'erreur
	This.cible.LeverException($options)
	
	
Function EnvoyerMessages($options : Collection; $libellé : Text; $source : Text; $description : Text)
	This.cible.EnvoyerMessages($options; "CARTO"; $libellé; $source; $description)
	
	
	
    

[class]$composant - 06/02/2026 17:53:02

      property trace : cs._Trace

Class constructor()
	
	This.trace:=cs._Trace.me
	
	
	
Function InitVariablesCARTO()
	
	Use (Storage)
		Storage["System"]:=New shared object
	End use 
	
	Use (Storage.System)
		// sert, rapidement, dans initExtensions
		Storage.System.Status:=0
		// sert, en particulier, pour les process de type monitoring
		Storage.System.ArrêtAPP:=False
		
		Storage.System.estExecuteDansHote:=False
		Storage.System.estExecuteDansAPP:=cs.xSDK.EnvironnementALV.new().estExecuteDansAPP()
	End use 
	
	
	// ----------------------
	// MARK:Installation
	// ----------------------
	
Function InstallerRessources($cheminDossier : Text)
	// installer les fichiers ressources carto du composant et d'OpenLayers dans le dossier $1
	// function appeler par un utilisateur du composant (serveur ALV, serveur Web, BDDmère)
	var $i : Integer
	var $nomDossier : Text
	
	$nomDossier:=Localized string("163")
	
	ARRAY OBJECT($tabDossiersSource; 0)
	ARRAY OBJECT($tabDossiersDestination; 0)
	
	// pour le serveur Web
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("TemplatesPagesWeb"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path))
	
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("javascripts").folder("OpenLayers"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path).folder($nomDossier).folder("js"))
	
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("css").folder("OpenLayers"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path).folder($nomDossier).folder("css"))
	
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("javascripts").folder("GpPluginOpenLayers"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path).folder($nomDossier).folder("js"))
	
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("css").folder("GpPluginOpenLayers"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path).folder($nomDossier).folder("css"))
	
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("Images"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path).folder($nomDossier).folder("images"))
	
	APPEND TO ARRAY($tabDossiersSource; Folder(Get 4D folder(Current resources folder); fk platform path).folder("css").folder("Cartographie"))
	APPEND TO ARRAY($tabDossiersDestination; Folder($cheminDossier; fk platform path).folder($nomDossier).folder("css"))
	
	// recopier le contenu des dossiers
	For ($i; 1; Size of array($tabDossiersSource))
		Dupliquer ContenuDeDossier($tabDossiersSource{$i}; $tabDossiersDestination{$i})
	End for 
	
	cs._Trace.me.EnvoyerMessages([msgk_event; msgk_log]; "Information"; Current method name; "Copie dans "+$cheminDossier+$nomDossier)
	
	
Function InstallerRessourcesAPP($cheminDossier : Text)
	// pour les App (BDDmère, ServeurAPP)
	var $dossierSource; $dossierDestination : 4D.Folder
	
	$dossierSource:=Folder(Get 4D folder(Current resources folder); fk platform path).folder("TemplatesPagesWeb")
	$dossierDestination:=Folder(Get 4D folder(Current resources folder; *); fk platform path).folder("TemplatesPagesWeb")
	
	Dupliquer ContenuDeDossier($dossierSource; $dossierDestination)
	
	
    

[class]_CARTO_DataStore - 29/05/2025 14:05:54

      property fct : Object
// attributs de la classe fct
property DataClassNom : Text
property ID : Integer
property drapeau; blason : Picture

Class extends $composant

Class constructor($DataClassNom : Text; $IDentity : Variant)
	
	Super()
	
	This.fct:=cs.xSQL[$DataClassNom].new($IDentity)
	// récupérer les attributs dans this
	cs.xSDK.Outils.me.CopierAttributs(This.fct; This)
	
	
	// ----------------------
	//MARK:Wrappers
	// ----------------------
	
Function Libellé($formats : Object)->$libellé : Text
	// renvoie le nom formaté de this suivant les options $formats
	$libellé:=This.fct.Libellé($formats)
	
	
Function Le($DataClassNom : Text)->$result : Object
	// renvoie l'entité [$DataClassNom] de ce composant (la classe doit exister !)
	var $entité : Object
	
	$entité:=This.fct.Le($DataClassNom)
	// ajouter les fonctions Carto
	$result:=cs[$DataClassNom].new($entité.ID)
	
	
Function LesLieux()->$c : Collection
	$c:=This.fct.LesLieux()
	
	
Function IDcodé()->$result : Integer
	$result:=This.fct.IDcodé()
	
	
	// ----------------------
	//MARK:Marker
	// -----------------------
	
Function getIconeID()->$result : Text
	// renvoyer l'ID de l'icone de l'entité this
	$result:=This.DataClassNom+"_"+String(This.ID)
	
	
Function getIconeURL($params : Object)->$result : Object
	// renvoyer les données standard de l'icone : 
	// .url : URL du fichier d'un icône standard
	// .nomFichier : nom du fichier de l'icone
	// .image : l'image
	var $image : Picture
	
	$result:=New object
	
	// URL du fichier
	$result.url:=$params.dossierURL+$params.sousDossierImages+"/"+This.DataClassNom+"_"+String(This.ID)+".png"
	
	// créer la ressource (blason)
	// l'entité n'a pas d'image ; image par défaut :
	READ PICTURE FILE(Folder(fk resources folder).folder("Images/Cartographie").file("60300.png").platformPath; $image)
	$result.nomFichier:=This.DataClassNom+"_"+String(This.ID)+".png"
	Case of 
		: (Not(OB Is defined(This; "blason")))
			// verrue pour le pays
			Case of 
				: (Not(OB Is defined(This; "drapeau")))
				: (Picture size(This.drapeau)=0)
					
				Else 
					// c'est ok, créer la ressource
					$image:=This.drapeau
			End case 
			
		: (Picture size(This.blason)=0)
			
		Else 
			// c'est ok, créer la ressource
			$image:=This.blason
	End case 
	CREATE THUMBNAIL($image; $image; 32; 32; Scaled to fit prop centered)
	$result.image:=$image
	
	
Function PopUpContenu($params : Object)->$result : Text
	// contenu standard
	var $texte : Text
	// 29/05/2024 ça sert ?
	
	// d'abord, le label de l'entité
	$texte:=This.PopUpLabel()
	
	// la description
	$texte:=$texte+This.PopUpDescription($params)
	
	$result:=$texte
	
	
Function PopUpLabel()->$result : Text
	// le label standard du popup
	var $formats : Object
	
	$result:=This.getIconeID()
	$formats:=New object("Options"; 0)  // toujours un label
	$result:="<p id="+Char(Double quote)+"label_"+$result+Char(Double quote)+">"+This.Libellé($formats)+"</p>"
	
	
Function PopUpDescription($params : Object)->$result : Text
	// la description standard du popup
	var $texte : Text
	var $formats : Object
	
	// le label complet
	$texte:="<div id="+Char(Double quote)+"popUpLabel_"+This.getIconeID()+Char(Double quote)+">"
	$texte:=$texte+"<div class="+Char(Double quote)+"item"+Char(Double quote)+" src="+Char(Double quote)+This.getIconeURL($params).url+Char(Double quote)+">"
	$formats:=New object("Options"; 0x01C80000)
	$texte:=$texte+"<p>"+This.Libellé($formats)+"</p>"
	$texte:=$texte+"</div>"+"</div>"
	
	$result:=$texte
	
    

[class]Sites - 14/12/2024 11:06:06

      // remarque : ne sert pas
Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDunique de la BDD
	
	Super("Sites"; $IDentity)
	
	
    

[class]Regions - 14/12/2024 11:05:56

      Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDunique de la BDD
	
	Super("Regions"; $IDentity)
	
	
	// ----------------------
	//MARK:Markers
	// -----------------------
	
Function PopUpContenu($params : Object)->$result : Text
	var $texte : Text
	var $formats : Object
	
	// d'abord, le label de l'entité
	$texte:=Super.PopUpLabel()
	
	// puis le label complet
	$texte:=$texte+"<div id="+Char(Double quote)+"popUpLabel_"+This.getIconeID()+Char(Double quote)+">"
	$texte:=$texte+"<div class="+Char(Double quote)+"item"+Char(Double quote)+" src="+Char(Double quote)+This.getIconeURL($params).url+Char(Double quote)+">"
	$formats:=New object("Options"; 0x01C80000)
	$texte:=$texte+"<p>"+This.Libellé($formats)
	$texte:=$texte+"</p>"+"</div>"+"</div>"
	
	$result:=$texte
	
    

[class]Pays - 14/12/2024 11:05:48

      Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDunique de la BDD
	
	Super("Pays"; $IDentity)
	
	
	// ----------------------
	//MARK:Markers
	// -----------------------
	
Function PopUpContenu($params : Object)->$result : Text
	var $texte : Text
	
	// d'abord, le label de l'entité
	$texte:=Super.PopUpLabel()
	
	// la description
	$texte:=$texte+This.PopUpDescription($params)
	
	$result:=$texte
    

[class]$carte - 29/01/2026 08:47:57

      property MarkersData; dossierCartoURL; dossierURL; ressourcesURL; nomFichierMarkers; cheminSessionFolder; cheminDossierSession; cheminDossierImages; sousDossierImages : Text
property formats; MarkersListe; IconesData; HTTPvars; data : Object
property markers; laZone; sélection; région; laRégion : Collection

Class extends $composant

Class constructor()
	
	Super()
	
	
	
Function InitClass($params : Object)
	var $attribut : Text
	
	// initialiser les paramètres dans la classe
	// séparément, pour le paramétrage des functions de this
	For each ($attribut; $params)
		This[$attribut]:=$params[$attribut]
	End for each 
	
	
	// ----------------------
	//MARK:Data
	// ----------------------
	
Function getCarteData($params : Object)
	// Créer les fichiers de données nécessaires à OpenStreet
	
	// tester les params
	Case of 
		: (Not(OB Is defined($params; "cheminSessionFolder")))
			This.trace.Créer(-15068; Current method name; "'cheminSessionFolder' n'est pas défini dans $params").LeverException([msgk_event; msgk_log])
		: (Not(OB Is defined($params; "Apparence")))
			This.trace.Créer(-15068; Current method name; "'Apparence' n'est pas défini dans $params").LeverException([msgk_event; msgk_log])
			
		Else 
			// ok
			// les formats
			$params.formats:=$params.Apparence
			
			// récupérer les paramètres dans la classe
			This.InitClass($params)
			
			// exécuter, pour l'instant dans le process courant
			This.getCarteData_process()
			// ajouter les données créées
			This.setCarteDataSession($params)
			This.setCarteDataApp()
	End case 
	
	
Function setCarteDataSession($params : Object)
	$params.data:=New object
	$params.data.MarkersData:=This.MarkersData
	$params.data.MarkersListe:=This.MarkersListe
	$params.data.IconesData:=This.IconesData
	$params.data.HTTPvars:=This.HTTPvars
	
	
Function setCarteDataApp()
	// données utilisées par Lire_MarkersData dans un contexte autre qu'une session
	Use (Session.storage)
		Session.storage.CARTO_Data:=New shared object  //This.MarkersData
		Use (Session.storage.CARTO_Data)
			Session.storage.CARTO_Data.MarkersData:=This.MarkersData
		End use 
	End use 
	
	
Function getCarteDataApp($params : Object)
	// insérer dans la page Web les données markers lus dans 'CARTO_Data' 
	// cette méthode traite le cas du serveur Web (site Web et mobile)
	var $texte; $dataTexte : Text
	
	$texte:=""
	Case of 
		: (Session.storage=Null)
			// on n' est pas dans une session user (=> BDDmère, client, site static...)
			$texte:=Storage.System.MarkersData
			
		: (Not(OB Is defined(Session.storage; "CARTO_Data")))
		Else 
			// ok, on est dans une session (WEB, MOB...)
			// renvoyer le contenu
			$texte:=Session.storage.CARTO_Data.MarkersData
	End case 
	BASE64 ENCODE($texte; $dataTexte)
	$params.MarkersData:=$dataTexte
	
	
Function getCarteData_process()
	var $data : Object
	var $dataTexte : Text
	
	// créer la sélection de lieux de la zone à afficher
	// rappel : la sélection peut-être hétérogène (lieux + communes +...)
	This.laZone:=This.CréerSélection(This.sélection)
	
	// calculer le centre et le zoom de la zone :
	$data:=New object
	Case of 
		: (OB Is defined(This; "région"))
			This.laRégion:=This.CréerSélection(This.région)
			This.getCentreDeLaZone(This.laRégion; $data)
			// on a le centre de la région
			
		: (This.getCentreDeLaZone(This.laZone; $data))
			// on a le centre de la zone
			
		Else 
			// on n'a rien
			$data:=Null
	End case 
	
	If ($data#Null)
		This.HTTPvars.wwwCarto_LatitudeCentre:=$data.LatitudeCentre
		This.HTTPvars.wwwCarto_LongitudeCentre:=$data.LongitudeCentre
		This.HTTPvars.wwwZoneWeb_Zoom:=$data.Zoom
	End if 
	
	// pour ??
	This.HTTPvars.ZoneWeb_Largeur:="100"+Char(37)
	This.HTTPvars.ZoneWeb_Hauteur:="100"+Char(37)
	
	// créer les données de la carte
	// pour la page web, URL des ressources
	This.dossierURL:=This.dossierCartoURL+"/"+Localized string("100")+"/"  // pour la page Web, icones d'instance vues au niveau de la session
	This.ressourcesURL:=This.HTTPvars.wwwRacineRessources+Localized string("163")+"/"  // pour la page Web, icones de ressources vues au niveau de la racine du site
	// url des ressources markers de la page
	This.HTTPvars.wwwMediaPath:=This.dossierCartoURL+"/"+Localized string("100")+"/"+This.nomFichierMarkers
	
	// créer le fichier dataGP.js dans le dossier de session
	This.getMarkersListe()
	// renvoyer les données des markers : MarkersData, MarkersListe, IconesData
	
	
	// ----------------------
	//MARK:Markers
	// ----------------------
	
Function getMarkersListe()
	// Créer le fichier des markers au format GeoPortail
	var $ID : Integer
	var $entité : Object
	
	Case of 
		: (Not(OB Is defined(This; "laZone")))
			This.trace.Créer(-15068; Current method name; "'laZone' n'est pas défini dans $params").LeverException([msgk_event; msgk_log])
			
		Else 
			This.trace.EnvoyerMessages([msgk_event; msgk_log]; "Démarrage"; Current method name; "Liste de "+String(This.laZone.length)+" lieux")
			
			This.MarkersListe:=New object
			This.MarkersData:=""
			This.IconesData:=New object
			
			// créer la structure
			This.MarkersListe.type:="FeatureCollection"
			This.MarkersListe.name:="Lieux ALV"
			This.MarkersListe.description:="Carte des lieux serveur AinsiLaVie"
			
			// recréer les objets de classe
			This.markers:=New collection
			For each ($ID; This.laZone)
				$entité:=cs.Lieux.new($ID)
				This.markers.push($entité)
			End for each 
			
			// Créer les styles des icones
			// Ajouter les données des lieux
			This.AjouterMarker()
			This.AjouterPopUp()
			
			// Ajouter les données des Communes
			This.getEntités("Communes")
			This.AjouterMarker()
			This.AjouterPopUp()
			
			// Ajouter les données des Departements
			This.getEntités("Departements")
			This.AjouterMarker()
			This.AjouterPopUp()
			
			// Ajouter les données des Regions
			This.getEntités("Regions")
			This.AjouterMarker()
			This.AjouterPopUp()
			
			// Ajouter les données des Pays
			This.getEntités("Pays")
			This.AjouterMarker()
			This.AjouterPopUp()
	End case 
	
	
Function AjouterMarker()
	// ajouter à $3 les positions à afficher de la sélection $3
	// {ajouter à $4 les icones (info-bulle en particulier)}
	var $entité; $data; $dataIcone : Object
	var $DataClassNom : Text
	
	If (Not(OB Is defined(This.MarkersListe; "features")))
		This.MarkersListe.features:=New collection
	End if 
	
	For each ($entité; This.markers)
		// filtrer les géoLoc vides (en particulier de pays, régions, départements, communes)
		$data:=New object("type"; "Feature"; "properties"; New object; "geometry"; New object)
		
		$DataClassNom:=$entité.DataClassNom
		// id du marqueur
		$data.properties.type:=$entité.getIconeID()
		$dataIcone:=$entité.getIconeURL(This)
		This.IconesData[$dataIcone.nomFichier]:=$dataIcone
		$data.properties.iconStyle:=$dataIcone.url
		$data.properties.textType:=Choose($entité.DataClassNom="Lieux"; ""; "hide")
		
		$data.geometry.type:="Point"
		$data.geometry.coordinates:=New collection(0; 0)
		Case of 
			: (Not(OB Is defined($entité; "latitude")))
			: (Not(OB Is defined($entité; "longitude")))
			Else 
				If (($entité.latitude#0) & ($entité.longitude#0))
					$data.geometry.coordinates:=New collection($entité.longitude; $entité.latitude)
				End if 
		End case 
		
		This.MarkersListe.features.push($data)
	End for each 
	
	
Function AjouterPopUp()
	// ajouter à This.MarkersData les données de  la sélection de This.markers : 
	//  . le label,
	// . le contenu de l'info bulle; les balises de style utilisent les CSS ALV
	var $dataTexte : Text
	var $formats; $entité : Object
	
	$dataTexte:=""
	If (OB Is defined(This; "MarkersData"))
		$dataTexte:=This.MarkersData
	End if 
	$formats:=This.formats
	
	For each ($entité; This.markers)
		$dataTexte:=$dataTexte+$entité.PopUpContenu(This)
	End for each 
	// mémoriser
	This.MarkersData:=$dataTexte
	
	
Function getEntités($DataClassNomCible : Text)
	// retourne dans this.markers la collections des entités administratives supérieures à this.markers
	var $c : Collection
	var $entité; $data : Object
	
	$c:=New collection
	For each ($entité; This.markers)
		$data:=$entité.Le($DataClassNomCible)
		Case of 
			: ($c.length=0)
				$c.push($data)
				
			: ($c.query("ID = :1"; $data.ID).length>0)
				// ne pas doublonnner
				
			Else 
				$c.push($data)
		End case 
	End for each 
	This.markers:=$c
	
	
	// ----------------------
	//MARK:BDDmère ou client
	// ----------------------
	
Function InstallerDonnées($params : Object)
	var $dossier : Object
	var $dataTexte : Text
	
	This.InitClass($params)
	
	// créer les fichiers de données dans la session courante
	$dossier:=Folder(This.cheminSessionFolder; fk platform path).folder(Localized string("100"))
	$dossier.create()
	This.cheminDossierSession:=$dossier.platformPath
	$dossier:=Folder(This.cheminDossierSession; fk platform path).folder(This.sousDossierImages)
	$dossier.create()
	This.cheminDossierImages:=$dossier.platformPath
	
	This.EnregistrerData()
	
	
Function EnregistrerData()
	// Créer le fichier.nomFichierMarkers
	var $dataTexte : Text
	
	Case of 
		: (Storage.System.ArrêtAPP)
		: (Not(OB Is defined(This; "cheminDossierSession")))
		: (Test path name(This.cheminDossierSession)#Is a folder)
			// la session n'existe peut-être plus
		: (Not(OB Is defined(This; "nomFichierMarkers")))
		Else 
			This.trace.EnvoyerMessages([msgk_event; msgk_log]; "CréerData"; Current method name; "Enregistrement des fichiers dans "+This.cheminDossierSession)
			
			// coté HTTP, les données sont lues par une balise <script>
			// pour cela le fichier doit être de type .js, et contenir une constante
			$dataTexte:=JSON Stringify(This.data.MarkersListe)
			// pour l'instant ...
			$dataTexte:=Replace string($dataTexte; "'"; "")
			$dataTexte:="const listeMarqueurs = "+Char(Quote)+$dataTexte+Char(Quote)+";"
			TEXT TO DOCUMENT(This.cheminDossierSession+This.nomFichierMarkers; $dataTexte)
			
			// placer les icones de la page
			This.EnregistrerDataImage()
	End case 
	
	
Function EnregistrerDataImage()
	// enregistrer les icones dans le dossier des images
	var $data; $dossier : Object
	var $fichier : Text
	var $image : Picture
	var $i : Integer
	ARRAY TEXT($Eléments; 0)
	
	Case of 
		: (Not(OB Is defined(This; "sousDossierImages")))
		: (Not(OB Is defined(This; "HTTPvars")))
		: (Not(OB Is defined(This.HTTPvars; "wwwContexteWeb")))
			This.trace.Créer(-15068; Current method name; "'ContexteWeb' n'est pas défini dans $params").LeverException([msgk_event; msgk_log])
		: (This.data.IconesData=Null)
		Else 
			// c'est ok
			$dossier:=Folder(This.cheminDossierImages; fk platform path)
			Case of 
				: (Not($dossier.exists))
					$dossier.create()
					
				: (This.HTTPvars.wwwContexteWeb="WEBstatic")
					// pour le site Web le dossier contient toutes images de tous les lieux
					
				Else 
					// serveur Web : on ré initialise
					$dossier.delete(Delete with contents)
					$dossier.create()
			End case 
			
			// liste des icones
			$data:=This.data.IconesData
			OB GET PROPERTY NAMES($data; $Eléments)
			For ($i; 1; Size of array($Eléments))
				$fichier:=$data[$Eléments{$i}].nomFichier
				$fichier:=$dossier.platformPath+$fichier
				$image:=$data[$Eléments{$i}].image
				WRITE PICTURE FILE($fichier; $image)
			End for 
	End case 
	
	
	// *****************
	//MARK:Utilitaires
	// *****************
	
Function getCentreDeLaZone($laZone : Collection; $data : Object)->$result : Boolean
	// on cherche une position de la zone
	// ici $laZone est une collection d'ID de lieux
	var $sélection : Collection
	var $entité : Object
	var $ID : Integer
	var $c : Collection
	
	// recréer les objets de classe
	$sélection:=New collection
	For each ($ID; $laZone)
		$entité:=cs.Lieux.new($ID)
		$sélection.push($entité)
	End for each 
	
	$c:=$sélection.query("latitude # 0 AND longitude # 0")
	If ($c.length=0)
		// essayer les départements
		$c:=$sélection.query("leSite.laCommune.leDepartement.latitude # 0 AND leLieu.leSite.laCommune.leDepartement.longitude # 0")
		
		If ($c.length=0)
			// essayer les régions
			$c:=$sélection.query("leSite.laCommune.leDepartement.laRegion.latitude # 0 AND leLieu.leSite.laCommune.leDepartement.laRegion.longitude # 0")
			
			If ($c.length=0)
				// essayer les pays
				$c:=$sélection.query("leSite.laCommune.leDepartement.laRegion.lePays.latitude # 0 AND leLieu.leSite.laCommune.leDepartement.laRegion.lePays.longitude # 0")
			End if 
		End if 
	End if 
	
	// en final :
	If ($c.length>0)
		// on a quelque chose
		This.CalculerCentreDeLaZone($c; $data)
		This.CalculerLeZoomDeLaZone($c; $data)
		
	Else 
		$data.latitude:=45
		$data.longitude:=0
		$data.Zoom:="6"
	End if 
	$result:=Not($c.length=0)
	
	// renvoyer la position trouvée
	$data.LatitudeCentre:=Replace string(String($data.latitude; "##0.######"); ","; ".")
	$data.LongitudeCentre:=Replace string(String($data.longitude; "###0.######"); ","; ".")
	
	
Function CalculerCentreDeLaZone($laZone : Collection; $data : Object)
	// calculer dans $data le centre géographique de la sélection d'entités Lieux $laZone
	var $c : Collection
	var $valeur : Real
	
	// calcul du centre géographique
	$c:=$laZone.orderBy("latitude asc")
	// on prend la valeur du milieu
	$valeur:=$c[0].latitude
	$data.latitude:=($valeur+$c[$c.length-1].latitude)/2
	
	$c:=$c.orderBy("longitude asc")
	// on prend la valeur du milieu
	$valeur:=$c[0].longitude
	$data.longitude:=($valeur+$c[$c.length-1].longitude)/2
	
	
Function CalculerLeZoomDeLaZone($laZone : Collection; $data : Object)
	// calcul du zoom de la carte (en pratique le zoom 3 couvre tout le globe)
	// étendue de la zone en longitude (360° au max)
	var $c : Collection
	var $Zoom : Real
	
	$c:=$laZone
	Case of 
		: ($c.length=0)
		: ($c[0].DataClassNom="Lieux")
			// zoom calculé
			$Zoom:=$c.max("longitude")-$c.min("longitude")
			If ($Zoom=0)
				$Zoom:=0.001
			End if 
			// modèle : on suppose que +1 sur le zoom divise la carte par 2
			$Zoom:=Int(1-(Log(($Zoom)/360)/Log(2)))
			// éviter de zoom sur l'univers
			If ($Zoom<3)
				$Zoom:=3
			End if 
			
			// carto IGN : au delà de 18 l'image ne s'affiche pas automatiquement
			If ($Zoom>18)
				$Zoom:=18
			End if 
			$data.Zoom:=String($Zoom)
			
			// zoom fixe
		: ($c[0].DataClassNom="Communes")
			$data.Zoom:="12"
		: ($c[0].DataClassNom="Departements")
			$data.Zoom:="9"
		: ($c[0].DataClassNom="Regions")
			$data.Zoom:="6"
		: ($c[0].DataClassNom="Pays")
			$data.Zoom:="4"
	End case 
	
	
Function CréerSélection($entitésRéduites : Collection)->$result : Collection
	// renvoyer une collection de ID des lieux de $entitésRéduites
	// rappel : la collection $entitésRéduite peut-être hétérogène (lieux + communes +...)
	var $entité; $data : Object
	var $ID : Integer
	
	$result:=New collection
	For each ($data; $entitésRéduites)
		Case of 
			: (Not(OB Is defined($data; "DataClassNom")))
			: (Not(OB Is defined($data; "IDs")))
			Else 
				// on a donc une classe et une collection d'ID de cette classe
				// pour chaque ID, chercher les Lieux
				For each ($ID; $data.IDs)
					$entité:=cs[$data.DataClassNom].new($ID)
					// ajouter les lieux de $entité
					$result:=$result.combine($entité.LesLieux())
				End for each 
		End case 
	End for each 
	
    

[class]Events - 19/04/2025 10:19:55

      Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDentity de la BDD
	// rappel : l'event est genré dynamiquement (voir le getEvent() de la classe Personne)
	
	Super("Events"; $IDentity)
	
	
	// ----------------------
	//MARK:Wrappers
	// ----------------------
	
Function LesProtagonistes()->$result : Collection
	$result:=This.fct.LesProtagonistes()
	
	
Function LesTémoins()->$result : Collection
	$result:=This.fct.LesTémoins()
	
	
	// ----------------------
	//MARK:Marker
	// ----------------------
	
Function getIconeURL($params : Object)->$result : Object
	// renvoyer les données de l'icone : 
	// .url : URL du fichier d'un icône standard
	// .nomFichier : nom du fichier de l'icone
	// .image : l'image
	var $image : Picture
	
	$result:=New object
	
	// déjà en ressources
	$result.nomFichier:="event.png"
	
	// chemin du fichier
	$result.url:=$params.dossierURL+$params.sousDossierImages+"/"+$result.nomFichier
	// image
	READ PICTURE FILE(Folder(fk resources folder).folder("Images").file($result.nomFichier).platformPath; $image)
	CREATE THUMBNAIL($image; $image; 32; 32; Scaled to fit prop centered)
	$result.image:=$image
	
	// ajouter à la collection
	$params.IconesData[$result.nomFichier]:=$result
	
	
    

[class]Medias - 29/05/2025 14:14:28

      // attributs de la classe
property vignette : Picture

Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDentity de la BDD
	
	Super("Medias"; $IDentity)
	
	
	// ----------------------
	//MARK:Wrappers
	// ----------------------
	
Function LesPersonnes()->$result : Collection
	$result:=This.fct.LesPersonnes()
	
	
	// ----------------------
	//MARK:Marker
	// ----------------------
	
Function getIconeURL($params : Object)->$result : Object
	// renvoyer les données de l'icone : 
	// .url : URL du fichier d'un icône standard
	// .nomFichier : nom du fichier de l'icone
	// .image : l'image
	var $image : Picture
	
	$result:=New object
	
	// déjà en ressources
	$result.nomFichier:=This.DataClassNom+"_"+String(This.ID)+".png"
	
	// chemin du fichier
	$result.url:=$params.dossierURL+$params.sousDossierImages+"/"+$result.nomFichier
	// image
	$image:=This.vignette
	CREATE THUMBNAIL($image; $image; 32; 32; Scaled to fit prop centered)
	$result.image:=$image
	
	// ajouter à la collection
	$params.IconesData[$result.nomFichier]:=$result
	
	
	
    

[class]Communes - 14/12/2024 11:05:03

      Class extends _CARTO_DataStore

Class constructor($IDentity : Variant)
	// initialiser l'objet avec les données de l'entité $IDunique de la BDD
	
	Super("Communes"; $IDentity)
	
	
	// ----------------------
	//MARK:Marker
	// ----------------------
	
Function PopUpContenu($params : Object)->$result : Text
	// le label de l'entité
	$result:=Super.PopUpLabel()
	
    

onStartup - 29/03/2025 17:17:36

      // ne s'exécute pas dans une base hôte

ON ERR CALL(Formula(traceHandler).source; ek global)

// pour les tests hors base hôte
cs.$composant.new().InitVariablesCARTO()

// pour les tests hors base hôte
CALL WORKER("WK_Composant_CARTO"; Formula(InitProcess).source)

    

onExit - 01/04/2025 19:45:30

      // ne s'exécute pas dans une base hôte

// exporter le code du composant si pas compilé
ON ERR CALL(Formula(traceHandler).source; ek local)

cs.xSDK.ExportCode4D.new().DémarrerComposant()


    

onHostDatabaseEvent - 06/02/2026 17:52:16

      #DECLARE($numFormEvent : Integer)
var $system; $environnement : Object

Case of 
	: ($numFormEvent=On before host database startup)
		// ici pas d'interaction avec les autres composants et la BDDmère
		ON ERR CALL(Formula(ErrorHandler).source; ek local)
		
		cs.$composant.new().InitVariablesCARTO()
		
		Use (Storage.System)
			Storage.System.estExecuteDansHote:=True
		End use 
		
		// déactiver les ASSERT si le composant est compilé (réactivable par les options d'appel du composant)
		SET ASSERT ENABLED(Not(Is compiled mode))
		
		CALL WORKER("WK_Composant_CARTO"; Formula(InitProcess).source)
		
		
	: ($numFormEvent=On after host database startup)
		// à faire ici tout est initialisé, en particulier le monde extérieur
		ON ERR CALL(Formula(traceHandler).source; ek global)
		
		$environnement:=cs.xSDK.EnvironnementALV.new()
		$system:=Storage.System
		Use ($system)
			$system.estServeurWeb:=$environnement.estServeur()
			
			Case of 
				: ($system.estServeurWeb)
					// on est sur le serveur
					Installer Cartographie
					
				Else 
					// BDDmère ou APP
					// pour les interfaces :
					Installer Cartographie("IntégrationDansHôte")
			End case 
		End use 
		
	: ($numFormEvent=On before host database exit)
		// placer ici le code à exécuter avant le "Sur fermeture" de la base hôte
		
	: ($numFormEvent=On after host database exit)
		// placer ici le code à exécuter après le "Sur fermeture" de la base hôte
End case