特征层的 Mapbox 设置图标

Posted

技术标签:

【中文标题】特征层的 Mapbox 设置图标【英文标题】:Mapbox set icon for featureLayer 【发布时间】:2017-01-29 16:16:04 【问题描述】:

我在为要素图层设置图标时遇到了一些问题。我不断收到layer.setIcon is not a function 和类似的错误。如何更改此图层的图标样式?

 var layer = L.mapbox.featureLayer()
            .loadURL(attrs.geoJsonSource)
            .addTo(map);

        layer.on('ready', function() 
            this.eachLayer(function(layer)
                layer.setIcon(L.mapbox.marker.icon(
                    'marker-color': '#8834bb',
                    'marker-size': 'large',
                    'marker-symbol': 'restaurant'
                ))
            );
            map.fitBounds(featureLayer.getBounds());
        );

【问题讨论】:

你想在哪里存储标记样式?在 geoJSON 端还是直接在网页端? 网页端是 那么您是否尝试过使用下面的“FIRST”方法? 【参考方案1】:

您可以使用简单的样式规范来设置 geojson 的样式。看起来这需要在您将其添加到要素图层之前发生。您可以尝试运行 eachLayer 而不是 for 循环,然后将该层添加到另一个要素层,一旦 geojson 具有您想要的样式/图标。这是从原始example 修改而来的。或者您可以使用 Leaflet pointToLayer 函数,如下所示。

var key = 'your key here'
L.mapbox.accessToken = key;
var map = L.mapbox.map('map')
  .setView([37.8, -96], 3);

var geojson = [
  
    type: 'Feature',
    geometry: 
      type: 'Point',
      coordinates: [-77.031952, 38.913184]
    ,
    properties: 
      title: 'Title'
    
  
 ];
//Option A - set the properties of the geojson using the simple style spec supported in mapbox.js for mapbox feature layers

/*for(i = 0; i < geojson.length; i++) 
  geojson[i].properties['marker-color'] = '#63b6e5';
  geojson[i].properties['marker-size'] = 'large';
  geojson[i].properties['marker-symbol'] = 'rocket';
*/

//Option B - use the native leaflet function for points - very simple and extendable to other icon plugins
var features = L.geoJson(geojson,  
  pointToLayer: function(feature, latlng)
    return new L.marker(latlng, 
      icon: L.mapbox.marker.icon(
        'marker-color': '#00f',
        'marker-symbol': 'star'
        )
    )
  
 ).addTo(map);
body  margin:0; padding:0; 
    .map  position:absolute; top:0; bottom:0; width:100%; 
<script src="https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.js"></script>
<link href='https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.css' rel='stylesheet' />
<div id='map' class='map'></div>

【讨论】:

但是我的数据为什么要知道它是如何呈现的呢?不能逐步改变风格吗? 是的,我认为这很愚蠢,但这是 mapbox.js 的一个特性。您可能只想将普通的 L.geoJson() 与上面的 pointToLayer 方法一起使用。请注意,它没有使用 simplestyle-spec,因为它不是 mapbox 要素图层。 @malcolm 您可能会从答案中删除您的访问令牌(现在每个人都可以使用它......) 接受的答案与我的答案基本相同,除了我使用 L.geoJson 中的 pointToLayer 函数而不是 mapbox 要素图层。这两个函数的作用完全相同!问题不在于如何使用 setIcon() 函数,而在于如何更改图标。【参考方案2】:

您可以查看https://www.mapbox.com/mapbox.js/example/v1.0.0/custom-marker/ 和http://leafletjs.com/examples/custom-icons/ 以获取更多信息,但显然您可能符合您的需要:

使用您自己的图标样式。 (第一)

和/或

使用 geoJSON 文件图标样式。 (第二)

代码:

var map = L.mapbox.map('map', 'mapbox.streets').setView([40, -74.50], 9);
var layer = L.mapbox.featureLayer().addTo(map);

layer.on('layeradd', function(e) 
    var marker = e.layer,feature = marker.feature;

    // TWO POSSIBILITIES

    // FIRST // your own method to define how icon will be rendered   
    marker.setIcon(L.mapbox.marker.icon(
        'marker-color': '#8834bb',
        'marker-size': 'large',
        'marker-symbol': 'restaurant' 
    ));

    // SECOND // use json directly to define how icon will be rendered   
    //marker.setIcon(L.mapbox.marker.icon(feature.properties.icon));
);

layer.setGeoJSON(geoJson);

假设 geoJSON 文件如下所示:

var geoJson = [
    "type": "Feature",
    "geometry": 
        "type": "Point",
        "coordinates": [-75.00, 40]
    ,
    "properties": 
        "title": "Small astronaut",
        "icon": 
            'marker-color': '#0034bb',
            'marker-size': 'large',
            'marker-symbol': 'restaurant' 
        
    
, 
    "type": "Feature",
    "geometry": 
        "type": "Point",
        "coordinates": [-74.00, 40]
    ,
    "properties": 
        "title": "Big astronaut",
        "icon": 
            'marker-color': '#8834bb',
            'marker-size': 'large',
            'marker-symbol': 'restaurant' 
        
    
];

【讨论】:

【参考方案3】:

我不知道为什么,但建议的解决方案都不适合我。相反,我必须遍历层的各个层。

        layer.on('layeradd', function(e) 
            var marker = e.layer, feature = marker.feature;
            e.layer.getLayers().forEach(function(marker) 
                marker.setIcon(L.mapbox.marker.icon(
                    'marker-color': '#8834bb',
                    'marker-size': 'large',
                    'marker-symbol': 'restaurant'
                ));
            )
        );

【讨论】:

以上是关于特征层的 Mapbox 设置图标的主要内容,如果未能解决你的问题,请参考以下文章

mapbox点击列表图标变大

react-mapbox-gl中的可样式标记/功能?

Mapbox大数据量渲染策略

mapboxgl实时修改图标透明度

动态计算图层的中心坐标、缩放和停止

MapBox 用户位置图标 (Android)