基于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 }