From 0ba08dcd554d3aa34bbf36de7fe39303c240b085 Mon Sep 17 00:00:00 2001 From: "978184212@qq.com" <978184212@qq.com> Date: Thu, 10 Sep 2026 18:11:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E7=AB=99=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/maps/index.vue | 952 ++++++++++++++++++++++++++----------------- 1 file changed, 583 insertions(+), 369 deletions(-) diff --git a/pages/maps/index.vue b/pages/maps/index.vue index a152760..016ff00 100644 --- a/pages/maps/index.vue +++ b/pages/maps/index.vue @@ -1,34 +1,70 @@ @@ -54,13 +90,28 @@ soilStationList: [], allStationList: [], stationTwoList: [], - mapCtx: null // 添加地图上下文 - + mapCtx: null, + // 企业相关 + enterpriseList: [], + showEnterprisePopup: false, + currentEnterprise: {}, + currentMarkerId: null, + maxMarkerId: 0, + // 当前筛选类型:'' 表示显示全部 + activeType: '' }; }, + computed: { + // 根据 activeType 过滤要显示的 marker + filteredMarkers() { + if (!this.activeType) { + return this.markers; + } + return this.markers.filter(item => item.stationType === this.activeType); + } + }, onLoad() {}, onReady() { - // 在onReady中初始化地图上下文 this.mapCtx = uni.createMapContext('map', this); }, onShow() { @@ -75,384 +126,470 @@ }) }, methods: { - // kaihs getList() { - this.markers = [] - this.stationList = [] - this.cusLocationList = [] - this.soilStationList = [] - this.allStationList = [] - this.stationTwoList = [] - - uni.showLoading({ - title: '加载中' - }); - - this.$http.get('/applet/survStationInfo/stationMap').then(res => { - // 处理数据 - this.stationList = [...res.data.data.stationInfo]; - this.cusLocationList = [...res.data.data.cusLocation]; - this.soilStationList = [...res.data.data.deviceList]; - this.allStationList.push(...this.stationList); - this.allStationList.push(...this.cusLocationList); - this.allStationList.push(...this.soilStationList); - this.allStationList.forEach((item, index) => { - item.id = index; - }); - - this.issscd = false - this.isssscd = false - this.isSoilShow = false - - // 渲染所有标记 - this.enterpriseRender(); - this.stationRender(); - this.monitorRender() - - // 使用增强的视野调整方法 - this.ensureAllMarkersVisible(); - - uni.hideLoading(); - }).catch(err => { - uni.hideLoading(); - uni.showToast({ - title: '数据加载失败', - icon: 'none' - }); - console.error('加载地图数据失败:', err); - }) + this.markers = [] + this.stationList = [] + this.cusLocationList = [] + this.soilStationList = [] + this.allStationList = [] + this.stationTwoList = [] + this.enterpriseList = [] + this.maxMarkerId = 0 + this.activeType = '' + + uni.showLoading({ + title: '加载中' + }); + + // 获取监测站数据 + this.$http.get('/applet/survStationInfo/stationMap').then(res => { + this.stationList = [...res.data.data.stationInfo]; + this.cusLocationList = [...res.data.data.cusLocation]; + this.soilStationList = [...res.data.data.deviceList]; + this.allStationList.push(...this.stationList); + this.allStationList.push(...this.cusLocationList); + this.allStationList.push(...this.soilStationList); + this.allStationList.forEach((item, index) => { + item.id = index + 1; + }); + + this.issscd = false + this.isssscd = false + this.isSoilShow = false + + // 记录已用的最大 id,避免与企业 marker 冲突 + this.maxMarkerId = this.allStationList.length + 1; + + // 渲染所有标记 + this.enterpriseRender(); + this.stationRender(); + this.monitorRender() + + // 使用增强的视野调整方法 + this.ensureAllMarkersVisible(); + + uni.hideLoading(); + }).catch(err => { + uni.hideLoading(); + uni.showToast({ + title: '数据加载失败', + icon: 'none' + }); + console.error('加载地图数据失败:', err); + }) + + // 获取企业列表 + this.$http.get('/applet/wxclient/getEntList').then(res => { + if (res.data.data && res.data.data.result) { + this.enterpriseList = res.data.data.result; + this.renderEnterpriseMarkers(); + this.$nextTick(() => { + this.ensureAllMarkersVisible(); + }); + } + uni.hideLoading(); + }).catch(err => { + uni.hideLoading(); + uni.showToast({ + title: '企业数据加载失败', + icon: 'none' + }); + console.error('加载企业数据失败:', err); + }) }, + + // 渲染企业标记(自动过滤掉无有效坐标的企业) + renderEnterpriseMarkers() { + if (!this.enterpriseList || this.enterpriseList.length === 0) { + console.warn('企业列表为空'); + return; + } + + // 过滤出有有效坐标的企业 + const validEnterpriseList = this.enterpriseList.filter((item) => { + const lat = Number(item.entLat); + const lng = Number(item.entLong); + return !isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0; + }); + + const invalidCount = this.enterpriseList.length - validEnterpriseList.length; + if (invalidCount > 0) { + console.log(`已过滤 ${invalidCount} 个缺少坐标的企业`); + } + + validEnterpriseList.forEach((item) => { + const lat = Number(item.entLat); + const lng = Number(item.entLong); + + const markerId = ++this.maxMarkerId; + + let iconPath = '/static/qiyebzIcon.png'; + if (item.entMapIcon) { + iconPath = this.baseUrl.replace(/\/$/, '') + '/' + item.entMapIcon.replace(/^\//, ''); + } + + const markerItem = { + id: markerId, + iconPath: iconPath, + latitude: lat, + longitude: lng, + width: 40, + height: 50, + stationType: 'enterprise', + stationName: item.entName, + entShortName: item.entShortName, + entCharge: item.entCharge, + entCredit: item.entCredit, + entCode: item.entCode, + entIntro: item.entIntro, + entPhone: item.entPhone, + createTime: item.createTime, + entId: item.id, + joinCluster: false, + zIndex: this.markersZIndex++, + enterpriseData: item, + callout: { + content: item.entName || '企业', + color: '#FFFFFF', + fontSize: 14, + borderRadius: 10, + bgColor: '#007AFF', + padding: 8, + display: 'ALWAYS' + } + }; + + this.markers.push(markerItem); + }); + }, + ensureAllMarkersVisible() { - // 确保地图上下文已初始化 - if (!this.mapCtx) { - this.mapCtx = uni.createMapContext('map', this); - } - - // 过滤出有效的坐标点 - const validPoints = this.markers - .filter(item => { - const lat = Number(item.latitude); - const lng = Number(item.longitude); - return !isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0; - }) - .map(item => ({ - latitude: Number(item.latitude), - longitude: Number(item.longitude) - })); - - if (validPoints.length === 0) { - console.warn('没有有效的坐标点'); - // 如果有默认坐标,使用默认坐标 - if (this.center.latitude && this.center.longitude) { - this.mapCtx.moveToLocation({ - latitude: this.center.latitude, - longitude: this.center.longitude, - scale: 10 - }); - } - return; - } - - console.log('有效坐标点数量:', validPoints.length); - - // 方法1:使用 includePoints(优先) - try { - this.mapCtx.includePoints({ - points: validPoints, - padding: [120, 120, 120, 120], // 增加边距让点位不贴边 - success: () => { - console.log('地图视野调整成功'); - }, - fail: (err) => { - console.error('includePoints失败:', err); - // 如果失败,使用备用方案 - this.fallbackAdjustMap(validPoints); - } - }); - } catch (e) { - console.error('调整地图视野异常:', e); - this.fallbackAdjustMap(validPoints); - } - - // 方法2:延迟重试(确保地图完全渲染) - setTimeout(() => { - if (this.mapCtx) { - try { - this.mapCtx.includePoints({ - points: validPoints, - padding: [150, 150, 150, 150] - }); - } catch (e) { - console.error('第二次调整失败:', e); - } - } - }, 500); - - // 方法3:第三次重试(更长的延迟) - setTimeout(() => { - if (this.mapCtx) { - try { - this.mapCtx.includePoints({ - points: validPoints, - padding: [180, 160, 160, 160] - }); - } catch (e) { - console.error('第三次调整失败:', e); - } - } - }, 1000); + if (!this.mapCtx) { + this.mapCtx = uni.createMapContext('map', this); + } + + const validPoints = this.markers + .filter(item => { + const lat = Number(item.latitude); + const lng = Number(item.longitude); + return !isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0; + }) + .map(item => ({ + latitude: Number(item.latitude), + longitude: Number(item.longitude) + })); + + if (validPoints.length === 0) { + console.warn('没有有效的坐标点'); + if (this.center.latitude && this.center.longitude) { + this.mapCtx.moveToLocation({ + latitude: this.center.latitude, + longitude: this.center.longitude, + scale: 10 + }); + } + return; + } + + console.log('有效坐标点数量:', validPoints.length); + + try { + this.mapCtx.includePoints({ + points: validPoints, + padding: [120, 120, 120, 120], + success: () => { + console.log('地图视野调整成功'); + }, + fail: (err) => { + console.error('includePoints失败:', err); + this.fallbackAdjustMap(validPoints); + } + }); + } catch (e) { + console.error('调整地图视野异常:', e); + this.fallbackAdjustMap(validPoints); + } + + setTimeout(() => { + if (this.mapCtx) { + try { + this.mapCtx.includePoints({ + points: validPoints, + padding: [150, 150, 150, 150] + }); + } catch (e) { + console.error('第二次调整失败:', e); + } + } + }, 500); + + setTimeout(() => { + if (this.mapCtx) { + try { + this.mapCtx.includePoints({ + points: validPoints, + padding: [180, 160, 160, 160] + }); + } catch (e) { + console.error('第三次调整失败:', e); + } + } + }, 1000); }, + fallbackAdjustMap(validPoints) { - if (!validPoints || validPoints.length === 0) return; - - try { - // 计算所有点位的中心点和范围 - const lats = validPoints.map(p => p.latitude); - const lngs = validPoints.map(p => p.longitude); - - const minLat = Math.min(...lats); - const maxLat = Math.max(...lats); - const minLng = Math.min(...lngs); - const maxLng = Math.max(...lngs); - - // 计算中心点 - const centerLat = (minLat + maxLat) / 2; - const centerLng = (minLng + maxLng) / 2; - - // 计算合适的缩放级别 - const latDiff = maxLat - minLat; - const lngDiff = maxLng - minLng; - const maxDiff = Math.max(latDiff, lngDiff); - - let scale = 13; - if (maxDiff > 2) scale = 6; - else if (maxDiff > 1) scale = 8; - else if (maxDiff > 0.5) scale = 10; - else if (maxDiff > 0.2) scale = 11; - else if (maxDiff > 0.1) scale = 12; - else scale = 13; - - console.log('备用方案 - 中心点:', centerLat, centerLng, '缩放:', scale); - - // 移动地图到计算出的中心位置 - this.mapCtx.moveToLocation({ - latitude: centerLat, - longitude: centerLng, - scale: scale - }); - } catch (e) { - console.error('备用方案失败:', e); - } + if (!validPoints || validPoints.length === 0) return; + + try { + const lats = validPoints.map(p => p.latitude); + const lngs = validPoints.map(p => p.longitude); + + const minLat = Math.min(...lats); + const maxLat = Math.max(...lats); + const minLng = Math.min(...lngs); + const maxLng = Math.max(...lngs); + + const centerLat = (minLat + maxLat) / 2; + const centerLng = (minLng + maxLng) / 2; + + const latDiff = maxLat - minLat; + const lngDiff = maxLng - minLng; + const maxDiff = Math.max(latDiff, lngDiff); + + let scale = 13; + if (maxDiff > 2) scale = 6; + else if (maxDiff > 1) scale = 8; + else if (maxDiff > 0.5) scale = 10; + else if (maxDiff > 0.2) scale = 11; + else if (maxDiff > 0.1) scale = 12; + else scale = 13; + + console.log('备用方案 - 中心点:', centerLat, centerLng, '缩放:', scale); + + this.mapCtx.moveToLocation({ + latitude: centerLat, + longitude: centerLng, + scale: scale + }); + } catch (e) { + console.error('备用方案失败:', e); + } }, + enterpriseRender() { - for (let i = 0; i < this.cusLocationList.length; i++) { - const item = this.cusLocationList[i]; - const lat = Number(item.stationLatitude); - const lng = Number(item.stationLongitude); - - // 验证坐标有效性 - if (isNaN(lat) || isNaN(lng) || lat === 0 || lng === 0) { - console.warn('企业点位坐标无效:', item.stationName, lat, lng); - continue; - } - - const markerItem = { - id: item.id || `enterprise_${i}`, - iconPath: '/static/qiyeIcon.png', - latitude: lat, - longitude: lng, - width: 35, - height: 52, - customCallout: { - anchorY: 0, - anchorX: 0, - display: 'ALWAYS' - }, - stationType: item.stationType, - stationName: item.stationName, - stationCode: item.stationCode, - joinCluster: false, - zIndex: this.markersZIndex, - }; - this.markers.push(markerItem); - } + for (let i = 0; i < this.cusLocationList.length; i++) { + const item = this.cusLocationList[i]; + const lat = Number(item.stationLatitude); + const lng = Number(item.stationLongitude); + + if (isNaN(lat) || isNaN(lng) || lat === 0 || lng === 0) { + console.warn('企业点位坐标无效:', item.stationName, lat, lng); + continue; + } + + const markerItem = { + id: item.id || `enterprise_${i}`, + iconPath: '/static/qiyeIcon.png', + latitude: lat, + longitude: lng, + width: 35, + height: 52, + customCallout: { + anchorY: 0, + anchorX: 0, + display: 'ALWAYS' + }, + stationType: item.stationType, + stationName: item.stationName, + stationCode: item.stationCode, + joinCluster: false, + zIndex: this.markersZIndex, + }; + this.markers.push(markerItem); + } }, - + stationRender() { - if (!this.issscd) { - for (let i = 0; i < this.stationList.length; i++) { - const item = this.stationList[i]; - const lat = Number(item.stationLatitude); - const lng = Number(item.stationLongitude); - - // 验证坐标有效性 - if (isNaN(lat) || isNaN(lng) || lat === 0 || lng === 0) { - console.warn('站房点位坐标无效:', item.stationName, lat, lng); - continue; - } - - const markerItem = { - id: item.id || `station_${i}`, - iconPath: this.baseUrl + '/' + item.stationIcon, - latitude: lat, - longitude: lng, - width: 239, - height: 186, - customCallout: { - anchorY: 0, - anchorX: 0, - display: 'ALWAYS' - }, - stationType: item.stationType, - stationName: item.stationName, - stationCode: item.stationCode, - joinCluster: false, - zIndex: this.markersZIndex, - }; - this.markers.push(markerItem); - } - } - }, - - monitorRender() { - this.soilStationList.forEach((item, index) => { - const lat = Number(item.latitude); - const lng = Number(item.longitude); - - // 验证坐标有效性 - if (isNaN(lat) || isNaN(lng) || lat === 0 || lng === 0) { - console.warn('监测点位坐标无效:', item.name, lat, lng); - return; - } - - let iconPath = ''; - let width = 35; - let height = 35; - - switch (item.type) { - case 'soil': - iconPath = this.baseUrl + '/icon/device/soil.png'; - width = 32; - height = 47; - break; - case 'camera': - iconPath = this.baseUrl + '/icon/device/cam.png'; - width = 45; - height = 45; - break; - default: - iconPath = this.baseUrl + '/icon/device/default.png'; - } - - const markerItem = { - id: item.id || `device_${index}`, - iconPath: iconPath, - latitude: lat, - longitude: lng, - width: width, - height: height, - customCallout: { - anchorY: 0, - anchorX: 0, - display: 'ALWAYS' - }, - stationType: 'device', - stationName: item.name, - stationCode: item.ids, - deviceType: item.type, - joinCluster: false, - zIndex: this.markersZIndex, - }; - this.markers.push(markerItem); - }); - }, - markertap(e) { - const index = e.detail.markerId - const marker = this.markers.find(m => m.id === index); - if (marker) { - if (['orient', 'livestock'].includes(marker.stationType)) { - uni.navigateTo({ - url: `/packDetail/pages/Site/detail?item=${encodeURIComponent(JSON.stringify(marker))}` - }) - } else if (marker.stationType === 'device') { - uni.navigateTo({ - url: `/packDetail/pages/vidio/soilindex` - }) + if (!this.issscd) { + for (let i = 0; i < this.stationList.length; i++) { + const item = this.stationList[i]; + const lat = Number(item.stationLatitude); + const lng = Number(item.stationLongitude); + + if (isNaN(lat) || isNaN(lng) || lat === 0 || lng === 0) { + console.warn('站房点位坐标无效:', item.stationName, lat, lng); + continue; + } + + const markerItem = { + id: item.id || `station_${i}`, + iconPath: this.baseUrl + '/' + item.stationIcon, + latitude: lat, + longitude: lng, + width: 239, + height: 186, + customCallout: { + anchorY: 0, + anchorX: 0, + display: 'ALWAYS' + }, + stationType: item.stationType, + stationName: item.stationName, + stationCode: item.stationCode, + joinCluster: false, + zIndex: this.markersZIndex, + }; + this.markers.push(markerItem); } } }, - switch2Change(name) { // 焦点显示图例 - // 更新对应区域的状态 - let that = this; - if (name === that.lastTap) { - that.adjustMapToFitAllMarkers(); - that.lastTap = ''; - } else { - // 聚焦到特定区域 - that.adjustMapToRegion(name); - that.lastTap = name; + monitorRender() { + this.soilStationList.forEach((item, index) => { + const lat = Number(item.latitude); + const lng = Number(item.longitude); + + if (isNaN(lat) || isNaN(lng) || lat === 0 || lng === 0) { + console.warn('监测点位坐标无效:', item.name, lat, lng); + return; + } + + let iconPath = ''; + let width = 35; + let height = 35; + + switch (item.type) { + case 'soil': + iconPath = this.baseUrl + '/icon/device/soil.png'; + width = 32; + height = 47; + break; + case 'camera': + iconPath = this.baseUrl + '/icon/device/cam.png'; + width = 45; + height = 45; + break; + default: + iconPath = this.baseUrl + '/icon/device/default.png'; + } + + const markerItem = { + id: item.id || `device_${index}`, + iconPath: iconPath, + latitude: lat, + longitude: lng, + width: width, + height: height, + customCallout: { + anchorY: 0, + anchorX: 0, + display: 'ALWAYS' + }, + stationType: 'device', + stationName: item.name, + stationCode: item.ids, + deviceType: item.type, + joinCluster: false, + zIndex: this.markersZIndex, + }; + this.markers.push(markerItem); + }); + }, + + markertap(e) { + const index = e.detail.markerId; + const marker = this.markers.find(m => Number(m.id) === Number(index)); + + if (!marker) { + console.warn('未找到对应的marker, ID:', index); + return; + } + + // 企业点位点击 -> 弹出企业信息 + if (marker.stationType === 'enterprise') { + this.currentEnterprise = marker.enterpriseData || { + entName: marker.stationName || '企业名称', + entShortName: marker.entShortName || '', + entCharge: marker.entCharge || '', + entCredit: marker.entCredit || '', + entCode: marker.entCode || '', + entIntro: marker.entIntro || '暂无简介', + entPhone: marker.entPhone || '暂无', + createTime: marker.createTime || '' + }; + + this.currentMarkerId = marker.id; + this.showEnterprisePopup = true; + return; + } + + // 监测站逻辑 + if (['orient', 'livestock'].includes(marker.stationType)) { + uni.navigateTo({ + url: `/packDetail/pages/Site/detail?item=${encodeURIComponent(JSON.stringify(marker))}` + }) + } else if (marker.stationType === 'device') { + uni.navigateTo({ + url: `/packDetail/pages/vidio/soilindex` + }) } }, - // 调整地图视野以包含所有标记点(类似setFitView效果) - adjustMapToFitAllMarkers() { - if (this.mapCtx && this.markers.length > 0) { - this.mapCtx.includePoints({ - points: this.markers.map(item => ({ - latitude: item.latitude, - longitude: item.longitude - })), - padding: [60, 60, 60, 60] // 上下左右的边距 - }); - } + + // 关闭企业弹窗 + closePopup() { + this.showEnterprisePopup = false; + this.currentEnterprise = {}; + this.currentMarkerId = null; }, - adjustMapToRegion(regionName) { - // 调整地图视野到特定区域的标记点 - //stationType: "orient" 农田 - //stationType: "livestock" 畜禽 - //stationType: "watershed" 小流域 - let that = this; - let points = []; - let markers = []; - if (regionName === 'orient' || regionName === 'livestock' || regionName === 'watershed') { - // 获取团柏河区域的所有标记点 - markers = this.markers.filter(item => item.stationType === regionName); - } else if (regionName === 'soil') { - // 获取所有土壤设备标记点 - markers = this.markers.filter(item => item.type === 'soil' || item.deviceType === 'soil'); - } - console.log(this.markers) - if (markers.length > 0) { - points = markers.map(item => { - item.zIndex = (that.markersZIndex++); - return { - latitude: Number(item.latitude || item.stationLatitude), - longitude: Number(item.longitude || item.stationLongitude) - } - }); - } - if (points.length > 0 && this.mapCtx) { - this.mapCtx.includePoints({ - points: points, - padding: [80, 110, 80, 110] // 增加边距以获得更好的显示效果 - }); - } else if (points.length === 0) { - // 如果没有找到对应的标记点,显示提示 - // uni.showToast({ - // title: `未找到${regionName}相关的监测点`, - // icon: 'none' - // }); + + // 图例点击:只显示对应类型,再点一次恢复全部 + switch2Change(name) { + if (this.activeType === name) { + // 再次点击 → 取消过滤,显示全部 + this.activeType = ''; + } else { + // 点击其他 → 只显示该类型 + this.activeType = name; } + + // 视野聚焦到当前显示的 marker + this.$nextTick(() => { + this.adjustMapToVisibleMarkers(); + }); }, + + // 根据当前显示的 marker 调整视野 + adjustMapToVisibleMarkers() { + const list = this.filteredMarkers; + if (!list || list.length === 0) { + return; + } + + const points = list + .filter(item => { + const lat = Number(item.latitude); + const lng = Number(item.longitude); + return !isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0; + }) + .map(item => ({ + latitude: Number(item.latitude), + longitude: Number(item.longitude) + })); + + if (points.length === 0 || !this.mapCtx) return; + + this.mapCtx.includePoints({ + points: points, + padding: [100, 100, 100, 100] + }); + } } } \ No newline at end of file