Leaflet.VectorGrid loading point vector tile mouse click report Cannot read properties of undefined solution

Table of contents

Preface

1. Data introduction

1. Vector tile metadata

2. Vector tile rendering 

1. Set tile rendering configuration

2. Map loading and event binding

3. Initial loading

3. Problem solving 

1. Problem finding

 2. Problem solving

3. Final effect

Summarize


Preface

        In previous blogs, I have written several blogs about loading and using Leaflet.VectorGrid in Leaflet to render vector tiles. Interested blogs can be found at the link below.

serial number blog address
1 Solve the problem of Y-axis offset of vector tiles based on VectorGrid
2 A brief discussion on front-end custom VectorGrid vector tile style
3 Load vector tile instances published by GeoServer based on VectorGrid

        The above blog provides detailed explanations on how to use VectorGrid to render vector tiles. However, the data types of the above vector tiles are mostly surface and line data, and there is no rendering display of point data. It is common to perform data rendering and display of POIs and city facilities.

        When using Leaflet.VectorGrid1.3.0 to render point vector tile data, and then turning on event interaction, taking mouseover as an example, when the event is added and the mouse is hovered, the corresponding data is not displayed, but is displayed at the bottom of the console. Report an error. As shown below:

        This article will introduce how to solve the problem of errors when loading point vector data and adding event listeners in Leaflet.VectorGrid. If you currently have these problems, you can try this solution, which may solve the problems you encounter. 

1. Data introduction

        Before the formal rendering, let’s give a brief introduction to the data involved. The map mainly contains three types of data. The base map uses Amap's online images, the national province data uses surface vector tiles published by itself, and the point data uses point data of geological disasters across the country. Disaster types can be divided into: small, medium and large.

serial number illustrate address
1 Amap https://wprd01.is.autonavi.com/appmaptile?&x={x}&y={y}&z={z}&lang=zh_cn&size=2&scl=1&style=6&ltype=7
2 Province vector tiles http://localhost:8086/data/province-4326/{z}/{x}/{y}.pbf
3 Earth disaster tiles http://localhost:8086/data/dizai1228/{z}/{x}/{y}.pbf

1. Vector tile metadata

The two vector tiles mentioned above, provincial and disaster tiles, are stored locally. Taking provincial tiles as an example, their directory is as follows:

 Among them, metadata.json is the metadata information used to describe vector tiles.

         From the above json description, we can know the parameter information of the vector tile, such as the center point position, boundary, data format, layer information, including the layer unique identifier and attribute fields. These are useful when the map is loading.

        It should be noted here that for the information described by metajson, the name and the layer corresponding to the loaded tile are not necessarily one-to-one correspondence. Therefore, it should be noted that, take the earthquake data as an example.

        When performing style matching, you must use the id attribute in vector_layers in the json description, and do not use name to avoid the problem that vector tiles cannot be rendered.

2. Vector tile rendering 

The rendering method of Leaflet.VectorGrid has been introduced in the previous blog. I will not go into details here. I will post the main code.

1. Set tile rendering configuration

const pbfUrl2 = "http://localhost:8086/data/dizai1228/{z}/{x}/{y}.pbf";

	var vectorTileOptions2 = {
		 layerURL: pbfUrl2,
		 rendererFactory: L.svg.tile,           
		 tms: false, 
		 interactive: true,	//开启VectorGrid触发mouse/pointer事件
		 vectorTileLayerStyles: vectorTileStyling,
		 getFeatureId: function(f) {
			return f.properties.LineUid;
		}
	 };      

        In the above code, use interactive: true to enable relevant events. If set to false, event response cannot be performed.

2. Map loading and event binding

var vectorTile2 = new L.vectorGrid.protobuf(pbfUrl2, vectorTileOptions2).addTo(map);
	
	vectorTile2.on('mouseover', function (e) {    
		var properties = e.layer.properties; 
		//console.log(properties);
		L.popup()
		 .setContent(properties.名称 + "<br/>" + properties.灾害类 + "<br/>" + properties.地理位)
		 .setLatLng(e.latlng)
		 .openOn(map);  
	});

3. Initial loading

        The above code completes the rendering of earthquake vector tiles. After publishing the static html file using a server such as nginx, the effect can be viewed in the browser.

        As you can see, the problem mentioned at the beginning is perfectly reproduced.

3. Problem solving 

        As you can see from the exception, the main problem is the longitude and latitude of the point data.

        When I first encountered this problem, I thought it was a problem with the cut vector tiles, so I searched for the data source for a long time, and then used the mapbox framework to load it without any problem.

1. Problem finding

        With the problem in mind, after trying the solution to no avail, I opened the open source address and found the issue, only to find that a senior had already stepped in for me. Let’s take a look at the original post 267 :

Here is a clue to open this connection address ,

 2. Problem solving

        After finding the problem, let's look at how to solve it and the solution .

 The original text describes it this way,

Point Symbolizer instances inherit from marker or circlemarker, but they lack latlng information, and on mouseover or click, leaflet will error on these features if it finds the getLatLng method, since that indicates it should be treated as a real marker instance, but even though the method is there, the value isn't, so leaflet produces an error.

Maybe these instance should have a latlng, I don't know, this was just an easy fix so that I could continue to use vectorgrid protobuf support with points and have mouseover and click events work.

My English is not good, so I used a degree to translate it into:

点符号化器实例继承自标记或circlemarker,但它们缺乏定位信息,当鼠标悬停或单击时,如果传单找到getLatLng方法,它将在这些功能上出错,因为这表明它应该被视为真正的标记实例,但即使该方法存在,值也不存在,因此传单会产生错误。

也许这些实例应该有一个平台,我不知道,这只是一个简单的修复,这样我就可以继续使用vectorgrid protobuf对点的支持,并让鼠标悬停和点击事件正常工作。

The getLatlng method has an impact on this, so we can leave getLatlng blank when creating the layer. The method of creating a layer is in the Leaflet.VectorGrid.js file, about line 496

_createLayer: function(feat, pxPerExtent, layerStyle) {
		var layer;
		switch (feat.type) {
		case 1:
			layer = new PointSymbolizer(feat, pxPerExtent);
			break;
		case 2:
			layer = new LineSymbolizer(feat, pxPerExtent);
			break;
		case 3:
			layer = new FillSymbolizer(feat, pxPerExtent);
			break;
		}

		if (this.options.interactive) {
			layer.addEventParent(this);
		}

		return layer;
	},

When creating new PointSymbolizer(feat, pxPerExtent);, set layer.getLatLng = null;

3. Final effect

         At this point, the problem of point vector tiles not being loaded has been perfectly solved. Thanks to the open source community, maybe this is the charm of open source.

Summarize

        The above is the main content of this article. This article will introduce how to solve the problem of errors when loading point vector data and adding event listeners in Leaflet.VectorGrid. If you currently have these problems, you can try this solution. Maybe Can solve the problems encountered.

Guess you like

Origin blog.csdn.net/yelangkingwuzuhu/article/details/135435390