openLayers基础总结

openlayers是一个开源免费的js库,用于在网页中实现地图的动态显示和交互。

初始化地图
  • 首先,引用ol.css和ol.js,因为我们已经下载了ol库,所以使用ol的本地路径就行了,如果网络方便,可以直接在从ol网站获取。
1
2
3
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
<script src="decision/static/js/jquery.min.js"></script>

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  // 底图  高德地图  ol.layer.Tile 提供被切分为切片的图片地图数据
var gaodeMapLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
})
});
this.map = new ol.Map({
target: "map",
//图层 可以添加多个地图地图
layers: [gaodeMapLayer],
controls:[scaleLineControl],//也可以this.map.addControl
view: new ol.View({
center: [117.814635,36.402033],
projection: 'EPSG:4326',
zoom: 8,//地图缩放级别
minZoom:5,
maxZoom:12
})
});
// 实例化比例尺控件
var scaleLineControl = new ol.control.ScaleLine({
// 设置比例尺单位为degrees、imperial、us、nautical或metric(度量单位)
units: "metric"
});
this.map.addControl(scaleLineControl);

 

  • 这段代码的作用是在网页是显示一个地图;
  • 和leaflet一样,地图必须显示在一个div中,因此首先创建一个div;
  • target:’map’ 指定了地图要显示在id为map的div中;
  • new ol.layer.Tile({ source: new ol.source.OSM() }) 定义了一个图层,数据来源是OpenStreetMap提供的切片数据;
  • new ol.View({ center: ol.proj.fromLonLat([37.41, 8.82]), zoom: 4 }) 定义了地图的中心位置,范围和层级。
  • ol.proj.fromLonLat([37.41, 8.82]) 是将一个经纬度坐标转换成当前地图投影的坐标;
openlayers自定义图层
  • 所有的数据都是不同的图层 可定义多个多层
1
2
3
4
5
6
7
8
9
//矢量标注的数据源  this.nodeSource.addFeature 添加标点   var nodeLayer 只是在地图上添加该图层
this.nodeSource = new ol.source.Vector({
features: []
});
// 矢量标注图层 也可以nodeLayer.addFeatures
var nodeLayer = new ol.layer.Vector({
source: this.nodeSource,
});
this.map.addLayer(nodeLayer);
获取自定义图层中的所有数据
  • this.nodeSource.getFeatureById(id) 获取指定id的图层
1
2
3
4
5
6
7
var allNodeMarker = this.nodeSource.getFeatures();
//获取图层对应自定义名称的features删除掉
for (let i = 0; i < allStartMarker.length-1; i++) {
if(allNodeMarker[i].values_.layerType == markerLayerName){
this.nodeSource.removeFeature(allStartMarker[i]);
}
}
创建图标
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
createNodeMarker(item, txt){
var newFeature = new ol.Feature({
geometry: new ol.geom.Point([item.longitude, item.latitude]), //几何信息
data: item,
type: 'event',//设置键值对的集合私有属性 setProperties设置也可以
layerType:'自定义私有属性' //
});
let data = newFeature.values_.data.eventType;
//设置要素样式 坐标图片
newFeature.setStyle(this.createNodeStyle(imgurl));
//nodeSource数据标点图层添加数据
this.nodeSource.addFeature(newFeature);
}
createNodeStyle(imgurl,size='0.5') {
return new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 60], //锚点
anchorOrigin: "top-right", //锚点源
anchorXUnits: "fraction", //锚点X值单位
anchorYUnits: "pixels", //锚点Y值单位
offsetOrigin: "top-right", //偏移原点
opacity: 1,
scale:size,
src: '/images/sign/'+imgurl+'.png'
}),
})
}
创建线
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var lineData = []
// [ [lng,lat],[lng,lat],[lng,lat],[lng,lat],[lng,lat]]
lineData.push(ol.proj.fromLonLat([points[i].longitude,points[i].latitude]));
var lineFeature = new ol.Feature({
geometry: new ol.geom.LineString(lineData),
layerType:type,
});
var lineStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 2
})
});
lineFeature.setStyle(lineStyle);
this.startAndEndMarker.addFeature(lineFeature);
openlayers添加鼠标右键
  • openlayers没有右键操作 需要通过jq监听右键来实现效果
  • 右键弹出的dom需要display:none否则会出现在地图上 操作的时候dom在显示出来
  • 删除右键图层会造成dom丢失所以取消设置定位为null即可 self.menu_overlay.setPosition(null);
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    <div v-show="menuShow" id="contextmenu_container" class="contextmenu">
    <ul>
    <div @click="creatNode">设置事件发生地点</div>
    <li v-for="(item,index) in this.addForm.pathPoints">
    <div @click="setStart(index)">设置起点{{index+1}}</div>
    <div @click="setEnd(index)">设置终点{{index+1}}</div>
    </li>
    </ul>
    </div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 addMenu_over(){
var self = this;
this.menuShow = true;
this.menu_overlay= new ol.Overlay({
element: document.getElementById("contextmenu_container"),
positioning: 'right-top'
});
this.map.addOverlay(self.menu_overlay);
$(self.map.getViewport()).unbind('contextmenu').on("contextmenu", function(event){
event.preventDefault();//屏蔽自带的右键事件
var pixel = [event.clientX,event.clientY];
let feature = self.map.forEachFeatureAtPixel(pixel, (feature, layer) => {
return feature;
});
var coordinate = self.map.getEventCoordinate(event.originalEvent);
self.menu_overlay.setPosition(coordinate);
});
},
openlayers中overlay 添加覆盖物
  • overlay是覆盖物的意思,主要是放置一些和地图位置相关的元素,
  • 如:infowindow、点标记、图片等,而这些覆盖物都是和html中的element等价的,
  • 通过overlay的属性element和html元素绑定同时设定坐标参数——达到将html元素放到地图上的位置,在平移缩放的时候html元素也会随着地图的移动而移动。
鼠标悬浮添加提示框
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <div id="popup">
    <el-popover
    placement="top-start"
    title="RSU编号"
    width="200"
    trigger="manual"
    v-model="popoverVisible"
    :content="currentRsuSnHoverId">
    </el-popover>
    </div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var container = document.getElementById("popup1");
this.overlay1 = new ol.Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true,
positioning: "top-center",
offset: [-20, -120]
});
//地图鼠标悬浮创建不同标注弹出层
this.map.on("pointermove", evt => {
//https://www.zybuluo.com/mgsky1/note/1132768#2geteventpixelevent
//e.coordinate是点击的坐标
//1在悬浮地图时触发getEventPixel函数返回区域- //在悬浮地图时获取像素区域
//2调用forEachFeatureAtPixel进行像素区域扫描,如果发现Feature,则激活弹出框。
var pixel = this.map.getEventPixel(evt.originalEvent);
var feature = this.map.forEachFeatureAtPixel(pixel, (feature, layer) => {
return feature
});
if (feature) {
//setProperties 设置键值对集合私有属性 getProperties获取私有键值对
if (feature.getProperties().type === 'rsu') {
this.popoverVisible = true;
this.overlay2.setPosition(feature.getGeometry().flatCoordinates);
//显示overlay
this.map.addOverlay(this.overlay2);
this.currentRsuSnHoverId = feature.getId();
}
} else {
this.popoverVisible = false;
}
});

 

点击某一图层添加覆盖物操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<div id="popup" class="ol-popup">
<div id="popup-content">
<el-tooltip
content="编辑点"
effect="dark"
placement="bottom"
>
<el-button
icon="el-icon-edit primary"
size="mini"
circle
@click="editPointSerial()"
/>
</el-tooltip>
<el-tooltip
:content="删除点"
effect="dark"
placement="bottom"
>
<el-button
icon="el-icon-delete"
size="mini"
type="danger"
circle
@click="deletePoint()"
/>
</el-tooltip>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 this.pointSource = new ol.source.Vector({
features: []
});
var pointLayer = new ol.layer.Vector({
source: this.pointSource
});
this.map.addLayer(pointLayer);

//添加popup覆盖物
var container = document.getElementById("popup");
this.overlay = new ol.Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true,
positioning: "top-center",
offset: [0, -48]
});
let pointSelect = new ol.interaction.Select({
//condition: ol.events.condition.pointerMove,
layers: [pointLayer],//选择哪个图层进行操作
style: feature => {//设置选中样式
return this.stylePointSelect(feature);
},
multi: false //multi设置是否可以多选
});
//图层选中的一些操作
pointSelect.on("select", e => {
if (e.selected.length > 0 && this.addPointWay === "") {
var coodinate = e.selected[0].getGeometry().flatCoordinates;
//设置弹出框内容,可以HTML自定义
// content.innerHTML = "<p>aaaaaAA</p>";
//设置overlay的显示位置
this.selectedPointSerial = e.selected[0].values_.id;
this.overlay.setPosition(coodinate);
//显示overlay
this.map.addOverlay(this.overlay);
} else {
this.map.removeOverlay(this.overlay);
}
});
this.map.addInteraction(pointSelect);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
stylePointSelect(feature) {
var fill = new ol.style.Fill({
color: "#EA5504"
});
var stroke = new ol.style.Stroke({
color: "#EA5504",
width: 1
});
return new ol.style.Style({
image: new ol.style.Circle({
fill: fill,
stroke: stroke,
radius: 12
}),
text: new ol.style.Text({
textAlign: "center", //位置
textBaseline: "middle", //基准线
font: "normal 14px 微软雅黑", //文字样式
text: feature.values_.id + "", //文本内容
fill: new ol.style.Fill({
//文本填充样式(即文字颜色)
color: "#DCDFE6"
}),
stroke: new ol.style.Stroke({
color: "#DCDFE6"
})
})
});
},
动态切换瓦片地图
1
2
3
4
5
6
7
8
9
10
this.picLayer = new ol.layer.Tile({});
this.map = new ol.Map({
target: "map",
layers: [gaodeMapLayer, this.picLayer],
view: new ol.View({
zoom: 14,
minZoom: 10,
maxZoom: 21
})
});
  • 通过setSource动态更换地图切片
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    this.picLayer.setSource(
    new ol.source.TileWMS({
    url: mapUrl + this.currentProject.name + "/wms",
    params: {
    LAYERS: this.currentProject.name, //此处可以是单个图层名称,也可以是图层组名称,或多个图层名称
    TILED: true
    },
    serverType: "geoserver" //服务器类型
    })
    );
只能在切片地图上操作
  • 通过Openlayers中getGetFeatureInfoUrl方法请求WMS服务数据到客户端(Browser)(基于Geoserver服务器)
  • 在WMS图像图层上单击如何触发WMS的GetFeatureInfo请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     var view = this.map.getView();
    var viewResolution = view.getResolution();
    var pixel = this.map.getEventPixel(evt.originalEvent);
    var url = this.picLayer.getSource().getFeatureInfoUrl(
    evt.coordinate,
    viewResolution,
    view.getProjection(),
    { INFO_FORMAT: "application/json", FEATURE_COUNT: 50 }
    );
    if (url) {
    $.ajax({
    url: url,
    type: "get",
    dataType: "json",
    timeout: 6000,
    success: data => {
    console.log(data.features);
    if (data.features.length === 0) {
    this.$message.warning("请将Point打在切片地图上" );
    return;
    }
    for (let i = 0; i < data.features.length; i++) {
    if (data.features[i].geometry.type == "Point") {
    this.nodeSource.getFeatureById(this.currentNodeId).setGeometry(
    new ol.geom.Point(data.features[i].geometry.coordinates)
    );
    let pos = [
    parseFloat(data.features[i].geometry.coordinates[0]),
    parseFloat(data.features[i].geometry.coordinates[1])
    ];
    pos = ol.proj.transform(pos,"EPSG:3857","EPSG:4326");
    this.nodeSource.changed();
    }
    }
    }
    })
    }
    ```
    ##### 自定义控件
    ```bash
    var viewport = map.getViewport();
    $(viewport).append('<div id="share" class="share">分享地图</div>');

    // 监听按钮点击事件,执行相关操作

    document.getElementById('share').onclick = function(){
    alert('分享当前地图给别人!');
    }
    openlayers不同坐标转换
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //****************************坐标点转换为大地坐标系*************************
    translateInMap(center) {
    return ol.proj.fromLonLat(center);
    },
    //****************************坐标点转换为wgs84******************************
    transFormMap(center) {
    let pos = [
    parseFloat(center[0]),
    parseFloat(center[1])
    ];
    return pos = ol.proj.transform(pos, "EPSG:3857", "EPSG:4326");
    },
地图平移动画
1
2
3
4
this.map.getView().animate({
center: this.translateInMap([longitude,latitude]),
duration: 800
});
自动打点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- startPointSerial 起始点号
- autoAddPointSerial 打点数
finishAddPoint() {
if (this.addPointWay === "auto") {
if (this.startPointSerial >= this.pointData.length) {
this.$message.error("起始位置不合法");
return;
} else {
var newLineFeature = new ol.Feature({
geometry: new ol.geom.LineString([
this.pointSource
.getFeatureById(parseInt(this.startPointSerial))
.getGeometry().flatCoordinates,
this.pointSource
.getFeatureById(parseInt(this.startPointSerial) + 1)
.getGeometry().flatCoordinates
])
});
this.linkSource.addFeature(newLineFeature);
let list = [];
for (let i = 0; i < this.autoAddPointSerial; i++) {
let pos = newLineFeature
.getGeometry()
.getCoordinateAt(
(i + 1) / (parseInt(this.autoAddPointSerial) + 1)
);
list.push(this.translatePosition(pos[0], pos[1]));
}
list.unshift(this.startPointSerial, 0);
Array.prototype.splice.apply(this.pointData, list);
this.linkSource.removeFeature(newLineFeature);
}
}
this.updateLanePoints();
this.addPointWay = "";
if (this.linkSource.getFeatureById("newLane")) {
this.linkSource.removeFeature(
this.linkSource.getFeatureById("newLane")
);
}
},

 

posted @ 2021-03-15 09:48  lianggl  阅读(1026)  评论(0)    收藏  举报