一、问题描述
在使用OpenLayer draw 绘制图形,使用双击事件结束绘制时,地图会放大。
1675066448279.png
二、直接解决办法
在创建map 时,直接禁止,但是会造成整个图层不能使用双击放大地图
import { defaults as defaultInteractions } from 'ol/interaction.js'
let map = new ol.Map({
target: id,
layers: options.mapLayers,
view: view,
controls: defaultControls({
zoom: false,
rotate: false,
attribution: false
}),
interactions: defaultInteractions({ doubleClickZoom: false })
})
三、使用动态函数,在需要的地方禁止掉
自定义绘制类,在绘制类里面禁止掉
import { Draw, Modify, DoubleClickZoom } from 'ol/interaction.js'
let doubleClickZoom = new DoubleClickZoom()
let doubleClickZoomArr = this.map.getInteractions().array_.filter(
item => {
return item.constructor.name === doubleClickZoom.constructor.name
}
)
this.map.removeInteraction(doubleClickZoomArr[0])
四、自定义绘制类
import * as ol from '../openLayer'
// import Draw from 'ol/interaction/Draw.js'
import { Draw, Modify, DoubleClickZoom } from 'ol/interaction.js'
import { getArea, getLength } from 'ol/sphere.js'
import { LineString, Point } from 'ol/geom.js'
import { drawDefaultConfig } from './config'
import { drawingLineStyle, drawEndLineStyle, pointTipStyle, setLabelStyle, setTipStyle, modifyStyle } from './style'
import { deepAssign } from '@/utils'
/**
* 绘制图形shap 类,
* 配置项参考config.js
* 样式项参考style.js
*/
export default class OlDrawShap {
constructor (_map, _config) {
this.map = _map
this.options = deepAssign(drawDefaultConfig, _config) // 配置项
this.draw = null
this.source = new ol.VectorSource()
let doubleClickZoom = new DoubleClickZoom()
let doubleClickZoomArr = this.map.getInteractions().array_.filter(
item => {
return item.constructor.name === doubleClickZoom.constructor.name
}
)
this.map.removeInteraction(doubleClickZoomArr[0])
const drawLayer = new ol.VectorLayer({
source: this.source,
className: 'DrawShapLayer',
properties: this.options.layerProperties,
style: (feature) => {
return this.getDrawStyle(feature, this.options.shapConfig.type, true)
}
})
this.map.addLayer(drawLayer)
this.mouseTipModify = new Modify({ source: this.source, style: this.modifyStyle })
this.mouseTip = this.options.mouseTipConfig.tipText
this.onDrawShap()
}
onDrawShap () {
let shapTypes = ['MultiLineString', 'MultiPolygon']
// console.log('this.options.shapConfig.type', this.options.shapConfig.type)
if (shapTypes.indexOf(this.options.shapConfig.type) > -1) {
this.handleDraw()
} else {
// console.log('类型错误')
alert('类型错误')
}
}
/**
* 更新配置
*/
updateOlDrawShap (_map, _config) {
// console.log('更新配置', this.source, this.draw)
this.options = deepAssign(drawDefaultConfig, _config) // 配置项
this.onDrawShap()
}
/**
* 获取线段长度
* @param {*} line
* @returns
*/
formatLength (line) {
const length = getLength(line)
let output
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + ' km'
} else {
output = Math.round(length * 100) / 100 + ' m'
}
return output
};
/**
* 计算区域面积
* @param {*} polygon
* @returns
*/
formatArea (polygon) {
const area = getArea(polygon)
// console.log('area', area)
let output
if (area > 10000) {
output = Math.round((area / 1000000) * 100) / 100 + ' km\xB2'
} else {
output = Math.round(area * 100000) / 100000 + ' m\xB2'
}
// console.log('output=', output)
return output
};
/**
* 获取当前绘制样式
*/
getDrawStyle (feature, drawType = 'MultiPolygon', drawEndBool = false, tip) {
let styles
if (drawEndBool) {
styles = [drawEndLineStyle(this.options)]
} else {
styles = [drawingLineStyle(this.options)]
}
const geometry = feature.getGeometry()
const type = geometry.getType()
let point, label, line, lines
if (drawEndBool) {
console.log('type', type, geometry)
}
//
if (this.options.labelConfig.show) { // 显示点位提示
if ((type === 'Polygon' || type === 'MultiPolygon')) { // 多边形求面积
if (type === 'Polygon') {
point = geometry.getInteriorPoint()
} else if (type === 'MultiPolygon') {
point = geometry.getInteriorPoints()
}
// console.log('point', point)
line = new LineString(geometry.getCoordinates()[0])
label = this.formatArea(geometry)
} else if (type === 'LineString' || type === 'MultiLineString') {
point = new Point(geometry.getLastCoordinate())
label = this.formatLength(geometry)
line = geometry
}
if (line) {
let count = 0
const pointTipStyles = [pointTipStyle(this.options, drawEndBool)]
if (type === 'MultiLineString') {
lines = geometry.getLineStrings()
for (let i in lines) {
// console.log('i=', i)
lines[i].forEachSegment((a, b) => {
const segment = new LineString([a, b])
const label = this.formatLength(segment)
if (pointTipStyles.length - 1 < count) {
pointTipStyles.push(pointTipStyle(this.options, drawEndBool).clone())
}
const segmentPoint = new Point(segment.getCoordinateAt(0.5))
pointTipStyles[count].setGeometry(segmentPoint)
pointTipStyles[count].getText().setText(label)
styles.push(pointTipStyles[count])
count++
})
}
if (drawEndBool) {
console.log('point=', point, 'lines=', lines)
}
} else {
line.forEachSegment((a, b) => {
const segment = new LineString([a, b])
const label = this.formatLength(segment)
if (pointTipStyles.length - 1 < count) {
pointTipStyles.push(pointTipStyle(this.options, drawEndBool).clone())
}
const segmentPoint = new Point(segment.getCoordinateAt(0.5))
pointTipStyles[count].setGeometry(segmentPoint)
pointTipStyles[count].getText().setText(label)
styles.push(pointTipStyles[count])
count++
})
}
}
// console.log('line=', line)
if (label) {
const labelStyle = setLabelStyle(this.options, drawEndBool)
// console.log('labelStyle', labelStyle)
labelStyle.setGeometry(point)
labelStyle.getText().setText(label)
styles.push(labelStyle)
}
if (this.options.mouseTipConfig.show) {
let tipPoint
const tipStyle = setTipStyle(this.options)
if (tip && type === 'Point' && !this.mouseTipModify.getOverlay().getSource().getFeatures().length) {
tipPoint = geometry
tipStyle.getText().setText(tip)
styles.push(tipStyle)
}
}
}
// console.log(styles)
return styles
}
/**
* 绘制
*/
handleDraw () {
if (!this.draw) {
this.draw = new Draw({
source: this.source,
type: this.options.shapConfig.type,
geometryName: this.options.layerProperties.id,
style: (feature) => {
// console.log('样式', this.getDrawStyle(feature, 'LineString', '测试'))
return this.getDrawStyle(feature, this.options.shapConfig.type, false, this.mouseTip)
}
})
this.draw.setActive(true)
this.draw.on('drawstart', () => {
if (!this.options.shapConfig.isMultipleBool && this.source) {
this.source.clear()
}
this.mouseTipModify.setActive(false)
this.mouseTip = this.options.mouseTipConfig.drawTipText
})
this.draw.on('drawend', (e) => {
this.mouseTip = this.options.mouseTipConfig.tipText
if (this.draw && !this.options.shapConfig.isMultipleBool) {
this.draw.finishDrawing()
e.stopPropagation()
e.preventDefault()
this.map.removeInteraction(this.draw)
this.draw.setActive(false)
this.draw = null
}
})
this.mouseTipModify.setActive(true)
this.map.addInteraction(this.draw)
}
}
}
四、默认配置
/**
* 默认图形配置
*/
export const drawDefaultConfig = {
type: 'DrawShapLayer',
layerProperties: {
id: 'DrawShapLayer',
name: 'DrawShapLayer',
geometryName: 'DrawShapLayer'
},
shapConfig: {
type: 'MultiPolygon',
isMultipleBool: false // 不允许多个存在 false-> 不允许,true -> 允许
},
labelConfig: {
show: false,
labelStyle: {
drawingStyle: {
textStyle: {
font: '14px Calibri,sans-serif',
fillColor: '#fff',
backgroundFillColor: 'rgba(0, 0, 0, 0.7)',
padding: [3, 3, 3, 3],
textBaseline: 'bottom',
offsetY: -15
},
imageStyle: {
radius: 8,
points: 3,
angle: Math.PI,
displacement: [0, 10],
fillColor: 'rgba(0, 0, 0, 0.7)'
}
},
drawEndStyle: {
textStyle: {
font: '14px Calibri,sans-serif',
fillColor: '#606266',
backgroundFillColor: 'rgba(255, 204, 51, 1)',
padding: [3, 3, 3, 3],
textBaseline: 'bottom',
offsetY: -15
},
imageStyle: {
radius: 8,
points: 3,
angle: Math.PI,
displacement: [0, 10],
fillColor: 'rgba(255, 204, 51, 1)'
}
}
},
pointTipStyle: { // 坐标点样式
drawingStyle: {
textStyle: {
font: '12px Calibri,sans-serif',
fillColor: '#fff',
backgroundFillColor: 'rgba(0, 0, 0, 0.4)',
padding: [2, 2, 2, 2],
textBaseline: 'bottom',
offsetY: -15
},
imageStyle: {
radius: 6,
points: 3,
angle: Math.PI,
displacement: [0, 8],
fillColor: 'rgba(0, 0, 0, 0.4)'
}
},
drawEndStyle: {
textStyle: {
font: '12px Calibri,sans-serif',
fillColor: '#606266',
backgroundFillColor: 'rgba(255, 204, 51,0.9)',
padding: [2, 2, 2, 2],
textBaseline: 'bottom',
offsetY: -13
},
imageStyle: {
radius: 6,
points: 3,
angle: Math.PI,
displacement: [0, 8],
fillColor: 'rgba(255, 204, 51,0.9)'
}
}
}
},
paintBrushConfig: { // 画笔样式设置
radius: 5,
strokeColor: 'rgba(0, 0, 0, 0.7)',
fillColor: 'rgba(255, 255, 255, 0.2)'
},
lineConfig: { // 线条样式设置
drawingStyle: { // 绘制中样式设置
fillColor: 'rgba(255, 255, 255, 0.2)',
strokeColor: 'rgba(0, 0, 0, 0.5)',
strokeLineDash: [10, 10],
strokeWidth: 2
},
drawEndStyle: { // 绘制完成样式设置
fillColor: 'rgba(255, 255, 255, 0.2)',
strokeColor: '#ffcc33',
strokeLineDash: [0, 0],
strokeWidth: 2
}
},
mouseTipConfig: {
show: true,
tipText: '点击开始绘制',
drawTipText: '继续点击绘制线条,双击结束绘制',
textStyle: {
font: '12px Calibri,sans-serif',
fillColor: 'rgba(255, 255, 255, 1)',
backgroundFillColor: 'rgba(0, 0, 0, 0.4)',
padding: [2, 2, 2, 2],
textAlign: 'left',
offsetX: 15
}
}
}
样式设置
import * as ol from '../openLayer'
/**
* 绘制时线条、画笔 的样式
*/
export const drawingLineStyle = (options) => {
return new ol.Style({ // 线条
fill: new ol.Fill({
color: options.lineConfig.drawingStyle.fillColor
}),
stroke: new ol.Stroke({
color: options.lineConfig.drawingStyle.strokeColor,
lineDash: options.lineConfig.drawingStyle.strokeLineDash,
width: options.lineConfig.drawingStyle.strokeWidth
}),
image: new ol.CircleStyle({ // 画笔
radius: options.paintBrushConfig.radius,
stroke: new ol.Stroke({
color: options.paintBrushConfig.strokeColor
}),
fill: new ol.Fill({
color: options.paintBrushConfig.fillColor
})
})
})
}
/**
* 绘制结束时线条、画笔 的样式
*/
export const drawEndLineStyle = (options) => {
return new ol.Style({ // 线条
fill: new ol.Fill({
color: options.lineConfig.drawEndStyle.fillColor
}),
stroke: new ol.Stroke({
color: options.lineConfig.drawEndStyle.strokeColor,
lineDash: options.lineConfig.drawEndStyle.strokeLineDash,
width: options.lineConfig.drawEndStyle.strokeWidth
}),
image: new ol.CircleStyle({ // 画笔
radius: options.paintBrushConfig.radius,
stroke: new ol.Stroke({
color: options.paintBrushConfig.strokeColor
}),
fill: new ol.Fill({
color: options.paintBrushConfig.fillColor
})
})
})
}
/**
* 坐标点提示样式
* @returns
*/
export const pointTipStyle = (options, bool = false) => {
if (bool) {
return new ol.Style({
text: new ol.Text({
font: options.labelConfig.pointTipStyle.drawEndStyle.textStyle.font,
fill: new ol.Fill({
color: options.labelConfig.pointTipStyle.drawEndStyle.textStyle.fillColor
}),
backgroundFill: new ol.Fill({
color: options.labelConfig.pointTipStyle.drawEndStyle.textStyle.backgroundFillColor
}),
padding: options.labelConfig.pointTipStyle.drawEndStyle.textStyle.padding,
textBaseline: options.labelConfig.pointTipStyle.drawEndStyle.textStyle.textBaseline,
offsetY: options.labelConfig.pointTipStyle.drawEndStyle.textStyle.offsetY
}),
image: new ol.RegularShape({
radius: options.labelConfig.pointTipStyle.drawEndStyle.imageStyle.radius,
points: options.labelConfig.pointTipStyle.drawEndStyle.imageStyle.points,
angle: options.labelConfig.pointTipStyle.drawEndStyle.imageStyle.angle,
displacement: options.labelConfig.pointTipStyle.drawEndStyle.imageStyle.displacement,
fill: new ol.Fill({
color: options.labelConfig.pointTipStyle.drawEndStyle.imageStyle.fillColor
})
})
})
} else {
return new ol.Style({
text: new ol.Text({
font: options.labelConfig.pointTipStyle.drawingStyle.textStyle.font,
fill: new ol.Fill({
color: options.labelConfig.pointTipStyle.drawingStyle.textStyle.fillColor
}),
backgroundFill: new ol.Fill({
color: options.labelConfig.pointTipStyle.drawingStyle.textStyle.backgroundFillColor
}),
padding: options.labelConfig.pointTipStyle.drawingStyle.textStyle.padding,
textBaseline: options.labelConfig.pointTipStyle.drawingStyle.textStyle.textBaseline,
offsetY: options.labelConfig.pointTipStyle.drawingStyle.textStyle.offsetY
}),
image: new ol.RegularShape({
radius: options.labelConfig.pointTipStyle.drawingStyle.imageStyle.radius,
points: options.labelConfig.pointTipStyle.drawingStyle.imageStyle.points,
angle: options.labelConfig.pointTipStyle.drawingStyle.imageStyle.angle,
displacement: options.labelConfig.pointTipStyle.drawingStyle.imageStyle.displacement,
fill: new ol.Fill({
color: options.labelConfig.pointTipStyle.drawingStyle.imageStyle.fillColor
})
})
})
}
}
/**
* 终点坐标点提示样式
* @returns
*/
export const setLabelStyle = (options, bool = false) => {
if (bool) {
return new ol.Style({
text: new ol.Text({
font: options.labelConfig.labelStyle.drawEndStyle.textStyle.font,
fill: new ol.Fill({
color: options.labelConfig.labelStyle.drawEndStyle.textStyle.fillColor
}),
backgroundFill: new ol.Fill({
color: options.labelConfig.labelStyle.drawEndStyle.textStyle.backgroundFillColor
}),
padding: options.labelConfig.labelStyle.drawEndStyle.textStyle.padding,
textBaseline: options.labelConfig.labelStyle.drawEndStyle.textStyle.textBaseline,
offsetY: options.labelConfig.labelStyle.drawEndStyle.textStyle.offsetY
}),
image: new ol.RegularShape({
radius: options.labelConfig.labelStyle.drawEndStyle.imageStyle.radius,
points: options.labelConfig.labelStyle.drawEndStyle.imageStyle.points,
angle: options.labelConfig.labelStyle.drawEndStyle.imageStyle.angle,
displacement: options.labelConfig.labelStyle.drawEndStyle.imageStyle.displacement,
fill: new ol.Fill({
color: options.labelConfig.labelStyle.drawEndStyle.imageStyle.fillColor
})
})
})
} else {
return new ol.Style({
text: new ol.Text({
font: options.labelConfig.labelStyle.drawingStyle.textStyle.font,
fill: new ol.Fill({
color: options.labelConfig.labelStyle.drawingStyle.textStyle.fillColor
}),
backgroundFill: new ol.Fill({
color: options.labelConfig.labelStyle.drawingStyle.textStyle.backgroundFillColor
}),
padding: options.labelConfig.labelStyle.drawingStyle.textStyle.padding,
textBaseline: options.labelConfig.labelStyle.drawingStyle.textStyle.textBaseline,
offsetY: options.labelConfig.labelStyle.drawingStyle.textStyle.offsetY
}),
image: new ol.RegularShape({
radius: options.labelConfig.labelStyle.drawingStyle.imageStyle.radius,
points: options.labelConfig.labelStyle.drawingStyle.imageStyle.points,
angle: options.labelConfig.labelStyle.drawingStyle.imageStyle.angle,
displacement: options.labelConfig.labelStyle.drawingStyle.imageStyle.displacement,
fill: new ol.Fill({
color: options.labelConfig.labelStyle.drawingStyle.imageStyle.fillColor
})
})
})
}
}
/**
* 鼠标提示样式
* @returns
*/
export const setTipStyle = (options) => {
return new ol.Style({
text: new ol.Text({
font: options.mouseTipConfig.textStyle.font,
fill: new ol.Fill({
color: options.mouseTipConfig.textStyle.fillColor
}),
backgroundFill: new ol.Fill({
color: options.mouseTipConfig.textStyle.backgroundFillColor
}),
padding: options.mouseTipConfig.textStyle.padding,
textAlign: options.mouseTipConfig.textStyle.textAlign,
offsetX: options.mouseTipConfig.textStyle.offsetX
})
})
}
/**
* 鼠标提示样式
* @returns
*/
export const modifyStyle = (options) => {
return new ol.Style({
image: new ol.CircleStyle({
radius: options.paintBrushConfig.radius,
stroke: new ol.Stroke({
color: options.paintBrushConfig.strokeColor
}),
fill: new ol.Fill({
color: options.paintBrushConfig.fillColor
})
}),
text: new ol.Text({
font: options.mouseTipConfig.textStyle.font,
fill: new ol.Fill({
color: options.mouseTipConfig.textStyle.fillColor
}),
backgroundFill: new ol.Fill({
color: options.mouseTipConfig.textStyle.backgroundFillColor
}),
padding: options.mouseTipConfig.textStyle.padding,
textAlign: options.mouseTipConfig.textStyle.textAlign,
offsetX: options.mouseTipConfig.textStyle.offsetX
})
})
}










网友评论