Leaflet介紹
Leaflet 是一個為建設交互性好適用於移動設備地圖,而開發的現代的、開源的 JavaScript 庫。代碼僅有 33 KB,但它具有開發在線地圖的大部分功能。支持插件擴展, Leaflet強大的開源庫插件涉及到地圖應用的各個方面包括地圖服務,數據提供,數據格式,地理編碼,路線和路線搜索,地圖控件和交互等類型的插件共有140多個。
在線API:http://leafletjs.com/reference-1.2.0.html
在線范例:http://leafletjs.com/examples.html
注:leaflet客戶端開發demo參考http://malagis.com/learning-leaflet-js-note.html
SuperMap iClient for Leaflet介紹
SuperMap iClient for Leaflet 是一套基於Leaflet的雲GIS網絡客戶端開發平台, 支持訪問SuperMap iServer / iExpress / iPortal / iManager / Online的地圖、服務和資源,為用戶提供了完整專業的GIS能力, 同時提供了優秀的可視化功能。
官網地址:http://iclient.supermap.io/
在線API:http://iclient.supermapol.com/web/apis/leaflet.html
在線范例:http://iclient.supermapol.com/examples/leaflet/examples.html#iServer
相關模塊如下圖,分為Mapping,Services, Overlay,Control四個模塊
開發入門
1、 引用所需的腳本庫和樣式文件

1 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" 2 crossorigin="" /> 3 <script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script> 4 <script type="text/javascript" src="http://iclient.supermap.io/dist/iclient9-leaflet.js"></script>
2、加載iServer發布的地圖服務,疊加圖層代碼如下:

1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>加載瓦片</title> 7 </head> 8 9 <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;"> 10 11 <div id="map" style="margin:0 auto;width: 100%;height: 100%"></div> 12 13 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" 14 crossorigin="" /> 15 <script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script> 16 <script type="text/javascript" src="http://iclient.supermap.io/dist/iclient9-leaflet.js"></script> 17 <script type="text/javascript"> 18 var host = window.isLocal ? document.location.protocol + "//" + document.location.host : "http://support.supermap.com.cn:8090"; 19 var map, resultLayer, infoWin, url = "http://localhost:8090/iserver/services/map-ugcv5-China1/rest/maps/China1"; 20 //定義出圖的比例尺,此處和切圖時設定的比例尺保持一致 21 var scaleDenominators = [591658711, 295829355, 147914678, 73957339, 36978669, 18489335, 9244667, 4622334, 2311167, 1155583, 577792, 288896, 144448]; 22 //地圖原點 23 var origin = [0, 0]; 24 //leaflet CRS投影設置 25 var crs = L.Proj.CRS("EPSG:3857", { 26 origin: origin, 27 scaleDenominators: scaleDenominators 28 }); 29 30 map = L.map('map', { 31 preferCanvas: true, 32 crs: crs, 33 center: { lon: 0, lat: 0 }, 34 maxZoom: 13, 35 zoom: 0 36 }); 37 L.supermap.tiledMapLayer(url, { 38 transparent: true, 39 cacheEnabled: true 40 }).addTo(map); 41 42 </script> 43 </body> 44 45 </html>
注:地圖投影參數設置,見如下代碼:

1 var crs = L.Proj.CRS("EPSG:4326", { 2 origin: [114.59, 42.31], 3 scaleDenominators: [100000, 50000, 25000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 1] 4 }); 5 map = L.map('map', { 6 crs: crs, 7 center: [39.79, 116.85], 8 }); 9 L.supermap.tiledMapLayer(url).addTo(map);
3、測量服務,在地圖界面上繪制線、面,計算距離和面積,代碼如下:

1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>地圖上測量demo</title> 7 </head> 8 9 <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;"> 10 <div id="toolbar"> 11 <input type="button" class="btn" value="測量距離" onclick="measureLength()" /> 12 <input type="button" class="btn" value="測量面積" onclick="measureArea()" /> 13 </div> 14 <div id="map" style="margin:0 auto;width: 100%;height: 100%"></div> 15 16 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" 17 crossorigin="" /> 18 <script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script> 19 <script type="text/javascript" src="http://iclient.supermap.io/dist/iclient9-leaflet.js"></script> 20 <script type="text/javascript"> 21 var host = window.isLocal ? document.location.protocol + "//" + document.location.host : "http://support.supermap.com.cn:8090"; 22 var map, resultLayer, infoWin, url = "http://support.supermap.com.cn:8090/iserver/services/map-china400/rest/maps/China"; 23 map = L.map('map', { 24 preferCanvas: true, 25 crs: L.CRS.EPSG3857, 26 center: { lon: 0, lat: 0 }, 27 maxZoom: 13, 28 zoom: 3 29 }); 30 L.supermap.tiledMapLayer(url).addTo(map); 31 resultLayer = L.featureGroup().addTo(map); 32 33 //繪制線,測量距離 34 function measureLength() { 35 var points = [], 36 points_length = 0, 37 polyline; 38 // 單擊 39 var clickFlag, 40 clickTimes = 1, 41 isDrag = false; 42 map.on('mousedown', function (e) { 43 map.off('mousemove'); 44 if (clickFlag) clearTimeout(clickFlag); 45 clickFlag = setTimeout(function () { 46 if (clickTimes == 1 && !isDrag) { 47 points.push([e.latlng.lat, e.latlng.lng]); 48 points_length = points.length; 49 // 移動 50 map.on('mousemove', function (e) { 51 // 清除 52 if (polyline) map.removeLayer(polyline); 53 // polyline 54 points[points_length] = [e.latlng.lat, e.latlng.lng]; 55 polyline = new L.Polyline(points, { color: "red" }); 56 resultLayer.addLayer(polyline); 57 }); 58 } 59 }, 300); 60 }); 61 var popup = new L.popup(); 62 // 雙擊 63 map.on('dblclick', function (e) { 64 if (points.length) { 65 clickTimes = 2; 66 // polyline 67 polyline = new L.Polyline(points, { color: "red" }); 68 //map.addLayer(polyline); 69 resultLayer.addLayer(polyline) 70 // 移除事件 71 map.off('mousemove'); 72 } 73 var distanceMeasureParam = new SuperMap.MeasureParameters(polyline); 74 L.supermap.measureService(url).measureDistance(distanceMeasureParam, function (serviceResult) { 75 //console.log("距離: " + serviceResult.result.distance + " 米"); 76 popup 77 .setLatLng(e.latlng) 78 .setContent("距離: " + serviceResult.result.distance + " 米") 79 .openOn(map); 80 }); 81 }); 82 // 拖動 83 map.on('movestart', function () { 84 isDrag = true; 85 }); 86 map.on('moveend', function () { 87 isDrag = false; 88 }); 89 } 90 91 //繪制面,測量面積 92 function measureArea() { 93 var points = [], 94 points_length = 0, 95 polyline, 96 polygon; 97 // 單擊 98 var clickFlag, 99 clickTimes = 1, 100 isDrag = false; 101 map.on('mousedown', function (e) { 102 map.off('mousemove'); 103 if (clickFlag) clearTimeout(clickFlag); 104 clickFlag = setTimeout(function () { 105 if (clickTimes == 1 && !isDrag) { 106 points.push([e.latlng.lat, e.latlng.lng]); 107 points_length = points.length; 108 // 移動 109 map.on('mousemove', function (e) { 110 // 清除 111 if (polyline) map.removeLayer(polyline); 112 if (polygon) map.removeLayer(polygon); 113 // polyline 114 points[points_length] = [e.latlng.lat, e.latlng.lng]; 115 polyline = new L.Polyline(points); 116 resultLayer.addLayer(polyline); 117 // polygon 118 polygon = new L.Polygon(points); 119 resultLayer.addLayer(polygon); 120 }); 121 } 122 }, 300); 123 }); 124 var popup = new L.popup(); 125 // 雙擊 126 map.on('dblclick', function (e) { 127 if (points.length) { 128 clickTimes = 2; 129 // polyline 130 polyline = new L.Polyline(points, { color: "red" }); 131 //map.addLayer(polyline); 132 resultLayer.addLayer(polyline) 133 polygon = new L.Polygon(points); 134 resultLayer.addLayer(polygon); 135 // 移除事件 136 map.off('mousemove'); 137 } 138 var areaMeasureParam = new SuperMap.MeasureParameters(polygon); 139 L.supermap 140 .measureService(url) 141 .measureArea(areaMeasureParam, function (serviceResult) { 142 popup 143 .setLatLng(polygon.getCenter()) 144 .setContent("面積: " + serviceResult.result.area + " 平方米") 145 .openOn(map); 146 }); 147 }); 148 // 拖動 149 map.on('movestart', function () { 150 isDrag = true; 151 }); 152 map.on('moveend', function () { 153 isDrag = false; 154 }); 155 } 156 </script> 157 </body> 158 159 </html>
測量的效果圖如下:
4、使用iServer發布的數據服務,進行sql查詢,代碼如下:

1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>數據集SQL查詢</title> 7 </head> 8 9 <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;"> 10 <div id="map" style="margin:0 auto;width: 100%;height: 100%"></div> 11 12 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" 13 crossorigin="" /> 14 <script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script> 15 <script type="text/javascript" src="http://iclient.supermap.io/dist/iclient9-leaflet.js"></script> 16 <script type="text/javascript"> 17 var host = window.isLocal ? document.location.protocol + "//" + document.location.host : "http://support.supermap.com.cn:8090"; 18 var map, resultLayer, 19 baseUrl = "http://localhost:8090/iserver/services/map-World/rest/maps/World_Google", 20 url = "http://localhost:8090/iserver/services/data-World/rest/data"; 21 map = L.map('map', { 22 preferCanvas: true, 23 crs: L.CRS.EPSG4326, 24 center: { lon: 0, lat: 0 }, 25 maxZoom: 18, 26 zoom: 1 27 }); 28 L.supermap.tiledMapLayer(baseUrl).addTo(map); 29 query(); 30 31 function query() { 32 var sqlParam = new SuperMap.GetFeaturesBySQLParameters({ 33 toIndex: -1, 34 maxFeatures:10000, 35 queryParameter: { 36 name: "world@World", 37 attributeFilter: "SMID>0", 38 }, 39 datasetNames: ["World:world"] 40 }); 41 L.supermap 42 .featureService(url) 43 .getFeaturesBySQL(sqlParam, function (serviceResult) { 44 resultLayer = L.geoJSON(serviceResult.result.features).addTo(map).bindPopup('SMID > 0'); 45 46 console.log(serviceResult.result.featureCount); 47 }); 48 } 49 //點擊地圖事,彈窗顯示坐標值 50 var popup = L.popup(); 51 52 function onMapClick(e) { 53 popup 54 .setLatLng(e.latlng) 55 .setContent("You clicked the map at " + e.latlng.toString()) 56 .openOn(map); 57 } 58 59 map.on('click', onMapClick); 60 </script> 61 </body> 62 63 </html>
查詢的效果圖如下:
5、使用iServer地圖服務,生成專題圖,進行繪制,代碼如下:

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>范圍分段專題圖</title> 6 </head> 7 <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;"> 8 <div id="map" style="margin:0 auto;width: 100%;height: 100%"></div> 9 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" 10 crossorigin="" /> 11 <script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script> 12 <script type="text/javascript" src="http://iclient.supermap.io/dist/iclient9-leaflet.js"></script> 13 14 15 <script type="text/javascript"> 16 var host = window.isLocal ? window.server : "http://support.supermap.com.cn:8090"; 17 var map, themeService, themeRange, themeParameters, themeLayer, 18 url = host + "/iserver/services/map-china400/rest/maps/China"; 19 map = L.map('map', { 20 center: [30, 84], 21 maxZoom: 18, 22 zoom: 3 23 }); 24 L.supermap.tiledMapLayer(url, {noWrap: true, transparent: true}).addTo(map); 25 createTheme(); 26 27 function createTheme() { 28 themeService = L.supermap.themeService(url); 29 var themeRangeItem1 = new SuperMap.ThemeRangeItem({ 30 start: 0, 31 end: 500000000000, 32 style: new SuperMap.ServerStyle({ 33 fillForeColor: new SuperMap.ServerColor(211, 255, 250), 34 lineColor: new SuperMap.ServerColor(179, 209, 193), 35 lineWidth: 0.1 36 }) 37 }); 38 var themeRangeItem2 = new SuperMap.ThemeRangeItem({ 39 start: 500000000000, 40 end: 1000000000000, 41 style: new SuperMap.ServerStyle({ 42 fillForeColor: new SuperMap.ServerColor(178, 218, 199), 43 lineColor: new SuperMap.ServerColor(179, 209, 193), 44 lineWidth: 0.1 45 }) 46 }); 47 var themeRangeItem3 = new SuperMap.ThemeRangeItem({ 48 start: 1000000000000, 49 end: 3000000000000, 50 style: new SuperMap.ServerStyle({ 51 fillForeColor: new SuperMap.ServerColor(58, 178, 166), 52 lineColor: new SuperMap.ServerColor(179, 209, 193), 53 lineWidth: 0.1 54 }) 55 }); 56 themeRange = new SuperMap.ThemeRange({ 57 rangeExpression: "SMAREA", 58 rangeMode: SuperMap.RangeMode.EQUALINTERVAL, 59 items: [themeRangeItem1, themeRangeItem2, themeRangeItem3] 60 }); 61 themeParameters = new SuperMap.ThemeParameters({ 62 datasetNames: ["China_Province_pg"], 63 dataSourceNames: ["China"], 64 joinItems: null, 65 themes: [themeRange] 66 }); 67 themeService.getThemeInfo(themeParameters, function (serviceResult) { 68 var result = serviceResult.result; 69 if (result && result.newResourceID) { 70 themeLayer = L.supermap.tiledMapLayer(url, { 71 noWrap: true, 72 cacheEnabled: false, 73 transparent: true, 74 layersID: result.newResourceID 75 }).addTo(map); 76 } 77 }); 78 } 79 </script> 80 </body> 81 </html>
專題圖的效果如下:
6、點聚合功能,代碼如下:

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>點聚合</title> 6 </head> 7 <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;"> 8 <div id="map" style="margin:0 auto;width: 100%;height: 100%"></div> 9 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" 10 crossorigin="" /> 11 <script type="text/javascript" src="https://cdn.bootcss.com/leaflet/1.0.3/leaflet.js"></script> 12 <script type="text/javascript" src="http://iclient.supermap.io/dist/iclient9-leaflet.js"></script> 13 <script type="text/javascript"> 14 var host = window.isLocal ? window.server : "http://support.supermap.com.cn:8090"; 15 var map, resultLayer, getFeatureBySQLParams, 16 dataUrl = host + "/iserver/services/data-DynamicData/rest/data", 17 url = host + "/iserver/services/map-china400/rest/maps/China"; 18 map = L.map('map', { 19 preferCanvas: true, 20 center: [32, 104], 21 maxZoom: 18, 22 zoom: 4 23 }); 24 L.supermap.tiledMapLayer(url).addTo(map); 25 resultLayer = L.markerClusterGroup({ 26 spiderfyOnMaxZoom: false, 27 showCoverageOnHover: false, 28 zoomToBoundsOnClick: false 29 }); 30 getFeatureBySQLParams = new SuperMap.GetFeaturesBySQLParameters({ 31 queryParameter: new SuperMap.FilterParameter({ 32 name: "Train@DynamicData", 33 attributeFilter: "SmID>100 and SmID < 800" 34 }), 35 toIndex: -1, 36 datasetNames: ["DynamicData:Train"] 37 }); 38 loadMarkerCluster(); 39 40 function loadMarkerCluster() { 41 L.supermap 42 .featureService(dataUrl) 43 .getFeaturesBySQL(getFeatureBySQLParams, function (serviceResult) { 44 createLayers(serviceResult.result.features); 45 }); 46 } 47 48 function createLayers(result) { 49 if (!result || !result.features || result.features.length < 1) { 50 return; 51 } 52 result.features.map(function (feature) { 53 var latLng = L.CRS.EPSG3857.unproject(L.point(feature.geometry.coordinates)); 54 resultLayer.addLayer(L.marker(latLng)); 55 }); 56 resultLayer.addTo(map); 57 } 58 </script> 59 </body> 60 </html>
聚合效果如下圖所示:
7、結合eCharts實例,代碼如下:
效果如下圖所示:
8、最佳路徑分析,代碼如下:
效果如下圖所示:
9、對繪制到地圖上的幾何對象進行緩沖區分析,代碼如下:
效果如下圖所示:
10、