如何在Mapbox GL JS动画中为LineString分段着色不同

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Mapbox GL JS动画中为LineString分段着色不同相关的知识,希望对你有一定的参考价值。

我正在根据获得的一些历史GPS项圈数据制作动画,显示狼的去向。该代码基于以下Mapbox示例:https://docs.mapbox.com/mapbox-gl-js/example/live-update-feature/

我想根据白天还是晚上来给线段上色,晚上是蓝色,白天是红色。像这样:

enter image description here

在时间段1中,狼向东向东北移动;现在是晚上,所以线段是蓝色的。在时间段2中,狼向东北移动;现在是白天,因此线段为红色。在时间段3,狼再次向东北移动。现在是晚上,所以线段再次变成蓝色。

但是我似乎无法使用其他颜色。我有一些玩具/示例数据:

 "type": "FeatureCollection", "features": [  "type": "Feature", "geometry": 
"type": "LineString", "coordinates" : [[-112.191833, 57.073668],
[-112.181833, 57.083668],
[-112.181833, 57.073668],
[-112.201833, 57.075668]]  ], 
"properties": "daytime" : [0, 1, 1, 0] 

有四个时间段,中间两个是白天(设置为1)。

这是我的代码。 (您需要将其粘贴到mapbox键中才能起作用):

mapboxgl.accessToken = 'INSERT YOUR MAPBOX KEY HERE';
var map = new mapboxgl.Map(
	container: 'map',
	style: 'mapbox://styles/mapbox/satellite-v9',
	zoom: 0
);

map.on('load', function() 
	// We use D3 to fetch the JSON here to parse and use it separately
	// from GL JS's use in the added source. You can use any request method 
	// that you want.
	d3.json(
		"https://raw.githubusercontent.com/pete-rodrigue/wolves_of_alberta/data_store/wolves_geojson_example.geojson?token=ACEMB42EH5NKZSF24MHPQSS6JFTMU",
		function(err, data) 
			if (err) throw err;
			
			// save full coordinate list for later
			var coordinates = data.features[0].geometry.coordinates;
			// save 1's and 0's for later
			var daynight = data.properties.daytime  
			
			// start by showing just the first coordinate
			data.features[0].geometry.coordinates = [coordinates[0]];
			// THIS NEXT LINE IS ONE PART OF MY FAILED APPROACH:
			data.properties.daytime = ['blue'];   //  set initial color value to blue
			
			// add it to the map
			map.addSource('trace',  type: 'geojson', data: data );
			map.addLayer(
				'id': 'trace',
				'type': 'line',
				'source': 'trace',
				'paint': 
					// THIS WILL WORK FINE
					'line-color': 'orange',   
					// 'line-color': ['to-string', ['get', 'daytime']], //  DOES NOT WORK
					'line-width': 8
				,
				layout: 'line-cap': 'round', 'line-join': 'round'
			);
			
			// setup the viewport
			map.jumpTo( 'center': coordinates[0], 'zoom': 13 );
			map.setPitch(30);
			
			// on a regular basis, add more coords from the saved list to update map
			var i = 0;
			var timer = window.setInterval(function() 
				if (i < coordinates.length) 
					data.features[0].geometry.coordinates.push(
						coordinates[i]
					);
					
					// if it's daytime, append blue; if it's nighttime, append red
					if (daynight[i] == 0) 
						data.properties.daytime.push(['blue']);
					 else data.properties.daytime.push(['red']);
				
				map.getSource('trace').setData(data);
				map.panTo(coordinates[i]);
				i++;
			 else 
				window.clearInterval(timer);
			
		, 150);
	
);
);
body  margin: 0; padding: 0; 
#map  position: absolute; top: 0; bottom: 0; width: 100%; 
<head>
<meta charset="utf-8" />
<title>Wolves GPS collar example data</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js"></script>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css" rel="stylesheet" />
<link rel="stylesheet" href="main_css.css">
</head>

<body>
  <div id="map"></div>
  <script type="text/javascript" src='main_js.js'></script>
</body>

也在这里:https://codepen.io/pete-rodrigue/pen/XWbJOpK

我已经注释掉了无效的部分,并留下了注释。

基本上,我正在尝试这样做:

'line-color': ['to-string', ['get', 'daytime']]

paintmap.addLayer()部分中,其中daytime属性是一个字符串数组,该字符串表示为“ blue”或“ red”,随着动画的进行,我将新元素压入其中-这就是代码:

if (daynight[i] == 0) 
   data.properties.daytime.push(['blue']);  // if it's daytime, append blue
  else 
   data.properties.daytime.push(['red']);  // if it's nighttime, append red
 

我肯定有一个显而易见的原因为什么这不起作用。但是我对此并不陌生。

非常感谢您对基本原理的任何帮助和解释。

答案

指定时:

'line-color': ['to-string', ['get', 'daytime']]

在带有'trace'Map#addLayer层中,告知地图渲染器使用'[0, 1, 1, 0]'(在您提供的示例数据的情况下)作为ID为source'trace'中各行的颜色]。它不会等待您设置计时器,即使这样做,您也可能会遇到JavaScript异步问题。如Mapbox的style specification中所述,'line-color'期望以html样式的十六进制值RGB,RGBA,HSL或HSLA的形式出现color,因此您可能会遇到错误,因为字符串化数组不是这些表格。

相反,我建议将每个时间段分解成自己的color,其中LineString由其在原始颜色数组中的对应值指定,并将这些'line-color'作为单独的图层添加到地图中。然后,您可以通过设置一些时间间隔来指定指定添加和动画化图层的顺序来创建动画效果,如LineString中所做的。

以上是关于如何在Mapbox GL JS动画中为LineString分段着色不同的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mapbox-gl 中为图层文本字段添加背景颜色

如何更改/偏移Mapbox GL JS中的摄像机中心点?

如何在 mapbox 中为 Geoserver 图层设置动画?

如何将 Mapbox Mapmatching API 输出与 mapbox-gl-js 一起使用?

如何在 mapbox-gl-js 的标记上添加“点击”侦听器

如何在 mapbox-gl-js 中以某些缩放级别隐藏点标签?