likes
comments
collection
share

JS 封装基于高德地图实现行政区域颜色标注及提示文字功能

作者站长头像
站长
· 阅读数 20

废话开篇:利用高德地图实现行政区域颜色标注及提示文字,那么,就简单的封装一下。

JS 封装基于高德地图实现行政区域颜色标注及提示文字功能

一、主要功能介绍

1、日期可选。修改日期调整搜索条件。

2、价格阀值显示。

3、搜索区域根据数值推断填充颜色,进行填充与标记。

4、刷新及修改地图比例尺操作。

二、入口代码

先简单看一下入口代码:

$mapOption.initMap('container').searchMap(function(){
			 return [
	         {name:"张家口",score:1690},
		 {name:"陕西",score:290},
                 {name:"合肥",score:690},
		 {name:"甘肃",score:9000},
		 {name:"石家庄",score:987},
		 {name:"枣庄",score:7622},
		 {name:"承德",score:922},
		 {name:"长春",score:1922}]
		 })
		 .setSegmentControl(function(segmentControlSelectIndex){
			 //js触发时间选择器
		 });

$mapOption 是被设置为了 window 的一个属性,这样方便直接调用。

入口代码是不是很简单,只需要传入一个闭包,一个返回一组行政区域的名称数值对象的闭包,搜索及地图渲染内部高度封装,就能实现上述效果。

三、功能实现

html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="initial-scale=1.0, user-scalable=no"> 
		<title></title>
		<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=83bc36d34f**********5650e518f&plugin=AMap.DistrictSearch,AMap.DistrictLayer"></script>
		<script src="./GDMapWeb.js"></script>
	    <link rel="stylesheet" type="text/css" href="./GDMapWeb.css"/>
	</head>
	<body>
		<div style="position: relative;"id="contentView">
			<!-- 地图 -->
			<div id="container"></div> 
			<!-- 指示器 -->
			<div class="indicator">
				<div style="text-align: left;font-size: 0.75rem;margin-top: 0.3125rem;margin-left: 0.1875rem;margin-bottom: 0.625rem;">涨幅值</div>
				<div id="indicator" style="width: 100%">
				</div>
			</div>
			<!-- 数据显示 -->
			<div class="scoreBar">
				<div style="width: 32%;height: 100%;float: left;position: relative;">
					<div style="width: 100%;margin-top: auto;margin-bottom: auto;position: relative;top:50%; transform:translate(0,-50%);">
						<p style="text-align: center;font-size: 0.75rem;color: darkgray;">平均价</p>
						<p style="text-align: center;font-size: 0.75rem;color: darkgray;" id="averageScoreLab">0</p>
					</div>
				</div>
				<div style="float: left;width: 0.0625rem;height: 70%;background-color: lightgray;position: relative;top:50%; transform:translate(0,-50%);"></div>
				<div style="width: 32%;height: 100%;float: left;position: relative;">
					<div style="width: 100%;margin-top: auto;margin-bottom: auto;position: relative;top:50%; transform:translate(0,-50%);">
						<p style="text-align: center;font-size: 0.75rem;color: darkgray;">最高价</p>
						<p style="text-align: center;font-size: 0.75rem;color: black;" id="maxScoreCityLab">-</p>
						<p style="text-align: center;font-size: 0.75rem;color: darkgray;" id="maxScoreLab">0</p>
					</div>
				</div>
				<div style="float: left;width: 0.0625rem;height: 70%;background-color: lightgray;position: relative;top:50%; transform:translate(0,-50%);"></div>
				<div style="width: 32%;height: 100%;float: left;position: relative;">
					<div style="width: 100%;margin-top: auto;margin-bottom: auto;position: relative;top:50%; transform:translate(0,-50%);">
						<p style="text-align: center;font-size: 0.75rem;color: darkgray;">最低价</p>
						<p style="text-align: center;font-size: 0.75rem;color: black;" id="minScoreCityLab">-</p>
						<p style="text-align: center;font-size: 0.75rem;color: darkgray;" id="minScoreLab">0</p>
					</div>
				</div>
			</div>
			<!-- 年月日选择器 -->
			<div class="segmentControl" id="segmentControl">
				<div class="segmentControlItem"></div>
				<div class="segmentControlSep"></div>
				<div class="segmentControlItem" ></div>
				<div class="segmentControlSep"></div>
			    <div class="segmentControlItem"></div>
			</div>
			<!-- 显示时间 -->
			<div id="showDateInfo"></div>
			<!-- 比例尺 -->
			<div class="mapScale">
				<div class="mapScaleItem">+</div>
				<div style="position: absolute;height: 0.0625rem;width: 96%;margin-left: 2%;margin-right: 2%;background-color: #DCDCDC;"></div>
				<div class="mapScaleItem">-</div>
			</div>
			<!-- 搜索 -->
			<div class="mapReload"><img src="./images/shuaxin.png" ></div>
			<!--  -->
		</div>
	</body>
	<script>
		 //初始化地图
		 $mapOption.initMap('container').searchMap(function(){
			 return [
	         {name:"张家口",score:1690},
		 {name:"陕西",score:290},
                 {name:"合肥",score:690},
		 {name:"甘肃",score:9000},
		 {name:"石家庄",score:987},
		 {name:"枣庄",score:7622},
		 {name:"承德",score:922},
		 {name:"长春",score:1922}]
		 })
		 .setSegmentControl(function(segmentControlSelectIndex){
			 //js触发时间选择器
		 });

	</script>
</html>

CSS

    *{
	padding:0px;
	    margin:0px;
	}
	#headerConditon{
		width: 100%;
		height: 2.8125rem;
		position: relative;
	}
	.headerConditonItem {
		width: 50%;
		background-color: #1E90FF;
	}
	
	.headerConditonItem div {
		display: flex;
		align-items: center;
		justify-content: space-around;
		flex-direction: row;
		font-size: 0.875rem;
	}
	
	.headerConditonItem img {
		width: 0.9375rem;
		height: 0.9375rem;
		display: flex;
		align-items: center;
		justify-content: space-around;
		flex-direction: row;
		
	}
	#container {width:100%; height: 100%;}
	.showInfoLab {
		height: 25px;
		width: 100px;
		display: inline-block;
	}
	.pointShowInfoLab {
		width: 5px;
		height: 5px;
		border-radius: 2.5px;
		background-color: black;
		margin-top: 12.5px;
		display: inline-block;
		float: left;
	}
	.areaShowInfoLab {
		font-size: 0.3rem;
		height: 50%;
	}
	.indicator {
		position: absolute;
		left: 0.625rem;
		top: 0.625rem;
		width: 5.5rem;
		background-color: white;
		box-shadow: -2px 0px 5px 1px #DCDCDC,0px -2px 5px 1px #DCDCDC,2px 0px 5px 1px #DCDCDC,0px 2px 5px 1px #DCDCDC;
	}
	
	.scoreBar {
		position: absolute;
		left: 0.625rem;
		bottom: 1.875rem;
		height: 3.125rem;
		width: 11.25rem;
		background-color:rgba(255,255,255,0.75);
		border-radius: 0.3125rem;
		box-shadow: -2px 0px 5px 1px #DCDCDC,0px -2px 5px 1px #DCDCDC,2px 0px 5px 1px #DCDCDC,0px 2px 5px 1px #DCDCDC;
	}
	
	.segmentControl {
		position: absolute;
		right: 0.625rem;
		top: 0.625rem;
		/* width: 8.125rem; */
		height: 1.875rem;
		background-color: white;
		border-radius: 0.25rem;
		border: solid 0.0625rem rgba(111,165,235,1.0);
	}
	
	#showDateInfo{
		position: absolute;
		right: 2rem;
		top: 2.9rem;
		color: #555555;
		visibility:hidden;
		height: 1.25rem;
		line-height: 1.25rem;
	}
	
	.segmentControlItem {
		height: 100%;
		width: 2.1875rem;
		line-height: 100%;
		display: flex;
		align-items: center;
		justify-content: space-around;
		flex-direction: column;
		float: left;
		text-align: center;
		position: relative;
		top:50%;
		transform:translate(0,-50%);
		z-index: 0;
	}
	
	.segmentControlSep {
		float: left;
		width: 0.0625rem;
		background-color: rgba(111,165,235,1.0);
		height: 100%;display: inline-block;
	}
	
	.mapScale {
		position: absolute;
		right: 0.625rem;
		bottom: 0.625rem;
		width: 2.0rem;
		height: 4.5rem;
		border-radius: 0.3125rem;
		background-color: white;
		box-shadow: -2px 0px 5px 1px #DCDCDC,0px -2px 5px 1px #DCDCDC,2px 0px 5px 1px #DCDCDC,0px 2px 5px 1px #DCDCDC;
	}
	
	.mapScaleItem {
		width: 100%;
		height: 50%;
		display: flex;
		align-items: center;
		justify-content: space-around;
		flex-direction: row;
	}
	
	.mapReload{
		position: absolute;
		right: 1.025rem;
		bottom: 6rem;
		width: 1.2rem;
		height: 1.2rem;
		border-radius: 0.6rem;
		background-color: white;
		text-align: center;
		vertical-align: middle;
		-webkit-transition: width 2s, height 2s, -webkit-transform 2s; /* For Safari 3.1 to 6.0 */
		transition: width 2s, height 2s, transform 2s;
	}
	
	.mapReload img {
		width: 80%;
		height: 80%;
		position: relative;
		top:50%;
		transform:translate(0,-50%);
	}

JS

(function(window){
	var indicators = [2000,800,500]
	var colors = ['rgba(208,53,37,1.0)','rgba(244,181,180,1.0)','rgba(180,216,143,1.0)','rgba(93,169,60,1.0)']
	var district = null; 
	var startDeg = 0;//刷新按钮旋转的角度
	var mapOption = {}//操作地图对象
	mapOption.map = null//地图对象
	mapOption.mapZoom = 4 //地图默认比例尺等级
	mapOption.areas = null
	mapOption.date = new Date()
	mapOption.scoreCallBack = null//计算阀值外部可回调闭包
	
	//行政区域相关配置
	var disCountry = new AMap.DistrictLayer.Country({
	    zIndex:10,
	    SOC:'CHN',
	    depth:1,//设置显示的行政区等级,这里设置1,就是只显示省级
	    styles:{//分界线样式
	        'nation-stroke':'#000000',//内路线
	        'coastline-stroke':'#888888',//海岸线
	        'province-stroke':'#888888',//省边际线
	        'fill':'rgba(245,245,245,1.0)'
	    }
	})
	//初始化地图
	mapOption.initMap = function(el){
		mapOption.map = new AMap.Map(el,{
			zoom:mapOption.mapZoom,//级别
			center: [116.397428, 39.90923],//地图初始化中心经纬度
			showLabel:false,//不显示默认标注
			mapStyle:'amap://styles/7e862995ee18*********07edbd958',//(替换为当前帐户下的)加载地图样式,这里可以去高德账户后台里修改,去掉其他渲染条件,只保留灰色地图
			layers:[disCountry],//填充样式
			viewMode:'2D',
		});
		this.map.on('zoomend', function(ev) {
			//当 map 的比例尺变化完成后,获取一下当前 map 的比例尺
			mapOption.mapZoom = mapOption.map.getZoom();
		})
		
		//展示标签
		var main = document.getElementById('contentView');
		//设置宽高
		main.style.width = window.innerWidth + 'px';
		main.style.height = window.innerHeight + 'px';
		//添加颜色指数指示器
		this.initIndicator()
		//添加修改地图比例尺功能
		this.changeMapScale()
		//添加刷新地图动画功能
		this.addReloadAnimationAction()
		return this;
	}
	
	//搜索
	mapOption.searchMap = function(areas){
		this.areas = areas
		for (var i= 0;i < areas().length;i++) {
			var area = areas()[i];
			this.startSearchMap(area);
		}
		//计算一些阀值
		this.getShowScoreData(function(average,maxCity,minCity,max,min){})
		return this;
	}
	//开始逐一搜索
	mapOption.startSearchMap = function(area){
		var that = this;
		if(!district){
			district = new AMap.DistrictSearch({
			    // 返回行政区边界坐标等具体信息
			    extensions: 'all',
			    // 设置查询行政区级别为 区 
			    level: 'district',
				subdistrict: 0
			 })
		}
		//通过名字搜索行政边界
		district.search(area.name, function(status, result) {
		   var bounds = result.districtList[0].boundaries//行政区域边界
		   var center = result.districtList[0].center//行政区域中心(比如:省会级城市)
		   //console.log(JSON.stringify(center));
		   that.addMark(center,{name:area.name,score:area.score});
		   if (bounds) {
		     for (var i = 0, l = bounds.length; i < l; i++) {
		      //生成行政区划polygon
		      var polygon = new AMap.Polygon({
		        map: that.map,
		        strokeWeight: 0.3,
		        path: bounds[i],
		        fillOpacity: 0.7,
		        fillColor: that.judgeScoreGetCoror(area.score),//根据数值获取填充颜色
		        strokeColor: '#888888',//边界颜色
		      })
		    }
		  }
		})
	}
	
	//添加标注
	mapOption.addMark = function(position,info){
		var marker = new AMap.Marker({
		        //点标记在地图上显示的位置
		        position: [position.lng, position.lat],
		        			 offset:new AMap.Pixel(0,-15),//调整标注偏移位置
		        			 content: '<div class="showInfoLab">' +
		                 '<div style="width: 10px;height: 100%;float: left;">' +
		        	                  '<span class="pointShowInfoLab">' +
		        	                  '</span>' +
		                 '</div>' +
		                 '<div style="height: 100%;float: left;">' +
		        	                  '<div class="areaShowInfoLab">'+info.name +'</div>' +
		        	                  '<div class="areaShowInfoLab">'+info.score +'</div>' +
		                 '</div>' +
		                 '</div>'
		    });
		    //为Marker指定目标显示地图。当参数值取null时,地图上移除当前Marker:setMap(null) 
		    marker.setMap(this.map);
	}
	
	//获取当前填充颜色值
	mapOption.judgeScoreGetCoror = function(score){
		var color = colors[colors.length - 1]
		var minScore = indicators[indicators.length - 1]
		var maxScore = indicators[0]
		if(score > maxScore) {
			return colors[0]
		} else if(score < minScore) {
			return color
		} else {
			for(var i = 0;i < indicators.length;i++){
				var currentScore = indicators[i];
				if(score < currentScore && score >= indicators[i + 1]) {						 
					color = colors[i + 1];
					break
				}
			}
		}
		return color
	}
	
	//初始化指示器
    mapOption.initIndicator = function (){
		var content = '> ' + indicators[0];
		var color = colors[0];
		var indicatorHtml = this.indicatorCell(color,content,false)
		for (var i = 1;i < indicators.length;i++) {
						color = colors[i];
						content = indicators[i] + '~' + indicators[i - 1]
						indicatorHtml += this.indicatorCell(color,content,false)
		}
		content = '< ' + indicators[indicators.length - 1]
		color = colors[colors.length - 1];
		indicatorHtml += this.indicatorCell(color,content,true)
		var indicator = document.getElementById('indicator')
		indicator.innerHTML = indicatorHtml;
		return this;
	}
	
	mapOption.indicatorCell = function(color,content,isLast){
		return '<div style="width: 100%;height: 1.1rem;margin-top: 0.1875rem;'+ (isLast ? 'margin-bottom: 0.1875rem;"' : '"') + '>'
											+'<span style="float: left;width: 1rem;height: 1rem;background-color: '+ color +';margin-left: 0.1875rem;display: inline-block;position: relative;top: 50%;margin-top: -0.5rem;"></span>'
											+'<div style="font-size: 0.8rem;color:#333333;margin-left: 0.3125rem;float: left;height: 1.5625rem;position: relative;top: 50%;margin-top: -0.78125rem;line-height: 1.5625rem;">'+ content +'</div>'
										    +'</div>'
	}
	
	//平均数、最高、最低数
	mapOption.getShowScoreData = function(callBack){
		this.scoreCallBack = callBack;
		var average = 0;
		var max = 0;
		var min = 0;
		var maxCity = '';
		var minCity = '';
		var areasData = this.areas();
		for(var i = 0;i < areasData.length;i++){
			var currentScore = areasData[i].score;
			var currentName = areasData[i].name;
			average += currentScore;
			if(i == 0){
				max = currentScore;
				maxCity = currentName;
				min = currentScore;
				minCity = currentName;
			} else {
				var currentMax = max < currentScore ? currentScore : max;
				maxCity = max < currentScore ? currentName : maxCity;
				max = currentMax;
				
				var currentMin = min > currentScore ? currentScore : min;
				minCity = min > currentScore ? currentName : minCity;
				min = currentMin;
			}
		}
		average = (average / areasData.length).toFixed(2);
		//这里对象存储的目的是可以以闭包的形式暴露给外界参数,并无其他意义
		this.scoreCallBack(average,maxCity,minCity,max,min);
		//阀值赋值
		mapOption.setHtml('averageScoreLab',average)
		mapOption.setHtml('maxScoreCityLab',maxCity)
		mapOption.setHtml('minScoreCityLab',minCity)
		mapOption.setHtml('maxScoreLab',max)
		mapOption.setHtml('minScoreLab',min)
		return this
	}
	
	//设置DOM内容封装
	mapOption.setHtml = function(el,content){
		var element = document.getElementById(el)
		element.innerHTML = content
	}
	
	//设置日期选择器 segmentControl 切换事件
	mapOption.setSegmentControl = function(selectCallBack){
		var that = this;
		var items = document.getElementsByClassName("segmentControlItem")
		for(var i = 0;i < items.length;i++){
			var item = items[i];
			item.index = i;
			item.onclick = function (){
				var segmentControl = document.getElementById('segmentControl');
				if(segmentControl.selectIndex != this.index){
					that.selectChangeStyle(this.index);
					selectCallBack(this.index);
				}
			}
			if(i == 0){
			   that.selectChangeStyle(0);
			}
			var borderRadius = ''
			var padding = ''
			if(i == 0) {
				borderRadius = '0.25rem 0 0 0.25rem'
				padding = '0'
			} else if(i == items.length - 1) {
				borderRadius = '0 0.25rem 0.25rem 0'
				padding = '0'
			} else {
				borderRadius = '0 0 0 0'
				padding = '0.'
			}
			item.style.borderRadius = borderRadius
			item.style.padding = padding
		}
		return this;
	}
	
	mapOption.selectChangeStyle = function(index){
		var items = document.getElementsByClassName("segmentControlItem")
		for(var i = 0;i < items.length;i++){
			var item = items[i];
			item.style.backgroundColor = (i == index) ? 'rgba(235,243,254,1.0)' : 'rgba(255,255,255,0.0)';
			item.style.color = (i == index) ?  'rgba(111,165,235,1.0)' : '#DCDCDC';
		}
		var segmentControl = document.getElementById('segmentControl');
		segmentControl.selectIndex = index;
	}
	
	mapOption.selectSegmentControl = function(index){
		var showDateInfoDiv = document.getElementById('showDateInfo');
		showDateInfoDiv.style.visibility = index == 0 ? 'hidden' : 'visible';
		var dateInfo = '';
		if(index == 1){
			 //星期日 - 星期六 算一个周期
			 //获取一周开始的第一天
			 var weekFirstDay = new Date(this.date- (this.date.getDay()) * 86400000)
			 //获取一周开始的月份
			 var firstMonth = Number(weekFirstDay.getMonth()) + 1
			 //获取一周结束的最后一天
			 var weekLastDay = new Date((weekFirstDay / 1000 + 6 * 86400) * 1000)
			 //获取一周结束的月份
			 var lastMonth = Number(weekLastDay.getMonth()) + 1
			 dateInfo = firstMonth + '-' + weekFirstDay.getDate() + '~' + lastMonth + '-' + weekLastDay.getDate() 
		} else if(index == 2) {
			 //获取当日所在的月份
			 var weekFirstDay = new Date(this.date)
			 var firstMonth = Number(weekFirstDay.getMonth()) + 1
			 dateInfo = weekFirstDay.getFullYear() + '年' + firstMonth + '月'
		}
		showDateInfoDiv.innerHTML = dateInfo;
	}
	
	//修改选择日期
	mapOption.changeSearchDate = function(newDate){
		var segmentControl = document.getElementById('segmentControl');
		this.date = new Date(newDate);
		this.selectSegmentControl(segmentControl.selectIndex);
	}
	
	//修改地图比例尺
	mapOption.changeMapScale = function(){
		var items = document.getElementsByClassName("mapScaleItem")
		var that = this;
		for(var i = 0;i < items.length;i++){
			var item = items[i];
			item.index = i;
			item.onclick = function (){
				if(this.index == 0) {
					if(that.mapZoom < 7){
						//调整 map 的比例尺
						that.map.setZoom(that.mapZoom += 1);
					}
				} else {
					if(that.mapZoom > 4.5){
						//调整 map 的比例尺
						that.map.setZoom(that.mapZoom -= 1);
					}
				}
			}
		}
		return this;
	}
	
	//添加旋转刷新动画
	mapOption.addReloadAnimationAction = function (){
		var item = document.getElementsByClassName("mapReload")[0];
		var that = this;
		item.onclick = function (){
			startDeg += 360;
			this.style.transform =  'rotate('+startDeg+'deg)';
			mapOption.map.destroy();
			mapOption.initMap('container')
			.searchMap(that.areas)//重新搜索
			.getShowScoreData(function(average,maxCity,minCity,max,min){});
			var segmentControl = document.getElementById('segmentControl');
			window.webkit.messageHandlers.chageDateJS.postMessage(segmentControl.selectIndex);
		}
		return this;
	}
	
	window.$mapOption = mapOption;
})(window)

代码拙劣,大神勿喷,互相学习进步[抱拳][抱拳][抱拳]

转载自:https://juejin.cn/post/7048152145945853960
评论
请登录