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

APIs Google Discussion :

Afficher uniquement les Marker du Viewport [Google Maps]


Sujet :

APIs Google

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut Afficher uniquement les Marker du Viewport
    Bonjour à tous,

    Comme je serai amener à avoir plusieurs milliers de markers sur ma carte, j'aimerai n'afficher que ceux dans le viewport en cours pour ne pas surcharger la carte.

    J'ai donc fait en sorte que mon fichier XML ne charge de la BDD que ceux-ci, et ca fonctionne bien.
    Seulement sur la carte, je n'ai maintenant plus qu'un seul marker qui charge. Si je bouge la carte, les autres chargent et comme les premiers chargés ne s'effacent pas, je récupère tous mes points au final....

    Mais au chargement, je n'ai donc qu'un marker qui apparait.
    Avez vous une idée du soucis ?

    Voici mon code :

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    ///////////////////////// Affichage de la carte /////////////////////////////////////////////////////////////////////////////////////
     
    function showMap() {
        document.getElementById("map").style.display = "block";
        var mapOptions = {
            zoom: 6,
    		minZoom: 3,
            center : new google.maps.LatLng(48, 5),
            mapTypeId: google.maps.MapTypeId.ROADMAP, 
    		zoomControlOptions: {
            	style: google.maps.ZoomControlStyle.LARGE,
            	position: google.maps.ControlPosition.RIGHT_BOTTOM
        	}, <!-- zoomControlOptions -->
    		panControl: false,
    		mapTypeControl: false,
    		streetViewControl: false,
        }; <!-- var mapOptions -->
     
        map = new google.maps.Map(document.getElementById("map"), mapOptions); 
    	google.maps.event.addListener(map, 'tilesloaded', function () { loadMapFromCurrentBounds(map);} ); 
     
        var infoWindow = new google.maps.InfoWindow;
    }  <!-- function showMap -->
     
    ///////////////////////// Recherche des données dans le fichier XML et placement des markers////////////////////////////////////////////////////////////////////
     
    function loadMapFromCurrentBounds() {
     
        var bounds = map.getBounds();
     
        var swPoint = bounds.getSouthWest();
        var nePoint = bounds.getNorthEast();
     
        var swLat = swPoint.lat();
        var swLng = swPoint.lng();
        var neLat = nePoint.lat();
        var neLng = nePoint.lng();
     
    	downloadUrl("donnees_xml.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"", function(data) {
            var xml = data.responseXML;
            var markers = xml.documentElement.getElementsByTagName("marker");
            for (var i = 0; i < markers.length; i++) {
            var id = markers[i].getAttribute("id");
            var pseudo = markers[i].getAttribute("pseudo");
            var avatar = markers[i].getAttribute("avatar");
            var ville = markers[i].getAttribute("ville");
    	var zipcode = markers[i].getAttribute("zipcode");
    	var pays = markers[i].getAttribute("pays");
            var type = markers[i].getAttribute("type");
            var point = new google.maps.LatLng(
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng")));
            var html =    '<a href="profil.php?ID='+ id +'" style="color: rgba(0,0,0,0.8)"><div style="text-align: left; font-family: arial; font-size: 12px; margin: 0;">'+
    		  				'<img src="http://localhost:8888/mobile/photos/avatars/' + avatar + '" class="avatar" alt="avatar" style="margin: 0 10px 0 0;">' +
    		  				"<b>" + pseudo + "</b> <br/>" + ville +", "+ zipcode +" (" + pays +")" +
    						'</div></a>';
            var icon = customIcons[type] || {};
            var marker = new google.maps.Marker({
                map: map,
                position: point,
                icon: icon.icon,
                shadow: icon.shadow
              }); <!-- var marker -->
           bindInfoWindow(marker, map, infoWindow, html);
            } <!-- for ... -->
        }); <!-- downloadUrl -->
    	}
     
    //////////////////////////////////////////////////////////////////
     
        function downloadUrl(url, callback) {
          var request = window.ActiveXObject ?
              new ActiveXObject('Microsoft.XMLHTTP') :
              new XMLHttpRequest;
     
          request.onreadystatechange = function() {
            if (request.readyState == 4) {
              request.onreadystatechange = doNothing;
              callback(request, request.status);
            }
          };
     
          request.open('GET', url, true);
          request.send(null);
        }
     
    	function bindInfoWindow(marker, map, infoWindow, html) {
          google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(html);
            infoWindow.open(map, marker);
          });
        }
    Merci !
    Florian

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 089
    Points : 44 660
    Points
    44 660
    Par défaut
    Bonjour,
    je ne sais pas si cela est voulu mais les commentaires lus dans ton code ne sont pas orthodoxes ex: <!-- zoomControlOptions -->.

    j'aimerai n'afficher que ceux dans le viewport en cours pour ne pas surcharger la carte.
    Google s'en occupe pour toi, il ne charge/affiche que ce qui est visible.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    mais les commentaires lus dans ton code ne sont pas orthodoxes
    Oups... en effet. Je débute en JS et j'ai utilisé mes réflexes de html.
    J'aurais mieux fais de prendre ceux de php il me semble

    Citation Envoyé par NoSmoking Voir le message
    Google s'en occupe pour toi, il ne charge/affiche que ce qui est visible.
    D'après ce que je comprends de la documentation google (https://developers.google.com/maps/a...ymarkers?hl=en) ca n'est pas le cas par défaut.



    Ci dessous l'extrait expliquant la méthode à appliquer :

    First attach a listener to the map idle event to make it execute a function called showMarkers() when the map stops panning.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      google.maps.event.addListener(map, 'idle', showMarkers);
    Note that you could listen to the bounds_changed event but it fires continuously as the user pans; instead, the idle will fire once the user has stopped panning/zooming.

    Then add the function showMarkers. This function gets the current viewport bounds by calling map.getBounds() which returns a object that has the NorthEast and SouthWest LatLng points of the bounds. With the bounds information you can send a request to your server (preferably with AJAX) to get the markers that are within those bounds.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function showMarkers() {
        var bounds = map.getBounds();
     
        // Call you server with ajax passing it the bounds
     
        // In the ajax callback delete the current markers and add new markers
      }
    With the new list of markers you can remove the current markers (marker.setMap(null)) that are on the map and add the new ones (marker.setMap(map)).
    C'est plus ou moins ce que j'essai de faire (XML) mais je rencontre le problème expliqué plus haut.
    Je ne vois pas non plus comment supprimer les markers qui disparaissent du viewport...

  4. #4
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Ah aussi...

    ...J'aimerai pouvoir faire fonctionner cette technique afin de remplir une sidebar qui donne une description des différents markers de la carte... et qui évolue dès que l'on se déplace sur la carte.
    Je pensais donc récupérer les données restreintes au viewport du fichier XML. Est ce la technique a employer ?

    Merci

  5. #5
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 089
    Points : 44 660
    Points
    44 660
    Par défaut
    j'ai pris le viewport comme étant la carte affichée.

    Le lien fourni montre les possibilités qui sont offertes pour gérer l'affichage des markers, j'ai donc un soucis de compréhension de ton problème.

    Tu peux afficher les markers ou non en testant leur position par rapport à un objet LatLngBounds que tu peux définir, mais est ce vraiment ton problème?.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    Tu peux afficher les markers ou non en testant leur position par rapport à un objet LatLngBounds que tu peux définir
    oui c'est ce que j'ai fait dans ces lignes mais cela ne fonctionne pas. J'ai un seul marker qui s'affiche a la fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    [...]
    var bounds = map.getBounds();
     
        var swPoint = bounds.getSouthWest();
        var nePoint = bounds.getNorthEast();
     
        var swLat = swPoint.lat();
        var swLng = swPoint.lng();
        var neLat = nePoint.lat();
        var neLng = nePoint.lng();
     
    	downloadUrl("donnees_xml.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"", function(data) {
    [...]

  7. #7
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 089
    Points : 44 660
    Points
    44 660
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    downloadUrl("donnees_xml.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"",
    - Si la fonction va lire un fichier XML sur le serveur, que te renvoie celui ci?

    - Le XML est-il bien formé?

    - Tu fais le tri coté serveur ou client?

  8. #8
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Le tri est fait dans mon fichier données_xml.php.

    J'ai mis les conditions suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    while ($row = @mysql_fetch_assoc($result)) {  
     
    if ( $_GET['swLat'] < $row['lat'] && 
         $row['lat'] < $_GET['neLat'] && 
         $_GET['swLng'] < $row['lng'] && 
         $row['lng'] < $_GET['neLng']) 
    {
    (...)
    }
    Et quand j'ouvre le fichier en indiquant dans l'url des coordonnées que j'ai moi meme choisi, cela fonctionne bien.
    Uniquement les fichiers présents dans la zone sont inséré.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Bon et bien après avoir mis ca de coté pour mettre en place mes infobox personnalisé, je viens de reprendre depuis ca depuis le début et du coup je ne sais pas ou était l'erreur mais cela fonctionne

    Par contre, j'aimerai que lorsque je bouge la carte, les marker qui sortent du viewport soit retiré... Il faudrait qu'a chaque mouvement tous les markers soit retiré puis remis, car pour le moment a chaque mouvement tous les markers sont rechargé, meme ceux qui existent deja.
    Je l'ai remarqué par hasard car l'ombre de mon icone de marker s'assombri a chaque déplacement de la carte

    Ca éviterai aussi que si quelqu'un se balade partout sur la carte, elle finisse "surchargée"

    Des idées sur la méthode à appliquer ?
    Il y a apparement la fonction setMap(null); mais il semble que celle ci ne supprime pas complétement l'overlay mais se contente de ne pas l'afficher...

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    function initialize() {
        var markers ="";
        var mapOptions = {
        zoom: 6,
        minZoom: 3,
        center : new google.maps.LatLng(52.25, 10.48),
        mapTypeId: google.maps.MapTypeId.ROADMAP, //On indique qu'il s'agit d'une "carte routière"
        zoomControlOptions: {
                 style: google.maps.ZoomControlStyle.LARGE,
                 position: google.maps.ControlPosition.RIGHT_BOTTOM
        	},
        panControl: false,
        mapTypeControl: false,
        streetViewControl: false,
        }; <!-- var mapOptions -->
     
        map = new google.maps.Map(document.getElementById("map"), mapOptions); 	
     
          //var GeoMarker = new GeolocationMarker(map); 
          //navigator.geolocation.getCurrentPosition(showPosition);	
     
     
     
         google.maps.event.addListener(map, 'bounds_changed', function () {
        loadMapFromCurrentBounds(map);
        }); 
     
    }
     
    function loadMapFromCurrentBounds(map) {		
     
        	var bounds = map.getBounds();
     
        	var swPoint = bounds.getSouthWest();
        	var nePoint = bounds.getNorthEast();
     
        	var swLat = swPoint.lat();
        	var swLng = swPoint.lng();
        	var neLat = nePoint.lat();
        	var neLng = nePoint.lng();
     
        	downloadUrl("donnees_xml2.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"", function(data) {
            var xml = data.responseXML;
            var markers = xml.documentElement.getElementsByTagName("marker");
            for (var i = 0; i < markers.length; i++) {
     
                        (...)
     
        	  var marker = new google.maps.Marker({
                map: map,
                position: point,
                icon: icon.icon,
                shadow: icon.shadow
        	  }); // var marker
     
    	  marker.mycategory = groupe;                                 
       	  marker.myname = name;
    	  newMarkers.push(marker);  
    	  // définition et style des infobox
              boxText = document.createElement("div"),
    		  boxText.style.cssText = "border: 0px ridge black; margin-top: 8px; background: rgba(0,0,0,0.7); box-shadow: inset 0 40px 20px -20px rgba(255,255,255,0.2);color:#FFF; font-family:Arial; font-size:12px; padding: 5px; border-radius:6px; -webkit-border-radius:6px; -moz-border-radius:6px;";
              boxText.innerHTML = html[groupe];
     
              infoboxOptions = {
                    content: boxText,
                    disableAutoPan: false,
                    maxWidth: 0,
                    pixelOffset: new google.maps.Size(-140, 0),
                    zIndex: null,
                    boxStyle: {
                        background: "url('http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/examples/tipbox.gif') no-repeat",
                        opacity: 1,
                        width: "280px"
                    },
                    closeBoxMargin: "12px 4px 2px 2px",
                    closeBoxURL: "http://localhost:8888/mobile/images/close.png",
                    infoBoxClearance: new google.maps.Size(1, 1),
                    isHidden: false,
                    pane: "floatPane",
                    enableEventPropagation: false
                };
     
              newMarkers[i].infobox = new InfoBox(infoboxOptions);
     
              google.maps.event.addListener(marker, 'click', (function(marker, i) {
                    return function() {
        				newMarkers[i].infobox.open(map, this);
        				map.panTo(newMarkers[i].getPosition());
    		} // return
              })(marker, i)); // addlistener
     
            }// for
          }); // downloadUrl
     
        return newMarkers;
     
    } // initialize

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 089
    Points : 44 660
    Points
    44 660
    Par défaut
    Par contre, j'aimerai que lorsque je bouge la carte,...
    il te faut mettre une écoute sur l'événement center_changed de la carte.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    google.maps.event.addListener( oMap, 'center_changed', function() {
      // test de la position des markers
    });
    Citation Envoyé par NoSmoking
    Tu peux afficher les markers ou non en testant leur position par rapport à un objet LatLngBounds que tu peux définir...
    il te suffit de récupérer le bornes de la carte.

    La question qui peut également se poser est ne serait-il pas préférable de charger toutes tes positions?

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    En faites je ne dois pas supprimer que les markers hors du view port, car si apres un déplacement de la carte certains markers restent dans le viewport ils sont rechargé a nouveaux et j'aimerai éviter cela.

    Il faut donc après chaque mouvement que je commence par supprimer tous les markers de la carte avant de recharger les nouveaux...

    Comme je test déjà les limites de la carte pour insérer les nouveaux a chaque mouvement, je pensais commencer ma fonction "loadMapFromCurrentBounds(map) { " par un simple setMap(null); pour tout vider avant de recharger.

    Mais ca ne fonctionne pas

  12. #12
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Bon eh bien voila, avec la méthode suivante cela fonctionne :

    Il faut d'abord vider l'array qui contient les markers avant d'y ré-insérer les nouveaux markers.

    J'ai donc déclaré cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function clearOverlays() {
      for (var i = 0; i < newMarkers.length; i++ ) {
        newMarkers[i].setMap(null);
      }
      newMarkers = [];
    }
    Et je l'ai appelé au début de "loadMapfromcurrentbounds ()".

    Par contre j'avais commencé avec l'évènement "center_changed" mais les markers chargent en permanence donc clignotent lorsqu'on déplace la carte... il faut donc préférer l'évènement "tilesloaded".

    Je pense que c'est donc tout bon pour ce sujet, merci

  13. #13
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 089
    Points : 44 660
    Points
    44 660
    Par défaut
    Je t'ai effectivement induit en erreur en utilisant center_changed, il préconise d'utiliser idle comme événement à surveiller, qui se déclenche avant le tilesloaded lorsque la carte est stabilisée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Afficher uniquement les cases saisies
    Par jordan49 dans le forum Langage
    Réponses: 17
    Dernier message: 20/10/2009, 15h43
  2. Quel webpart pour afficher uniquement les sous-sites d'un site?
    Par gracouille dans le forum SharePoint
    Réponses: 0
    Dernier message: 02/06/2008, 19h37
  3. [cURL] Afficher uniquement les entêtes
    Par LordDaedalus dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 08/02/2008, 22h55
  4. Réponses: 1
    Dernier message: 12/07/2006, 09h51
  5. Réponses: 4
    Dernier message: 05/07/2006, 21h58

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