@ray-js/robot-map-sdk 0.0.3-beta-19 → 0.0.3-beta-20
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/components/Base/Zone.js +1 -1
- package/dist/components/ChargingStation/index.js +1 -1
- package/dist/components/Controls/Divider.js +1 -1
- package/dist/components/Controls/Spot.js +1 -1
- package/dist/components/Controls/VirtualWall.js +1 -1
- package/dist/components/Robot/index.js +1 -1
- package/dist/components/RoomInfo/RoomProperty.js +1 -1
- package/dist/components/RoomInfo/RoomSelectionIndicator.js +1 -1
- package/dist/constant/config.js +1 -1
- package/dist/constant/methods.js +1 -1
- package/dist/index.d.ts +67 -2
- package/dist/index.js +1 -1
- package/dist/index.rjs.js +1 -1
- package/dist/managers/CustomElementsManager.js +1 -1
- package/dist/managers/MapManager.js +1 -1
- package/dist/utils/algorithm.js +1 -1
- package/dist/utils/index.js +1 -1
- package/dist-app/assets/{index-DFAEtWgf.js → index-CMaxpPPD.js} +1 -1
- package/dist-app/index.html +1 -1
- package/dist-docs/404.html +2 -2
- package/dist-docs/assets/{app.C1hdwNGd.js → app.DP1O8BNS.js} +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.BXv7BdiO.js +1 -0
- package/dist-docs/assets/chunks/{VPLocalSearchBox.D7RLqunb.js → VPLocalSearchBox.UpWCcVfL.js} +1 -1
- package/dist-docs/assets/chunks/{theme.Bgk1r3C0.js → theme.uu9-XYwr.js} +2 -2
- package/dist-docs/assets/{guide_getting-started.md.8wgboX-g.js → guide_getting-started.md.u5zOtdU6.js} +1 -1
- package/dist-docs/assets/{reference_config.md.DKXC2aOe.js → reference_config.md.zb-n1yzx.js} +2 -2
- package/dist-docs/assets/{reference_config.md.DKXC2aOe.lean.js → reference_config.md.zb-n1yzx.lean.js} +1 -1
- package/dist-docs/assets/{reference_methods.md.Cw2UFl8i.js → reference_methods.md.D1VYgciC.js} +10 -4
- package/dist-docs/assets/{reference_methods.md.Cw2UFl8i.lean.js → reference_methods.md.D1VYgciC.lean.js} +1 -1
- package/dist-docs/assets/{reference_types.md.CteNuaxc.js → reference_types.md.g_JJ8gNY.js} +74 -15
- package/dist-docs/assets/{reference_types.md.CteNuaxc.lean.js → reference_types.md.g_JJ8gNY.lean.js} +1 -1
- package/dist-docs/assets/{reference_utils.md.DU5CMWXW.js → reference_utils.md.C5spobZN.js} +6 -2
- package/dist-docs/assets/reference_utils.md.C5spobZN.lean.js +1 -0
- 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 +5 -5
- package/dist-docs/reference/data.html +3 -3
- package/dist-docs/reference/methods.html +13 -7
- package/dist-docs/reference/runtime.html +3 -3
- package/dist-docs/reference/types.html +77 -18
- package/dist-docs/reference/utils.html +9 -5
- package/package.json +1 -1
- package/dist-docs/assets/chunks/@localSearchIndexroot.BNXBBbhn.js +0 -1
- package/dist-docs/assets/reference_utils.md.DU5CMWXW.lean.js +0 -1
- /package/dist-docs/assets/{guide_getting-started.md.8wgboX-g.lean.js → guide_getting-started.md.u5zOtdU6.lean.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Assets as e,Ticker as t}from"pixi.js";import{
|
|
1
|
+
import{Assets as e,Ticker as t}from"pixi.js";import{CustomGif as i}from"../components/CustomElements/CustomGif.js";import{CustomImage as s}from"../components/CustomElements/CustomImage.js";import{CustomHTML as a}from"../components/CustomElements/CustomHTML.js";import{LAYER_CUSTOM_ELEMENT as n,LAYER_CUSTOM_ELEMENT_GIF as r}from"../application/AppContainer.js";import{Logger as o}from"../utils/logger.js";import{useAppService as m}from"../application/AppService.js";class p{customElementsMap=new Map;gifTicker=null;gifElements=new Set;constructor(){}updatePositionByOrigin(e,t){const i=m(),s=i.appContainer.getLayer(n),a=i.appContainer.getLayer(r);s&&s.position.set(e,t),a&&a.position.set(e,t)}async drawCustomElements(e){if(!e||0===e.length)return void this.clearAllCustomElements();const t=new Set(e.map(e=>e.id)),i=Array.from(this.customElementsMap.keys());for(const e of i)t.has(e)||this.removeCustomElement(e);const s=e.map(async e=>{const t=this.customElementsMap.get(e.id);t?this.isSameData(t,e)||("gif"===e.type&&t.getElementData().src!==e.src?(this.removeCustomElement(e.id),await this.addNewCustomElement(e)):await this.updateElementData(t,e)):await this.addNewCustomElement(e)});await Promise.all(s),this.updateGifTicker()}clearAllCustomElements(){const e=m();this.customElementsMap.forEach(t=>{t instanceof i?e.appContainer.removeFromLayer(r,t):e.appContainer.removeFromLayer(n,t),t.destroy()}),this.customElementsMap.clear(),this.gifElements.clear(),this.stopGifTicker()}async addNewCustomElement(t){const o=m();let p;switch(t.type){case"image":p=new s(t);break;case"gif":{const s=await e.load(t.src);p=new i(s,t);break}case"html":p=new a(t);break;default:throw new Error(`Unsupported custom element type: ${t.type}`)}await p.initialize(),this.customElementsMap.set(t.id,p),p instanceof i?(o.appContainer.addToLayer(r,p),this.gifElements.add(p)):o.appContainer.addToLayer(n,p)}removeCustomElement(e){const t=m(),s=this.customElementsMap.get(e);s&&(s instanceof i?(this.gifElements.delete(s),t.appContainer.removeFromLayer(r,s)):t.appContainer.removeFromLayer(n,s),s.destroy(),this.customElementsMap.delete(e))}isSameData(e,t){return e.getElementData().type===t.type&&("image"===t.type&&e instanceof s||"gif"===t.type&&e instanceof i||"html"===t.type&&e instanceof a)&&e.isSameData(t)}async updateElementData(e,t){if("image"===t.type&&e instanceof s)await e.updateElementData(t);else if("gif"===t.type&&e instanceof i)await e.updateElementData(t);else{if(!("html"===t.type&&e instanceof a))throw new Error("Element type mismatch during update");await e.updateElementData(t)}}updateGifTicker(){this.gifElements.size>0?this.startGifTicker():this.stopGifTicker()}startGifTicker(){this.gifTicker?.started||(this.gifTicker?this.gifTicker.maxFPS=1:(this.gifTicker=new t,this.gifTicker.maxFPS=1,this.gifTicker.add(()=>{this.renderGifContainer()})),this.gifTicker.start())}stopGifTicker(){this.gifTicker?.started&&(o.log("⏸️ [GifTicker] 停止 GIF 专用渲染"),this.gifTicker.stop())}renderGifContainer(){const e=m();if(0===this.gifElements.size)return;const t=e.getApp();t.renderer.render(t.stage)}destroy(){this.stopGifTicker(),this.gifTicker&&(this.gifTicker.destroy(),this.gifTicker=null),this.clearAllCustomElements()}}export{p as CustomElementsManager};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isEqual as o}from"lodash-es";import{Logger as t}from"../utils/logger.js";import{Rectangle as e}from"pixi.js";import{calculateRasterMapBounds as r,generateOutlineData as s,calculateRoomCenterPoint as a,mergeBounds as i,calculateRasterRoomCenter as n,fourColorGreedyAlgorithm as l,areStructuredRoomsAdjacent as c,areRasterRoomsAdjacent as h}from"../utils/algorithm.js";import{Obstacle as m}from"../components/Map/Obstacle.js";import{Free as p}from"../components/Map/Free.js";import{RoomFill as u}from"../components/Map/RoomFill.js";import{Carpet as d}from"../components/Map/Carpet.js";import{ChargingStation as g}from"../components/ChargingStation/index.js";import{subscribeKey as f}from"valtio/vanilla/utils";import{SPECIAL_ROOM_IDS as C}from"@ray-js/robot-protocol";import{useAppService as x}from"../application/AppService.js";class M{obstacle=new m;free=new p;roomFill=new u;carpet=new d;chargingStation=new g;mapBounds={minX:0,minY:0,maxX:0,maxY:0};lastMapId=null;roomGeometryMap=new Map;rasterRoomPixelsMap=new Map;fourColorCache=null;carpetData=null;unsubscribeFns=[];constructor(){const o=x();this.validateColorConfig();const e=f(o.runtime,"enableRoomSelection",e=>{if(t.log(`[runtime] enableRoomSelection: ${e}`),e){this.roomFill.setAllRoomsState(!1);const t=o.runtimeSnapshot.selectRoomIds;this.roomFill.setRoomStateBySelectIds(t)}else this.roomFill.setAllRoomsState(!0)}),r=f(o.runtime,"selectRoomIds",o=>{t.log(`[runtime] selectRoomIds: ${o}`),this.roomFill.setRoomStateBySelectIds(o)}),s=f(o.runtime,"showChargingStation",o=>{t.log(`[runtime] showChargingStation: ${o}`),this.chargingStation.visible=o}),a=f(o.runtime,"showCarpet",o=>{t.log(`[runtime] showCarpet: ${o}`),o?this.createCarpet():this.carpet.clearCarpet()});this.unsubscribeFns.push(e,r,s,a)}async drawMap(e){const r=x(),{id:s,obstacles:a,free:i,rooms:n,charger:l,carpet:c}=e;this.clearComponents(),this.resetGeometryData();const h=this.processRoomsGeometry(n);this.roomFill.draw(h),this.free.draw(i),this.obstacle.draw(a),this.carpetData={type:"structured",carpetData:c},this.createCarpet();const m=this.mergeLayerBounds();o(m,this.mapBounds)||(t.debug("[Map] Map bounds updated:",m),this.mapBounds=m,this.lastMapId!==s&&(r.getApp().fitMapToView(this.mapBounds),this.lastMapId=s));const p=((e.charger.angle??0)+r.chargingStationConfig.rotationCorrection)*Math.PI/180;return await this.chargingStation.draw({x:l.coordinate[0],y:l.coordinate[1],rotation:p}),r.roomsManager.refresh(),!0}async drawRasterMap(e,s){const a=x();this.clearComponents();const{id:i,width:n,height:l,charger:c,chargerDirection:h}=s;t.debug("[Map] Parsed Raster Map Data",e),this.obstacle.drawRaster(e.obstacles,n),this.carpetData={type:"raster",carpetPixels:e.carpet,mapWidth:n},this.createCarpet();const m=this.processRasterData(e);this.roomFill.drawRaster(m);const p=r(e,n,l);o(p,this.mapBounds)||(t.debug("[Map] Raster map bounds updated:",p),this.mapBounds=p,this.lastMapId!==i&&(a.getApp().fitMapToView(this.mapBounds),this.lastMapId=i));const u=(h+a.chargingStationConfig.rotationCorrection)*Math.PI/180;return await this.chargingStation.draw({x:c.x,y:c.y,rotation:u}),this.generateRoomGeometryFromRaster(e),a.roomsManager.refresh(),!0}resetGeometryData(){this.roomGeometryMap.clear(),this.rasterRoomPixelsMap.clear(),this.fourColorCache=null,this.mapBounds={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}async createCarpet(){if(x().runtimeSnapshot.showCarpet&&this.carpetData)if("raster"===this.carpetData.type){const{carpetPixels:o,mapWidth:t}=this.carpetData;await this.carpet.createCarpetFromRasterData(o,t)}else if("structured"===this.carpetData.type){const{carpetData:o}=this.carpetData;await this.carpet.createCarpetFromStructuredData(o)}}processRoomsGeometry(o){if(!o)return[];const t=x(),{active:r}=t.roomConfig.colors,i=t.roomConfig.colors[C.UNKNOWN_ROOM];if(0===Object.keys(o).length)return this.mapBounds={minX:0,minY:0,maxX:0,maxY:0},[];const n=Object.keys(o).sort((o,t)=>Number(o)-Number(t)),l=n.filter(o=>Number(o)<255),c=n.filter(o=>Number(o)>=255),h=[],m=[];l.forEach(t=>{const{coordinates:r}=o[t];if(r.length<4)return;const i=Number(t);let n=1/0,l=1/0,c=-1/0,h=-1/0;const p=[];for(let o=0;o<r.length;o+=2){const t=r[o],e=r[o+1];n=Math.min(n,t),l=Math.min(l,e),c=Math.max(c,t),h=Math.max(h,e),p.push({x:t,y:e})}const u=new e(n,l,c-n+1,h-l+1),d=s(p),g=d.flatMap(o=>[o.x+.5,o.y+.5]),f=a(d,n,l,c,h);m.push({id:i,points:p,outlinePoints:d,polyPoints:g,centerPoint:f,boundingBox:u}),this.mapBounds.minX=Math.min(this.mapBounds.minX,n),this.mapBounds.minY=Math.min(this.mapBounds.minY,l),this.mapBounds.maxX=Math.max(this.mapBounds.maxX,c),this.mapBounds.maxY=Math.max(this.mapBounds.maxY,h)});const p=[...m].sort((o,t)=>{const e=o.outlinePoints.length;return t.outlinePoints.length-e}),u=this.assignColorsUsingFourColorAlgorithm(p,r.length,"structured");return m.forEach(o=>{const t=u.get(o.id)||0,e=r[t],s={id:o.id,color:e,colorIndex:t,boundingBox:o.boundingBox,points:o.points,outlinePoints:o.outlinePoints,polyPoints:o.polyPoints,centerPoint:o.centerPoint};this.roomGeometryMap.set(o.id,s),h.push(s)}),c.forEach(t=>{const{coordinates:r}=o[t];if(r.length<4)return;const n=Number(t);let l=1/0,c=1/0,m=-1/0,p=-1/0;const u=[];for(let o=0;o<r.length;o+=2){const t=r[o],e=r[o+1];l=Math.min(l,t),c=Math.min(c,e),m=Math.max(m,t),p=Math.max(p,e),u.push({x:t,y:e})}const d=new e(l,c,m-l+1,p-c+1),g=s(u),f=g.flatMap(o=>[o.x+.5,o.y+.5]),C=a(g,l,c,m,p),x={id:n,color:i,boundingBox:d,points:u,outlinePoints:g,polyPoints:f,centerPoint:C};h.push(x),this.mapBounds.minX=Math.min(this.mapBounds.minX,l),this.mapBounds.minY=Math.min(this.mapBounds.minY,c),this.mapBounds.maxX=Math.max(this.mapBounds.maxX,m),this.mapBounds.maxY=Math.max(this.mapBounds.maxY,p)}),h}mergeLayerBounds(){let o={...this.mapBounds};if(this.obstacle.bounds&&(o=i(o,this.obstacle.bounds)),this.roomFill.children.length>0){const t=this.roomFill.getLocalBounds();t.width>0&&t.height>0&&(o=i(o,{minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height}))}return o}getRoomById(o){return this.roomGeometryMap.get(o)}clearComponents(){this.obstacle.clear(),this.obstacle.destroy(),this.obstacle=new m,this.free.clear(),this.free.destroy(),this.free=new p,this.carpet.clearCarpet(),this.carpetData=null,this.roomFill.removeChildren(),this.roomFill.destroy(),this.roomFill=new u}processRasterData(o){const t=x().roomConfig,e=[],r=[];o.rooms.forEach((o,t)=>{"number"==typeof t?e.push([t,o]):r.push([t,o])}),e.sort(([o],[t])=>o-t);const s=e.map(([o,t])=>({id:o,pixels:t})).sort((o,t)=>t.pixels.length-o.pixels.length),a=this.assignColorsUsingFourColorAlgorithm(s,t.colors.active.length,"raster"),i=[...e.map(([o,e])=>{const r=a.get(o)||0;return{roomId:o,pixelIndices:e,activeColor:t.colors.active[r],inactiveColor:t.colors.inactive[r%t.colors.inactive.length],colorIndex:r}}),...r.map(([o,e])=>{const r=t.colors[o]||"#ebebeb";return{roomId:o,pixelIndices:e,activeColor:r,inactiveColor:r}})];return{obstacles:o.obstacles,carpet:o.carpet,sortedRooms:i,width:o.width,height:o.height,totalPixels:o.totalPixels}}generateRoomGeometryFromRaster(o){const t=x();this.roomGeometryMap.clear(),this.rasterRoomPixelsMap.clear();const{active:r}=t.roomConfig.colors,s=[];o.rooms.forEach((o,t)=>{"number"==typeof t&&s.push(t)}),s.sort((o,t)=>o-t);const a=[];s.forEach(t=>{const r=o.rooms.get(t);this.rasterRoomPixelsMap.set(t,r);let s=1/0,i=1/0,l=-1/0,c=-1/0;for(let t=0;t<r.length;t++){const e=r[t],a=e%o.width,n=Math.floor(e/o.width);s=Math.min(s,a),i=Math.min(i,n),l=Math.max(l,a),c=Math.max(c,n)}const h=n(r,o.width,s,i,l,c),m=new e(s,i,l-s+1,c-i+1);a.push({id:t,pixelIndices:r,boundingBox:m,centerPoint:h})});const i=[...a].sort((o,t)=>t.pixelIndices.length-o.pixelIndices.length),l=this.assignColorsUsingFourColorAlgorithm(i,r.length,"raster");a.forEach(o=>{const t=l.get(o.id)||0,e=r[t],s={id:o.id,color:e,colorIndex:t,boundingBox:o.boundingBox,points:[],outlinePoints:[],polyPoints:[],centerPoint:o.centerPoint};this.roomGeometryMap.set(o.id,s)})}getRasterRoomPixels(o){return this.rasterRoomPixelsMap.get(o)}validateColorConfig(){const o=x().roomConfig.colors,e=o.active.length,r=o.inactive.length,s=o.name.length,a=o.propertyTheme.length,i=o.selectionIndicatorBackground.length,n=o.selectionIndicatorIcon.length;e<4&&t.warn(`[FourColor] room.colors.active requires at least 4 colors for the four-color theorem, but got ${e}. Adjacent rooms may have the same color.`),r!==e&&t.warn(`[FourColor] room.colors.inactive length (${r}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),s!==e&&t.warn(`[FourColor] room.colors.name length (${s}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),a!==e&&t.warn(`[FourColor] room.colors.propertyTheme length (${a}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),i!==e&&t.warn(`[FourColor] room.colors.selectionIndicatorBackground length (${i}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),n!==e&&t.warn(`[FourColor] room.colors.selectionIndicatorIcon length (${n}) does not match room.colors.active length (${e}). Using modulo for color assignment.`)}assignColorsUsingFourColorAlgorithm(o,e,r){const s=x(),a=s.mapState?.id??null;if(this.fourColorCache&&this.fourColorCache.mapId===a&&this.fourColorCache.colorMap.size===o.length)return t.debug("[FourColor] Using cached color map"),this.fourColorCache.colorMap;const i=s.getApp().config.map.adjacencyThreshold||3;t.debug(`[FourColor] Starting algorithm for ${o.length} rooms with ${e} colors`);const n=l(o,(o,t)=>{if("structured"===r){const e=o.outlinePoints,r=t.outlinePoints;return!(!e||!r)&&c(e,r,i)}{const e=o.pixels,r=t.pixels;if(!e||!r)return!1;const a=s.mapState?.width||0;return h(e,r,a,i)}},e);this.fourColorCache={mapId:a,colorMap:n};const m=new Array(e).fill(0);return n.forEach(o=>{m[o]++}),t.debug("[FourColor] Color distribution:",m),n}destroy(){this.obstacle.destroy(),this.free.destroy(),this.roomFill.destroy(),this.carpet.destroy(),this.chargingStation.destroy(),this.unsubscribeFns.forEach(o=>o()),this.unsubscribeFns=[],this.fourColorCache=null}}export{M as MapManager};
|
|
1
|
+
import{isEqual as o}from"lodash-es";import{Logger as t}from"../utils/logger.js";import{Rectangle as e}from"pixi.js";import{calculateRasterMapBounds as r,generateOutlineData as s,calculateRoomCenterPoint as a,mergeBounds as i,calculateRasterRoomCenter as n,fourColorGreedyAlgorithm as l,areStructuredRoomsAdjacent as c,areRasterRoomsAdjacent as h}from"../utils/algorithm.js";import{Obstacle as m}from"../components/Map/Obstacle.js";import{RoomFill as p}from"../components/Map/RoomFill.js";import{Carpet as u}from"../components/Map/Carpet.js";import{Free as d}from"../components/Map/Free.js";import{ChargingStation as g}from"../components/ChargingStation/index.js";import{subscribeKey as f}from"valtio/vanilla/utils";import{SPECIAL_ROOM_IDS as C}from"@ray-js/robot-protocol";import{useAppService as x}from"../application/AppService.js";class M{obstacle=new m;free=new d;roomFill=new p;carpet=new u;chargingStation=new g;mapBounds={minX:0,minY:0,maxX:0,maxY:0};lastMapId=null;roomGeometryMap=new Map;rasterRoomPixelsMap=new Map;fourColorCache=null;carpetData=null;unsubscribeFns=[];constructor(){const o=x();this.validateColorConfig();const e=f(o.runtime,"enableRoomSelection",e=>{if(t.log(`[runtime] enableRoomSelection: ${e}`),e){this.roomFill.setAllRoomsState(!1);const t=o.runtimeSnapshot.selectRoomIds;this.roomFill.setRoomStateBySelectIds(t)}else this.roomFill.setAllRoomsState(!0)}),r=f(o.runtime,"selectRoomIds",o=>{t.log(`[runtime] selectRoomIds: ${o}`),this.roomFill.setRoomStateBySelectIds(o)}),s=f(o.runtime,"showChargingStation",o=>{t.log(`[runtime] showChargingStation: ${o}`),this.chargingStation.visible=o}),a=f(o.runtime,"showCarpet",o=>{t.log(`[runtime] showCarpet: ${o}`),o?this.createCarpet():this.carpet.clearCarpet()});this.unsubscribeFns.push(e,r,s,a)}async drawMap(e){const r=x(),{id:s,obstacles:a,free:i,rooms:n,charger:l,carpet:c}=e;this.clearComponents(),this.resetGeometryData();const h=this.processRoomsGeometry(n);this.roomFill.draw(h),this.free.draw(i),this.obstacle.draw(a),this.carpetData={type:"structured",carpetData:c},this.createCarpet();const m=this.mergeLayerBounds();o(m,this.mapBounds)||(t.debug("[Map] Map bounds updated:",m),this.mapBounds=m,this.lastMapId!==s&&(r.getApp().fitMapToView(this.mapBounds),this.lastMapId=s));const p=((e.charger.angle??0)+r.chargingStationConfig.rotationCorrection)*Math.PI/180;return await this.chargingStation.draw({x:l.coordinate[0],y:l.coordinate[1],rotation:p}),r.roomsManager.refresh(),!0}async drawRasterMap(e,s){const a=x();this.clearComponents();const{id:i,width:n,height:l,charger:c,chargerDirection:h}=s;t.debug("[Map] Parsed Raster Map Data",e),this.obstacle.drawRaster(e.obstacles,n),this.carpetData={type:"raster",carpetPixels:e.carpet,mapWidth:n},this.createCarpet();const m=this.processRasterData(e);this.roomFill.drawRaster(m);const p=r(e,n,l);o(p,this.mapBounds)||(t.debug("[Map] Raster map bounds updated:",p),this.mapBounds=p,this.lastMapId!==i&&(a.getApp().fitMapToView(this.mapBounds),this.lastMapId=i));const u=(h+a.chargingStationConfig.rotationCorrection)*Math.PI/180;return await this.chargingStation.draw({x:c.x,y:c.y,rotation:u}),this.generateRoomGeometryFromRaster(e),a.roomsManager.refresh(),!0}resetGeometryData(){this.roomGeometryMap.clear(),this.rasterRoomPixelsMap.clear(),this.fourColorCache=null,this.mapBounds={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}async createCarpet(){if(x().runtimeSnapshot.showCarpet&&this.carpetData)if("raster"===this.carpetData.type){const{carpetPixels:o,mapWidth:t}=this.carpetData;await this.carpet.createCarpetFromRasterData(o,t)}else if("structured"===this.carpetData.type){const{carpetData:o}=this.carpetData;await this.carpet.createCarpetFromStructuredData(o)}}processRoomsGeometry(o){if(!o)return[];const t=x(),{active:r}=t.roomConfig.colors,i=t.roomConfig.colors[C.UNKNOWN_ROOM];if(0===Object.keys(o).length)return this.mapBounds={minX:0,minY:0,maxX:0,maxY:0},[];const n=Object.keys(o).sort((o,t)=>Number(o)-Number(t)),l=n.filter(o=>Number(o)<255),c=n.filter(o=>Number(o)>=255),h=[],m=[];l.forEach(t=>{const{coordinates:r}=o[t];if(r.length<4)return;const i=Number(t);let n=1/0,l=1/0,c=-1/0,h=-1/0;const p=[];for(let o=0;o<r.length;o+=2){const t=r[o],e=r[o+1];n=Math.min(n,t),l=Math.min(l,e),c=Math.max(c,t),h=Math.max(h,e),p.push({x:t,y:e})}const u=new e(n,l,c-n+1,h-l+1),d=s(p),g=d.flatMap(o=>[o.x+.5,o.y+.5]),f=a(d,n,l,c,h);m.push({id:i,points:p,outlinePoints:d,polyPoints:g,centerPoint:f,boundingBox:u}),this.mapBounds.minX=Math.min(this.mapBounds.minX,n),this.mapBounds.minY=Math.min(this.mapBounds.minY,l),this.mapBounds.maxX=Math.max(this.mapBounds.maxX,c),this.mapBounds.maxY=Math.max(this.mapBounds.maxY,h)});const p=[...m].sort((o,t)=>{const e=o.outlinePoints.length;return t.outlinePoints.length-e}),u=this.assignColorsUsingFourColorAlgorithm(p,r.length,"structured");return m.forEach(o=>{const t=u.get(o.id)||0,e=r[t],s={id:o.id,color:e,colorIndex:t,boundingBox:o.boundingBox,points:o.points,outlinePoints:o.outlinePoints,polyPoints:o.polyPoints,centerPoint:o.centerPoint};this.roomGeometryMap.set(o.id,s),h.push(s)}),c.forEach(t=>{const{coordinates:r}=o[t];if(r.length<4)return;const n=Number(t);let l=1/0,c=1/0,m=-1/0,p=-1/0;const u=[];for(let o=0;o<r.length;o+=2){const t=r[o],e=r[o+1];l=Math.min(l,t),c=Math.min(c,e),m=Math.max(m,t),p=Math.max(p,e),u.push({x:t,y:e})}const d=new e(l,c,m-l+1,p-c+1),g=s(u),f=g.flatMap(o=>[o.x+.5,o.y+.5]),C=a(g,l,c,m,p),x={id:n,color:i,boundingBox:d,points:u,outlinePoints:g,polyPoints:f,centerPoint:C};h.push(x),this.mapBounds.minX=Math.min(this.mapBounds.minX,l),this.mapBounds.minY=Math.min(this.mapBounds.minY,c),this.mapBounds.maxX=Math.max(this.mapBounds.maxX,m),this.mapBounds.maxY=Math.max(this.mapBounds.maxY,p)}),h}mergeLayerBounds(){let o={...this.mapBounds};if(this.obstacle.bounds&&(o=i(o,this.obstacle.bounds)),this.roomFill.children.length>0){const t=this.roomFill.getLocalBounds();t.width>0&&t.height>0&&(o=i(o,{minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height}))}return o}getRoomById(o){return this.roomGeometryMap.get(o)}getAllRooms(){return Array.from(this.roomGeometryMap.values())}clearComponents(){this.obstacle.clear(),this.obstacle.destroy(),this.obstacle=new m,this.free.clear(),this.free.destroy(),this.free=new d,this.carpet.clearCarpet(),this.carpetData=null,this.roomFill.removeChildren(),this.roomFill.destroy(),this.roomFill=new p}processRasterData(o){const t=x().roomConfig,e=[],r=[];o.rooms.forEach((o,t)=>{"number"==typeof t?e.push([t,o]):r.push([t,o])}),e.sort(([o],[t])=>o-t);const s=e.map(([o,t])=>({id:o,pixels:t})).sort((o,t)=>t.pixels.length-o.pixels.length),a=this.assignColorsUsingFourColorAlgorithm(s,t.colors.active.length,"raster"),i=[...e.map(([o,e])=>{const r=a.get(o)||0;return{roomId:o,pixelIndices:e,activeColor:t.colors.active[r],inactiveColor:t.colors.inactive[r%t.colors.inactive.length],colorIndex:r}}),...r.map(([o,e])=>{const r=t.colors[o]||"#ebebeb";return{roomId:o,pixelIndices:e,activeColor:r,inactiveColor:r}})];return{obstacles:o.obstacles,carpet:o.carpet,sortedRooms:i,width:o.width,height:o.height,totalPixels:o.totalPixels}}generateRoomGeometryFromRaster(o){const t=x();this.roomGeometryMap.clear(),this.rasterRoomPixelsMap.clear();const{active:r}=t.roomConfig.colors,s=[];o.rooms.forEach((o,t)=>{"number"==typeof t&&s.push(t)}),s.sort((o,t)=>o-t);const a=[];s.forEach(t=>{const r=o.rooms.get(t);this.rasterRoomPixelsMap.set(t,r);let s=1/0,i=1/0,l=-1/0,c=-1/0;for(let t=0;t<r.length;t++){const e=r[t],a=e%o.width,n=Math.floor(e/o.width);s=Math.min(s,a),i=Math.min(i,n),l=Math.max(l,a),c=Math.max(c,n)}const h=n(r,o.width,s,i,l,c),m=new e(s,i,l-s+1,c-i+1);a.push({id:t,pixelIndices:r,boundingBox:m,centerPoint:h})});const i=[...a].sort((o,t)=>t.pixelIndices.length-o.pixelIndices.length),l=this.assignColorsUsingFourColorAlgorithm(i,r.length,"raster");a.forEach(o=>{const t=l.get(o.id)||0,e=r[t],s={id:o.id,color:e,colorIndex:t,boundingBox:o.boundingBox,points:[],outlinePoints:[],polyPoints:[],centerPoint:o.centerPoint};this.roomGeometryMap.set(o.id,s)})}getRasterRoomPixels(o){return this.rasterRoomPixelsMap.get(o)}validateColorConfig(){const o=x().roomConfig.colors,e=o.active.length,r=o.inactive.length,s=o.name.length,a=o.propertyTheme.length,i=o.selectionIndicatorBackground.length,n=o.selectionIndicatorIcon.length;e<4&&t.warn(`[FourColor] room.colors.active requires at least 4 colors for the four-color theorem, but got ${e}. Adjacent rooms may have the same color.`),r!==e&&t.warn(`[FourColor] room.colors.inactive length (${r}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),s!==e&&t.warn(`[FourColor] room.colors.name length (${s}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),a!==e&&t.warn(`[FourColor] room.colors.propertyTheme length (${a}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),i!==e&&t.warn(`[FourColor] room.colors.selectionIndicatorBackground length (${i}) does not match room.colors.active length (${e}). Using modulo for color assignment.`),n!==e&&t.warn(`[FourColor] room.colors.selectionIndicatorIcon length (${n}) does not match room.colors.active length (${e}). Using modulo for color assignment.`)}assignColorsUsingFourColorAlgorithm(o,e,r){const s=x(),a=s.mapState?.id??null;if(this.fourColorCache&&this.fourColorCache.mapId===a&&this.fourColorCache.colorMap.size===o.length)return t.debug("[FourColor] Using cached color map"),this.fourColorCache.colorMap;const i=s.getApp().config.map.adjacencyThreshold||3;t.debug(`[FourColor] Starting algorithm for ${o.length} rooms with ${e} colors`);const n=l(o,(o,t)=>{if("structured"===r){const e=o.outlinePoints,r=t.outlinePoints;return!(!e||!r)&&c(e,r,i)}{const e=o.pixels,r=t.pixels;if(!e||!r)return!1;const a=s.mapState?.width||0;return h(e,r,a,i)}},e);this.fourColorCache={mapId:a,colorMap:n};const m=new Array(e).fill(0);return n.forEach(o=>{m[o]++}),t.debug("[FourColor] Color distribution:",m),n}destroy(){this.obstacle.destroy(),this.free.destroy(),this.roomFill.destroy(),this.carpet.destroy(),this.chargingStation.destroy(),this.unsubscribeFns.forEach(o=>o()),this.unsubscribeFns=[],this.fourColorCache=null}}export{M as MapManager};
|
package/dist/utils/algorithm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=t=>{if(t.length<=1)return[...t];const r=n(t),e=r.slice(1).map((t,n)=>({prev:r[n],current:t})),y=new Map;return e.forEach(({prev:t,current:n})=>{x(t,n).forEach(t=>{const n=`${t.x},${t.y}`;y.has(n)||y.set(n,t)})}),Array.from(y.values())},n=t=>{if(t.length<=1)return[...t];const n=t[0],x=t[t.length-1];return n.x===x.x&&n.y===x.y?[...t]:[...t,n]},x=(t,n)=>{const x=[],r=Math.abs(n.x-t.x),e=Math.abs(n.y-t.y),y=t.x<n.x?1:-1,a=t.y<n.y?1:-1;let o=r-e,h=t.x,s=t.y;for(;x.push({x:h,y:s}),h!==n.x||s!==n.y;){const t=2*o;t>-e&&(o-=e,h+=y),t<r&&(o+=r,s+=a)}return x},r=(t,n,x=1,r=2e3)=>{const e=[],y=n.x-t.x,a=n.y-t.y,o=Math.sqrt(y*y+a*a);if(0===o)return[t];const h=Math.min(Math.max(Math.ceil(o/x),2),r);for(let n=0;n<=h;n++){const x=n/h,r={x:t.x+x*y,y:t.y+x*a};e.push(r)}return e},e=(t,n,x,r,e,o=8)=>{const s={x:(n+r)/2,y:(x+e)/2},i=r-n,c=e-x,m=Math.min(o,.2*Math.min(i,c));return h(s,t)&&a(s,t)>=m?s:y(t,s,m)},y=(t,n,x)=>{const{minX:r,minY:e,maxX:y,maxY:o}=c(t),s=y-r,i=o-e,m=n.x,l=n.y,f=Math.min(.5,.05*Math.min(s,i)),M=[];if(h({x:m,y:l},t)){const n=a({x:m,y:l},t);M.push({point:{x:m,y:l},distance:n,centerDistance:0})}const g=.6*Math.max(s,i),d=Math.PI/16;for(let n=f;n<=g;n+=f){const s=d*(1+n/g);for(let i=0;i<2*Math.PI;i+=s){const s=m+n*Math.cos(i),c=l+n*Math.sin(i);if(s>=r&&s<=y&&c>=e&&c<=o){const n={x:s,y:c};if(h(n,t)){const r=a(n,t),e=u({x:s,y:c},{x:m,y:l});r>=x&&M.push({point:n,distance:r,centerDistance:e})}}}if(M.length>=15)break}if(M.length>0){const t=M.map(t=>({...t,score:1.5*t.distance-.5*t.centerDistance}));return t.sort((t,n)=>n.score-t.score),t[0].point}if(0===M.length){let n={x:m,y:l},x=0;const s=2*f;for(let i=r;i<=y;i+=s)for(let r=e;r<=o;r+=s){const e={x:i,y:r};if(h(e,t)){const r=a(e,t);r>x&&(x=r,n=e)}}return n}return{x:m,y:l}},a=(t,n)=>{let x=1/0;for(let r=0,e=n.length-1;r<n.length;e=r++){const y=n[e],a=n[r],h=o(t,y,a);x=Math.min(x,h)}return x},o=(t,n,x)=>{const r=(n.x-x.x)**2+(n.y-x.y)**2;if(0===r)return u(t,n);const e=Math.max(0,Math.min(1,((t.x-n.x)*(x.x-n.x)+(t.y-n.y)*(x.y-n.y))/r)),y=n.x+e*(x.x-n.x),a=n.y+e*(x.y-n.y);return u(t,{x:y,y:a})},h=(t,n,x=!1)=>{if(n.length<3)return!1;if(x&&s(t,n))return!0;let r=!1;for(let x=0,e=n.length-1;x<n.length;e=x++){const y=n[x].x,a=n[x].y,o=n[e].x,h=n[e].y;a>t.y!=h>t.y&&t.x<(o-y)*(t.y-a)/(h-a)+y&&(r=!r)}return r},s=(t,n)=>{if(n.length<2)return!1;for(let x=0;x<n.length;x++){const r=(x+1)%n.length;if(i(t,n[x],n[r]))return!0}return!1},i=(t,n,x,r=.5)=>{if(o(t,n,x)>r)return!1;const e=Math.min(n.x,x.x)-r,y=Math.max(n.x,x.x)+r,a=Math.min(n.y,x.y)-r,h=Math.max(n.y,x.y)+r;return t.x>=e&&t.x<=y&&t.y>=a&&t.y<=h},c=t=>{if(0===t.length)return{minX:0,minY:0,maxX:0,maxY:0};let n=1/0,x=1/0,r=-1/0,e=-1/0;for(const y of t)n=Math.min(n,y.x),x=Math.min(x,y.y),r=Math.max(r,y.x),e=Math.max(e,y.y);return{minX:n,minY:x,maxX:r,maxY:e}},m=t=>{const n=t.reduce((t,n)=>({x:t.x+n.x,y:t.y+n.y}),{x:0,y:0});return{x:n.x/t.length,y:n.y/t.length}},l=t=>{if(4!==t.length)return t;const n=m(t),x=u(t[0],t[1]),r=u(t[1],t[2]),e=Math.atan2(t[1].y-t[0].y,t[1].x-t[0].x),y=[{x:-x/2,y:-r/2},{x:x/2,y:-r/2},{x:x/2,y:r/2},{x:-x/2,y:r/2}],a=Math.cos(e),o=Math.sin(e);return y.map(t=>({x:t.x*a-t.y*o+n.x,y:t.x*o+t.y*a+n.y}))},f=(t,n,x,r=10)=>{if(0===x)return 1;const e=(t.x*n.x+t.y*n.y)/x/x,y=r/x;return e<=0?y:Math.max(e,y)},u=(t,n)=>{const x=t.x-n.x,r=t.y-n.y;return Math.sqrt(x*x+r*r)},M=t=>Math.sqrt(t.x*t.x+t.y*t.y),g=(t,n)=>({x:n.x-t.x,y:n.y-t.y}),d=t=>{const n=M(t);return 0===n?{x:0,y:0}:{x:t.x/n,y:t.y/n}},p=(t,n)=>{const x=g(t,n);return d(x)},X=t=>({x:-t.y,y:t.x}),Y=(t,n)=>{const x=p(t,n);return X(x)},w=(t,n)=>{const x=d(t),r=d(n),e={x:(x.x+r.x)/2,y:(x.y+r.y)/2};return d(e)},S=(t,n)=>{const x=g(t,n);let r=Math.atan2(x.y,x.x);return(r>Math.PI/2||r<-Math.PI/2)&&(r+=Math.PI),r},$=(t,n,x)=>{const r=m([t,n]),e=Y(t,n);return{x:r.x+e.x*x,y:r.y+e.y*x}},b=(t,n,x)=>{const r=Math.cos(x),e=Math.sin(x),y=t.x-n.x,a=t.y-n.y;return{x:y*r-a*e+n.x,y:y*e+a*r+n.y}},q=(t,n,x)=>t.map(t=>b(t,n,x)),I=(t,n,x)=>{if(0===u(t,n))return[t,t,t,t];const r=p(t,n),e=X(r),y=t.x-r.x*x,a=t.y-r.y*x,o=n.x+r.x*x,h=n.y+r.y*x;return[{x:y+e.x*x,y:a+e.y*x},{x:o+e.x*x,y:h+e.y*x},{x:o-e.x*x,y:h-e.y*x},{x:y-e.x*x,y:a-e.y*x}]},P=(t,n)=>{if(t.length<3)return t;const x=[];for(let r=0;r<t.length;r++){const e=t[r],y=t[(r+1)%t.length],a=t[(r-1+t.length)%t.length],o=g(e,y);if(0===M(o)){x.push(e);continue}const h=d(o),s={x:h.y,y:-h.x},i=g(a,e);let c={x:0,y:0};if(M(i)>0){const t=d(i);c={x:t.y,y:-t.x}}const m=w(c,s),l=c.x*s.x+c.y*s.y,f=1/Math.max(.1,Math.sqrt((1+l)/2)),u={x:e.x+m.x*n*f,y:e.y+m.y*n*f};x.push(u)}return x},v=(t,n,x)=>{if(0===u(t,n))return[];const r=Y(t,n),e=x/2;return[t.x+r.x*e,t.y+r.y*e,n.x+r.x*e,n.y+r.y*e,n.x-r.x*e,n.y-r.y*e,t.x-r.x*e,t.y-r.y*e]},A=(t,n,x,r)=>{const e=g(t,n),y=g(t,x),a=w(e,y),o=-a.x,h=-a.y;return{x:t.x+o*r,y:t.y+h*r}},E=(t,n,x,r,e,y)=>{const a=new Set(t),o=D(t,n);return k(o,a,n,x,r,e,y)||o},D=(t,n)=>{let x=0,r=0;for(let e=0;e<t.length;e++){const y=t[e];x+=y%n,r+=Math.floor(y/n)}return{x:x/t.length,y:r/t.length}},k=(t,n,x,r,e,y,a)=>{const o={x:r-10,y:t.y},h={x:y+10,y:t.y},s={x:y,y:e},i={x:y,y:a},c=z(o,h,{x:r,y:e},{x:r,y:a}),m=z(o,h,s,i);if(!c||!m)return null;const l=[],f=Math.max(r,Math.min(c.x,m.x)),u=Math.min(y,Math.max(c.x,m.x)),M=Math.round(t.y);for(let t=Math.round(f);t<=Math.round(u);t++){const r=M*x+t;n.has(r)&&l.push({x:t,y:M})}if(l.length>=2){const t=j(l),r={x:(t.min.x+t.max.x)/2,y:(t.min.y+t.max.y)/2},e=Math.round(r.y)*x+Math.round(r.x);if(n.has(e))return r}return null},z=(t,n,x,r)=>{const e=(t.x-x.x)*(n.y-x.y)-(t.y-x.y)*(n.x-x.x),y=(t.x-r.x)*(n.y-r.y)-(t.y-r.y)*(n.x-r.x);if(e*y>=0)return null;const a=(x.x-t.x)*(r.y-t.y)-(x.y-t.y)*(r.x-t.x);if(a*(a+e-y)>=0)return null;const o=a/(y-e),h=o*(n.x-t.x),s=o*(n.y-t.y);return{x:t.x+h,y:t.y+s}},j=t=>{if(!t||0===t.length)return{min:{x:0,y:0},max:{x:0,y:0}};let n=t[0],x=t[0];const r=t=>t.x-t.y;for(let e=1;e<t.length;e++){const y=t[e];r(y)<r(n)&&(n=y),r(y)>r(x)&&(x=y)}return{min:n,max:x}},B=(t,n)=>({minX:Math.min(t.minX,n.minX),minY:Math.min(t.minY,n.minY),maxX:Math.max(t.maxX,n.maxX),maxY:Math.max(t.maxY,n.maxY)}),C=t=>{if(0===t.length)return{x:0,y:0,width:0,height:0};let n=t[0].x,x=t[0].y,r=t[0].x+t[0].width,e=t[0].y+t[0].height;return t.forEach(t=>{n=Math.min(n,t.x),x=Math.min(x,t.y),r=Math.max(r,t.x+t.width),e=Math.max(e,t.y+t.height)}),{x:n,y:x,width:r-n,height:e-x}},F=(t,n,x)=>{let r=1/0,e=1/0,y=-1/0,a=-1/0;for(let x=0;x<t.obstacles.length;x++){const o=t.obstacles[x],h=o%n,s=Math.floor(o/n);r=Math.min(r,h),e=Math.min(e,s),y=Math.max(y,h),a=Math.max(a,s)}return t.rooms.forEach(t=>{for(let x=0;x<t.length;x++){const o=t[x],h=o%n,s=Math.floor(o/n);r=Math.min(r,h),e=Math.min(e,s),y=Math.max(y,h),a=Math.max(a,s)}}),r===1/0?{minX:0,minY:0,maxX:n,maxY:x}:{minX:Math.max(0,r),minY:Math.max(0,e),maxX:Math.min(n,y),maxY:Math.min(x,a)}},G=(t,n,x,r,e,y)=>{const a=x+e,o=r+y,h=Math.min(t.x,n.x),s=Math.max(t.x,n.x),i=Math.min(t.y,n.y),c=Math.max(t.y,n.y);if(s<x||h>a||c<r||i>o)return!1;if(H(t,x,r,e,y)||H(n,x,r,e,y))return!0;const m=[{x:x,y:r},{x:a,y:r},{x:a,y:o},{x:x,y:o}];for(let x=0;x<4;x++)if(z(t,n,m[x],m[(x+1)%4]))return!0;return!1},H=(t,n,x,r,e)=>t.x>=n&&t.x<=n+r&&t.y>=x&&t.y<=x+e,J=(t,n,x,r)=>{const e=x/2;return"horizontal"===r?[{x:t-e,y:n},{x:t+e,y:n}]:[{x:t,y:n-e},{x:t,y:n+e}]},K=(t,n,x)=>{const r=n.x-t.x,e=n.y-t.y,y=Math.sqrt(r*r+e*e);if(0===y)return[t,n];const a=r/y,o=e/y;return[{x:t.x-a*x,y:t.y-o*x},{x:n.x+a*x,y:n.y+o*x}]},L=(t,n,x)=>{const r=c(t),e=c(n),y=Math.max(0,Math.max(r.minX,e.minX)-Math.min(r.maxX,e.maxX)),a=Math.max(0,Math.max(r.minY,e.minY)-Math.min(r.maxY,e.maxY));if(y>x||a>x)return!1;let[o,h]=[t,n];n.length>t.length&&([o,h]=[n,t]);const s=Math.max(1,Math.floor(x)),i=new Map;for(const t of o){const n=`${Math.floor(t.x/s)},${Math.floor(t.y/s)}`;i.has(n)||i.set(n,[]),i.get(n).push(t)}const m=x*x;for(const t of h){const n=Math.floor(t.x/s),x=Math.floor(t.y/s);for(let r=-1;r<=1;r++)for(let e=-1;e<=1;e++){const y=`${n+r},${x+e}`,a=i.get(y);if(a)for(const n of a){const x=t.x-n.x,r=t.y-n.y;if(x*x+r*r<=m)return!0}}}return!1},N=(t,n,x,r)=>{let[e,y]=[t,n];n.length>t.length&&([e,y]=[n,t]);const a=new Set(e),o=r*r;for(let t=0;t<y.length;t++){const n=y[t],e=n%x,h=Math.floor(n/x);for(let t=-r;t<=r;t++)for(let n=-r;n<=r;n++){const r=(h+n)*x+(e+t);if(a.has(r)&&t*t+n*n<=o)return!0}}return!1},O=(t,n)=>{if(t<=1)return!0;if(0===n.length)return!1;const x=Array.from({length:t},(t,n)=>n),r=Array(t).fill(0),e=t=>(x[t]!==t&&(x[t]=e(x[t])),x[t]),y=(t,n)=>{const y=e(t),a=e(n);y!==a&&(r[y]<r[a]?x[y]=a:r[y]>r[a]?x[a]=y:(x[a]=y,r[y]++))};for(const[t,x]of n)y(t,x);const a=e(0);for(let n=1;n<t;n++)if(e(n)!==a)return!1;return!0},Q=(t,n,x)=>{const r=new Map;if(0===t.length)return r;if(1===t.length)return r.set(t[0].id,0),r;const e=new Map;for(let x=0;x<t.length;x++){const r=t[x];e.has(r.id)||e.set(r.id,new Set);for(let y=x+1;y<t.length;y++){const x=t[y];n(r,x)&&(e.get(r.id).add(x.id),e.has(x.id)||e.set(x.id,new Set),e.get(x.id).add(r.id))}}const y=new Array(x).fill(0);for(const n of t){const t=e.get(n.id)||new Set,a=new Set;for(const n of t){const t=r.get(n);void 0!==t&&a.add(t)}const o=[];for(let t=0;t<x;t++)a.has(t)||o.push(t);let h=o[0],s=y[h];for(const t of o)y[t]<s&&(h=t,s=y[t]);r.set(n.id,h),y[h]++}return r};export{O as areMultipleRoomsConnected,N as areRasterRoomsAdjacent,L as areStructuredRoomsAdjacent,c as calculateBoundingBox,m as calculateCenter,x as calculateCoordinatesBetweenPoints,A as calculateCornerExtension,J as calculateLineEndpoints,$ as calculateLineMidpointOffset,v as calculateLineSegmentHitArea,I as calculateLineSegmentOutline,C as calculateMergedBounds,a as calculateMinDistanceToBoundary,D as calculatePixelWeightedCenter,P as calculatePolygonOutline,F as calculateRasterMapBounds,E as calculateRasterRoomCenter,e as calculateRoomCenterPoint,f as calculateScaleRatio,S as calculateUprightLineAngle,g as createVector,n as ensureClosedPath,K as extendLineSegment,y as findBestInnerPoint,j as findExtremePoints,Q as fourColorGreedyAlgorithm,t as generateOutlineData,w as getBisectorDirection,u as getDistance,Y as getPerpendicularUnitVector,X as getPerpendicularVector,p as getUnitVector,M as getVectorLength,H as isPointInBox,h as isPointInPolygon,i as isPointOnLineSegment,s as isPointOnPolygonBoundary,G as lineIntersectsBox,z as lineSegmentsIntersection,B as mergeBounds,l as normalizeToRectangle,d as normalizeVector,k as optimizeRasterCenterWithLineIntersection,o as pointToSegmentDistance,b as rotatePointAroundCenter,q as rotatePointsAroundCenter,r as sampleLinePoints};
|
|
1
|
+
const t=t=>{if(t.length<=1)return[...t];const r=n(t),x=r.slice(1).map((t,n)=>({prev:r[n],current:t})),o=new Map;return x.forEach(({prev:t,current:n})=>{e(t,n).forEach(t=>{const n=`${t.x},${t.y}`;o.has(n)||o.set(n,t)})}),Array.from(o.values())},n=t=>{if(t.length<=1)return[...t];const n=t[0],e=t[t.length-1];return n.x===e.x&&n.y===e.y?[...t]:[...t,n]},e=(t,n)=>{const e=[],r=Math.abs(n.x-t.x),x=Math.abs(n.y-t.y),o=t.x<n.x?1:-1,a=t.y<n.y?1:-1;let y=r-x,h=t.x,s=t.y;for(;e.push({x:h,y:s}),h!==n.x||s!==n.y;){const t=2*y;t>-x&&(y-=x,h+=o),t<r&&(y+=r,s+=a)}return e},r=(t,n)=>{let e=0,r=t.length-1;for(;e<=r;){const x=Math.floor((e+r)/2),o=t[x];if(o===n)return!0;o<n?e=x+1:r=x-1}return!1},x=(t,n,e=1,r=2e3)=>{const x=[],o=n.x-t.x,a=n.y-t.y,y=Math.sqrt(o*o+a*a);if(0===y)return[t];const h=Math.min(Math.max(Math.ceil(y/e),2),r);for(let n=0;n<=h;n++){const e=n/h,r={x:t.x+e*o,y:t.y+e*a};x.push(r)}return x},o=(t,n,e,r,x,o=8)=>{const h={x:(n+r)/2,y:(e+x)/2},i=r-n,c=x-e,l=Math.min(o,.2*Math.min(i,c));return s(h,t)&&y(h,t)>=l?h:a(t,h,l)},a=(t,n,e)=>{const{minX:r,minY:x,maxX:o,maxY:a}=l(t),h=o-r,i=a-x,c=n.x,f=n.y,m=Math.min(.5,.05*Math.min(h,i)),u=[];if(s({x:c,y:f},t)){const n=y({x:c,y:f},t);u.push({point:{x:c,y:f},distance:n,centerDistance:0})}const g=.6*Math.max(h,i),d=Math.PI/16;for(let n=m;n<=g;n+=m){const h=d*(1+n/g);for(let i=0;i<2*Math.PI;i+=h){const h=c+n*Math.cos(i),l=f+n*Math.sin(i);if(h>=r&&h<=o&&l>=x&&l<=a){const n={x:h,y:l};if(s(n,t)){const r=y(n,t),x=M({x:h,y:l},{x:c,y:f});r>=e&&u.push({point:n,distance:r,centerDistance:x})}}}if(u.length>=15)break}if(u.length>0){const t=u.map(t=>({...t,score:1.5*t.distance-.5*t.centerDistance}));return t.sort((t,n)=>n.score-t.score),t[0].point}if(0===u.length){let n={x:c,y:f},e=0;const h=2*m;for(let i=r;i<=o;i+=h)for(let r=x;r<=a;r+=h){const x={x:i,y:r};if(s(x,t)){const r=y(x,t);r>e&&(e=r,n=x)}}return n}return{x:c,y:f}},y=(t,n)=>{let e=1/0;for(let r=0,x=n.length-1;r<n.length;x=r++){const o=n[x],a=n[r],y=h(t,o,a);e=Math.min(e,y)}return e},h=(t,n,e)=>{const r=(n.x-e.x)**2+(n.y-e.y)**2;if(0===r)return M(t,n);const x=Math.max(0,Math.min(1,((t.x-n.x)*(e.x-n.x)+(t.y-n.y)*(e.y-n.y))/r)),o=n.x+x*(e.x-n.x),a=n.y+x*(e.y-n.y);return M(t,{x:o,y:a})},s=(t,n,e=!1)=>{if(n.length<3)return!1;if(e&&i(t,n))return!0;let r=!1;for(let e=0,x=n.length-1;e<n.length;x=e++){const o=n[e].x,a=n[e].y,y=n[x].x,h=n[x].y;a>t.y!=h>t.y&&t.x<(y-o)*(t.y-a)/(h-a)+o&&(r=!r)}return r},i=(t,n)=>{if(n.length<2)return!1;for(let e=0;e<n.length;e++){const r=(e+1)%n.length;if(c(t,n[e],n[r]))return!0}return!1},c=(t,n,e,r=.5)=>{if(h(t,n,e)>r)return!1;const x=Math.min(n.x,e.x)-r,o=Math.max(n.x,e.x)+r,a=Math.min(n.y,e.y)-r,y=Math.max(n.y,e.y)+r;return t.x>=x&&t.x<=o&&t.y>=a&&t.y<=y},l=t=>{if(0===t.length)return{minX:0,minY:0,maxX:0,maxY:0};let n=1/0,e=1/0,r=-1/0,x=-1/0;for(const o of t)n=Math.min(n,o.x),e=Math.min(e,o.y),r=Math.max(r,o.x),x=Math.max(x,o.y);return{minX:n,minY:e,maxX:r,maxY:x}},f=t=>{const n=t.reduce((t,n)=>({x:t.x+n.x,y:t.y+n.y}),{x:0,y:0});return{x:n.x/t.length,y:n.y/t.length}},m=t=>{if(4!==t.length)return t;const n=f(t),e=M(t[0],t[1]),r=M(t[1],t[2]),x=Math.atan2(t[1].y-t[0].y,t[1].x-t[0].x),o=[{x:-e/2,y:-r/2},{x:e/2,y:-r/2},{x:e/2,y:r/2},{x:-e/2,y:r/2}],a=Math.cos(x),y=Math.sin(x);return o.map(t=>({x:t.x*a-t.y*y+n.x,y:t.x*y+t.y*a+n.y}))},u=(t,n,e,r=10)=>{if(0===e)return 1;const x=(t.x*n.x+t.y*n.y)/e/e,o=r/e;return x<=0?o:Math.max(x,o)},M=(t,n)=>{const e=t.x-n.x,r=t.y-n.y;return Math.sqrt(e*e+r*r)},g=t=>Math.sqrt(t.x*t.x+t.y*t.y),d=(t,n)=>({x:n.x-t.x,y:n.y-t.y}),p=t=>{const n=g(t);return 0===n?{x:0,y:0}:{x:t.x/n,y:t.y/n}},X=(t,n)=>{const e=d(t,n);return p(e)},Y=t=>({x:-t.y,y:t.x}),w=(t,n)=>{const e=X(t,n);return Y(e)},S=(t,n)=>{const e=p(t),r=p(n),x={x:(e.x+r.x)/2,y:(e.y+r.y)/2};return p(x)},$=(t,n)=>{const e=d(t,n);let r=Math.atan2(e.y,e.x);return(r>Math.PI/2||r<-Math.PI/2)&&(r+=Math.PI),r},b=(t,n,e)=>{const r=f([t,n]),x=w(t,n);return{x:r.x+x.x*e,y:r.y+x.y*e}},q=(t,n,e)=>{const r=Math.cos(e),x=Math.sin(e),o=t.x-n.x,a=t.y-n.y;return{x:o*r-a*x+n.x,y:o*x+a*r+n.y}},v=(t,n,e)=>t.map(t=>q(t,n,e)),I=(t,n,e)=>{if(0===M(t,n))return[t,t,t,t];const r=X(t,n),x=Y(r),o=t.x-r.x*e,a=t.y-r.y*e,y=n.x+r.x*e,h=n.y+r.y*e;return[{x:o+x.x*e,y:a+x.y*e},{x:y+x.x*e,y:h+x.y*e},{x:y-x.x*e,y:h-x.y*e},{x:o-x.x*e,y:a-x.y*e}]},P=(t,n)=>{if(t.length<3)return t;const e=[];for(let r=0;r<t.length;r++){const x=t[r],o=t[(r+1)%t.length],a=t[(r-1+t.length)%t.length],y=d(x,o);if(0===g(y)){e.push(x);continue}const h=p(y),s={x:h.y,y:-h.x},i=d(a,x);let c={x:0,y:0};if(g(i)>0){const t=p(i);c={x:t.y,y:-t.x}}const l=S(c,s),f=c.x*s.x+c.y*s.y,m=1/Math.max(.1,Math.sqrt((1+f)/2)),u={x:x.x+l.x*n*m,y:x.y+l.y*n*m};e.push(u)}return e},A=(t,n,e)=>{if(0===M(t,n))return[];const r=w(t,n),x=e/2;return[t.x+r.x*x,t.y+r.y*x,n.x+r.x*x,n.y+r.y*x,n.x-r.x*x,n.y-r.y*x,t.x-r.x*x,t.y-r.y*x]},E=(t,n,e,r)=>{const x=d(t,n),o=d(t,e),a=S(x,o),y=-a.x,h=-a.y;return{x:t.x+y*r,y:t.y+h*r}},z=(t,n,e,r,x,o)=>{const a=new Set(t),y=D(t,n);return O(y,a,n,e,r,x,o)||y},D=(t,n)=>{let e=0,r=0;for(let x=0;x<t.length;x++){const o=t[x];e+=o%n,r+=Math.floor(o/n)}return{x:e/t.length,y:r/t.length}},O=(t,n,e,r,x,o,a)=>{const y={x:r-10,y:t.y},h={x:o+10,y:t.y},s={x:o,y:x},i={x:o,y:a},c=k(y,h,{x:r,y:x},{x:r,y:a}),l=k(y,h,s,i);if(!c||!l)return null;const f=[],m=Math.max(r,Math.min(c.x,l.x)),u=Math.min(o,Math.max(c.x,l.x)),M=Math.round(t.y);for(let t=Math.round(m);t<=Math.round(u);t++){const r=M*e+t;n.has(r)&&f.push({x:t,y:M})}if(f.length>=2){const t=j(f),r={x:(t.min.x+t.max.x)/2,y:(t.min.y+t.max.y)/2},x=Math.round(r.y)*e+Math.round(r.x);if(n.has(x))return r}return null},k=(t,n,e,r)=>{const x=(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x),o=(t.x-r.x)*(n.y-r.y)-(t.y-r.y)*(n.x-r.x);if(x*o>=0)return null;const a=(e.x-t.x)*(r.y-t.y)-(e.y-t.y)*(r.x-t.x);if(a*(a+x-o)>=0)return null;const y=a/(o-x),h=y*(n.x-t.x),s=y*(n.y-t.y);return{x:t.x+h,y:t.y+s}},j=t=>{if(!t||0===t.length)return{min:{x:0,y:0},max:{x:0,y:0}};let n=t[0],e=t[0];const r=t=>t.x-t.y;for(let x=1;x<t.length;x++){const o=t[x];r(o)<r(n)&&(n=o),r(o)>r(e)&&(e=o)}return{min:n,max:e}},B=(t,n)=>({minX:Math.min(t.minX,n.minX),minY:Math.min(t.minY,n.minY),maxX:Math.max(t.maxX,n.maxX),maxY:Math.max(t.maxY,n.maxY)}),C=t=>{if(0===t.length)return{x:0,y:0,width:0,height:0};let n=t[0].x,e=t[0].y,r=t[0].x+t[0].width,x=t[0].y+t[0].height;return t.forEach(t=>{n=Math.min(n,t.x),e=Math.min(e,t.y),r=Math.max(r,t.x+t.width),x=Math.max(x,t.y+t.height)}),{x:n,y:e,width:r-n,height:x-e}},F=(t,n,e)=>{let r=1/0,x=1/0,o=-1/0,a=-1/0;for(let e=0;e<t.obstacles.length;e++){const y=t.obstacles[e],h=y%n,s=Math.floor(y/n);r=Math.min(r,h),x=Math.min(x,s),o=Math.max(o,h),a=Math.max(a,s)}return t.rooms.forEach(t=>{for(let e=0;e<t.length;e++){const y=t[e],h=y%n,s=Math.floor(y/n);r=Math.min(r,h),x=Math.min(x,s),o=Math.max(o,h),a=Math.max(a,s)}}),r===1/0?{minX:0,minY:0,maxX:n,maxY:e}:{minX:Math.max(0,r),minY:Math.max(0,x),maxX:Math.min(n,o),maxY:Math.min(e,a)}},G=(t,n,e,r,x,o)=>{const a=e+x,y=r+o,h=Math.min(t.x,n.x),s=Math.max(t.x,n.x),i=Math.min(t.y,n.y),c=Math.max(t.y,n.y);if(s<e||h>a||c<r||i>y)return!1;if(H(t,e,r,x,o)||H(n,e,r,x,o))return!0;const l=[{x:e,y:r},{x:a,y:r},{x:a,y:y},{x:e,y:y}];for(let e=0;e<4;e++)if(k(t,n,l[e],l[(e+1)%4]))return!0;return!1},H=(t,n,e,r,x)=>t.x>=n&&t.x<=n+r&&t.y>=e&&t.y<=e+x,J=(t,n,e,r)=>{const x=e/2;return"horizontal"===r?[{x:t-x,y:n},{x:t+x,y:n}]:[{x:t,y:n-x},{x:t,y:n+x}]},K=(t,n,e)=>{const r=n.x-t.x,x=n.y-t.y,o=Math.sqrt(r*r+x*x);if(0===o)return[t,n];const a=r/o,y=x/o;return[{x:t.x-a*e,y:t.y-y*e},{x:n.x+a*e,y:n.y+y*e}]},L=(t,n,e)=>{const r=l(t),x=l(n),o=Math.max(0,Math.max(r.minX,x.minX)-Math.min(r.maxX,x.maxX)),a=Math.max(0,Math.max(r.minY,x.minY)-Math.min(r.maxY,x.maxY));if(o>e||a>e)return!1;let[y,h]=[t,n];n.length>t.length&&([y,h]=[n,t]);const s=Math.max(1,Math.floor(e)),i=new Map;for(const t of y){const n=`${Math.floor(t.x/s)},${Math.floor(t.y/s)}`;i.has(n)||i.set(n,[]),i.get(n).push(t)}const c=e*e;for(const t of h){const n=Math.floor(t.x/s),e=Math.floor(t.y/s);for(let r=-1;r<=1;r++)for(let x=-1;x<=1;x++){const o=`${n+r},${e+x}`,a=i.get(o);if(a)for(const n of a){const e=t.x-n.x,r=t.y-n.y;if(e*e+r*r<=c)return!0}}}return!1},N=(t,n,e,r)=>{let[x,o]=[t,n];n.length>t.length&&([x,o]=[n,t]);const a=new Set(x),y=r*r;for(let t=0;t<o.length;t++){const n=o[t],x=n%e,h=Math.floor(n/e);for(let t=-r;t<=r;t++)for(let n=-r;n<=r;n++){const r=(h+n)*e+(x+t);if(a.has(r)&&t*t+n*n<=y)return!0}}return!1},Q=(t,n)=>{if(t<=1)return!0;if(0===n.length)return!1;const e=Array.from({length:t},(t,n)=>n),r=Array(t).fill(0),x=t=>(e[t]!==t&&(e[t]=x(e[t])),e[t]),o=(t,n)=>{const o=x(t),a=x(n);o!==a&&(r[o]<r[a]?e[o]=a:r[o]>r[a]?e[a]=o:(e[a]=o,r[o]++))};for(const[t,e]of n)o(t,e);const a=x(0);for(let n=1;n<t;n++)if(x(n)!==a)return!1;return!0},R=(t,n,e)=>{const r=new Map;if(0===t.length)return r;if(1===t.length)return r.set(t[0].id,0),r;const x=new Map;for(let e=0;e<t.length;e++){const r=t[e];x.has(r.id)||x.set(r.id,new Set);for(let o=e+1;o<t.length;o++){const e=t[o];n(r,e)&&(x.get(r.id).add(e.id),x.has(e.id)||x.set(e.id,new Set),x.get(e.id).add(r.id))}}const o=new Array(e).fill(0),a=[...t].sort((n,e)=>{const r=(x.get(n.id)||new Set).size,o=(x.get(e.id)||new Set).size,a=t.indexOf(n);return.7*-t.indexOf(e)+.3*o-(.7*-a+.3*r)});for(const t of a){const n=x.get(t.id)||new Set,a=new Set,y=new Set;for(const e of n){const o=r.get(e);if(void 0!==o){a.add(o);const h=x.get(e)||new Set;for(const e of h)if(e!==t.id&&!n.has(e)){const t=r.get(e);void 0!==t&&y.add(t)}}}const h=[];for(let t=0;t<e;t++)a.has(t)||h.push(t);if(0===h.length){let n=1/0,x=0;for(let t=0;t<e;t++)o[t]<n&&(n=o[t],x=t);r.set(t.id,x),o[x]++;continue}const s=h.filter(t=>!y.has(t)),i=s.length>0?s:h;let c=i[0],l=o[c];for(const t of i)(o[t]<l||o[t]===l&&t<c)&&(c=t,l=o[t]);r.set(t.id,c),o[c]++}return r};export{Q as areMultipleRoomsConnected,N as areRasterRoomsAdjacent,L as areStructuredRoomsAdjacent,r as binarySearch,l as calculateBoundingBox,f as calculateCenter,e as calculateCoordinatesBetweenPoints,E as calculateCornerExtension,J as calculateLineEndpoints,b as calculateLineMidpointOffset,A as calculateLineSegmentHitArea,I as calculateLineSegmentOutline,C as calculateMergedBounds,y as calculateMinDistanceToBoundary,D as calculatePixelWeightedCenter,P as calculatePolygonOutline,F as calculateRasterMapBounds,z as calculateRasterRoomCenter,o as calculateRoomCenterPoint,u as calculateScaleRatio,$ as calculateUprightLineAngle,d as createVector,n as ensureClosedPath,K as extendLineSegment,a as findBestInnerPoint,j as findExtremePoints,R as fourColorGreedyAlgorithm,t as generateOutlineData,S as getBisectorDirection,M as getDistance,w as getPerpendicularUnitVector,Y as getPerpendicularVector,X as getUnitVector,g as getVectorLength,H as isPointInBox,s as isPointInPolygon,c as isPointOnLineSegment,i as isPointOnPolygonBoundary,G as lineIntersectsBox,k as lineSegmentsIntersection,B as mergeBounds,m as normalizeToRectangle,p as normalizeVector,O as optimizeRasterCenterWithLineIntersection,h as pointToSegmentDistance,q as rotatePointAroundCenter,v as rotatePointsAroundCenter,x as sampleLinePoints};
|
package/dist/utils/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1}import{decodeMapRooms as
|
|
1
|
+
function e(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1}import{decodeMapRooms as r}from"@ray-js/robot-protocol";const o=(e,o)=>(r(e)??[]).map(e=>({id:e.roomId,name:e.name,cleanTimes:e.sweepTimes,order:e.order,floorType:e.floorMaterial,yMop:e.yMop?1:0,suction:e.suction,cistern:e.cistern,cleanMode:e.sweepForbidden||e.mopForbidden?e.sweepForbidden?2:1:0,...o?.(e.reservedStr)??{}})),n=(e,r,o=20)=>{const n=[...e];let t=0;for(;t<o&&r.some(e=>{return o=e,(r=n).length===o.length&&r.every((e,r)=>{const n=o[r];return e.x===n.x&&e.y===n.y});var r,o});)t++,n.forEach(e=>{e.x+=5,e.y+=5});return n};export{o as decodeRoomProperties,e as easeInOutCubic,n as offsetPointsToAvoidOverlap};
|