GeoTools实现shpefile数据的读取查询

使用geotools实现对shpefile数据的属性查询和空间查询。
参考文章:
GeoTools 查询那点事-CQL
Maven中GeoTools的引入
GeoTools应用-Filter
GeoTools之shp文件操作

封装示例代码
package cn.lutuo.sx.app.server.dao.geoengine;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lutuo.sx.app.server.appexception.GeoQueryException;
import cn.lutuo.sx.app.server.commons.GeoQueryParams;
import com.vividsolutions.jts.geom.Geometry;
import lombok.extern.slf4j.Slf4j;
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.filter.text.cql2.CQLException;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.geojson.feature.FeatureJSON;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.spatial.Intersects;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ShapefileServer {

    private static String shpFileRootPath;

    private Map<String, ShapefileDataStore> shapefileMap = new HashMap<>();

    private static final String SHAPEFILE_PREFIX = "shp";

    @Value("${sx.shp_file_root_path}")
    public void setShpFileRootPath(String shpFileRootPath) {
        ShapefileServer.shpFileRootPath = shpFileRootPath;
        initShapefileServer();
    }

    private void initShapefileServer() {
        if (null == shpFileRootPath) return;
        File rootFile = new File(shpFileRootPath);
        if (rootFile.exists() && rootFile.isDirectory()
                && Objects.requireNonNull(rootFile.listFiles()).length > 0) {
            Arrays.stream(Objects.requireNonNull(rootFile.listFiles())).forEach(file -> {
                String name = file.getName();
                String fileName = name.substring(0, name.lastIndexOf("."));
                String filePrefix = name.substring(name.lastIndexOf(".") + 1);
                if (filePrefix.equals(SHAPEFILE_PREFIX)) {
                    try {
                        ShapefileDataStore shapefileDataStore = new ShapefileDataStore(file.toURI().toURL());
                        // 设置编码,防止属性的中文字符出现乱码
                        shapefileDataStore.setCharset(StandardCharsets.UTF_8);
                        shapefileMap.put(fileName, shapefileDataStore);
                    } catch (MalformedURLException e) {
                        log.debug("加载shapefile文件出错:" + e.getMessage());
                    }
                }
            });
        }
    }

    public List<String> getDatasetList() {
        return new ArrayList<>(shapefileMap.keySet());
    }

    public SimpleFeatureCollection queryFeature(GeoQueryParams geoQueryParams) throws GeoQueryException {
        SimpleFeatureCollection simpleFeatureCollection = null;
        String datasetName = geoQueryParams.getDatasetName();
        String attributeFilter = geoQueryParams.getAttributeFilter();
        Geometry queryGeometry = geoQueryParams.getGeometry();

        if (!shapefileMap.containsKey(datasetName)) {
            throw new GeoQueryException(datasetName + "数据集不存在!");
        }


        try {
            ShapefileDataStore shapefileDataStore = shapefileMap.get(datasetName);
            FeatureSource<SimpleFeatureType, SimpleFeature> featuresource = shapefileDataStore.getFeatureSource(shapefileDataStore.getTypeNames()[0]);
            // 读取要素
            if (null != attributeFilter && !attributeFilter.trim().isEmpty()) {
                simpleFeatureCollection = filterCQLOfSql(featuresource, attributeFilter);
            } else if (null != queryGeometry) {
                simpleFeatureCollection = filterGeoCQLOfGeometry(featuresource, queryGeometry);
            } else {
                simpleFeatureCollection = (SimpleFeatureCollection) featuresource.getFeatures();
            }
        } catch (IOException | CQLException e) {
            throw new GeoQueryException("获取数据出错!" + e.getMessage());
        }
        return simpleFeatureCollection;
    }

    public JSONObject queryFeatureCollection(GeoQueryParams geoQueryParams) throws GeoQueryException {
        JSONObject result = null;
        SimpleFeatureCollection simpleFeatureCollection = this.queryFeature(geoQueryParams);
        StringWriter writer = new StringWriter();
        FeatureJSON fJson = new FeatureJSON();
        try {
            fJson.writeFeatureCollection(simpleFeatureCollection, writer);
            result = JSONUtil.parseObj(writer.toString());
        } catch (IOException e) {
            log.debug("GeoJSON转换出错!" + e.getMessage());
            throw new GeoQueryException("GeoJSON转换出错!" + e.getMessage());
        }
        return result;
    }

    public List<JSONObject> queryFeature2GeoJSON(GeoQueryParams geoQueryParams) throws GeoQueryException {
        List<JSONObject> resultList = new ArrayList<>();
        SimpleFeatureCollection simpleFeatureCollection = this.queryFeature(geoQueryParams);
        if (null != simpleFeatureCollection) {
            // 拿到迭代器
            SimpleFeatureIterator simpleFeatureIterator = simpleFeatureCollection.features();
            // 遍历每一个要素
            while (simpleFeatureIterator.hasNext()) {
                SimpleFeature simpleFeature = simpleFeatureIterator.next();
                //feature转geojson
                StringWriter writer = new StringWriter();
                FeatureJSON fjson = new FeatureJSON();
                try {
                    fjson.writeFeature(simpleFeature, writer);
                    resultList.add(JSONUtil.parseObj(writer.toString()));
                } catch (IOException e) {
                    log.debug("GeoJSON转换出错!" + e.getMessage());
                    throw new GeoQueryException("GeoJSON转换出错!" + e.getMessage());
                }
            }
            simpleFeatureIterator.close();
        }
        return resultList;
    }

    private SimpleFeatureCollection filterCQLOfSql(FeatureSource<SimpleFeatureType, SimpleFeature> fs, String sql) throws CQLException, IOException {
        //ECQL是CQL的扩展类,支持 IN 查询
        return (SimpleFeatureCollection) fs.getFeatures(ECQL.toFilter(sql));
    }

    private SimpleFeatureCollection filterGeoCQLOfGeometry(FeatureSource<SimpleFeatureType, SimpleFeature> fs, Geometry geometry) throws CQLException, IOException {
        // 相交 拼接样式 "INTERSECTS(the_geom," + wktStr + ")"
        Filter filter = CQL.toFilter(Intersects.NAME + "(the_geom," + geometry.toString() + ")");
        return (SimpleFeatureCollection) fs.getFeatures(filter);
    }
}
测试
public static void main(String[] args) {
        String shpFileRootPath = "D:\\workdata\\shp";
        File rootFile = new File(shpFileRootPath);
        ShapefileServer shpFileServer = new ShapefileServer();
        if (rootFile.exists() && rootFile.isDirectory()
                && Objects.requireNonNull(rootFile.listFiles()).length > 0) {
            List<File> files = Arrays.stream(Objects.requireNonNull(rootFile.listFiles())).collect(Collectors.toList());
            files.forEach(file -> {
                System.out.println(file.getAbsolutePath());
                String name = file.getName();
                String fileName = name.substring(0, name.lastIndexOf("."));
                String filePrefix = name.substring(name.lastIndexOf(".") + 1);

            });
        }
        shpFileServer = null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值