From 660021a28de9b84b4362c171fdbbf89587f0c5af Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期四, 13 二月 2025 17:30:50 +0800
Subject: [PATCH] 1. 修改部分bug 2. 新增2D路线轨迹绘制

---
 test/grid_test_data.js                              |  112 ++++++++++++
 src/components/mission/MissionEdit.vue              |   43 +++-
 src/views/historymode/HistoryMode.vue               |    8 
 src/views/satellitetelemetry/SatelliteTelemetry.vue |   40 ++++
 src/utils/map/grid.js                               |   52 +++++
 src/api/missionApi.js                               |    4 
 src/components.d.ts                                 |    2 
 src/components/mission/MissionManage.vue            |   27 +-
 src/utils/map/calculate.js                          |   19 ++
 src/views/HomePage.vue                              |    5 
 src/utils/map/marks.js                              |    2 
 src/components/monitor/DataTable.vue                |    2 
 src/utils/color.js                                  |   30 +++
 src/stores/mission.js                               |    2 
 src/utils/map/line.js                               |   44 ++++
 src/constant/checkbox-options.js                    |    5 
 src/constant/checkbox-options/options.js            |   91 ++++++++++
 17 files changed, 457 insertions(+), 31 deletions(-)

diff --git a/src/api/missionApi.js b/src/api/missionApi.js
index d33ebf0..5d881ba 100644
--- a/src/api/missionApi.js
+++ b/src/api/missionApi.js
@@ -15,6 +15,10 @@
     return $http.post(`air/mission/create`, mission).then((res) => res.data);
   },
 
+  updateMission(mission) {
+    return $http.post(`air/mission/update`, mission).then((res) => res.data);
+  },
+
   deleteMission(missionCode) {
     let params = `missionCode=${missionCode}`;
     return $http.post(`air/mission/delete?${params}`).then((res) => res.data);
diff --git a/src/components.d.ts b/src/components.d.ts
index 11c6829..bdf25d1 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -56,7 +56,7 @@
     MapScene: typeof import('./components/map/MapScene.vue')['default']
     MapToolbox: typeof import('./components/map/MapToolbox.vue')['default']
     MessageBox: typeof import('./components/MessageBox.vue')['default']
-    MissionCreate: typeof import('./components/mission/MissionCreate.vue')['default']
+    MissionEdit: typeof import('./components/mission/MissionEdit.vue')['default']
     MissionImport: typeof import('./components/mission/MissionImport.vue')['default']
     MissionManage: typeof import('./components/mission/MissionManage.vue')['default']
     OptionDevice: typeof import('./components/search/OptionDevice.vue')['default']
diff --git a/src/components/mission/MIssionCreate.vue b/src/components/mission/MissionEdit.vue
similarity index 86%
rename from src/components/mission/MIssionCreate.vue
rename to src/components/mission/MissionEdit.vue
index c7d00f8..c8695b7 100644
--- a/src/components/mission/MIssionCreate.vue
+++ b/src/components/mission/MissionEdit.vue
@@ -1,12 +1,5 @@
 <template>
-  <el-button
-    type="primary"
-    class="el-button-custom"
-    @click="dialogVisible = !dialogVisible"
-  >
-    鏂板缓浠诲姟
-  </el-button>
-  <CardDialog v-model="dialogVisible" title="鏂板缓璧拌埅浠诲姟">
+  <CardDialog v-model="visible" title="鏂板缓璧拌埅浠诲姟">
     <el-form
       :inline="false"
       :model="formObj"
@@ -50,6 +43,22 @@
       </el-form-item>
     </el-form>
   </CardDialog>
+  <el-button
+    v-if="mode == 'create'"
+    type="primary"
+    class="el-button-custom"
+    @click="visible = !visible"
+  >
+    鏂板缓浠诲姟
+  </el-button>
+  <el-button
+    v-else
+    type="primary"
+    size="small"
+    icon="EditPen"
+    class="el-button-custom"
+    @click="visible = !visible"
+  ></el-button>
 </template>
 <script setup>
 import moment from 'moment';
@@ -60,8 +69,20 @@
 import { useFetchData } from '@/composables/fetchData';
 import { useMissionStore } from '@/stores/mission';
 
+const props = defineProps({
+  // 璧拌埅浠诲姟缂栬緫妯″紡锛屾柊寤烘垨鏇存柊
+  mode: {
+    type: String,
+    default: 'create'
+  }
+  // visible: {
+  //   type: String,
+  //   default: 'create'
+  // }
+});
+
 const missionStore = useMissionStore();
-const dialogVisible = ref(false);
+const visible = ref(false);
 const { loading, fetchData } = useFetchData();
 const rules = reactive({
   location: [
@@ -113,7 +134,7 @@
 function createMission() {
   fetchData((page, pageSize) => {
     return missionApi.putNewMission(param.value).then((res) => {
-      dialogVisible.value = false;
+      visible.value = false;
       missionStore.fetchMission();
       // 閫氱煡鏈嶅姟绔惎鍔ㄤ换鍔¤寖鍥村唴鐨勭涓夋柟鏁版嵁鑾峰彇浠诲姟
       thirdPartyDataApi.fetchMissionData(param.value.missionCode);
@@ -126,7 +147,7 @@
   },
   cancel: {
     do: () => {
-      dialogVisible.value = false;
+      visible.value = false;
     }
   }
 });
diff --git a/src/components/mission/MissionManage.vue b/src/components/mission/MissionManage.vue
index a385a6e..5695155 100644
--- a/src/components/mission/MissionManage.vue
+++ b/src/components/mission/MissionManage.vue
@@ -21,7 +21,7 @@
           :show-overflow-tooltip="true"
           border
           height="64vh"
-          row-class-name="t-row"
+          row-class-name="t-row-normal"
           cell-class-name="t-cell"
           header-row-class-name="t-header-row"
           header-cell-class-name="t-header-cell"
@@ -38,41 +38,44 @@
             label="寮�濮嬫椂闂�"
             align="center"
             :formatter="timeFormatter"
+            width="150"
           />
           <el-table-column
             prop="endTime"
             label="缁撴潫鏃堕棿"
             align="center"
             :formatter="timeFormatter"
+            width="150"
           />
-          <el-table-column label="绠$悊" width="140" align="center">
+          <el-table-column label="绠$悊" width="160" align="center">
             <template #default="{ row }">
+              <MissionEdit mode="update"></MissionEdit>
               <el-button
                 type="primary"
                 size="small"
+                icon="Delete"
                 class="el-button-custom"
                 @click="deleteMission(row)"
-                >鍒犻櫎</el-button
-              >
+              ></el-button>
               <el-button
                 :loading="row.downloadLoading"
                 type="primary"
                 size="small"
+                icon="Document"
                 class="el-button-custom"
                 @click="downloadReport(row)"
-                >鎶ュ憡</el-button
-              >
+              ></el-button>
             </template>
           </el-table-column>
         </el-table>
       </el-col>
       <el-col :span="4" class="flex-col">
-        <div>
-          <!-- <el-button type="primary" class="el-button-custom">
+        <!-- <div> -->
+        <!-- <el-button type="primary" class="el-button-custom">
                 鏂板缓浠诲姟
               </el-button> -->
-          <MissionCreate></MissionCreate>
-        </div>
+        <MissionEdit></MissionEdit>
+        <!-- </div> -->
         <!-- <div>
           <el-button type="primary" class="el-button-custom">
             鏁版嵁瀵煎叆
@@ -166,4 +169,8 @@
 .mission-table {
   /* height: 60vh; */
 }
+
+:deep(.t-row-normal) {
+  background-color: transparent !important;
+}
 </style>
diff --git a/src/components/monitor/DataTable.vue b/src/components/monitor/DataTable.vue
index 6579e51..c918ade 100644
--- a/src/components/monitor/DataTable.vue
+++ b/src/components/monitor/DataTable.vue
@@ -177,7 +177,7 @@
     //   }
     // },
     tableColumn() {
-      return checkboxOptions(this.deviceType);
+      return checkboxOptions(this.deviceType, true);
     }
   },
   methods: {
diff --git a/src/constant/checkbox-options.js b/src/constant/checkbox-options.js
index fa3108d..e3d5327 100644
--- a/src/constant/checkbox-options.js
+++ b/src/constant/checkbox-options.js
@@ -1,6 +1,7 @@
 import { TYPE0, TYPE1, TYPE2, TYPE4 } from '@/constant/device-type';
 import {
   option1,
+  option1All,
   default1,
   option2,
   option3,
@@ -13,7 +14,7 @@
 } from '@/constant/checkbox-options/options-jingan';
 
 // 鐩戞祴鍥犲瓙鍗曢�夋閫夐」
-function checkboxOptions(deviceType) {
+function checkboxOptions(deviceType, allOptions) {
   if (import.meta.env.VITE_DATA_MODE == 'jingan') {
     switch (deviceType) {
       case TYPE0:
@@ -24,7 +25,7 @@
   } else {
     switch (deviceType) {
       case TYPE0:
-        return option1;
+        return allOptions ? option1All : option1;
       case TYPE1:
         return option3;
       case TYPE2:
diff --git a/src/constant/checkbox-options/options.js b/src/constant/checkbox-options/options.js
index f41fac0..9bfd565 100644
--- a/src/constant/checkbox-options/options.js
+++ b/src/constant/checkbox-options/options.js
@@ -71,6 +71,95 @@
   // }
 ];
 
+const option1All = [
+  {
+    label: 'NO2',
+    name: 'NO2',
+    value: '1'
+  },
+  {
+    label: 'CO',
+    name: 'CO',
+    value: '2'
+  },
+  {
+    label: 'H2S',
+    name: 'H2S',
+    value: '3'
+  },
+  {
+    label: 'SO2',
+    name: 'SO2',
+    value: '4'
+  },
+  {
+    label: 'O3',
+    name: 'O3',
+    value: '5'
+  },
+  {
+    label: 'PM2.5',
+    name: 'PM25',
+    value: '6'
+  },
+  {
+    label: 'PM10',
+    name: 'PM10',
+    value: '7'
+  },
+  {
+    label: '娓╁害',
+    name: 'TEMPERATURE',
+    value: '8'
+  },
+  {
+    label: '婀垮害',
+    name: 'HUMIDITY',
+    value: '9'
+  },
+  {
+    label: 'TVOC',
+    name: 'VOC',
+    value: '10'
+  },
+
+  // {
+  //     label: "NOI",
+  //     name: "NOI",
+  //     value: "11"
+  // },
+  {
+    label: '缁忓害',
+    name: 'LNG',
+    value: '12'
+  },
+  {
+    label: '绾害',
+    name: 'LAT',
+    value: '13'
+  },
+  {
+    label: '杞﹂��',
+    name: 'VELOCITY',
+    value: '14'
+  },
+  {
+    label: '椋庨��',
+    name: 'WIND_SPEED',
+    value: '16'
+  },
+  {
+    label: '椋庡悜',
+    name: 'WIND_DIRECTION',
+    value: '17'
+  }
+  // {
+  //   label: '楂樺害',
+  //   name: 'HEIGHT',
+  //   value: '18'
+  // }
+];
+
 // 榛樿閫夐」
 const default1 = [option1[5].value, option1[6].value, option1[7].value];
 
@@ -181,4 +270,4 @@
   }
 ];
 
-export { option1, default1, option2, option3, default3, option4 };
+export { option1, option1All, default1, option2, option3, default3, option4 };
diff --git a/src/stores/mission.js b/src/stores/mission.js
index 37c2871..b90e8e2 100644
--- a/src/stores/mission.js
+++ b/src/stores/mission.js
@@ -6,7 +6,7 @@
 // 璧拌埅浠诲姟
 export const useMissionStore = defineStore('mission', () => {
   const missionList = ref([]);
-  const { loading, fetchData } = useFetchData();
+  const { loading, fetchData } = useFetchData(1000);
 
   function fetchMission(type) {
     return fetchData((page, pageSize) => {
diff --git a/src/utils/color.js b/src/utils/color.js
new file mode 100644
index 0000000..03a6ced
--- /dev/null
+++ b/src/utils/color.js
@@ -0,0 +1,30 @@
+//杞寲棰滆壊
+function getHexColor(values) {
+  // 浼犵殑color椤讳负瀛楃涓�
+  // var values = color
+  //   .replace(/rgba?\(/, '')  // 鎶� "rgba(" 鍘绘帀锛屽彉鎴�  "194, 7, 15, 1)"
+  //   .replace(/\)/, '')		 // 鎶� ")" 鍘绘帀锛屽彉鎴� "194, 7, 15, 1"
+  //   .replace(/[\s+]/g, '')   // 鎶婄┖鏍煎幓鎺夛紝鍙樻垚 "194,7,15,1"
+  //   .split(',')				 // 鍙樻垚鏁扮粍 [194,7,15,1]
+  var a = parseFloat(values[3] || 1), // values[3]鏄痳gba涓殑a鍊硷紝娌℃湁鐨勮瘽璁剧疆a涓�1锛宎鍙兘涓哄皬鏁帮紝鎵�浠ョ敤parseFloat鍑芥暟
+    r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255), // 杞崲涓�16杩涘埗
+    g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255),
+    b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255);
+  return (
+    '#' +
+    ('0' + r.toString(16)).slice(-2) + // 杞崲鍚庣殑16杩涘埗鍙兘涓轰竴浣嶏紝姣斿 7 灏辫浆鎹负 7 锛� 15 杞崲涓� f
+    ('0' + g.toString(16)).slice(-2) + // 褰撲负涓�浣嶇殑鏃跺�欏氨鍦ㄥ墠闈㈠姞涓� 0锛�
+    ('0' + b.toString(16)).slice(-2)
+  ); // 鑻ユ槸涓轰袱浣嶏紝鍔� 0 鍚庡氨鍙樻垚浜嗕笁浣嶏紝鎵�浠ヨ鐢� slice(-2) 鎴彇鍚庝袱浣�
+}
+
+//璁$畻绾挎�ф笎鍙樼殑涓棿棰滆壊鍊�
+function getColorBetweenTwoColors(colorA, colorB, ratio) {
+  const r = Math.round((colorB[0] - colorA[0]) * ratio + colorA[0]);
+  const g = Math.round((colorB[1] - colorA[1]) * ratio + colorA[1]);
+  const b = Math.round((colorB[2] - colorA[2]) * ratio + colorA[2]);
+
+  return getHexColor([r, g, b, 1]);
+}
+
+export { getHexColor, getColorBetweenTwoColors };
diff --git a/src/utils/map/calculate.js b/src/utils/map/calculate.js
index b9ad407..71859bc 100644
--- a/src/utils/map/calculate.js
+++ b/src/utils/map/calculate.js
@@ -197,5 +197,24 @@
       let mglng = Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000;
       return [mglng, mglat];
     }
+  },
+
+  //浠嶨PS杞珮寰�
+  wgs84_To_Gcj02(lon, lat) {
+    if (out_of_china(lon, lat)) {
+      return [lon, lat];
+    } else {
+      let dLat = transformlat(lon - 105.0, lat - 35.0);
+      let dLon = transformlng(lon - 105.0, lat - 35.0);
+      let radLat = (lat / 180.0) * PI;
+      let magic = Math.sin(radLat);
+      magic = 1 - ee * magic * magic;
+      let sqrtMagic = Math.sqrt(magic);
+      dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * PI);
+      dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
+      let mgLat = lat + dLat;
+      let mgLon = lon + dLon;
+      return [mgLon, mgLat];
+    }
   }
 };
diff --git a/src/utils/map/grid.js b/src/utils/map/grid.js
new file mode 100644
index 0000000..351bd2c
--- /dev/null
+++ b/src/utils/map/grid.js
@@ -0,0 +1,52 @@
+/**
+ * 缃戞牸缁樺埗
+ */
+import { map } from './index_old';
+
+export default {
+  /**
+   * 缁樺埗缃戞牸椋庨櫓鍥�
+   * @param {*} points
+   */
+  drawRectangle: function (points) {
+    const gridViews = [];
+    points.forEach((p) => {
+      const { lb, rt, c } = p;
+
+      // eslint-disable-next-line no-undef
+      let pList = [lb, rt].map((v) => new AMap.LngLat(v[0], v[1]));
+      // eslint-disable-next-line no-undef
+      var bounds = new AMap.Bounds(...pList);
+      // eslint-disable-next-line no-undef
+      var rectangle = new AMap.Rectangle({
+        bounds: bounds,
+        // strokeColor: '#ffffffff',
+        strokeWeight: 0,
+        strokeOpacity: 0,
+        // strokeStyle杩樻敮鎸� solid
+        strokeStyle: 'solid',
+        fillColor: '990D0D',
+        fillOpacity: 0.8,
+        cursor: 'pointer',
+        zIndex: 50
+      });
+
+      // var text = new AMap.Text({
+      //   text: p.value,
+      //   anchor: 'center', // 璁剧疆鏂囨湰鏍囪閿氱偣
+      //   draggable: false,
+      //   style: {
+      //     'background-color': 'transparent',
+      //     'border-width': 0,
+      //     'text-align': 'center',
+      //     'font-size': '12px',
+      //     color: 'white'
+      //   },
+      //   position: c
+      // });
+      gridViews.push(rectangle);
+      // that.textView.push(text);
+    });
+    map.add(gridViews);
+  }
+};
diff --git a/src/utils/map/line.js b/src/utils/map/line.js
new file mode 100644
index 0000000..5334f3a
--- /dev/null
+++ b/src/utils/map/line.js
@@ -0,0 +1,44 @@
+import { map } from './index_old';
+import calculate from './calculate';
+import { getHexColor } from '../color';
+
+var _polylineArr = [];
+
+export default {
+  drawLine(fDatas, factor) {
+    const lnglats_GD = fDatas.lnglats_GD;
+    const colors = factor.colors;
+
+    if (_polylineArr) {
+      map.remove(_polylineArr);
+      _polylineArr = [];
+    }
+    var path = calculate.parse2LngLat(lnglats_GD);
+
+    let sIndex = 0;
+    for (let i = 1; i < path.length; i++) {
+      // if (colors[i] == colors[i - 1]) {
+      // } else {
+      // }
+      const _path = [path[i], path[i + 1]];
+      const _color = getHexColor(colors[i + 1].map((v) => v * 255));
+      // 鍒涘缓鎶樼嚎瀹炰緥
+      // eslint-disable-next-line no-undef
+      const polyline = new AMap.Polyline({
+        path: _path,
+        strokeStyle: 'solid',
+        isOutline: true,
+        borderWeight: 2,
+        outlineColor: 'white',
+        strokeWeight: 4, // 绾挎潯瀹藉害锛岄粯璁や负 1
+        strokeColor: _color, // 绾挎潯棰滆壊
+        lineJoin: 'round', // 鎶樼嚎鎷愮偣杩炴帴澶勬牱寮�
+        showDir: true
+      });
+      _polylineArr.push(polyline);
+    }
+    // 灏嗘姌绾挎坊鍔犺嚦鍦板浘瀹炰緥
+    map.add(_polylineArr);
+    return _polylineArr;
+  }
+};
diff --git a/src/utils/map/marks.js b/src/utils/map/marks.js
index a72dcdf..03ebbc5 100644
--- a/src/utils/map/marks.js
+++ b/src/utils/map/marks.js
@@ -25,7 +25,7 @@
     for (let i = 0; i < lnglats.length; i++) {
       data.push({
         lnglat: lnglats[i], //鐐规爣璁颁綅缃�
-        name: `${fDatas.times[i]}<br/>${_factor.factorName}: ${_factor.datas[i].factorData} mg/m鲁`,
+        name: `${fDatas.times[i]}<br/>${_factor.factorName}: ${_factor.datas[i].factorData} 渭g/m鲁`,
         id: i
       });
     }
diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue
index 2e68604..6e0f275 100644
--- a/src/views/HomePage.vue
+++ b/src/views/HomePage.vue
@@ -4,6 +4,7 @@
     <CoreHeader></CoreHeader>
     <el-row class="dropdown-wrap">
       <MapToolbox></MapToolbox>
+      <!-- <SatelliteTelemetry></SatelliteTelemetry> -->
       <!-- <MissionManage></MissionManage> -->
       <ConfigManage></ConfigManage>
       <!-- <MapLocation></MapLocation> -->
@@ -15,7 +16,9 @@
   </div>
 </template>
 
-<script setup></script>
+<script setup>
+import SatelliteTelemetry from '@/views/satellitetelemetry/SatelliteTelemetry.vue';
+</script>
 
 <style scoped>
 .overlay-container {
diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue
index 9f9c573..b63cf49 100644
--- a/src/views/historymode/HistoryMode.vue
+++ b/src/views/historymode/HistoryMode.vue
@@ -49,6 +49,7 @@
 
 <script>
 import Layer from '@/utils/map/3dLayer';
+import mapLine from '@/utils/map/line';
 import marks from '@/utils/map/marks';
 import sector from '@/utils/map/sector';
 import mapUtil from '@/utils/map/util';
@@ -137,7 +138,8 @@
       // 鍒锋柊鍥句緥
       const factor = this.factorDatas.factor[this.factorType];
       sector.clearSector();
-      this.drawRoadMap(factor);
+      this.drawRoadLine(factor);
+      // this.drawRoadMap(factor);
       this.drawMassMarks(factor);
     },
     // 缁樺埗3D璧拌璺嚎鍥�
@@ -145,7 +147,9 @@
       this.factorDatas.refreshHeight(this.factorType);
 
       Layer.drawRoadMap(this.factorDatas, e, this.merge, this.setCenter);
-      // }
+    },
+    drawRoadLine(e) {
+      mapLine.drawLine(this.factorDatas, e);
     },
     drawMassMarks(e) {
       marks.drawMassMarks(this.factorDatas, e, (index) => {
diff --git a/src/views/satellitetelemetry/SatelliteTelemetry.vue b/src/views/satellitetelemetry/SatelliteTelemetry.vue
new file mode 100644
index 0000000..fd1a40d
--- /dev/null
+++ b/src/views/satellitetelemetry/SatelliteTelemetry.vue
@@ -0,0 +1,40 @@
+<template>
+  <div class="p-events-auto">
+    <el-button type="info" icon="Memo" plain @click="drawGrid">
+      缁樺埗缃戞牸
+    </el-button>
+  </div>
+</template>
+<script setup>
+import calculate from '@/utils/map/calculate';
+import grid from '@/utils/map/grid';
+import { gridData } from '../../../test/grid_test_data';
+
+function drawGrid() {
+  // const points = gridData.map((v) => {
+  //   return calculate.wgs84_To_Gcj02(v[0], v[1]);
+  // });
+  // const p1 = points[0];
+  // const p2 = points[1];
+  // const diffLng = Math.abs(p1[0] - p2[0]);
+  // const diffLat = Math.abs(p1[1] - p2[1]);
+  // const bounds = points.map((v) => {
+  //   return {
+  //     // 涓滅粡锛屽寳绾儏鍐典笅
+  //     lb: [v[0] - diffLng, v[1] - diffLat],
+  //     rt: [v[0] + diffLng, v[1] - diffLat],
+  //     c: v
+  //   };
+  // });
+
+  const bounds = [
+    {
+      lb: [121.360898, 31.222733],
+      rt: [121.364898, 31.226733],
+      c: [121.362898, 31.224733]
+    }
+  ];
+
+  grid.drawRectangle(bounds);
+}
+</script>
diff --git a/test/grid_test_data.js b/test/grid_test_data.js
new file mode 100644
index 0000000..5b72b3d
--- /dev/null
+++ b/test/grid_test_data.js
@@ -0,0 +1,112 @@
+const gridData = [
+  [121.329723, 31.240625],
+  [121.339366, 31.241204],
+  [121.34901, 31.241781],
+  [121.358654, 31.242358],
+  [121.368299, 31.242935],
+  [121.377943, 31.24351],
+  [121.387588, 31.244085],
+  [121.397234, 31.244659],
+  [121.406879, 31.245233],
+  [121.416525, 31.245805],
+  [121.426171, 31.246377],
+  [121.435818, 31.246949],
+  [121.330396, 31.232339],
+  [121.340039, 31.232918],
+  [121.349682, 31.233495],
+  [121.359325, 31.234072],
+  [121.368969, 31.234648],
+  [121.378613, 31.235223],
+  [121.388257, 31.235798],
+  [121.397901, 31.236372],
+  [121.407546, 31.236945],
+  [121.417191, 31.237518],
+  [121.426836, 31.23809],
+  [121.436482, 31.238661],
+  [121.331069, 31.224054],
+  [121.340711, 31.224632],
+  [121.350353, 31.225209],
+  [121.359996, 31.225786],
+  [121.369639, 31.226362],
+  [121.379282, 31.226937],
+  [121.388925, 31.227511],
+  [121.398569, 31.228085],
+  [121.408213, 31.228658],
+  [121.417857, 31.22923],
+  [121.427501, 31.229802],
+  [121.437146, 31.230373],
+  [121.331742, 31.215768],
+  [121.341383, 31.216346],
+  [121.351025, 31.216923],
+  [121.360666, 31.217499],
+  [121.370308, 31.218075],
+  [121.379951, 31.21865],
+  [121.389593, 31.219224],
+  [121.399236, 31.219798],
+  [121.408879, 31.220371],
+  [121.418522, 31.220943],
+  [121.428166, 31.221514],
+  [121.43781, 31.222085],
+  [121.332415, 31.207482],
+  [121.342055, 31.20806],
+  [121.351696, 31.208637],
+  [121.361337, 31.209213],
+  [121.370978, 31.209788],
+  [121.380619, 31.210363],
+  [121.390261, 31.210937],
+  [121.399903, 31.211511],
+  [121.409545, 31.212083],
+  [121.419188, 31.212655],
+  [121.42883, 31.213227],
+  [121.438473, 31.213797],
+  [121.333087, 31.199196],
+  [121.342727, 31.199774],
+  [121.352366, 31.20035],
+  [121.362006, 31.200926],
+  [121.371647, 31.201502],
+  [121.381287, 31.202076],
+  [121.390928, 31.20265],
+  [121.400569, 31.203224],
+  [121.410211, 31.203796],
+  [121.419853, 31.204368],
+  [121.429494, 31.204939],
+  [121.439137, 31.205509],
+  [121.333759, 31.19091],
+  [121.343398, 31.191488],
+  [121.353037, 31.192064],
+  [121.362676, 31.19264],
+  [121.372316, 31.193215],
+  [121.381955, 31.19379],
+  [121.391595, 31.194363],
+  [121.401236, 31.194936],
+  [121.410876, 31.195509],
+  [121.420517, 31.19608],
+  [121.430158, 31.196651],
+  [121.4398, 31.197221],
+  [121.334431, 31.182624],
+  [121.344069, 31.183201],
+  [121.353707, 31.183778],
+  [121.363345, 31.184354],
+  [121.372984, 31.184928],
+  [121.382623, 31.185503],
+  [121.392262, 31.186076],
+  [121.401902, 31.186649],
+  [121.411542, 31.187221],
+  [121.421182, 31.187793],
+  [121.430822, 31.188363],
+  [121.440462, 31.188933],
+  [121.335103, 31.174338],
+  [121.34474, 31.174915],
+  [121.354377, 31.175492],
+  [121.364015, 31.176067],
+  [121.373652, 31.176642],
+  [121.38329, 31.177216],
+  [121.392929, 31.177789],
+  [121.402568, 31.178362],
+  [121.412206, 31.178934],
+  [121.421846, 31.179505],
+  [121.431485, 31.180076],
+  [121.441125, 31.180645]
+];
+
+export { gridData };

--
Gitblit v1.9.3