GeoTools应用:读取Shape文件对象属性值(3)


一、环境准备

装配GeoTools有两种方式,一种是配置maven工程的pom文件(配置方式参考官网),另一种是下载geotools的jar包到本地导入依赖。我采用的是下载jar的方式,下载路径:https://sourceforge.net/projects/geotools/files/

二、实现功能

前面两章讲了如何从shape文件中提取属性列头信息和对象的空间坐标数据。这章讲解如何从shape文件中读取每个对象的属性值。

shape文件不是一个文件而是一堆文件,不同的文件描述了GIS对象的不同信息。.shp存储的是坐标数据; .dbf存储对象的属性; *.prj存储的是坐标系信息。这章讲的读取对象属性信息其实就是从dbf文件读取数据。

基础的GIS对象模型参考第二篇:《Java编程基础:GeoTools读取Shape文件中的空间坐标数据(2)》(https://blog.csdn.net/ylforever/article/details/80813711)。

三、样例代码

下面的代码在读取GIS对象时提取出每个对象的属性值,存储在基础GIS对象模型中。

1、GIS对象模型

package com.elon.model.gismodel;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.opengis.feature.simple.SimpleFeature;

import com.elon.constant.EnumGISObjectType;
import com.elon.model.ShapeFieldInfo;

/**
 * GIS对象基类定义。
 * 
 * @author elon
 * @version 2018年6月26日
 */
public class GISObjectBase implements Serializable {

    private static final long serialVersionUID = -6147262367078689317L;

    /**
     * 对象类型枚举
     */
    private final EnumGISObjectType type;

    private SimpleFeature simpleFeature = null;

    /**
     * 属性列信息
     */
    private List<ShapeFieldInfo> attrFieldList = new ArrayList<>();

    /**
     * 属性值信息<属性名称, 属性值>
     */
    private Map<String, Object> attributeMap = new HashMap<>();

    protected GISObjectBase(EnumGISObjectType type, SimpleFeature simpleFeature,
            List<ShapeFieldInfo> attrFieldList){
        this.type = type;
        this.simpleFeature = simpleFeature;
        this.attrFieldList = attrFieldList;
    }

    public EnumGISObjectType getType() {
        return type;
    }

    public SimpleFeature getSimpleFeature() {
        return simpleFeature;
    }

    public Map<String, Object> getAttributeMap() {
        return attributeMap;
    }

    public void setAttributeMap(Map<String, Object> attributeMap) {
        this.attributeMap = attributeMap;
    }

    public void addAttribute(String attrName, Object value) {
        attributeMap.put(attrName, value);
    }

    public void setSimpleFeature(SimpleFeature simpleFeature) {
        this.simpleFeature = simpleFeature;
    }

    public List<ShapeFieldInfo> getAttrFieldList() {
        return attrFieldList;
    }

    public void setAttrFieldList(List<ShapeFieldInfo> attrFieldList) {
        this.attrFieldList = attrFieldList;
    }
}

2、读取GIS对象时填充属性MAP表

package com.elon.shape;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;

import com.elon.model.ShapeFieldInfo;
import com.elon.model.gismodel.GISObjectBase;
import com.elon.model.gismodel.GISPoint;
import com.elon.model.gismodel.GisLine;
import com.elon.model.gismodel.GisMultiPolygon;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;

/**
 * Shape文件操作公共类。
 * @author elon
 * @version 2018年6月24日
 */
public class ShapeUtils {

    /**
     * 提取shape文件包含的属性字段名称和类型信息。
     * 
     * @param shpFilePath shape文件路径
     * @return 属性信息
     */
    public static List<ShapeFieldInfo> distillShapeFieldInfo(String shpFilePath) {
        List<ShapeFieldInfo> fieldList = new ArrayList<>();
        ShapefileDataStore dataStroe = buildDataStore(shpFilePath);

        try {
            List<AttributeDescriptor> attrList = dataStroe.getFeatureSource().getSchema()
                    .getAttributeDescriptors();
            for (AttributeDescriptor attr : attrList) {
                ShapeFieldInfo field = new ShapeFieldInfo();
                field.setFieldName(attr.getLocalName());
                field.setFieldType(attr.getType().getBinding());
                fieldList.add(field);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            dataStroe.dispose();
        }

        return fieldList;
    }

    /**
     * 读取GIS图层对象。
     * @param shpFilePath shp文件路径
     * @return 对象列表
     */
    @SuppressWarnings("unchecked")
    public static <T extends GISObjectBase> List<T> readGisObject(String shpFilePath) {
        List<T> gisObjectList = new ArrayList<>();
        List<ShapeFieldInfo> attrFieldList = distillShapeFieldInfo(shpFilePath);
        ShapefileDataStore dataStore = buildDataStore(shpFilePath);

        try {
            String typeName = dataStore.getTypeNames()[0];
            FeatureSource<SimpleFeatureType, SimpleFeature> fs = dataStore.getFeatureSource(typeName);
            FeatureCollection<SimpleFeatureType, SimpleFeature> fcResult = fs.getFeatures();
            System.out.println("fcResult size:" + fcResult.size());

            FeatureIterator<SimpleFeature> iter = fcResult.features();
            while (iter.hasNext()) {
                SimpleFeature sf = iter.next();
                Collection<Property> property = sf.getProperties();
                Iterator<Property> iterP = property.iterator();
                while (iterP.hasNext()) {
                    Property pro = iterP.next();

                    if (pro.getValue() instanceof MultiPolygon) {
                        gisObjectList.add((T) new GisMultiPolygon((MultiPolygon) pro.getValue(), sf, attrFieldList));
                    } else if (pro.getValue() instanceof Point) {
                        gisObjectList.add((T) new GISPoint((Point) pro.getValue(), sf, attrFieldList));
                    } else if (pro.getValue() instanceof MultiLineString) {
                        gisObjectList.add((T) new GisLine((MultiLineString) pro.getValue(), sf, attrFieldList));
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            dataStore.dispose();
        }

        fillGisObjectAttr(gisObjectList);
        return gisObjectList;
    }

    /**
     * 填充GIS对象的属性信息。
     * 
     * @param gisObjectList gis对象列表
     */
    private static <T extends GISObjectBase> void fillGisObjectAttr(List<T> gisObjectList) {
        for(T gisObject : gisObjectList) {
            for(ShapeFieldInfo field : gisObject.getAttrFieldList()) {
                Object value = gisObject.getSimpleFeature().getAttribute(field.getFieldName());
                gisObject.addAttribute(field.getFieldName(), value);
            }

            System.out.println(gisObject.getAttributeMap());
        }
    }

    /**
     * 构建ShapeDataStore对象。
     * @param shpFilePath shape文件路径。
     * @return
     */
    public static ShapefileDataStore buildDataStore(String shpFilePath) {
        ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
        try {
            ShapefileDataStore dataStore = (ShapefileDataStore) factory
                    .createDataStore(new File(shpFilePath).toURI().toURL());
            if (dataStore != null) {
                dataStore.setCharset(Charset.forName("UTF-8"));
            }
            return dataStore;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

四、补充说明

通过这种方式读取的属性MAP表中存储了GIS对象的坐标信息,对应的key是the_geom。多变形和线的the_geom值很长,如果需要在在界面展示属性,可以把它去掉。

转载自:https://blog.csdn.net/ylforever/article/details/80827950

You may also like...