custom-service.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <template>
  2. <div id="CustomService-panel" class="sm-panel" v-drag :style="panelStyle">
  3. <div class="sm-function-module-sub-section" style="margin:0" v-stopdrag>
  4. <div class="sm-half-L">
  5. <label style="width:40%">打开图层</label>
  6. <select class="sm-select" style="width:58%" v-model="layersType">
  7. <option value="SCENE">场景</option>
  8. <option value="S3M">S3M</option>
  9. <option value="IMG">地图服务</option>
  10. <option value="TERRAIN">地形服务</option>
  11. <option value="MVT">矢量要素</option>
  12. <option value="GEOJSON">GeoJSON</option>
  13. <option value="SHP">SHP上传</option>
  14. </select>
  15. </div>
  16. <div class="sm-half-L flex-start">
  17. <input
  18. type="text"
  19. class="sm-input sm-margin-M"
  20. style="width:100%"
  21. placeholder="URL"
  22. v-model="layerURL"
  23. v-show="layersType !== 'SHP'"
  24. />
  25. <div v-show="layersType === 'SHP'" class="shp-upload-container">
  26. <input
  27. type="file"
  28. ref="shpFileInput"
  29. accept=".zip,.shp"
  30. @change="handleShpFileChange"
  31. class="sm-input"
  32. style="width:100%"
  33. />
  34. <div class="upload-tip">支持 .zip(包含.shp,.shx,.dbf等) 或单独.shp文件</div>
  35. </div>
  36. <input
  37. type="text"
  38. class="sm-input sm-margin-M"
  39. style="width:100%"
  40. placeholder="自定义名称"
  41. v-model="layerName"
  42. v-show="layersType !== 'SHP'"
  43. />
  44. <!-- v-show="layersType === 'S3M'" -->
  45. <label class="label-S">添加token</label>
  46. <input checked type="checkbox" v-model="isAddToken" v-show="layersType !== 'SHP' && layersType !== 'GEOJSON'" />
  47. <input
  48. type="text"
  49. class="sm-input sm-margin-M"
  50. style="width:100%"
  51. placeholder="token"
  52. v-model="token"
  53. v-show="isAddToken && layersType !== 'SHP' && layersType !== 'GEOJSON'"
  54. />
  55. </div>
  56. <div class="sm-half-L flex-start" v-show="layersType === 'TERRAIN'">
  57. <label class="label-S">isSct</label>
  58. <input checked type="checkbox" v-model="isSct" />
  59. </div>
  60. <div class="boxchild">
  61. <button class="tbtn tbtn-margin-left" type="button" v-on:click="addLayer">添加</button>
  62. <button @click="clear" class="tbtn tbtn-margin-left" type="button">取消</button>
  63. </div>
  64. </div>
  65. </div>
  66. </template>
  67. <script>
  68. import layerManagement from "../../js/common/layerManagement.js";
  69. import tool from "../../js/tool/tool.js";
  70. import { watch, ref, reactive, toRefs, onBeforeUnmount, onMounted, getCurrentInstance } from "vue";
  71. import { uploadShp, getGeoJsonList, getGeoJsonUrl } from "../../api/cesium/geojson.js";
  72. export default {
  73. name: "Sm3dCustomService",
  74. props: {
  75. //点击确定时回调
  76. addCallback: {
  77. type: Function
  78. },
  79. //点击取消时回调
  80. clearCallback: {
  81. type: Function
  82. },
  83. getLayerName:{
  84. type: Function
  85. }
  86. },
  87. setup(props) {
  88. onMounted(() => {
  89. setTimeout(() => {
  90. const panel = document.getElementById('CustomService-panel');
  91. if (panel) {
  92. panel.style.left = '35%';
  93. panel.style.top = '25%';
  94. }
  95. }, 50);
  96. });
  97. const shpFileInput = ref(null);
  98. const shpFile = ref(null);
  99. const uploadProgress = ref(0);
  100. const isUploading = ref(false);
  101. let state = reactive({
  102. layersType: "SCENE",
  103. layerURL: null,
  104. layerName: null,
  105. isAddToken: false,
  106. token: null,
  107. isSct: false
  108. });
  109. async function handleShpFileChange(event) {
  110. const file = event.target.files[0];
  111. if (!file) return;
  112. const fileName = file.name.toLowerCase();
  113. if (!fileName.endsWith('.zip') && !fileName.endsWith('.shp')) {
  114. tool.Message.warnMsg("请上传 .zip 或 .shp 格式的文件");
  115. return;
  116. }
  117. shpFile.value = file;
  118. tool.Message.infoMsg("已选择文件: " + file.name);
  119. }
  120. async function uploadShpFile() {
  121. if (!shpFile.value) {
  122. tool.Message.warnMsg("请先选择SHP文件");
  123. return null;
  124. }
  125. isUploading.value = true;
  126. uploadProgress.value = 0;
  127. const formData = new FormData();
  128. formData.append('file', shpFile.value);
  129. if (state.layerName) {
  130. formData.append('layerName', state.layerName);
  131. }
  132. try {
  133. const result = await uploadShp(formData);
  134. isUploading.value = false;
  135. uploadProgress.value = 100;
  136. if (result.code === 200 && result.data) {
  137. tool.Message.successMsg("文件上传成功");
  138. return result.data;
  139. } else {
  140. tool.Message.errorMsg(result.msg || "上传失败");
  141. return null;
  142. }
  143. } catch (error) {
  144. isUploading.value = false;
  145. tool.Message.errorMsg("上传失败: " + error.message);
  146. return null;
  147. }
  148. }
  149. async function addGeoJsonLayer() {
  150. const url = state.layerURL;
  151. if (!url) {
  152. tool.Message.warnMsg("请输入GeoJSON URL");
  153. return;
  154. }
  155. const serviceInfo = {
  156. url: url,
  157. type: 'GEOJSON'
  158. };
  159. layerManagement.addGeoJsonLayer(url, state.layerName || 'GeoJSON', (geoJsonLayer) => {
  160. addCallback(geoJsonLayer, "GEOJSON", serviceInfo);
  161. });
  162. }
  163. async function addShpLayer() {
  164. const geoJsonUrl = await uploadShpFile();
  165. if (!geoJsonUrl) return;
  166. const serviceInfo = {
  167. url: geoJsonUrl,
  168. type: 'GEOJSON'
  169. };
  170. layerManagement.addGeoJsonLayer(geoJsonUrl, state.layerName || 'SHP_Data', (geoJsonLayer) => {
  171. addCallback(geoJsonLayer, "GEOJSON", serviceInfo);
  172. });
  173. }
  174. let addCallback = () => {};
  175. let clearCallback = () => {};
  176. let getLayerName = () => {};
  177. if (props && props.clearCallback) {
  178. clearCallback = props.clearCallback;
  179. }
  180. if (props && props.addCallback) {
  181. addCallback = props.addCallback;
  182. }
  183. if (props && props.getLayerName) {
  184. getLayerName = props.getLayerName;
  185. }
  186. function check() {
  187. if (state.layersType === 'SHP') {
  188. if (!shpFile.value) {
  189. tool.Message.warnMsg("请先选择SHP文件");
  190. return false;
  191. }
  192. return true;
  193. }
  194. if (state.layersType === 'GEOJSON') {
  195. if (!state.layerURL || state.layerURL === "") {
  196. tool.Message.warnMsg("请填写GeoJSON URL");
  197. return false;
  198. }
  199. return true;
  200. }
  201. if (!state.layerURL || state.layerURL === "") {
  202. tool.Message.warnMsg("请填写正确的URL");
  203. return false;
  204. }
  205. if (
  206. state.layersType != "SCENE" &&
  207. (!state.layerName || state.layerName === "")
  208. ) {
  209. tool.Message.warnMsg("请补充图层名称");
  210. return false;
  211. }
  212. if (state.isAddToken && !state.token) {
  213. tool.Message.warnMsg("勾选token后请填写token");
  214. return false;
  215. }
  216. return true;
  217. }
  218. function checkLayersType(){
  219. if (state.layersType === 'SHP' || state.layersType === 'GEOJSON') {
  220. return true;
  221. }
  222. let arr = state.layerURL.split('/');
  223. let layer_type = arr[arr.length -1];
  224. if(layer_type === 'realspace' && state.layersType != "SCENE") return false;
  225. if(layer_type === 'config' && state.layersType != "S3M") return false;
  226. if(layer_type === 'image' && state.layersType != "IMG") return false;
  227. return true;
  228. }
  229. function addLayer() {
  230. if (!checkLayersType()) {
  231. tool.Message.warnMsg("请检查添加类型是否正常?");
  232. return;
  233. };
  234. getLayerName(state.layerName);
  235. const currentURL = state.layerURL;
  236. const currentToken = state.token;
  237. const currentTokenRequired = state.isAddToken;
  238. const currentLayerName = state.layerName;
  239. const currentLayersType = state.layersType;
  240. const serviceInfo = {
  241. url: currentURL,
  242. token: currentToken,
  243. tokenRequired: currentTokenRequired
  244. };
  245. console.log('addLayer - serviceInfo:', serviceInfo);
  246. console.log('addLayer - currentURL:', currentURL);
  247. switch (currentLayersType) {
  248. case "SCENE":
  249. if (check()) {
  250. let options = {};
  251. if (currentTokenRequired) options.SceneToken = currentToken;
  252. console.log('SCENE回调前serviceInfo:', serviceInfo);
  253. layerManagement.addScene(currentURL, options, (layers) => {
  254. console.log('SCENE回调中serviceInfo:', serviceInfo);
  255. addCallback(layers, "SCENE", serviceInfo);
  256. });
  257. }
  258. break;
  259. case "S3M":
  260. if (check()) {
  261. let scps = [
  262. { url: currentURL, options: { name: currentLayerName } }
  263. ];
  264. layerManagement.addS3mLayers(scps, (layers) => {
  265. addCallback(layers, "S3M", serviceInfo);
  266. });
  267. }
  268. break;
  269. case "IMG":
  270. if (check()) {
  271. let layer = layerManagement.addImageLayer(currentURL);
  272. addCallback(layer, "IMG", serviceInfo);
  273. }
  274. break;
  275. case "TERRAIN":
  276. if (check()) {
  277. let terrainProvider = layerManagement.addTerrainLayer(currentURL, state.isSct);
  278. addCallback(terrainProvider, "TERRAIN", serviceInfo);
  279. }
  280. break;
  281. case "MVT":
  282. if (check()) {
  283. layerManagement.addMvtLayer(currentURL, currentLayerName, (mvtlayer) => {
  284. addCallback(mvtlayer, "MVT", serviceInfo);
  285. });
  286. }
  287. break;
  288. case "GEOJSON":
  289. if (check()) {
  290. addGeoJsonLayer();
  291. }
  292. break;
  293. case "SHP":
  294. if (check()) {
  295. addShpLayer();
  296. }
  297. break;
  298. }
  299. clearState();
  300. }
  301. function clearState() {
  302. state.layerURL = null;
  303. state.layerName = null;
  304. state.isAddToken = false;
  305. state.token = null;
  306. state.isSct = false;
  307. }
  308. function clear() {
  309. clearState();
  310. clearCallback();
  311. }
  312. return {
  313. ...toRefs(state),
  314. panelStyle,
  315. addLayer,
  316. clear,
  317. handleShpFileChange,
  318. shpFileInput,
  319. uploadProgress,
  320. isUploading
  321. };
  322. }
  323. };
  324. </script>
  325. <style scoped>
  326. .shp-upload-container {
  327. width: 100%;
  328. margin-bottom: 10px;
  329. }
  330. .upload-tip {
  331. font-size: 12px;
  332. color: #999;
  333. margin-top: 5px;
  334. }
  335. </style>