Appronfondir - Custom Control

Les Customs Controls permettent de personnaliser la représentation et les interactions que l’on a avec les layers de façon plus avancée que ce que l’on peut faire avec le fichier de configuration XML.

Voici un exemple, le custom control s’affiche dans la légende en dessous des attributions :

Profil en long

Première méthode : Définition Simple (CustomControl)

Cette méthode permet de créer des customs controls plus simples qu’avec la deuxième méthode mais permet moins de personnalisation.

Dans ce cas précis on utilise la classe de base CustomControl dans le fichier custom.js.

La classe possède une méthode constructor() qui prend en paramètre les méthodes init() et destroy() que l’on peut définir dans le fichier JavaScript (dans cet exemple moncontrol.js) présent dans l’arborescence suivante:

/apps
    ├── ma_carte1
    │   ├── addons
    │   │   ├── couche1
    │   │   │   ├── control
    │   │   │   │   ├── moncontrol.html
    │   │   │   │   └── moncontrol.js
    │   │   │   └── layer
    │   │   └── couche2
    │   │       ├── control
    │   │       └── layer
    │   ├── data
    │   ├── css
    │   ├── sld
    │   ├── img
    │   ├── templates
    │   └── ma_carte1.xml
    └── ma_carte2

Pour cela il faut donc définir les deux fonctions en les déclarant avec le mot-clé const pour les rendre inaccessibles depuis le reste de l’application indépendamment du custom control dans lequel elles sont définies, puis il faudra les donner en paramètre à la classe CustomControl vue plutôt.

 1  const init = function() {
 2  // Obligatoire - code exécuté quand le panel est ouvert
 3  // Votre code ici
 4  ...
 5
 6  };
 7
 8  const destroy =  function() {
 9      // Obligatoire - code exécuté quand le panel se ferme
10      // Votre code ici
11      ...
12  }
13  // Initialiser l'objet avec les fonctions init() et destroy() et l'id de couche "monControl".
14  new CustomControl("monControl", init, destroy);

Ajouter des fonctions et des variables

Une fonction/variable privée ne sera pas accessible en dehors du code de la classe alors qu’une fonction/variable publique sera accessible depuis n’importe où ce qui peut entrainer des conflits avec d’autres fonctions/variables de l’application si l’on ne fait pas attention.

Pour les variables et fonctions de classe publique

Il faut définir un nouvel attribut pour la classe CustomControl de la manière suivante :

 1  ...
 2  // Initialiser l'objet avec les fonctions init() et destroy() et l'id de couche "monControl".
 3  var monControl = new CustomControl("monControl", init, destroy);
 4
 5  // Une fois créer on peut ajouter des propriétés (une propriété peut être une fonction ou une variable)
 6
 7  // Ajouter une fonction
 8  monControl.maNouvelleFonction = function(){
 9      // Votre Code ici
10      ...
11  }
12
13  // Ajouter une variable
14  monControl.maNouvelleVariable = "je suis un exemple";

Ces attributs seront alors publics et accessibles depuis l’éxterieur.

Deuxième méthode : Création d’une sous-classe (AdvancedCustomControl)

Cette méthode est la plus complète des deux et permet de créer des customs controls plus poussés.

Tous les Custom Control ont une base commune dans le fichier custom.js où est définie la classe AdvancedCustomControl.

Pour utiliser cette classe il faut modifier le fichier Javascript (dans cet exemple moncontrol.js) présent dans l’arborescence suivante:

/apps
    ├── ma_carte1
    │   ├── addons
    │   │   ├── couche1
    │   │   │   ├── control
    │   │   │   │   ├── moncontrol.html
    │   │   │   │   └── moncontrol.js
    │   │   │   └── layer
    │   │   └── couche2
    │   │       ├── control
    │   │       └── layer
    │   ├── data
    │   ├── css
    │   ├── sld
    │   ├── img
    │   ├── templates
    │   └── ma_carte1.xml
    └── ma_carte2

Ce fichier définit une classe qui étend (est un héritier de la classe) la classe AdvancedCustomControl :

 1  // Classe qui étend la classe abstraite et décrit le custom Control
 2  class MonControl extends AdvancedCustomControl {
 3      constructor(id) {
 4          // Initialise l'id de l'objet avec le constructeur parent
 5          super(id);
 6      }
 7      // Obligatoire - ce code est exécuté lors de l'ouverture du panel
 8      init() {
 9          // Votre code ici
10          ...
11      }
12      // Obligatoire - ce code est exécuté lors de la fermeture du panel
13      destroy() {
14          // Votre code ici
15          ...
16      }
17  }

La classe AdvancedCustomControl étant abstraite cela signifie qu’elle nous oblige à redéfinir les fonctions init() et destroy() qui sont obligatoires sinon elle nous renvoie une erreur.

De plus la fonction constructor(id) permet à l’objet d’être initialisé avec la valeur id (obligatoire) lors de la création d’un objet MonControl.

Pour créer cet objet et le rendre disponible au reste de l’application il faut rajouter le code suivant :

1  // Créer l'objet MonControl avec l'id 'monControl' qui est le nom de la couche
2  new MonControl("monControl");

Ajouter des fonctions

Pour empêcher de potentiels téléscopage de variables ou de méthodes on peut ajouter à la classe MonControl (vue dans les parties précendentes) des fonctions privées ou publiques.

Une fonction privée ne sera pas accessible en dehors du code de la classe alors qu’une fonction publique sera accessible depuis n’importe où ce qui peut entrainer des conflits avec d’autres fonctions de l’application si l’on ne fait pas attention.

Pour une fonction publique

Directement en ajoutant dans le code de la classe MonControl :

 1  // Classe qui étend la classe abstraite et décrit le custom Control
 2  class MonControl extends AdvancedCustomControl {
 3      ...
 4      maFonctionPublique(){
 5          // Votre code ici
 6          ...
 7      }
 8  }
 9  // Créer l'objet control avec l'id 'monControl' qui est le nom de la couche
10  new MonControl("monControl");

Cette fonction sera appelable grâce à monobjet.maFonctionPublique() et l’on peut bien sûr y passer des paramètres.

Pour une fonction privée

En dehors du code de la classe MonControl et en la déclarant comme une constante :

 1  // Fonction privée non utilisable en dehors de ce code
 2  const maFonctionPrivée = function(){
 3      // Votre code ici
 4      ...
 5  }
 6  // Classe qui étend la classe abstraite et décrit le custom Control
 7  class MonControl extends AdvancedCustomControl {
 8      ...
 9      maFonctionPublique(){
10          maFonctionPrivée();
11          // Votre code ici
12          ...
13      }
14  }
15  // Créer l'objet control avec l'id 'monControl' qui est le nom de la couche
16  new MonControl("monControl");

Cette fonction sera appelable grâce à maFonctionPrivée() seulement dans ce bout de code et donc on peut par exemple l’utiliser dans une fonction publique (ici maFonctionPublique()).

Ajouter des variables

Pour empêcher de potentiels bugs on peut ajouter à la classe MonControl (vue dans les parties précendentes) des variables de classe privée ou publique.

Une variable de classe privée ne sera pas accessible en dehors du code de la classe alors qu’une variable de classe publique sera accessible depuis n’importe où ce qui peut entrainer des bugs (modification involontaire de celle-ci) si l’on ne fait pas attention.

Pour une variable de classe publique

Pour ajouter une variable de classe publique il faut juste ajouter une propriété à l’objet :

 1  // Classe qui étend la classe abstraite et décrit le custom Control
 2  class MonControl extends AdvancedCustomControl {
 3      constructor(id,maVariablePublique){
 4          // Initialise l'id de l'objet avec le constructeur parent
 5          super(id);
 6          // Initialiser maVariablePublique
 7          this.maVariablePublique = maVariablePublique
 8          ...
 9      }
10      ...
11  }
12  // Initialiser l'objet avec la chaine de caractères "maVariablePublique" dans la variable de classe publique maVariablePublique et l'id de couche "monControl".
13  new MonControl("monControl","maVariablePublique");

Cette variable est accessible à partir du moment où l’on accède à l’objet (dans le navigateur par exemple).

Si on ne souhaite pas forcément donner une valeur à maVariablePublique on peut déclarer une valeur par défaut en spécifiant une valeur dans les paramètres de la fonction constructor() :

 1  // Classe qui étend la classe abstraite et décrit le custom Control
 2  class MonControl extends AdvancedCustomControl {
 3      // Fonction avec un paramètre ayant une valeur par défaut
 4      constructor(id,maVariablePublique = "valeurParDefaut"){
 5          // Initialise l'id de l'objet avec le constructeur parent
 6          super(id);
 7          // Initialiser maVariablePublique
 8          this.maVariablePublique = maVariablePublique
 9          ...
10      }
11      ...
12  }
13  // Initialiser l'objet avec la chaine de caractères par défaut "valeurParDefaut" dans la variable de classe publique maVariablePublique et l'id de couche "monControl".
14  new MonControl("monControl");

La valeur de maVariablePublique sera toujours « valeurParDefaut » tant que vous ne spécifiez pas d’autres valeurs.

Pour une variable de classe privée

Attention

La syntaxe suivante ne fonctionne que sur Chrome pour les autres navigateurs remplacez le « # » par un « _ » et vous n’aurez plus besoin de déclarer la variable.

Pour ajouter une variable de classe privée il faut ajouter le « # » avant le nom de la variable et la déclarer avant la fonction constructor() :

// Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
    // Déclaration de la variable Privée
    #maVariablePrivee;
    constructor(id,maVariablePrivee = "valeurParDefaut"){
        // Initialise l'id de l'objet avec le constructeur parent
        super(id);
        // Initialiser #maVariablePrivee
        this.#maVariablePrivee = maVariablePrivee
        ...
    }
    ...
}
// Initialiser un objet avec la chaine de caractères "maVariablePrivee" dans la variable de classe privée #maVariablePrivee et l'id de couche "monControl".
new MonControl("monControl","maVariablePrivee");

Si vous voulez quand même pouvoir accéder et modifier la valeur de cette variable en dehors de ce code mais de manière plus sécurisée, il faut déclarer une fonction get() pour récupérer la valeur et une fonction set(valeur) pour la modifier :

// Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
    // Déclaration de la variable Privée
    #maVariablePrivee;
    constructor(id,maVariablePrivee = "valeurParDefaut"){
        // Initialise l'id de l'objet avec le constructeur parent
        super(id);
        // Initialiser #maVariablePrivee
        this.#maVaribalePrivée = maVariablePrivee
        ...
    }
    // Fonction pour récupérer la valeur de #maVariablePrivee
    getMaVariablePrivee(){
        return this.#maVariablePrivee;
    }
    // Fonction pour modifier la valeur de #maVariablePrivee
    setMaVariablePrivee(valeur){
        this.#maVariablePrivee = valeur;
    }
}
// Initialiser un objet avec la chaine de caractères "maVariablePrivee" dans la variable de classe privée #maVariablePrivee et l'id de couche "monControl".
new MonControl("monControl","maVariablePrivee");

Interactions customLayer et mviewer

Depuis le customControl il est possible de communiquer et d’interagir avec la carte et d’une façon plus générale avec mviewer. Vous pouvez ainsi mobiliser toutes les méthodes publiques dans votre développement. Pour en savoir plus, consultez, dans la documentation développeur, la partie « Les fonctions publiques de mviewer ».