
1、加载高德底图//引入依赖 import { Map, View } from ol import Draw, { createBox, createRegularPolygon, } from ol/interaction/Draw; import Polygon from ol/geom/Polygon; import { Vector as VectorSource } from ol/source; import { Circle, Point } from ol/geom; import { Tile as TileLayer, Vector as VectorLayer } from ol/layer; import XYZ from ol/source/XYZ; // XYZ 格式的瓦片数据源支持自定义瓦片地址如天地图、百度地图等 import { Circle as CircleStyle, Fill, Icon, Stroke, Style } from ol/style; import { ViewSerach, PointRadius } from /utils/tianAPI import Feature from ol/Feature; import Heatmap from ol/layer/Heatmap; //初始化地图 this.map new Map({ target: map,//指定挂载dom注意必须是id layers: [ new TileLayer({ source: new XYZ({// 使用 XYZ 数据源加载天地图的地形瓦片 url: http://webst0{1-4}.is.autonavi.com/appmaptile?langzh_cnsize1scale1style7x{x}y{y}z{z} }), }), vector, ], //配置视图 view: new View({ center: [115.81, 28.60], //视图中心位置 projection: EPSG:4326, //指定投影 zoom: 13, //缩放到的级别 }) });2、创建openlayer绘制工具,并输入搜索的地点类别addDraw(type) { if (type ! None) { this.draw new Draw({ type: type,//绘制的几何图形的几何类型 clickTolerance: 6,//点击公差 source: this.source, geometryFunction: geometryFunction, wrapX: false,//草图在x水平方向平铺 freehand: false//是否开启手绘模式 }); this.map.addInteraction(this.draw); } },3、调用天地图API获取绘制区域的点位数据/** * 视野内搜索 * param queryString:关键字;param mapBound:搜索的范围例如mapBound [116.02524,39.83833,116.65592,39.99185] * return {string} */ export const ViewSerach (queryString, mapBound) { let coords mapBound.join(,) return axios .get(http://api.tianditu.gov.cn/v2/search, { params: { postStr: {keyWord:${queryString},level:12, mapBound:${coords},queryType:2,start:0,count:100}, type: query, tk: 换成自己的tk, }, }).then((response) { const res response.data; let pois res.pois return pois }).catch((error) { console.error(请求失败详情, error); }); }4、创建heatmap图层将API返回的坐标创建Feature加入heatMap图层。this.heatMapSourve new VectorSource() const heatmapLayer new Heatmap({ source: this.heatMapSourve, // 包含点的矢量源 radius: 15, // 热点半径像素 blur: 10, // 模糊程度 gradient: [ // 颜色渐变从低温到高温 #00f, #0ff, #0f0, #ff0, #f00 ], weight: function (feature) { // 每个点的权重值可以根据属性如数量、强度返回数值 // 如果所有点权重相同则热力图反映密度 return 1; // 默认权重为1 } }); this.map.addLayer(heatmapLayer)完整代码template !--地图挂载dom-- div idmap div classMapTool !-- change选择变化事件当用户选择不同选项时触发 drawChange 方法 -- el-select v-modelvalue placeholder请选择 changedrawChange el-option v-foritem in options :keyitem.value :labelitem.label :valueitem.value /el-option /el-select /div !-- 地名类型输入dialog -- el-dialog title提示: :visible.syncdialogVisible width30% span请输入查询的地点:/span br el-input v-modelinputPalce placeholder/el-input el-button typeprimary clicksearchPlace(Retangle)确定/el-button /el-dialog !-- 半径输入 -- el-dialog title提示: :visible.syncpointdialogVisible width30% span请输入查询的地点:/span br el-input v-modelinputPalce placeholder/el-input span请输入查询的半径:/span br el-input v-modelradiusPoint placeholder/el-input el-button typeprimary clicksearchPlace(Point)确定/el-button /el-dialog !-- 结果展示列表dailog -- el-dialog title结果列表 :visible.syncresultVisible width30% table border1 cellpadding8 cellspacing0 stylewidth:100%; border-collapse:collapse; text-align:left; thead tr stylebackground-color:#f5f5f5; th经纬度/th th名称/th th地址/th /tr /thead tbody tr v-for(item, index) in tableData :keyindex td{{ item.lonlat }}/td td{{ item.name }}/td td{{ item.address }}/td /tr /tbody /table /el-dialog /div /template script //引入依赖 import { Map, View } from ol import Draw, { createBox, createRegularPolygon, } from ol/interaction/Draw; import Polygon from ol/geom/Polygon; import { Vector as VectorSource } from ol/source; import { Circle, Point } from ol/geom; import { Tile as TileLayer, Vector as VectorLayer } from ol/layer; import XYZ from ol/source/XYZ; // XYZ 格式的瓦片数据源支持自定义瓦片地址如天地图、百度地图等 import { Circle as CircleStyle, Fill, Icon, Stroke, Style } from ol/style; import { ViewSerach, PointRadius } from /utils/tianAPI import Feature from ol/Feature; import Heatmap from ol/layer/Heatmap; export default { name: DrawInteraction, data() { return { options: [{ value: Point, label: 点 }, { value: Box, label: 长方形 }], value: , dialogVisible: false, inputPalce: , resultVisible: false, tableKey: 0, tableData: null, radiusPoint: null, pointdialogVisible: false, } }, mounted() { //定义点的样式 const image new CircleStyle({ radius: 8, // 半径像素 fill: new Fill({ color: rgba(255, 0, 0, 0.8) // 填充色 }), stroke: new Stroke({ color: #fff, width: 2 }), }) const styles { Point: new Style({ image: image, }), Polygon: new Style({ stroke: new Stroke({ color: green, lineDash: [2], width: 3, }), fill: new Fill({ color: rgba(0, 100, 255, 0.1), }), }), Circle: new Style({ stroke: new Stroke({ color: red, width: 2, }), fill: new Fill({ color: rgba(255,0,0,0.2), }), }), }; const styleFunction function (feature) { return styles[feature.getGeometry().getType()]; }; //绘制的矢量数据 this.source new VectorSource({ wrapX: false }); const vector new VectorLayer({ source: this.source, style: styleFunction, }); //初始化地图 this.map new Map({ target: map,//指定挂载dom注意必须是id layers: [ new TileLayer({ source: new XYZ({// 使用 XYZ 数据源加载天地图的地形瓦片 url: http://webst0{1-4}.is.autonavi.com/appmaptile?langzh_cnsize1scale1style7x{x}y{y}z{z}// url 中的 {x}、{y}、{z} 是 OpenLayers 自动填充的瓦片坐标和层级tk 是天地图的访问密钥需自行申请 }), }), vector, ], //配置视图 view: new View({ center: [115.81, 28.60], //视图中心位置 projection: EPSG:4326, //指定投影 zoom: 13, //缩放到的级别 }) }); this.heatMapSourve new VectorSource() const heatmapLayer new Heatmap({ source: this.heatMapSourve, // 包含点的矢量源 radius: 15, // 热点半径像素 blur: 10, // 模糊程度 gradient: [ // 颜色渐变从低温到高温 #00f, #0ff, #0f0, #ff0, #f00 ], weight: function (feature) { // 每个点的权重值可以根据属性如数量、强度返回数值 // 如果所有点权重相同则热力图反映密度 return 1; // 默认权重为1 } }); this.map.addLayer(heatmapLayer) }, methods: { drawChange(type) { if (this.map) { //先移除之前的绘制交互对象 this.map.removeInteraction(this.draw); this.addDraw(type) } }, addDraw(type) { if (type ! None) { this.draw new Draw({ type: type,//绘制的几何图形的几何类型 clickTolerance: 6,//点击公差 source: this.source, geometryFunction: geometryFunction, wrapX: false,//草图在x水平方向平铺 freehand: false//是否开启手绘模式 }); this.map.addInteraction(this.draw); this.draw.on(drawend, (event) { // 刚刚绘制的Feature const drawnFeature event.feature let geometryType drawnFeature.getGeometry().getType() if (geometryType Polygon) { let extent drawnFeature.getGeometry().getExtent() const withoutBrackets extent.join(, ); this.extent extent this.dialogVisible true } else if (geometryType Point) { // console.log(drawnFeature.getGeometry().getCoordinates(),------geo-----) this.coord drawnFeature.getGeometry().getCoordinates() this.clickCoord this.coord this.pointdialogVisible true } }) } }, searchPlace(type) { if (type Retangle) { ViewSerach(this.inputPalce, this.extent).then(res { this.dialogVisible false this.tableData res this.resultVisible true res.forEach(item { let lonlat item.lonlat let coord lonlat.split(,) let name item.name let PointGeometry new Point(coord) let PointFea new Feature(PointGeometry) PointFea.setStyle(new Style({ image: new CircleStyle({ radius: 8, // 半径像素 fill: new Fill({ color: rgba(255, 0, 0, 0.8) // 填充色 }), stroke: new Stroke({ color: #fff, width: 2 }), }), })) this.source.addFeature(PointFea) this.heatMapSourve.addFeature(PointFea) }) }) } else if (type Point) { const circleGeom new Circle(this.coord, this.radiusPoint / 111000); // radius 为度数 let circleFeature new Feature(circleGeom) this.source.addFeature(circleFeature) PointRadius(this.inputPalce, this.coord, this.radiusPoint).then(res { this.pointdialogVisible false this.tableData res this.resultVisible true res.forEach(item { let lonlat item.lonlat let coord lonlat.split(,) let name item.name let PointGeometry new Point(coord) let PointFea new Feature(PointGeometry) PointFea.setStyle(new Style({ image: new CircleStyle({ radius: 8, // 半径像素 fill: new Fill({ color: rgba(255, 0, 0, 0.8) // 填充色 }), stroke: new Stroke({ color: #fff, width: 2 }), }), })) this.source.addFeature(PointFea) this.heatMapSourve.addFeature(PointFea) }) }) } } } } /script style scoped .MapTool { position: absolute; top: .5em; right: .5em; z-index: 9999; } /style