bingMap的使用小结

这两天研究了一下必应地图,并且按照官方文档编写封装成地图工具类,此过程中也遇到一些问题,在这里记录一下。

1.为什么要用bing地图

其实在国外有google,在国内有百度,怎么着应该都轮不到研究bing地图,但是现在的问题是,我需要在国内使用世界地图,如果要用google地图,就必须翻墙使用,这就造成了访问瓶颈,而百度地图又不提供世界地图。所以bing就变成了最好的选择。

2.准备工作

使用bing地图,首先要有一个微软的账户,这个可以去这个官网注册,之后申请一个bing地图的api-key。bing地图的文档归档在msdn中,可以直接去msdn搜索,这里还有一个教学类似的网站可以引导大家学习。

3.遇到的问题

bing地图似乎没有提供鼠标坐标和地球坐标的转换,或者我没有找到类似的转换,所以这里自己写了一个,大家遇到同样的问题可以参考一下。

首先要注意的是,注意的是,注意的是!!!重要的话说三遍:

longitude是经度,latitude是维度!!!!

经度相当于x,维度相当于y!!!!

好了,接下来说下问题主体:

比如我点击地图上某个点,要再这个点上做个图钉,map-api提供一个方法可以在地图上添加图钉。

var p = new Microsoft.Maps.Location(latitude,longitude);
var map = this.map;//已经初始好的map对象
var pushpinOptions = {draggable: true};
var pushpin= Map.Pushpin(p||map.getCenter(), pushpinOptions);
map.entities.push(pushpin);

上面的代码可以看出,要在地图上添加一个图钉,必须拥有一个location对象,必须知道这个点的地图上的经纬度。

接下来看,当点击了map时,能够获取的坐标。

var event= 
Microsoft.Maps.Events.addHandler(map,eventName, function(e){
    var eventName = e.eventName;
    if(eventName==“click”
     ||eventName==“leftclick”
     ||eventName==“rightclick”){
       var clickLocation = Map.p(e.pageY, e.pageX);
       //e.pageY e.pageX 值为相对浏览器左上角的坐标
       var location 
           = _this._transformPage2Location(clickLocation);
    }else{

    }
    if(callback){
       callback(e,location);
    }
});

点击过后,能够获取的是相对浏览器左上角的坐标,但这并不是地图的经纬度坐标,所以需要做一个转换,上面代码中,_transformPage2Location就是这个转换方法。下面就是这个转换方法。

_transformPage2Location:function(page){
     var map = this.map;
     var width = map.getWidth();
     //获取地图dom宽度
     var height = map.getHeight();
     //获取地图dom高度
     var bounds = map.getBounds();
     //获取地图宽高覆盖的经纬度跨度
     var bheight = bounds.height;
     //获取纬度跨度
     var bwidth = bounds.width;
     //获取经度跨度
     var centerLocation = bounds.center;
     //获取当前地图中心的坐标
     var viewportX = map.getViewportX();
     //获取当前地图中心点对应的page坐标
     var viewportY = map.getViewportY();
     //同上
     var rateX = bwidth/width;
     //计算经度方向的比率
     var rateY = bheight/height;
     //计算维度方向的比率
     var locationx = centerLocation.longitude
                   +(page.longitude-viewportX)*rateX;
     //计算经度方向的真实值,算法自行体会
     var locationy = centerLocation.latitude
                   -(page.latitude-viewportY)*rateY;
     //计算纬度方向的真实值
     if(Math.abs(locationx)>180){
         locationx = (Math.abs(locationx)-360)
                   *locationx/Math.abs(locationx);
         //如果经度方向跨越了180经度线,需要对经度做修正
     }
     return Map.p(locationy,locationx);
}


上述方式可以计算出点击点的地图经纬度坐标,之后带入添加图钉的方法中去,就可以了在点击的地方添加图钉了。

应该还有其他的问题,但暂时只遇到这么多。

对地图api做了简单的封装,完整代码如下:

(function(window){
    function Map(){}
    Map.prototype={
        mapConfig:null,
        map:null,
        initConfig:function(){
            this.mapConfig={
                credentials:'******',
                //map key  http://www.bingmapsportal.com/ 可以申请
                enableClickableLogo:false,//不加logo
                enableSearchLogo:false,      //搜索框
                showDashboard:true,    //控制栏
                showMapTypeSelector:true,  
                // 当控制栏true时 是否显示autoMatic选项
                showScalebar:false,         
                //当控制栏true时,是否显示放大缩小控件
                center: Map.p(47.609771, -122.2321543125),
                //中心点坐标 和
                zoom: 8, // 放缩比
//            mapTypeId: Microsoft.Maps.MapTypeId.aerial,
//            mapTypeId: Microsoft.Maps.MapTypeId.birdseye,
                width:500,
                height:500
            }
        },
        init:function(params){
            this.initConfig();
            this.mapConfig = $.extend(params,this.mapConfig);
            this.initMap();
            this.log();
        },
        initMap:function(){
            var myMap = document.getElementById('myMap');
            myMap.oncontextmenu = function(){return false;};
            this.map = 
            new Microsoft.Maps.Map(myMap,this.mapConfig);
        },

        addMark:function(p){
            var map = this.map;
            var pushpinOptions = {draggable: true};
            var pushpin= 
            Map.Pushpin(p||map.getCenter(), pushpinOptions);
            map.entities.push(pushpin);
            return pushpin;
        },
        addTipMark:function(font,p){
            var map = this.map;
            font = font||"自定义";
            var html="<div style='font-size:12px;"+
            "font-weight:bold;border:solid 2px;"+
            "background-color:LightBlue;width:"+
            font.length*14+"px;"+
            "'>"+font+"</div>";
            var pushpinOptions = {
                width:null,
                height: null,
                htmlContent:html,
                draggable: true
            };
            var pushpin= 
            Map.Pushpin(p||map.getCenter(), pushpinOptions);
            map.entities.push(pushpin);
            return pushpin;
        },

        linePoints:function(locations,options,polyline){
            options = $.extend({
                strokeColor:
                Map.Color(Math.round(255),
                          Math.round(0),
                          Math.round(0),
                          Math.round(255)),
                strokeThickness: 3
            },options);
            if(!polyline){
                var map = this.map;
                polyline = Map.Polyline([]);
                map.entities.push(polyline);
            }
            polyline.setLocations(locations);
            return polyline;
        },

        fillPoints:function(locations,options,polygon){
            options = $.extend({
                strokeColor: 
                    Map.Color(
                        Math.round(255),
                        Math.round(0),
                        Math.round(0),
                        Math.round(255)),
                strokeThickness: 3,
                fillColor:
                    Map.Color(
                        Math.round(0),
                        Math.round(255),
                        Math.round(0),
                        Math.round(122))
            },options);
            if(!polygon){
                var map = this.map;
                polygon = Map.Polygon([]);
                map.entities.push(polygon);
            }
            polygon.setLocations(locations);
            return polygon;
        },
        removePolyline:function(polyline){
            var map = this.map;
            if(polyline instanceof Microsoft.Maps.Polyline){
                map.entities.remove(polyline);
            }
        },

        addMarkClickListener:function(mark,callback){
            return 
            this._addMarkListener(“click”,mark,callback);
        },
        addMarkLeftClickListener:function(mark,callback){
            return 
            this._addMarkListener(“leftclick”,mark,callback);
        },
        addMarkRightClickListener:function(mark,callback){
            return 
            this._addMarkListener(“rightclick”,mark,callback);
        },
        addMarkDragStartListener:function(mark,callback){
            return 
            this._addMarkListener(“dragstart”,mark,callback);
        },
        addMarkDragListener:function(mark,callback){
            return 
            this._addMarkListener(“drag”,mark,callback);
        },
        addMarkDragEndListener:function(mark,callback){
            return 
            this._addMarkListener(“dragend”,mark,callback);
        },
        removeMarkEvent:function(event){
            if(event)
                Microsoft.Maps.Events.removeHandler(event);
        },

        addMapClickListener:function(callback){
            return 
            this._addMapListener(“click”,callback);
        },
        addMapRightClickListener:function(callback){
            return 
            this._addMapListener(“rightclick”,callback);
        },
        addMapDClickListener:function(callback){
            return 
            this._addMapListener(“dblclick”,callback);
        },

        _addMapListener:function(eventName,callback){
            var map = this.map;
            var _this = this;
            var event= 
            Microsoft.Maps.Events.addHandler(
                map,
                eventName, 
                function(e){
                    var eventName = e.eventName;
                    if(eventName==“click”
                     ||eventName==“leftclick”
                     ||eventName==“rightclick”){
                        var clickLocation = 
                            Map.p(e.pageY, e.pageX);
                        var location = 
                            _this._transformPage2Location(
                                clickLocation);
                    }else{

                    }
                    if(callback){
                        callback(e,location);
                    }
                });
            return event;
        },

        _transformPage2Location:function(page){
            var map = this.map;
            var width = map.getWidth();
            var height = map.getHeight();
            var bounds = map.getBounds();
            var bheight = bounds.height;
            var bwidth = bounds.width;
            var centerLocation = bounds.center;
            var viewportX = map.getViewportX();
            var viewportY = map.getViewportY();
            var rateX = bwidth/width;
            var rateY = bheight/height;
            var locationx = centerLocation.longitude
                    +(page.longitude-viewportX)*rateX;
            var locationy = centerLocation.latitude
                    -(page.latitude-viewportY)*rateY;
            if(Math.abs(locationx)>180){
                locationx = (Math.abs(locationx)-360)
                          *locationx/Math.abs(locationx);
            }
            return Map.p(locationy,locationx);
        },

        _addMarkListener:function(eventName,mark,callback){
            if(!mark){
                throw “mark is null”;
            }
            var event= 
            Microsoft.Maps.Events.addHandler(
                mark,
                eventName, 
                function(e){
                var eventName = e.eventName;
                if(eventName==“click”
                 ||eventName==“leftclick”
                 ||eventName==“rightclick”){
                    var location = e.target._location;
                }else{
                    var location = e.entity._location;
                }
                if(callback){
                    callback(e,location);
                }
            });
            return event;
        },

        getRealMap:function(){
            return this.map;
        },

        log:function(){
            var map = this.map;
            console.log(map.getImageryId());
            console.log(map.getHeading());
            console.log(map.getZoom());
            console.log(map.getWidth()+”/“+map.getHeight());
            console.log(“map.getViewport:”
                +map.getViewportX()+”/“+map.getViewportY());
            console.log(“map.getMetersPerPixel:”
                +map.getMetersPerPixel());
            console.log(“map.getBounds:”+map.getBounds());
            console.log(“map.isRotationEnabled:”
                +map.isRotationEnabled());
            console.log(“map.isMercator:”+map.isMercator());
            console.log(“map.getZoomRange:”
                +map.getZoomRange().min+”-“
                +map.getZoomRange().max);
        }
    }
    Map.createMap = function(params){
        var myMap = new Map();
        myMap.init(params);
        return myMap;
    }
    Map.p =Map.Location = function(y,x){
        //latitude 维度 longitude经度
        return new Microsoft.Maps.Location(y,x);
    }
    Map.c = Map.Color = function(r,g,b,a){
        return new Microsoft.Maps.Color(r,g,b,a);
    }
    Map.pg = Map.Polygon=function(locations){
        return new Microsoft.Maps.Polygon(locations);
    }
    Map.pl = Map.Polyline=function(locations){
        return new Microsoft.Maps.Polyline(locations);
    }
    Map.pp = Map.Pushpin = function(location,params){
        return new Microsoft.Maps.Pushpin(location,params);
    }


    window.Map = Map;
})(window);

上面代码托管在github上,地址是:

git@github.com:gagaprince/bingMap.git

大家可以fork看下。

转载请注明出处:http://gagalulu.wang/blog/detail/18 您的支持是我最大的动力!







版权声明:本文为gagaprince原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。