【问题标题】:Leaflet slider group by year传单滑块按年份分组
【发布时间】:2015-06-06 11:30:32
【问题描述】:

我正在使用传单滑块 - https://github.com/dwilhelm89/LeafletSlider - 但我无法获得所需的结果,即使从插件描述中它似乎可以做到。

我有一个特征集合,几何类型是多边形,我根据插件的要求插入了一个属性“时间”。 我已经尝试过使用 "time":"2014" 和 "time":"2014-01-01 00:00:00" 的机器人,没有区别。 我总共有 30 个功能,2012 年有 10 个,2013 年有 10 个,2014 年有 10 个

我想要实现的是通过移动滑块显示 2012 年、2013 年和 2014 年的所有多边形,这应该有 3 个步骤,每年一个步骤。

相反,每次滑块移动时我总是得到一个多边形。 一开始我也得到了所有的多边形(30)设计在彼此之上,即使我指定“showAllOnStart: false

这是我的js代码:

var geojson;
    $(document).ready(function () {
        $.getJSON("urlWhereIretrieveTheJson", function (geoJson) {
            geojson = L.geoJson(geoJson, { style: style, onEachFeature: onEachFeature }).addTo(map);

            var sliderControl = L.control.sliderControl({
                position: "bottomleft",
                layer: geojson,
                range: false,
                showAllOnStart: false
            });

            map.addControl(sliderControl);
            sliderControl.startSlider();
            ;
        });
    });

json 架构如下:

{"type": "FeatureCollection",
"features": [
{"type":"Feature",
"properties": {"name": "Thies","bl": 6,"**time**": "**2013-01-01 00:00:00+00**"},
"geometry":{"type":"Polygon","coordinates":[....]} 
},{....}
]}

这是一个带有完整代码和数据源的 jsFiddle: http://jsfiddle.net/brainsengineering/nboo4ksg/

【问题讨论】:

  • 有没有机会将整个设置放到演示站点上?
  • @snkashis 用 jsFiddle 更新

标签: jquery-ui dictionary slider gis leaflet


【解决方案1】:

一件事的答案

即使我指定“showAllOnStart: false”,我也得到了所有的多边形(30 个)设计在彼此之上,

你是这样添加geojson的吗

geojson = L.geoJson(geoJson, { style: style, onEachFeature: onEachFeature }).addTo(map);

不要在末尾添加addTo(map),只需这样做

geojson = L.geoJson(geoJson, { style: style, onEachFeature: onEachFeature });

另一件事是您希望根据相同的值对数据进行分组,即对 2013、2014 和 2015 年的数据进行分组。为此,我们需要稍微更改插件,因为目前插件不要处理基于相同值的数据分组。所以这里是代码

L.Control.SliderControl = L.Control.extend({
options: {
    position: 'topright',
    layers: null,
    timeAttribute: 'time',
    isEpoch: false,     // whether the time attribute is seconds elapsed from epoch
    startTimeIdx: 0,    // where to start looking for a timestring
    timeStrLength: 19,  // the size of  yyyy-mm-dd hh:mm:ss - if millis are present this will be larger
    maxValue: -1,
    minValue: -1,
    showAllOnStart: false,
    markers: null,
    range: false,
    follow: false,
    alwaysShowDate : false,
    rezoom: null
},

initialize: function (options) {
    L.Util.setOptions(this, options);
    this._layer = this.options.layer;

},

extractTimestamp: function(time, options) {
    if (options.isEpoch) {
        time = (new Date(parseInt(time))).toString(); // this is local time
    }
    return time.substr(options.startTimeIdx, options.startTimeIdx + options.timeStrLength);
},

setPosition: function (position) {
    var map = this._map;

    if (map) {
        map.removeControl(this);
    }

    this.options.position = position;

    if (map) {
        map.addControl(this);
    }
    this.startSlider();
    return this;
},

onAdd: function (map) {
    this.options.map = map;

    // Create a control sliderContainer with a jquery ui slider
    var sliderContainer = L.DomUtil.create('div', 'slider', this._container);
    $(sliderContainer).append('<div id="leaflet-slider" style="width:200px"><div class="ui-slider-handle"></div><div id="slider-timestamp" style="width:200px; margin-top:13px; background-color:#FFFFFF; text-align:center; border-radius:5px;"></div></div>');
    //Prevent map panning/zooming while using the slider
    $(sliderContainer).mousedown(function () {
        map.dragging.disable();
    });
    $(document).mouseup(function () {
        map.dragging.enable();
        //Hide the slider timestamp if not range and option alwaysShowDate is set on false
        if (options.range || !options.alwaysShowDate) {
            $('#slider-timestamp').html('');
        }
    });

    var options = this.options;
    this.options.markers = [];
    this.options.unique_time_values = [];

    //If a layer has been provided: calculate the min and max values for the slider
    if (this._layer) {
        /*var index_temp = 0;
        this._layer.eachLayer(function (layer) {
            //console.log(layer);
            options.markers[index_temp] = layer;
            ++index_temp;
        });
        options.maxValue = index_temp - 1;
        this.options = options;*/

        var flags = [], unique_values = [],len;
        this._layer.eachLayer(function (layer) {

            if( flags[layer.feature.properties.time]) return;
            flags[layer.feature.properties.time] = true;
            unique_values.push(layer.feature.properties.time);
            ++len;

        });
        //console.log(unique_values);

        var all_features = [];
        for (var i=0;i<unique_values.length;i++){
            all_features[i] = [];
        }
        //console.log(all_features);

        //console.log(this._layer.getLayers().length)
        var layers = this._layer.getLayers()
        for(var i=0;i<layers.length;i++){

            //console.log(layers[i].feature.properties.time);
            var index = unique_values.indexOf(layers[i].feature.properties.time)
            //console.log(index);
            all_features[index].push(layers[i]);

        }
        //console.log(all_features);

        for (var i=0;i<all_features.length;i++){
            options.markers[i] = L.featureGroup(all_features[i]);
        }
        options.maxValue = all_features.length - 1;
        this.options = options;
        this.options.unique_time_values = unique_values

    } else {
        console.log("Error: You have to specify a layer via new SliderControl({layer: your_layer});");
    }
    return sliderContainer;
},

onRemove: function (map) {
    //Delete all markers which where added via the slider and remove the slider div
    for (i = this.options.minValue; i < this.options.maxValue; i++) {
        map.removeLayer(this.options.markers[i]);
    }
    $('#leaflet-slider').remove();
},

startSlider: function () {
    _options = this.options;
    _extractTimestamp = this.extractTimestamp
    var index_start = _options.minValue;
    if(_options.showAllOnStart){
        index_start = _options.maxValue;
        if(_options.range) _options.values = [_options.minValue,_options.maxValue];
        else _options.value = _options.maxValue;
    }
    $("#leaflet-slider").slider({
        range: _options.range,
        value: _options.minValue,
        values: _options.values,
        min: _options.minValue,
        max: _options.maxValue,
        step: 1,
        slide: function (e, ui) {
            var map = _options.map;
            var fg = L.featureGroup();
            if(!!_options.markers[ui.value]) {
                //console.log('inside');
                // If there is no time property, this line has to be removed (or exchanged with a different property)
                if(_options.markers[ui.value].feature !== undefined) {
                    if(_options.markers[ui.value].feature.properties[_options.timeAttribute]){
                        if(_options.markers[ui.value]) $('#slider-timestamp').html(
                            _extractTimestamp(_options.unique_values[ui.value].feature.properties[_options.timeAttribute], _options));
                    }else {
                        console.error("Time property "+ _options.timeAttribute +" not found in data");
                    }
                }else {
                    // set by leaflet Vector Layers
                    if(_options.unique_time_values[ui.value]){
                        if(_options.markers[ui.value]) $('#slider-timestamp').html(
                            _extractTimestamp(_options.unique_time_values[ui.value], _options));
                    }else {
                        console.error("Time property "+ _options.timeAttribute +" not found in data");
                    }
                }

                var i;
                // clear markers
                for (i = _options.minValue+1; i <= _options.maxValue; i++) {
                    if(_options.markers[i]) map.removeLayer(_options.markers[i]); 
                }
                if(_options.range){
                    // jquery ui using range
                    for (i = ui.values[0]; i <= ui.values[1]; i++){
                       if(_options.markers[i]) {
                           map.addLayer(_options.markers[i]);
                           fg.addLayer(_options.markers[i]);
                       }
                    }
                }else if(_options.follow){
                    for (i = ui.value - _options.follow + 1; i <= ui.value ; i++) {
                        if(_options.markers[i]) {
                            map.addLayer(_options.markers[i]);
                            fg.addLayer(_options.markers[i]);
                        }
                    }
                }else{
                    for (i = _options.minValue; i <= ui.value ; i++) {
                        if(_options.markers[i]) {
                            map.addLayer(_options.markers[i]);
                            fg.addLayer(_options.markers[i]);
                        }
                    }
                }
            };
            if(_options.rezoom) {
                map.fitBounds(fg.getBounds(), {
                    maxZoom: _options.rezoom
                });
            }
        }
    });
    if (!_options.range && _options.alwaysShowDate) {
        $('#slider-timestamp').html(_extractTimeStamp(_options.markers[index_start].feature.properties[_options.timeAttribute], _options));
    }
    for (i = _options.minValue; i < index_start; i++) {
        _options.map.addLayer(_options.markers[i]);
    }
}
});

L.control.sliderControl = function (options) {
    return new L.Control.SliderControl(options);
};

只需删除插件当前源的链接并使用上面提供的代码代替插件文件即可。如果您遇到任何问题,请告诉我,我也会为您创建一个fiddle

注意:由于我已针对您的具体情况修改了代码,因此在其他情况下可能无法正常工作

【讨论】:

  • 只有一个问题:它不会删除“旧”多边形,但会重叠:如果我选择 2015,我会看到 2013、2014 和 2015 相互重叠。我正在尝试修改代码以将它们全部删除
  • 当您调用sliderControl 代替range:false 时,只需将follow:true 作为参数传递。希望它会工作
  • 在我使用您的解决方案调整代码后,无法让 alwaysShowDate 属性正常工作。知道如何解决它吗?
猜你喜欢
  • 1970-01-01
  • 2020-04-22
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多