1. 地圖數(shù)據(jù)來源
echarts倉庫里面就有校翔,地圖數(shù)據(jù)不會經(jīng)常改變,沒必要在線獲取浪读,還慢
地圖數(shù)據(jù)有json
和js
格式的,json
是echarts
壓縮過的,js
本質(zhì)就是引入json
只是包裝了導(dǎo)出
2. 整形工具
最重要的部分就是利用工具處理這些數(shù)據(jù)节沦,實(shí)現(xiàn)如扣去某塊區(qū)域
、添加某塊區(qū)域
础爬、去除邊界
等功能
- echarts-mapmaker壓縮解碼地圖數(shù)據(jù)甫贯、合并拆分地圖數(shù)據(jù)
- mapshaper整形地圖,主要就是來去除邊界
- 文檔看蚜,上面有例子
- 這個倉庫也有很多新的地圖數(shù)據(jù)叫搁,自己可以翻看
3. 實(shí)戰(zhàn)
3.1 拆分地圖區(qū)域
這里我們拆分重慶各個區(qū)縣為例
const path = require('path')
const fs = require('fs')
const fsp = require('fs/promises')
const distFolder = path.resolve(__dirname, './dist')
const dest = (fileName) => {
try {
fs.accessSync(distFolder, fs.constants.W_OK)
}catch(err) {
fs.mkdirSync(distFolder)
}
return path.resolve(__dirname, distFolder, fileName)
}
// 引入mapmaker
const maker = require('echarts-mapmaker/src/maker')
// 引入原始地圖數(shù)據(jù)
const chongqingJson = path.resolve(__dirname, './map/province/chongqing.json')
// 解碼地圖數(shù)據(jù)并輸出
// 解碼后的文件就是GeoJson 方便后續(xù)操作
const dec_chonggqing = dest('dec_chongqing.json')
maker.decompress(chongqingJson, dec_chonggqing)
// 分割區(qū)域
maker.splitAsGeojson(dec_chonggqing, distFolder)
3.2 合并區(qū)域
比如我需要合并中部地區(qū)、西部地區(qū)之類的供炎,就需要合并區(qū)域
// 只需要這一句話
// 合并第一個和第二個json
maker.merge('./dist/九龍坡區(qū).geojson', './dist/大渡口區(qū).geojson')
這個方法有些問題:
- 無法自定義輸出位置和輸出文件名
- 每合并一次輸出文件前面會加一個
merge_
渴逻,處理起來很麻煩
可以考慮自己寫一個方法,參考源碼其實(shí)不難(最好還是了解一下geojson
)
// 源碼
function merge(geojson, geojsonToBeMerged){
// 讀取兩個文件
const data = fs.readFileSync(geojson, 'utf8');
const data2 = fs.readFileSync(geojsonToBeMerged, 'utf8');
var parent = JSON.parse(data);
var child = JSON.parse(data2);
// features要素音诫,就是描述邊界信息的一個數(shù)組
child.features.forEach(function(feature){
// 只合并不同name的區(qū)域
parent.features = parent.features.filter((featurex)=>{
return featurex.properties.name!==feature.properties.name;
});
// 直接把一個數(shù)據(jù)的邊界信息放入另一個的features中
parent.features.push(feature);
});
// 寫入文件
fs.writeFileSync('merged_'+path.basename(geojson), JSON.stringify(parent));
}
邏輯很簡單惨奕,主要就是提取要素然后放入另一個地圖里面,下面是我簡單的一個封裝
function mergeToOne(targetJSON, distDir, ...childrenJSONList){
// 讀取目標(biāo)json竭钝,其他json都往這個json合并
const data = fs.readFileSync(targetJSON, 'utf8');
const parentData = JSON.parse(data);
// 循環(huán)需要合并的數(shù)據(jù)
childrenJSONList.forEach(child => {
const childJSON= fs.readFileSync(child, 'utf8')
const childData = JSON.parse(childJSON)
// 合并
childData.features.forEach(function(feature){
parentData.features = parentData.features.filter((featurex)=>{
return featurex.properties.name!==feature.properties.name;
});
parentData.features.push(feature);
});
})
// 寫文件
fs.writeFileSync(distDir, JSON.stringify(parentData));
}
// 使用
// 最后會輸出一個`合并文件.json`梨撞,合并了三個區(qū)
mergeToOne('./dist/九龍坡區(qū).geojson', './合并文件.json', './dist/大渡口區(qū).geojson', './dist/沙坪壩區(qū).geojson')
3.3 鑲嵌區(qū)域
只用合并也可以,但是在echarts
中看起來就不大一樣香罐,使用合并高亮地圖的時候看起來不是一體的卧波,還有其他區(qū)別自行確認(rèn)。
所以還要結(jié)合扣去區(qū)域cut
// 使用
maker.cut('a.json', '重慶', '沙坪壩區(qū)')
但是源碼似乎有問題穴吹,反正我用開頭給的地圖數(shù)據(jù)是無法正確切除的
// 源碼
var cutAHoleInFeatureAWithFB = (jsonFile, featureA, featureB) => {
data = fs.readFileSync(jsonFile, 'utf8');
var geojson = JSON.parse(data);
var featurea = geojson.features.find(feature => feature.properties.name === featureA);
var featureb = geojson.features.find(feature => feature.properties.name === featureB);
// https://stackoverflow.com/questions/43645172/geojson-multipolygon-with-multiple-holes
// 就是這一步 似乎不正確
featurea.geometry.coordinates.push(featureb.geometry.coordinates[0]);
fs.writeFileSync("cut_" + jsonFile, JSON.stringify(geojson));
};
查閱資料發(fā)現(xiàn)幽勒,geojson
挖去孔洞就是使用MultiPolygon
要素,
多邊形帶空洞的數(shù)據(jù)格式是一個四維數(shù)組港令,
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPolygon",
"coordinates":
[
[
[
// 這個就是孔洞的多邊形數(shù)據(jù)
[101.6455078125,27.68352808378776],
[114.78515624999999,27.68352808378776],
[114.78515624999999,35.209721645221386],
[101.6455078125,35.209721645221386],
[101.6455078125,27.68352808378776]
],
[
[104.2822265625,30.107117887092357],
[108.896484375,30.107117887092357],
[108.896484375,33.76088200086917],
[104.2822265625,33.76088200086917],
[104.2822265625,30.107117887092357]
]
]
]
}
}
// 再簡化
{
"type": "MultiPolygon",
"coordinates": [
[
{polygon},
{hole},
{hole},
{hole}
]
]
}
源碼的問題就是
// coordinates層級錯了
featurea.geometry.coordinates.push(featureb.geometry.coordinates[0]);
// 改為
featurea.geometry.coordinates[0].push(featureb.geometry.coordinates[0]);
下面是我修改后的
var cutArea = (jsonFile, featureA, featureB) => {
data = fs.readFileSync(jsonFile, 'utf8');
var geojson = JSON.parse(data);
var featurea = geojson.features.find(feature => feature.properties.name === featureA);
var featureb = geojson.features.find(feature => feature.properties.name === featureB);
featurea.geometry.coordinates[0].push(featureb.geometry.coordinates[0])
fs.writeFileSync("cut_" + jsonFile, JSON.stringify(geojson));
}
所以鑲嵌的過程就是:
- 合并兩個地圖
- 扣去鑲嵌的區(qū)域
mergeToOne('./dist/d_china.json', './合并文件.json', './dist/沙坪壩區(qū).geojson')
cutArea('合并文件.json', '重慶', '沙坪壩區(qū)')
3.4 消除內(nèi)部邊界
主要用到mapshaper啥容,挺復(fù)雜的一個東西,有時間可以詳細(xì)研究
const maker = require('echarts-mapmaker/src/maker')
const shaper = require('mapshaper')
shaper.runCommands('./dist/d_chongqing.json -dissolve2 -o chongqing_shape_only.geojson', (err) => {
if(!err) {
maker.transform('./chongqing_shape_only.geojson', './chongqing_shape_only.echarts.json', '重慶市')
}
})
- 主要利用
mapshaper
的dissolve2
命令 - 去除邊界完成后
echarts
不能直接使用顷霹,要用mapmaker
轉(zhuǎn)化一次咪惠,這里和掛網(wǎng)的文檔不一樣注意使用transform
方法 - 官網(wǎng)文檔使用的是全局安裝
mapshaper
然后用命令行,我這里用的是wiki
上的變成方式淋淀,本質(zhì)上也是命令行遥昧。
4 總結(jié)
以上就是基本的一些操作,通過結(jié)合上面的基本方法,我們可以隨意組合想要的地圖數(shù)據(jù)炭臭。