valetudo-map-parser 0.1.11b1__py3-none-any.whl → 0.1.12b0__py3-none-any.whl

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.
@@ -376,170 +376,141 @@ class ImageDraw:
376
376
  else:
377
377
  self.img_h.zooming = False
378
378
 
379
+ def _create_robot_position_dict(
380
+ self, robot_x: int, robot_y: int, angle: float, room_name: str | None
381
+ ) -> RobotPosition:
382
+ """Create a robot position dictionary."""
383
+ return {
384
+ "x": robot_x,
385
+ "y": robot_y,
386
+ "angle": angle,
387
+ "in_room": room_name,
388
+ }
389
+
390
+ def _check_cached_room_outline(
391
+ self, robot_x: int, robot_y: int, angle: float
392
+ ) -> RobotPosition | None:
393
+ """Check if robot is still in cached room using outline."""
394
+ if "outline" in self.img_h.robot_in_room:
395
+ outline = self.img_h.robot_in_room["outline"]
396
+ if point_in_polygon(int(robot_x), int(robot_y), outline):
397
+ self._check_active_zone_and_set_zooming()
398
+ return self._create_robot_position_dict(
399
+ robot_x, robot_y, angle, self.img_h.robot_in_room["room"]
400
+ )
401
+ return None
402
+
403
+ def _check_cached_room_bbox(
404
+ self, robot_x: int, robot_y: int, angle: float
405
+ ) -> RobotPosition | None:
406
+ """Check if robot is still in cached room using bounding box."""
407
+ if all(k in self.img_h.robot_in_room for k in ["left", "right", "up", "down"]):
408
+ if (
409
+ (self.img_h.robot_in_room["right"] >= int(robot_x))
410
+ and (self.img_h.robot_in_room["left"] <= int(robot_x))
411
+ ) and (
412
+ (self.img_h.robot_in_room["down"] >= int(robot_y))
413
+ and (self.img_h.robot_in_room["up"] <= int(robot_y))
414
+ ):
415
+ self._check_active_zone_and_set_zooming()
416
+ return self._create_robot_position_dict(
417
+ robot_x, robot_y, angle, self.img_h.robot_in_room["room"]
418
+ )
419
+ return None
420
+
421
+ def _check_room_with_outline(
422
+ self, room: dict, room_count: int, robot_x: int, robot_y: int, angle: float
423
+ ) -> RobotPosition | None:
424
+ """Check if robot is in room using outline polygon."""
425
+ outline = room["outline"]
426
+ if point_in_polygon(int(robot_x), int(robot_y), outline):
427
+ self.img_h.robot_in_room = {
428
+ "id": room.get("id", room_count),
429
+ "room": str(room["name"]),
430
+ "outline": outline,
431
+ }
432
+ self._check_active_zone_and_set_zooming()
433
+ return self._create_robot_position_dict(
434
+ robot_x, robot_y, angle, self.img_h.robot_in_room["room"]
435
+ )
436
+ return None
437
+
438
+ def _check_room_with_corners(
439
+ self, room: dict, room_count: int, robot_x: int, robot_y: int, angle: float
440
+ ) -> RobotPosition | None:
441
+ """Check if robot is in room using corner bounding box."""
442
+ corners = room["corners"]
443
+ self.img_h.robot_in_room = {
444
+ "id": room.get("id", room_count),
445
+ "left": int(corners[0][0]),
446
+ "right": int(corners[2][0]),
447
+ "up": int(corners[0][1]),
448
+ "down": int(corners[2][1]),
449
+ "room": str(room["name"]),
450
+ }
451
+ if (
452
+ (self.img_h.robot_in_room["right"] >= int(robot_x))
453
+ and (self.img_h.robot_in_room["left"] <= int(robot_x))
454
+ ) and (
455
+ (self.img_h.robot_in_room["down"] >= int(robot_y))
456
+ and (self.img_h.robot_in_room["up"] <= int(robot_y))
457
+ ):
458
+ self._check_active_zone_and_set_zooming()
459
+ return self._create_robot_position_dict(
460
+ robot_x, robot_y, angle, self.img_h.robot_in_room["room"]
461
+ )
462
+ return None
463
+
379
464
  async def async_get_robot_in_room(
380
465
  self, robot_y: int = 0, robot_x: int = 0, angle: float = 0.0
381
466
  ) -> RobotPosition:
382
467
  """Get the robot position and return in what room is."""
383
- # First check if we already have a cached room and if the robot is still in it
384
- if self.img_h.robot_in_room:
385
- # If we have outline data, use point_in_polygon for accurate detection
386
- if "outline" in self.img_h.robot_in_room:
387
- outline = self.img_h.robot_in_room["outline"]
388
- if point_in_polygon(int(robot_x), int(robot_y), outline):
389
- temp = {
390
- "x": robot_x,
391
- "y": robot_y,
392
- "angle": angle,
393
- "in_room": self.img_h.robot_in_room["room"],
394
- }
395
- # Handle active zones
396
- self._check_active_zone_and_set_zooming()
397
- return temp
398
- # Fallback to bounding box check if no outline data
399
- elif all(
400
- k in self.img_h.robot_in_room for k in ["left", "right", "up", "down"]
401
- ):
402
- if (
403
- (self.img_h.robot_in_room["right"] >= int(robot_x))
404
- and (self.img_h.robot_in_room["left"] <= int(robot_x))
405
- ) and (
406
- (self.img_h.robot_in_room["down"] >= int(robot_y))
407
- and (self.img_h.robot_in_room["up"] <= int(robot_y))
408
- ):
409
- temp = {
410
- "x": robot_x,
411
- "y": robot_y,
412
- "angle": angle,
413
- "in_room": self.img_h.robot_in_room["room"],
414
- }
415
- # Handle active zones
416
- self._check_active_zone_and_set_zooming()
417
- return temp
418
-
419
- # If we don't have a cached room or the robot is not in it, search all rooms
420
- last_room = None
421
- room_count = 0
468
+ # Check cached room first
422
469
  if self.img_h.robot_in_room:
423
- last_room = self.img_h.robot_in_room
424
-
425
- # Check if the robot is far outside the normal map boundaries
426
- # This helps prevent false positives for points very far from any room
427
- map_boundary = 20000 # Typical map size is around 5000-10000 units
428
- if abs(robot_x) > map_boundary or abs(robot_y) > map_boundary:
429
- self.img_h.robot_in_room = last_room
430
- self.img_h.zooming = False
431
- temp = {
432
- "x": robot_x,
433
- "y": robot_y,
434
- "angle": angle,
435
- "in_room": last_room["room"] if last_room else None,
436
- }
437
- return temp
438
-
439
- # Search through all rooms to find which one contains the robot
440
- if self.img_h.rooms_pos is None:
470
+ result = self._check_cached_room_outline(robot_x, robot_y, angle)
471
+ if result:
472
+ return result
473
+ result = self._check_cached_room_bbox(robot_x, robot_y, angle)
474
+ if result:
475
+ return result
476
+
477
+ # Prepare for room search
478
+ last_room = self.img_h.robot_in_room
479
+ map_boundary = 20000
480
+
481
+ # Check boundary conditions or missing room data
482
+ if (
483
+ abs(robot_x) > map_boundary
484
+ or abs(robot_y) > map_boundary
485
+ or self.img_h.rooms_pos is None
486
+ ):
441
487
  self.img_h.robot_in_room = last_room
442
488
  self.img_h.zooming = False
443
- temp = {
444
- "x": robot_x,
445
- "y": robot_y,
446
- "angle": angle,
447
- "in_room": last_room["room"] if last_room else None,
448
- }
449
- return temp
489
+ return self._create_robot_position_dict(
490
+ robot_x, robot_y, angle, last_room["room"] if last_room else None
491
+ )
450
492
 
451
- for room in self.img_h.rooms_pos:
452
- # Check if the room has an outline (polygon points)
493
+ # Search through all rooms
494
+ for room_count, room in enumerate(self.img_h.rooms_pos):
453
495
  if "outline" in room:
454
- outline = room["outline"]
455
- # Use point_in_polygon for accurate detection with complex shapes
456
- if point_in_polygon(int(robot_x), int(robot_y), outline):
457
- # Robot is in this room
458
- self.img_h.robot_in_room = {
459
- "id": room.get(
460
- "id", room_count
461
- ), # Use actual segment ID if available
462
- "room": str(room["name"]),
463
- "outline": outline,
464
- }
465
- temp = {
466
- "x": robot_x,
467
- "y": robot_y,
468
- "angle": angle,
469
- "in_room": self.img_h.robot_in_room["room"],
470
- }
471
-
472
- # Handle active zones - Map segment ID to active_zones position
473
- if self.img_h.active_zones:
474
- segment_id = str(self.img_h.robot_in_room["id"])
475
- room_store = RoomStore(self.file_name)
476
- room_keys = list(room_store.get_rooms().keys())
477
-
478
- if segment_id in room_keys:
479
- position = room_keys.index(segment_id)
480
- if position < len(self.img_h.active_zones):
481
- self.img_h.zooming = bool(
482
- self.img_h.active_zones[position]
483
- )
484
- else:
485
- self.img_h.zooming = False
486
- else:
487
- _LOGGER.warning(
488
- "%s: Segment ID %s not found in room_keys %s",
489
- self.file_name,
490
- segment_id,
491
- room_keys,
492
- )
493
- self.img_h.zooming = False
494
- else:
495
- self.img_h.zooming = False
496
-
497
- return temp
498
- # Fallback to bounding box if no outline is available
496
+ result = self._check_room_with_outline(
497
+ room, room_count, robot_x, robot_y, angle
498
+ )
499
+ if result:
500
+ return result
499
501
  elif "corners" in room:
500
- corners = room["corners"]
501
- # Create a bounding box from the corners
502
- self.img_h.robot_in_room = {
503
- "id": room.get(
504
- "id", room_count
505
- ), # Use actual segment ID if available
506
- "left": int(corners[0][0]),
507
- "right": int(corners[2][0]),
508
- "up": int(corners[0][1]),
509
- "down": int(corners[2][1]),
510
- "room": str(room["name"]),
511
- }
512
- # Check if the robot is inside the bounding box
513
- if (
514
- (self.img_h.robot_in_room["right"] >= int(robot_x))
515
- and (self.img_h.robot_in_room["left"] <= int(robot_x))
516
- ) and (
517
- (self.img_h.robot_in_room["down"] >= int(robot_y))
518
- and (self.img_h.robot_in_room["up"] <= int(robot_y))
519
- ):
520
- temp = {
521
- "x": robot_x,
522
- "y": robot_y,
523
- "angle": angle,
524
- "in_room": self.img_h.robot_in_room["room"],
525
- }
526
-
527
- # Handle active zones
528
- self._check_active_zone_and_set_zooming()
529
-
530
- return temp
531
- room_count += 1
502
+ result = self._check_room_with_corners(
503
+ room, room_count, robot_x, robot_y, angle
504
+ )
505
+ if result:
506
+ return result
532
507
 
533
508
  # Robot not found in any room
534
509
  self.img_h.robot_in_room = last_room
535
510
  self.img_h.zooming = False
536
- temp = {
537
- "x": robot_x,
538
- "y": robot_y,
539
- "angle": angle,
540
- "in_room": last_room["room"] if last_room else None,
541
- }
542
- return temp
511
+ return self._create_robot_position_dict(
512
+ robot_x, robot_y, angle, last_room["room"] if last_room else None
513
+ )
543
514
 
544
515
  async def async_get_robot_position(self, entity_dict: dict) -> tuple | None:
545
516
  """Get the robot position from the entity data."""