一个抓取阿里云GeoJson地图区域数据的nodejs脚本

上篇文章使用Ycc库的多边形绘制了一个中国地图,但这个地图不能下钻,不能查看省市区的地图。

想要实现这个查看省市区的功能怎么办呢?

看过前篇文章的朋友都应该知道,这不就一个json文件就搞定了吗?

事实确实如此,不过,json文件的来源才是这篇文章的重点

试想一下,中国地图的json文件有了,四川地图的json文件从哪来呢?四川省下成都市的地图json文件从哪来呢?

再细了说,成都市下高新区的json文件从哪来呢?带着这些疑问开始吧。

背景

中国的区域划分大致是这么个结构:中国->省->市->区->县->镇->乡。

对于我们一般的开发者或者中小型企业,要我们自己来收集这些区域信息,显然是不可能的。

这个时候我们就得借助一些成熟的地图数据,比如百度地图、高德地图、阿里云数据等等。

对于绝大部分的需求,能取到省市区的数据已经完全满足,这篇文章就使用脚本来获取阿里云的json数据。

地址为:http://datav.aliyun.com/tools/atlas

脚本

废话不多,直接贴上写好的脚本

var https = require('https');
var fs = require('fs');

var isFull = process.argv.slice(-1)[0]==="full";
console.log(isFull);
// 获取行政区域ID
logLog('1、获取行政区域列表...');
httpsGet("https://datav.aliyun.com/tools/atlas/data/all.json",function (err, data) {
	if(err) return logError('获取行政区域失败!',err);
	writeFile('area',data);
	logLog('1、获取行政区域列表成功!','area');
	
	var list = JSON.parse(data);

	// 拼装GeoJSON的url
	var geoJsonUrls = list.map(function(item){
		if(item.level!=="district")
			return {item:item,url:"https://geo.datav.aliyun.com/areas/bound/"+item.adcode+(isFull?"_full":"")+".json"};
		return {item:item};
	});

	// 拼装地区的url
	var areaUrls = list.map(function(item){
		var level = ['country','province','city','district'];
		var index = level.indexOf(item.level);
		if(index<3)
			return {item:item,url:"https://geo.datav.aliyun.com/areas/csv/510000_"+(level[index+1])+".json"};
		return {item:item};
	});

	// 获取GeoJSON
	httpsGetList(geoJsonUrls,function (err,data,index,area){
		var areaName = area.item.name;
		if(err) return logError(index,areaName,'获取GeoJSON失败!',err.message);
		logLog(index,areaName,'获取GeoJSON成功!');

		var filename = area.item.adcode+"_geojson"+(isFull?"_full":"");
		writeFile(filename,data);
		logLog(index,areaName,'写入成功!',filename);
	},()=>{

		// 获取地区json
		httpsGetList(areaUrls,function (err,data,index,area){
			var areaName = area.item.name;
			if(err) return logError(index,areaName,'获取area失败!',err.message);
			logLog(index,areaName,'获取area成功!');

			var filename = area.item.adcode+"_area";
			writeFile(filename,data);
			logLog(index,areaName,'写入成功!',filename);
		});
	});
});


function writeFile(filename, strData) {
	var fd = fs.openSync('./data/'+filename+'.json','w+');
	fs.writeFileSync(fd,strData);
	fs.closeSync(fd);
}
function logLog(log){
	Array.prototype.push.call(arguments,'\033[0m');
	Array.prototype.unshift.call(arguments,'\033[;32m =>');
	console.log.apply(this,arguments);
}

function logError(log){
	Array.prototype.push.call(arguments,'\033[0m');
	Array.prototype.unshift.call(arguments,'\033[;31m =>');
	console.log.apply(this,arguments);
}

function httpsGet(url,cb) {
	if(!url) return cb({message:"url为空"});

	https.get(url,function (res) {
		if(res.statusCode!==200) return cb({message:"状态不等于200!"});
		res.setTimeout(5000);
		res.setEncoding('utf8');
		var rawData = '';
		res.on('data', function(chunk){ rawData += chunk; });
		res.on('end', function(){
			cb(null,rawData);
		});
	}).on('error', function(e){
		cb(e);
	});
}

function httpsGetList(urlObjList,progressCb,endCb,index){
	index = index ||0;

	// 县级地区忽略
	if(urlObjList[index].item.level=='district'){
		progressCb&&progressCb({message:"县级地区忽略!"},null,index,urlObjList[index]);
		++index;
		// 判断结尾
		if(index===urlObjList.length-1) {
			return endCb&&endCb();
		}
		httpsGetList(urlObjList,progressCb,endCb,index);
		return;
	}

	httpsGet(urlObjList[index].url,(err,data)=>{
		progressCb&&progressCb(err,data,index,urlObjList[index]);
		++index;
		// 判断结尾
		if(index===urlObjList.length-1) {
			return endCb&&endCb();
		}
		httpsGetList(urlObjList,progressCb,endCb,index);
	});
}

脚本的思路:

1、首先根据地址https://datav.aliyun.com/tools/atlas/data/all.json获取中国地图所有的区域列表。

2、循环遍历区域获取https://geo.datav.aliyun.com/areas/bound/xxxxxx.json区域的GeoJSON文件,链接中的xxx为行政区域的ID,获取之后存入至data目录中。

3、阿里云中县级及以下的数据大部分是没有的,所有遍历的时候直接就忽略了。

4、脚步可以传入一个full参数,带full参数的脚步表示json文件中包含子区域,不带full则没有子区域(主要针对有的项目在绘制的时候不需要划分子区域)。

5、data目录中文件的命令都根据区域ID命名,带子级的json文件会有一个后缀"_full",比如四川省的510000_geojson.json表示不带子级的文件,而510000_geojson_full.json表示带子级的文件。

脚本运行效果

image.png

伸手党福利

对于一个懒人,懒得运行脚本,也没空了解其原理,那就去我的github下载已经抓取好现成的json文件吧。

https://github.com/lizhiqianduan/geojson-of-china-full

这个项目只包含这个抓取脚本,data目录也已经下载好了,偷懒的人直接下载下来就可以用,满满的福利!

下载完了别忘记给项目点个爱心!在此谢过!



打赏作者

发表评论

电子邮件地址不会被公开。 必填项已用*标注