|
@@ -0,0 +1,234 @@
|
|
|
+package com.onemap.spatial.util;
|
|
|
+
|
|
|
+import com.onemap.common.core.utils.StringUtils;
|
|
|
+import com.onemap.spatial.domain.WriteShpVo;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.geotools.data.FeatureWriter;
|
|
|
+import org.geotools.data.Transaction;
|
|
|
+import org.geotools.data.shapefile.ShapefileDataStore;
|
|
|
+import org.geotools.data.shapefile.ShapefileDataStoreFactory;
|
|
|
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
|
|
|
+import org.geotools.referencing.crs.DefaultGeographicCRS;
|
|
|
+import org.locationtech.jts.geom.Geometry;
|
|
|
+import org.locationtech.jts.geom.MultiPolygon;
|
|
|
+import org.locationtech.jts.geom.Polygon;
|
|
|
+import org.locationtech.jts.io.ParseException;
|
|
|
+import org.locationtech.jts.io.WKTReader;
|
|
|
+import org.opengis.feature.simple.SimpleFeature;
|
|
|
+import org.opengis.feature.simple.SimpleFeatureType;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.*;
|
|
|
+import java.nio.charset.Charset;
|
|
|
+import java.text.DateFormat;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.zip.ZipEntry;
|
|
|
+import java.util.zip.ZipOutputStream;
|
|
|
+
|
|
|
+/**
|
|
|
+ * shp导出工具类
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class WriteShapeUtil {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成shape文件 ,只支持4326坐标系的
|
|
|
+ *
|
|
|
+ * @param shpPath 生成shape文件路径(包含文件名称)
|
|
|
+ * @param encode 编码
|
|
|
+ * // * @param geoms 图幅集合
|
|
|
+ */
|
|
|
+ public static void write2Shape(String shpPath, String fileName, String encode, List<WriteShpVo> exp_shp, WKTReader reader) throws IOException, ParseException {
|
|
|
+ if (exp_shp == null || exp_shp.size() == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (StringUtils.isNull(shpPath)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (StringUtils.isNull(fileName)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //创建shape文件对象
|
|
|
+ File file = new File(shpPath);
|
|
|
+ File fileNameUrl = new File(shpPath + File.separator + fileName);
|
|
|
+ if (!file.exists()) {// 如果目录不存在,创建目录
|
|
|
+ file.mkdirs();
|
|
|
+ fileNameUrl.createNewFile();
|
|
|
+ } else {
|
|
|
+ fileNameUrl.delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Serializable> params = new HashMap<String, Serializable>();
|
|
|
+ params.put(ShapefileDataStoreFactory.URLP.key, fileNameUrl.toURI().toURL());
|
|
|
+ ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
|
|
|
+ //定义图形信息和属性信息
|
|
|
+ SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
|
|
|
+ tb.setCRS(DefaultGeographicCRS.WGS84);
|
|
|
+ tb.setName("shapefile");
|
|
|
+ //判断空间类型,先只支持面,后期再加
|
|
|
+ Geometry geomTypeData = reader.read(exp_shp.get(0).getWkt());
|
|
|
+ if ("Polygon".equals(geomTypeData.getGeometryType())) {
|
|
|
+ tb.add("the_geom", Polygon.class);
|
|
|
+ } else if ("MultiPolygon".equals(geomTypeData.getGeometryType())) {
|
|
|
+ tb.add("the_geom", MultiPolygon.class);
|
|
|
+ }
|
|
|
+ //下面添加属性,暂时不做
|
|
|
+// tb.add("pro_Name", String.class);
|
|
|
+// tb.add("las_Name", String.class);
|
|
|
+ ds.createSchema(tb.buildFeatureType());
|
|
|
+ //设置编码
|
|
|
+ Charset charset = Charset.forName(encode);
|
|
|
+ ds.setCharset(charset);
|
|
|
+ //设置Writer
|
|
|
+ FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
|
|
|
+
|
|
|
+ for (WriteShpVo shp : exp_shp) {
|
|
|
+ SimpleFeature feature = writer.next();
|
|
|
+ Geometry geom = reader.read(shp.getWkt());
|
|
|
+ feature.setAttribute("the_geom", geom);
|
|
|
+// feature.setAttribute("pro_Name", shp.getProjectName());
|
|
|
+// feature.setAttribute("las_Name", shp.getLasname());
|
|
|
+ }
|
|
|
+ System.out.println("保存完成: " + fileNameUrl.getPath());
|
|
|
+ writer.write();
|
|
|
+ writer.close();
|
|
|
+ ds.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 压缩shape文件
|
|
|
+ *
|
|
|
+ * @param shpPath shape文件路径(包含shape文件名称)
|
|
|
+ */
|
|
|
+ public static void zipShapeFile(String shpPath, String zipName) {
|
|
|
+ try {
|
|
|
+ String zipPath = shpPath + File.separator + zipName;
|
|
|
+ File zipFile = new File(zipPath);
|
|
|
+ InputStream input = null;
|
|
|
+ ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
|
|
|
+
|
|
|
+ File[] shpFiles = new File(shpPath).listFiles();
|
|
|
+
|
|
|
+ for (File file : shpFiles) {
|
|
|
+ input = new FileInputStream(file);
|
|
|
+ if (zipName.equals(file.getName())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ zipOut.putNextEntry(new ZipEntry(file.getName()));
|
|
|
+ int temp = 0;
|
|
|
+ while ((temp = input.read()) != -1) {
|
|
|
+ zipOut.write(temp);
|
|
|
+ }
|
|
|
+ input.close();
|
|
|
+ }
|
|
|
+ zipOut.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void zip(String sourceFileName, HttpServletResponse response) throws IOException {
|
|
|
+ ZipOutputStream out = null;
|
|
|
+ BufferedOutputStream bos = null;
|
|
|
+ DateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ try {
|
|
|
+ //将zip以流的形式输出到前台
|
|
|
+ response.setHeader("content-type", "application/octet-stream");
|
|
|
+ response.setCharacterEncoding("utf-8");
|
|
|
+ // 设置浏览器响应头对应的Content-disposition
|
|
|
+ //参数中 testZip 为压缩包文件名,尾部的.zip 为文件后缀
|
|
|
+ response.setHeader("Content-disposition",
|
|
|
+ "attachment;filename=" + java.net.URLEncoder.encode("expProject", "utf-8") + sf.format(new Date()) + ".zip");
|
|
|
+ //创建zip输出流
|
|
|
+ out = new ZipOutputStream(response.getOutputStream());
|
|
|
+ //创建缓冲输出流
|
|
|
+ bos = new BufferedOutputStream(out);
|
|
|
+ File sourceFile = new File(sourceFileName);
|
|
|
+ //调用压缩函数
|
|
|
+ compress(out, bos, sourceFile, sourceFile.getName());
|
|
|
+ out.flush();
|
|
|
+ log.info("压缩完成");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("ZIP压缩异常:" + e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ //关闭流
|
|
|
+ if (null != bos) {
|
|
|
+ bos.close();
|
|
|
+ }
|
|
|
+ if (null != out) {
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+ deleteFile(new File(sourceFileName));
|
|
|
+ log.info("删除生成的文件夹:" + sourceFileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将服务器上生成的目录及文件删除
|
|
|
+ *
|
|
|
+ * @param file
|
|
|
+ */
|
|
|
+ public static void deleteFile(File file) {
|
|
|
+ //判断文件不为null或文件目录存在
|
|
|
+ if (file == null || !file.exists()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //取得这个目录下的所有子文件对象
|
|
|
+ File[] files = file.listFiles();
|
|
|
+ //遍历该目录下的文件对象
|
|
|
+ for (File f : files) {
|
|
|
+ //判断子目录是否存在子目录,如果是文件则删除
|
|
|
+ if (f.isDirectory()) {
|
|
|
+ deleteFile(f);
|
|
|
+ } else {
|
|
|
+ f.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //删除空文件夹 for循环已经把上一层节点的目录清空。
|
|
|
+ file.delete();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void compress(ZipOutputStream out, BufferedOutputStream bos, File sourceFile, String base) {
|
|
|
+ FileInputStream fos = null;
|
|
|
+ BufferedInputStream bis = null;
|
|
|
+ try {
|
|
|
+ //如果路径为目录(文件夹)
|
|
|
+ if (sourceFile.isDirectory()) {
|
|
|
+ //取出文件夹中的文件(或子文件夹)
|
|
|
+ File[] flist = sourceFile.listFiles();
|
|
|
+ if (flist.length == 0) {//如果文件夹为空,则只需在目的地zip文件中写入一个目录进入点
|
|
|
+ out.putNextEntry(new ZipEntry(base + "/"));
|
|
|
+ } else {//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
|
|
|
+ for (int i = 0; i < flist.length; i++) {
|
|
|
+ compress(out, bos, flist[i], base + "/" + flist[i].getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入zip文件中
|
|
|
+ out.putNextEntry(new ZipEntry(base));
|
|
|
+ fos = new FileInputStream(sourceFile);
|
|
|
+ bis = new BufferedInputStream(fos);
|
|
|
+
|
|
|
+ int tag;
|
|
|
+ //将源文件写入到zip文件中
|
|
|
+ while ((tag = bis.read()) != -1) {
|
|
|
+ out.write(tag);
|
|
|
+ }
|
|
|
+
|
|
|
+ bis.close();
|
|
|
+ fos.close();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|