valetudo-map-parser 0.1.8__py3-none-any.whl → 0.1.9a2__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.
- valetudo_map_parser/__init__.py +19 -12
- valetudo_map_parser/config/auto_crop.py +174 -116
- valetudo_map_parser/config/color_utils.py +105 -0
- valetudo_map_parser/config/colors.py +662 -13
- valetudo_map_parser/config/drawable.py +624 -279
- valetudo_map_parser/config/drawable_elements.py +292 -0
- valetudo_map_parser/config/enhanced_drawable.py +324 -0
- valetudo_map_parser/config/optimized_element_map.py +406 -0
- valetudo_map_parser/config/rand25_parser.py +42 -28
- valetudo_map_parser/config/room_outline.py +148 -0
- valetudo_map_parser/config/shared.py +73 -6
- valetudo_map_parser/config/types.py +102 -51
- valetudo_map_parser/config/utils.py +841 -0
- valetudo_map_parser/hypfer_draw.py +398 -132
- valetudo_map_parser/hypfer_handler.py +259 -241
- valetudo_map_parser/hypfer_rooms_handler.py +599 -0
- valetudo_map_parser/map_data.py +45 -64
- valetudo_map_parser/rand25_handler.py +429 -310
- valetudo_map_parser/reimg_draw.py +55 -74
- valetudo_map_parser/rooms_handler.py +470 -0
- valetudo_map_parser-0.1.9a2.dist-info/METADATA +93 -0
- valetudo_map_parser-0.1.9a2.dist-info/RECORD +27 -0
- {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a2.dist-info}/WHEEL +1 -1
- valetudo_map_parser/images_utils.py +0 -398
- valetudo_map_parser-0.1.8.dist-info/METADATA +0 -23
- valetudo_map_parser-0.1.8.dist-info/RECORD +0 -20
- {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a2.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a2.dist-info}/NOTICE.txt +0 -0
valetudo_map_parser/map_data.py
CHANGED
@@ -10,47 +10,12 @@ from __future__ import annotations
|
|
10
10
|
|
11
11
|
import numpy as np
|
12
12
|
|
13
|
-
from .config.types import
|
14
|
-
Colors,
|
15
|
-
ImageSize,
|
16
|
-
JsonType,
|
17
|
-
NumpyArray,
|
18
|
-
)
|
13
|
+
from .config.types import ImageSize, JsonType
|
19
14
|
|
20
15
|
|
21
16
|
class ImageData:
|
22
17
|
"""Class to handle the image data."""
|
23
18
|
|
24
|
-
@staticmethod
|
25
|
-
async def async_extract_color_coordinates(
|
26
|
-
source_array: NumpyArray, search_for_colours_list: Colors
|
27
|
-
) -> list:
|
28
|
-
"""Search for specific colors in an image array and return their coordinates."""
|
29
|
-
# Initialize an empty list to store color and coordinates tuples
|
30
|
-
color_coordinates_list = []
|
31
|
-
|
32
|
-
# Iterate over the search_for_colours_list
|
33
|
-
for color_to_search in search_for_colours_list:
|
34
|
-
# Initialize an empty list to store coordinates for the current color
|
35
|
-
color_coordinates = []
|
36
|
-
|
37
|
-
# Iterate over the image array
|
38
|
-
for y in range(source_array.shape[0]):
|
39
|
-
for x in range(source_array.shape[1]):
|
40
|
-
# Extract the pixel color at the current coordinates
|
41
|
-
pixel_color = source_array[y, x]
|
42
|
-
|
43
|
-
# Check if the current pixel color matches the color_to_search
|
44
|
-
if np.all(pixel_color == color_to_search):
|
45
|
-
# Record the coordinates for the current color
|
46
|
-
color_coordinates.append((x, y))
|
47
|
-
|
48
|
-
# Append the color and its coordinates to the final list
|
49
|
-
color_coordinates_list.append((color_to_search, color_coordinates))
|
50
|
-
|
51
|
-
# Return the final list of color and coordinates tuples
|
52
|
-
return color_coordinates_list
|
53
|
-
|
54
19
|
@staticmethod
|
55
20
|
def sublist(lst, n):
|
56
21
|
"""Sub lists of specific n number of elements"""
|
@@ -69,6 +34,30 @@ class ImageData:
|
|
69
34
|
# list the specific Layers, Paths, Zones and Pints in the
|
70
35
|
# Vacuums Json in parallel.
|
71
36
|
|
37
|
+
@staticmethod
|
38
|
+
def get_obstacles(entity_dict: dict) -> list:
|
39
|
+
"""Get the obstacles positions from the entity data."""
|
40
|
+
try:
|
41
|
+
obstacle_data = entity_dict.get("obstacle")
|
42
|
+
except KeyError:
|
43
|
+
return []
|
44
|
+
obstacle_positions = []
|
45
|
+
if obstacle_data:
|
46
|
+
for obstacle in obstacle_data:
|
47
|
+
label = obstacle.get("metaData", {}).get("label")
|
48
|
+
points = obstacle.get("points", [])
|
49
|
+
image_id = obstacle.get("metaData", {}).get("id")
|
50
|
+
|
51
|
+
if label and points:
|
52
|
+
obstacle_pos = {
|
53
|
+
"label": label,
|
54
|
+
"points": {"x": points[0], "y": points[1]},
|
55
|
+
"id": image_id,
|
56
|
+
}
|
57
|
+
obstacle_positions.append(obstacle_pos)
|
58
|
+
return obstacle_positions
|
59
|
+
return []
|
60
|
+
|
72
61
|
@staticmethod
|
73
62
|
def find_layers(
|
74
63
|
json_obj: JsonType, layer_dict: dict, active_list: list
|
@@ -209,10 +198,11 @@ class ImageData:
|
|
209
198
|
max_y * pixel_size,
|
210
199
|
)
|
211
200
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
201
|
+
|
202
|
+
class RandImageData:
|
203
|
+
"""This functions read directly the data from the json created
|
204
|
+
from the parser for Valetudo Re. They allow to use the
|
205
|
+
functions to draw the image without changes on the drawing class."""
|
216
206
|
|
217
207
|
@staticmethod
|
218
208
|
def from_rrm_to_compressed_pixels(
|
@@ -243,7 +233,7 @@ class ImageData:
|
|
243
233
|
return compressed_pixels
|
244
234
|
|
245
235
|
@staticmethod
|
246
|
-
def
|
236
|
+
def _calculate_max_x_y(coord_array):
|
247
237
|
"""Calculate the max and min x and y coordinates."""
|
248
238
|
max_x = -float("inf")
|
249
239
|
max_y = -float("inf")
|
@@ -297,7 +287,7 @@ class ImageData:
|
|
297
287
|
except KeyError:
|
298
288
|
return None
|
299
289
|
predicted_path = ImageData.sublist_join(
|
300
|
-
|
290
|
+
RandImageData.rrm_valetudo_path_array(points), 2
|
301
291
|
)
|
302
292
|
return predicted_path
|
303
293
|
|
@@ -330,7 +320,7 @@ class ImageData:
|
|
330
320
|
return None
|
331
321
|
|
332
322
|
if path_data and path_data != []:
|
333
|
-
path_data =
|
323
|
+
path_data = RandImageData.rrm_coordinates_to_valetudo(path_data)
|
334
324
|
return path_data
|
335
325
|
return None
|
336
326
|
|
@@ -338,18 +328,18 @@ class ImageData:
|
|
338
328
|
def get_rrm_currently_cleaned_zones(json_data: JsonType) -> dict:
|
339
329
|
"""Get the currently cleaned zones from the json."""
|
340
330
|
re_zones = json_data.get("currently_cleaned_zones", [])
|
341
|
-
formatted_zones =
|
331
|
+
formatted_zones = RandImageData._rrm_valetudo_format_zone(re_zones)
|
342
332
|
return formatted_zones
|
343
333
|
|
344
334
|
@staticmethod
|
345
335
|
def get_rrm_forbidden_zones(json_data: JsonType) -> dict:
|
346
336
|
"""Get the forbidden zones from the json."""
|
347
337
|
re_zones = json_data.get("forbidden_zones", [])
|
348
|
-
formatted_zones =
|
338
|
+
formatted_zones = RandImageData._rrm_valetudo_format_zone(re_zones)
|
349
339
|
return formatted_zones
|
350
340
|
|
351
341
|
@staticmethod
|
352
|
-
def
|
342
|
+
def _rrm_valetudo_format_zone(coordinates: list) -> any:
|
353
343
|
"""Format the zones from RRM to Valetudo."""
|
354
344
|
formatted_zones = []
|
355
345
|
for zone_data in coordinates:
|
@@ -391,7 +381,7 @@ class ImageData:
|
|
391
381
|
return formatted_zones
|
392
382
|
|
393
383
|
@staticmethod
|
394
|
-
def
|
384
|
+
def _rrm_valetudo_lines(coordinates: list) -> list:
|
395
385
|
"""Format the lines from RRM to Valetudo."""
|
396
386
|
formatted_lines = []
|
397
387
|
for lines in coordinates:
|
@@ -406,7 +396,7 @@ class ImageData:
|
|
406
396
|
tmp_data = json_data.get("virtual_walls", [])
|
407
397
|
except KeyError:
|
408
398
|
return None
|
409
|
-
virtual_walls =
|
399
|
+
virtual_walls = RandImageData._rrm_valetudo_lines(tmp_data)
|
410
400
|
return virtual_walls
|
411
401
|
|
412
402
|
@staticmethod
|
@@ -424,7 +414,7 @@ class ImageData:
|
|
424
414
|
"""Get the image size from the json."""
|
425
415
|
if isinstance(json_data, tuple):
|
426
416
|
return 0, 0
|
427
|
-
image =
|
417
|
+
image = RandImageData.get_rrm_image(json_data)
|
428
418
|
if image == {}:
|
429
419
|
return 0, 0
|
430
420
|
dimensions = image.get("dimensions", {})
|
@@ -433,20 +423,20 @@ class ImageData:
|
|
433
423
|
@staticmethod
|
434
424
|
def get_rrm_image_position(json_data: JsonType) -> tuple:
|
435
425
|
"""Get the image position from the json."""
|
436
|
-
image =
|
426
|
+
image = RandImageData.get_rrm_image(json_data)
|
437
427
|
position = image.get("position", {})
|
438
428
|
return position.get("top", 0), position.get("left", 0)
|
439
429
|
|
440
430
|
@staticmethod
|
441
431
|
def get_rrm_floor(json_data: JsonType) -> list:
|
442
432
|
"""Get the floor data from the json."""
|
443
|
-
img =
|
433
|
+
img = RandImageData.get_rrm_image(json_data)
|
444
434
|
return img.get("pixels", {}).get("floor", [])
|
445
435
|
|
446
436
|
@staticmethod
|
447
437
|
def get_rrm_walls(json_data: JsonType) -> list:
|
448
438
|
"""Get the walls data from the json."""
|
449
|
-
img =
|
439
|
+
img = RandImageData.get_rrm_image(json_data)
|
450
440
|
return img.get("pixels", {}).get("walls", [])
|
451
441
|
|
452
442
|
@staticmethod
|
@@ -460,7 +450,7 @@ class ImageData:
|
|
460
450
|
) -> tuple or list:
|
461
451
|
"""Get the segments data from the json."""
|
462
452
|
|
463
|
-
img =
|
453
|
+
img = RandImageData.get_rrm_image(json_data)
|
464
454
|
seg_data = img.get("segments", {})
|
465
455
|
seg_ids = seg_data.get("id")
|
466
456
|
segments = []
|
@@ -469,7 +459,7 @@ class ImageData:
|
|
469
459
|
for id_seg in seg_ids:
|
470
460
|
tmp_data = seg_data.get("pixels_seg_" + str(id_seg))
|
471
461
|
segments.append(
|
472
|
-
|
462
|
+
RandImageData.from_rrm_to_compressed_pixels(
|
473
463
|
tmp_data,
|
474
464
|
image_width=size_x,
|
475
465
|
image_height=size_y,
|
@@ -493,17 +483,8 @@ class ImageData:
|
|
493
483
|
def get_rrm_segments_ids(json_data: JsonType) -> list or None:
|
494
484
|
"""Get the segments ids from the json."""
|
495
485
|
try:
|
496
|
-
img =
|
486
|
+
img = RandImageData.get_rrm_image(json_data)
|
497
487
|
seg_ids = img.get("segments", {}).get("id", [])
|
498
488
|
except KeyError:
|
499
489
|
return None
|
500
490
|
return seg_ids
|
501
|
-
|
502
|
-
@staticmethod
|
503
|
-
def convert_negative_angle(angle: int) -> int:
|
504
|
-
"""Convert negative angle to positive."""
|
505
|
-
angle_c = angle % 360 # Ensure angle is within 0-359
|
506
|
-
if angle_c < 0:
|
507
|
-
angle_c += 360 # Convert negative angle to positive
|
508
|
-
angle = angle_c + 180 # add offset
|
509
|
-
return angle
|