标记消失在Google地图中

ul

我遇到的情况有点难以解释,大概是从哪儿来的(我是google maps API的新手)

我使用其javascript API(v3)在Google地图中创建了一些标记,并使用来自我自己的API的gps坐标对它们进行了定位。问题是,当我到达地图的左侧边框时(或您想要的右侧),这些标记便消失了。我的意思不是我设置的某些自定义边界,而是世界的边界。当我走得更远时,他们又回来了。当我越过其中一条线时,它们便消失了,如下图所示:

谷歌地图边框

My markers are from the center of the map (Europe), it's like when I cross one of those line, let's say from the left just a little bit, the script starts to load the markers on the left map, which I don't see because I zoomed, and I'm still on the right map.

Sorry, quite hard to explain. Here's my complete script:

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 = [];
}

I also tried to bound the map, but I don't think that's a good idea (and that wasn't working). Is there an "integrated" way to disable those infinite maps, to only have ONE map and not a bunch when I drag to borders? Or anything else that can fix this frustrating "error"?
Thank you!

EDIT: I'll try to give an example of what's happening.
This is what I want: I'm on a google map, I get the borders of the map to get where the user is looking, and in this area (delimited by the top left and bottom right corner which I've got) I want to load every picture that is in it. The pictures are saved with gps coordinates in my database.
Here are the 7 pictures I've got in my database:

 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

When I've got the pictures from my database, I want to display where they are to the user using markers. That's why I'm creating a marker at the place where the picture is for each picture. But the user only sees markers where he looks, so if a picture is at Brazil, and he looks at Europe, the response from the database wont even contain the picture at Brazil.

So at the end, I should have markers set in the area the user is looking, and only in this area.

Now that's what is happening: I've put some debug code to see the array of markers I have on the map, so I can see which picture I have. I've added console.log(markers.length); after of my for loop which sets all the markers to see how many marker I've got and compare this number to the number of markers I see. And this gave me I think informations about what's the problem. Here is what I see in a normal case:

正常1

Everything is normal, I've got 4 pictures in this area so the script displays me 4 markers. The console prints 4 for the console.log(markers.length);.

Now another normal case, but just "next to" when it bugs:

普通2

The console prints 2, so everything's fine.
But then, when I go like a few kilometers at the left, when I exit the "bounds" of the map to be on another map, here's what I've got:

漏洞

Nothing, as you can see. And the console prints 4. We see the border line on the map, it's a little bit dark because of the theme. I saw that when I overpass this border line, it starts bugging. It's like it tries to load the markers on the left map, but I'm still on the right map so I can't see them.

EDIT: Here is the server-side SQL query:

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;
antonio

Your problem is that your map's view is crossing the International Date Line (also called the anti-meridian) which is the 180 degrees longitude line.

When you approach this line coming from the east, longitudes go from 0 to -180, and when you approach this line coming from the west logitudes grow from 0 to 180.

So, when you get the map bounds including this line you are getting a bounds that looks like (using your variable names):

t1_long: 72
br_long: -72

And as your server code is expecting t1_long to be < br_long you are getting an array of markers that are out of the real bounds of your map (you are drawing markers that lay on the hidden side of the map).

You are not showing your server implementation but you need to take this into account. So, your implementation is OK when t1_long < br_long, but you need to add some conditions when t1_long > br_long. For example (pseudocode)

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

Update:

I'm adding an image to illustrate my point:

在此处输入图片说明

根据您的查询,当您的地图边界类似于图片(红色正方形)时,您正在查询:

WHERE gps_long BETWEEN SYMMETRIC 100 AND -90

因此,查询返回的绿色标记为-90 <-70 <100,而不是粉红色标记。

SYMMETRIC在这种情况下运算符不能解决问题,因为它只允许-90和100极限顺序不相关。因此WHERE gps_long BETWEEN SYMMETRIC 100 AND -90WHERE gps_long BETWEEN SYMMETRIC -90 AND 100对于绿色标记,两者均为true;对于粉红色标记均为false。

更新:

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;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章