7-高级视图定位

本博客合集是我的openlayers学习笔记,希望能帮助到刚开始接触openlayers的同学
@commnet 所用openlayers版本:v5.3.0
@commnet 阅读本文前需要对前端知识有一定的了解
@comment 本文内容只提供参考,建议结合openlayers官网的APIexamples来学习
@comment 部分代码参考了@老胡

有些情景需要在地图上对图形进行定位,如点击了某文本中的“泰坦尼克号”链接,希望自动在地图上定位出该船的位置。

在确定了地图视角和位置的情况下,图形也就定位了,常有以下几种方式的定位(请忽略我这吃力的网速):

  • 地图内容区外接图形(内容区外接多边形的上下顶点)
  • 地图内容区以最大的整数zoom,定位完整图形(当前zoom是能看到完整多边形最大的整数zoom了)
  • 地图内容区以最小的整数zoom,让图形铺满地图
  • 地图内容区以某分辨率,中心定位图形(中间的小圆圈)
  • 地图内容区相对于地图视窗大小,以指定偏移量定位图形(小圆圈偏移到了指定的正方形区域中)

注:这里的“内容区”是我的理解,可以把地图的view理解成css中的盒模型,当view.fit函数(下面会提到)没有指定padding参数时,内容区就是整个view,一旦指定了padding参数,内容区就变成了padding圈起来的视区了。

  • 创建5个功能测试按钮和地图容器
<button id="zoomtoswitzerlandbest">外接匹配</button><br />
<button id="zoomtoswitzerlandconstrained">最佳分辨率匹配</button><br />
<button id="zoomtoswitzerlandnearest">最佳范围匹配</button><br />
<button id="zoomtolausanne">点居中</button><br />
<button id="centerlausanne">定位点到指定位置</button>
<div class="mapcontainer">
    <div id="map" class="map"></div>
    <div class="padding-top"></div>
    <div class="padding-left"></div>
    <div class="padding-right"></div>
    <div class="padding-bottom"></div>
    <div class="center"></div>
</div>
  • 添加样式
.mapcontainer {
    position: relative;
    margin-bottom: 20px;
}

.map {
    width: 1000px;
    height: 600px;
}

div.ol-zoom {
    top: 178px;
    left: 158px;
}

div.ol-rotate {
    top: 178px;
    right: 58px;
}

.map div.ol-attribution {
    bottom: 30px;
    right: 50px;
}

.padding-top {
    position: absolute;
    top: 0;
    left: 0px;
    width: 1000px;
    height: 170px;
    background: rgba(255, 255, 255, 0.5);
}

.padding-left {
    position: absolute;
    top: 170px;
    left: 0;
    width: 150px;
    height: 400px;
    background: rgba(255, 255, 255, 0.5);
}

.padding-right {
    position: absolute;
    top: 170px;
    left: 950px;
    width: 50px;
    height: 400px;
    background: rgba(255, 255, 255, 0.5);
}

.padding-bottom {
    position: absolute;
    top: 570px;
    left: 0px;
    width: 1000px;
    height: 30px;
    background: rgba(255, 255, 255, 0.5);
}

.center {
    position: absolute;
    border: solid 1px black;
    top: 490px;
    left: 560px;
    width: 20px;
    height: 20px;
}
  • 创建地图对象
//在矢量图层上添加一个多边形(ol.geom.Polygon)和一个点(ol.geom.Point)
var source = new ol.source.Vector({
    url: '../data/switzerland.geojson',
    format: new ol.format.GeoJSON()
});

//创建样式对象
var style = new ol.style.Style({
    fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.6)'
    }),
    stroke: new ol.style.Stroke({
        color: '#319FD3',
        width: 1
    }),
    image: new ol.style.Circle({
        radius: 5,
        fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.6)'
        }),
        stroke: new ol.style.Stroke({
            color: '#319FD3',
            width: 1
        })
    })
});

//创建矢量图层
var vectorLayer = new ol.layer.Vector({
    source: source,
    style: style
});

var view = new ol.View({
    center: [0, 0],
    zoom: 1
});

//地图包含底图和矢量图层
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        }),
        vectorLayer
    ],
    target: 'map',
    view: view
});
  • 为5个功能测试按钮添加点击事件,注释中详细说明了几种定位的用法和区别
//多边形的外接匹配:地图的内容区外接多边形
var zoomtoswitzerlandbest = document.getElementById('zoomtoswitzerlandbest');
zoomtoswitzerlandbest.addEventListener('click', function() {
    var feature = source.getFeatures()[0];
    var polygon = feature.getGeometry();
    //将view理解成css中的盒模型,多边形相对于padding里的内容区进行定位
    //constrainResolution默认为true,这里设为false即不限制分辨率,zoom不必是整数,因此可以实现精确的外接定位
    view.fit(polygon, {
        padding: [170, 50, 30, 150],
        constrainResolution: false
    });
    console.log(map.getView().getZoom())
}, false);

//多边形的最佳分辨率匹配:再继续放大,多边形就超出内容区了
var zoomtoswitzerlandconstrained =
    document.getElementById('zoomtoswitzerlandconstrained');
zoomtoswitzerlandconstrained.addEventListener('click', function() {
    var feature = source.getFeatures()[0];
    var polygon = feature.getGeometry();
    //如果不写constrainResolution,默认为true
    //即该定位结果是在zoom为整数的前提下,能看到完整多边形的最大分辨率
    view.fit(polygon, {
        padding: [170, 50, 30, 150]
    });
    console.log(map.getView().getZoom())
}, false);

//多边形的最佳范围匹配
var zoomtoswitzerlandnearest =
    document.getElementById('zoomtoswitzerlandnearest');
zoomtoswitzerlandnearest.addEventListener('click', function() {
    var feature = source.getFeatures()[0];
    var polygon = feature.getGeometry();
    //设置nearest为true,以最小的整数zoom,让图形铺满地图
    view.fit(polygon, {
        padding: [170, 50, 30, 150],
        nearest: true
    });
    console.log(map.getView().getZoom())
}, false);

//将点以某分辨率居中
var zoomtolausanne = document.getElementById('zoomtolausanne');
zoomtolausanne.addEventListener('click', function() {
    var feature = source.getFeatures()[1];
    var point = feature.getGeometry();
    //将点point以分辨率minResolution居中
    view.fit(point, {
        padding: [170, 50, 30, 150],
        minResolution: 250
    });

}, false);

//将点相对map.getSize()以指定偏移量定位
var centerlausanne = document.getElementById('centerlausanne');
centerlausanne.addEventListener('click', function() {
    var feature = source.getFeatures()[1];
    var point = feature.getGeometry();
    var size = map.getSize();
    console.log(size)
    //相对于size,点point距离顶部偏移了500px,距离左边偏移了570px
    view.centerOn(point.getCoordinates(), size, [570, 500]);
}, false);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352