效果图
路线:
区域:
整体效果:
代码及思路过程
路线 是将一个个坐标点连接起来组成一个 feature
所以要首先需要一组坐标点的数据,
在有一段数据之后考虑 feature 所需要的内容,
feature需要图层(layer即 ol/layer/Vector ) ,
而图层需要一个源 ( source 即 ol/source/Vector )
这些都一一引入,配置好, 另外就是绘制路线所需要的具体实现的工具了
import { Point, LineString, Polygon } from 'ol/geom'
依次为点 线 和多边形
/**
* 设置线路
*/
addLine () {
const _that = this
_that.routeFeature = new Feature({
type: 'route',
geometry: new LineString(_that.coordinates1)
})
_that.routeFeature.setStyle(new Style({
stroke: new Stroke({
width: 4,
color: [255, 0, 0, 0.5]
}),
text: new Text({
text: '这是线路'
})
}))
// 设置图层
_that.routeLayer = new VectorLayer({
source: new VectorSource({
features: [_that.routeFeature]
})
})
// 添加图层
_that.map.addLayer(_that.routeLayer)
}
这是具体的代码, 流程是
1. 新建一个要素(feature)
2. 要素的内容是一条路(route) 几何特征(geometry)是 LineString
3. 利用LineString 连接 事先准备好的很多坐标点 (coordinates)
4. 新建好要素(feature)之后 为要素添加样式(style)
5. stroke 笔迹/线 设置宽度和颜色以及透明度
6. 文本随意添加设置
7. 将routeLayer 线路图层赋一个openlayers的图层对象 并将要素在构造时放入 也可使用方法另外放入
8. 新建好之后将图层(layer) 加入地图(map)中
区域:
和线路是一样的思路 区别在于Polygon和LineString一个会连接第一和最后一个点, 一个不会.
代码:
addPolygon () {
const _that = this
_that.polygonFeature = new Feature({
type: 'polygon',
geometry: new Polygon([_that.coordinates1])
})
_that.polygonFeature.setStyle(new Style({
stroke: new Stroke({
width: 5,
color: [255, 255, 0, 0.8]
}),
fill: new Fill({
color: [248, 172, 166, 0.6]
}),
text: new Text({
text: '这是区域'
})
}))
_that.polygonLayer = new VectorLayer({
source: new VectorSource({
features: [_that.polygonFeature]
})
})
_that.map.addLayer(_that.polygonLayer)
}
1. 同样的 首先需要创建一个要素(feature) 声明好要素的type之后, 为他新建一个几何对象, new Polygon()
注意: 此处放入坐标点时是在一个数组内放置, 具体可以去翻阅一下文档
2. 设置多边形的 边框颜色 和 填充颜色 以及 文本
3. 将多边形(polygon) 放置进多边形图层(polygonLayer) 同时将要素(feature)也放入
4. 最后将多边形图层加入地图即可
全部代码 vue + element + openlayers
<template>
<section style="display: flex">
<section style="height: 600px; width: 1200px;border: 1px red solid; margin: 10px 10px 10px 50px;">
<section id="Map" style="width: 100%; height: 100%;"></section>
</section>
<section style="height: 600px; width: 300px;border: 1px gray solid; margin: 10px">
<section>
<el-button class="items" type="text">X:{{x}}</el-button>
<el-button class="items" type="text">Y:{{y}}</el-button>
<el-button class="items" @click="addLine" type="primary">显示线路</el-button>
<el-button class="items" @click="addPolygon" type="primary">显示区域</el-button>
</section>
<section>
</section>
</section>
</section>
</template>
<script>
import 'ol/ol.css'
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import XYZ from 'ol/source/XYZ'
import { Map, View, Feature } from 'ol'
import { Style, Icon, Stroke } from 'ol/style'
import Text from 'ol/style/Text'
import Fill from 'ol/style/Fill'
import { Point, LineString, Polygon } from 'ol/geom'
import {defaults} from 'ol/control/util.js'
export default {
name: 'map6',
data () {
return {
map: null,
x: 0,
y: 0,
coordinates: [
{
x: 112.87197876066057,
y: 28.22084712811648
},
{
x: 112.8720016491825,
y: 28.225383281160706
},
{
x: 112.87314605792562,
y: 28.228450298111515
},
{
x: 112.87527465926178,
y: 28.23101377452122
},
{
x: 112.87994384801641,
y: 28.232203960351857
},
{
x: 112.88353729301525,
y: 28.23128843224413
},
{
x: 112.8825531017319,
y: 28.225932597479645
}
],
coordinates1: [[112.87197876066057, 28.22084712811648], [112.8720016491825, 28.225383281160706], [112.87314605792562, 28.228450298111515],
[112.87527465926178, 28.23101377452122], [112.87994384801641, 28.232203960351857], [112.88353729301525, 28.23128843224413], [112.8825531017319, 28.225932597479645]],
features: [],
flagLayer: null,
routeLayer: null,
routeFeature: null,
polygonLayer: null,
polygonFeature: null
}
},
computed: {
},
methods: {
/**
* 初始化地图
*/
initMap () {
this.map = new Map({
target: 'Map',
controls: defaults({zoom: false}),
layers: [
new TileLayer({
source: new XYZ({
url: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'
})
})
],
view: new View({
// 指定地图投影模式
projection: 'EPSG:4326',
// 定义地图显示的坐标
center: [112.87, 28.23],
// 限制地图中心范围,但无法限制缩小范围
// extent: [110, 26, 114, 30],
// 定义地图显示层级为16
zoom: 13,
// 限制缩放级别,可以和extent同用限制范围
maxZoom: 19,
// 最小级别,越大则面积越大
minZoom: 5
})
})
},
/**
* 变换XY坐标
* @param e
*/
changeXY (e) {
const _that = this
_that.x = e.coordinate[0]
_that.y = e.coordinate[1]
console.log(_that.x, _that.y)
},
/**
* 批量添加坐标点
*/
handleAddBatchFeature () {
const _that = this
// 设置图层
_that.flagLayer = new VectorLayer({
source: new VectorSource()
})
// 添加图层
_that.map.addLayer(_that.flagLayer)
// 循环添加feature
for (let i = 0; i < this.coordinates.length; i++) {
// 创建feature
let feature = new Feature({
geometry: new Point([_that.coordinates[i].x, _that.coordinates[i].y])
})
// 设置ID
feature.setId(i)
// 设置样式
feature.setStyle(_that.getStyls(feature))
// 放入features
_that.features.push(feature)
} // for 结束
// 批量添加feature
_that.flagLayer.getSource().addFeatures(_that.features)
},
/**
* 设置Style
*/
getStyls (feature) {
let Styles = []
// 绘制圆角矩形
let canvas = document.createElement('canvas')
let context = canvas.getContext('2d')
let length = (feature.id_ + '标记点').length + 2
canvas.width = length * 15
canvas.height = 35
let x = 0
let y = 0
let w = canvas.width
let h = canvas.height
let r = 15
// 缩放
context.scale(0.8, 0.8)
context.fillStyle = 'rgba(255,255,255,1)'
// 绘制圆角矩形
context.beginPath()
context.moveTo(x + r, y)
context.arcTo(x + w, y, x + w, y + h, r)
context.arcTo(x + w, y + h, x, y + h, r)
context.arcTo(x, y + h, x, y, r)
context.arcTo(x, y, x + w, y, r)
// 设置阴影
context.shadowColor = 'rgba(0, 0, 0, 0.2)' // 颜色
context.shadowBlur = 5 // 模糊尺寸
context.shadowOffsetX = 2 // 阴影Y轴偏移
context.shadowOffsetY = 2 // 阴影X轴偏移
// ----
context.closePath()
// 填充
context.fill()
// 设置style
Styles.push(
new Style({
image: new Icon({
img: canvas,
imgSize: [w, h],
anchor: [0, 1]
}),
text: new Text({
textAlign: 'center',
text: '标记点' + feature.id_,
offsetX: 35,
offsetY: -18
}),
zIndex: feature.id_
})
)
Styles.push(
new Style({
image: new Icon({
src: 'http://weilin.me/ol3-primer/img/anchor.png',
anchor: [0.5, 1]
}),
zIndex: feature.id_
})
)
return Styles
},
/**
* 设置线路
*/
addLine () {
const _that = this
_that.routeFeature = new Feature({
type: 'route',
geometry: new LineString(_that.coordinates1)
})
_that.routeFeature.setStyle(new Style({
stroke: new Stroke({
width: 4,
color: [255, 0, 0, 0.5]
}),
text: new Text({
text: '这是线路'
})
}))
// 设置图层
_that.routeLayer = new VectorLayer({
source: new VectorSource({
features: [_that.routeFeature]
})
})
// 添加图层
_that.map.addLayer(_that.routeLayer)
},
addPolygon () {
const _that = this
_that.polygonFeature = new Feature({
type: 'polygon',
geometry: new Polygon([_that.coordinates1])
})
_that.polygonFeature.setStyle(new Style({
stroke: new Stroke({
width: 5,
color: [255, 255, 0, 0.8]
}),
fill: new Fill({
color: [248, 172, 166, 0.6]
}),
text: new Text({
text: '这是区域'
})
}))
_that.polygonLayer = new VectorLayer({
source: new VectorSource({
features: [_that.polygonFeature]
})
})
_that.map.addLayer(_that.polygonLayer)
}
},
mounted () {
this.initMap()
this.handleAddBatchFeature()
this.map.on('singleclick', this.changeXY)
},
created () {
}
}
</script>
<style scoped>
.items{
display: block;
margin: 10px auto;
}
</style>