1.定位,移动图标,清空图标,地图级别
openlayers官网: openlayers.org/en/latest/d…
npm init 初始化 再安装 npm i ol // "ol": "^6.5.0"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{margin: 0;padding: 0;}
#map{
width: 100vw;
height: 100vh;
}
#icon1{
cursor: pointer;
}
@keyframes zoom{
from {top: 0; left: 0; width: 32px; height: 32px;}
50% {top: -16px; left: -16px; width: 64px; height: 64px;}
to {top: 0; left: 0; width: 32px; height: 32px;}
}
@-moz-keyframes zoom{ /* Firefox */
from {top: 0; left: 0; width: 32px; height: 32px;}
50% {top: -16px; left: -16px; width: 64px; height: 64px;}
to {top: 0; left: 0; width: 32px; height: 32px;}
}
@-webkit-keyframes zoom{ /* Safari 和 Chrome */
from {top: 0; left: 0; width: 32px; height: 32px;}
50% {top: -16px; left: -16px; width: 64px; height: 64px;}
to {top: 0; left: 0; width: 32px; height: 32px;}
}
@-o-keyframes zoom{ /* Opera */
from {top: 0; left: 0; width: 32px; height: 32px;}
50% {top: -16px; left: -16px; width: 64px; height: 64px;}
to {top: 0; left: 0; width: 32px; height: 32px;}
}
/* 应用css动画到图标元素上 */
#iconImg1{
display: block;
position: absolute;
animation: zoom 5s;
animation-iteration-count: infinite; /* 一直重复动画 */
-moz-animation: zoom 5s; /* Firefox */
-moz-animation-iteration-count: infinite; /* 一直重复动画 */
-webkit-animation: zoom 5s; /* Safari 和 Chrome */
-webkit-animation-iteration-count: infinite; /* 一直重复动画 */
-o-animation: zoom 5s; /* Opera */
-o-animation-iteration-count: infinite; /* 一直重复动画 */
}
#iconImg2{
display: block;
position: absolute;
animation: zoom 5s;
animation-iteration-count: infinite; /* 一直重复动画 */
-moz-animation: zoom 5s; /* Firefox */
-moz-animation-iteration-count: infinite; /* 一直重复动画 */
-webkit-animation: zoom 5s; /* Safari 和 Chrome */
-webkit-animation-iteration-count: infinite; /* 一直重复动画 */
-o-animation: zoom 5s; /* Opera */
-o-animation-iteration-count: infinite; /* 一直重复动画 */
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div class="control">
<button @click="location(118.09853733, 24.47033414, 18)">定位到厦门市计量检定测试院</button>
<button @click="clearMarker">清空图标</button>
<button @click="renderArea">根据经纬度画出区域</button>
<button @click="showText">文字显示</button>
<button @click="addIcon(118.09853733, 24.47233414, 1)">添加外部图标1</button>
<button @click="addIcon(118.09980333, 24.47337838, 2)">添加外部图标2</button>
<button @click="moverIcon(0.0001, 0.00002)">移动外部图标1</button>
<button @click="moverIcon(0.001, 0.0002)">移动外部图标2</button>
<button @click="addSvg">添加svg图片</button>
<div id="myposition"></div>
</div>
<div id="map"></div>
<div id="icon1">
<img id="iconImg1" src="http://linwei.xyz/ol3-primer/img/anchor.png" alt="示例锚点">
</div>
<div id="icon2">
<img id="iconImg2" src="http://linwei.xyz/ol3-primer/img/anchor.png" alt="示例锚点">
</div>
</div>
</body>
<script src="./index.js"></script>
</html>
index.js
import 'ol/ol.css'
import { Map, View, Feature, Overlay } from 'ol'
import {FullScreen, defaults as defaultControls, MousePosition} from 'ol/control'
// import MultiPoint from 'ol/geom/MultiPoint'
import { Point, MultiPoint, Polygon } from 'ol/geom'
import { transform, fromLonLat } from 'ol/proj.js'
import GeoJSON from 'ol/format/GeoJSON'
import { Circle as CircleStyle, Fill, Stroke, Style, Icon, Text } from 'ol/style'
// import OSM from 'ol/source/OSM'
// import XYZ from 'ol/source/XYZ'
import { OSM, XYZ, Vector as VectorSource } from 'ol/source'
// import TileLayer from 'ol/layer/Tile'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
const app = new Vue({
el: '#app',
data: {
normalMap: null,
map: null,
vectorLayer: null,
vectorSource: null,
timer: null,
shoIcon: false,
shoIcon2: false,
icon1: null,
icon2: null,
lng: 118.098537,
lat: 24.47233414,
},
mounted() {
this.mapInit()
this.mousePosition()
this.draw()
// this.renderArea()
this.watchMap()
},
methods: {
mapInit() {
this.normalMap = new TileLayer({ // 标准地图,类似再找卫星地图链接
visible: true, // 显示地图
source: new XYZ({
attributions: '我是右边最下面 i 点我下展开,默认空',
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
// url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7'
// url: 'http://webst0{1-4}.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}'
// url: 'https://mt0.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}'
})
})
// const offlineMapLayer = new TileLayer({ // 离线加载瓦片地图
// visible: false,
// source: new XYZ({
// url: '.../{z}/{x}/{y}.png' // z表示的是层级,如果瓦片地图都放在一个目录下,那么url参数就得写成: {z}-{x}-{y}.png
// })
// })
// this.map.addLayer(offlineMapLayer)
this.map = new Map({
target: 'map',
layers: [this.normalMap],
// projection: 'EPSG:3857', // 投影
view: new View({
// extent: [102, 29, 104, 31],
center: transform([118.09853733, 24.47033414], 'EPSG:4326', 'EPSG:3857'),
zoom: 16,
maxZoom: 18,
minZoom: 6
})
})
this.vectorSource = new VectorSource({})
this.marker(118.09853733, 24.47033414, 12)
this.marker(118.09893733, 24.47333414, 22)
this.timer = setInterval(this.translate, 500, 12)
},
location (lng, lat, size) { // 定位指定位置
let view = this.map.getView()
view.setCenter(transform([lng, lat], 'EPSG:4326', 'EPSG:3857')) // 设置中心点
view.setZoom(size) // 地图放大级别
// console.log(view.getCenter()) // 获取中心点坐标
},
marker (lng, lat, id, img) { // 标记点(经纬度和id)
if (!lng || !lat) return false
let iconFeature = new Feature({ // 创建图标特性
id, // 用来区分多个点
geometry: new Point(transform([lng, lat], 'EPSG:4326', 'EPSG:3857'))
})
this.vectorSource.addFeature(iconFeature)
this.vectorLayer = new VectorLayer({ // 创建矢量层
source: this.vectorSource,
fill: new Fill({ // 自定义个标记点
color: 'rgba(255, 0, 0, 1)'
}),
stroke: new Stroke({
color: 'red',
width: 1
}),
style: new Style({ // 使用图片
image: new Icon({
opacity: 1,
src: 'https://www.amap.com/assets/img/pos_marker.png',
anchor: [0, 0] // 设置图标位置
}),
text: new Text({
font: '12px sans-serif', // 默认这个字体,可以修改成其他的,格式和css的字体设置一样
text: '无人机1号',
offsetX: 40, // 文字位置(x偏移量)
offsetY: 0, // 文字位置(y偏移量)
fill: new Fill({
color: 'red',
})
})
})
})
this.map.addLayer(this.vectorLayer) // 添加进map
},
translate(id) {
this.vectorSource.forEachFeature(f => {
// console.log(f.values_.id) // 用来区分不同的图标id
if (id === f.values_.id) {
const x = Math.random() * 5
const y = Math.random() * 3
f.getGeometry().translate(x, y)
}
})
},
clearMarker() {
clearInterval(this.timer)
this.vectorSource.clear() // 清空标记
},
mousePosition() { // 鼠标在地图上显示经纬度
const mousePositionControl = new MousePosition({
className: 'mosuePosition',
projection: 'EPSG:4326',
target: document.getElementById('myposition')
})
this.map.addControl(mousePositionControl)
},
drawArea() { // 根据多个经纬度点画出区域
const styles = [
new Style({
stroke: new Stroke({
color: 'blue',
width: 3
}),
fill: new Fill({
color: 'red'
})
}),
new Style({
image: new CircleStyle({
radius: 5,
fill: new Fill({
color: 'orange'
})
}),
geometry: function(feature) {
const coordinates = feature.getGeometry().getCoordinates()[0]
return new MultiPoint(coordinates)
}
})
]
const geojsonObject = {
'type': 'FeatureCollection',
'crs': {
'type': 'name',
'properties': {
'name': 'EPSG:3857',
},
},
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[[118.0959624, 24.4715889], [118.096413, 24.4703976], [118.10038268, 24.4715889], [118.09924543, 24.4733466]]
]
}
}
]
}
const source = new VectorSource({
features: new GeoJSON().readFeatures(geojsonObject)
})
const layer = new VectorLayer({
source: source,
style: styleFunction,
})
const styleFunction = feature => {
return styles[feature.getGeometry().getType()]
}
console.log(styleFunction)
feature = new Feature({
geometry: new Polygon(coordinatesPolygona)
})
},
draw() {
let coordinatesPolygon = []
const coordinates = [
[[118.0959624, 24.4715889], [118.096413, 24.4703976], [118.10038268, 24.4715889], [118.09924543, 24.4733466]]
]
// for (let i = 0; i < coordinates.length; i++) {
// let pointTransform = fromLonLat([coordinates[i][0], coordinates[i][1]], 'EPSG:3857')
// coordinatesPolygon.push(pointTransform)
// }
let polygon = new Polygon([coordinates])
let feature = new Feature({
geometry: polygon
})
let source = new VectorSource()
source.addFeature(feature)
let vector = new VectorLayer({
source: source,
style: new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.1)'
}),
stroke: new Stroke({
color: 'red',
width: 2
}),
// image: new Circle({
// radius: 10,
// fill: new Fill({
// color: '#ffcc33'
// })
// })
})
})
// 将经纬度坐标转换为map对应的坐标
// let geom = new Polygon(coord)
// geom = geom.transform('EPSG:4326', map.getView().getProjection())
},
renderArea() {
const data = [[118.0959624, 24.4715889], [118.096413, 24.4703976], [118.10038268, 24.4715889], [118.09924543, 24.4733466]]
// 创建要素
const features = [
new Feature({
geometry: new Polygon([data])// 使用多边形类型
})
]
// 创建矢量数据源
const source = new VectorSource({
features
})
// 创建样式
const style = new Style({
stroke: new Stroke({
color: '#4C99F8',
width: 3,
lineDash: [5]
}),
fill: new Fill({
color: 'rgba(255,255,255,0.1)'
})
})
// 创建矢量图层
const areaLayer = new VectorLayer({
source,
style,
zIndex: 1
})
areaLayer.on('postrender', evt => { // 添加阴影
evt.context.shadowBlur = 0
evt.context.shadowColor = 'rgba(0, 0, 0, 0.20)'
})
this.map.addLayer(areaLayer) // 添加到地图实例
},
showText() { // 显示文字
let layer = new VectorLayer({
source: new VectorSource()
})
let anchor = new Feature({
geometry: new Point(transform([118.0959624, 24.4715889], 'EPSG:4326', 'EPSG:3857'))
})
anchor.setStyle(new Style({
text: new Text({
font: '12px sans-serif', // 默认这个字体,可以修改成其他的,格式和css的字体设置一样
text: '最帅的那个男人在这里',
fill: new Fill({
color: 'red',
})
})
}))
layer.getSource().addFeature(anchor)
this.map.addLayer(layer)
},
addGeoJSON() { // 加载矢量地图
const data = [] // 矢量地图数据
let layer = new VectorLayer({
source: new VectorSource({
features: (new GeoJSON()).readFeatures(data, { // 用readFeatures方法可以自定义坐标系
dataProjection: 'EPSG:4326', // 设定JSON数据使用的坐标系
featureProjection: 'EPSG:3857' // 设定当前地图使用的feature的坐标系
})
})
})
},
addIcon(lng, lat, id) { // 外部添加图标到地图上
let icon = 'icon' + id
icon = new Overlay({
element: document.getElementById(icon)
})
icon.setPosition(transform([lng, lat], 'EPSG:4326', 'EPSG:3857'))
this.map.addOverlay(icon)
this.location(lng, lat, 18)
},
moverIcon(x, y) {
this.icon1.setPosition(transform([this.lng + x, this.lat + y], 'EPSG:4326', 'EPSG:3857'))
},
addSvg() { // 添加svg图片
let lng = 118.09853733
let lat = 24.47033414
let anchor = new Feature({
geometry: new Point(transform([lng, lat], 'EPSG:4326', 'EPSG:3857'))
})
const svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">'+
'<path fill="#156BB1" d="M22.906,10.438c0,4.367-6.281,14.312-7.906,17.031c-1.719-2.75-7.906-12.665-7.906-17.031S10.634,2.531,15,2.531S22.906,6.071,22.906,10.438z"/>'+
'<circle fill="#FFFFFF" cx="15" cy="10.677" r="3.291"/></svg>'
let mysvg = new Image()
mysvg.src = 'data:image/svg+xml,' + escape(svg)
anchor.setStyle(new Style({
image: new Icon({
img: mysvg, // 设置Image对象
imgSize: [30, 30] // 及图标大小
// src: 'http://www.williambuck.com/portals/0/Skins/WilliamBuck2014/images/location-icon.svg',
// size: [30, 30]
})
}))
let layer = new VectorLayer({
source: new VectorSource()
})
layer.getSource().addFeature(anchor)
this.map.addLayer(layer)
},
watchMap() { // 监听地图事件
this.map.getView().on('change:resolution', () => { // 监听地图缩放
})
let click = this.map.on('singleclick', evt => { // 监听单击地图
let coordinate = evt.coordinate
console.log(evt)
})
},
test() {
// 长时间不操作
let minute = 2
setInterval(() => {
minute--
if (minute <= 0) {
console.log(1)
}
}, 1000 * 6)
addEventListener('mousemove', () => minute = 2)
}
}
})