图层创建
// featureGroup图层创建
// 在实际项目中地图数据分为不同类型,这时如果把所有数据同时加载到地图上来进行操作会带来各种问题,所以此时需要利用L.featureGroup方法创建不同的图层,用来加载不同类型的数据,以方便操作,具体方法如下:
var _viewSpotLayer=new L.featureGroup([]);
_map.addLayer(_viewSpotLayer);
// 如需要清除图层上的数据集合,使用内置方法即可:
_viewSpotLayer.clearLayers();
// --------------------------示例:
var pointFeature = new L.marker([39.905,116.399],{ icon: viewIcon,title:"故宫"}).bindLabel("故宫",{noHide:true}).addTo(_viewSpotLayer);
参数说明:
// icon //用于渲染标记的图标实例。使用L.icon创建,下面会有详细讲解
// title //鼠标悬停时提示文本
// alt //图像文本
// riseOnHover //true/false(默认),为true时当您将鼠标悬停在其上时,标记将会显示在其他标记之上。
// 方法说明:
.addTo(layer) //添加到指定图层当中
.bindLabel() //给marker绑定label,使用方法及参数下面详解
// 事件说明:
// marker支持各种鼠标事件,使用方法为
marker.on("event",function(){
//do something
})
// ps:如果通过ajax请求加载多个marker,并且都需要添加点击事件,请使用【封闭空间】循环加载数据点
// 使用示例:
$.ajax({
url:"js/demo.json",
type:"POST",
success:function(data){
for(var i=0;i<data.rows.length;i++){
(function (index){ //封闭空间开始
var row=data.rows[index];
var pointFeature = new L.marker([row.lat,row.lng],{ icon:
viewIcon,title:row.name}).bindLabel(row.name,{noHide:true});
pointFeature.options.sm_sid = "rwjg";
pointFeature.on("click",function(){
alert(row.name)
});
pointFeature.addTo(_viewSpotLayer)
})(i) //封闭空间结束
}
}
})
polyLine
使用示例
new L.polyline(数据集合,{options})
var lineArr=[[39.920969009399414, 116.38572692871094],[39.91101264953613,
116.3862419128418],[39.91161346435547, 116.39636993408203],[39.9217414855957,
116.3957691192627],[39.9213981628418, 116.38589859008789]];
var line =newL.polyline(lineArr,{color:'red',opacity:'0.8',weight:'3'})
.addTo(_viewSpotLayer);
参数说明:
color:线段颜色
weight:线段宽度
opacity:线段透明度
dashArray:虚线间隔
fill:是否填充内部(true/false)
fillColor:内部填充颜色,如不设置,默认为color颜色
fillOpacity:内部填充透明度
方法:
.setStyle() 设置样式;
事件:
line.on("event",function(){
//do something
})
// ps:线段的事件,是能在鼠标位于线段上方时操作才会触发
https://openwhatevermap.xyz/#3/39.64/210.50
绘制的多个图形组合成一个整体通过 layerGroup 作为 overlayer 添加上去
https://blog.csdn.net/sinat_36226553/article/details/107287753
加载各种服务- 加载WMTS服务加载WMS服务 加载TMS服务 加载Geojson数据
- 注:如果手上有shp数据,可以通过mapshaper转换得到geojson数据
- leaflet本身并不支持WMTS服务,需要借助 leaflet-tilelayer-wmts 插件实现
var bj = L.marker([39.92,116.46]).bindPopup('这里是北京');
sh = L.marker([31.213,121.445]).bindPopup('这里是上海');
gz = L.marker([23.16,113.23]).bindPopup('这里是广州');
var cities = L.layerGroup([bj, sh, gz]).addTo(map);
图层a
let markericon = []
this.pointList.forEach(item => {
const myIcon = L.divIcon({
html: `<div class="marker-box flex flex-col items-center">
<div class="board-box flex flex-col items-center">
<div class="board">
${ item.name }
${ item.distance ? `<div>距离分指挥部:${ item.distance }</div>` : '' }
<div class="logo">
<img src="${ pointLogo }"/>
</div>
</div>
<img class="line" src="${ pointLine }"/>
</div>
${JSON.parse(item.image).length ? `<img src="${ '/sys/sysFile/download?fileId=' + JSON.parse(item?.image)[0]?.id }"/>` : ''}
<div class="circle-box">
<div class="circle1"></div>
<div class="circle2" style="animation-delay: 0.5s;"></div>
<div class="circle3" style="animation-delay: 1.5s;></div>
</div>
</div>
`,
// iconSize: [50 , 70], // icon大小
});
const m = L.marker([item.wd, item.jd], { icon: myIcon });
markericon.push(m);
})
this.markerLayer = L.layerGroup(markericon);
this.map.addLayer(this.markerLayer);
// Leaflet Ant Path:
// 在交通项目、管网应用的项目中,常常需要标注出道路的走向、河流的流向或者管线的流向等等,Leaflet Ant Path能够很好的解决这类问题:
qgis 下载
- https://download.osgeo.org/qgis/windows/
Leaflet的轨迹模拟回放 MovingMarker.js 插件
- https://github.com/ewoken/Leaflet.MovingMarker
npm i Leaflet-MovingMaker
let config = {
id: 'id', // 唯一标识, 后期删除轨迹要用
iconUrl: 'https:******.png', // iconUrl
speed: 10000, // 速度
latlngs: [[lat1,lng2], [lat2,lng2], …],
html: `<div> .... </div>` // 标牌, 样式自理
}
this.handleCreateTrack(config);
handleCreateTrack(config) {
let featureGroup = [];
// 轨迹线
let routeLine = L.polyline(config.latlngs, {
weight: 4,
opacity: 0.7, // 定义线的透明度
});
// 定位该线至可视窗口
this.map.fitBounds(routeLine.getBounds());
// 创建icon
let carIcon = L.icon({
iconSize: [30, 30],
iconUrl: config.iconUrl,
});
// 动态marker
let animatedMarker = L.Marker.movingMarker(
routeLine.getLatLngs(),
config.speed,
// 以下配置项在github上有详细注解-----
{
autostart: true,
loop: false,
icon: carIcon,
rotate: false,
}
).bindPopup(config.html);
// 移动结束时弹出标牌
animatedMarker.on("end", function () {
animatedMarker.openPopup();
});
// 记录划线过程
let path = [];
animatedMarker.on("move", (res) => {
// 回调中会返回经纬度信息,点移动改变地图中心点
this.map.panTo([res.latlng.lat, res.latlng.lng])
// 动态画已走路线
let polyline = ...
});
featureGroup.push(animatedMarker);
featureGroup.push(routeLine);
let featureGroup = L.featureGroup(featureGroup);
// 记录地图上的点、线、面 ... 根据id 可动态删除
this.clusterLayer.push({
type: config.id,
value: featureGroup,
});
this.map.addLayer(featureGroup);
},
this.map.fitBounds(这里是我们的点位数据) // 将地图视层尽可能大的设定在给定的地理边界内
var marker2 = L.Marker.movingMarker(点位数据格式与marker内的一样[lat,lng],
10000 '//动画时长' ,
{ autostart: true, loop: false, icon: policeCarIcon, rotate: false }
).addTo(this.map)
//后面这些可以参考上面的插件文档进行解读
// 地图根据点位移动,一直设置点位为中心点
let path = [] // 声明绘制线的临时使用变量
marker2.on('move', res => { // 监听点位移动事件 move
this.map.panTo([res.latlng.lat, res.latlng.lng]) //回调中会返回经纬度信息,点移动改变地图中心点
path.length > 1 && path.shift() // 保持数组长度,避免过度push不断重新绘制之前的路径
path.push([res.latlng.lat, res.latlng.lng]) // 将数据push到数组中
L.polyline(path, { color: '#20a080', weight: 2 }).addTo(this.map) // 绘制线到地图图层
})
// 这里我做了一个轨迹回放结束事件 end
marker2.on('end', function () {
// closeOnClick: false 点击别处不会消失
marker2.bindPopup('<b>轨迹结束显示</b>', { closeOnClick: true }).openPopup()
})
//--------------------------------------------------------------------------------------------------------------
/**
*
*/
var parisKievLL = [
[28.8567, 112.3508],
[30.45, 130.523333],
];
var londonParisRomeBerlinBucarest = [
[31.507222, 110.1275],
[28.8567, 112.3508],
[31.9, 112.5],
[31.516667, 113.383333],
[31.4166, 126.1],
];
map_dom.fitBounds(londonParisRomeBerlinBucarest);
var marker1 = L.Marker.movingMarker(parisKievLL, [10000]).addTo(map_dom);
L.polyline(parisKievLL).addTo(map_dom);
marker1.once("click", function () {
marker1.start();
marker1.closePopup();
marker1.unbindPopup();
marker1.on("click", function () {
if (marker1.isRunning()) {
marker1.pause();
} else {
marker1.start();
}
});
setTimeout(function () {
marker1.bindPopup("<b>点我暂停 !</b>").openPopup();
}, 2000);
});
marker1.bindPopup("<b>点我开始!</b>", { closeOnClick: false });
marker1.openPopup();
Leaflet.PM插件实现创建和编辑几何图形(点、线、面、圆等):
使用用L.polylineDecorator插件可以实现轨迹带箭头效果。 Leaflet.AnimatedMarker插件可以更流畅的实现marker沿线播放,但是没有考虑marker角度和轨迹线的动态绘制。 参考Leaflet.AnimatedMarker、leaflet-moving-marker中核心代码,解决角度问题以及轨迹线动态绘制等问题。 将代码重新封装成插件,方便调用。
视频ckPlayer
- ckplayer插件可以用来播放网页视频,也可以用来做直播项目,同页面调用2个ckplayer插件时。需要将官网上设置的container的值变成class或者标签
https://www.codeleading.com/article/35113304750/
- ckplayer在一个页面中调用两个播放器的方法,现在是用推流在播放,想做成一个页面并排着放两个相同的视频,用
<table>
做了两个表格每个表格放一样的代码,但是打开只会出现一个播放器。
var videoObject = {
// ckplayer插件 可以绑定在页面中的任何一个容器中(需要在html中写一个空的容器 class名或者id或者标签名 与下文调用时的container保持一致)
container: '.videosamplex',//“#”代表容器的ID,“.”或“”代表容器的class
variable: 'player',//该属性必需设置,值等于下面的new ckplayer()的对象
poster:'pic/wdm.jpg', // 封面图片
// mobileCkControls:true,//是否在移动端(包括ios)环境中显示控制栏
// mobileAutoFull:false,//在移动端播放后是否按系统设置的全屏播放
// h5container:'#videoplayer',//h5环境中使用自定义容器
video:'http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4'//视频地址
};
var player=new ckplayer(videoObject);
var videoObject2 = {
container: '.videosamplex2',//“#”代表容器的ID,“.”或“”代表容器的class
variable: 'player2',//该属性必需设置,值等于下面的new ckplayer()的对象
poster:'pic/wdm.jpg',
mobileCkControls:true,//是否在移动端(包括ios)环境中显示控制栏
mobileAutoFull:false,//在移动端播放后是否按系统设置的全屏播放
video:'http://img.ksbbs.com/asset/Mon_1703/d30e02a5626c066.mp4'//视频地址
};
var player2=new ckplayer(videoObject2);
https://www.codeleading.com/article/35113304750/
- 在main.js文件内全局引入阿里云字体图标 css,记得使用路径要正确
滚动插件
- vue3-scroll-seamless
https://xiaofulzm.github.io/vue3-scroll-seamless/guide/properties.html
- 谷歌插件
https://chrome.zzzmh.cn/info/cdonnmffkdaoajfknoeeecmchibpmkmg
- 聚合
https://github.com/SINTEF-9012/PruneCluster
缩放显示不同坐标
https://github.com/Leaflet/Leaflet.Editable -https://leaflet.github.io/Leaflet.Editable/doc/api.html
绘制 Leaflet.draw
https://github.com/codeofsumit/leaflet.pm
- 图层切换,要素显示隐藏 图层组展示 npm install leaflet-groupedlayercontrol https://github.com/ismyrnow/leaflet-groupedlayercontrol
heatMap
var baseURL = 'http://{s}.tile.cloudmade.com/{API}/{map_style}/256/{z}/{x}/{y}.png';
var base = L.tileLayer(baseURL, {
API: your-api,
map_style: '44094'
});
//Halifax, Nova Scotia
var map = L.map('map', {layers: [base]}).setView([44.65, -63.57], 12);
L.control.scale().addTo(map);
//custom size for this example, and autoresize because map style has a percentage width
var heatmap = new L.TileLayer.WebGLHeatMap({size: 1000, autoresize: true});
// dataPoints is an array of arrays: [[lat, lng, intensity]...]
var dataPoints = [[44.6674, -63.5703, 37], [44.6826, -63.7552, 34], [44.6325, -63.5852, 41], [44.6467, -63.4696, 67], [44.6804, -63.487, 64], [44.6622, -63.5364, 40], [44.603, - 63.743, 52] ...];
for (var i = 0, len = dataPoints.length; i < len; i++) {
var point = dataPoints[i];
heatmap.addDataPoint(point[0],
point[1],
point[2]);
}
// alternatively, you can skip the for loop and add the whole dataset with heatmap.setData(dataPoints)
map.addLayer(heatmap);
leaflet.PM
// 添加绘制工具
this.map.pm.setLang("zh");
this.map.pm.addControls({
position: "topleft",
drawPolygon: true, //绘制多边形
drawMarker: false, //绘制标记点
drawCircleMarker: false, //绘制圆形标记
drawPolyline: false, //绘制线条
drawRectangle: false, //绘制矩形
drawCircle: false, //绘制圆圈
editMode: true, //编辑多边形
dragMode: true, //拖动多边形
cutPolygon: false, //添加⼀个按钮以删除多边形⾥⾯的部分内容
removalMode: true, //清除多边形
});
// 全局设置绘制样式
this.map.pm.setPathOptions({
color: "orange",
fillColor: "green",
fillOpacity: 0.4,
});
// 或者单独设置绘制样式
var options = {
// 连接线标记之间的线
templineStyle: {
color: "red",
},
// 提⽰线从最后⼀个标记到⿏标光标的线
hintlineStyle: {
color: "red",
dashArray: [5, 5],
},
// 绘制完成的样式
pathOptions: {
color: "orange",
fillColor: "green",
},
};
// 激活绘制多边形功能-1、单独设置某个模式的样式
this.map.pm.enableDraw("Polygon", options);
// 启用绘制--多边形功能
this.map.pm.enableDraw("Polygon", {
snappable: true, //启⽤捕捉到其他绘制图形的顶点
snapDistance: 20, //顶点捕捉距离
});
// 关闭绘制--注意也可以关闭其他模式的绘制功能
this.map.pm.disableDraw("Polygon");
// 绘制事件监听
this.map.on("pm:drawstart", (e) => {
console.log(e, "绘制开始第一个点");
});
this.map.on("pm:drawend", (e) => {
console.log(e, "禁⽌绘制、绘制结束");
});
this.map.on("pm:create", (e) => {
console.log(e, "绘制完成时调⽤");
if (e.shape == "Circle") {
console.log(e.layer._latlng, e.layer._radius, "绘制坐标");
} else {
console.log(e.layer._latlngs[0], "绘制坐标");
}
});
this.map.on("pm:globalremovalmodetoggled", (e) => {
console.log(e, "清除图层时调用");
});
marker ICON
// 仿照MSN 天气 做的ICON
let iconIdv = new L.DivIcon({
className: 'my-div-icon',
html: ` <div class="ic_tool"> <span class="my-div-span" >${row.hospitalName}</span>
</div>
<div class='ic_point'>
</div>
`
// '<img class="my-div-image" src="http://png-3.vector.me/files/images/4/0/402272/aiga_air_transportation_bg_thumb"/>'+
})
.my-div-icon {
width: 150px !important;
/* height: 100px!important; */
display: flex;
background-size: 100% 100%;
border-left: 2px solid yellow;
height: 100px !important;
padding: 3px !important;
/* border-radius: 5px; */
top: -100px !important;
flex-direction: column;
}
.ic_tool {
background-color: #444D52;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 25px;
padding-left: 10%;
line-height: 25px;
}
.ic_point {
position: absolute;
bottom: 0;
left: -5px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: red;
}
.my-div-span {
font-size: 16px !important;
position: absolute;
color: aliceblue;
}