Explorar o código

滨江一本帐导入和下载

liutao hai 11 meses
pai
achega
803ce596b2

BIN=BIN
BJYSYBZ_C/public/img2.png


+ 170 - 0
BJYSYBZ_C/public/部系统界址点格式文档.html

@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<!-- saved from url=(0053)https://govphjg.zjzwfw.gov.cn/webgis/static/help.html -->
+<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    
+    <title>部系统界址点格式文档</title>
+</head>
+<body>
+
+
+<p>
+
+</p><h1 id="Pkl6L" style="font-size:28px;">
+    界址点帮助说明
+</h1>
+
+
+[属性描述]
+<br>
+
+
+格式版本号=
+<br>
+
+
+数据产生单位=
+<br>
+
+
+数据产生日期=
+<br>
+
+
+坐标系=2000国家大地坐标系
+<br>
+
+
+几度分带=
+<br>
+
+
+投影类型=
+<br>
+
+
+计量单位=米
+<br>
+
+
+带号=
+<br>
+
+
+精度=
+<br>
+
+
+转换参数=X平移,Y平移,Z平移,X旋转,Y旋转,Z旋转,尺度参数
+<br>
+
+
+[地块坐标]
+<br>
+
+
+界址点数,地块面积,地块编号,地块名称,记录图形属性(点、线、面),图幅号,地块用途,地类编码,@
+<br>
+
+
+{点号,地块圈号,X坐标,Y坐标
+<br>
+
+
+...
+<br>
+
+
+...
+<br>
+
+
+点号,地块圈号,X坐标,Y坐标}
+<br>
+
+
+界址点数,地块面积,地块编号,地块名称,记录图形属性(点、线、面),图幅号,地块用途,地类编码,@
+<br>
+
+
+{点号,地块圈号,X坐标,Y坐标
+<br>
+
+
+...
+<br>
+
+
+...
+<br>
+
+
+点号,地块圈号,X坐标,Y坐标}
+<br>
+
+
+<h3>注意:</h3>
+<br>
+
+
+所有的逗号分隔符都必须是英文输入法状态下的逗号;地块圈号不能小于零;数据产生日期的格式为:2000-12-12;坐标系为2000国家大地坐标系;投影类型为高斯克吕格或等角多圆锥;几度分带为3或6;带号、精度、转换参数、界址点数、地块面积、地块圈号,X坐标,Y坐标必须为数字型;且不能用该(9999,000,000)方式表示;地块编号、地块名称、记录图形属性(点、线、面)、图幅号、地块用途、地类编码、点号的每项里不能含有“,”
+、“@”符号。
+<br>
+
+
+&nbsp;
+<br>
+
+
+对于地图有扣挖情况的宗地,扣挖出来的地块需要使用不同的圈号来表示。而不另外单独作为一块宗地,否则在上报时会返回地块重叠的错误。
+<br>
+
+
+<h3>示例:</h3>
+
+
+<br>
+
+<div style="background-color: #EFEFEF; margin: 2px; padding: 20px">
+ <pre>    [属性描述]
+    坐标系=2000国家大地坐标系
+    几度分带=3
+    投影类型=高斯克吕格
+    计量单位=米
+    带号=40
+    精度=0.0001
+    转换参数=,,,,,,
+    [地块坐标]
+    9,9.6371,1,体育公园,面,,工业用地,,@
+    J1,1,3334427.2091,40708900.7855
+    J2,1,3334611.3375,40709024.4967
+    J3,1,3334565.3054,40709283.4272
+    J4,1,3334389.8081,40709355.3524
+    J5,1,3334248.8348,40709332.3363
+    J6,1,3334317.8829,40709280.5502
+    J7,1,3334366.7920,40709246.0262
+    J8,1,3334317.8829,40708984.2186
+    J1,1,3334427.2091,40708900.7855    
+     </pre>
+</div>
+
+特别注意,保存界址点的txt文件最后面不要留空行。否则会出现导入错误。
+<br>
+
+
+检查是否有空行的方法:
+<br>
+
+
+打开txt文件,按ctrl+A 看看是不是所有选择到的地方都有字符。如果有选择到的地方没有字符,那就说明那个地方是空行或者空白字符。需要删除这些空行或空白字符。
+<br>
+<br>
+<p>
+   
+	</p><h3>文件编码说明:</h3>
+	用记事打开,另存为,必须为ANSI编码<br>
+<br>
+	<img src="./img2.png">
+	<br>
+    <br>
+
+</body></html>

+ 29 - 1
BJYSYBZ_C/src/views/BjWlydManageView/components/Td.vue

@@ -203,6 +203,10 @@
       <div></div>
 
       <div class="btns">
+          <div class="btn" @click="exportShape">
+          <!-- <img src="@/assets/images/bjybz/file.png" alt="" /> -->
+          <p>导出图形</p>
+        </div>
         <div class="btn" @click="save">
           <img src="@/assets/images/bjybz/save2.png" alt="" />
           <p>保存</p>
@@ -233,7 +237,7 @@
 
 <script>
 import YjsqDetail from './yjsqDetail.vue';
-
+import axios from "axios";
 import { gddwInfo } from '@/utils/gddwInfo.js';
 export default {
   name: 'Td',
@@ -308,6 +312,30 @@ export default {
     yjsqClick() {
       this.$refs.yjsqRef.initShow(this.obj);
     },
+    exportShape() {
+      let urlApi = `/api/ybz-bj/exportOneShape`;
+      let params = {id: this.sumbitObj.dksyh};
+      axios({
+          baseURL: window.ApplicationConfig.baseUrl,
+          url: urlApi,
+          method: "get",
+          params: params,
+          responseType: "blob",
+      }).then(
+          //得到的是一个blob对象
+          (res) => {
+              if (!res || !res.data || res.data.size == 0) {
+                  console.log("导出图形失败!");
+                  return;
+              }
+              const url = window.URL.createObjectURL(res.data);
+              const a = document.createElement("a");
+              a.href = url;
+              a.download = `地块.zip`;
+              a.click();
+          }
+      );
+    },
     sumbit() {
       this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
         confirmButtonText: '确定',

+ 74 - 1
BJYSYBZ_C/src/views/YgxqView/components/FourContent.vue

@@ -117,6 +117,7 @@
               </td>
               <th>
                 <el-button size="medium" type="primary" @click="queryData()" icon="el-icon-search" style="position: absolute;top:2px;right:0px">查询</el-button>
+                
               </th>
             </tr>
           </table>
@@ -229,6 +230,7 @@
               </td>
               <th>
                 <el-button size="medium" type="primary" @click="queryData()" icon="el-icon-search" style="position: absolute;top:2px;right:0px">查询</el-button>
+                <el-button size="medium"  type="primary" @click="importCoordinate()" icon="el-icon-top" style="position: absolute;top:2px;right:110px">导入</el-button>
               </th>
             </tr>
           </table>
@@ -323,6 +325,34 @@
         </el-pagination>
       </div>
     </cart-item>
+    <Modal v-model="isImportCoordinate" title="导入坐标" :footer-hide="true">
+      <Upload
+        :before-upload="handleUpload"
+        style="display: inline-block"
+        accept=".txt,.TXT"
+        action=""
+      >
+        <Button icon="ios-cloud-upload-outline">选择文件</Button>
+      </Upload>
+      <Button
+        type="primary"
+        style="position: absolute; right: 120px"
+        :loading="loadingStatus"
+        @click="uploadTxt"
+      >上传</Button>
+      <Button style="position: absolute; right: 20px" @click="openHelpPage">帮助说明</Button>
+      <div v-if="txtFile !== null" style="color: red">
+        选择的文件: {{ txtFile.name }}
+      </div>
+      <p style="margin-top:8px;font-weight:bold;font-size:16px">提示:如果界址点数量很多,需要等待比较长的时间。</p>
+    </Modal>
+    <Modal
+      v-model="isErrorVisiable"
+      title="提示"
+      :footer-hide="true"
+    >
+      <p v-for="(item, index) in uploadErrorList" :key="index">{{ item }}</p>
+    </Modal>
   </div>
 </template>
 
@@ -375,7 +405,12 @@ export default {
         total: 0
       },
       foldShow: false,
-      nowModel: 'gyyd'
+      nowModel: 'gyyd',
+      txtFile:null,
+      loadingStatus: false,
+      isImportCoordinate: false,
+      uploadErrorList: [],
+      isErrorVisiable: false,
     }
   },
   mounted() {
@@ -408,6 +443,44 @@ export default {
       this.initJyydHZ()
       this.initJyydListData();
     },
+    handleUpload(file) {
+      this.txtFile = file
+      return false
+    },
+    openHelpPage() {
+      window.open('/部系统界址点格式文档.html')
+    },
+    importCoordinate() {
+      this.isImportCoordinate = true
+      this.txtFile = null
+    },
+    async uploadTxt() {
+      if (!this.txtFile) {
+        this.$Message.error('请选择文件!')
+        return
+      }
+      this.loadingStatus = true
+      const formData = new FormData()
+      formData.append('file', this.txtFile)
+      const urlStr = '/api/ybz-bj/uploadTxt'
+      const response = await this.$ajax.post(urlStr, formData, this)
+      if (response.success) {
+        this.isImportCoordinate = false
+        const errorList = response.data.errorList
+        if (!errorList || !errorList.length) {
+          this.$Message.success('上传界址点成功!')
+        } else {
+          this.isErrorVisiable = true
+          this.uploadErrorList = errorList
+        }
+        this.queryData();
+      } else {
+        this.isErrorVisiable = true
+        this.uploadErrorList = [response.message]
+      }
+      this.loadingStatus = false
+      return false
+    },
     queryData() {
       if (this.nowModel === 'gyyd') {
         this.$vm.$emit("setVisibleLayerIdEvent", 'bj-gyyd-new')

+ 10 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/dao/BjlsydMapper.java

@@ -0,0 +1,10 @@
+package com.zjugis.ysgzybz.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zjugis.ysgzybz.domain.entity.Bjlsyd;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface BjlsydMapper extends BaseMapper<Bjlsyd> {
+    void updateGeometry(String geometry, Float id);
+}

+ 40 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/domain/entity/Bjlsyd.java

@@ -0,0 +1,40 @@
+package com.zjugis.ysgzybz.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@TableName(value = "sde.bjlsyd")
+public class Bjlsyd {
+    private Float id;
+
+    private String shape;
+
+    private Float objectid;
+
+    private String xh;
+
+    private String jsdw;
+
+    private String jsdz;
+
+    private Double spmj;
+
+    private String fzsj;
+
+    private String lxr;
+
+    private String lxfs;
+
+    private String dqsj;
+
+    private Float xh1;
+
+    private String xmmc;
+
+
+}

+ 9 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/domain/entity/UploadTxtResultVO.java

@@ -0,0 +1,9 @@
+package com.zjugis.ysgzybz.domain.entity;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class UploadTxtResultVO {
+    private List<String> errorList;
+}

+ 267 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/ShapeUtil.java

@@ -0,0 +1,267 @@
+package com.zjugis.ysgzybz.utils;
+
+import com.vividsolutions.jts.geom.*;
+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;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ShapeUtil {
+
+    /**
+     * 生成shape文件
+     *
+     * @param shpPath 生成shape文件路径(包含文件名称)
+     * @param encode  编码
+     * @param geoType 图幅类型,Point和Rolygon
+     * @param geoms   图幅集合
+     */
+    public static void write2Shape(String shpPath, String encode, String geoType, List<Geometry> geoms) {
+        try {
+            //创建shape文件对象
+            File file = new File(shpPath);
+            Map<String, Serializable> params = new HashMap<>();
+            params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
+            ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
+            //定义图形信息和属性信息
+            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+            /**
+             *  //方式一
+             *	CRS.decode("EPSG:4326");
+             *  //方式二
+             *	DefaultGeographicCRS.WGS84;
+             *
+             *  EPSG:4490为大地坐标系_国家2000大地坐标系CGCS2000
+             *  EPSG:4326支持一种默认的定义方式, 坐标系WGS84
+             */
+            tb.setCRS(CRS.decode("EPSG:4490"));
+
+            tb.setName("shapefile");
+
+            if ("Polygon".equals(geoType) || "polygon".equals(geoType)) {
+                tb.add("the_geom", Polygon.class);
+            } else if ("MultiPolygon".equals(geoType)) {
+                tb.add("the_geom", MultiPolygon.class);
+            } else if ("Point".equals(geoType) || "point".equals(geoType)) {
+                tb.add("the_geom", Point.class);
+            } else if ("MultiPoint".equals(geoType)) {
+                tb.add("the_geom", MultiPoint.class);
+            } else if ("LineString".equals(geoType)) {
+                tb.add("the_geom", LineString.class);
+            } else if ("MultiLineString".equals(geoType) || "Polyline".equals(geoType) || "polyline".equals(geoType)) {
+                tb.add("the_geom", MultiLineString.class);
+            } else {
+                throw new Exception("Geometry中没有该类型:" + geoType);
+            }
+
+            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 (Geometry geom : geoms) {
+                //String type = geom.getGeometryType();
+
+                //写下一条
+                SimpleFeature feature = writer.next();
+
+                feature.setAttribute("the_geom", geom);
+            }
+            writer.write();
+            writer.close();
+            ds.dispose();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 生成shape文件
+     *
+     * @param shpPath  生成shape文件路径(包含文件名称)
+     * @param encode   编码
+     * @param geoType  图幅类型,Point和Rolygon
+     * @param shpKey   data中图幅的key
+     * @param attrKeys 属性key集合
+     * @param data     图幅和属性集合
+     */
+    public static void write2Shape(String shpPath, String encode, String geoType, String shpKey, List<String> attrKeys, List<Map<String, Object>> data) {
+        try {
+            if (data == null || data.size() == 0) {
+                return;
+            }
+            //创建shape文件对象
+            File file = new File(shpPath);
+            Map<String, Serializable> params = new HashMap<>();
+            params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
+            ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
+
+            //定义图形信息和属性信息
+            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+            CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
+            CoordinateReferenceSystem sourceCRS = factory.createCoordinateReferenceSystem(String.format("EPSG:%d", 4490));
+            tb.setCRS(sourceCRS);
+            tb.setName("shapefile");
+
+            if ("Polygon".equals(geoType)) {
+                tb.add("the_geom", Polygon.class);
+            } else if ("MultiPolygon".equals(geoType)) {
+                tb.add("the_geom", MultiPolygon.class);
+            } else if ("Point".equals(geoType)) {
+                tb.add("the_geom", Point.class);
+            } else if ("MultiPoint".equals(geoType)) {
+                tb.add("the_geom", MultiPoint.class);
+            } else if ("LineString".equals(geoType)) {
+                tb.add("the_geom", LineString.class);
+            } else if ("MultiLineString".equals(geoType)) {
+                tb.add("the_geom", MultiLineString.class);
+            } else {
+                throw new Exception("Geometry中没有该类型:" + geoType);
+            }
+
+            String[] excludeKeyGroup = {"SHAPE", "GEOMETRY"};
+            HashSet<String> excludeSet = new HashSet<>(Arrays.asList(excludeKeyGroup));
+            for (String field : attrKeys) {
+                String fieldName = field.toUpperCase();
+                if (excludeSet.contains(fieldName)) {
+                    continue;
+                }
+                tb.add(fieldName, 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 (int i = 0; i < data.size(); i++) {
+                SimpleFeature feature = writer.next();
+                Map<String, Object> row = data.get(i);
+                Geometry geom = (Geometry) row.get(shpKey);
+                feature.setAttribute("the_geom", geom);
+                for (String key : row.keySet()) {
+                    if (key.equals(shpKey)) {
+                        continue;
+                    }
+                    String transformKey = key.toUpperCase();
+                    if (excludeSet.contains(transformKey)) {
+                        continue;
+                    }
+
+                    if (row.get(key) == null) {
+                        continue;
+                    }
+                    String s = row.get(key).toString();
+                    if (transformKey.length() > 10) {
+                        transformKey = transformKey.substring(0, 10);
+                    }
+                    if (!attrKeys.contains(transformKey)) {
+                        continue;
+                    }
+                    feature.setAttribute(transformKey, s);
+                }
+            }
+            writer.write();
+            writer.close();
+            ds.dispose();
+
+            //添加到压缩文件geotoogeo
+            //zipShapeFile(shpPath);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static String getEncoding(String str) {
+        String encode = "GB2312";
+        try {
+            if (str.equals(new String(str.getBytes(encode), encode))) {      //判断是不是GB2312
+                String s = encode;
+                return s;      //是的话,返回“GB2312“,以下代码同理
+            }
+        } catch (Exception exception) {
+        }
+        encode = "ISO-8859-1";
+        try {
+            if (str.equals(new String(str.getBytes(encode), encode))) {      //判断是不是ISO-8859-1
+                String s1 = encode;
+                return s1;
+            }
+        } catch (Exception exception1) {
+        }
+        encode = "UTF-8";
+        try {
+            if (str.equals(new String(str.getBytes(encode), encode))) {   //判断是不是UTF-8
+                String s2 = encode;
+                return s2;
+            }
+        } catch (Exception exception2) {
+        }
+        encode = "GBK";
+        try {
+            if (str.equals(new String(str.getBytes(encode), encode))) {      //判断是不是GBK
+                String s3 = encode;
+                return s3;
+            }
+        } catch (Exception exception3) {
+        }
+        return "";        //如果都不是,说明输入的内容不属于常见的编码格式。
+    }
+
+    /**
+     * 压缩shape文件
+     *
+     * @param shpPath shape文件路径(包含shape文件名称)
+     */
+    public static void zipShapeFile(String shpPath) {
+        try {
+            File shpFile = new File(shpPath);
+            String shpRoot = shpFile.getParentFile().getPath();
+            String shpName = shpFile.getName().substring(0, shpFile.getName().lastIndexOf("."));
+
+            String zipPath = shpRoot + File.separator + shpName + ".zip";
+            File zipFile = new File(zipPath);
+            InputStream input = null;
+            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
+            // zip的名称为
+            zipOut.setComment(shpName);
+            String[] shpFiles = new String[]{
+                    shpRoot + File.separator + shpName + ".dbf",
+                    shpRoot + File.separator + shpName + ".prj",
+                    shpRoot + File.separator + shpName + ".shp",
+                    shpRoot + File.separator + shpName + ".shx",
+                    shpRoot + File.separator + shpName + ".fix"
+            };
+
+            for (int i = 0; i < shpFiles.length; i++) {
+                File file = new File(shpFiles[i]);
+                input = new FileInputStream(file);
+                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();
+        }
+    }
+}

+ 28 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/geocomm/GisConstant.java

@@ -0,0 +1,28 @@
+package com.zjugis.ysgzybz.utils.geocomm;
+
+public class GisConstant {
+
+    public final static String FILE_HEAD = "[地块坐标]";
+    public final static String FILE_AT = "@";
+    public final static String FILE_ATTRIBUTE = "[属性描述]";
+    public final static String ZBX = "坐标系";
+    public final static String JDFD = "几度分带";
+    public final static String TYLX = "投影类型";
+    public final static String JLDW = "计量单位";
+    public final static String DH = "带号";
+
+    public final static String JD = "精度";
+    public final static String ZHCS = "转换参数";
+
+    public final static String EQUAL = "=";
+
+    public final static String CGCS2000 = "2000国家大地坐标系";
+
+    public final static String ZHCS_NONE = ",,,,,,";
+
+    public final static String EMPTY = "";
+
+    public final static String COMMA = ",";
+
+
+}

+ 29 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/geocomm/JzdDk.java

@@ -0,0 +1,29 @@
+package com.zjugis.ysgzybz.utils.geocomm;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.vividsolutions.jts.geom.Geometry;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class JzdDk {
+    private String id;
+    private String jzdsxGuid;
+    private String zdGuid;
+    private String dkbh;
+    private String dkmc;
+    private Integer jzds;
+    /**
+     * 地块面积 单位:公顷
+     */
+    private Double dkmj;
+    private String dkyt;
+    private String tfh;
+    private Date createDate;
+    private Date updateDate;
+
+    private Geometry geometry;
+
+}

+ 25 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/geocomm/JzdSx.java

@@ -0,0 +1,25 @@
+package com.zjugis.ysgzybz.utils.geocomm;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class JzdSx {
+    private String id;
+    private String zbGuid;
+    private String zdGuid;
+    private String zbx;
+    private String tylx;
+
+    private String jdfd;
+    private String dh;
+    private String jldw;
+    private Double jd;
+    private Integer xzqdm;
+
+    private Date createDate;
+    private Date updateDate;
+
+}

+ 27 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/geocomm/JzdZb.java

@@ -0,0 +1,27 @@
+package com.zjugis.ysgzybz.utils.geocomm;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class JzdZb {
+    private String id;
+    private String jzdsxGuid;
+    private String zdGuid;
+    private String jzdGuid;
+    private String dkbh;
+    private String jzdh;
+
+    private String qh;
+    private Double xzb;
+    private Double yzb;
+
+    //反算边长
+    private Double fsbc;
+    private Integer jzdorder;
+    private Date createDate;
+    private Date update_date;
+
+}

+ 39 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/geocomm/ParseResult.java

@@ -0,0 +1,39 @@
+package com.zjugis.ysgzybz.utils.geocomm;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class ParseResult {
+    private Geometry geometry;
+    private JzdSx jzdSx;
+    private List<JzdDk> jzdDkList;
+    private List<JzdZb> jzdZbList;
+
+    private List<String> errorList = new ArrayList<>();
+
+    public void setZdGuid(String zdGuid) {
+        if (null == zdGuid) {
+            return;
+        }
+        if (jzdSx != null) {
+            jzdSx.setZdGuid(zdGuid);
+        }
+        if (jzdDkList != null && jzdDkList.size() > 0) {
+            for (JzdDk jzdDk : jzdDkList) {
+                jzdDk.setZdGuid(zdGuid);
+            }
+        }
+        if (jzdZbList != null && jzdZbList.size() > 0) {
+            for (JzdZb jzdZb : jzdZbList) {
+                jzdZb.setZdGuid(zdGuid);
+            }
+        }
+    }
+
+
+}

+ 344 - 0
BJYSYBZ_S/src/main/java/com/zjugis/ysgzybz/utils/geocomm/TxtReader.java

@@ -0,0 +1,344 @@
+package com.zjugis.ysgzybz.utils.geocomm;
+
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.operation.IsSimpleOp;
+
+import com.zjugis.ysgzybz.utils.GisUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+
+import java.io.*;
+import java.util.*;
+
+public class TxtReader {
+
+    private GeometryFactory geometryFactory;
+    private BufferedReader reader;
+
+    private ParseResult parseResult;
+
+    public final static double AERA_MISTAKE = 0.01;
+
+    public TxtReader(File file) throws Exception {
+        this(new BufferedReader(new InputStreamReader(new FileInputStream(file), "gbk")));
+    }
+
+    public TxtReader(InputStream inputStream) throws Exception {
+        this(new BufferedReader(new InputStreamReader(inputStream, "gbk")));
+    }
+
+    public TxtReader(BufferedReader reader) {
+        this.reader = reader;
+        geometryFactory = JTSFactoryFinder.getGeometryFactory();
+    }
+
+    /**
+     * 将 1,1,3339023.0372,40513893.3519解析为(3339023.0372,40513893.3519)
+     *
+     * @param line
+     * @return
+     * @throws Exception
+     */
+    private Coordinate getCoordinate(String line) throws Exception {
+        String[] split = line.split(",");
+        if (split.length != 4) {
+            throw new ParseException("文件格式错误!");
+        }
+        double y = Double.parseDouble(split[2]);
+        double x = Double.parseDouble(split[3]);
+        Coordinate coordinate = new Coordinate(x, y);
+
+        return coordinate;
+    }
+
+    /**
+     * 读取一个LinearRing
+     *
+     * @param lineList
+     * @return
+     * @throws Exception
+     */
+    private LinearRing getLinearRing(List<String> lineList) throws Exception {
+        List<Coordinate> coordinateList = new ArrayList<>();
+        for (String s : lineList) {
+            Coordinate coordinate = getCoordinate(s);
+            coordinateList.add(coordinate);
+        }
+        return geometryFactory.createLinearRing(coordinateList.toArray(new Coordinate[coordinateList.size()]));
+    }
+
+    /**
+     * 读取一个Polygon
+     *
+     * @param lineList
+     * @return
+     * @throws Exception
+     */
+    private Polygon getPolygon(List<String> lineList) throws Exception {
+        Map<String, List<String>> map = new HashMap<>();
+        for (String s : lineList) {
+            String[] split = s.split(",");
+            String qh = split[1];
+            if (!map.containsKey(qh)) {
+                map.put(qh, new ArrayList<>());
+            }
+            map.get(qh).add(s);
+        }
+        List<String> shellList = map.get("1");
+        LinearRing shell = getLinearRing(shellList);
+
+        List<LinearRing> holes = new ArrayList<>();
+        for (String s : map.keySet()) {
+            if (!"1".equals(s)) {
+                List<String> list = map.get(s);
+                LinearRing linearRing = getLinearRing(list);
+                holes.add(linearRing);
+            }
+        }
+
+        return geometryFactory.createPolygon(shell, holes.toArray(new LinearRing[holes.size()]));
+    }
+
+    /**
+     * 读取MultiPolygon
+     *
+     * @return
+     * @throws Exception
+     */
+    private MultiPolygon getMultiPolygon() throws Exception {
+        List<JzdDk> jzdDkList = new ArrayList<>();
+        List<JzdZb> jzdZbList = new ArrayList<>();
+        parseResult.setJzdDkList(jzdDkList);
+        parseResult.setJzdZbList(jzdZbList);
+        String s = reader.readLine();
+        List<String> lineList = null;
+        List<Polygon> polygonList = new ArrayList<>();
+        while (s != null) {
+            if (s.endsWith(GisConstant.FILE_AT)) {
+                JzdDk jzdDk = getJzdDk(s);
+
+                validateJzdDk(jzdDk);
+                double dkmj = jzdDk.getDkmj();
+                String dkbh = jzdDk.getDkbh();
+                jzdDkList.add(jzdDk);
+                lineList = new ArrayList<>();
+                s = reader.readLine();
+                int order = 1;
+                JzdZb preJzdZb = null;
+                while (s != null && !s.endsWith(GisConstant.FILE_AT)) {
+                    lineList.add(s);
+                    JzdZb jzdZb = getJzdZb(s, jzdDk, order++, preJzdZb);
+                    jzdZbList.add(jzdZb);
+                    s = reader.readLine();
+                    preJzdZb = jzdZb;
+                }
+                if (lineList.size() > 0) {
+                    Polygon polygon = getPolygon(lineList);
+                    polygonList.add(polygon);
+                    MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[]{polygon});
+                    double area = multiPolygon.getArea() / 10000;
+
+                    if (dkmj - area > 1e-4) {
+                        String formatErrorMsg = String.format("地块编号:【%s】填写的地块面积:【%.4f】实际面积:【%.4f】,误差大于0", dkbh, dkmj, area);
+                        parseResult.getErrorList().add(formatErrorMsg);
+                    }
+
+                    jzdDk.setGeometry(multiPolygon);
+                }
+            }
+        }
+
+        return geometryFactory.createMultiPolygon(polygonList.toArray(new Polygon[polygonList.size()]));
+    }
+
+    /**
+     * 就仅校验一个
+     *
+     * @param dk
+     */
+    private void validateJzdDk(JzdDk dk) throws ParseException {
+        if (dk.getJzds() == 0) {
+            throw new ParseException("界址点数必须大于0");
+        }
+        if (dk.getDkmj() == 0) {
+            throw new ParseException("地块面积必须大于0");
+        }
+        if (StringUtils.isEmpty(dk.getDkbh())) {
+            throw new ParseException("地块编号不能为空");
+        }
+        if (StringUtils.isEmpty(dk.getDkmc())) {
+            throw new ParseException("地块名称不能为空");
+        }
+    }
+
+    /**
+     * 将11,0,1,杭州地铁4号线浦沿站(二期),,,,,@解析为JzdDk
+     *
+     * @param line
+     * @return
+     */
+    private JzdDk getJzdDk(String line) {
+        JzdDk jzddk = new JzdDk();
+        jzddk.setId(UUID.randomUUID().toString());
+        jzddk.setJzdsxGuid(UUID.randomUUID().toString());
+//        界址点数,地块面积,地块编号,地块名称,记录图形属性(点、线、面),图幅号,地块用途,地类编码,@
+//        66,1.5397,1,浦乐单元BJ0704-M1-08地块(原浦乐单元M1-29地块),面,,,,@
+        String[] group = line.split(",");
+        jzddk.setJzds(Integer.parseInt(group[0]));
+        jzddk.setDkmj(Double.parseDouble(group[1]));
+        jzddk.setDkbh(group[2]);//报提示
+        jzddk.setDkmc(group[3]);//报提示
+        jzddk.setTfh(group[5]);
+        jzddk.setDkyt(group[6]);
+        jzddk.setCreateDate(new Date());
+        jzddk.setUpdateDate(new Date());
+        return jzddk;
+    }
+
+    /**
+     * 将1,1,3339023.0372,40513893.3519解析为JzdZb
+     *
+     * @param line
+     * @param jzdDk
+     * @param order
+     * @param preJzdzb
+     * @return
+     */
+    private JzdZb getJzdZb(String line, JzdDk jzdDk, int order, JzdZb preJzdzb) {
+        JzdZb jzdzb = new JzdZb();
+        jzdzb.setId(UUID.randomUUID().toString());
+        jzdzb.setJzdGuid(UUID.randomUUID().toString());
+        String[] split = line.split(",");
+        double y = Double.parseDouble(split[2]);
+        double x = Double.parseDouble(split[3]);
+        jzdzb.setXzb(x);
+        jzdzb.setYzb(y);
+        jzdzb.setQh(split[1]);
+        String jzdh = split[0];
+        if (jzdh.startsWith("J")) {
+            jzdh = jzdh.substring(1);
+        }
+        jzdzb.setJzdh(jzdh);
+        jzdzb.setJzdsxGuid(jzdDk.getJzdsxGuid());
+        jzdzb.setDkbh(jzdDk.getDkbh());
+        jzdzb.setJzdorder(order);
+
+        //反算边长
+        if (preJzdzb != null) {
+            double xzb = preJzdzb.getXzb();
+            double yzb = preJzdzb.getYzb();
+            jzdzb.setFsbc(GisUtils.calculateDistance(xzb, yzb, jzdzb.getXzb(), jzdzb.getYzb()));
+        }
+        jzdzb.setCreateDate(new Date());
+        jzdzb.setUpdate_date(new Date());
+        return jzdzb;
+    }
+
+    /**
+     * 根据文件头解析地块属性信息
+     *
+     * @param map
+     * @return
+     */
+    private JzdSx getJzdsx(Map<String, String> map) {
+        JzdSx jzdsx = new JzdSx();
+        jzdsx.setId(UUID.randomUUID().toString());
+        jzdsx.setZbGuid(UUID.randomUUID().toString());
+        if (map.containsKey(GisConstant.ZBX)) {
+            jzdsx.setZbx(map.get(GisConstant.ZBX));
+        }
+        if (map.containsKey(GisConstant.JDFD)) {
+            jzdsx.setJdfd(map.get(GisConstant.JDFD));
+        }
+        if (map.containsKey(GisConstant.TYLX)) {
+            jzdsx.setTylx(map.get(GisConstant.TYLX));
+        }
+        if (map.containsKey(GisConstant.JLDW)) {
+            jzdsx.setJldw(map.get(GisConstant.JLDW));
+        }
+        if (map.containsKey(GisConstant.DH)) {
+            jzdsx.setDh(map.get(GisConstant.DH));
+        }
+        if (map.containsKey(GisConstant.JD)) {
+            double jd = Double.parseDouble(map.get(GisConstant.JD));
+            jzdsx.setJd(jd);
+        }
+        jzdsx.setCreateDate(new Date());
+        jzdsx.setUpdateDate(new Date());
+        return jzdsx;
+    }
+
+    /**
+     * 入口
+     *
+     * @return
+     * @throws Exception
+     */
+    public ParseResult read() throws Exception {
+        parseResult = new ParseResult();
+        //读取到[地块坐标]这一行
+        String s = reader.readLine();
+
+        if (!GisConstant.FILE_ATTRIBUTE.equals(s)) {
+            throw new ParseException("请确认文件编码是否为ANSI格式,请查看帮助文档!");
+        }
+
+        Map<String, String> sxMap = new HashMap<>();
+        while (s != null && !GisConstant.FILE_HEAD.equals(s)) {
+            String[] propGroup = s.split(GisConstant.EQUAL);
+            if (propGroup.length == 2 && !sxMap.containsKey(propGroup[0])) {
+                sxMap.put(propGroup[0], propGroup[1]);
+            }
+            s = reader.readLine();
+        }
+        JzdSx jzdsx = getJzdsx(sxMap);
+        if (!GisConstant.CGCS2000.equals(jzdsx.getZbx())) {
+            throw new ParseException("坐标系必须为2000国家大地坐标系,请查看帮助文档!");
+        }
+
+        parseResult.setJzdSx(jzdsx);
+        MultiPolygon multiPolygon = getMultiPolygon();
+        if (!multiPolygon.isValid()) {
+//            parseResult.getErrorList().add("图形存在拓扑错误");
+            throw new ParseException("图形存在拓扑错误");
+        }
+        IsSimpleOp isSimple = new IsSimpleOp(multiPolygon);
+
+        // 如果geometry自相交,isSimple.isSimple()将返回false
+        if (!isSimple.isSimple()) {
+//            parseResult.getErrorList().add("图形自相交");
+            throw new ParseException("图形自相交");
+        }
+        parseResult.setGeometry(multiPolygon);
+        return parseResult;
+    }
+
+    /**
+     * dkmj和geometry的面积误差超过1%,则视为不合法
+     *
+     * @param dkmj
+     * @param geometry
+     * @return
+     */
+    private boolean validDkmj(double dkmj, Geometry geometry) {
+        double area = geometry.getArea();
+        return Math.abs((area - dkmj * 10000) / area) < TxtReader.AERA_MISTAKE;
+    }
+
+//    public static void main(String[] args) throws Exception {
+//        String filePath = "D:\\Users\\Desktop\\杭州地铁.txt";
+//        //校验坐标系
+//
+//        TxtReader parseTxtExtend = new TxtReader(new File(filePath));
+//        ParseResult result = parseTxtExtend.read();
+////        System.out.println(result.getJzdSx());
+////        System.out.println(result.getJzdDkList());
+////        System.out.println(result.getJzdZbList());
+//
+//        TxtWriter writer = new TxtWriter();
+//        String writer1 = writer.writer(result);
+//        System.out.println(writer1);
+//    }
+
+}

+ 10 - 0
BJYSYBZ_S/src/main/resources/mapper/BjlsydMapper.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zjugis.ysgzybz.dao.BjlsydMapper">
+
+    <update id="updateGeometry">
+        update sde.bjlsyd
+        set shape = st_transform(st_geomfromtext(#{geometry}, 4528), 4490)
+        where id = #{id}
+    </update>
+</mapper>