GIS开发时如何获取GeoJson数据

1,347 阅读2分钟

导读

WEBGIS开发有时需要一些GeoJson的数据,尤其对于我们初学者来说,没有合适的数据太抓狂了。为此,我这里总结一些获取数据的方式。

行政区划分

GeoJson最常见的大概就是行政区划分了,其相关的数据可以从阿里的蚂蚁地理空间数据可视化中找到。例如选中湖南省,子区域级别选中市级,就可以下载到湖南省所有市的GeoJson数据了。如需要县级数据,子区域选择县级就可以了。

image.png

利用node爬取分析数据

除了一些开放平台,我们还可以通过node来爬取分析数据。使用node来爬取也很方便,毕竟node也是javascript,不需要再另外学习新的语言。以下就以爬取高德上的北京地铁数据为例。

F12调试寻找接口

打开高德北京市地铁网页,打开F12,在网络(NetWork)里找到相关的接口。

image.png

下面将只爬取绘制接口的数据。

使用axios获取数据

新建一个node项目,并新建文件app.js。

npm init -y
touch app.js

安装axios

npm install axios

在app.js中使用axios请求

const axios =require("axios");
const request =axios.create({timeout:10000});
request.get("/subway?_1686622933186&srhdata=1100_drw_beijing.json").then(res=>{
    const data =res.data;
});

这样,我们就可以拿到数据了。

将数据处理为标准格式的GeoJson

拿到数据,我们还要分析一下,将其处理为标准化的GeoJsonGeoJson的基础知识和标准请查阅知乎文章

按照GeoJson的标准定义三个类来规范存储数据。

class GeoJson{
    constructor(features=[],metaData ={}) {
        this.type = "FeatureCollection";
        this.metadata = metaData;
        this.features =features;
    }
}
​
class Geometry{
    constructor(type,coordinates) {
        this.type=type;
        this.coordinates =coordinates;
    }
}
​
class Feature {
    constructor(geomType,properties,coordinates) {
        this.type = "Feature";
        this.properties =properties;
        this.geometry = new Geometry(geomType,coordinates)
    }
}

image.png

根据数据格式处理数据,解析出基本信息和坐标信息。

request.get("/subway?_1686622933186&srhdata=1100_drw_beijing.json").then(res=>{
    const data =res.data;
    const { l } =data;
    let lines=[],stations=[];
    l.forEach(({kn,st})=>{
        let lineCoords=[];
        st.forEach(d=>{
            const sl = d.sl.split(',').map(Number)
            lineCoords.push(sl)
            stations.push(new Feature("Point",d,sl))
        })
        lines.push(new Feature("LineString",{kn},lineCoords))
    })
    const linesGeoJson = new GeoJson(lines);
    const stationsGeoJson = new GeoJson(stations);

将数据写入到文件中

const fs =require('fs');
···
fs.writeFileSync("./data/lines.geojson",JSON.stringify(linesGeoJson),{
        encoding:'utf8'
    });
    fs.writeFileSync("./data/stations.geojson",JSON.stringify(stationsGeoJson),{
        encoding:'utf8'
    });

image.png

解决跨域的问题

遇到跨域的问题,可以使用Nginx解决。

思路就是请求本地端口,本地端口代理到要高德的服务器,并添加必要的请求头。

server{
    listen 8000;
    server_name localhost;
    location /subway {            
        proxy_pass  http://map.amap.com/service/subway; 
        # 设置是否允许 cookie 传输            
        add_header Access-Control-Allow-Credentials true;            
        # 允许请求地址跨域 * 做为通配符            
        add_header Access-Control-Allow-Origin * always;            
        # 允许跨域的请求方法            
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';            
        add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';            
        proxy_set_header Host $proxy_host;             
        proxy_set_header X-Real-IP $remote_addr;            
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    } 
}

axiosbaseURL指定本地端口

const request = axios.create({
    timeout:10000,
    baseURL:"http://localhost:8000"
});
​

参考文章:爬取高德地铁数据并转为geojson在QGIS中可视化