前期准备
ol版本7.1.0 node版本16.14.2 npm版本8.5.0
import 'ol/ol.css';
import { Overlay, sphere } from 'ol';
// import { getDistance } from 'ol/sphere';
import Map from 'ol/Map';
import XYZ from 'ol/source/XYZ'
import View from 'ol/View';
import { get, fromLonLat, transform } from 'ol/proj';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import { getTopLeft, getWidth } from 'ol/extent';
import Feature from 'ol/Feature';
import { Fill, Stroke, Icon, Style } from 'ol/style'
import { Polygon, MultiPolygon, LinearRing, Point, Circle } from "ol/geom";//添加图层按钮
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON.js';
import { fromExtent } from "ol/geom/Polygon";
// import OLCesium from 'olcs';
import geoJson from '../../../public/json/hf.json'
import markerImg from '@/assets/img/bg.png'
html准备部分
<div id="contextmenu" class="contextmenu" draggable="true">
<img width="18" height="14" src="@/assets/zzz.png">
</div>
中间的图片是拖动部分的图标
style部分
.contextmenu {
width: 44px;
height: 30px;
text-align: center;
border-radius: 35px;
background: #ddd;
border: 2px solid #aaa;
cursor: pointer;
}
.contextmenu:after {
position: absolute;
background: #ddd;
border: 1px solid #aaa;
left: calc(100% + 5px);
height: 20px;
line-height: 20px;
padding: 2px;
white-space: nowrap;
content: attr(radius);
border-radius: 3px;
}
data准备部分
olLayer: null,//存储olLayer数据
radius: 1000,//范围半径
radiusCenter: [117.283406, 31.860356],//范围中心 4326编码(google编码)
radiusCenterEPSG: [13055929.034420766, 3744994.1081686635],//范围中心 3857编码(openlayers编码)投影坐标
radiusOverlay: null,//范围图层数据
radiusVector: null,//范围图层数据
radiusSource: null,//范围图层数据源数据
radiusDom: null,//范围缩放按钮dom
先初始化地图
// 初始化地图
initMap() {
let that = this;
// 先尝试清除
this.mapClear()
// 获取地图容器
this.mapDom = document.getElementById('map')
// 初始化地图配置
this.map = new Map({
target: this.mapDom, // 地图容器
view: new View({
center: this.mapCenter, // 地图中心点
zoom: 10.5, // 缩放
projection: 'EPSG:3857', // 坐标系 4326编码(google编码)
}),
controls: [] // 不显示任何控件
})
var projection = get('EPSG:3857');
var projectionExtent = projection.getExtent();
var size = getWidth(projectionExtent) / 256;
var resolutions = new Array(19);
var matrixIds = new Array(19);
for (var z = 1; z < 19; ++z) {
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
// //线路图
this.roadmap = new TileLayer({
visible: true,
name: '电子图',
className: 'blueLayer',//增加className属性 样式地图关键
source: new XYZ({
url: "离线地图地址/{z}/{x}/{y}.png",
// crossOrigin: "anonymous", //离线瓦片跨域处理
}),
});
// 将图层添加到地图
this.map.addLayer(this.roadmap)
},
mapClear() {
if (this.mapDom) {
this.mapDom.innerHTML = ''
this.mapDom = null
}
},
初始化范围方法
// 初始化半径的逻辑代码
initRadius() {
//范围图层数据
let that = this
if (this.radiusVector && this.radiusOverlay) {
this.radiusVector.setVisible(true)
this.radiusOverlay.setVisible(true)
// this.radius = 1000
this.radiusDom.style.display = 'block';
this.radiusSource.clear();
this.radiusSource.addFeature(this.getCircleFeature(this.radius));
this.setDomAttr();
// console.log('object :>> ', this.radiusCenterEPSG[0] + this.radius);
this.radiusOverlay.setPosition([this.radiusCenterEPSG[0] + this.radius, this.radiusCenterEPSG[1]]);
} else {
var overlay = new Overlay({
element: document.getElementById("contextmenu"),
positioning: 'center-center',
position: this.getRadiusCoord(),
visible: true
});
this.radiusOverlay = overlay
this.map.addOverlay(overlay);
var source = new VectorSource({
features: []
});
this.radiusSource = source
var vector = new VectorLayer({
source: source,
style: new Style({
fill: new Fill({
color: 'rgba(135,206,250, 0.2)'
}),
stroke: new Stroke({
color: '#87CEFA',
width: 2
})
}),
visible: true
});
this.radiusVector = vector
this.map.addLayer(vector);
source.addFeature(this.getCircleFeature(this.radius));
var dom = document.getElementById("contextmenu");
dom.style.display = 'block';
this.radiusDom = dom
dom.onmousedown = function () {
dom.draggable = true;
dom.ondrag = function (ev) {
that.dragEvent(ev);
};
dom.ondragend = function (ev) {
that.dragEvent(ev);
dom.draggable = false;
//如果需要做筛选,在这里调用方法
};
};
this.setDomAttr()
}
},
hiddenRadius() {
if (this.radiusVector && this.radiusOverlay) {
this.radiusVector.setVisible(false)
this.radiusOverlay.setVisible(false)
// this.radius = 1000
this.radiusDom.style.display = 'none';
}
},
拖动范围框鼠标弹起调用的方法
dragEvent(ev) {
var _pixel = this.map.getPixelFromCoordinate(this.radiusCenterEPSG);
var pixel = [ev.layerX, _pixel[1]];
var coord = this.map.getCoordinateFromPixel(pixel);
this.radiusOverlay.setPosition(coord);
this.radius = this.getRadius(coord);
// let num = this.getRadius(coord);
this.radiusSource.clear();
this.radiusSource.addFeature(this.getCircleFeature(this.radius));
this.setDomAttr();
},
setDomAttr() {
let radiusAbs = Math.abs(this.radius)
var _radius = radiusAbs > 1000 ? (radiusAbs / 1000).toFixed(1) + '千米' : radiusAbs.toFixed(0) + '米';
this.radiusDom.setAttribute("radius", _radius);
},
getRadius(radiusCoord) {
return radiusCoord[0] - this.radiusCenterEPSG[0];
},
getRadiusCoord() {
return [this.radiusCenterEPSG[0] + this.radius, this.radiusCenterEPSG[1]];
},
getCircleFeature(radius) {
var geom = new Circle(this.radiusCenterEPSG, radius);
var feature = new Feature({
geometry: geom
});
return feature;
},
实现效果