IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

IGN API Géoportail Discussion :

Surcharge de méthodes d'OpenLayers


Sujet :

IGN API Géoportail

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut Surcharge de méthodes d'OpenLayers
    Bonjour à tous,

    Il y a parfois des moment ou l'on veut surcharger des méthodes des API que nous utilisons sans modifier directement le contenu des fichiers.

    J'ai donc fais des tests de surcharge, qui n'ont pas été concluant, dans mon initGeoportalMap, j'ai mis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function initGeoportalMap() {
    
    
        OpenLayers.Layer.prototype.getZIndex = function () {
            alert('getZ index');
            return this.div.style.zIndex;
        };
    
        OpenLayers.Layer.prototype.getTestIndex = function () {
             alert('getZ index');
            return this.div.style.zIndex;
        };
    Quand j'introspecte avec le debugger OpenLayers.Layer je retrouve bien ma méthode getTestIndex ce qui me fait penser que ma surcharge aurait du s'appliquer.

    Cependant quand je met un point d'arrêt dans le code, c'est toujours le getZIndex de l'API openLayers qui est appelé et non ma surcharge .

    Quelle est la bonne pratique?

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur cartographe
    Inscrit en
    Avril 2009
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 173
    Points : 4 224
    Points
    4 224
    Par défaut
    Citation Envoyé par nicknolt Voir le message
    Quand j'introspecte avec le debugger OpenLayers.Layer je retrouve bien ma méthode getTestIndex ce qui me fait penser que ma surcharge aurait du s'appliquer.
    Je ne connais pas cette méthode dans OpenLayers, je suppose que tu l'appelles directement dans ta page ?

    Citation Envoyé par nicknolt Voir le message
    Cependant quand je met un point d'arrêt dans le code, c'est toujours le getZIndex de l'API openLayers qui est appelé et non ma surcharge .
    Cette méthode ne sera appelée que si le type du layer ne surcharge pas déjà cette méthode

    Ceci écrit : elle n'est surchargée par personne
    Donc: si elle n'est pas appelé, c'est que l'on ne passe jamais dedans
    Une recherche dans le code complet de l'API montre que cette méthode n'est appelée que par :

    * OpenLayers.Handler.Feature : quant on active/désactive un contrôleur sur une couche vectorielle (KML, GPX, etc ...);
    * Geoportal.Control.LayerSwitcher (quant on clique sur les flêches haut/bas dans le gestionnaire de couche);

    Citation Envoyé par nicknolt Voir le message
    Quelle est la bonne pratique?
    Consulter les documentations API respectives d'OpenLayers et Geoportail : si une méthode surcharge la méthode de base, elle s'y trouvera, sinon le code source permet de traquer quant la méthode sera appelée.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut
    Je ne connais pas cette méthode dans OpenLayers, je suppose que tu l'appelles directement dans ta page ?
    Non, cette méthode est en fait appelé lors de la "desinstanciation" de certains handler que j'ai ajouté dans mon appli.

    Ceci écrit : elle n'est surchargée par personne
    Donc: si elle n'est pas appelé, c'est que l'on ne passe jamais dedans
    Si je met un point d'arrêt dans le code "original", je constate que cette méthode est pourtant bien appelée, et non ma surcharge ...

    Je me demande bien ce que j'ai bien pu faire de pas correct

    Ce n'est pas grave dans le sens ou la parade pas propre est de modifier le code directement

    Merci pour ta réponse.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur cartographe
    Inscrit en
    Avril 2009
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 173
    Points : 4 224
    Points
    4 224
    Par défaut
    Citation Envoyé par nicknolt Voir le message
    Si je met un point d'arrêt dans le code "original", je constate que cette méthode est pourtant bien appelée, et non ma surcharge ...
    Ce qui sous-entendrait que ta surcharge est en fait écrasée par le code original, donc intervient trop tôt ?!

    Quelle est la structure de ta page web (ordre d'insertions des scripts) ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut
    Oui c'est en effet une explication possible, voila comment j'appelle mes librairies JS (dans le head de ma page web).
    J'aurais pensé que les libs auraient été lues sequentiellement dans l'ordre de déclarations.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <script type="text/javascript" src="http://api.ign.fr/geoportail/api?v=1.0&amp;key=xxxxxxxxxxxxx&instance=VISU&includeEngine=false"></script>
    <script type="text/javascript" src="LibJS/Geoportail-API-1.0-src/geoportal-1.0/js/1.0/lib/openlayers/lib/OpenLayers.js"></script>
    <script type="text/javascript" src="LibJS/Geoportail-API-1.0-src/geoportal-1.0/js/1.0/lib/geoportal/lib/Geoportal.js"></script>
    <script type="text/javascript" src="LibJS/MonScript.js"></script>
    MonScript.js contient la surcharge ainsi que la méthode d'initialisation de geoportail.

    Merci pour ton aide.

  6. #6
    Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 94
    Points : 55
    Points
    55
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function initGeoportalMap() {
    }
    As-tu essayé de mettre tes surchages en dehors de cette fonction (comme ton 1er exemple) ?
    Je veux dire sans aucune attende de fin de chargement de librairie (et en chargeant le fichier JS après (OL et) Geoportal.

  7. #7
    Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 94
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par nicknolt Voir le message
    ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <script type="text/javascript" src="http://api.ign.fr/geoportail/api?v=1.0&amp;key=xxxxxxxxxxxxx&instance=VISU&includeEngine=false"></script>
    <script type="text/javascript" src="LibJS/Geoportail-API-1.0-src/geoportal-1.0/js/1.0/lib/openlayers/lib/OpenLayers.js"></script>
    <script type="text/javascript" src="LibJS/Geoportail-API-1.0-src/geoportal-1.0/js/1.0/lib/geoportal/lib/Geoportal.js"></script>
    <script type="text/javascript" src="LibJS/MonScript.js"></script>
    En fait là tu charges 2 fois les librairie OpenLayers... (Geoportail.js inclue le chargement des fichiers OpenLayers, du moins dans la 1.1)
    M'est d'avis que ta surchage fonctionne bien mais pas sur l'instance utilisé par la suite.

    Bref essaye donc en supprimant l'appel à OpenLayers.js et en ne concervant que Geoportal.js

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur cartographe
    Inscrit en
    Avril 2009
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 173
    Points : 4 224
    Points
    4 224
    Par défaut
    Tu peux aussi faire en sorte que ta bibliothèque soit chargée après l'API :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
        <script type="text/javascript" src="http://api.ign.fr/geoportail/api?v=1.0&amp;key=xxxxxxxxxxxxx&instance=VISU&includeEngine=false"></script>
        <script type="text/javascript" src="LibJS/Geoportail-API-1.0-src/geoportal-1.0/js/1.0/lib/geoportal/lib/Geoportal.js"></script>
        <script type="text/javascript">
        VISU= null;
        if (window.__Geoportal$timer===undefined) {
            var __Geoportal$timer= null;
        }
    
        function initGeoportalMap() {
            if (__Geoportal$timer!=null) {
                window.clearTimeout(__Geoportal$timer);
                __Geoportal$timer= null;
            }
            if (typeof(OpenLayers)=='undefined'              ||
                typeof(Geoportal)=='undefined'               ||
                typeof(Geoportal.Viewer)=='undefined'        ||
                typeof(Geoportal.Viewer.Default)=='undefined') {
                __Geoportal$timer= window.setTimeout('initGeoportalMap();', 300);
                return;
            }
            Geoportal.Util.loadJS('LibJS/MonScript.js','__MonScript__','',monCallback);
        }
    
       function monCallback() {
         // tout les scripts sont chargés ...
         // on peut créer l'interface, etc ...
       }
       </script>

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut
    shama : oui j'ai essayé dans tous les sens et toutes les combinaisons possible mais rien a faire dans initGeoportal en dehors, avant, après ...

    dgrichard : je n'ai pas encore essayé de procéder avec ta méthode mais je ferais un retour dès que testé. Je ne savais même pas qu'il y avait une fonction pour charger les JS dans Geoportal, très instructif ce forum!

    Merci pour l'info au sujet du double chargement d'open layers, ça va me faire gagner du temps au chargement de la page!

    A bientôt donc

  10. #10
    Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 94
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par nicknolt Voir le message
    Merci pour l'info au sujet du double chargement d'open layers, ça va me faire gagner du temps au chargement de la page!
    Et ça règle ton pb ?

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut
    Voici le compte rendu des tests :

    Lorsque j'exécute le code suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
        <script type="text/javascript">
        VISU= null;
        if (window.__Geoportal$timer===undefined) {
            var __Geoportal$timer= null;
        }
    
        function initGeoportalMap() {
            if (__Geoportal$timer!=null) {
                window.clearTimeout(__Geoportal$timer);
                __Geoportal$timer= null;
            }
            if (typeof(OpenLayers)=='undefined'              ||
                typeof(Geoportal)=='undefined'               ||
                typeof(Geoportal.Viewer)=='undefined'        ||
                typeof(Geoportal.Viewer.Default)=='undefined') {
                __Geoportal$timer= window.setTimeout('initGeoportalMap();', 300);
                return;
            }
            Geoportal.Util.loadJS('LibJS/MonScript.js','__MonScript__','',monCallback);
        }
    
       function monCallback() {
         // tout les scripts sont chargés ...
         // on peut créer l'interface, etc ...
         initInterface();//code présent dans MonScript.js
       }
       </script>
    Le script MonScript.js est bien chargé et monCallBack est bien appelée mais la fonction initInterface n'est pas connue.

    J'ai donc changé le code en ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
        <script language="javascript">
    
            VISU = null;
            if (window.__Geoportal$timer === undefined) {
                var __Geoportal$timer = null;
            }
    
            function initGeoportalMap() {
                alert('init en ligne');
                if (__Geoportal$timer != null) {
                    window.clearTimeout(__Geoportal$timer);
                    __Geoportal$timer = null;
                }
                if (typeof (OpenLayers) == 'undefined' ||
                typeof (Geoportal) == 'undefined' ||
                typeof (Geoportal.Viewer) == 'undefined' ||
                typeof (Geoportal.Viewer.Default) == 'undefined') {
                    __Geoportal$timer = window.setTimeout('initGeoportalMap();', 300);
                    return;
                }
                Geoportal.Util.loadJS('LibJS/MonScript.js');
                monCallback();
            }
    
    
            function monCallback() {
                // tout les scripts sont chargés ...
                // on peut créer l'interface, etc ...
                alert('callback');
                initInterface();
            }
    
    
        </script>
    La tout se passe bien et dans l'ordre souhaité mais même en plaçant a tous les endroits possibles (dans initInterface ou en dehors d'une fonction) la surcharge qui suit n'est pas prise en compte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    OpenLayers.Layer.prototype.getZIndex = function () {
        alert(surcharge!');
        return this.div.style.zIndex;
    };
    
    OpenLayers.Layer.prototype.getTestIndex = function () {
        alert(surcharge!');
        return this.div.style.zIndex;
    };
    J'ai mis la surcharge aussi dans initGeoportalMap et aussi dans MonCallback, bref partout partout sans succès

    De plus, j'ai retiré le chargement de la lib openlayers superflue et cela n'a pas eu d'impact sur le problème de surcharge.

    Ce problème est dérangeant mais pas critique dans le sens ou on peut toujours modifier directement la méthode Layer de OpenLayers.

    Merci encore pour votre aide

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut
    Voici ma dernière tentative qui utilise le timer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
      function monCallBack() {
                
        
                if (typeof (OpenLayers.Layer.prototype.getZIndex) == 'undefined') {
    
                    alert('OPEN layer ZIndex inconnu au bataillon');
                    window.setTimeout('monCallBack();', 600);
                    return;
                }
    
                OpenLayers.Layer.prototype.getZIndex = function () {
                    alert('surcharge!');
                    return this.div.style.zIndex;
                };
    
                initInterface();
               
    }
    A priori, avec ça on est sur que la méthode a déjà été chargée et qu'on la surcharge a coup sûr ... mais dans la réalité ça fonctionne pas non plus

  13. #13
    Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 94
    Points : 55
    Points
    55
    Par défaut
    Marrant ce truc

    Aller vers le début d'une solution (cf fichier joint). Je laisse le soin à DRichard de t'expliquer pourquoi la méthode doit-être surcharger au niveau de Geoportal.Layer
    Fichiers attachés Fichiers attachés

  14. #14
    Expert confirmé
    Homme Profil pro
    Ingénieur cartographe
    Inscrit en
    Avril 2009
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 173
    Points : 4 224
    Points
    4 224
    Par défaut
    Il suffit de regarder le code source des surcharges d'OpenLayers pour comprendre le mécanisme

    Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        OpenLayers.Layer.WMS.Untiled.prototype.setMap=
        OpenLayers.Layer.WMS.prototype.setMap=
        OpenLayers.Layer.Grid.prototype.setMap=
        OpenLayers.Layer.HTTPRequest.prototype.setMap=
        OpenLayers.Layer.prototype.setMap= function(map) {
            ...
        };
    En bref:

    Soit une méthode f0() définie pour une classe A.
    Soit une sous-classe B héritant de A, B.f0()===A.f0();
    Les classes A et B étant chargées, la surcharge de A.f0() ne modifie pas celle de B (tout est par valeur en Javascript)

    Si on veut surcharger les deux, il faut le faire explicitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    B.prototype.f0= A.prototype.f0= function f1();
    Geoportal.Layer hérite de OpenLayers.Layers.
    Modifier seulement OpenLayers.Layers.getZIndex() ne suffit pas à changer le comportement de Geoportal.Layer.getZIndex()

  15. #15
    Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 94
    Points : 55
    Points
    55
    Par défaut
    bel exposé... bravo et je pense pb résolu

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 72
    Points : 46
    Points
    46
    Par défaut
    Haha ça c'est un bel exposé en effet DgRichard!

    Voila qui m'éclaire un peu plus sur "l'héritage" à la JS et comment ainsi que ou chercher pour trouver des indices sur le fonctionnement de nos API JS préférées.

    J'ai essayé ton exemple Shama (au passage merci pour le TransitionEffect du plus bel effet) et j'arrive a appeller le ZIndex qui se comporte comme prévu.

    Cependant, afin de faire un peu le rabat joie :
    La méthode que je voulais initialement surcharger est celle d'OpenLayer et pour l'instant le seul moyen d'agir sur ce ZIndex est de la modifier directement, la surcharge définie dans le code n'est pas prise en compte (si je met un point d'arrêt dans la méthode OpenLayer, on y passe bien mais pas dans la surcharge).

    Ne vous usez pas sur ce sujet non plus je vois des messages bien tardifs et le week end aussi

  17. #17
    Expert confirmé
    Homme Profil pro
    Ingénieur cartographe
    Inscrit en
    Avril 2009
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 173
    Points : 4 224
    Points
    4 224
    Par défaut
    Citation Envoyé par nicknolt Voir le message
    Haha ça c'est un bel exposé en effet DgRichard!

    Voila qui m'éclaire un peu plus sur "l'héritage" à la JS et comment ainsi que ou chercher pour trouver des indices sur le fonctionnement de nos API JS préférées.

    J'ai essayé ton exemple Shama (au passage merci pour le TransitionEffect du plus bel effet) et j'arrive a appeller le ZIndex qui se comporte comme prévu.

    Cependant, afin de faire un peu le rabat joie :
    La méthode que je voulais initialement surcharger est celle d'OpenLayer et pour l'instant le seul moyen d'agir sur ce ZIndex est de la modifier directement, la surcharge définie dans le code n'est pas prise en compte (si je met un point d'arrêt dans la méthode OpenLayer, on y passe bien mais pas dans la surcharge).

    Ne vous usez pas sur ce sujet non plus je vois des messages bien tardifs et le week end aussi
    N'oublie pas que la surcharge doit être faite en profondeur ...

    Si ta couche est du type LAYERTYPE, alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (Geoportal|OpenLayers).Layer.LAYERTYPE.prototype.getZIndex=  function() { ... };
    modifiera la méthode pour ce type de couche, pas pour les autres

Discussions similaires

  1. [POO] Héritage et surcharge de méthodes
    Par defkid dans le forum Langage
    Réponses: 4
    Dernier message: 26/02/2007, 14h51
  2. surcharge de méthode
    Par Zen_Fou dans le forum Langage
    Réponses: 2
    Dernier message: 22/03/2006, 10h23
  3. [POO] Surcharge de méthode
    Par ouioui2000 dans le forum Langage
    Réponses: 4
    Dernier message: 09/03/2006, 15h25
  4. [Custom Tags] Problème avec une surcharge de méthode
    Par Strab dans le forum Taglibs
    Réponses: 19
    Dernier message: 26/08/2005, 16h34
  5. Comment surcharger la méthode OnClose d'un TFrame ?
    Par sdebrois dans le forum Composants VCL
    Réponses: 2
    Dernier message: 17/01/2005, 20h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo