geoserver源码学习与扩展——CSV转shapefile文件

基于geotools实现csv转换为shapefile文件。

1、读取CSV文件,将其装入FeatureCollection;

2、利用ShapefileDumper类将FeatureCollection转存到硬盘;

    /*
    * transform CSV to FeatureCollection
    */
1
public void processCSVFile(File csvFile){ 2 3 ListFeatureCollection collection; 4 try{ 5 typeName = csvFile.getName().replace(".", "_"); 6 typeName = replaceBlank(typeName); 7 BufferedReader reader = new BufferedReader(new FileReader(csvFile)); 8 try{ 9 /* First line of the data file is the header */ 10 String line = reader.readLine(); 11 System.out.println("Header: " + line); 12 13 /* 14 * We use the DataUtilities class to create a FeatureType that will describe the data in our 15 * shapefile. 16 * 17 * See also the createFeatureType method below for another, more flexible approach. 18 */ 19 String[] strArray = line.split("\\,"); 20 int latDex = -1; 21 int longDex = -1; 22 List<String> typeSpec = new ArrayList<String>(); 23 typeSpec.add("the_geom:Point:srid="+ SRID); // <- the geometry attribute: Point type 24 for(int i = 0; i < strArray.length; i ++){ 25 if(strArray[i].contains("Lat")){ 26 latDex = i; 27 } 28 else if(strArray[i].contains("Long")){ 29 longDex = i; 30 } 31 else{ 32 typeSpec.add(strArray[i] + ":String"); //all String type 33 } 34 } 35 if(CreateCluster) 36 typeSpec.add("cluster:String"); //add cluster field 37 String typeSpecs = String.join(",", typeSpec); 38 final SimpleFeatureType TYPE = DataUtilities.createType(typeName, 39 typeSpecs // other attribute 40 ); 41 /* 42 * GeometryFactory will be used to create the geometry attribute of each feature (a Point 43 * object for the location) 44 */ 45 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); 46 SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE); 47 /* 48 * We create a FeatureCollection into which we will put each Feature created from a record 49 * in the input csv data file 50 */ 51 collection = new ListFeatureCollection(TYPE); 52 53 for (line = reader.readLine(); line != null; line = reader.readLine()) { 54 if (line.trim().length() > 0) { // skip blank lines 55 String tokens[] = line.split("\\,"); 56 double latitude = Double.parseDouble(tokens[latDex]); 57 double longitude = Double.parseDouble(tokens[longDex]); 58 59 /* Longitude (= x coord) first ! */ 60 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); 61 62 featureBuilder.add(point);; 63 for(int i = 0; i < tokens.length; i ++){ 64 if(latDex != i && longDex != i){ 65 String strVal = tokens[i].trim(); 66 featureBuilder.add(strVal); 67 } 68 } 69 70 if(CreateCluster) 71 featureBuilder.add(""); //add cluster field value 72 SimpleFeature feature = featureBuilder.buildFeature(null); 73 collection.add(feature); 74 } 75 } 76 } finally { 77 reader.close(); 78 } 79 writeShapeFile(collection); 80 81 } 82 catch(Exception ex){ 83 System.out.println(ex.getMessage()); 84 } 85 }

CSV文件并不包含各字段的类型说明,将经纬度字段转换为Geometry,其他字段都为String类型;

另外,DataUtilities.createType方法创建要素方案时,将所有的String类型的字段长度都设为了java环境下的默认长度254,若字段太多或要素太多会导致shapefile中的dbf文件过大,可参考DataUtilities类,编写自定义类将String类型长度设为自定义长度;

 1     /*
 2      * FeatureCollection to shapefile
 3     */
 4     private void writeShapeFile(SimpleFeatureCollection collection){
 5         final File baseDir = resourceLoader.getBaseDirectory();
 6         File shpDir = new File(baseDir.getAbsolutePath() + "/Data/upload");
 7         if(!shpDir.exists()){
 8             shpDir.mkdirs();
 9         }
10         if(!shpDir.exists())
11             return;
12 
13         ShapefileDumper dumper = new ShapefileDumper(shpDir);
14         dumper.setMaxDbfSize(maxDbfSize);
15         dumper.setMaxShpSize(maxShpSize);
16         dumper.setCharset(Charset.forName(charSet));
17 
18 
19         // target charset
20 
21         try {
22             // if an empty result out of feature type with unknown geometry is created, the
23             // zip file will be empty and the zip output stream will break
24             boolean shapefileCreated = false;
25             shapefileCreated |= dumper.dump(collection);
26 
27             // take care of the case the output is completely empty
28             if(!shapefileCreated) {
29                 createEmptyWarning(shpDir);
30             }
31 
32         }
33         catch(Exception ex){
34             System.out.println(ex.getMessage());
35         }
36 
37     }
38 
39     private void createEmptyWarning(File tempDir) throws IOException {
40         PrintWriter pw = null;
41         try {
42             pw = new PrintWriter(new File(tempDir, "README.TXT"));
43             pw.print("The CSV Upload result is empty, and the geometric type of the features is unknwon:"
44                     + "an empty point shapefile has been created");
45         } finally {
46             pw.close();
47         }
48     }

 

posted @ 2018-03-21 14:50  GISer-Li  阅读(1326)  评论(0编辑  收藏  举报