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

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

问题描述

我使用传单滑块 - https://github.com/dwilhelm89/LeafletSlider - 但是我不能得到所需的结果,即使从插件描述看来它可以做。



我有一个功能的集合,几何类型是多边形,其中我根据插件的要求插入了一个属性time。
我试过机器人与时间:2014和时间:2014-01-01 00:00:00没有区别。
我共有30个功能,2012年10个,2013年10个,2014年10个。



我想要实现的是显示所有的多边形2012年,然后到2014年,然后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,
范围: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 **},
几何 :{type:Polygon,coordinates:[....]}
},{....}
]}
这是一个完整的代码和数据源的jsFiddle:
http://jsfiddle.net/brainsengineering/nboo4ksg/

解决方案

有一件事,即使我指定了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,//时间属性是否从epoch过去的秒数
startTimeIdx:0,//从哪里开始查找时间戳
timeStrLength:19,// yyyy-mm-dd的大小hh:mm:ss - 如果存在millis,则会更大
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(); //这是本地时间
}
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();
返回这个;
},

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

//使用jquery ui滑块创建控件sliderContainer
var sliderContainer = L.DomUtil.create('div','slider',this._container);
$(sliderContainer).append('< div id =leaflet-sliderstyle =width:200px>< div class =ui-slider-handle>< / div> < div id =slider-timestampstyle =width:200px; margin-top:13px; background-color:#FFFFFF; text-align:center; border-radius:5px;>< / div> < / DIV>');
//使用滑块时阻止地图平移/缩放
$(sliderContainer).mousedown(function(){
map.dragging.disable();
});
$(document).mouseup(function(){
map.dragging.enable();
//隐藏滑块时间戳,如果不是范围,并且选项alwaysShowDate设置为false
if(options.range ||!options.alwaysShowDate){
$('#slider-timestamp')。html('');
}
});

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

//如果提供了一个图层:计算滑块的最小值和最大值
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 = []; (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(错误:您必须通过新的SliderControl({layer:your_layer})指定一个图层; );
}
return sliderContainer;
},

onRemove:function(map){
//删除所有通过滑块添加的标记,并删除滑块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。值
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(_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.timeAttribu te],_options));
} else {
console.error(Time property+ _options.timeAttribute +在数据中找不到);
}
} else {
//通过传单设置矢量图层
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 +在数据中找不到);
}
}

var i;
//清除标记
(i = _options.minValue + 1; i <= _options.maxValue; i ++){
if(_options.markers [i])map.removeLayer _options.markers [I]);
}
if(_options.range){
// jquery ui使用范围
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)); (i = _options.minValue; i< index_start; i ++){
_options.map.addLayer(_options.markers [i]);
}

}
}
});

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

只需删除与当前插件源的链接,并使用上面提供的代码代替插件文件它会工作。告诉我,如果你遇到任何问题,所以我会为你创建一个小提琴



注意:由于我修改了特定案例的代码,因此在其他情况下可能无法正常工作。


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.

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

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.

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"

here is my js code:

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();
            ;
        });
    });

the json schema is like the following:

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

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

解决方案

The answer to one thing that

I get also all the polygons (30) designed on top of each other, even if I specify "showAllOnStart: false"

is that you're adding geojson this way

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

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

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

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);
};

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.

Note: As I've modified the code for your specific case, it might not work in other scenarios

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

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