SuperMap iClient for JavaScript 实现拖动半径进行距离查询

作者:sniper

    前一段时间有很多朋友问我,怎么用SuperMap iClient for JavaScript实现类似百度地图或高德地图那样拖动一个按钮选择半径,从而查询附近的地理要素。因此,我们今天就来聊一聊怎么实现鼠标拖动进行距离查询。先来看一看是什么效果:
SuperMap iClient for JavaScript 实现拖动半径进行距离查询_第1张图片

说明
    本文使用的数据为iserver自带的范例数据长春市区图;查询的圆点是地图的中心点,在使用中需要根据实际情况相应改变;查询的目标是中心点周围的学校;
实现拖动查询的代码,主要由以下三部分组成。
    1、距离查询。
    2、拖动按钮选择半径。
    3、在地图移动的时候按钮位置随地图移动。

1、距离查询
    首先使地图缩放至当前查询距离的范围。然后根据半径queryDis进行距离查询,查询出中心点周围的学校。具体请参考iserver范例程序中的距离查询,在这里不再赘述。

function queryByDistanceStart(){
    dis = 500;//设置第一次查询的默认值
    queryByDistance(dis);//初始半径距离查询
    setDrag();//拖动选择半径
}
//距离查询
function queryByDistance(queryDis) {
    //地图定位至当前查询范围
    var polygon = SuperMap.Geometry.Polygon.createRegularPolygon(centerPoint,queryDis,50,270);
    map.zoomToExtent(polygon.getBounds());
    markerLayer.clearMarkers();
    var queryByDistanceParams = new SuperMap.REST.QueryByDistanceParameters({
        queryParams: new Array(new SuperMap.REST.FilterParameter({name: "School@Changchun"})),
        returnContent: true,
        distance: queryDis,
        geometry: new SuperMap.Geometry.Point(X, Y)
    });
    var queryByDistanceService = new SuperMap.REST.QueryByDistanceService(url);
    queryByDistanceService.events.on({
        "processCompleted": processCompleted,
        "processFailed": processFailed
    });
    queryByDistanceService.processAsync(queryByDistanceParams);
    }
function processCompleted(queryEventArgs) {
    var i, j, result = queryEventArgs.result;
    for(i = 0;i < result.recordsets.length; i++) {
        for(j = 0; j < result.recordsets[i].features.length; j++) {
            var point = result.recordsets[i].features[j].geometry,
            size = new SuperMap.Size(44, 33),
            offset = new SuperMap.Pixel(-(size.w/2), -size.h),
            icon = new SuperMap.Icon("img/marker.png", size, offset);
            markerLayer.addMarker(new SuperMap.Marker(new SuperMap.LonLat(point.x, point.y), icon));
         }
    }
}
function processFailed(e){
    alert(e.error.errorMsg);
}

    以上为距离查询的部分,主要是根据传入的半径值,查询出距离中心点的距离小于该半径的学校,并以marker的形式添加到地图上。

2、拖动按钮选择半径
    我们在做这一部分的功能时,首先要考虑到拖动按钮的类型以及它的位置。本文使用的拖动按钮实际上是一个div,放在map的div之中,具体如下:

<div id = "map">
    <div id="dragButton" style="display: none;">
        <input type="image" id="TDimg" calss="TD" src="img/TD.png">
        <input type="text" id="distance" style="font-family: '黑体'; font-weight: bold;" />      <!--这个文本框用于显示拖动时候的半径距离显示-->
    </div> 
</div>

    接下来就到了本文的重点,实现拖动按钮控制半径的功能。

function setDrag(){
    vectorLayer.removeAllFeatures();

    //显示初始圆
    var polygon = SuperMap.Geometry.Polygon.createRegularPolygon(centerPoint,dis,50,270);
    vectorLayer.addFeatures(new SuperMap.Feature.Vector(polygon,circleStyle));

    //显示初始拖动按钮
    var dragButtonLonlat=new SuperMap.LonLat(X+dis,Y);
    var pixe=map.getPixelFromLonLat(dragButtonLonlat);
    $("#dragButton").css({top:(pixe.y-8)+"px",left:(pixe.x-13)+"px"});
    $("#distance").val(dis +"米");
    $("#dragButton").show();

    $('#dragButton').mousedown(
        function (event){
            //鼠标按下时,获取圆心的屏幕坐标
            var centerPixelX = event.pageX - map.getPixelFromLonLat(new SuperMap.LonLat(X,Y)).x;
            var centerPixelY = map.getPixelFromLonLat(new SuperMap.LonLat(X,Y)).y;

            $('#map').mousemove(
                function (event){
                    //取消浏览器的默认拖动事件
                    event.preventDefault();
                    event.stopPropagation();
                    var eventPixel = new SuperMap.Pixel(event.pageX,centerPixelY);//拖动时的鼠标屏幕坐标
                    dis = map.getLonLatFromPixel(eventPixel).lon-X;//拖动时的半径
                    var obj = $('#dragButton');
                    //控制拖动按钮向左不能超过圆心
                    if(event.pageX>map.getPixelFromLonLat(new SuperMap.LonLat(X,Y)).x){
                        obj.css({'left':event.pageX-13, 'top':centerPixelY-8});//拖动按钮的位置随鼠标移动改变
                        $("#distance").val(dis.toFixed(0)+"米");//显示半径文本框中的半径值
                        //实时画圆
                        var polygon = SuperMap.Geometry.Polygon.createRegularPolygon(centerPoint,dis,50,270);
                        vectorLayer.removeAllFeatures();
                        vectorLayer.addFeatures(new SuperMap.Feature.Vector(polygon,circleStyle));
                    }
                }
            ).mouseup(
                function (event){
                    //移除鼠标拖动方法
                    $('#map').unbind("mousemove");
                    //根据当前半径进行距离查询
                    queryByDistance(dis);
                    //移除鼠标抬起方法
                    $('#map').unbind("mouseup");
                }
            );
        }

    );
}

    鼠标在拖动按钮的过程主要分三个阶段:鼠标按下;鼠标移动;鼠标抬起。
    因此根据这三个过程,鼠标按下时触发接下来的方法。鼠标移动时,根据鼠标当前的屏幕坐标,调整拖动按钮的位置,并把屏幕坐标转换成地理坐标然后实时在地图上绘圆,同时在文本框中实时显示当前的半径。鼠标抬起时把当前半径传入距离查询方法进行距离查询并解除之前的事件绑定。
    要注意的是,浏览器在鼠标拖动控件的时候有一个默认的提示,鼠标旁边会出现一个禁止的符号。这会影响我们的功能实现,所以要取消浏览器的默认拖动事件。
3、在地图移动的时候使按钮随地图移动
    到上一步结束,大家可以发现我们其实已经可以实现鼠标拖动选择半径并进行距离查询了。但是我们的拖动按钮position设置的是absolute,它在屏幕上的位置是绝对的,他不会随着用户拖动地图而改变位置,所以我们就要对地图做一个监控,当地图移动时拖动按钮跟着移动。具体方法如下:
    首先对地图的移动事件添加监控。

map.events.on({"move":move});

    然后在地图移动的时候调整按钮的位置。

function move(){
    //在拖动地图的过程中,使拖动按钮随着地图移动
    if($('#dragButton').is(":visible")){
        var pixcel = map.getPixelFromLonLat(new SuperMap.LonLat(X+dis,Y));
        $('#dragButton').css({'left':pixcel.x-13,'top':pixcel.y-8});
    }
}

4、结束
    到目前为止,我们的功能已经全部实现了。如有需要改进的地方,欢迎大家多多批评指正。
    完整代码如下。
http://download.csdn.net/download/supermapsupport/9495975

你可能感兴趣的:(JavaScript,supermap)