java8驱动GADL读取gdb、shp数据并返回Layer范围(文末附全部代码与GDAL驱动压缩包!)

2 篇文章 0 订阅

小白最近进入一家gis研发公司,由于需求原因,需要读取gdb与shp数据源作为图层发布,特意写了一个java读取gdb与shp的工具,来获取里面的数据,并根据Layer属性来生成表结构

1.首先设置GDAL支持中文字符,并且注册驱动,指定Proj位置,

static {
        gdal.AllRegister();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
//        gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
//        gdal.SetConfigOption("FILEGDB_ENCODING", "CP936");
        gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
        gdal.SetConfigOption("FILEGDB_ENCODING", "UTF-8");
//        gdal.SetConfigOption("PGEO_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
//        gdal.SetConfigOption("MDB_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
        gdal.SetConfigOption("PGEO_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
        gdal.SetConfigOption("MDB_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
        osr.SetPROJSearchPath(System.getenv("JAVA_HOME") + "\\bin\\proj9\\share");
    }

2.获取数据源

gdbPath路径等于你想要读取的gdb文件路径

protected static DataSource getDataSource(String gdbPath) {
        if (!StringUtils.hasLength(gdbPath)) {
            return null;
        }
        return ogr.Open(gdbPath, gdalconst.GA_ReadOnly);
    }

3.获取图层信息(如果你明确业务知道图层可直接通过图层名获取相关数据)

 /**
     * 获取图层列表
     *
     * @param dataSource 数据源
     * @param readField  是否读取字段
     * @return
     */
    private static List<GisLayer> getLayers(DataSource dataSource, boolean readField) {
        if (null == dataSource) {
            return null;
        }
        List<GisLayer> gisLayerList = new ArrayList<>();
        // 获取图层数量
        int layerCount = dataSource.GetLayerCount();
        for (int i = 0; i < layerCount; i++) {
            //  获取图层
            Layer layer = dataSource.GetLayer(i);
            gisLayerList.add(getLayer(layer, readField));
        }
        return gisLayerList;
    }

 private static GisLayer getLayer(Layer layer, boolean readField) {
        if (null == layer) {
            return null;
        }
        GisLayer gisLayer = new GisLayer();
        // 获取图层名称
        gisLayer.setName(layer.GetName());
        gisLayer.setAlias(layer.GetName());
        if (StringUtils.hasLength(layer.GetDescription())) {
            gisLayer.setAlias(layer.GetDescription());
        }
        gisLayer.setGeometryColumn(layer.GetGeometryColumn());
        if (!StringUtils.hasLength(gisLayer.getGeometryColumn())) {
            gisLayer.setGeometryColumn("shape");
        }
        gisLayer.setFeatureCount(layer.GetFeatureCount());
        SpatialReference sourceSrs = layer.GetSpatialRef();
        if (null != sourceSrs) {
            gisLayer.setSpatialRefWkt(sourceSrs.ExportToWkt());
            String sridString = sourceSrs.GetAttrValue("AUTHORITY", 1);
            if (null != sridString) {
                gisLayer.setSrid(Integer.parseInt(sridString));
            }
            SpatialReference targetSrs = new SpatialReference();
            targetSrs.ImportFromEPSG(4326);
            CoordinateTransformation ct = new CoordinateTransformation(sourceSrs, targetSrs);
            if (null != ct) {
                double[] doubles = layer.GetExtent();
                if (null != doubles && doubles.length > 0) {
                    double[] doubles1 = ct.TransformPoint(doubles[0], doubles[2]);
                    double[] doubles2 = ct.TransformPoint(doubles[1], doubles[3]);
                    gisLayer.setExtent(new double[]{doubles1[1], doubles1[0], doubles2[1], doubles2[0]});
                } else {
                    gisLayer.setExtent(new double[]{0, 0, 0, 0});
                }
            } else {
                gisLayer.setExtent(new double[]{0, 0, 0, 0});
            }
        } else {
            gisLayer.setExtent(new double[]{0, 0, 0, 0});
        }

        gisLayer.setFidColumn(layer.GetFIDColumn());
        gisLayer.setGeomType(layer.GetGeomType());
        //字段
        if (readField) {
            gisLayer.setFieldList(getFields(layer));
        }
        return gisLayer;
    }

protected static List<GisLayerField> getFields(Layer layer) {
        List<GisLayerField> gisLayerFieldList = new ArrayList<>();
        GisLayerField gisLayerField;
        for (int i = 0; i < layer.GetLayerDefn().GetFieldCount(); i++) {
            FieldDefn fieldDefn = layer.GetLayerDefn().GetFieldDefn(i);
            gisLayerField = new GisLayerField();
            gisLayerField.setName(fieldDefn.GetName());
            gisLayerField.setAlias(fieldDefn.GetName());
            if (StringUtils.hasLength(fieldDefn.GetAlternativeName())) {
                gisLayerField.setAlias(fieldDefn.GetAlternativeName());
            }
            gisLayerField.setType(fieldDefn.GetFieldType());
            gisLayerField.setLength(fieldDefn.GetWidth());

            gisLayerFieldList.add(gisLayerField);
        }
        return gisLayerFieldList;
    }

这里核心方法主要为getFields与getLayer其本质都是获取图层图形属性、空间范围、字段类型、字段名

4数据读取,这里采用的是分页读取,因为有的gdb数据高达几十万条,一次性读取全部容易崩溃,遂采用分页读取的方式,如果你数据量不大,可不传分页信息

  /**
     * 分页读取数据
     *
     * @param layerName    图层名称
     * @param where        sql条件
     * @param page         页码
     * @param pageSize     页大小
     * @param targetCrsWkt 目标坐标系
     * @return
     */
    public List<Map> getDataListByPage(String layerName, String where, Integer page, Integer pageSize, String targetCrsWkt) {
        if (!StringUtils.hasLength(layerName)) {
            return null;
        }
        Layer layer = this.dataSource.GetLayer(layerName);
        //设置条件
        if (StringUtils.hasLength(where)) {
            layer.SetAttributeFilter(where);
        }
        //获取字段
        List<GisLayerField> fields = getFields(layer);
        //设置分页信息
        long nextIndex = 0;
        if (null != page && null != pageSize) {
            nextIndex = (page - 1) * pageSize;
        }
        //设置读取位置为nextIndex
        try {
            layer.SetNextByIndex(nextIndex);
        } catch (Exception ex) {
            return null;
        }
        //设置坐标转换
        CoordinateTransformation ct = null;
        if (null != targetCrsWkt && !targetCrsWkt.isEmpty()) {
            SpatialReference sourceSrs = layer.GetSpatialRef();
            SpatialReference targetSrs = new SpatialReference(targetCrsWkt);
            targetSrs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
            ct = new CoordinateTransformation(sourceSrs, targetSrs);
        }
        int count = 0;
        List<Map> dataList = new ArrayList<>();
        Map data;
        Feature feature;
        while ((feature = layer.GetNextFeature()) != null) {
            data = new HashMap();
            //读取几何信息
            readGeometry(layer, feature, data, ct);
            //获取属性值
            readProperty(data, feature, fields);
            dataList.add(data);
            //如果分页信息不空
            if (null != page && null != pageSize) {
                // 增加计数
                count++;
                // 如果达到一页的数量,则跳出循环
                if (count >= pageSize) {
                    break;
                }
            }
        }
        return dataList;
    }

 protected static void readGeometry(Layer layer, Feature feature, Map data, CoordinateTransformation ct) {
        Geometry geometry = feature.GetGeometryRef();
        //如果坐标转换类不空,进行转换
        if (null != ct) {
            geometry.Transform(ct);
        }
        //转二维
        geometry.FlattenTo2D();
        String geometryColumnName = layer.GetGeometryColumn();
        //如果空间字段名为空,用shape作为字段名
        if (!StringUtils.hasLength(geometryColumnName)) {
            geometryColumnName = "shape";
        }
        data.put(geometryColumnName, geometry.ExportToWkt());
    }

 /**
     * 读取属性值
     *
     * @param data    数据
     * @param feature 要素
     * @param fields  字段信息
     */
    protected static void readProperty(Map data, Feature feature, List<GisLayerField> fields) {
        //获取属性值
        for (GisLayerField field : fields) {
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getByValue(field.getType());
            if (null == fieldTypeEnum) {
                continue;
            }
            switch (fieldTypeEnum) {
                case OFTString:
                    data.put(field.getName(), feature.GetFieldAsString(field.getName()));
                    break;
                case OFTStringList:
                    data.put(field.getName(), feature.GetFieldAsString(field.getName()));
                    break;
                case OFTInteger:
                    data.put(field.getName(), feature.GetFieldAsInteger(field.getName()));
                    break;
                case OFTReal:
                    data.put(field.getName(), feature.GetFieldAsDouble(field.getName()));
                    break;
                case OFTInteger64:
                    data.put(field.getName(), feature.GetFieldAsInteger64(field.getName()));
                    break;
                case OFTBinary:
                    data.put(field.getName(), feature.GetFieldAsBinary(field.getName()));
                    break;
                case OFTDate:
                    data.put(field.getName(), feature.GetFieldAsISO8601DateTime(field.getName()));
                    break;
                case OFTTime:
                    data.put(field.getName(), feature.GetFieldAsISO8601DateTime(field.getName()));
                    break;
                case OFTDateTime:
                    data.put(field.getName(), feature.GetFieldAsISO8601DateTime(field.getName()));
                    break;
            }
        }
    }

这里存在一个空间坐标转换与去掉ZM值的方式,因为小编业务需求同一将所有gdb文件下内容转换到同一空间坐标参考,如果你们不需要的话 null就行。

5文后附上整片文章代码

public class GisLayerField {

    private String name;
    private String alias;
    private Integer type;
    private Integer length;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }
}
import java.util.List;

public class GisLayer {

    //图层名称
    private String name;
    //别名
    private String alias;
    //矢量要素列
    private String geometryColumn;
    //矢量要素数量
    private Long featureCount;
    //空间参考
    private String spatialRefWkt;
    //SRID
    private Integer srid;
    //矢量要素范围
    private double[] extent;
    //FID列
    private String fidColumn;
    //矢量要素类型:
    private Integer geomType;
    //字段列表
    private List<GisLayerField> fieldList;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public String getGeometryColumn() {
        return geometryColumn;
    }

    public void setGeometryColumn(String geometryColumn) {
        this.geometryColumn = geometryColumn;
    }

    public Long getFeatureCount() {
        return featureCount;
    }

    public void setFeatureCount(Long featureCount) {
        this.featureCount = featureCount;
    }

    public String getSpatialRefWkt() {
        return spatialRefWkt;
    }

    public void setSpatialRefWkt(String spatialRefWkt) {
        this.spatialRefWkt = spatialRefWkt;
    }


    public double[] getExtent() {
        return extent;
    }

    public void setExtent(double[] extent) {
        this.extent = extent;
    }

    public String getFidColumn() {
        return fidColumn;
    }

    public void setFidColumn(String fidColumn) {
        this.fidColumn = fidColumn;
    }

    public Integer getGeomType() {
        return geomType;
    }

    public void setGeomType(Integer geomType) {
        this.geomType = geomType;
    }

    public Integer getSrid() {
        return srid;
    }

    public void setSrid(Integer srid) {
        this.srid = srid;
    }

    public List<GisLayerField> getFieldList() {
        return fieldList;
    }

    public void setFieldList(List<GisLayerField> fieldList) {
        this.fieldList = fieldList;
    }
}


import com.alibaba.fastjson.JSON;
import com.mepu.gis.analyse.gisDataEntity.FieldTypeEnum;
import com.mepu.gis.analyse.gisDataEntity.GisLayer;
import com.mepu.gis.analyse.gisDataEntity.GisLayerField;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconst;
import org.gdal.ogr.*;
import org.gdal.osr.CoordinateTransformation;
import org.gdal.osr.SpatialReference;
import org.gdal.osr.osr;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.gdal.osr.osrConstants.OAMS_TRADITIONAL_GIS_ORDER;

/**
 * 空间数据读取工具: 如gdb、shp、kml
 */
public class FileGdbReader implements IGisDataReader {

    static {
        gdal.AllRegister();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
//        gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
//        gdal.SetConfigOption("FILEGDB_ENCODING", "CP936");
        gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
        gdal.SetConfigOption("FILEGDB_ENCODING", "UTF-8");
//        gdal.SetConfigOption("PGEO_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
//        gdal.SetConfigOption("MDB_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
        gdal.SetConfigOption("PGEO_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
        gdal.SetConfigOption("MDB_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s");
        osr.SetPROJSearchPath(System.getenv("JAVA_HOME") + "\\bin\\proj9\\share");
    }

    //数据源
    protected DataSource dataSource;

    public FileGdbReader(String gdbPath) {
        this.dataSource = getDataSource(gdbPath);
    }

    /**
     * 获取数据源
     *
     * @param gdbPath
     * @return
     */
    protected static DataSource getDataSource(String gdbPath) {
        if (!StringUtils.hasLength(gdbPath)) {
            return null;
        }
        return ogr.Open(gdbPath, gdalconst.GA_ReadOnly);
    }

    /**
     * 获取图层列表
     *
     * @param readField 是否读取字段
     * @return
     */
    @Override
    public List<GisLayer> getLayers(boolean readField) {
        if (dataSource == null) {
            return null;
        }
        return getLayers(dataSource, readField);
    }

    /**
     * 获取图层列表
     *
     * @param gdbPath   gdb路径
     * @param readField 是否读取字段
     * @return
     */
    public static List<GisLayer> getLayers(String gdbPath, boolean readField) {
        if (!StringUtils.hasLength(gdbPath)) {
            return null;
        }
        DataSource dataSource = getDataSource(gdbPath);
        List<GisLayer> gisLayerList = getLayers(dataSource, readField);
        dataSource.delete();
        return gisLayerList;
    }

    /**
     * 获取图层列表
     *
     * @param dataSource 数据源
     * @param readField  是否读取字段
     * @return
     */
    private static List<GisLayer> getLayers(DataSource dataSource, boolean readField) {
        if (null == dataSource) {
            return null;
        }
        List<GisLayer> gisLayerList = new ArrayList<>();
        // 获取图层数量
        int layerCount = dataSource.GetLayerCount();
        for (int i = 0; i < layerCount; i++) {
            //  获取图层
            Layer layer = dataSource.GetLayer(i);
            gisLayerList.add(getLayer(layer, readField));
        }
        return gisLayerList;
    }

    /**
     * 获取图层信息
     *
     * @param layerName 图层名称
     * @param readField 是否读取字段
     * @return
     */
    @Override
    public GisLayer getLayer(String layerName, boolean readField) {
        if (null == dataSource) {
            return null;
        }
        //  获取图层
        Layer layer = dataSource.GetLayer(layerName);
        return getLayer(layer, readField);
    }

    /**
     * 获取图层信息
     *
     * @param layer     图层
     * @param readField 是否读取字段
     * @return
     */
    private static GisLayer getLayer(Layer layer, boolean readField) {
        if (null == layer) {
            return null;
        }
        GisLayer gisLayer = new GisLayer();
        // 获取图层名称
        gisLayer.setName(layer.GetName());
        gisLayer.setAlias(layer.GetName());
        if (StringUtils.hasLength(layer.GetDescription())) {
            gisLayer.setAlias(layer.GetDescription());
        }
        gisLayer.setGeometryColumn(layer.GetGeometryColumn());
        if (!StringUtils.hasLength(gisLayer.getGeometryColumn())) {
            gisLayer.setGeometryColumn("shape");
        }
        gisLayer.setFeatureCount(layer.GetFeatureCount());
        SpatialReference sourceSrs = layer.GetSpatialRef();
        if (null != sourceSrs) {
            gisLayer.setSpatialRefWkt(sourceSrs.ExportToWkt());
            String sridString = sourceSrs.GetAttrValue("AUTHORITY", 1);
            if (null != sridString) {
                gisLayer.setSrid(Integer.parseInt(sridString));
            }
            SpatialReference targetSrs = new SpatialReference();
            targetSrs.ImportFromEPSG(4326);
            CoordinateTransformation ct = new CoordinateTransformation(sourceSrs, targetSrs);
            if (null != ct) {
                double[] doubles = layer.GetExtent();
                if (null != doubles && doubles.length > 0) {
                    double[] doubles1 = ct.TransformPoint(doubles[0], doubles[2]);
                    double[] doubles2 = ct.TransformPoint(doubles[1], doubles[3]);
                    gisLayer.setExtent(new double[]{doubles1[1], doubles1[0], doubles2[1], doubles2[0]});
                } else {
                    gisLayer.setExtent(new double[]{0, 0, 0, 0});
                }
            } else {
                gisLayer.setExtent(new double[]{0, 0, 0, 0});
            }
        } else {
            gisLayer.setExtent(new double[]{0, 0, 0, 0});
        }

        gisLayer.setFidColumn(layer.GetFIDColumn());
        gisLayer.setGeomType(layer.GetGeomType());
        //字段
        if (readField) {
            gisLayer.setFieldList(getFields(layer));
        }
        return gisLayer;
    }

    /**
     * 获取图层字段列表
     *
     * @param gdbPath
     * @param layerName
     * @return
     */
    public static List<GisLayerField> getFields(String gdbPath, String layerName) {
        if (StringUtils.hasLength(gdbPath) && StringUtils.hasLength(layerName)) {
            DataSource dataSource = getDataSource(gdbPath);
            List<GisLayerField> gisLayerFieldList = getFields(dataSource, layerName);
            dataSource.delete();
            return gisLayerFieldList;
        }
        return null;
    }

    private static List<GisLayerField> getFields(DataSource dataSource, String layerName) {
        if (null != dataSource && StringUtils.hasLength(layerName)) {
            Layer layer = dataSource.GetLayerByName(layerName);
            List<GisLayerField> gisLayerFieldList = getFields(layer);
            return gisLayerFieldList;
        }
        return null;
    }

    protected static List<GisLayerField> getFields(Layer layer) {
        List<GisLayerField> gisLayerFieldList = new ArrayList<>();
        GisLayerField gisLayerField;
        for (int i = 0; i < layer.GetLayerDefn().GetFieldCount(); i++) {
            FieldDefn fieldDefn = layer.GetLayerDefn().GetFieldDefn(i);
            gisLayerField = new GisLayerField();
            gisLayerField.setName(fieldDefn.GetName());
            gisLayerField.setAlias(fieldDefn.GetName());
            if (StringUtils.hasLength(fieldDefn.GetAlternativeName())) {
                gisLayerField.setAlias(fieldDefn.GetAlternativeName());
            }
            gisLayerField.setType(fieldDefn.GetFieldType());
            gisLayerField.setLength(fieldDefn.GetWidth());

            gisLayerFieldList.add(gisLayerField);
        }
        return gisLayerFieldList;
    }

    @Override
    public List<Map> getDataList(String layerName, String where) {
        return getDataList(layerName, where, null);
    }

    public List<Map> getDataList(String layerName, String where, String targetCrsWkt) {
        return getDataListByPage(layerName, where, null, null, targetCrsWkt);
    }

    /**
     * 分页读取数据
     *
     * @param layerName 图层名称
     * @param where     sql条件
     * @param page      页码
     * @param pageSize  页大小
     * @return
     */
    public List<Map> getDataListByPage(String layerName, String where, Integer page, Integer pageSize) {
        return getDataListByPage(layerName, where, page, pageSize, null);
    }

    /**
     * 分页读取数据
     *
     * @param layerName    图层名称
     * @param where        sql条件
     * @param page         页码
     * @param pageSize     页大小
     * @param targetCrsWkt 目标坐标系
     * @return
     */
    public List<Map> getDataListByPage(String layerName, String where, Integer page, Integer pageSize, String targetCrsWkt) {
        if (!StringUtils.hasLength(layerName)) {
            return null;
        }
        Layer layer = this.dataSource.GetLayer(layerName);
        //设置条件
        if (StringUtils.hasLength(where)) {
            layer.SetAttributeFilter(where);
        }
        //获取字段
        List<GisLayerField> fields = getFields(layer);
        //设置分页信息
        long nextIndex = 0;
        if (null != page && null != pageSize) {
            nextIndex = (page - 1) * pageSize;
        }
        //设置读取位置为nextIndex
        try {
            layer.SetNextByIndex(nextIndex);
        } catch (Exception ex) {
            return null;
        }
        //设置坐标转换
        CoordinateTransformation ct = null;
        if (null != targetCrsWkt && !targetCrsWkt.isEmpty()) {
            SpatialReference sourceSrs = layer.GetSpatialRef();
            SpatialReference targetSrs = new SpatialReference(targetCrsWkt);
            targetSrs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
            ct = new CoordinateTransformation(sourceSrs, targetSrs);
        }
        int count = 0;
        List<Map> dataList = new ArrayList<>();
        Map data;
        Feature feature;
        while ((feature = layer.GetNextFeature()) != null) {
            data = new HashMap();
            //读取几何信息
            readGeometry(layer, feature, data, ct);
            //获取属性值
            readProperty(data, feature, fields);
            dataList.add(data);
            //如果分页信息不空
            if (null != page && null != pageSize) {
                // 增加计数
                count++;
                // 如果达到一页的数量,则跳出循环
                if (count >= pageSize) {
                    break;
                }
            }
        }
        return dataList;
    }

    /**
     * 按范围查询数据
     *
     * @param layerName 图层名称
     * @param extentWkt 范围wkt
     * @param where     sql条件
     * @return
     */
    public List<Map> getDataListByExtent(String layerName, String extentWkt, String where, String targetCrsWkt) {
        if (!StringUtils.hasLength(layerName)) {
            return null;
        }
        Layer layer = dataSource.GetLayer(layerName);
        //设置条件
        if (StringUtils.hasLength(where)) {
            layer.SetAttributeFilter(where);
        }
        //设置空间查询条件
        layer.SetSpatialFilter(Geometry.CreateFromWkt(extentWkt));
        //设置读取位置为0
        try {
            layer.SetNextByIndex(0);
        } catch (Exception ex) {
            return null;
        }
        //设置坐标转换
        CoordinateTransformation ct = null;
        if (null != targetCrsWkt && !targetCrsWkt.isEmpty()) {
            SpatialReference sourceSrs = layer.GetSpatialRef();
            SpatialReference targetSrs = new SpatialReference(targetCrsWkt);
            targetSrs.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
            ct = new CoordinateTransformation(sourceSrs, targetSrs);
        }
        //获取字段
        List<GisLayerField> fields = getFields(layer);
        List<Map> dataList = new ArrayList<>();
        Map data;
        Feature feature;
        while ((feature = layer.GetNextFeature()) != null) {
            data = new HashMap();
            //读取几何信息
            readGeometry(layer, feature, data, ct);
            //获取属性值
            readProperty(data, feature, fields);
            dataList.add(data);
        }
        return dataList;
    }

    /**
     * 读取几何信息
     *
     * @param layer   图层
     * @param feature 要素
     * @param data    数据
     * @param ct      坐标转换类
     */
    protected static void readGeometry(Layer layer, Feature feature, Map data, CoordinateTransformation ct) {
        Geometry geometry = feature.GetGeometryRef();
        //如果坐标转换类不空,进行转换
        if (null != ct) {
            geometry.Transform(ct);
        }
        //转二维
        geometry.FlattenTo2D();
        String geometryColumnName = layer.GetGeometryColumn();
        //如果空间字段名为空,用shape作为字段名
        if (!StringUtils.hasLength(geometryColumnName)) {
            geometryColumnName = "shape";
        }
        data.put(geometryColumnName, geometry.ExportToWkt());
    }

    /**
     * 读取属性值
     *
     * @param data    数据
     * @param feature 要素
     * @param fields  字段信息
     */
    protected static void readProperty(Map data, Feature feature, List<GisLayerField> fields) {
        //获取属性值
        for (GisLayerField field : fields) {
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getByValue(field.getType());
            if (null == fieldTypeEnum) {
                continue;
            }
            switch (fieldTypeEnum) {
                case OFTString:
                    data.put(field.getName(), feature.GetFieldAsString(field.getName()));
                    break;
                case OFTStringList:
                    data.put(field.getName(), feature.GetFieldAsString(field.getName()));
                    break;
                case OFTInteger:
                    data.put(field.getName(), feature.GetFieldAsInteger(field.getName()));
                    break;
                case OFTReal:
                    data.put(field.getName(), feature.GetFieldAsDouble(field.getName()));
                    break;
                case OFTInteger64:
                    data.put(field.getName(), feature.GetFieldAsInteger64(field.getName()));
                    break;
                case OFTBinary:
                    data.put(field.getName(), feature.GetFieldAsBinary(field.getName()));
                    break;
                case OFTDate:
                    data.put(field.getName(), feature.GetFieldAsISO8601DateTime(field.getName()));
                    break;
                case OFTTime:
                    data.put(field.getName(), feature.GetFieldAsISO8601DateTime(field.getName()));
                    break;
                case OFTDateTime:
                    data.put(field.getName(), feature.GetFieldAsISO8601DateTime(field.getName()));
                    break;
            }
        }
    }

    /**
     * 关闭数据源
     */
    @Override
    public void close() {
        if (null != this.dataSource) {
            this.dataSource.delete();
            System.gc();
        }
    }

    public static void main(String[] args) throws IOException {
//        String gdbPath = "I:\\xx\\xxxxx.gdb";

//        gdbPath=getGdbPath(gdbPath);
        List<GisLayer> layers1 = FileGdbReader.getLayers(gdbPath, false);
        FileGdbReader fileGdbReadUtil = new FileGdbReader(gdbPath);
        List<GisLayer> layers = fileGdbReadUtil.getLayers(true);
        //A1是图层名称
        GisLayer layer = fileGdbReadUtil.getLayer("A1", false);
        System.out.println(JSON.toJSONString(layer));
        Long featureCount = layer.getFeatureCount();
        int pageSize = 10;
        int pageCount = featureCount.intValue() / pageSize;
        if (featureCount.intValue() % pageSize > 0) {
            pageCount++;
        }
        System.out.println(String.format("总条数:%s,总页数:%s", featureCount, pageCount));
        for (int i = 1; i <= pageCount; i++) {
            List<Map> dataList = fileGdbReadUtil.getDataListByPage(layer.getName(), null, i, pageSize, null);
            System.out.println(String.format("第%s页数据,条数:%s", i, dataList.size()));
            System.out.println(JSON.toJSONString(dataList));
            if (i == 5) {
                break;
            }
        }
        fileGdbReadUtil.close();
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值