前段時間需要做一個地圖,由於思路錯誤等各種原因,走走停停也搞了大半個月。。。。。記錄以下心路歷程,希望能幫助到有需要的同學們。。。
要求的效果大概是這個樣子的:
第一反應就是,拿bmap作爲底圖,然後再用geo畫一個地圖,兩個地圖重合不就OK了嘛!結果。。太天真。。。查了很多資料,大概就是說,這樣子做,會導致兩個地圖使用的是各自的地圖組件,這樣如果用戶縮放的時候,就不會同步縮放,而且會有座標點不在同一個地方的情況!
出現的效果大概是這個樣子:
(上面的效果,是我用geo畫的,拿到深圳地圖的GeoJSON之後,註冊到echarts,再畫出來的)
可以很明顯看到是不重合的,雖然經緯度是一樣的,但是縮放的比例不一樣,沒有辦法調整。。
(查文檔的時候,看到有series-map可以使用geoIndex來讓兩個組件共享同一個地圖組件,但是我用的是bmap,這個思路砍掉砍掉!)
然後就思考了一下,不如用series-custom??OMG,還要搞一堆座標點,好像還要寫好多個series-custom,太麻煩了,終歸不是好的解決辦法。。。
就這樣走走停停,整個面板都塊做完了,就剩地圖了,不行,今天一定要搞出來!!!
換個思路,既然百度地圖是echarts的擴展。。那麼,何不直接使用百度地圖提供的API?試試吧!
查了一下各自資料和文章,發現原來echarts使用了bmap以後,可以通過charts實例來獲取裏面使用到的地圖組件。
let mapCharts= this.$echarts.init(document.getElementById('mapCharts'))
let map = mapCharts.getModel().getComponent('bmap').getBMap();
這樣,就拿到這個地圖組件了,可以隨意使用百度地圖提供的API了!
官方有提供畫行政區域的的例子:http://lbsyun.baidu.com/jsdemo.htm#c1_10
主要是使用Boundary()畫邊界、Label()畫標籤。
(我只拿了比較關鍵的代碼過來,完整的還是去官方例子看比較清楚)
var bdary = new BMap.Boundary()
bdary.get("北京市海淀區", function(rs){ //獲取行政區域
var count = rs.boundaries.length; //行政區域的點有多少個
var pointArray = [];
for (var i = 0; i < count; i++) {
var ply = new BMap.Polygon(rs.boundaries[i], {strokeWeight: 2, strokeColor: "#ff0000"}); //建立多邊形覆蓋物
map.addOverlay(ply); //添加覆蓋物
pointArray = pointArray.concat(ply.getPath());
}
}
效果:
參考了以後,終於解決了問題!
這是後面做出來的:
附上完整代碼(代碼裏面還包括了折線圖和標題內容可做參考):
項目使用的是Vue,需要引入:
// main.js中 引入
import echarts from "echarts"
Vue.prototype.$echarts = echarts
// 當前模塊引入
import 'echarts/extension/bmap/bmap'
option:
mapChartsOpt: {
title: [
{
text: '累計上報車輛',
top: '1%',
left: '50%',
textStyle: {
color: '#fff',
fontWeight: 'normal',
fontSize: 15
}
},
{
text: `{number|2,600.0 } 輛`,
top: '6%',
left: '50%',
textStyle: {
color: '#fff',
fontWeight: 'normal',
fontSize: 10,
rich: {
number: {
color: '#FF7800',
fontWeight: 'normal',
fontSize: '180%'
}
}
},
},
{
text: '累計里程',
top: '1%',
left: '75%',
textStyle: {
color: '#fff',
fontWeight: 'normal',
fontSize: 15
}
},
{
text: `{number|54,350.0 } 輛 `,
top: '6%',
left: '75%',
textStyle: {
color: '#fff',
fontWeight: 'normal',
fontSize: 10,
rich: {
number: {
color: '#05BDAB',
fontWeight: 'normal',
fontSize: '180%'
}
}
},
}
],
bmap: {
center: [114.173632,22.648713],
zoom: 11,
roam: true,
mapStyle: {
styleJson: [
{
"featureType": "water",
"elementType": "all",
"stylers": {
"color": "#03324C"
}
},
{
"featureType": "land",
"elementType": "all",
"stylers": {
"color": "#031F33"
}
},
{
"featureType": "boundary",
"elementType": "geometry",
"stylers": {
"color": "#3C4952"
}
},
{
"featureType": "railway",
"elementType": "all",
"stylers": {
"visibility": "off",
"color": "#030C12"
}
},
{
"featureType": "highway",
"elementType": "geometry",
"stylers": {
"color": "#030C12"
}
},
{
"featureType": "highway",
"elementType": "geometry.fill",
"stylers": {
"color": "#030C12",
"lightness": 1
}
},
{
"featureType": "highway",
"elementType": "labels",
"stylers": {
"visibility": "off",
"color": "#030C12"
}
},
{
"featureType": "arterial",
"elementType": "geometry",
"stylers": {
"color": "#030C12",
}
},
{
"featureType": "arterial",
"elementType": "geometry.fill",
"stylers": {
"color": "#030C12"
}
},
{
"featureType": "poi",
"elementType": "all",
"stylers": {
"visibility": "off",
"color": "#030C12"
}
},
{
"featureType": "green",
"elementType": "all",
"stylers": {
"color": "#17312C",
"visibility": "on"
}
},
{
"featureType": "local",
"elementType": "all",
"stylers": {
"visibility": "off",
"color": "#030C12"
}
},
{
"featureType": "arterial",
"elementType": "labels",
"stylers": {
"visibility": "off",
"color": "#030C12"
}
},
{
"featureType": "building",
"elementType": "all",
"stylers": {
"color": "#1a5787"
}
},
{
"featureType": "label",
"elementType": "all",
"stylers": {
"visibility": "off",
"color": "#030C12"
}
},
{
"featureType": "subway",
"elementType": "all",
"stylers": {
"visibility": "off"
}
}
]
}
},
grid: {
left: '3.5%',
top: '3%',
bottom: '4%',
right: '6%'
},
xAxis: {
type: 'category',
data: ['01/01', '02/01', '03/01', '04/01', '05/01', '06/01'],
axisLabel: {
color: '#9AACB4'
},
axisLine: {
lineStyle: {
color: '#9AACB4'
}
},
axisTick: {
show: false
}
},
yAxis: {
type: 'value',
axisLabel: {
color: '#9AACB4'
},
axisLine: {
lineStyle: {
color: '#9AACB4'
}
},
axisTick: {
show: false
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
opacity: 0.3
}
}
},
series: [
{
type: 'line',
smooth: true,
lineStyle: {
color: '#007EB1',
opacity: 0.3
},
itemStyle: {
normal: {
color: '#007EB1'
},
opacity: 0.3
},
data: [
{
name: '01/01',
value: 1
},
{
name: '02/01',
value: 3
},
{
name: '03/01',
value: 5
},
{
name: '04/01',
value: 9
},
{
name: '05/01',
value: 14
},
{
name: '06/01',
value: 21
}
]
}
]
}
initCharts:
initCharts() {
// 項目使用的是Vue,所以這裏用了this
let mapCharts = this.$echarts.init(document.getElementById('mapCharts '))
mapCharts .setOption(this.mapChartsOpt)
// ========================== 以下是遮罩層繪製 ==========================
var map = mapCharts .getModel().getComponent('bmap').getBMap();
let districtList = ['深圳市羅湖區','深圳市南山區','深圳市福田區','深圳市鹽田區','深圳市寶安區','深圳市龍崗區','深圳市龍華區','光明區','坪山區']
let bdary = new BMap.Boundary(); // 邊界
// 覆蓋物繪製
districtList.forEach(item => {
bdary.get(item, (rs) => { //獲取行政區域
let count = rs.boundaries.length; //行政區域的點有多少個
if (count === 0) {
alert('未能獲取當前輸入行政區域');
return ;
}
let pointArray = [];
for (let i = 0; i < count; i++) {
let ply = new BMap.Polygon(rs.boundaries[i], { //建立多邊形覆蓋物
strokeWeight: 1.5,
strokeColor: "#ffffff",
strokeStyle: 'dashed',
strokeOpacity:0.5,
fillColor: '#cccccc',
fillOpacity: 0.3
});
map.addOverlay(ply); //添加覆蓋物
pointArray = pointArray.concat(ply.getPath());
}
});
})
// 標籤繪製
let labelPoints = [ new BMap.Point(114.133407,22.586888), new BMap.Point(113.935636,22.549798), new BMap.Point(114.024068,22.564752),
new BMap.Point(114.249191,22.617713), new BMap.Point(113.858371,22.660982), new BMap.Point(114.238041,22.7282),
new BMap.Point(114.022692,22.720197), new BMap.Point(113.909312,22.789131), new BMap.Point(114.361997,22.705532)]
let optsArray = [{},{},{},{},{},{},{},{},{}]
let labelArray = []
let contentArray = ["羅湖區", "南山區", "福田區", "鹽田區", "寶安區", "龍崗區", "龍華區", "光明新區", "坪山區"]
for(let i = 0;i < labelPoints.length; i++) {
optsArray[i].position = labelPoints[i]
labelArray[i] = new BMap.Label(contentArray[i],optsArray[i])
labelArray[i].setStyle({
color : "white",
fontSize : "12px",
height : "20px",
lineHeight : "20px",
fontFamily:"微軟雅黑",
borderWidth: 0,
backgroundColor: 'transparent'
});
map.addOverlay(labelArray[i])
}
}
【補充】下面是我參考的,覺得有幫助的各種資料、文章和工具
百度地圖官方API地址:http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a3b11
百度地圖-行政劃區示例:http://lbsyun.baidu.com/jsdemo.htm#c1_10
阿里官方提供的在線獲取GeoJSON、SVG:http://datav.aliyun.com/tools/atlas/#&lat=31.769817845138945&lng=104.29901249999999&zoom=4
百度地圖-座標拾取:http://api.map.baidu.com/lbsapi/getpoint/
【Echarts-百度地圖省分着色】https://segmentfault.com/a/1190000014717854
【EchartsGallery實例】https://gallery.echartsjs.com/editor.html?c=xr1IEt3r4Q