valetudo-map-parser 0.1.9b51__py3-none-any.whl → 0.1.9b53__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/config/colors.py +14 -4
- valetudo_map_parser/config/drawable.py +0 -3
- valetudo_map_parser/config/enhanced_drawable.py +2 -2
- valetudo_map_parser/hypfer_rooms_handler.py +295 -102
- {valetudo_map_parser-0.1.9b51.dist-info → valetudo_map_parser-0.1.9b53.dist-info}/METADATA +1 -1
- {valetudo_map_parser-0.1.9b51.dist-info → valetudo_map_parser-0.1.9b53.dist-info}/RECORD +9 -9
- {valetudo_map_parser-0.1.9b51.dist-info → valetudo_map_parser-0.1.9b53.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.9b51.dist-info → valetudo_map_parser-0.1.9b53.dist-info}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.9b51.dist-info → valetudo_map_parser-0.1.9b53.dist-info}/WHEEL +0 -0
@@ -492,10 +492,20 @@ class ColorsManagement:
|
|
492
492
|
background = tuple(map(int, array[y, x]))
|
493
493
|
|
494
494
|
# Update cache (with simple LRU-like behavior)
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
495
|
+
try:
|
496
|
+
if len(cache) >= ColorsManagement._cache_size:
|
497
|
+
# Remove a random entry if cache is full
|
498
|
+
if cache: # Make sure cache is not empty
|
499
|
+
cache.pop(next(iter(cache)))
|
500
|
+
else:
|
501
|
+
# If cache is somehow empty but len reported >= _cache_size
|
502
|
+
# This is an edge case that shouldn't happen but we handle it
|
503
|
+
pass
|
504
|
+
cache[cache_key] = background
|
505
|
+
except KeyError:
|
506
|
+
# If we encounter a KeyError, reset the cache
|
507
|
+
# This is a rare edge case that might happen in concurrent access
|
508
|
+
ColorsManagement._bg_color_cache = {cache_key: background}
|
499
509
|
|
500
510
|
except (IndexError, ValueError):
|
501
511
|
return foreground
|
@@ -57,9 +57,6 @@ class Drawable:
|
|
57
57
|
# Extract alpha from color
|
58
58
|
alpha = color[3] if len(color) == 4 else 255
|
59
59
|
|
60
|
-
# For debugging
|
61
|
-
_LOGGER.debug("Drawing with color %s and alpha %s", color, alpha)
|
62
|
-
|
63
60
|
# Create the full color with alpha
|
64
61
|
full_color = color if len(color) == 4 else (*color, 255)
|
65
62
|
|
@@ -14,11 +14,11 @@ from typing import Optional, Tuple
|
|
14
14
|
import numpy as np
|
15
15
|
|
16
16
|
from .drawable import Drawable
|
17
|
-
from
|
17
|
+
from .drawable_elements import (
|
18
18
|
DrawableElement,
|
19
19
|
DrawingConfig,
|
20
20
|
)
|
21
|
-
from
|
21
|
+
from .colors import ColorsManagement
|
22
22
|
|
23
23
|
|
24
24
|
# Type aliases
|
@@ -38,48 +38,130 @@ class HypferRoomsHandler:
|
|
38
38
|
"""
|
39
39
|
self.vacuum_id = vacuum_id
|
40
40
|
self.drawing_config = drawing_config
|
41
|
+
self.current_json_data = None # Will store the current JSON data being processed
|
41
42
|
|
42
43
|
@staticmethod
|
43
44
|
def sublist(data: list, chunk_size: int) -> list:
|
44
45
|
return [data[i : i + chunk_size] for i in range(0, len(data), chunk_size)]
|
45
46
|
|
47
|
+
# Cache for RDP results
|
48
|
+
_rdp_cache = {}
|
49
|
+
|
46
50
|
@staticmethod
|
47
51
|
def perpendicular_distance(
|
48
52
|
point: tuple[int, int], line_start: tuple[int, int], line_end: tuple[int, int]
|
49
53
|
) -> float:
|
50
|
-
"""Calculate the perpendicular distance from a point to a line.
|
54
|
+
"""Calculate the perpendicular distance from a point to a line.
|
55
|
+
Optimized for performance.
|
56
|
+
"""
|
57
|
+
# Fast path for point-to-point distance
|
51
58
|
if line_start == line_end:
|
52
|
-
|
53
|
-
|
54
|
-
)
|
59
|
+
dx = point[0] - line_start[0]
|
60
|
+
dy = point[1] - line_start[1]
|
61
|
+
return sqrt(dx*dx + dy*dy)
|
55
62
|
|
56
63
|
x, y = point
|
57
64
|
x1, y1 = line_start
|
58
65
|
x2, y2 = line_end
|
59
66
|
|
60
|
-
#
|
61
|
-
|
62
|
-
|
67
|
+
# Precompute differences for efficiency
|
68
|
+
dx = x2 - x1
|
69
|
+
dy = y2 - y1
|
70
|
+
|
71
|
+
# Calculate the line length squared (avoid sqrt until needed)
|
72
|
+
line_length_sq = dx*dx + dy*dy
|
73
|
+
if line_length_sq == 0:
|
63
74
|
return 0
|
64
75
|
|
65
76
|
# Calculate the distance from the point to the line
|
66
|
-
|
77
|
+
# Using the formula: |cross_product| / |line_vector|
|
78
|
+
# This is more efficient than the original formula
|
79
|
+
cross_product = abs(dy * x - dx * y + x2 * y1 - y2 * x1)
|
80
|
+
return cross_product / sqrt(line_length_sq)
|
67
81
|
|
68
82
|
async def rdp(
|
69
83
|
self, points: List[Tuple[int, int]], epsilon: float
|
70
84
|
) -> List[Tuple[int, int]]:
|
71
|
-
"""Ramer-Douglas-Peucker algorithm for simplifying a curve.
|
85
|
+
"""Ramer-Douglas-Peucker algorithm for simplifying a curve.
|
86
|
+
Optimized with caching and better performance.
|
87
|
+
"""
|
88
|
+
# Create a hashable key for caching
|
89
|
+
# Convert points to a tuple for hashing
|
90
|
+
points_tuple = tuple(points)
|
91
|
+
cache_key = (points_tuple, epsilon)
|
92
|
+
|
93
|
+
# Check cache first
|
94
|
+
if cache_key in self._rdp_cache:
|
95
|
+
return self._rdp_cache[cache_key]
|
96
|
+
|
97
|
+
# Base case
|
72
98
|
if len(points) <= 2:
|
73
99
|
return points
|
74
100
|
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
101
|
+
# For very small point sets, process directly without recursion
|
102
|
+
if len(points) <= 5:
|
103
|
+
# Find the point with the maximum distance
|
104
|
+
dmax = 0
|
105
|
+
index = 0
|
106
|
+
for i in range(1, len(points) - 1):
|
107
|
+
d = self.perpendicular_distance(points[i], points[0], points[-1])
|
108
|
+
if d > dmax:
|
109
|
+
index = i
|
110
|
+
dmax = d
|
111
|
+
|
112
|
+
# If max distance is greater than epsilon, keep the point
|
113
|
+
if dmax > epsilon:
|
114
|
+
result = [points[0]] + [points[index]] + [points[-1]]
|
115
|
+
else:
|
116
|
+
result = [points[0], points[-1]]
|
117
|
+
|
118
|
+
# Cache and return
|
119
|
+
self._rdp_cache[cache_key] = result
|
120
|
+
return result
|
121
|
+
|
122
|
+
# For larger point sets, use numpy for faster distance calculation
|
123
|
+
if len(points) > 20:
|
124
|
+
# Convert to numpy arrays for vectorized operations
|
125
|
+
points_array = np.array(points)
|
126
|
+
start = points_array[0]
|
127
|
+
end = points_array[-1]
|
128
|
+
|
129
|
+
# Calculate perpendicular distances in one vectorized operation
|
130
|
+
line_vector = end - start
|
131
|
+
line_length = np.linalg.norm(line_vector)
|
132
|
+
|
133
|
+
if line_length == 0:
|
134
|
+
# If start and end are the same, use direct distance
|
135
|
+
distances = np.linalg.norm(points_array[1:-1] - start, axis=1)
|
136
|
+
else:
|
137
|
+
# Normalize line vector
|
138
|
+
line_vector = line_vector / line_length
|
139
|
+
# Calculate perpendicular distances using vector operations
|
140
|
+
vectors_to_points = points_array[1:-1] - start
|
141
|
+
# Project vectors onto line vector
|
142
|
+
projections = np.dot(vectors_to_points, line_vector)
|
143
|
+
# Calculate projected points on line
|
144
|
+
projected_points = start + np.outer(projections, line_vector)
|
145
|
+
# Calculate distances from points to their projections
|
146
|
+
distances = np.linalg.norm(points_array[1:-1] - projected_points, axis=1)
|
147
|
+
|
148
|
+
# Find the point with maximum distance
|
149
|
+
if len(distances) > 0:
|
150
|
+
max_idx = np.argmax(distances)
|
151
|
+
dmax = distances[max_idx]
|
152
|
+
index = max_idx + 1 # +1 because we skipped the first point
|
153
|
+
else:
|
154
|
+
dmax = 0
|
155
|
+
index = 0
|
156
|
+
else:
|
157
|
+
# For medium-sized point sets, use the original algorithm
|
158
|
+
dmax = 0
|
159
|
+
index = 0
|
160
|
+
for i in range(1, len(points) - 1):
|
161
|
+
d = self.perpendicular_distance(points[i], points[0], points[-1])
|
162
|
+
if d > dmax:
|
163
|
+
index = i
|
164
|
+
dmax = d
|
83
165
|
|
84
166
|
# If max distance is greater than epsilon, recursively simplify
|
85
167
|
if dmax > epsilon:
|
@@ -88,9 +170,23 @@ class HypferRoomsHandler:
|
|
88
170
|
second_segment = await self.rdp(points[index:], epsilon)
|
89
171
|
|
90
172
|
# Build the result list (avoiding duplicating the common point)
|
91
|
-
|
173
|
+
result = first_segment[:-1] + second_segment
|
92
174
|
else:
|
93
|
-
|
175
|
+
result = [points[0], points[-1]]
|
176
|
+
|
177
|
+
# Limit cache size
|
178
|
+
if len(self._rdp_cache) > 100: # Keep only 100 most recent items
|
179
|
+
try:
|
180
|
+
self._rdp_cache.pop(next(iter(self._rdp_cache)))
|
181
|
+
except (StopIteration, KeyError):
|
182
|
+
pass
|
183
|
+
|
184
|
+
# Cache the result
|
185
|
+
self._rdp_cache[cache_key] = result
|
186
|
+
return result
|
187
|
+
|
188
|
+
# Cache for corner results
|
189
|
+
_corners_cache = {}
|
94
190
|
|
95
191
|
async def async_get_corners(
|
96
192
|
self, mask: np.ndarray, epsilon_factor: float = 0.05
|
@@ -98,6 +194,7 @@ class HypferRoomsHandler:
|
|
98
194
|
"""
|
99
195
|
Get the corners of a room shape as a list of (x, y) tuples.
|
100
196
|
Uses contour detection and Douglas-Peucker algorithm to simplify the contour.
|
197
|
+
Optimized with caching and faster calculations.
|
101
198
|
|
102
199
|
Args:
|
103
200
|
mask: Binary mask of the room (1 for room, 0 for background)
|
@@ -106,7 +203,18 @@ class HypferRoomsHandler:
|
|
106
203
|
Returns:
|
107
204
|
List of (x, y) tuples representing the corners of the room
|
108
205
|
"""
|
109
|
-
#
|
206
|
+
# Create a hash of the mask and epsilon factor for caching
|
207
|
+
mask_hash = hash((mask.tobytes(), epsilon_factor))
|
208
|
+
|
209
|
+
# Check if we have a cached result
|
210
|
+
if mask_hash in self._corners_cache:
|
211
|
+
return self._corners_cache[mask_hash]
|
212
|
+
|
213
|
+
# Fast path for empty masks
|
214
|
+
if not np.any(mask):
|
215
|
+
return []
|
216
|
+
|
217
|
+
# Find contours in the mask - this uses our optimized method with caching
|
110
218
|
contour = await self.async_moore_neighbor_trace(mask)
|
111
219
|
|
112
220
|
if not contour:
|
@@ -118,7 +226,7 @@ class HypferRoomsHandler:
|
|
118
226
|
x_min, x_max = np.min(x_indices), np.max(x_indices)
|
119
227
|
y_min, y_max = np.min(y_indices), np.max(y_indices)
|
120
228
|
|
121
|
-
|
229
|
+
result = [
|
122
230
|
(x_min, y_min), # Top-left
|
123
231
|
(x_max, y_min), # Top-right
|
124
232
|
(x_max, y_max), # Bottom-right
|
@@ -126,12 +234,28 @@ class HypferRoomsHandler:
|
|
126
234
|
(x_min, y_min), # Back to top-left to close the polygon
|
127
235
|
]
|
128
236
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
237
|
+
# Cache the result
|
238
|
+
self._corners_cache[mask_hash] = result
|
239
|
+
return result
|
240
|
+
|
241
|
+
# For small contours (less than 10 points), skip simplification
|
242
|
+
if len(contour) <= 10:
|
243
|
+
# Ensure the contour is closed
|
244
|
+
if contour[0] != contour[-1]:
|
245
|
+
contour.append(contour[0])
|
246
|
+
|
247
|
+
# Cache and return
|
248
|
+
self._corners_cache[mask_hash] = contour
|
249
|
+
return contour
|
250
|
+
|
251
|
+
# For larger contours, calculate perimeter more efficiently using numpy
|
252
|
+
points = np.array(contour)
|
253
|
+
# Calculate differences between consecutive points
|
254
|
+
diffs = np.diff(points, axis=0)
|
255
|
+
# Calculate squared distances
|
256
|
+
squared_dists = np.sum(diffs**2, axis=1)
|
257
|
+
# Calculate perimeter as sum of distances
|
258
|
+
perimeter = np.sum(np.sqrt(squared_dists))
|
135
259
|
|
136
260
|
# Apply Douglas-Peucker algorithm to simplify the contour
|
137
261
|
epsilon = epsilon_factor * perimeter
|
@@ -147,7 +271,7 @@ class HypferRoomsHandler:
|
|
147
271
|
LOGGER.debug(
|
148
272
|
f"{self.vacuum_id}: Too few points in contour, using bounding box"
|
149
273
|
)
|
150
|
-
|
274
|
+
result = [
|
151
275
|
(x_min, y_min), # Top-left
|
152
276
|
(x_max, y_min), # Top-right
|
153
277
|
(x_max, y_max), # Bottom-right
|
@@ -155,16 +279,34 @@ class HypferRoomsHandler:
|
|
155
279
|
(x_min, y_min), # Back to top-left to close the polygon
|
156
280
|
]
|
157
281
|
|
282
|
+
# Cache the result
|
283
|
+
self._corners_cache[mask_hash] = result
|
284
|
+
return result
|
285
|
+
|
158
286
|
# Ensure the contour is closed
|
159
287
|
if simplified_contour[0] != simplified_contour[-1]:
|
160
288
|
simplified_contour.append(simplified_contour[0])
|
161
289
|
|
290
|
+
# Limit cache size
|
291
|
+
if len(self._corners_cache) > 50: # Keep only 50 most recent items
|
292
|
+
try:
|
293
|
+
self._corners_cache.pop(next(iter(self._corners_cache)))
|
294
|
+
except (StopIteration, KeyError):
|
295
|
+
pass
|
296
|
+
|
297
|
+
# Cache the result
|
298
|
+
self._corners_cache[mask_hash] = simplified_contour
|
162
299
|
return simplified_contour
|
163
300
|
|
301
|
+
# Cache for labeled arrays to avoid redundant calculations
|
302
|
+
_label_cache = {}
|
303
|
+
_hull_cache = {}
|
304
|
+
|
164
305
|
@staticmethod
|
165
306
|
async def async_moore_neighbor_trace(mask: np.ndarray) -> List[Tuple[int, int]]:
|
166
307
|
"""
|
167
|
-
Trace the contour of a binary mask using an optimized
|
308
|
+
Trace the contour of a binary mask using an optimized approach.
|
309
|
+
Uses caching and simplified algorithms for better performance.
|
168
310
|
|
169
311
|
Args:
|
170
312
|
mask: Binary mask of the room (1 for room, 0 for background)
|
@@ -172,81 +314,129 @@ class HypferRoomsHandler:
|
|
172
314
|
Returns:
|
173
315
|
List of (x, y) tuples representing the contour
|
174
316
|
"""
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
for
|
183
|
-
|
184
|
-
if np.any(padded[y]):
|
185
|
-
# Find the first 1 in this row
|
186
|
-
x = np.where(padded[y] == 1)[0][0]
|
187
|
-
start = (int(x), int(y))
|
188
|
-
break
|
189
|
-
|
190
|
-
if start is None:
|
317
|
+
# Create a hash of the mask for caching
|
318
|
+
mask_hash = hash(mask.tobytes())
|
319
|
+
|
320
|
+
# Check if we have a cached result
|
321
|
+
if mask_hash in HypferRoomsHandler._hull_cache:
|
322
|
+
return HypferRoomsHandler._hull_cache[mask_hash]
|
323
|
+
|
324
|
+
# Fast path for empty masks
|
325
|
+
if not np.any(mask):
|
191
326
|
return []
|
192
327
|
|
193
|
-
#
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
(
|
201
|
-
(
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
#
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
#
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
):
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
328
|
+
# Find bounding box of non-zero elements (much faster than full labeling for simple cases)
|
329
|
+
y_indices, x_indices = np.where(mask > 0)
|
330
|
+
if len(x_indices) == 0 or len(y_indices) == 0:
|
331
|
+
return []
|
332
|
+
|
333
|
+
# For very small rooms (less than 100 pixels), just use bounding box
|
334
|
+
if len(x_indices) < 100:
|
335
|
+
x_min, x_max = np.min(x_indices), np.max(x_indices)
|
336
|
+
y_min, y_max = np.min(y_indices), np.max(y_indices)
|
337
|
+
|
338
|
+
# Create a simple rectangle
|
339
|
+
hull_vertices = [
|
340
|
+
(int(x_min), int(y_min)), # Top-left
|
341
|
+
(int(x_max), int(y_min)), # Top-right
|
342
|
+
(int(x_max), int(y_max)), # Bottom-right
|
343
|
+
(int(x_min), int(y_max)), # Bottom-left
|
344
|
+
(int(x_min), int(y_min)), # Back to top-left to close the polygon
|
345
|
+
]
|
346
|
+
|
347
|
+
# Cache and return the result
|
348
|
+
HypferRoomsHandler._hull_cache[mask_hash] = hull_vertices
|
349
|
+
return hull_vertices
|
350
|
+
|
351
|
+
# For larger rooms, use convex hull but with optimizations
|
352
|
+
try:
|
353
|
+
# Import here to avoid overhead for small rooms
|
354
|
+
from scipy import ndimage
|
355
|
+
from scipy.spatial import ConvexHull
|
356
|
+
|
357
|
+
# Use cached labeled array if available
|
358
|
+
if mask_hash in HypferRoomsHandler._label_cache:
|
359
|
+
labeled_array = HypferRoomsHandler._label_cache[mask_hash]
|
360
|
+
else:
|
361
|
+
# Find connected components - this is expensive
|
362
|
+
labeled_array, _ = ndimage.label(mask)
|
363
|
+
# Cache the result for future use
|
364
|
+
HypferRoomsHandler._label_cache[mask_hash] = labeled_array
|
365
|
+
|
366
|
+
# Limit cache size to prevent memory issues
|
367
|
+
if len(HypferRoomsHandler._label_cache) > 50: # Keep only 50 most recent items
|
368
|
+
# Remove oldest item (first key)
|
369
|
+
try:
|
370
|
+
HypferRoomsHandler._label_cache.pop(next(iter(HypferRoomsHandler._label_cache)))
|
371
|
+
except (StopIteration, KeyError):
|
372
|
+
# Handle edge case of empty cache
|
373
|
+
pass
|
374
|
+
|
375
|
+
# Create a mask with all components
|
376
|
+
all_components_mask = (labeled_array > 0)
|
377
|
+
|
378
|
+
# Sample points instead of using all points for large masks
|
379
|
+
# This significantly reduces computation time for ConvexHull
|
380
|
+
if len(x_indices) > 1000:
|
381
|
+
# Sample every 10th point for very large rooms
|
382
|
+
step = 10
|
383
|
+
elif len(x_indices) > 500:
|
384
|
+
# Sample every 5th point for medium-sized rooms
|
385
|
+
step = 5
|
386
|
+
else:
|
387
|
+
# Use all points for smaller rooms
|
388
|
+
step = 1
|
389
|
+
|
390
|
+
# Sample points using the step size
|
391
|
+
sampled_y = y_indices[::step]
|
392
|
+
sampled_x = x_indices[::step]
|
393
|
+
|
394
|
+
# Create a list of points
|
395
|
+
points = np.column_stack((sampled_x, sampled_y))
|
396
|
+
|
397
|
+
# Compute the convex hull
|
398
|
+
hull = ConvexHull(points)
|
399
|
+
|
400
|
+
# Extract the vertices of the convex hull
|
401
|
+
hull_vertices = [(int(points[v, 0]), int(points[v, 1])) for v in hull.vertices]
|
402
|
+
|
403
|
+
# Ensure the hull is closed
|
404
|
+
if hull_vertices[0] != hull_vertices[-1]:
|
405
|
+
hull_vertices.append(hull_vertices[0])
|
406
|
+
|
407
|
+
# Cache and return the result
|
408
|
+
HypferRoomsHandler._hull_cache[mask_hash] = hull_vertices
|
409
|
+
|
410
|
+
# Limit hull cache size
|
411
|
+
if len(HypferRoomsHandler._hull_cache) > 50:
|
412
|
+
try:
|
413
|
+
HypferRoomsHandler._hull_cache.pop(next(iter(HypferRoomsHandler._hull_cache)))
|
414
|
+
except (StopIteration, KeyError):
|
415
|
+
pass
|
416
|
+
|
417
|
+
return hull_vertices
|
418
|
+
|
419
|
+
except Exception as e:
|
420
|
+
LOGGER.warning(f"Failed to compute convex hull: {e}. Falling back to bounding box.")
|
421
|
+
|
422
|
+
# Fallback to bounding box if convex hull fails
|
423
|
+
x_min, x_max = np.min(x_indices), np.max(x_indices)
|
424
|
+
y_min, y_max = np.min(y_indices), np.max(y_indices)
|
425
|
+
|
426
|
+
# Create a simple rectangle
|
427
|
+
hull_vertices = [
|
428
|
+
(int(x_min), int(y_min)), # Top-left
|
429
|
+
(int(x_max), int(y_min)), # Top-right
|
430
|
+
(int(x_max), int(y_max)), # Bottom-right
|
431
|
+
(int(x_min), int(y_max)), # Bottom-left
|
432
|
+
(int(x_min), int(y_min)), # Back to top-left to close the polygon
|
433
|
+
]
|
434
|
+
|
435
|
+
# Cache and return the result
|
436
|
+
HypferRoomsHandler._hull_cache[mask_hash] = hull_vertices
|
437
|
+
return hull_vertices
|
438
|
+
|
439
|
+
|
250
440
|
|
251
441
|
async def async_extract_room_properties(
|
252
442
|
self, json_data: Dict[str, Any]
|
@@ -267,6 +457,9 @@ class HypferRoomsHandler:
|
|
267
457
|
vacuum_id = self.vacuum_id
|
268
458
|
room_id_counter = 0
|
269
459
|
|
460
|
+
# Store the JSON data for reference in other methods
|
461
|
+
self.current_json_data = json_data
|
462
|
+
|
270
463
|
for layer in json_data.get("layers", []):
|
271
464
|
if layer.get("__class") == "MapLayer" and layer.get("type") == "segment":
|
272
465
|
meta_data = layer.get("metaData", {})
|
@@ -2,10 +2,10 @@ valetudo_map_parser/__init__.py,sha256=cewtLadNSOg3X2Ts2SuG8mTJqo0ncsFRg_sQ4VkM4
|
|
2
2
|
valetudo_map_parser/config/__init__.py,sha256=DQ9plV3ZF_K25Dp5ZQHPDoG-40dQoJNdNi-dfNeR3Zc,48
|
3
3
|
valetudo_map_parser/config/auto_crop.py,sha256=6OvRsWzXMXBaSEvgwpaaisNdozDKiDyTmPjknFxoUMc,12624
|
4
4
|
valetudo_map_parser/config/color_utils.py,sha256=D4NXRhuPdQ7UDKM3vLNYR0HnACl9AB75EnfCp5tGliI,4502
|
5
|
-
valetudo_map_parser/config/colors.py,sha256=
|
6
|
-
valetudo_map_parser/config/drawable.py,sha256=
|
5
|
+
valetudo_map_parser/config/colors.py,sha256=LE7sl4Qy0TkxbkjgB3dotYIfXqhc-fllkFQxexVvUvg,29909
|
6
|
+
valetudo_map_parser/config/drawable.py,sha256=qenuxD1-Vvyus9o8alJFYRqL54aO3pakMqPSYNGvpe8,34169
|
7
7
|
valetudo_map_parser/config/drawable_elements.py,sha256=bkEwdbx1upt9vaPaqE_VR1rtwRsaiH-IVKc3mHNa8IY,12065
|
8
|
-
valetudo_map_parser/config/enhanced_drawable.py,sha256=
|
8
|
+
valetudo_map_parser/config/enhanced_drawable.py,sha256=6yGoOq_dLf2VCghO_URSyGfLAshFyzS3iEPeHw1PeDo,12586
|
9
9
|
valetudo_map_parser/config/optimized_element_map.py,sha256=52BCnkvVv9bre52LeVIfT8nhnEIpc0TuWTv1xcNu0Rk,15744
|
10
10
|
valetudo_map_parser/config/rand25_parser.py,sha256=kIayyqVZBfQfAMkiArzqrrj9vqZB3pkgT0Y5ufrQmGA,16448
|
11
11
|
valetudo_map_parser/config/room_outline.py,sha256=D20D-yeyKnlmVbW9lI7bsPtQGn2XkcWow6YNOEPnWVg,4800
|
@@ -14,13 +14,13 @@ valetudo_map_parser/config/types.py,sha256=e-eZSwbPm3m5JfCDaKhnUFspmcRFSv74huxeg
|
|
14
14
|
valetudo_map_parser/config/utils.py,sha256=RsMjpjVqNbkI502yhLiRaB0GjCADqmRRcz-TkC6zklQ,31073
|
15
15
|
valetudo_map_parser/hypfer_draw.py,sha256=P8CrKysLaBb63ZArfqxN2Og6JCU6sPHPFHOte5noCGg,26654
|
16
16
|
valetudo_map_parser/hypfer_handler.py,sha256=WYFrp-q5wBsy0cTcVQUCXXVGTtW30z2W2dYvjKz2el8,23292
|
17
|
-
valetudo_map_parser/hypfer_rooms_handler.py,sha256=
|
17
|
+
valetudo_map_parser/hypfer_rooms_handler.py,sha256=NkpOA6Gdq-2D3lLAxvtNuuWMvPXHxeMY2TO5RZLSHlU,22652
|
18
18
|
valetudo_map_parser/map_data.py,sha256=zQKE8EzWxR0r0qyfD1QQq51T1wFrpcIeXtnpm92-LXQ,17743
|
19
19
|
valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
20
|
valetudo_map_parser/rand25_handler.py,sha256=eLFX_gmGLaWQwvp8hVj8CgcNOfLsYNIdE1OLRcQy_yM,19988
|
21
21
|
valetudo_map_parser/reimg_draw.py,sha256=1q8LkNTPHEA9Tsapc_JnVw51kpPYNhaBU-KmHkefCQY,12507
|
22
|
-
valetudo_map_parser-0.1.
|
23
|
-
valetudo_map_parser-0.1.
|
24
|
-
valetudo_map_parser-0.1.
|
25
|
-
valetudo_map_parser-0.1.
|
26
|
-
valetudo_map_parser-0.1.
|
22
|
+
valetudo_map_parser-0.1.9b53.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
|
23
|
+
valetudo_map_parser-0.1.9b53.dist-info/METADATA,sha256=i8nDujD2s2Qs62WwEv-3AIO23XJTvxvSZXY5QcswEtc,3321
|
24
|
+
valetudo_map_parser-0.1.9b53.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
|
25
|
+
valetudo_map_parser-0.1.9b53.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
26
|
+
valetudo_map_parser-0.1.9b53.dist-info/RECORD,,
|
File without changes
|
{valetudo_map_parser-0.1.9b51.dist-info → valetudo_map_parser-0.1.9b53.dist-info}/NOTICE.txt
RENAMED
File without changes
|
File without changes
|