java geotools shpfile to featureCollection

Article directory

  • A brief description
  • maven dependencies
  • Sample code

Brief description

Convert shpfile to featureCollection

maven dependencies

 <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>27.0</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-render</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-coverage</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>it.geosolutions.imageio-ext</groupId>
            <artifactId>imageio-ext-utilities</artifactId>
            <version>1.4.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.conversantmedia/disruptor -->
        <dependency>
            <groupId>com.conversantmedia</groupId>
            <artifactId>disruptor</artifactId>
            <version>1.2.15</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.geotools/gt-geojson -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>27.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.geotools/gt-epsg-hsql -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>27.0</version>
        </dependency>
        <dependency>
            <groupId>si.uom</groupId>
            <artifactId>si-quantity</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>si.uom</groupId>
            <artifactId>si-units</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>tech.uom.lib</groupId>
            <artifactId>uom-lib-common</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>systems.uom</groupId>
            <artifactId>systems-common</artifactId>
            <version>2.0.2</version>
        </dependency>

Sample code

public static void main(String[] args) {<!-- -->
        String featureCollection = getFeatureCollectionFromFile();
        System.out.println(featureCollection);
    }
    /**
     * Get the featureCollection of shpfile
     *
     * @return
     */
    private static String getFeatureCollectionFromFile() {<!-- -->
        File file = new File("D:\xxx.shp");
        Map<String, Object> params = new HashMap<String, Object>();
        ShapefileDataStore dataStore = null;
        SimpleFeatureType simpleFeatureType = null;
        try {<!-- -->
            params.put("url", file.toURI().toURL());
            dataStore = (ShapefileDataStore) DataStoreFinder.getDataStore(params);
            dataStore.setCharset(Charset.forName("GBK"));
            FeatureSource featureSource = dataStore.getFeatureSource(dataStore.getTypeNames()[0]);
            FeatureCollection featureCollection = featureSource.getFeatures();
            FeatureIterator featureIterator = featureCollection.features();
            Feature firstFeature = featureIterator.next();
            Collection<Property> firstProperties = firstFeature.getProperties();
            //For different space types
            List<String> geometryTypelist = Arrays.asList("point", "linestring", "polygon", "multipoint", "multilinestring", "multipolygon");
            Property geoProperty = firstProperties.stream().filter(f -> geometryTypelist.contains(f.getType().getName().toString().toLowerCase())).findFirst().orElse(null);
            String geoNameStr = geoProperty.getName().toString();
            String geoTypeStr = geoProperty.getType().getName().toString();
            StringBuilder typeSpecBuilder = new StringBuilder("geometry:");
            typeSpecBuilder.append(geoTypeStr);
            for (Property property : firstProperties) {<!-- -->
                String columnStr = property.getName().toString();
                if (columnStr.equals(geoNameStr)) {<!-- -->
                    continue;
                }
                typeSpecBuilder.append(",").append(columnStr).append(":").append(convertShpFieldType2Str(property.getType().getBinding()));
            }
            simpleFeatureType = DataUtilities.createType("simpleFeature", typeSpecBuilder.toString());
            //SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(simpleFeatureType);
            FeatureJSON fjson = new FeatureJSON(new GeometryJSON(6));
            List<SimpleFeature> features = new ArrayList<>();
            SimpleFeatureCollection collection = new ListFeatureCollection(simpleFeatureType, features);
            CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
            //Convert the first piece of data to the coordinate system
            Geometry firstGeometry = (Geometry) ((SimpleFeature) firstFeature).getDefaultGeometry();
            SimpleFeatureType sourceSimpleFeatureType = dataStore.getSchema();
            CoordinateReferenceSystem coordinateReferenceSystem = sourceSimpleFeatureType.getCoordinateReferenceSystem();
            ConvertCoordinateReferenceSystem(factory, coordinateReferenceSystem, (SimpleFeature)firstFeature, firstGeometry);
            features.add((SimpleFeature) firstFeature);
            while (featureIterator.hasNext()) {<!-- -->
                SimpleFeature feature = (SimpleFeature) featureIterator.next();
                Geometry sourceGeometry = (Geometry)feature.getDefaultGeometry();
                ConvertCoordinateReferenceSystem(factory, coordinateReferenceSystem, feature, sourceGeometry);
                features.add(feature);
            }
            featureIterator.close();
            StringWriter writer = new StringWriter();
            fjson.writeFeatureCollection(collection, writer);
            return writer.toString();
        } catch (IOException e) {<!-- -->
            e.printStackTrace();
        } catch (SchemaException e) {<!-- -->
            e.printStackTrace();
        }

        return null;
    }

    /**
     * Convert coordinate system
     * @param factory
     * @param fileSrid
     * @param feature
     * @param sourceGeometry
     */
    private static void ConvertCoordinateReferenceSystem(CRSAuthorityFactory factory, CoordinateReferenceSystem fileSrid, SimpleFeature feature, Geometry sourceGeometry) {<!-- -->
        //CoordinateReferenceSystem sourceCoordinate = null;
        CoordinateReferenceSystem targetCoordinate = null;
        try {<!-- -->
            //Target coordinate system
            targetCoordinate = factory.createCoordinateReferenceSystem("EPSG:" + 4490);
            //Create conversion
            MathTransform transform = CRS.findMathTransform(fileSrid, targetCoordinate,true);
            //Convert
            Geometry res = JTS.transform(sourceGeometry, transform);
            feature.setDefaultGeometry(res);
        } catch (FactoryException e) {<!-- -->
            e.printStackTrace();
        } catch (TransformException e) {<!-- -->
            e.printStackTrace();
        }
    }

    /**
     * convert shpFileType to db field type
     * Field types include: short integer, long integer, floating point, double precision, text, date
     *
     * @param value
     * @return
     */
    public static String convertShpFieldType2Str(Class value) {<!-- -->
        if (value == String.class) {<!-- -->//Text
            return "String";
        }
        if (value == Integer.class || value == Long.class) {<!-- -->//Short integer type
            return "Integer";
        }
        /*if (value == Long.class) {//Long integer type
            return "Long";
        }*/
        if (value == Float.class) {<!-- -->
            return "Float";
        }
        if (value == Double.class) {<!-- -->//Floating point double precision
            return "Double";
        }
        if (value == Date.class) {<!-- -->
            return "Date";//Date
        }
        if (Geometry.class.isAssignableFrom(value)) {<!-- -->
            return "geometry";
        }
        return null;
    }