将 Shp 文件转换为 geojson 加载到 echarts 使用

时间:2024-04-17 08:29:23
一般情况下,我们的功能需求并不是要整个地图来展示,也许只是需要某一个市或地区的一个形状来制作出一个地图效果,这个时候其实使用 Echarts 地图是一个不错的选择。

由于Echarts 官方下架了地图数据的下载,所以可以采用自己制作的方式来满足需求。

shp文件准备
shp文件为地图矢量文件,使用ArcMap给shp文件的属性表中添加 name 属性,因为Echarts 是通过 name 属性来配置地图,将shp文件转换为网页专门使用的 web墨卡托系统,将shp导出,选择数据框选项才能生效。坐标系转换及请自行搜索方法。(一般情况下使用Web墨卡托,4326)

将shp文件转换为geojosn文件
方法一:
使用 geotools 工具后台转换,geotools是一个java的库,里面有很多处理地理对象的方法 
示例代码(Java):

package com.kay;

import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.feature.FeatureJSON;
import org.json.simple.JSONArray;
import org.opengis.feature.simple.SimpleFeature;
import java.io.*;
import java.nio.charset.Charset;

/**
 * Created 
 */
public class ShpFormatUtil {

    public static void shp2Json(String shpPath){
        StringBuffer sb = new StringBuffer();
        FeatureJSON fjson = new FeatureJSON();
        try{
            sb.append("{\"type\": \"FeatureCollection\",\"features\": ");

            File file = new File(shpPath);
            ShapefileDataStore shpDataStore = null;

            shpDataStore = new ShapefileDataStore(file.toURL());
            //设置编码
            Charset charset = Charset.forName("UTF-8");
            shpDataStore.setCharset(charset);
            String typeName = shpDataStore.getTypeNames()[0];
            SimpleFeatureSource featureSource = null;
            featureSource =  shpDataStore.getFeatureSource (typeName);
            SimpleFeatureCollection result = featureSource.getFeatures();
            SimpleFeatureIterator itertor = result.features();
            JSONArray array = new JSONArray();
            while (itertor.hasNext())
            {
                SimpleFeature feature = itertor.next();
                StringWriter writer = new StringWriter();
                fjson.writeFeature(feature, writer);
                array.add(writer);
            }
            itertor.close();
            sb.append(array.toString());
            sb.append("}");
            //写到文件
            writeToFile("E:\\workspace\\GISFile\\testFile\\beijing.geojson",sb.toString());
        }
        catch(Exception e){
            e.printStackTrace();
        }

    }


    /**
     *  写出到文件
     * @param targetFile  目标文件路径
     * @param soure         json
     */
    public static void writeToFile(String targetFile,String soure) {
        File file = new File(targetFile);

        try {
            OutputStream os = new FileOutputStream(file);
            OutputStreamWriter osw = new OutputStreamWriter(os);
            osw.write(soure);
            osw.flush();
            osw.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

方法二:使用现成的转换工具
-> 网站:http://mapshaper.org/ 上传shp导出 json文件 
-> Geoserver 转换,上传到geoserver然后导出(其实也是geotools)

通过对比发现geotools转换的文件要小一些,不知道是不是偶然,没研究。

使用Echarts加载 json
引入 echarts和 jquery的js文件

/**
 *  Created by Kay
 */

var mapChart2;
var option;
//bj.json 即为我们将shp导出的json文件
$.get(\'data/bj.json\', function (beijingJson) {
    echarts.registerMap(\'bj\', beijingJson);
    mapChart2 = echarts.init(document.getElementById(\'mapDiv2\'));
    option = {
        title: {
            text: \'北京市地图\',
            left: \'center\'
        },
        tooltip: {
            trigger: \'item\',
            formatter: \'{b}<br/>{c}\'
        },
        toolbox: {
            show: true,
            orient: \'vertical\',
            left: \'right\',
            top: \'left\',
            feature: {
                dataView: {readOnly: false},
                restore: {},
                saveAsImage: {}
            }
        },
        visualMap: {
            min: 0,
            max: 2000,
            text: [\'高\', \'低\'],
            calculable: true,
            inRange: {
                color: [\'lightskyblue\', \'yellow\', \'orangered\']
            }
        },
        series: [
            {
                name: \'北京市各区\',
                type: \'map\',
                map: \'bj\', // 自定义扩展图表类型
                aspectScale: 1.0, //长宽比. default: 0.75
                zoom: 1.1,
                roam: false,    //是否开启滑动和缩放
                itemStyle: {
                    normal: {label: {show: true}},
                    emphasis: {label: {show: true}}
                },
                data: [
                    {name: \'昌平区\', value: 100},
                    {name: \'朝阳区\', value: 200},
                    {name: \'大兴区\', value: 300},
                    {name: \'东城区\', value: 800},
                    {name: \'房山区\', value: 1000},
                    {name: \'丰台区\', value: 1500},
                    {name: \'海淀区\', value: 2300},
                    {name: \'怀柔区\', value: 1340},
                    {name: \'门头沟区\', value: 2425},
                    {name: \'密云区\', value: 1555},
                    {name: \'平谷区\', value: 700},
                    {name: \'石景山区\', value: 652},
                    {name: \'顺义区\', value: 200},
                    {name: \'通州区\', value: 200},
                    {name: \'西城区\', value: 200},
                    {name: \'延庆区\', value: 200}
                ]
            }
        ]
    }
    mapChart2.setOption(option);
});

效果