当前位置: 首页 > news >正文

石首做网站模板建站网页

石首做网站,模板建站网页,建设银行e房通网站,win wordpress 静态目录 前言 一、场景重现 1、遇到问题的代码 2、问题排查 二、通过实验验证猜想 1、排查LayerGroup和FeatureGroup 2、排查Leaflet.canvaslabel.js 三、柳暗花明又一村 1、点聚类的办法 2、歪打正着 总结 前言 在上一篇博客中介绍了基于SpringBoot的全国风景区WebGIS按…

目录

前言

一、场景重现

1、遇到问题的代码

2、问题排查

二、通过实验验证猜想

1、排查LayerGroup和FeatureGroup

2、排查Leaflet.canvaslabel.js

三、柳暗花明又一村

1、点聚类的办法

2、歪打正着

总结


前言

        在上一篇博客中介绍了基于SpringBoot的全国风景区WebGIS按省展示实践。在这篇博客中,关于旅游景点我是使用Leaflet.canvaslabel.js进行静态标注的,其实在案例中要实现点击风景区点,然后自动弹出它的其它信息,比如景点名称,所在省市县信息,还有设立年份。最开始打算采用bindPopup的方案,在编写代码的过程当中,发现一个有趣的问题。在点击所在省份之后,再把景点信息列表在地图上渲染出来,然后针对每个点绑定popup。但实际的情况是,界面上的景点点击后,没有任何反应,奇怪的是有时候又可以点。当时想着,如果是代码的绑定得有问题,肯定是都出不来,不存在一份代码,两种效果的情况。

        遇到了问题,便解决问题。在没有找到具体的问题前,首先检查代码的问题,然后检查相应的组件是否有什么缺陷,最后再梳理解决办法,大致的思路如此。本文在此背景下诞生,博文首先详细介绍了风景区展示时具体的问题,然后分析排查思路和方向,接着使用不同的方案验证思路,最后给出最终的解决方案。解决问题就是对症下药一样,找到了病根基本上就是药到病除,解决了问题的酸爽感一定让很多技术圈朋友深有体会吧。

一、场景重现

        我想在讲述一些解决办法之前,还是把碰到的详细问题描述清楚。首先是不至于让看到博文的朋友感到很诧异,第二是对于解决方案的前提条件有一个具象的描述。能让我们知道为什么会这样?出现了什么情况?我们要解决的问题是什么。这里结合代码和实际效果来讲解,这样可能比较有针对性。

1、遇到问题的代码

        这里将之前的第一版代码贴出来,肯定有朋友第一眼就能看到问题的所在,但当时折腾了我很久。也许旁观者清,也许是经验比较多,曾经遇到过,一下子就解决了。

/* 展示省份geojson范围*/
function showProvince(id){var myStyle = {color:"white",weight:5,"opacity":1,fillOpacity: 0};$.ajax({  type:"get",  url:prefix + "/geojson/" + id, dataType:"json",  cache:false,processData:false,success:function(result){if(undefined != provinceAreaLayer ){provinceAreaLayer.removeFrom(mymap);//先移除}if(result.code == web_status.SUCCESS){var geojson = JSON.parse(result.data);provinceAreaLayer = L.geoJSON(geojson,{style:myStyle}).addTo(mymap);//同时设置中心位置和级别,一般省份设置为7mymap.setView(provinceAreaLayer.getBounds().getCenter(),7);}},error:function(){$.modal.alertWarning("获取空间信息失败");});
}/*风景区展示*/        
function showScenicSpot(code){$.ajax({  type:"get",  url:prefix + "/datalist/" + code,  dataType:"json",  success:function(result){if(result.code == web_status.SUCCESS){var strokeStyleSet = "#23168d";var lat,lng,cityInfo;for(var i=0;i<result.data.length;i++){var dataInfo = result.data[i];var geomObj = JSON.parse(dataInfo.geomJson);if(i == 0){lat = geomObj.coordinates[1];lng = geomObj.coordinates[0];continue;}var radiusSize = 5;var content = "<strong>名称:</strong>"+dataInfo.name + "<br/><strong>级别:</strong>"+ dataInfo.level;content += "<br/><strong>所属行政区划:</strong>"+ dataInfo.province + "/" + dataInfo.city + "/" + dataInfo.area;content += "<br/><strong>评定时间:</strong>"+ dataInfo.evaluationTime ;var latlng = new L.latLng(geomObj.coordinates[1], geomObj.coordinates[0]);let marker = L.circleMarker(latlng, {radius: radiusSize,color: strokeStyleSet,labelStyle: {offsetX: 0, //横坐标偏移(像素)offsetY: 30, //纵坐标偏移(像素)text: dataInfo.name,rotation: 0,zIndex: radiusSize,minZoom : 5,strokeStyle: strokeStyleSet}}).addTo(showLayerGroup);marker.bindPopup(content); }mymap.addLayer(showLayerGroup);}},error:function(){$.modal.alertWarning("获取信息失败");}});
}

        不出意外的话还是出了意外,我们来计划在点击风景区时,通过bindPopup弹出经典的一些附属信息。但是无论点击哪个景点,似乎都没有符合我们的预期,效果如下:

         遇到点击了没有效果的情况,第一个想到的原因是看一下网页的控制台,看是否有什么报错信息。根据这个思路,我们打开浏览器的控制台看一下:

        很遗憾,控制台没有想要的信息,代码是没有问题的,可以正常运行的。那么问题到底出在哪里呢? 

2、问题排查

        在明确没有代码语法问题和报错的前提下,怎么解决这个问题呢?代码是严格按照我们的设计去执行的,但是为什么没有按照我们的预期效果来展示呢?当时,博主从下面两个方向进行思考。首先、排查相关组件的引用是否有问题,因为在本案例中,涉及到LayerGroup和FeatureGroup的使用,是否是因为涉及Group的增加和删除导致了标记对象的事件显示不征程。其次想到的是Leaflet.canvaslabel.js这个组件本身是不是有问题,在数量规模和事件绑定上是不是有什么不对的地方。受限于博主的经验,首先想到了这两个方面,因此排查工作也由此展开。

二、通过实验验证猜想

        针对问题我们有了两个方面的猜想,要想验证猜想的成立,就必须通过代码实验,通过实验说明问题可以解决,这样才是有说服力的。本节针对上述猜想,阐述两个实验环节。

1、排查LayerGroup和FeatureGroup

        怀疑LayerGroup和FeatureGroup有问题的根据是因为,在展示省份地理范围和风景区点位列表时,我们都会设计Group的操作,通过Group,可以实现图层级的隐藏和展示,可以实现某一专题的元素共同的可视化。但是在切换省份时,要想实现只展示当前省份和所属的风景区信息,首先要把之前的省份地理范围清空掉,同时也把之前省份的风景区列表清除掉。所以映入眼帘的第一个嫌疑人出现。添加元素和移除的方法如下:

function preview(code,id){showLayerGroup.clearLayers();//图层要素清除showProvince(id);showScenicSpot(code);
}

        要素添加到图层的代码如下:

let marker = L.circleMarker(/*省略*/).addTo(showLayerGroup);
mymap.addLayer(showLayerGroup);

        通过在Leaflet的官方网站中查看API文档,查看相关的示例代码,并没有发现什么问题。甚至在当时调试的情况下,已经不采用Group的方案,直接把marker添加到Map当中,问题依然没有解决,至此,排除是LayerGroup或者FeatureGroup引起的问题。

2、排查Leaflet.canvaslabel.js

        在把LayerGroup和FeatureGroup排除了嫌疑之后,把目光转向了Leaflet.canvaslabel.js。思考是不是因为Leaflet.canvaslabel.js这个组件自身有什么缺陷(在大规模数据量的时候),或者说我们在API的调用有没有什么问题。带着这个疑问,我们来做两个实验。第一个实验是针对性的看API,是否有什么方法或者属性配置没有正确配置。第二个实验是Leaflet.canvaslabel.js配合大规模数据点,比如5000个点的情况下,能否正常bindPopup。下面逐步来进行验证:

options: {defaultLabelStyle: {offsetX: 0, //横坐标偏移(像素)offsetY: 0, //纵坐标偏移(像素)scale: 1, //放大比例rotation: 0, //旋转角度(弧度),可能会导致碰撞检测不准确text: null, //标注文本内容minZoom: null, //最小显示级别maxZoom: null, //最大显示级别collisionFlg: true, //碰撞检测center: null, //标注位置,默认为null,会自动计算几何中心zIndex: 0, //排序defaultHeight: 20, //文本高度,无法自动计算,所以直接传参手动调整//文本样式,具体值请参考[canvas](https://www.runoob.com/tags/ref-canvas.html)font: "10px sans-serif",fillStyle: "rgba(0,0,0,1)",lineCap: "round",lineDash: [],lineDashOffset: 0,lineJoin: "round",strokeStyle: "rgba(0,0,0,1)",textAlign: "center",textBaseline: "middle",lineWidth: 1,},},

        这是组件的属性配置,基本上与标注的可视化没有关系。再来看事件和执行器:

/*** 执行侦听器*/_executeListeners: function (event) {if (!this._textBounds) return;var me = this;var ret = this.getTextByEvent(event);if (ret && ret.length > 0) {me._map._container.style.cursor = "pointer";if (event.type === "click") {me._onClickListeners.forEach(function (listener) {listener(event, ret);});}if (event.type === "mousemove") {me._onHoverListeners.forEach(function (listener) {listener(event, ret);});}if (event.type === "mousedown") {me._onMouseDownListeners.forEach(function (listener) {listener(event, ret);});}if (event.type === "mouseup") {me._onMouseUpListeners.forEach(function (listener) {listener(event, ret);});}} else {me._map._container.style.cursor = "";}},/*** 添加click侦听器*/addOnClickListener: function (listener) {this._onClickListeners.push(listener);},

        通过代码发现,组件也并有修改逻辑,只是接收点击事件,然后添加到执行器中。基本排除了组件自身的问题。那么剩下最后一个猜想,大规模数量下组件的事件是不是失效了。因此我们进行大规模数据量的加载试验。

        在之前的博文中在Leaflet中点对象使用SVG和Canvas两种模式的对比,对组件的加载能力有较详细的描述,在使用5000甚至10000个点的规模下,展示非常迅速,同时点击对象,也能实现Popup的快速提示。

var count = 30000;
for (let i = 0; i < count; i++) {let latlng = L.latLng(23.95 + Math.random() * 10, 112.40034 + Math.random() * 15);var content = "<strong>名称:</strong>城市"+i + "<br/><strong>级别:</strong>"+ i;content += "<br/><strong>所属行政区划:</strong>"+ i + "/" ;content += "<br/><strong>评定时间:</strong>"+ i ;var title = "重要城市" + Math.random();let c = L.circleMarker(latlng, {radius: 5,labelStyle: {text: title,rotation: 0,zIndex: 1,strokeStyle: "red",}}).addTo(showGroup);c.bindPopup(content);
}
map.addLayer(showGroup);

        经过两个方向,几个步骤的排查,依然没有找到具体的原因,也没有找到解决方案。有点懊恼,于是想着换个思路。对组件的多点展示能力有初步怀疑,但没有找到原因。

三、柳暗花明又一村

        山重水复疑无路,柳暗花明又一村。这句话用形容当时解决问题的情况非常贴切,在两个方向都明确没有定位最终问题的情况下。我决定用之前遇到的一个点聚类的思路。遇到问题不要放弃,再没有方向的时候,发散思路,解决了问题,经验值就此提升。因此,遇到bug,解决bug才是好的态度。这里分两个步骤描述问题的解决办法。

1、点聚类的办法

        带着之前没有找到的根本问题,一直将注意力集中在风景区的点数量上。怀疑是不是点多了,导致了事件响应的问题。所以考虑减少点位信息,在Leaflet当中,可以通过点聚类的办法介绍视野内的对象,通过减少点的渲染,保障Popup的正常可视化。

        大家还记得点聚类的组件用什么吗?之前也有文章进行深入讲解,就是用leaflet.markercluster-src。代码就不详细贴了,创建聚合图层,将点添加到图层中。

//创建聚合图层并设置最大聚合半径为 26像素
var markersGroup = L.markerClusterGroup({maxClusterRadius: 26});

        通过点聚合,发现确实能解决几个省的展示问题,当时以为找到了解决办法很欣喜,但是在浙江时,发现有风景区不能很好的展示出来。开始对数据的加载机制有个第一次怀疑,这算个歪打正着。本来没有怀疑数据的加载机制。

2、歪打正着

        在对数据的加载机制有了怀疑之后,便迅速去看代码。在展示省份地理范围的代码中,我们使用ajax的方式去后台请求数据,ajax请求头如下:

type:"get",  
url:prefix + "/geojson/" + id,  
data:{},  
dataType:"json"

        众所周知,在ajax当中,其默认的数据加载方式异步的,也就是async=true。其实到了这里,才是真正的问题根源。就是由于数据请求的异步方式导致了组件的事件响应问题。再来看一下代码:

 function preview(code,id){showLayerGroup.clearLayers();//图层要素清除showProvince(id);showScenicSpot(code);}

        在上述代码中,首先异步加载省份的geojson地理范围,再异步加载风景区信息。也就是异步的问题导致的,虽然方法看起来像是先加载地理范围,实际上设置了异步,可能地理范围还没有加载完,风景区信息已经再加载了。也正是这个原因导致了事件不响应。按照这个思路,我们将ajax方法设置为同步的方式,即async=false

        再来看具体的效果,以浙江为例:

杭州西湖风景区

杭州市千岛湖风景区

浙江普陀山风景区

        至此,问题得以全部解决,Leaflet.canvaslabel在Ajax异步请求时bindPopup无效的解决办法。导致popup无效的问题是ajax的异步机制导致的。当然在实际开发当中,您可以使用一个解决返回所有的数据,把空间范围和数据列表同时返回就不存在上述问题了。解决办法很多,找到问题根本很重要。遇到问题,慢慢分析,大胆设想,小心验证,一定会有收获,不放弃。

总结

        以上就是本文的主要内容,本文分享了作者在排查GIS问题当中的一些思路和方法。在没有找到具体的问题前,首先检查代码的问题,然后检查相应的组件是否有什么缺陷,最后再梳理解决办法,大致的思路如此。本文在此背景下诞生,博文首先详细介绍了风景区展示时具体的问题,然后分析排查思路和方向,接着使用不同的方案验证思路,最后给出最终的解决方案。行文仓促,定有不足之处,案例的排查方法和经验都不足,欢迎有经验的大佬基于批评指正,万分感谢。

http://www.hkea.cn/news/814013/

相关文章:

  • 南安市网站建设成都今天重大新闻事件
  • 网站后台补丁如何做软文有哪几种类型
  • 网站建设的费用包括哪些内容资讯门户类网站有哪些
  • 一站式服务图片制作网页的基本步骤
  • 个人网站建设网站网络网站推广
  • asp做的药店网站模板北京百度快照推广公司
  • 网站建设泉州效率网络seo的优化策略有哪些
  • 页网站无锡网站制作推广
  • 一流的龙岗网站建设目前最靠谱的推广平台
  • 企业营销型网站费用短视频推广引流
  • 化妆品可做的团购网站有哪些seo研究中心南宁线下
  • 网站空间域名是什么做电商必备的几个软件
  • 软件公司运营是做什么的seo公司运营
  • 专业云南做网站福州短视频seo服务
  • 网站开发技术期中试题电商培训机构排名
  • 网站设计连接数据库怎么做如何进行百度推广
  • 日本网站图片做淘宝代购网络营销促销方案
  • 网站开发导航栏网站制作的费用
  • 盐城网站设计网站流量统计工具
  • 网站上如何做相关推荐郑州建网站的公司
  • 漂亮大气的装潢室内设计网站模板 单页式html5网页模板包前端优化
  • 论坛网站开发开题报告青岛百度推广多少钱
  • 文山做网站如何优化百度seo排名
  • 上海展陈设计公司有哪些成都网站seo性价比高
  • 小韩网站源码360广告投放平台
  • 网站地图的重要性短信广告投放软件
  • 搭建直播网站需要怎么做教育培训机构平台
  • 濮阳网站网站建设网络营销策划是什么
  • 做新闻网站需要什么手续河北软文搜索引擎推广公司
  • 广州网站建设联系电话seo推广的公司