传单滑块按年份分组 [英] Leaflet slider group by year

查看:41
本文介绍了传单滑块按年份分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用传单滑块 - https://github.com/dwilhelm89/LeafletSlider - 但是我无法得到想要的结果,即使从插件描述看来它可以做到.

I'm using leaflet slider - https://github.com/dwilhelm89/LeafletSlider - but I can't get the desired result, even if from the plugin description it seems it can do.

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

I have a collection of features, geometry type is polygon, where I've inserted a property "time" as requested by the plugin. I've tried bot with "time":"2014" and "time":"2014-01-01 00:00:00" with no difference. I have in total 30 features, 10 for 2012, 10 for 2013 and 10 for 2014

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

What I'm trying to achieve is to show all the polygon of 2012, then 2013 and then 2014, by moving the slider, that should have 3 steps, each year one step.

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

Instead I get always one polygon at each slider move. At the beginning I get also all the polygons (30) designed on top of each other, even if I specify "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/

Here is a jsFiddle with complete code and datasource: http://jsfiddle.net/brainsengineering/nboo4ksg/

推荐答案

一件事的答案

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

是你这样添加geojson

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

不要在末尾添加 addTo(map),直接这样做

don't add addTo(map) at the end, simply do this

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

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

the other thing is that you want to group your data based on same values i.e group data for year 2013, 2014 and 2015. For this we need to alter the plugin a bit because currently the plugin don't handle to group data based on same values. So here is the code

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.

Just remove the link to current source of the plugin and use the code provided above in place of plugin file and it'd work. Tell me if you face any problem, so i'll create a fiddle for you as well.

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

这篇关于传单滑块按年份分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆