leaflet实现自定义线、矩形和扇形的绘制
创始人
2024-02-20 07:02:12
0

leaflet实现地图上的自定义绘制,主要是通过监听map的click、mousemove、dblclick事件来获得对应的点位,然后根据获得的点位进行实时的绘制来达到相应的效果。

矩形绘制的实现

监听map的click事件,获得第一个点,然后开启map的mousemove事件监听,实时重绘矩形,然后再地图第二次点击时,获得第二个点,构成最终绘制的矩形,同时去掉对map的click事件和mousemove事件的监听。

  createRectangle() {let tmplist = []let juxing;map.on("click", (e) => {tmplist.push([e.latlng.lat, e.latlng.lng])this.map.on('mousemove', (ev) => {if (tmplist.length > 1) {tmplist.splice(1)}tmplist.push([ev.latlng.lat, ev.latlng.lng])this.tmpgroup.clearLayers()juxing = L.rectangle(tmplist, {//绘制矩形color: "#ff7800",weight: 1}).addTo(this.tmpgroup);})if (tmplist.length > 1) {tmplist.pop()//第二次点击会触发第一次的push()导致得到三个数据(后两个一样),所以删除最后一个this.map.off('mousemove')//两点确定,移除鼠标移动事件this.map.off('click')//两点确定,移除点击事件,this.tmpgroup.clearLayers()L.rectangle(tmplist, {//绘制矩形color: "#ff7800",weight: 1}).addTo(this.rectgroup);}})
}

扇形的绘制

监听map的click事件,获得第一个点,然后开启map的mousemove事件监听,当点少于1个的时候,绘制成线,做扇形的一条边,然后再地图第二次点击时,获得第二个点,构成扇形的第二个点,同时在移动时有第3个点,则可构成扇形,进行实时重绘,在地图地3次点击时,绘制成最终的扇形。
扇形需要计算第1个点和第2个点之间的距离作为扇形的半径,计算第1个点和第2个点、第1个点和第3个点的夹角,可以使用地理空间分析库turf来完成计算,

扇形的图形绘制有两种方式实现:
  • 第一种方法:采用Leaflet-semicircle来直接绘制,这种是采用svg进行的绘制,存在一个问题就是无法获取到会指出来的扇形的点位;
  • 第二种方法,采用计算公式来计算出整个扇形的点位,然后以面的方式在地图上绘制出来。
_circle(latlng, options) {let svg = L.svg();return L.semiCircle(latlng, L.extend({radius: 50000,color: '#f03',opacity: 1,renderer: svg,weight: 1}, options));},_dis(fromPoint, toPoint) {let from = turf.point(fromPoint); //[-75.343, 39.984]let to = turf.point(toPoint);let options = { units: 'kilometers' };let distance = turf.rhumbDistance(from, to, options);return distance;},_ber(fromPoint, toPoint) {let point1 = turf.point(fromPoint);let point2 = turf.point(toPoint);let bearing = turf.rhumbBearing(point1, point2);return bearing;},_drawSemiCircle(pointList, layerGroup) {let tmp = JSON.parse(JSON.stringify(pointList))console.log(JSON.stringify(pointList));let p1 = tmp[0].reverse();let p2 = tmp[1].reverse();let radius = this._dis(p1, p2);//计算第1个点和第2点前鼠标点之间的弧度let ber1 = this._ber(p1, p2);//计算第1个点和第3点前鼠标点之间的弧度let p3 = tmp[2].reverse();let ber2 = this._ber(p1, p3);console.log('radius-->' + radius + ',ber1--->' + ber1 + ',ber2--->' + ber2);if (!!radius && !!ber1 && !!ber2) {/*方式一:采用SemiCircle类库,但是无法获取到点串let scircle = this._circle(p1.reverse(), {radius: radius * 1000,color: '#2260b4',startAngle: ber1,stopAngle: ber2,weight: 4});scircle.addTo(layerGroup);*///方式二,通过计算出扇形的点位,以面的方式在地图上叠加let points = this._getSemiCirclePoints(p1.reverse(), radius / 100, ber1, ber2, 500);points[points.length] = points[0];let semiCirclePolygon = L.polygon(points);semiCirclePolygon.addTo(layerGroup)}},/**** @param center 中心点 数组 [lat, lon]* @param radius 半径* @param startAngle 起始角度* @param endAngle 终止角度* @param pointNum 圆弧上点的个数*/_getSemiCirclePoints(center, radius, startAngle, endAngle, pointNum) {let sin;let cos;let x;let y;let angle;let points = [];points.push(center);for (let i = 0; i <= pointNum; i++) {angle = startAngle + (endAngle - startAngle) * i / pointNum;sin = Math.sin(angle * Math.PI / 180);cos = Math.cos(angle * Math.PI / 180);y = center[0] + radius * cos;x = center[1] + radius * sin;points[i] = [y, x];}let point = points;point.push(center);return point;},createSemiCircle() {let pointList = [];this.semicirclegroup.clearLayers();this.map.on("click", (e) => {pointList.push([e.latlng.lat, e.latlng.lng]);this.map.on('mousemove', (ev) => {let lastPoint = pointList[pointList.length - 1];if (pointList.length === 1) {let latlngs = [lastPoint,[ev.latlng.lat, ev.latlng.lng]]this.semicirclegroup.clearLayers();L.polyline(latlngs, {color: "#03f",weight: 3}).addTo(this.semicirclegroup);} else if (pointList.length === 2) {//绘制成一个扇形let arr = JSON.parse(JSON.stringify(pointList));arr.push([ev.latlng.lat, ev.latlng.lng]);this.semicirclegroup.clearLayers();this._drawSemiCircle(arr, this.semicirclegroup);}})if (pointList.length > 2) {this.map.off('mousemove')//两点确定,移除鼠标移动事件this.map.off('click')//两点确定,移除点击事件,//绘制扇形在地图上this.semicirclegroup.clearLayers();let arr = [pointList[0], pointList[1], pointList[pointList.length - 1]];this._drawSemiCircle(arr, this.semicirclegroup);}})},

线绘制的实现

线绘制的实现思路跟上面的类似,只是多一个,这个会做一个临时图层来显示最后一段绘制的效果。

createPolyline() {let pointList = [];map.on("click", (e) => {pointList.push([e.latlng.lat, e.latlng.lng]);this.map.on('mousemove', (ev) => {//临时图层直线是最后一段线即可let lastPoint = pointList[pointList.length - 1]let latlngs = [lastPoint,[ev.latlng.lat, ev.latlng.lng]]this.tmpgroup.clearLayers();L.polyline(latlngs, {color: "#2260b4",weight: 3}).addTo(this.tmpgroup);})this.map.on('dblclick', (ev) => {this.map.off('mousemove')//两点确定,移除鼠标移动事件this.map.off('click')//两点确定,移除点击事件,pointList.push([ev.latlng.lat, ev.latlng.lng]);this.tmpgroup.clearLayers();this.semicirclegroup.clearLayers()if (pointList.length > 1) {L.polyline(pointList, {color: "#ff7800",weight: 5}).addTo(this.semicirclegroup);}})if (pointList.length > 1) {this.semicirclegroup.clearLayers();L.polyline(pointList, {color: "#ff7800",weight: 3}).addTo(this.semicirclegroup);}})
},

参考文章:
leaflet 画扇形

相关内容

热门资讯

谁能给我发几个好看的穿越文,女... 谁能给我发几个好看的穿越文,女主要聪明点的,还有请给我发下《蛇蝎皇后》这篇小说我有比较多的小说,但是...
网络语叫粉丝是什么意思? 网络语叫粉丝是什么意思?'粉丝’是英语‘Fans’(狂热、热爱之意,后引申为影迷、追星等意思)的音译...
你们希望柯南的最后大结局是新兰... 你们希望柯南的最后大结局是新兰永恒吗肯定滴啊,如果新兰都不永恒了谁还相信爱情、、、 上次预告还有五年...
出师表朗诵 出师表朗诵出师表的朗诵应该配上什么音乐,或者歌曲(最好是现代的),给点建议!新三国片头曲吧试试王宗贤...
《率土之滨》平民新手开局怎么玩... 《率土之滨》平民新手开局怎么玩?前期开荒核心是完美的利用每一点资源,把他变为你前期最有利的抢地武器!...
咒怨里面的白老妇[那个鬼 的扮... 咒怨里面的白老妇[那个鬼 的扮演者是谁?告诉我吧求求你们了 我要是不知道他是活人演的拿篮球的那个老婆...
体验当家的辛苦 体验当家的辛苦自己体会会有灵感的。什么事情还是自己做一下比较真实这样的作文就必须要自己去亲身体会,让...
(只要人物时间地点的正确就能开... (只要人物时间地点的正确就能开启尘封已久的记忆)能解释一下这个是什么含义是一个女的写给我的是表白吗大...
科学和迷信你们信哪个?不能解释... 科学和迷信你们信哪个?不能解释的东西事物算得上是迷信吗迷信我是不会相信的,如果对所谓的科学百分之百的...
请问延世大学韩语教程和标准韩国... 请问延世大学韩语教程和标准韩国语哪本更适合自学?哪本语法更详细,更易于学习。先谢谢啦。你好,标准韩国...
有谁曾经暗恋一个人,很久都没有... 有谁曾经暗恋一个人,很久都没有见到却还是很想念他想就想呗,随自己的意就可以了让她留在心里吧.我也曾暗...
昨天在车上看的碟子,好像是,一... 昨天在车上看的碟子,好像是,一个DJ现场,一个人边唱边喝酒,还互动问题,答完就喝。提问的歌曲有:洪湖...
魔兽世界小白任务和战场问题 魔兽世界小白任务和战场问题去魔兽数据库里找 多玩 嘟牛 这两个网站的 数据库很全 什么任务...
《公主回宫》什么时候开播? 《公主回宫》什么时候开播?已经开播了,祝你愉快.
到底大灰狼和小绵羊是一对,还是... 到底大灰狼和小绵羊是一对,还是和小白兔是一对很显然小绵羊和小白兔是一对
你觉着《他来了请闭眼》中霍建华... 你觉着《他来了请闭眼》中霍建华演技如何?《他来了请闭眼》中霍建华演技很好。霍建华的演技很好,能够表现...
九色神鹿故事? 九色神鹿故事?很久以前,在恒河边上有一只九种毛色的鹿,它那闪闪发光的鲜艳毛色和洁白如雪的美丽鹿角,以...
刘州成坚强的故事 刘州成坚强的故事就是男子汉一点的 刘小美的刘州成他是一个很坚强的人来的.. 一路走来他都是勇敢地走来...
书籍设计的内容简介 书籍设计的内容简介《书籍设计》立足于新世纪中国艺术教育的改革,将艺术理论与技能培训融会贯通,从内容选...
2024年山西中考初二考地理生... 2024年山西中考初二考地理生物吗不考。截止2022年6月1日山西中考除晋中和阳泉两个改革试点区域外...