shape 文件操作

本文介绍如何使用Java实现GeoJSON与Shapefile之间的相互转换,包括解析GeoJSON文件、创建Shapefile、写入特征数据及从Shapefile读取特征并转换为GeoJSON。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.Shape 文件

Shapefile(常缩写为 shp 文件)是一种常用的地理信息系统(GIS)矢量数据格式,由 ESRI(美国环境系统研究所公司)提出,用来存储地图几何数据及其属性信息。

它其实不是单独一个文件,而是一文件共同工作,核心包括:

扩展名

内容

必要性

.shp

几何形状(点、线、面等空间数据)

必须

.shx

几何索引(快速定位空间对象)

必须

.dbf

属性数据表(基于 dBASE 格式,存储每个对象的属性字段,如名称、人口等)

必须

.prj

投影信息(坐标系、投影方式)

可选

.cpg

属性表的字符编码信息

可选

二.Shape 转 geojson

引入相应的 pom 依赖:

	<dependencies>
		<dependency>
			<groupId>nl.cloudfarming.client</groupId>
			<artifactId>lib-geotools</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-geojson</artifactId>
			<version>18.0</version>
		</dependency>
		<dependency>
			<groupId>com.googlecode.json-simple</groupId>
			<artifactId>json-simple</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.62</version>
		</dependency>
	</dependencies>

java 代码:

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.opengis.feature.simple.SimpleFeature;

import java.io.*;
import java.nio.charset.Charset;

public class ShapeToGeojson {


    public static void main(String[] args) {
        shape2Geojson("E:\\jingwei\\china_2000.shp","E:\\points.geojson");
    }

    /**
     * shp转换为Geojson
     * @param shpPath
     * @return
     */
    public static void shape2Geojson(String shpPath, String jsonPath){
        FeatureJSON featureJson = new FeatureJSON();
        try{
            BufferedWriter out =new BufferedWriter(new OutputStreamWriter(new FileOutputStream(jsonPath),"UTF-8"));

            out.write("{\"type\": \"FeatureCollection\",\"features\": [");

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

            // 设置编码,防止中文乱码
            shpDataStore.setStringCharset(Charset.forName("gbk"));

            String typeName = shpDataStore.getTypeNames()[0];
            SimpleFeatureSource featureSource = null;
            featureSource =  shpDataStore.getFeatureSource (typeName);
            SimpleFeatureCollection result = featureSource.getFeatures();

            System.out.println(result.size());

            SimpleFeatureIterator itertor = result.features();
            int count = 1;
            while (itertor.hasNext()) {
                SimpleFeature feature = itertor.next();
                StringWriter writer = new StringWriter();
                featureJson.writeFeature(feature, writer);
                out.write(writer.toString());
                System.out.println(count);
                if (count != result.size() ){
                    out.write( ",");
                }
                count ++;
            }
            out.write( "]}");
            itertor.close();
            out.flush();
            out.close();
        }
        catch(Exception e){
            System.out.println("转换失败");
            e.printStackTrace();
        }

    }

}

三.Shape 转 csv

引入相应的 pom 依赖:

	<dependencies>
		<dependency>
			<groupId>nl.cloudfarming.client</groupId>
			<artifactId>lib-geotools</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-geojson</artifactId>
			<version>18.0</version>
		</dependency>
	</dependencies>

java 代码:

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.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.AttributeType;
 
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class ShapeToCsv {
 
 
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        System.out.println(startTime);
        System.out.println(shape2Geojson("E:\\jingwei\\china_2000.shp","E:\\csv\\北京.csv"));
        long endTime = System.currentTimeMillis();
        System.out.println(endTime-startTime);
    }
 
    /**
     * shp转换为Geojson
     * @param shpPath
     * @return
     */
    public static int shape2Geojson(String shpPath, String csvPath){
        int size = 0;
        try{
            BufferedWriter out =new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvPath),"UTF-8"));
            File file = new File(shpPath);
            ShapefileDataStore shpDataStore = null;
            shpDataStore = new ShapefileDataStore(file.toURL());
            // 设置编码,防止中文乱码
            shpDataStore.setStringCharset(Charset.forName("utf8"));
            String typeName = shpDataStore.getTypeNames()[0];
            SimpleFeatureSource featureSource = null;
            featureSource =  shpDataStore.getFeatureSource (typeName);
            SimpleFeatureCollection result = featureSource.getFeatures();
 
            Map<String, Class> mapFields = new HashMap();
            List<AttributeType > attributeTypes = result.getSchema().getTypes();
 
            // geometry的类型
            String geometryType = result.getSchema().getGeometryDescriptor().getType().getName().toString();
 
            List<String> csvHeader = new ArrayList<>();
            for (int i=0;i<attributeTypes.size();i++){
                AttributeType attributeType = attributeTypes.get(i);
                String key = attributeType.getName().toString();
                Class classType = attributeType.getBinding();
                if (geometryType.equals(key)){
                    continue;
                }
                csvHeader.add(key);
                out.write(key + ",");
                mapFields.put(key,classType);
            }
 
            out.write("coords");
            out.newLine();
 
            SimpleFeatureIterator itertor = result.features();
            while (itertor.hasNext()) {
                SimpleFeature feature = itertor.next();
                for(int i=0;i<csvHeader.size();i++){
                    String key = csvHeader.get(i);
                    String classType = mapFields.get(key).getTypeName();
                    String oneCsvData = feature.getAttribute(csvHeader.get(i)).toString();
 
                    if (classType.contains("Double")){
                        BigDecimal bd = new BigDecimal(oneCsvData);
                        oneCsvData = bd.toPlainString();
                    }
 
                    if(oneCsvData.contains(",")){
                        oneCsvData = "\"" + oneCsvData + "\"";
                    }
 
                    out.write(oneCsvData);
                    out.write(",");
                }
 
                String coords = feature.getDefaultGeometry().toString();
                if(coords.contains(",")){
                    coords = "\"" + coords + "\"";
                }
                out.write(coords);
                out.newLine();
                size++;
            }
            itertor.close();
            out.flush();
            out.close();
        }
        catch(Exception e){
            System.out.println("转换失败");
            e.printStackTrace();
        }
        return size;
 
    }
 
 
}

四.geojson转shape

引入相应的 pom 依赖:

	<dependencies>
		<dependency>
			<groupId>nl.cloudfarming.client</groupId>
			<artifactId>lib-geotools</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-geojson</artifactId>
			<version>18.0</version>
		</dependency>
		<dependency>
			<groupId>com.googlecode.json-simple</groupId>
			<artifactId>json-simple</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.62</version>
		</dependency>
	</dependencies>

java 代码:

import com.alibaba.fastjson.JSONObject;
import com.vividsolutions.jts.geom.*;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GeojsonToShape {

	public static void main(String[] args) {

		geojson2Shape( "E:\\points.geojson", "E:\\college\\college.shp");

	}

	public static void geojson2Shape(String jsonPath, String shpPath){
		GeometryJSON geojson = new GeometryJSON();
		try{
			String geojsonStr = readJson(jsonPath);
			Map<String, Object> geojsonMap = JSONObject.parseObject(geojsonStr, Map.class);
			List<Map> features = (List<Map>) geojsonMap.get("features");
			Map geojsonExemple = features.get(0);
			String geojsonType = ((Map) geojsonExemple.get("geometry")).get("type").toString();
			Map<String, Class> mapFields = new HashMap();
			for (int i = 0; i < features.size(); i++) {
				Map<String, Object> attributes = (Map<String, Object>) features.get(i).get("properties");
				for (String key : attributes.keySet()) {
					Class type = attributes.get(key).getClass();
					mapFields.put(key, type);
				}
			}

			Class<?> geoType = null;
			switch(geojsonType){
				case "Point":
					geoType = Point.class;
					break;
				case "MultiPoint":
					geoType = MultiPoint.class;
					break;
				case "LineString":
					geoType = LineString.class;
					break;
				case "MultiLineString":
					geoType = MultiLineString.class;
					break;
				case "Polygon":
					geoType = Polygon.class;
					break;
				case "MultiPolygon":
					geoType = MultiPolygon.class;
					break;
			}

			//创建shape文件对象
			File file = new File(shpPath);
			Map<String, Serializable> params = new HashMap<String, Serializable>();
			params.put( ShapefileDataStoreFactory.URLP.key, file.toURI().toURL() );
			ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
			//定义图形信息和属性信息
			SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
			tb.setCRS(DefaultGeographicCRS.WGS84);
			tb.setName("shapefile");
			tb.add("the_geom", geoType);

			for (String key : mapFields.keySet()) {
				tb.add(key, mapFields.get(key));
			}

			ds.createSchema(tb.buildFeatureType());
			//设置Writer
			FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.
					getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);

			for(int i=0,len=features.size();i<len;i++){
				Map oneGeojson = features.get(i);
				Map<String,Object> attributes = (Map<String, Object>) oneGeojson.get("properties");
				String strFeature = JSONObject.toJSONString(oneGeojson);
				Reader reader = new StringReader(strFeature);
				SimpleFeature feature = writer.next();

				switch(geojsonType){
					case "Point":
						feature.setAttribute("the_geom",geojson.readPoint(reader));
						break;
					case "MultiPoint":
						feature.setAttribute("the_geom",geojson.readMultiPoint(reader));
						break;
					case "LineString":
						feature.setAttribute("the_geom",geojson.readLine(reader));
						break;
					case "MultiLineString":
						feature.setAttribute("the_geom",geojson.readMultiLine(reader));
						break;
					case "Polygon":
						feature.setAttribute("the_geom",geojson.readPolygon(reader));
						break;
					case "MultiPolygon":
						feature.setAttribute("the_geom",geojson.readMultiPolygon(reader));
						break;
				}

				for (String key : attributes.keySet()) {
					feature.setAttribute(key,attributes.get(key));
				}
				writer.write();
			}
			writer.close();
			ds.dispose();
		}
		catch(Exception e){
			System.out.println("转换失败");
			e.printStackTrace();
		}
	}


	/**
	 * 读取文件
	 * @param filepath 文件路径
	 * @throws IOException
	 */
	public static String readJson(String filepath) {
		FileReader re = null;
		BufferedReader buff = null;
		String line = "";
		try {
			File file = new File(filepath);
			re = new FileReader(file);
			buff = new BufferedReader(re);
			String tempString = null;
			while ((tempString = buff.readLine()) != null) {
				line += tempString;
			}
			return line;
		} catch (Exception e) {
			System.out.println("失败了");
		} finally {
			try {
				re.close();
				buff.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return line;
	}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯洁的小魔鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值