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