需求:在右图map中框选一部分区域,通过接口搜索相似图像
-
创建map实例
mounted() {
this.initMap()
},
methods:{
initMap() {
this.raster = new TileLayer({
source:new OSM(),
preload: Infinity
})
this.vectorLayer = new VectorLayer({
source: new VectorSource({ wrapX: false })
})
let view = new View({
resolutions: rasterSource.getTileGrid().getResolutions(),
center: [this.imageDetail.width / 4, -this.imageDetail.height / 4],
zoom: 3,
zoomFactor: 2 // 这个会影响像素坐标的计算, 使点坐标变得非常小
})
let map = new Map({
target: this.$refs.openlayersMap,
layers: [
this.raster,
this.vectorLayer
],
view: view
})
this.map = map
this.doDraw()
},
}
- 创建draw 实例,并监听 绘制结束事件(drawend),获取 矢量数据(imageGeometry)
doDraw() {
var extent = []
let source = this.vectorLayer.getSource()
let toolConfig = { value: 'Circle', freehand: false, geometryFunction: createBox(), title: '矩形测量', icon: 'icon-juxing' }
let draw = new Draw({
source: source,
type: toolConfig.value,
freehand: toolConfig.freehand,
maxPoints: toolConfig.maxPoints,
geometryFunction: toolConfig.geometryFunction,
style: new Style({
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.5)',
lineDash: [10, 10],
width: 2
})
}),
// 在标注完成的时候会自动单击,这里需要防止select操作发生导致的选中被取消
stopClick: true
})
draw.on('drawend', e => {
this.imageGeometry = e.feature.getGeometry()
})
draw.on('drawstart', evt => {
source.clear()
})
this.raster.on('postrender', this.doClipLayer1)
this.map.addInteraction(draw)
},
- 图层渲染之后进行图像信息的获取,一定要是渲染之后(postrender),不然获取到的图像信息为0
- 获取矢量数据的四至(extent),通过自带的方法: getTopLeft 获取 左上角的像素距离 、宽:getWidth、高:getHeight()。注意:getWidth、getHeight获取的是地理坐标宽高,要转成像素宽度需要除以分辨率进行转换
- 这样就可以通过 getImageData,来获取图像数据,再通过创建canvas=>填入图像信息putImageData=>转换成base64图像信息toDataURL
//渲染之后,获取框选区域图像信息
doClipLayer(event) {
if (!this.imageGeometry) return
let ctx = event.context
let canvas = ctx.canvas
let extent = this.imageGeometry.getExtent()
//左上角 的像素距离
let [x, y] = this.map.getPixelFromCoordinate(getTopLeft(extent))
this.currentPixelZoom = this.map.getView().getZoom()
this.resolution1 = this.map.getView().getResolutionForZoom(this.currentPixelZoom)
//getWidth、getHeight获取的是地理坐标宽高,要转成像素宽度需要除以分辨率进行转换
let w = getWidth(extent) / this.resolution1
let h = getHeight(extent) / this.resolution1
let imageData = ctx.getImageData(x, y, w, h)
let newCanvas = document.createElement('canvas')
newCanvas.width = w
newCanvas.height = h
let newCtx = newCanvas.getContext('2d')
newCtx.putImageData(imageData, 0, 0)
this.urlBase64 = newCanvas.toDataURL()
},
- 最后监听 urlBase64 的改变,调用接口获取相似图像列表
watch: {
urlBase64(val) {
if (!val) return
this.startPicSearch({ file: this.dataURLtoFile(val) })
//imageGeometry置为空,不然 postrender 事件会一直更新urlBase64
this.imageGeometry = null
}
},
methods:{
startPicSearch({ file }) {
let formData = new FormData()
formData.append('image', file)
this.picData = formData
this.picSearch()
},
//将base64 转为file对象
dataURLtoFile(dataurl) {
const arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
},
}