2016-06-13 3 views
0

J'ai une situation qui est un peu difficile à expliquer, d'où le titre approximatif (et je suis tout à fait nouveau à l'API Google Maps)Marqueurs dans google maps disparaissent

J'ai créé quelques marqueurs dans une carte Google avec leur javascript API (v3) et les positionné avec les coordonnées GPS provenant de ma propre API. Le problème est que lorsque j'arrive à la bordure gauche de la carte (ou à droite, comme vous voulez), ces marqueurs disparaissent. Je ne veux pas dire des frontières personnalisées que j'ai définies, je veux dire les frontières du monde. Et quand je vais plus loin, ils reviennent. Ils disparaissent quand je croise une de ces lignes, comme on le voit dans cette image:

google maps border

Mes marqueurs sont du centre de la carte (Europe), il est comme quand je croise une de ces lignes, disons à partir de la gauche juste un peu, le script commence à charger les marqueurs sur la carte de gauche, que je ne vois pas parce que j'ai zoomé, et je suis toujours sur la bonne carte.

Désolé, assez difficile à expliquer. Voici mon script complet:

var map; 
var markers = []; // this will hold all the markers on the map 
// google maps API callback, we init the map 
function initMap() { 
    map = new google.maps.Map(document.getElementById('map'), { 
    center: {lat: 30, lng: 10.3}, // FIXME 
    zoom: 2, // default zoom 
    styles: map_style, // dark style 
    disableDefaultUI: false, // FIXME 
    minZoom: 3, // the maximum zoom-out 
    maxZoom: 15, // the maximum zoom-in: we can't set this to higher values because the pictures would be 
       // at their exact locations, if somebody takes a picture in his home, this would show the 
       // exact location of his home 
    }); 

    // first time idle (when map is loaded) XXX: think about this design, can do better 
    google.maps.event.addListenerOnce(map, 'idle', function(){ 
    // we get the gps coords of the current view's bounds 
    var view_bounds = map.getBounds(); 
    var NE = view_bounds.getNorthEast(); 
    var SW = view_bounds.getSouthWest(); 

    // we need NW and SE but the API only gives us NE and SW, so a little bit of conversion... 
    var NW = new google.maps.LatLng(NE.lat(), SW.lng()); 
    var SE = new google.maps.LatLng(SW.lat(), NE.lng()); 

    var tl_lat = NW.lat(); 
    var tl_long = NW.lng(); 
    var br_lat = SE.lat(); 
    var br_long = SE.lng(); 

    // get the newest pictures in those bounds 
    get_newest_pictures(tl_lat, tl_long, br_lat, br_long); 
    }); 

    // when the user stops dragging, check for pictures in the view bounds 
    google.maps.event.addListener(map, 'dragend', function(e){ 
    // clear all markers 
    deleteMarkers(); 

    // we get the gps coords of the current view's bounds 
    // need North West lat & long, and South East lat & long 
    var view_bounds = map.getBounds(); 
    var NE = view_bounds.getNorthEast(); 
    var SW = view_bounds.getSouthWest(); 

    // we need NW and SE but the API only gives us NE and SW, so a little bit of conversion... 
    var NW = new google.maps.LatLng(NE.lat(), SW.lng()); 
    var SE = new google.maps.LatLng(SW.lat(), NE.lng()); 

    var tl_lat = NW.lat(); 
    var tl_long = NW.lng(); 
    var br_lat = SE.lat(); 
    var br_long = SE.lng(); 

    // get the newest pictures in those bounds 
    get_newest_pictures(tl_lat, tl_long, br_lat, br_long); 
    }); 
} 

// get the newest pictures in an area (in bounds) 
function get_newest_pictures(tl_lat, tl_long, br_lat, br_long) { 

    var pictures; 

    $.ajax({ 
    url: "http://127.0.0.1:6767/pictures/newest?tl_lat="+tl_lat 
                 +"&tl_long="+tl_long 
                 +"&br_lat="+br_lat 
                 +"&br_long="+br_long, 
    success: function(pictures) { 
     // parse the return data in JSON 
     pictures = JSON.parse(pictures); 

     // for each pictures, create a marker at the location 
     for (i = 0; i < pictures.length; i++) { 
     var coords = new google.maps.LatLng(pictures[i]["gps_lat"], pictures[i]["gps_long"]); 
     var marker = new google.maps.Marker({ 
      position: coords, 
      title: "Hello World!", 
      icon: "img/pin_newest.png" 
     }); 
     marker["author"] = pictures[i]["author"]; 
     // push the marker in the markers array 
     markers.push(marker); 

     // set the marker 
     marker.setMap(map); 
     } 

     console.log(markers); 
    }, 
    error: function(XHR, textStatus, errorThrown) { 
     console.log(textStatus); 
     console.log(errorThrown); 
    }, 
    }); 
} 

// delete all the markers 
function deleteMarkers() { 
    for(i = 0; i < markers.length; i++){ 
    markers[i].setMap(null); 
    } 
    // empty the markers array 
    markers = []; 
} 

J'ai aussi essayé de la carte lié, mais je ne pense pas que ce soit une bonne idée (et qui ne fonctionnait pas). Existe-t-il un moyen "intégré" pour désactiver ces cartes infinies, pour avoir seulement UNE carte et pas un tas quand je traîne aux frontières? Ou toute autre chose qui peut réparer cette "erreur" frustrante?
Merci!

EDIT: Je vais essayer de donner un exemple de ce qui se passe.
C'est ce que je veux: Je suis sur une carte Google, je reçois les frontières de la carte pour obtenir où l'utilisateur regarde, et dans cette zone (délimité par le coin supérieur gauche et en bas à droite que je ' J'ai) Je veux charger chaque image qui s'y trouve. Les images sont enregistrées avec les coordonnées GPS dans ma base de données.
Voici les 7 photos que j'ai dans ma base de données:

id | author | gps_lat | gps_long 
---+--------+----------+---------- 
31 | user2 | 2.82717 | 95.98167 
32 | user2 | -8.52182 | -51.46316 
33 | user2 | 44.41541 | 143.46929 
34 | user3 | 22.15819 | -77.90592 
35 | user3 | 51.28558 | 9.05738 
36 | user4 | 22.08282 | 9.06114 
37 | user5 | -9.47497 | -46.55858 

Quand j'ai les photos de ma base de données, je veux montrer où ils se trouvent à l'utilisateur en utilisant des marqueurs . C'est pourquoi je crée un marqueur à l'endroit où la photo est pour chaque image. Mais l'utilisateur ne voit que les marqueurs où il a l'air, donc si une image est au Brésil, et qu'il regarde l'Europe, la réponse de la base de données ne contiendra même pas l'image au Brésil. Donc, à la fin, je devrais avoir des marqueurs dans la zone que l'utilisateur regarde, et seulement dans cette zone.

Maintenant c'est ce qui se passe: J'ai mis du code de débogage pour voir le tableau de marqueurs que j'ai sur la carte, donc je peux voir quelle image j'ai. J'ai ajouté console.log(markers.length); après de ma boucle for qui met tous les marqueurs pour voir combien de marqueur j'ai et compare ce nombre au nombre de marqueurs que je vois. Et cela m'a donné des informations sur le problème. Voici ce que je vois dans un cas normal:

normal1

Tout est normal, j'ai 4 photos dans ce domaine afin que le script me affiche 4 marqueurs. La console imprime 4 pour le console.log(markers.length);.

maintenant un autre cas normal, mais juste "à côté de" quand il bugs:

normal2

Les impressions de la console 2, donc tout va bien.
Mais alors, quand je vais comme quelques kilomètres à gauche, quand je quitte les « limites » de la carte d'être sur une autre carte, voici ce que j'ai:

bug

Rien, comme vous pouvez le voir. Et la console imprime 4. Nous voyons la ligne de frontière sur la carte, c'est un peu sombre à cause du thème. J'ai vu que quand je dépasse cette limite, il commence à écoutes. C'est comme si elle essayait de charger les marqueurs sur la carte de gauche, mais je suis toujours sur la bonne carte donc je ne peux pas les voir.

EDIT: Voici le côté serveur requête SQL:

SELECT * FROM pictures 
WHERE gps_long BETWEEN SYMMETRIC <tl_long> AND <br_long> 
AND gps_lat BETWEEN SYMMETRIC <tl_lat> AND <br_lat> 
ORDER BY date_taken DESC LIMIT 50; 
+0

S'il vous plaît fournir un [minimal, complet, testé et Lisible par exemple] (http://stackoverflow.com/help/mcve) (avec suffisamment de données d'échantillons pour démontrer la question) – geocodezip

+0

J'ai édité le fil, j'espère que cela donnera plus d'informations. – mgul

+0

try var rectangle = nouveau google.maps.Rectangle ({map: map, bounds: view_bounds}); – kaskader

Répondre

2

Votre problème est que le point de vue de votre carte traverse la ligne de date internationale (également appelé anti-méridien) qui est 180 degrés ligne de longitude.

Lorsque vous approchez cette ligne venant de l'est, longitudes aller entre 0 et -180, et quand vous vous approchez de cette ligne venant des logitudes ouest poussent de 0 à 180.

Alors, quand vous obtenez la carte bornes dont cette ligne vous obtenez un géant qui ressemble (en utilisant vos noms de variables):

t1_long: 72 
br_long: -72 

Et comme votre code serveur attend t1_long être < br_long vous obtenez un tableau de marqueurs qui sont hors de la les vraies limites de votre carte (vous tracez des marqueurs qui se trouvent du côté caché de la carte).

Vous ne montrez pas l'implémentation de votre serveur, mais vous devez en tenir compte. Donc, votre implémentation est OK quand t1_long < br_long, mais vous devez ajouter quelques conditions lorsque t1_long > br_long. Par exemple (pseudocode)

if (t1_long > br_long) { 
    longitude_condition = " longitude > " + t1_long " and longitude < 180 or longitude < " + br_long + " and longitude > -180 "; 
} 

Mise à jour:

J'ajoute une image pour illustrer mon point:

enter image description here

Selon votre requête, lorsque vos limites cartographiques sont comme dans l'image (le carré rouge) vous interrogez:

WHERE gps_long BETWEEN SYMMETRIC 100 AND -90 

Et ainsi, la requête renvoie le marqueur vert comme -90 < -70 < 100 au lieu du marqueur rose. Dans ce cas, l'opérateur SYMMETRIC ne résout pas le problème, car il ne permet que l'ordre des limites -90 et 100 d'être sans importance. donc les deux WHERE gps_long BETWEEN SYMMETRIC 100 AND -90 et WHERE gps_long BETWEEN SYMMETRIC -90 AND 100 sont vrais pour le marqueur vert et faux pour le marqueur rose.

Mise à jour:

if (t1_long > br_long) { 
    SELECT * FROM pictures 
    WHERE (gps_long BETWEEN SYMMETRIC <tl_long> AND 180 OR gps_long BETWEEN SYMMETRIC <br_long> AND -180) 
    AND gps_lat BETWEEN SYMMETRIC <tl_lat> AND <br_lat> 
    ORDER BY date_taken DESC LIMIT 50; 
} else { 
    SELECT * FROM pictures 
    WHERE gps_long BETWEEN SYMMETRIC <tl_long> AND <br_long> 
    AND gps_lat BETWEEN SYMMETRIC <tl_lat> AND <br_lat> 
    ORDER BY date_taken DESC LIMIT 50; 
} 
+0

Merci pour votre réponse, le problème est en effet lorsque tl_long> br_long, mais je n'ai pas compris comment je devrais gérer ce cas pour garder les marqueurs visibles. J'ai également édité le fil pour montrer ma requête SQL côté serveur. – mgul

+0

J'ai mis à jour ma réponse. J'espère que cela aide à clarifier le problème – antonio

+0

Merci pour la clarification que j'ai compris où le problème était maintenant. Je ne peux pas "obtenir" le marqueur rose car aucune de mes conditions SQL n'inclut sa longitude ... Mais, je m'excuse d'être si insistante, as-tu une idée sur la façon de résoudre ce problème? C'est comme si je devais réécrire toute la requête SQL mais je ne vois pas comment ... Ou peut-être réparer est évident, mais je ne le vois pas – mgul