标记在谷歌地图中消失

时间:2016-06-13 22:40:10

标签: javascript google-maps google-maps-api-3

我有一种情况有点难以解释,从而近似标题(我在谷歌地图API上全新)

我使用他们的javascript API(v3)在谷歌地图中创建了一些标记,并使用来自我自己的API的gps坐标定位它们。问题是当我到达地图的左边界(或右边,你想要)时,那些标记就会消失。我并不是指我设定的一些自定义边界,我指的是世界的边界。当我走得更远时,他们会回来。当我穿过其中一条线时,它们会消失,如图所示:

google maps border

我的标记来自地图的中心(欧洲),就像当我穿过其中一条线时,让我们从左边稍微说一下,脚本开始加载左侧地图上的标记,我不要看,因为我放大了,我仍然在正确的地图上。

对不起,很难解释。这是我的完整脚本:

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

我也试图绑定地图,但我认为这不是一个好主意(而且这不起作用)。是否有一种“集成”的方式来禁用那些无限的地图,当我拖到边界时只有一张地图而不是一堆?还是可以解决这个令人沮丧的“错误”的其他任何事情? 谢谢!

编辑:我会尝试举例说明正在发生的事情 这就是我想要的东西:我在谷歌地图上,我得到了地图的边框以获得用户所在的位置,并在此区域(由左上角和右下角分隔)我有它)我想加载其中的每张图片。图片以gps坐标保存在我的数据库中 以下是我在数据库中收到的7张图片:

 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

当我从我的数据库中获取图片时,我想使用标记显示用户的位置。这就是我在每张图片的图片所在位置创建标记的原因。但是用户只看到他看起来的标记,所以如果一张照片出现在巴西,他看着欧洲,那么数据库的反应甚至不会包含巴西的照片。

所以最后,我应该在用户正在查看的区域设置标记,并且只在此区域设置。

现在正在发生的事情:我已经放了一些调试代码来查看我在地图上的标记数组,所以我可以看到我的图片。我在for循环之后添加了console.log(markers.length);,它设置了所有标记以查看我得到了多少标记,并将此数字与我看到的标记数量进行比较。这让我想到了有关问题的信息。 以下是我在正常情况下看到的内容:

normal1

一切正常,我在这个区域有4张照片,所以脚本显示4个标记。控制台为4打印console.log(markers.length);

现在是另一个正常的情况,但只是在它旁边的“错误”:

normal2

控制台打印2,所以一切都很好。
但是,当我走到左边几公里的地方时,当我退出地图的“界限”到另一张地图时,这就是我所拥有的:

bug

没有,你可以看到。控制台打印4。我们在地图上看到边界线,由于主题,它有点暗。我看到当我越过这条边界线时,它开始窃听。这就像它试图在左侧地图上加载标记,但我仍然在正确的地图上,所以我看不到它们。

编辑:这是服务器端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;

1 个答案:

答案 0 :(得分:2)

您的问题是您的地图视图正在穿越国际日期线(也称为反子午线),即180度经度线。

当你接近来自东方的这条线时,经度从0到-180,当你接近来自西方的这条线时,逻辑从0增加到180.

因此,当您获得包含此行的地图边界时,您将获得一个看起来像的边界(使用您的变量名称):

t1_long: 72
br_long: -72

由于您的服务器代码期望t1_long为&lt; br_long您将获得一组超出地图实际边界的标记(您正在绘制位于地图隐藏边的标记)。

您没有展示您的服务器实施,但您需要考虑这一点。因此,t1_long < br_long,时您的实施正常,但您需要在t1_long > br_long时添加一些条件。例如(伪代码)

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

<强>更新

我添加了一张图片来说明我的观点:

enter image description here

根据您的查询,当你的地图边界就像图片(红色方块)中那样你正在查询:

WHERE gps_long BETWEEN SYMMETRIC 100 AND -90

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

在这种情况下,SYMMETRIC运算符无法解决问题,因为它只允许-90和100限制顺序无关紧要。所以WHERE gps_long BETWEEN SYMMETRIC 100 AND -90WHERE gps_long BETWEEN SYMMETRIC -90 AND 100对于绿色标记都是正确的,而对于粉红标记则是假的。

<强>更新

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