MapBox中的聚类标记,如何只"accumulate"不同的属性?



我想在地图上显示标记,其中每个标记都是UserLocation。一个User可以有多个UserLocation。当我聚集标记时,我想显示这些聚集标记的用户列表,没有重复。

例如,让我们以这3个附近标记为例:

{ // Marker1
type: 'Feature',
properties: {user_id : "Daniele"},
geometry: { type        : 'Point',
coordinates : [lng0, lat0]
}
},
{// Marker2
type: 'Feature',
properties: {user_id : "Daniele"},
geometry: { type        : 'Point',
coordinates : [lng1, lat1]
}
},
{// Marker3
type: 'Feature',
properties: {user_id : "Roberto"},
geometry: { type        : 'Point',
coordinates : [lng2, lat2]
}
}

当我聚集它们时,点击聚集的圆圈,我想看到"Daniele, roberto"。我该怎么做呢?

此外,我想根据聚集的不同用户的不同数量来设置圆圈的大小(在上面的例子中,应该是2)。


* *更新2


JSFIDDLE& lt;——

可以建立一个不同名称的数组,然后使用length表达式来确定圆的大小。

无论如何,应该有一种语法错误…

clusterProperties: {
distinctNames : 
['case', 
/*cond  */ ["!", ['in',['get', 'user_id'], ['accumulated']]], 
/*result*/ ['concat', ['concat', ['get', 'user_id'], ',']],

/*default*/ ['accumulated']
]
}

根据文档,您需要这样做:

map.addSource(userData, {
id: 'user-locations',
type: 'geojson',
data: 'myuserdata.geojson',
cluster: true,
clusterProperties: {
names: ['concat', ['concat', ['get', 'user_id'], ',']]
}
}

源中的集群点现在将有一个属性names,它将包含逗号分隔(和逗号结束)的名称字符串。

此外,我想设置圆圈的大小,根据不同的用户聚集的不同数量(在上面的例子中,应该是2)

听起来……挑战。我能想到的一种方法是编写一个自定义累加器函数,如下所示:

  • 使函数返回一个包含两个值的数组,[distinctNames, allNames],其中第一个是整数,第二个是字符串。
  • 如果allNames包含我们的当前名称,只返回数组。
  • 否则,返回[distinctNames + 1, allNames + thisName]数组。

在Mapbox GL表达式中像这样操作数组是可能的,但是非常繁琐。您需要使用['literal', ...]['at', ...]

代码看起来像这样:

clusterProperties: {
names: ['concat', ['concat', ['get', 'user_id'], ',']],
distinctNames: [
['case', ['in', ['get', 'distinctNames'], ['at', ['accumulated'], 1]
['accumulated'],
['literal', ['+', ['at', ['accumulated'], 0], 1], ['concat', ['at', ['accumulated'], 1], ['get', 'distinctNames']]]
],
['concat', '%', ['get', 'user_id'], '%'] // wrap user ID in some unique character so we don't accidentally find user "rob" within another user "robin" for instance.
]
}

从文档中不清楚累加器函数是如何工作的,或者如何访问当前值。他们的例子暗示它将是['get', <name of cluster property>],尽管这看起来有点奇怪。

文档不是很清楚,但这里是我如何实现这个"独特的累积"。

来自clusterProperties定义:

引用特殊["累加"]值的自定义reduce表达式,例如:

{"sum": [["+", ["accumulated"], ["get", "sum"]], ["get", "scalerank"]]}

结果与:{"sum": ["+", ["get", "scalerank"]]}

相同

在您的示例中,您希望从标记中积累user_id属性,而不需要重复项。

逻辑是只在user_id尚未添加到累积值中时才添加它。

clusterProperties: {
distinctUsers: [
// ['accumulated'] is the current value iterated during the reduce (the property is defined at [1])
// ['get', 'distinctCountries'] is the accumulated / concatenated string
[
// Concat accumulated value + current value if not present in accumulated
'concat',
['get', 'distinctUsers'],
[
'case',
['in', ['accumulated'], ['get', 'distinctUsers']],  // If accumulated (user_id) has already been added
'',  // Add EMPTY string
['concat', ', ', ['accumulated']],  // Add the user_id (concatenated with a comma in your case)
],
],
['get', 'user_id'], // [1]: source marker property iterated in the custom reduce function
]
}

正如Steve在他的回答中所说,你也可以用一些独特的字符来包装user_id,这样你就不会意外地发现用户"抢劫"了。在另一个用户"robin"例如,

[1]定义的源属性['get', 'user_id']将变成:

['concat', '%', ['get', 'user_id'], '%']

相关内容

  • 没有找到相关文章

最新更新