OpenLayers之多源数据加载六:静态地图及应用

    此处说的静态地图指没有经过地理投影什么的普通地图,比如一些规划图,室内建筑图,平面示意图等等,这些图一般都不会很大,但常用于一些演示系统中。会涉及到一些简单的定位,标注等。

    OpenLayers也充分考虑到了这样的需求,提供了对应的source类:ol.source.ImageStatic。示例请看下面这个地图,显示的是成都熊猫基地的平面图:

    因为应用于OpenLayers中,所以地图可以放大、缩小,具备相应的功能,对于演示而言,无疑加快了开发效率。对应的代码如下:

    <div id="map"></div>

    <script>
        //地图设置中心,设置到成都,在本地离线地图offlineMapTiles刚好有一张zoom为4的成都瓦片
        var center = ol.proj.transform([104.06667, 30.66667], 'EPSG:4326', 'EPSG:3857');
        //计算熊猫基地地图映射到地图上的范围,图片像素为550*344,保持比例的情况下,把分辨率放大一些
        var extent = [
            center[0] - 550 * 1000 / 2, 
            center[1] - 344 * 1000 / 2, 
            center[0] + 550 * 1000 / 2, 
            center[1] + 344 * 1000 / 2
            ];
        //创建地图
        var map = new ol.Map({
            target: 'map',
            view: new ol.View({
                center: center,
                zoom: 7
            })
        });
        //加载熊猫基地静态图层
        map.addLayer(new ol.layer.Image({
            source: new ol.source.ImageStatic({
                url: 'img/pandaBase.jpg', // 熊猫基地地图
                imageExtent: extent          //映射到地图的范围
            })
        }));
    </script>

    代码中有详细注释,可帮助理解,要应用静态地图,需要注意设置图片在地图中占据的extent。如果没有这个设置,图片就不能和位置关联在一起,也就不能应用于OpenLayers中。

    大家肯定非常关心extent的计算[center[0] – 550 * 1000 / 2, center[1] – 344 * 1000 / 2, center[0] + 550 * 1000 / 2, center[1] + 344 * 1000 / 2],为什么这样计算?这个地方我想让图片本身的大小和地理范围产生联系,图片的大小为550*334像素,在此基础上同比放大1000倍,作地理范围。当然也可以不用放大,直接作为地理范围,只是这样需要放大地图到很高的层级才能看到它。有了这样的映射关系后,图片能保持长宽比不变,从而不变形。

    为什么引入center,除以2相关的计算?这是一个简单计算,目的在于设置图片显示在地图中心。

    把地图加载出来只是第一步,我们最重要的是在地图上定位,并处理相应的业务。比如我们希望在图片[390, 145]像素位置添加一个活动图标表示这个地方有现场活动,就像下面这样:

    看到图片上的小旗帜没有,它就是新加上去的活动图标。那么我们是如何做到的呢:

    <div id="map2"></div>
    
    <script>
        // 地图设置中心,设置到成都,在本地离线地图 offlineMapTiles刚好有一张zoom为4的成都瓦片
        var center2 = ol.proj.transform([104.06667, 30.66667], 'EPSG:4326', 'EPSG:3857');
        // 计算熊猫基地地图映射到地图上的范围,图片像素为 550*344,保持比例的情况下,把分辨率放大一些
        var extent2 = [
            center2[0] - 550 * 1000 / 2, 
            center2[1] - 344 * 1000 / 2, 
            center2[0] + 550 * 1000 / 2, 
            center2[1] + 344 * 1000 / 2
        ];
        //创建地图
        var map2 = new ol.Map({
            view: new ol.View({
                center: center2,
                zoom: 7
            }),
            target: 'map2'
        });
        //加载熊猫基地静态地图层
        map2.addLayer(new ol.layer.Image({
            source: new ol.source.ImageStatic({
                url: 'img/pandaBase.jpg',           //熊猫基地地图
                imageExtent: extent2                //映射到地图的范围
            })
        }));
        //创建一个用于放置活动图标的layer
        var activityLayer = new ol.layer.Vector({
            source: new ol.source.Vector()
        });
        //创建一个活动图标需要的Feature,并设置位置
        var activity = new ol.Feature({
            geometry: new ol.geom.Point([center2[0]- 550*1000/2 + 390 * 1000, center2[1]-344*1000/2 + (344 - 145) * 1000])
        });
        //设置Feature的样式,使用小旗帜图标
        activity.setStyle(new ol.style.Style({
            image: new ol.style.Icon({
                src: 'img/flag_right.png',
                anchor: [0, 1],
                scale: 0.2
            })
        }));
        //添加活动Feature到layer上,并把layer添加到地图中
        activityLayer.getSource().addFeature(activity);
        map2.addLayer(activityLayer);
    </script>

    注释足够帮助大家理解代码意图,我想最关键的在于activity这个feature的位置为什么要这样计算:

    [center2[0]- 550*1000/2 + 390 * 1000, center2[1]-344*1000/2 + (344 – 145) * 1000]。如果翻译成下面这样,你可能会更容易理解:extentLeft+picX,extentTop+picY,此处的picX和picY显然是需要在图片像素位置的基础上放大1000倍,才能对应于地理位置。center[0]-550*1000/2对应的就是extentLeft,center[1]-344*1000/2对应的是extentBottom,并不是extentTop,所以我们要做一个简单的计算(344-145)*1000,而不是直接用145*1000。

    从图片的像素坐标转换为地图的地理坐标,关键在于通过像素大小,映射到一个地图的extent,希望能理解这个过程。在此基础上,就能充分应用OpenLayer3的功能了。

    

转载自:https://blog.csdn.net/qq_35732147/article/details/81386253

You may also like...