谷歌地图 - FusionTablesLayer 转换成多边形

9
我正在使用Google Maps API和jquery-ui-maps(这个问题与正常工作的插件无关)。
我已经创建了一个FusionTablesLayer,包括所有国家,除了莫桑比克。用户可以放置标记并重新定位它。我试图找到一种方法来阻止拖动(或者警告用户,现在不重要),如果他试图在融合表层外面放置标记(即超过融合表层上的边界)。
经过一些研究,我发现了这个方法:containsLocation(point:LatLng, polygon:Polygon),它计算给定点是否在指定的多边形内部。
应该接收一个多边形,但我却得到了一个FusionTablesLayer。有什么线索可以解决这个问题吗?
下面是我的代码:FIDDLE 尝试放置标记并拖动它...
//Initialize the map
var mapa = $('#map_canvas').gmap({'center': '-18.646245,35.815918'});
$('#map_canvas').gmap('option', 'zoom', 7);

//create the layer (all countries except Mozambique)
var world_geometry;
$('#map_canvas').gmap().bind('init', function(event, map) {
    world_geometry = new google.maps.FusionTablesLayer({
        query: {
            select: 'geometry',
            from: '1N2LBk4JHwWpOY4d9fobIn27lfnZ5MDy-NoqqRpk',
            where: "ISO_2DIGIT NOT EQUAL TO 'MZ'"
        },
        styles: [{
                polygonOptions: {
                    fillColor: "#333333",
                    fillOpacity: 0.3
                }
            }],
        map: map,
        suppressInfoWindows: true
    });

});

$('#map_canvas').gmap().bind('init', function(event, map) {
    $(map).click(function(event) {
        $('#map_canvas').gmap('clear', 'markers');
        $('#map_canvas').gmap('addMarker', {
            'position': event.latLng,
            'draggable': true,
            'bounds': false
        }, function(map, marker) {
        }).dragend(function(event) {
            //I need to check if the marker is over the FusionTablesLayer and block the drag.
            //var test = google.maps.geometry.poly.containsLocation(event.latLng, world_geometry);
        }).click(function() {
        })
    });
});
1个回答

5
由于FusionTablesLayer中没有“containsLocation”方法,并且不支持除click以外的鼠标事件(这会使问题变得更加简单) - 没有其他方法可以检查是否正在拖出Mozambique区域本身,而不是进入FusionTablesLayer。 解决方案是为Mozambique创建一个不可见的多边形,并在拖动完成时使用该多边形来检查“containsLocation”。
该多边形可以基于您要排除的行的KML,即“MZ”。 可以使用google.visualization.Query来完成此操作。
1)将Google API加载程序包含在您的项目中:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>

2) 初始化可视化:

google.load('visualization', '1.0');

3)为包含莫桑比克边界的多边形定义一个变量:

var mozambique;

以下是一个函数,用于加载莫桑比克的几何数据,并在地图上创建一个不可见的多边形。我们使用google.visualization.Query而不是自动化的FusionTablesLayer来提取KML中的,并将其用作多边形的基础。
基本上,这就是将来自FusionTable的KML数据转换为多边形的方法:
function initMozambique(map) {
    //init the query string, select mozambique borders
    var sql = encodeURIComponent("SELECT 'geometry' FROM 1N2LBk4JHwWpOY4d9fobIn27lfnZ5MDy-NoqqRpk WHERE ISO_2DIGIT ='MZ'");
    var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + sql);
    query.send(function (response) {
        var data = response.getDataTable().getValue(0, 0);
        //create a XML parser
        if (window.DOMParser) {
            var parser = new DOMParser();
            var kml = parser.parseFromString(data, "text/xml");
        } else { // Internet Explorer 
            var kml = new ActiveXObject("Microsoft.XMLDOM");
            kml.loadXML(data);
        }
        //get the coordinates of Mozambique
        var latLngs = kml.getElementsByTagName("coordinates")[0].childNodes[0].nodeValue.split(' ');
        //create an array of LatLngs
        var mzLatLngs = [];
        for (var i = 0; i < latLngs.length; i++) {
            var latLng = latLngs[i].split(',');
            //<coordinates> for this FusionTable comes in lng,lat format
            mzLatLngs.push(new google.maps.LatLng(latLng[1], latLng[0]));
        }
        //initialize the mozambique polygon
        mozambique = new google.maps.Polygon({
            paths: mzLatLngs,
            fillColor: 'transparent',
            strokeColor : 'transparent',
            map: map
        });
        //make the mozambique polygon "transparent" for clicks (pass clicks to map)
        google.maps.event.addListener(mozambique, 'click', function(event) {
            google.maps.event.trigger(map, 'click', event);
        });
    });
}

在你的第二个 gmap().bind('init'... 中调用上面的 initMozambique 函数:
$('#map_canvas').gmap().bind('init', function(event, map) {
   initMozambique(map);
   ...

现在您可以在拖动后检查mozambique-polygon是否包含 containsLocation
...
}).dragend(function(event) {
  if (!google.maps.geometry.poly.containsLocation(event.latLng, mozambique)) {
     alert('You are not allowed to drag the marker outside Mozambique');
  }
  //I need to check if the marker is over the FusionTablesLayer and block the drag.
  //var test = google.maps.geometry.poly.containsLocation(event.latLng, world_geometry);
}).click(function() {
})
...

请查看分叉的fiddle,其中包含上述代码的工作演示 -> http://jsfiddle.net/yb5t6cw6/

在Chrome、FF和IE、ubuntu和windows中进行了测试。


我自己没有时间测试,但它的意义都很清楚!谢谢你详细的答复。 - Pedro Gil
@davidkonrad 但是如果一个国家有太多的多边形,我们该如何处理呢? - Quynh Nguyen
@QuỳnhNguyễn,感谢您指向这个旧答案。已更新[fiddle](http://jsfiddle.net/yb5t6cw6/),旧的不再工作,因为CDN已过时。我不确定您考虑的是哪个国家? - davidkonrad
@davidkonrad https://jsfiddle.net/srxnu8pc/ 这是我的融合表图层。我正在尝试检查拖动标记是否在这些区域内部或外部。很抱歉,因为您的解决方案无法适用于此情况。因为我们不能查询“不等于”... - Quynh Nguyen
@davidkonrad 我已经尝试使用 google.visualization.QueryST_INTERSECTS 来处理带有 geometry 数据的 Circle,但是查询太重了,导致有一点延迟... 你能理解吗? - Quynh Nguyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接