Skip to content

Commit f8cc6c5

Browse files
author
John75SunCity
committed
feat: Add 2D Blueprint Editor with indoor navigation
Features: - Canvas-based 2D blueprint editor for warehouse layout - Draw walls, zones, shelving units, and aisles - A* pathfinding algorithm for indoor navigation - Turn-by-turn directions like Google Maps for buildings - Export coordinates to JSON, CSV, GeoJSON formats - Seamless integration with existing 3D visualization - Mobile-friendly responsive design Components: - warehouse_blueprint_editor.js (1592 lines) - OWL component - warehouse_blueprint_editor.xml - OWL template - warehouse_blueprint_editor.scss - Styles API endpoints added: - /warehouse/blueprint/<id>/data - Get blueprint data - /warehouse/blueprint/<id>/save - Save blueprint changes - /warehouse/blueprint/<id>/navigate - Calculate paths - /warehouse/blueprint/<id>/export - Export coordinates - /warehouse/blueprint/<id>/locations - List locations Model methods added: - _get_blueprint_editor_data() - _save_blueprint_editor_data() - _calculate_navigation_path() - _export_coordinates() - action_open_2d_editor()
1 parent 9748354 commit f8cc6c5

File tree

6 files changed

+2562
-1
lines changed

6 files changed

+2562
-1
lines changed

records_management_3d_warehouse/controllers/warehouse_3d_data.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,111 @@ def export_visualization(self, config_id, format='png', **kw):
7575
# This will be handled client-side using canvas.toDataURL()
7676
# This endpoint could generate server-side exports if needed
7777
pass
78+
79+
# Blueprint Editor API Routes
80+
@http.route('/warehouse/blueprint/<int:blueprint_id>/data', type='json', auth='user')
81+
def get_blueprint_data(self, blueprint_id, **kw):
82+
"""
83+
Get complete blueprint data for 2D editor
84+
85+
Returns:
86+
dict: Blueprint dimensions, walls, zones, shelves, aisles, locations
87+
"""
88+
blueprint = request.env['warehouse.blueprint'].browse(blueprint_id)
89+
90+
if not blueprint.exists():
91+
return {'error': 'Blueprint not found'}
92+
93+
return blueprint._get_blueprint_editor_data()
94+
95+
@http.route('/warehouse/blueprint/<int:blueprint_id>/save', type='json', auth='user')
96+
def save_blueprint_data(self, blueprint_id, data, **kw):
97+
"""
98+
Save blueprint modifications from 2D editor
99+
100+
Args:
101+
blueprint_id: ID of warehouse.blueprint record
102+
data: dict containing walls, zones, shelves, aisles to update
103+
104+
Returns:
105+
dict: Success status and any warnings
106+
"""
107+
blueprint = request.env['warehouse.blueprint'].browse(blueprint_id)
108+
109+
if not blueprint.exists():
110+
return {'error': 'Blueprint not found'}
111+
112+
try:
113+
blueprint._save_blueprint_editor_data(data)
114+
return {'success': True}
115+
except Exception as e:
116+
return {'error': str(e)}
117+
118+
@http.route('/warehouse/blueprint/<int:blueprint_id>/navigate', type='json', auth='user')
119+
def get_navigation_path(self, blueprint_id, start_location_id, end_location_id, **kw):
120+
"""
121+
Calculate navigation path between two locations using A* algorithm
122+
123+
Args:
124+
blueprint_id: ID of warehouse.blueprint record
125+
start_location_id: Starting stock.location ID
126+
end_location_id: Destination stock.location ID
127+
128+
Returns:
129+
dict: Path coordinates, turn-by-turn directions, distance, estimated time
130+
"""
131+
blueprint = request.env['warehouse.blueprint'].browse(blueprint_id)
132+
133+
if not blueprint.exists():
134+
return {'error': 'Blueprint not found'}
135+
136+
return blueprint._calculate_navigation_path(start_location_id, end_location_id)
137+
138+
@http.route('/warehouse/blueprint/<int:blueprint_id>/export', type='json', auth='user')
139+
def export_blueprint_coordinates(self, blueprint_id, format='json', **kw):
140+
"""
141+
Export blueprint coordinates for 3D integration
142+
143+
Args:
144+
blueprint_id: ID of warehouse.blueprint record
145+
format: Export format (json, csv, geojson)
146+
147+
Returns:
148+
dict/str: Exported data in requested format
149+
"""
150+
blueprint = request.env['warehouse.blueprint'].browse(blueprint_id)
151+
152+
if not blueprint.exists():
153+
return {'error': 'Blueprint not found'}
154+
155+
return blueprint._export_coordinates(format)
156+
157+
@http.route('/warehouse/blueprint/<int:blueprint_id>/locations', type='json', auth='user')
158+
def get_blueprint_locations(self, blueprint_id, **kw):
159+
"""
160+
Get all locations for a blueprint for navigation endpoints
161+
162+
Returns:
163+
list: List of locations with id, name, barcode, coordinates
164+
"""
165+
blueprint = request.env['warehouse.blueprint'].browse(blueprint_id)
166+
167+
if not blueprint.exists():
168+
return {'error': 'Blueprint not found'}
169+
170+
# Get all locations associated with this blueprint's warehouse
171+
locations = request.env['stock.location'].search([
172+
('warehouse_blueprint_id', '=', blueprint_id),
173+
('usage', '=', 'internal'),
174+
])
175+
176+
return [{
177+
'id': loc.id,
178+
'name': loc.name,
179+
'barcode': loc.barcode or '',
180+
'posx': loc.posx or 0,
181+
'posy': loc.posy or 0,
182+
'posz': loc.posz or 0,
183+
'current_usage': len(loc.container_ids) if hasattr(loc, 'container_ids') else 0,
184+
'max_capacity': loc.max_capacity if hasattr(loc, 'max_capacity') else 0,
185+
} for loc in locations]

0 commit comments

Comments
 (0)