@ray-js/robot-map-sdk 0.0.3-beta-9 → 0.0.3-beta-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/MapApplication.js +1 -1
- package/dist/constant/methods.js +1 -1
- package/dist/index.d.ts +43 -1
- package/dist/index.rjs.js +1 -1
- package/dist/managers/MapManager.js +1 -1
- package/dist/utils/algorithm.js +1 -1
- package/dist-app/assets/{index-C3rjigWj.js → index-zPCor596.js} +1 -1
- package/dist-app/index.html +1 -1
- package/dist-docs/404.html +2 -2
- package/dist-docs/assets/{app.BGQfBD4o.js → app.CWzbsird.js} +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.DRAHC9Wk.js +1 -0
- package/dist-docs/assets/chunks/{VPLocalSearchBox.YvMlJA6m.js → VPLocalSearchBox.C1dzEhbA.js} +1 -1
- package/dist-docs/assets/chunks/{theme.1StzhkaW.js → theme.Dh1LIHtb.js} +2 -2
- package/dist-docs/assets/{guide_getting-started.md.D0sqgiqb.js → guide_getting-started.md.9TA9iDUN.js} +1 -1
- package/dist-docs/assets/{reference_methods.md.BkU-PXMt.js → reference_methods.md.B71e_LYO.js} +6 -3
- package/dist-docs/assets/{reference_methods.md.BkU-PXMt.lean.js → reference_methods.md.B71e_LYO.lean.js} +1 -1
- package/dist-docs/guide/advanced-usage.html +3 -3
- package/dist-docs/guide/concepts.html +3 -3
- package/dist-docs/guide/getting-started.html +5 -5
- package/dist-docs/hashmap.json +1 -1
- package/dist-docs/index.html +3 -3
- package/dist-docs/reference/callbacks.html +3 -3
- package/dist-docs/reference/config.html +3 -3
- package/dist-docs/reference/data.html +3 -3
- package/dist-docs/reference/methods.html +9 -6
- package/dist-docs/reference/runtime.html +3 -3
- package/dist-docs/reference/types.html +3 -3
- package/dist-docs/reference/utils.html +3 -3
- package/package.json +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.CSdgg9Q0.js +0 -1
- /package/dist-docs/assets/{guide_getting-started.md.D0sqgiqb.lean.js → guide_getting-started.md.9TA9iDUN.lean.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Application as e,isMobile as t,Assets as a}from"pixi.js";import{Interaction as n}from"./Interaction.js";import{merge as r}from"lodash-es";import{proxy as i}from"valtio/vanilla";import{MAIN_INSTANCE_KEY as s}from"../constant/index.js";import o from"mitt";import{Logger as c}from"../utils/logger.js";import{AppContext as h}from"./AppService.js";import{nanoid as d}from"nanoid/non-secure";import{calculateLineEndpoints as p}from"../utils/algorithm.js";import{ViewportContainer as m}from"./ViewportContainer.js";import{AppContainer as l}from"./AppContainer.js";import{MapManager as g}from"../managers/MapManager.js";import{PathManager as u}from"../managers/PathManager.js";import{HeatmapManager as w}from"../managers/HeatmapManager.js";import{ControlsManager as M}from"../managers/ControlsManager.js";import{DetectedObjectManager as y}from"../managers/DetectedObjectManager.js";import{CustomElementsManager as f}from"../managers/CustomElementsManager.js";import{RoomManager as x}from"../managers/RoomManager.js";import{getOptimalAntialiasingStrategy as S}from"../utils/browser.js";import{DEFAULT_CONFIG as b,DEFAULT_RUNTIME_CONFIG as v}from"../constant/config.js";class C extends e{mapState=null;components={};managers={};config=b;runtime;scaleMin=.5;scaleMax=5;events={};instanceKey;containerElement;emitter=o();tickerState={renderReasons:new Set,renderTimer:null};pendingAsyncRender=!1;isFirstMapDraw=!0;constructor(e=s){super(),this.instanceKey=e,h.registerInstance(e,this),globalThis.__PIXI_APP__=this}async initialize(e){return h.provideAsync(this,async()=>{const{resizeTo:a,events:n,config:o,runtime:c={},...h}=e;this.config=r(this.config,o??{}),this.runtime=i(Object.assign({},v,c));const d=this.instanceKey===s;this.containerElement=a;const p=d?{textureGCMaxIdle:t.any?180:3600,textureGCCheckCountMax:t.any?100:50,autoStart:!1,eventFeatures:{move:!0,globalMove:!1,click:!0,wheel:!0}}:{textureGCMaxIdle:60,textureGCCheckCountMax:10,autoStart:!1,eventFeatures:{move:!1,globalMove:!1,click:!1,wheel:!1}};await this.init({resizeTo:d?a:void 0,preferWebGLVersion:2,resolution:window.devicePixelRatio||1,antialias:S(),autoDensity:!0,backgroundColor:this.config.global.backgroundColor,...p,...h}),this.preloadAssets(),this.scaleMax=this.config.interaction.zoomRange.max,this.scaleMin=this.config.interaction.zoomRange.min,this.events=n,this.initializeViewportContainer(),this.initializeInteraction(),this.initializeAppContainer(),this.managers.mapManager=new g,this.managers.heatmapManager=new w,this.managers.pathManager=new u,this.managers.controlsManager=new M,this.managers.detectedObjectManager=new y,this.managers.customElementsManager=new f,this.managers.roomsManager=new x,document.addEventListener("visibilitychange",this.onVisibilityChange)})}async drawMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawMap",e);const{size:t,resolution:a,origin:n}=e;n[0]===this.mapState?.origin.x&&n[1]===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(...n),this.managers.controlsManager.updatePositionByOrigin(...n),this.managers.detectedObjectManager.updatePositionByOrigin(...n),this.managers.customElementsManager.updatePositionByOrigin(...n)),this.mapState={id:e.id,status:1===e.status,origin:{x:n[0],y:n[1]},charger:{x:e.charger.coordinate[0],y:e.charger.coordinate[1]},chargerDirection:e.charger.angle??0,resolution:a,width:t[0],height:t[1]},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawMap(e),this.renderOnce()})}async drawRasterMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawRasterMap",e);const{mapHeader:t,mapData:a}=e,{originX:n,originY:r}=t;n===this.mapState?.origin.x&&r===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(n,r),this.managers.controlsManager.updatePositionByOrigin(n,r),this.managers.detectedObjectManager.updatePositionByOrigin(n,r),this.managers.customElementsManager.updatePositionByOrigin(n,r)),this.mapState={id:t.id,status:t.mapStable,origin:{x:n,y:r},charger:{x:t.chargeX,y:t.chargeY},chargerDirection:t.chargeDirection??0,resolution:100*t.mapResolution,width:t.mapWidth,height:t.mapHeight,version:t.version},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawRasterMap(a.parsed,this.mapState),this.renderOnce()})}drawPath(e){return h.provide(this,()=>{c.log("[Path] drawPath",e),this.events?.onPathDrawed?.({id:e.pathHeader.pathId,type:e.pathHeader.type,direction:e.pathHeader.direction,count:e.pathHeader.count,initFlag:e.pathHeader.initFlag,robotPosition:e.pathPoints[e.pathPoints.length-1]??null}),this.managers.pathManager.draw(e),this.renderOnce()})}async drawRoomProperty(e){return h.provide(this,()=>{c.log("[Room] drawRoomProperty",e),this.events?.onRoomPropertiesDrawed?.(e),this.managers.roomsManager.drawRoomProperty(e),this.renderOnceNextFrame()})}drawHeatmap({mapData:e,heatmapPoints:t,useGradient:a=!0}){return h.provide(this,()=>{c.log("[Heatmap] drawHeatmap",t),this.managers.heatmapManager.draw({mapData:e,heatmapPoints:t,useGradient:a}),this.renderOnce()})}drawForbiddenSweepZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenSweepZones",e),this.managers.controlsManager.drawForbiddenSweepZones(e),this.renderOnceNextFrame()})}drawForbiddenMopZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenMopZones",e),this.managers.controlsManager.drawForbiddenMopZones(e),this.renderOnceNextFrame()})}drawCleanZones(e){return h.provide(this,()=>{c.log("[Controls] drawCleanZones",e),this.managers.controlsManager.drawCleanZones(e),this.renderOnceNextFrame()})}drawVirtualWalls(e){return h.provide(this,()=>{c.log("[Controls] drawVirtualWalls",e),this.managers.controlsManager.drawVirtualWalls(e),this.renderOnceNextFrame()})}drawSpots(e){return h.provide(this,()=>{c.log("[Controls] drawSpots",e),this.managers.controlsManager.drawSpots(e),this.renderOnceNextFrame()})}async drawDetectedObjects(e){return h.provideAsync(this,async()=>{c.log("[DetectedObject] drawDetectedObjects",e),await this.managers.detectedObjectManager.drawDetectedObjects(e),this.renderOnceNextFrame()})}async drawCustomElements(e){return h.provideAsync(this,async()=>{c.log("[CustomElements] drawCustomElements",e),await this.managers.customElementsManager.drawCustomElements(e),this.renderOnceNextFrame()})}getForbiddenSweepZones(){return this.managers.controlsManager.getForbiddenSweepZones()}getForbiddenMopZones(){return this.managers.controlsManager.getForbiddenMopZones()}getCleanZones(){return this.managers.controlsManager.getCleanZones()}getVirtualWalls(){return this.managers.controlsManager.getVirtualWalls()}getSpots(){return this.managers.controlsManager.getSpots()}getEffectiveDividerPoints(){return this.managers.controlsManager.getEffectiveDividerPoints()}getDividerEndPoints(){return this.managers.controlsManager.getDividerEndPoints()}resetPanZoom(){this.components.interaction.setPanZoom()}fitMapToView(e,t=!1){return h.provide(this,()=>{if(!e||e.minX===e.maxX||e.minY===e.maxY)return void c.warn("地图边界无效,无法自动适配视图");const a=this.config.map.autoPaddingPercent||.1,n=this.getViewportBounds(),r=e.maxX-e.minX,i=e.maxY-e.minY,s=n.width,o=n.height,h=s*(1-2*a)/r,d=o*(1-2*a)/i,p=Math.min(h,d),m=Math.max(this.config.interaction.fitMinScale,this.scaleMin),l=Math.min(this.config.interaction.fitMaxScale,this.scaleMax),g=Math.max(m,Math.min(l,p)),u=s/2-(e.minX+r/2)*g,w=o/2-(e.minY+i/2)*g;this.components.interaction.setPanZoom({targetPosition:{x:u,y:w},targetScale:{x:g,y:g},setCenter:!0,setScale:!0},t)})}getViewportBounds(){return this.components.viewportContainer?.getViewportBounds()||{x:0,y:0,width:this.renderer.width,height:this.renderer.height}}updateRuntime(e){Object.assign(this.runtime,e),this.renderOnceNextFrame()}metersToPixels(e){return this.mapState?.resolution?e*(1/(this.mapState.resolution/100)):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),20*e)}pixelsToMeters(e){return this.mapState?.resolution?e*(this.mapState.resolution/100):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),.05*e)}toFixedSize(e,t){return e/(t??this.components.appContainer.scale.x)}fromFixedSize(e,t){return e*(t??this.components.appContainer.scale.x)}getViewportCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate center point"),null;const e=this.getViewportBounds(),t=e.x+e.width/2,a=e.y+e.height/2,n=this.components.appContainer,r=n.scale.x,i=(t-n.x)/r,s=(a-n.y)/r;return{x:i-this.mapState.origin.x,y:s-this.mapState.origin.y}}getMapCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate map center point"),null;const e=this.managers.mapManager.mapBounds;if(e.minX===1/0||e.minY===1/0||e.maxX===-1/0||e.maxY===-1/0)return c.warn("Invalid map bounds, cannot calculate map center point"),null;const t=(e.minX+e.maxX)/2,a=(e.minY+e.maxY)/2;return{x:t-this.mapState.origin.x,y:a-this.mapState.origin.y}}getWallPointsByViewportCenter(e){const{width:t=this.config.controls.virtualWall.minWidth,direction:a="horizontal",offsetX:n=0,offsetY:r=0}=e||{},i=this.getViewportCenterPoint()||{x:0,y:0},s=this.metersToPixels(t);return p(i.x,i.y,s,a).map(e=>({x:e.x+n,y:e.y+r}))}getForbiddenSweepZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenSweepZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getForbiddenMopZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenMopZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getCleanZonePointsByViewportCenter(e){const t=this.config.controls.cleanZone,{size:a=t.minSize,offsetX:n=0,offsetY:r=0}=e||{};return this.generateZonePoints(a,n,r)}getSpotPointByViewportCenter(e){const{offsetX:t=0,offsetY:a=0}=e||{},n=this.getViewportCenterPoint()||{x:0,y:0};return{x:n.x+t,y:n.y+a}}async snapshot(){this.render(),await new Promise(e=>setTimeout(e,0));const{snapshot:e}=this.config;return await this.renderer.extract.base64({target:this.components.appContainer,format:e.format,quality:e.quality,resolution:e.resolution,antialias:e.antialias})}async snapshotByData({map:e,path:t,roomProperties:a,customElements:n,forbiddenSweepZones:r,forbiddenMopZones:i,virtualWalls:s,detectedObjects:o},h={}){const p=`SNAPSHOT_${d()}`;c.log(`[MapApplication] ${p} snapshot start`);const m=new C(p);try{if(await m.initialize({config:this.config,runtime:h}),!e)throw new Error("Map data is required");if(e.startsWith("7b22")){const{decodeMapStructured:t}=await import("@ray-js/robot-protocol"),a=t(e);await m.drawMap(a)}else{const{decodeMap:t}=await import("@ray-js/robot-protocol"),a=t(e);if(!a)throw new Error("Failed to decode raster map data");await m.drawRasterMap(a)}if(t){const{decodePath:e}=await import("@ray-js/robot-protocol"),a=e(t);m.drawPath(a)}a&&a.length>0&&m.drawRoomProperty(a),r&&r.length>0&&m.drawForbiddenSweepZones(r),i&&i.length>0&&m.drawForbiddenMopZones(i),s&&s.length>0&&m.drawVirtualWalls(s),o&&o.length>0&&await m.drawDetectedObjects(o),n&&n.length>0&&await m.drawCustomElements(n);const d=await m.snapshot();return c.log(`[MapApplication] ${p} snapshot completed successfully`),d}catch(e){throw c.error(`[MapApplication] ${p} snapshot other map failed:`,e),e}finally{c.log(`[MapApplication] ${p} destroy`),m.destroy()}}renderOnce(){c.log("[Pixi] renderOnce"),this.render()}renderOnceNextFrame(){this.pendingAsyncRender||(this.pendingAsyncRender=!0,requestAnimationFrame(()=>{c.log("[Pixi] renderOnceNextFrame"),this.render(),this.pendingAsyncRender=!1}))}requestRender(e,t=!1){t?(this.tickerState.renderReasons.add(e),this.ticker.started||(c.debug(`🎬 [Ticker] START: ${e}`),this.ticker.start())):this.renderOnceNextFrame()}stopRender(e){this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&this.scheduleStopRender("final",100)}destroy(){h.unregisterInstance(this.instanceKey),this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderReasons.clear(),this.emitter.all.clear(),document.removeEventListener("visibilitychange",this.onVisibilityChange),this.managers.pathManager.destroy(),this.managers.mapManager.destroy(),this.managers.controlsManager.destroy(),this.managers.detectedObjectManager.destroy(),this.managers.customElementsManager.destroy(),this.managers.roomsManager.destroy(),this.components.interaction.destroy(),this.components.viewportContainer.destroy(),this.components.appContainer.destroy(),super.destroy()}initializeViewportContainer(){this.components.viewportContainer=new m(this.config,this.containerElement),this.stage.addChild(this.components.viewportContainer)}initializeAppContainer(){this.components.appContainer=new l,this.components.interaction.addChild(this.components.appContainer)}initializeInteraction(){this.components.interaction=new n,this.components.viewportContainer.addChild(this.components.interaction)}scheduleStopRender(e,t){this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderTimer=setTimeout(()=>{this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&(c.debug("⏸️ [Ticker] STOP"),this.ticker.stop())},t)}generateZonePoints(e,t,a){const n=this.getViewportCenterPoint()||{x:0,y:0},r=this.metersToPixels(e)/2,i=n.x+t,s=n.y+a;return[{x:i-r,y:s-r},{x:i+r,y:s-r},{x:i+r,y:s+r},{x:i-r,y:s+r}]}preloadAssets(){const e=this.config.robot.icon.src,t=this.config.chargingStation.icon.src,n=[];a.add({alias:"robot",src:e}),n.push("robot"),a.add({alias:"chargingStation",src:t}),n.push("chargingStation"),a.add({alias:"deleteIcon",src:this.config.controls.deleteIconSrc}),n.push("deleteIcon"),a.add({alias:"rotateIcon",src:this.config.controls.rotateIconSrc}),n.push("rotateIcon"),a.add({alias:"scaleIcon",src:this.config.controls.scaleIconSrc}),n.push("scaleIcon"),a.add({alias:"moveIcon",src:this.config.controls.moveIconSrc}),n.push("moveIcon"),a.add({alias:"checkmark",src:this.config.room.selectionIndicator.iconSrc}),n.push("checkmark"),a.add({alias:"spotIcon",src:this.config.controls.spot.iconSrc}),n.push("spotIcon"),this.config.room.property.cleanMode.assets.forEach((e,t)=>{const r=`cleanMode_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.suction.assets.forEach((e,t)=>{const r=`fan_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.cistern.assets.forEach((e,t)=>{const r=`water_${t}`;a.add({alias:r,src:e}),n.push(r)}),this.config.room.property.cleanTimes.assets.forEach((e,t)=>{const r=`cleanTimes${t+1}`;a.add({alias:r,src:e}),n.push(r)}),a.backgroundLoad(n)}onVisibilityChange=()=>{"visible"===document.visibilityState||this.components.interaction?.clearTouches()}}export{C as MapApplication};
|
|
1
|
+
import{Application as e,isMobile as t,Assets as n}from"pixi.js";import{Interaction as a}from"./Interaction.js";import{merge as r}from"lodash-es";import{proxy as i}from"valtio/vanilla";import{MAIN_INSTANCE_KEY as o}from"../constant/index.js";import s from"mitt";import{Logger as c}from"../utils/logger.js";import{AppContext as h}from"./AppService.js";import{nanoid as d}from"nanoid/non-secure";import{calculateLineEndpoints as p,areStructuredRoomsAdjacent as m,areMultipleRoomsConnected as l,areRasterRoomsAdjacent as g}from"../utils/algorithm.js";import{ViewportContainer as u}from"./ViewportContainer.js";import{AppContainer as w}from"./AppContainer.js";import{MapManager as f}from"../managers/MapManager.js";import{PathManager as M}from"../managers/PathManager.js";import{HeatmapManager as y}from"../managers/HeatmapManager.js";import{ControlsManager as x}from"../managers/ControlsManager.js";import{DetectedObjectManager as S}from"../managers/DetectedObjectManager.js";import{CustomElementsManager as v}from"../managers/CustomElementsManager.js";import{RoomManager as b}from"../managers/RoomManager.js";import{getOptimalAntialiasingStrategy as P}from"../utils/browser.js";import{DEFAULT_CONFIG as C,DEFAULT_RUNTIME_CONFIG as R}from"../constant/config.js";class O extends e{mapState=null;components={};managers={};config=C;runtime;scaleMin=.5;scaleMax=5;events={};instanceKey;containerElement;emitter=s();tickerState={renderReasons:new Set,renderTimer:null};pendingAsyncRender=!1;isFirstMapDraw=!0;constructor(e=o){super(),this.instanceKey=e,h.registerInstance(e,this),globalThis.__PIXI_APP__=this}async initialize(e){return h.provideAsync(this,async()=>{const{resizeTo:n,events:a,config:s,runtime:c={},...h}=e;this.config=r(this.config,s??{}),this.runtime=i(Object.assign({},R,c));const d=this.instanceKey===o;this.containerElement=n;const p=d?{textureGCMaxIdle:t.any?180:3600,textureGCCheckCountMax:t.any?100:50,autoStart:!1,eventFeatures:{move:!0,globalMove:!1,click:!0,wheel:!0}}:{textureGCMaxIdle:60,textureGCCheckCountMax:10,autoStart:!1,eventFeatures:{move:!1,globalMove:!1,click:!1,wheel:!1}};await this.init({resizeTo:d?n:void 0,preferWebGLVersion:2,resolution:window.devicePixelRatio||1,antialias:P(),autoDensity:!0,backgroundColor:this.config.global.backgroundColor,...p,...h}),this.preloadAssets(),this.scaleMax=this.config.interaction.zoomRange.max,this.scaleMin=this.config.interaction.zoomRange.min,this.events=a,this.initializeViewportContainer(),this.initializeInteraction(),this.initializeAppContainer(),this.managers.mapManager=new f,this.managers.heatmapManager=new y,this.managers.pathManager=new M,this.managers.controlsManager=new x,this.managers.detectedObjectManager=new S,this.managers.customElementsManager=new v,this.managers.roomsManager=new b,document.addEventListener("visibilitychange",this.onVisibilityChange)})}async drawMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawMap",e);const{size:t,resolution:n,origin:a}=e;a[0]===this.mapState?.origin.x&&a[1]===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(...a),this.managers.controlsManager.updatePositionByOrigin(...a),this.managers.detectedObjectManager.updatePositionByOrigin(...a),this.managers.customElementsManager.updatePositionByOrigin(...a)),this.mapState={id:e.id,status:1===e.status,origin:{x:a[0],y:a[1]},charger:{x:e.charger.coordinate[0],y:e.charger.coordinate[1]},chargerDirection:e.charger.angle??0,resolution:n,width:t[0],height:t[1]},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawMap(e),this.renderOnce()})}async drawRasterMap(e){return h.provideAsync(this,async()=>{c.log("[Map] drawRasterMap",e);const{mapHeader:t,mapData:n}=e,{originX:a,originY:r}=t;a===this.mapState?.origin.x&&r===this.mapState?.origin.y||(this.managers.pathManager.updatePositionByOrigin(a,r),this.managers.controlsManager.updatePositionByOrigin(a,r),this.managers.detectedObjectManager.updatePositionByOrigin(a,r),this.managers.customElementsManager.updatePositionByOrigin(a,r)),this.mapState={id:t.id,status:t.mapStable,origin:{x:a,y:r},charger:{x:t.chargeX,y:t.chargeY},chargerDirection:t.chargeDirection??0,resolution:100*t.mapResolution,width:t.mapWidth,height:t.mapHeight,version:t.version},this.isFirstMapDraw&&(this.isFirstMapDraw=!1,this.events?.onMapFirstDrawed?.(this.mapState)),this.events?.onMapDrawed?.(this.mapState),await this.managers.mapManager.drawRasterMap(n.parsed,this.mapState),this.renderOnce()})}drawPath(e){return h.provide(this,()=>{c.log("[Path] drawPath",e),this.events?.onPathDrawed?.({id:e.pathHeader.pathId,type:e.pathHeader.type,direction:e.pathHeader.direction,count:e.pathHeader.count,initFlag:e.pathHeader.initFlag,robotPosition:e.pathPoints[e.pathPoints.length-1]??null}),this.managers.pathManager.draw(e),this.renderOnce()})}async drawRoomProperty(e){return h.provide(this,()=>{c.log("[Room] drawRoomProperty",e),this.events?.onRoomPropertiesDrawed?.(e),this.managers.roomsManager.drawRoomProperty(e),this.renderOnceNextFrame()})}drawHeatmap({mapData:e,heatmapPoints:t,useGradient:n=!0}){return h.provide(this,()=>{c.log("[Heatmap] drawHeatmap",t),this.managers.heatmapManager.draw({mapData:e,heatmapPoints:t,useGradient:n}),this.renderOnce()})}drawForbiddenSweepZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenSweepZones",e),this.managers.controlsManager.drawForbiddenSweepZones(e),this.renderOnceNextFrame()})}drawForbiddenMopZones(e){return h.provide(this,()=>{c.log("[Controls] drawForbiddenMopZones",e),this.managers.controlsManager.drawForbiddenMopZones(e),this.renderOnceNextFrame()})}drawCleanZones(e){return h.provide(this,()=>{c.log("[Controls] drawCleanZones",e),this.managers.controlsManager.drawCleanZones(e),this.renderOnceNextFrame()})}drawVirtualWalls(e){return h.provide(this,()=>{c.log("[Controls] drawVirtualWalls",e),this.managers.controlsManager.drawVirtualWalls(e),this.renderOnceNextFrame()})}drawSpots(e){return h.provide(this,()=>{c.log("[Controls] drawSpots",e),this.managers.controlsManager.drawSpots(e),this.renderOnceNextFrame()})}async drawDetectedObjects(e){return h.provideAsync(this,async()=>{c.log("[DetectedObject] drawDetectedObjects",e),await this.managers.detectedObjectManager.drawDetectedObjects(e),this.renderOnceNextFrame()})}async drawCustomElements(e){return h.provideAsync(this,async()=>{c.log("[CustomElements] drawCustomElements",e),await this.managers.customElementsManager.drawCustomElements(e),this.renderOnceNextFrame()})}getForbiddenSweepZones(){return this.managers.controlsManager.getForbiddenSweepZones()}getForbiddenMopZones(){return this.managers.controlsManager.getForbiddenMopZones()}getCleanZones(){return this.managers.controlsManager.getCleanZones()}getVirtualWalls(){return this.managers.controlsManager.getVirtualWalls()}getSpots(){return this.managers.controlsManager.getSpots()}getEffectiveDividerPoints(){return this.managers.controlsManager.getEffectiveDividerPoints()}getDividerEndPoints(){return this.managers.controlsManager.getDividerEndPoints()}resetPanZoom(){this.components.interaction.setPanZoom()}fitMapToView(e,t=!1){return h.provide(this,()=>{if(!e||e.minX===e.maxX||e.minY===e.maxY)return void c.warn("地图边界无效,无法自动适配视图");const n=this.config.map.autoPaddingPercent||.1,a=this.getViewportBounds(),r=e.maxX-e.minX,i=e.maxY-e.minY,o=a.width,s=a.height,h=o*(1-2*n)/r,d=s*(1-2*n)/i,p=Math.min(h,d),m=Math.max(this.config.interaction.fitMinScale,this.scaleMin),l=Math.min(this.config.interaction.fitMaxScale,this.scaleMax),g=Math.max(m,Math.min(l,p)),u=o/2-(e.minX+r/2)*g,w=s/2-(e.minY+i/2)*g;this.components.interaction.setPanZoom({targetPosition:{x:u,y:w},targetScale:{x:g,y:g},setCenter:!0,setScale:!0},t)})}getViewportBounds(){return this.components.viewportContainer?.getViewportBounds()||{x:0,y:0,width:this.renderer.width,height:this.renderer.height}}updateRuntime(e){Object.assign(this.runtime,e),this.renderOnceNextFrame()}metersToPixels(e){return this.mapState?.resolution?e*(1/(this.mapState.resolution/100)):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),20*e)}pixelsToMeters(e){return this.mapState?.resolution?e*(this.mapState.resolution/100):(c.warn("Map resolution not available, using default resolution (5cm/pixel)"),.05*e)}toFixedSize(e,t){return e/(t??this.components.appContainer.scale.x)}fromFixedSize(e,t){return e*(t??this.components.appContainer.scale.x)}getViewportCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate center point"),null;const e=this.getViewportBounds(),t=e.x+e.width/2,n=e.y+e.height/2,a=this.components.appContainer,r=a.scale.x,i=(t-a.x)/r,o=(n-a.y)/r;return{x:i-this.mapState.origin.x,y:o-this.mapState.origin.y}}getMapCenterPoint(){if(!this.mapState)return c.warn("Map state not available, cannot calculate map center point"),null;const e=this.managers.mapManager.mapBounds;if(e.minX===1/0||e.minY===1/0||e.maxX===-1/0||e.maxY===-1/0)return c.warn("Invalid map bounds, cannot calculate map center point"),null;const t=(e.minX+e.maxX)/2,n=(e.minY+e.maxY)/2;return{x:t-this.mapState.origin.x,y:n-this.mapState.origin.y}}getWallPointsByViewportCenter(e){const{width:t=this.config.controls.virtualWall.minWidth,direction:n="horizontal",offsetX:a=0,offsetY:r=0}=e||{},i=this.getViewportCenterPoint()||{x:0,y:0},o=this.metersToPixels(t);return p(i.x,i.y,o,n).map(e=>({x:e.x+a,y:e.y+r}))}getForbiddenSweepZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenSweepZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getForbiddenMopZonePointsByViewportCenter(e){const t=this.config.controls.forbiddenMopZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getCleanZonePointsByViewportCenter(e){const t=this.config.controls.cleanZone,{size:n=t.minSize,offsetX:a=0,offsetY:r=0}=e||{};return this.generateZonePoints(n,a,r)}getSpotPointByViewportCenter(e){const{offsetX:t=0,offsetY:n=0}=e||{},a=this.getViewportCenterPoint()||{x:0,y:0};return{x:a.x+t,y:a.y+n}}areRoomsAdjacent(e,t=3){return h.provide(this,()=>{if(!e||0===e.length)return c.warn("[Room] No room IDs provided"),!1;if(1===e.length)return!0;const n=Array.from(new Set(e));return 1===n.length||(void 0!==this.mapState?.version?this.areRasterRoomsAdjacentInternal(n,t):this.areStructuredRoomsAdjacentInternal(n,t))})}areStructuredRoomsAdjacentInternal(e,t){const n=[];for(const t of e){const e=this.managers.mapManager.getRoomById(t);if(!e)return c.warn(`[Room] Room ${t} not found in map`),!1;if(!e.outlinePoints||0===e.outlinePoints.length)return c.warn(`[Room] Room ${t} has no outline points`),!1;n.push({id:t,points:e.outlinePoints})}const a=[];for(let e=0;e<n.length;e++)for(let r=e+1;r<n.length;r++){const i=n[e],o=n[r];m(i.points,o.points,t)&&a.push([e,r])}return l(n.length,a)}areRasterRoomsAdjacentInternal(e,t){if(!this.mapState)return c.warn("[Room] Map state not available"),!1;const n=this.mapState.width,a=[];for(const t of e){const e=this.managers.mapManager.getRasterRoomPixels(t);if(!e)return c.warn(`[Room] Room ${t} pixel data not found in raster map`),!1;a.push({id:t,pixels:e})}const r=[];for(let e=0;e<a.length;e++)for(let i=e+1;i<a.length;i++){const o=a[e],s=a[i];g(o.pixels,s.pixels,n,t)&&r.push([e,i])}return l(a.length,r)}async snapshot(){this.render(),await new Promise(e=>setTimeout(e,0));const{snapshot:e}=this.config;return await this.renderer.extract.base64({target:this.components.appContainer,format:e.format,quality:e.quality,resolution:e.resolution,antialias:e.antialias})}async snapshotByData({map:e,path:t,roomProperties:n,customElements:a,forbiddenSweepZones:r,forbiddenMopZones:i,virtualWalls:o,detectedObjects:s},h={}){const p=`SNAPSHOT_${d()}`;c.log(`[MapApplication] ${p} snapshot start`);const m=new O(p);try{if(await m.initialize({config:this.config,runtime:h}),!e)throw new Error("Map data is required");if(e.startsWith("7b22")){const{decodeMapStructured:t}=await import("@ray-js/robot-protocol"),n=t(e);await m.drawMap(n)}else{const{decodeMap:t}=await import("@ray-js/robot-protocol"),n=t(e);if(!n)throw new Error("Failed to decode raster map data");await m.drawRasterMap(n)}if(t){const{decodePath:e}=await import("@ray-js/robot-protocol"),n=e(t);m.drawPath(n)}n&&n.length>0&&m.drawRoomProperty(n),r&&r.length>0&&m.drawForbiddenSweepZones(r),i&&i.length>0&&m.drawForbiddenMopZones(i),o&&o.length>0&&m.drawVirtualWalls(o),s&&s.length>0&&await m.drawDetectedObjects(s),a&&a.length>0&&await m.drawCustomElements(a);const d=await m.snapshot();return c.log(`[MapApplication] ${p} snapshot completed successfully`),d}catch(e){throw c.error(`[MapApplication] ${p} snapshot other map failed:`,e),e}finally{c.log(`[MapApplication] ${p} destroy`),m.destroy()}}renderOnce(){c.log("[Pixi] renderOnce"),this.render()}renderOnceNextFrame(){this.pendingAsyncRender||(this.pendingAsyncRender=!0,requestAnimationFrame(()=>{c.log("[Pixi] renderOnceNextFrame"),this.render(),this.pendingAsyncRender=!1}))}requestRender(e,t=!1){t?(this.tickerState.renderReasons.add(e),this.ticker.started||(c.debug(`🎬 [Ticker] START: ${e}`),this.ticker.start())):this.renderOnceNextFrame()}stopRender(e){this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&this.scheduleStopRender("final",100)}destroy(){h.unregisterInstance(this.instanceKey),this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderReasons.clear(),this.emitter.all.clear(),document.removeEventListener("visibilitychange",this.onVisibilityChange),this.managers.pathManager.destroy(),this.managers.mapManager.destroy(),this.managers.controlsManager.destroy(),this.managers.detectedObjectManager.destroy(),this.managers.customElementsManager.destroy(),this.managers.roomsManager.destroy(),this.components.interaction.destroy(),this.components.viewportContainer.destroy(),this.components.appContainer.destroy(),super.destroy()}initializeViewportContainer(){this.components.viewportContainer=new u(this.config,this.containerElement),this.stage.addChild(this.components.viewportContainer)}initializeAppContainer(){this.components.appContainer=new w,this.components.interaction.addChild(this.components.appContainer)}initializeInteraction(){this.components.interaction=new a,this.components.viewportContainer.addChild(this.components.interaction)}scheduleStopRender(e,t){this.tickerState.renderTimer&&clearTimeout(this.tickerState.renderTimer),this.tickerState.renderTimer=setTimeout(()=>{this.tickerState.renderReasons.delete(e),0===this.tickerState.renderReasons.size&&(c.debug("⏸️ [Ticker] STOP"),this.ticker.stop())},t)}generateZonePoints(e,t,n){const a=this.getViewportCenterPoint()||{x:0,y:0},r=this.metersToPixels(e)/2,i=a.x+t,o=a.y+n;return[{x:i-r,y:o-r},{x:i+r,y:o-r},{x:i+r,y:o+r},{x:i-r,y:o+r}]}preloadAssets(){const e=this.config.robot.icon.src,t=this.config.chargingStation.icon.src,a=[];n.add({alias:"robot",src:e}),a.push("robot"),n.add({alias:"chargingStation",src:t}),a.push("chargingStation"),n.add({alias:"deleteIcon",src:this.config.controls.deleteIconSrc}),a.push("deleteIcon"),n.add({alias:"rotateIcon",src:this.config.controls.rotateIconSrc}),a.push("rotateIcon"),n.add({alias:"scaleIcon",src:this.config.controls.scaleIconSrc}),a.push("scaleIcon"),n.add({alias:"moveIcon",src:this.config.controls.moveIconSrc}),a.push("moveIcon"),n.add({alias:"checkmark",src:this.config.room.selectionIndicator.iconSrc}),a.push("checkmark"),n.add({alias:"spotIcon",src:this.config.controls.spot.iconSrc}),a.push("spotIcon"),this.config.room.property.cleanMode.assets.forEach((e,t)=>{const r=`cleanMode_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.suction.assets.forEach((e,t)=>{const r=`fan_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.cistern.assets.forEach((e,t)=>{const r=`water_${t}`;n.add({alias:r,src:e}),a.push(r)}),this.config.room.property.cleanTimes.assets.forEach((e,t)=>{const r=`cleanTimes${t+1}`;n.add({alias:r,src:e}),a.push(r)}),n.backgroundLoad(a)}onVisibilityChange=()=>{"visible"===document.visibilityState||this.components.interaction?.clearTouches()}}export{O as MapApplication};
|
package/dist/constant/methods.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=["resetPanZoom","getForbiddenSweepZones","getForbiddenMopZones","getCleanZones","getVirtualWalls","getSpots","getViewportCenterPoint","getMapCenterPoint","getWallPointsByViewportCenter","getForbiddenSweepZonePointsByViewportCenter","getForbiddenMopZonePointsByViewportCenter","getCleanZonePointsByViewportCenter","getSpotPointByViewportCenter","getEffectiveDividerPoints","getDividerEndPoints","snapshot","snapshotByData"],o=["onMapFirstDrawed","onMapDrawed","onPathDrawed","onRoomPropertiesDrawed","onClickRoom","onClickRoomProperties","onRemoveForbiddenSweepZone","onRemoveForbiddenMopZone","onRemoveCleanZone","onRemoveVirtualWall","onUpdateForbiddenSweepZone","onUpdateForbiddenMopZone","onUpdateCleanZone","onUpdateVirtualWall","onUpdateSpot","onUpdateDivider","onClickForbiddenSweepZone","onClickForbiddenMopZone","onClickCleanZone","onClickVirtualWall","onClickSpot","onClickDetectedObject","onClickCustomElement"];export{e as MAP_API_METHODS,o as MAP_CALLBACK_METHODS};
|
|
1
|
+
const e=["areRoomsAdjacent","resetPanZoom","getForbiddenSweepZones","getForbiddenMopZones","getCleanZones","getVirtualWalls","getSpots","getViewportCenterPoint","getMapCenterPoint","getWallPointsByViewportCenter","getForbiddenSweepZonePointsByViewportCenter","getForbiddenMopZonePointsByViewportCenter","getCleanZonePointsByViewportCenter","getSpotPointByViewportCenter","getEffectiveDividerPoints","getDividerEndPoints","snapshot","snapshotByData"],o=["onMapFirstDrawed","onMapDrawed","onPathDrawed","onRoomPropertiesDrawed","onClickRoom","onClickRoomProperties","onRemoveForbiddenSweepZone","onRemoveForbiddenMopZone","onRemoveCleanZone","onRemoveVirtualWall","onUpdateForbiddenSweepZone","onUpdateForbiddenMopZone","onUpdateCleanZone","onUpdateVirtualWall","onUpdateSpot","onUpdateDivider","onClickForbiddenSweepZone","onClickForbiddenMopZone","onClickCleanZone","onClickVirtualWall","onClickSpot","onClickDetectedObject","onClickCustomElement"];export{e as MAP_API_METHODS,o as MAP_CALLBACK_METHODS};
|
package/dist/index.d.ts
CHANGED
|
@@ -1727,7 +1727,7 @@ declare type Managers = {
|
|
|
1727
1727
|
roomsManager: RoomManager;
|
|
1728
1728
|
};
|
|
1729
1729
|
|
|
1730
|
-
export declare const MAP_API_METHODS: readonly ["resetPanZoom", "getForbiddenSweepZones", "getForbiddenMopZones", "getCleanZones", "getVirtualWalls", "getSpots", "getViewportCenterPoint", "getMapCenterPoint", "getWallPointsByViewportCenter", "getForbiddenSweepZonePointsByViewportCenter", "getForbiddenMopZonePointsByViewportCenter", "getCleanZonePointsByViewportCenter", "getSpotPointByViewportCenter", "getEffectiveDividerPoints", "getDividerEndPoints", "snapshot", "snapshotByData"];
|
|
1730
|
+
export declare const MAP_API_METHODS: readonly ["areRoomsAdjacent", "resetPanZoom", "getForbiddenSweepZones", "getForbiddenMopZones", "getCleanZones", "getVirtualWalls", "getSpots", "getViewportCenterPoint", "getMapCenterPoint", "getWallPointsByViewportCenter", "getForbiddenSweepZonePointsByViewportCenter", "getForbiddenMopZonePointsByViewportCenter", "getCleanZonePointsByViewportCenter", "getSpotPointByViewportCenter", "getEffectiveDividerPoints", "getDividerEndPoints", "snapshot", "snapshotByData"];
|
|
1731
1731
|
|
|
1732
1732
|
export declare const MAP_CALLBACK_METHODS: readonly ["onMapFirstDrawed", "onMapDrawed", "onPathDrawed", "onRoomPropertiesDrawed", "onClickRoom", "onClickRoomProperties", "onRemoveForbiddenSweepZone", "onRemoveForbiddenMopZone", "onRemoveCleanZone", "onRemoveVirtualWall", "onUpdateForbiddenSweepZone", "onUpdateForbiddenMopZone", "onUpdateCleanZone", "onUpdateVirtualWall", "onUpdateSpot", "onUpdateDivider", "onClickForbiddenSweepZone", "onClickForbiddenMopZone", "onClickCleanZone", "onClickVirtualWall", "onClickSpot", "onClickDetectedObject", "onClickCustomElement"];
|
|
1733
1733
|
|
|
@@ -1884,6 +1884,18 @@ export declare interface MapApi {
|
|
|
1884
1884
|
offsetX?: number;
|
|
1885
1885
|
offsetY?: number;
|
|
1886
1886
|
}): Point;
|
|
1887
|
+
/**
|
|
1888
|
+
* 判断指定的房间是否相邻(连通)
|
|
1889
|
+
*
|
|
1890
|
+
* 支持结构化地图和点阵地图两种协议。对于多个房间,使用连通性算法判断:
|
|
1891
|
+
* 只要房间之间能通过相邻关系连接起来,就认为它们是相邻的。
|
|
1892
|
+
* 例如:房间A和B相邻,房间B和C相邻,则认为A、B、C三个房间都相邻。
|
|
1893
|
+
*
|
|
1894
|
+
* @param roomIds - 要检测的房间ID数组
|
|
1895
|
+
* @param threshold - 距离阈值(像素),默认为5。两个房间的边界点距离小于等于此阈值时认为相邻
|
|
1896
|
+
* @returns 是否所有指定的房间都相邻(连通)
|
|
1897
|
+
*/
|
|
1898
|
+
areRoomsAdjacent(roomIds: number[], threshold?: number): boolean;
|
|
1887
1899
|
/**
|
|
1888
1900
|
* 地图截图
|
|
1889
1901
|
*
|
|
@@ -2254,6 +2266,29 @@ export declare class MapApplication extends Application implements MapApi {
|
|
|
2254
2266
|
offsetX?: number;
|
|
2255
2267
|
offsetY?: number;
|
|
2256
2268
|
}): Point;
|
|
2269
|
+
/**
|
|
2270
|
+
* 判断指定的房间是否相邻(连通)
|
|
2271
|
+
*
|
|
2272
|
+
* 支持结构化地图和点阵地图两种协议。对于多个房间,使用连通性算法判断:
|
|
2273
|
+
* 只要房间之间能通过相邻关系连接起来,就认为它们是相邻的。
|
|
2274
|
+
* 例如:房间A和B相邻,房间B和C相邻,则认为A、B、C三个房间都相邻。
|
|
2275
|
+
*
|
|
2276
|
+
* @param roomIds - 要检测的房间ID数组
|
|
2277
|
+
* @param threshold - 距离阈值(像素),默认为3。两个房间的边界点距离小于等于此阈值时认为相邻
|
|
2278
|
+
* @returns 是否所有指定的房间都相邻(连通)
|
|
2279
|
+
*
|
|
2280
|
+
* @example
|
|
2281
|
+
* ```typescript
|
|
2282
|
+
* // 判断两个房间是否相邻
|
|
2283
|
+
* const isAdjacent = mapApi.areRoomsAdjacent([1, 2])
|
|
2284
|
+
*
|
|
2285
|
+
* // 判断三个房间是否相邻(连通),使用自定义阈值
|
|
2286
|
+
* const isAdjacent = mapApi.areRoomsAdjacent([1, 2, 3], 8)
|
|
2287
|
+
* ```
|
|
2288
|
+
*/
|
|
2289
|
+
areRoomsAdjacent(roomIds: number[], threshold?: number): boolean;
|
|
2290
|
+
/* Excluded from this release type: areStructuredRoomsAdjacentInternal */
|
|
2291
|
+
/* Excluded from this release type: areRasterRoomsAdjacentInternal */
|
|
2257
2292
|
/**
|
|
2258
2293
|
* 地图截图
|
|
2259
2294
|
*
|
|
@@ -2605,6 +2640,7 @@ declare class MapManager {
|
|
|
2605
2640
|
mapBounds: Bounds;
|
|
2606
2641
|
private lastMapId;
|
|
2607
2642
|
private roomGeometryMap;
|
|
2643
|
+
private rasterRoomPixelsMap;
|
|
2608
2644
|
private carpetData;
|
|
2609
2645
|
private unsubscribeFns;
|
|
2610
2646
|
constructor();
|
|
@@ -2657,6 +2693,12 @@ declare class MapManager {
|
|
|
2657
2693
|
* @param rasterData 解析后的栅格数据
|
|
2658
2694
|
*/
|
|
2659
2695
|
private generateRoomGeometryFromRaster;
|
|
2696
|
+
/**
|
|
2697
|
+
* 获取点阵房间的像素数据
|
|
2698
|
+
* @param roomId 房间ID
|
|
2699
|
+
* @returns 像素索引数组,如果不存在则返回 undefined
|
|
2700
|
+
*/
|
|
2701
|
+
getRasterRoomPixels(roomId: number): Uint32Array | undefined;
|
|
2660
2702
|
destroy(): void;
|
|
2661
2703
|
}
|
|
2662
2704
|
|