关键词搜索

源码搜索 ×
×

java用geotools类库读取shapefile

发布2020-06-12浏览1575次

详情内容

前文再续,书接上一回:java读取shapefile且用arcgis for js展示

java怎么读取shapefile呢?

shapefile是esri公司最先搞出来的,那么arcgis应该是有相关的类库的吧?好像找不到?我问过搞移动端的同事,arcgis for android确有处理shapefile的类库,处理起来易如反掌。但是,在WEB系统,服务器端从shapefile读出数据,最终是要在前端浏览器中展示,像我们目前在建的项目,就是要用arcgis for js来展示这些数据,而安卓系统类似CS项目,有很大的不同。最大的不同,WEB系统中,数据要以JSON的形式给前端,这样才好处理。arcgis for android,没接触过,心存敬畏,会不会很庞大?有没有用?不清楚,我有点害怕,本能地放弃了。

arcgis for java的SDK应该是arcgis engine吧。有时间要了解下。

在java世界里,处理空间信息,最流行的也许就是用GeoTools了,一个开源的JAVA处理空间信息类库。

网上例子很多,但大同小异。其实读出shp的数据一点都不难。难就难在,geotools读出来的数据形式,如果转成json的话,是GeoJson,而不是EsriJson,前端想用arcgis for js绘制,很难。所以,读取出来后,要转成EsriJson。如何转换,是另一个课题。现在,先读出来再说。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.dbf.DbaseFileHeader;
import org.geotools.data.shapefile.dbf.DbaseFileReader;
import org.geotools.data.shapefile.files.ShpFiles;
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.geotools.geometry.jts.ReferencedEnvelope;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;

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

/*
    shapefile操作类
 */
public class ShapefileHelper {

    public static Object read(String path) throws IOException {
    	/*
			参数path就是shp文件的完整路径,如:E:\\蟠桃会资源清查\\调查图斑.shp  
			系统会自动检查同一个目录下有没有其他相关文件,有的话会一并读出,
			相关文件的路径无须给出
			.shp 存储地理形状和位置信息
			.dbf 存储属性信息
			.shx 索引文件
			.prj 坐标系
			.cpg 字符编码,如UTF-8
			
			读取出来的结果类型为 List<Map<String, Object>>
		 */
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

        File file = getFile(path);
        if (file == null) {
            return list;
        }

        String charset = getCharSet(path);

        FileDataStore store = FileDataStoreFinder.getDataStore(file);
        ((ShapefileDataStore)store).setCharset(Charset.forName(charset));
        SimpleFeatureSource featureSource = store.getFeatureSource();
        SimpleFeatureCollection collection = featureSource.getFeatures();
        SimpleFeatureIterator features = collection.features();
        while (features.hasNext()) {
            Map<String, Object> item = new HashMap<String, Object>();

            SimpleFeature f = features.next();
            Collection<Property> p = f.getProperties();
            Iterator<Property> it = p.iterator();
            while (it.hasNext()) {
                Property pro = it.next();

                String field = pro.getName().toString();
                field = field.equals("the_geom") ? "wkt" : field;

                String value = pro.getValue().toString();
                item.put(field, value);
            }

            list.add(item);
        }

        return list;
    }
    
    private static File getFile(String path){
        File file = new File(path);
        if (file == null) {
            System.out.println("找不到路径:" + path);
        }
        return file;
    }
    /*
    	获取shapefile字符编码
    	如果存在.cpg文件,则从中读取,否则默认为UTF-8
     */
    private static String getCharSet(String path){
        String charset = "UTF-8";

        int p = path.lastIndexOf(".");
        String cpg = path.substring(0,p) + ".cpg";
        File file = getFile(cpg);
        if(file != null) {
            RandomAccessFile raf = null;
            try {
                raf = new RandomAccessFile(cpg, "r");
                charset = raf.readLine();
                raf.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return charset;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

pom.xml

<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-shapefile</artifactId>
    <version>23.0</version>
</dependency>
<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-geojson</artifactId>
    <version>23.0</version>
</dependency>
<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-epsg-hsql</artifactId>
    <version>23.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

测试一下

@Test
void readSha() throws IOException {
	List<Map<String, Object>> list = (List<Map<String, Object>>) ShapefileHelper.read("E:\\蟠桃会资源清查\\导出成果20200420093045-2\\导出成果20200420093045\\图斑矢量\\调查图斑.shp");
	Console.print(list.size());
}
  • 1
  • 2
  • 3
  • 4
  • 5

但是,从shapefile里读出内容十分轻松,但这只是第一步,要想在前端的arcgis for js中展示出来,考验才刚刚开始。

请听下回分解。

参考文章:
JAVA用geotools读写shape格式文件
GeoTools——读取shapefile数据

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载