您的位置:首页 > 产品设计 > UI/UE

修改selectToUISlider实现历史影像的对比与显示

2014-12-07 15:58 429 查看
2014年12月7日,星期日,天气,晴,是个好日子,闲来无事,将selectToUISlider与Arcgis for JS结合起来,做了一个类似于历史影像对比的东西,共享出来给大家,希望对大家有所帮助。

首先,看看实现的效果:



初始化状态



在实例中,因为没有实际的做好的影像的切片,就用这个代替了,在实际实现的过程中可根据自己的实际需求去修改。

接下来,讲讲我的实现思路。

想要实现历史影像的对比,需要考虑以下两点问题:

1、数据源。

一般来说,为了操作方便,同时也为了展示方便,很多人的解决思路是直接用tif或者JPG的图片作为数据源。这种方式可以展示出变化,但是脱离了地图。

2、存储方式

直接用图片作为数据源的时候,你的数据怎么存储?文件的形式还是入库?当为地图服务的时候,切片?

有了数据源和存储方式,我们就可以继续讨论怎么实现了。在本文中是通过切片的方式做的,选择切片,原因有:1、能够与地图紧密的结合起来去展示;2、切片提高数据的访问效率与速度。

影像之间的切换是先将原来的图层remove掉,再重新实例化图层,再添加到map中去。

关键代码:

1、selectToUISlider.jQuery.js

jQuery.fn.selectToUISlider = function(settings){
var selects = jQuery(this);

//accessible slider options
var options = jQuery.extend({
labels: 3, //number of visible labels
tooltip: true, //show tooltips, boolean
tooltipSrc: 'text',//accepts 'value' as well
labelSrc: 'value',//accepts 'value' as well	,
sliderOptions: null,
step:1,
selectshow:true,
orientation:"horizontal",
baseUrl:""
}, settings);

//handle ID attrs - selects each need IDs for handles to find them
var handleIds = (function(){
var tempArr = [];
selects.each(function(){
tempArr.push('handle_'+jQuery(this).attr('id'));
});
return tempArr;
})();

//array of all option elements in select element (ignores optgroups)
var selectOptions = (function(){
var opts = [];
selects.eq(0).find('option').each(function(){
opts.push({
value: jQuery(this).attr('value'),
text: jQuery(this).text()
});
});
return opts;
})();

//array of opt groups if present
var groups = (function(){
if(selects.eq(0).find('optgroup').size()>0){
var groupedData = [];
selects.eq(0).find('optgroup').each(function(i){
groupedData[i] = {};
groupedData[i].label = jQuery(this).attr('label');
groupedData[i].options = [];
jQuery(this).find('option').each(function(){
groupedData[i].options.push({text: jQuery(this).text(), value: jQuery(this).attr('value')});
});
});
return groupedData;
}
else return null;
})();

//check if obj is array
function isArray(obj) {
return obj.constructor == Array;
}
//return tooltip text from option index
function ttText(optIndex){
return selectOptions[optIndex].text;
}

<strong>function changeMap(optIndex){
require([
"esri/layers/FeatureLayer"
],
function(FeatureLayer){
map.removeLayer(fch);
var fchUrl  = options.baseUrl+selectOptions[optIndex].value;
fch = new FeatureLayer(fchUrl);
map.addLayer(fch);
});
}</strong>
//plugin-generated slider options (can be overridden)
var sliderOptions = {
step: options.step,
min: 0,
orientation: options.orientation,
max: selectOptions.length-1,
range: selects.length > 1,//multiple select elements = true
slide: function(e, ui) {//slide function
var thisHandle = jQuery(ui.handle);
//handle feedback
var textval = ttText(ui.value);
thisHandle
.attr('aria-valuetext', textval)
.attr('aria-valuenow', ui.value)
.find('.ui-slider-tooltip .ttContent')
.text( textval );

//control original select menu
var currSelect = jQuery('#' + thisHandle.attr('id').split('handle_')[1]);
currSelect.find('option').eq(ui.value).attr('selected', 'selected');
<strong>changeMap(ui.value);</strong>
},
values: (function(){
var values = [];
selects.each(function(){
values.push( jQuery(this).get(0).selectedIndex );
});
return values;
})()
};

//slider options from settings
options.sliderOptions = (settings) ? jQuery.extend(sliderOptions, settings.sliderOptions) : sliderOptions;

//select element change event
selects.bind('change keyup click', function(){
var thisIndex = jQuery(this).get(0).selectedIndex;
var thisHandle = jQuery('#handle_'+ jQuery(this).attr('id'));
var handleIndex = thisHandle.data('handleNum');
thisHandle.parents('.ui-slider:eq(0)').slider("values", handleIndex, thisIndex);
});

//create slider component div
var sliderComponent = jQuery('<div></div>');

//CREATE HANDLES
selects.each(function(i){
var hidett = '';

//associate label for ARIA
var thisLabel = jQuery('label[for=' + jQuery(this).attr('id') +']');
//labelled by aria doesn't seem to work on slider handle. Using title attr as backup
var labelText = (thisLabel.size()>0) ? 'Slider control for '+ thisLabel.text()+'' : '';
var thisLabelId = thisLabel.attr('id') || thisLabel.attr('id', 'label_'+handleIds[i]).attr('id');

if( options.tooltip == false ){hidett = ' style="display: none;"';}
jQuery('<a '+
'href="#" tabindex="0" '+
'id="'+handleIds[i]+'" '+
'class="ui-slider-handle" '+
'role="slider" '+
'aria-labelledby="'+thisLabelId+'" '+
'aria-valuemin="'+options.sliderOptions.min+'" '+
'aria-valuemax="'+options.sliderOptions.max+'" '+
'aria-valuenow="'+options.sliderOptions.values[i]+'" '+
'aria-valuetext="'+ttText(options.sliderOptions.values[i])+'" '+
'><span class="screenReaderContext">'+labelText+'</span>'+
'<span class="ui-slider-tooltip ui-widget-content ui-corner-all"'+ hidett +'><span class="ttContent"></span>'+
'<span class="ui-tooltip-pointer-down ui-widget-content"><span class="ui-tooltip-pointer-down-inner"></span></span>'+
'</span></a>')
.data('handleNum',i)
.appendTo(sliderComponent);
});

//CREATE SCALE AND TICS

//write dl if there are optgroups
if(groups) {
var inc = 0;
var scale = sliderComponent.append('<dl class="ui-slider-scale ui-helper-reset" role="presentation"></dl>').find('.ui-slider-scale:eq(0)');
jQuery(groups).each(function(h){
scale.append('<dt style="width: '+ (100/groups.length).toFixed(2) +'%' +'; left:'+ (h/(groups.length-1) * 100).toFixed(2)  +'%' +'"><span>'+this.label+'</span></dt>');//class name becomes camelCased label
var groupOpts = this.options;
jQuery(this.options).each(function(i){
var style = (inc == selectOptions.length-1 || inc == 0) ? 'style="display: none;"' : '' ;
var labelText = (options.labelSrc == 'text') ? groupOpts[i].text : groupOpts[i].value;
scale.append('<dd style="left:'+ leftVal(inc) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></dd>');
inc++;
});
});
}
//write ol
else {
var scale = sliderComponent.append('<ol class="ui-slider-scale ui-helper-reset" role="presentation"></ol>').find('.ui-slider-scale:eq(0)');
jQuery(selectOptions).each(function(i){
var style = (i == selectOptions.length-1 || i == 0) ? 'style="display: none;"' : '' ;
var labelText = (options.labelSrc == 'text') ? this.text : this.value;
scale.append('<li style="left:'+ leftVal(i) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></li>');
});
}

function leftVal(i){
return (i/(selectOptions.length-1) * 100).toFixed(2)  +'%';

}
function onChange(value){
ttText(value);
}

//show and hide labels depending on labels pref
//show the last one if there are more than 1 specified
if(options.labels > 1) sliderComponent.find('.ui-slider-scale li:last span.ui-slider-label, .ui-slider-scale dd:last span.ui-slider-label').addClass('ui-slider-label-show');

//set increment
var increm = Math.max(1, Math.round(selectOptions.length / options.labels));
//show em based on inc
for(var j=0; j<selectOptions.length; j+=increm){
if((selectOptions.length - j) > increm){//don't show if it's too close to the end label
sliderComponent.find('.ui-slider-scale li:eq('+ j +') span.ui-slider-label, .ui-slider-scale dd:eq('+ j +') span.ui-slider-label').addClass('ui-slider-label-show');
}
}

//style the dt's
sliderComponent.find('.ui-slider-scale dt').each(function(i){
jQuery(this).css({
'left': ((100 /( groups.length))*i).toFixed(2) + '%'
});
});

//inject and return
sliderComponent
.insertAfter(jQuery(this).eq(this.length-1))
.slider(options.sliderOptions)
.attr('role','application')
.find('.ui-slider-label')
.each(function(){
jQuery(this).css('marginLeft', -jQuery(this).width()/2);
});

//update tooltip arrow inner color
sliderComponent.find('.ui-tooltip-pointer-down-inner').each(function(){
var bWidth = jQuery('.ui-tooltip-pointer-down-inner').css('borderTopWidth');
var bColor = jQuery(this).parents('.ui-slider-tooltip').css('backgroundColor')
jQuery(this).css('border-top', bWidth+' solid '+bColor);
});

var values = sliderComponent.slider('values');

if(isArray(values)){
jQuery(values).each(function(i){
sliderComponent.find('.ui-slider-tooltip .ttContent').eq(i).text( ttText(this) );
});
}
else {
sliderComponent.find('.ui-slider-tooltip .ttContent').eq(0).text( ttText(values) );
}
if(!options.selectshow){
this.css("display","none");
}
return this;
}
代码中,加粗的为重点代码。

2、map.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title></title>
<link rel="stylesheet" href="jquery-slider/css/redmond/jquery-ui-1.7.1.custom.css" type="text/css" />
<link rel="Stylesheet" href="jquery-slider/css/ui.slider.extras.css" type="text/css" />
<link rel="stylesheet" href="http://localhost/arcgis_js_api/library/3.9/3.9/js/esri/css/esri.css">
<style type="text/css">
html, body, #map {
height: 100%;
margin: 0;
padding: 0;
font-size: 62.5%;
font-family:"Segoe UI","Helvetica Neue",Helvetica,Arial,sans-serif;
}
fieldset {
background: #fff;
border:0;
margin: 0em 4em;
height: 4em;
}
label {
font-weight: normal;
float: left;
margin-right: .5em;
font-size: 1.1em;
}
select {
margin-right: 1em;
float: left;
}
</style>
<script src="jquery-slider/jquery-1.8.3.js"></script>
<script src="jquery-slider/jquery-ui-1.7.1.custom.min.js"></script>
<script src="jquery-slider/selectToUISlider.jQuery.js"></script>
<script src="http://localhost/arcgis_js_api/library/3.9/3.9/init.js"></script>
<script type="text/javascript">
var map, fch;
require([
"esri/map",
"esri/layers/ArcGISTiledMapServiceLayer",
"esri/layers/FeatureLayer",
"esri/geometry/Point",
"dojo/domReady!"],
function(Map,
Tiled,
FeatureLayer,
Point)
{
map = new Map("map",{logo:false});
var tiled = new Tiled("http://localhost:6080/arcgis/rest/services/image/MapServer");
map.addLayer(tiled);
var mapCenter = new Point(103.847, 36.0473, map.spatialReference);
map.centerAndZoom(mapCenter,4);
<strong> map.on("load",function(){
fch = new FeatureLayer("http://localhost:6080/arcgis/rest/services/china/MapServer/6");
map.addLayer(fch);
$('select#layers').selectToUISlider({
labels:6,
tooltip:true,
step:1,
selectshow:false,
baseUrl:"http://localhost:6080/arcgis/rest/services/china/MapServer/",
orientation:"horizontal"//vertical,horizontal
});
});</strong>
});
</script>
</head>
<body>
<div id="map">
<div style="position: absolute; bottom: 0px; left:35%; width: 600px;z-index: 99;">
<strong><fieldset>
<select name="layers" id="layers">
<optgroup label="省级">
<option value="6">省会城市</option>
<option value="0">省级行政区</option>
</optgroup>
<optgroup label="市级">
<option value="4">地级市</option>
<option value="1">地州界</option>
</optgroup>
<optgroup label="县级">
<option value="3">县城驻地</option>
<option value="2">市县界</option>
</optgroup>
</select>
</fieldset></strong>
</div>
</div>
</body>
</html>
在本实例中由于数据的关系是通过FeatureLayer来实现的,你可以通过ArcGISTiledMapServiceLayer来实现。

如有疑问,请联系:

QQ:1004740957

Email:niujp08@qq.com

加我或者来邮件请说明来意,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐