leaflet plugin
插件
- 常用地图切换加载(osm、google、baidu、gaode、tianditu.etc)
https://github.com/htoooth/Leaflet.ChineseTmsProviders
切片地图加载(wmts)(支持矢量切片)
https://github.com/mylen/leaflet.TileLayer.WMTS
wms地图服务加载
https://github.com/heigeo/leaflet.wms
视窗范围框定(只容许查看和编辑给定范围地图)
https://github.com/aparshin/leaflet-boundary-canvas
地图要素显示比例尺控制(不同比例尺要素渲染)(根据屏幕坐标控制)(非常重要,常用)
https://github.com/GreenInfo-Network/L.TileLayer.PixelFilter/
卷帘对比(卷积运算)(历史对比)(非常重要)
https://github.com/digidem/leaflet-side-by-side
webGL地图要素渲染(适用于三维要素绘制)(非常重要)
https://gitlab.com/IvanSanchez/Leaflet.TileLayer.GL
快速重新渲染地图要素,动态修改地图样式(适用于矢量切片)(不用二次发布服务)(很实用)
(颜色获取) https://github.com/frogcat/leaflet-tilelayer-colorpicker
(样式调整)https://github.com/hnrchrdl/leaflet-tilelayer-colorizr
快速获取要素范围和属性信息(tootip方式)
https://github.com/consbio/Leaflet.UTFGrid
缓冲区(不推荐,存在bug,推荐使用geotools api后台生成缓冲区,需要坐标转换)
https://github.com/TolonUK/Leaflet.EdgeBuffer https://github.com/skeate/Leaflet.buffer
要素图层组加载过程数据获取(支持FeatureGroup loading和load事件)
https://github.com/Outdooractive/Leaflet.FeatureGroup.LoadEvents
地图要素移除,动态重新渲染底图(动画效果,缓冲效果)
https://gitlab.com/IvanSanchez/Leaflet.GridLayer.FadeOut
地图矢量切片服务加载和渲染(非常重要)
https://github.com/Leaflet/Leaflet.VectorGrid
(mapbox切片渲染)https://github.com/SpatialServer/Leaflet.MapboxVectorTile
(geojson格式渲染)https://github.com/mapbox/geojson-vt
常用格式地理数据加载(WKT、GeoJSON、KML、GPX、CSV、MDB、Shp等)
https://github.com/mapbox/leaflet-omnivore
https://github.com/makinacorpus/Leaflet.FileLayer
https://github.com/calvinmetcalf/leaflet.shapefile
地图WFS服务操作,
- 数据增删改查(Inert、Update、Delete、Query、Transaction)(重中之重,WFS服务封装,结合oracle或者postgis数据库,arcgis server或者geoserver后台服务搭建)
https://github.com/Flexberry/Leaflet-WFST
存在bug,需要修改,已在github issues中为作者留言,希望尽快解决;
如果geoserver搭建服务端:
typeNS表示工作区间, typeName表示图层名称(表名一致)
自定义label标签(Marker,polygon)
https://github.com/Leaflet/Leaflet.label
自定义marker
https://github.com/marslan390/BeautifyMarker
聚合数据
https://github.com/Leaflet/Leaflet.markercluster
https://github.com/MazeMap/Leaflet.LayerGroup.Collision
https://github.com/SINTEF-9012/PruneCluster
热力图
https://github.com/Leaflet/Leaflet.heat
http://ursudio.com/webgl-heatmap-leaflet/
加载echarts图(聚合图、迁徙图、热力图)(非常实用)
https://github.com/wandergis/leaflet-echarts.git
要素编辑(面合并、分割、创建要素等)(结合leaflet.wfst)(非常实用)
https://github.com/Leaflet/Leaflet.toolbar
https://github.com/Leaflet/Leaflet.draw
https://github.com/Leaflet/Leaflet.Editable
https://github.com/codeofsumit/leaflet.pm
https://github.com/willfarrell/Leaflet.Clipper
图层切换,要素显示隐藏
https://github.com/ismyrnow/leaflet-groupedlayercontrol
地图导航条、全屏控件
https://github.com/turbo87/sidebar-v2/
https://github.com/kartena/Leaflet.Pancontrol
https://github.com/kartena/Leaflet.zoomslider
https://github.com/Leaflet/Leaflet.fullscreen
https://github.com/brunob/leaflet.fullscreen
鹰眼图
https://github.com/Norkart/Leaflet-MiniMap
测量控件
https://github.com/ljagis/leaflet-measure
控件按钮样式设置
https://github.com/CliffCloud/Leaflet.EasyButton
https://github.com/aratcliffe/Leaflet.contextmenu
地图打印插件
https://github.com/rowanwins/leaflet-easyPrint
https://github.com/Igor-Vladyka/leaflet.browser.print
定位当前位置
https://github.com/domoritz/leaflet-locatecontrol
坐标转换插件(与缓冲区、测量配合使用)(非常实用)
https://github.com/kartena/Proj4Leaflet
空间位置分析(非常实用)
(点是否在面内)https://github.com/kartena/Proj4Leaflet
(计算面积、距离)https://github.com/makinacorpus/Leaflet.GeometryUtil/blob/master/src/leaflet.geometryutil.js
路径分析(纠偏,地图匹配算法)
https://github.com/perliedman/leaflet-routing-machine
https://github.com/Project-OSRM/osrm-frontend
poi模糊查询
https://github.com/smeijer/leaflet-geosearch
https://github.com/perliedman/leaflet-control-geocoder
等势线、等势面
https://github.com/timwis/leaflet-choropleth
Leaflet.pm插件
用于创建和编辑几何图层的插件
可绘制、编辑、拖动、剪切和捕捉图层
支持标记、CircleMarkers、折线、多边形、圆形、矩形、LayerGroups、GeoJSON 和 MultiPolygons
<template>
<div id="map" class="map"></div>
</template>
<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import "leaflet.pm";
import "leaflet.pm/dist/leaflet.pm.css";
export default {
name: "leafletPm",
data() {
return {
map: null,
OSMUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
};
},
mounted() {
this.initMap();
},
methods: {
initMap() {
this.map = L.map("map");
this.map.setView([34.03, -118.15], 13);
let tileLayer = L.tileLayer(this.OSMUrl);
tileLayer.addTo(this.map);
// 添加绘制工具
this.map.pm.setLang("zh");
this.map.pm.addControls({
position: "topleft",
drawPolygon: true, //绘制多边形
drawMarker: false, //绘制标记点
drawCircleMarker: false, //绘制圆形标记
drawPolyline: true, //绘制线条
drawRectangle: false, //绘制矩形
drawCircle: false, //绘制圆圈
editMode: true, //编辑多边形
dragMode: true, //拖动多边形
cutPolygon: true, //添加⼀个按钮以删除多边形⾥⾯的部分内容
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, "清除图层时调用");
});
},
},
};
</script>
https://turfjs.fenxianglu.cn/
Leaflet的轨迹模拟回放 animatedmarker
npm i -save leaflet.animatedmarker
// 在页面引入
import 'leaflet.animatedmarker/src/AnimatedMarker';
/**
* PolyLine
*/
var latlngs = [
[39.89571049162436, 116.28887714936559],
[39.89574033334674, 116.30303539096508],
[39.89696383279323, 116.30326876857339],
[39.89696383279323, 116.30428007154455],
[39.904930965629774, 116.30431896781283],
[39.905080154037904, 116.30599150734332],
[39.90591560311958, 116.30653605509644],
[39.906184091768495, 116.31839941532661],
[39.90624376607943, 116.32345593018351],
[39.906184091768495, 116.3293292666715],
[39.90586571685398, 116.33772942258247],
[39.905716530156496, 116.34900934033908],
[39.90595522871635, 116.35033181345642],
[39.90881804431149, 116.3502732434797],
[39.91388998013704, 116.3504288285514],
[39.91761910511673, 116.35031213974798],
[39.92012496302843, 116.3502732434797],
[39.922392088792634, 116.3500009696017],
[39.922213107908675, 116.34568348384079],
[39.92203412655681, 116.34012131749762],
[39.92198349105365, 116.33823159519835],
[39.92484713865562, 116.33788152878526],
[39.92487696768799, 116.33967075711911],
];
var polyline = L.polyline(latlngs, { color: "red" }).addTo(map_dom);
// 轨迹回放
let animatedMarker = L.animatedMarker(latlngs, {
icon: hospitalCarIcon, autoStart: false,
interval: 1000,
onEnd: function () {
// 结束
},
}).addTo(map_dom);
map_dom.fitBounds(latlngs).setZoom(15);
setTimeout(() => {
animatedMarker.start();
}, 5000);
sidebar
import "@/utils/sidebar/leaflet-sidebar.css";
import "@/utils/sidebar/leaflet-sidebar.js";
var sidebar = L.control.sidebar("sidebar", {
position: "left",
});
sidebar.addTo(map_dom)
// map_dom.addControl(sidebar);
setTimeout(function () {
sidebar.show();
}, 500);
<div id="sidebar" class="sidebar collapsed">
<!-- Nav tabs -->
<div class="sidebar-tabs">
<ul role="tablist">
<li><a href="#home" role="tab" id="xz_info">ooxx </a></li>
<li><a href="#profile" role="tab">aacc</a></li>
<li ><a href="#messages" role="tab">vva</a></li>
<li><a href="https://github.com/Turbo87/sidebar-v2" role="tab" target="_blank">aacc</a></li>
</ul>
<ul role="tablist">
<li><a href="#settings" role="tab"><i class="fa fa-gear"></i></a></li>
</ul>
</div>
<!-- Tab panes -->
<div class="sidebar-content">
<div class="sidebar-pane" id="home">
<h1 class="sidebar-header">
sidebar-v2
<span class="sidebar-close"><i class="fa fa-caret-right"></i></span>
</h1>
<p>A responsive sidebar for mapping libraries like <a href="http://leafletjs.com/">Leaflet</a> or <a href="http://openlayers.org/">OpenLayers</a>.</p>
<p class="lorem">Lo t.</p>
<p class="lorem">L met.</p>
<p class="lorem">Lor met.</p>
</div>
<div class="sidebar-pane" id="profile">
<h1 class="sidebar-header">Profile<span class="sidebar-close"><i class="fa fa-caret-right"></i></span></h1>
</div>
<div class="sidebar-pane" id="messages">
<h1 class="sidebar-header">Messages<span class="sidebar-close"><i class="fa fa-caret-right"></i></span></h1>
</div>
<div class="sidebar-pane" id="settings">
<h1 class="sidebar-header">Settings<span class="sidebar-close"><i class="fa fa-caret-right"></i></span></h1>
</div>
</div>
</div>
扩展工具栏指南
第一、自己基于dom创建页面元素,并挂载在其默认的工具栏中。
第二、基于Leaflet.EasyButton进行扩展。
其实,围绕着LeafLet,有许多实用的插件,比如工具栏扩展组件,大家可以针对自己的业务进行选取使用。本文将介绍如何基于Leaflet.EasyButton进行扩展。
第一步:在github上下载相关资源,插件地址:https://github.com/CliffCloud/Leaflet.EasyButton。
第二步、引入easyButton相关资源
<link rel="stylesheet" href="/2d/css/font-awesome.min.css" />
<script src="/2d/Leaflet.EasyButton/src/easy-button.css"></script>
<script src="/2d/leaflet/leaflet.js?v=1.0.0"></script>
<script src="/2d/Leaflet.EasyButton/src/easy-button.js"></script>
第三步、定义button对象
L.easyButton("<span class='fa fa-globe ' style='font-size:18px;height:30px;line-height:30px;'></span>", function(btn, map){
helloPopup.setLatLng(map.getCenter()).openOn(map);
}).addTo(mymap);
L.easyButton("<span class='fa fa-star ' style='font-size:18px;height:30px;line-height:30px;'></span>", function(btn, map){
//helloPopup.setLatLng(map.getCenter()).openOn(map);
layer.msg("我被点击了",{icon: 1});
}).addTo(mymap);
LeafLet的多点聚合展示markercluster
- 批量操作存放在layerGroup中的所有元素
- var cities = L.layerGroup();
- L.marker([36.606445, 109.522705],{icon:flagIcon,title:'延安分公司'}).bindPopup('延安分公司').addTo(cities); 将layerGroup添加到地图上
var overlays = {
"分公司": cities
};
L.control.layers([],overlays).addTo(mymap);
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();
var myMovingMarker = L.Marker.movingMarker([[48.8567, 2.3508],[50.45, 30.523333]],
[20000]).addTo(map);
//...
myMovingMarker.start();
API
Factory
L.movingMarker(<LatLng[]> latlngs, <Number[]> durations [,<Object> options]);
durations:
- if array of number : duration in ms per line segment.
- if number : total duration (autocalculate duration in ms per line segment proportionnaly to distance between points).
Note: As Leaftlet's other functions, it also accept them in a simple Array form and simple object form (see Leaflet docs).
Options All the marker's options are available.
autostart
: iftrue
the marker will start automatically after it is added to map. Default:false
loop
: iftrue
the marker will start automatically at the beginning of the polyline when the it arrives at the end. Default:false
Methods
Getter
isRunning()
: returntrue
if the marker is currently moving.isPaused()
: returntrue
if the marker is pausedisEnded()
: returntrue
if the marker is arrived to the last position or it has been stopped manuallyisStarted()
: returntrue
if the marker has started
Note: Marker.getLatLng()
still works and give the current position
Setter
start()
: the marker begins its path or resumes if it is paused.stop()
: manually stops the marker, if you call ```start`` after, the marker starts again the polyline at the beginning.pause()
: just pauses the markerresume()
: the marker resumes its animationaddLatLng(latlng, duration)
: adds a point to the polyline. Useful, if we have to set the path one by one.moveTo(latlng, duration)
: stops current animation and make the marker move tolatlng
induration
ms.addStation(pointIndex, duration)
: the marker will stop at thepointIndex
th points of the polyline duringduration
ms. You can't add a station at the first or last point of the polyline.
Events
start
: fired when the marker startsend
: fired when the marker stopsloop
: fired when the marker begin a new loop