leaflet地图的一些问题

leaflet

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

地图的制作

leaflet官方网址:https://leafletjs.com/examples/quick-start/

需求:用leaflet制作地图,地图上要有标记,点击标记,要展示模态框(运用lazyUI写的),模态框是表格,点击模态框的按钮,又要弹出一个模态框,在第二个模态框中要运用echarts进行展示图形。所制作的这个地图是一个iframe,要嵌入react中。最后新增加了一个全屏的功能,全屏时,marker标记也是可以点击的。

创建地图的步骤:
引入文件:

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" />
	<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script>
	<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
	<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
	<script src="leaflet.ChineseTmsProviders.js"></script>
	<script src="./layui/layui.all.js"></script>
	<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	<meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
	<link rel="stylesheet" href="screen.css" />
	<link rel="stylesheet" href="MarkerCluster.css" />
	<link rel="stylesheet" href="MarkerCluster.Default.css" />
    <link rel="stylesheet" href="./layui/css/layui.css" media="all">
	<script src="leaflet.markercluster-src.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts-en.common.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
    <script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js'></script>
    <link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css' rel='stylesheet' />
    <script src="leaflet.spin.min.js" charset="utf-8"></script>
    <script src="spin.min.js" charset="utf-8"></script>

在body定义div
因为所制作的地图的双层的展示,所以要利用分层的概念
在这里插入图片描述
有两个层,地图和影像这就是实现的效果

//初始化站点信息
	var site_name = "";//站点名称
	var site_code = "";//站点编号:
	var map = L.map("map",{
	    center:[20.04194,110.34136],
	    zoom:8,
	    layers:[normal],
	    zoomControl:false,
        // fullscreenControl: true,//这个就是全屏的插件
    });
    L.control.layers(baseLayers,overlayLayers).addTo(map);
  L.control.zoom({zoomInTitle:'放大', zoomOutTitle:'缩小'}).addTo(map);
   var markers = new L.MarkerClusterGroup();

async function  populate(a) {
        map.spin(true);//这个是加载的插件,当数据还没请求过来的时候,进行loading
      this.axios.get(`${Path}/device/findAllDevice`, //这里是请求marker标记的数据,
        })
           .then(function (response) {
            map.spin(false);
            var lists = [];
             lists = response.data.list;
             var i = 0;
             setInterval(
                ()=>{
                i++;
                if(((i-1)*100)<lists.length){
                loadmaker(lists,(i-1)*100,i*100);//这里运用了懒加载,数据太过庞大,所以运用懒加载加载出来
                }
            }
            ,10)
        })
           .catch(function (error) {
            map.spin(false);
             console.log(error,'失败');
           });
         return false;
        }
      function loadmaker(lists,start,end){
        for (var i = start; i < end; ++i) {
            if(i<lists.length){
                var m = new L.Marker(L.latLng(lists[i].lat,lists[i].lng),//(纬度,经度)
                    { icon: L.icon({
                        iconUrl: lists[i].type == 1 ? 'helicopter.png' : 'airplane.png',//这里是自定义marker标记的图标
                                iconSize: [32, 32]
                                })},
                    );
                    m.markMessage = lists[i];
                    markers.addLayer(m);       
        }
    }
}
    function getSiteByid(siteId,a) {//这里是点击的时候获取的站点信息
	this.axios.post(`${Path}/pub/dict/value/deailByCode`, {
			siteCode:siteId
      })
       .then(function (response) {
		 console.log(response,'成功');
		 site_name = response.data.list.name;
		 site_code = response.data.list.code;
         load_dialog(a);//这里就调出了弹框,弹框都是运用lazyUI写的
		 _thisA = a;
       })
       .catch(function (error) {
         console.log(error,'失败');
       });
		return false;
    }

//加载弹窗
	function load_dialog(a){
        var zname =  a.layer.markMessage.dveCode;
		var state_name = ""; //状态显示值
		if(a.layer.markMessage.status == 0){
			state_name = "启用";
		}else{
			state_name = "禁用";
        }
        var hname = ''
        if(a.layer.markMessage.hname === undefined){
            hname = ''
        }else{
            hname = a.layer.markMessage.hname
        } 
      
          var code = document.getElementById("code");
          var name = document.getElementById("name");
          var Adress = document.getElementById("Adress");
          var staffName = document.getElementById("staffName");
          var TIME = document.getElementById("TIME");
          var HuZhu = document.getElementById("HuZhu");
          var Status = document.getElementById("Status");
        
          code.innerHTML = site_code?site_code:''
          name.innerHTML = site_name?site_name:''
          Adress.innerHTML = a.layer.markMessage.installAddress?a.layer.markMessage.installAddress:''
          staffName.innerHTML = a.layer.markMessage.staffName?a.layer.markMessage.staffName:''
          TIME.innerHTML = a.layer.markMessage.instaffTime?moment(a.layer.markMessage.instaffTime).format('YYYY-MM-DD HH:mm:ss'):''
          HuZhu.innerHTML = a.layer.markMessage.hname?a.layer.markMessage.hname:''
          Status.innerHTML = state_name?state_name:''
        
		  openModal1 = layer.open({//lazyUI表格的定义
				  type: 1, 
                  title: zname,
                  id:'ae',
                  closeBtn: 1,
                  zIndex:layer.zIndex,
				  area: ['500px', '400px'],
				  skin: 'layui-layer-molv' ,
				  icon: 6,
                  content: $('#modal'),
                  cancel: function(index, layero){ 
                    var modal = document.getElementById("modal");
                    modal.style.display = "none";
                    var layModal = document.getElementById("layModal");
                    layModal.style.display = "none";
                    layer.closeAll();
              },
            }); 
	} 
	markers.on('click', function (a) {//表达点击事件
		var siteId = a.layer.markMessage.siteNm;//获取站点id
		getSiteByid(siteId,a);
    });       
    populate();   //地图初始化
	map.addLayer(markers);

在这里插入图片描述这里是弹出的模态框。
在这里插入图片描述
这是在react中嵌入iframe.

全屏插件

https://leafletjs.com/plugins.html#fullscreen-controls 这个是讲述leaflet全屏插件的网址

具体应用:
在这里插入图片描述
因为是iframe嵌入的,而且我要显示的模态框并不是像其他地图一样,是自带的模态框,所以当我用leaflet中自带的全屏插件时,当我点击的时候,模态框虽然出来了,但是被地图覆盖了,不管怎么调z-index都没有用。(但是有个大佬告诉了我一个方法,他说叫我把模态框也放在全屏的节点中,这样就能实现,但是。。。我不会)最后我只能自己写一个全屏的功能,把整个iframe进行全屏。这样就能展示了。这里多亏了这篇文章https://blog.csdn.net/qq_38122518/article/details/81035253

全屏的实现

一个大佬的文章

https://www.itsvse.com/misc.php?mod=tag&id=2726

iframe.html中自己设置一个按钮
在这里插入图片描述
raect中也要进行设置:
在这里插入图片描述

当点击按钮是时,进行showFullScreen()方法的触发
// 全屏,
     launchFullscreen=(element)=> {
        if (element.requestFullscreen) {
            element.requestFullscreen();
        } else if (element.mozRequestFullScreen) {
            element.mozRequestFullScreen();
        } else if (element.msRequestFullscreen) {
            element.msRequestFullscreen();//ie浏览器
        } else if (element.webkitRequestFullscreen) {
            element.webkitRequestFullScreen();//谷歌浏览器
        }
    }
    exitFullscreen=()=> {            
        if (document.exitFullscreen) { 
           document.exitFullscreen(); 
        } else if (
            document.msExitFullscreen){ 
           document.msExitFullscreen();
        } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        } 
    }  
  //全屏按钮上调用的方法
    showFullScreen=()=>{
      var elm = document.getElementById("map");
      var iframe = document.getElementById("iframe");
      if (document.fullscreenEnabled) {
       var fullscreenElement =  document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; 
    
       if (fullscreenElement) {
         iframe.style.height = '91%'
         this.exitFullscreen(); 
       } else {
         iframe.style.height = '100%'//全屏的时候设置高度
         this.launchFullscreen(elm);  
      } 
    }
    } 

 我以为这样就实现了,可是发现当用户按键盘esc键时,其实是没有触发方法的,虽然按esc键退出了全屏,但是它的高度没用变化。这就需要有个方法进行判断,当时找了很多方法,全局监听键盘事件,监听窗口的大小等,最后终于找到了一个方法。
var isFullscreen = true//用这个变量进行判断
 componentDidMount(){
    this.props.dispatch({
        type:'home/fetch',
        payload:{}
    })
    var elm = document.getElementById("map");
    var iframe = document.getElementById("iframe");  
    document.addEventListener("fullscreenchange", function(e) {
        if (isFullscreen) {
            iframe.style.height = '100%'
            isFullscreen=false
        } else {
            iframe.style.height = '91%'
            isFullscreen=true
        }
      });
      document.addEventListener("mozfullscreenchange", function(e) {
        if (isFullscreen) {
            iframe.style.height = '100%'
            isFullscreen=false
        } else {
            iframe.style.height = '91%'
            isFullscreen=true 
        }
      });
      document.addEventListener("webkitfullscreenchange", function(e) {
        if (isFullscreen) {
            iframe.style.height = '100%'
           isFullscreen=false
        } else {
           iframe.style.height = '91%'
           isFullscreen=true   
        }
      });
      document.addEventListener("msfullscreenchange", function(e) {
        if (isFullscreen) {
            iframe.style.height = '100%'
           isFullscreen=false
        } else {
            iframe.style.height = '91%'
            isFullscreen=true
        }
      });
}

到这里就把所有的功能都实现了。在这一系列进行摸索的过程中,我学会了很多知识。

react添加监听事件监听键盘事件

componentDidMount(){
  window.addEventListener('keypress', function(e){
           console.log(e,e.which,88)
      }
}

监听退出全屏事件

 window.onresize = function() {
        if (!checkFull()) {
            //要执行的动作
            $("#dashboard_id").removeClass('expand').addClass('contract');//这里捡个懒,直接用JQ来改className
        }
    }
    function checkFull() {
        var isFull = document.fullscreenEnabled || window.fullScreen || document.webkitIsFullScreen || document.msFullscreenEnabled;
        //to fix : false || undefined == undefined
        if (isFull === undefined) {isFull = false;}
        return isFull;
    }

//方法二

  window.onresize = function(){
    if(!checkFull()){
//要执行的动作
}
}

function checkFull(){
//判断浏览器是全屏的,但是对我这一点用也没得,一直是true,判断不出来
var isFull =  document.fullscreenEnabled || window.fullScreen || document.webkitIsFullScreen || document.msFullscreenEnabled;
//to fix : false || undefined == undefined
if(isFull === undefined) isFull = false;
return isFull;
}

react中 怎么在componentDidmount中使用addEventListener和componentWillUnmount中使用removeEventListener

export default class A extends React.Component {
constructor(props) {
    super(props);
     this.keyPress = this.keyPress.bind(this);
}
   keyPress(e) {
    console.log(e,e.which,'c触发')
    }
componentDidMount() {
   window.addEventListener("keypress", this.keyPress);
}    
componentWillUnmount(){
    window.removeEventListener("keypress", this.keyPress, false);
}
render() {
};

}

总结

  1. iframe的运用,第一次知道可以直接嵌入一个heml页面
  2. 地图上显示的标记太多,刚开始总是卡死,后来用了懒加载,数据快了一点,最后发现get请求比post请求获取数据更快
  3. iframe嵌入到react中要使用一个组件及逆行搭桥
发布了7 篇原创文章 · 获赞 1 · 访问量 1322

猜你喜欢

转载自blog.csdn.net/lydia_love/article/details/100729100