├── .gitignore ├── app ├── common │ ├── plugin │ │ ├── README.md │ │ ├── echartsLegend.css │ │ ├── measureControl.css │ │ ├── images │ │ │ ├── measure-control.png │ │ │ ├── measure-area-control.png │ │ │ └── measure-control.svg │ │ ├── echartsIcon.scss │ │ ├── measureAreaControl.css │ │ ├── echartsIcon.js │ │ ├── echartsLegend.js │ │ ├── easyPrint.js │ │ ├── leaflet.baidu.js │ │ ├── measureAreaControl.js │ │ ├── clickMeasureAreaControl.js │ │ └── measureControl.js │ ├── imgs │ │ ├── dvf1.png │ │ ├── dvf2.png │ │ ├── edit.png │ │ ├── line.png │ │ ├── map.png │ │ ├── pie.png │ │ ├── rect.png │ │ ├── save.png │ │ ├── china.png │ │ ├── delete.png │ │ ├── heatmap.png │ │ ├── point.png │ │ ├── polygon.png │ │ ├── print.png │ │ ├── qianxi.png │ │ ├── scatter.png │ │ ├── select.png │ │ ├── style.png │ │ └── toolbar.png │ ├── css │ │ ├── images │ │ │ ├── layers.png │ │ │ ├── geocoder.png │ │ │ ├── throbber.gif │ │ │ ├── layers-2x.png │ │ │ ├── marker-icon.png │ │ │ ├── spritesheet.png │ │ │ ├── marker-shadow.png │ │ │ ├── marker-icon-2x.png │ │ │ ├── measure-control.png │ │ │ ├── spritesheet-2x.png │ │ │ ├── spritesheet.svg │ │ │ └── measure-control.svg │ │ ├── measurecontrol.css │ │ ├── index.scss │ │ ├── Control.OSMGeocoder.css │ │ ├── _css-reset.scss │ │ └── Control.Geocoder.css │ ├── leaflet-plugin │ │ ├── README.md │ │ ├── leaflet.ChineseTmsProviders.js │ │ ├── lib │ │ │ └── simpleheat.js │ │ ├── L.MeasureAreaControl.js │ │ ├── leaflet.measurecontrol.js │ │ ├── Leaflet.dvf │ │ │ └── css │ │ │ │ └── dvf.css │ │ └── Control.OSMGeocoder.js │ └── util.js ├── component │ ├── mapServer.scss │ ├── gConfig.js │ ├── dvf.scss │ ├── viz.scss │ ├── basemap.js │ ├── editbar.scss │ ├── toolbar.scss │ ├── toolbar.js │ ├── mapServer.js │ └── editbar.js ├── index.js └── index.html ├── output ├── app │ └── common │ │ ├── plugin │ │ ├── README.md │ │ ├── echartsLegend.css │ │ ├── measureControl.css │ │ ├── images │ │ │ ├── measure-control.png │ │ │ ├── measure-area-control.png │ │ │ └── measure-control.svg │ │ ├── measureAreaControl.css │ │ ├── echartsIcon.scss │ │ ├── echartsIcon.js │ │ ├── echartsLegend.js │ │ ├── easyPrint.js │ │ ├── leaflet.baidu.js │ │ ├── measureAreaControl.js │ │ ├── clickMeasureAreaControl.js │ │ └── measureControl.js │ │ ├── imgs │ │ ├── china.png │ │ ├── dvf1.png │ │ ├── dvf2.png │ │ ├── edit.png │ │ ├── line.png │ │ ├── map.png │ │ ├── pie.png │ │ ├── point.png │ │ ├── print.png │ │ ├── rect.png │ │ ├── save.png │ │ ├── style.png │ │ ├── delete.png │ │ ├── heatmap.png │ │ ├── polygon.png │ │ ├── qianxi.png │ │ ├── scatter.png │ │ ├── select.png │ │ └── toolbar.png │ │ ├── css │ │ ├── images │ │ │ ├── layers.png │ │ │ ├── geocoder.png │ │ │ ├── layers-2x.png │ │ │ ├── throbber.gif │ │ │ ├── marker-icon.png │ │ │ ├── spritesheet.png │ │ │ ├── marker-icon-2x.png │ │ │ ├── marker-shadow.png │ │ │ ├── spritesheet-2x.png │ │ │ ├── measure-control.png │ │ │ ├── spritesheet.svg │ │ │ └── measure-control.svg │ │ ├── measurecontrol.css │ │ ├── index.scss │ │ ├── Control.OSMGeocoder.css │ │ ├── _css-reset.scss │ │ └── Control.Geocoder.css │ │ ├── leaflet-plugin │ │ ├── README.md │ │ ├── leaflet.ChineseTmsProviders.js │ │ ├── lib │ │ │ └── simpleheat.js │ │ ├── L.MeasureAreaControl.js │ │ ├── leaflet.measurecontrol.js │ │ ├── Leaflet.dvf │ │ │ └── css │ │ │ │ └── dvf.css │ │ └── Control.OSMGeocoder.js │ │ └── util.js └── index.html ├── LICENSE ├── package.json ├── test ├── leaflet-mapserver.html └── openlayers-mapserver.html └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /npm-debug.log 3 | -------------------------------------------------------------------------------- /app/common/plugin/README.md: -------------------------------------------------------------------------------- 1 | ###说明 2 | 文件夹下是我基于开源库的一些修改扩展 3 | -------------------------------------------------------------------------------- /output/app/common/plugin/README.md: -------------------------------------------------------------------------------- 1 | ###说明 2 | 文件夹下是我基于开源库的一些修改扩展 3 | -------------------------------------------------------------------------------- /app/common/imgs/dvf1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/dvf1.png -------------------------------------------------------------------------------- /app/common/imgs/dvf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/dvf2.png -------------------------------------------------------------------------------- /app/common/imgs/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/edit.png -------------------------------------------------------------------------------- /app/common/imgs/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/line.png -------------------------------------------------------------------------------- /app/common/imgs/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/map.png -------------------------------------------------------------------------------- /app/common/imgs/pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/pie.png -------------------------------------------------------------------------------- /app/common/imgs/rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/rect.png -------------------------------------------------------------------------------- /app/common/imgs/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/save.png -------------------------------------------------------------------------------- /app/common/imgs/china.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/china.png -------------------------------------------------------------------------------- /app/common/imgs/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/delete.png -------------------------------------------------------------------------------- /app/common/imgs/heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/heatmap.png -------------------------------------------------------------------------------- /app/common/imgs/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/point.png -------------------------------------------------------------------------------- /app/common/imgs/polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/polygon.png -------------------------------------------------------------------------------- /app/common/imgs/print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/print.png -------------------------------------------------------------------------------- /app/common/imgs/qianxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/qianxi.png -------------------------------------------------------------------------------- /app/common/imgs/scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/scatter.png -------------------------------------------------------------------------------- /app/common/imgs/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/select.png -------------------------------------------------------------------------------- /app/common/imgs/style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/style.png -------------------------------------------------------------------------------- /app/common/imgs/toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/imgs/toolbar.png -------------------------------------------------------------------------------- /app/component/mapServer.scss: -------------------------------------------------------------------------------- 1 | #json { 2 | background: url(../common/imgs/china.png) no-repeat; 3 | } 4 | -------------------------------------------------------------------------------- /app/common/css/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/layers.png -------------------------------------------------------------------------------- /app/common/plugin/echartsLegend.css: -------------------------------------------------------------------------------- 1 | /* .leaflet-control-echarts-legend{ 2 | width:90px; 3 | height:140px; 4 | } */ -------------------------------------------------------------------------------- /output/app/common/imgs/china.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/china.png -------------------------------------------------------------------------------- /output/app/common/imgs/dvf1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/dvf1.png -------------------------------------------------------------------------------- /output/app/common/imgs/dvf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/dvf2.png -------------------------------------------------------------------------------- /output/app/common/imgs/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/edit.png -------------------------------------------------------------------------------- /output/app/common/imgs/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/line.png -------------------------------------------------------------------------------- /output/app/common/imgs/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/map.png -------------------------------------------------------------------------------- /output/app/common/imgs/pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/pie.png -------------------------------------------------------------------------------- /output/app/common/imgs/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/point.png -------------------------------------------------------------------------------- /output/app/common/imgs/print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/print.png -------------------------------------------------------------------------------- /output/app/common/imgs/rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/rect.png -------------------------------------------------------------------------------- /output/app/common/imgs/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/save.png -------------------------------------------------------------------------------- /output/app/common/imgs/style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/style.png -------------------------------------------------------------------------------- /app/common/css/images/geocoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/geocoder.png -------------------------------------------------------------------------------- /app/common/css/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/throbber.gif -------------------------------------------------------------------------------- /output/app/common/imgs/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/delete.png -------------------------------------------------------------------------------- /output/app/common/imgs/heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/heatmap.png -------------------------------------------------------------------------------- /output/app/common/imgs/polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/polygon.png -------------------------------------------------------------------------------- /output/app/common/imgs/qianxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/qianxi.png -------------------------------------------------------------------------------- /output/app/common/imgs/scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/scatter.png -------------------------------------------------------------------------------- /output/app/common/imgs/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/select.png -------------------------------------------------------------------------------- /output/app/common/imgs/toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/imgs/toolbar.png -------------------------------------------------------------------------------- /output/app/common/plugin/echartsLegend.css: -------------------------------------------------------------------------------- 1 | /* .leaflet-control-echarts-legend{ 2 | width:90px; 3 | height:140px; 4 | } */ -------------------------------------------------------------------------------- /app/common/css/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/layers-2x.png -------------------------------------------------------------------------------- /app/common/css/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/marker-icon.png -------------------------------------------------------------------------------- /app/common/css/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/spritesheet.png -------------------------------------------------------------------------------- /app/common/css/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/marker-shadow.png -------------------------------------------------------------------------------- /output/app/common/css/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/layers.png -------------------------------------------------------------------------------- /app/common/css/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/marker-icon-2x.png -------------------------------------------------------------------------------- /app/common/css/images/measure-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/measure-control.png -------------------------------------------------------------------------------- /app/common/css/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/css/images/spritesheet-2x.png -------------------------------------------------------------------------------- /app/common/css/measurecontrol.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-draw-measure { 2 | background-image: url(images/measure-control.png); 3 | } 4 | -------------------------------------------------------------------------------- /app/common/plugin/measureControl.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-draw-measure { 2 | background-image: url(images/measure-control.png); 3 | } 4 | -------------------------------------------------------------------------------- /app/component/gConfig.js: -------------------------------------------------------------------------------- 1 | let config = { 2 | mapOpt:{ 3 | center:[30, 104], 4 | zoom:5 5 | } 6 | } 7 | 8 | export default config; -------------------------------------------------------------------------------- /output/app/common/css/images/geocoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/geocoder.png -------------------------------------------------------------------------------- /output/app/common/css/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/layers-2x.png -------------------------------------------------------------------------------- /output/app/common/css/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/throbber.gif -------------------------------------------------------------------------------- /app/common/plugin/images/measure-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/plugin/images/measure-control.png -------------------------------------------------------------------------------- /output/app/common/css/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/marker-icon.png -------------------------------------------------------------------------------- /output/app/common/css/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/spritesheet.png -------------------------------------------------------------------------------- /output/app/common/css/measurecontrol.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-draw-measure { 2 | background-image: url(images/measure-control.png); 3 | } 4 | -------------------------------------------------------------------------------- /output/app/common/css/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/marker-icon-2x.png -------------------------------------------------------------------------------- /output/app/common/css/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/marker-shadow.png -------------------------------------------------------------------------------- /output/app/common/css/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/spritesheet-2x.png -------------------------------------------------------------------------------- /output/app/common/plugin/measureControl.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-draw-measure { 2 | background-image: url(images/measure-control.png); 3 | } 4 | -------------------------------------------------------------------------------- /app/common/plugin/images/measure-area-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/app/common/plugin/images/measure-area-control.png -------------------------------------------------------------------------------- /output/app/common/css/images/measure-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/css/images/measure-control.png -------------------------------------------------------------------------------- /app/common/plugin/echartsIcon.scss: -------------------------------------------------------------------------------- 1 | .echarts-icon{ 2 | width:100px; 3 | height:100px; 4 | } 5 | .my-div-icon{ 6 | background-color:rgba(255,255,255,0); 7 | } -------------------------------------------------------------------------------- /app/common/plugin/measureAreaControl.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-draw-measure-area { 2 | background-image: url(images/measure-area-control.png); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /output/app/common/plugin/images/measure-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/plugin/images/measure-control.png -------------------------------------------------------------------------------- /output/app/common/plugin/measureAreaControl.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-draw-measure-area { 2 | background-image: url(images/measure-area-control.png); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /app/component/dvf.scss: -------------------------------------------------------------------------------- 1 | .mag-value { 2 | vertical-align: middle; 3 | text-align: center; 4 | line-height: 10px; 5 | color: rgba(0, 0, 0, 0.8); 6 | } 7 | -------------------------------------------------------------------------------- /output/app/common/plugin/echartsIcon.scss: -------------------------------------------------------------------------------- 1 | .echarts-icon{ 2 | width:100px; 3 | height:100px; 4 | } 5 | .my-div-icon{ 6 | background-color:rgba(255,255,255,0); 7 | } -------------------------------------------------------------------------------- /output/app/common/plugin/images/measure-area-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zrysmt/leaflet-viz/HEAD/output/app/common/plugin/images/measure-area-control.png -------------------------------------------------------------------------------- /app/common/leaflet-plugin/README.md: -------------------------------------------------------------------------------- 1 | ## 文件说明 2 | 3 | 注意:项目中使用的均是通过npm下载后import引入的,该文件夹提供查看源码的作用 4 | 5 | * leaflet-src 是leaflet的原库 6 | * leafleat.measurecontrol.js 是下载的库,使用的plugin文件夹下的mesureControl是根据此定制的 7 | * Leaflet.draw文件夹是绘图的源码 8 | -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/README.md: -------------------------------------------------------------------------------- 1 | ## 文件说明 2 | 3 | 注意:项目中使用的均是通过npm下载后import引入的,该文件夹提供查看源码的作用 4 | 5 | * leaflet-src 是leaflet的原库 6 | * leafleat.measurecontrol.js 是下载的库,使用的plugin文件夹下的mesureControl是根据此定制的 7 | * Leaflet.draw文件夹是绘图的源码 8 | -------------------------------------------------------------------------------- /app/common/css/index.scss: -------------------------------------------------------------------------------- 1 | @import '_css-reset'; 2 | 3 | #mapbar{ 4 | position: absolute; 5 | display: flex; 6 | display: -webkit-flex; 7 | align-items: center; 8 | width: 90%; 9 | padding-left:10%; 10 | background-color: rgba(255,255,255,0.8); 11 | z-index: 9999; 12 | } 13 | 14 | #map{ 15 | height:1000px; 16 | } 17 | -------------------------------------------------------------------------------- /output/app/common/css/index.scss: -------------------------------------------------------------------------------- 1 | @import '_css-reset'; 2 | 3 | #mapbar{ 4 | position: absolute; 5 | display: flex; 6 | display: -webkit-flex; 7 | align-items: center; 8 | width: 90%; 9 | padding-left:10%; 10 | background-color: rgba(255,255,255,0.8); 11 | z-index: 9999; 12 | } 13 | 14 | #map{ 15 | height:1000px; 16 | } 17 | -------------------------------------------------------------------------------- /app/component/viz.scss: -------------------------------------------------------------------------------- 1 | 2 | #heatbar{ 3 | background: url(../common/imgs/heatmap.png) no-repeat; 4 | } 5 | #echarts1{ 6 | background: url(../common/imgs/scatter.png) no-repeat; 7 | } 8 | #echarts2{ 9 | background: url(../common/imgs/qianxi.png) no-repeat; 10 | } 11 | #divicon{ 12 | background: url(../common/imgs/pie.png) no-repeat; 13 | } 14 | #dvf1{ 15 | background: url(../common/imgs/dvf1.png) no-repeat; 16 | } 17 | #dvf2{ 18 | background: url(../common/imgs/dvf2.png) no-repeat; 19 | } 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | // import './common/css/leaflet.css'; 2 | import './common/css/index.scss'; 3 | import util from './common/util.js'; 4 | 5 | import {map} from './component/basemap.js'; 6 | import {Toolbar} from './component/toolbar.js'; 7 | import {Editbar} from './component/editbar.js'; 8 | import {Maptypebar} from './component/maptypebar.js'; 9 | import {Viz} from './component/viz.js'; 10 | import {MapServer} from './component/mapServer.js'; 11 | 12 | util.adaptHeight("map",0); 13 | 14 | 15 | let toolbar = new Toolbar(); 16 | toolbar.init(map); 17 | let editbar = new Editbar(); 18 | editbar.init(map); 19 | let maptypebar = new Maptypebar(); 20 | maptypebar.init(map); 21 | let viz = new Viz(); 22 | viz.init(map); 23 | let mapServer = new MapServer(); 24 | mapServer.init(); -------------------------------------------------------------------------------- /app/component/basemap.js: -------------------------------------------------------------------------------- 1 | // import '../common/css/Control.Geocoder.css'; 2 | // import 'leaflet-control-geocoder'; 3 | import L from 'leaflet'; 4 | import "../common/css/Control.OSMGeocoder.css"; 5 | import "../common/leaflet-plugin/Control.OSMGeocoder.js"; 6 | 7 | 8 | let map = L.map('map',{ 9 | crs:L.CRS.EPSG3857 //默认墨卡托投影 ESPG:3857 10 | }).setView([30, 104], 5); 11 | let osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { 12 | attribution: '© OpenStreetMap contributors' 13 | }) 14 | osm.addTo(map); 15 | L.control.scale().addTo(map); //比例尺 16 | let editableLayers = new L.FeatureGroup(); 17 | let drawnItems = editableLayers.addTo(map); 18 | let osmGeocoder = new L.Control.OSMGeocoder({ 19 | collapsed: false, 20 | position: 'topright', 21 | text: 'Search', 22 | }); 23 | osmGeocoder.addTo(map); 24 | 25 | export { map, osm, editableLayers, drawnItems }; 26 | -------------------------------------------------------------------------------- /app/common/css/Control.OSMGeocoder.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-geocoder a { 2 | background-position: 50% 50%; 3 | background-repeat: no-repeat; 4 | display: block; 5 | } 6 | 7 | .leaflet-control-geocoder { 8 | margin-top: 40px !important; 9 | box-shadow: 0 1px 7px #999; 10 | background: #f8f8f9; 11 | -moz-border-radius: 8px; 12 | -webkit-border-radius: 8px; 13 | border-radius: 8px; 14 | } 15 | 16 | .leaflet-control-geocoder a { 17 | background-image: url(images/geocoder.png); 18 | width: 36px; 19 | height: 36px; 20 | } 21 | 22 | .leaflet-touch .leaflet-control-geocoder a { 23 | width: 44px; 24 | height: 44px; 25 | } 26 | 27 | .leaflet-control-geocoder .leaflet-control-geocoder-form, 28 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-toggle { 29 | display: none; 30 | } 31 | 32 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-form { 33 | display: block; 34 | position: relative; 35 | } 36 | 37 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-form { 38 | padding: 5px; 39 | } -------------------------------------------------------------------------------- /output/app/common/css/Control.OSMGeocoder.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-geocoder a { 2 | background-position: 50% 50%; 3 | background-repeat: no-repeat; 4 | display: block; 5 | } 6 | 7 | .leaflet-control-geocoder { 8 | margin-top: 40px !important; 9 | box-shadow: 0 1px 7px #999; 10 | background: #f8f8f9; 11 | -moz-border-radius: 8px; 12 | -webkit-border-radius: 8px; 13 | border-radius: 8px; 14 | } 15 | 16 | .leaflet-control-geocoder a { 17 | background-image: url(images/geocoder.png); 18 | width: 36px; 19 | height: 36px; 20 | } 21 | 22 | .leaflet-touch .leaflet-control-geocoder a { 23 | width: 44px; 24 | height: 44px; 25 | } 26 | 27 | .leaflet-control-geocoder .leaflet-control-geocoder-form, 28 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-toggle { 29 | display: none; 30 | } 31 | 32 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-form { 33 | display: block; 34 | position: relative; 35 | } 36 | 37 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-form { 38 | padding: 5px; 39 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Zhao Ruyi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/component/editbar.scss: -------------------------------------------------------------------------------- 1 | /* .e-item { 2 | width: 24px; 3 | height: 24px; 4 | // margin-top: 8px; 5 | } 6 | #editbar { 7 | display: inline-block; 8 | padding-left: 8px; 9 | border-left: solid 1px #ccc; 10 | border-right: solid 1px #ccc; 11 | div{ 12 | margin:3px 8px; 13 | display: inline-block; 14 | vertical-align: middle; 15 | &:hover { 16 | cursor: pointer; 17 | opacity: 0.6; 18 | } 19 | } 20 | } 21 | 22 | */ 23 | .sr-only{ 24 | display: none; 25 | } 26 | .leaflet-control-container .leaflet-top .leaflet-draw{ 27 | margin-top: 36px; 28 | } 29 | .leaflet-marker-icon.leaflet-div-icon.leaflet-editing-icon.leaflet-touch-icon{ 30 | margin-left: -7px !important; 31 | margin-top: -7px !important; 32 | width: 10px !important; 33 | height: 10px !important; 34 | } 35 | /* .leaflet-draw.leaflet-control{ 36 | position: absolute; 37 | left: 10%; 38 | } 39 | .leaflet-draw .leaflet-draw-section{ 40 | display: inline-block; 41 | } 42 | .leaflet-draw-toolbar.leaflet-bar.leaflet-draw-toolbar-top a{ 43 | display: inline-block; 44 | } */ -------------------------------------------------------------------------------- /app/component/toolbar.scss: -------------------------------------------------------------------------------- 1 | .t-item { 2 | width: 24px; 3 | height: 24px; 4 | // margin-top: 8px; 5 | background: url(../common/imgs/toolbar.png) no-repeat; 6 | } 7 | .leaflet-control-container .leaflet-top .leaflet-control-zoom{ 8 | margin-top: 36px; 9 | } 10 | 11 | .mapbar{ 12 | display: inline-block; 13 | padding-left: 8px; 14 | border-left: solid 1px #ccc; 15 | border-right: solid 1px #ccc; 16 | div { 17 | // padding: 0 8px; 18 | margin:3px 8px; 19 | display: inline-block; 20 | &:hover { 21 | cursor: pointer; 22 | opacity: 0.6; 23 | } 24 | } 25 | } 26 | 27 | .mapbar div{ 28 | width:23px; 29 | height:23px; 30 | } 31 | 32 | #toolbar { 33 | #pan { 34 | background-position: -30px -277px; 35 | } 36 | #zoomtoall { 37 | background-position: -30px -15px; 38 | } 39 | #distance { 40 | background-position: -30px -40px; 41 | } 42 | #area { 43 | background-position: -30px -63px; 44 | } 45 | #myposition{ 46 | background-position: -30px -87px; 47 | } 48 | #click2find{ 49 | background-position: -30px -135px; 50 | } 51 | #print2img{ 52 | background-position: -5px -87px; 53 | } 54 | #print2pdf{ 55 | background-position: -5px -108px; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "SET DEBUG=true && webpack-dev-server --history-api-fallback --progress --profile --inline --colors --hot --port 5000 --open", 8 | "build": "SET DEBUG=false && webpack -p --progress --profile --colors" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babel-core": "^6.24.0", 14 | "babel-loader": "^6.4.1", 15 | "babel-preset-es2015": "^6.24.0", 16 | "css-loader": "^0.27.3", 17 | "echarts": "^3.5.3", 18 | "fs": "^0.0.1-security", 19 | "html-webpack-plugin": "^2.28.0", 20 | "json-loader": "^0.5.4", 21 | "leaflet-dvf": "^0.3.1", 22 | "leaflet-easyprint": "^1.0.0", 23 | "leaflet-image": "^0.4.0", 24 | "moment": "^2.18.1", 25 | "node-sass": "^4.5.2", 26 | "path": "^0.12.7", 27 | "sass-loader": "^6.0.3", 28 | "stats.js": "^0.17.0", 29 | "style-loader": "^0.16.1", 30 | "url-loader": "^0.5.8", 31 | "webpack": "^2.3.2", 32 | "webpack-dev-server": "^2.4.2" 33 | }, 34 | "dependencies": { 35 | "autolinker": "^1.4.3", 36 | "jquery": "^3.2.1", 37 | "leaflet": "^1.0.3", 38 | "leaflet-control-geocoder": "^1.5.4", 39 | "leaflet-draw": "^0.4.9", 40 | "leaflet.measurecontrol": "^1.1.0", 41 | "proj4": "^2.4.3", 42 | "proj4leaflet": "^1.0.1", 43 | "projzh": "^0.5.0", 44 | "mapbox-gl": "^0.37.0", 45 | "mapbox-gl-leaflet": "^0.0.3" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /output/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Leaflet可视化平台 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 | 23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/common/css/images/spritesheet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /output/app/common/css/images/spritesheet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/common/plugin/echartsIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 自定义echarts的图例 3 | * by zry 4 | * @Date 2017-05-05 5 | */ 6 | import './echartsIcon.scss'; 7 | import L from 'leaflet'; 8 | import echarts from 'echarts'; 9 | /** 10 | * echartsIcon DivIcon 11 | * @param {L.map} map leaflet地图类 12 | * @param {[[],[]]} latlngs 坐标数组 13 | * @param {Object} option [配置对象] 14 | * 其中重要的是option.datas 传送数据,如: 15 | * option.datas = [ 16 | [ 17 | { value: 335, name: '直接访问' }, 18 | { value: 310, name: '邮件营销' }, 19 | { value: 234, name: '联盟广告' }, 20 | { value: 135, name: '视频广告' }, 21 | { value: 1548, name: '搜索引擎' } 22 | ], 23 | [ 24 | { value: 345, name: '直接访问' }, 25 | { value: 410, name: '邮件营销' }, 26 | { value: 244, name: '联盟广告' }, 27 | { value: 145, name: '视频广告' }, 28 | { value: 548, name: '搜索引擎' } 29 | ], 30 | [ 31 | { value: 445, name: '直接访问' }, 32 | { value: 410, name: '邮件营销' }, 33 | { value: 244, name: '联盟广告' }, 34 | { value: 145, name: '视频广告' }, 35 | { value: 148, name: '搜索引擎' } 36 | ], 37 | ]; 38 | */ 39 | function echartsIcon(map, latlngs, option) { 40 | for (var i = 0; i < latlngs.length; i++) { 41 | var latlng = latlngs[i]; 42 | var newClassName = 'icon-' + latlng.join('-'); 43 | var myIcon = L.divIcon({ 44 | className: 'my-div-icon', 45 | html: "
" 46 | }); 47 | // you can set .my-div-icon styles in CSS 48 | L.marker(latlng, { icon: myIcon }).addTo(map); 49 | 50 | var myChart = echarts.init(document.getElementsByClassName(newClassName)[0]); 51 | option.series[0].data = option.datas[i]; 52 | myChart.setOption(option); 53 | } 54 | } 55 | 56 | export default echartsIcon; 57 | -------------------------------------------------------------------------------- /output/app/common/plugin/echartsIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 自定义echarts的图例 3 | * by zry 4 | * @Date 2017-05-05 5 | */ 6 | import './echartsIcon.scss'; 7 | import L from 'leaflet'; 8 | import echarts from 'echarts'; 9 | /** 10 | * echartsIcon DivIcon 11 | * @param {L.map} map leaflet地图类 12 | * @param {[[],[]]} latlngs 坐标数组 13 | * @param {Object} option [配置对象] 14 | * 其中重要的是option.datas 传送数据,如: 15 | * option.datas = [ 16 | [ 17 | { value: 335, name: '直接访问' }, 18 | { value: 310, name: '邮件营销' }, 19 | { value: 234, name: '联盟广告' }, 20 | { value: 135, name: '视频广告' }, 21 | { value: 1548, name: '搜索引擎' } 22 | ], 23 | [ 24 | { value: 345, name: '直接访问' }, 25 | { value: 410, name: '邮件营销' }, 26 | { value: 244, name: '联盟广告' }, 27 | { value: 145, name: '视频广告' }, 28 | { value: 548, name: '搜索引擎' } 29 | ], 30 | [ 31 | { value: 445, name: '直接访问' }, 32 | { value: 410, name: '邮件营销' }, 33 | { value: 244, name: '联盟广告' }, 34 | { value: 145, name: '视频广告' }, 35 | { value: 148, name: '搜索引擎' } 36 | ], 37 | ]; 38 | */ 39 | function echartsIcon(map, latlngs, option) { 40 | for (var i = 0; i < latlngs.length; i++) { 41 | var latlng = latlngs[i]; 42 | var newClassName = 'icon-' + latlng.join('-'); 43 | var myIcon = L.divIcon({ 44 | className: 'my-div-icon', 45 | html: "
" 46 | }); 47 | // you can set .my-div-icon styles in CSS 48 | L.marker(latlng, { icon: myIcon }).addTo(map); 49 | 50 | var myChart = echarts.init(document.getElementsByClassName(newClassName)[0]); 51 | option.series[0].data = option.datas[i]; 52 | myChart.setOption(option); 53 | } 54 | } 55 | 56 | export default echartsIcon; 57 | -------------------------------------------------------------------------------- /app/common/css/_css-reset.scss: -------------------------------------------------------------------------------- 1 | /* 2 | KISSY CSS Reset 3 | 理念:清除和重置是紧密不可分的 4 | 特色:1.适应中文 2.基于最新主流浏览器 5 | 维护:玉伯(lifesinger@gmail.com), 正淳(ragecarrier@gmail.com) 6 | */ 7 | 8 | /* 清除内外边距 */ 9 | body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */ 10 | dl, dt, dd, ul, ol, li, /* list elements 列表元素 */ 11 | pre, /* text formatting elements 文本格式元素 */ 12 | fieldset, lengend, button, input, textarea, /* form elements 表单元素 */ 13 | th, td { /* table elements 表格元素 */ 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | /* 设置默认字体 */ 19 | body, 20 | button, input, select, textarea { /* for ie */ 21 | /*font: 12px/1 Tahoma, Helvetica, Arial, "宋体", sans-serif;*/ 22 | font: 12px/1 Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif; /* 用 ascii 字符表示,使得在任何编码下都无问题 */ 23 | } 24 | 25 | h1 { font-size: 18px; /* 18px / 12px = 1.5 */ } 26 | h2 { font-size: 16px; } 27 | h3 { font-size: 14px; } 28 | h4, h5, h6 { font-size: 100%; } 29 | 30 | address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */ 31 | code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 统一等宽字体 */ 32 | small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */ 33 | 34 | /* 重置列表元素 */ 35 | ul, ol { list-style: none; } 36 | 37 | /* 重置文本格式元素 */ 38 | a { text-decoration: none; } 39 | a:hover { text-decoration: underline; } 40 | 41 | abbr[title], acronym[title] { /* 注:1.ie6 不支持 abbr; 2.这里用了属性选择符,ie6 下无效果 */ 42 | border-bottom: 1px dotted; 43 | cursor: help; 44 | } 45 | 46 | q:before, q:after { content: ''; } 47 | 48 | /* 重置表单元素 */ 49 | legend { color: #000; } /* for ie6 */ 50 | fieldset, img { border: none; } /* img 搭车:让链接里的 img 无边框 */ 51 | /* 注:optgroup 无法扶正 */ 52 | button, input, select, textarea { 53 | font-size: 100%; /* 使得表单元素在 ie 下能继承字体大小 */ 54 | } 55 | 56 | /* 重置表格元素 */ 57 | table { 58 | border-collapse: collapse; 59 | border-spacing: 0; 60 | } 61 | 62 | /* 重置 hr */ 63 | hr { 64 | border: none; 65 | height: 1px; 66 | } 67 | 68 | /* 让非ie浏览器默认也显示垂直滚动条,防止因滚动条引起的闪烁 */ 69 | html { overflow-y: scroll; } -------------------------------------------------------------------------------- /output/app/common/css/_css-reset.scss: -------------------------------------------------------------------------------- 1 | /* 2 | KISSY CSS Reset 3 | 理念:清除和重置是紧密不可分的 4 | 特色:1.适应中文 2.基于最新主流浏览器 5 | 维护:玉伯(lifesinger@gmail.com), 正淳(ragecarrier@gmail.com) 6 | */ 7 | 8 | /* 清除内外边距 */ 9 | body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */ 10 | dl, dt, dd, ul, ol, li, /* list elements 列表元素 */ 11 | pre, /* text formatting elements 文本格式元素 */ 12 | fieldset, lengend, button, input, textarea, /* form elements 表单元素 */ 13 | th, td { /* table elements 表格元素 */ 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | /* 设置默认字体 */ 19 | body, 20 | button, input, select, textarea { /* for ie */ 21 | /*font: 12px/1 Tahoma, Helvetica, Arial, "宋体", sans-serif;*/ 22 | font: 12px/1 Tahoma, Helvetica, Arial, "\5b8b\4f53", sans-serif; /* 用 ascii 字符表示,使得在任何编码下都无问题 */ 23 | } 24 | 25 | h1 { font-size: 18px; /* 18px / 12px = 1.5 */ } 26 | h2 { font-size: 16px; } 27 | h3 { font-size: 14px; } 28 | h4, h5, h6 { font-size: 100%; } 29 | 30 | address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */ 31 | code, kbd, pre, samp, tt { font-family: "Courier New", Courier, monospace; } /* 统一等宽字体 */ 32 | small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */ 33 | 34 | /* 重置列表元素 */ 35 | ul, ol { list-style: none; } 36 | 37 | /* 重置文本格式元素 */ 38 | a { text-decoration: none; } 39 | a:hover { text-decoration: underline; } 40 | 41 | abbr[title], acronym[title] { /* 注:1.ie6 不支持 abbr; 2.这里用了属性选择符,ie6 下无效果 */ 42 | border-bottom: 1px dotted; 43 | cursor: help; 44 | } 45 | 46 | q:before, q:after { content: ''; } 47 | 48 | /* 重置表单元素 */ 49 | legend { color: #000; } /* for ie6 */ 50 | fieldset, img { border: none; } /* img 搭车:让链接里的 img 无边框 */ 51 | /* 注:optgroup 无法扶正 */ 52 | button, input, select, textarea { 53 | font-size: 100%; /* 使得表单元素在 ie 下能继承字体大小 */ 54 | } 55 | 56 | /* 重置表格元素 */ 57 | table { 58 | border-collapse: collapse; 59 | border-spacing: 0; 60 | } 61 | 62 | /* 重置 hr */ 63 | hr { 64 | border: none; 65 | height: 1px; 66 | } 67 | 68 | /* 让非ie浏览器默认也显示垂直滚动条,防止因滚动条引起的闪烁 */ 69 | html { overflow-y: scroll; } -------------------------------------------------------------------------------- /app/component/toolbar.js: -------------------------------------------------------------------------------- 1 | import './toolbar.scss'; 2 | 3 | // import L from 'leaflet'; 4 | import $ from 'jquery'; 5 | import config from './gConfig.js'; 6 | import {map} from './basemap.js'; 7 | import leafletImage from 'leaflet-image'; 8 | // import 'leaflet-easyprint'; 9 | 10 | import mControl from '../common/plugin/measureControl.js';//距离量算库,依赖于leaflet-draw 11 | import mAreaControl from '../common/plugin/measureAreaControl.js';//面积量算库 12 | import {addClickListenerToPrint} from '../common/plugin/easyPrint.js';//打印成pdf 13 | class Toolbar{ 14 | init(){ 15 | this._handlePan(); 16 | this._handleZoomToall(); 17 | this._handlePosition(); 18 | this._handlePrint(); 19 | 20 | L.control.measureControl().addTo(map); 21 | L.control.measureAreaControl().addTo(map); 22 | } 23 | _handlePrint(){ 24 | //生成图片 不支持绘制的图层 25 | $('#mapbar').on('click', '#print2img', (event)=> { 26 | // console.log(leafletImage); 27 | leafletImage(map, function(err, canvas) { 28 | var iframe = document.createElement('iframe');//或者img 29 | var dimensions = map.getSize(); 30 | iframe.width = dimensions.x; 31 | iframe.height = dimensions.y; 32 | iframe.src = canvas.toDataURL(); 33 | // iframe.crossOrigin = "Anonymous"; 34 | window.open(iframe.src); 35 | // document.getElementById('snapshot').innerHTML = ''; 36 | // document.getElementById('snapshot').appendChild(img); 37 | }); 38 | }); 39 | $('#mapbar').on('click', '#print2pdf', (event)=> { 40 | addClickListenerToPrint({ 41 | map:map, 42 | elementsToHide: 'p, h2,.leaflet-control-layers,.leaflet-control-container,#mapbar' 43 | }) 44 | }); 45 | } 46 | _handlePan(){ 47 | $('#mapbar').on('click', '#pan', (event)=> { 48 | console.log("平移"); 49 | }); 50 | } 51 | _handleZoomToall(){ 52 | $('#mapbar').on('click', '#zoomtoall', (event)=> { 53 | let mapOpt = config.mapOpt; 54 | map.flyTo(mapOpt.center||[30, 104],mapOpt.zoom||5); 55 | }); 56 | } 57 | _handlePosition(){ 58 | $('#mapbar').on('click', '#myposition', (event)=> { 59 | console.log("定位"); 60 | function onLocationFound(e) { 61 | var radius = e.accuracy / 2; 62 | console.log(e.latlng); 63 | map.flyTo(e.latlng,15); 64 | L.marker(e.latlng).addTo(map) 65 | .bindPopup("距离您" + radius + "米").openPopup(); 66 | L.circle(e.latlng, radius).addTo(map); 67 | } 68 | map.on('locationfound', onLocationFound); 69 | map.on('locationerror ', ()=>{ 70 | console.warn("定位失败"); 71 | }); 72 | map.locate({watch: true,timeout:1000}); 73 | }); 74 | } 75 | } 76 | 77 | export {Toolbar}; -------------------------------------------------------------------------------- /test/leaflet-mapserver.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | leaflet加载MapServer示例子 7 | 8 | 9 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/openlayers-mapserver.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | openlayers 3加载MapServer示例子 7 | 8 | 14 | 15 | 16 | 17 |
18 | 19 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var HtmlwebpackPlugin = require('html-webpack-plugin'); // 生成html文件 4 | 5 | var projectName = "leaflet-demo"; 6 | var assetsFolder = '/assets/' + projectName + '/'; 7 | var templateFolder = '/template/' + projectName + '/'; 8 | // 定义当前是否处于开发debug阶段 9 | var isDebug = JSON.stringify(JSON.parse(process.env.DEBUG || 'false')); 10 | 11 | // 根据isDebug变量定义相关config变量 12 | var configVarObj = {}; 13 | if(isDebug === 'true') { 14 | console.log('I am in debuging............'); 15 | configVarObj = { 16 | htmlPath: 'index.html', // 定义输出html文件路径 17 | // devtool: 'cheap-source-map' // 生成sourcemap,便于开发调试 18 | devtool: 'eval' // 生成sourcemap,便于开发调试 19 | }; 20 | } else { 21 | console.log('I am in releasing............'); 22 | configVarObj = { 23 | htmlPath: /*'./template/' + projectName +*/ '/index.html', // 定义输出html文件路径 24 | devtool: '' 25 | }; 26 | } 27 | 28 | module.exports = { 29 | context: path.join(__dirname, 'app'), 30 | entry:{ 31 | page: "./index.js" 32 | }, 33 | output: { 34 | // 文件输出目录 35 | path: path.resolve(__dirname, 'output'), 36 | // 输出文件名 37 | filename: /*assetsFolder +'js/'+*/ '[name].min.js?[hash]', 38 | // cmd、amd异步加载脚本配置名称 39 | // chunkFilename: templateFolder + 'js/[name].chunk.js?[hash]', 40 | publicPath: '' 41 | }, 42 | module: { 43 | loaders: [ 44 | { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },//支持es6 45 | // { test: /\.js?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } }, //同时支持es6 react 46 | {test: /\.(png|jpg|svg|gif)$/, loader: 'url-loader?limit=8192'}, 47 | { test: /\.css$/, loader: "style-loader!css-loader" }, 48 | { test: /\.scss$/, loader: "style-loader!css-loader!sass-loader" }, //sass加载器 49 | { test: /\.json$/,exclude: /node_modules/,loader: 'json-loader'}, 50 | ], 51 | // noParse: [path.join(__dirname, "dist/leaflet-src.js")] 52 | }, 53 | resolve: { 54 | extensions: ['.js', '.json'] 55 | }, 56 | 57 | plugins: [ 58 | // new webpack.NoErrorsPlugin(), //允许错误不打断程序 59 | new HtmlwebpackPlugin({ 60 | title:"leaflet-demo", 61 | template:path.join(__dirname,'./app/index.html'), 62 | filename:configVarObj.htmlPath,//最后编译的index.html文件路径 63 | minify: { 64 | minifyJS: true, 65 | removeComments: true, 66 | minifyCSS: true 67 | } 68 | }), 69 | new webpack.DefinePlugin({ 70 | __DEV__:isDebug 71 | }), 72 | new webpack.ProvidePlugin({ 73 | 74 | }) 75 | ], 76 | devtool: configVarObj.devtool 77 | }; 78 | -------------------------------------------------------------------------------- /app/common/css/Control.Geocoder.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-geocoder { 2 | margin-top: 40px !important; 3 | background: white; 4 | } 5 | 6 | .leaflet-control-geocoder a, .leaflet-control-geocoder .leaflet-control-geocoder-icon { 7 | border-bottom-left-radius: 4px; 8 | border-bottom-right-radius: 4px; 9 | border-bottom: none; 10 | display: inline-block; 11 | } 12 | 13 | .leaflet-control-geocoder .leaflet-control-geocoder-alternatives a { 14 | width: inherit; 15 | height: inherit; 16 | line-height: inherit; 17 | } 18 | 19 | .leaflet-control-geocoder a:hover, .leaflet-control-geocoder .leaflet-control-geocoder-icon:hover { 20 | border-bottom: none; 21 | display: inline-block; 22 | } 23 | 24 | .leaflet-control-geocoder-form { 25 | display: none; 26 | vertical-align: middle; 27 | } 28 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-form { 29 | display: inline-block; 30 | } 31 | .leaflet-control-geocoder-form input { 32 | font-size: 120%; 33 | border: 0; 34 | background-color: transparent; 35 | width: 246px; 36 | } 37 | .leaflet-control-geocoder-icon { 38 | width: 30px; 39 | height: 23px; 40 | background-image: url(images/geocoder.png); 41 | background-repeat: no-repeat; 42 | background-position: center; 43 | } 44 | .leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon { 45 | background-image: url(images/throbber.gif); 46 | } 47 | 48 | .leaflet-control-geocoder-form-no-error { 49 | display: none; 50 | } 51 | 52 | .leaflet-control-geocoder-form input:focus { 53 | outline: none; 54 | } 55 | 56 | .leaflet-control-geocoder-form button { 57 | display: none; 58 | } 59 | .leaflet-control-geocoder-error { 60 | margin-top: 8px; 61 | margin-left: 8px; 62 | display: block; 63 | color: #444; 64 | } 65 | .leaflet-control-geocoder-alternatives { 66 | display: block; 67 | width: 272px; 68 | list-style: none; 69 | padding: 0; 70 | margin: 0; 71 | } 72 | 73 | .leaflet-control-geocoder-alternatives-minimized { 74 | display: none; 75 | height: 0; 76 | } 77 | .leaflet-control-geocoder-alternatives li { 78 | white-space: nowrap; 79 | display: block; 80 | overflow: hidden; 81 | padding: 5px 8px; 82 | text-overflow: ellipsis; 83 | border-bottom: 1px solid #ccc; 84 | cursor: pointer; 85 | } 86 | 87 | .leaflet-control-geocoder-alternatives li a, .leaflet-control-geocoder-alternatives li a:hover { 88 | width: inherit; 89 | height: inherit; 90 | line-height: inherit; 91 | background: inherit; 92 | border-radius: inherit; 93 | text-align: left; 94 | } 95 | 96 | .leaflet-control-geocoder-alternatives li:last-child { 97 | border-bottom: none; 98 | } 99 | .leaflet-control-geocoder-alternatives li:hover, .leaflet-control-geocoder-selected { 100 | background-color: #f5f5f5; 101 | } 102 | .leaflet-control-geocoder-address-detail { 103 | 104 | } 105 | .leaflet-control-geocoder-address-context { 106 | color: #666; 107 | } -------------------------------------------------------------------------------- /output/app/common/css/Control.Geocoder.css: -------------------------------------------------------------------------------- 1 | .leaflet-control-geocoder { 2 | margin-top: 40px !important; 3 | background: white; 4 | } 5 | 6 | .leaflet-control-geocoder a, .leaflet-control-geocoder .leaflet-control-geocoder-icon { 7 | border-bottom-left-radius: 4px; 8 | border-bottom-right-radius: 4px; 9 | border-bottom: none; 10 | display: inline-block; 11 | } 12 | 13 | .leaflet-control-geocoder .leaflet-control-geocoder-alternatives a { 14 | width: inherit; 15 | height: inherit; 16 | line-height: inherit; 17 | } 18 | 19 | .leaflet-control-geocoder a:hover, .leaflet-control-geocoder .leaflet-control-geocoder-icon:hover { 20 | border-bottom: none; 21 | display: inline-block; 22 | } 23 | 24 | .leaflet-control-geocoder-form { 25 | display: none; 26 | vertical-align: middle; 27 | } 28 | .leaflet-control-geocoder-expanded .leaflet-control-geocoder-form { 29 | display: inline-block; 30 | } 31 | .leaflet-control-geocoder-form input { 32 | font-size: 120%; 33 | border: 0; 34 | background-color: transparent; 35 | width: 246px; 36 | } 37 | .leaflet-control-geocoder-icon { 38 | width: 30px; 39 | height: 23px; 40 | background-image: url(images/geocoder.png); 41 | background-repeat: no-repeat; 42 | background-position: center; 43 | } 44 | .leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon { 45 | background-image: url(images/throbber.gif); 46 | } 47 | 48 | .leaflet-control-geocoder-form-no-error { 49 | display: none; 50 | } 51 | 52 | .leaflet-control-geocoder-form input:focus { 53 | outline: none; 54 | } 55 | 56 | .leaflet-control-geocoder-form button { 57 | display: none; 58 | } 59 | .leaflet-control-geocoder-error { 60 | margin-top: 8px; 61 | margin-left: 8px; 62 | display: block; 63 | color: #444; 64 | } 65 | .leaflet-control-geocoder-alternatives { 66 | display: block; 67 | width: 272px; 68 | list-style: none; 69 | padding: 0; 70 | margin: 0; 71 | } 72 | 73 | .leaflet-control-geocoder-alternatives-minimized { 74 | display: none; 75 | height: 0; 76 | } 77 | .leaflet-control-geocoder-alternatives li { 78 | white-space: nowrap; 79 | display: block; 80 | overflow: hidden; 81 | padding: 5px 8px; 82 | text-overflow: ellipsis; 83 | border-bottom: 1px solid #ccc; 84 | cursor: pointer; 85 | } 86 | 87 | .leaflet-control-geocoder-alternatives li a, .leaflet-control-geocoder-alternatives li a:hover { 88 | width: inherit; 89 | height: inherit; 90 | line-height: inherit; 91 | background: inherit; 92 | border-radius: inherit; 93 | text-align: left; 94 | } 95 | 96 | .leaflet-control-geocoder-alternatives li:last-child { 97 | border-bottom: none; 98 | } 99 | .leaflet-control-geocoder-alternatives li:hover, .leaflet-control-geocoder-selected { 100 | background-color: #f5f5f5; 101 | } 102 | .leaflet-control-geocoder-address-detail { 103 | 104 | } 105 | .leaflet-control-geocoder-address-context { 106 | color: #666; 107 | } -------------------------------------------------------------------------------- /app/component/mapServer.js: -------------------------------------------------------------------------------- 1 | import './mapServer.scss'; 2 | 3 | import L from 'leaflet'; 4 | import { map } from './basemap.js'; 5 | import $ from 'jquery'; 6 | import Autolinker from 'autolinker'; 7 | import { json_china } from '../data/china.js'; 8 | 9 | class MapServer { 10 | init() { 11 | /*加载GeoJson的例子*/ 12 | $('#mapbar').on('click', '#json', (event) => { 13 | this.chinaJson(); 14 | }); 15 | } 16 | chinaJson() { 17 | function pop_0(feature, layer) { 18 | let popupContent = '\ 19 | \ 20 | \ 21 | \ 22 | \ 23 | \ 24 | \ 25 | \ 26 | \ 27 | \ 28 | \ 29 | \ 30 | \ 31 | \ 32 | \ 33 | \ 34 | \ 35 | \ 36 | \ 37 | \ 38 | \ 39 | \ 40 |
面积:' + (feature.properties['AREA'] !== null ? Autolinker.link(String(feature.properties['AREA'])) : '') + '
周长:' + (feature.properties['PERIMETER'] !== null ? Autolinker.link(String(feature.properties['PERIMETER'])) : '') + '
BOU2_4M_:' + (feature.properties['BOU2_4M_'] !== null ? Autolinker.link(String(feature.properties['BOU2_4M_'])) : '') + '
BOU2_4M_ID:' + (feature.properties['BOU2_4M_ID'] !== null ? Autolinker.link(String(feature.properties['BOU2_4M_ID'])) : '') + '
编号93:' + (feature.properties['ADCODE93'] !== null ? Autolinker.link(String(feature.properties['ADCODE93'])) : '') + '
编号99:' + (feature.properties['ADCODE99'] !== null ? Autolinker.link(String(feature.properties['ADCODE99'])) : '') + '
名称:' + (feature.properties['NAME'] !== null ? Autolinker.link(String(feature.properties['NAME'])) : '') + '
'; 41 | layer.bindPopup(popupContent); 42 | } 43 | 44 | function style_0() { 45 | return { 46 | pane: 'pane_0', 47 | opacity: 1, 48 | color: 'rgba(0,0,0,0.494117647059)', 49 | dashArray: '', 50 | lineCap: 'butt', 51 | lineJoin: 'miter', 52 | weight: 1.0, 53 | fillOpacity: 1, 54 | fillColor: 'rgba(64,98,210,0.494117647059)', 55 | } 56 | } 57 | map.createPane('pane_0'); 58 | map.getPane('pane_0').style.zIndex = 400; 59 | map.getPane('pane_0').style['mix-blend-mode'] = 'normal'; 60 | let layer_0 = new L.geoJson(json_china, { 61 | attribution: '', 62 | pane: 'pane_0', 63 | onEachFeature: pop_0, 64 | style: style_0 65 | }); 66 | 67 | map.addLayer(layer_0); 68 | 69 | 70 | } 71 | } 72 | 73 | export { MapServer }; 74 | -------------------------------------------------------------------------------- /app/common/plugin/echartsLegend.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 自定义echarts的图例 3 | * by zry 4 | * @Date 2017-05-05 5 | */ 6 | import L from 'leaflet'; 7 | import echarts from 'echarts'; 8 | /** 9 | * [echartsLegend description] 10 | * @param {L.map} map leaflet地图类 11 | * @param {Object} option [配置对象] 12 | * 13 | * 配置项 option = { 14 | orient: 'vertical', 15 | left: 'left', 16 | width: "90px", 17 | height: "140px", 18 | data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] 19 | }; 20 | */ 21 | function echartsLegend(map, option) { 22 | if(!option||!option.data){ 23 | console.warn("没有图例的数据或者图例数据不是数组"); 24 | return; 25 | } 26 | L.Control.echartsLegend().addTo(map); 27 | 28 | var dom = document.getElementsByClassName('leaflet-control-echarts-legend')[0]; 29 | dom.style.width = option.width || "90px"; 30 | dom.style.height = option.height || "140px"; 31 | var myLegendChart = echarts.init(dom); 32 | var legendOption = { 33 | legend: { 34 | orient:option.orient || 'vertical', 35 | left:option.left || 'left', 36 | data:option.data 37 | }, 38 | 39 | series: [{ 40 | type: 'pie', 41 | data: [], 42 | label: { 43 | normal: { 44 | show: false 45 | }, 46 | emphasis: { 47 | show: false 48 | } 49 | }, 50 | lableLine: { 51 | normal: { 52 | show: false 53 | }, 54 | emphasis: { 55 | show: false 56 | } 57 | }, 58 | itemStyle: { 59 | normal: { 60 | opacity: 0 61 | }, 62 | emphasis: { 63 | opacity: 0 64 | } 65 | } 66 | }] 67 | }; 68 | for (var i = 0; i < option.data.length; i++) { 69 | var datai = option.data[i]; 70 | legendOption.series[0].data.push({name:datai}); 71 | } 72 | myLegendChart.setOption(legendOption); 73 | } 74 | 75 | L.Control.EchartsLegend = L.Control.extend({ 76 | 77 | statics: { 78 | TITLE: '图例' 79 | }, 80 | options: { 81 | position: 'bottomright', 82 | }, 83 | initialize: function(options) { 84 | L.Control.prototype.initialize.call(this, options); 85 | 86 | }, 87 | onAdd: function(map) { 88 | var className = 'leaflet-control'; 89 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 90 | var link = L.DomUtil.create('div', className + '-echarts-legend', this._container); 91 | // link.href = '#'; 92 | link.title = L.Control.EchartsLegend.TITLE; 93 | 94 | return this._container; 95 | }, 96 | toggle: function() { 97 | if (this.handler.enabled()) { 98 | this.handler.disable.call(this.handler); 99 | } else { 100 | this.handler.enable.call(this.handler); 101 | } 102 | }, 103 | }); 104 | 105 | 106 | 107 | L.Control.echartsLegend = function(options) { 108 | return new L.Control.EchartsLegend(options); 109 | }; 110 | 111 | 112 | export default echartsLegend; 113 | -------------------------------------------------------------------------------- /output/app/common/plugin/echartsLegend.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 自定义echarts的图例 3 | * by zry 4 | * @Date 2017-05-05 5 | */ 6 | import L from 'leaflet'; 7 | import echarts from 'echarts'; 8 | /** 9 | * [echartsLegend description] 10 | * @param {L.map} map leaflet地图类 11 | * @param {Object} option [配置对象] 12 | * 13 | * 配置项 option = { 14 | orient: 'vertical', 15 | left: 'left', 16 | width: "90px", 17 | height: "140px", 18 | data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] 19 | }; 20 | */ 21 | function echartsLegend(map, option) { 22 | if(!option||!option.data){ 23 | console.warn("没有图例的数据或者图例数据不是数组"); 24 | return; 25 | } 26 | L.Control.echartsLegend().addTo(map); 27 | 28 | var dom = document.getElementsByClassName('leaflet-control-echarts-legend')[0]; 29 | dom.style.width = option.width || "90px"; 30 | dom.style.height = option.height || "140px"; 31 | var myLegendChart = echarts.init(dom); 32 | var legendOption = { 33 | legend: { 34 | orient:option.orient || 'vertical', 35 | left:option.left || 'left', 36 | data:option.data 37 | }, 38 | 39 | series: [{ 40 | type: 'pie', 41 | data: [], 42 | label: { 43 | normal: { 44 | show: false 45 | }, 46 | emphasis: { 47 | show: false 48 | } 49 | }, 50 | lableLine: { 51 | normal: { 52 | show: false 53 | }, 54 | emphasis: { 55 | show: false 56 | } 57 | }, 58 | itemStyle: { 59 | normal: { 60 | opacity: 0 61 | }, 62 | emphasis: { 63 | opacity: 0 64 | } 65 | } 66 | }] 67 | }; 68 | for (var i = 0; i < option.data.length; i++) { 69 | var datai = option.data[i]; 70 | legendOption.series[0].data.push({name:datai}); 71 | } 72 | myLegendChart.setOption(legendOption); 73 | } 74 | 75 | L.Control.EchartsLegend = L.Control.extend({ 76 | 77 | statics: { 78 | TITLE: '图例' 79 | }, 80 | options: { 81 | position: 'bottomright', 82 | }, 83 | initialize: function(options) { 84 | L.Control.prototype.initialize.call(this, options); 85 | 86 | }, 87 | onAdd: function(map) { 88 | var className = 'leaflet-control'; 89 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 90 | var link = L.DomUtil.create('div', className + '-echarts-legend', this._container); 91 | // link.href = '#'; 92 | link.title = L.Control.EchartsLegend.TITLE; 93 | 94 | return this._container; 95 | }, 96 | toggle: function() { 97 | if (this.handler.enabled()) { 98 | this.handler.disable.call(this.handler); 99 | } else { 100 | this.handler.enable.call(this.handler); 101 | } 102 | }, 103 | }); 104 | 105 | 106 | 107 | L.Control.echartsLegend = function(options) { 108 | return new L.Control.EchartsLegend(options); 109 | }; 110 | 111 | 112 | export default echartsLegend; 113 | -------------------------------------------------------------------------------- /app/component/editbar.js: -------------------------------------------------------------------------------- 1 | import './editbar.scss'; 2 | import '../common/css/leaflet.draw.css'; 3 | 4 | import {editableLayers} from './basemap.js' 5 | import draw from 'leaflet-draw'; //矢量画图工具 6 | 7 | class Editbar { 8 | init(map) { 9 | this._handleEdit(map); 10 | } 11 | _handleEdit(map) { 12 | 13 | map.addLayer(editableLayers); 14 | 15 | var MyCustomMarker = L.Icon.extend({ 16 | options: { 17 | shadowUrl: null, 18 | iconAnchor: new L.Point(12, 12), 19 | iconSize: new L.Point(16, 24), 20 | iconUrl: 'app/common/css/images/marker-icon.png' 21 | } 22 | }); 23 | 24 | var options = { 25 | position: 'topright', 26 | draw: { 27 | polyline: { 28 | shapeOptions: { 29 | color: '#f357a1', 30 | weight: 5 31 | } 32 | }, 33 | polygon: { 34 | showArea: true, //显示面积 35 | metric: true, 36 | allowIntersection: false, // Restricts shapes to simple polygons 37 | drawError: { 38 | color: '#e1e100', // Color the shape will turn when intersects 39 | message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect 40 | }, 41 | shapeOptions: { 42 | color: '#bada55' 43 | } 44 | }, 45 | circle: false, // Turns off this drawing tool 46 | rectangle: { 47 | metric: true, 48 | showArea: true, //显示面积 49 | shapeOptions: { 50 | clickable: false 51 | } 52 | }, 53 | marker: { 54 | icon: new MyCustomMarker() 55 | } 56 | }, 57 | edit: { 58 | featureGroup: editableLayers, //REQUIRED!! 59 | remove: true //是否有删除按钮 60 | } 61 | }; 62 | 63 | var drawControl = new L.Control.Draw(options); 64 | map.addControl(drawControl); 65 | console.info(L.DrawToolbar.TYPE); 66 | 67 | map.on(L.Draw.Event.CREATED, function(e) { 68 | var type = e.layerType, 69 | layer = e.layer; 70 | console.log("e(L.Draw.Event.CREATED)", e); 71 | var pos = e.layer._latlngs ? e.layer._latlngs : e.layer._latlng; 72 | // console.log("坐标", pos); 73 | if (document.getElementsByClassName("leaflet-draw-tooltip-subtext")[0]){ 74 | var area = document.getElementsByClassName("leaflet-draw-tooltip-subtext")[0].innerHTML; 75 | // console.log("面积", area); 76 | } 77 | //使用[GeoJSON.js](https://github.com/caseycesari/GeoJSON.js)转化为GeoJSON 78 | //leaflet 中有转化的方法toGeoJSON 79 | if (type === 'marker') { 80 | if(e.layer._latlng) layer.bindPopup('坐标:'+ e.layer._latlng); 81 | } else if (type === 'rectangle' || type === 'polygon') { 82 | if(area) layer.bindPopup('面积:'+area); 83 | } 84 | 85 | editableLayers.addLayer(layer); 86 | }); 87 | } 88 | } 89 | 90 | export { Editbar }; 91 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Leaflet可视化平台 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | 22 |
23 |
24 |
25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 70 |
71 |
72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/common/leaflet-plugin/leaflet.ChineseTmsProviders.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 增加百度地图 3 | * 4 | * 有问题 5 | * @Date 2017-05-08 6 | */ 7 | L.TileLayer.ChinaProvider = L.TileLayer.extend({ 8 | 9 | initialize: function(type, options) { // (type, Object) 10 | var providers = L.TileLayer.ChinaProvider.providers; 11 | 12 | var parts = type.split('.'); 13 | 14 | var providerName = parts[0]; 15 | var mapName = parts[1]; 16 | var mapType = parts[2]; 17 | 18 | var url = providers[providerName][mapName][mapType]; 19 | options.subdomains = providers[providerName].Subdomains; 20 | 21 | L.TileLayer.prototype.initialize.call(this, url, options); 22 | } 23 | }); 24 | 25 | L.TileLayer.ChinaProvider.providers = { 26 | /* Baidu:{ 27 | Normal: { 28 | Map: "http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl", 29 | }, 30 | Satellite: { 31 | Map: "http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46&udt=20150504&app=webearth2&v=009&udt=20150601", 32 | }, 33 | Subdomains: ["0","1", "2", "3", "4"] 34 | },*/ 35 | TianDiTu: { 36 | Normal: { 37 | Map: "http://t{s}.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}", 38 | Annotion: "http://t{s}.tianditu.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}", 39 | }, 40 | Satellite: { 41 | Map: "http://t{s}.tianditu.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}", 42 | Annotion: "http://t{s}.tianditu.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}", 43 | }, 44 | Terrain: { 45 | Map: "http://t{s}.tianditu.cn/DataServer?T=ter_w&X={x}&Y={y}&L={z}", 46 | Annotion: "http://t{s}.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}", 47 | }, 48 | Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] 49 | }, 50 | 51 | GaoDe: { 52 | Normal: { 53 | Map: 'http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', 54 | }, 55 | Satellite: { 56 | Map: 'http://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', 57 | Annotion: 'http://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}' 58 | }, 59 | Subdomains: ["1", "2", "3", "4"] 60 | }, 61 | 62 | Google: { 63 | Normal: { 64 | Map: "http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}" 65 | }, 66 | Satellite: { 67 | Map: "http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}", 68 | Road: "http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}" 69 | }, 70 | Subdomains: [] 71 | }, 72 | 73 | Geoq: { 74 | Normal: { 75 | Map: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}", 76 | Color: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetColor/MapServer/tile/{z}/{y}/{x}", 77 | PurplishBlue: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}", 78 | Gray: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}", 79 | Warm: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{y}/{x}", 80 | Cold: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetCold/MapServer/tile/{z}/{y}/{x}" 81 | }, 82 | Subdomains: [] 83 | 84 | } 85 | }; 86 | 87 | L.tileLayer.chinaProvider = function(type, options) { 88 | return new L.TileLayer.ChinaProvider(type, options); 89 | }; 90 | -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/leaflet.ChineseTmsProviders.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 增加百度地图 3 | * 4 | * 有问题 5 | * @Date 2017-05-08 6 | */ 7 | L.TileLayer.ChinaProvider = L.TileLayer.extend({ 8 | 9 | initialize: function(type, options) { // (type, Object) 10 | var providers = L.TileLayer.ChinaProvider.providers; 11 | 12 | var parts = type.split('.'); 13 | 14 | var providerName = parts[0]; 15 | var mapName = parts[1]; 16 | var mapType = parts[2]; 17 | 18 | var url = providers[providerName][mapName][mapType]; 19 | options.subdomains = providers[providerName].Subdomains; 20 | 21 | L.TileLayer.prototype.initialize.call(this, url, options); 22 | } 23 | }); 24 | 25 | L.TileLayer.ChinaProvider.providers = { 26 | /* Baidu:{ 27 | Normal: { 28 | Map: "http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl", 29 | }, 30 | Satellite: { 31 | Map: "http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46&udt=20150504&app=webearth2&v=009&udt=20150601", 32 | }, 33 | Subdomains: ["0","1", "2", "3", "4"] 34 | },*/ 35 | TianDiTu: { 36 | Normal: { 37 | Map: "http://t{s}.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}", 38 | Annotion: "http://t{s}.tianditu.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}", 39 | }, 40 | Satellite: { 41 | Map: "http://t{s}.tianditu.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}", 42 | Annotion: "http://t{s}.tianditu.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}", 43 | }, 44 | Terrain: { 45 | Map: "http://t{s}.tianditu.cn/DataServer?T=ter_w&X={x}&Y={y}&L={z}", 46 | Annotion: "http://t{s}.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}", 47 | }, 48 | Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] 49 | }, 50 | 51 | GaoDe: { 52 | Normal: { 53 | Map: 'http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', 54 | }, 55 | Satellite: { 56 | Map: 'http://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', 57 | Annotion: 'http://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}' 58 | }, 59 | Subdomains: ["1", "2", "3", "4"] 60 | }, 61 | 62 | Google: { 63 | Normal: { 64 | Map: "http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}" 65 | }, 66 | Satellite: { 67 | Map: "http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}", 68 | Road: "http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}" 69 | }, 70 | Subdomains: [] 71 | }, 72 | 73 | Geoq: { 74 | Normal: { 75 | Map: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}", 76 | Color: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetColor/MapServer/tile/{z}/{y}/{x}", 77 | PurplishBlue: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}", 78 | Gray: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}", 79 | Warm: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{y}/{x}", 80 | Cold: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetCold/MapServer/tile/{z}/{y}/{x}" 81 | }, 82 | Subdomains: [] 83 | 84 | } 85 | }; 86 | 87 | L.tileLayer.chinaProvider = function(type, options) { 88 | return new L.TileLayer.ChinaProvider(type, options); 89 | }; 90 | -------------------------------------------------------------------------------- /app/common/css/images/measure-control.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 60 | 63 | 70 | 75 | 80 | 85 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /app/common/plugin/images/measure-control.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 60 | 63 | 70 | 75 | 80 | 85 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /output/app/common/css/images/measure-control.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 60 | 63 | 70 | 75 | 80 | 85 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /output/app/common/plugin/images/measure-control.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 60 | 63 | 70 | 75 | 80 | 85 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /app/common/plugin/easyPrint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 打印 3 | * https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist/leaflet.easyPrint.js 4 | */ 5 | import L from 'leaflet'; 6 | 7 | L.Control.EasyPrint = L.Control.extend({ 8 | options: { 9 | title: 'Print map', 10 | position: 'topleft' 11 | }, 12 | 13 | onAdd: function() { 14 | var container = L.DomUtil.create('div', 'leaflet-control-easyPrint leaflet-bar leaflet-control'); 15 | 16 | this.link = L.DomUtil.create('a', 'leaflet-control-easyPrint-button leaflet-bar-part', container); 17 | this.link.id = "leafletEasyPrint"; 18 | this.link.title = this.options.title; 19 | 20 | L.DomEvent.addListener(this.link, 'click', printPage, this); 21 | L.DomEvent.disableClickPropagation(container); 22 | 23 | return container; 24 | } 25 | 26 | }); 27 | 28 | L.easyPrint = function(options) { 29 | addCSS() 30 | return new L.Control.EasyPrint(options); 31 | }; 32 | 33 | function printPage() { 34 | if (this.options.elementsToHide) { 35 | var htmlElementsToHide = document.querySelectorAll(this.options.elementsToHide); 36 | 37 | for (var i = 0; i < htmlElementsToHide.length; i++) { 38 | htmlElementsToHide[i].className = htmlElementsToHide[i].className + ' _epHidden'; 39 | } 40 | } 41 | this._map.fire("beforePrint"); 42 | window.print(); 43 | this._map.fire("afterPrint"); 44 | if (this.options.elementsToHide) { 45 | var htmlElementsToHide = document.querySelectorAll(this.options.elementsToHide); 46 | for (var i = 0; i < htmlElementsToHide.length; i++) { 47 | htmlElementsToHide[i].className = htmlElementsToHide[i].className.replace(' _epHidden', ''); 48 | } 49 | } 50 | } 51 | 52 | function addCSS() { 53 | var css = document.createElement("style"); 54 | css.type = "text/css"; 55 | css.innerHTML = ".leaflet-control-easyPrint a { \ 56 | background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPGc+Cgk8cGF0aCBkPSJNMTI4LDMyaDI1NnY2NEgxMjhWMzJ6IE00ODAsMTI4SDMyYy0xNy42LDAtMzIsMTQuNC0zMiwzMnYxNjBjMCwxNy42LDE0LjM5OCwzMiwzMiwzMmg5NnYxMjhoMjU2VjM1Mmg5NiAgIGMxNy42LDAsMzItMTQuNCwzMi0zMlYxNjBDNTEyLDE0Mi40LDQ5Ny42LDEyOCw0ODAsMTI4eiBNMzUyLDQ0OEgxNjBWMjg4aDE5MlY0NDh6IE00ODcuMTk5LDE3NmMwLDEyLjgxMy0xMC4zODcsMjMuMi0yMy4xOTcsMjMuMiAgIGMtMTIuODEyLDAtMjMuMjAxLTEwLjM4Ny0yMy4yMDEtMjMuMnMxMC4zODktMjMuMiwyMy4xOTktMjMuMkM0NzYuODE0LDE1Mi44LDQ4Ny4xOTksMTYzLjE4Nyw0ODcuMTk5LDE3NnoiIGZpbGw9IiMwMDAwMDAiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K); \ 57 | background-size:16px 16px; \ 58 | cursor: pointer; \ 59 | } \ 60 | ._epHidden{ \ 61 | display:none!important; \ 62 | } \ 63 | @media print { \ 64 | html {padding: 0px!important;} \ 65 | .leaflet-control-easyPrint-button{display: none!important;} \ 66 | }"; 67 | document.body.appendChild(css); 68 | } 69 | /*增加*/ 70 | function addClickListenerToPrint(options) { 71 | addCSS(); 72 | if (options.elementsToHide) { 73 | var htmlElementsToHide = document.querySelectorAll(options.elementsToHide); 74 | 75 | for (var i = 0; i < htmlElementsToHide.length; i++) { 76 | htmlElementsToHide[i].className = htmlElementsToHide[i].className + ' _epHidden'; 77 | } 78 | } 79 | options.map.fire("beforePrint"); 80 | window.print(); 81 | options.map.fire("afterPrint"); 82 | if (options.elementsToHide) { 83 | var htmlElementsToHide = document.querySelectorAll(options.elementsToHide); 84 | for (var i = 0; i < htmlElementsToHide.length; i++) { 85 | htmlElementsToHide[i].className = htmlElementsToHide[i].className.replace(' _epHidden', ''); 86 | } 87 | } 88 | } 89 | 90 | var easyPrint = L.easyPrint; 91 | 92 | export { easyPrint, addClickListenerToPrint }; 93 | -------------------------------------------------------------------------------- /output/app/common/plugin/easyPrint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 打印 3 | * https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist/leaflet.easyPrint.js 4 | */ 5 | import L from 'leaflet'; 6 | 7 | L.Control.EasyPrint = L.Control.extend({ 8 | options: { 9 | title: 'Print map', 10 | position: 'topleft' 11 | }, 12 | 13 | onAdd: function() { 14 | var container = L.DomUtil.create('div', 'leaflet-control-easyPrint leaflet-bar leaflet-control'); 15 | 16 | this.link = L.DomUtil.create('a', 'leaflet-control-easyPrint-button leaflet-bar-part', container); 17 | this.link.id = "leafletEasyPrint"; 18 | this.link.title = this.options.title; 19 | 20 | L.DomEvent.addListener(this.link, 'click', printPage, this); 21 | L.DomEvent.disableClickPropagation(container); 22 | 23 | return container; 24 | } 25 | 26 | }); 27 | 28 | L.easyPrint = function(options) { 29 | addCSS() 30 | return new L.Control.EasyPrint(options); 31 | }; 32 | 33 | function printPage() { 34 | if (this.options.elementsToHide) { 35 | var htmlElementsToHide = document.querySelectorAll(this.options.elementsToHide); 36 | 37 | for (var i = 0; i < htmlElementsToHide.length; i++) { 38 | htmlElementsToHide[i].className = htmlElementsToHide[i].className + ' _epHidden'; 39 | } 40 | } 41 | this._map.fire("beforePrint"); 42 | window.print(); 43 | this._map.fire("afterPrint"); 44 | if (this.options.elementsToHide) { 45 | var htmlElementsToHide = document.querySelectorAll(this.options.elementsToHide); 46 | for (var i = 0; i < htmlElementsToHide.length; i++) { 47 | htmlElementsToHide[i].className = htmlElementsToHide[i].className.replace(' _epHidden', ''); 48 | } 49 | } 50 | } 51 | 52 | function addCSS() { 53 | var css = document.createElement("style"); 54 | css.type = "text/css"; 55 | css.innerHTML = ".leaflet-control-easyPrint a { \ 56 | background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPGc+Cgk8cGF0aCBkPSJNMTI4LDMyaDI1NnY2NEgxMjhWMzJ6IE00ODAsMTI4SDMyYy0xNy42LDAtMzIsMTQuNC0zMiwzMnYxNjBjMCwxNy42LDE0LjM5OCwzMiwzMiwzMmg5NnYxMjhoMjU2VjM1Mmg5NiAgIGMxNy42LDAsMzItMTQuNCwzMi0zMlYxNjBDNTEyLDE0Mi40LDQ5Ny42LDEyOCw0ODAsMTI4eiBNMzUyLDQ0OEgxNjBWMjg4aDE5MlY0NDh6IE00ODcuMTk5LDE3NmMwLDEyLjgxMy0xMC4zODcsMjMuMi0yMy4xOTcsMjMuMiAgIGMtMTIuODEyLDAtMjMuMjAxLTEwLjM4Ny0yMy4yMDEtMjMuMnMxMC4zODktMjMuMiwyMy4xOTktMjMuMkM0NzYuODE0LDE1Mi44LDQ4Ny4xOTksMTYzLjE4Nyw0ODcuMTk5LDE3NnoiIGZpbGw9IiMwMDAwMDAiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K); \ 57 | background-size:16px 16px; \ 58 | cursor: pointer; \ 59 | } \ 60 | ._epHidden{ \ 61 | display:none!important; \ 62 | } \ 63 | @media print { \ 64 | html {padding: 0px!important;} \ 65 | .leaflet-control-easyPrint-button{display: none!important;} \ 66 | }"; 67 | document.body.appendChild(css); 68 | } 69 | /*增加*/ 70 | function addClickListenerToPrint(options) { 71 | addCSS(); 72 | if (options.elementsToHide) { 73 | var htmlElementsToHide = document.querySelectorAll(options.elementsToHide); 74 | 75 | for (var i = 0; i < htmlElementsToHide.length; i++) { 76 | htmlElementsToHide[i].className = htmlElementsToHide[i].className + ' _epHidden'; 77 | } 78 | } 79 | options.map.fire("beforePrint"); 80 | window.print(); 81 | options.map.fire("afterPrint"); 82 | if (options.elementsToHide) { 83 | var htmlElementsToHide = document.querySelectorAll(options.elementsToHide); 84 | for (var i = 0; i < htmlElementsToHide.length; i++) { 85 | htmlElementsToHide[i].className = htmlElementsToHide[i].className.replace(' _epHidden', ''); 86 | } 87 | } 88 | } 89 | 90 | var easyPrint = L.easyPrint; 91 | 92 | export { easyPrint, addClickListenerToPrint }; 93 | -------------------------------------------------------------------------------- /app/common/leaflet-plugin/lib/simpleheat.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (typeof module !== 'undefined') module.exports = simpleheat; 4 | 5 | function simpleheat(canvas) { 6 | if (!(this instanceof simpleheat)) return new simpleheat(canvas); 7 | 8 | this._canvas = canvas = typeof canvas === 'string' ? document.getElementById(canvas) : canvas; 9 | 10 | this._ctx = canvas.getContext('2d'); 11 | this._width = canvas.width; 12 | this._height = canvas.height; 13 | 14 | this._max = 1; 15 | this._data = []; 16 | } 17 | 18 | simpleheat.prototype = { 19 | 20 | defaultRadius: 25, 21 | 22 | defaultGradient: { 23 | 0.4: 'blue', 24 | 0.6: 'cyan', 25 | 0.7: 'lime', 26 | 0.8: 'yellow', 27 | 1.0: 'red' 28 | }, 29 | 30 | data: function (data) { 31 | this._data = data; 32 | return this; 33 | }, 34 | 35 | max: function (max) { 36 | this._max = max; 37 | return this; 38 | }, 39 | 40 | add: function (point) { 41 | this._data.push(point); 42 | return this; 43 | }, 44 | 45 | clear: function () { 46 | this._data = []; 47 | return this; 48 | }, 49 | 50 | radius: function (r, blur) { 51 | blur = blur === undefined ? 15 : blur; 52 | 53 | // create a grayscale blurred circle image that we'll use for drawing points 54 | var circle = this._circle = this._createCanvas(), 55 | ctx = circle.getContext('2d'), 56 | r2 = this._r = r + blur; 57 | 58 | circle.width = circle.height = r2 * 2; 59 | 60 | ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2; 61 | ctx.shadowBlur = blur; 62 | ctx.shadowColor = 'black'; 63 | 64 | ctx.beginPath(); 65 | ctx.arc(-r2, -r2, r, 0, Math.PI * 2, true); 66 | ctx.closePath(); 67 | ctx.fill(); 68 | 69 | return this; 70 | }, 71 | 72 | resize: function () { 73 | this._width = this._canvas.width; 74 | this._height = this._canvas.height; 75 | }, 76 | 77 | gradient: function (grad) { 78 | // create a 256x1 gradient that we'll use to turn a grayscale heatmap into a colored one 79 | var canvas = this._createCanvas(), 80 | ctx = canvas.getContext('2d'), 81 | gradient = ctx.createLinearGradient(0, 0, 0, 256); 82 | 83 | canvas.width = 1; 84 | canvas.height = 256; 85 | 86 | for (var i in grad) { 87 | gradient.addColorStop(+i, grad[i]); 88 | } 89 | 90 | ctx.fillStyle = gradient; 91 | ctx.fillRect(0, 0, 1, 256); 92 | 93 | this._grad = ctx.getImageData(0, 0, 1, 256).data; 94 | 95 | return this; 96 | }, 97 | 98 | draw: function (minOpacity) { 99 | if (!this._circle) this.radius(this.defaultRadius); 100 | if (!this._grad) this.gradient(this.defaultGradient); 101 | 102 | var ctx = this._ctx; 103 | 104 | ctx.clearRect(0, 0, this._width, this._height); 105 | 106 | // draw a grayscale heatmap by putting a blurred circle at each data point 107 | for (var i = 0, len = this._data.length, p; i < len; i++) { 108 | p = this._data[i]; 109 | ctx.globalAlpha = Math.max(p[2] / this._max, minOpacity === undefined ? 0.05 : minOpacity); 110 | ctx.drawImage(this._circle, p[0] - this._r, p[1] - this._r); 111 | } 112 | 113 | // colorize the heatmap, using opacity value of each pixel to get the right color from our gradient 114 | var colored = ctx.getImageData(0, 0, this._width, this._height); 115 | this._colorize(colored.data, this._grad); 116 | ctx.putImageData(colored, 0, 0); 117 | 118 | return this; 119 | }, 120 | 121 | _colorize: function (pixels, gradient) { 122 | for (var i = 0, len = pixels.length, j; i < len; i += 4) { 123 | j = pixels[i + 3] * 4; // get gradient color from opacity value 124 | 125 | if (j) { 126 | pixels[i] = gradient[j]; 127 | pixels[i + 1] = gradient[j + 1]; 128 | pixels[i + 2] = gradient[j + 2]; 129 | } 130 | } 131 | }, 132 | 133 | _createCanvas: function () { 134 | if (typeof document !== 'undefined') { 135 | return document.createElement('canvas'); 136 | } else { 137 | // create a new canvas instance in node.js 138 | // the canvas class needs to have a default constructor without any parameter 139 | return new this._canvas.constructor(); 140 | } 141 | } 142 | }; 143 | -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/lib/simpleheat.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (typeof module !== 'undefined') module.exports = simpleheat; 4 | 5 | function simpleheat(canvas) { 6 | if (!(this instanceof simpleheat)) return new simpleheat(canvas); 7 | 8 | this._canvas = canvas = typeof canvas === 'string' ? document.getElementById(canvas) : canvas; 9 | 10 | this._ctx = canvas.getContext('2d'); 11 | this._width = canvas.width; 12 | this._height = canvas.height; 13 | 14 | this._max = 1; 15 | this._data = []; 16 | } 17 | 18 | simpleheat.prototype = { 19 | 20 | defaultRadius: 25, 21 | 22 | defaultGradient: { 23 | 0.4: 'blue', 24 | 0.6: 'cyan', 25 | 0.7: 'lime', 26 | 0.8: 'yellow', 27 | 1.0: 'red' 28 | }, 29 | 30 | data: function (data) { 31 | this._data = data; 32 | return this; 33 | }, 34 | 35 | max: function (max) { 36 | this._max = max; 37 | return this; 38 | }, 39 | 40 | add: function (point) { 41 | this._data.push(point); 42 | return this; 43 | }, 44 | 45 | clear: function () { 46 | this._data = []; 47 | return this; 48 | }, 49 | 50 | radius: function (r, blur) { 51 | blur = blur === undefined ? 15 : blur; 52 | 53 | // create a grayscale blurred circle image that we'll use for drawing points 54 | var circle = this._circle = this._createCanvas(), 55 | ctx = circle.getContext('2d'), 56 | r2 = this._r = r + blur; 57 | 58 | circle.width = circle.height = r2 * 2; 59 | 60 | ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2; 61 | ctx.shadowBlur = blur; 62 | ctx.shadowColor = 'black'; 63 | 64 | ctx.beginPath(); 65 | ctx.arc(-r2, -r2, r, 0, Math.PI * 2, true); 66 | ctx.closePath(); 67 | ctx.fill(); 68 | 69 | return this; 70 | }, 71 | 72 | resize: function () { 73 | this._width = this._canvas.width; 74 | this._height = this._canvas.height; 75 | }, 76 | 77 | gradient: function (grad) { 78 | // create a 256x1 gradient that we'll use to turn a grayscale heatmap into a colored one 79 | var canvas = this._createCanvas(), 80 | ctx = canvas.getContext('2d'), 81 | gradient = ctx.createLinearGradient(0, 0, 0, 256); 82 | 83 | canvas.width = 1; 84 | canvas.height = 256; 85 | 86 | for (var i in grad) { 87 | gradient.addColorStop(+i, grad[i]); 88 | } 89 | 90 | ctx.fillStyle = gradient; 91 | ctx.fillRect(0, 0, 1, 256); 92 | 93 | this._grad = ctx.getImageData(0, 0, 1, 256).data; 94 | 95 | return this; 96 | }, 97 | 98 | draw: function (minOpacity) { 99 | if (!this._circle) this.radius(this.defaultRadius); 100 | if (!this._grad) this.gradient(this.defaultGradient); 101 | 102 | var ctx = this._ctx; 103 | 104 | ctx.clearRect(0, 0, this._width, this._height); 105 | 106 | // draw a grayscale heatmap by putting a blurred circle at each data point 107 | for (var i = 0, len = this._data.length, p; i < len; i++) { 108 | p = this._data[i]; 109 | ctx.globalAlpha = Math.max(p[2] / this._max, minOpacity === undefined ? 0.05 : minOpacity); 110 | ctx.drawImage(this._circle, p[0] - this._r, p[1] - this._r); 111 | } 112 | 113 | // colorize the heatmap, using opacity value of each pixel to get the right color from our gradient 114 | var colored = ctx.getImageData(0, 0, this._width, this._height); 115 | this._colorize(colored.data, this._grad); 116 | ctx.putImageData(colored, 0, 0); 117 | 118 | return this; 119 | }, 120 | 121 | _colorize: function (pixels, gradient) { 122 | for (var i = 0, len = pixels.length, j; i < len; i += 4) { 123 | j = pixels[i + 3] * 4; // get gradient color from opacity value 124 | 125 | if (j) { 126 | pixels[i] = gradient[j]; 127 | pixels[i + 1] = gradient[j + 1]; 128 | pixels[i + 2] = gradient[j + 2]; 129 | } 130 | } 131 | }, 132 | 133 | _createCanvas: function () { 134 | if (typeof document !== 'undefined') { 135 | return document.createElement('canvas'); 136 | } else { 137 | // create a new canvas instance in node.js 138 | // the canvas class needs to have a default constructor without any parameter 139 | return new this._canvas.constructor(); 140 | } 141 | } 142 | }; 143 | -------------------------------------------------------------------------------- /app/common/leaflet-plugin/L.MeasureAreaControl.js: -------------------------------------------------------------------------------- 1 | L.Polygon.Measure = L.Handler.extend({ 2 | includes: L.Mixin.Events, 3 | 4 | initialize: function(map, layers, isGeodesic){ 5 | L.Handler.prototype.initialize.call(this, map); 6 | this._layers = layers || null; 7 | this.isGeodesic = isGeodesic; 8 | }, 9 | 10 | enable: function(){ 11 | if(!this._enabled){ 12 | this.fire('enabled'); 13 | L.Handler.prototype.enable.call(this); 14 | } 15 | }, 16 | 17 | disable: function(){ 18 | if(this._enabled){ 19 | this.fire('disabled'); 20 | L.Handler.prototype.disable.call(this); 21 | } 22 | }, 23 | 24 | addHooks: function () { 25 | if (this._map) { 26 | this.bindEventListener(); 27 | } 28 | }, 29 | 30 | removeHooks: function () { 31 | if (this._map) { 32 | this.removeEventListener(); 33 | } 34 | }, 35 | 36 | bindEventListener: function () { 37 | var data = this._layers; 38 | for (var i in data) { 39 | data[i].layer.on('click', this.onElementClick, this); 40 | } 41 | }, 42 | 43 | removeEventListener: function(){ 44 | var data = this._layers; 45 | for (var i in data) { 46 | data[i].layer.off('click', this.onElementClick, this); 47 | } 48 | }, 49 | 50 | onElementClick: function(e) { 51 | var area = this.getArea(e); 52 | var popup = L.popup() 53 | .setLatLng(e.latlng) 54 | .setContent('

' + area + '

') 55 | .openOn(this._map); 56 | }, 57 | 58 | getArea: function(e){ 59 | var obj = e.target; 60 | var area = L.GeometryUtil.geodesicArea(obj.getLatLngs()); 61 | if(this.isGeodesic) 62 | return area.toFixed(2) + ' m2'; 63 | else 64 | return L.GeometryUtil.readableArea(area); 65 | } 66 | }); 67 | 68 | L.Control.MeasureArea = L.Control.extend({ 69 | 70 | statics: { 71 | TITLE: 'Measure area' 72 | }, 73 | options: { 74 | position: 'topleft', 75 | geodesic: true 76 | }, 77 | 78 | initialize: function (options, layers) { 79 | L.Control.prototype.initialize.call(this, options); 80 | 81 | this._layers = {}; 82 | for (var i in layers) { 83 | this.addLayer(layers[i]); 84 | } 85 | }, 86 | 87 | onAdd: function(map) { 88 | var className = 'leaflet-control'; 89 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 90 | var link = L.DomUtil.create('a', className+'-measure', this._container); 91 | link.href = '#'; 92 | link.title = L.Control.MeasureArea.TITLE; 93 | var i = L.DomUtil.create('i', 'fa fa-comment-o', link); 94 | 95 | this.handler = new L.Polygon.Measure(map, this._layers, this.options.geodesic); 96 | 97 | this.handler.on('enabled', function () { 98 | L.DomUtil.addClass(this._container, 'enabled'); 99 | }, this); 100 | 101 | this.handler.on('disabled', function () { 102 | L.DomUtil.removeClass(this._container, 'enabled'); 103 | }, this); 104 | 105 | L.DomEvent 106 | .addListener(link, 'click', L.DomEvent.stopPropagation) 107 | .addListener(link, 'click', L.DomEvent.preventDefault) 108 | .addListener(link, 'click', this.toggle, this); 109 | 110 | return this._container; 111 | }, 112 | 113 | 114 | addLayer: function (layers) { 115 | 116 | if (layers instanceof L.LayerGroup){ 117 | for (var i in layers._layers) { 118 | var layer = layers._layers[i]; 119 | if(layer instanceof L.Path && !(layer instanceof L.Circle)){ 120 | var id = L.stamp(layer); 121 | this._layers[id] = { 122 | layer: layer 123 | }; 124 | } 125 | } 126 | } else { 127 | if(layers instanceof L.Path && !(layers instanceof L.Circle)){ 128 | var id = L.stamp(layers); 129 | this._layers[id] = { 130 | layer: layers 131 | }; 132 | } 133 | } 134 | }, 135 | 136 | removeLayer: function (layers) { 137 | if (layers instanceof L.LayerGroup){ 138 | for (var i in layers._layers) { 139 | var layer = layers._layers[i]; 140 | var id = L.stamp(layer); 141 | delete this._layers[id]; 142 | } 143 | } else { 144 | var id = L.stamp(layers); 145 | delete this._layers[id]; 146 | } 147 | return this; 148 | }, 149 | 150 | toggle: function() { 151 | if (this.handler.enabled()) { 152 | this.handler.disable.call(this.handler); 153 | } else { 154 | this.handler.enable.call(this.handler); 155 | } 156 | }, 157 | }); 158 | 159 | L.Control.measureAreaControl = function (options, layers) { 160 | return new L.Control.MeasureArea(options, layers); 161 | }; 162 | 163 | -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/L.MeasureAreaControl.js: -------------------------------------------------------------------------------- 1 | L.Polygon.Measure = L.Handler.extend({ 2 | includes: L.Mixin.Events, 3 | 4 | initialize: function(map, layers, isGeodesic){ 5 | L.Handler.prototype.initialize.call(this, map); 6 | this._layers = layers || null; 7 | this.isGeodesic = isGeodesic; 8 | }, 9 | 10 | enable: function(){ 11 | if(!this._enabled){ 12 | this.fire('enabled'); 13 | L.Handler.prototype.enable.call(this); 14 | } 15 | }, 16 | 17 | disable: function(){ 18 | if(this._enabled){ 19 | this.fire('disabled'); 20 | L.Handler.prototype.disable.call(this); 21 | } 22 | }, 23 | 24 | addHooks: function () { 25 | if (this._map) { 26 | this.bindEventListener(); 27 | } 28 | }, 29 | 30 | removeHooks: function () { 31 | if (this._map) { 32 | this.removeEventListener(); 33 | } 34 | }, 35 | 36 | bindEventListener: function () { 37 | var data = this._layers; 38 | for (var i in data) { 39 | data[i].layer.on('click', this.onElementClick, this); 40 | } 41 | }, 42 | 43 | removeEventListener: function(){ 44 | var data = this._layers; 45 | for (var i in data) { 46 | data[i].layer.off('click', this.onElementClick, this); 47 | } 48 | }, 49 | 50 | onElementClick: function(e) { 51 | var area = this.getArea(e); 52 | var popup = L.popup() 53 | .setLatLng(e.latlng) 54 | .setContent('

' + area + '

') 55 | .openOn(this._map); 56 | }, 57 | 58 | getArea: function(e){ 59 | var obj = e.target; 60 | var area = L.GeometryUtil.geodesicArea(obj.getLatLngs()); 61 | if(this.isGeodesic) 62 | return area.toFixed(2) + ' m2'; 63 | else 64 | return L.GeometryUtil.readableArea(area); 65 | } 66 | }); 67 | 68 | L.Control.MeasureArea = L.Control.extend({ 69 | 70 | statics: { 71 | TITLE: 'Measure area' 72 | }, 73 | options: { 74 | position: 'topleft', 75 | geodesic: true 76 | }, 77 | 78 | initialize: function (options, layers) { 79 | L.Control.prototype.initialize.call(this, options); 80 | 81 | this._layers = {}; 82 | for (var i in layers) { 83 | this.addLayer(layers[i]); 84 | } 85 | }, 86 | 87 | onAdd: function(map) { 88 | var className = 'leaflet-control'; 89 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 90 | var link = L.DomUtil.create('a', className+'-measure', this._container); 91 | link.href = '#'; 92 | link.title = L.Control.MeasureArea.TITLE; 93 | var i = L.DomUtil.create('i', 'fa fa-comment-o', link); 94 | 95 | this.handler = new L.Polygon.Measure(map, this._layers, this.options.geodesic); 96 | 97 | this.handler.on('enabled', function () { 98 | L.DomUtil.addClass(this._container, 'enabled'); 99 | }, this); 100 | 101 | this.handler.on('disabled', function () { 102 | L.DomUtil.removeClass(this._container, 'enabled'); 103 | }, this); 104 | 105 | L.DomEvent 106 | .addListener(link, 'click', L.DomEvent.stopPropagation) 107 | .addListener(link, 'click', L.DomEvent.preventDefault) 108 | .addListener(link, 'click', this.toggle, this); 109 | 110 | return this._container; 111 | }, 112 | 113 | 114 | addLayer: function (layers) { 115 | 116 | if (layers instanceof L.LayerGroup){ 117 | for (var i in layers._layers) { 118 | var layer = layers._layers[i]; 119 | if(layer instanceof L.Path && !(layer instanceof L.Circle)){ 120 | var id = L.stamp(layer); 121 | this._layers[id] = { 122 | layer: layer 123 | }; 124 | } 125 | } 126 | } else { 127 | if(layers instanceof L.Path && !(layers instanceof L.Circle)){ 128 | var id = L.stamp(layers); 129 | this._layers[id] = { 130 | layer: layers 131 | }; 132 | } 133 | } 134 | }, 135 | 136 | removeLayer: function (layers) { 137 | if (layers instanceof L.LayerGroup){ 138 | for (var i in layers._layers) { 139 | var layer = layers._layers[i]; 140 | var id = L.stamp(layer); 141 | delete this._layers[id]; 142 | } 143 | } else { 144 | var id = L.stamp(layers); 145 | delete this._layers[id]; 146 | } 147 | return this; 148 | }, 149 | 150 | toggle: function() { 151 | if (this.handler.enabled()) { 152 | this.handler.disable.call(this.handler); 153 | } else { 154 | this.handler.enable.call(this.handler); 155 | } 156 | }, 157 | }); 158 | 159 | L.Control.measureAreaControl = function (options, layers) { 160 | return new L.Control.MeasureArea(options, layers); 161 | }; 162 | 163 | -------------------------------------------------------------------------------- /app/common/plugin/leaflet.baidu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Projection class for Baidu Spherical Mercator 3 | * 4 | * @class BaiduSphericalMercator 5 | */ 6 | L.Projection.BaiduSphericalMercator = { 7 | /** 8 | * Project latLng to point coordinate 9 | * 10 | * @method project 11 | * @param {Object} latLng coordinate for a point on earth 12 | * @return {Object} leafletPoint point coordinate of L.Point 13 | */ 14 | project: function(latLng) { 15 | var projection = new BMap.MercatorProjection(); 16 | var originalPoint = new BMap.Point(latLng.lng, latLng.lat); 17 | //var baiduPoint = window.translatePoint(originalPoint); 18 | var point = projection.lngLatToPoint(originalPoint); 19 | var leafletPoint = new L.Point(point.x, point.y); 20 | return leafletPoint; 21 | }, 22 | 23 | /** 24 | * unproject point coordinate to latLng 25 | * 26 | * @method unproject 27 | * @param {Object} bpoint baidu point coordinate 28 | * @return {Object} latitude and longitude 29 | */ 30 | unproject: function (bpoint) { 31 | var projection= new BMap.MercatorProjection(); 32 | var point = projection.pointToLngLat( 33 | new BMap.Pixel(bpoint.x, bpoint.y) 34 | ); 35 | var latLng = new L.LatLng(point.lat, point.lng); 36 | return latLng; 37 | }, 38 | 39 | /** 40 | * Don't know how it used currently. 41 | * 42 | * However, I guess this is the range of coordinate. 43 | * Range of pixel coordinate is gotten from 44 | * BMap.MercatorProjection.lngLatToPoint(180, -90) and (180, 90) 45 | * After getting max min value of pixel coordinate, use 46 | * pointToLngLat() get the max lat and Lng. 47 | */ 48 | bounds: (function () { 49 | var MAX_X= 20037726.37; 50 | var MIN_Y= -11708041.66; 51 | var MAX_Y= 12474104.17; 52 | var bounds = L.bounds( 53 | [-MAX_X, MIN_Y], //-180, -71.988531 54 | [MAX_X, MAX_Y] //180, 74.000022 55 | ); 56 | var MAX = 33554432; 57 | bounds = new L.Bounds( 58 | [-MAX, -MAX], 59 | [MAX, MAX] 60 | ); 61 | return bounds; 62 | })() 63 | }; 64 | 65 | /** 66 | * Coordinate system for Baidu EPSGB3857 67 | * 68 | * @class EPSGB3857 69 | */ 70 | L.CRS.EPSGB3857 = L.extend({}, L.CRS, { 71 | code: 'EPSG:B3857', 72 | projection: L.Projection.BaiduSphericalMercator, 73 | 74 | transformation: (function () { 75 | var z = -18 - 8; 76 | var scale = Math.pow(2, z); 77 | return new L.Transformation(scale, 0.5, -scale, 0.5); 78 | }()) 79 | }); 80 | 81 | /** 82 | * Tile layer for Baidu Map 83 | * 84 | * @class BaiduLayer 85 | */ 86 | L.TileLayer.BaiduLayer = L.TileLayer.extend({ 87 | statics: { 88 | attribution: '© 2014 Baidu - GS(2012)6003;- Data © NavInfo & CenNavi & DaoDaoTong' 89 | }, 90 | 91 | options: { 92 | minZoom: 3, 93 | maxZoom: 19 94 | }, 95 | 96 | initialize: function (type, options) { 97 | var desc = L.TileLayer.BaiduLayer.desc; 98 | type = type || 'Normal.Map'; 99 | var parts = type.split('.'); 100 | var mapName = parts[0], 101 | mapType = parts[1], 102 | mapStyle = parts[2]; 103 | var url = desc[mapName][mapType]; 104 | if(mapName === 'CustomStyle') { 105 | if(mapStyle) { 106 | url = url+'&customid='+mapStyle; 107 | }else if(options.styles) { 108 | url = url+'&styles='+options.styles; 109 | } 110 | } 111 | options = options || {}; 112 | options.subdomains = desc[mapName].subdomains || desc.subdomains; 113 | options.attribution = L.TileLayer.BaiduLayer.attribution; 114 | L.TileLayer.prototype.initialize.call(this, url, options); 115 | }, 116 | 117 | getTileUrl: function (coords) { 118 | var offset = Math.pow(2, coords.z - 1), 119 | x = coords.x - offset, 120 | y = offset - coords.y - 1, 121 | baiduCoords = L.point(x, y); 122 | baiduCoords.z = coords.z; 123 | return L.TileLayer.prototype.getTileUrl.call(this, baiduCoords); 124 | } 125 | }); 126 | 127 | L.TileLayer.BaiduLayer.desc = { 128 | Normal: { 129 | Map: 'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl' 130 | }, 131 | Satellite: { 132 | Map: 'http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46', 133 | Road: 'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl' 134 | }, 135 | CustomStyle: { 136 | Map: 'http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}', 137 | subdomains: '012' 138 | }, 139 | subdomains: '0123456789' 140 | }; 141 | 142 | L.tileLayer.baiduLayer = function (type, options) { 143 | return new L.TileLayer.BaiduLayer(type, options); 144 | }; -------------------------------------------------------------------------------- /output/app/common/plugin/leaflet.baidu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Projection class for Baidu Spherical Mercator 3 | * 4 | * @class BaiduSphericalMercator 5 | */ 6 | L.Projection.BaiduSphericalMercator = { 7 | /** 8 | * Project latLng to point coordinate 9 | * 10 | * @method project 11 | * @param {Object} latLng coordinate for a point on earth 12 | * @return {Object} leafletPoint point coordinate of L.Point 13 | */ 14 | project: function(latLng) { 15 | var projection = new BMap.MercatorProjection(); 16 | var originalPoint = new BMap.Point(latLng.lng, latLng.lat); 17 | //var baiduPoint = window.translatePoint(originalPoint); 18 | var point = projection.lngLatToPoint(originalPoint); 19 | var leafletPoint = new L.Point(point.x, point.y); 20 | return leafletPoint; 21 | }, 22 | 23 | /** 24 | * unproject point coordinate to latLng 25 | * 26 | * @method unproject 27 | * @param {Object} bpoint baidu point coordinate 28 | * @return {Object} latitude and longitude 29 | */ 30 | unproject: function (bpoint) { 31 | var projection= new BMap.MercatorProjection(); 32 | var point = projection.pointToLngLat( 33 | new BMap.Pixel(bpoint.x, bpoint.y) 34 | ); 35 | var latLng = new L.LatLng(point.lat, point.lng); 36 | return latLng; 37 | }, 38 | 39 | /** 40 | * Don't know how it used currently. 41 | * 42 | * However, I guess this is the range of coordinate. 43 | * Range of pixel coordinate is gotten from 44 | * BMap.MercatorProjection.lngLatToPoint(180, -90) and (180, 90) 45 | * After getting max min value of pixel coordinate, use 46 | * pointToLngLat() get the max lat and Lng. 47 | */ 48 | bounds: (function () { 49 | var MAX_X= 20037726.37; 50 | var MIN_Y= -11708041.66; 51 | var MAX_Y= 12474104.17; 52 | var bounds = L.bounds( 53 | [-MAX_X, MIN_Y], //-180, -71.988531 54 | [MAX_X, MAX_Y] //180, 74.000022 55 | ); 56 | var MAX = 33554432; 57 | bounds = new L.Bounds( 58 | [-MAX, -MAX], 59 | [MAX, MAX] 60 | ); 61 | return bounds; 62 | })() 63 | }; 64 | 65 | /** 66 | * Coordinate system for Baidu EPSGB3857 67 | * 68 | * @class EPSGB3857 69 | */ 70 | L.CRS.EPSGB3857 = L.extend({}, L.CRS, { 71 | code: 'EPSG:B3857', 72 | projection: L.Projection.BaiduSphericalMercator, 73 | 74 | transformation: (function () { 75 | var z = -18 - 8; 76 | var scale = Math.pow(2, z); 77 | return new L.Transformation(scale, 0.5, -scale, 0.5); 78 | }()) 79 | }); 80 | 81 | /** 82 | * Tile layer for Baidu Map 83 | * 84 | * @class BaiduLayer 85 | */ 86 | L.TileLayer.BaiduLayer = L.TileLayer.extend({ 87 | statics: { 88 | attribution: '© 2014 Baidu - GS(2012)6003;- Data © NavInfo & CenNavi & DaoDaoTong' 89 | }, 90 | 91 | options: { 92 | minZoom: 3, 93 | maxZoom: 19 94 | }, 95 | 96 | initialize: function (type, options) { 97 | var desc = L.TileLayer.BaiduLayer.desc; 98 | type = type || 'Normal.Map'; 99 | var parts = type.split('.'); 100 | var mapName = parts[0], 101 | mapType = parts[1], 102 | mapStyle = parts[2]; 103 | var url = desc[mapName][mapType]; 104 | if(mapName === 'CustomStyle') { 105 | if(mapStyle) { 106 | url = url+'&customid='+mapStyle; 107 | }else if(options.styles) { 108 | url = url+'&styles='+options.styles; 109 | } 110 | } 111 | options = options || {}; 112 | options.subdomains = desc[mapName].subdomains || desc.subdomains; 113 | options.attribution = L.TileLayer.BaiduLayer.attribution; 114 | L.TileLayer.prototype.initialize.call(this, url, options); 115 | }, 116 | 117 | getTileUrl: function (coords) { 118 | var offset = Math.pow(2, coords.z - 1), 119 | x = coords.x - offset, 120 | y = offset - coords.y - 1, 121 | baiduCoords = L.point(x, y); 122 | baiduCoords.z = coords.z; 123 | return L.TileLayer.prototype.getTileUrl.call(this, baiduCoords); 124 | } 125 | }); 126 | 127 | L.TileLayer.BaiduLayer.desc = { 128 | Normal: { 129 | Map: 'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl' 130 | }, 131 | Satellite: { 132 | Map: 'http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46', 133 | Road: 'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl' 134 | }, 135 | CustomStyle: { 136 | Map: 'http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}', 137 | subdomains: '012' 138 | }, 139 | subdomains: '0123456789' 140 | }; 141 | 142 | L.tileLayer.baiduLayer = function (type, options) { 143 | return new L.TileLayer.BaiduLayer(type, options); 144 | }; -------------------------------------------------------------------------------- /app/common/leaflet-plugin/leaflet.measurecontrol.js: -------------------------------------------------------------------------------- 1 | (function (factory, window) { 2 | // define an AMD module that relies on 'leaflet' 3 | if (typeof define === 'function' && define.amd) { 4 | define(['leaflet'], function (L) { 5 | factory(L, window.toGeoJSON); 6 | }); 7 | 8 | // define a Common JS module that relies on 'leaflet' 9 | } else if (typeof exports === 'object') { 10 | module.exports = function (L) { 11 | if (L === undefined) { 12 | if (typeof window !== 'undefined') { 13 | L = require('leaflet'); 14 | } 15 | } 16 | factory(L); 17 | return L; 18 | }; 19 | } else if (typeof window !== 'undefined' && window.L) { 20 | factory(window.L); 21 | } 22 | }(function (L) { 23 | L.Polyline.Measure = L.Draw.Polyline.extend({ 24 | addHooks: function () { 25 | L.Draw.Polyline.prototype.addHooks.call(this); 26 | if (this._map) { 27 | this._markerGroup = new L.LayerGroup(); 28 | this._map.addLayer(this._markerGroup); 29 | 30 | this._markers = []; 31 | this._map.on('click', this._onClick, this); 32 | this._startShape(); 33 | } 34 | }, 35 | 36 | removeHooks: function () { 37 | L.Draw.Polyline.prototype.removeHooks.call(this); 38 | 39 | this._clearHideErrorTimeout(); 40 | 41 | // !\ Still useful when control is disabled before any drawing (refactor needed?) 42 | this._map 43 | .off('pointermove', this._onMouseMove, this) 44 | .off('mousemove', this._onMouseMove, this) 45 | .off('click', this._onClick, this); 46 | 47 | this._clearGuides(); 48 | this._container.style.cursor = ''; 49 | 50 | this._removeShape(); 51 | }, 52 | 53 | _startShape: function () { 54 | this._drawing = true; 55 | this._poly = new L.Polyline([], this.options.shapeOptions); 56 | // this is added as a placeholder, if leaflet doesn't recieve 57 | // this when the tool is turned off all onclick events are removed 58 | this._poly._onClick = function () {}; 59 | 60 | this._container.style.cursor = 'crosshair'; 61 | 62 | this._updateTooltip(); 63 | this._map 64 | .on('pointermove', this._onMouseMove, this) 65 | .on('mousemove', this._onMouseMove, this); 66 | }, 67 | 68 | _finishShape: function () { 69 | this._drawing = false; 70 | 71 | this._cleanUpShape(); 72 | this._clearGuides(); 73 | 74 | this._updateTooltip(); 75 | 76 | this._map 77 | .off('pointermove', this._onMouseMove, this) 78 | .off('mousemove', this._onMouseMove, this); 79 | 80 | this._container.style.cursor = ''; 81 | }, 82 | 83 | _removeShape: function () { 84 | if (!this._poly) return; 85 | this._map.removeLayer(this._poly); 86 | delete this._poly; 87 | this._markers.splice(0); 88 | this._markerGroup.clearLayers(); 89 | }, 90 | 91 | _onClick: function () { 92 | if (!this._drawing) { 93 | this._removeShape(); 94 | this._startShape(); 95 | return; 96 | } 97 | }, 98 | 99 | _getTooltipText: function () { 100 | var labelText = L.Draw.Polyline.prototype._getTooltipText.call(this); 101 | if (!this._drawing) { 102 | labelText.text = ''; 103 | } 104 | return labelText; 105 | } 106 | }); 107 | 108 | L.Control.MeasureControl = L.Control.extend({ 109 | 110 | statics: { 111 | TITLE: 'Measure distances' 112 | }, 113 | options: { 114 | position: 'topleft', 115 | handler: {} 116 | }, 117 | 118 | toggle: function () { 119 | if (this.handler.enabled()) { 120 | this.handler.disable.call(this.handler); 121 | } else { 122 | this.handler.enable.call(this.handler); 123 | } 124 | }, 125 | 126 | onAdd: function (map) { 127 | var link = null; 128 | var className = 'leaflet-control-draw'; 129 | 130 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 131 | 132 | this.handler = new L.Polyline.Measure(map, this.options.handler); 133 | 134 | this.handler.on('enabled', function () { 135 | this.enabled = true; 136 | L.DomUtil.addClass(this._container, 'enabled'); 137 | }, this); 138 | 139 | this.handler.on('disabled', function () { 140 | delete this.enabled; 141 | L.DomUtil.removeClass(this._container, 'enabled'); 142 | }, this); 143 | 144 | link = L.DomUtil.create('a', className + '-measure', this._container); 145 | link.href = '#'; 146 | link.title = L.Control.MeasureControl.TITLE; 147 | 148 | L.DomEvent 149 | .addListener(link, 'click', L.DomEvent.stopPropagation) 150 | .addListener(link, 'click', L.DomEvent.preventDefault) 151 | .addListener(link, 'click', this.toggle, this); 152 | 153 | return this._container; 154 | } 155 | }); 156 | 157 | 158 | L.Map.mergeOptions({ 159 | measureControl: false 160 | }); 161 | 162 | 163 | L.Map.addInitHook(function () { 164 | if (this.options.measureControl) { 165 | this.measureControl = L.Control.measureControl().addTo(this); 166 | } 167 | }); 168 | 169 | 170 | L.Control.measureControl = function (options) { 171 | return new L.Control.MeasureControl(options); 172 | }; 173 | }, window)); 174 | -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/leaflet.measurecontrol.js: -------------------------------------------------------------------------------- 1 | (function (factory, window) { 2 | // define an AMD module that relies on 'leaflet' 3 | if (typeof define === 'function' && define.amd) { 4 | define(['leaflet'], function (L) { 5 | factory(L, window.toGeoJSON); 6 | }); 7 | 8 | // define a Common JS module that relies on 'leaflet' 9 | } else if (typeof exports === 'object') { 10 | module.exports = function (L) { 11 | if (L === undefined) { 12 | if (typeof window !== 'undefined') { 13 | L = require('leaflet'); 14 | } 15 | } 16 | factory(L); 17 | return L; 18 | }; 19 | } else if (typeof window !== 'undefined' && window.L) { 20 | factory(window.L); 21 | } 22 | }(function (L) { 23 | L.Polyline.Measure = L.Draw.Polyline.extend({ 24 | addHooks: function () { 25 | L.Draw.Polyline.prototype.addHooks.call(this); 26 | if (this._map) { 27 | this._markerGroup = new L.LayerGroup(); 28 | this._map.addLayer(this._markerGroup); 29 | 30 | this._markers = []; 31 | this._map.on('click', this._onClick, this); 32 | this._startShape(); 33 | } 34 | }, 35 | 36 | removeHooks: function () { 37 | L.Draw.Polyline.prototype.removeHooks.call(this); 38 | 39 | this._clearHideErrorTimeout(); 40 | 41 | // !\ Still useful when control is disabled before any drawing (refactor needed?) 42 | this._map 43 | .off('pointermove', this._onMouseMove, this) 44 | .off('mousemove', this._onMouseMove, this) 45 | .off('click', this._onClick, this); 46 | 47 | this._clearGuides(); 48 | this._container.style.cursor = ''; 49 | 50 | this._removeShape(); 51 | }, 52 | 53 | _startShape: function () { 54 | this._drawing = true; 55 | this._poly = new L.Polyline([], this.options.shapeOptions); 56 | // this is added as a placeholder, if leaflet doesn't recieve 57 | // this when the tool is turned off all onclick events are removed 58 | this._poly._onClick = function () {}; 59 | 60 | this._container.style.cursor = 'crosshair'; 61 | 62 | this._updateTooltip(); 63 | this._map 64 | .on('pointermove', this._onMouseMove, this) 65 | .on('mousemove', this._onMouseMove, this); 66 | }, 67 | 68 | _finishShape: function () { 69 | this._drawing = false; 70 | 71 | this._cleanUpShape(); 72 | this._clearGuides(); 73 | 74 | this._updateTooltip(); 75 | 76 | this._map 77 | .off('pointermove', this._onMouseMove, this) 78 | .off('mousemove', this._onMouseMove, this); 79 | 80 | this._container.style.cursor = ''; 81 | }, 82 | 83 | _removeShape: function () { 84 | if (!this._poly) return; 85 | this._map.removeLayer(this._poly); 86 | delete this._poly; 87 | this._markers.splice(0); 88 | this._markerGroup.clearLayers(); 89 | }, 90 | 91 | _onClick: function () { 92 | if (!this._drawing) { 93 | this._removeShape(); 94 | this._startShape(); 95 | return; 96 | } 97 | }, 98 | 99 | _getTooltipText: function () { 100 | var labelText = L.Draw.Polyline.prototype._getTooltipText.call(this); 101 | if (!this._drawing) { 102 | labelText.text = ''; 103 | } 104 | return labelText; 105 | } 106 | }); 107 | 108 | L.Control.MeasureControl = L.Control.extend({ 109 | 110 | statics: { 111 | TITLE: 'Measure distances' 112 | }, 113 | options: { 114 | position: 'topleft', 115 | handler: {} 116 | }, 117 | 118 | toggle: function () { 119 | if (this.handler.enabled()) { 120 | this.handler.disable.call(this.handler); 121 | } else { 122 | this.handler.enable.call(this.handler); 123 | } 124 | }, 125 | 126 | onAdd: function (map) { 127 | var link = null; 128 | var className = 'leaflet-control-draw'; 129 | 130 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 131 | 132 | this.handler = new L.Polyline.Measure(map, this.options.handler); 133 | 134 | this.handler.on('enabled', function () { 135 | this.enabled = true; 136 | L.DomUtil.addClass(this._container, 'enabled'); 137 | }, this); 138 | 139 | this.handler.on('disabled', function () { 140 | delete this.enabled; 141 | L.DomUtil.removeClass(this._container, 'enabled'); 142 | }, this); 143 | 144 | link = L.DomUtil.create('a', className + '-measure', this._container); 145 | link.href = '#'; 146 | link.title = L.Control.MeasureControl.TITLE; 147 | 148 | L.DomEvent 149 | .addListener(link, 'click', L.DomEvent.stopPropagation) 150 | .addListener(link, 'click', L.DomEvent.preventDefault) 151 | .addListener(link, 'click', this.toggle, this); 152 | 153 | return this._container; 154 | } 155 | }); 156 | 157 | 158 | L.Map.mergeOptions({ 159 | measureControl: false 160 | }); 161 | 162 | 163 | L.Map.addInitHook(function () { 164 | if (this.options.measureControl) { 165 | this.measureControl = L.Control.measureControl().addTo(this); 166 | } 167 | }); 168 | 169 | 170 | L.Control.measureControl = function (options) { 171 | return new L.Control.MeasureControl(options); 172 | }; 173 | }, window)); 174 | -------------------------------------------------------------------------------- /app/common/leaflet-plugin/Leaflet.dvf/css/dvf.css: -------------------------------------------------------------------------------- 1 | div.leaflet-div-icon { 2 | text-align: center; 3 | vertical-align: middle; 4 | border-radius: 4px; 5 | padding: 2px 2px 0px 2px; 6 | font-size: small; 7 | margin: 0px auto; 8 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | width: auto; 10 | background: '#fff'; 11 | background-color: #f5f5f5; 12 | background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); 13 | background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); 14 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); 15 | background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); 16 | background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); 17 | background-image: linear-gradient(top, #ffffff, #e6e6e6); 18 | background-repeat: repeat-x; 19 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); 20 | border-color: #e6e6e6 #e6e6e6 #bfbfbf; 21 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 22 | border: 1px solid #cccccc; 23 | border-bottom-color: #b3b3b3; 24 | -webkit-border-radius: 10px; 25 | -moz-border-radius: 10px; 26 | border-radius: 10px; 27 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 28 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 29 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 30 | } 31 | 32 | div.leaflet-div-icon div { 33 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 34 | margin: 0px; 35 | padding: 0px; 36 | line-height: 12px; 37 | } 38 | 39 | div.leaflet-div-icon div div { 40 | display: block; 41 | font-size: xx-small; 42 | } 43 | 44 | div.legend-content { 45 | margin: 0px; 46 | padding: 0px; 47 | } 48 | 49 | div.legend-box { 50 | width: 10px; 51 | height: 10px; 52 | display: inline-block; 53 | margin-right: 8px; 54 | border: solid 1px #000; 55 | margin-bottom: 0px; 56 | } 57 | 58 | div.leaflet-div-icon div div.legend-box { 59 | width: 5px; 60 | height: 5px; 61 | display: inline-block; 62 | margin-right: 4px; 63 | margin-bottom: 0px; 64 | } 65 | 66 | div.leaflet-div-icon div div.key { 67 | margin: 2px 4px 0px 0px; 68 | font-weight: bold; 69 | line-height: 10px; 70 | display: inline-block; 71 | } 72 | 73 | .data-layer-legend div { 74 | display: inline-block; 75 | font-size: small; 76 | } 77 | 78 | .data-layer-legend .legend-box, .data-layer-legend .key { 79 | vertical-align: middle; 80 | } 81 | 82 | .choropleth-text { 83 | font-size: x-small; 84 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 85 | vertical-align: middle; 86 | text-align: center; 87 | } 88 | 89 | .scale-bars i { 90 | vertical-align: bottom; 91 | display: inline-block; 92 | background-color: silver; 93 | height: 14px; 94 | } 95 | 96 | .min-value, .max-value { 97 | vertical-align: middle; 98 | width: 50px; 99 | } 100 | 101 | .min-value { 102 | text-align: right; 103 | margin-right: 6px; 104 | } 105 | 106 | .max-value { 107 | text-align: left; 108 | margin-left: 6px; 109 | } 110 | 111 | .scale-value { 112 | text-align: center; 113 | position: relative; 114 | } 115 | 116 | .data-layer-legend { 117 | padding: 8px 0px 0px 0px; 118 | } 119 | 120 | .scale-bars { 121 | vertical-align: middle; 122 | line-height: 10px; 123 | } 124 | 125 | .legend-title { 126 | font-weight: bold; 127 | } 128 | 129 | .leaflet-popup-content { 130 | overflow: auto; 131 | max-height: 300px; 132 | } 133 | 134 | .palette-element { 135 | display: inline-block; 136 | width: 12px; 137 | height: 14px; 138 | } 139 | 140 | .leaflet-control-legend { 141 | background-color: rgba(255, 255, 255, 0.7); 142 | padding: 0px; 143 | border-radius: 4px; 144 | -webkit-border-radius: 4px; 145 | -moz-border-radius: 4px; 146 | max-height: 70px; 147 | width: 268px; 148 | box-shadow: 0 1px 7px #999; 149 | overflow: hidden; 150 | } 151 | 152 | .leaflet-control-legend.larger { 153 | max-height: 50%; 154 | overflow: auto; 155 | } 156 | 157 | .leaflet-control-legend .legend { 158 | padding: 10px; 159 | } 160 | 161 | .leaflet-control-legend i { 162 | background-image: none; 163 | vertical-align: text-bottom; 164 | } 165 | 166 | .photo { 167 | width: 100%; 168 | height: 100%; 169 | padding: 2px; 170 | background-color: white; 171 | box-shadow: 2px 2px 3px rgba(100, 100, 100, 0.5); 172 | opacity: 0; 173 | -moz-transition: opacity 1s; /* Firefox 4 */ 174 | -webkit-transition: opacity 1s; /* Safari and Chrome */ 175 | -o-transition: opacity 1s; 176 | transition: opacity 1s; 177 | } 178 | 179 | .photo-info { 180 | background-color: rgba(0, 0, 0, 0.6); 181 | padding: 10px; 182 | position: absolute; 183 | top: 0px; 184 | color: white; 185 | margin: 2px; 186 | } 187 | 188 | .photo-link { 189 | float: right; 190 | height: 14px; 191 | } 192 | 193 | .author-link { 194 | margin-left: 2px; 195 | width: 400px; 196 | display: block; 197 | font-style: italic; 198 | font-weight: bold; 199 | } 200 | 201 | text.leaflet-svg-text { 202 | alignment-baseline: central; 203 | dominant-baseline: central; 204 | text-anchor: middle; 205 | } -------------------------------------------------------------------------------- /app/common/plugin/measureAreaControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 面积量算 3 | * 依赖 leaflet-draw(包括js和css) 4 | * by zry 5 | * @Date 2017-04-19 6 | */ 7 | import L from 'leaflet'; 8 | import draw from 'leaflet-draw'; //矢量画图工具 9 | import '../css/leaflet.draw.css'; 10 | import './measureAreaControl.css'; 11 | 12 | L.Polygon.Measure = L.Draw.Polygon.extend({ 13 | options: { 14 | showArea: true, 15 | shapeOptions: { 16 | stroke: true, 17 | color: '#ff0000', 18 | weight: 4, 19 | opacity: 0.5, 20 | fill: true, 21 | fillColor: null, //same as color by default 22 | fillOpacity: 0.2, 23 | clickable: true 24 | }, 25 | metric: true // Whether to use the metric measurement system or imperial 26 | }, 27 | addHooks: function() { 28 | L.Draw.Polyline.prototype.addHooks.call(this); 29 | if (this._map) { 30 | this._markerGroup = new L.LayerGroup(); 31 | this._map.addLayer(this._markerGroup); 32 | 33 | this._markers = []; 34 | this._bindAreaDrawListener(); 35 | } 36 | }, 37 | removeHooks: function() { 38 | L.Draw.Polyline.prototype.removeHooks.call(this); 39 | 40 | this._clearHideErrorTimeout(); 41 | 42 | this._clearGuides(); 43 | this._container.style.cursor = ''; 44 | this._unbindAreaDrawListener(); 45 | }, 46 | _bindAreaDrawListener:function(){ 47 | this._map.on(L.Draw.Event.CREATED, function(e) { 48 | this._showArea(e); 49 | },this); 50 | }, 51 | _unbindAreaDrawListener:function(){ 52 | this._map.off(L.Draw.Event.CREATED, function(e) { 53 | this._showArea(e); 54 | },this); 55 | }, 56 | _showArea:function(e){ 57 | var self = this; 58 | var type = e.layerType, 59 | layer = e.layer; 60 | window.ee =e; 61 | if (type === 'rectangle' || type === 'polygon') { 62 | if(!e.layer._latlngs) return; 63 | var pos = e.layer._latlngs[0] ; 64 | var area = L.GeometryUtil.readableArea(L.GeometryUtil.geodesicArea(pos),this.options.metric); 65 | console.log("area:",area); 66 | /*var tooltip = L.marker(pos[pos.length-1].lat,pos[pos.length-1].lng) 67 | .bindTooltip("hello").openTooltip();*/ 68 | var popup = L.popup() 69 | .setLatLng(pos[0]) 70 | .setContent('

' + "面积:"+area + '

') 71 | .openOn(self._map); 72 | } 73 | }, 74 | _getTooltipText: function() { 75 | var text, subtext; 76 | 77 | if (this._markers.length === 0) { 78 | text = "开始"||L.drawLocal.draw.handlers.polygon.tooltip.start; 79 | } else if (this._markers.length < 3) { 80 | text = "继续点击"||L.drawLocal.draw.handlers.polygon.tooltip.cont; 81 | } else { 82 | text = "双击结束"||L.drawLocal.draw.handlers.polygon.tooltip.end; 83 | subtext = ""; 84 | } 85 | 86 | return { 87 | text: text, 88 | } 89 | }, 90 | }); 91 | 92 | L.Control.MeasureAreaControl = L.Control.extend({ 93 | 94 | statics: { 95 | TITLE: '测量面积' 96 | }, 97 | options: { 98 | position: 'topleft', 99 | handler: {}, 100 | showArea: true 101 | }, 102 | 103 | toggle: function() { 104 | if (this.handler.enabled()) { 105 | this.handler.disable.call(this.handler); 106 | } else { 107 | this.handler.enable.call(this.handler); 108 | } 109 | }, 110 | //addTo(map) -->onAdd(map) 111 | onAdd: function(map) { 112 | var link = null; 113 | var className = 'leaflet-control-draw'; 114 | 115 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 116 | 117 | this.handler = new L.Polygon.Measure(map, this.options); 118 | 119 | this.handler.on('enabled', function() { 120 | this.enabled = true; 121 | L.DomUtil.addClass(this._container, 'enabled'); 122 | }, this); 123 | 124 | this.handler.on('disabled', function() { 125 | delete this.enabled; 126 | L.DomUtil.removeClass(this._container, 'enabled'); 127 | }, this); 128 | 129 | link = L.DomUtil.create('a', className + '-measure-area', this._container); 130 | link.href = '#'; 131 | link.title = L.Control.MeasureAreaControl.TITLE; 132 | 133 | L.DomEvent 134 | .addListener(link, 'click', L.DomEvent.stopPropagation) 135 | .addListener(link, 'click', L.DomEvent.preventDefault) 136 | .addListener(link, 'click', this.toggle, this); 137 | 138 | console.log("this.handler:", this.handler); 139 | return this._container; 140 | } 141 | }); 142 | 143 | 144 | L.Map.mergeOptions({ 145 | measureAreaControl: false 146 | }); 147 | 148 | /** 149 | * 如果配置中有measureAreaControl的话 150 | * 例如:var map = L.map('map', {measureAreaControl:true}); 151 | */ 152 | L.Map.addInitHook(function() { 153 | if (this.options.measureAreaControl) { 154 | this.measureAreaControl = L.Control.measureAreaControl().addTo(this); 155 | } 156 | }); 157 | 158 | 159 | L.control.measureAreaControl = function(options) { 160 | return new L.Control.MeasureAreaControl(options); 161 | }; 162 | 163 | export default L.control.measureAreaControl; 164 | -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/Leaflet.dvf/css/dvf.css: -------------------------------------------------------------------------------- 1 | div.leaflet-div-icon { 2 | text-align: center; 3 | vertical-align: middle; 4 | border-radius: 4px; 5 | padding: 2px 2px 0px 2px; 6 | font-size: small; 7 | margin: 0px auto; 8 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | width: auto; 10 | background: '#fff'; 11 | background-color: #f5f5f5; 12 | background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); 13 | background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); 14 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); 15 | background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); 16 | background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); 17 | background-image: linear-gradient(top, #ffffff, #e6e6e6); 18 | background-repeat: repeat-x; 19 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); 20 | border-color: #e6e6e6 #e6e6e6 #bfbfbf; 21 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 22 | border: 1px solid #cccccc; 23 | border-bottom-color: #b3b3b3; 24 | -webkit-border-radius: 10px; 25 | -moz-border-radius: 10px; 26 | border-radius: 10px; 27 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 28 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 29 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 30 | } 31 | 32 | div.leaflet-div-icon div { 33 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 34 | margin: 0px; 35 | padding: 0px; 36 | line-height: 12px; 37 | } 38 | 39 | div.leaflet-div-icon div div { 40 | display: block; 41 | font-size: xx-small; 42 | } 43 | 44 | div.legend-content { 45 | margin: 0px; 46 | padding: 0px; 47 | } 48 | 49 | div.legend-box { 50 | width: 10px; 51 | height: 10px; 52 | display: inline-block; 53 | margin-right: 8px; 54 | border: solid 1px #000; 55 | margin-bottom: 0px; 56 | } 57 | 58 | div.leaflet-div-icon div div.legend-box { 59 | width: 5px; 60 | height: 5px; 61 | display: inline-block; 62 | margin-right: 4px; 63 | margin-bottom: 0px; 64 | } 65 | 66 | div.leaflet-div-icon div div.key { 67 | margin: 2px 4px 0px 0px; 68 | font-weight: bold; 69 | line-height: 10px; 70 | display: inline-block; 71 | } 72 | 73 | .data-layer-legend div { 74 | display: inline-block; 75 | font-size: small; 76 | } 77 | 78 | .data-layer-legend .legend-box, .data-layer-legend .key { 79 | vertical-align: middle; 80 | } 81 | 82 | .choropleth-text { 83 | font-size: x-small; 84 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 85 | vertical-align: middle; 86 | text-align: center; 87 | } 88 | 89 | .scale-bars i { 90 | vertical-align: bottom; 91 | display: inline-block; 92 | background-color: silver; 93 | height: 14px; 94 | } 95 | 96 | .min-value, .max-value { 97 | vertical-align: middle; 98 | width: 50px; 99 | } 100 | 101 | .min-value { 102 | text-align: right; 103 | margin-right: 6px; 104 | } 105 | 106 | .max-value { 107 | text-align: left; 108 | margin-left: 6px; 109 | } 110 | 111 | .scale-value { 112 | text-align: center; 113 | position: relative; 114 | } 115 | 116 | .data-layer-legend { 117 | padding: 8px 0px 0px 0px; 118 | } 119 | 120 | .scale-bars { 121 | vertical-align: middle; 122 | line-height: 10px; 123 | } 124 | 125 | .legend-title { 126 | font-weight: bold; 127 | } 128 | 129 | .leaflet-popup-content { 130 | overflow: auto; 131 | max-height: 300px; 132 | } 133 | 134 | .palette-element { 135 | display: inline-block; 136 | width: 12px; 137 | height: 14px; 138 | } 139 | 140 | .leaflet-control-legend { 141 | background-color: rgba(255, 255, 255, 0.7); 142 | padding: 0px; 143 | border-radius: 4px; 144 | -webkit-border-radius: 4px; 145 | -moz-border-radius: 4px; 146 | max-height: 70px; 147 | width: 268px; 148 | box-shadow: 0 1px 7px #999; 149 | overflow: hidden; 150 | } 151 | 152 | .leaflet-control-legend.larger { 153 | max-height: 50%; 154 | overflow: auto; 155 | } 156 | 157 | .leaflet-control-legend .legend { 158 | padding: 10px; 159 | } 160 | 161 | .leaflet-control-legend i { 162 | background-image: none; 163 | vertical-align: text-bottom; 164 | } 165 | 166 | .photo { 167 | width: 100%; 168 | height: 100%; 169 | padding: 2px; 170 | background-color: white; 171 | box-shadow: 2px 2px 3px rgba(100, 100, 100, 0.5); 172 | opacity: 0; 173 | -moz-transition: opacity 1s; /* Firefox 4 */ 174 | -webkit-transition: opacity 1s; /* Safari and Chrome */ 175 | -o-transition: opacity 1s; 176 | transition: opacity 1s; 177 | } 178 | 179 | .photo-info { 180 | background-color: rgba(0, 0, 0, 0.6); 181 | padding: 10px; 182 | position: absolute; 183 | top: 0px; 184 | color: white; 185 | margin: 2px; 186 | } 187 | 188 | .photo-link { 189 | float: right; 190 | height: 14px; 191 | } 192 | 193 | .author-link { 194 | margin-left: 2px; 195 | width: 400px; 196 | display: block; 197 | font-style: italic; 198 | font-weight: bold; 199 | } 200 | 201 | text.leaflet-svg-text { 202 | alignment-baseline: central; 203 | dominant-baseline: central; 204 | text-anchor: middle; 205 | } -------------------------------------------------------------------------------- /output/app/common/plugin/measureAreaControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 面积量算 3 | * 依赖 leaflet-draw(包括js和css) 4 | * by zry 5 | * @Date 2017-04-19 6 | */ 7 | import L from 'leaflet'; 8 | import draw from 'leaflet-draw'; //矢量画图工具 9 | import '../css/leaflet.draw.css'; 10 | import './measureAreaControl.css'; 11 | 12 | L.Polygon.Measure = L.Draw.Polygon.extend({ 13 | options: { 14 | showArea: true, 15 | shapeOptions: { 16 | stroke: true, 17 | color: '#ff0000', 18 | weight: 4, 19 | opacity: 0.5, 20 | fill: true, 21 | fillColor: null, //same as color by default 22 | fillOpacity: 0.2, 23 | clickable: true 24 | }, 25 | metric: true // Whether to use the metric measurement system or imperial 26 | }, 27 | addHooks: function() { 28 | L.Draw.Polyline.prototype.addHooks.call(this); 29 | if (this._map) { 30 | this._markerGroup = new L.LayerGroup(); 31 | this._map.addLayer(this._markerGroup); 32 | 33 | this._markers = []; 34 | this._bindAreaDrawListener(); 35 | } 36 | }, 37 | removeHooks: function() { 38 | L.Draw.Polyline.prototype.removeHooks.call(this); 39 | 40 | this._clearHideErrorTimeout(); 41 | 42 | this._clearGuides(); 43 | this._container.style.cursor = ''; 44 | this._unbindAreaDrawListener(); 45 | }, 46 | _bindAreaDrawListener:function(){ 47 | this._map.on(L.Draw.Event.CREATED, function(e) { 48 | this._showArea(e); 49 | },this); 50 | }, 51 | _unbindAreaDrawListener:function(){ 52 | this._map.off(L.Draw.Event.CREATED, function(e) { 53 | this._showArea(e); 54 | },this); 55 | }, 56 | _showArea:function(e){ 57 | var self = this; 58 | var type = e.layerType, 59 | layer = e.layer; 60 | window.ee =e; 61 | if (type === 'rectangle' || type === 'polygon') { 62 | if(!e.layer._latlngs) return; 63 | var pos = e.layer._latlngs[0] ; 64 | var area = L.GeometryUtil.readableArea(L.GeometryUtil.geodesicArea(pos),this.options.metric); 65 | console.log("area:",area); 66 | /*var tooltip = L.marker(pos[pos.length-1].lat,pos[pos.length-1].lng) 67 | .bindTooltip("hello").openTooltip();*/ 68 | var popup = L.popup() 69 | .setLatLng(pos[0]) 70 | .setContent('

' + "面积:"+area + '

') 71 | .openOn(self._map); 72 | } 73 | }, 74 | _getTooltipText: function() { 75 | var text, subtext; 76 | 77 | if (this._markers.length === 0) { 78 | text = "开始"||L.drawLocal.draw.handlers.polygon.tooltip.start; 79 | } else if (this._markers.length < 3) { 80 | text = "继续点击"||L.drawLocal.draw.handlers.polygon.tooltip.cont; 81 | } else { 82 | text = "双击结束"||L.drawLocal.draw.handlers.polygon.tooltip.end; 83 | subtext = ""; 84 | } 85 | 86 | return { 87 | text: text, 88 | } 89 | }, 90 | }); 91 | 92 | L.Control.MeasureAreaControl = L.Control.extend({ 93 | 94 | statics: { 95 | TITLE: '测量面积' 96 | }, 97 | options: { 98 | position: 'topleft', 99 | handler: {}, 100 | showArea: true 101 | }, 102 | 103 | toggle: function() { 104 | if (this.handler.enabled()) { 105 | this.handler.disable.call(this.handler); 106 | } else { 107 | this.handler.enable.call(this.handler); 108 | } 109 | }, 110 | //addTo(map) -->onAdd(map) 111 | onAdd: function(map) { 112 | var link = null; 113 | var className = 'leaflet-control-draw'; 114 | 115 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 116 | 117 | this.handler = new L.Polygon.Measure(map, this.options); 118 | 119 | this.handler.on('enabled', function() { 120 | this.enabled = true; 121 | L.DomUtil.addClass(this._container, 'enabled'); 122 | }, this); 123 | 124 | this.handler.on('disabled', function() { 125 | delete this.enabled; 126 | L.DomUtil.removeClass(this._container, 'enabled'); 127 | }, this); 128 | 129 | link = L.DomUtil.create('a', className + '-measure-area', this._container); 130 | link.href = '#'; 131 | link.title = L.Control.MeasureAreaControl.TITLE; 132 | 133 | L.DomEvent 134 | .addListener(link, 'click', L.DomEvent.stopPropagation) 135 | .addListener(link, 'click', L.DomEvent.preventDefault) 136 | .addListener(link, 'click', this.toggle, this); 137 | 138 | console.log("this.handler:", this.handler); 139 | return this._container; 140 | } 141 | }); 142 | 143 | 144 | L.Map.mergeOptions({ 145 | measureAreaControl: false 146 | }); 147 | 148 | /** 149 | * 如果配置中有measureAreaControl的话 150 | * 例如:var map = L.map('map', {measureAreaControl:true}); 151 | */ 152 | L.Map.addInitHook(function() { 153 | if (this.options.measureAreaControl) { 154 | this.measureAreaControl = L.Control.measureAreaControl().addTo(this); 155 | } 156 | }); 157 | 158 | 159 | L.control.measureAreaControl = function(options) { 160 | return new L.Control.MeasureAreaControl(options); 161 | }; 162 | 163 | export default L.control.measureAreaControl; 164 | -------------------------------------------------------------------------------- /app/common/plugin/clickMeasureAreaControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 点击元素量算面积 基于L.MeasureAreaControl.js 3 | * [https://github.com/zvaraondrej/Leaflet.MeasureAreaControl] 4 | * by zry 5 | * @Date 2017-04-19 6 | */ 7 | import L from 'leaflet'; 8 | import './measureAreaControl.css'; 9 | 10 | L.Polygon.Measure = L.Handler.extend({ 11 | includes: L.Mixin.Events, 12 | 13 | initialize: function(map, layers, isGeodesic) { 14 | L.Handler.prototype.initialize.call(this, map); 15 | this._layers = layers || null; 16 | this.isGeodesic = isGeodesic; 17 | }, 18 | 19 | enable: function() { 20 | if (!this._enabled) { 21 | this.fire('enabled'); 22 | L.Handler.prototype.enable.call(this); 23 | } 24 | }, 25 | 26 | disable: function() { 27 | if (this._enabled) { 28 | this.fire('disabled'); 29 | L.Handler.prototype.disable.call(this); 30 | } 31 | }, 32 | 33 | addHooks: function() { 34 | if (this._map) { 35 | this.bindEventListener(); 36 | } 37 | }, 38 | 39 | removeHooks: function() { 40 | if (this._map) { 41 | this.removeEventListener(); 42 | } 43 | }, 44 | 45 | bindEventListener: function() { 46 | var data = this._layers; 47 | for (var i in data) { 48 | data[i].layer.on('click', this.onElementClick, this); 49 | } 50 | }, 51 | 52 | removeEventListener: function() { 53 | var data = this._layers; 54 | for (var i in data) { 55 | data[i].layer.off('click', this.onElementClick, this); 56 | } 57 | }, 58 | 59 | onElementClick: function(e) { 60 | var area = this.getArea(e); 61 | var popup = L.popup() 62 | .setLatLng(e.latlng) 63 | .setContent('

' + area + '

') 64 | .openOn(this._map); 65 | }, 66 | 67 | getArea: function(e) { 68 | var obj = e.target; 69 | var area = L.GeometryUtil.geodesicArea(obj.getLatLngs()); 70 | if (this.isGeodesic) 71 | return area.toFixed(2) + ' m2'; 72 | else 73 | return L.GeometryUtil.readableArea(area); 74 | } 75 | }); 76 | 77 | L.Control.MeasureArea = L.Control.extend({ 78 | 79 | statics: { 80 | TITLE: 'Measure area' 81 | }, 82 | options: { 83 | position: 'topleft', 84 | geodesic: true 85 | }, 86 | 87 | initialize: function(options, layers) { 88 | L.Control.prototype.initialize.call(this, options); 89 | 90 | this._layers = {}; 91 | for (var i in layers) { 92 | this.addLayer(layers[i]); 93 | } 94 | }, 95 | 96 | onAdd: function(map) { 97 | var className = 'leaflet-control'; 98 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 99 | var link = L.DomUtil.create('a', className + '-measure', this._container); 100 | link.href = '#'; 101 | link.title = L.Control.MeasureArea.TITLE; 102 | var i = L.DomUtil.create('i', 'fa fa-comment-o', link); 103 | 104 | this.handler = new L.Polygon.Measure(map, this._layers, this.options.geodesic); 105 | 106 | this.handler.on('enabled', function() { 107 | L.DomUtil.addClass(this._container, 'enabled'); 108 | }, this); 109 | 110 | this.handler.on('disabled', function() { 111 | L.DomUtil.removeClass(this._container, 'enabled'); 112 | }, this); 113 | 114 | L.DomEvent 115 | .addListener(link, 'click', L.DomEvent.stopPropagation) 116 | .addListener(link, 'click', L.DomEvent.preventDefault) 117 | .addListener(link, 'click', this.toggle, this); 118 | 119 | return this._container; 120 | }, 121 | 122 | 123 | addLayer: function(layers) { 124 | 125 | if (layers instanceof L.LayerGroup) { 126 | for (var i in layers._layers) { 127 | var layer = layers._layers[i]; 128 | if (layer instanceof L.Path && !(layer instanceof L.Circle)) { 129 | var id = L.stamp(layer); 130 | this._layers[id] = { 131 | layer: layer 132 | }; 133 | } 134 | } 135 | } else { 136 | if (layers instanceof L.Path && !(layers instanceof L.Circle)) { 137 | var id = L.stamp(layers); 138 | this._layers[id] = { 139 | layer: layers 140 | }; 141 | } 142 | } 143 | }, 144 | 145 | removeLayer: function(layers) { 146 | if (layers instanceof L.LayerGroup) { 147 | for (var i in layers._layers) { 148 | var layer = layers._layers[i]; 149 | var id = L.stamp(layer); 150 | delete this._layers[id]; 151 | } 152 | } else { 153 | var id = L.stamp(layers); 154 | delete this._layers[id]; 155 | } 156 | return this; 157 | }, 158 | 159 | toggle: function() { 160 | if (this.handler.enabled()) { 161 | this.handler.disable.call(this.handler); 162 | } else { 163 | this.handler.enable.call(this.handler); 164 | } 165 | }, 166 | }); 167 | 168 | /** 169 | * 如果配置中有measureAreaControl的话 170 | * 例如:var map = L.map('map', {measureAreaControl:true}); 171 | */ 172 | L.Map.addInitHook(function() { 173 | if (this.options.measureControl) { 174 | this.measureControl = L.Control.measureAreaControl().addTo(this); 175 | } 176 | }); 177 | 178 | L.Control.measureAreaControl = function(options, layers) { 179 | return new L.Control.MeasureArea(options, layers); 180 | }; 181 | 182 | export default L.control.measureAreaControl; 183 | -------------------------------------------------------------------------------- /output/app/common/plugin/clickMeasureAreaControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 点击元素量算面积 基于L.MeasureAreaControl.js 3 | * [https://github.com/zvaraondrej/Leaflet.MeasureAreaControl] 4 | * by zry 5 | * @Date 2017-04-19 6 | */ 7 | import L from 'leaflet'; 8 | import './measureAreaControl.css'; 9 | 10 | L.Polygon.Measure = L.Handler.extend({ 11 | includes: L.Mixin.Events, 12 | 13 | initialize: function(map, layers, isGeodesic) { 14 | L.Handler.prototype.initialize.call(this, map); 15 | this._layers = layers || null; 16 | this.isGeodesic = isGeodesic; 17 | }, 18 | 19 | enable: function() { 20 | if (!this._enabled) { 21 | this.fire('enabled'); 22 | L.Handler.prototype.enable.call(this); 23 | } 24 | }, 25 | 26 | disable: function() { 27 | if (this._enabled) { 28 | this.fire('disabled'); 29 | L.Handler.prototype.disable.call(this); 30 | } 31 | }, 32 | 33 | addHooks: function() { 34 | if (this._map) { 35 | this.bindEventListener(); 36 | } 37 | }, 38 | 39 | removeHooks: function() { 40 | if (this._map) { 41 | this.removeEventListener(); 42 | } 43 | }, 44 | 45 | bindEventListener: function() { 46 | var data = this._layers; 47 | for (var i in data) { 48 | data[i].layer.on('click', this.onElementClick, this); 49 | } 50 | }, 51 | 52 | removeEventListener: function() { 53 | var data = this._layers; 54 | for (var i in data) { 55 | data[i].layer.off('click', this.onElementClick, this); 56 | } 57 | }, 58 | 59 | onElementClick: function(e) { 60 | var area = this.getArea(e); 61 | var popup = L.popup() 62 | .setLatLng(e.latlng) 63 | .setContent('

' + area + '

') 64 | .openOn(this._map); 65 | }, 66 | 67 | getArea: function(e) { 68 | var obj = e.target; 69 | var area = L.GeometryUtil.geodesicArea(obj.getLatLngs()); 70 | if (this.isGeodesic) 71 | return area.toFixed(2) + ' m2'; 72 | else 73 | return L.GeometryUtil.readableArea(area); 74 | } 75 | }); 76 | 77 | L.Control.MeasureArea = L.Control.extend({ 78 | 79 | statics: { 80 | TITLE: 'Measure area' 81 | }, 82 | options: { 83 | position: 'topleft', 84 | geodesic: true 85 | }, 86 | 87 | initialize: function(options, layers) { 88 | L.Control.prototype.initialize.call(this, options); 89 | 90 | this._layers = {}; 91 | for (var i in layers) { 92 | this.addLayer(layers[i]); 93 | } 94 | }, 95 | 96 | onAdd: function(map) { 97 | var className = 'leaflet-control'; 98 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 99 | var link = L.DomUtil.create('a', className + '-measure', this._container); 100 | link.href = '#'; 101 | link.title = L.Control.MeasureArea.TITLE; 102 | var i = L.DomUtil.create('i', 'fa fa-comment-o', link); 103 | 104 | this.handler = new L.Polygon.Measure(map, this._layers, this.options.geodesic); 105 | 106 | this.handler.on('enabled', function() { 107 | L.DomUtil.addClass(this._container, 'enabled'); 108 | }, this); 109 | 110 | this.handler.on('disabled', function() { 111 | L.DomUtil.removeClass(this._container, 'enabled'); 112 | }, this); 113 | 114 | L.DomEvent 115 | .addListener(link, 'click', L.DomEvent.stopPropagation) 116 | .addListener(link, 'click', L.DomEvent.preventDefault) 117 | .addListener(link, 'click', this.toggle, this); 118 | 119 | return this._container; 120 | }, 121 | 122 | 123 | addLayer: function(layers) { 124 | 125 | if (layers instanceof L.LayerGroup) { 126 | for (var i in layers._layers) { 127 | var layer = layers._layers[i]; 128 | if (layer instanceof L.Path && !(layer instanceof L.Circle)) { 129 | var id = L.stamp(layer); 130 | this._layers[id] = { 131 | layer: layer 132 | }; 133 | } 134 | } 135 | } else { 136 | if (layers instanceof L.Path && !(layers instanceof L.Circle)) { 137 | var id = L.stamp(layers); 138 | this._layers[id] = { 139 | layer: layers 140 | }; 141 | } 142 | } 143 | }, 144 | 145 | removeLayer: function(layers) { 146 | if (layers instanceof L.LayerGroup) { 147 | for (var i in layers._layers) { 148 | var layer = layers._layers[i]; 149 | var id = L.stamp(layer); 150 | delete this._layers[id]; 151 | } 152 | } else { 153 | var id = L.stamp(layers); 154 | delete this._layers[id]; 155 | } 156 | return this; 157 | }, 158 | 159 | toggle: function() { 160 | if (this.handler.enabled()) { 161 | this.handler.disable.call(this.handler); 162 | } else { 163 | this.handler.enable.call(this.handler); 164 | } 165 | }, 166 | }); 167 | 168 | /** 169 | * 如果配置中有measureAreaControl的话 170 | * 例如:var map = L.map('map', {measureAreaControl:true}); 171 | */ 172 | L.Map.addInitHook(function() { 173 | if (this.options.measureControl) { 174 | this.measureControl = L.Control.measureAreaControl().addTo(this); 175 | } 176 | }); 177 | 178 | L.Control.measureAreaControl = function(options, layers) { 179 | return new L.Control.MeasureArea(options, layers); 180 | }; 181 | 182 | export default L.control.measureAreaControl; 183 | -------------------------------------------------------------------------------- /app/common/leaflet-plugin/Control.OSMGeocoder.js: -------------------------------------------------------------------------------- 1 | if (typeof console == "undefined") { 2 | this.console = { log: function (msg) { /* do nothing since it would otherwise break IE */} }; 3 | } 4 | 5 | 6 | L.Control.OSMGeocoder = L.Control.extend({ 7 | options: { 8 | collapsed: true, 9 | position: 'topright', 10 | text: 'Locate', 11 | placeholder: '', 12 | bounds: null, // L.LatLngBounds 13 | email: null, // String 14 | callback: function (results) { 15 | if (results.length == 0) { 16 | console.log("ERROR: didn't find a result"); 17 | return; 18 | } 19 | var bbox = results[0].boundingbox, 20 | first = new L.LatLng(bbox[0], bbox[2]), 21 | second = new L.LatLng(bbox[1], bbox[3]), 22 | bounds = new L.LatLngBounds([first, second]); 23 | this._map.fitBounds(bounds); 24 | } 25 | }, 26 | 27 | _callbackId: 0, 28 | 29 | initialize: function (options) { 30 | L.Util.setOptions(this, options); 31 | }, 32 | 33 | onAdd: function (map) { 34 | this._map = map; 35 | 36 | var className = 'leaflet-control-geocoder', 37 | container = this._container = L.DomUtil.create('div', className); 38 | 39 | L.DomEvent.disableClickPropagation(container); 40 | 41 | var form = this._form = L.DomUtil.create('form', className + '-form'); 42 | 43 | var input = this._input = document.createElement('input'); 44 | input.type = "text"; 45 | input.placeholder = this.options.placeholder || ''; 46 | 47 | var submit = document.createElement('input'); 48 | submit.type = "submit"; 49 | submit.value = this.options.text; 50 | 51 | form.appendChild(input); 52 | form.appendChild(submit); 53 | 54 | L.DomEvent.addListener(form, 'submit', this._geocode, this); 55 | 56 | if (this.options.collapsed) { 57 | L.DomEvent.addListener(container, 'mouseover', this._expand, this); 58 | L.DomEvent.addListener(container, 'mouseout', this._collapse, this); 59 | 60 | var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container); 61 | link.href = '#'; 62 | link.title = 'Nominatim Geocoder'; 63 | 64 | L.DomEvent.addListener(link, L.Browser.touch ? 'click' : 'focus', this._expand, this); 65 | 66 | this._map.on('movestart', this._collapse, this); 67 | } else { 68 | this._expand(); 69 | } 70 | 71 | container.appendChild(form); 72 | 73 | return container; 74 | }, 75 | 76 | /* helper functions for cordinate extraction */ 77 | _createSearchResult : function(lat, lon) { 78 | //creates an position description similar to the result of a Nominatim search 79 | var diff = 0.005; 80 | var result = []; 81 | result[0] = {}; 82 | result[0]["boundingbox"] = [parseFloat(lat)-diff,parseFloat(lat)+diff,parseFloat(lon)-diff,parseFloat(lon)+diff]; 83 | result[0]["class"]="boundary"; 84 | result[0]["display_name"]="Position: "+lat+" "+lon; 85 | result[0]["lat"] = lat; 86 | result[0]["lon"] = lon; 87 | return result; 88 | }, 89 | _isLatLon : function (q) { 90 | //"lon lat" => xx.xxx x.xxxxx 91 | var re = /(-?\d+\.\d+)\s(-?\d+\.\d+)/; 92 | var m = re.exec(q); 93 | if (m != undefined) return m; 94 | 95 | //lat...xx.xxx...lon...x.xxxxx 96 | re = /lat\D*(-?\d+\.\d+)\D*lon\D*(-?\d+\.\d+)/; 97 | m = re.exec(q); 98 | //showRegExpResult(m); 99 | if (m != undefined) return m; 100 | else return null; 101 | }, 102 | _isLatLon_decMin : function (q) { 103 | console.log("is LatLon?: "+q); 104 | //N 53° 13.785' E 010° 23.887' 105 | //re = /[NS]\s*(\d+)\D*(\d+\.\d+).?\s*[EW]\s*(\d+)\D*(\d+\.\d+)\D*/; 106 | re = /([ns])\s*(\d+)\D*(\d+\.\d+).?\s*([ew])\s*(\d+)\D*(\d+\.\d+)/i; 107 | m = re.exec(q.toLowerCase()); 108 | //showRegExpResult(m); 109 | if ((m != undefined)) return m; 110 | else return null; 111 | // +- dec min +- dec min 112 | }, 113 | 114 | _geocode : function (event) { 115 | L.DomEvent.preventDefault(event); 116 | var q = this._input.value; 117 | //try to find corrdinates 118 | if (this._isLatLon(q) != null) 119 | { 120 | var m = this._isLatLon(q); 121 | console.log("LatLon: "+m[1]+" "+m[2]); 122 | //m = {lon, lat} 123 | this.options.callback.call(this, this._createSearchResult(m[1],m[2])); 124 | return; 125 | } 126 | else if (this._isLatLon_decMin(q) != null) 127 | { 128 | var m = this._isLatLon_decMin(q); 129 | //m: [ns, lat dec, lat min, ew, lon dec, lon min] 130 | var temp = new Array(); 131 | temp['n'] = 1; 132 | temp['s'] = -1; 133 | temp['e'] = 1; 134 | temp['w'] = -1; 135 | this.options.callback.call(this,this._createSearchResult( 136 | temp[m[1]]*(Number(m[2]) + m[3]/60), 137 | temp[m[4]]*(Number(m[5]) + m[6]/60) 138 | )); 139 | return; 140 | } 141 | 142 | //and now Nominatim 143 | //http://wiki.openstreetmap.org/wiki/Nominatim 144 | console.log(this._callbackId); 145 | window[("_l_osmgeocoder_"+this._callbackId)] = L.Util.bind(this.options.callback, this); 146 | 147 | 148 | /* Set up params to send to Nominatim */ 149 | var params = { 150 | // Defaults 151 | q: this._input.value, 152 | json_callback : ("_l_osmgeocoder_"+this._callbackId++), 153 | format: 'json' 154 | }; 155 | 156 | if (this.options.bounds && this.options.bounds != null) { 157 | if( this.options.bounds instanceof L.LatLngBounds ) { 158 | params.viewbox = this.options.bounds.toBBoxString(); 159 | params.bounded = 1; 160 | } 161 | else { 162 | console.log('bounds must be of type L.LatLngBounds'); 163 | return; 164 | } 165 | } 166 | 167 | if (this.options.email && this.options.email != null) { 168 | if (typeof this.options.email == 'string') { 169 | params.email = this.options.email; 170 | } 171 | else{ 172 | console.log('email must be a string'); 173 | } 174 | } 175 | 176 | var protocol = location.protocol; 177 | if (protocol == "file:") protocol = "https:"; 178 | var url = protocol + "//nominatim.openstreetmap.org/search" + L.Util.getParamString(params), 179 | script = document.createElement("script"); 180 | 181 | 182 | 183 | 184 | script.type = "text/javascript"; 185 | script.src = url; 186 | script.id = this._callbackId; 187 | document.getElementsByTagName("head")[0].appendChild(script); 188 | }, 189 | 190 | _expand: function () { 191 | L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded'); 192 | }, 193 | 194 | _collapse: function () { 195 | this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', ''); 196 | } 197 | }); -------------------------------------------------------------------------------- /output/app/common/leaflet-plugin/Control.OSMGeocoder.js: -------------------------------------------------------------------------------- 1 | if (typeof console == "undefined") { 2 | this.console = { log: function (msg) { /* do nothing since it would otherwise break IE */} }; 3 | } 4 | 5 | 6 | L.Control.OSMGeocoder = L.Control.extend({ 7 | options: { 8 | collapsed: true, 9 | position: 'topright', 10 | text: 'Locate', 11 | placeholder: '', 12 | bounds: null, // L.LatLngBounds 13 | email: null, // String 14 | callback: function (results) { 15 | if (results.length == 0) { 16 | console.log("ERROR: didn't find a result"); 17 | return; 18 | } 19 | var bbox = results[0].boundingbox, 20 | first = new L.LatLng(bbox[0], bbox[2]), 21 | second = new L.LatLng(bbox[1], bbox[3]), 22 | bounds = new L.LatLngBounds([first, second]); 23 | this._map.fitBounds(bounds); 24 | } 25 | }, 26 | 27 | _callbackId: 0, 28 | 29 | initialize: function (options) { 30 | L.Util.setOptions(this, options); 31 | }, 32 | 33 | onAdd: function (map) { 34 | this._map = map; 35 | 36 | var className = 'leaflet-control-geocoder', 37 | container = this._container = L.DomUtil.create('div', className); 38 | 39 | L.DomEvent.disableClickPropagation(container); 40 | 41 | var form = this._form = L.DomUtil.create('form', className + '-form'); 42 | 43 | var input = this._input = document.createElement('input'); 44 | input.type = "text"; 45 | input.placeholder = this.options.placeholder || ''; 46 | 47 | var submit = document.createElement('input'); 48 | submit.type = "submit"; 49 | submit.value = this.options.text; 50 | 51 | form.appendChild(input); 52 | form.appendChild(submit); 53 | 54 | L.DomEvent.addListener(form, 'submit', this._geocode, this); 55 | 56 | if (this.options.collapsed) { 57 | L.DomEvent.addListener(container, 'mouseover', this._expand, this); 58 | L.DomEvent.addListener(container, 'mouseout', this._collapse, this); 59 | 60 | var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container); 61 | link.href = '#'; 62 | link.title = 'Nominatim Geocoder'; 63 | 64 | L.DomEvent.addListener(link, L.Browser.touch ? 'click' : 'focus', this._expand, this); 65 | 66 | this._map.on('movestart', this._collapse, this); 67 | } else { 68 | this._expand(); 69 | } 70 | 71 | container.appendChild(form); 72 | 73 | return container; 74 | }, 75 | 76 | /* helper functions for cordinate extraction */ 77 | _createSearchResult : function(lat, lon) { 78 | //creates an position description similar to the result of a Nominatim search 79 | var diff = 0.005; 80 | var result = []; 81 | result[0] = {}; 82 | result[0]["boundingbox"] = [parseFloat(lat)-diff,parseFloat(lat)+diff,parseFloat(lon)-diff,parseFloat(lon)+diff]; 83 | result[0]["class"]="boundary"; 84 | result[0]["display_name"]="Position: "+lat+" "+lon; 85 | result[0]["lat"] = lat; 86 | result[0]["lon"] = lon; 87 | return result; 88 | }, 89 | _isLatLon : function (q) { 90 | //"lon lat" => xx.xxx x.xxxxx 91 | var re = /(-?\d+\.\d+)\s(-?\d+\.\d+)/; 92 | var m = re.exec(q); 93 | if (m != undefined) return m; 94 | 95 | //lat...xx.xxx...lon...x.xxxxx 96 | re = /lat\D*(-?\d+\.\d+)\D*lon\D*(-?\d+\.\d+)/; 97 | m = re.exec(q); 98 | //showRegExpResult(m); 99 | if (m != undefined) return m; 100 | else return null; 101 | }, 102 | _isLatLon_decMin : function (q) { 103 | console.log("is LatLon?: "+q); 104 | //N 53° 13.785' E 010° 23.887' 105 | //re = /[NS]\s*(\d+)\D*(\d+\.\d+).?\s*[EW]\s*(\d+)\D*(\d+\.\d+)\D*/; 106 | re = /([ns])\s*(\d+)\D*(\d+\.\d+).?\s*([ew])\s*(\d+)\D*(\d+\.\d+)/i; 107 | m = re.exec(q.toLowerCase()); 108 | //showRegExpResult(m); 109 | if ((m != undefined)) return m; 110 | else return null; 111 | // +- dec min +- dec min 112 | }, 113 | 114 | _geocode : function (event) { 115 | L.DomEvent.preventDefault(event); 116 | var q = this._input.value; 117 | //try to find corrdinates 118 | if (this._isLatLon(q) != null) 119 | { 120 | var m = this._isLatLon(q); 121 | console.log("LatLon: "+m[1]+" "+m[2]); 122 | //m = {lon, lat} 123 | this.options.callback.call(this, this._createSearchResult(m[1],m[2])); 124 | return; 125 | } 126 | else if (this._isLatLon_decMin(q) != null) 127 | { 128 | var m = this._isLatLon_decMin(q); 129 | //m: [ns, lat dec, lat min, ew, lon dec, lon min] 130 | var temp = new Array(); 131 | temp['n'] = 1; 132 | temp['s'] = -1; 133 | temp['e'] = 1; 134 | temp['w'] = -1; 135 | this.options.callback.call(this,this._createSearchResult( 136 | temp[m[1]]*(Number(m[2]) + m[3]/60), 137 | temp[m[4]]*(Number(m[5]) + m[6]/60) 138 | )); 139 | return; 140 | } 141 | 142 | //and now Nominatim 143 | //http://wiki.openstreetmap.org/wiki/Nominatim 144 | console.log(this._callbackId); 145 | window[("_l_osmgeocoder_"+this._callbackId)] = L.Util.bind(this.options.callback, this); 146 | 147 | 148 | /* Set up params to send to Nominatim */ 149 | var params = { 150 | // Defaults 151 | q: this._input.value, 152 | json_callback : ("_l_osmgeocoder_"+this._callbackId++), 153 | format: 'json' 154 | }; 155 | 156 | if (this.options.bounds && this.options.bounds != null) { 157 | if( this.options.bounds instanceof L.LatLngBounds ) { 158 | params.viewbox = this.options.bounds.toBBoxString(); 159 | params.bounded = 1; 160 | } 161 | else { 162 | console.log('bounds must be of type L.LatLngBounds'); 163 | return; 164 | } 165 | } 166 | 167 | if (this.options.email && this.options.email != null) { 168 | if (typeof this.options.email == 'string') { 169 | params.email = this.options.email; 170 | } 171 | else{ 172 | console.log('email must be a string'); 173 | } 174 | } 175 | 176 | var protocol = location.protocol; 177 | if (protocol == "file:") protocol = "https:"; 178 | var url = protocol + "//nominatim.openstreetmap.org/search" + L.Util.getParamString(params), 179 | script = document.createElement("script"); 180 | 181 | 182 | 183 | 184 | script.type = "text/javascript"; 185 | script.src = url; 186 | script.id = this._callbackId; 187 | document.getElementsByTagName("head")[0].appendChild(script); 188 | }, 189 | 190 | _expand: function () { 191 | L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded'); 192 | }, 193 | 194 | _collapse: function () { 195 | this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', ''); 196 | } 197 | }); -------------------------------------------------------------------------------- /app/common/plugin/measureControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 距离量算 3 | * 修改参考:https://github.com/makinacorpus/Leaflet.MeasureControl 4 | * 依赖 leaflet-draw(包括js和css) 5 | * by zry 6 | * @Date 2017-04-05 7 | */ 8 | import L from 'leaflet'; 9 | import draw from 'leaflet-draw';//矢量画图工具 10 | import '../css/leaflet.draw.css'; 11 | import './measureControl.css'; 12 | 13 | L.Polyline.Measure = L.Draw.Polyline.extend({ 14 | addHooks: function() { 15 | L.Draw.Polyline.prototype.addHooks.call(this); 16 | if (this._map) { 17 | this._markerGroup = new L.LayerGroup(); 18 | this._map.addLayer(this._markerGroup); 19 | 20 | this._markers = []; 21 | this._map.on('click', this._onClick, this); 22 | this._startShape(); 23 | } 24 | }, 25 | 26 | removeHooks: function() { 27 | L.Draw.Polyline.prototype.removeHooks.call(this); 28 | 29 | this._clearHideErrorTimeout(); 30 | 31 | // !\ Still useful when control is disabled before any drawing (refactor needed?) 32 | this._map 33 | .off('pointermove', this._onMouseMove, this) 34 | .off('mousemove', this._onMouseMove, this) 35 | .off('click', this._onClick, this); 36 | 37 | this._clearGuides(); 38 | this._container.style.cursor = ''; 39 | 40 | this._removeShape(); 41 | }, 42 | 43 | _startShape: function() { 44 | this._drawing = true; 45 | this._poly = new L.Polyline([], this.options.shapeOptions); 46 | // this is added as a placeholder, if leaflet doesn't recieve 47 | // this when the tool is turned off all onclick events are removed 48 | this._poly._onClick = function() {}; 49 | 50 | this._container.style.cursor = 'crosshair'; 51 | 52 | this._updateTooltip(); 53 | 54 | this._map 55 | .on('pointermove', this._onMouseMove, this) //移动端支持 56 | .on('mousemove', this._onMouseMove, this); 57 | }, 58 | 59 | _finishShape: function() { 60 | this._drawing = false; 61 | 62 | this._cleanUpShape(); 63 | this._clearGuides(); 64 | 65 | this._updateTooltip(); 66 | this._map 67 | .off('pointermove', this._onMouseMove, this) 68 | .off('mousemove', this._onMouseMove, this); 69 | 70 | this._container.style.cursor = ''; 71 | }, 72 | 73 | _removeShape: function() { 74 | if (!this._poly) return; 75 | this._map.removeLayer(this._poly); 76 | delete this._poly; 77 | this._markers.splice(0); 78 | this._markerGroup.clearLayers(); 79 | }, 80 | 81 | _onClick: function() { 82 | if (!this._drawing) { 83 | this._removeShape(); 84 | this._startShape(); 85 | return; 86 | } 87 | }, 88 | 89 | _getTooltipText: function() { 90 | 91 | var showLength = this.options.showLength, 92 | labelText, distanceStr; 93 | 94 | if (this._markers.length === 0) { 95 | labelText = { 96 | text: "开始"||L.drawLocal.draw.handlers.polyline.tooltip.start 97 | }; 98 | } else { 99 | distanceStr = showLength ? this._getMeasurementString() : ''; 100 | 101 | if (this._markers.length === 1) { 102 | labelText = { 103 | text: "下一个点"||L.drawLocal.draw.handlers.polyline.tooltip.cont, 104 | subtext: distanceStr 105 | }; 106 | } else { 107 | labelText = { 108 | text: "点击最后一个点结束"||L.drawLocal.draw.handlers.polyline.tooltip.end, 109 | subtext: distanceStr 110 | }; 111 | } 112 | } 113 | 114 | if (!this._drawing) { 115 | labelText.text = ''; 116 | } 117 | return labelText; 118 | }, 119 | //设定单位 120 | _getMeasurementString: function () { 121 | var currentLatLng = this._currentLatLng, 122 | previousLatLng = this._markers[this._markers.length - 1].getLatLng(), 123 | distance; 124 | 125 | // calculate the distance from the last fixed point to the mouse position 126 | distance = this._measurementRunningTotal + currentLatLng.distanceTo(previousLatLng); 127 | 128 | return L.GeometryUtil.readableDistance(distance, this.options.metric/*, this.options.feet*/); 129 | } 130 | }); 131 | 132 | L.Control.MeasureControl = L.Control.extend({ 133 | 134 | statics: { 135 | TITLE: '测量距离' 136 | }, 137 | options: { 138 | position: 'topleft', 139 | handler: {}, 140 | }, 141 | 142 | toggle: function() { 143 | if (this.handler.enabled()) { 144 | this.handler.disable.call(this.handler); 145 | } else { 146 | this.handler.enable.call(this.handler); 147 | } 148 | }, 149 | //addTo(map) -->onAdd(map) 150 | onAdd: function(map) { 151 | var link = null; 152 | var className = 'leaflet-control-draw'; 153 | 154 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 155 | 156 | this.handler = new L.Polyline.Measure(map, this.options.handler); 157 | 158 | this.handler.on('enabled', function() { 159 | this.enabled = true; 160 | L.DomUtil.addClass(this._container, 'enabled'); 161 | }, this); 162 | 163 | this.handler.on('disabled', function() { 164 | delete this.enabled; 165 | L.DomUtil.removeClass(this._container, 'enabled'); 166 | }, this); 167 | 168 | link = L.DomUtil.create('a', className + '-measure', this._container); 169 | link.href = '#'; 170 | link.title = L.Control.MeasureControl.TITLE; 171 | 172 | L.DomEvent 173 | .addListener(link, 'click', L.DomEvent.stopPropagation) 174 | .addListener(link, 'click', L.DomEvent.preventDefault) 175 | .addListener(link, 'click', this.toggle, this); 176 | 177 | return this._container; 178 | } 179 | }); 180 | 181 | 182 | L.Map.mergeOptions({ 183 | measureControl: false 184 | }); 185 | 186 | /** 187 | * 如果配置中有measureControl的话 188 | * 例如:var map = L.map('map', {measureControl:true}); 189 | */ 190 | L.Map.addInitHook(function() { 191 | if (this.options.measureControl) { 192 | this.measureControl = L.Control.measureControl().addTo(this); 193 | } 194 | }); 195 | 196 | 197 | L.control.measureControl = function(options) { 198 | return new L.Control.MeasureControl(options); 199 | }; 200 | 201 | export default L.control.measureControl; -------------------------------------------------------------------------------- /output/app/common/plugin/measureControl.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 距离量算 3 | * 修改参考:https://github.com/makinacorpus/Leaflet.MeasureControl 4 | * 依赖 leaflet-draw(包括js和css) 5 | * by zry 6 | * @Date 2017-04-05 7 | */ 8 | import L from 'leaflet'; 9 | import draw from 'leaflet-draw';//矢量画图工具 10 | import '../css/leaflet.draw.css'; 11 | import './measureControl.css'; 12 | 13 | L.Polyline.Measure = L.Draw.Polyline.extend({ 14 | addHooks: function() { 15 | L.Draw.Polyline.prototype.addHooks.call(this); 16 | if (this._map) { 17 | this._markerGroup = new L.LayerGroup(); 18 | this._map.addLayer(this._markerGroup); 19 | 20 | this._markers = []; 21 | this._map.on('click', this._onClick, this); 22 | this._startShape(); 23 | } 24 | }, 25 | 26 | removeHooks: function() { 27 | L.Draw.Polyline.prototype.removeHooks.call(this); 28 | 29 | this._clearHideErrorTimeout(); 30 | 31 | // !\ Still useful when control is disabled before any drawing (refactor needed?) 32 | this._map 33 | .off('pointermove', this._onMouseMove, this) 34 | .off('mousemove', this._onMouseMove, this) 35 | .off('click', this._onClick, this); 36 | 37 | this._clearGuides(); 38 | this._container.style.cursor = ''; 39 | 40 | this._removeShape(); 41 | }, 42 | 43 | _startShape: function() { 44 | this._drawing = true; 45 | this._poly = new L.Polyline([], this.options.shapeOptions); 46 | // this is added as a placeholder, if leaflet doesn't recieve 47 | // this when the tool is turned off all onclick events are removed 48 | this._poly._onClick = function() {}; 49 | 50 | this._container.style.cursor = 'crosshair'; 51 | 52 | this._updateTooltip(); 53 | 54 | this._map 55 | .on('pointermove', this._onMouseMove, this) //移动端支持 56 | .on('mousemove', this._onMouseMove, this); 57 | }, 58 | 59 | _finishShape: function() { 60 | this._drawing = false; 61 | 62 | this._cleanUpShape(); 63 | this._clearGuides(); 64 | 65 | this._updateTooltip(); 66 | this._map 67 | .off('pointermove', this._onMouseMove, this) 68 | .off('mousemove', this._onMouseMove, this); 69 | 70 | this._container.style.cursor = ''; 71 | }, 72 | 73 | _removeShape: function() { 74 | if (!this._poly) return; 75 | this._map.removeLayer(this._poly); 76 | delete this._poly; 77 | this._markers.splice(0); 78 | this._markerGroup.clearLayers(); 79 | }, 80 | 81 | _onClick: function() { 82 | if (!this._drawing) { 83 | this._removeShape(); 84 | this._startShape(); 85 | return; 86 | } 87 | }, 88 | 89 | _getTooltipText: function() { 90 | 91 | var showLength = this.options.showLength, 92 | labelText, distanceStr; 93 | 94 | if (this._markers.length === 0) { 95 | labelText = { 96 | text: "开始"||L.drawLocal.draw.handlers.polyline.tooltip.start 97 | }; 98 | } else { 99 | distanceStr = showLength ? this._getMeasurementString() : ''; 100 | 101 | if (this._markers.length === 1) { 102 | labelText = { 103 | text: "下一个点"||L.drawLocal.draw.handlers.polyline.tooltip.cont, 104 | subtext: distanceStr 105 | }; 106 | } else { 107 | labelText = { 108 | text: "点击最后一个点结束"||L.drawLocal.draw.handlers.polyline.tooltip.end, 109 | subtext: distanceStr 110 | }; 111 | } 112 | } 113 | 114 | if (!this._drawing) { 115 | labelText.text = ''; 116 | } 117 | return labelText; 118 | }, 119 | //设定单位 120 | _getMeasurementString: function () { 121 | var currentLatLng = this._currentLatLng, 122 | previousLatLng = this._markers[this._markers.length - 1].getLatLng(), 123 | distance; 124 | 125 | // calculate the distance from the last fixed point to the mouse position 126 | distance = this._measurementRunningTotal + currentLatLng.distanceTo(previousLatLng); 127 | 128 | return L.GeometryUtil.readableDistance(distance, this.options.metric/*, this.options.feet*/); 129 | } 130 | }); 131 | 132 | L.Control.MeasureControl = L.Control.extend({ 133 | 134 | statics: { 135 | TITLE: '测量距离' 136 | }, 137 | options: { 138 | position: 'topleft', 139 | handler: {}, 140 | }, 141 | 142 | toggle: function() { 143 | if (this.handler.enabled()) { 144 | this.handler.disable.call(this.handler); 145 | } else { 146 | this.handler.enable.call(this.handler); 147 | } 148 | }, 149 | //addTo(map) -->onAdd(map) 150 | onAdd: function(map) { 151 | var link = null; 152 | var className = 'leaflet-control-draw'; 153 | 154 | this._container = L.DomUtil.create('div', 'leaflet-bar'); 155 | 156 | this.handler = new L.Polyline.Measure(map, this.options.handler); 157 | 158 | this.handler.on('enabled', function() { 159 | this.enabled = true; 160 | L.DomUtil.addClass(this._container, 'enabled'); 161 | }, this); 162 | 163 | this.handler.on('disabled', function() { 164 | delete this.enabled; 165 | L.DomUtil.removeClass(this._container, 'enabled'); 166 | }, this); 167 | 168 | link = L.DomUtil.create('a', className + '-measure', this._container); 169 | link.href = '#'; 170 | link.title = L.Control.MeasureControl.TITLE; 171 | 172 | L.DomEvent 173 | .addListener(link, 'click', L.DomEvent.stopPropagation) 174 | .addListener(link, 'click', L.DomEvent.preventDefault) 175 | .addListener(link, 'click', this.toggle, this); 176 | 177 | return this._container; 178 | } 179 | }); 180 | 181 | 182 | L.Map.mergeOptions({ 183 | measureControl: false 184 | }); 185 | 186 | /** 187 | * 如果配置中有measureControl的话 188 | * 例如:var map = L.map('map', {measureControl:true}); 189 | */ 190 | L.Map.addInitHook(function() { 191 | if (this.options.measureControl) { 192 | this.measureControl = L.Control.measureControl().addTo(this); 193 | } 194 | }); 195 | 196 | 197 | L.control.measureControl = function(options) { 198 | return new L.Control.MeasureControl(options); 199 | }; 200 | 201 | export default L.control.measureControl; -------------------------------------------------------------------------------- /app/common/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 工具函数 3 | * @Date 2017-04-05 4 | */ 5 | let util = { 6 | /** 7 | * [adapt 屏幕自适应] 8 | * @param {Number} designWidth [标准设计稿尺寸] 9 | * @param {Number} rem2px [标准设计稿下1rem等于多少px] 10 | * @return {[null]} [] 11 | */ 12 | adapt(designWidth = 640,rem2px = 100){ 13 | let doc = window.document, 14 | d = doc.createElement('div'); 15 | d.style.width ='1rem'; 16 | d.style.display = 'none'; 17 | let head = doc.getElementsByTagName('head')[0]; 18 | head.appendChild(d); 19 | let defaultFontSize = parseFloat(window.getComputedStyle(d,null).getPropertyValue('width')); 20 | d.remove(); 21 | doc.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px /defaultFontSize * 100 +'%'; 22 | let st = doc.createElement('style'); 23 | let portrait = "@media screen and (min-width: "+window.innerWidth+"px) {html{font-size:"+ ((window.innerWidth/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}"; 24 | let landscape = "@media screen and (min-width: "+window.innerHeight+"px) {html{font-size:"+ ((window.innerHeight/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}" 25 | st.innerHTML = portrait + landscape; 26 | head.appendChild(st); 27 | }, 28 | /** 29 | * [debounce 防反跳] 30 | * @param {[Function]} func [防反跳的函数] 31 | * @param {[Number]} threshold [时间间隔] 32 | * @param {[Boolean]} execAsap [是否立即执行,true立即执行,默认为false] 33 | * @param {[Function]} fun [如果存在,一定会执行的函数] 34 | * @return {[null]} 35 | */ 36 | debounce(func, threshold = 100, execAsap = false, fun){ 37 | let timeout; 38 | return function debounced(){ 39 | let self = this, args = arguments; 40 | function delayed(){ 41 | if(!execAsap) func.apply(self,args); 42 | timeout = null; 43 | } 44 | 45 | if(timeout){ 46 | clearTimeout(timeout); 47 | }else if(execAsap){ 48 | func.apply(self,args); 49 | } 50 | timeout = setTimeout(delayed,threshold); 51 | 52 | if(fun) fun.apply(self,args); 53 | } 54 | }, 55 | /** 56 | * [debounceAdapt 动态计算媒体查询] 57 | * @param {Number} designWidth [标准设计稿尺寸] 58 | * @param {Number} rem2px [标准设计稿下1rem等于多少px] 59 | */ 60 | debounceAdapt(designWidth = 640,rem2px = 100) { 61 | this.adapt(designWidth,rem2px);//屏幕自适应处理 62 | window.onresize = this.debounce(() => { 63 | this.adapt(designWidth,rem2px); 64 | },200,false); 65 | }, 66 | /** 67 | * [adaptHeight 高度自适应] 68 | * @param {[String]} domId [控制dom高度的id] 69 | * @param {[Number]} otherHeight [除了domId其余部分高度] 70 | * @param {[Number]} threshold [时间间隔] 71 | */ 72 | adaptHeight(domId,otherHeight,threshold = 300){ 73 | let mapDom,bodyHeight ; 74 | otherHeight = parseFloat(otherHeight)||0; 75 | mapDom = document.getElementById(domId); 76 | mapDom.style.height = getHeight()+"px"; 77 | 78 | window.onresize = this.debounce(()=>{ 79 | if(__DEV__) console.log(mapDom.style.height); 80 | mapDom.style.height = getHeight()+"px"; 81 | },threshold); 82 | 83 | function getHeight(){ 84 | var height = 500;//最好设置个最小 85 | if(document.documentElement.clientHeight > 500) 86 | height = document.documentElement.clientHeight - otherHeight; 87 | return height; 88 | } 89 | }, 90 | /** 91 | * [getJSON 获取json文件] 92 | * @param {[String]} url [url地址] 93 | * @return {[Promise]} [promise] 94 | */ 95 | getJson(url){ 96 | let promise = new Promise((resolve, reject)=>{ 97 | let client = new XMLHttpRequest(); 98 | client.open("GET", url); 99 | client.onreadystatechange = handler; 100 | client.responseType = "json"; 101 | client.setRequestHeader("Accept", "application/json"); 102 | client.send(); 103 | 104 | function handler() { 105 | if (this.readyState !== 4) { 106 | return; 107 | } 108 | if (this.status === 200) { 109 | resolve(this.response); 110 | } else { 111 | reject(new Error(this.statusText)); 112 | } 113 | }; 114 | }); 115 | 116 | return promise; 117 | 118 | }, 119 | /*showTipWin(text,time = 500,style={width:"100px",height:"100px"}){ 120 | let div = document.createElement('div'); 121 | div.style.display = "absolute"; 122 | div.style.width = style.width; 123 | div.style.height = style.height; 124 | div.style. 125 | },*/ 126 | /** 127 | * [cloneObj 深拷贝对象] 128 | * @param {[Object]} obj [被拷贝的对象] 129 | * @return {[Object]} [返回拷贝后的对象] 130 | */ 131 | cloneObj(obj){ 132 | let newObj,s; 133 | if(typeof obj!== 'object') return; 134 | newObj = obj.constructor === Object ? {} : []; 135 | if(window.JSON){ 136 | s = JSON.stringify(obj); 137 | newObj = JSON.parse(s); 138 | }else{ 139 | if(newObj.constructor === Array){ 140 | newObj.concat(obj); 141 | }else{ 142 | for(let o in obj){ 143 | newObj[i] = obj[i]; 144 | } 145 | } 146 | } 147 | 148 | return newObj; 149 | }, 150 | byClassName(className,index){ 151 | if(index !== undefined) return document.getElementsByClassName(className)[index]; 152 | return document.getElementsByClassName(className); 153 | }, 154 | ByIdName(id){ 155 | return document.getElementById(id); 156 | }, 157 | /** 158 | * [getScript 异步加载script] 159 | * @param {[String]} url [script地址] 160 | * @return {[Promise]} [promise] 161 | */ 162 | getScript(url){ 163 | let promise = new Promise((resolve,reject)=>{ 164 | let script = document.createElement('script'); 165 | script.type = 'text/javascript'; 166 | 167 | script.onreadystatechange = ()=>{ 168 | if(this.readyState=='complete'){ 169 | resolve(); 170 | } 171 | } 172 | script.onload = ()=>{ 173 | resolve(); 174 | } 175 | script.onerror = ()=>{ 176 | reject(); 177 | } 178 | script.src = url; 179 | document.getElementsByTagName('head')[0].appendChild(script); 180 | }) 181 | 182 | return promise; 183 | } 184 | 185 | } 186 | 187 | 188 | export default util; -------------------------------------------------------------------------------- /output/app/common/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 工具函数 3 | * @Date 2017-04-05 4 | */ 5 | let util = { 6 | /** 7 | * [adapt 屏幕自适应] 8 | * @param {Number} designWidth [标准设计稿尺寸] 9 | * @param {Number} rem2px [标准设计稿下1rem等于多少px] 10 | * @return {[null]} [] 11 | */ 12 | adapt(designWidth = 640,rem2px = 100){ 13 | let doc = window.document, 14 | d = doc.createElement('div'); 15 | d.style.width ='1rem'; 16 | d.style.display = 'none'; 17 | let head = doc.getElementsByTagName('head')[0]; 18 | head.appendChild(d); 19 | let defaultFontSize = parseFloat(window.getComputedStyle(d,null).getPropertyValue('width')); 20 | d.remove(); 21 | doc.documentElement.style.fontSize = window.innerWidth / designWidth * rem2px /defaultFontSize * 100 +'%'; 22 | let st = doc.createElement('style'); 23 | let portrait = "@media screen and (min-width: "+window.innerWidth+"px) {html{font-size:"+ ((window.innerWidth/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}"; 24 | let landscape = "@media screen and (min-width: "+window.innerHeight+"px) {html{font-size:"+ ((window.innerHeight/(designWidth/rem2px)/defaultFontSize)*100) +"%;}}" 25 | st.innerHTML = portrait + landscape; 26 | head.appendChild(st); 27 | }, 28 | /** 29 | * [debounce 防反跳] 30 | * @param {[Function]} func [防反跳的函数] 31 | * @param {[Number]} threshold [时间间隔] 32 | * @param {[Boolean]} execAsap [是否立即执行,true立即执行,默认为false] 33 | * @param {[Function]} fun [如果存在,一定会执行的函数] 34 | * @return {[null]} 35 | */ 36 | debounce(func, threshold = 100, execAsap = false, fun){ 37 | let timeout; 38 | return function debounced(){ 39 | let self = this, args = arguments; 40 | function delayed(){ 41 | if(!execAsap) func.apply(self,args); 42 | timeout = null; 43 | } 44 | 45 | if(timeout){ 46 | clearTimeout(timeout); 47 | }else if(execAsap){ 48 | func.apply(self,args); 49 | } 50 | timeout = setTimeout(delayed,threshold); 51 | 52 | if(fun) fun.apply(self,args); 53 | } 54 | }, 55 | /** 56 | * [debounceAdapt 动态计算媒体查询] 57 | * @param {Number} designWidth [标准设计稿尺寸] 58 | * @param {Number} rem2px [标准设计稿下1rem等于多少px] 59 | */ 60 | debounceAdapt(designWidth = 640,rem2px = 100) { 61 | this.adapt(designWidth,rem2px);//屏幕自适应处理 62 | window.onresize = this.debounce(() => { 63 | this.adapt(designWidth,rem2px); 64 | },200,false); 65 | }, 66 | /** 67 | * [adaptHeight 高度自适应] 68 | * @param {[String]} domId [控制dom高度的id] 69 | * @param {[Number]} otherHeight [除了domId其余部分高度] 70 | * @param {[Number]} threshold [时间间隔] 71 | */ 72 | adaptHeight(domId,otherHeight,threshold = 300){ 73 | let mapDom,bodyHeight ; 74 | otherHeight = parseFloat(otherHeight)||0; 75 | mapDom = document.getElementById(domId); 76 | mapDom.style.height = getHeight()+"px"; 77 | 78 | window.onresize = this.debounce(()=>{ 79 | if(__DEV__) console.log(mapDom.style.height); 80 | mapDom.style.height = getHeight()+"px"; 81 | },threshold); 82 | 83 | function getHeight(){ 84 | var height = 500;//最好设置个最小 85 | if(document.documentElement.clientHeight > 500) 86 | height = document.documentElement.clientHeight - otherHeight; 87 | return height; 88 | } 89 | }, 90 | /** 91 | * [getJSON 获取json文件] 92 | * @param {[String]} url [url地址] 93 | * @return {[Promise]} [promise] 94 | */ 95 | getJson(url){ 96 | let promise = new Promise((resolve, reject)=>{ 97 | let client = new XMLHttpRequest(); 98 | client.open("GET", url); 99 | client.onreadystatechange = handler; 100 | client.responseType = "json"; 101 | client.setRequestHeader("Accept", "application/json"); 102 | client.send(); 103 | 104 | function handler() { 105 | if (this.readyState !== 4) { 106 | return; 107 | } 108 | if (this.status === 200) { 109 | resolve(this.response); 110 | } else { 111 | reject(new Error(this.statusText)); 112 | } 113 | }; 114 | }); 115 | 116 | return promise; 117 | 118 | }, 119 | /*showTipWin(text,time = 500,style={width:"100px",height:"100px"}){ 120 | let div = document.createElement('div'); 121 | div.style.display = "absolute"; 122 | div.style.width = style.width; 123 | div.style.height = style.height; 124 | div.style. 125 | },*/ 126 | /** 127 | * [cloneObj 深拷贝对象] 128 | * @param {[Object]} obj [被拷贝的对象] 129 | * @return {[Object]} [返回拷贝后的对象] 130 | */ 131 | cloneObj(obj){ 132 | let newObj,s; 133 | if(typeof obj!== 'object') return; 134 | newObj = obj.constructor === Object ? {} : []; 135 | if(window.JSON){ 136 | s = JSON.stringify(obj); 137 | newObj = JSON.parse(s); 138 | }else{ 139 | if(newObj.constructor === Array){ 140 | newObj.concat(obj); 141 | }else{ 142 | for(let o in obj){ 143 | newObj[i] = obj[i]; 144 | } 145 | } 146 | } 147 | 148 | return newObj; 149 | }, 150 | byClassName(className,index){ 151 | if(index !== undefined) return document.getElementsByClassName(className)[index]; 152 | return document.getElementsByClassName(className); 153 | }, 154 | ByIdName(id){ 155 | return document.getElementById(id); 156 | }, 157 | /** 158 | * [getScript 异步加载script] 159 | * @param {[String]} url [script地址] 160 | * @return {[Promise]} [promise] 161 | */ 162 | getScript(url){ 163 | let promise = new Promise((resolve,reject)=>{ 164 | let script = document.createElement('script'); 165 | script.type = 'text/javascript'; 166 | 167 | script.onreadystatechange = ()=>{ 168 | if(this.readyState=='complete'){ 169 | resolve(); 170 | } 171 | } 172 | script.onload = ()=>{ 173 | resolve(); 174 | } 175 | script.onerror = ()=>{ 176 | reject(); 177 | } 178 | script.src = url; 179 | document.getElementsByTagName('head')[0].appendChild(script); 180 | }) 181 | 182 | return promise; 183 | } 184 | 185 | } 186 | 187 | 188 | export default util; --------------------------------------------------------------------------------