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

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

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

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

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

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

脚本

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

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表示带子级的文件。

脚本运行效果

一个抓取阿里云GEOJSON地图区域数据的NODEJS脚本_第1张图片

伸手党福利

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

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

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

项目内还包含了一个更新脚本,也可以实时更新,满满的福利!下载完了别忘记给这个项目点个star~

觉得有用,还请点赞收藏!
励志前端,CSDN唯一账号!关注我,带你了解更多前端知识!

你可能感兴趣的:(阿里云,javascript,node.js)