maptalks引入minemap地图资源插件:maptalks.minedata

在基于maptalks的合作项目中,遇到minemap地图资源的集成挑战。经过一天的尝试,成功引入maptalks.minedata插件。关键在于将minemap.js和minemap.css升级到2.1.0版本,遵循官方说明进行操作。

基于合作项目需要maptalks需要使用minemap地图资源,找到插件maptalks.minedata

https://github.com/sakitam-gis/maptalks.minedata

踩了将近一天坑最终成功引入,插件官方给出的文件注意把minemap.js和minemap.css的版本升级到2.1.0即可。其他按照官方说明执行

 

minemap.js:31 Error: layers.device-labels.layout.text-background-color: unknown property "text-background-color" at Object.In [as emitValidationErrors] (minemap.js:31:158571) at ii (minemap.js:35:123706) at i._validate (minemap.js:35:147183) at i.addLayer (minemap.js:35:137345) at n.addLayer (minemap.js:35:424802) minemap.js:31 Error: layers.device-labels.layout.text-background-radius: unknown property "text-background-radius" at Object.In [as emitValidationErrors] (minemap.js:31:158571 minemap.js:31 Error: layers.device-labels.layout.text-background-padding: unknown property "text-background-padding" showDevicesOnMap(devices) { // 清除旧图层和资源 ["devices-layer", "device-labels", "selection-layer"].forEach( (layerId) => { if (this.mapObj.getLayer(layerId)) this.mapObj.removeLayer(layerId); } ); if (this.mapObj.getSource("devices-source")) { this.mapObj.removeSource("devices-source"); } // 创建GeoJSON数据源 const geojson = { type: "FeatureCollection", features: devices.map((device, index) => ({ type: "Feature", geometry: { type: "Point", coordinates: [device.longitude, device.latitude], }, properties: { ...device, index: index + 1, isSelected: this.selectedDeviceId === device.id, }, })), }; // 添加数据源 this.mapObj.addSource("devices-source", { type: "geojson", data: geojson, }); // 预加载图标 const loadImage = (name, url) => { return new Promise((resolve) => { if (this.mapObj.hasImage(name)) return resolve(); this.mapObj.loadImage(url, (error, image) => { if (error) throw error; this.mapObj.addImage(name, image); resolve(); }); }); }; Promise.all([ loadImage("jk_online", "/images/jk_online.png"), loadImage("jk_unline", "/images/jk_unline.png"), ]).then(() => { // 添加设备图标层 this.mapObj.addLayer({ id: "devices-layer", type: "symbol", source: "devices-source", layout: { "icon-image": [ "case", ["==", ["get", "online"], true], "jk_online", "jk_unline", ], "icon-size": 0.8, "icon-anchor": "bottom", "icon-allow-overlap": true, }, }); // 添加序号标签层(关键修改) this.mapObj.addLayer({ id: "device-labels", type: "symbol", source: "devices-source", layout: { "text-field": ["get", "index"], // 显示序号 "text-font": ["Noto Sans Bold"], "text-size": 12, "text-offset": [0, -1.8], // 位置调整到图标上方 "text-anchor": "top", "text-background-color": [ "case", ["==", ["get", "isSelected"], true], "#FF6666", // 选中时红色背景 "#45CCDA", // 未选中时蓝色背景 ], "text-background-radius": 10, // 圆形背景 "text-background-padding": [5, 4], // 控制圆形大小 "text-allow-overlap": true, }, paint: { "text-color": "#FFFFFF", // 白色文字 "text-halo-color": "rgba(0, 0, 0, 0.5)", "text-halo-width": 1, }, }); // 添加选中状态的高亮圈 this.mapObj.addLayer({ id: "selection-layer", type: "circle", source: "devices-source", paint: { "circle-radius": 15, "circle-color": "#FF6666", "circle-opacity": ["case", ["get", "isSelected"], 1, 0], }, }); }); // 点击事件处理(支持点击图标和标签) this.mapObj.on("click", ["devices-layer", "device-labels"], (e) => { if (e.features.length > 0) { const deviceId = e.features[0].properties.id; this.toggleDeviceSelection(deviceId); } }); // 添加悬停效果 this.mapObj.on("mouseenter", ["devices-layer", "device-labels"], () => { this.mapObj.getCanvas().style.cursor = "pointer"; }); this.mapObj.on("mouseleave", ["devices-layer", "device-labels"], () => { this.mapObj.getCanvas().style.cursor = ""; }); }, toggleDeviceSelection(deviceId) { // 支持点击取消选中 const newSelectedId = this.selectedDeviceId === deviceId ? null : deviceId; // 更新组件状态 this.selectedDeviceId = newSelectedId; // 通知父组件 this.$emit("device-selected", newSelectedId); // 更新数据源选中状态 const source = this.mapObj.getSource("devices-source"); const data = source._data; data.features = data.features.map((feature) => ({ ...feature, properties: { ...feature.properties, isSelected: feature.properties.id === newSelectedId, }, })) source.setData(data); },怎么让序号和图标同时显示,并且解决这个报错[Vue warn]: Error in nextTick: "TypeError: Cannot read properties of undefined (reading 'clearValidate')" found in ---> <SpeLineList> at src/views/components/SpeLineList/index.vue <Index> at src/views/largeScreen/SpecialLine/index.vue <App> at src/views/App.vue <Root> warn$2 @ vue.js:4857 logError @ vue.js:3547 globalHandleError @ vue.js:3543 handleError @ vue.js:3511 eval @ vue.js:3640 flushCallbacks @ vue.js:3566 Promise.then timerFunc @ vue.js:3591 nextTick @ vue.js:3648 Vue.$nextTick @ vue.js:2345 updateRouteSetting @ index.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options:641 handler @ index.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options:282 invokeWithErrorHandling @ vue.js:3519 Watcher.run @ vue.js:4057 flushSchedulerQueue @ vue.js:3141 eval @ vue.js:3638 flushCallbacks @ vue.js:3566 Promise.then timerFunc @ vue.js:3591 nextTick @ vue.js:3648 queueWatcher @ vue.js:3223 Watcher.update @ vue.js:4037 Dep.notify @ vue.js:773 reactiveSetter @ vue.js:986 proxySetter @ vue.js:4112 mapClick @ index.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options:697 invokeWithErrorHandling @ vue.js:3519 invoker @ vue.js:1461 invokeWithErrorHandling @ vue.js:3519 Vue.$emit @ vue.js:2638 _callee2$ @ index.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options:709 tryCatch @ regeneratorRuntime.js:72 eval @ regeneratorRuntime.js:161 eval @ regeneratorRuntime.js:102 asyncGeneratorStep @ asyncToGenerator.js:9 _next @ asyncToGenerator.js:28 eval @ asyncToGenerator.js:33 Wrapper @ export.js:20 eval @ asyncToGenerator.js:25 eval @ index.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options:799 ct.fire @ minemap.js:31 Rn.click @ minemap.js:35 mo.handleEvent @ minemap.js:35 minemap.js:31 TypeError: Cannot read properties of undefined (reading 'clearValidate')
07-24
showDevicesOnMap(devices) { // 存储当前设备列表,用于后续更新状态 this.currentDevices = devices; // 清除旧图层和事件监听 this.removeExistingLayers(); // 创建GeoJSON数据源(确保每个特征有唯一ID) const geojson = { type: "FeatureCollection", features: devices.map((device, index) => ({ type: "Feature", id: device.channelId, // 确保id唯一 geometry: { type: "Point", coordinates: [device.longitude, device.latitude], }, properties: { ...device, index: index + 1, // isSelected: this.selectedDeviceIds.has(device.channelId), }, })), }; // 添加数据源 this.mapObj.addSource("devices-source", { type: "geojson", data: geojson, generateId: true, // 如果特征本身没有id,则生成一个 }); // 预加载图标 const loadPromises = [ this.loadImageSafe("jk_online", "/images/jk_online.png"), this.loadImageSafe("jk_unline", "/images/jk_unline.png"), ]; // 加载图标并添加图层 Promise.all(loadPromises) .then(() => { // // 添加设备图标层 this.mapObj.addLayer({ id: "devices-layer", type: "symbol", source: "devices-source", interactive: true, // 显式启用交互 layout: { "icon-image": [ "case", ["==", ["get", "online"], true], "jk_online", "jk_unline", ], "icon-size": [ "interpolate", ["linear"], ["zoom"], 10, 0.5, // 当缩放级别为10时,大小为0.5 22, 1.0, // 当缩放级别为22时,大小为1.0 ], "icon-anchor": "bottom", "icon-allow-overlap": true, // 防止图标被隐藏 }, }); // 添加序号背景层(圆形) this.mapObj.addLayer({ id: "label-backgrounds", type: "circle", source: "devices-source", paint: { "circle-radius": 10, "circle-color": [ "case", ["==", ["feature-state", "isSelected"], true], "#FF6666", "#45CCDA", ], "circle-stroke-color": "#fff", "circle-translate": [0, -28], // 向上平移,与图标位置配合 }, }); // 添加序号文本层 this.mapObj.addLayer({ id: "device-labels", type: "symbol", source: "devices-source", layout: { "text-field": ["get", "index"], "text-size": 12, "text-offset": [0, -2.4], // 调整位置到背景圆中心 "text-anchor": "center", "text-allow-overlap": true, }, paint: { "text-color": "#FFFFFF", "text-halo-color": "rgba(0, 0, 0, 0.5)", "text-halo-width": 1, }, }); // // 设置初始特征状态 // devices.forEach((device) => { // this.mapObj.setFeatureState( // { source: "devices-source", id: device.channelId }, // { isSelected: this.selectedDeviceIds.has(device.channelId) } // ); // const state = this.mapObj.getFeatureState({ // source: 'devices-source', // id: device.channelId // }); // console.log("Feature state:", state); // }); // 确保在样式加载后更新状态 // 等待地图空闲(确保样式加载完成) this.mapObj.once('idle', () => { this.updateFeatureStates(); }); console.log(this.mapObj.getLayer('label-backgrounds').paint, 'label-backgrounds---000'); // 确认circle-color表达式正确 console.log(this.mapObj.getLayer('label-backgrounds').paint['circle-color'],'label-backgrounds---111'); // 点击事件处理 this.mapObj.off("click"); // 移除旧的监听器,避免重复绑定 this.mapObj.on("click", (e) => { const features = this.mapObj.queryRenderedFeatures(e.point, { layers: ["devices-layer"] }); if (features.length > 0) { console.log(features, '0000000000'); console.log("Clicked feature ID:", features[0].properties.channelId); // 确保与device.channelId一致 this.toggleDeviceSelection(features[0].properties.channelId); } }); }) .catch((error) => { console.error("图层添加失败:", error); }); }, // 选中 toggleDeviceSelection(deviceId) { console.log(deviceId, 'deviceId-11111111111'); // 更新选中状态 const newSelectedId = this.selectedDeviceId === deviceId ? null : deviceId; this.selectedDeviceId = newSelectedId; console.log(newSelectedId, 'newSelectedId-2222222'); // 更新所有特征的状态 // 使用Set实现多选切换 const newSelectedIds = new Set(this.selectedDeviceIds); if (newSelectedIds.has(deviceId)) { newSelectedIds.delete(deviceId); // 如果已选中,则取消 } else { newSelectedIds.add(deviceId); // 否则选中 } this.selectedDeviceIds = newSelectedIds; // 更新地图上所有特征的状态 this.updateFeatureStates(); // 立即更新特征状态 this.mapObj.setFeatureState( { source: 'devices-source', id: deviceId }, { isSelected: this.selectedDeviceIds.has(deviceId) } ); // 通知父组件 this.$emit("device-selected", newSelectedId, deviceId); }, // 更新所有特征状态 updateFeatureStates() { console.log('5555555555'); const source = this.mapObj.getSource("devices-source"); if (!source) return; // 使用设备列表而非遍历特征 this.currentDevices.forEach(device => { const isSelected = this.selectedDeviceIds.has(device.channelId); // 调试:检查特征状态 const currentState = this.mapObj.getFeatureState({ source: 'devices-source', id: device.channelId }); console.log(`Device ${device.channelId} state:`, currentState); this.mapObj.setFeatureState( { source: "devices-source", id: device.channelId }, { isSelected } ); }); },初次渲染ui {_properties: fi, _values: {…}}_properties: fidefaultPossiblyEvaluatedValues: {circle-radius: si, circle-color: si, circle-blur: si, circle-opacity: si, circle-translate: Array(2), …}defaultPropertyValues: {circle-radius: ei, circle-color: ei, circle-blur: ei, circle-opacity: ei, circle-translate: ei, …}defaultTransitionablePropertyValues: {circle-radius: ri, circle-color: ri, circle-blur: ri, circle-opacity: ri, circle-translate: ri, …}defaultTransitioningPropertyValues: {circle-radius: ii, circle-color: ii, circle-blur: ii, circle-opacity: ii, circle-translate: ii, …}overridableProperties: []properties: circle-blur: pi {specification: {…}, overrides: undefined}circle-color: pi {specification: {…}, overrides: undefined}circle-opacity: pi {specification: {…}, overrides: undefined}circle-pitch-alignment: li {specification: {…}}circle-pitch-scale: li {specification: {…}}circle-radius: pi {specification: {…}, overrides: undefined}circle-stroke-color: pi {specification: {…}, overrides: undefined}circle-stroke-opacity: pi {specification: {…}, overrides: undefined}circle-stroke-width: pi {specification: {…}, overrides: undefined}circle-translate: li {specification: {…}}circle-translate-anchor: li {specification: {…}}[[Prototype]]: Object[[Prototype]]: Object_values: {}[[Prototype]]: Objectget: ƒ (t)constructor: ƒ (t)[[Prototype]]: Object 'label-backgrounds---000' index.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options:671 undefined 'label-backgrounds---111' minemap.js:31 5555555555 minemap.js:31 Device 64030213001310050836 state: {} minemap.js:31 Device 64030213001310356419 state: {} minemap.js:31 Device 64030213001310396864 state: {} minemap.js:31 Device 64030213001310419525 state: {} minemap.js:31 Device 64030213001310513717 state: {} minemap.js:31 Device 64030213001310606506 state: {} minemap.js:31 Device 64030213001310690712 state: {} minemap.js:31 Device 64030213001310694513 state: {} minemap.js:31 Device 64030213001310993501 state: {} minemap.js:31 Device 64030214001320000824 state: {},点击其中一个[Sc]0: Sc {type: 'Feature', _vectorTileFeature: cs, properties: {…}, id: 9, layer: {…}, …}length: 1[[Prototype]]: Array(0) '0000000000' minemap.js:31 Clicked feature ID: 64030214001320000824 minemap.js:31 64030214001320000824 deviceId-11111111111 minemap.js:31 64030214001320000824 newSelectedId-2222222 minemap.js:31 5555555555 minemap.js:31 Device 64030213001310050836 state: {isSelected: false} minemap.js:31 Device 64030213001310356419 state: {isSelected: false} minemap.js:31 Device 64030213001310396864 state: {isSelected: false} minemap.js:31 Device 64030213001310419525 state: {isSelected: false} minemap.js:31 Device 64030213001310513717 state: {isSelected: false} minemap.js:31 Device 64030213001310606506 state: {isSelected: false} minemap.js:31 Device 64030213001310690712 state: {isSelected: false} minemap.js:31 Device 64030213001310694513 state: {isSelected: false} minemap.js:31 Device 64030213001310993501 state: {isSelected: false} minemap.js:31 Device 64030214001320000824 state: {isSelected: false}再次点击[Sc] '0000000000' minemap.js:31 Clicked feature ID: 64030214001320000824 minemap.js:31 64030214001320000824 deviceId-11111111111 minemap.js:31 null 'newSelectedId-2222222' minemap.js:31 5555555555 minemap.js:31 Device 64030213001310050836 state: {isSelected: false} minemap.js:31 Device 64030213001310356419 state: {isSelected: false} minemap.js:31 Device 64030213001310396864 state: {isSelected: false} minemap.js:31 Device 64030213001310419525 state: {isSelected: false} minemap.js:31 Device 64030213001310513717 state: {isSelected: false} minemap.js:31 Device 64030213001310606506 state: {isSelected: false} minemap.js:31 Device 64030213001310690712 state: {isSelected: false} minemap.js:31 Device 64030213001310694513 state: {isSelected: false} minemap.js:31 Device 64030213001310993501 state: {isSelected: false} minemap.js:31 Device 64030214001320000824 state: {isSelected: true},但是页面还是没有变化,没有切换背景色
07-25
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辣姐什么鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值