{"version":3,"sources":["components/language-switch/language-popover.tsx","components/buttons.tsx","components/dense-icon.tsx","components/dialogs.tsx","components/draggable-list.tsx","components/enhanced-table.tsx","components/menu-items.tsx","components/inputs.tsx","components/progress.tsx","components/tabs.tsx","components/toolbar.tsx","components/tooltips.tsx","components/memos.tsx","electron-menu.ts","components/language-switch/index.tsx","components/account-button/account-popover.tsx","components/account-button/index.tsx","components/toaster.tsx","components/links.tsx","components/color-picker.tsx","redux/store.ts","viewer/js/file-system-loader.ts","../node_modules/web-ifc sync","redux/projections-slice.ts","projections/projections.tsx","projections/manager.tsx","engine-viewer.tsx","index.tsx","providers/auth-provider.tsx","providers/tools-provider.tsx","providers/task-queue-provider.tsx","providers/viewer-provider.tsx","providers/bookmarks-provider.tsx","hooks/use-table-state.ts","redux/bookmarks-slice.ts","electron-modules.ts","move-settings.ts","types/project.ts","localization/i18n.ts","localization/index.ts","classifications.ts","theme/colors.ts","theme/index.ts","api/tags.ts","api/bookmarks.ts","api/index.ts","api/folders.ts","redux/assets-slice.ts","hooks/use-dialog.tsx","hooks/use-task-queue.ts","hooks/use-viewer.ts","hooks/use-active-tool.ts","hooks/use-project-watcher.ts","hooks/use-popover.tsx","hooks/use-auth.ts","hooks/use-context-menu.ts","hooks/use-global-settings.ts","hooks/use-websockets.ts","hooks/use-bookmarks.ts","types/controls.ts","redux/custom-links-slice.ts","viewer/js/projections.ts","viewer/js/worker-pool.ts","viewer/js/utilities/change-detection.ts","viewer/js/utilities/unit-converter.ts","viewer/js/utilities/misc-utils.ts","viewer/js/utilities/polygon.ts","viewer/js/utilities/parse.ts","viewer/js/utilities/mesh-utils.ts","utilities/dates.ts","providers/global-settings-provider.tsx","providers/websocket-provider.tsx","viewer/textures/colormaps/classifications.png","file-extensions.ts","types/measurements.ts","redux/settings-slice.ts","urls.ts","point-profile/point-profile.tsx","redux/camera-slice.ts","executable.ts","export/utils/misc.ts","redux/folders-slice.ts","types/tags.ts","viewer/js/measurements/land-xml-calculation.ts","viewer/textures/tag-icons/basic-pins/basic-pin-large-0.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-1.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-2.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-3.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-4.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-5.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-6.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-7.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-8.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-9.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-10.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-11.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-12.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-13.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-14.png","viewer/textures/tag-icons/basic-pins/basic-pin-large-15.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-0.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-1.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-2.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-3.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-4.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-5.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-6.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-7.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-8.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-9.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-10.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-11.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-12.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-13.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-14.png","viewer/textures/tag-icons/basic-pins/basic-pin-small-15.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-0.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-1.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-2.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-3.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-4.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-5.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-6.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-7.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-8.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-9.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-10.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-11.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-12.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-13.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-14.png","viewer/textures/tag-icons/basic-pins/basic-push-pin-15.png","viewer/textures/tag-icons/basic-pins/index.ts","viewer/textures/tag-icons/traffic-signs/001-ahead only.png","viewer/textures/tag-icons/traffic-signs/002-crossroads.png","viewer/textures/tag-icons/traffic-signs/003-falling rocks.png","viewer/textures/tag-icons/traffic-signs/004-give way.png","viewer/textures/tag-icons/traffic-signs/005-hump.png","viewer/textures/tag-icons/traffic-signs/006-left turn.png","viewer/textures/tag-icons/traffic-signs/007-parking.png","viewer/textures/tag-icons/traffic-signs/008-level crossing.png","viewer/textures/tag-icons/traffic-signs/009-speed limit.png","viewer/textures/tag-icons/traffic-signs/010-narrow bridge.png","viewer/textures/tag-icons/traffic-signs/011-no bike.png","viewer/textures/tag-icons/traffic-signs/012-no trucks.png","viewer/textures/tag-icons/traffic-signs/013-no alarm.png","viewer/textures/tag-icons/traffic-signs/014-no turn left.png","viewer/textures/tag-icons/traffic-signs/015-no motorcycles.png","viewer/textures/tag-icons/traffic-signs/016-speed limit.png","viewer/textures/tag-icons/traffic-signs/017-no overtaking.png","viewer/textures/tag-icons/traffic-signs/018-pedestrian.png","viewer/textures/tag-icons/traffic-signs/019-no entry.png","viewer/textures/tag-icons/traffic-signs/020-u turn.png","viewer/textures/tag-icons/traffic-signs/021-Two way.png","viewer/textures/tag-icons/traffic-signs/022-pedestrian crossing.png","viewer/textures/tag-icons/traffic-signs/023-right turn.png","viewer/textures/tag-icons/traffic-signs/024-road work.png","viewer/textures/tag-icons/traffic-signs/025-roundabout.png","viewer/textures/tag-icons/traffic-signs/026-pedestrian crossing.png","viewer/textures/tag-icons/traffic-signs/027-Slippery road.png","viewer/textures/tag-icons/traffic-signs/028-traffic lights.png","viewer/textures/tag-icons/traffic-signs/029-turn left.png","viewer/textures/tag-icons/traffic-signs/030-turn right.png","viewer/textures/tag-icons/traffic-signs/031-uneven.png","viewer/textures/tag-icons/traffic-signs/032-maximum.png","viewer/textures/tag-icons/traffic-signs/033-wild animals.png","viewer/textures/tag-icons/traffic-signs/index.ts","viewer/textures/tag-icons/uk-road-signs/001-narrow.png","viewer/textures/tag-icons/uk-road-signs/002-merge.png","viewer/textures/tag-icons/uk-road-signs/003-curve.png","viewer/textures/tag-icons/uk-road-signs/004-curve.png","viewer/textures/tag-icons/uk-road-signs/005-Junction.png","viewer/textures/tag-icons/uk-road-signs/006-curve.png","viewer/textures/tag-icons/uk-road-signs/007-crossroads.png","viewer/textures/tag-icons/uk-road-signs/008-hump.png","viewer/textures/tag-icons/uk-road-signs/009-uneven.png","viewer/textures/tag-icons/uk-road-signs/010-roundabout.png","viewer/textures/tag-icons/uk-road-signs/011-Two way.png","viewer/textures/tag-icons/uk-road-signs/012-Junction.png","viewer/textures/tag-icons/uk-road-signs/013-Junction.png","viewer/textures/tag-icons/uk-road-signs/014-Two way.png","viewer/textures/tag-icons/uk-road-signs/015-level.png","viewer/textures/tag-icons/uk-road-signs/016-warning.png","viewer/textures/tag-icons/uk-road-signs/017-hump.png","viewer/textures/tag-icons/uk-road-signs/018-dock.png","viewer/textures/tag-icons/uk-road-signs/019-merge.png","viewer/textures/tag-icons/uk-road-signs/020-falling rocks.png","viewer/textures/tag-icons/uk-road-signs/021-speed limit.png","viewer/textures/tag-icons/uk-road-signs/022-speed limit.png","viewer/textures/tag-icons/uk-road-signs/023-speed limit.png","viewer/textures/tag-icons/uk-road-signs/024-speed limit.png","viewer/textures/tag-icons/uk-road-signs/025-speed limit.png","viewer/textures/tag-icons/uk-road-signs/026-speed limit.png","viewer/textures/tag-icons/uk-road-signs/027-speed limit.png","viewer/textures/tag-icons/uk-road-signs/028-priority.png","viewer/textures/tag-icons/uk-road-signs/029-no overtaking.png","viewer/textures/tag-icons/uk-road-signs/030-no turn right.png","viewer/textures/tag-icons/uk-road-signs/031-u turn.png","viewer/textures/tag-icons/uk-road-signs/032-no stopping.png","viewer/textures/tag-icons/uk-road-signs/033-no waiting.png","viewer/textures/tag-icons/uk-road-signs/034-ahead.png","viewer/textures/tag-icons/uk-road-signs/035-turn left.png","viewer/textures/tag-icons/uk-road-signs/036-keep left.png","viewer/textures/tag-icons/uk-road-signs/037-direction.png","viewer/textures/tag-icons/uk-road-signs/038-turn left.png","viewer/textures/tag-icons/uk-road-signs/039-roundabout.png","viewer/textures/tag-icons/uk-road-signs/040-no entry.png","viewer/textures/tag-icons/uk-road-signs/041-parking.png","viewer/textures/tag-icons/uk-road-signs/042-priority.png","viewer/textures/tag-icons/uk-road-signs/043-cul de sac.png","viewer/textures/tag-icons/uk-road-signs/044-countdown.png","viewer/textures/tag-icons/uk-road-signs/045-countdown.png","viewer/textures/tag-icons/uk-road-signs/046-countdown.png","viewer/textures/tag-icons/uk-road-signs/047-hospital.png","viewer/textures/tag-icons/uk-road-signs/048-information.png","viewer/textures/tag-icons/uk-road-signs/049-speed camera.png","viewer/textures/tag-icons/uk-road-signs/050-lane.png","viewer/textures/tag-icons/uk-road-signs/051-end motorway.png","viewer/textures/tag-icons/uk-road-signs/052-motorway.png","viewer/textures/tag-icons/uk-road-signs/053-one way.png","viewer/textures/tag-icons/uk-road-signs/054-direction.png","viewer/textures/tag-icons/uk-road-signs/055-stop.png","viewer/textures/tag-icons/uk-road-signs/056-road.png","viewer/textures/tag-icons/uk-road-signs/057-emergency diversion.png","viewer/textures/tag-icons/uk-road-signs/058-emergency diversion.png","viewer/textures/tag-icons/uk-road-signs/059-emergency diversion.png","viewer/textures/tag-icons/uk-road-signs/060-emergency diversion.png","viewer/textures/tag-icons/uk-road-signs/index.ts","viewer/textures/tag-icons/package_objects/construction--barrier--temporary.png","viewer/textures/tag-icons/package_objects/construction--flat--crosswalk-plain.png","viewer/textures/tag-icons/package_objects/construction--flat--driveway.png","viewer/textures/tag-icons/package_objects/construction--flat--flat-driveway.png","viewer/textures/tag-icons/package_objects/marking--discrete--arrow--left.png","viewer/textures/tag-icons/package_objects/marking--discrete--arrow--right.png","viewer/textures/tag-icons/package_objects/marking--discrete--arrow--split-left-or-straight.png","viewer/textures/tag-icons/package_objects/marking--discrete--arrow--split-right-or-straight.png","viewer/textures/tag-icons/package_objects/marking--discrete--arrow--straight.png","viewer/textures/tag-icons/package_objects/marking--discrete--crosswalk-zebra.png","viewer/textures/tag-icons/package_objects/marking--discrete--give-way-row.png","viewer/textures/tag-icons/package_objects/marking--discrete--give-way-single.png","viewer/textures/tag-icons/package_objects/marking--discrete--other-marking.png","viewer/textures/tag-icons/package_objects/marking--discrete--stop-line.png","viewer/textures/tag-icons/package_objects/marking--discrete--symbol--bicycle.png","viewer/textures/tag-icons/package_objects/marking--discrete--text.png","viewer/textures/tag-icons/package_objects/object--banner.png","viewer/textures/tag-icons/package_objects/object--bench.png","viewer/textures/tag-icons/package_objects/object--bike-rack.png","viewer/textures/tag-icons/package_objects/object--catch-basin.png","viewer/textures/tag-icons/package_objects/object--cctv-camera.png","viewer/textures/tag-icons/package_objects/object--fire-hydrant.png","viewer/textures/tag-icons/package_objects/object--junction-box.png","viewer/textures/tag-icons/package_objects/object--mailbox.png","viewer/textures/tag-icons/package_objects/object--manhole.png","viewer/textures/tag-icons/package_objects/object--parking-meter.png","viewer/textures/tag-icons/package_objects/object--phone-booth.png","viewer/textures/tag-icons/package_objects/object--sign--advertisement.png","viewer/textures/tag-icons/package_objects/object--sign--information.png","viewer/textures/tag-icons/package_objects/object--sign--store.png","viewer/textures/tag-icons/package_objects/object--street-light.png","viewer/textures/tag-icons/package_objects/object--support--pole.png","viewer/textures/tag-icons/package_objects/object--support--traffic-sign-frame.png","viewer/textures/tag-icons/package_objects/object--support--utility-pole.png","viewer/textures/tag-icons/package_objects/object--traffic-cone.png","viewer/textures/tag-icons/package_objects/object--traffic-light.png","viewer/textures/tag-icons/package_objects/object--trash-can.png","viewer/textures/tag-icons/package_objects/object--water-valve.png","viewer/textures/tag-icons/package_objects/index.ts","viewer/textures/tag-icons/package_signs/complementary--accident-area--g1.png","viewer/textures/tag-icons/package_signs/complementary--accident-area--g2.png","viewer/textures/tag-icons/package_signs/complementary--accident-area--g3.png","viewer/textures/tag-icons/package_signs/complementary--accident-area--g4.png","viewer/textures/tag-icons/package_signs/complementary--advisory-exit-or-ramp-speed--g1.png","viewer/textures/tag-icons/package_signs/complementary--bicycles--g1.png","viewer/textures/tag-icons/package_signs/complementary--bicycles-and-pedestrians-detour--g1.png","viewer/textures/tag-icons/package_signs/complementary--bicycles-or-pedestrians-detour--g1.png","viewer/textures/tag-icons/package_signs/complementary--bicycles-turn-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--bike-route--g1.png","viewer/textures/tag-icons/package_signs/complementary--bike-route--g3.png","viewer/textures/tag-icons/package_signs/complementary--both-directions--g1.png","viewer/textures/tag-icons/package_signs/complementary--both-directions--g2.png","viewer/textures/tag-icons/package_signs/complementary--buses--g1.png","viewer/textures/tag-icons/package_signs/complementary--buses-and-trucks--g1.png","viewer/textures/tag-icons/package_signs/complementary--camera--g1.png","viewer/textures/tag-icons/package_signs/complementary--camera--g2.png","viewer/textures/tag-icons/package_signs/complementary--camera--g3.png","viewer/textures/tag-icons/package_signs/complementary--camera--g4.png","viewer/textures/tag-icons/package_signs/complementary--camera--g5.png","viewer/textures/tag-icons/package_signs/complementary--caravan-trailers--g2.png","viewer/textures/tag-icons/package_signs/complementary--caravan-trailers--g3.png","viewer/textures/tag-icons/package_signs/complementary--caravans--g2.png","viewer/textures/tag-icons/package_signs/complementary--carts--g1.png","viewer/textures/tag-icons/package_signs/complementary--chevron-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--chevron-left--g2.png","viewer/textures/tag-icons/package_signs/complementary--chevron-left--g3.png","viewer/textures/tag-icons/package_signs/complementary--chevron-left--g4.png","viewer/textures/tag-icons/package_signs/complementary--chevron-left--g5.png","viewer/textures/tag-icons/package_signs/complementary--chevron-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--chevron-right--g2.png","viewer/textures/tag-icons/package_signs/complementary--chevron-right--g3.png","viewer/textures/tag-icons/package_signs/complementary--chevron-right--g4.png","viewer/textures/tag-icons/package_signs/complementary--chevron-right--g5.png","viewer/textures/tag-icons/package_signs/complementary--dangerous-or-pollutant-good--g1.png","viewer/textures/tag-icons/package_signs/complementary--dead-end--g1.png","viewer/textures/tag-icons/package_signs/complementary--detour--g1.png","viewer/textures/tag-icons/package_signs/complementary--disabled-persons--g1.png","viewer/textures/tag-icons/package_signs/complementary--distance--g1.png","viewer/textures/tag-icons/package_signs/complementary--distance--g2.png","viewer/textures/tag-icons/package_signs/complementary--distance--g3.png","viewer/textures/tag-icons/package_signs/complementary--end-of-road-works--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-bicycles--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-bicycles--g2.png","viewer/textures/tag-icons/package_signs/complementary--except-buses--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-carts--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-motorcycles--g2.png","viewer/textures/tag-icons/package_signs/complementary--except-polluting-level-green--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-polluting-level-green-yellow--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-polluting-level-green-yellow-red--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-tractors--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-tractors--g2.png","viewer/textures/tag-icons/package_signs/complementary--except-trailers--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-trailers--g2.png","viewer/textures/tag-icons/package_signs/complementary--except-trains--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-trams--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-trucks--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-vehicles--g1.png","viewer/textures/tag-icons/package_signs/complementary--except-vehicles--g2.png","viewer/textures/tag-icons/package_signs/complementary--go-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--go-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--go-straight-or-turn-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--go-straight-or-turn-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--height-limit--g1.png","viewer/textures/tag-icons/package_signs/complementary--height-limit--g2.png","viewer/textures/tag-icons/package_signs/complementary--including-bicycles-and-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/complementary--including-buses-vehicles--g1.png","viewer/textures/tag-icons/package_signs/complementary--keep-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--keep-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--lane-control--g1.png","viewer/textures/tag-icons/package_signs/complementary--lane-control--g2.png","viewer/textures/tag-icons/package_signs/complementary--lane-control--g3.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-10--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-15--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-20--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-25--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-30--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-35--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-40--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-45--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-50--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-55--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-60--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-65--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-70--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-75--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-80--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-85--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-90--g1.png","viewer/textures/tag-icons/package_signs/complementary--maximum-speed-limit-95--g1.png","viewer/textures/tag-icons/package_signs/complementary--motorcycles--g1.png","viewer/textures/tag-icons/package_signs/complementary--motorcycles--g2.png","viewer/textures/tag-icons/package_signs/complementary--motorcycles--g3.png","viewer/textures/tag-icons/package_signs/complementary--motorcycles--g4.png","viewer/textures/tag-icons/package_signs/complementary--obstacle-delineator--g1.png","viewer/textures/tag-icons/package_signs/complementary--obstacle-delineator--g2.png","viewer/textures/tag-icons/package_signs/complementary--obstacle-delineator--g3.png","viewer/textures/tag-icons/package_signs/complementary--one-direction-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--one-direction-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--pass-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--pass-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--pedestrians-and-bicycles--g1.png","viewer/textures/tag-icons/package_signs/complementary--pedestrians-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--pedestrians-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--photo-enforced--g1.png","viewer/textures/tag-icons/package_signs/complementary--playground--g1.png","viewer/textures/tag-icons/package_signs/complementary--priority-route-at-intersection--g1.png","viewer/textures/tag-icons/package_signs/complementary--priority-route-at-intersection--g2.png","viewer/textures/tag-icons/package_signs/complementary--priority-route-at-intersection--g3.png","viewer/textures/tag-icons/package_signs/complementary--priority-route-at-intersection--g4.png","viewer/textures/tag-icons/package_signs/complementary--priority-route-at-intersection--g5.png","viewer/textures/tag-icons/package_signs/complementary--priority-route-at-intersection--g6.png","viewer/textures/tag-icons/package_signs/complementary--railroad--g1.png","viewer/textures/tag-icons/package_signs/complementary--railroad--g2.png","viewer/textures/tag-icons/package_signs/complementary--railroad--g3.png","viewer/textures/tag-icons/package_signs/complementary--restriction-in-both-directions--g1.png","viewer/textures/tag-icons/package_signs/complementary--roundabout-go-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--roundabout-go-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--roundabout-go-straight--g1.png","viewer/textures/tag-icons/package_signs/complementary--slippery-for-caravan-trailers--g1.png","viewer/textures/tag-icons/package_signs/complementary--snow--g2.png","viewer/textures/tag-icons/package_signs/complementary--snow--g4.png","viewer/textures/tag-icons/package_signs/complementary--snow--g5.png","viewer/textures/tag-icons/package_signs/complementary--snowmobiles--g1.png","viewer/textures/tag-icons/package_signs/complementary--soft-shoulder--g1.png","viewer/textures/tag-icons/package_signs/complementary--soft-shoulder--g2.png","viewer/textures/tag-icons/package_signs/complementary--steep-ascent--g1.png","viewer/textures/tag-icons/package_signs/complementary--steep-descent--g1.png","viewer/textures/tag-icons/package_signs/complementary--time-restrictions--g1.png","viewer/textures/tag-icons/package_signs/complementary--time-restrictions--g3.png","viewer/textures/tag-icons/package_signs/complementary--tow-away-zone--g1.png","viewer/textures/tag-icons/package_signs/complementary--tow-away-zone--g3.png","viewer/textures/tag-icons/package_signs/complementary--tractors--g1.png","viewer/textures/tag-icons/package_signs/complementary--traffic-queues--g1.png","viewer/textures/tag-icons/package_signs/complementary--trailers--g1.png","viewer/textures/tag-icons/package_signs/complementary--trailers--g2.png","viewer/textures/tag-icons/package_signs/complementary--trailers--g3.png","viewer/textures/tag-icons/package_signs/complementary--trailers--g4.png","viewer/textures/tag-icons/package_signs/complementary--trains--g1.png","viewer/textures/tag-icons/package_signs/complementary--trams--g1.png","viewer/textures/tag-icons/package_signs/complementary--trees--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks--g2.png","viewer/textures/tag-icons/package_signs/complementary--trucks--g3.png","viewer/textures/tag-icons/package_signs/complementary--trucks-and-trailers--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-buses-trailers--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-go-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-go-left-ahead--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-go-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-go-right-ahead--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-go-straight--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-turn-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--trucks-turn-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--turn-left--g1.png","viewer/textures/tag-icons/package_signs/complementary--turn-left--g2.png","viewer/textures/tag-icons/package_signs/complementary--turn-right--g1.png","viewer/textures/tag-icons/package_signs/complementary--turn-right--g2.png","viewer/textures/tag-icons/package_signs/complementary--two-way-traffic--g1.png","viewer/textures/tag-icons/package_signs/complementary--two-way-traffic--g2.png","viewer/textures/tag-icons/package_signs/complementary--two-way-traffic--g3.png","viewer/textures/tag-icons/package_signs/complementary--two-way-traffic--g4.png","viewer/textures/tag-icons/package_signs/complementary--two-way-traffic--g5.png","viewer/textures/tag-icons/package_signs/complementary--vehicles--g1.png","viewer/textures/tag-icons/package_signs/complementary--vehicles--g2.png","viewer/textures/tag-icons/package_signs/complementary--vehicles-or-buses--g1.png","viewer/textures/tag-icons/package_signs/complementary--weekends-or-holidays--g1.png","viewer/textures/tag-icons/package_signs/complementary--weight-limit--g1.png","viewer/textures/tag-icons/package_signs/complementary--when-foggy--g1.png","viewer/textures/tag-icons/package_signs/complementary--when-rainy--g1.png","viewer/textures/tag-icons/package_signs/complementary--when-rainy--g2.png","viewer/textures/tag-icons/package_signs/complementary--when-rainy--g3.png","viewer/textures/tag-icons/package_signs/complementary--when-snowy--g1.png","viewer/textures/tag-icons/package_signs/complementary--when-snowy--g2.png","viewer/textures/tag-icons/package_signs/complementary--when-snowy-or-rainy--g1.png","viewer/textures/tag-icons/package_signs/complementary--when-snowy-or-rainy--g2.png","viewer/textures/tag-icons/package_signs/complementary--when-wet--g1.png","viewer/textures/tag-icons/package_signs/complementary--width-limit--g1.png","viewer/textures/tag-icons/package_signs/complementary--working-days--g1.png","viewer/textures/tag-icons/package_signs/information--airport--g1.png","viewer/textures/tag-icons/package_signs/information--airport--g2.png","viewer/textures/tag-icons/package_signs/information--bicycle-lane--g1.png","viewer/textures/tag-icons/package_signs/information--bicycles-both-ways--g1.png","viewer/textures/tag-icons/package_signs/information--bicycles-crossing--g1.png","viewer/textures/tag-icons/package_signs/information--bicycles-crossing--g2.png","viewer/textures/tag-icons/package_signs/information--bicycles-crossing--g3.png","viewer/textures/tag-icons/package_signs/information--bike-route--g1.png","viewer/textures/tag-icons/package_signs/information--bike-route--g2.png","viewer/textures/tag-icons/package_signs/information--built-up-area--g1.png","viewer/textures/tag-icons/package_signs/information--built-up-area--g2.png","viewer/textures/tag-icons/package_signs/information--bus-lane-straight--g1.png","viewer/textures/tag-icons/package_signs/information--bus-stop--g1.png","viewer/textures/tag-icons/package_signs/information--bus-stop--g2.png","viewer/textures/tag-icons/package_signs/information--camera--g1.png","viewer/textures/tag-icons/package_signs/information--camera--g2.png","viewer/textures/tag-icons/package_signs/information--camera--g3.png","viewer/textures/tag-icons/package_signs/information--camp--g1.png","viewer/textures/tag-icons/package_signs/information--camp--g2.png","viewer/textures/tag-icons/package_signs/information--car-pool-lane--g1.png","viewer/textures/tag-icons/package_signs/information--caravan-parking--g1.png","viewer/textures/tag-icons/package_signs/information--caravan-trailer-parking--g1.png","viewer/textures/tag-icons/package_signs/information--cargo-loading-zone--g1.png","viewer/textures/tag-icons/package_signs/information--central-lane--g1.png","viewer/textures/tag-icons/package_signs/information--charging-station--g1.png","viewer/textures/tag-icons/package_signs/information--children--g1.png","viewer/textures/tag-icons/package_signs/information--children--g2.png","viewer/textures/tag-icons/package_signs/information--children-crossing--g5.png","viewer/textures/tag-icons/package_signs/information--cycling-two-abreast-permitted--g1.png","viewer/textures/tag-icons/package_signs/information--dead-end--g1.png","viewer/textures/tag-icons/package_signs/information--dead-end--g2.png","viewer/textures/tag-icons/package_signs/information--dead-end--g3.png","viewer/textures/tag-icons/package_signs/information--dead-end--g4.png","viewer/textures/tag-icons/package_signs/information--dead-end-except-bicycles--g1.png","viewer/textures/tag-icons/package_signs/information--dead-end-except-bicycles-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/information--dead-end-except-bicycles-and-pedestrians--g2.png","viewer/textures/tag-icons/package_signs/information--dead-end-left--g1.png","viewer/textures/tag-icons/package_signs/information--dead-end-left--g2.png","viewer/textures/tag-icons/package_signs/information--dead-end-right--g1.png","viewer/textures/tag-icons/package_signs/information--dead-end-right--g2.png","viewer/textures/tag-icons/package_signs/information--dead-end-right--g3.png","viewer/textures/tag-icons/package_signs/information--directions--g1.png","viewer/textures/tag-icons/package_signs/information--disabled-persons--g1.png","viewer/textures/tag-icons/package_signs/information--disabled-persons--g2.png","viewer/textures/tag-icons/package_signs/information--disabled-persons--g3.png","viewer/textures/tag-icons/package_signs/information--emergency-facility--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-advisory-maximum-speed-limit-20--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-advisory-maximum-speed-limit-40--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-advisory-maximum-speed-limit-60--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-advisory-maximum-speed-limit-70--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-advisory-maximum-speed-limit-80--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-advisory-maximum-speed-limit-90--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-bicycle-lane--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-built-up-area--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-built-up-area--g2.png","viewer/textures/tag-icons/package_signs/information--end-of-built-up-area--g3.png","viewer/textures/tag-icons/package_signs/information--end-of-built-up-area--g4.png","viewer/textures/tag-icons/package_signs/information--end-of-car-pool-lane--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-limited-access-road--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-living-street--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-living-street--g2.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-10--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-20--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-25--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-30--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-35--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-40--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-50--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-60--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-70--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-75--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-80--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-90--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-100--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-110--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-120--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-minimum-speed-130--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-motorway--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-overtaking-permitted-heavy-good-vehicles--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-road-works--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-tunnel--g1.png","viewer/textures/tag-icons/package_signs/information--end-of-tunnel--g2.png","viewer/textures/tag-icons/package_signs/information--end-of-two-way-traffic--g1.png","viewer/textures/tag-icons/package_signs/information--equestrians-permitted--g1.png","viewer/textures/tag-icons/package_signs/information--exit-ahead--g1.png","viewer/textures/tag-icons/package_signs/information--exit-ahead--g2.png","viewer/textures/tag-icons/package_signs/information--exit-ahead--g3.png","viewer/textures/tag-icons/package_signs/information--flight-port--g1.png","viewer/textures/tag-icons/package_signs/information--food--g1.png","viewer/textures/tag-icons/package_signs/information--food--g2.png","viewer/textures/tag-icons/package_signs/information--gas-station--g1.png","viewer/textures/tag-icons/package_signs/information--gas-station--g2.png","viewer/textures/tag-icons/package_signs/information--gas-station--g3.png","viewer/textures/tag-icons/package_signs/information--general-speed-limit-at-city-border--g1.png","viewer/textures/tag-icons/package_signs/information--go-left--g1.png","viewer/textures/tag-icons/package_signs/information--go-right--g1.png","viewer/textures/tag-icons/package_signs/information--go-straight--g1.png","viewer/textures/tag-icons/package_signs/information--go-straight-or-left--g1.png","viewer/textures/tag-icons/package_signs/information--go-straight-or-right--g1.png","viewer/textures/tag-icons/package_signs/information--go-straight-or-turn-left--g1.png","viewer/textures/tag-icons/package_signs/information--go-straight-or-turn-right--g1.png","viewer/textures/tag-icons/package_signs/information--hazardous-goods-vehicles-lane--g1.png","viewer/textures/tag-icons/package_signs/information--height-limit--g1.png","viewer/textures/tag-icons/package_signs/information--height-limit--g2.png","viewer/textures/tag-icons/package_signs/information--highway-directions--g1.png","viewer/textures/tag-icons/package_signs/information--highway-exit--g1.png","viewer/textures/tag-icons/package_signs/information--highway-interchange--g1.png","viewer/textures/tag-icons/package_signs/information--highway-interstate-route--g1.png","viewer/textures/tag-icons/package_signs/information--highway-interstate-route--g2.png","viewer/textures/tag-icons/package_signs/information--highway-preferential-lane--g1.png","viewer/textures/tag-icons/package_signs/information--highway-preferential-lane--g2.png","viewer/textures/tag-icons/package_signs/information--highway-reference-location--g1.png","viewer/textures/tag-icons/package_signs/information--highway-reference-location--g2.png","viewer/textures/tag-icons/package_signs/information--hiking--g1.png","viewer/textures/tag-icons/package_signs/information--hospital--g1.png","viewer/textures/tag-icons/package_signs/information--hurricane-evacuation-route--g1.png","viewer/textures/tag-icons/package_signs/information--interstate-route--g1.png","viewer/textures/tag-icons/package_signs/information--lane-control-intersections--g1.png","viewer/textures/tag-icons/package_signs/information--lane-control-left-turn--g1.png","viewer/textures/tag-icons/package_signs/information--lane-control-multiple-lanes--g1.png","viewer/textures/tag-icons/package_signs/information--lane-control-multiple-lanes--g2.png","viewer/textures/tag-icons/package_signs/information--lane-control-right-turn--g1.png","viewer/textures/tag-icons/package_signs/information--limited-access-road--g1.png","viewer/textures/tag-icons/package_signs/information--litter-container--g1.png","viewer/textures/tag-icons/package_signs/information--living-street--g1.png","viewer/textures/tag-icons/package_signs/information--living-street--g2.png","viewer/textures/tag-icons/package_signs/information--living-street--g3.png","viewer/textures/tag-icons/package_signs/information--lodging--g1.png","viewer/textures/tag-icons/package_signs/information--lodging--g2.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-10--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-20--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-25--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-30--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-35--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-40--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-50--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-60--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-70--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-75--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-80--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-90--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-100--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-110--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-120--g1.png","viewer/textures/tag-icons/package_signs/information--minimum-speed-130--g1.png","viewer/textures/tag-icons/package_signs/information--motorway--g1.png","viewer/textures/tag-icons/package_signs/information--motorway-exit-ahead--g1.png","viewer/textures/tag-icons/package_signs/information--motorway-exit-ahead--g2.png","viewer/textures/tag-icons/package_signs/information--motorway-exit-ahead--g3.png","viewer/textures/tag-icons/package_signs/information--overtaking-allowed-heavy-good-vehicles--g1.png","viewer/textures/tag-icons/package_signs/information--parallel-parking--g1.png","viewer/textures/tag-icons/package_signs/information--park-and-ride--g1.png","viewer/textures/tag-icons/package_signs/information--park-and-ride--g2.png","viewer/textures/tag-icons/package_signs/information--parking--g1.png","viewer/textures/tag-icons/package_signs/information--parking--g2.png","viewer/textures/tag-icons/package_signs/information--parking--g3.png","viewer/textures/tag-icons/package_signs/information--parking--g4.png","viewer/textures/tag-icons/package_signs/information--parking--g5.png","viewer/textures/tag-icons/package_signs/information--parking--g6.png","viewer/textures/tag-icons/package_signs/information--parking-area--g1.png","viewer/textures/tag-icons/package_signs/information--parking-with-restrictions--g1.png","viewer/textures/tag-icons/package_signs/information--pass-on-either-side--g1.png","viewer/textures/tag-icons/package_signs/information--passenger-loading-zone--g1.png","viewer/textures/tag-icons/package_signs/information--pedestrians-crossing--g1.png","viewer/textures/tag-icons/package_signs/information--pedestrians-crossing--g2.png","viewer/textures/tag-icons/package_signs/information--pedestrians-crossing--g3.png","viewer/textures/tag-icons/package_signs/information--pedestrians-only--g4.png","viewer/textures/tag-icons/package_signs/information--pedestrians-permitted--g1.png","viewer/textures/tag-icons/package_signs/information--perpendicular-parking--g1.png","viewer/textures/tag-icons/package_signs/information--picnic-site--g1.png","viewer/textures/tag-icons/package_signs/information--playground--g1.png","viewer/textures/tag-icons/package_signs/information--recreational-vehicle-sanitary-station--g1.png","viewer/textures/tag-icons/package_signs/information--recycle-collection-center--g1.png","viewer/textures/tag-icons/package_signs/information--rest-area--g1.png","viewer/textures/tag-icons/package_signs/information--road-bump--g1.png","viewer/textures/tag-icons/package_signs/information--road-skating--g1.png","viewer/textures/tag-icons/package_signs/information--safety-zone--g1.png","viewer/textures/tag-icons/package_signs/information--safety-zone--g2.png","viewer/textures/tag-icons/package_signs/information--safety-zone--g3.png","viewer/textures/tag-icons/package_signs/information--shared-path-vehicles-and-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/information--stairs--g1.png","viewer/textures/tag-icons/package_signs/information--stairs--g2.png","viewer/textures/tag-icons/package_signs/information--stairs--g3.png","viewer/textures/tag-icons/package_signs/information--stairs--g4.png","viewer/textures/tag-icons/package_signs/information--stop-line--g1.png","viewer/textures/tag-icons/package_signs/information--stop-permitted--g1.png","viewer/textures/tag-icons/package_signs/information--street-name-one-line--g1.png","viewer/textures/tag-icons/package_signs/information--street-name-three-lines--g1.png","viewer/textures/tag-icons/package_signs/information--street-name-two-lines--g1.png","viewer/textures/tag-icons/package_signs/information--subway--g1.png","viewer/textures/tag-icons/package_signs/information--telephone--g1.png","viewer/textures/tag-icons/package_signs/information--telephone--g2.png","viewer/textures/tag-icons/package_signs/information--telephone-device-for-the-deaf--g1.png","viewer/textures/tag-icons/package_signs/information--toll-station--g1.png","viewer/textures/tag-icons/package_signs/information--tourism-information--g1.png","viewer/textures/tag-icons/package_signs/information--tourist-attraction--g1.png","viewer/textures/tag-icons/package_signs/information--traffic-merges-left--g1.png","viewer/textures/tag-icons/package_signs/information--traffic-merges-right--g1.png","viewer/textures/tag-icons/package_signs/information--trail-crossing--g1.png","viewer/textures/tag-icons/package_signs/information--trail-crossing--g2.png","viewer/textures/tag-icons/package_signs/information--trail-crossing--g3.png","viewer/textures/tag-icons/package_signs/information--trailer-camping--g1.png","viewer/textures/tag-icons/package_signs/information--train-or-light-rail-station--g1.png","viewer/textures/tag-icons/package_signs/information--tram-bus-stop--g1.png","viewer/textures/tag-icons/package_signs/information--tram-bus-stop--g2.png","viewer/textures/tag-icons/package_signs/information--trams-crossing--g1.png","viewer/textures/tag-icons/package_signs/information--truck-lane-left--g1.png","viewer/textures/tag-icons/package_signs/information--truck-parking--g1.png","viewer/textures/tag-icons/package_signs/information--truck-trailer-lane-right--g1.png","viewer/textures/tag-icons/package_signs/information--truck-trailer-lane-straight--g1.png","viewer/textures/tag-icons/package_signs/information--trucks-both-ways--g1.png","viewer/textures/tag-icons/package_signs/information--trucks-only--g1.png","viewer/textures/tag-icons/package_signs/information--tsunami-evacuation_route--g1.png","viewer/textures/tag-icons/package_signs/information--tunnel--g1.png","viewer/textures/tag-icons/package_signs/information--tunnel--g2.png","viewer/textures/tag-icons/package_signs/information--tunnel--g3.png","viewer/textures/tag-icons/package_signs/information--tunnel-ahead--g1.png","viewer/textures/tag-icons/package_signs/information--turn-left--g1.png","viewer/textures/tag-icons/package_signs/information--turn-left-ahead--g1.png","viewer/textures/tag-icons/package_signs/information--turn-right--g1.png","viewer/textures/tag-icons/package_signs/information--turn-right-ahead--g1.png","viewer/textures/tag-icons/package_signs/information--urban-area--g1.png","viewer/textures/tag-icons/package_signs/information--vehicles-on-rails--g1.png","viewer/textures/tag-icons/package_signs/information--water-protection-zone--g1.png","viewer/textures/tag-icons/package_signs/information--weight-and-height-limit--g1.png","viewer/textures/tag-icons/package_signs/information--weight-limit--g1.png","viewer/textures/tag-icons/package_signs/information--wireless-internet--g1.png","viewer/textures/tag-icons/package_signs/regulatory--advisory-maximum-speed-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--all-directions-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--all-way--g1.png","viewer/textures/tag-icons/package_signs/regulatory--atvs-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--axle-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--axle-limit--g2.png","viewer/textures/tag-icons/package_signs/regulatory--bicycle-lane-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycle-parking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-and-buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-only--g3.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-only--g4.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-push-button--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-push-button--g2.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-stop-on-red--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-wrong-way--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bicycles-yield-or-use-signal--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bike-route--g1.png","viewer/textures/tag-icons/package_signs/regulatory--building-direction--g1.png","viewer/textures/tag-icons/package_signs/regulatory--bus-priority-lane--g1.png","viewer/textures/tag-icons/package_signs/regulatory--buses-and-taxi-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--buses-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--circular-intersection--g1.png","viewer/textures/tag-icons/package_signs/regulatory--circular-intersection--g2.png","viewer/textures/tag-icons/package_signs/regulatory--circular-intersection--g3.png","viewer/textures/tag-icons/package_signs/regulatory--circular-intersection--g4.png","viewer/textures/tag-icons/package_signs/regulatory--cross-only-on-green--g1.png","viewer/textures/tag-icons/package_signs/regulatory--cross-only-on-pedestrian-signal--g1.png","viewer/textures/tag-icons/package_signs/regulatory--crosswalk-stop-on-red--g1.png","viewer/textures/tag-icons/package_signs/regulatory--cycling-restriction--g1.png","viewer/textures/tag-icons/package_signs/regulatory--cyclists-dismount-and-walk--g1.png","viewer/textures/tag-icons/package_signs/regulatory--detour-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--detour-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--divided-highway-crossing--g1.png","viewer/textures/tag-icons/package_signs/regulatory--divided-highway-ends--g1.png","viewer/textures/tag-icons/package_signs/regulatory--divided-highway-starts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--do-not-block-intersection--g1.png","viewer/textures/tag-icons/package_signs/regulatory--do-not-pass--g1.png","viewer/textures/tag-icons/package_signs/regulatory--do-not-stop-on-tracks--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-all-directions-on-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-all-directions-on-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-bicyclists-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-go-left-or-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-go-straight-on-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-go-straight-on-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-turn-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-turn-left-no-u-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-turn-left-or-straight--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-lanes-turn-right-or-straight--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-bicycles-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-bicycles-and-pedestrians--g2.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-bicycles-and-pedestrians--g3.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-equestrians-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-equestrians-and-pedestrians-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-pedestrians-and-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-pedestrians-and-bicycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-pedestrians-and-equestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-path-pedestrians-bicycles-and-equestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-speed-limits--g1.png","viewer/textures/tag-icons/package_signs/regulatory--dual-speed-limits--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-bicycles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-bicycles-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-bus-and-taxi-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-buses-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-cycling-restriction--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-dual-path-bicycles-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-dual-path-pedestrians-and-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-equestrians-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-low-beam-headlights--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-10--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-10--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-20--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-20--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-25--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-25--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-30--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-30--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-35--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-35--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-40--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-40--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-50--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-50--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-60--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-60--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-65--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-65--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-70--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-70--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-75--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-75--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-80--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-80--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-90--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-90--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-100--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-100--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-110--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-110--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-120--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-120--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-130--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit-130--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-maximum-speed-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-mopeds-and-bicycles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-heavy-goods-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-horn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking--g3.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking--g4.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking--g5.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-overtaking-by-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-parking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-parking--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-no-parking-or-stopping--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-one-way-straight--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-parking-zone--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-parking-zone--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-pedestrians-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-pedestrians-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-pedestrians-only--g3.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-pedestrians-only--g4.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-priority-road--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-prohibition--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-school-zone--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-shared-path-bicycles-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-shared-path-pedestrians-and-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-snow-chains--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-snow-chains--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-snowmobiles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-speed-limit-zone--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-speed-limit-zone--g2.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-speed-limit-zone--g3.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-tractors-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-trams-and-buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-trams-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-trucks-and-buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-trucks-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--end-of-trucks-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--equestrians-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--except-railroad-crossing--g1.png","viewer/textures/tag-icons/package_signs/regulatory--fine-for-littering--g1.png","viewer/textures/tag-icons/package_signs/regulatory--give-way-to-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--give-way-to-oncoming-traffic--g1.png","viewer/textures/tag-icons/package_signs/regulatory--give-way-to-oncoming-traffic--g2.png","viewer/textures/tag-icons/package_signs/regulatory--go-left-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--go-right-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight--g1.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight--g3.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-or-turn-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-or-turn-left--g2.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-or-turn-left--g3.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-or-turn-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-or-turn-right--g2.png","viewer/textures/tag-icons/package_signs/regulatory--go-straight-or-turn-right--g3.png","viewer/textures/tag-icons/package_signs/regulatory--heavy-goods-vehicles-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--height-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--high-beam-headlights--g1.png","viewer/textures/tag-icons/package_signs/regulatory--horn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--in-street-pedestrian-crossing--g1.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g2.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g3.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g4.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g5.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g6.png","viewer/textures/tag-icons/package_signs/regulatory--keep-left--g7.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g2.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g3.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g4.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g5.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g6.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g7.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g8.png","viewer/textures/tag-icons/package_signs/regulatory--keep-right--g9.png","viewer/textures/tag-icons/package_signs/regulatory--lane-control--g1.png","viewer/textures/tag-icons/package_signs/regulatory--left-turn-yield-on-green--g1.png","viewer/textures/tag-icons/package_signs/regulatory--length-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--length-limit--g2.png","viewer/textures/tag-icons/package_signs/regulatory--light-rail-divided-highway--g1.png","viewer/textures/tag-icons/package_signs/regulatory--light-rail-do-not-pass--g1.png","viewer/textures/tag-icons/package_signs/regulatory--light-rail-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--look--g1.png","viewer/textures/tag-icons/package_signs/regulatory--low-beam-headlights--g1.png","viewer/textures/tag-icons/package_signs/regulatory--low-beam-headlights--g2.png","viewer/textures/tag-icons/package_signs/regulatory--low-beam-headlights--g3.png","viewer/textures/tag-icons/package_signs/regulatory--low-speed-vehicle-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-5--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-5--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-10--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-10--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-15--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-15--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-20--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-20--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-25--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-25--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-30--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-30--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-35--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-35--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-40--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-40--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-45--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-45--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-50--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-50--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-55--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-60--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-60--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-65--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-65--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-70--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-70--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-75--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-80--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-80--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-85--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-90--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-90--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-100--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-100--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-110--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-110--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-120--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-120--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-130--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-130--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-5--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-5--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-10--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-10--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-10--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-15--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-15--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-20--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-20--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-20--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-25--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-25--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-25--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-30--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-30--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-30--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-35--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-35--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-35--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-40--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-40--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-40--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-45--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-45--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-50--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-50--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-50--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-55--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-55--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-60--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-60--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-60--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-65--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-65--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-70--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-70--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-70--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-75--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-75--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-75--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-80--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-80--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-80--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-85--g2.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-85--g3.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-90--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-100--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-110--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-120--g1.png","viewer/textures/tag-icons/package_signs/regulatory--maximum-speed-limit-led-130--g1.png","viewer/textures/tag-icons/package_signs/regulatory--minimum-safe-distance--g1.png","viewer/textures/tag-icons/package_signs/regulatory--minimum-safe-distance--g2.png","viewer/textures/tag-icons/package_signs/regulatory--mopeds-and-bicycles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--motorcycles-and-bicycles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--motorcycles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--motorcycles-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-5--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-10--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-15--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-20--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-25--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-30--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-35--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-40--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-45--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-50--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-55--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-60--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-65--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-70--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-75--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-80--g1.png","viewer/textures/tag-icons/package_signs/regulatory--night-speed-limit-85--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-abnormal-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-atvs--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles-carts-or-hand-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles-mopeds-or-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles-mopeds-or-motorcycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles-or-hand-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles-or-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-bicycles-tractors-or-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-buses--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-buses--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-buses--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-caravan-trailers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-caravans--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-caravans-or-caravan-trailers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-cargo-loading--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-carts--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-carts--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-carts-or-tractors--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-construction-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-entry--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-equestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-go-straight-or-turn-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-go-straight-or-turn-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-good-trailers--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-goods-vehicle-trailers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-hand-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-hand-carts--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-hand-carts-or-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-hawkers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles-or-buses--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles-or-tractors--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-heavy-goods-vehicles-or-trailers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-horizontal-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-horn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-horn--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-lane-change-to-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-lane-change-to-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-learner-drivers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-left-or-u-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-left-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-left-turn--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-left-turn--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-left-turn--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-left-turn--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-low-speed-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-mopeds-or-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicle-trailers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles--g6.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles--g7.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles-except-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles-except-motorcycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles-except-motorcycles--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles-or-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles-or-buses--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motor-vehicles-or-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-motorcycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking--g6.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking--g7.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking-atvs--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-overtaking-by-heavy-goods-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g6.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g7.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g8.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking--g9.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-bicycles-or-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-bus-stop--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-or-no-stopping--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-or-no-stopping--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-or-no-stopping--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-or-no-stopping--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-parking-or-no-stopping--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-passenger-loading--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians--g6.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians-bicycles-animals-or-hand-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians-or-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians-or-bicycles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-pedestrians-or-bicycles--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-rickshaws--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-rickshaws--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-rickshaws--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-right-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-right-turn--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-right-turn--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-right-turn-on-red--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-skiing--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-snowmobiles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-snowmobiles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-snowmobiles-or-atvs--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping--g5.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping--g6.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping--g7.png","viewer/textures/tag-icons/package_signs/regulatory--no-stopping-on-pavement--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-straight-through--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-straight-through--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-studded-snow-chains--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-through-trucks--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-tour-buses--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-tractors--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-tractors-mopeds-or-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-tractors-or-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-trailers--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-tricycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-tricycles-or-hand-carts--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-turn-on-red--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-turn-on-red--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-turn-on-red--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-turns--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-turns--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-two-stage-right-turn-for-mopeds--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-u-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-u-turn--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-u-turn--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-dangerous-goods--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-dangerous-goods--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-dangerous-goods--g3.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-dangerous-goods--g4.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-dangerous-water-pollutants--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-dangerous-water-pollutants--g2.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-explosives--g1.png","viewer/textures/tag-icons/package_signs/regulatory--no-vehicles-carrying-explosives-or-dangerous-water-pollutants--g1.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-left--g2.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-left--g3.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-right--g2.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-right--g3.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-straight--g1.png","viewer/textures/tag-icons/package_signs/regulatory--one-way-straight--g3.png","viewer/textures/tag-icons/package_signs/regulatory--parking-fee-station--g1.png","viewer/textures/tag-icons/package_signs/regulatory--parking-restrictions--g1.png","viewer/textures/tag-icons/package_signs/regulatory--parking-restrictions--g2.png","viewer/textures/tag-icons/package_signs/regulatory--parking-restrictions--g3.png","viewer/textures/tag-icons/package_signs/regulatory--pass-on-either-side--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pass-on-either-side--g2.png","viewer/textures/tag-icons/package_signs/regulatory--pass-on-either-side--g3.png","viewer/textures/tag-icons/package_signs/regulatory--pass-with-care--g1.png","viewer/textures/tag-icons/package_signs/regulatory--passing-lane-ahead--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-bicycles-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-keep-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-only--g2.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-only--g3.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-priority-zone--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-push-button--g1.png","viewer/textures/tag-icons/package_signs/regulatory--pedestrians-push-button--g2.png","viewer/textures/tag-icons/package_signs/regulatory--priority-over-oncoming-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--priority-over-oncoming-vehicles--g2.png","viewer/textures/tag-icons/package_signs/regulatory--priority-road--g1.png","viewer/textures/tag-icons/package_signs/regulatory--priority-road--g2.png","viewer/textures/tag-icons/package_signs/regulatory--radar-enforced--g1.png","viewer/textures/tag-icons/package_signs/regulatory--reserved-parking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--reversible-lanes--g1.png","viewer/textures/tag-icons/package_signs/regulatory--reversible-lanes--g2.png","viewer/textures/tag-icons/package_signs/regulatory--road-closed--g1.png","viewer/textures/tag-icons/package_signs/regulatory--road-closed--g2.png","viewer/textures/tag-icons/package_signs/regulatory--road-closed-to-vehicles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--road-closed-to-vehicles--g3.png","viewer/textures/tag-icons/package_signs/regulatory--roundabout--g1.png","viewer/textures/tag-icons/package_signs/regulatory--roundabout--g2.png","viewer/textures/tag-icons/package_signs/regulatory--roundabout--g3.png","viewer/textures/tag-icons/package_signs/regulatory--shared-path-bicycles-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--shared-path-pedestrians-and-bicycles--g1.png","viewer/textures/tag-icons/package_signs/regulatory--sidewalk-closed--g1.png","viewer/textures/tag-icons/package_signs/regulatory--slanted-parking--g1.png","viewer/textures/tag-icons/package_signs/regulatory--snow-chains--g1.png","viewer/textures/tag-icons/package_signs/regulatory--snow-chains--g2.png","viewer/textures/tag-icons/package_signs/regulatory--snow-chains--g3.png","viewer/textures/tag-icons/package_signs/regulatory--snowmobiles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--snowmobiles-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--speed-limit-zone--g1.png","viewer/textures/tag-icons/package_signs/regulatory--speeding-fines-increased--g1.png","viewer/textures/tag-icons/package_signs/regulatory--state-route--g1.png","viewer/textures/tag-icons/package_signs/regulatory--stay-in-lane--g1.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g1.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g2.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g3.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g4.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g5.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g6.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g7.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g8.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g9.png","viewer/textures/tag-icons/package_signs/regulatory--stop--g10.png","viewer/textures/tag-icons/package_signs/regulatory--stop-here-on-red-or-flashing-light--g1.png","viewer/textures/tag-icons/package_signs/regulatory--stop-here-on-red-or-flashing-light--g2.png","viewer/textures/tag-icons/package_signs/regulatory--stop-signals--g1.png","viewer/textures/tag-icons/package_signs/regulatory--stop-signals--g2.png","viewer/textures/tag-icons/package_signs/regulatory--tanks-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--taxi-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--text--g1.png","viewer/textures/tag-icons/package_signs/regulatory--text--g2.png","viewer/textures/tag-icons/package_signs/regulatory--toll-pass-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--tractors-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--traffic-signal-photo-enforced--g1.png","viewer/textures/tag-icons/package_signs/regulatory--trams-and-buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--trams-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--triple-lanes--g1.png","viewer/textures/tag-icons/package_signs/regulatory--triple-lanes-go-straight-center-lane--g1.png","viewer/textures/tag-icons/package_signs/regulatory--triple-lanes-turn-left-center-lane--g1.png","viewer/textures/tag-icons/package_signs/regulatory--triple-lanes-turn-right-center-lane--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-route--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-5--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-10--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-15--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-20--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-25--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-30--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-35--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-40--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-45--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-50--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-55--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-60--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-65--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-70--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-75--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-80--g1.png","viewer/textures/tag-icons/package_signs/regulatory--truck-speed-limit-85--g1.png","viewer/textures/tag-icons/package_signs/regulatory--trucks-and-buses-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--trucks-on-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--trucks-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left--g2.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left--g3.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left-ahead--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left-ahead--g2.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left-or-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left-or-right--g2.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left-or-right--g3.png","viewer/textures/tag-icons/package_signs/regulatory--turn-left-or-u-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-right--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-right--g2.png","viewer/textures/tag-icons/package_signs/regulatory--turn-right--g3.png","viewer/textures/tag-icons/package_signs/regulatory--turn-right-ahead--g1.png","viewer/textures/tag-icons/package_signs/regulatory--turn-right-ahead--g2.png","viewer/textures/tag-icons/package_signs/regulatory--turning-vehicles-yield-to-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--two-stage-right-turn-for-mopeds--g1.png","viewer/textures/tag-icons/package_signs/regulatory--two-way--g1.png","viewer/textures/tag-icons/package_signs/regulatory--u-turn--g1.png","viewer/textures/tag-icons/package_signs/regulatory--u-turn--g2.png","viewer/textures/tag-icons/package_signs/regulatory--u-turn--g3.png","viewer/textures/tag-icons/package_signs/regulatory--use-crosswalk--g1.png","viewer/textures/tag-icons/package_signs/regulatory--vehicles-carrying-dangerous-goods-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--vehicles-carrying-dangerous-goods-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--vehicles-carrying-explosives-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--vehicles-carrying-hazardous-goods-permitted--g1.png","viewer/textures/tag-icons/package_signs/regulatory--vehicles-only--g1.png","viewer/textures/tag-icons/package_signs/regulatory--wear-seat-belt--g1.png","viewer/textures/tag-icons/package_signs/regulatory--wear-seat-belt--g2.png","viewer/textures/tag-icons/package_signs/regulatory--wear-seat-belt--g3.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g2.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g3.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g4.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g5.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g6.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit--g7.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit-per-axle--g1.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit-per-tandem-axle--g1.png","viewer/textures/tag-icons/package_signs/regulatory--weight-limit-with-trucks--g1.png","viewer/textures/tag-icons/package_signs/regulatory--width-limit--g1.png","viewer/textures/tag-icons/package_signs/regulatory--wrong-way--g1.png","viewer/textures/tag-icons/package_signs/regulatory--yield--g1.png","viewer/textures/tag-icons/package_signs/regulatory--yield-or-stop-for-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/regulatory--your-speed--g1.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g1.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g2.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g3.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g4.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g5.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g6.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g7.png","viewer/textures/tag-icons/package_signs/warning--accident-area--g8.png","viewer/textures/tag-icons/package_signs/warning--added-lane-from-entering-roadway--g1.png","viewer/textures/tag-icons/package_signs/warning--added-lane-from-entering-roadway--g2.png","viewer/textures/tag-icons/package_signs/warning--added-lane-left--g1.png","viewer/textures/tag-icons/package_signs/warning--added-lane-right--g1.png","viewer/textures/tag-icons/package_signs/warning--animal-drawn-vehicles--g1.png","viewer/textures/tag-icons/package_signs/warning--arch-bridge--g1.png","viewer/textures/tag-icons/package_signs/warning--atv-and-snowmobiles--g1.png","viewer/textures/tag-icons/package_signs/warning--atv-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--atv-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--axle-restriction--g1.png","viewer/textures/tag-icons/package_signs/warning--bear-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--bear-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--bicycles-and-others--g1.png","viewer/textures/tag-icons/package_signs/warning--bicycles-caution-on-rail-tracks--g1.png","viewer/textures/tag-icons/package_signs/warning--bicycles-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--bicycles-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--bicycles-crossing--g3.png","viewer/textures/tag-icons/package_signs/warning--bicycles-crossing--g4.png","viewer/textures/tag-icons/package_signs/warning--bollard--g1.png","viewer/textures/tag-icons/package_signs/warning--bridge--g1.png","viewer/textures/tag-icons/package_signs/warning--bridge--g2.png","viewer/textures/tag-icons/package_signs/warning--bus-stop-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--bus-stop-ahead--g2.png","viewer/textures/tag-icons/package_signs/warning--bus-stop-ahead--g3.png","viewer/textures/tag-icons/package_signs/warning--camel-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--camel-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--camera--g1.png","viewer/textures/tag-icons/package_signs/warning--camera--g2.png","viewer/textures/tag-icons/package_signs/warning--carts--g1.png","viewer/textures/tag-icons/package_signs/warning--carts--g2.png","viewer/textures/tag-icons/package_signs/warning--checkpoint--g1.png","viewer/textures/tag-icons/package_signs/warning--children--g1.png","viewer/textures/tag-icons/package_signs/warning--children--g2.png","viewer/textures/tag-icons/package_signs/warning--children--g3.png","viewer/textures/tag-icons/package_signs/warning--children--g4.png","viewer/textures/tag-icons/package_signs/warning--children--g6.png","viewer/textures/tag-icons/package_signs/warning--cliff--g1.png","viewer/textures/tag-icons/package_signs/warning--cliff--g2.png","viewer/textures/tag-icons/package_signs/warning--closed-lane-in-triple-lanes--g1.png","viewer/textures/tag-icons/package_signs/warning--closed-lane-in-triple-lanes--g2.png","viewer/textures/tag-icons/package_signs/warning--construction-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--crossroads--g1.png","viewer/textures/tag-icons/package_signs/warning--crossroads--g2.png","viewer/textures/tag-icons/package_signs/warning--crossroads--g3.png","viewer/textures/tag-icons/package_signs/warning--crossroads--g4.png","viewer/textures/tag-icons/package_signs/warning--crossroads--g5.png","viewer/textures/tag-icons/package_signs/warning--crossroads--g6.png","viewer/textures/tag-icons/package_signs/warning--crossroads-with-priority-to-the-right--g1.png","viewer/textures/tag-icons/package_signs/warning--curve-left--g1.png","viewer/textures/tag-icons/package_signs/warning--curve-left--g2.png","viewer/textures/tag-icons/package_signs/warning--curve-left--g3.png","viewer/textures/tag-icons/package_signs/warning--curve-left-with-junction--g1.png","viewer/textures/tag-icons/package_signs/warning--curve-out-intersection-left--g1.png","viewer/textures/tag-icons/package_signs/warning--curve-out-intersection-right--g1.png","viewer/textures/tag-icons/package_signs/warning--curve-right--g1.png","viewer/textures/tag-icons/package_signs/warning--curve-right--g2.png","viewer/textures/tag-icons/package_signs/warning--curve-right--g3.png","viewer/textures/tag-icons/package_signs/warning--curve-right-with-junction--g1.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-left--g1.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-left--g2.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-left--g4.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-right--g1.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-right--g2.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-right--g3.png","viewer/textures/tag-icons/package_signs/warning--dangerous-crosswinds-right--g4.png","viewer/textures/tag-icons/package_signs/warning--dead-end--g1.png","viewer/textures/tag-icons/package_signs/warning--dead-end--g2.png","viewer/textures/tag-icons/package_signs/warning--dead-end--g3.png","viewer/textures/tag-icons/package_signs/warning--dead-end-go-left--g1.png","viewer/textures/tag-icons/package_signs/warning--dead-end-go-right--g1.png","viewer/textures/tag-icons/package_signs/warning--descent-or-climbing-lanes-in-triple-lanes--g1.png","viewer/textures/tag-icons/package_signs/warning--detour-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--detour-or-construction-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--dip--g1.png","viewer/textures/tag-icons/package_signs/warning--dip--g2.png","viewer/textures/tag-icons/package_signs/warning--disabled-persons-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--disabled-persons-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g1.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g2.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g3.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g4.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g5.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g6.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g7.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g8.png","viewer/textures/tag-icons/package_signs/warning--divided-highway--g9.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-ends--g1.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-ends--g2.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-ends--g3.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-ends--g4.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-on-left--g1.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-on-left--g2.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-on-right--g1.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-on-right--g2.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-to-left--g1.png","viewer/textures/tag-icons/package_signs/warning--divided-highway-to-right--g1.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g1.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g2.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g3.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g4.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g5.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g6.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g7.png","viewer/textures/tag-icons/package_signs/warning--domestic-animals--g8.png","viewer/textures/tag-icons/package_signs/warning--double-curve-first-left--g1.png","viewer/textures/tag-icons/package_signs/warning--double-curve-first-left--g2.png","viewer/textures/tag-icons/package_signs/warning--double-curve-first-right--g1.png","viewer/textures/tag-icons/package_signs/warning--double-curve-first-right--g2.png","viewer/textures/tag-icons/package_signs/warning--double-descent--g1.png","viewer/textures/tag-icons/package_signs/warning--double-reverse-curve-left--g1.png","viewer/textures/tag-icons/package_signs/warning--double-reverse-curve-left--g2.png","viewer/textures/tag-icons/package_signs/warning--double-reverse-curve-right--g1.png","viewer/textures/tag-icons/package_signs/warning--double-reverse-curve-right--g2.png","viewer/textures/tag-icons/package_signs/warning--double-side-roads-left--g1.png","viewer/textures/tag-icons/package_signs/warning--double-side-roads-left--g3.png","viewer/textures/tag-icons/package_signs/warning--double-side-roads-right--g1.png","viewer/textures/tag-icons/package_signs/warning--double-side-roads-right--g3.png","viewer/textures/tag-icons/package_signs/warning--double-turn-first-left--g1.png","viewer/textures/tag-icons/package_signs/warning--double-turn-first-right--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-all-directions-on-left--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-all-directions-on-right--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-go-straight-or-turn-left--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-go-straight-or-turn-right--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-left-turn--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-left-turn-or-go-straight--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-right-turn--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-right-turn-or-go-straight--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-turn-left--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-turn-left-or-right--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-turn-left-or-right--g2.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-turn-left-or-right--g3.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-turn-left-or-right--g4.png","viewer/textures/tag-icons/package_signs/warning--dual-lanes-turn-right--g1.png","viewer/textures/tag-icons/package_signs/warning--dual-path-cyclists-and-pedestrians--g1.png","viewer/textures/tag-icons/package_signs/warning--electricity--g1.png","viewer/textures/tag-icons/package_signs/warning--electricity--g2.png","viewer/textures/tag-icons/package_signs/warning--elephant-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--emergency-vehicles--g1.png","viewer/textures/tag-icons/package_signs/warning--emu-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--emu-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--entering-roadway-merge--g1.png","viewer/textures/tag-icons/package_signs/warning--entering-roadway-merge--g2.png","viewer/textures/tag-icons/package_signs/warning--equestrians-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--equestrians-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--expressway--g1.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-left--g1.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-left--g2.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-left--g3.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-left--g4.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-right--g1.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-right--g2.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-right--g3.png","viewer/textures/tag-icons/package_signs/warning--falling-rocks-or-debris-right--g4.png","viewer/textures/tag-icons/package_signs/warning--ferry--g1.png","viewer/textures/tag-icons/package_signs/warning--flaggers-in-road--g1.png","viewer/textures/tag-icons/package_signs/warning--flaggers-in-road--g2.png","viewer/textures/tag-icons/package_signs/warning--foggy-road--g1.png","viewer/textures/tag-icons/package_signs/warning--foggy-road--g2.png","viewer/textures/tag-icons/package_signs/warning--ford--g1.png","viewer/textures/tag-icons/package_signs/warning--forest--g1.png","viewer/textures/tag-icons/package_signs/warning--fresh-oil--g1.png","viewer/textures/tag-icons/package_signs/warning--frog-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--gate--g1.png","viewer/textures/tag-icons/package_signs/warning--gate--g2.png","viewer/textures/tag-icons/package_signs/warning--gate-left--g1.png","viewer/textures/tag-icons/package_signs/warning--gate-right--g1.png","viewer/textures/tag-icons/package_signs/warning--go-left--g1.png","viewer/textures/tag-icons/package_signs/warning--go-right--g1.png","viewer/textures/tag-icons/package_signs/warning--golf-carts-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--gravel-road-surface--g1.png","viewer/textures/tag-icons/package_signs/warning--hairpin-curve-left--g1.png","viewer/textures/tag-icons/package_signs/warning--hairpin-curve-left--g2.png","viewer/textures/tag-icons/package_signs/warning--hairpin-curve-left--g3.png","viewer/textures/tag-icons/package_signs/warning--hairpin-curve-right--g1.png","viewer/textures/tag-icons/package_signs/warning--hairpin-curve-right--g3.png","viewer/textures/tag-icons/package_signs/warning--height-restriction--g2.png","viewer/textures/tag-icons/package_signs/warning--height-restriction--g3.png","viewer/textures/tag-icons/package_signs/warning--height-restriction--g4.png","viewer/textures/tag-icons/package_signs/warning--height-restriction--g5.png","viewer/textures/tag-icons/package_signs/warning--horizontal-alignment-left--g1.png","viewer/textures/tag-icons/package_signs/warning--horizontal-alignment-left--g3.png","viewer/textures/tag-icons/package_signs/warning--horizontal-alignment-right--g1.png","viewer/textures/tag-icons/package_signs/warning--horizontal-alignment-right--g3.png","viewer/textures/tag-icons/package_signs/warning--horse-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--icy-road--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-acute-left--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-acute-left--g2.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-acute-right--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-acute-right--g2.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-left--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-left--g2.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-left--g3.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-left--g4.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-right--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-right--g2.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-right--g3.png","viewer/textures/tag-icons/package_signs/warning--junction-with-a-side-road-perpendicular-right--g4.png","viewer/textures/tag-icons/package_signs/warning--junction-with-merge-from-left--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-merge-from-right--g1.png","viewer/textures/tag-icons/package_signs/warning--junction-with-side-roads--g1.png","viewer/textures/tag-icons/package_signs/warning--kangaloo-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--keep-distance--g1.png","viewer/textures/tag-icons/package_signs/warning--keep-left--g1.png","viewer/textures/tag-icons/package_signs/warning--keep-right--g1.png","viewer/textures/tag-icons/package_signs/warning--kiwi-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--kiwi-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--koala-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--koala-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--koala-crossing--g3.png","viewer/textures/tag-icons/package_signs/warning--koala-crossing--g4.png","viewer/textures/tag-icons/package_signs/warning--lane-closed-in-dual-lanes-left--g1.png","viewer/textures/tag-icons/package_signs/warning--lane-closed-in-dual-lanes-left--g2.png","viewer/textures/tag-icons/package_signs/warning--lane-closed-in-dual-lanes-right--g1.png","viewer/textures/tag-icons/package_signs/warning--lane-closed-in-dual-lanes-right--g2.png","viewer/textures/tag-icons/package_signs/warning--length-restriction--g1.png","viewer/textures/tag-icons/package_signs/warning--length-restriction--g2.png","viewer/textures/tag-icons/package_signs/warning--light-rail-transit-vehicles--g1.png","viewer/textures/tag-icons/package_signs/warning--limited-lighting-under-trees--g1.png","viewer/textures/tag-icons/package_signs/warning--logging-vehicles--g1.png","viewer/textures/tag-icons/package_signs/warning--loop-270-degree--g1.png","viewer/textures/tag-icons/package_signs/warning--loop-pretzel--g1.png","viewer/textures/tag-icons/package_signs/warning--loose-road-surface--g1.png","viewer/textures/tag-icons/package_signs/warning--loose-road-surface--g2.png","viewer/textures/tag-icons/package_signs/warning--loose-road-surface--g3.png","viewer/textures/tag-icons/package_signs/warning--loose-road-surface--g4.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g1.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g2.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g3.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g4.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g5.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g6.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g7.png","viewer/textures/tag-icons/package_signs/warning--low-flying-aircraft--g8.png","viewer/textures/tag-icons/package_signs/warning--low-ground-clearance--g1.png","viewer/textures/tag-icons/package_signs/warning--low-ground-clearance--g2.png","viewer/textures/tag-icons/package_signs/warning--low-ground-clearance--g3.png","viewer/textures/tag-icons/package_signs/warning--monkey-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--motorcycles-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--narrow-bridge--g1.png","viewer/textures/tag-icons/package_signs/warning--narrow-bridge--g2.png","viewer/textures/tag-icons/package_signs/warning--narrow-bridge--g3.png","viewer/textures/tag-icons/package_signs/warning--no-passing-zone--g1.png","viewer/textures/tag-icons/package_signs/warning--no-passing-zone--g2.png","viewer/textures/tag-icons/package_signs/warning--occupied-lanes--g1.png","viewer/textures/tag-icons/package_signs/warning--offset-roads--g1.png","viewer/textures/tag-icons/package_signs/warning--offset-roads--g2.png","viewer/textures/tag-icons/package_signs/warning--offset-roads--g3.png","viewer/textures/tag-icons/package_signs/warning--offset-roads--g4.png","viewer/textures/tag-icons/package_signs/warning--opening-or-swing-bridge--g1.png","viewer/textures/tag-icons/package_signs/warning--opening-or-swing-bridge--g2.png","viewer/textures/tag-icons/package_signs/warning--other-danger--g1.png","viewer/textures/tag-icons/package_signs/warning--other-danger--g2.png","viewer/textures/tag-icons/package_signs/warning--other-danger--g3.png","viewer/textures/tag-icons/package_signs/warning--panda-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--pass-left-or-right--g1.png","viewer/textures/tag-icons/package_signs/warning--pass-left-or-right--g2.png","viewer/textures/tag-icons/package_signs/warning--pass-left-or-right--g3.png","viewer/textures/tag-icons/package_signs/warning--pavement-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--pavement-ends--g1.png","viewer/textures/tag-icons/package_signs/warning--pavement-ends--g2.png","viewer/textures/tag-icons/package_signs/warning--pavement-ends--g3.png","viewer/textures/tag-icons/package_signs/warning--pavement-ends--g4.png","viewer/textures/tag-icons/package_signs/warning--pavement-ends--g5.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g4.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g5.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g6.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g7.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g8.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g9.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g10.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g11.png","viewer/textures/tag-icons/package_signs/warning--pedestrians-crossing--g12.png","viewer/textures/tag-icons/package_signs/warning--playground--g1.png","viewer/textures/tag-icons/package_signs/warning--playground--g3.png","viewer/textures/tag-icons/package_signs/warning--polar-bear-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--quay-or-river-bank--g1.png","viewer/textures/tag-icons/package_signs/warning--quay-or-river-bank--g2.png","viewer/textures/tag-icons/package_signs/warning--quay-or-river-bank--g3.png","viewer/textures/tag-icons/package_signs/warning--quay-or-river-bank--g4.png","viewer/textures/tag-icons/package_signs/warning--rabbit-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--raccoon-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing--g3.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing--g4.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g1.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g2.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g3.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g4.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g5.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g6.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-with-barriers--g7.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-without-barriers--g1.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-without-barriers--g2.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-without-barriers--g3.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-without-barriers--g4.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-without-barriers--g5.png","viewer/textures/tag-icons/package_signs/warning--railroad-crossing-without-barriers--g6.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g1.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g2.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g3.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g4.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g5.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g6.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g7.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g8.png","viewer/textures/tag-icons/package_signs/warning--railroad-intersection--g9.png","viewer/textures/tag-icons/package_signs/warning--ramp-closed--g1.png","viewer/textures/tag-icons/package_signs/warning--reduced-maximum-speed-limit--g1.png","viewer/textures/tag-icons/package_signs/warning--reserved-lane--g1.png","viewer/textures/tag-icons/package_signs/warning--restricted-zone--g1.png","viewer/textures/tag-icons/package_signs/warning--reversible-lanes--g1.png","viewer/textures/tag-icons/package_signs/warning--reversible-lanes--g2.png","viewer/textures/tag-icons/package_signs/warning--rickshaws-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--road-blocks--g1.png","viewer/textures/tag-icons/package_signs/warning--road-bump--g1.png","viewer/textures/tag-icons/package_signs/warning--road-bump--g2.png","viewer/textures/tag-icons/package_signs/warning--road-bump--g3.png","viewer/textures/tag-icons/package_signs/warning--road-bump-with-speed-limit--g1.png","viewer/textures/tag-icons/package_signs/warning--road-closed--g3.png","viewer/textures/tag-icons/package_signs/warning--road-narrows--g1.png","viewer/textures/tag-icons/package_signs/warning--road-narrows--g2.png","viewer/textures/tag-icons/package_signs/warning--road-narrows-left--g1.png","viewer/textures/tag-icons/package_signs/warning--road-narrows-left--g2.png","viewer/textures/tag-icons/package_signs/warning--road-narrows-left-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--road-narrows-right--g1.png","viewer/textures/tag-icons/package_signs/warning--road-narrows-right--g2.png","viewer/textures/tag-icons/package_signs/warning--road-narrows-right-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--road-toll-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--road-widens--g1.png","viewer/textures/tag-icons/package_signs/warning--road-widens-left--g1.png","viewer/textures/tag-icons/package_signs/warning--road-widens-right--g1.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g1.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g2.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g3.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g5.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g6.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g8.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g9.png","viewer/textures/tag-icons/package_signs/index.ts","viewer/textures/tag-icons/package_signs/warning--roadworks--g10.png","viewer/textures/tag-icons/package_signs/warning--roadworks--g11.png","viewer/textures/tag-icons/package_signs/warning--roadworks-go-left-or-straight--g1.png","viewer/textures/tag-icons/package_signs/warning--roadworks-go-right-or-straight--g1.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g1.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g2.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g3.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g4.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g5.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g6.png","viewer/textures/tag-icons/package_signs/warning--roundabout--g7.png","viewer/textures/tag-icons/package_signs/warning--ruts--g1.png","viewer/textures/tag-icons/package_signs/warning--sand--g1.png","viewer/textures/tag-icons/package_signs/warning--sand-drift--g1.png","viewer/textures/tag-icons/package_signs/warning--school-zone--g2.png","viewer/textures/tag-icons/package_signs/warning--severe-weather--g1.png","viewer/textures/tag-icons/package_signs/warning--shared-lane-motorcycles-bicycles--g1.png","viewer/textures/tag-icons/package_signs/warning--sharp-turn--g1.png","viewer/textures/tag-icons/package_signs/warning--single-reverse-curve--g1.png","viewer/textures/tag-icons/package_signs/warning--skewed-t-roads-left--g1.png","viewer/textures/tag-icons/package_signs/warning--skewed-t-roads-left--g2.png","viewer/textures/tag-icons/package_signs/warning--skewed-t-roads-left--g3.png","viewer/textures/tag-icons/package_signs/warning--skewed-t-roads-right--g1.png","viewer/textures/tag-icons/package_signs/warning--skewed-t-roads-right--g2.png","viewer/textures/tag-icons/package_signs/warning--skewed-t-roads-right--g3.png","viewer/textures/tag-icons/package_signs/warning--skiers--g1.png","viewer/textures/tag-icons/package_signs/warning--skiers--g2.png","viewer/textures/tag-icons/package_signs/warning--skiers--g3.png","viewer/textures/tag-icons/package_signs/warning--slippery-bicycles--g1.png","viewer/textures/tag-icons/package_signs/warning--slippery-motorcycles--g1.png","viewer/textures/tag-icons/package_signs/warning--slippery-motorcycles--g2.png","viewer/textures/tag-icons/package_signs/warning--slippery-road-surface--g1.png","viewer/textures/tag-icons/package_signs/warning--slippery-road-surface--g2.png","viewer/textures/tag-icons/package_signs/warning--slow--g1.png","viewer/textures/tag-icons/package_signs/warning--snow-tractors--g1.png","viewer/textures/tag-icons/package_signs/warning--snowmobiles--g1.png","viewer/textures/tag-icons/package_signs/warning--snowmobiles--g2.png","viewer/textures/tag-icons/package_signs/warning--snowmobiles--g3.png","viewer/textures/tag-icons/package_signs/warning--snowmobiles-and-others--g1.png","viewer/textures/tag-icons/package_signs/warning--soft-road-surface--g1.png","viewer/textures/tag-icons/package_signs/warning--soft-road-surface--g2.png","viewer/textures/tag-icons/package_signs/warning--soft-shoulder--g1.png","viewer/textures/tag-icons/package_signs/warning--soft-shoulder--g2.png","viewer/textures/tag-icons/package_signs/warning--soft-shoulder--g3.png","viewer/textures/tag-icons/package_signs/warning--soft-shoulder--g4.png","viewer/textures/tag-icons/package_signs/warning--speed-camera--g1.png","viewer/textures/tag-icons/package_signs/warning--steep-ascent--g1.png","viewer/textures/tag-icons/package_signs/warning--steep-ascent--g2.png","viewer/textures/tag-icons/package_signs/warning--steep-ascent--g3.png","viewer/textures/tag-icons/package_signs/warning--steep-ascent--g4.png","viewer/textures/tag-icons/package_signs/warning--steep-ascent-and-descent--g1.png","viewer/textures/tag-icons/package_signs/warning--steep-descent--g1.png","viewer/textures/tag-icons/package_signs/warning--steep-descent--g2.png","viewer/textures/tag-icons/package_signs/warning--steep-descent--g3.png","viewer/textures/tag-icons/package_signs/warning--steep-descent--g4.png","viewer/textures/tag-icons/package_signs/warning--steep-descent--g5.png","viewer/textures/tag-icons/package_signs/warning--steep-descent--g6.png","viewer/textures/tag-icons/package_signs/warning--stop-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--stop-ahead--g3.png","viewer/textures/tag-icons/package_signs/warning--stop-ahead--g4.png","viewer/textures/tag-icons/package_signs/warning--stop-ahead--g5.png","viewer/textures/tag-icons/package_signs/warning--stop-ahead--g6.png","viewer/textures/tag-icons/package_signs/warning--t-roads--g1.png","viewer/textures/tag-icons/package_signs/warning--t-roads--g2.png","viewer/textures/tag-icons/package_signs/warning--tanks-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--tanks-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--texts--g1.png","viewer/textures/tag-icons/package_signs/warning--texts--g2.png","viewer/textures/tag-icons/package_signs/warning--texts--g3.png","viewer/textures/tag-icons/package_signs/warning--towing--g1.png","viewer/textures/tag-icons/package_signs/warning--tractors--g1.png","viewer/textures/tag-icons/package_signs/warning--tractors--g2.png","viewer/textures/tag-icons/package_signs/warning--tractors--g3.png","viewer/textures/tag-icons/package_signs/warning--tractors--g4.png","viewer/textures/tag-icons/package_signs/warning--tractors--g5.png","viewer/textures/tag-icons/package_signs/warning--tractors--g6.png","viewer/textures/tag-icons/package_signs/warning--tractors--g7.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-at-signalized-intersections--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-left--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-left--g2.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-left--g3.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-left--g4.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-left-and-right--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-left-buses--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-right--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-right--g2.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-right--g3.png","viewer/textures/tag-icons/package_signs/warning--traffic-merges-right-buses--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-queues-likely--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-queues-likely--g2.png","viewer/textures/tag-icons/package_signs/warning--traffic-queues-likely--g3.png","viewer/textures/tag-icons/package_signs/warning--traffic-queues-likely--g4.png","viewer/textures/tag-icons/package_signs/warning--traffic-queues-likely--g5.png","viewer/textures/tag-icons/package_signs/warning--traffic-signals--g1.png","viewer/textures/tag-icons/package_signs/warning--traffic-signals--g2.png","viewer/textures/tag-icons/package_signs/warning--traffic-signals--g3.png","viewer/textures/tag-icons/package_signs/warning--traffic-signals--g4.png","viewer/textures/tag-icons/package_signs/warning--traffic-signals--g5.png","viewer/textures/tag-icons/package_signs/warning--traffic-signals--g6.png","viewer/textures/tag-icons/package_signs/warning--traffic-slow--g1.png","viewer/textures/tag-icons/package_signs/warning--trail-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--trail-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--trail-crossing--g3.png","viewer/textures/tag-icons/package_signs/warning--trail-crossing--g4.png","viewer/textures/tag-icons/package_signs/warning--trail-crossing--g5.png","viewer/textures/tag-icons/package_signs/warning--trail-crossing--g6.png","viewer/textures/tag-icons/package_signs/warning--trams-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--trams-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--triple-curve-left--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-curve-right--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-lanes-left-turn--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-lanes-left-turn-or-go-straight--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-lanes-right-turn--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-lanes-right-turn-or-go-straight--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-lanes-with-directions--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-reverse-curve-left--g1.png","viewer/textures/tag-icons/package_signs/warning--triple-reverse-curve-right--g1.png","viewer/textures/tag-icons/package_signs/warning--trucks-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--trucks-crossing--g2.png","viewer/textures/tag-icons/package_signs/warning--trucks-rollover--g1.png","viewer/textures/tag-icons/package_signs/warning--trucks-rollover--g2.png","viewer/textures/tag-icons/package_signs/warning--trucks-rollover--g3.png","viewer/textures/tag-icons/package_signs/warning--trucks-rollover--g4.png","viewer/textures/tag-icons/package_signs/warning--trucks-rollover--g5.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g1.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g2.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g3.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g4.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g5.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g6.png","viewer/textures/tag-icons/package_signs/warning--tunnel--g7.png","viewer/textures/tag-icons/package_signs/warning--turn-left--g1.png","viewer/textures/tag-icons/package_signs/warning--turn-left--g2.png","viewer/textures/tag-icons/package_signs/warning--turn-left--g3.png","viewer/textures/tag-icons/package_signs/warning--turn-left-or-right--g1.png","viewer/textures/tag-icons/package_signs/warning--turn-right--g1.png","viewer/textures/tag-icons/package_signs/warning--turn-right--g2.png","viewer/textures/tag-icons/package_signs/warning--turn-right--g3.png","viewer/textures/tag-icons/package_signs/warning--two-way-traffic--g1.png","viewer/textures/tag-icons/package_signs/warning--two-way-traffic--g2.png","viewer/textures/tag-icons/package_signs/warning--two-way-traffic--g3.png","viewer/textures/tag-icons/package_signs/warning--two-way-traffic--g4.png","viewer/textures/tag-icons/package_signs/warning--two-way-traffic--g5.png","viewer/textures/tag-icons/package_signs/warning--two-way-traffic--g6.png","viewer/textures/tag-icons/package_signs/warning--u-turn--g1.png","viewer/textures/tag-icons/package_signs/warning--u-turn--g2.png","viewer/textures/tag-icons/package_signs/warning--uneven-road--g1.png","viewer/textures/tag-icons/package_signs/warning--uneven-road--g2.png","viewer/textures/tag-icons/package_signs/warning--uneven-roads-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--vehicles-and-others--g1.png","viewer/textures/tag-icons/package_signs/warning--vehicles-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--village--g1.png","viewer/textures/tag-icons/package_signs/warning--weight-limit--g5.png","viewer/textures/tag-icons/package_signs/warning--weight-limit-per-tandem-axle--g1.png","viewer/textures/tag-icons/package_signs/warning--width-restriction--g1.png","viewer/textures/tag-icons/package_signs/warning--width-restriction--g2.png","viewer/textures/tag-icons/package_signs/warning--width-restriction--g3.png","viewer/textures/tag-icons/package_signs/warning--width-restriction--g4.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g1.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g2.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g3.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g4.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g5.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g6.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g7.png","viewer/textures/tag-icons/package_signs/warning--wild-animals--g8.png","viewer/textures/tag-icons/package_signs/warning--wind--g1.png","viewer/textures/tag-icons/package_signs/warning--winding-road--g1.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-left--g1.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-left--g2.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-left--g3.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-right--g1.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-right--g2.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-right--g3.png","viewer/textures/tag-icons/package_signs/warning--winding-road-first-right--g4.png","viewer/textures/tag-icons/package_signs/warning--winding-road-to-left--g1.png","viewer/textures/tag-icons/package_signs/warning--winding-road-to-right--g1.png","viewer/textures/tag-icons/package_signs/warning--wombat-crossing--g1.png","viewer/textures/tag-icons/package_signs/warning--y-roads--g1.png","viewer/textures/tag-icons/package_signs/warning--y-roads--g2.png","viewer/textures/tag-icons/package_signs/warning--yield-ahead--g1.png","viewer/textures/tag-icons/package_signs/warning--yield-ahead--g3.png","viewer/textures/tag-icons/allterra/index.ts","viewer/textures/tag-icons/allterra/beginn schiessuebungsraum.png","viewer/textures/tag-icons/allterra/beginn schiessuebungsstrecke.png","viewer/textures/tag-icons/allterra/doppelrhombus.png","viewer/textures/tag-icons/allterra/doppelwinkel.png","viewer/textures/tag-icons/allterra/ende schiessuebungsraum.png","viewer/textures/tag-icons/allterra/ende schiessuebungsstrecke.png","viewer/textures/tag-icons/allterra/rhombus.png","viewer/textures/tag-icons/allterra/stellung feuerhalt.png","viewer/textures/tag-icons/allterra/winkel.png","viewer/textures/tag-icons/index.ts","utilities/assets.ts","utilities/camera.ts","redux/config-upgrade.ts","utilities/project.ts","functions/definitions/blur_vehicles_people.tsx","utilities/index.ts","functions/definitions/classify_export.tsx","functions/definitions/las_to_orthomosaic.tsx","functions/definitions/convert_units.tsx","functions/definitions/thin_las.tsx","functions/definitions/las_to_solv3d_streamable.tsx","functions/definitions/sampling.tsx","types/web-sources.ts","functions/functions.tsx","folder/asset.tsx","events.ts","folder/tags.tsx","folder/folder.tsx","folder/web-sources.tsx","folder/folder-list.tsx","folder/models.tsx","bookmarks/bookmark-list.tsx","bookmarks/bookmark.tsx","asset-drawer.tsx","settings/global-settings.tsx","viewer/textures/colormaps/awesome-green.png","viewer/textures/colormaps/black-orange.png","viewer/textures/colormaps/blue-hue.png","viewer/textures/colormaps/blue-orange.png","viewer/textures/colormaps/blue-red.png","viewer/textures/colormaps/grayscale.png","viewer/textures/colormaps/heat-map.png","viewer/textures/colormaps/jet.png","viewer/textures/colormaps/pastel-shades.png","viewer/textures/colormaps/index.ts","settings/settings-drawer.tsx","app-bar.tsx","viewer/js/classifications.ts","viewer/js/shaders/index.ts","viewer/js/shaders/pointcloud.vert","viewer/js/shaders/pointcloud.frag","viewer/js/shaders/panoramic.vert","viewer/js/shaders/panoramic.frag","viewer/js/shaders/planar.vert","viewer/js/shaders/planar.frag","viewer/js/shaders/edl.vert","viewer/js/shaders/edl.frag","viewer/js/shaders/opacity.vert","viewer/js/shaders/opacity.frag","viewer/js/shaders/image.vert","viewer/js/shaders/image.frag","viewer/js/shaders/markers.vert","viewer/js/shaders/markers.frag","viewer/js/shaders/utilities.vert","viewer/js/shaders/utilities.frag","viewer/js/shaders/picker_basic.vert","viewer/js/shaders/picker_basic.frag","viewer/js/shaders/gpu_picker.vert","viewer/js/shaders/gpu_picker.frag","viewer/js/shaders/texture_pack.vert","viewer/js/shaders/tags.vert","viewer/js/shaders/tags.frag","viewer/js/shaders/sprite.vert","viewer/js/shaders/sprite.frag","viewer/js/rendering/render-materials.ts","viewer/js/rendering/render-targets.ts","viewer/js/rendering/render-utils.ts","viewer/js/pointcloud/point-cloud.ts","viewer/js/binary-heap.ts","viewer/js/pointcloud/point-loader.ts","viewer/js/pointcloud/generic-pointcloud.ts","viewer/js/pointcloud/streamable-pointcloud.ts","viewer/js/pointcloud/encompass-pointcloud.ts","viewer/js/pointcloud/point-attributes.ts","viewer/js/pointcloud/potree-pointcloud.ts","viewer/js/controls/orbit-controls.ts","viewer/js/labelling/categories.ts","viewer/js/aerial/map.ts","viewer/textures/misc/no-image-panoramic.png","viewer/textures/misc/no-image-planar.png","viewer/js/cameras/cameras.ts","viewer/js/cameras/cache.ts","context-menu/context-menu.tsx","context-menu/custom-links.tsx","viewer/js/markup/point-markup.ts","viewer/js/aerial/orthos.ts","viewer/js/labelling/image-label.ts","viewer/js/labelling/ortho-label.ts","viewer/js/ray-caster.ts","viewer/js/labelling/scene-label.ts","viewer/js/markup/clipping-box.ts","viewer/js/controls/mobile-controls.ts","viewer/js/point-profile/point-profile.ts","viewer/js/controls/controls.ts","viewer/js/controls/compass.ts","viewer/js/controls/mouse-controls.ts","viewer/js/controls/multi-image.ts","viewer/textures/misc/arrow-standard.png","viewer/textures/misc/arrow-shadow.png","viewer/js/markers/markers.ts","viewer/js/measurements/measurement.ts","viewer/js/measurements/measurement-aerial-view.ts","viewer/js/measurements/measurement-constructor.ts","viewer/js/measurements/measurement-controller.ts","viewer/js/measurements/measurement-formatter.ts","viewer/js/measurements/measurement-group-exporter.ts","viewer/js/measurements/measurement-group.ts","viewer/js/measurements/measurement-scene-view.ts","viewer/js/gpu-picker.ts","stats.module.js","viewer/js/linework/cad.ts","viewer/js/tags.ts","viewer/textures/sprites/point.png","viewer/js/data-aligner/local-projection.ts","viewer/js/linework/ifc.ts","viewer/js/linework/shp.ts","viewer/js/linework/dxf.ts","viewer/js/web-sources/loader.ts","viewer/js/web-sources/web-sources.ts","viewer/js/main.ts","viewer/textures/map-preview/index.ts","viewer/textures/map-preview/open-street-maps.png","viewer/textures/map-preview/arcgis-world.png","viewer/textures/map-preview/arcgis-street.png","viewer/layer-switcher.tsx","viewer/viewer.tsx","viewer/js/data-aligner/image-aligner-advanced.ts","viewer/js/data-aligner/image-aligner-basic.ts","viewer/js/data-aligner/observations.ts","labelling/image-labelling.tsx","alignment/observations.tsx","alignment/image-aligner-advanced.tsx","alignment/image-aligner-basic.tsx","alignment/local-projection.tsx","types/cloud-export.ts","navigation/quick-nav.tsx","export/static/utils.ts","export/static/state.ts","export/static/exporter.ts","export/common.tsx","export/static/static-export.tsx","export/cloud/exporter.ts","export/cloud/cloud-export.tsx","markup/point-markup.tsx","measurements/measurements.tsx","measurements/multi-image.tsx","viewer/textures/misc/about-icon.png","about.tsx","task-queue.tsx","hooks/use-item-search.ts","cloud-projects.tsx","app.tsx","redux/project-slice.ts"],"names":["LanguageOptions","useStyles","makeStyles","theme","createStyles","olButtonParent","background","position","zIndex","borderRadius","olButtonTopLeft","top","left","olButtonBottomLeft","bottom","olButton","padding","margin","backgroundColor","color","minWidth","outline","width","height","olButtonRotate","transition","transform","EnhancedIconButton","props","title","visible","onClick","disabled","children","tooltipText","tooltipTitle","isHtml","dangerouslySetInnerHTML","__html","Fragment","IconButton","size","event","style","opacity","OpenLayersIcon","rotate","placement","classes","className","clsx","Button","DenseIcon","useTheme","centered","other","noPadding","ListItemIcon","spacing","paddingRight","alignItems","draggableTitleClose","palette","grey","marginRight","draggableTitleMinimize","draggableContentStaticHeight","draggableContent","paddingTop","maxWidth","maxHeight","draggableMouseDown","modal","draggableContentParent","display","flexDirection","minHeight","overflow","resize","draggableResizeHandler","float","right","draggableTopDiv","draggableBackdropPaper","draggableBackdropRounded","draggableRoundCorner","draggableTitle","userSelect","cursor","flex","draggableTitleDown","progressContent","progressNoTransition","dropdownGrid","justifyContent","dropdownSpacing","marginBottom","simpleDialogMain","simpleDialogHeader","simpleDialogTitle","simpleDialogEdit","simpleDialogClose","PromptDialog","open","prompt","button","onCancel","onSubmit","t","useTranslation","Dialog","onClose","DialogTitle","DialogContent","DialogContentText","DialogActions","AlertDialog","error","marginTop","marginLeft","fontSize","main","success","TextDialog","label","placeholder","clear","useState","text","setText","setDisabled","useEffect","trim","handleSubmit","trimmedText","TextField","onChange","target","value","onKeyDown","key","autoFocus","type","fullWidth","DropDownDialog","defaultValue","options","setValue","Select","map","option","index","MenuItem","SimpleDialog","onEdit","canSubmit","canClose","DraggableDialog","initialHeight","initialWidth","initialPositionX","initialPositionY","headerHeight","paperPropID","nanoid","resizeElementID","bounds","setBounds","mouseDown","setMouseDown","x","y","modifiedSize","setModifiedSize","setPosition","interval","setInterval","element","document","getElementById","elementWidth","clientWidth","elementHeight","clientHeight","newModifiedSize","newBounds","window","innerWidth","innerHeight","getNewBoundary","newPosition","rightOutOfBounds","leftOutOfBounds","bottomOutOfBounds","topOutOfBounds","Math","min","max","checkOutOfBounds","isEqual","clearInterval","handle","onDrag","data","fullScreen","onFocus","parentElement","removeAttribute","aria-labelledby","paperFullScreen","scrollPaper","BackdropProps","PaperProps","id","onMouseDown","onMouseUp","aria-label","ProgressDialog","percent","animated","toFixed","LinearProgress","variant","bar","draggingListItem","staticListItem","borderBottom","flexGrow","DraggableListItem","item","setData","inputName","listLength","useStaticListItem","draggableId","provided","snapshot","ListItem","ref","innerRef","draggableProps","dragHandleProps","isDragging","Grid","container","xs","Typography","InputLabel","primary","secondary","step","DraggableList","memo","items","onDragEnd","droppableId","droppableProps","length","header","fontWeight","whiteSpace","densePadding","denseFooter","hiddenSort","border","clip","noSelect","rowDisabled","rowIcon","buttonCell","buttonHeader","tableRow","paddingLeft","EnhancedTableCheckboxHead","values","numVisible","filter","checked","indeterminate","Checkbox","stopPropagation","EnhancedTableHead","sortDir","sortBy","onRequestSort","columns","actions","dense","hasActions","TableHead","TableRow","column","property","center","sortable","TableCell","align","sortDirection","TableSortLabel","active","hideSortIcon","direction","EnhancedTableBody","rows","setSelectedRow","handleContextMenu","TableBody","row","hover","tabIndex","EnhancedTableCell","i18n","isString","condition","numeric","content","date","toLocaleString","language","tooltip","slice","cellContent","wordBreak","forceOpacity","pointer","textAlign","EnhancedTable","state","contextMenu","useContextMenu","search","setSearch","selectedRow","handleSearchChange","pageNumber","maxPageNumber","handlePageNumberChange","tableRows","handleSearch","numberOfRows","handleSort","handlePages","ceil","rowsPerPage","searchable","Paper","Input","startAdornment","TableContainer","Table","stickyHeader","handleRequestSort","handleOpen","TablePagination","rowsPerPageOptions","component","count","labelRowsPerPage","labelDisplayedRows","page","from","to","backIconButtonText","nextIconButtonText","toolbar","onChangePage","onChangeRowsPerPage","handleRowsPerPageChange","DenseMenu","handleClose","anchorPosition","action","icon","subMenuRoot","subMenuLabel","NestedMenuItem","React","forwardRef","parentMenuOpen","rightIcon","tabIndexProp","ContainerProps","ContainerPropsProp","MenuItemProps","containerRefProp","menuItemRef","useRef","useImperativeHandle","current","containerRef","menuContainerRef","isSubMenuOpen","setIsSubMenuOpen","isSubmenuFocused","ownerDocument","activeElement","undefined","onMouseEnter","onMouseLeave","focus","firstChild","Menu","pointerEvents","anchorEl","anchorOrigin","vertical","horizontal","transformOrigin","MenuListProps","keepMounted","disableAutoFocus","disableEnforceFocus","NestedMenu","MenuDivider","Divider","transitionProps","timeout","enter","transitions","duration","enteringScreen","exit","anchorReference","TransitionComponent","Grow","TransitionProps","converter","UnitConverter","flexibleHeight","filePath","fileButtonDiv","dropdownWithLabel","paddingBottom","inputParent","inputLabel","inputSwitch","inputFolder","warning","NumberField","units","NumberFieldWithLabel","NumberFieldNoUnits","adornment","helperText","endAdornment","InputAdornment","InputProps","inputProps","hasError","floatValue","parseFloat","isNaN","NumberFieldWithUnits","LocalScene","viewProjectionUnits","convertedMin","setConvertedMin","convertedMax","setConvertedMax","convertedData","setConvertedData","convertNearestStep","roundFunc","numSteps","convert","floor","DropdownWithLabel","seperator","menuOptions","forEach","push","hasSeperator","includes","isLastItem","FolderWithLabel","handleFolderChange","a","dialog","showOpenDialog","properties","result","canceled","folderPath","slash","filePaths","FileWithLabel","optional","saveFile","handleChange","showSaveDialog","filters","then","Delete","Save","AttachFile","InputWithLabel","required","touched","setTouched","onInputChange","useCallback","onBlur","TextWithLabel","renderAsHTML","typography","body1","CheckboxWithLabel","onCheckboxChange","_","Switch","LinearProgressWithLabel","Box","mr","roundDigit","TabPanel","panel","box","role","p","TabProps","PanelProps","verticalDivider","icons","iconButton","iconSize","listIcon","DenseDivider","spacingDown","spacingUp","DividerWithText","Chip","IconToolBar","ToolBarDivider","FontAwesomeIcon","errorColor","Icon","colorPrimary","ToolBarButton","isVisible","SlimScrollbar","scrollHeight","autoHide","autoHeight","autoHeightMin","autoHeightMax","autoHideTimeout","autoHideDuration","DynamicScrollbar","scrollPercent","scroll","setScroll","setMaxHeight","listElementID","checkScrollHeight","offsetHeight","percentHeight","getMaxHeight","addEventListener","removeEventListener","ArrowTooltip","Tooltip","arrow","CursorTooltip","textLines","useMemo","line","onMouseMove","pageX","pageY","PopperProps","getBoundingClientRect","memoWithOpen","areEqual","prevProps","nextProps","menuStateCache","fileMenu","submenu","click","WorkflowExecutable","run","command","sendToMainWindow","app","helpMenu","isDevMode","accelerator","remote","getCurrentWindow","toggleDevTools","shell","openPath","logDirectoryPath","clearMlResources","openExternal","toolsMenu","enabled","debugMenu","reload","message","payload","mainWindow","webContents","send","PythonExecutable","saveLogs","showMessageBox","noLink","setToolEnabled","toolName","getApplicationMenu","getMenuItemById","setMenuState","running","showStatus","onLine","jsonData","license_check","valid","checkAllowedMenuItems","isStandardProject","LanguagePopover","viewer","useViewer","useSelector","selectProjectType","ProjectType","Standard","changeLanguage","toast","template","menu","buildFromTemplate","setApplicationMenu","buildElectronMenu","updateCompass","setTimeout","setLocalizedURL","clearTimeout","Popover","disableScrollLock","Object","keys","ListItemText","LanguageSwitch","popover","usePopover","anchorRef","textTransform","divider","buttonParent","AccountPopover","useAuth","linkAccount","signOut","loggedIn","user","permissions","accountType","AccessType","ViewOnly","Admin","getAccountType","firstName","lastName","isCloudSite","email","AccountButton","Toaster","toasts","useToasterStore","i","remove","toastOptions","backdropFilter","fade","corporate","blue","common","white","boxShadow","shadows","typographyLink","textDecoration","textDecorationColor","TypographyLink","url","openExternalLink","colorPicker","ColorPicker","setColor","disableUnderline","input","appReducer","combineReducers","project","projectReducer","camera","cameraReducer","folders","foldersReducer","projections","projectionsReducer","settings","settingsReducer","assets","assetsReducer","bookmarks","bookmarksReducer","custom_links","customLinksReducer","middleware","MiddlewareArray","concat","thunk","store","configureStore","reducer","newProject","loadConfig","configInit","projectJSON","parameters","savedTagID","tag","forcedTagID","updateStateFromTag","bookmarkID","bookmark","find","aerialState","sceneState","asset","visibleAssets","updateStateFromBookmark","getModifiedSceneState","getModifiedAerialState","switched","toBoolean","expanded","updateStateFromParameters","isMobile","useAppDispatch","useDispatch","readFileJSON","path","isStaticSite","isValidURL","readJsonFromURL","readJsonElectron","readFileText","readTextFromURL","readTextElectron","readFileBuffer","byteRange","readBufferFromURL","readBufferElectron","headers","fetch","response","status","Error","json","fse","readFile","JSON","parse","first","last","arrayBuffer","bytesRequested","byteLength","tmpBuffer","Buffer","alloc","file","read","buffer","bytesRead","close","webpackEmptyContext","req","e","code","resolve","module","exports","projectionsSlice","createSlice","name","initialState","unknownProjectionMeters","view","measureUnits","reducers","updateDataProjection","updateViewProjection","changeMeasureUnits","selectViewProjection","selectDataProjection","selectMeasureUnits","default","string","unknownProjectionFeet","defaultProjection","defaultTransform","origin","Array","fill","translation","rotation","scale","uniqueProjectionID","replace","userProjections","this","load","exists","storage","setSync","getSync","isArray","indexOf","splice","delete","save","titleClose","adornedEnd","utmParent","utmZone","utmButton","dropdown","formControl","buttonDiv","tabsParent","tabsHeaders","UserProjectionPanel","loadProjectionToEdit","setActiveTab","tableState","deleteDialog","useDialog","custom","isDataProjection","deletePrompt","results","projection","onDelete","EditPanel","customProjection","updateEditableValues","hasTransform","setHasTransform","newProjection","existingName","projString","translate","nameTrim","stringTrim","originXError","originYError","originZError","translateXError","translateYError","translateZError","rotationError","scaleError","updateString","updateOrigin","updateTranslation","multiline","FormControlLabel","control","InputLabelProps","shrink","stringify","nameChanged","duplicateName","isValidProjection","update","SearchPanel","setType","searchTerm","setSearchTerm","hemisphere","setHemisphere","searching","setSearching","searchResults","setSearchResults","handleString","getProjections","searchText","previousResults","parsed","proj4","combined","epsg","parseInt","labelId","select","reset","ProjectionsManager","uniqueProjectID","useUniqueProjectID","projectionsDialog","userTableState","useTableState","defaultSort","searchTableState","setExistingName","setNewProjection","activeTab","setTabValue","setCustomProjection","clearProjectionValues","projectionData","dataCopy","hasOwnProperty","transformCopy","registerEvent","AppBar","Tabs","newactiveTab","Tab","newValues","createTheme","EngineViewer","ThemeProvider","ReactDOM","render","originalFetch","asyncTimeout","ms","Promise","handler","locked","accessTokenKey","refreshTokenKey","localStorage","removeItem","tokenKey","has","token","get","setItem","checkForKey","init","others","accessToken","engineCloudURL","method","refreshToken","updateTokens","getItem","initialUserState","adminPermissions","access","create","edit","emptyPermissions","AuthContext","createContext","initialized","getAppCode","activate","AuthProvider","websockets","useWebSockets","setState","appCode","getLocalizedURL","useAppCode","stSignOut","redirectToLogin","clearTokens","disconnect","String","access_code","reject","retryAttempt","initialize","getUser","getPermissions","location","pathname","newState","isElectronApp","connect","Provider","SuperTokens","appInfo","appName","apiDomain","apiBasePath","recipeList","Session","EmailPassword","customFetch","wait","initCustomFetch","TaskStatus","ActiveToolContext","activeToolOpen","setActiveToolOpen","ActiveToolProvider","ViewerContext","setViewer","ViewerProvider","TaskQueueContext","taskQueue","addRunningTask","commands","onFinish","stopRunningTask","task","clearTaskQueue","TaskQueueProvider","setTaskQueue","setRunning","runningTask","Running","exe","destroy","updateTaskStatus","taskID","tasks","availableTasks","Waiting","runAvailableTask","Finished","newTask","BookmarksContext","loadBookmark","deleteBookmarks","BookmarksProvider","dispatch","selectAllAssets","selectAllBookmarks","selectVisibleAssets","updateSettingsState","applySavedAerialState","visibleAssetIDs","bookmarkAssetIDs","assetIDs","assetID","getValidAssetIDs","sort","applySavedSceneState","setInitialStateFlag","changeCameraState","setVisibleAssets","deleteBookmark","pageSize","rowPropertyMap","query","setQuery","setSortDir","setSortBy","setPageNumber","setRowsPerPage","descendingComparator","b","compA","compB","toLowerCase","getComparator","debounce","queryParts","split","searchableColumns","parts","getByID","bookmarksSlice","createBookmark","attributes","Date","toISOString","api","updateBookmark","updates","modified","wsCreateBookmark","wsUpdateBookmark","wsDeleteBookmark","electron","require","child","process","ipcRenderer","fs","glob","cloudProjectID","pattern","URL","href","test","getCloudProjectID","checkForCloudSite","isPackaged","tempDirectoryPath","join","getPath","getTemporaryFile","suffix","clearTemporaryFiles","numRemoved","maxTimeElapsedSeconds","readdir","filenames","filename","stat","stats","currentDate","now","birthtimeMs","console","log","eventName","callback","removeAllListeners","on","existsSync","mkdirSync","userSettings","storagePath","engineStoragePath","viewerStoragePath","settingName","oldName","newName","copyFileSync","setDataPath","engineProjectionExist","viewerProjectionExist","dataPath","engineProjections","finalData","projectionsByName","changeDuplicateNames","setStoragePath","resources","en","de","fr","es","ja","supportedLngs","use","initReactI18next","LanguageDetector","detection","cookieMinutes","fallbackLng","interpolation","escapeValue","searchParams","set","history","pushState","numberOfClassifications","classifications","alias","getClassificationColors","image","Image","onload","canvas","createElement","context","getContext","drawImage","imageData","getImageData","colors","red","green","hexColor","toString","padStart","src","classificationsShader","getGradient","fadeColor","lighten","createMuiTheme","appBar","drawer","snackbar","overrides","MuiPopover","root","MuiTooltip","MuiDialogTitle","MuiDialogContent","MuiIconButton","light","dark","darken","mixins","createTagCollection","folderID","texture","tagCollection","body","withOriginalID","deleteTagCollection","updateTagCollection","createTags","tags","updateTag","tagID","createCollection","deleteCollection","updateCollection","folder","tagsActions","bookmarkActions","AssetType","pointCloudType","ext","lasFileFormat","LAS","encompassFileFormat","Encompass","e57FileFormat","E57Points","potreeFileFormat","Potree","Unknown","getAssetByTagID","Tag","getAssetPayload","saved","cloud","assetsSlice","addAsset","addAssets","updateAsset","deleteAsset","toggleFolderVisibility","setVisibleFolder","setSavedState","updateModelLayer","layerID","DXF","SHP","getAssetByModelLayerID","layer","updateWebMapLayer","Webmap","layers","getAssetByWebMapLayerID","deleteTag","wsCreateAsset","wsUpdateAsset","wsDeleteAsset","createAsset","getState","assetData","getModelAssets","IFC","getTagAssets","getPointCloudAssets","getCameraFileAssets","Panoramic","Planar","getCameraListFromAssets","checkVisible","cameraFile","csv","assetType","flat","getOrthoAssets","OrthoMosaic","getLandXMLAssets","LandXML","getWebMapAssets","useTaskQueue","useContext","useActiveTool","selectSessionID","setOpen","handleToggle","prevState","preventDefault","clientX","clientY","useGlobalSettings","GlobalSettingsContext","WebSocketContext","useBookmarks","ControlType","ControlModes","0","ORBIT","MOUSE","LEFT","ZOOM","MIDDLE","PAN","RIGHT","1","2","customLinkSlice","createCustomLink","customURL","updateCustomLink","linkID","deleteCustomLink","selectAllCustomLinks","transformCache","unitsToValue","latitudeLongitude","webMercator","workerPool","AsyncWorkerPool","verifyProjection","info","verifyProj4String","verifyTransformObject","estimateTransform","estimator","inputValues","outputValues","domain","range","errors","estimate","nudged","getScale","getRotation","getTranslation","transformed","point","transformMany","dX","dY","sqrt","MathUtils","radToDeg","reprojectPoints","points","projectionFrom","projectionTo","positions","postMessage","reprojectPoint","isVector3","toArray","rotateAxis","Vector3","angle","degToRad","sub","applyAxisAngle","divide","add","heightScale","transformKey","projToMeters1","projectionToMeters","getTransform","forward","multiply","closestUtmZone","lonlat","ScenePointConverter","_sceneShift","_sceneScale","_dataProjection","_viewProjection","dataToMeters","dataProjectionUnits","isLonLatProject","proj4String","origin_east","origin_north","origin_elevation","translation_east","translation_north","translation_elevation","scale_factor_h","scale_factor_v","projectionToUnits","isLonLatProjection","resetSceneShift","offset","clone","dx","haversineDistance","dy","checkForOffset","ProjectedCoordinate","toLonLat","lonLat","_dataToLonLat","copy","divideScalar","multiplyScalar","SceneCoordinate","dataProjection","_sceneToData","_dataToAerial","viewProjection","Coordinate","z","_sceneToAerial","_sceneToLonLat","LonLatCoordinate","toGeocentric","DataProjectionCoordinate","toDataProjection","toViewProjection","GeocentricCoordinate","toProjection","ViewProjectionCoordinate","_dataToScene","pow","ep","th","atan2","lon","lat","sin","cos","N","alt","PI","abs","isLonLat1","isLonLat2","vector","distanceTo","SphericalPosition","radius","_theta","_phi","limits","precision","divisor","round","pivot","orbit","theta","dist2d","phi","projectionString","getEulerInverse","euler","quaternion","Quaternion","setFromEuler","invert","Euler","setFromQuaternion","geometryToArray","geometry","polygon","coordinates","flatCoordinates","totalPoints","ecef","calculatePointsPCA","vertices","returnFlat","mean","vertex","eigen","executeWithoutLogging","PCA","getEigenVectors","calculateEigenVectors","matrix","Matrix4","makeBasis","fromArray","transpose","applyMatrix4","pointsFlat","proj","Proj","position1","position2","diffLat","diffLng","arc","distance2d","distance","assign","toUpperCase","fileName","numWorkers","workers","queue","initWorkers","worker","Worker","transfer","processQueue","shift","onmessage","ChangeDetector","oldZoom","oldFov","oldLookatVector","oldCameraPosition","oldUpVector","oldCameraID","oldHeight","oldWidth","oldOrbitState","orbitChanged","cameraChanged","changed","lookatChanged","angleTo","newLookatVector","upChanged","newUpVector","positionChanged","newCameraPosition","fovChanged","newFov","zoomChanged","newZoom","newCameraID","heightChanged","newHeight","widthChanged","newWidth","newOrbitState","fov","getAerialZoomLevel","lookatVector","upVector","getCurrentCameraName","orbitState","metresToSurveyFeetRatio","metresToFeetRatio","allowedUnits","Set","fromUnits","toUnits","fixedLength","convertedValue","navigator","userAgent","isUrl","encodeURI","getProjFactor","screenHeight","projFactor","tan","getPointScale","mesh","meshPosition","getWorldPosition","toScreenPosition","eventToPixel","uv","offsetX","offsetY","layerX","layerY","randomHexColor","random","closestPowerOfTwo","power","num","digits","multiplyFactor","Number","EPSILON","logger","windowSafeDateISO","chunkedArray","array","tmp","coordinatesToArray","numPoints","newPoints","interpolate1D","start","end","steps","linspace","mergeBoundingBoxes","boundingBoxes","bbox","allIndexOf","indices","simplepolygon","pointInPolygon","numberOfVertices","insidePolygon","j","verti","vertj","dy1","dy2","cond1","cond2","planeFromVectors","directions","normal","setLength","Plane","checkValidPolygon","shifted","features","parseURLParams","hash","substring","urlParams","URLSearchParams","fromEntries","params","zoom","ox","oy","oz","px","py","pz","initialSceneState","lookat","cam","angles","mapBoundsStyle","Style","stroke","Stroke","boundsToMapLayer","boundingBox","polygonPoints","toAerial","vectorsource","VectorSource","wrapX","Polygon","feature","Feature","addFeature","VectorLayer","source","getDateTimeFormat","memoizeFormatConstructor","Intl","DateTimeFormat","defaultOptions","timeStyle","dateStyle","createdAt","formatter","format","orthoQuality","orthoOpacity","controlType","openQuickNav","volumeType","VolumeType","MultiPlane","volumeSampleRate","SamplingRate","Medium","viewerBackground","aerialBackground","getGlobalSettingsFromStorage","cache","configURL","GlobalSettingsProvider","loadFromStorage","saveToStorage","EventType","ObjectType","joinRoom","roomID","WebSocketProvider","socket","setSocket","currentRoomID","setCurrentRoomID","onCreate","Assets","Folders","wsCreateFolder","Bookmarks","onUpdate","wsUpdateFolder","objectID","wsDeleteFolder","register","CreateObject","UpdateObject","DeleteObject","extraHeaders","Authorization","io","addTrailingSlash","connected","emit","LeaveRoom","JoinRoom","LocalizedFileFilter","extensions","getCombinedExtension","pngFilter","pointCloudFileFormats","pointCloudFilter","configFileType","configFilter","customURLFilter","imageOrthoFormat","imageOrthoFilter","imageCSVFormat","imageCSVFilter","projFileFormat","imagePlanarFormat","imagePlanarFilter","csvExportFilter","cameraMatrixFilter","measureDataFormat","measureDataFilter","measureCSVFilter","tagCSVFilter","DXFFileFormat","SHPFileFormat","IFCFileFormat","xmlFileFormat","drawingFilter","DXFModelFilter","SHPModelFilter","ZIPFileFilter","modelFileFilter","labelFilter","modelFilter","xmlFileFilter","lasFileFilter","MeasureType","ColorType","MarkerNavType","defaultClassifications","classification","available","initialSettingsState","colorMap","colorType","Height","dynamicSize","circularPoints","arrowMarkers","Arrows","cloudMaxPoints","cloudDistance","cloudScale","cloudMinimum","tagDistance","drawerOpen","heightClip","intensityClip","saveSettingsDefaults","cloneDeep","applySavedSettings","settingsSlice","applySavedDefaults","defaults","changeDefaultSettings","changeOpacity","changeTagDistance","changeCloudDistance","changeCloudMaxPoints","changeCloudScale","changeCloudMinimum","changeHeightClip","changeIntensityClip","changeColorMap","changeColorType","changeDynamicSize","changeCircularPoints","changeAvailableClassifications","availableClassifications","changeClassificationVisibility","changeAllClassificationVisibility","changeSwitched","changeSelectedTab","changeDrawerOpen","changeArrowMarkers","selectOpacity","selectTagDistance","selectCloudDistance","selectCloudMaxPoints","selectCloudScale","selectCloudMinimum","selectHeightClip","selectIntensityClip","selectColorMap","selectColorType","selectDynamicSize","selectCircularPoints","selectViewerSwitched","selectSelectedTab","selectDrawerOpen","selectArrowMarkers","selectClassifications","getAvailableClassifications","getClassificationVisibilities","engineCloudURLKey","setEngineCloudURL","force","currentEngineCloudURL","returnTo","setAttribute","appendChild","removeChild","profileContainer","toolbarDropdown","profileChart","PointProfile","samplingType","setSamplingType","displayUnits","setDisplayUnits","savePointProfileImageBrowser","imageBase64","getPointProfileImage","projectName","savePointProfileImageElectron","defaultPath","imageBase64Data","imageBuffer","writeFileSync","encoding","catch","setPointProfileSampling","setPointProfileUnits","resetPointProfile","refreshPointProfile","resetPointProfileView","initProfileContainer","initialAerialState","basemap","cameraStateSlice","adjustments","changeCameraTransform","changeCameraHeight","changeBasicAdjustments","changeSavedAerialState","selectCameraHeight","selectActiveCamera","selectCameraState","selectCameraTransform","selectBasicAdjustments","selectSavedAerialState","selectForcedTagID","engineMessageTypeJSON","devModeConfig","appPath","getAppPath","readFileSync","testing","warn","getDevModeConfig","Executable","exePath","exeName","developerKey","spawnDetached","logText","pid","opts","onData","onLogs","parseCommandsList","executablePath","cwd","dirname","spawn","env","PYTHONUNBUFFERED","NODEJS","detached","copyPasteCommands","copyableCommands","statusMessage","commandIndex","commandName","stderr","stdout","parseLines","messageType","messageData","err","execSync","basePath","onbeforeunload","stdin","write","logPrefix","maxLogFiles","dateString","replaceAll","logPath","logs","writeFile","oldest","birthtime","oldestFilePath","trackToolUsage","isModelFile","isStreamablePointsFile","isRawPointsFile","getModelLayers","originalId","getWebmapLayers","identifier","getBaseAsset","getTagsData","comment","roll","pitch","yaw","config","object","defaultFolderTitle","generateDefaultFolder","foldersSlice","createFolder","updateFolder","newDefaultFolder","deleteFolder","selectDefaultFolder","selectAllFolders","TagSize","spiralIntersect","spiral","stepDist","sigDigs","spiralParams","spiType","reverseCurve","RL","constant","partial","radiusEnd","radiusStart","delta","cw","rot","L","dirEnd","dirStart","xStart","yStart","xEnd","yEnd","segmentMin","segmentMax","Start","c","End","d","xCorr","yCorr","deltaCorr","ls","le","distMin","endPointError","chosenDelta","deltaTrial","l","xRotated","yRotated","xDiff","yDiff","dist","spiralParamaters","spiralCoord","distAlong","distAcross","xAtLength","yAtLength","lengthLocal","distAcrossNew","sideOfLine","lineDist","curveDist","calcAngle","acos","textures","icon0","icon1","icon2","icon3","icon4","icon5","icon6","icon7","icon8","icon9","icon10","icon11","icon12","icon13","icon14","icon15","icon16","icon17","icon18","icon19","icon20","icon21","icon22","icon23","icon24","icon25","icon26","icon27","icon28","icon29","icon30","icon31","icon32","icon33","icon34","icon35","icon36","icon37","icon38","icon39","icon40","icon41","icon42","icon43","icon44","icon45","icon46","icon47","icon48","icon49","icon50","icon51","icon52","icon53","icon54","icon55","icon56","icon57","icon58","icon59","icon60","icon61","icon62","icon63","icon64","icon65","icon66","icon67","icon68","icon69","icon70","icon71","icon72","icon73","icon74","icon75","icon76","icon77","icon78","icon79","icon80","icon81","icon82","icon83","icon84","icon85","icon86","icon87","icon88","icon89","icon90","icon91","icon92","icon93","icon94","icon95","icon96","icon97","icon98","icon99","icon100","icon101","icon102","icon103","icon104","icon105","icon106","icon107","icon108","icon109","icon110","icon111","icon112","icon113","icon114","icon115","icon116","icon117","icon118","icon119","icon120","icon121","icon122","icon123","icon124","icon125","icon126","icon127","icon128","icon129","icon130","icon131","icon132","icon133","icon134","icon135","icon136","icon137","icon138","icon139","icon140","icon141","icon142","icon143","icon144","icon145","icon146","icon147","icon148","icon149","icon150","icon151","icon152","icon153","icon154","icon155","icon156","icon157","icon158","icon159","icon160","icon161","icon162","icon163","icon164","icon165","icon166","icon167","icon168","icon169","icon170","icon171","icon172","icon173","icon174","icon175","icon176","icon177","icon178","icon179","icon180","icon181","icon182","icon183","icon184","icon185","icon186","icon187","icon188","icon189","icon190","icon191","icon192","icon193","icon194","icon195","icon196","icon197","icon198","icon199","icon200","icon201","icon202","icon203","icon204","icon205","icon206","icon207","icon208","icon209","icon210","icon211","icon212","icon213","icon214","icon215","icon216","icon217","icon218","icon219","icon220","icon221","icon222","icon223","icon224","icon225","icon226","icon227","icon228","icon229","icon230","icon231","icon232","icon233","icon234","icon235","icon236","icon237","icon238","icon239","icon240","icon241","icon242","icon243","icon244","icon245","icon246","icon247","icon248","icon249","icon250","icon251","icon252","icon253","icon254","icon255","icon256","icon257","icon258","icon259","icon260","icon261","icon262","icon263","icon264","icon265","icon266","icon267","icon268","icon269","icon270","icon271","icon272","icon273","icon274","icon275","icon276","icon277","icon278","icon279","icon280","icon281","icon282","icon283","icon284","icon285","icon286","icon287","icon288","icon289","icon290","icon291","icon292","icon293","icon294","icon295","icon296","icon297","icon298","icon299","icon300","icon301","icon302","icon303","icon304","icon305","icon306","icon307","icon308","icon309","icon310","icon311","icon312","icon313","icon314","icon315","icon316","icon317","icon318","icon319","icon320","icon321","icon322","icon323","icon324","icon325","icon326","icon327","icon328","icon329","icon330","icon331","icon332","icon333","icon334","icon335","icon336","icon337","icon338","icon339","icon340","icon341","icon342","icon343","icon344","icon345","icon346","icon347","icon348","icon349","icon350","icon351","icon352","icon353","icon354","icon355","icon356","icon357","icon358","icon359","icon360","icon361","icon362","icon363","icon364","icon365","icon366","icon367","icon368","icon369","icon370","icon371","icon372","icon373","icon374","icon375","icon376","icon377","icon378","icon379","icon380","icon381","icon382","icon383","icon384","icon385","icon386","icon387","icon388","icon389","icon390","icon391","icon392","icon393","icon394","icon395","icon396","icon397","icon398","icon399","icon400","icon401","icon402","icon403","icon404","icon405","icon406","icon407","icon408","icon409","icon410","icon411","icon412","icon413","icon414","icon415","icon416","icon417","icon418","icon419","icon420","icon421","icon422","icon423","icon424","icon425","icon426","icon427","icon428","icon429","icon430","icon431","icon432","icon433","icon434","icon435","icon436","icon437","icon438","icon439","icon440","icon441","icon442","icon443","icon444","icon445","icon446","icon447","icon448","icon449","icon450","icon451","icon452","icon453","icon454","icon455","icon456","icon457","icon458","icon459","icon460","icon461","icon462","icon463","icon464","icon465","icon466","icon467","icon468","icon469","icon470","icon471","icon472","icon473","icon474","icon475","icon476","icon477","icon478","icon479","icon480","icon481","icon482","icon483","icon484","icon485","icon486","icon487","icon488","icon489","icon490","icon491","icon492","icon493","icon494","icon495","icon496","icon497","icon498","icon499","icon500","icon501","icon502","icon503","icon504","icon505","icon506","icon507","icon508","icon509","icon510","icon511","icon512","icon513","icon514","icon515","icon516","icon517","icon518","icon519","icon520","icon521","icon522","icon523","icon524","icon525","icon526","icon527","icon528","icon529","icon530","icon531","icon532","icon533","icon534","icon535","icon536","icon537","icon538","icon539","icon540","icon541","icon542","icon543","icon544","icon545","icon546","icon547","icon548","icon549","icon550","icon551","icon552","icon553","icon554","icon555","icon556","icon557","icon558","icon559","icon560","icon561","icon562","icon563","icon564","icon565","icon566","icon567","icon568","icon569","icon570","icon571","icon572","icon573","icon574","icon575","icon576","icon577","icon578","icon579","icon580","icon581","icon582","icon583","icon584","icon585","icon586","icon587","icon588","icon589","icon590","icon591","icon592","icon593","icon594","icon595","icon596","icon597","icon598","icon599","icon600","icon601","icon602","icon603","icon604","icon605","icon606","icon607","icon608","icon609","icon610","icon611","icon612","icon613","icon614","icon615","icon616","icon617","icon618","icon619","icon620","icon621","icon622","icon623","icon624","icon625","icon626","icon627","icon628","icon629","icon630","icon631","icon632","icon633","icon634","icon635","icon636","icon637","icon638","icon639","icon640","icon641","icon642","icon643","icon644","icon645","icon646","icon647","icon648","icon649","icon650","icon651","icon652","icon653","icon654","icon655","icon656","icon657","icon658","icon659","icon660","icon661","icon662","icon663","icon664","icon665","icon666","icon667","icon668","icon669","icon670","icon671","icon672","icon673","icon674","icon675","icon676","icon677","icon678","icon679","icon680","icon681","icon682","icon683","icon684","icon685","icon686","icon687","icon688","icon689","icon690","icon691","icon692","icon693","icon694","icon695","icon696","icon697","icon698","icon699","icon700","icon701","icon702","icon703","icon704","icon705","icon706","icon707","icon708","icon709","icon710","icon711","icon712","icon713","icon714","icon715","icon716","icon717","icon718","icon719","icon720","icon721","icon722","icon723","icon724","icon725","icon726","icon727","icon728","icon729","icon730","icon731","icon732","icon733","icon734","icon735","icon736","icon737","icon738","icon739","icon740","icon741","icon742","icon743","icon744","icon745","icon746","icon747","icon748","icon749","icon750","icon751","icon752","icon753","icon754","icon755","icon756","icon757","icon758","icon759","icon760","icon761","icon762","icon763","icon764","icon765","icon766","icon767","icon768","icon769","icon770","icon771","icon772","icon773","icon774","icon775","icon776","icon777","icon778","icon779","icon780","icon781","icon782","icon783","icon784","icon785","icon786","icon787","icon788","icon789","icon790","icon791","icon792","icon793","icon794","icon795","icon796","icon797","icon798","icon799","icon800","icon801","icon802","icon803","icon804","icon805","icon806","icon807","icon808","icon809","icon810","icon811","icon812","icon813","icon814","icon815","icon816","icon817","icon818","icon819","icon820","icon821","icon822","icon823","icon824","icon825","icon826","icon827","icon828","icon829","icon830","icon831","icon832","icon833","icon834","icon835","icon836","icon837","icon838","icon839","icon840","icon841","icon842","icon843","icon844","icon845","icon846","icon847","icon848","icon849","icon850","icon851","icon852","icon853","icon854","icon855","icon856","icon857","icon858","icon859","icon860","icon861","icon862","icon863","icon864","icon865","icon866","icon867","icon868","icon869","icon870","icon871","icon872","icon873","icon874","icon875","icon876","icon877","icon878","icon879","icon880","icon881","icon882","icon883","icon884","icon885","icon886","icon887","icon888","icon889","icon890","icon891","icon892","icon893","icon894","icon895","icon896","icon897","icon898","icon899","icon900","icon901","icon902","icon903","icon904","icon905","icon906","icon907","icon908","icon909","icon910","icon911","icon912","icon913","icon914","icon915","icon916","icon917","icon918","icon919","icon920","icon921","icon922","icon923","icon924","icon925","icon926","icon927","icon928","icon929","icon930","icon931","icon932","icon933","icon934","icon935","icon936","icon937","icon938","icon939","icon940","icon941","icon942","icon943","icon944","icon945","icon946","icon947","icon948","icon949","icon950","icon951","icon952","icon953","icon954","icon955","icon956","icon957","icon958","icon959","icon960","icon961","icon962","icon963","icon964","icon965","icon966","icon967","icon968","icon969","icon970","icon971","icon972","icon973","icon974","icon975","icon976","icon977","icon978","icon979","icon980","icon981","icon982","icon983","icon984","icon985","icon986","icon987","icon988","icon989","icon990","icon991","icon992","icon993","icon994","icon995","icon996","icon997","icon998","icon999","icon1000","icon1001","icon1002","icon1003","icon1004","icon1005","icon1006","icon1007","icon1008","icon1009","icon1010","icon1011","icon1012","icon1013","icon1014","icon1015","icon1016","icon1017","icon1018","icon1019","icon1020","icon1021","icon1022","icon1023","icon1024","icon1025","icon1026","icon1027","icon1028","icon1029","icon1030","icon1031","icon1032","icon1033","icon1034","icon1035","icon1036","icon1037","icon1038","icon1039","icon1040","icon1041","icon1042","icon1043","icon1044","icon1045","icon1046","icon1047","icon1048","icon1049","icon1050","icon1051","icon1052","icon1053","icon1054","icon1055","icon1056","icon1057","icon1058","icon1059","icon1060","icon1061","icon1062","icon1063","icon1064","icon1065","icon1066","icon1067","icon1068","icon1069","icon1070","icon1071","icon1072","icon1073","icon1074","icon1075","icon1076","icon1077","icon1078","icon1079","icon1080","icon1081","icon1082","icon1083","icon1084","icon1085","icon1086","icon1087","icon1088","icon1089","icon1090","icon1091","icon1092","icon1093","icon1094","icon1095","icon1096","icon1097","icon1098","icon1099","icon1100","icon1101","icon1102","icon1103","icon1104","icon1105","icon1106","icon1107","icon1108","icon1109","icon1110","icon1111","icon1112","icon1113","icon1114","icon1115","icon1116","icon1117","icon1118","icon1119","icon1120","icon1121","icon1122","icon1123","icon1124","icon1125","icon1126","icon1127","icon1128","icon1129","icon1130","icon1131","icon1132","icon1133","icon1134","icon1135","icon1136","icon1137","icon1138","icon1139","icon1140","icon1141","icon1142","icon1143","icon1144","icon1145","icon1146","icon1147","icon1148","icon1149","icon1150","icon1151","icon1152","icon1153","icon1154","icon1155","icon1156","icon1157","icon1158","icon1159","icon1160","icon1161","icon1162","icon1163","icon1164","icon1165","icon1166","icon1167","icon1168","icon1169","icon1170","icon1171","icon1172","icon1173","icon1174","icon1175","icon1176","icon1177","icon1178","icon1179","icon1180","icon1181","icon1182","icon1183","icon1184","icon1185","icon1186","icon1187","icon1188","icon1189","icon1190","icon1191","icon1192","icon1193","icon1194","icon1195","icon1196","icon1197","icon1198","icon1199","icon1200","icon1201","icon1202","icon1203","icon1204","icon1205","icon1206","icon1207","icon1208","icon1209","icon1210","icon1211","icon1212","icon1213","icon1214","icon1215","icon1216","icon1217","icon1218","icon1219","icon1220","icon1221","icon1222","icon1223","icon1224","icon1225","icon1226","icon1227","icon1228","icon1229","icon1230","icon1231","icon1232","icon1233","icon1234","icon1235","icon1236","icon1237","icon1238","icon1239","icon1240","icon1241","icon1242","icon1243","icon1244","icon1245","icon1246","icon1247","icon1248","icon1249","icon1250","icon1251","icon1252","icon1253","icon1254","icon1255","icon1256","icon1257","icon1258","icon1259","icon1260","icon1261","icon1262","icon1263","icon1264","icon1265","icon1266","icon1267","icon1268","icon1269","icon1270","icon1271","icon1272","icon1273","icon1274","icon1275","icon1276","icon1277","icon1278","icon1279","icon1280","icon1281","icon1282","icon1283","icon1284","icon1285","icon1286","icon1287","icon1288","icon1289","icon1290","icon1291","icon1292","icon1293","icon1294","icon1295","icon1296","icon1297","icon1298","icon1299","icon1300","icon1301","icon1302","icon1303","icon1304","icon1305","icon1306","icon1307","icon1308","icon1309","icon1310","icon1311","icon1312","icon1313","icon1314","icon1315","icon1316","icon1317","icon1318","icon1319","icon1320","icon1321","icon1322","icon1323","icon1324","icon1325","icon1326","icon1327","icon1328","icon1329","icon1330","icon1331","icon1332","icon1333","icon1334","icon1335","icon1336","icon1337","icon1338","icon1339","icon1340","icon1341","icon1342","icon1343","icon1344","icon1345","icon1346","icon1347","icon1348","icon1349","icon1350","icon1351","icon1352","icon1353","icon1354","icon1355","icon1356","icon1357","icon1358","icon1359","icon1360","tagTextures","basicPins","trafficSigns","UKRoadSigns","packageObjects","packageSigns","allterra","defaultTagTexture","getTagTexturePath","useAssetTools","addAssetPaths","assetPaths","cloudPaths","isPointCloudFile","cameraPaths","isCameraFile","modelPaths","orthoPaths","isOrthomosaicFile","planarPaths","isPlanarFile","xmlPaths","isXmlFile","numClouds","numModels","numImageFiles","numXmlFiles","addPlanarFiles","planarFilesAdded","addCSVFiles","csvFilesAdded","pointsAdded","addPointCloudFiles","addOrthoFiles","orthosAdded","addModelFiles","modelsAdded","addXMLFiles","xmlAdded","totalAdded","ifcPaths","isIFCFile","shpPaths","isSHPFile","dxfPaths","isDXFFile","addIFCFiles","addSHPFiles","addDXFFiles","assetsList","pointPath","extension","extname","basename","showBackdrop","addOrthoBatch","numAdded","hideBackdrop","assetPath","addCameraFile","addTagCSV","addTagCSVs","reason","missingHeaders","lineNumber","row_number","lineText","addCameraFiles","pathError","addPlanarFile","addXMLFile","addFilePaths","configs","isConfigFile","isAssetFile","isProjectionFile","loadProjectFile","projectionPath","addWebSource","downloadFile","fileType","fileFilter","contentType","encodeURIComponent","getPathFromDialog","savePath","pathWithExtension","isPanoramicFile","isCSVFile","isTXTFile","getDXFLayerNames","getSHPLayerNames","dbf","layerData","dbfPath","geotiff","file_path","corners","base64","base64_split","scale_x","scale_y","orthoData","imageBounds","imageDataSplit","imageSize","imageSizeOriginal","width_original","height_original","imagePath","scaleX","scaleY","decoded","cameras","numCameras","cameraNames","detectImagePath","pathFound","imageExt","hasImageExt","cameraData","buildFilePath","imageName","rowData","engineStyleProjection","csv_data","estimatedPath","estimated_path","parser","Parser","explicitChildren","preserveChildrenOrder","textAll","parseStringPromise","xmlJSON","xmlData","$","Units","$$","alignments","enu","Alignments","Alignment","alignment","alignObject","staStart","about","desc","CoordGeom","geom","geometryElement","shapeType","dollarSignKeys","featureKeys","key$","aboutValue","fKey","splitCoordValue","coordValue","coordValueCorrected","scv","overwriteLength","overwriteStaStart","valid_tags","invalid_rows","missing_headers","newTags","openDialogMulti","showErrorBox","openDialogFile","parseDirectory","directoryPath","withFileTypes","entries","files","entry","isFile","directories","isDirectory","directory","checkImagePath","searchDepth","duplicate","singleFolderSearch","dirSeperator","depth","paths","subset","filenameQuery","globPath","sync","singleImageValid","multiImageValid","imageNames","testImageExt","showOpenDialogSync","manual","saveMatrixFile","cameraTransformPath","copyFile","readTransformFile","errorResponse","arr","cols","col","getMatrixValues","setFromMatrixPosition","setFromRotationMatrix","toVector3","upgradeVersion321","oldVersion","semver","gt","getConfigVersion","upgradeVersion320","upgradeVersion319","links","upgradeVersion318","mappedCamerasIDs","upgradeVersion317","overrideSettings","fromJSON","upgradeVersion316","upgradeVersion315","uniqueSession","upgradeVersion314","isDefault","upgradeVersion313","upgradeVersion312","upgradeVersion311","cloudSize","upgradeVersion310","newVersion","configVersion","upgradeVersion39","extent","resolution","log2","upgradeVersion38","upgradeVersion37","upgradeVersion36","upgradeVersion35","upgradeVersion34","getLocalizedProjectName","defaultProjectTitle","getLocalizedFolderName","saveProjectAs","localizedProjectName","changePath","nameWithoutExt","updateProjectName","writeProject","saveProject","allowSaveAs","loadProjectJSON","version","clearWindowHash","lt","minimumConfigVersion","currentConfigVersion","exitWithChanges","Cloud","originalState","modifiedState","hasChanged","buttons","defaultId","DetectionType","OperationTypes","mixedDataWarning","BlurVehiclesPeople","outputPath","setOutputPath","VehiclesAndPeople","detectionType","setDetectionType","blurStrength","setBlurStrength","accuracy","setAccuracy","importResult","setImportResult","pythonName","tempImagePath","imagesCSVPath","getCamerasForCSV","pathsJSON","getCameraRowsCSV","writeToString","getCameraFolders","pathOverlap","Vehicles","People","multipleSelectWithLabel","ChannelType","ClassifyExport","Include","operationType","setOperationType","classValues","setClassValues","classList","pointclouds","uniqueClassifications","formatClassValue","classValue","afterClose","Exclude","multiple","renderValue","selected","renderedClasses","classVal","savedLocation","wordWrap","ConvertUnits","inputUnits","setInputUnits","outputUnits","setOutputUnits","nullUnits","sameUnits","pathNameNoExt","outputName","FormHelperText","ThinTechniques","ThinDimensions","ChannelSelector","Empty","Red","Green","Blue","Linearity","Planarity","Scattering","Normal","Intensity","NumReturns","ReturnNumber","Classification","LasToOrthomosaic","channelOne","setChannelOne","channelTwo","setChannelTwo","channelThree","setChannelThree","pixelSize","setPixelSize","emptyChannels","tifPath","LasToSolv3dStreamable","isSingleFile","setSingleFile","binPath","Sampling","defaultSamplingRateOptions","samplingRate","setSamplingRate","validSampling","decimalSamplingRate","ServerType","invalidThinningError","ThinLas","defaultThinningOptions","Lowest","thinTechnique","setThinTechnique","Two","thinDimension","setThinDimension","thinning","setThinning","inValidThinningValue","Average","Highest","Three","generateFunctionData","FunctionsMenu","contextOpen","closeContextMenu","blurVehiclesPeopleDialog","lasToOrthomosaicDialog","lasToSolv3dStreamableDialog","thinLasDialog","samplingDialog","classifyExportDialog","convertUnitsDialog","LASFiles","cameraFiles","hasLASFiles","hasCameraFiles","handleBlurVehiclesPeople","handleLasToOrthomosaic","handleLasToSolv3dStreamable","handleThinLas","handleSampling","handleClassifyExport","handleConvertUnits","filtered","localeCompare","getMenuItems","initialAssetState","assetPercent","assetError","assetIsLarge","floatRight","itemList","itemText","assetMargins","assetWarning","assetInfo","assetCheckbox","checkboxParent","percentLabel","fileInfoHeading","fileInfoText","tagAvatar","remoteAssetIcon","LasFileInfoDialog","hasVLRSData","vlrs_data","vlrsKeys","gutterBottom","x_min","x_max","y_min","y_max","z_min","z_max","record_id","has_time_stamp","has_rgb","has_intensity","AssetItem","setDraggingAsset","fileInfoDialog","detailsDialog","renameDialog","iconUpdateDialog","modelLayersDialog","webmapLayersDialog","landXMLDialog","fileInfo","setFileInfo","assetState","setAssetState","isPanoramic","isPlanar","isEncompassCloud","isPotreeCloud","isLASFile","isE57File","isOrtho","isTag","isIFC","isSHP","isDXF","isLandXML","isWebMap","isCamera","isPointCloud","canEditLayers","ArcGISImageServer","TileServer","updateAssetState","newAssetState","getCloudStatus","getModelStatus","handleTagCSVExport","getTagsForCSV","getTagRowsCSV","handleImageCSVExport","submitTagIcon","isLargeCloud","showPercent","assetText","getAssetText","tagTexture","tagSize","getTagAttributes","isRemoteAsset","canDeleteAsset","canEditAsset","draggable","onContextMenu","onDragStart","snapToOrtho","snapToPointCloud","snapToImages","snapToModel","Avatar","ListItemSecondaryAction","edge","getLasFileInfo","TagIconDialog","currentTexture","currentSize","sendCustomEvent","detail","CustomEvent","dispatchEvent","NEW_CSV_ID","NEW_FOLDER_ID","textField","selectDivider","asterisk","avatarParent","tagIconPagination","tagIconSearchParent","tagIconPageParent","tagIconParent","tagIconCheck","tagIconImage","setPage","setTagTexture","setTagSize","selectedPage","tagsPerPage","resetDefaults","searchTerms","matches","iconChanged","sizeChanged","tagIconsPerRow","numPages","texturesForPage","handleIconClick","XSmall","Small","Large","XLarge","TagItemsDialog","getMeasurementFormatter","getVectorPrecision","showTagDetails","tagItems","zoomToTag","jumpToTag","copyPosition","copyTextToClipboard","coordinate","copyURL","deleteRow","editRow","isAerialTag","TagDeleteDialog","toDelete","numTagsToDelete","TagDetailsDialog","tagAssets","tagDetailsDialog","setTitle","setComment","tagToEdit","setTagToEdit","editing","setEditing","canEdit","TagCreateDialog","collectionID","setCollectionID","collectionName","setCollectionName","setFolderID","newTag","createNewFolder","tagFolderID","createNewFile","tagCollectionID","hasExistingFolders","hasExistingCSVs","titleMissing","nameMissing","folderOptions","tagCSV","Collapse","in","localizedFolderName","assetFolderClass","AssetFolder","draggingAsset","setExpanded","dragDropHover","setDragDropHover","numHidden","onDragOver","onDragLeave","onDrop","dataTransfer","addAssetsToFolder","newVisibility","List","disablePadding","WebSourceDialog","serverURL","setServerURL","serverName","setServerName","ArcGISMapServer","serverType","setServerType","submitting","setSubmitting","getMapLayers","webmapData","public","getMapServerLayers","baseURL","getFeatureServerLayers","getImageServerLayers","ok","getWMSLayers","WMSCapabilities","capabilities","Capability","Layer","Name","Title","getWFSLayers","XMLParser","featureTypeList","FeatureTypeList","FeatureType","getWMTSLayers","WMTSCapabilities","Contents","Identifier","getTileServerLayers","ArcGISFeatureServer","OGCWMS","OGCWFS","OGCWMTS","isSecureURL","protocol","mapType","pop","hasX","hasY","hasZ","ArcGISOnline","warnings","showEsriWarning","WebSourceLayerCheckbox","onVisibilityChange","WebSourceLayerDialog","visible_checkbox","visible_sortable","getRows","AddAssetList","webmapDialog","handleAddModels","handleAddPoints","handleAddOrtho","handleAddPanoramics","handleAddTags","handleAddPlanars","handleAddXML","handleAddWebMap","FolderList","newFolderDialog","defaultFolder","handleAddFolder","ModelLayerCheckbox","ModelLayerColor","ModelLayerDialog","color_picker","addItem","footerDiv","footerCheckbox","getStoredState","BookmarkList","bookmarkDialog","getCameraPosition","BookmarkItem","updateDialog","assetDrawerWidth","backdrop","inside","drawerPaper","tab","flexBasis","flexShrink","tabGrow","toggleDrawer","AssetDrawer","assetDrawerState","projectActiveTab","setSelectedTab","newAnnotations","annotation","addAnnotation","updateAnnotations","removeAnnotation","Drawer","anchor","transitionDuration","paper","sectionTitle","slider","checkBoxWithLabel","GlobalSettings","settingsDialog","globalSettings","setOpenQuickNav","setOrthoQuality","setOrthoOpacity","setControlType","setVolumeType","setVolumeSampleRate","setViewerBackground","setAerialBackground","globalEngineCloudURL","setGlobalEngineCloudURL","FormControl","Reverse","Autocad","LowestPlane","High","Low","magnitude","ColorMap","colorMaps","heatMap","awesomeGreen","pastelShades","blueOrange","blackOrange","blueHue","blueRed","jet","grayScale","getColorMap","settingsDrawerWidth","drawerHeader","list","listItem","switch","colorPreview","img","objectFit","classificationPreview","borderColor","borderStyle","borderWidth","switchLabel","switchElement","inputText","inputPropDiv","sliderInputText","boldTitleTypography","rightInput","sliderInputParent","sliderInputToggle","InputSlider","labelFunction","isRangeType","labelFormat","marks","openState","sliderValue","setSliderValue","roundToStep","changeCallback","throttle","finishCallback","scaledValue","out","toInput","saveValue","fromInput","StyledSlider","valueLabelDisplay","valueLabelFormat","KeyboardArrowUp","KeyboardArrowDown","setValues","withStyles","rail","track","borderTopLeftRadius","borderBottomLeftRadius","thumb","valueLabel","borderTopColor","mark","markLabel","markLabelActive","Slider","SingleInputProp","inputValue","setInputValue","inputError","setInputError","errorState","RangeInputProp","minValue","setMinValue","maxValue","setMaxValue","minError","setMinError","maxError","setMaxError","InputField","SingleSlider","RangeSlider","ClassificationList","classificationColors","setClassificationColors","updateColorsList","hasClassifications","SettingsDrawer","savedColorMap","savedColorType","savedDynamicSize","savedCircularPoints","savedArrowMarkers","pickerDebug","setPickerDebug","boundsVisible","setBoundsVisible","renderPaused","setRenderPaused","savedOpacity","savedTagDistance","savedCloudDistance","savedCloudScale","savedCloudMinimum","savedMaxPoints","savedHeightClip","savedIntensityClip","savedAvailableClassifications","savedClassificationVisibilities","newClasses","oldClasses","setPointCloudOpacity","setTagDistance","setPointCloudDistance","setPointCloudScale","setPointCloudMinimum","setPointCloudMaxPoints","setPointCloudHeightClip","setPointCloudIntensityClip","setVisibleClassifications","setPointCloudColorMap","setPointCloudColorType","setPointCloudDynamicSize","setPointCloudCircularPoints","setNavigationType","isIntensity","isHeightmap","colorMapRequired","togglePickerDebug","setPointsShouldUpdate","setPointBoundsVisible","Markers","None","subtitle2","every","menuButton","projectionText","footerCoords","textShadow","footerOffset","footer","slimButton","matrixValuesParent","matrixValues","matrixButtons","ProjectDetails","projectDialog","warnDialog","setName","setHeight","setProj","matchedProjection","setMatchedProjection","imported","setImported","setProjections","cameraTransform","setCameraTransform","correction","setErrors","selectProjectName","projectHeight","basicAdjustments","unknownTextMeters","unknownTextFeet","trimmedName","emptyName","emptyHeight","emptyProjection","heightInMeters","toMeters","projectionName","selectedProjection","onCorrectionSelect","onMatrixChange","onCorrectionRemove","importedProjection","userProjection","handleImported","sortedProjections","name1","name2","getNewProjection","hasBasicAlignment","isDefaultProjection","localizedProjectionName","getLocalizedProjectionName","getTransformValues","hasUserProjections","noWrap","ListSubheader","disableSticky","conflict","resetBasicAlignerCamera","MainAppBar","settingsDrawerState","setSettingsDrawerState","measurementsDialog","customURLDialog","Toolbar","MainAppFooter","mouseCoords","setMouseCoords","coordData","setCoordData","setCoordinates","coords","disableGutters","classificationTexture","TextureLoader","minFilter","NearestFilter","magFilter","shaders","pointcloud","vert","frag","panoramic","planar","edl","markers","utilities","basic_picker","gpu_picker","texture_packer","sprite","packedTextureScale","assignPackedData","xIndex","yIndex","valueInt","generateDataTexture","channels","Color","Uint8Array","r","g","RGBFormat","RGBAFormat","DataTexture","needsUpdate","BaseMaterial","uniforms","defineProperty","ShaderMaterial","PointCloudMaterial","gpuPicker","minSize","adaptiveSize","isOctreeCloud","currentCameraTarget","screenwidth","octreeSpacing","octreeSize","octreeCorner","intensityRange","rgbMax","heightRange","timeStamp","classificationVisible","visibleClassTexture","crossSectionWidth","crossSectionStart","crossSectionEnd","clipBoxTexture","areaTriangleTexture","visibleNodesTexture","numClippingBoxes","numAreaTriangles","loader","colorMapTexture","updateVisibleClassifications","Uniform","maxSize","Vector2","heightClamp","intensityClamp","classificationData","visibleNodes","areaTriangleData","clipPolygonData","defines","NUMBER_OF_CLASSIFICATIONS","CLIP_TEXTURE_WIDTH","CLIP_TEXTURE_HEIGHT","AREA_TEXTURE_WIDTH","AREA_TEXTURE_HEIGHT","VISIBLE_NODES_WIDTH","PACKED_TEXTURE_SCALE","fragmentShader","vertexShader","vertexColors","transparent","depthWrite","initProperties","NUM_CLIP_BOXES","NUM_AREA_TRIANGLES","EDLMaterial","near","far","pixelRatio","screenWidth","edlStrength","neighbourCount","neighbours","Float32Array","NEIGHBOUR_COUNT","tDepth","OpacityMaterial","ImageMaterial","side","DoubleSide","TagMaterial","currentCameraPosition","currentCameraRotation","windowHeight","initialCameraLoading","texturePath","textureData","uniform","imageTexture","PanoramicImageMaterial","tImage","PlanarImageMaterial","imageWidth","imageHeight","fx","fy","cx","cy","MarkerMaterial","currentIndex","orbitMode","CustomSpriteMaterial","updateValues","BasicPickerMaterial","BasicRenderTarget","hasAlpha","LinearFilter","stencilBuffer","WebGLRenderTarget","EDLRenderTarget","isWebGL2","generateMipmaps","depthBuffer","depthTexture","DepthTexture","FloatType","UnsignedIntType","OpacityRenderTarget","RenderPass","screenScene","screenQuad","PlaneBufferGeometry","material","MeshBasicMaterial","depthTest","Scene","Mesh","Camera","renderer","setRenderTarget","RenderUtils","screenPass","targets","opacityMaterial","opacityRenderTarget","initTargets","addTarget","EDLSupport","updateEDLValues","resizeTextures","w","h","dispose","setSize","scenes","toRender","scene","renderTarget","updateMaterial","renderMaterial","renderTargetAttrs","renderToScreen","maxVaryings","floatFragmentTextures","renderSize","getSize","PointCloudNode","parent","pointsScene","pointsPicker","boundingBoxMesh","_bounding_sphere","_bounding_box","nodeCenter","density","loaded","loading","node","clearChildNodes","removeFromScene","disposeGeometry","picker","boundingBoxVisibility","BufferGeometry","BufferAttribute","intensity","gpu_index","computeBoundingBox","Sphere","subScalar","addScalar","Box3","PointCloud","rgbArray","maxColor","materialScene","materialPicker","materials","_tightBoundingBox","generateEdgeMesh","boxGeometry","BoxGeometry","edgeGeometry","EdgesGeometry","boxMaterial","LineBasicMaterial","LineSegments","materialDefaults","updateMinimapExtent","disposeNodes","getVisibleNodes","intensityMin","intensityMax","closestValue","arrMax","midpoint","gpuPickers","BinaryHeap","scoreFunction","bubbleUp","sinkDown","n","score","parentN","elemScore","child2N","child1N","swap","child1","child1Score","child2","PointCloudManager","clouds","visiblePointsTarget","maxUnloadedNodes","unloadedGeometry","maxUnloadedClouds","maxloadedToGPUPerFrame","loadedToGPUThisFrame","nodeCacheSize","exeLaunchTimeout","lastExeLaunched","performance","numLoadedPoints","numVisiblePoints","numSceneNodesVisible","minPixelPercent","transparency","rawJsonResponse","shouldUpdate","initScene","pointClouds","currentPointClouds","newPointClouds","pointCloudsToLoad","pointCloudsToDelete","numCloudsRemoved","numCloudsAdded","pointCloud","deletePointCloud","newPointCloud","cloudDetails","GenericPointCloud","EncompassPointCloud","PotreePointCloud","toggleVisibility","AmbientLight","updateMeasureList","controls","measurements","refreshMeasurementList","setVisibility","minimap","removeLayer","combinedBoundingBox","addLayer","getCameraTarget","StreamablePointCloud","tightBoundingBox","sampledPoints","setDrawRange","Points","drawRange","nodes","nodeMap","Map","visibleNodeTextureOffsets","offsetsToChild","Infinity","nodeIndex","parentName","parentOffset","parentOffsetToChild","lodOffset","offsetUint8","pointMarkup","clippingBoxes","numClipBoxes","clippingBox","hidePoints","updateClassification","newClassification","ignoredClassification","inverse","updateNumClippingBoxes","areaGeometry","getAreaGeometry","triangleIndex","volumeStatus","vertex1","vertex2","vertex3","updateNumAreaTriangles","getX","getY","getZ","pointsInPolygon","highest","keyfunc","samples","dtmPoints","sampled","updateProjectionMatrix","updateMatrixWorld","matrixWorldInverse","matrixWorld","cameraViewProjectionMatrix","multiplyMatrices","projectionMatrix","frustum","Frustum","setFromProjectionMatrix","stack","unusedNodes","streamingPointClouds","numberOfNodes","numberToDelete","reverse","numLoading","cloudsToExecute","genericPointClouds","canReadData","exeRunning","timeNow","launchExecutable","hideDescendants","cameraList","waitForCameras","calculateGenericVisibility","calculateStreamingVisibility","manageNodeCache","newNodes","intersectsBox","isGeometryNode","isTreeNode","addToScene","priorityQueue","weight","MAX_VALUE","maxAllowedPoints","maxNodeDistance","measurePoint","cameraPosition","minNodeSize","bounds2d","camera2d","childDistance","insideSphere","nodeScreenSize","updateMaterialValues","updateAreaTriangleTexture","updateClipBoxTexture","updateVisibilityTexture","getCameraFrustum","updateGenericPointClouds","updateStreamingPointClouds","loadUnloadedGeometry","launchNewExecutables","updateMaterials","updateCloudSampling","calculatePointsVisible","GenericPointCloudNode","_shift","num_points","bytes_path","xyz_min","xyz_max","addChildNode","offsetToScene","updateColorLimits","rgb_max","updateIntensityRange","intensity_min","intensity_max","updateBoundingBox","updateRootNode","setGeometry","updateClassifications","addCloudData","getBinaryData","getGeometry","GenericPointCloudRootNode","workerExe","cancelled","loadStart","timeEnd","byteCutoffSize","pointsDataParsed","numSampledPoints","minPointSize","updatePercent","elapsed","points_to_process","updateSizeInfo","addPointCloud","setIdentifier","fileLoadStart","fileLoadFinish","fileLoadCancel","parseHeaderResponse","parsePointsResponse","fileLoadFinished","isLargeFile","fileLoadProgress","loadFromData","zoomToSceneExtent","estimatedBoundingBox","sceneOffset","apply","maxs","mins","file_info","number_of_bytes","StreamablePointCloudNode","level","childName","childSize","childLevel","getChildOffset","childCenter","NodeConstructor","constructor","structure","metadataPath","metadata","decodeMetadata","EncompassPointCloudNode","getDataPath","nodePath","minCorner","corner","readNodeHierarchy","removeChildNode","hierarchy","EncompassPointCloudNodeV0","args","childIndex","getChildNode","EncompassPointCloudNodeV1","EncompassPointCloudNodeV2","hrcPath","updateHierarchy","isFolderRoot","loadHierarchy","folderDepth","dataDir","dirs","match","RegExp","hierarchy_step_size","point_offset","tight_bounding_box","nodeSize","hasHierarchyV1","checkLegacyHierarchy","hasHierarchyV2","contains_hierarchy","rootNode","availableNodes","node_structure","PointAttributeTypes","DATA_TYPE_DOUBLE","ordinal","DATA_TYPE_FLOAT","DATA_TYPE_INT8","DATA_TYPE_UINT8","DATA_TYPE_INT16","DATA_TYPE_UINT16","DATA_TYPE_INT32","DATA_TYPE_UINT32","DATA_TYPE_INT64","DATA_TYPE_UINT64","typenameTypeattributeMap","obj","PointAttribute","numElements","byteSize","description","initialRange","POSITION_CARTESIAN","RGBA_PACKED","COLOR_PACKED","RGB_PACKED","NORMAL_FLOATS","INTENSITY","CLASSIFICATION","NORMAL_SPHEREMAPPED","NORMAL_OCT16","NORMAL","RETURN_NUMBER","NUMBER_OF_RETURNS","SOURCE_ID","INDICES","SPACING","GPS_TIME","PointAttributes","pointAttributes","vectors","pointAttributeName","pointAttribute","DataView64","littleEndian","getBigUint64","getBigInt64","DataView","PotreePointCloudNode","nodeType","hierarchyByteOffset","hierarchyByteSize","byteOffset","attemptNumber","maxAttempts","hierarchyPath","parseHierarchy","bytesPerNode","numNodes","nodePos","getUint8","childMask","getUint32","getInt64","ArrayBuffer","octreePath","xyzScale","xyzCenter","xyzOffset","attributeBuffers","jsonAttributes","replacements","jsonAttribute","attribute","addVector","parseAttributes","bboxMin","bboxMax","xyzMin","xyzMax","firstChunkSize","CustomOrbitControls","domElement","keyPressed","walkMode","walkVelocity","walkRotation","Spherical","maxWalkSpeed","walkIncrement","walkPercent","walkPercentMin","walkPercentMax","oldRadiusState","focused","minDistance","maxDistance","minZoom","maxZoom","minPolarAngle","maxPolarAngle","minAzimuthAngle","maxAzimuthAngle","enableDamping","dampingFactor","enableZoom","zoomSpeed","enableRotate","rotateSpeed","enablePan","panSpeed","panningMode","keyPanSpeed","autoRotate","autoRotateSpeed","enableKeys","UP","BOTTOM","SPACE","PLUS","MINUS","NUMPAD_PLUS","NUMPAD_MINUS","WALK_FORWARD","WALK_BACK","WALK_RIGHT","WALK_LEFT","WALK_UP","WALK_DOWN","mouseButtons","target0","position0","zoom0","setControls","getPolarAngle","spherical","getAzimuthalAngle","clearSphericalDelta","sphericalDelta","clearPanOffset","panOffset","saveState","scope","resetWalkValues","incrementWalkSpeed","static","decreaseWalkSpeed","setWalkMode","quat","setFromUnitVectors","up","applyQuaternion","setFromVector3","activePosition","activeTarget","applyWalkOffset","scaleFactor","changeEvent","STATE","NONE","quatInverse","lastPosition","lastQuaternion","lastUpdated","changeDetected","rotateLeft","makeSafe","lookAt","setFromSpherical","distanceToSquared","EPS","dot","moveStopEvent","onMouseWheel","onTouchStart","onTouchEnd","onTouchMove","onMouseFocus","onKeyUp","startEvent","endEvent","ROTATE","DOLLY","TOUCH_ROTATE","TOUCH_DOLLY","TOUCH_PAN","rotateStart","rotateEnd","rotateDelta","panStart","panEnd","panDelta","dollyStart","dollyEnd","dollyDelta","getZoomScale","rotateUp","panLeft","v","objectMatrix","setFromMatrixColumn","panUp","crossVectors","pan","deltaX","deltaY","isPerspectiveCamera","targetDistance","isOrthographicCamera","dollyIn","dollyScale","dollyOut","switchTo","shiftKey","handleMouseDownRotate","handleMouseDownDolly","handleMouseDownPan","subVectors","handleMouseMoveRotate","handleMouseMoveDolly","handleMouseMovePan","handleMouseWheel","keyCode","handleKeyDown","handleKeyUp","touches","handleTouchStartRotate","handleTouchStartDolly","handleTouchStartPan","handleTouchMoveRotate","handleTouchMoveDolly","handleTouchMovePan","prototype","EventDispatcher","MarkerShape","parseHex","getClassFromAlias","classNum","getColorFromClassNum","hex","textToColor","rgbColor","textToColorArray","colorHash","createHash","digest","s","imageCache","processing","maxNumProcessing","maxCacheSize","mimeType","bypassQueue","lastAccess","waitForImage","loadToCache","removeOldData","missing","arrayBufferView","blob","Blob","blobPath","createObjectURL","loadImageFromPath","missingPanoramicTexture","noImagePanoramicPath","missingPlanarTexture","noImagePlanarPath","ImagePosition","_value","_euler","applyEuler","eulerCSV","toScene","ImageRotation","setRotation","adjustment","rotationWithTransform","multiplyRotations","rotationWithAdjustment","degrees","CameraImage","ctx","missingImageTexture","pixel","positionToCameraAngle","loadFromCache","setCameraPosition","setCameraParameters","loadImageData","setObjectVisible","generateObject","grabImageFromPath","angleEuler","tempRotation","Texture","setTexture","PanoramicImage","mouseControls","u","imageDirection","sphere","fromVectors","planarSize","plane","projectPoint","allX","allY","xMin","xMax","yMin","yMax","interpolated","xyz","xyzTemp","xyz1","nextIndex","xyz2","_x","_y","_z","interpTemp","xyzNoDups","previous","PlanarImage","normalize","outOfBounds","CameraList","mappingByID","mappingByName","aligned","newCameraLoading","cameraLoadedOnce","cameraHeight","cameraAdjustments","initEvents","camerasFiles","newCameras","currentCameras","camerasToLoad","camerasToDelete","numCamerasRemoved","numCamerasAdded","deleteCameras","addCameras","addCameraMarkers","updateArrowNavigation","incrementCamera","setOrbitValues","cameraImage","addedIndex","cameraConfig","cameraInfo","newCamera","getNewCamera","updateCameraMapping","toRemove","currentRemoved","remaining","removeCameraMarkers","setCurrentImage","cameraID","CameraObjectClass","setCorrectionMatrix","cameraName","csvEncompassOut","eulerDegrees","centerOnImage","setNormalCamera","setActiveCamera","cameraLoaded","setWaitForCameras","loadCameraData","clearImages","activateCamera","preloadNearbyImages","getCurrentCameraIndex","getNextCamera","previousIndex","getPreviousCamera","currentCamera","increment","nextCamera","loadImage","recalculateAllMarkers","elements","newMatrix","equals","applyMatrixToCameras","savedCameraState","savedcameraID","activeCamera","savedLookat","closestCameraID","closestCameraToPosition","cameraLoadOptions","bestDistance","rotationA","rotationB","matrixA","makeRotationFromEuler","matrixB","cameraPos","ContextMenu","newTagDialog","customLinks","modelProperties","setModelProperties","tagsToDelete","setTagsToDelete","tagCoordinate","setTagCoordinate","isAerial","labelData","selectedTags","modelData","sceneCoord","aerialCoord","clearCadHighlight","listItemSeperator","menuEvent","numLabelsSelected","numLabelsHighlighted","profileActive","pointProfileActive","labelSelected","labelID","labelPointSelected","pointID","hasLabelCoord","numTagsSelected","hasModelData","hasSceneCoord","hasAerialCoord","noTagSelected","oneTagSelected","pointProfileActions","pointProfileStart","pointProfileEnd","pointProfileCancel","tagActions","orbitModeActions","hasPoints","cameraSelected","toggleOrbitState","resetCamera","modelActions","labelActions","anyLabelSelected","deleteHighlighted","deleteLabelPoint","unHighlightAll","insertLabelPoint","editLabel","moveToLabel","customUserActions","showInAerial","showInScene","urlString","constructCustomURL","hasCustom","onEnter","clearTooltipText","ModelProperties","showContextMenu","contextData","card","cardHeader","cardButtons","alignSelf","headerTitle","cardContent","EditLinkDialog","setUrl","setTarget","setShowInScene","setShowInAerial","addNewLink","CustomLink","editDialog","handleDownload","Card","CardHeader","titleTypographyProps","subheader","subheaderTypographyProps","CardContent","CustomContextURL","newURLDialog","handleImport","importURLData","OperationType","BasemapLayer","Tile","BaseCameraFeature","cameraCSV","PanoramicFeature","PlanarFeature","TagFeature","ViewTriangle","aerial","generateSource","Fill","ring","generateMarkerCoordinates","getTargetElement","coneAngle","axis","coneLength","getView","getResolution","v0","v1","v2","setVisible","changeDetector","rotateViewMarker","AerialMap","containerElement","orthoList","triangle","maxLayerZoom","maxMapZoomLevel","maxCameraZoomLevel","styleCache","pointsSource","clusterSource","clusterLayer","activeCameraLayer","clusterDistance","clusterCircleSize","camerasToIterate","maxIterationTime","calculating","observer","mapSystem","initMap","initResize","initDataLayers","OrthoMosaicList","setCenter","setZoom","setVisibleBasemap","attribution","Attribution","collapsible","defaultLayers","defaultControls","extend","View","resetView","onresize","handleWindowResize","onMapClick","bind","onDoubleClick","updateSavedState","un","Cluster","clusterStyle","Point","styleGenerator","Circle","orthoLabels","localAligner","aerialTags","hovering","getFeatureForEvent","currentView","maxZoomReached","getZoom","selectedTagID","selectedCameraID","getCoordinates","boundingExtent","mapSize","fit","nearest","clearAerialTooltip","isLeftClick","isRightClick","openContextMenu","onMouseMoveAerial","setAerialState","anyToolEnabled","mapCoordinate","getCoordinateFromPixel","getFeaturesAtPixel","reduce","updateSize","getInteractions","interaction","DragPan","setActive","getExtent","setMapExtent","calculatingSceneMarkers","cameraIndex","numToIterate","camerasCalculated","timeStart","addFeatures","centerOnImages","remainingCameras","remainingFeatures","shape","strokeColor","fillColor","Square","RegularShapeStyle","CircleStyle","Text","numSquares","numCircles","basemapID","basemapLayers","mapPosition","getSource","getFeatures","setStyle","jumpToPosition","removeEvents","calculateCameras","arcGISBase","OSM","XYZ","attributions","scrollWidth","uniqueIDs","getLayers","getArray","getVisible","activeBasemap","getCenter","imageLabels","aerialController","extentFromPoints","reproject","xPositions","yPositions","OrthoImageLayer","ImageLayer","orthosList","aerialBounds","splitData","cropBase64","cropCorners","calculateCroppedData","calculateExtent","calculateAerialPolygon","addMapLayer","aerialMap","transformExtent","imagePixelsToAerial","cornerPixels","proj4Projection","index_start","index_end","width_start","width_end","height_start","height_end","extentWidth","extentHeight","subtileCorners","aerialPoints","turfIntersect","turfPolygon","aerialToImagePixels","coordinatesTransformed","coordTransformed","allLayers","numSubtiles","Static","imageExtent","interpolate","imageLoadFunction","getImage","ortho","addImageChunk","LayerGroup","setOpacity","zoomToExtent","dataProjectionName","x_scale","y_scale","x_offset","y_offset","x_skew","y_skew","originalSize","orthos","maxAsyncLoad","chunksLoading","chunksToLoad","orthoID","loadAvailableData","orthoFiles","currentOrthos","newOrthos","orthosToLoad","deleteOrtho","orthoInfo","addNewOrtho","loadable","toLoad","projected","ImageLabel","category","completed","drawable","highlighted","textScore","findText","duplicatePixelDistance","stateChanged","draw","complete","highlight","coordArray","oldPoint","newPoint","screenPosNew","pointToScreen","screenPosOld","dU","dV","LabelCategory","listIdx","labels","invalidLabels","sorted","originalOrder","getLabelByID","drawLabel","createCoordData","idxCoord","minDistanceIdx","insertPoint","endIdx","createSegment","closestPointToPointParameter","labelIDs","deleteLabel","setHighlighted","updateColor","hasEnoughPoints","unSelect","scoreThreshold","allLabels","order","unsortedLabels","ImageLabelTools","sceneLabels","activeLabeler","categories","setCategoryList","setTrainingArea","currentCategory","allowUpdate","AerialLabelTools","SceneLabelTools","setCategories","validCategory","categoryID","setFindText","getCategoryByID","activeLabel","which","completeLabel","deletePoint","addLabel","deleteAllCategories","setDragState","activeImagePaths","activeImages","loadedImagePaths","trainingArea","sortType","categoryToSort","getCategoryByName","unSelectAll","sortLabels","drawAll","undoSort","getNewCategory","getNewTrainingArea","updateName","deleteCategory","deleteTrainingArea","addNewLabel","unSelectLabels","selectLabel","coord","unHighlight","clearTooltips","deleteSpecificPoint","zoomToLabel","deleteLabels","isTrainingArea","resetTemporaryPoint","moveToLabelInList","simplePolygon","tolerance","highQuality","simplified","turfSimplify","labelsToMerge","mergedLabels","firstLabel","isPlanarImage","isPanoramicImage","mergeLabel","points1","points2","point1","index1","matchFound","point2","index2","polygonPoints1","polygonPoints2","union","turfUnion","addPoint","remainingLabels","mergeTrainingLabels","simplifyPolygon","bufferSize","geomJSTS","GeoJSONReader","BufferOp","bufferOp","hasOverlap","visibleOrthos","intersectAerialPoints","polygonPointsOnly","images","progressData","addedLabel","image_id","segmentation","minPoints","is_linestring","is_point","skippedLabels","lineGeom","turfLineString","geometryWithBuffer","buffer_size","pointGeom","turfPoint","linework_data","getByName","file_name","pointsToPixels","newLabel","addTrainingAreaLabel","setScore","setCamera","setKnownImageSize","importLabel","labelTotal","labelIndex","progress","mergeID","merge_id","newCategory","checkOverlap","checkForImageOverlap","clearViewerTooltip","progressCallback","overwrite","annotations","hasTrainingArea","numLabelsTotal","setUpdateState","trainingAreaCategory","addTrainingArea","addCategoryLabels","trainingAreas","mergeList","newLabels","category_id","addCategory","checkLabelOverlap","simplifyPanoramicLabels","checkLabelInvalid","setDrawable","supercategory","getLabelAnnotations","getTrainingAnnotations","jsonImageObj","numHighlighted","sectionsFromIntersection","intersection","removeDuplicate","sections","intersectPoints","annotationFromPolygon","imageID","segment","boundBox","area","areaFromPolygon","findTextNum","iscrowd","contour","ShapeUtils","shortestDistance","closestPoint","idx","closestPointToPoint","P1","P2","startPoint","endPoint","Line3","LabelPoint","LabelPolygon","OrthoLabel","minCoordinates","featureStyle","editingStyle","checkDefaultStyle","defaultStyleParams","styleKey","getLayerStyle","getPixelFromCoordinate","checkDuplicate","duplicatePoint","newCoord","temporaryPoint","completedSource","editingSource","validPolygon","drawPoints","drawPolygon","setFeatureStyle","sources","hasFeature","removeFeature","featuresLayer","editingLayer","getLayerFromCache","OrthoCategory","aerialTools","addMapLayers","pointColor","categoryColor","TrainingAreaCategory","lineDash","darkenedColor","VectorImageLayer","updateWhileInteracting","updateWhileAnimating","imageLabelTools","clearStyleCache","TrainingAreaLabel","aerialToPixels","setPointDelete","setPointAdd","polygonHover","pointHover","calculatePolygonPixels","pixelPolygon","pixelPoint","trainingLabels","trainingLabel","trainingLabelIndex","polygonsInsideImage","markLastPointDraggable","updatePoint","pointFeatures","lastPoint","setPointHover","setToolTipText","setPointGrabTooltip","canDrag","drawActiveLabel","dragging","checkFeatureHover","updateDraggablePoint","setPolygonHoverTooltip","drawing","cancelLabel","onRightClick","oneHighlighted","noneHighlighted","ctrlKey","highlightLabel","MouseEvent","selectedPoint","getFeatureAtPixel","pointFeaturesForExtent","selectedPolygon","polygonFeaturesForExtent","setPolygonHover","mousePixel","mouseCoord","mouseBuffer","values_","pointExtent","intersectsCoordinate","pointRadius","helpMsg","startTooltip","moreTooltip","invalidTooltip","setAerialTooltip","dragTooltip","highlightTooltip","removePoint","removeSpecificPoint","imageIndex","orthoName","boundsToCheck","boundsPolygon","labelPolygon","pointCount","getFeaturesInExtent","isValid","RayCaster","raycaster","vectorFromEvent","defaultRaycaster","threshold","intersect","ray","intersectPlane","intersectObject","P3","intersectTriangle","sortByRay","recursive","objects","intersectObjects","distanceToRay","raycastDirection","vec","unproject","Raycaster","_direction","_position","pixelToDirection","SceneLabel","_imageWidth","_imageHeight","standardMeshes","opacityMeshes","sphereGeometry","SphereGeometry","sphereMaterial","lineGeometry","lineMaterial","lineDashedMaterial","polygonMaterial","minPoleAngle","standardColor","LineDashedMaterial","dashSize","gapSize","computeBoundingSphere","standardScene","setPointScale","setFromPoints","Line","computeLineDistances","pixels","coordinates3d","directionsToPlanar","oldState","coordinates2d","polygonAtPoles","coordinatesFlat","earcut","deviation","numTriangles","Triangle","getMidpoint","setIndex","opacityScene","drawLines","drawPolygons","pointsAtPole","minAngle","maxAngle","polyPointRing","booleanContains","averageDirection","fovRequired","getCurrentCamera","getCameraBestFit","SceneCategory","numberOfLabels","getClickedDirection","directionToPixel","getImagePixel","labelPoints","targetPoly","polygons","setViewerTooltip","mouseMoved","mouseClick","imageBorders","horizontalShift","getHorizontalShift","interpolatePixels","imageBordersLeft","imageBordersRight","polygonLeft","polygonRight","intersectionLeft","intersectionRight","minSpread","widthCutoff","xValues","minX","maxX","shiftedMin","shiftedMax","spread","calculatePlanarSections","calculatePanoramicSections","visibleCameras","getCameraSize","mergeIndex","polygonsInside","polygonInImage","mergeable","deleteUnfinishedLabel","visited","ScaleHandle","PlaneGeometry","minusPoint","lineStart","lineEnd","camOnLine","setFromNormalAndCoplanarPoint","intersectOnLine","setScale","newScale","RotateHandle","ordering","zAxis","xAxis","newAxis","cross","PositionHandle","getPickerResults","ClippingBox","operationID","wireframe","positionHandle","scaleHandles","rotateHandles","wireframeMaterialStandard","wireframeMaterialHover","addWireframe","addScaleHandles","addRotateHandles","addPositionHandle","wireframeMaterial","edgeMesh","xAxisMaterial","xAxisGeometry","yAxisMaterial","yAxisGeometry","yAxis","zAxisMaterial","zAxisGeometry","intersects","raycast","parentScale","objectScale","highlightScale","setFromObject","Group","ClippingGroup","markupList","isDelete","isClassify","setHover","axisOffset","smooth","dz","Classify","Split","PointMarkupList","setMarkupGroups","mouseEvent","shiftDown","dragObject","clippingGroups","clippingGroup","refreshMarkupList","group","newGroup","enable","disable","resetRotation","removeByID","setNewClassification","setIgnoredClassification","cameraAngle","newBoxScale","setScalar","activeGroup","setMovementState","containsPoint","handleOverride","isPosition","isRotation","setDragObject","addNewBlock","clearNewBlock","rotateTooltip","moveTooltip","scaleTooltip","standardTooltip","drag","getDragObject","isFirstTouch","numTouching","pinchStart","Chart","zoomPlugin","line2D","line3D","lineWidth","hoverColor","markerSize","ProfileChart","initSphere","clearScene","updateUniforms","hideSphere","updateCrossSection","localPosition","setZ","updatePoints","resetZoom","pointsInRadius","linePoint","validWidth","distanceAlongLine","validDistance","show","distanceClamped","at","updateUnits","updateSampling","chartImageBase64","toBase64Image","pointProfile","sampleMinimum","sampleMaximum","chart","setPointProfileOpen","scales","ticks","output","plugins","caretPadding","displayColors","callbacks","dataIndex","drawSphere","raw","legend","mode","wheel","pinch","datasets","pointHoverBackgroundColor","pointHoverBorderColor","onHover","showSphere","maintainAspectRatio","animation","animationDuration","responsive","responsiveAnimationDuration","updateChart","getSampledPoints","needsSampling","getSampledData","chartTitle","PanoControls","cameraAlignerAdv","cameraAlignerBasic","hammer","flyControls","Hammer","OrbitController","FlyMoveControls","MouseControls","CameraAlignerAdv","CameraAlignerBasic","LocalAligner","onMouseDoubleClick","touchHandler","touchEvent","changedPointers","bubbles","cancelable","screenX","screenY","altKey","metaKey","onDoubleTap","down","updatePickers","newOrbit","newPivot","smoothTransition","rotateLength","setPositionValues","controller","setMeshVisible","updateCamera","getClosestCoordinate","sceneTags","cadHandler","combinedBounds","orbitFromBounds","boxSize","boxMean","boundSize","orbitWithAngle","fromValues","initialEvent","scrolling","clearCoordinates","updateCoordinates","onMouseMoveScene","compass","movement","updateRotation","measureGrabFinished","toggle","mouseClicked","onMouseScroll","currentOrbit","getProperties","orbitObject","pivotLength","approxDistance","getCameraDistance","defaultFarPlane","changedTouches","eventType","pinchMove","sign","touchToMouse","move","sceneViewController","panoControls","numberOfSteps","sphereStart","sphereFinish","dRadius","dPhi","dTheta","currentPivot","getAngleDiff","dPivot","pivotOffset","TextMaterial","MeshPhongMaterial","CompassControls","composer","antialias","sizeRatioLarge","sizeRatioSmall","alphaTest","lightPosition","cube","cubeSize","cubeColorStandard","cubeColorHover","cubeEdgeColor","cubeTextColor","cubeMaterials","donutSize","donutColor","donutTextColor","north","west","east","south","compassClassName","initAntiAliasing","addObjects","addLights","WebGLRenderer","alpha","setPixelRatio","PerspectiveCamera","cameraDistance","EffectComposer","ssaaRenderPass","SSAARenderPass","unbiased","sampleLevel","addPass","copyPass","ShaderPass","CopyShader","addRotationCube","addCompassRing","addCompassLetters","ambientLight","spotLight","SpotLight","castShadow","cubeGeometry","BoxBufferGeometry","getTextMaterial","donutGeometry","donutMaterial","getCircleMaterial","letters","letter","getDirectionMesh","canvasSize","maxLength","fontScale","cubeColor","fillStyle","fillRect","font","fillText","strokeStyle","strokeText","beginPath","textHeight","geometryUpper","materialUpper","getLetterMaterial","FrontSide","meshUpper","geometryLower","materialLower","BackSide","meshLower","checkMouseHover","getSelectedSide","togglePointer","offsetLeft","offsetTop","mouse","setFromCamera","materialIndex","faceIndex","setCubeMaterials","hoverIndex","pointA","pointB","zenith","startLat","destLat","startLng","destLng","brng","ratio","setContainerCursor","lookatLocal","lookatLonLat","yPosLocal","yPosLonLat","cameraLocal","cameraLatLon","groupYaw","bearing","groupPitch","rotateLetters","cubeYaw","calculateRotations","minimumFOV","maximumFOV","phiDelta","thetaDelta","wheelDelta","wheelTimeout","wheelDelay","endTimeout","endDelay","rotating","zooming","moveInterval","moveStart","moveEnd","moveDelta","moveDistance","lastMovement","maxPixelDistance","minFOV","maxFOV","getCustomEvent","invertX","invertY","newEvent","updateCameraMatrix","MultiImageWindow","cameraScene","objectScene","renderUtils","imageRenderMaterial","imageRenderTarget","setMultiImageOpen","setMultiImageState","tools","onComplete","onAddMore","closePrompt","intersectResponse","canComplete","canAddMore","disablePreviousImage","disableNextImage","disableAddMore","disableComplete","initRenderer","initMaterials","initMouseEvents","MultipleCameraMeasurement","calculate","newIndex","loadCamera","CameraConstructor","resetSecondObservation","updateIntersect","resetObservations","autoClear","addSecondObservation","getClickedPoint","resetFirstObservation","addFirstObservation","aspect","clearDepth","renderScenes","renderPanoramic","renderSceneObjects","offsetWidth","firstPoint","secondPoint","rayA","rayB","sameCamera","getIntersection","defaultResponse","distances","calculated","setButtonDisabled","viewerScene","windowScene","getEndpoint","getSphereMesh","updatePointScale","viewerCamera","windowCamera","Nv","Na","Nb","Da","Db","da","db","ptA","ptB","lineSegment","segmentLength","midPoint","d1n","d2n","a1","a2","origin1","origin2","CameraMarkers","arrowNavigation","markerNavigation","navigationType","modifier","initKeyDown","MarkerNavigation","ArrowNavigation","drawCameraMarkers","isArrows","loadSectionsToCache","updatePicker","updateNavigation","clearNavigation","isOrbitMode","isHidden","isMarkers","setEnabled","markerMesh","pickingMesh","standardMaterial","pickingMaterial","verticesPerCamera","uvs","selectedID","markerPositions","initGeometry","Int32Array","markerShape","cameraIndices","cameraShape","numUvs","uvIndex","numVertices","updateGeometry","markerID","meshes","camera_index","marker","numCorners","cornerIndex","arrIndex","cameraPickerID","markCameraSelected","ArrowMarker","section","Object3D","addMesh","geometryStandard","materialStandard","userData","numSections","defaultScale","zoomedScale","loadTextures","initMeshObject","sectionToAngle","arrowPathStandard","arrowPathShadow","validCameras","markerPos","tooClose","tooFar","angleToSection","getIntersect","sectionID","Measurement","_header","_title","timeCreated","isoTime","getTime","Measurement3D","maxVertexLength","minVertexRequired","Length","setHeader","finished","addedPoint","added","MeasurementArea","ignoreHeight","vertexA","vertexB","getLineDistance","lastIndex","NaN","atan","rise","distance2D","StationMeasurement","Station","stationStart","clickedPoint","curveIntersect","x1","x2","x3","y1","y2","y3","distEndsSquared","crossProduct","dotProduct","segments","minDist","chosenSegment","segmentTest","lineIntersect","intersectCoordinate","clickedCoordinate","startCoordinate","checkOnly","unshift","sideValue","Center","pointVector","startVector","endVector","pointArc","distStartToArc","angleStart","angleEnd","angleLarge","angleSmall","angleSmallQuadrant","angleLargeQuadrant","angleQuadrant","angleReverse","spiralIntersection","clickPointInData","alignmentInfo","xmlAlignment","isBetween","getClosestSegment","measurement","along","across","station","activeAlignment","getAlignmentByID","MeasurementLine","cancelMessage","MeasurementPoint","surfaceGenerator","Area","SurfaceGenerator","generate","MeasurementVolume","volumeHelper","Volume","setSampleRate","sampleRate","renderMeasurement","stopCalculation","VolumeHelper","setVolume","destroyWorker","calculatingVolume","HeightMeasurement","vertex0","SnapMeasurement","snapResult","snap","snapCoordinate","finalHeight","validHeights","pos","heights","SnapDownMeasurement","acc","curr","SnapUpMeasurement","AerialMeasurement","AerialLengthMeasurement","LineString","getLength","AerialAreaMeasurement","getArea","sigma","numNeighbours","initWebworker","rate","getCalculatedBounds","calculateVolume","zMin","zMax","terminate","triangles","volume","tri","p1","p2","p3","signedTetrahedronVolume","v3","final","validTriangles","reverseWinding","delaunay","Delaunator","generateTriangleArray","removeInvalidTriangles","denseBounds","getDensePolygon","removeOutliers","calculationFinished","webWorkerFinished","pointsArray","upperPoints","trianglesUpper","getDelaunayTriangles","lowerPoints","trianglesLower","trianglesCombined","getVolume","drawMesh","changeRequired","renderInScene","removeMeshesFromScene","triangleIndices","verticesModified","numIndices","triIndexA","triA","triB","triIndexB","vertSet","allVerts","sharedVerts","uniqueVerts","modTriA","modTriB","t1","t2","oldArea","t3","t4","newArea","optimize","triVertices","generateMesh","addMeshesToScene","calculateArea","densePolygonTemp","vectorLength","directionIncrement","densePolygon","old","MinimapMeasure","mapSource","mapLayer","styleHover","styleDefault","drawStyle","measurementType","sketch","tempTooltips","addInteraction","mapElement","reloadInteraction","removeInteraction","tooltips","getTooltipsForGeometry","removeOverlay","validMeasureType","objectMessage","objectPosition","getSegmentInfo","addNewTooltip","innerHTML","formatLength","getLastCoordinate","hasEnoughSegments","formatArea","getInteriorPoint","clearTempTooltips","listener","editable","Draw","drawingType","originalEvent","unByKey","addAerialMeasurement","alternateColor","Overlay","positioning","addOverlay","index0","getDistance","MeasurementConstructor","measureType","isFinished","measureAssets","builderType","getEmptyMeasurement","setController","SnapUp","SnapDown","MeasurementController","measurementSceneView","measurementAerialView","measurementBuilder","measurementGroupExporter","measurementGroup","setMeasurements","MeasurementFormatter","MeasurementSceneView","MeasurementGroupExporter","MeasurementGroup","xmlFiles","currentAssets","measurementAssets","newAssets","assetsToLoad","xml","assetToDelete","updateMeasureAssets","xmlFile","loadMeasureAsset","createNewMeasurementGroup","removeAll","stopDrawingItems","multiImageWindow","removeIDs","deletable","alignUnits","linearUnit","loadMeasurements","temporaryMeasurement","activeMeasurement","multiImage","isSinglePoint","cancelMeasurement","onClickFinish","canFinish","hoveredPoint","getCoordinate","addTemporaryPoint","updateMeasureText","addSceneMeasurement","measuring","isImageOnly","clickMultiImage","clickStandard","getMeasurement","generateSurface","enableTimeout","removeTemporaryObjects","measureEndpoints","MeasureEndpoint","measurementID","checkMorePoints","morepoints","setTooltipText","setMeasurementType","setBuilder","clearViews","exportCSV","exportDAT","exportLinework","setUnits","refreshVolume","stopVolumeCalculation","emptyValue","metersCutoff","squareMetersCutoff","formatterPrecision","vectorPrecisionLonLat","vectorPrecisionStandard","TypeError","finalValue","metresToFeet","isSurveyFeet","feet","inches","metresToMiles","metresToKiloMetres","cubicMetresToCubicYards","squareMetresToSquareMiles","squareMetresToSquareFeet","squareMetresToSquareKilometres","nullValue","maxGrade","isFinite","distanceAlong","lengthUnits","alongFinal","stationFinal","imperial","feetToMetres","stationNumber","stationAlong","stationTotal","distanceAcross","sideOfSegment","precisionX","precisionY","precisionZ","isMetric","isSurveryFeet","metres","squareMetres","val","cubicMetres","metresToYards","getDataExport","temp3DMPath","handleExport3D","handleExport2D","getExportRows2D","getExportRows3D","measurements2D","measurements3D","vertextView","time_created","measureCsvOut","mapProjection","getHeaderValues2D","convertUnits","area2d","getHeaderValues3D","distance3D","formatGrade","grade","formatAngle","formatStation","formatOffset","areaValue","volumeValue","area3D","areaInvalidMessage","invalidVolumeMessage","areaUnits","volumeUnits","measurementVertices","updateMeasurements","removeFromArray","measure3D","newMeasurement","setTimestamp","loadExistingVolume","loadExistingStation","measure2D","loadFromCoordinates","timestamp","resetDragObject","lines","names","getProjectedVertices","areaMeasurements","measureGeometry","surfaceVertices","surfaceIndices","alternateAnnotationColor","measurementVertex","boundingSphere","intersectsSphere","TemporaryEndpoint","sphereBuffer","sphereMaterialStandard","sphereMaterialHover","lineMaterialStandard","lineMaterialHeight","lineMaterialHover","temporaryEndpoints","temporaryLines","temporaryAnnotations","dragValid","checkEndpointSelected","addActiveEndpoint","updateMeasureEndpoint","vertexIndex","setRestrictedPointTooltip","restrictedTooltip","endTooltipCount","moreTooltipMulti","endTooltipMulti","endTooltip","startTooltipMulti","createTempEndpoint","removeObjects","removeAnnotations","drawAnnotations","useAlternate","defaultMaterial","pointMaterial","posScene","createEndpoint","createLine","firstPointHigher","line0","line1","totalLength","fromBufferAttribute","addVectors","isHeight","lastLines","annotationStyle","hasEnoughLines","formatVolume","oldMeasurement","removeMeasurement","geometryWithIndex","pickerGeometry","copyGeometryValues","pickerMesh","getBasicPicker","getCustomSpritePicker","GPUPicker","debug","_needsUpdate","oldClearColor","newClearColor","LinearEncoding","clearSections","tX","tY","sectionWidth","sectionHeight","sectionX","sectionY","sectionIndex","pixelIndex","startX","startY","pixelBuffer","readRenderTargetPixels","time","mouseResult","pickerID","updateBaseIDs","oldRenderTarget","getRenderTarget","getClearColor","oldClearAlpha","getClearAlpha","setClearColor","setClearAlpha","currentBaseID","gpuIndex","getSelectedObject","getObjectPosition","minIndex","maxIndex","coordinateFromMesh","coordinateFromLine","trianglesToCheck","faces","face","isFirstPoint","Stats","addPanel","dom","showPanel","cssText","beginTime","prevTime","frames","fpsPanel","Panel","msPanel","self","memory","memPanel","REVISION","begin","usedJSHeapSize","jsHeapSizeLimit","setMode","fg","bg","PR","devicePixelRatio","WIDTH","HEIGHT","TEXT_X","TEXT_Y","GRAPH_X","GRAPH_Y","GRAPH_WIDTH","GRAPH_HEIGHT","textBaseline","globalAlpha","GeomType","TagMesh","TagPosition","TagItem","TagFile","visibleChanged","textureChanged","newTagIDs","currentTagIDs","tagsChanged","TagController","tagState","updateTagData","SceneViewTags","AerialTags","allTags","tagName","tagCsvOut","hasHeight","setMaxDistance","tagFiles","currentFiles","newFiles","filesToLoad","filesToDelete","deleteFile","addNewFile","updated","boundingBoxForTags","tagController","pickingMeshes","sceneViewTags","visibilities","gpuIndices","cornerNumber","tagIndex","tagMaterial","standardMesh","numberOfTags","arrayIndex","tagFromPickerIndex","markTagSelected","baseIndex","newSelectedID","getTooltipText","getClusterStyle","tagScale","texturePaths","mostFrequent","combinedStyles","anchorXUnits","anchorYUnits","LocalObservationTypes","validGeomTypes","pointTexture","spritePath","WebGLLayer","symbol","symbolType","generateStyle","WebGLVectorLayerRenderer","LineworkPoints","LineworkLine","LineworkText","lineThickness","borderThickness","SpriteMaterial","Sprite","addLevel","moveTo","lineTo","quadraticCurveTo","closePath","numLines","textWidth","measureText","xScale","textScale","flipY","generateTexture","LOD","LineworkLayer","mapLayers","getCoordinateArray","segmentInfo","geomType","addTextData","addSceneData","addAerialData","shpMesh","meshColor","reprojected","geometries","Polygons","polygonRings","numFaces","MultiPolygon","Lines","startIndex","mapCoordinates","endIndex","MultiLineString","setFeatureColor","bufferGeometry","bufferIndices","getLineIndices","geomIndex","styleColor","withOpacity","LineworkFile","LineworkHandler","FileConstructor","updateProperties","modelFiles","ifc","SHPFile","DXFFile","getCurrentLevel","updateTexture","loadNextfile","updateMeshes","CADHandler","ifcHandler","shpHandler","dxfHandler","IFCHandler","SHPHandler","DXFHandler","handlers","clearHighlight","ifcFiles","reconcile","IFCFile","shpFiles","dxfFiles","numberOfFiles","colorWithOpacity","olColor","useWebWorkers","highlightMaterial","IFCLoader","initManager","parseFromBuffer","manager","ifcWorker","handleResponse","modelID","ifcAPI","GetCoordinationMatrix","coordinationMatrix","workerPath","wasmPath","setWasmPath","applyWebIfcConfig","COORDINATE_TO_ORIGIN","USE_FAST_BOOLS","setOnProgress","total","ifcMesh","removeSubset","expressID","getExpressId","getItemProperties","attributesToProperties","subsetMesh","createSubset","ids","removePrevious","removeMapLayer","ifcManager","selectedFile","SHPLayer","addLayers","shpPath","shp","layerNames","validBounds","layerName","addNewGeometry","newLayer","DXFLayer","parseFromText","WebSourceList","webSources","currentSources","newSources","sourcesToLoad","webSource","deleteSource","addNewSource","newSource","getNewSource","projectionToEsriSRID","getCode","WebSource","webmapHandler","clearable","removeOnClear","visibleIdentifier","newIdentifiers","clearLayers","generateLayers","identifiers","removeLayers","FeatureVectorSource","tileGrid","createXYZ","tileSize","strategy","getExtents","prevResolution","onResolutionChange","getZForResolution","fromUserResolution","tileRange","getTileRangeForExtentAndZ","fromUserExtent","extents","minY","maxY","tileCoord","getTileCoordExtent","toUserExtent","newFeatures","featureID","getId","oldFeature","getFeatureById","FeatureWebSource","controllers","cancelRequests","clearLoadedExtents","abort","loadedExtentsRtree_","TileArcGISRest","crossOrigin","LAYERS","featureCount","advancedQueryCapabilities","supportsPagination","supportsQueryWithResultType","supportsQuantization","supportsCoordinatesQuantization","spatialReference","wkid","xmin","ymin","xmax","ymax","esriResponse","setLayerVisible","getCapabilities","getNumberOfFeatures","vectorSource","getProjection","createStyleFunction","styleFunction","geometryType","rings","resultOffset","srid","isComplexLayer","extendBounds","quantizationParameters","originPosition","AbortController","fetchError","signal","reconstructQuantizedGeometry","EsriJSON","readFeatures","featureProjection","updateFeatures","exceededTransferLimit","newResultOffset","TileWMS","geomExtent","serverResponse","GeoJSON","optionsFromCapabilities","matrixSet","TileLayer","WMTS","Viewer","viewContainer","mapContainer","defaultNearPlane","updateMouseCoords","isEmpty","drawPickerScene","initialZoomApplied","initialStateApplied","timingDebug","estimateLocalTransform","getLocalProjection","clearLocalTransformErrors","resetErrorValues","sortCategory","labelObject","getOrthoLabelPolygons","isAerialLabels","checkIfSelected","getCameraFeaturesForCSV","getByCSV","getRowsCSV","initGpuPickers","Tags","StatsPanel","addContainerElements","animate","customStyle","div","onclick","clamp","updateClamping","colorMapKey","toggleCamera","removeContainerElements","setDataProjection","setViewProjection","setActiveAlignment","setInitialZoomFlag","loadSavedCameraState","hasModels","hasTags","drawObservations","numRows","addNewObservations","setActiveObservation","addNewGroup","removeClippingGroup","removeClippingBox","loadNextImage","loadPreviousImage","selectStart","selectEnd","selectCancel","getProfileImage","export","loadMeasurementData","loadImageLabelData","setActiveLabelType","editCategoryName","currentCategoryName","getIdxInList","categoryName","checkUniqueName","headerFileInfo","tagFile","tagBBOX","clearErrors","cameraAngles","flashObservations","setCurrentObservation","updateOffset","folderPaths","previousCSV","reconcileXMLs","applySavedTagState","allCameras","numCamerasChanged","setOrbitCamera","resetSceneView","clearArrowNavigation","preloadBookmarks","getTagByID","hasCameras","setCameraHeights","setCameraAdjustments","setCameraMatrix","redrawImageObsMarkers","resetCameraMatrix","resetInitialFlag","setOrbitState","setCameraState","setTagState","logarithmicDepthBuffer","powerPreference","renderInFront","toolScenes","withTiming","scenePos","isBehindCamera","updateSceneElements","renderPickerScene","showCompassElement","requestAnimationFrame","getPositionValues","nodesVisible","pointsVisible","getElementsByClassName","drawExpandedState","indexToShow","childCount","timeElapsed","preview","EmptyBasemapIcon","aerialGradient","backgroundImage","LayerPreviewIcon","previews","LayerSwitcher","setAnchorEl","Boolean","basemapIDs","currentTarget","containerLarge","offsetLarge","containerSmall","offsetSmall","borderTop","compassElement","ViewSwitcher","SceneViewer","setLocalObservations","setAlignerObservations","viewerRef","aerialRef","viewerSwitched","savedAerialState","viewerTooltipLines","setViewerTooltipLines","aerialTooltipLines","setAerialTooltipLines","cameraState","viewerGradient","handleSwitched","addAllAssets","assetList","viewerAssets","reconcileAssets","setEmptyProject","handleHashUpdate","setWindowHash","resetDefaultAerialCamera","resetDefaultControlState","setProjectName","removeInteractions","onhashchange","modifiedSceneState","modifiedAerialState","handleHashChange","newURL","updateVolumeType","updateVolumeSampleRate","viewerProps","viewerObj","defs","refreshLocalTransform","cancel","mapClasses","viewerClasses","classLarge","classSmall","getClasses","setObservations","observations","imageObsInterval","pointObsInterval","observation","imageMesh","pointMesh","refreshObservationList","numObservations","imageObs","imageHidden","imageSelected","pointObs","pointHidden","pointSelected","imageIdentifier","pose","pointIdx","imageIdx","cancelAlignment","currentRow","imageDir","addImageObservationMesh","addPointObservationMesh","selecting","observationType","observationToAdd","clickScene","clickImage","resetSelectedState","updateAllMeshes","pointObsColor","PointObservation","imageObsColor","ImageObservation","defaultColor","numberOfFlashes","setHex","flashColor","clearFlashIntervals","flashObservation","obs","rotations","meshPos","eulerCsvInvert","currentID","updateAlignment","applyTempRotation","aerialObsColor","LabelImportType","activeObservation","filled","latlon","average","local","drawPointObservations","drawAerialObservations","isSceneObs","isAerialObs","clearActiveObservation","onSceneClick","sceneTooltip","aerialTooltip","Aerial","aerialObservationSuccess","imageObservationSuccess","pointObservationSuccess","errorLow","errorMedium","errorHigh","PointObservationIcon","ObservationIcon","AerialObservationIcon","ImageObservationIcon","buttonColor","clicked","ObservationError","lowCutoff","highCutoff","minHeightContent","toggleOptionParent","toggleOptionCheckbox","toggleOptionFlex","userWarning","selectMargin","checkboxPadding","ResidualError","ImageAlignerAdvanced","alignerAdvDialog","removeDialog","setCalculating","alignerMatrixPath","setAlignerMatrixPath","setClosePrompt","alignPosition","setAlignPosition","alignRotation","setAlignRotation","newRotation","setNewRotation","newOffset","setNewOffset","observationsCSV","tmpObservationPath","encompassCSV","tmpEncompassPath","observationsCSVContent","encompassCSVContent","runCalculation","isConverted","largeResiduals","camPoseEntry","initialPath","nameCorrection","correctionName","correctionPath","residualsTemp","parseResiduals","setErrorsCameraAligner","resArray","res","rounded","clearErrorsCameraAligner","isTableEmpty","removed","noCameras","toggleCameraAligner","generateAdvancedAlignerRows","imageClicked","pointClicked","img_obs","pc_obs","hasAdvancedAlignment","hasAlignment","requiredRows","camID","deleteRowCameraAligner","titleTop","AlignerShortcuts","ImageAlignerBasic","alignerBasicDialog","singleAlignment","setSingleAlignment","hasActiveCamera","setBasicAlignerState","savedAngle","getBasicAlignerValue","activeCameraName","isModified","epsilon","checkDataModified","transformInfo","transformValues","AlignmentError","lowCutoffWithUnits","highCutoffWithUnits","localAlignerDialog","setRotate","setUtmZone","savePrompt","setSavePrompt","oldProjection","setOldProjection","getEstimator","tempProjection","updateViewerProjection","deleteViewerProjection","aerialSelected","aerialClicked","aerialObs","setLocalAlignerActive","map_obs","toggleLocalAligner","generateLocalAlignerRows","translateX","translateY","scaling","deleteLocalAlignment","StatusCode","geometryLimit","titleInfo","titleMin","listContent","folderList","labelFixedHeight","labelParent","labelTitleWarning","labelTitleError","classificationText","progressToolbar","toolbarLinear","toolbarProgressCenter","downloadMargin","downloadResourceDialog","tableDropdown","mappingMargin","checkBoxParent","captionPadding","paddingBottomAndTop","paddingBottomAndTopMinimal","outputFolder","infoLabel","flexPaper","Label","isScrolling","labelName","isSceneLabel","getInfo","setGetInfo","isTrainingLabel","scoreValidity","scoreClass","CategoryContent","listRef","scrollingDivLength","useScrollingDiv","scrollingDivHeight","scrollToItem","useIsScrolling","itemCount","itemSize","CategoryExpand","TrainingArea","setDeletePrompt","addNewLabelDisabled","addNewlabelTooltip","disableTypography","Category","isValidCategory","labelDisabled","runTextDetection","editPrompt","setEditPrompt","sortPrompt","setSortPrompt","textDetectPrompt","setTextDetectPrompt","setSorted","numLabelsTooltip","numLabelsAll","substr","runSort","scoreValue","defaultScore","LabelIntersectDialog","forceInitialProgress","setTrainClassifyExe","setTrainClassifyProgress","resetExecutableValues","checkTrainingData","setProcessType","setMethod","LASfiles","minLasVersion","visibleClouds","cloudsAvailable","maxNumClasses","availableLasClasses","imageSamplingDistance","setImageSamplingDistance","intersectionAngle","setIntersectionAngle","minNumMatches","setMinNumMatches","positionConfidence","setPositionConfidence","maxDistanceFromCamera","setMaxDistanceFromCamera","closeLabelDist","setCloseLabelDist","minCameraDistance","setMinCameraDistance","maxCameraDistance","setMaxCameraDistance","maxIntersectDistance","setMaxIntersectDistance","setClusterDistance","numMatchesRequired","setNumMatchesRequired","extractPoints","setExtractPoints","objSize","setObjSize","setOverwrite","collapse1","setCollapse1","collapse2","setCollapse2","categoryClasses","setCategoryClasses","ignoreClasses","setIgnoreClasses","getIgnoreClasses","ignoreTemp","classicationCheck","getNameFromClass","runIntersection","tempCocoPath","csvEncompassPath","useFunctionV1","useFunctionV2","classesToIgnore","ic","categoryClassesNames","categoryClassesNums","successEstimate","successLabelInPC","successCombine","successConvert","convertAttempted","successLasWritten","csvOutputPaths","position_estimate_progress","positions_found","csvs_written","labels_found_pointcloud","combine_las","combine_las_complete","las_to_3dp","las_to_3dp_success","writing_las","las_written","lasOutputPath","resetDefaultValues","categoriesTemp","lasClass","getCategoryClasses","destination","rowsTemp","ignoreClass","updateIgnoreClasses","ImportDialog","importCategory","setImportCategory","importLarge","setImportLarge","importPoints","setImportPoints","importLines","setImportLines","setCheckOverlap","lineBuffer","setLineBuffer","pointBuffer","setPointBuffer","importData","setImportData","isOrthoLabel","categoryList","setLabelLoadProgress","hasLines","hasLargeClasses","categoryNames","filterAnnotationTypes","validBufferSize","minIterations","maxIterations","importCategories","newCategoryName","getMappedCategory","numGeometry","Ignore","anno","createSelect","getLayerMenuItems","Default","ClassifyFromAerial","setProgress","setRows","sortedAlpha","setSortedAlpha","sortByNum","setSortByNum","overwriteFile","setOverwriteFile","preserveGround","setPreserveGround","newLasPath","setNewLasPath","mixedData","checkNamesForClass","classifyPointclouds","applicationOrder","lasClasses","inputPaths","overwriteGround","polygonData","class","tempTextPath","newCloudPaths","label_bounds_error","overwrite_failure","output_paths","sortButtonTitle","reverseSort","sortRowsByClassNum","sortRowsAlphabetically","sortReset","ClassificationParameters","runClassification","modelPath","setModelPath","runOnCPU","setRunOnCPU","TrainingParameters","runTraining","defaultIterations","pretrainedPath","setPretrainedPath","iterations","setIterations","GetInfoWindow","orignalText","txtList","newText","setLabelText","updateLabelText","classValid","classHighlight","txt","handleTextChange","TextDetectionParameters","spellcheck","setSpellcheck","setLabelFindText","ScoreSortingParameters","setSortType","ImageLabelling","imageLabelDialog","labelType","setLabelType","setAddCategory","classifyLasPrompt","setClassifyLasPrompt","labelLoadProgress","classifyAerialProgress","setClassifyAerialProgress","trainClassifyProgress","updateTrainClassifyProgress","trainClassifyExe","processType","classifyImage","setClassifyImage","readingLabelFile","setReadingLabelFile","training","setTraining","trainingURL","setTrainingURL","downloadingResources","setDownloadingResources","downloadResourcesDialog","setDownloadResourcesDialog","trainingPrompt","setTrainingPrompt","classificationPrompt","setClassificationPrompt","labelExportOpen","setLabelExportOpen","textDetection","setTextDetection","pointCloudFiles","numPanoramics","numPlanars","canExportCSV","handleCancelProgress","checkCategoryUniqueness","handleCategoryChange","showTrainingWindow","canTrain","exportLabels3DL","exportToLinework","outputKey","importLabelsPTH","downloading_resources","extracting_resources","coco_data","importLabelData","importLabelsLinework","label_data","importLabels3DL","cudaErrorDialog","cudaError","selection","updateDownloadingResources","canRunClassification","imagePaths","loadedImageLabelPaths","canClassify","spellcheckCommand","activeImageLabelPaths","labelJSON","imageJSON","HTMLInputElement","labelHotkey","exportDisabled","trainingLinkDisabled","sceneTrainingDisabled","categoryListDisabled","localizedProcessType","modalName","downloadTooltip","canRunAerialToLas","combinedExtension","CircularProgress","areas","numIterations","pretrainedModelPath","gpu_memory_error","model_diverge_error","model_file_path","class_number_mismatch","old_classes","new_classes","borderRight","QuickNav","camerasForFolder","getBestSceneState","folderAssetIds","folderAsset","getFolderAssets","snapToFolder","isSelected","folderAssets","numFolderAssets","numAssetsVisible","openNav","mkdirs","moveCameraData","imagesPath","imagesData","newImagePath","moveStreamablePointsData","inputPath","moveGenericPointCloud","singleFileOutput","getMiniViewerPath","moveModelData","onExportError","modelName","copyToFile","shpInput","shpOutput","dbfInput","dbfOutput","assetsFolder","getAssetIndex","updateCameraDataState","assetIndex","finalPath","updateModelDataState","updateStreamablePointsState","updateRawPointsState","updateCameraTransformPath","matrixPath","moveAssetData","handleExportError","exporterOptsDefaults","onError","onProgress","getStaticExporter","buildPath","getBuildPath","cancelFlag","webOutputPath","rootOutputPath","miniViewerPath","exeOutputPath","globalSettingsPath","globalSettingsOutput","projectJson","projectPath","BulletListItem","NewProjectInfo","landXMLFiles","webmapSources","numGenericPointCloud","numberOfImages","cameraAsset","tagAsset","exportText","contentCenter","cancelProgress","cancelContent","StaticExporter","exporterDialog","messageDialog","successDialog","cancelDialog","setSingleFileOutput","exportTopMessage","setExportTopMessage","exportBottomMessage","setExportBottomMessage","exportPercent","updateExportPercent","isExportRunning","setIsExportRunning","startExport","cancelExport","setExportPercent","canExport","onExportFinished","setExportMessage","exportToStatic","exportName","sanitizedName","sanitize","SHP_FILE_TYPES","POTREE_FILES","onStart","createProject","panoramics","panoAsset","planars","pointCloudAsset","orthomosaics","orthoAsset","landxmls","landXMLAsset","ifcAsset","shpAsset","dxfAsset","webmapAsset","map_type","link","measurementUnits","request","getAssetsToUpload","projectID","uploadList","uploads","uploadId","getUploadURL","processPoints","getCloudExporter","statuses","tempOutputPath","status_code","Errored","LinkedProjectInfo","AssetStatusText","Uploaded","Uploading","Preparing","Queued","getColor","getText","CloudExporter","status_text","selectProjectID","assetStatuses","updateAssetStatuses","isExportFinished","setIsExportFinished","projectExists","setProjectExists","hasErrors","setHasErrors","projectURL","setProjectURL","setAssetStatuses","checkProject","originalID","exportToCloud","uploadMessage","assetStatus","clippingBoxParent","clippingBoxButtons","operationList","overflowY","boxOrientation","dropdownRoot","dropdownSelect","PointMarkupBox","onMouseOver","setPointMarkupHover","pointMarkupZoom","resetPointMarkupRotation","pointMarkupDeleteBox","PointMarkupGroup","operation","isSplit","newBoxDisabled","pointMarkupActive","operationBoxes","defaultIgnoreValue","setPointMarkupNewClassification","setPointMarkupIgnoredClassification","classOptions","displayName","setPointMarkupActive","pointMarkupDeleteGroup","pointMarkupNameExists","updatePointMarkupName","DataExportSplit","markupGroups","exportPoints","setExportPoints","exportImages","setExportImages","inputFoldersPoints","getAllCameras","inputFolderCameras","operationData","outputPaths","clearPointMarkup","DataExportMarkup","PointMarkup","pointMarkupDialog","toolType","setToolType","exportPromptMarkup","setExportPromptMarkup","exportPromptSplit","setExportPromptSplit","newOperationPrompt","setNewOperationPrompt","newOutputPrompt","setNewOutputPrompt","conversionProgress","setConversionProgress","pointMarkupToggle","isPointMarkup","isFolderSplit","dialogTitle","addPointMarkupOperation","copyClipboard","measurementUnitsParent","flexWrap","measurementUnitsRadio","imageOnlyInfoButton","marginside","expandText","bold","alignmentSelect","cell","tableCell","cellParent","measureTable","calculateButton","recalculate","recalculateButton","ExportDialog","exportType","setExportType","setOrdering","exportMeasurements","MeasureTypeIcon","setMeasureType","ImportExportIcon","ClipboardCopy","MeasurementCard","verticesReprojected","generateVertexPositions","is3DArea","isVolume","is2DArea","is3DLength","is2DLength","isStationMeasurement","updateMeasureHover","getVolumeComponent","deleteMeasurement","renameMeasurement","Measurements","exportDialog","xmlAssets","activeMeasurePrompt","setActiveMeasurePrompt","alignmentChoice","setAlignmentChoice","setMeasureUnits","loadImportData","encoded","decodeURIComponent","onModalClose","toggleMeasurements","updateMeasurementType","setMeasurementUnits","xmlAlignments","updateDefaultDropdown","reversed","iconProps","importDisabled","allowStationMeasurements","RadioGroup","Radio","fileDialog","accept","reader","FileReader","readAsText","buttonParentLeft","buttonParentRight","smallButton","buttonRight","multiImageHeader","fontFamily","WindowButton","hidden","MultiImageInfo","clampedColor","midValue","observationStyle1","observationStyle2","observationText1","observationText2","errorStyle","errorValue","errorElement","distanceStyle1","distanceValue1","distanceElement1","distanceStyle2","distanceValue2","distanceElement2","multiImageState","multiImageOpen","customPromptOpen","setCustomPromptOpen","customPromptState","setCustomPromptState","toggleMultiImageWindow","multiImageClosePrompt","initMultiImageContainer","multiImagePreviousImage","multiImageNextImage","multiImageOnAddMore","multiImageOnComplete","dependencies","dialogDiv","dialogContent","lineHeight","dialogPaper","divContent","indent","listItems","logoImage","support","titleParent","AboutDialog","helpDialog","javascriptDependencies","jquery","manifest","ol","react","three","typescript","devDependencies","pythonDependencies","numpy","scipy","matplotlib","pykml","lxml","miscDependancies","jsDependencies","pyDependencies","getDependencies","elevation","logoPath","underline","rel","consoleDialogHeader","consoleDialogTitle","consoleDialogClose","consoleHeight","consoleLine","TaskQueue","selectedTaskID","ConsoleWindow","lineData","setLineData","activeTask","scrollTop","useItemsSearch","handleSortChange","sortByDate","dateA","dateB","nameParts","initialSort","nameA","nameB","sortByName","ProjectListRow","cloudProject","accentColor","stc","borderLeft","CloudProjectList","userProjects","setUserProjects","itemsSearch","sortOptions","getUserProjects","projects","isAdmin","hasProjects","sortValue","backdropText","debugStandard","debugShifted","DragDropLoader","closest","ProjectLoader","loadFromCompiledExe","rawArgs","argv","arg","getAllFileArgs","loadFromStaticSite","oncontextmenu","configRoot","BackdropToggle","backdropOpen","setBackdropOpen","Backdrop","AppWithAuth","appAccess","setAppAccess","accessDialog","App","projectDrawerState","setDrawerState","localObservations","alignerObservations","pointProfileOpen","handleLinkWithoutTargets","quit","updateCompassOffset","hotToast","projectSlice","updateProjectID","updateSessionID"],"mappings":"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1B,OAA0B,kFCA1B,OAA0B,wECA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,kECA1B,OAA0B,mECA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,wECA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,8DCA1B,OAA0B,0DCA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,8ECA1B,OAA0B,kECA1B,OAA0B,mECA1B,OAA0B,sECA1B,OAA0B,6ECA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,2DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,4DCA1B,OAA0B,6DCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,wDCA1B,OAA0B,8DCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,sDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,mECA1B,OAA0B,qECA1B,OAA0B,8DCA1B,OAA0B,oECA1B,OAA0B,+DCA1B,OAA0B,qECA1B,OAA0B,kECA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,iECA1B,OAA0B,oECA1B,OAA0B,4DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,wDCA1B,OAA0B,2DCA1B,OAA0B,4DCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,0DCA1B,OAA0B,gECA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,+DCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,2DCA1B,OAA0B,6DCA1B,OAA0B,qECA1B,OAA0B,gECA1B,OAA0B,0DCA1B,OAA0B,8DCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,+DCA1B,OAA0B,2ECA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sECA1B,OAA0B,sFCA1B,OAA0B,sFCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,wDCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,gECA1B,OAA0B,oFCA1B,OAA0B,oFCA1B,OAA0B,oFCA1B,OAA0B,oFCA1B,OAA0B,oFCA1B,OAA0B,oFCA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,wECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,6DCA1B,OAA0B,6FCA1B,OAA0B,+DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,oECA1B,OAA0B,mECA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,yDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,gFCA1B,OAA0B,qDCA1B,OAA0B,sDCA1B,OAA0B,yDCA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,sECA1B,OAA0B,uECA1B,OAA0B,2ECA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,gECA1B,OAA0B,0DCA1B,OAA0B,iECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,wECA1B,OAA0B,wECA1B,OAA0B,oDCA1B,OAA0B,sDCA1B,OAA0B,wECA1B,OAA0B,8DCA1B,OAA0B,wECA1B,OAA0B,oECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,qECA1B,OAA0B,iECA1B,OAA0B,8DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,sDCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,oFCA1B,OAA0B,8DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,0DCA1B,OAA0B,uECA1B,OAA0B,iECA1B,OAA0B,oECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,8DCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,yDCA1B,OAA0B,wDCA1B,OAA0B,mFCA1B,OAA0B,uECA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,0DCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,kFCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,uDCA1B,OAA0B,4DCA1B,OAA0B,kECA1B,OAA0B,qECA1B,OAA0B,mECA1B,OAA0B,oDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,2ECA1B,OAA0B,0DCA1B,OAA0B,iECA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,6DCA1B,OAA0B,yECA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,4DCA1B,OAA0B,6DCA1B,OAA0B,2DCA1B,OAA0B,sECA1B,OAA0B,yECA1B,OAA0B,8DCA1B,OAA0B,yDCA1B,OAA0B,sECA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,0DCA1B,OAA0B,uDCA1B,OAA0B,6DCA1B,OAA0B,wDCA1B,OAA0B,8DCA1B,OAA0B,wDCA1B,OAA0B,+DCA1B,OAA0B,mECA1B,OAA0B,qECA1B,OAA0B,0DCA1B,OAA0B,+DCA1B,OAA0B,yECA1B,OAA0B,qECA1B,OAA0B,oDCA1B,OAA0B,2DCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,8DCA1B,OAA0B,4DCA1B,OAA0B,oECA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,+DCA1B,OAA0B,yECA1B,OAA0B,uDCA1B,OAA0B,+DCA1B,OAA0B,8DCA1B,OAA0B,gECA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,gECA1B,OAA0B,4ECA1B,OAA0B,kECA1B,OAA0B,gECA1B,OAA0B,uECA1B,OAA0B,wDCA1B,OAA0B,yDCA1B,OAA0B,qECA1B,OAA0B,iECA1B,OAA0B,mECA1B,OAA0B,sECA1B,OAA0B,wDCA1B,OAA0B,kECA1B,OAA0B,8ECA1B,OAA0B,+ECA1B,OAA0B,kFCA1B,OAA0B,wECA1B,OAA0B,2ECA1B,OAA0B,4ECA1B,OAA0B,iECA1B,OAA0B,2ECA1B,OAA0B,6ECA1B,OAA0B,8ECA1B,OAA0B,+ECA1B,OAA0B,+ECA1B,OAA0B,+ECA1B,OAA0B,kFCA1B,OAA0B,2FCA1B,OAA0B,+ECA1B,OAA0B,+ECA1B,OAA0B,kFCA1B,OAA0B,2FCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,qECA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,uECA1B,OAA0B,sFCA1B,OAA0B,sFCA1B,OAA0B,oECA1B,OAA0B,uECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,2ECA1B,OAA0B,uECA1B,OAA0B,4ECA1B,OAA0B,2ECA1B,OAA0B,2DCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,yFCA1B,OAA0B,yFCA1B,OAA0B,gFCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,0ECA1B,OAA0B,oECA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,iECA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,wFCA1B,OAA0B,wFCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,iECA1B,OAA0B,wECA1B,OAA0B,8DCA1B,OAA0B,yECA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,6DCA1B,OAA0B,qECA1B,OAA0B,+DCA1B,OAA0B,iECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,6DCA1B,OAA0B,8DCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,iECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,2ECA1B,OAA0B,yDCA1B,OAA0B,iECA1B,OAA0B,iDCA1B,OAA0B,0ECA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,yDCA1B,OAA0B,qECA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,uECA1B,OAA0B,mECA1B,OAA0B,4DCA1B,OAA0B,iDCA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,wECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,wECA1B,OAA0B,wECA1B,OAA0B,wECA1B,OAA0B,wECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,qECA1B,OAA0B,0ECA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,oDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,4ECA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,sECA1B,OAA0B,uECA1B,OAA0B,0ECA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,gECA1B,OAA0B,wDCA1B,OAA0B,4ECA1B,OAA0B,6DCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,iECA1B,OAA0B,qECA1B,OAA0B,qDCA1B,OAA0B,2DCA1B,OAA0B,wECA1B,OAA0B,yECA1B,OAA0B,6DCA1B,OAA0B,sECA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,sECA1B,OAA0B,uDCA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,4FCA1B,OAA0B,4FCA1B,OAA0B,6ECA1B,OAA0B,gFCA1B,OAA0B,gFCA1B,OAA0B,+DCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,mECA1B,OAA0B,oECA1B,OAA0B,+DCA1B,OAA0B,8DCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,sECA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,iFCA1B,OAA0B,iFCA1B,OAA0B,iFCA1B,OAA0B,0ECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,+DCA1B,OAA0B,kFCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,+ECA1B,OAA0B,gECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,iECA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,0FCA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,iECA1B,OAA0B,sDCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,mECA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,oECA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,mECA1B,OAA0B,8DCA1B,OAA0B,0DCA1B,OAA0B,wDCA1B,OAA0B,2ECA1B,OAA0B,iECA1B,OAA0B,wDCA1B,OAA0B,yDCA1B,OAA0B,uECA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,+ECA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,iFCA1B,OAA0B,iFCA1B,OAA0B,iFCA1B,OAA0B,iFCA1B,OAA0B,4FCA1B,OAA0B,4FCA1B,OAA0B,4ECA1B,OAA0B,0GCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,2DCA1B,OAA0B,+DCA1B,OAA0B,2ECA1B,OAA0B,kECA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,sECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,4ECA1B,OAA0B,4ECA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,2DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,iFCA1B,OAA0B,iFCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,6DCA1B,OAA0B,kECA1B,OAA0B,6DCA1B,OAA0B,qECA1B,OAA0B,wDCA1B,OAA0B,yDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,kDCA1B,OAA0B,+ECA1B,OAA0B,+ECA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,uDCA1B,OAA0B,sDCA1B,OAA0B,iDCA1B,OAA0B,iDCA1B,OAA0B,2DCA1B,OAA0B,0DCA1B,OAA0B,0ECA1B,OAA0B,iECA1B,OAA0B,uDCA1B,OAA0B,yDCA1B,OAA0B,iFCA1B,OAA0B,+ECA1B,OAA0B,gFCA1B,OAA0B,wDCA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,4DCA1B,OAA0B,wDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,gECA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,kFCA1B,OAA0B,4ECA1B,OAA0B,oDCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,OAA0B,0DCA1B,OAA0B,mFCA1B,OAA0B,wFCA1B,OAA0B,8ECA1B,OAA0B,wFCA1B,OAA0B,0DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,kECA1B,OAA0B,yECA1B,OAA0B,qECA1B,OAA0B,wDCA1B,OAA0B,sDCA1B,OAA0B,kDCA1B,OAA0B,0ECA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,0ECA1B,OAA0B,0ECA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,+DCA1B,OAA0B,qDCA1B,OAA0B,6DCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,0DCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,6DCA1B,OAA0B,yECA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,iDCA1B,OAA0B,gDCA1B,OAA0B,gDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,gDCA1B,OAA0B,gDCA1B,OAA0B,+CCA1B,OAA0B,+CCA1B,OAA0B,oDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,+CCA1B,OAA0B,+CCA1B,OAA0B,qECA1B,OAA0B,qECA1B,OAA0B,4DCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,+ECA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,kECA1B,OAA0B,qECA1B,OAA0B,sECA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,kDCA1B,OAA0B,0DCA1B,OAA0B,2DCA1B,OAA0B,mFCA1B,OAA0B,sDCA1B,OAA0B,sECA1B,OAA0B,6CCA1B,OAA0B,6CCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,kECA1B,OAA0B,kECA1B,OAA0B,wDCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,gECA1B,OAA0B,iECA1B,OAA0B,2ECA1B,OAA0B,4ECA1B,OAA0B,6ECA1B,OAA0B,8ECA1B,OAA0B,8DCA1B,OAA0B,6ECA1B,OAA0B,+DCA1B,OAA0B,8ECA1B,OAA0B,8DCA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,+DCA1B,OAA0B,4ECA1B,OAA0B,qDCA1B,OAA0B,qDCA1B,OAA0B,2DCA1B,OAA0B,4DCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,gECA1B,OAA0B,gECA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,oDCA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,sECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,uECA1B,OAA0B,+CCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,8CCA1B,OAA0B,gDCA1B,OAA0B,mDCA1B,OAA0B,uDCA1B,OAA0B,8CCA1B,OAA0B,8CCA1B,OAA0B,mDCA1B,OAA0B,oDCA1B,OAA0B,iDCA1B,OAA0B,kDCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,mECA1B,OAA0B,mECA1B,OAA0B,oECA1B,OAA0B,oECA1B,OAA0B,wDCA1B,OAA0B,kDCA1B,OAA0B,8ECA1B,OAA0B,8ECA1B,OAA0B,+ECA1B,OAA0B,+ECA1B,OAA0B,sFCA1B,OAA0B,sFCA1B,OAA0B,sFCA1B,OAA0B,sFCA1B,OAA0B,uFCA1B,OAA0B,uFCA1B,OAA0B,uFCA1B,OAA0B,uFCA1B,OAA0B,uECA1B,OAA0B,wECA1B,OAA0B,kECA1B,OAA0B,2DCA1B,OAA0B,uDCA1B,OAA0B,mDCA1B,OAA0B,oDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wDCA1B,OAA0B,wECA1B,OAA0B,wECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,qECA1B,OAA0B,sECA1B,OAA0B,0DCA1B,OAA0B,yDCA1B,OAA0B,sDCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,6DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,yDCA1B,OAA0B,8DCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,yDCA1B,OAA0B,yDCA1B,OAA0B,wDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,iECA1B,OAA0B,iECA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,wDCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,wDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,uDCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,8DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,oDCA1B,OAA0B,oDCA1B,OAA0B,6DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,yECA1B,OAA0B,4ECA1B,OAA0B,4ECA1B,OAA0B,4ECA1B,OAA0B,4ECA1B,OAA0B,4ECA1B,OAA0B,4ECA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,+DCA1B,OAA0B,qDCA1B,OAA0B,qECA1B,OAA0B,uDCA1B,OAA0B,yDCA1B,OAA0B,0DCA1B,OAA0B,0DCA1B,OAA0B,4DCA1B,OAA0B,qDCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,OAA0B,oECA1B,OAA0B,qDCA1B,OAA0B,sDCA1B,OAA0B,sDCA1B,OAA0B,2DCA1B,OAA0B,2DCA1B,OAA0B,iECA1B,OAA0B,4DCA1B,OAA0B,4DCA1B,OAA0B,kECA1B,OAA0B,yDCA1B,OAA0B,qDCA1B,OAA0B,0DCA1B,OAA0B,2DCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,OAA0B,mDCA1B,O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BK91Fa,IAA0B,oDL+1FvC,0BM/1Fa,IAA0B,oDNg2FvC,0BOh2Fa,IAA0B,oDPi2FvC,0BQj2Fa,IAA0B,oDRk2FvC,0BSl2Fa,IAA0B,oDTm2FvC,0BUn2Fa,IAA0B,oDVo2FvC,0BWp2Fa,IAA0B,oDXq2FvC,oBYr2Fa,IAA0B,8CZs2FvC,oBat2Fa,IAA0B,8Cbu2FvC,0Bcv2Fa,IAA0B,oDdw2FvC,2Bex2Fa,IAA0B,qDfy2FvC,8BgBz2Fa,IAA0B,wDhB02FvC,gDiB12Fa,IAA0B,0EjB22FvC,0BkB32Fa,IAA0B,oDlB42FvC,oCmB52Fa,IAA0B,8DnB62FvC,mCoB72Fa,IAA0B,6DpB82FvC,mCqB92Fa,IAA0B,6DrB+2FvC,mCsB/2Fa,IAA0B,6DtBg3FvC,oCuBh3Fa,IAA0B,8DvBi3FvC,oCwBj3Fa,IAA0B,8DxBk3FvC,oCyBl3Fa,IAA0B,8DzBm3FvC,sB0Bn3Fa,IAA0B,gD1Bo3FvC,sB2Bp3Fa,IAA0B,gD3Bq3FvC,sB4Br3Fa,IAA0B,gD5Bs3FvC,iC6Bt3Fa,IAA0B,2D7Bu3FvC,oC8Bv3Fa,IAA0B,8D9Bw3FvC,oC+Bx3Fa,IAA0B,8D/By3FvC,qCgCz3Fa,IAA0B,+DhC03FvC,qCiC13Fa,IAA0B,+DjC23FvC,oBkC33Fa,IAA0B,8ClC43FvC,6BmC53Fa,IAA0B,uDnC63FvC,2BoC73Fa,IAA0B,qDpC83FvC,2BqC93Fa,IAA0B,qDrC+3FvC,2BsC/3Fa,IAA0B,qDtCg4FvC,sCuCh4Fa,IAA0B,gEvCi4FvC,iCwCj4Fa,IAA0B,2DxCk4FvC,iCyCl4Fa,IAA0B,2DzCm4FvC,6B0Cn4Fa,IAA0B,uD1Co4FvC,6B2Cp4Fa,IAA0B,uD3Cq4FvC,6B4Cr4Fa,IAA0B,uD5Cs4FvC,6B6Ct4Fa,IAA0B,uD7Cu4FvC,4B8Cv4Fa,IAA0B,sD9Cw4FvC,4B+Cx4Fa,IAA0B,sD/Cy4FvC,4BgDz4Fa,IAA0B,sDhD04FvC,4BiD14Fa,IAA0B,sDjD24FvC,4BkD34Fa,IAA0B,sDlD44FvC,wCmD54Fa,IAA0B,kEnD64FvC,6BoD74Fa,IAA0B,uDpD84FvC,6BqD94Fa,IAA0B,uDrD+4FvC,6BsD/4Fa,IAA0B,uDtDg5FvC,6BuDh5Fa,IAA0B,uDvDi5FvC,6BwDj5Fa,IAA0B,uDxDk5FvC,6ByDl5Fa,IAA0B,uDzDm5FvC,0B0Dn5Fa,IAA0B,oD1Do5FvC,0B2Dp5Fa,IAA0B,oD3Dq5FvC,0B4Dr5Fa,IAA0B,oD5Ds5FvC,0B6Dt5Fa,IAA0B,oD7Du5FvC,0B8Dv5Fa,IAA0B,oD9Dw5FvC,uB+Dx5Fa,IAA0B,iD/Dy5FvC,uBgEz5Fa,IAA0B,iDhE05FvC,8BiE15Fa,IAA0B,wDjE25FvC,8BkE35Fa,IAA0B,wDlE45FvC,qBmE55Fa,IAA0B,+CnE65FvC,qBoE75Fa,IAA0B,+CpE85FvC,qBqE95Fa,IAA0B,+CrE+5FvC,sBsE/5Fa,IAA0B,gDtEg6FvC,wBuEh6Fa,IAA0B,kDvEi6FvC,wBwEj6Fa,IAA0B,kDxEk6FvC,wByEl6Fa,IAA0B,kDzEm6FvC,wB0En6Fa,IAA0B,kD1Eo6FvC,wB2Ep6Fa,IAA0B,kD3Eq6FvC,wB4Er6Fa,IAA0B,kD5Es6FvC,wB6Et6Fa,IAA0B,kD7Eu6FvC,0D8Ev6Fa,IAA0B,oF9Ew6FvC,mC+Ex6Fa,IAA0B,6D/Ey6FvC,mCgFz6Fa,IAA0B,6DhF06FvC,mCiF16Fa,IAA0B,6DjF26FvC,mCkF36Fa,IAA0B,6DlF46FvC,6CmF56Fa,IAA0B,uEnF66FvC,yCoF76Fa,IAA0B,mEpF86FvC,oCqF96Fa,IAA0B,8DrF+6FvC,oCsF/6Fa,IAA0B,8DtFg7FvC,oCuFh7Fa,IAA0B,8DvFi7FvC,0CwFj7Fa,IAA0B,oExFk7FvC,qCyFl7Fa,IAA0B,+DzFm7FvC,qC0Fn7Fa,IAA0B,+D1Fo7FvC,qC2Fp7Fa,IAA0B,+D3Fq7FvC,qC4Fr7Fa,IAA0B,+D5Fs7FvC,qC6Ft7Fa,IAA0B,+D7Fu7FvC,+B8Fv7Fa,IAA0B,yD9Fw7FvC,+B+Fx7Fa,IAA0B,yD/Fy7FvC,+BgGz7Fa,IAA0B,yDhG07FvC,+BiG17Fa,IAA0B,yDjG27FvC,+BkG37Fa,IAA0B,yDlG47FvC,+BmG57Fa,IAA0B,yDnG67FvC,4BoG77Fa,IAA0B,sDpG87FvC,8BqG97Fa,IAA0B,wDrG+7FvC,8BsG/7Fa,IAA0B,wDtGg8FvC,8BuGh8Fa,IAA0B,wDvGi8FvC,8BwGj8Fa,IAA0B,wDxGk8FvC,8ByGl8Fa,IAA0B,wDzGm8FvC,8B0Gn8Fa,IAA0B,wD1Go8FvC,8B2Gp8Fa,IAA0B,wD3Gq8FvC,8B4Gr8Fa,IAA0B,wD5Gs8FvC,iC6Gt8Fa,IAA0B,2D7Gu8FvC,kC8Gv8Fa,IAA0B,4D9Gw8FvC,sC+Gx8Fa,IAA0B,gE/Gy8FvC,qDgHz8Fa,IAA0B,+EhH08FvC,uCiH18Fa,IAA0B,iEjH28FvC,sDkH38Fa,IAA0B,gFlH48FvC,4CmH58Fa,IAA0B,sEnH68FvC,yCoH78Fa,IAA0B,mEpH88FvC,0CqH98Fa,IAA0B,oErH+8FvC,+BsH/8Fa,IAA0B,yDtHg9FvC,+BuHh9Fa,IAA0B,yDvHi9FvC,+BwHj9Fa,IAA0B,yDxHk9FvC,+ByHl9Fa,IAA0B,yDzHm9FvC,+B0Hn9Fa,IAA0B,yD1Ho9FvC,+B2Hp9Fa,IAA0B,yD3Hq9FvC,+B4Hr9Fa,IAA0B,yD5Hs9FvC,sB6Ht9Fa,IAA0B,gD7Hu9FvC,sB8Hv9Fa,IAA0B,gD9Hw9FvC,sB+Hx9Fa,IAA0B,gD/Hy9FvC,sBgIz9Fa,IAA0B,gDhI09FvC,sBiI19Fa,IAA0B,gDjI29FvC,sBkI39Fa,IAA0B,gDlI49FvC,sBmI59Fa,IAA0B,gDnI69FvC,yBoI79Fa,IAA0B,mDpI89FvC,yBqI99Fa,IAA0B,mDrI+9FvC,yBsI/9Fa,IAA0B,mDtIg+FvC,kCuIh+Fa,IAA0B,4DvIi+FvC,0BwIj+Fa,IAA0B,oDxIk+FvC,0ByIl+Fa,IAA0B,oDzIm+FvC,0B0In+Fa,IAA0B,oD1Io+FvC,+B2Ip+Fa,IAA0B,yD3Iq+FvC,+B4Ir+Fa,IAA0B,yD5Is+FvC,+B6It+Fa,IAA0B,yD7Iu+FvC,+B8Iv+Fa,IAA0B,yD9Iw+FvC,+B+Ix+Fa,IAA0B,yD/Iy+FvC,+BgJz+Fa,IAA0B,yDhJ0+FvC,sBiJ1+Fa,IAA0B,gDjJ2+FvC,sBkJ3+Fa,IAA0B,gDlJ4+FvC,2BmJ5+Fa,IAA0B,qDnJ6+FvC,2BoJ7+Fa,IAA0B,qDpJ8+FvC,kCqJ9+Fa,IAA0B,4DrJ++FvC,mCsJ/+Fa,IAA0B,6DtJg/FvC,iCuJh/Fa,IAA0B,2DvJi/FvC,uBwJj/Fa,IAA0B,iDxJk/FvC,4ByJl/Fa,IAA0B,sDzJm/FvC,4C0Jn/Fa,IAA0B,sE1Jo/FvC,iC2Jp/Fa,IAA0B,2D3Jq/FvC,iC4Jr/Fa,IAA0B,2D5Js/FvC,iC6Jt/Fa,IAA0B,2D7Ju/FvC,iC8Jv/Fa,IAA0B,2D9Jw/FvC,4B+Jx/Fa,IAA0B,sD/Jy/FvC,4BgKz/Fa,IAA0B,sDhK0/FvC,4BiK1/Fa,IAA0B,sDjK2/FvC,4BkK3/Fa,IAA0B,sDlK4/FvC,4BmK5/Fa,IAA0B,sDnK6/FvC,4BoK7/Fa,IAA0B,sDpK8/FvC,4BqK9/Fa,IAA0B,sDrK+/FvC,4BsK//Fa,IAA0B,sDtKggGvC,oBuKhgGa,IAA0B,8CvKigGvC,4BwKjgGa,IAA0B,sDxKkgGvC,uCyKlgGa,IAA0B,iEzKmgGvC,uC0KngGa,IAA0B,iE1KogGvC,uC2KpgGa,IAA0B,iE3KqgGvC,wC4KrgGa,IAA0B,kE5KsgGvC,wC6KtgGa,IAA0B,kE7KugGvC,wC8KvgGa,IAA0B,kE9KwgGvC,wC+KxgGa,IAA0B,kE/KygGvC,oCgLzgGa,IAA0B,8DhL0gGvC,qCiL1gGa,IAA0B,+DjL2gGvC,+BkL3gGa,IAA0B,yDlL4gGvC,uBmL5gGa,IAA0B,iDnL6gGvC,uBoL7gGa,IAA0B,iDpL8gGvC,2BqL9gGa,IAA0B,qDrL+gGvC,2BsL/gGa,IAA0B,sDCsB1Bj1C,GAZE,CACf,4BCXa,IAA0B,sDDYvC,+BEZa,IAA0B,yDFavC,cGba,IAA0B,0CHcvC,aIda,IAA0B,yCJevC,0BKfa,IAA0B,oDLgBvC,6BMhBa,IAA0B,uDNiBvC,QOjBa,IAA0B,oCPkBvC,qBQlBa,IAA0B,+CRmBvC,OSnBa,IAA0B,oCCOnCk1C,GAAW,2EACZC,IACAC,IACAC,IACAC,IACAC,IACAC,IAGQC,GAAoB9pF,OAAOC,KAAKspF,IAAa,GAE7CQ,GAAoB,SAACppG,GAChC,OAAO4oG,GAAY5oG,IAGN4oG,O,S3sDtBH34C,O,qBAAAA,I,kBAAAA,I,mBAAAA,I,iBAAAA,I,oBAAAA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","file":"static/js/main.4ca01873.chunk.js","sourcesContent":["import React, { FC, useEffect } from 'react';\r\nimport { useCallback } from 'react';\r\nimport PropTypes from 'prop-types';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { toast } from '../../app';\r\nimport { setLocalizedURL } from '../../localization';\r\nimport { ListItemText, MenuItem, Popover, Typography } from '@material-ui/core';\r\nimport { buildElectronMenu } from '../../electron-menu';\r\nimport { useViewer } from '../../hooks';\r\nimport { useSelector } from 'react-redux';\r\nimport { selectProjectType } from '../../redux/project-slice';\r\nimport { ProjectType } from '../../types/project';\r\n\r\nexport type Language = 'en' | 'de' | 'es' | 'fr' | 'ja';\r\n\r\nexport enum LanguageOptions {\r\n en = 'English',\r\n de = 'Deutsch',\r\n fr = 'Français',\r\n es = 'Español',\r\n ja = '日本語<'\r\n};\r\n\r\ninterface LanguagePopoverProps {\r\n anchorEl: null | Element;\r\n onClose?: () => void;\r\n open?: boolean;\r\n}\r\n\r\nexport const LanguagePopover: FC = (props) => {\r\n const { anchorEl, onClose, open = false, ...other } = props;\r\n const { i18n, t } = useTranslation();\r\n const {viewer} = useViewer();\r\n\r\n const projectType = useSelector(selectProjectType);\r\n const isStandardProject = projectType === ProjectType.Standard;\r\n\r\n const handleChange = useCallback(async (language: Language): Promise => {\r\n onClose?.();\r\n await i18n.changeLanguage(language);\r\n const message = t('language-picker.language_changed');\r\n toast.success(message);\r\n }, [onClose, t, i18n]);\r\n\r\n useEffect(() => {\r\n buildElectronMenu(isStandardProject);\r\n viewer?.updateCompass();\r\n\r\n // Update language option in url. A small timeout is required\r\n const timeout = setTimeout(() => {\r\n setLocalizedURL(i18n.language);\r\n }, 500);\r\n\r\n return () => {\r\n clearTimeout(timeout);\r\n };\r\n }, [i18n.language, isStandardProject]);\r\n\r\n return (\r\n \r\n {(Object.keys(LanguageOptions) as Language[]).map((language) => {\r\n const text = LanguageOptions[language];\r\n\r\n return (\r\n handleChange(language)}\r\n key={language}\r\n >\r\n \r\n {text}\r\n \r\n )}\r\n />\r\n \r\n );\r\n })}\r\n \r\n );\r\n};\r\n\r\nLanguagePopover.propTypes = {\r\n anchorEl: PropTypes.any,\r\n onClose: PropTypes.func,\r\n open: PropTypes.bool\r\n};\r\n","import React from \"react\";\r\nimport { Button, createStyles, IconButton, makeStyles, Theme } from \"@material-ui/core\";\r\nimport isHtml from 'is-html';\r\nimport { ArrowTooltip } from \".\";\r\nimport clsx from 'clsx';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n olButtonParent: {\r\n background: \"var(--ol-subtle-background-color)\",\r\n position: 'absolute',\r\n\r\n zIndex: 10,\r\n borderRadius: \"4px\"\r\n },\r\n olButtonTopLeft: {\r\n top: \"0.5em\",\r\n left: \"0.5em\",\r\n },\r\n olButtonBottomLeft: {\r\n bottom: \"0.5em\",\r\n left: \"0.5em\",\r\n },\r\n olButton: {\r\n padding: \"0px\",\r\n margin: \"1px\",\r\n borderRadius: \"2px\",\r\n backgroundColor: \"var(--ol-background-color) !important\",\r\n color: \"var(--ol-subtle-foreground-color)\",\r\n minWidth: \"22px\",\r\n \"&:hover\": {\r\n outline: \"1px solid var(--ol-subtle-foreground-color)\",\r\n color: \"var(--ol-foreground-color)\"\r\n },\r\n \"& svg\": {\r\n width: \"22px\",\r\n height: \"22px\"\r\n }\r\n },\r\n olButtonRotate: {\r\n \"-webkit-transition\": \"-webkit-transform .3s ease-in-out\",\r\n transition: \"transform .3s ease-in-out\",\r\n \"&:hover\": {\r\n \"-webkit-transform\": \"rotate(-180deg)\",\r\n transform: \"rotate(-180deg)\"\r\n }\r\n }\r\n }),\r\n);\r\n\r\ninterface EnhancedIconButtonProps {\r\n title: string\r\n visible?: boolean\r\n onClick?(event?): void,\r\n disabled?: boolean\r\n children: any\r\n}\r\n\r\nexport const EnhancedIconButton = (props: EnhancedIconButtonProps) => {\r\n const {title, visible=true, onClick, disabled=false, children} = props;\r\n\r\n let tooltipText = disabled\r\n ? `${title} (Disabled)`\r\n : title;\r\n\r\n let tooltipTitle = isHtml(tooltipText)\r\n ? (
)\r\n : tooltipText;\r\n\r\n return (\r\n \r\n {visible && (\r\n {\r\n if (disabled) return;\r\n if (!onClick) return;\r\n onClick(event);\r\n }}\r\n style={{\r\n ...(disabled && {opacity: 0.3}),\r\n }}\r\n >\r\n {children}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\ninterface OpenLayersIconProps {\r\n rotate?: boolean;\r\n onClick(event): void;\r\n placement: \"top-left\" | \"bottom-left\"\r\n children: any;\r\n}\r\n\r\nexport const OpenLayersIcon = (props: OpenLayersIconProps) => {\r\n const {rotate=false, placement, onClick, children} = props;\r\n\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n \r\n {children}\r\n \r\n
\r\n );\r\n};\r\n","import React from \"react\";\r\nimport { ListItemIcon, useTheme } from \"@material-ui/core\";\r\n\r\nexport const DenseIcon = (props) => {\r\n const theme = useTheme();\r\n const {children, centered, noPadding, ...other} = props;\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};","import {\r\n Button,\r\n createStyles,\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n DialogContentText,\r\n DialogTitle,\r\n IconButton,\r\n LinearProgress,\r\n makeStyles,\r\n TextField,\r\n Theme,\r\n useTheme\r\n} from \"@material-ui/core\";\r\nimport clsx from 'clsx';\r\nimport React, {useEffect, useState} from \"react\";\r\nimport CloseIcon from '@material-ui/icons/Close';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';\r\nimport CheckCircleOutlineIcon from '@material-ui/icons/CheckCircleOutline';\r\nimport Draggable from \"react-draggable\";\r\nimport { headerHeight } from \"../app\";\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport Select from '@material-ui/core/Select';\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { isEqual } from 'lodash';\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\nexport interface DropDownInfo {\r\n value: string;\r\n title: string;\r\n entries: string[];\r\n text: string;\r\n}\r\n\r\nconst minDialogWidth = 300; // Used for prompt, dropdown, text... etc\r\n\r\ntype DialogWidth = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n draggableTitleClose: {\r\n color: theme.palette.grey[500],\r\n marginRight: theme.spacing(1)\r\n },\r\n draggableTitleMinimize: {\r\n color: theme.palette.grey[500],\r\n },\r\n draggableContentStaticHeight: {\r\n height: `min(75vh, 500px) !important`,\r\n },\r\n draggableContent: {\r\n padding: theme.spacing(0),\r\n paddingTop: \"0px !important\",\r\n height: \"fit-content\",\r\n width: \"fit-content\",\r\n maxWidth: 'none',\r\n maxHeight: 'none'\r\n },\r\n draggableMouseDown: {\r\n \"z-index\": `${theme.zIndex.modal + 1} !important`\r\n },\r\n draggableContentParent: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n minWidth: \"400px\",\r\n maxWidth: \"75vw\",\r\n minHeight: \"200px\",\r\n maxHeight: \"75vh\",\r\n overflow: \"hidden\",\r\n position: \"relative\",\r\n resize: \"both\",\r\n zIndex: 1 // Fixes slimscroll visual issues\r\n },\r\n draggableResizeHandler: {\r\n float: \"right\",\r\n position: \"absolute\",\r\n bottom: \"0px\",\r\n right: \"0px\"\r\n },\r\n draggableTopDiv: {\r\n display: \"flex\",\r\n alignItems: \"center\"\r\n },\r\n draggableBackdropPaper: {\r\n height: \"inherit\"\r\n },\r\n draggableBackdropRounded: {\r\n borderRadius: theme.spacing(0.5),\r\n height: \"inherit\",\r\n },\r\n draggableRoundCorner: {\r\n backgroundColor: \"transparent\"\r\n },\r\n draggableTitle: {\r\n userSelect: \"none\",\r\n cursor: \"grab\",\r\n flex: \"1 !important\"\r\n },\r\n draggableTitleDown: {\r\n cursor: \"grabbing\"\r\n },\r\n progressContent: {\r\n padding: `${theme.spacing(3)}px !important`,\r\n },\r\n progressNoTransition: {\r\n transition: \"none\"\r\n },\r\n dropdownGrid: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"space-between\",\r\n \"& span\": {\r\n flex: 1\r\n }\r\n },\r\n dropdownSpacing: {\r\n marginBottom: theme.spacing(2)\r\n },\r\n simpleDialogMain: {\r\n \"z-index\": `${theme.zIndex.modal + 1} !important`\r\n },\r\n simpleDialogHeader: {\r\n display: \"flex\",\r\n alignItems: \"center\"\r\n },\r\n simpleDialogTitle: {\r\n userSelect: \"none\",\r\n flex: 1\r\n },\r\n simpleDialogEdit: {\r\n color: theme.palette.grey[500],\r\n },\r\n simpleDialogClose: {\r\n color: theme.palette.grey[500],\r\n marginRight: theme.spacing(1)\r\n }\r\n }),\r\n);\r\n\r\ninterface PromptDialogProps {\r\n open: boolean;\r\n title: string;\r\n prompt: string;\r\n button: string;\r\n onCancel(): void;\r\n onSubmit(): void;\r\n}\r\n\r\nexport const PromptDialog = (props: PromptDialogProps) => {\r\n const {open, title, prompt, button, onCancel, onSubmit} = props;\r\n const {t} = useTranslation();\r\n\r\n return (\r\n \r\n \r\n {title}\r\n \r\n\r\n \r\n \r\n {prompt}\r\n \r\n \r\n\r\n \r\n \r\n \r\n {button}\r\n \r\n \r\n \r\n );\r\n};\r\n\r\ninterface AlertDialogProps {\r\n open: boolean;\r\n error?: boolean\r\n title: string;\r\n onClose(): void;\r\n children: any;\r\n}\r\n\r\nexport const AlertDialog = (props: AlertDialogProps) => {\r\n const {open, onClose, title, error=false} = props;\r\n\r\n const {t} = useTranslation();\r\n const theme = useTheme();\r\n\r\n return (\r\n \r\n
\r\n {error && }\r\n\r\n {!error && }\r\n\r\n \r\n {title}\r\n \r\n
\r\n\r\n \r\n {props.children}\r\n \r\n\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\ninterface TextDialogProps {\r\n open: boolean;\r\n title: string;\r\n label: string;\r\n prompt: string;\r\n placeholder?: string;\r\n onCancel(): void;\r\n onSubmit(value: string): void;\r\n clear?: boolean;\r\n}\r\n\r\nexport const TextDialog = (props: TextDialogProps) => {\r\n const {open, onSubmit, onCancel, label, prompt,\r\n placeholder=\"\", clear=false} = props;\r\n\r\n const [text, setText] = useState(\"\");\r\n const [disabled, setDisabled] = useState(true);\r\n const {t} = useTranslation();\r\n\r\n const handleTextChange = (event) => {\r\n setText(event.target.value);\r\n };\r\n\r\n useEffect(() => {\r\n if (text.trim() !== '') {\r\n setDisabled(false);\r\n } else {\r\n setDisabled(true);\r\n }\r\n }, [text]);\r\n\r\n useEffect(() => {\r\n setText(placeholder);\r\n }, [open]);\r\n\r\n const handleCancel = () => {\r\n onCancel();\r\n setText(placeholder);\r\n };\r\n\r\n const handleSubmit = () => {\r\n const trimmedText = text.trim();\r\n\r\n onSubmit(trimmedText);\r\n\r\n if (clear) {\r\n setText('');\r\n } else {\r\n setText(trimmedText);\r\n }\r\n };\r\n\r\n const handleKeyDown = (event) => {\r\n if (event.key === 'Enter') {\r\n if (text === '') {\r\n return;\r\n }\r\n\r\n handleSubmit();\r\n }\r\n };\r\n\r\n return (\r\n \r\n {props.title}\r\n \r\n \r\n {prompt}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\ninterface DropdownDialogProps {\r\n open: boolean;\r\n title: string;\r\n prompt: string;\r\n defaultValue: any;\r\n onCancel(): void;\r\n onSubmit(value: any): void;\r\n options: [value: any, text: string][];\r\n}\r\n\r\nexport const DropDownDialog = (props: DropdownDialogProps) => {\r\n const {open, defaultValue, title, prompt, options, onCancel, onSubmit} = props;\r\n\r\n const [value, setValue] = useState(defaultValue);\r\n const {t} = useTranslation();\r\n\r\n const resetDefaults = () => {\r\n setValue(defaultValue);\r\n };\r\n\r\n const handleSubmit = () => {\r\n onSubmit(value);\r\n };\r\n\r\n const handleChange = (event) => {\r\n setValue(event.target.value);\r\n };\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n return (\r\n \r\n {title}\r\n \r\n \r\n {prompt}\r\n \r\n \r\n {options.map((option, index) => {\r\n const [value, text] = option;\r\n\r\n return (\r\n \r\n {text}\r\n \r\n );\r\n })}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\ninterface SimpleDialogProps {\r\n open: boolean\r\n title: string\r\n button?: string\r\n onSubmit?(): void\r\n onClose(): void\r\n onEdit?(): void\r\n canSubmit?: boolean\r\n canClose?: boolean\r\n children: any\r\n maxWidth?: DialogWidth\r\n}\r\n\r\nexport const SimpleDialog = (props: SimpleDialogProps) => {\r\n const {title, button = \"Submit\", open, onSubmit, onClose, onEdit,\r\n canSubmit=true, canClose=true, children, maxWidth=\"sm\", ...other} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n return (\r\n \r\n
\r\n \r\n {title}\r\n \r\n\r\n {!!onEdit && (\r\n \r\n \r\n \r\n )}\r\n\r\n {/* Close button */}\r\n \r\n \r\n \r\n
\r\n\r\n \r\n {children}\r\n \r\n\r\n \r\n \r\n {t('buttons.cancel')}\r\n \r\n\r\n {!!onSubmit && (\r\n \r\n {button}\r\n \r\n )}\r\n \r\n\r\n \r\n );\r\n};\r\n\r\ninterface DraggableDialogProps {\r\n open: boolean\r\n title: string\r\n onClose?(): void\r\n initialHeight?: number | string\r\n initialWidth?: number | string\r\n resize?: boolean\r\n children: any\r\n}\r\n\r\nexport const DraggableDialog = (props: DraggableDialogProps) => {\r\n const {open, title, initialHeight, initialWidth, onClose} = props;\r\n\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n\r\n const initialPositionX = theme.spacing(2);\r\n const initialPositionY = headerHeight + theme.spacing(2);\r\n\r\n const paperPropID = useState(nanoid())[0];\r\n const resizeElementID = useState(nanoid())[0];\r\n const [bounds, setBounds] = useState(null);\r\n const [mouseDown, setMouseDown] = useState(false);\r\n\r\n const [modifiedSize, setModifiedSize] = useState({\r\n x: initialWidth ? initialWidth : \"450px\",\r\n y: initialHeight ? initialHeight : \"fit-content\"\r\n });\r\n\r\n const [position, setPosition] = useState({\r\n x: initialPositionX,\r\n y: initialPositionY\r\n });\r\n\r\n const onDragMouseDown = () => {\r\n setMouseDown(true);\r\n };\r\n\r\n const onDragMouseUp = () => {\r\n setMouseDown(false);\r\n };\r\n\r\n const getNewBoundary = (elementWidth) => {\r\n let newBounds = {\r\n right : window.innerWidth - elementWidth,\r\n left : 0,\r\n bottom : window.innerHeight - 40,\r\n top : headerHeight\r\n };\r\n\r\n if (newBounds.right - newBounds.left < elementWidth) {\r\n newBounds.right = window.innerWidth - elementWidth;\r\n newBounds.left = 0;\r\n }\r\n\r\n // Add bounds padding\r\n const boundsPadding = 10;\r\n newBounds.right -= boundsPadding;\r\n newBounds.left += boundsPadding;\r\n newBounds.top += boundsPadding;\r\n\r\n return newBounds;\r\n };\r\n\r\n const checkOutOfBounds = (position, newBounds) => {\r\n let x = position.x;\r\n let y = position.y;\r\n\r\n const rightOutOfBounds = (x > newBounds.right);\r\n const leftOutOfBounds = (x < newBounds.left);\r\n const bottomOutOfBounds = (y > newBounds.bottom);\r\n const topOutOfBounds = (y < newBounds.top);\r\n\r\n if (rightOutOfBounds) {\r\n x = Math.min(x, newBounds.right);\r\n }\r\n\r\n if (leftOutOfBounds) {\r\n x = Math.max(newBounds.left, x);\r\n }\r\n\r\n if (bottomOutOfBounds) {\r\n y = Math.min(y, newBounds.bottom);\r\n }\r\n\r\n if (topOutOfBounds) {\r\n y = Math.max(y, newBounds.top);\r\n }\r\n\r\n return {x, y};\r\n };\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n const interval = setInterval(() => {\r\n let element = document.getElementById(resizeElementID);\r\n if (!element) return;\r\n\r\n // Remember our resized width and height so it can be applied\r\n // the next time that the dialog is opened\r\n const elementWidth = element.clientWidth;\r\n const elementHeight = element.clientHeight;\r\n\r\n const newModifiedSize = {\r\n x: `${elementWidth}px`,\r\n y: `${elementHeight}px`\r\n };\r\n\r\n // Calculate new boundary values\r\n const newBounds = getNewBoundary(elementWidth);\r\n\r\n // Move dialog if we are out of bounds\r\n const newPosition = checkOutOfBounds(position, newBounds);\r\n\r\n /** NOTE: React is bad with object equality, so lodash is used */\r\n\r\n if (!isEqual(modifiedSize, newModifiedSize)) {\r\n setModifiedSize(newModifiedSize);\r\n }\r\n\r\n if (!isEqual(bounds, newBounds)) {\r\n setBounds(newBounds);\r\n }\r\n\r\n if (!isEqual(position, newPosition)) {\r\n setPosition(newPosition);\r\n }\r\n }, 100);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }, [open, bounds, position, modifiedSize]);\r\n\r\n return (\r\n {\r\n const {x,y} = data;\r\n setPosition({x, y});\r\n }}\r\n >\r\n {\r\n /** Remove tabindex from paper to stop drag/drop issues */\r\n let element = document.getElementById(paperPropID);\r\n element?.parentElement.removeAttribute(\"tabindex\");\r\n }}\r\n aria-labelledby=\"draggable-dialog-title\"\r\n className={clsx(classes.draggableContent, {\r\n [classes.draggableMouseDown]: mouseDown\r\n })}\r\n classes={{\r\n paperFullScreen: classes.draggableBackdropRounded,\r\n scrollPaper: classes.draggableBackdropPaper\r\n }}\r\n BackdropProps={{\r\n className: classes.draggableRoundCorner\r\n }}\r\n PaperProps={{\r\n id: paperPropID\r\n }}\r\n >\r\n \r\n {/* Draggable title */}\r\n \r\n {title}\r\n \r\n\r\n {/* Close button */}\r\n \r\n \r\n \r\n
\r\n\r\n \r\n {props.children}\r\n \r\n\r\n \r\n \r\n );\r\n};\r\n\r\ninterface ProgressDialogProps {\r\n open: boolean;\r\n text: string;\r\n percent: number;\r\n animated?: boolean\r\n}\r\n\r\nexport const ProgressDialog = (props: ProgressDialogProps) => {\r\n const {open, text, percent, animated=false} = props;\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n \r\n \r\n {text} {percent.toFixed(2)}%\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\n","import React, {memo} from \"react\";\r\nimport {\r\n createStyles,\r\n Grid,\r\n InputLabel,\r\n makeStyles,\r\n Theme,\r\n Typography\r\n} from \"@material-ui/core\";\r\nimport { Draggable } from 'react-beautiful-dnd';\r\nimport ListItem from '@material-ui/core/ListItem';\r\nimport {\r\n DragDropContext,\r\n Droppable,\r\n OnDragEndResponder\r\n} from 'react-beautiful-dnd';\r\nimport { NumberField } from \".\";\r\nimport {t} from \"../localization\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n draggingListItem: {\r\n background: 'rgb(235,235,235)'\r\n },\r\n staticListItem: {\r\n borderBottom: \"2px dashed lightgray\"\r\n },\r\n flexGrow: {\r\n flexGrow: 1\r\n }\r\n })\r\n);\r\n\r\ntype DraggableItemProps = {\r\n id: string;\r\n primary: string;\r\n secondary: number;\r\n index: number;\r\n min?: number,\r\n max?: number,\r\n step?: number\r\n};\r\n\r\ntype DraggableListProps = {\r\n items: DraggableItemProps[];\r\n onDragEnd: OnDragEndResponder;\r\n setData: any;\r\n inputName: string;\r\n};\r\n\r\nconst DraggableListItem = (props) => {\r\n const {item, index, setData, inputName, listLength} = props;\r\n const classes = useStyles();\r\n const useStaticListItem = (index === listLength-1) ? '' : classes.staticListItem;\r\n\r\n return (\r\n \r\n {(provided, snapshot) => (\r\n \r\n
\r\n \r\n \r\n {t(\"labels.category-name\")}\r\n \r\n \r\n {inputName}\r\n \r\n \r\n \r\n \r\n {item.primary}\r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n )}\r\n
\r\n );\r\n};\r\n\r\nexport const DraggableList = memo((props: DraggableListProps) => {\r\n const {items, onDragEnd, setData, inputName} = props;\r\n\r\n return (\r\n \r\n \r\n {provided => (\r\n
\r\n {items.map((item, index) => (\r\n \r\n ))}\r\n {provided.placeholder}\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n});\r\n","import React, { useEffect, useState } from 'react';\r\nimport {\r\n Checkbox,\r\n createStyles,\r\n Input,\r\n makeStyles,\r\n MenuItem,\r\n Paper,\r\n Table,\r\n TableBody,\r\n TableCell,\r\n TableContainer,\r\n TableHead,\r\n TablePagination,\r\n TableRow,\r\n TableSortLabel,\r\n Theme,\r\n Typography,\r\n useTheme\r\n} from '@material-ui/core';\r\nimport SearchIcon from '@material-ui/icons/Search';\r\nimport MoreHorizIcon from '@material-ui/icons/MoreHoriz';\r\nimport clsx from 'clsx';\r\nimport {\r\n ArrowTooltip,\r\n DenseIcon,\r\n DenseMenu,\r\n EnhancedIconButton\r\n} from '.';\r\nimport { useTranslation } from 'react-i18next';\r\nimport isHtml from 'is-html';\r\nimport {\r\n EnhancedTableBodyProps,\r\n EnhancedTableCellProps,\r\n EnhancedTableCheckboxHeadProps,\r\n EnhancedTableHeadProps,\r\n EnhancedTableProps\r\n} from '../types/enhanced-table';\r\nimport { toLocaleString } from '../utilities/dates';\r\nimport { useContextMenu } from '../hooks';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n header: {\r\n fontWeight: \"bold\",\r\n userSelect: \"none\",\r\n whiteSpace: \"nowrap\"\r\n },\r\n densePadding: {\r\n padding: `${theme.spacing(0.5)}px ${theme.spacing(1.0)}px !important`,\r\n },\r\n denseFooter: {\r\n height: theme.spacing(4),\r\n minHeight: \"0px\",\r\n overflow: \"hidden\"\r\n },\r\n hiddenSort: {\r\n border: 0,\r\n clip: 'rect(0 0 0 0)',\r\n height: 1,\r\n margin: -1,\r\n overflow: 'hidden',\r\n padding: 0,\r\n position: 'absolute',\r\n top: 20,\r\n width: 1,\r\n },\r\n noSelect: {\r\n userSelect: \"none\"\r\n },\r\n rowDisabled: {\r\n \"& th\": {\r\n opacity: 0.3\r\n },\r\n \"& td\": {\r\n opacity: 0.3\r\n }\r\n },\r\n rowIcon: {\r\n fontSize: \"1em\"\r\n },\r\n buttonCell: {\r\n width: \"1%\",\r\n whiteSpace: \"nowrap\",\r\n padding: \"0px !important\"\r\n },\r\n buttonHeader: {\r\n padding: \"0px !important\"\r\n },\r\n tableRow: {\r\n \"& td:last-child\": {\r\n paddingRight: `${theme.spacing(1.5)}px !important`\r\n },\r\n \"& td:first-child\": {\r\n paddingLeft: `${theme.spacing(1.5)}px !important`\r\n },\r\n \"& th:last-child\": {\r\n paddingRight: `${theme.spacing(1.5)}px !important`\r\n },\r\n \"& th:first-child\": {\r\n paddingLeft: `${theme.spacing(1.5)}px !important`\r\n }\r\n }\r\n }),\r\n);\r\n\r\n/** Column header with label and checkbox */\r\nexport const EnhancedTableCheckboxHead = (props: EnhancedTableCheckboxHeadProps) => {\r\n const {label, values, onChange} = props;\r\n\r\n const numVisible = values.filter(x => x === true).length;\r\n const checked = numVisible > 0;\r\n const indeterminate = checked && (values.length !== numVisible);\r\n\r\n return (\r\n \r\n {\r\n // Stop click event from triggering sort function\r\n event.stopPropagation();\r\n }}\r\n onChange={(event) => {\r\n onChange(indeterminate || event.target.checked);\r\n }}\r\n />\r\n\r\n {label}\r\n \r\n );\r\n};\r\n\r\nconst EnhancedTableHead = (props: EnhancedTableHeadProps) => {\r\n const {sortDir, sortBy, onRequestSort, columns, actions, dense} = props;\r\n\r\n const classes = useStyles();\r\n\r\n const createSortHandler = (property) => (event) => {\r\n onRequestSort(event, property);\r\n };\r\n\r\n const hasActions = actions.length > 0;\r\n\r\n return (\r\n \r\n \r\n {columns.map(column => {\r\n\r\n const {id, label, center, sortable=true} = column;\r\n\r\n return (\r\n \r\n {/* Non-sortable column header */}\r\n {!sortable && \r\n {label}\r\n }\r\n\r\n {/* Sortable column header */}\r\n {sortable && \r\n {label}\r\n {sortBy === id ? (\r\n \r\n {sortDir === 'desc' ? 'sorted descending' : 'sorted ascending'}\r\n \r\n ) : null}\r\n }\r\n \r\n );\r\n })}\r\n\r\n {/** Custom actions */}\r\n {hasActions && }\r\n\r\n \r\n \r\n );\r\n};\r\n\r\nconst EnhancedTableBody = (props: EnhancedTableBodyProps) => {\r\n const {rows, actions, columns, onClick, dense,\r\n setSelectedRow, handleContextMenu} = props;\r\n\r\n const classes = useStyles();\r\n const hasActions = actions.length > 0;\r\n\r\n return (\r\n \r\n {rows.map(row =>\r\n \r\n {columns.map((column, index) =>\r\n \r\n )}\r\n\r\n {/** Custom actions */}\r\n {hasActions && \r\n {\r\n setSelectedRow(row);\r\n handleContextMenu(event);\r\n }}\r\n >\r\n \r\n \r\n }\r\n\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nconst EnhancedTableCell = (props: EnhancedTableCellProps) => {\r\n const {row, column, dense, index, onClick} = props;\r\n\r\n const theme = useTheme();\r\n const {i18n} = useTranslation();\r\n\r\n const key = `${row.id}_${column.id}`;\r\n const text = row[column.id] as any;\r\n const isString = typeof(text) === \"string\";\r\n const condition = (column.numeric || text.length <= 100);\r\n\r\n const cellContent = (column, content, condition) => {\r\n if (column.date) {\r\n const dateString = toLocaleString(content, i18n.language);\r\n return dateString;\r\n }\r\n\r\n const renderAsHTML = isString\r\n ? isHtml(content)\r\n : false;\r\n\r\n if (renderAsHTML) {\r\n if (column.tooltip) {\r\n return (\r\n \r\n
\r\n \r\n );\r\n } else {\r\n return (\r\n
\r\n );\r\n }\r\n }\r\n\r\n if (isString) {\r\n content = condition ? content : `${content.slice(0,100)}...`;\r\n }\r\n\r\n if (column.tooltip) {\r\n return (\r\n \r\n
\r\n {content}\r\n
\r\n
\r\n );\r\n }\r\n\r\n return content;\r\n };\r\n\r\n const title = isString ? text : \"\";\r\n const content = cellContent(column, text, condition);\r\n\r\n return (\r\n {\r\n if (row.disabled || !onClick) return;\r\n onClick(row, index);\r\n }}\r\n style={{\r\n ...(column.wordBreak && {\r\n wordBreak: \"break-all\"\r\n }),\r\n ...(column.forceOpacity && {\r\n opacity: 1.0\r\n }),\r\n ...(column.pointer && {\r\n cursor: \"pointer\"\r\n }),\r\n ...(column.center && {\r\n textAlign: \"center\"\r\n }),\r\n ...(dense && {\r\n padding: `${theme.spacing(0.5)}px ${theme.spacing(1.0)}px`\r\n })\r\n }}\r\n title={title}\r\n >\r\n {content}\r\n \r\n );\r\n};\r\n\r\nexport const EnhancedTable = (props: EnhancedTableProps) => {\r\n const {state, columns, rows, actions=[], onClick,\r\n dense = true, maxHeight} = props;\r\n\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n const {t} = useTranslation();\r\n\r\n const contextMenu = useContextMenu();\r\n\r\n const [search, setSearch] = useState(\"\");\r\n const [selectedRow, setSelectedRow] = useState(null);\r\n\r\n const onSearch = (event) => {\r\n const value = event.target.value;\r\n state.handleSearchChange(value);\r\n setSearch(value);\r\n };\r\n\r\n useEffect(() => {\r\n // Restore previously saved search terms\r\n //setSearch(state.query);\r\n\r\n // Reset the search string\r\n setSearch(\"\");\r\n state.handleSearchChange(\"\");\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (state.pageNumber <= maxPageNumber) return;\r\n state.handlePageNumberChange(null, maxPageNumber);\r\n }, [state.pageNumber, rows]);\r\n\r\n let tableRows = state.handleSearch(columns, [...rows]);\r\n\r\n // Number of rows must be calculated after\r\n // search and before pagination\r\n const numberOfRows = tableRows.length;\r\n\r\n tableRows = state.handleSort(tableRows);\r\n tableRows = state.handlePages(tableRows);\r\n\r\n // Make sure our max page is valid\r\n const maxPageNumber = Math.max(\r\n 0, Math.ceil(numberOfRows / state.rowsPerPage) - 1);\r\n const pageNumber = Math.min(state.pageNumber, maxPageNumber);\r\n\r\n const searchable = columns.filter(\r\n column => column.searchable).length > 0;\r\n\r\n return (\r\n \r\n
\r\n \r\n\r\n {/** Search bar */}\r\n {searchable && }\r\n />}\r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n\r\n \r\n `${page.from}–${page.to} ${t(\"enhanced-table.displayed-rows-of\")} ${page.count !== -1 ?\r\n page.count : `${t(\"enhanced-table.displayed-rows-more-than\")} ${page.to}`}`\r\n }\r\n backIconButtonText={t(\"enhanced-table.prev-page\")}\r\n nextIconButtonText={t(\"enhanced-table.next-page\")}\r\n page={pageNumber}\r\n classes={{\r\n toolbar: dense ? classes.denseFooter : \"\"\r\n }}\r\n onChangePage={state.handlePageNumberChange}\r\n onChangeRowsPerPage={state.handleRowsPerPageChange}\r\n />\r\n\r\n \r\n
\r\n\r\n {/** Context menu */}\r\n \r\n {actions.map((action, index) =>\r\n {\r\n if (!selectedRow) return;\r\n action.onClick(selectedRow);\r\n contextMenu.handleClose();\r\n }}\r\n >\r\n \r\n {action.icon}\r\n \r\n\r\n \r\n {action.title}\r\n \r\n \r\n )}\r\n \r\n\r\n
\r\n );\r\n};\r\n","import React, { useEffect, useImperativeHandle, useRef, useState } from \"react\";\r\nimport { DenseIcon } from \"./dense-icon\";\r\nimport { Divider, Grow, makeStyles, Menu, MenuItem, MenuItemProps, Typography, useTheme } from \"@material-ui/core\";\r\nimport ArrowRight from '@material-ui/icons/ArrowRight';\r\nimport clsx from 'clsx';\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n subMenuRoot: (props: any) => ({\r\n justifyContent: \"space-between\",\r\n backgroundColor: props.open\r\n ? theme.palette.action.hover\r\n : 'rgba(0,0,0,0)'\r\n }),\r\n subMenuLabel: {\r\n display: \"flex\",\r\n alignItems: \"center\"\r\n }\r\n}));\r\n\r\ninterface NestedMenuItemProps extends Omit {\r\n parentMenuOpen: boolean\r\n label?: React.ReactNode\r\n rightIcon?: React.ReactNode\r\n dense: boolean,\r\n ContainerProps?: React.HTMLAttributes & React.RefAttributes\r\n button?: true | undefined\r\n}\r\n\r\n/**\r\n * https://github.com/azmenak/material-ui-nested-menu-item\r\n * Modifications have been made to close submenu when open is false.\r\n * This is required because we use keepMounted on all of our menus. Also\r\n * modified the right arrow to be better aligned\r\n**/\r\nconst NestedMenuItem = React.forwardRef((props: NestedMenuItemProps, ref) => {\r\n const {\r\n parentMenuOpen,\r\n label,\r\n rightIcon = ,\r\n dense = false,\r\n children,\r\n className,\r\n tabIndex: tabIndexProp,\r\n ContainerProps: ContainerPropsProp = {},\r\n ...MenuItemProps\r\n } = props;\r\n\r\n const {ref: containerRefProp, ...ContainerProps} = ContainerPropsProp;\r\n\r\n const menuItemRef = useRef(null);\r\n useImperativeHandle(ref, () => menuItemRef.current);\r\n\r\n const containerRef = useRef(null);\r\n useImperativeHandle(containerRefProp, () => containerRef.current);\r\n\r\n const menuContainerRef = useRef(null);\r\n\r\n const [isSubMenuOpen, setIsSubMenuOpen] = useState(false);\r\n\r\n const handleMouseEnter = (event: React.MouseEvent) => {\r\n setIsSubMenuOpen(true);\r\n\r\n if (ContainerProps?.onMouseEnter) {\r\n ContainerProps.onMouseEnter(event);\r\n }\r\n };\r\n\r\n const handleMouseLeave = (event: React.MouseEvent) => {\r\n setIsSubMenuOpen(false);\r\n\r\n if (ContainerProps?.onMouseLeave) {\r\n ContainerProps.onMouseLeave(event);\r\n }\r\n };\r\n\r\n // Check if any immediate children are active\r\n const isSubmenuFocused = () => {\r\n const active = containerRef.current?.ownerDocument?.activeElement;\r\n for (const child of menuContainerRef.current?.children ?? []) {\r\n if (child === active) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n };\r\n\r\n const handleFocus = (event: React.FocusEvent) => {\r\n if (event.target === containerRef.current) {\r\n setIsSubMenuOpen(true);\r\n }\r\n\r\n if (ContainerProps?.onFocus) {\r\n ContainerProps.onFocus(event);\r\n }\r\n };\r\n\r\n const handleKeyDown = (event: React.KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n return;\r\n }\r\n\r\n if (isSubmenuFocused()) {\r\n event.stopPropagation();\r\n }\r\n\r\n const active = containerRef.current?.ownerDocument?.activeElement;\r\n\r\n if (event.key === 'ArrowLeft' && isSubmenuFocused()) {\r\n containerRef.current?.focus();\r\n }\r\n\r\n if (\r\n event.key === 'ArrowRight' &&\r\n event.target === containerRef.current &&\r\n event.target === active\r\n ) {\r\n const firstChild = menuContainerRef.current?.children[0] as\r\n | HTMLElement\r\n | undefined;\r\n firstChild?.focus();\r\n }\r\n };\r\n\r\n /** Custom Code */\r\n useEffect(() => {\r\n setIsSubMenuOpen(false);\r\n }, [parentMenuOpen]);\r\n\r\n const open = isSubMenuOpen && parentMenuOpen;\r\n const classes = useStyles({open});\r\n\r\n // Root element must have a `tabIndex` attribute for keyboard navigation\r\n let tabIndex;\r\n if (!props.disabled) {\r\n tabIndex = tabIndexProp !== undefined ? tabIndexProp : -1;\r\n }\r\n\r\n return (\r\n \r\n \r\n {/** Custom Code */}\r\n
{label}
\r\n
{rightIcon}
\r\n \r\n\r\n {\r\n setIsSubMenuOpen(false);\r\n }}\r\n >\r\n
\r\n {children}\r\n
\r\n \r\n
\r\n );\r\n});\r\n\r\ninterface NestedMenuProps {\r\n parentMenuOpen: boolean;\r\n text: string;\r\n ref?: any;\r\n icon: any;\r\n children: any;\r\n}\r\n\r\nexport const NestedMenu = React.forwardRef((props: NestedMenuProps, ref) => {\r\n const {parentMenuOpen, text, icon} = props;\r\n\r\n return (\r\n \r\n {icon}\r\n {text}\r\n \r\n }\r\n ref={ref}\r\n parentMenuOpen={parentMenuOpen}\r\n >\r\n {props.children}\r\n \r\n );\r\n});\r\n\r\nexport const MenuDivider = React.forwardRef((props: any, ref) => {\r\n const {...other} = props;\r\n\r\n return (\r\n \r\n );\r\n});\r\n\r\ninterface DenseMenuProps {\r\n open: boolean;\r\n onClose(): void;\r\n onEnter?(): void;\r\n anchorPosition: {left: number, top: number};\r\n keepMounted?: boolean;\r\n children: any;\r\n}\r\n\r\nexport const DenseMenu = React.forwardRef((props: DenseMenuProps, ref) => {\r\n const {children, keepMounted=true, ...other} = props;\r\n\r\n const theme = useTheme();\r\n\r\n const {enteringScreen} = theme.transitions.duration;\r\n\r\n const transitionProps = {\r\n timeout: {\r\n enter: enteringScreen,\r\n exit: 0\r\n }\r\n };\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n});\r\n\r\n","import React, {\r\n useCallback,\r\n useEffect,\r\n useState,\r\n} from \"react\";\r\nimport {\r\n createStyles,\r\n InputAdornment,\r\n InputLabel,\r\n makeStyles,\r\n MenuItem,\r\n Select,\r\n Switch,\r\n TextField,\r\n Theme,\r\n Typography,\r\n IconButton,\r\n Input,\r\n useTheme,\r\n} from \"@material-ui/core\";\r\nimport clsx from 'clsx';\r\nimport slash from 'slash';\r\nimport { dialog } from \"../electron-modules\";\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport { UnitConverter } from \"../viewer/js/utilities\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport FolderIcon from \"@material-ui/icons/Folder\";\r\nimport {AttachFile, Delete, Save} from \"@material-ui/icons\";\r\nimport { MenuDivider } from \"./menu-items\";\r\nimport isHtml from 'is-html';\r\n\r\nconst converter = new UnitConverter();\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n flexibleHeight: {\r\n height: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"space-between\",\r\n \"& span\": {\r\n flex: 1\r\n }\r\n },\r\n filePath: {\r\n wordBreak: \"break-word\"\r\n },\r\n fileButtonDiv: {\r\n paddingTop: theme.spacing(1),\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n dropdownWithLabel: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"space-between\",\r\n \"& span\": {\r\n flex: 1\r\n }\r\n },\r\n paddingBottom: {\r\n paddingBottom: `${theme.spacing(1)}px !important`,\r\n },\r\n inputParent: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n minHeight: theme.spacing(3),\r\n paddingBottom: theme.spacing(0.5)\r\n },\r\n inputLabel: {\r\n height: \"fit-content\"\r\n },\r\n inputSwitch: {\r\n marginTop: \"-0.25rem\"\r\n },\r\n inputFolder: {\r\n padding: theme.spacing(0.5),\r\n marginBottom: theme.spacing(-0.5)\r\n },\r\n error: {\r\n color: theme.palette.error.main\r\n },\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n })\r\n);\r\n\r\n// TODO: add props for NumberField / NumberFieldWithLabel\r\n\r\nexport const NumberField = (props) => {\r\n const {units=false, ...other} = props;\r\n\r\n return units\r\n ? \r\n : ;\r\n};\r\n\r\nexport const NumberFieldWithLabel = (props) => {\r\n const {title, label, ...other} = props;\r\n\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n
\r\n {title}\r\n
\r\n\r\n \r\n {label}\r\n \r\n\r\n \r\n
\r\n );\r\n};\r\n\r\nconst NumberFieldNoUnits = (props) => {\r\n const {data, setData, min, max, adornment, step=1.0, index=0, ...other} = props;\r\n\r\n const {t} = useTranslation();\r\n\r\n // NOTE: Space character is required for even positioning in UI\r\n const helperText = data.error\r\n ? t('dialog.accepted-range-is-min-max', {min, max})\r\n : undefined;\r\n\r\n const endAdornment = adornment\r\n ? {adornment}\r\n : null;\r\n\r\n return (\r\n {\r\n let hasError = false;\r\n\r\n let floatValue = parseFloat(event.target.value);\r\n if (isNaN(floatValue)) {\r\n hasError = true;\r\n }\r\n\r\n if (floatValue > max) {\r\n hasError = true;\r\n } else if (floatValue < min) {\r\n hasError = true;\r\n }\r\n\r\n setData({\r\n value: event.target.value,\r\n error: hasError,\r\n index: index\r\n });\r\n }}\r\n />\r\n );\r\n};\r\n\r\nconst NumberFieldWithUnits = (props) => {\r\n const {data, min, max, setData, step=1.0, ...other} = props;\r\n const units = LocalScene.viewProjectionUnits;\r\n\r\n const [convertedMin, setConvertedMin] = useState(0);\r\n const [convertedMax, setConvertedMax] = useState(0);\r\n const [convertedData, setConvertedData] = useState({\r\n value: 0,\r\n error: false\r\n });\r\n\r\n const convertNearestStep = (value, roundFunc) => {\r\n if (units === \"m\") {\r\n return value;\r\n };\r\n\r\n const converted = converter.convert(value, \"m\", units, 2);\r\n let numSteps = roundFunc(converted / step);\r\n return parseFloat((numSteps * step).toFixed(2));\r\n };\r\n\r\n useEffect(() => {\r\n // Initial conversion from meters to new units\r\n setConvertedMin(convertNearestStep(min, Math.floor));\r\n setConvertedMax(convertNearestStep(max, Math.ceil));\r\n setConvertedData({\r\n value: convertNearestStep(data.value, Math.floor),\r\n error: data.error\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n // Update the original state\r\n setData({...convertedData});\r\n }, [convertedData]);\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\ninterface DropdownWithLabelProps {\r\n title: string;\r\n label?: string;\r\n value: string | number;\r\n onChange: Function;\r\n disabled?: boolean;\r\n seperator?: number[]\r\n options: [value: any, text: string][];\r\n}\r\n\r\nexport const DropdownWithLabel = (props: DropdownWithLabelProps) => {\r\n const {title, label, value, onChange, disabled=false,\r\n seperator, options} = props;\r\n\r\n const classes = useStyles();\r\n\r\n let menuOptions = [];\r\n\r\n options.forEach((data, index) => {\r\n const [value, text] = data;\r\n\r\n menuOptions.push((\r\n \r\n {text}\r\n \r\n ));\r\n\r\n const hasSeperator = seperator && seperator.includes(index);\r\n const isLastItem = index === options.length - 1;\r\n\r\n if (hasSeperator && !isLastItem) {\r\n menuOptions.push((\r\n \r\n ));\r\n }\r\n });\r\n\r\n return (\r\n
\r\n
\r\n \r\n {title}\r\n \r\n
\r\n\r\n {label && \r\n {label}\r\n }\r\n\r\n {\r\n onChange(event.target.value);\r\n }}\r\n >\r\n {menuOptions}\r\n \r\n
\r\n );\r\n};\r\n\r\ninterface FolderWithLabelProps {\r\n title: string;\r\n label?: string;\r\n value: string | number;\r\n onChange: Function;\r\n}\r\n\r\nexport const FolderWithLabel = (props: FolderWithLabelProps) => {\r\n const {title, label, value, onChange} = props;\r\n const classes = useStyles();\r\n\r\n const handleFolderChange = async () => {\r\n const result = await dialog.showOpenDialog({\r\n properties: ['openDirectory']\r\n });\r\n\r\n if (result.canceled) return;\r\n let folderPath = slash(result.filePaths[0]);\r\n onChange(folderPath);\r\n };\r\n\r\n return (\r\n
\r\n
\r\n \r\n {title}\r\n \r\n\r\n \r\n \r\n \r\n
\r\n\r\n \r\n {value ? value : label}\r\n \r\n
\r\n );\r\n};\r\n\r\ninterface FileWithLabelProps {\r\n title: string;\r\n label?: string;\r\n filter: {name: string; extensions: string[]}[]\r\n value: string | number;\r\n onChange: Function;\r\n optional?: boolean;\r\n saveFile?: boolean;\r\n}\r\n\r\nexport const FileWithLabel = (props: FileWithLabelProps) => {\r\n const {title, label, filter, value, onChange,\r\n optional=false, saveFile=false} = props;\r\n\r\n const classes = useStyles();\r\n\r\n const handleFileChange = () => {\r\n dialog.showOpenDialog({\r\n title: title,\r\n properties: ['openFile'],\r\n filters: filter\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n\r\n let folderPath = slash(result.filePaths[0]);\r\n onChange(folderPath);\r\n });\r\n };\r\n\r\n const handleSaveFileChange = () => {\r\n dialog.showSaveDialog({\r\n title: title,\r\n filters: filter\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n onChange(result.filePath);\r\n });\r\n };\r\n\r\n const handleChange = saveFile\r\n ? handleSaveFileChange\r\n : handleFileChange;\r\n\r\n return (\r\n
\r\n
\r\n \r\n {title}\r\n \r\n\r\n
\r\n {value && optional && ( {\r\n onChange(null);\r\n }}\r\n >\r\n \r\n )}\r\n\r\n \r\n {saveFile ? \r\n : }\r\n \r\n
\r\n\r\n
\r\n\r\n \r\n {value ? value : label}\r\n \r\n
\r\n );\r\n};\r\n\r\ninterface InputWithLabelProps {\r\n title: string;\r\n label?: string | JSX.Element;\r\n value: string | number;\r\n onChange: Function;\r\n required?: boolean;\r\n disabled?: boolean;\r\n error?: boolean;\r\n multiline?: boolean;\r\n placeholder?: string;\r\n}\r\n\r\nexport const InputWithLabel = (props: InputWithLabelProps) => {\r\n const classes = useStyles();\r\n const {value, title, onChange, label, required=true,\r\n disabled=false, error=false, ...other} = props;\r\n\r\n const [touched, setTouched] = useState(false);\r\n\r\n const onInputChange = useCallback((event) => {\r\n onChange(event.target.value);\r\n }, [onChange]);\r\n\r\n const onBlur = useCallback(() => {\r\n setTouched(true);\r\n }, []);\r\n\r\n return (\r\n
\r\n
\r\n {title}\r\n
\r\n\r\n \r\n\r\n \r\n {label}\r\n \r\n
\r\n );\r\n};\r\n\r\ninterface TextWithLabelProps {\r\n title: string\r\n value?: string\r\n label?: string | JSX.Element\r\n}\r\n\r\nexport const TextWithLabel = (props: TextWithLabelProps) => {\r\n const {title, label, value} = props;\r\n\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n const renderAsHTML = (typeof value === \"string\") ? isHtml(value) : false;\r\n\r\n return (\r\n
\r\n
\r\n {title}\r\n
\r\n\r\n {value && \r\n {renderAsHTML && }\r\n\r\n {!renderAsHTML && \r\n {value}\r\n }\r\n }\r\n\r\n {label && \r\n {label}\r\n }\r\n
\r\n );\r\n};\r\n\r\ninterface CheckboxWithLabelProps {\r\n title: string;\r\n label?: string;\r\n value: boolean;\r\n onChange: Function;\r\n}\r\n\r\nexport const CheckboxWithLabel = (props: CheckboxWithLabelProps) => {\r\n const {title, label, value, onChange} = props;\r\n\r\n const classes = useStyles();\r\n\r\n const onCheckboxChange = useCallback((_, checked) => {\r\n onChange(checked);\r\n }, [onChange]);\r\n\r\n return (\r\n
\r\n
\r\n \r\n {title}\r\n \r\n\r\n \r\n
\r\n\r\n \r\n {label}\r\n \r\n
\r\n );\r\n};","import React from 'react';\r\nimport {\r\n Box,\r\n LinearProgress,\r\n LinearProgressProps,\r\n Typography\r\n} from '@material-ui/core';\r\nimport { roundDigit } from '../viewer/js/utilities';\r\n\r\n// TODO: replace other linear progress with label with this (might need extra customization)\r\n\r\nexport const LinearProgressWithLabel = (props: LinearProgressProps & { value: number }) => {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {`${roundDigit(props.value, 2)}%`}\r\n \r\n \r\n \r\n );\r\n};\r\n","import React from 'react';\r\nimport {Box} from '@material-ui/core';\r\n\r\nexport const TabPanel = (props) => {\r\n const {children, classes, value, index, ...other} = props;\r\n\r\n const panel = classes?.panel ? classes.panel : undefined;\r\n const box = classes?.box ? classes.box : undefined;\r\n const visible = value === index;\r\n\r\n return (\r\n \r\n {visible && \r\n \r\n {children}\r\n \r\n
}\r\n \r\n );\r\n};\r\n\r\nexport const TabProps = (index) => {\r\n return {\r\n id: `tab-${index}`,\r\n 'aria-controls': `tabpanel-${index}`,\r\n };\r\n};\r\n\r\nexport const PanelProps = (value, index) => {\r\n return {\r\n value: value,\r\n index: index\r\n };\r\n};\r\n","import {\r\n Button,\r\n Chip,\r\n createStyles,\r\n Divider,\r\n Icon,\r\n makeStyles,\r\n Theme,\r\n Typography,\r\n useTheme\r\n} from \"@material-ui/core\";\r\nimport React, { useEffect, useState } from \"react\";\r\nimport clsx from 'clsx';\r\nimport { ArrowTooltip } from \".\";\r\nimport { Scrollbars } from 'react-custom-scrollbars';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { DividerProps } from \"@material-ui/core/Divider\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n verticalDivider: {\r\n padding: theme.spacing(0.5, 0.25),\r\n display: \"flex\",\r\n alignItems: \"center\"\r\n },\r\n icons: {\r\n '& > .fa': {\r\n margin: theme.spacing(2),\r\n },\r\n display: \"flex\",\r\n padding: theme.spacing(0.5),\r\n },\r\n iconButton: {\r\n minWidth: \"0px !important\",\r\n flex: 1\r\n },\r\n iconSize: {\r\n fontSize: \"1.0em\",\r\n width: \"auto\"\r\n },\r\n success: {\r\n color: theme.palette.success.main\r\n },\r\n error: {\r\n color: theme.palette.error.main\r\n },\r\n disabled: {\r\n opacity: 0.3\r\n },\r\n listIcon: {\r\n color: \"rgba(0, 0, 0, 0.54)\",\r\n fontSize: \"20px\"\r\n }\r\n })\r\n);\r\n\r\ninterface DenseDividerProps extends DividerProps {\r\n spacing?: number[] | number;\r\n}\r\n\r\nexport const DenseDivider = (props: DenseDividerProps) => {\r\n const {spacing, ...other} = props;\r\n\r\n let spacingDown;\r\n let spacingUp;\r\n\r\n if (typeof(spacing) == \"number\") {\r\n spacingDown = spacing;\r\n spacingUp = spacing;\r\n } else if (typeof(spacing) == \"object\") {\r\n spacingUp = spacing[0];\r\n spacingDown = spacing[1];\r\n } else {\r\n spacingUp = 20;\r\n spacingDown = 20;\r\n }\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\ninterface DividerWithTextProps {\r\n label: string;\r\n paddingTop?: number;\r\n paddingBottom?: number;\r\n}\r\n\r\n/**\r\n * Creates a divider with a chip element in the middle. Something\r\n * similar exists in the new material ui (5.x and up), but not in\r\n * our version (4.x), so we make our own instead.\r\n */\r\nexport const DividerWithText = (props: DividerWithTextProps) => {\r\n const theme = useTheme();\r\n\r\n const {label, paddingTop=32, paddingBottom=0} = props;\r\n\r\n return (\r\n
\r\n
\r\n\r\n \r\n \r\n \r\n\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport const IconToolBar = (props) => {\r\n const classes = useStyles();\r\n const {children, margin} = props;\r\n\r\n return (\r\n
\r\n {children}\r\n
\r\n );\r\n};\r\n\r\nexport const ToolBarDivider = () => {\r\n const classes = useStyles();\r\n\r\n return (\r\n {\"|\"}\r\n );\r\n};\r\n\r\nexport const FontAwesomeIcon = (props) => {\r\n const classes = useStyles();\r\n const {icon, color, success, error, disabled, listIcon} = props;\r\n const errorColor = error ? classes.error : \"\";\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport const ToolBarButton = (props) => {\r\n const {icon, visible, title, onClick, color, success,\r\n error, disabled, ...other} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const isVisible = visible !== undefined ? visible : true;\r\n const tooltipText = disabled ? `${title} (${t('toolbar.button-disabled')})` : title;\r\n\r\n return (\r\n \r\n {isVisible && (\r\n \r\n \r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport const SlimScrollbar = (props) => {\r\n const {scrollHeight, children} = props;\r\n\r\n return (\r\n \r\n {/** Use scroll height that was passed in */}\r\n {scrollHeight && (\r\n {children}\r\n )}\r\n\r\n {/** No scroll height was provided */}\r\n {!scrollHeight && (\r\n {children}\r\n )}\r\n \r\n );\r\n};\r\n\r\nexport const DynamicScrollbar = (props) => {\r\n const {scrollHeight, scrollPercent, children} = props;\r\n\r\n const [scroll, setScroll] = useState(false);\r\n const [maxHeight, setMaxHeight] = useState(0);\r\n const listElementID = useState(nanoid())[0];\r\n\r\n const getMaxHeight = () => {\r\n const percentHeight = (scrollPercent/100) * window.innerHeight;\r\n return Math.min(scrollHeight, percentHeight);\r\n };\r\n\r\n const checkScrollHeight = () => {\r\n let element = document.getElementById(listElementID);\r\n if (!element) return;\r\n\r\n const height = element.offsetHeight;\r\n const maxHeight = getMaxHeight();\r\n\r\n setScroll(height > maxHeight);\r\n setMaxHeight(maxHeight);\r\n };\r\n\r\n useEffect(() => {\r\n checkScrollHeight();\r\n window.addEventListener('resize', checkScrollHeight);\r\n\r\n return () => {\r\n window.removeEventListener('resize', checkScrollHeight);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n checkScrollHeight();\r\n }, [children, window.innerHeight]);\r\n\r\n return (\r\n \r\n {(!scroll) && (\r\n
\r\n {children}\r\n
\r\n )}\r\n\r\n {(scroll) && (\r\n \r\n
\r\n {children}\r\n
\r\n
\r\n )}\r\n
\r\n );\r\n};","\r\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\r\nimport {\r\n Grow,\r\n Tooltip,\r\n useTheme\r\n} from \"@material-ui/core\";\r\n\r\nexport const ArrowTooltip = (props) => {\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};\r\n\r\ninterface CursorTooltipProps {\r\n textLines: string[]\r\n children: any\r\n}\r\n\r\ntype TooltipPosition = {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport const CursorTooltip = memo((props: CursorTooltipProps) => {\r\n const {textLines, children} = props;\r\n\r\n const theme = useTheme();\r\n\r\n const [position, setPosition] = useState({\r\n x: undefined,\r\n y: undefined\r\n });\r\n\r\n const title = useMemo(() => {\r\n return textLines.map((line, index) => (\r\n \r\n {(index !== 0) && (
)}\r\n {line}\r\n
\r\n ));\r\n }, [textLines]);\r\n\r\n const onClose = useCallback(() => {\r\n setPosition({\r\n x: undefined,\r\n y: undefined\r\n });\r\n }, []);\r\n\r\n const onMouseMove = useCallback((event) => {\r\n setPosition({\r\n x: event.pageX,\r\n y: event.pageY\r\n });\r\n }, []);\r\n\r\n const visible = (textLines.length > 0)\r\n && (position.x !== undefined);\r\n\r\n const {enteringScreen} = theme.transitions.duration;\r\n\r\n const transitionProps = {\r\n timeout: {\r\n enter: enteringScreen,\r\n exit: 0\r\n }\r\n };\r\n\r\n return (\r\n ({\r\n top: position.y,\r\n left: position.x,\r\n right: position.x,\r\n bottom: position.y,\r\n width: 0,\r\n height: 0\r\n } as any)\r\n }\r\n }}\r\n >\r\n {children}\r\n \r\n );\r\n});","import { memo } from \"react\";\r\n\r\n/** Component that only gets evaluated when the open state is modified */\r\nexport const memoWithOpen = (component) => {\r\n const areEqual = (prevProps, nextProps) => {\r\n return prevProps.open === nextProps.open;\r\n };\r\n\r\n return memo(component, areEqual);\r\n};","import {\r\n dialog,\r\n getCurrentWindow,\r\n Menu,\r\n isDevMode,\r\n remote,\r\n shell,\r\n logDirectoryPath,\r\n app\r\n} from './electron-modules';\r\nimport {\r\n WorkflowExecutable,\r\n PythonExecutable\r\n} from \"./executable\";\r\nimport {t} from './localization';\r\n\r\nconst menuStateCache = {} as any;\r\n\r\nconst fileMenu = {\r\n get label() {\r\n return t(\"electron-menu.file.header\");\r\n },\r\n submenu: [\r\n {\r\n get label() {\r\n return t(\"electron-menu.file.open-workflow\");\r\n },\r\n click: async () => {\r\n new WorkflowExecutable().run({command: []});\r\n }\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.file.global-settings\");\r\n },\r\n click: async () => {\r\n sendToMainWindow('open-global-settings');\r\n }\r\n },\r\n {\r\n type: 'separator'\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.file.new-project\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"new-project\");\r\n }\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.file.open-project\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"load-project\");\r\n }\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.file.open-project-cloud\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-cloud-projects\");\r\n }\r\n },\r\n {\r\n id: \"save-project\",\r\n get label() {\r\n return t(\"electron-menu.file.save-project\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"save-project\");\r\n }\r\n },\r\n {\r\n id: \"save-project-as\",\r\n get label() {\r\n return t(\"electron-menu.file.save-as\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"save-project-as\");\r\n }\r\n },\r\n {\r\n type: 'separator'\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.file.exit-without-saving\");\r\n },\r\n click: async () => {\r\n app.exit();\r\n }\r\n },\r\n ]\r\n};\r\n\r\nconst helpMenu = {\r\n get label() {\r\n return t(\"electron-menu.help.header\");\r\n },\r\n submenu: [\r\n {\r\n get label() {\r\n return t(\"electron-menu.help.about\");\r\n },\r\n click: async () => {\r\n sendToMainWindow('open-about');\r\n },\r\n },\r\n {\r\n visible: isDevMode,\r\n accelerator: 'Shift+F12',\r\n get label() {\r\n return t(\"electron-menu.help.dev-tools\");\r\n },\r\n click: () => {\r\n const mainWindow = remote.getCurrentWindow();\r\n mainWindow.toggleDevTools();\r\n },\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.help.open-logs\");\r\n },\r\n click: async () => {\r\n shell.openPath(logDirectoryPath);\r\n }\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.help.clear-cache\");\r\n },\r\n click: async () => {\r\n clearMlResources();\r\n }\r\n },\r\n {\r\n get label() {\r\n return t(\"electron-menu.help.support\");\r\n },\r\n click: async () => {\r\n shell.openExternal('https://solv3d.com/support/');\r\n }\r\n },\r\n ]\r\n};\r\n\r\nconst toolsMenu = {\r\n id: 'tools',\r\n get label() {\r\n return t(\"electron-menu.tools.header\");\r\n },\r\n submenu: [\r\n {\r\n id: 'projections',\r\n get label() {\r\n return t(\"electron-menu.tools.projections.header\");\r\n },\r\n submenu: [\r\n {\r\n id: 'projection-manager',\r\n get label() {\r\n return t(\"electron-menu.tools.projections.manager\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-projection-manager\");\r\n }\r\n },\r\n {\r\n id: 'local-projections',\r\n get label() {\r\n return t(\"electron-menu.tools.projections.local\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-local-projection\");\r\n }\r\n },\r\n ]\r\n },\r\n {\r\n id: \"aligner-menu\",\r\n get label() {\r\n return t(\"electron-menu.tools.data-aligner.header\");\r\n },\r\n submenu: [\r\n {\r\n id: 'aligner-advanced-menu',\r\n enabled: false,\r\n get label() {\r\n return t(\"electron-menu.tools.data-aligner.advanced\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-image-aligner-adv\");\r\n }\r\n },\r\n {\r\n id: 'aligner-basic-menu',\r\n enabled: false,\r\n get label() {\r\n return t(\"electron-menu.tools.data-aligner.basic\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-image-aligner-basic\");\r\n }\r\n },\r\n ]\r\n },\r\n {\r\n id: \"training-menu\",\r\n get label() {\r\n return t(\"electron-menu.tools.training.header\");\r\n },\r\n submenu: [\r\n {\r\n id: 'label-ortho-menu',\r\n enabled: false,\r\n get label() {\r\n return t(\"electron-menu.tools.training.ortho\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-label-ortho\");\r\n }\r\n },\r\n {\r\n id: 'label-scene-menu',\r\n get label() {\r\n return t(\"electron-menu.tools.training.scene\");\r\n },\r\n enabled: false,\r\n click: async () => {\r\n sendToMainWindow(\"open-label-scene\");\r\n }\r\n },\r\n ]\r\n },\r\n {\r\n id: 'point-markup-menu',\r\n get label() {\r\n return t(\"electron-menu.tools.markup.header\");\r\n },\r\n submenu: [\r\n {\r\n id: \"point-markup\",\r\n get label() {\r\n return t(\"electron-menu.tools.markup.modify\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-point-markup\");\r\n }\r\n },\r\n {\r\n id: \"data-splitting\",\r\n get label() {\r\n return t(\"electron-menu.tools.markup.split\");\r\n },\r\n click: async () => {\r\n sendToMainWindow(\"open-data-splitting\");\r\n }\r\n },\r\n ]\r\n },\r\n {\r\n id: 'exporter-menu',\r\n get label() {\r\n return t(\"electron-menu.tools.export.header\");\r\n },\r\n submenu: [\r\n {\r\n id: \"static-exporter-menu\",\r\n get label() {\r\n return t(\"electron-menu.tools.export.local\");\r\n },\r\n enabled: false,\r\n click: async () => {\r\n sendToMainWindow(\"open-static-export\");\r\n }\r\n },\r\n {\r\n id: \"cloud-exporter-menu\",\r\n get label() {\r\n return t(\"electron-menu.tools.export.cloud\");\r\n },\r\n enabled: false,\r\n click: async () => {\r\n sendToMainWindow(\"open-cloud-export\");\r\n }\r\n }\r\n ]\r\n }\r\n ]\r\n};\r\n\r\nconst debugMenu = {\r\n get label() {\r\n return t(\"electron-menu.debug.refresh\");\r\n },\r\n click: () => {\r\n getCurrentWindow().reload();\r\n }\r\n};\r\n\r\nconst sendToMainWindow = (message, payload=null) => {\r\n const mainWindow = remote.getCurrentWindow();\r\n mainWindow.webContents.send(message, payload);\r\n};\r\n\r\nconst clearMlResources = () => {\r\n let exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", \"remove_ml_resources\",\r\n \"--remove\", true\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onClose: () => {\r\n dialog.showMessageBox({\r\n type: 'info',\r\n title: t(\"dialog.clear-cache-title\"),\r\n message: t(\"dialog.clear-cache-message\"),\r\n noLink: true\r\n });\r\n }\r\n });\r\n};\r\n\r\nconst setToolEnabled = (toolName, state) => {\r\n const menu = Menu.getApplicationMenu();\r\n const element = menu.getMenuItemById(toolName);\r\n if (!element) return;\r\n element.enabled = state;\r\n};\r\n\r\nconst setMenuState = async toolName => {\r\n if (isDevMode) {\r\n setToolEnabled(toolName, true);\r\n return;\r\n }\r\n\r\n if (toolName in menuStateCache) {\r\n const {running, state} = menuStateCache[toolName];\r\n if (running) return;\r\n\r\n // Apply saved menu state\r\n setToolEnabled(toolName, state);\r\n return;\r\n }\r\n\r\n // Insert default cache values\r\n menuStateCache[toolName] = {\r\n running: true,\r\n state: null\r\n };\r\n\r\n const exe = new PythonExecutable();\r\n\r\n exe.run({\r\n command: ['--check-tool', toolName],\r\n showStatus: false,\r\n onLine: jsonData => {\r\n if (!jsonData.license_check) return;\r\n let {valid} = jsonData.license_check;\r\n\r\n // Update cache values\r\n menuStateCache[toolName] = {\r\n running: false,\r\n state: valid\r\n };\r\n\r\n setToolEnabled(toolName, valid);\r\n }\r\n });\r\n};\r\n\r\nconst checkAllowedMenuItems = async (isStandardProject: boolean) => {\r\n if (isStandardProject) {\r\n setMenuState('aligner-advanced-menu');\r\n setMenuState('static-exporter-menu');\r\n setMenuState('label-ortho-menu');\r\n setMenuState('label-scene-menu');\r\n } else {\r\n setToolEnabled('aligner-advanced-menu', false);\r\n setToolEnabled('training-menu', false);\r\n setToolEnabled('point-markup-menu', false);\r\n setToolEnabled('static-exporter-menu', false);\r\n setToolEnabled('save-project', false);\r\n setToolEnabled('save-project-as', false);\r\n }\r\n\r\n setMenuState('aligner-basic-menu');\r\n setMenuState('cloud-exporter-menu');\r\n};\r\n\r\nexport const buildElectronMenu = (isStandardProject: boolean) => {\r\n if (!Menu) return;\r\n\r\n const template = isDevMode\r\n ? [fileMenu, toolsMenu, helpMenu, debugMenu]\r\n : [fileMenu, toolsMenu, helpMenu];\r\n\r\n const menu = Menu.buildFromTemplate(template);\r\n Menu.setApplicationMenu(menu);\r\n checkAllowedMenuItems(isStandardProject);\r\n};\r\n","import React, { FC } from 'react';\r\nimport { Button, Typography } from '@material-ui/core';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { usePopover } from '../../hooks';\r\nimport { Language, LanguageOptions, LanguagePopover } from './language-popover';\r\nimport { ArrowTooltip } from '../tooltips';\r\n\r\nexport const LanguageSwitch: FC = () => {\r\n const { i18n, t } = useTranslation();\r\n const popover = usePopover();\r\n let text = LanguageOptions[i18n.language as Language];\r\n\r\n return (\r\n <>\r\n \r\n \r\n {\r\n text ? text : \"Unknown\"\r\n }\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import React, { FC } from 'react';\r\nimport { Box, Button, Divider, Popover, Typography } from '@material-ui/core';\r\nimport { createStyles, makeStyles, Theme, useTheme } from \"@material-ui/core/styles\";\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '../../hooks';\r\nimport { isCloudSite } from '../../electron-modules';\r\nimport { AccessType } from '../../types/project';\r\n\r\ninterface AccountPopoverProps {\r\n anchorEl: null | Element;\r\n onClose?: () => void;\r\n open?: boolean;\r\n}\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n divider: {\r\n margin: theme.spacing(0, 1.5)\r\n },\r\n buttonParent: {\r\n display: \"flex\",\r\n padding: theme.spacing(0.5),\r\n justifyContent: \"center\"\r\n }\r\n })\r\n);\r\n\r\nexport const AccountPopover: FC = (props) => {\r\n const { anchorEl, onClose, open = false } = props;\r\n\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n const { t } = useTranslation();\r\n\r\n const {linkAccount, signOut, loggedIn, user, permissions} = useAuth();\r\n\r\n const getAccountType = () => {\r\n switch (permissions.type) {\r\n case AccessType.ViewOnly:\r\n return t('user-account.view_only');\r\n case AccessType.Standard:\r\n return t('user-account.standard_user');\r\n case AccessType.Admin:\r\n return t('user-account.administrator');\r\n default:\r\n return t('user-account.unknown_user_type');\r\n }\r\n };\r\n\r\n const accountType = getAccountType();\r\n\r\n return (\r\n \r\n {/** Standard user profile */}\r\n {loggedIn && \r\n \r\n {(user?.firstName || user?.lastName) && \r\n {`${user.firstName} ${user.lastName}`}\r\n }\r\n\r\n {isCloudSite && \r\n {`(${accountType})`}\r\n }\r\n\r\n {user?.email && \r\n {user.email}\r\n }\r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n {t(\"user-account.logout_engine_cloud\")}\r\n \r\n \r\n }\r\n\r\n {/** Anonymous view only */}\r\n {!loggedIn && isCloudSite && \r\n \r\n \r\n {t('user-account.accessing_the_project_as_an_anonymous')}\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n {t(\"user-account.login_engine_cloud\")}\r\n \r\n \r\n }\r\n\r\n {/** Unlinked account */}\r\n {!loggedIn && !isCloudSite && \r\n \r\n \r\n {t('user-account.an_linked_engine_cloud_account_is_required')}\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n {t(\"user-account.login_engine_cloud\")}\r\n \r\n \r\n }\r\n\r\n \r\n );\r\n};\r\n","import React, { FC } from 'react';\r\nimport AccountCircleIcon from '@material-ui/icons/AccountCircle';\r\nimport { ArrowTooltip } from '../tooltips';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { usePopover } from '../../hooks';\r\nimport { IconButton } from '@material-ui/core';\r\nimport { AccountPopover } from './account-popover';\r\n\r\nexport const AccountButton: FC = () => {\r\n const { t } = useTranslation();\r\n const popover = usePopover();\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n );\r\n};","import React, { FC, useEffect } from \"react\";\r\nimport { toast, Toaster as HotToaster, useToasterStore } from 'react-hot-toast';\r\nimport { useTheme, fade } from \"@material-ui/core\";\r\nimport { corporate } from \"../theme\";\r\n\r\nexport const Toaster: FC = () => {\r\n const theme = useTheme();\r\n const { toasts } = useToasterStore();\r\n\r\n const maxNumberToasts = 3;\r\n\r\n useEffect(() => {\r\n toasts\r\n .filter((t) => t.visible)\r\n .filter((_, i) => i >= maxNumberToasts)\r\n .forEach((t) => toast.remove(t.id));\r\n }, [toasts]);\r\n\r\n return (\r\n \r\n );\r\n};\r\n","import React, { useCallback } from \"react\";\r\nimport { makeStyles, Theme, createStyles } from \"@material-ui/core\";\r\nimport Typography, { TypographyProps } from \"@material-ui/core/Typography\";\r\nimport { openExternalLink } from \"../urls\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n typographyLink: {\r\n display: \"inline\",\r\n fontWeight: \"bold\",\r\n color: \"rgb(25, 118, 210)\",\r\n cursor: \"pointer\",\r\n \"&:hover\": {\r\n textDecoration: \"underline\",\r\n textDecorationColor: \"rgb(25, 118, 210, 0.4)\",\r\n }\r\n }\r\n }),\r\n);\r\n\r\ninterface TypographyLinkProps extends TypographyProps {\r\n text: string\r\n url: string\r\n}\r\n\r\nexport const TypographyLink = (props: TypographyLinkProps) => {\r\n const classes = useStyles();\r\n const {text, url, ...other} = props;\r\n\r\n const onClick = useCallback(() => {\r\n openExternalLink(url);\r\n }, [url]);\r\n\r\n return (\r\n \r\n {text}\r\n \r\n );\r\n};\r\n","import { makeStyles, Theme, createStyles, Input } from \"@material-ui/core\";\r\nimport React from \"react\";\r\nimport { useState, useEffect, useCallback } from \"react\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n colorPicker: {\r\n width: \"3.5em\",\r\n height: \"1.25em\",\r\n padding: \"0px\",\r\n border: \"1px solid darkgray\",\r\n borderRadius: \"2px\",\r\n \"&:hover\": {\r\n border: \"1px solid black\"\r\n }\r\n }\r\n })\r\n);\r\n\r\ninterface ColorPickerProps {\r\n value: string;\r\n onSubmit(value): void;\r\n}\r\n\r\nexport const ColorPicker = (props: ColorPickerProps) => {\r\n const {value, onSubmit} = props;\r\n\r\n const classes = useStyles();\r\n const [color, setColor] = useState(\"#000000\");\r\n\r\n useEffect(() => {\r\n setColor(value);\r\n }, [value]);\r\n\r\n const onChange = useCallback((event) => {\r\n setColor(event.target.value);\r\n }, []);\r\n\r\n return (\r\n {\r\n onSubmit(color);\r\n }}\r\n disableUnderline={true}\r\n classes={{\r\n input: classes.colorPicker\r\n }}\r\n type=\"color\"\r\n />\r\n );\r\n};","import {configureStore, combineReducers, nanoid, MiddlewareArray} from '@reduxjs/toolkit';\r\nimport projectReducer from './project-slice';\r\nimport foldersReducer from './folders-slice';\r\nimport assetsReducer from './assets-slice';\r\nimport projectionsReducer from './projections-slice';\r\nimport settingsReducer from './settings-slice';\r\nimport cameraReducer from './camera-slice';\r\nimport bookmarksReducer, { Bookmark } from './bookmarks-slice';\r\nimport customLinksReducer from './custom-links-slice';\r\nimport thunk from 'redux-thunk';\r\nimport {\r\n isMobile,\r\n getModifiedSceneState,\r\n getModifiedAerialState,\r\n toBoolean\r\n} from '../viewer/js/utilities';\r\nimport { useDispatch } from 'react-redux';\r\n\r\nconst appReducer = combineReducers({\r\n project: projectReducer,\r\n camera: cameraReducer,\r\n folders: foldersReducer,\r\n projections: projectionsReducer,\r\n settings: settingsReducer,\r\n assets: assetsReducer,\r\n bookmarks: bookmarksReducer,\r\n custom_links: customLinksReducer\r\n});\r\n\r\nconst updateStateFromParameters = (state, parameters) => {\r\n if (!parameters) return state;\r\n\r\n const {sceneState, aerialState} = state.camera;\r\n\r\n state.camera.sceneState = getModifiedSceneState(\r\n sceneState, parameters);\r\n\r\n state.camera.aerialState = getModifiedAerialState(\r\n aerialState, parameters);\r\n\r\n if (\"expanded\" in parameters) {\r\n const switched = toBoolean(parameters.expanded);\r\n state.settings.switched = switched;\r\n }\r\n\r\n return state;\r\n};\r\n\r\nconst updateStateFromBookmark = (state, parameters) => {\r\n if (!parameters) return state;\r\n\r\n if (\"bookmark\" in parameters) {\r\n const bookmarkID = parameters.bookmark;\r\n const bookmark = state.bookmarks.find(bookmark => {\r\n return bookmark.id === bookmarkID;\r\n }) as Bookmark;\r\n\r\n if (!bookmark) return state;\r\n\r\n state.settings = bookmark.settings;\r\n state.camera.aerialState = bookmark.aerialState;\r\n state.camera.sceneState = bookmark.sceneState;\r\n\r\n state.assets.forEach(asset => {\r\n asset.visible = bookmark.visibleAssets.includes(asset.id);\r\n });\r\n }\r\n\r\n return state;\r\n};\r\n\r\nconst updateStateFromTag = (state, parameters) => {\r\n if (!parameters) return state;\r\n\r\n if (\"tag\" in parameters) {\r\n const savedTagID = parameters.tag;\r\n state.camera.forcedTagID = savedTagID;\r\n }\r\n\r\n return state;\r\n};\r\n\r\nconst rootReducer = (state, action) => {\r\n const newProject = action.type === 'NEW';\r\n const loadConfig = action.type === 'LOAD';\r\n const configInit = state === undefined;\r\n\r\n if (newProject) {\r\n state = undefined;\r\n } else if (loadConfig) {\r\n const {projectJSON} = action.payload;\r\n state = projectJSON;\r\n }\r\n\r\n state = appReducer(state, action);\r\n\r\n if (loadConfig) {\r\n // Modify project state based on URL parameters\r\n const {parameters} = action.payload;\r\n state = updateStateFromParameters(state, parameters);\r\n state = updateStateFromBookmark(state, parameters);\r\n state = updateStateFromTag(state, parameters);\r\n }\r\n\r\n if (configInit || newProject) {\r\n state = appReducer(state, {\r\n type: \"settings/applySavedDefaults\",\r\n payload: null\r\n });\r\n }\r\n\r\n if (newProject) {\r\n /** Create unique project ID */\r\n state = appReducer(state, {\r\n type: \"project/updateProjectID\",\r\n payload: nanoid()\r\n });\r\n }\r\n\r\n if (newProject || loadConfig) {\r\n /** Update unique session ID */\r\n state = appReducer(state, {\r\n type: \"project/updateSessionID\",\r\n payload: nanoid()\r\n });\r\n }\r\n\r\n // Asset drawer will be forced to closed\r\n // for mobile devices on initial load\r\n if (loadConfig && isMobile) {\r\n state = appReducer(state, {\r\n type: \"settings/changeDrawerOpen\",\r\n payload: false\r\n });\r\n }\r\n\r\n if (loadConfig) {\r\n appReducer(state, {\r\n type: \"settings/changeDefaultSettings\",\r\n payload: null\r\n });\r\n }\r\n\r\n return state;\r\n};\r\n\r\nconst middleware = new MiddlewareArray()\r\n .concat(thunk);\r\n\r\nexport const store = configureStore({\r\n reducer: rootReducer,\r\n middleware\r\n});\r\n\r\nexport type AppDispatch = typeof store.dispatch;\r\n\r\n/** Custom useDispatch with proper typing for our store */\r\nexport const useAppDispatch: () => AppDispatch = useDispatch;","import { fse, isCloudSite, isStaticSite } from '../../electron-modules';\r\nimport { isValidURL } from './utilities';\r\n\r\ninterface ByteRange {\r\n first: number\r\n last: number\r\n}\r\n\r\nexport const toDataURL = async (src: string): Promise => {\r\n return new Promise(resolve => {\r\n const image = new Image();\r\n\r\n image.onload = () => {\r\n const canvas = document.createElement('canvas');\r\n canvas.width = image.width;\r\n canvas.height = image.height;\r\n const context = canvas.getContext('2d');\r\n context.drawImage(image, 0, 0);\r\n const dataURL = canvas.toDataURL('image/png');\r\n resolve(dataURL);\r\n };\r\n\r\n image.src = src;\r\n });\r\n};\r\n\r\nexport const readFileJSON = (path: string): Promise => {\r\n if (isStaticSite || isCloudSite || isValidURL(path)) {\r\n return readJsonFromURL(path);\r\n } else {\r\n return readJsonElectron(path);\r\n }\r\n};\r\n\r\nexport const readFileText = (path: string): Promise => {\r\n if (isStaticSite || isCloudSite || isValidURL(path)) {\r\n return readTextFromURL(path);\r\n } else {\r\n return readTextElectron(path);\r\n }\r\n};\r\n\r\nexport const readFileBuffer = (path: string, byteRange: ByteRange = null) => {\r\n if (isStaticSite || isCloudSite || isValidURL(path)) {\r\n return readBufferFromURL(path, byteRange);\r\n } else {\r\n return readBufferElectron(path, byteRange);\r\n }\r\n};\r\n\r\nconst readJsonFromURL = async (path) => {\r\n let headers = {\r\n 'Content-Type': 'application/json'\r\n };\r\n\r\n const response = await fetch(path, {headers});\r\n\r\n if ((response.status === 404) || (response.status === 403)) {\r\n throw new Error(\"File Not Found\");\r\n }\r\n\r\n const data = await response.json();\r\n return data;\r\n};\r\n\r\nconst readJsonElectron = async (path) => {\r\n const data = await fse.readFile(path, 'utf-8');\r\n return JSON.parse(data);\r\n};\r\n\r\nconst readTextFromURL = async (path) => {\r\n let headers = {\r\n 'Content-Type': 'text/html; charset=utf-8'\r\n };\r\n\r\n const response = await fetch(path, {headers});\r\n\r\n if ((response.status === 404) || (response.status === 403)) {\r\n throw new Error(\"File Not Found\");\r\n }\r\n\r\n const data = await response.text();\r\n return data;\r\n};\r\n\r\nconst readTextElectron = async (path) => {\r\n return await fse.readFile(path, 'utf-8');\r\n};\r\n\r\nconst readBufferFromURL = async (path, byteRange: ByteRange) : Promise => {\r\n let headers = {};\r\n\r\n if (byteRange) {\r\n const first = byteRange.first;\r\n const last = byteRange.last - 1;\r\n headers['Content-Type'] = 'multipart/byteranges';\r\n headers['Range'] = `bytes=${first}-${last}`;\r\n }\r\n\r\n const response = await fetch(path, {headers});\r\n\r\n if ((response.status === 404) || (response.status === 403)) {\r\n throw new Error(\"File Not Found\");\r\n }\r\n\r\n const data = await response.arrayBuffer();\r\n\r\n if (byteRange) {\r\n const bytesRequested = byteRange.last - byteRange.first;\r\n if (data.byteLength !== bytesRequested) {\r\n throw new Error(\"Invalid number of bytes read\");\r\n }\r\n }\r\n\r\n if (data.byteLength === 0) {\r\n throw new Error(\"File Not Found\");\r\n }\r\n\r\n return data;\r\n};\r\n\r\nconst readBufferElectron = async (path, byteRange: ByteRange) : Promise => {\r\n if (byteRange) {\r\n const byteLength = byteRange.last - byteRange.first;\r\n const tmpBuffer = Buffer.alloc(byteLength);\r\n\r\n const file = await fse.open(path, \"r\");\r\n const {buffer, bytesRead} = await fse.read(\r\n file, tmpBuffer, 0, byteLength, byteRange.first);\r\n fse.close(file);\r\n\r\n if (bytesRead === 0) {\r\n throw new Error(\"No bytes read\");\r\n }\r\n\r\n return buffer.buffer;\r\n } else {\r\n const data = await fse.readFile(path);\r\n return data.buffer;\r\n }\r\n};\r\n","function webpackEmptyContext(req) {\n\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\te.code = 'MODULE_NOT_FOUND';\n\tthrow e;\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nmodule.exports = webpackEmptyContext;\nwebpackEmptyContext.id = 1115;","import {createSlice, PayloadAction} from '@reduxjs/toolkit';\r\nimport {unknownProjectionMeters} from '../projections';\r\n\r\nexport interface Projection {\r\n type: string,\r\n name?: string,\r\n string: string,\r\n default?: boolean,\r\n transform?: Transform\r\n}\r\n\r\nexport interface Transform {\r\n origin: number[];\r\n translation: number[];\r\n rotation: number;\r\n scale: number;\r\n}\r\n\r\ninterface ProjectionData {\r\n data: Projection;\r\n view: Projection;\r\n measureUnits: string\r\n}\r\n\r\nexport const projectionsSlice = createSlice({\r\n name: 'projections',\r\n initialState: {\r\n data: unknownProjectionMeters,\r\n view: unknownProjectionMeters,\r\n measureUnits: \"m\"\r\n } as ProjectionData,\r\n reducers: {\r\n updateDataProjection: (state, action: PayloadAction) => {\r\n state.data = action.payload;\r\n },\r\n updateViewProjection: (state, action: PayloadAction) => {\r\n state.view = action.payload;\r\n },\r\n changeMeasureUnits: (state, action: PayloadAction) => {\r\n state.measureUnits = action.payload;\r\n },\r\n }\r\n});\r\n\r\nexport const {\r\n updateDataProjection,\r\n updateViewProjection,\r\n changeMeasureUnits\r\n} = projectionsSlice.actions;\r\n\r\nexport default projectionsSlice.reducer;\r\n\r\nexport const selectViewProjection = state => state.projections.view;\r\nexport const selectDataProjection = state => state.projections.data;\r\nexport const selectMeasureUnits = state => state.projections.measureUnits;","import {Projection, Transform} from '../redux/projections-slice';\r\nimport {isStaticSite, storage} from \"../electron-modules\";\r\n\r\nexport const unknownProjectionMeters = {\r\n type: 'proj4',\r\n default: true,\r\n units: \"m\",\r\n name: \"unknown-projection-m\",\r\n string: '+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m',\r\n} as Projection;\r\n\r\nexport const unknownProjectionFeet = {\r\n type: 'proj4',\r\n default: true,\r\n units: \"ft\",\r\n name: \"unknown-projection-ft\",\r\n string: '+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=ft',\r\n};\r\n\r\nexport const defaultProjection = {\r\n type: 'proj4',\r\n name: '',\r\n string: ''\r\n} as Projection;\r\n\r\nexport const defaultTransform = {\r\n origin: Array(3).fill(0),\r\n translation: Array(3).fill(0),\r\n rotation: 0,\r\n scale: 1\r\n} as Transform;\r\n\r\nexport const uniqueProjectionID = (text) : string => {\r\n return text.replace(/\\s/g, '.');\r\n};\r\n\r\nclass UserProjections {\r\n public data: Projection[] = [];\r\n private readonly file: string;\r\n\r\n constructor() {\r\n this.file = 'user-projections';\r\n this.load();\r\n }\r\n\r\n exists(name: string) {\r\n const names = this.data.map(x => x.name);\r\n return names.includes(name);\r\n }\r\n\r\n async save(data: Projection) {\r\n if (this.exists(data.name)) return false;\r\n\r\n this.data.push(data);\r\n storage.setSync(this.file, this.data);\r\n\r\n this.load();\r\n return true;\r\n }\r\n\r\n load() {\r\n if (isStaticSite) return {};\r\n let data = storage.getSync(this.file);\r\n this.data = Array.isArray(data) ? data : [];\r\n }\r\n\r\n delete(name: string) {\r\n if (!this.exists(name)) return;\r\n\r\n const rows = this.data.map(x => x.name);\r\n const index = rows.indexOf(name);\r\n this.data.splice(index, 1);\r\n\r\n storage.setSync(this.file, this.data);\r\n this.load();\r\n }\r\n\r\n update(name: string, data: Projection) {\r\n if (!this.exists(name)) return false;\r\n this.delete(name);\r\n return this.save(data);\r\n }\r\n}\r\n\r\nexport const userProjections = new UserProjections();\r\n","import React, {useEffect} from 'react';\r\nimport clsx from 'clsx';\r\nimport Button from '@material-ui/core/Button';\r\nimport Dialog from '@material-ui/core/Dialog';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport CloseIcon from '@material-ui/icons/Close';\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport {createStyles, makeStyles, Theme} from \"@material-ui/core/styles\";\r\nimport {\r\n userProjections,\r\n defaultProjection,\r\n defaultTransform,\r\n uniqueProjectionID\r\n} from './projections';\r\nimport {useState} from 'react';\r\nimport {\r\n AppBar,\r\n Checkbox,\r\n FormControlLabel,\r\n Grid,\r\n InputAdornment,\r\n InputLabel,\r\n MenuItem,\r\n Select,\r\n Tab,\r\n Tabs,\r\n TextField,\r\n Typography\r\n} from '@material-ui/core';\r\nimport LocalScene, { isValidProjection } from '../viewer/js/projections';\r\nimport {\r\n DropdownWithLabel,\r\n EnhancedTable,\r\n InputWithLabel,\r\n PanelProps,\r\n PromptDialog,\r\n TabPanel,\r\n TabProps\r\n} from '../components';\r\nimport { toast } from '../app';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useDialog, useUniqueProjectID } from '../hooks';\r\nimport { registerEvent } from '../electron-modules';\r\nimport { useTableState } from '../hooks/use-table-state';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n title: {\r\n margin: 0,\r\n padding: theme.spacing(1,2,1,2),\r\n },\r\n content: {\r\n padding: theme.spacing(0),\r\n paddingTop: \"0px !important\"\r\n },\r\n titleClose: {\r\n color: \"white\"\r\n },\r\n marginTop: {\r\n marginTop: theme.spacing(2)\r\n },\r\n marginBottom: {\r\n marginBottom: theme.spacing(2)\r\n },\r\n adornedEnd: {\r\n paddingRight: theme.spacing(0)\r\n },\r\n utmParent: {\r\n display: \"flex\"\r\n },\r\n utmZone: {\r\n flex: 2\r\n },\r\n utmButton: {\r\n flex: 1,\r\n marginLeft: theme.spacing(1)\r\n },\r\n button: {\r\n marginTop: theme.spacing(2),\r\n marginLeft: theme.spacing(1)\r\n },\r\n dropdown: {\r\n minWidth: 200,\r\n },\r\n formControl: {\r\n width: '100%'\r\n },\r\n buttonDiv: {\r\n textAlign: \"right\"\r\n },\r\n panel: {\r\n minHeight: \"240px\"\r\n },\r\n tabsParent: {\r\n display: \"flex\",\r\n padding: theme.spacing(0, 1)\r\n },\r\n tabsHeaders: {\r\n flex: 1\r\n }\r\n }),\r\n);\r\n\r\nconst UserProjectionPanel = (props) => {\r\n const {loadProjectionToEdit, setActiveTab, tableState} = props;\r\n const {t} = useTranslation();\r\n\r\n const deleteDialog = useDialog();\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t('projections.projection-name'),\r\n searchable: true\r\n },\r\n {\r\n id: 'type',\r\n label: t('projections.projection-type')\r\n },\r\n {\r\n id: 'custom',\r\n label: t('projections.custom-parameters')\r\n },\r\n ];\r\n\r\n // Convert projections to data row\r\n const data = userProjections.data;\r\n\r\n const getRows = () => {\r\n return data.map(option => {\r\n return {\r\n id: uniqueProjectionID(option.name),\r\n name: option.name,\r\n custom: option.transform ? t('general.yes') : t('general.no'),\r\n type: option.type,\r\n disabled: LocalScene.isDataProjection(option.name)\r\n };\r\n });\r\n };\r\n\r\n const onClick = (row) => {\r\n const results = data.filter(x => x.name === row.name);\r\n if (results.length !== 1) {\r\n return;\r\n }\r\n\r\n const projection = results[0];\r\n loadProjectionToEdit(projection, false);\r\n setActiveTab(1);\r\n };\r\n\r\n const onDelete = (row) => {\r\n const results = data.filter(x => x.name === row.name);\r\n if (results.length !== 1) {\r\n return;\r\n }\r\n\r\n // Delete projection + force reload\r\n const projection = results[0];\r\n userProjections.delete(projection.name);\r\n toast.error(t(\"toast.projection-deleted\"));\r\n\r\n // Force projection list refresh\r\n setActiveTab(0);\r\n };\r\n\r\n const rows = getRows();\r\n\r\n const actions = [\r\n {\r\n title: t(\"buttons.delete\"),\r\n icon: ,\r\n onClick: (row) => {\r\n deleteDialog.handleOpen(row);\r\n }\r\n }\r\n ];\r\n\r\n let deletePrompt = \"\";\r\n if (deleteDialog.open) {\r\n deletePrompt = t('projections.do_you_want_to_delete_this_projection_row_name', {\r\n name: deleteDialog.data.name\r\n });\r\n }\r\n\r\n return (\r\n \r\n
\r\n {rows.length === 0 && (\r\n {t('projections.no-user-projections-have-been-added')}\r\n )}\r\n\r\n {(rows.length > 0) && ()}\r\n
\r\n\r\n {/* Delete Dialog */}\r\n {\r\n onDelete(deleteDialog.data);\r\n deleteDialog.handleClose();\r\n }}\r\n title={t(\"enhanced-table.prompt-delete-title\")}\r\n prompt={deletePrompt}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n
\r\n );\r\n};\r\n\r\nconst EditPanel = (props) => {\r\n const {customProjection, updateEditableValues,\r\n hasTransform, setHasTransform,\r\n newProjection, setActiveTab, existingName} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const name = customProjection.name;\r\n const type = customProjection.type;\r\n const projString = customProjection.string;\r\n\r\n const transform = customProjection.transform;\r\n const origin = transform.origin;\r\n const translate = transform.translation;\r\n const rotation = transform.rotation;\r\n const scale = transform.scale;\r\n\r\n const handleChecked = (event) => {\r\n setHasTransform(event.target.checked);\r\n };\r\n\r\n const saveProjection = () => {\r\n // Create copy of our data\r\n let data = JSON.parse(JSON.stringify(customProjection));\r\n\r\n // Use trimmed versions of name and string\r\n data.name = nameTrim;\r\n data.string = stringTrim;\r\n\r\n if (!hasTransform) {\r\n delete data.transform;\r\n }\r\n\r\n const nameChanged = data.name !== existingName;\r\n const duplicateName = userProjections.exists(data.name);\r\n\r\n // Check for duplicates if our name has changed\r\n if (nameChanged && duplicateName) {\r\n toast.error(t(\"toast.projection-duplicate\"));\r\n return;\r\n }\r\n\r\n // Check for valid projection string\r\n let validProjection = isValidProjection(projString);\r\n if (!validProjection) {\r\n toast.error(t(\"toast.projection-invalid\"));\r\n return;\r\n }\r\n\r\n const success = newProjection\r\n ? userProjections.save(data)\r\n : userProjections.update(existingName, data);\r\n\r\n if (!success) return;\r\n\r\n if (newProjection) {\r\n toast.success(t(\"toast.projection-added\"));\r\n } else {\r\n toast.success(t(\"toast.projection-updated\"));\r\n }\r\n\r\n setActiveTab(0);\r\n };\r\n\r\n // Remove excess whitespace from name and string\r\n let nameTrim = name.trim();\r\n let stringTrim = projString.trim();\r\n\r\n let originXError = origin[0] === \"\";\r\n let originYError = origin[1] === \"\";\r\n let originZError = origin[2] === \"\";\r\n\r\n let translateXError = translate[0] === \"\";\r\n let translateYError = translate[1] === \"\";\r\n let translateZError = translate[2] === \"\";\r\n\r\n let rotationError = rotation === \"\";\r\n let scaleError = scale === \"\";\r\n\r\n let canSubmit = (nameTrim !== \"\")\r\n && stringTrim !== \"\";\r\n\r\n if (hasTransform) {\r\n canSubmit = canSubmit\r\n && !originXError\r\n && !originYError\r\n && !originZError\r\n && !translateXError\r\n && !translateYError\r\n && !translateZError\r\n && !rotationError\r\n && !scaleError;\r\n }\r\n\r\n const updateType = (value) => {\r\n // Update projection type and clear projection string\r\n updateEditableValues({\r\n 'type': value,\r\n 'string': \"\"\r\n });\r\n };\r\n\r\n const updateName = (value) => {\r\n updateEditableValues({\"name\": value});\r\n };\r\n\r\n const updateString = (value) => {\r\n let string = (customProjection['type'] === \"epsg\")\r\n ? `EPSG:${value}`\r\n : value;\r\n\r\n updateEditableValues({\"string\": string});\r\n };\r\n\r\n const updateOrigin = (event, index) => {\r\n const value = parseFloat(event.target.value);\r\n let transform = customProjection.transform;\r\n transform['origin'][index] = isNaN(value) ? \"\" : value;\r\n\r\n updateEditableValues({\r\n \"transform\":transform\r\n });\r\n };\r\n\r\n const updateTranslation = (event, index) => {\r\n const value = parseFloat(event.target.value);\r\n let transform = customProjection.transform;\r\n transform['translation'][index] = isNaN(value) ? \"\" : value;\r\n\r\n updateEditableValues({\r\n \"transform\":transform\r\n });\r\n };\r\n\r\n const updateScale = (event) => {\r\n const value = parseFloat(event.target.value);\r\n let transform = customProjection.transform;\r\n transform['scale'] = isNaN(value) ? \"\" : value;\r\n\r\n updateEditableValues({\r\n \"transform\":transform\r\n });\r\n };\r\n\r\n const updateRotation = (event) => {\r\n let value = parseFloat(event.target.value);\r\n let transform = customProjection.transform;\r\n transform['rotation'] = isNaN(value) ? \"\" : value;\r\n\r\n updateEditableValues({\r\n \"transform\":transform\r\n });\r\n };\r\n\r\n return (\r\n
\r\n\r\n \r\n\r\n {/** Projection Type */}\r\n \r\n \r\n \r\n\r\n {/** Projection Name */}\r\n \r\n \r\n \r\n\r\n {/** Projection string (proj4) */}\r\n {type===\"proj4\" && (\r\n \r\n )}\r\n\r\n {/** Projection string (WKT) */}\r\n {type===\"wkt\" && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n }\r\n label={t('projections.additional-parameters')}\r\n />\r\n\r\n {hasTransform && (\r\n {/* Origin */}\r\n \r\n \r\n {\r\n updateOrigin(e, 0);\r\n }}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={originXError}\r\n />\r\n \r\n\r\n \r\n {\r\n updateOrigin(e, 1);\r\n }}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={originYError}\r\n />\r\n \r\n\r\n \r\n {\r\n updateOrigin(e, 2);\r\n }}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={originZError}\r\n />\r\n \r\n \r\n\r\n {/* Translation */}\r\n \r\n \r\n {\r\n updateTranslation(e, 0);\r\n }}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={translateXError}\r\n />\r\n \r\n\r\n \r\n {\r\n updateTranslation(e, 1);\r\n }}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={translateYError}\r\n />\r\n \r\n\r\n \r\n {\r\n updateTranslation(e, 2);\r\n }}\r\n InputLabelProps={{\r\n shrink: true,\r\n }}\r\n error={translateZError}\r\n />\r\n \r\n \r\n\r\n {/* Rotation and scaling */}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n )}\r\n\r\n
\r\n {!newProjection && ( {\r\n setActiveTab(0);\r\n }}\r\n className={classes.button}\r\n >\r\n {t(\"buttons.cancel\")}\r\n )}\r\n\r\n \r\n {newProjection ? t('projections.add-projection') : t('projections.save-changes')}\r\n \r\n
\r\n
\r\n );\r\n};\r\n\r\nconst SearchPanel = (props) => {\r\n const {tableState, setActiveTab, loadProjectionToEdit} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [type, setType] = useState(\"text\");\r\n const [searchTerm, setSearchTerm] = useState(\"\");\r\n const [hemisphere, setHemisphere] = useState(\"N\");\r\n const [searching, setSearching] = useState(false);\r\n const [searchResults, setSearchResults] = useState([]);\r\n\r\n const handleChange = (event) => {\r\n setType(event.target.value);\r\n };\r\n\r\n const handleHemisphere = (event) => {\r\n setHemisphere(event.target.value);\r\n };\r\n\r\n const handleString = (event) => {\r\n setSearchTerm(event.target.value);\r\n };\r\n\r\n const searchOnline = () => {\r\n if (searchTerm === \"\") {\r\n return;\r\n }\r\n\r\n let value = searchTerm;\r\n if (type === \"utm\") {\r\n value = `utm ${value}${hemisphere}`;\r\n }\r\n\r\n tableState.reset();\r\n getProjections(value);\r\n };\r\n\r\n const getProjections = (searchText, pageNumber = 1, previousResults = [], maxPageNumber = 10) => {\r\n if (pageNumber === 1) {\r\n setSearchResults([]);\r\n setSearching(true);\r\n }\r\n\r\n const text = type !== \"epsg\" ?\r\n `${searchText} kind:PROJCRS` :\r\n searchText;\r\n\r\n const url = \"https://epsg.io/?q=\" + text + \"&format=json&page=\" + pageNumber;\r\n\r\n fetch(url)\r\n .then(response => response.json())\r\n .then(data => {\r\n const results = data.results;\r\n const parsed = [];\r\n\r\n results.forEach(result => {\r\n if (type === \"epsg\") {\r\n if (result.code !== searchText) {\r\n return;\r\n }\r\n }\r\n\r\n if (result.proj4 === \"\") {\r\n return;\r\n }\r\n\r\n parsed.push(result);\r\n });\r\n\r\n const combined = [...previousResults, ...parsed];\r\n setSearchResults(combined);\r\n\r\n if ((results.length > 0) && (pageNumber < maxPageNumber)) {\r\n setTimeout(() =>{\r\n getProjections(searchText, pageNumber + 1, combined);\r\n }, 250);\r\n } else {\r\n setSearching(false);\r\n }\r\n });\r\n };\r\n\r\n const onClick = (row) => {\r\n loadProjectionToEdit({\r\n type: \"proj4\",\r\n name: row.name,\r\n string: row.proj4\r\n }, true);\r\n setActiveTab(1);\r\n };\r\n\r\n const getRows = () => {\r\n return searchResults.map(projection => {\r\n return {\r\n id: uniqueProjectionID(projection.name),\r\n name: projection.name as string,\r\n epsg: parseInt(projection.code),\r\n proj4: projection.proj4 as string,\r\n };\r\n });\r\n };\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t('projections.name')\r\n },\r\n {\r\n id: 'epsg',\r\n label: t('projections.epsg'),\r\n numeric: true\r\n },\r\n {\r\n id: 'proj4',\r\n label: t('projections.proj4-string')\r\n },\r\n ];\r\n\r\n const rows = getRows();\r\n\r\n return (\r\n
\r\n {/* Search Type */}\r\n
\r\n \r\n {t('projections.search-type')}\r\n \r\n \r\n {t('projections.text')}\r\n {t('projections.utm-zone')}\r\n {t('projections.epsg-code')}\r\n \r\n
\r\n\r\n {/* UTM Zone */}\r\n {type===\"utm\" && (
\r\n \r\n {t('projections.utm-zone')}\r\n \r\n }}\r\n className={clsx(classes.marginTop, classes.utmZone)}\r\n />\r\n\r\n \r\n {t('directions.north')}\r\n {t('directions.south')}\r\n \r\n\r\n
)}\r\n\r\n {/* EPSG Code */}\r\n {type===\"epsg\" && (EPSG:,\r\n }}\r\n className={classes.marginTop}\r\n />)}\r\n\r\n {/* Text Search */}\r\n {type===\"text\" && ()}\r\n\r\n {/* Search button */}\r\n
\r\n \r\n {searching ? t('projections.searching-epsg-io') : t('projections.search-online')}\r\n \r\n
\r\n\r\n {/* Results table */}\r\n {(rows.length > 0) && }\r\n
\r\n );\r\n};\r\n\r\nexport const ProjectionsManager = () => {\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const projectionsDialog = useDialog();\r\n\r\n // Must be defined here to persist (dialog is not mounted)\r\n const userTableState = useTableState({defaultSort: \"name\"});\r\n const searchTableState = useTableState();\r\n\r\n const [existingName, setExistingName] = useState(\"\");\r\n const [newProjection, setNewProjection] = useState(false);\r\n const [activeTab, setTabValue] = useState(0);\r\n const [customProjection, setCustomProjection] = useState({});\r\n const [hasTransform, setHasTransform] = useState(false);\r\n\r\n const setActiveTab = (value) => {\r\n if (value === 0) {\r\n clearProjectionValues();\r\n }\r\n\r\n setTabValue(value);\r\n };\r\n\r\n const updateEditableValues = (newValues) => {\r\n const combined = {...customProjection, ...newValues};\r\n setCustomProjection(combined);\r\n };\r\n\r\n const clearProjectionValues = () => {\r\n loadProjectionToEdit(defaultProjection, true);\r\n };\r\n\r\n const loadProjectionToEdit = (projectionData, newProjection) => {\r\n const dataCopy = JSON.parse(JSON.stringify(projectionData));\r\n const hasTransform = dataCopy.hasOwnProperty(\"transform\");\r\n if (!hasTransform) {\r\n const transformCopy = JSON.parse(JSON.stringify(defaultTransform));\r\n dataCopy.transform = transformCopy;\r\n }\r\n\r\n setHasTransform(hasTransform);\r\n setCustomProjection({...dataCopy});\r\n setExistingName(dataCopy.name);\r\n setNewProjection(newProjection);\r\n };\r\n\r\n const handleChange = (event, newactiveTab) => {\r\n setActiveTab(newactiveTab);\r\n };\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n projectionsDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-projection-manager\", () => {\r\n projectionsDialog.handleOpen();\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n clearProjectionValues();\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!projectionsDialog.open) return;\r\n userProjections.load();\r\n }, [projectionsDialog.open]);\r\n\r\n return (\r\n
\r\n \r\n\r\n \r\n
\r\n \r\n \r\n {newProjection && ()}\r\n {!newProjection && ()}\r\n \r\n \r\n\r\n {/* Close button */}\r\n \r\n \r\n \r\n\r\n
\r\n
\r\n\r\n {/* Existing projections */}\r\n \r\n \r\n \r\n\r\n {/* Custom projections */}\r\n \r\n \r\n \r\n\r\n {/* Online projection search */}\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n","import React from \"react\";\r\nimport {ThemeProvider} from \"@material-ui/core\";\r\nimport {AppWithAuth} from \"./app\";\r\nimport {store} from \"./redux/store\";\r\nimport {Provider} from \"react-redux\";\r\nimport './localization';\r\nimport {\r\n TaskQueueProvider,\r\n ViewerProvider,\r\n ActiveToolProvider,\r\n AuthProvider,\r\n BookmarksProvider\r\n} from \"./providers\";\r\nimport { createTheme } from \"./theme\";\r\nimport { GlobalSettingsProvider } from \"./providers/global-settings-provider\";\r\nimport { WebSocketProvider } from \"./providers/websocket-provider\";\r\n\r\nconst theme = createTheme();\r\n\r\nconst EngineViewer = () => {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default EngineViewer;","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport EngineViewer from './engine-viewer';\r\n\r\nReactDOM.render(\r\n ,\r\n document.getElementById('root')\r\n);","/* eslint-disable react-hooks/rules-of-hooks */\r\nimport React, { createContext, useEffect, useState } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { toast } from \"../app\";\r\nimport { isCloudSite, isElectronApp } from \"../electron-modules\";\r\nimport { getLocalizedURL } from \"../localization\";\r\nimport { engineCloudURL, openExternalLink, redirectToLogin } from \"../urls\";\r\nimport SuperTokens from \"supertokens-web-js\";\r\nimport { AccessType } from \"../types/project\";\r\nimport Session from \"supertokens-web-js/recipe/session\";\r\nimport EmailPassword from \"supertokens-web-js/recipe/emailpassword\";\r\nimport {signOut as stSignOut} from \"supertokens-web-js/lib/build/recipe/emailpassword\";\r\nimport { useWebSockets } from \"../hooks\";\r\n\r\ninterface User {\r\n id: string;\r\n email: string;\r\n firstName: string;\r\n lastName: string;\r\n}\r\n\r\ninterface ProjectPermissions {\r\n type: AccessType;\r\n access: boolean;\r\n create: boolean;\r\n delete: boolean;\r\n edit: boolean;\r\n}\r\n\r\nconst appCodeRefreshRate = 2000;\r\nconst appCodeMaxAttempts = 100;\r\nconst originalFetch = fetch;\r\n\r\nexport const asyncTimeout = (ms) => {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n};\r\n\r\nclass AuthHandler {\r\n public locked = false;\r\n private accessTokenKey = \"st-access-token\"\r\n private refreshTokenKey = \"st-refresh-token\"\r\n\r\n get accessToken() {\r\n return localStorage.getItem(this.accessTokenKey);\r\n }\r\n\r\n get refreshToken() {\r\n return localStorage.getItem(this.refreshTokenKey);\r\n }\r\n\r\n clearTokens() {\r\n localStorage.removeItem(this.accessTokenKey);\r\n localStorage.removeItem(this.refreshTokenKey);\r\n }\r\n\r\n checkForKey(headers, tokenKey: string) {\r\n if (!headers.has(tokenKey)) return;\r\n const token = headers.get(tokenKey);\r\n localStorage.setItem(tokenKey, token);\r\n }\r\n\r\n updateTokens(headers) {\r\n this.checkForKey(headers, this.accessTokenKey);\r\n this.checkForKey(headers, this.refreshTokenKey);\r\n }\r\n\r\n async wait() {\r\n while (this.locked) {\r\n await asyncTimeout(100);\r\n }\r\n }\r\n\r\n async fetch(input: string, init: RequestInit) {\r\n const {headers = {}, ...others} = init;\r\n\r\n const response = await originalFetch(input, {\r\n headers: {\r\n 'Authorization': `Bearer ${this.accessToken}`,\r\n ...headers,\r\n },\r\n ...others\r\n });\r\n\r\n return response;\r\n }\r\n\r\n async update() {\r\n this.locked = true;\r\n\r\n const url = `${engineCloudURL}/auth/session/refresh`;\r\n\r\n const response = await originalFetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n 'rid': 'session',\r\n 'Authorization': `Bearer ${this.refreshToken}`\r\n }\r\n });\r\n\r\n let success = response.status === 200;\r\n\r\n if (success) {\r\n this.updateTokens(response.headers);\r\n }\r\n\r\n this.locked = false;\r\n\r\n return success;\r\n }\r\n}\r\n\r\nconst handler = new AuthHandler();\r\n\r\nconst initCustomFetch = () => {\r\n const customFetch = async (input: string, init: RequestInit = {}) => {\r\n if (!input.includes(engineCloudURL)) {\r\n return originalFetch(input, init);\r\n }\r\n\r\n if (handler.locked) {\r\n await handler.wait();\r\n }\r\n\r\n const response = await handler.fetch(input, init);\r\n\r\n if (response.status !== 401) {\r\n return response;\r\n }\r\n\r\n if (handler.locked) {\r\n return customFetch(input, init);\r\n }\r\n\r\n const updated = await handler.update();\r\n\r\n if (updated) {\r\n return customFetch(input, init);\r\n } else {\r\n throw new Error(\"Unauthorized\");\r\n }\r\n };\r\n\r\n window['fetch'] = customFetch;\r\n};\r\n\r\nconst initSuperTokens = () => {\r\n SuperTokens.init({\r\n appInfo: {\r\n appName: \"Solv3D Engine Cloud\",\r\n apiDomain: window.location.origin,\r\n apiBasePath: \"/auth\"\r\n },\r\n recipeList: [\r\n Session.init(),\r\n EmailPassword.init(),\r\n ]\r\n });\r\n};\r\n\r\nconst initialUserState = {\r\n id: null,\r\n email: null,\r\n firstName: null,\r\n lastName: null\r\n} as User;\r\n\r\nconst adminPermissions = {\r\n type: AccessType.Admin,\r\n access: true,\r\n create: true,\r\n delete: true,\r\n edit: true\r\n} as ProjectPermissions;\r\n\r\nconst emptyPermissions = {\r\n type: AccessType.ViewOnly,\r\n access: false,\r\n create: false,\r\n delete: false,\r\n edit: false\r\n} as ProjectPermissions;\r\n\r\nexport const AuthContext = createContext({\r\n user: null as User,\r\n permissions: null as ProjectPermissions,\r\n loggedIn: false,\r\n initialized: false,\r\n linkAccount: async () => false,\r\n signOut: () => {},\r\n getAppCode: async (activate: boolean) => null as string,\r\n});\r\n\r\nexport const AuthProvider = (props) => {\r\n const { i18n, t } = useTranslation();\r\n\r\n const websockets = useWebSockets();\r\n\r\n const [state, setState] = useState({\r\n user: {...initialUserState},\r\n permissions: null,\r\n initialized: false\r\n });\r\n\r\n const linkAccount = async () => {\r\n try {\r\n const appCode = await getAppCode();\r\n const url = getLocalizedURL(\r\n `${engineCloudURL}/link?code=${appCode}`,\r\n i18n.language\r\n );\r\n\r\n openExternalLink(url);\r\n return useAppCode(appCode);\r\n } catch {\r\n toast.error(t('user-account.error_linking_account'));\r\n return false;\r\n }\r\n };\r\n\r\n const signOut = async () => {\r\n if (isCloudSite) {\r\n await stSignOut();\r\n redirectToLogin();\r\n } else {\r\n setState({\r\n ...state,\r\n user: {...initialUserState}\r\n });\r\n\r\n handler.clearTokens();\r\n toast.success(t('user-account.account_unlinked'));\r\n }\r\n\r\n websockets.disconnect();\r\n };\r\n\r\n const getAppCode = async (activate=false) => {\r\n const url = `${engineCloudURL}/api/app_codes/request`;\r\n const response = await fetch(url);\r\n const data = await response.json();\r\n const appCode = String(data.access_code);\r\n\r\n if (activate) {\r\n const url = `${engineCloudURL}/api/app_codes/activate/${appCode}`;\r\n await fetch(url, {method: \"PUT\"});\r\n }\r\n\r\n return appCode;\r\n };\r\n\r\n /** Consume app code until it returns a success code */\r\n const useAppCode = async (appCode: string): Promise => {\r\n if (!appCode) return true;\r\n\r\n return new Promise((resolve, reject) => {\r\n let retryAttempt = 0;\r\n\r\n const interval = setInterval(async () => {\r\n if (retryAttempt >= appCodeMaxAttempts) {\r\n resolve(false);\r\n clearInterval(interval);\r\n toast.error(t('user-account.error_linking_account'));\r\n return;\r\n };\r\n\r\n const url = `${engineCloudURL}/api/app_codes/consume/${appCode}`;\r\n const response = await fetch(url);\r\n const success = response.status === 200;\r\n\r\n if (success) {\r\n handler.updateTokens(response.headers);\r\n await initialize();\r\n toast.success(t('user-account.account_linked'));\r\n clearInterval(interval);\r\n resolve(true);\r\n }\r\n\r\n retryAttempt += 1;\r\n }, appCodeRefreshRate);\r\n });\r\n };\r\n\r\n const getUser = async () : Promise => {\r\n try {\r\n const url = `${engineCloudURL}/api/users/me`;\r\n const response = await fetch(url);\r\n if (response.status !== 200) {\r\n return initialUserState;\r\n }\r\n\r\n const user = await response.json();\r\n return user;\r\n } catch {\r\n return initialUserState;\r\n }\r\n };\r\n\r\n const getPermissions = async () : Promise => {\r\n try {\r\n const url = `${window.location.pathname}/permissions`;\r\n const response = await fetch(url);\r\n if (response.status !== 200) {\r\n return emptyPermissions;\r\n }\r\n\r\n const permissions = await response.json();\r\n return permissions;\r\n } catch {\r\n return emptyPermissions;\r\n }\r\n };\r\n\r\n const initialize = async () => {\r\n const newState = {...state};\r\n\r\n if (isCloudSite || isElectronApp) {\r\n const user = await getUser();\r\n newState.user = {...user};\r\n\r\n await websockets.connect(handler.accessToken);\r\n\r\n if (!user.id) {\r\n handler.clearTokens();\r\n }\r\n }\r\n\r\n if (isCloudSite) {\r\n const permissions = await getPermissions();\r\n newState.permissions = {...permissions};\r\n } else if (isElectronApp) {\r\n newState.permissions = {...adminPermissions};\r\n } else {\r\n newState.permissions = {\r\n ...emptyPermissions,\r\n access: true\r\n };\r\n }\r\n\r\n setState({...newState, initialized: true});\r\n };\r\n\r\n /** Initialize on first load */\r\n useEffect(() => {\r\n initialize();\r\n }, []);\r\n\r\n const {user, permissions, initialized} = state;\r\n const loggedIn = !!user.id;\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};\r\n\r\n\r\nif (isCloudSite) {\r\n // Cloud site uses cookie based auth. Fetch function\r\n // is automatically patched with supertokens-web-js\r\n initSuperTokens();\r\n} else if (isElectronApp) {\r\n // Initialize custom header based auth with localStorage.\r\n // Fetch function is patched with a custom implementation\r\n initCustomFetch();\r\n}","import React, { createContext, useState } from \"react\";\r\n\r\nexport const ActiveToolContext = createContext({\r\n activeToolOpen: false,\r\n setActiveToolOpen: (state: boolean) => {}\r\n});\r\n\r\nexport const ActiveToolProvider = (props) => {\r\n const [activeToolOpen, setActiveToolOpen] = useState(false);\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};","import React, { createContext, useEffect, useState } from \"react\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { PythonExecutable } from \"../executable\";\r\nimport { useUniqueProjectID } from \"../hooks\";\r\n\r\nexport enum TaskStatus {\r\n Waiting,\r\n Running,\r\n Finished\r\n}\r\n\r\ninterface ExecutableTask {\r\n id: string,\r\n commands: string[],\r\n status: TaskStatus,\r\n exe: PythonExecutable,\r\n onFinish: Function\r\n}\r\n\r\nexport const TaskQueueContext = createContext({\r\n taskQueue: [] as ExecutableTask[],\r\n addRunningTask: (commands: string[], onFinish: Function) => {},\r\n stopRunningTask: (task: string) => {},\r\n clearTaskQueue: () => {}\r\n});\r\n\r\nexport const TaskQueueProvider = (props) => {\r\n const [taskQueue, setTaskQueue] = useState([]);\r\n const [running, setRunning] = useState(false);\r\n const uniqueProjectID = useUniqueProjectID();\r\n\r\n const runningTask = taskQueue.find(x => x.status === TaskStatus.Running);\r\n\r\n const addRunningTask = (commands: string[], onFinish: Function) => {\r\n const newTask = {\r\n id: nanoid(),\r\n onFinish,\r\n commands,\r\n exe: new PythonExecutable(),\r\n status: TaskStatus.Waiting\r\n } as ExecutableTask;\r\n\r\n setTaskQueue([...taskQueue, newTask]);\r\n };\r\n\r\n const clearTaskQueue = () => {\r\n runningTask?.exe.destroy();\r\n setTaskQueue([]);\r\n setRunning(false);\r\n };\r\n\r\n const stopRunningTask = (taskID: string) => {\r\n const task = taskQueue.find(x => x.id === taskID);\r\n if (!task) return;\r\n\r\n task.exe.destroy();\r\n setRunning(false);\r\n };\r\n\r\n const updateTaskStatus = (taskID, status) => {\r\n const tasks = taskQueue.map(task => {\r\n if (task.id === taskID) {\r\n return {...task, status: status};\r\n }\r\n\r\n return task;\r\n });\r\n\r\n setTaskQueue([...tasks]);\r\n };\r\n\r\n const runAvailableTask = () => {\r\n const availableTasks = taskQueue\r\n .filter(x => x.status === TaskStatus.Waiting);\r\n\r\n if ((availableTasks.length === 0) || runningTask) return;\r\n\r\n const task = availableTasks[0];\r\n setRunning(true);\r\n updateTaskStatus(task.id, TaskStatus.Running);\r\n\r\n task.exe.run({\r\n command: task.commands,\r\n saveLogs: true,\r\n onClose: async (error) => {\r\n if (error) return;\r\n setRunning(false);\r\n await task.onFinish();\r\n }\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n /** Clear task queue when new project is loaded */\r\n clearTaskQueue();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n runAvailableTask();\r\n }, [taskQueue]);\r\n\r\n useEffect(() => {\r\n if (running || !runningTask) return;\r\n updateTaskStatus(runningTask.id, TaskStatus.Finished);\r\n }, [running]);\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};\r\n","import React from \"react\";\r\nimport { createContext, useState } from \"react\";\r\nimport { Viewer } from \"../viewer/js/main\";\r\n\r\nexport const ViewerContext = createContext({\r\n viewer: null as Viewer,\r\n setViewer: (value: any) => {}\r\n});\r\n\r\nexport const ViewerProvider = (props) => {\r\n const [viewer, setViewer] = useState(null);\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};","import React from \"react\";\r\nimport { createContext } from \"react\";\r\nimport { useDispatch, useSelector } from \"react-redux\";\r\nimport { toast } from \"../app\";\r\nimport { useViewer } from \"../hooks\";\r\nimport { Bookmark, deleteBookmark, selectAllBookmarks } from \"../redux/bookmarks-slice\";\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport {isEqual} from 'lodash';\r\nimport { t } from \"i18next\";\r\nimport { selectAllAssets, selectVisibleAssets, setVisibleAssets } from \"../redux/assets-slice\";\r\nimport { changeCameraState } from \"../redux/camera-slice\";\r\nimport { updateSettingsState } from \"../redux/settings-slice\";\r\n\r\nexport const BookmarksContext = createContext({\r\n bookmarks: [] as Bookmark[],\r\n loadBookmark: (bookmarkID: string) : boolean => null,\r\n deleteBookmarks: () => {}\r\n});\r\n\r\nexport const BookmarksProvider = (props) => {\r\n const {viewer} = useViewer();\r\n const dispatch = useDispatch();\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const bookmarks = useSelector(selectAllBookmarks);\r\n const visibleAssets = useSelector(selectVisibleAssets);\r\n\r\n /**\r\n * Get visible bookmark assets, ignoring assets that have\r\n * been removed from the project\r\n **/\r\n const getValidAssetIDs = (bookmark: Bookmark) => {\r\n const assetIDs = assets.map(asset => asset.id);\r\n return bookmark.visibleAssets.filter(assetID => {\r\n return assetIDs.includes(assetID);\r\n });\r\n };\r\n\r\n const loadBookmark = (bookmarkID: string) => {\r\n if (!viewer) return;\r\n\r\n if (!LocalScene.initialized) {\r\n toast.warning(t('bookmarks.invalid_position'));\r\n return;\r\n }\r\n\r\n const bookmark = bookmarks.find(x => x.id === bookmarkID);\r\n if (!bookmark) return;\r\n\r\n dispatch(updateSettingsState(bookmark.settings));\r\n\r\n viewer.applySavedAerialState(bookmark.aerialState);\r\n\r\n const visibleAssetIDs = visibleAssets.map(asset => asset.id);\r\n const bookmarkAssetIDs = getValidAssetIDs(bookmark);\r\n\r\n visibleAssetIDs.sort();\r\n bookmarkAssetIDs.sort();\r\n\r\n if (isEqual(visibleAssetIDs, bookmarkAssetIDs)) {\r\n // Apply scene state directly\r\n viewer.applySavedSceneState(bookmark.sceneState, true);\r\n } else {\r\n // Set saved scene state and apply new asset visibility\r\n viewer.setInitialStateFlag(false);\r\n dispatch(changeCameraState(bookmark.sceneState));\r\n dispatch(setVisibleAssets(bookmarkAssetIDs));\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const deleteBookmarks = () => {\r\n for (let bookmark of bookmarks) {\r\n dispatch(deleteBookmark(bookmark.id));\r\n }\r\n };\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};","import { useCallback, useState } from \"react\";\r\nimport {\r\n EnhancedTableColumn,\r\n EnhancedTableRow,\r\n EnhancedTableState,\r\n TableSortDir\r\n} from \"../types/enhanced-table\";\r\nimport { debounce } from 'throttle-debounce';\r\n\r\ninterface TableStateProps {\r\n defaultSort?: string;\r\n pageSize?: number;\r\n rowPropertyMap?: {[key: string]: string};\r\n}\r\n\r\nexport const useTableState = (props: TableStateProps = {}) : EnhancedTableState => {\r\n const {defaultSort, pageSize = 10, rowPropertyMap = {}} = props;\r\n\r\n const [query, setQuery] = useState(\"\");\r\n const [sortDir, setSortDir] = useState('asc');\r\n const [sortBy, setSortBy] = useState(defaultSort);\r\n const [pageNumber, setPageNumber] = useState(0);\r\n const [rowsPerPage, setRowsPerPage] = useState(pageSize);\r\n\r\n const reset = () => {\r\n setQuery(\"\");\r\n setSortDir(\"asc\");\r\n setSortBy(defaultSort);\r\n setPageNumber(0);\r\n setRowsPerPage(pageSize);\r\n };\r\n\r\n const descendingComparator = (a, b, sortBy) => {\r\n sortBy = (sortBy in rowPropertyMap)\r\n ? rowPropertyMap[sortBy]\r\n : sortBy;\r\n\r\n let compA = a[sortBy];\r\n let compB = b[sortBy];\r\n\r\n if (typeof compA === \"string\") {\r\n compA = compA.toLowerCase();\r\n }\r\n\r\n if (typeof compB === \"string\") {\r\n compB = compB.toLowerCase();\r\n }\r\n\r\n if (compB < compA) {\r\n return -1;\r\n } else if (compB > compA) {\r\n return 1;\r\n } else {\r\n return 0;\r\n }\r\n };\r\n\r\n const getComparator = (sortDir, sortBy) => {\r\n return sortDir === 'desc'\r\n ? (a, b) => descendingComparator(a, b, sortBy)\r\n : (a, b) => -descendingComparator(a, b, sortBy);\r\n };\r\n\r\n const handlePageNumberChange = (event, value) => {\r\n setPageNumber(value);\r\n };\r\n\r\n const handleRowsPerPageChange = (event) => {\r\n const value = parseInt(event.target.value, 10);\r\n setRowsPerPage(value);\r\n setPageNumber(0);\r\n };\r\n\r\n const handleSearchChange = useCallback(debounce(200, (value) => {\r\n setQuery(value);\r\n setPageNumber(0);\r\n }), []);\r\n\r\n const handleRequestSort = (event, value) => {\r\n const ascending = sortBy === value && sortDir === 'asc';\r\n setSortDir(ascending ? 'desc' : 'asc');\r\n setSortBy(value);\r\n };\r\n\r\n const handleSearch = (columns: EnhancedTableColumn[], rows: EnhancedTableRow[]) => {\r\n if (!query) return rows;\r\n\r\n const queryParts = query\r\n .split(\" \")\r\n .map(x => x.toLowerCase());\r\n\r\n const searchableColumns = columns\r\n .filter(column => column.searchable)\r\n .map(column => column.id);\r\n\r\n return rows.filter(row => {\r\n let valid = false;\r\n\r\n searchableColumns.forEach(column => {\r\n if (valid) return;\r\n\r\n const parts = row[column]\r\n .split(\" \")\r\n .map(x => x.toLowerCase());\r\n\r\n valid = valid || queryParts.filter(text => {\r\n return parts.filter(x => x.includes(text)).length > 0;\r\n }).length === queryParts.length;\r\n });\r\n\r\n return valid;\r\n });\r\n };\r\n\r\n const handleSort = (rows: EnhancedTableRow[]) => {\r\n rows.sort(getComparator(sortDir, sortBy));\r\n return rows;\r\n };\r\n\r\n const handlePages = (rows: EnhancedTableRow[]) => {\r\n return rows.slice(\r\n pageNumber * rowsPerPage,\r\n pageNumber * rowsPerPage + rowsPerPage\r\n );\r\n };\r\n\r\n return {\r\n query,\r\n rowsPerPage,\r\n pageNumber,\r\n sortDir,\r\n sortBy,\r\n handlePageNumberChange,\r\n handleRowsPerPageChange,\r\n handleSearchChange,\r\n handleRequestSort,\r\n handleSearch,\r\n handleSort,\r\n handlePages,\r\n reset\r\n };\r\n};","import {createSlice, nanoid, PayloadAction} from '@reduxjs/toolkit';\r\nimport api from '../api';\r\nimport { AerialViewState, SceneCameraState } from './camera-slice';\r\nimport { SettingsState } from './settings-slice';\r\n\r\nexport interface Bookmark {\r\n id: string;\r\n name: string;\r\n date: string;\r\n position: number[];\r\n visible: boolean;\r\n visibleAssets: string[],\r\n settings: SettingsState;\r\n aerialState: AerialViewState;\r\n sceneState: SceneCameraState;\r\n}\r\n\r\nconst getByID = (state, bookmarkID: string) => {\r\n return state.find(bookmark => bookmark.id === bookmarkID);\r\n};\r\n\r\nexport const bookmarksSlice = createSlice({\r\n name: 'bookmarks',\r\n initialState: [] as Bookmark[],\r\n reducers: {\r\n createBookmark: (state, action: PayloadAction<{\r\n name: string,\r\n position: number[],\r\n visibleAssets: string[],\r\n settings: SettingsState,\r\n aerialState: AerialViewState,\r\n sceneState: SceneCameraState\r\n }>) => {\r\n const attributes = action.payload;\r\n\r\n const bookmark = {\r\n id: nanoid(),\r\n date: new Date().toISOString(),\r\n visible: true,\r\n ...attributes\r\n };\r\n\r\n state.push(bookmark);\r\n\r\n // Update cloud site\r\n api.bookmarks.create(bookmark);\r\n },\r\n updateBookmark: (state, action: PayloadAction<{\r\n bookmarkID: string,\r\n name?: string,\r\n position?: number[],\r\n visible?: boolean,\r\n visibleAssets?: string[],\r\n settings?: SettingsState,\r\n aerialState?: AerialViewState,\r\n sceneState?: SceneCameraState;\r\n }>) => {\r\n const {bookmarkID, ...updates} = action.payload;\r\n\r\n const bookmark = getByID(state, bookmarkID);\r\n if (!bookmark) return;\r\n\r\n for (let key in updates) {\r\n if (bookmark.hasOwnProperty(key)) {\r\n bookmark[key] = updates[key];\r\n };\r\n };\r\n\r\n // Update modified date\r\n bookmark.date = new Date().toISOString();\r\n\r\n // Update cloud site\r\n api.bookmarks.update(bookmarkID, {...updates, date: bookmark.date});\r\n },\r\n deleteBookmark: (state, action: PayloadAction) => {\r\n const bookmarkID = action.payload;\r\n const modified = state.filter(bookmark => bookmark.id !== bookmarkID);\r\n\r\n // Update cloud site\r\n api.bookmarks.delete(bookmarkID);\r\n\r\n return modified;\r\n },\r\n\r\n /** Websocket specific */\r\n wsCreateBookmark: (state, action: PayloadAction) => {\r\n const bookmark = action.payload;\r\n if (getByID(state, bookmark.id)) return;\r\n\r\n state.push(bookmark);\r\n },\r\n wsUpdateBookmark: (state, action: PayloadAction) => {\r\n const {id, ...updates} = action.payload;\r\n\r\n let bookmark = getByID(state, id);\r\n if (!bookmark) return;\r\n\r\n for (let key in updates) {\r\n if (bookmark.hasOwnProperty(key)) {\r\n bookmark[key] = updates[key];\r\n };\r\n };\r\n },\r\n wsDeleteBookmark: (state, action: PayloadAction) => {\r\n const bookmarkID = action.payload;\r\n return state.filter(bookmark => bookmark.id !== bookmarkID);\r\n },\r\n }\r\n});\r\n\r\nexport default bookmarksSlice.reducer;\r\n\r\nexport const {\r\n wsCreateBookmark,\r\n wsUpdateBookmark,\r\n wsDeleteBookmark,\r\n createBookmark,\r\n deleteBookmark,\r\n updateBookmark,\r\n} = bookmarksSlice.actions;\r\n\r\nexport const selectAllBookmarks = state => state.bookmarks as Bookmark[];\r\n","import { nanoid } from '@reduxjs/toolkit';\r\nimport path from 'path';\r\nimport {setStoragePath} from \"./move-settings\";\r\n\r\n/** Electron specific modules that will fail for static html site */\r\n\r\nconst getCloudProjectID = () : string => {\r\n const pattern = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;\r\n const url = new URL(window.location.href);\r\n const parts = url.pathname.split(\"/\");\r\n return parts.find(x => pattern.test(x));\r\n};\r\n\r\nconst checkForCloudSite = (cloudProjectID) => {\r\n const url = new URL(window.location.href);\r\n const parts = url.pathname.split(\"/\");\r\n const hasViewer = parts.includes(\"viewer\");\r\n return hasViewer && !!cloudProjectID;\r\n};\r\n\r\nexport const electron = window.require\r\n ? window.require(\"electron\")\r\n : null;\r\n\r\nexport const child = electron\r\n ? window.require(\"child_process\")\r\n : null;\r\n\r\nexport const process = electron\r\n ? window.require(\"process\")\r\n : null;\r\n\r\nexport const remote = electron?.remote;\r\nexport const shell = electron?.shell;\r\nexport const ipcRenderer = electron?.ipcRenderer;\r\nexport const dialog = remote?.dialog;\r\nexport const app = remote?.app;\r\nexport const getCurrentWindow = remote?.getCurrentWindow;\r\nexport const Menu = remote?.Menu;\r\nexport const fs = remote?.require('fs');\r\nexport const fse = remote?.require('fs-extra');\r\nexport const glob = remote?.require('glob');\r\n\r\nexport const cloudProjectID = getCloudProjectID();\r\nexport const isStaticSite = !electron;\r\nexport const isElectronApp = !!electron;\r\nexport const isCloudSite = checkForCloudSite(cloudProjectID);\r\n\r\nexport const storage = electron\r\n ? remote.require('electron-json-storage')\r\n : null;\r\n\r\nexport const isDevMode = remote\r\n ? (app.isPackaged === false)\r\n : false;\r\n\r\nexport const tempDirectoryPath = app\r\n ? path.join(app.getPath('userData'), \"temp\")\r\n : null;\r\n\r\nexport const logDirectoryPath = app\r\n ? path.join(app.getPath('userData'), \"logs\")\r\n : null;\r\n\r\nexport const getTemporaryFile = (suffix) => {\r\n return path.join(tempDirectoryPath, `${nanoid()}.${suffix}`);\r\n};\r\n\r\nconst clearTemporaryFiles = async () => {\r\n if (isStaticSite) return;\r\n\r\n let numRemoved = 0;\r\n const maxTimeElapsedSeconds = 3600; // One hour\r\n const filenames = await fse.readdir(tempDirectoryPath);\r\n\r\n for (let filename of filenames) {\r\n const filePath = path.join(tempDirectoryPath, filename);\r\n const stats = await fse.stat(filePath);\r\n const currentDate = Date.now();\r\n const timeElapsed = (currentDate - stats.birthtimeMs)/1000;\r\n\r\n if (timeElapsed > maxTimeElapsedSeconds) {\r\n fse.remove(filePath);\r\n numRemoved += 1;\r\n }\r\n }\r\n\r\n if (numRemoved === 0) return;\r\n console.log(`Deleted ${numRemoved} temporary files`);\r\n};\r\n\r\nconst createInitialFolders = () => {\r\n if (isStaticSite) return;\r\n\r\n if (!fs.existsSync(tempDirectoryPath)) {\r\n console.log(\"Creating temporary file folder...\");\r\n fs.mkdirSync(tempDirectoryPath);\r\n }\r\n\r\n if (!fs.existsSync(logDirectoryPath)) {\r\n console.log(\"Creating log output folder...\");\r\n fs.mkdirSync(logDirectoryPath);\r\n }\r\n};\r\n\r\nexport const registerEvent = (eventName, callback) => {\r\n if(!ipcRenderer) return;\r\n ipcRenderer.removeAllListeners(eventName);\r\n ipcRenderer.on(eventName, callback);\r\n};\r\n\r\ncreateInitialFolders();\r\nclearTemporaryFiles();\r\n\r\nconst userSettings = ['default-settings', 'global-settings'];\r\nsetStoragePath(userSettings, isStaticSite);","import path from \"path\";\r\nimport {app, storage, fs} from \"./electron-modules\";\r\n\r\nconst changeDuplicateNames = (projections) => {\r\n const projectionsByName = {};\r\n\r\n projections.forEach((projection) => {\r\n if (!projectionsByName[projection.name]) {\r\n projectionsByName[projection.name] = 2;\r\n } else {\r\n const newName = `${projection.name} (${projectionsByName[projection.name]})`;\r\n projectionsByName[projection.name]++;\r\n projection.name = newName;\r\n }\r\n });\r\n};\r\n\r\nexport const setStoragePath = (userSettings, isStaticSite) => {\r\n if (isStaticSite) return;\r\n const storagePath = path.join(app.getPath('appData'), 'SOLV3D Data');\r\n\r\n if (!fs.existsSync(storagePath)) {\r\n fs.mkdirSync(storagePath);\r\n }\r\n\r\n const engineStoragePath = path.join(app.getPath('appData'), 'SOLV3D engine/storage');\r\n const viewerStoragePath = path.join(app.getPath('appData'), 'SOLV3D engine viewer/storage');\r\n\r\n for (const settingName of userSettings) {\r\n let oldName = path.join(viewerStoragePath, `${settingName}.json`);\r\n let newName = path.join(storagePath, `${settingName}.json`);\r\n if (fs.existsSync(oldName) && !fs.existsSync(newName)) {\r\n fs.copyFileSync(oldName, newName);\r\n }\r\n }\r\n if (fs.existsSync(path.join(storagePath, 'user-projections.json'))) {\r\n storage.setDataPath(storagePath);\r\n return;\r\n }\r\n\r\n const engineProjectionExist = fs.existsSync(path.join(engineStoragePath, 'user-projections.json'));\r\n const viewerProjectionExist = fs.existsSync(path.join(viewerStoragePath, 'projection.json'));\r\n\r\n let projectionData = [];\r\n if (viewerProjectionExist) {\r\n projectionData = [\r\n ...projectionData,\r\n ...storage.getSync('projection', {dataPath: viewerStoragePath})];\r\n }\r\n if (engineProjectionExist) {\r\n let engineProjections = storage.getSync('user-projections', {dataPath: engineStoragePath});\r\n Object.keys(engineProjections).forEach((key) => {\r\n let data = engineProjections[key];\r\n if ('transform' in data) {\r\n data.transform = {\r\n origin: data.transform.origin,\r\n translation: data.transform.translation,\r\n rotation: data.transform.rotation,\r\n scale: data.transform.scale\r\n };\r\n }\r\n let finalData = {type: 'proj4', name: key, ...data};\r\n projectionData.push(finalData);\r\n });\r\n }\r\n if (viewerProjectionExist && engineProjectionExist) {\r\n changeDuplicateNames(projectionData);\r\n }\r\n storage.setDataPath(storagePath);\r\n storage.setSync('user-projections', projectionData);\r\n};\r\n","export enum ProjectType {\r\n Standard = 0,\r\n Static = 1,\r\n Cloud = 2\r\n}\r\n\r\nexport enum AccessType {\r\n ViewOnly = 0,\r\n Standard = 1,\r\n Admin = 2\r\n}\r\n","/* eslint-disable import/no-webpack-loader-syntax */\r\nimport i18n from \"i18next\";\r\nimport { initReactI18next } from \"react-i18next\";\r\nimport LanguageDetector from \"i18next-browser-languagedetector\";\r\n\r\nimport en from \"./translations/en.json\";\r\nimport de from \"./translations/de.json\";\r\nimport fr from \"./translations/fr.json\";\r\nimport es from \"./translations/es.json\";\r\nimport ja from \"./translations/ja.json\";\r\n\r\nconst resources = {\r\n en: {translation: en},\r\n de: {translation: de},\r\n fr: {translation: fr},\r\n es: {translation: es},\r\n ja: {translation: ja}\r\n};\r\n\r\n/** Makes sure that unsupported languages are ignored */\r\nconst supportedLngs = Object.keys(resources);\r\n\r\ni18n\r\n .use(initReactI18next)\r\n .use(LanguageDetector)\r\n .init({\r\n resources,\r\n detection: {\r\n cookieMinutes: 365*24*60 // one year\r\n },\r\n supportedLngs,\r\n fallbackLng: \"en\",\r\n interpolation: {\r\n escapeValue: false\r\n }\r\n });\r\n\r\nexport default i18n;\r\nexport const t = i18n.t;","export * from \"./i18n\";\r\n\r\n/** Add the language flag to the specified url */\r\nexport const getLocalizedURL = (url: string, language: string) => {\r\n return url.includes(\"?\")\r\n ? `${url}&lng=${language}`\r\n : `${url}?lng=${language}`;\r\n};\r\n\r\n/** Update the window url to include the language flag */\r\nexport const setLocalizedURL = (language: string) => {\r\n const url = new URL(window.location as any);\r\n url.searchParams.set('lng', language);\r\n window.history.pushState({}, '', url as any);\r\n};\r\n","import classificationsShader from \"./viewer/textures/colormaps/classifications.png\";\r\n\r\nexport interface Classification {\r\n id: number;\r\n name: string;\r\n alias: Array<[]>;\r\n}\r\n\r\nconst numberOfDefinedClassifications = 19;\r\nexport const numberOfClassifications = 256;\r\n\r\nexport const classifications = [\r\n {\r\n id: 0,\r\n name: \"Never Classified\",\r\n alias: [\"never classified\", \"unclassified\"]\r\n },\r\n {\r\n id: 1,\r\n name: \"Unassigned\",\r\n alias: [\"unassigned\"]\r\n },\r\n {\r\n id: 2,\r\n name: \"Ground\",\r\n alias: ['ground', 'dtm', 'base', 'earth', 'dirt', 'land', 'd.t.m'],\r\n },\r\n {\r\n id: 3,\r\n name: \"Low Vegetation\",\r\n alias: ['low_vegetation','low vegetation', 'low_veg', 'low veg', 'lo veg','lo_veg'],\r\n\r\n },\r\n {\r\n id: 4,\r\n name: \"Medium Vegetation\",\r\n alias: ['vegetation', 'tree', 'trees', 'bushes', 'lawn', 'forest', 'garden',\r\n 'gardens', 'arbor', 'flora', 'crops', 'crop', 'green', 'greenery',\r\n 'medium_vegetation', 'medium vegetation', 'med_veg', 'med veg', 'medium veg',\r\n 'medium_veg']\r\n },\r\n {\r\n id: 5,\r\n name: \"High Vegetation\",\r\n alias: ['high_vegetation', 'high vegetation', 'high_veg', 'high veg', 'hi veg',\r\n 'hi veg', 'canopy']\r\n },\r\n {\r\n id: 6,\r\n name: \"Building\",\r\n alias: ['building', 'buildings', 'structures', 'built']\r\n },\r\n {\r\n id: 7,\r\n name: \"Noise\",\r\n alias: ['noise', 'errors', 'multipass']\r\n },\r\n {\r\n id: 8,\r\n name: 'Model Key/Reserved',\r\n alias: ['lightpole', 'light pole', 'pole', 'power pole', 'powerpole', 'lightpoles',\r\n 'light poles', 'light_poles', 'power_pole', 'power_poles', 'model key', 'reserved']\r\n },\r\n {\r\n id: 9,\r\n name: \"Water\",\r\n alias: ['water', 'river', 'stream', 'sea', 'ocean', 'lake', 'bay','lagoon','lakes',\r\n 'rivers', 'streams', 'lagoons', 'waterway', 'waterways']\r\n },\r\n {\r\n id: 10,\r\n name: \"Rail\",\r\n alias: ['rail', 'railroad', 'rail road', 'train', 'trains', 'rail-road', 'rail_road',\r\n 'railway', 'railways', 'railroads']\r\n },\r\n {\r\n id: 11,\r\n name: \"Road Surface\",\r\n alias: ['road', 'roads', 'streets', 'highway', 'highways', 'avenues', 'pavement',\r\n 'road surface', 'road_surface', 'road surfaces', 'road_surfaces']\r\n },\r\n {\r\n id: 12,\r\n name: 'Overlap/Reserved',\r\n alias: ['overlap', 'overlap reserved', 'overlap_reserved']\r\n },\r\n {\r\n id: 13,\r\n name: \"Wire - Guard\",\r\n alias: ['wire guard', 'wire-guard', 'wires - guard', 'wire_guard']\r\n },\r\n {\r\n id: 14,\r\n name: \"Wire - Conductor\",\r\n alias: ['wire conductor', 'wire-conductor', 'wires - conductor', 'wire_conductor']\r\n },\r\n {\r\n id: 15,\r\n name: \"Transmission Tower\",\r\n alias: ['transmission tower', 'transmission-tower', 'transmission_tower']\r\n },\r\n {\r\n id: 16,\r\n name: \"Wire - Connector\",\r\n alias: ['powerlines', 'power lines', 'powerline', 'power line', 'power_lines',\r\n 'power_line', 'wire', 'wires', 'connectors', 'wire_connector', 'wire connector',\r\n 'wire_connectors', 'wire connectors']\r\n },\r\n {\r\n id: 17,\r\n name: \"Bridge Deck\",\r\n alias: ['bridge', 'bridge deck', 'bridge-deck', 'bridge_deck', 'bridges', 'overpass',\r\n 'overpasses', 'fly over', 'fly-over', 'fly_over']\r\n },\r\n {\r\n id: 18,\r\n name: \"High Noise\",\r\n alias: ['high noise', 'high_noise', 'high-noise', 'highnoise']\r\n },\r\n ...Array.from(Array(numberOfClassifications - numberOfDefinedClassifications).keys()).map(key => ({id: key + numberOfDefinedClassifications, name: 'Reserved', alias:[]}))\r\n];\r\n\r\nexport const getClassificationColors = (): Promise => {\r\n return new Promise(resolve => {\r\n const image = new Image();\r\n\r\n image.onload = () => {\r\n const canvas = document.createElement('canvas');\r\n canvas.width = image.width;\r\n canvas.height = image.height;\r\n\r\n const context = canvas.getContext('2d');\r\n context.drawImage(image, 0, 0);\r\n\r\n const imageData = context.getImageData(0, 0, canvas.width, canvas.height);\r\n let colors = [];\r\n\r\n for (let i = 0; i < classifications.length; i++) {\r\n let index = i * 4;\r\n\r\n let red = imageData.data[index] << 16;\r\n let green = imageData.data[index + 1] << 8;\r\n let blue = imageData.data[index + 2];\r\n\r\n const hexColor = `#${(red + blue + green).toString(16).padStart(6, '0')}`;\r\n colors.push(hexColor);\r\n }\r\n\r\n resolve(colors);\r\n };\r\n\r\n image.src = classificationsShader;\r\n });\r\n};","import { lighten } from \"@material-ui/core\";\r\n\r\nexport const corporate = {\r\n red: '#DD0C29',\r\n blue: '#162031',\r\n grey: '#A8AFBA'\r\n};\r\n\r\nexport const getGradient = (color: string) => {\r\n const fadeColor = lighten(color, 0.35);\r\n return `linear-gradient(180deg, ${fadeColor} 0%, ${color} 100%)`;\r\n};\r\n","import { createMuiTheme, darken, lighten } from \"@material-ui/core\";\r\nimport { corporate } from \"./colors\";\r\n\r\nexport * from \"./colors\";\r\n\r\nconst themeSpacing = 8;\r\n\r\nexport const createTheme = () => {\r\n return createMuiTheme({\r\n spacing: themeSpacing,\r\n zIndex: {\r\n appBar: 1100,\r\n modal: 1250,\r\n drawer: 1200,\r\n snackbar: 1400,\r\n tooltip: 1500\r\n },\r\n overrides: {\r\n MuiPopover: {\r\n root: {\r\n \"z-index\": \"1300 !important\"\r\n }\r\n },\r\n MuiTooltip: {\r\n tooltip: {\r\n backgroundColor: \"rgba(0, 0, 0, 0.7)\",\r\n },\r\n arrow: {\r\n \"&::before\": {\r\n backgroundColor: \"rgba(0, 0, 0, 0.7)\",\r\n border: \"0px\"\r\n }\r\n },\r\n },\r\n MuiDialogTitle: {\r\n root: {\r\n padding: `${themeSpacing}px`,\r\n '& h2': {\r\n fontSize: \"1.0rem !important\"\r\n }\r\n }\r\n },\r\n MuiDialogContent: {\r\n root: {\r\n padding: `${2*themeSpacing}px`,\r\n }\r\n },\r\n MuiIconButton: {\r\n root: {\r\n padding: `${themeSpacing}px`\r\n }\r\n }\r\n },\r\n palette: {\r\n primary: {\r\n main: corporate.blue,\r\n light: lighten(corporate.blue, 0.25),\r\n dark: darken(corporate.blue, 0.25)\r\n },\r\n secondary: {\r\n main: corporate.red,\r\n light: lighten(corporate.red, 0.25),\r\n dark: darken(corporate.red, 0.25)\r\n }\r\n },\r\n mixins: {\r\n toolbar: {\r\n // override default\r\n }\r\n }\r\n });\r\n};\r\n","import { isCloudSite } from \"../electron-modules\";\r\nimport { withOriginalID } from \"../export/utils/misc\";\r\nimport { Asset, TagData, TagItemData } from \"../redux/assets-slice\";\r\nimport { SceneCameraState } from \"../redux/camera-slice\";\r\nimport { TagSize } from \"../types/tags\";\r\nimport { engineCloudURL } from \"../urls\";\r\n\r\n\r\nconst createTagCollection = async (folderID: string, asset: Asset) => {\r\n if (!isCloudSite) return;\r\n\r\n const {texture, size} = asset.data as TagData;\r\n const tagCollection = {...asset, texture, size};\r\n delete tagCollection.data;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/folders/${folderID}/tag-collections`;\r\n await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(withOriginalID(tagCollection))\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst deleteTagCollection = async (assetID: string) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/tag-collections/${assetID}`;\r\n await fetch(url, {method: \"DELETE\"});\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst updateTagCollection = async (assetID: string, options: {\r\n name?: string,\r\n visible?: boolean,\r\n size?: TagSize,\r\n texture?: string,\r\n}) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/tag-collections/${assetID}`;\r\n await fetch(url, {\r\n method: \"PUT\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(options)\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst createTags = async (assetID: string, tags: TagItemData[]) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/tag-collections/${assetID}/tags`;\r\n await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(tags.map(tag => withOriginalID(tag)))\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst updateTag = async (tagID: string, options: {\r\n name?: string,\r\n comment?: string,\r\n sceneState?: SceneCameraState,\r\n date?: string\r\n}) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/tags/${tagID}`;\r\n await fetch(url, {\r\n method: \"PUT\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(options)\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst deleteTag = async (tagID: string) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/tags/${tagID}`;\r\n await fetch(url, {method: \"DELETE\"});\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst actions = {\r\n create: createTags,\r\n delete: deleteTag,\r\n update: updateTag,\r\n createCollection: createTagCollection,\r\n deleteCollection: deleteTagCollection,\r\n updateCollection: updateTagCollection\r\n};\r\n\r\nexport default actions;","import { cloudProjectID, isCloudSite } from \"../electron-modules\";\r\nimport { withOriginalID } from \"../export/utils/misc\";\r\nimport { Bookmark } from \"../redux/bookmarks-slice\";\r\nimport { AerialViewState, SceneCameraState } from \"../redux/camera-slice\";\r\nimport { SettingsState } from \"../redux/settings-slice\";\r\nimport { engineCloudURL } from \"../urls\";\r\n\r\nconst createBookmark = async (bookmark: Bookmark) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/projects/${cloudProjectID}/bookmarks`;\r\n await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(withOriginalID(bookmark))\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\ninterface UpdateOptions {\r\n name?: string,\r\n date?: string,\r\n position?: number[],\r\n visible?: boolean,\r\n visibleAssets?: string[],\r\n settings?: SettingsState,\r\n aerialState?: AerialViewState,\r\n sceneState?: SceneCameraState;\r\n}\r\n\r\nconst updateBookmark = async (bookmarkID: string, options: UpdateOptions) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/bookmarks/${bookmarkID}`;\r\n await fetch(url, {\r\n method: \"PUT\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(options)\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst deleteBookmark = async (bookmarkID: string) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/bookmarks/${bookmarkID}`;\r\n await fetch(url, {method: \"DELETE\"});\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst actions = {\r\n create: createBookmark,\r\n delete: deleteBookmark,\r\n update: updateBookmark,\r\n};\r\n\r\nexport default actions;","import tagsActions from \"./tags\";\r\nimport bookmarkActions from \"./bookmarks\";\r\nimport foldersActions from \"./folders\";\r\n\r\nconst actions = {\r\n folders: foldersActions,\r\n tags: tagsActions,\r\n bookmarks: bookmarkActions\r\n};\r\n\r\nexport default actions;","import { isCloudSite, cloudProjectID } from \"../electron-modules\";\r\nimport { withOriginalID } from \"../export/utils/misc\";\r\nimport { Folder } from \"../redux/folders-slice\";\r\nimport { engineCloudURL } from \"../urls\";\r\n\r\nconst createFolder = async (folder: Folder) => {\r\n if (!isCloudSite) return;\r\n\r\n try {\r\n const url = `${engineCloudURL}/api/projects/${cloudProjectID}/folders`;\r\n await fetch(url, {\r\n method: \"POST\",\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify(withOriginalID(folder))\r\n });\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n};\r\n\r\nconst actions = {\r\n create: createFolder\r\n};\r\n\r\nexport default actions;","import {createSlice, nanoid, PayloadAction} from '@reduxjs/toolkit';\r\nimport api from '../api';\r\nimport {\r\n e57FileFormat,\r\n encompassFileFormat,\r\n potreeFileFormat,\r\n lasFileFormat\r\n} from '../file-extensions';\r\nimport { TagSize } from '../types/tags';\r\nimport { ServerType } from '../types/web-sources';\r\nimport { SceneCameraState } from './camera-slice';\r\n\r\nexport interface PlanarConfig {\r\n width: number;\r\n height: number;\r\n cx: number;\r\n cy: number;\r\n fx: number;\r\n fy: number;\r\n}\r\n\r\nexport interface CameraData {\r\n id: string;\r\n x: number;\r\n y: number;\r\n z: number;\r\n roll: number;\r\n pitch: number;\r\n yaw: number;\r\n path: string;\r\n name: string;\r\n config?: PlanarConfig;\r\n}\r\n\r\nexport interface OrthoData {\r\n imageBounds: [];\r\n imageDataSplit: [];\r\n imageData: string;\r\n imageSize: [number, number];\r\n imageSizeOriginal: [number, number];\r\n imagePath: string;\r\n scaleX: number;\r\n scaleY: number;\r\n}\r\n\r\nexport interface TagItemData {\r\n id: string;\r\n name: string;\r\n comment: string;\r\n date: string;\r\n x: number;\r\n y: number;\r\n z?: number;\r\n sceneState: SceneCameraState;\r\n}\r\n\r\nexport interface TagData {\r\n size: TagSize;\r\n texture: string;\r\n items: TagItemData[];\r\n}\r\n\r\nexport interface LineworkLayerData {\r\n id: string;\r\n name: string;\r\n visible: boolean;\r\n color: string;\r\n}\r\n\r\nexport interface WebMapData {\r\n url: string;\r\n type: ServerType;\r\n public: boolean;\r\n layers: WebMapLayerData[];\r\n}\r\n\r\nexport interface WebMapLayerData {\r\n id: string;\r\n name: string;\r\n visible: boolean;\r\n identifier: string;\r\n}\r\n\r\ninterface XMLAlignment {\r\n id: string;\r\n name: string;\r\n length: number;\r\n staStart: number;\r\n about: string;\r\n geometry: object[];\r\n}\r\n\r\nexport interface XMLData {\r\n info: object;\r\n units: object;\r\n alignments: XMLAlignment[];\r\n enu: boolean;\r\n}\r\n\r\ntype assetData = OrthoData | CameraData[] | TagData\r\n | LineworkLayerData[] | XMLData | WebMapData\r\n\r\n\r\nexport interface Asset {\r\n id: string;\r\n name: string;\r\n path: string;\r\n saved: boolean;\r\n cloud: boolean;\r\n date: string;\r\n visible: boolean;\r\n folderID: string;\r\n type: AssetType;\r\n data: assetData;\r\n}\r\n\r\nexport interface WebSourceAsset extends Asset {\r\n type: AssetType.Webmap;\r\n data: WebMapData;\r\n}\r\n\r\nexport interface AssetInfo {\r\n name: string;\r\n path: string;\r\n folderID: string;\r\n type: AssetType;\r\n data?: assetData;\r\n}\r\n\r\nexport enum AssetType {\r\n LAS = 0,\r\n Encompass = 1,\r\n Panoramic = 2,\r\n Unknown = 3,\r\n OrthoMosaic = 4,\r\n Planar = 5,\r\n E57Points = 6,\r\n Tag = 7,\r\n IFC = 8,\r\n Potree = 9,\r\n SHP = 10,\r\n DXF = 11,\r\n LandXML = 12,\r\n Webmap = 13\r\n}\r\n\r\nexport const pointCloudType = (ext: string): AssetType => {\r\n if (ext === lasFileFormat) {\r\n return AssetType.LAS;\r\n } else if (ext === encompassFileFormat) {\r\n return AssetType.Encompass;\r\n } else if (ext === e57FileFormat) {\r\n return AssetType.E57Points;\r\n } else if (ext === potreeFileFormat) {\r\n return AssetType.Potree;\r\n } else {\r\n return AssetType.Unknown;\r\n }\r\n};\r\n\r\nconst getByID = (state, assetID: string) => {\r\n return state.find(asset => asset.id === assetID);\r\n};\r\n\r\nconst getAssetByTagID = (state, tagID: string): Asset => {\r\n for (let asset of state) {\r\n if (asset.type !== AssetType.Tag) continue;\r\n\r\n const tags = (asset.data as TagData).items;\r\n const tagIDs = tags.map(x => x.id);\r\n if (tagIDs.includes(tagID)) return asset;\r\n }\r\n};\r\n\r\nconst getAssetByWebMapLayerID = (state, layerID: string): Asset => {\r\n for (let asset of state) {\r\n if (asset.type !== AssetType.Webmap) continue;\r\n\r\n const layers = (asset.data as WebMapData).layers;\r\n const layerIDs = layers.map(x => x.id);\r\n if (layerIDs.includes(layerID)) return asset;\r\n }\r\n};\r\n\r\nconst getAssetByModelLayerID = (state, layerID: string): Asset => {\r\n for (let asset of state) {\r\n const isModelWithLayers = (asset.type === AssetType.DXF)\r\n || (asset.type === AssetType.SHP);\r\n if (!isModelWithLayers) continue;\r\n\r\n const layers = asset.data as LineworkLayerData[];\r\n const layerIDs = layers.map(x => x.id);\r\n if (layerIDs.includes(layerID)) return asset;\r\n }\r\n};\r\n\r\nconst getAssetPayload = (item: AssetInfo): Asset => {\r\n return {\r\n id: nanoid(),\r\n name: item.name,\r\n path: item.path,\r\n date: new Date().toISOString(),\r\n type: item.type,\r\n folderID: item.folderID,\r\n visible: true,\r\n saved: false,\r\n cloud: false,\r\n data: item.data\r\n } as Asset;\r\n};\r\n\r\nexport const assetsSlice = createSlice({\r\n name: 'assets',\r\n initialState: [] as Asset[],\r\n reducers: {\r\n addAsset: (state, action: PayloadAction) => {\r\n const asset = getAssetPayload(action.payload);\r\n state.push(asset);\r\n },\r\n addAssets: (state, action: PayloadAction) => {\r\n action.payload.forEach(payload => {\r\n const asset = getAssetPayload(payload);\r\n state.push(asset);\r\n });\r\n },\r\n updateAsset: (state, action: PayloadAction<{\r\n assetID: string,\r\n folderID?: string,\r\n visible?: boolean,\r\n name?: string,\r\n size?: TagSize,\r\n texture?: string,\r\n enu?: boolean\r\n }>) => {\r\n const {assetID, ...updates} = action.payload;\r\n\r\n const asset = getByID(state, assetID);\r\n if (!asset) return;\r\n\r\n for (let key in updates) {\r\n // Generic asset values\r\n if (asset.hasOwnProperty(key)) {\r\n asset[key] = updates[key];\r\n };\r\n\r\n // Data specific values\r\n if (asset.data && asset.data.hasOwnProperty(key)) {\r\n asset.data[key] = updates[key];\r\n };\r\n };\r\n },\r\n deleteAsset: (state, action: PayloadAction) => {\r\n return state.filter(asset => asset.id !== action.payload);\r\n },\r\n\r\n toggleFolderVisibility: (state, action) => {\r\n const {folderID, visible} = action.payload;\r\n const assets = state.filter(asset => asset.folderID === folderID);\r\n\r\n assets.forEach(asset => {\r\n asset.visible = visible;\r\n });\r\n },\r\n setVisibleAssets: (state, action) => {\r\n const visibleAssets = action.payload;\r\n state.forEach(asset => {\r\n asset.visible = visibleAssets.includes(asset.id);\r\n });\r\n },\r\n setVisibleFolder: (state, action) => {\r\n const folderID = action.payload;\r\n state.forEach(asset => {\r\n asset.visible = asset.folderID === folderID;\r\n });\r\n },\r\n setSavedState: (state, action) => {\r\n state.forEach(asset => {\r\n asset.saved = true;\r\n });\r\n },\r\n\r\n /** Model files */\r\n updateModelLayer: (state, action: PayloadAction<{\r\n layerID: string,\r\n visible?: boolean,\r\n color?: string\r\n }>) => {\r\n const {layerID, color, visible} = action.payload;\r\n const asset = getAssetByModelLayerID(state, layerID);\r\n if (!asset) return;\r\n\r\n const layers = asset.data as LineworkLayerData[];\r\n const layer = layers.find(x => x.id === layerID);\r\n if (!layer) return;\r\n\r\n if (\"visible\" in action.payload) {\r\n layer.visible = visible;\r\n }\r\n\r\n if (\"color\" in action.payload) {\r\n layer.color = color;\r\n }\r\n },\r\n\r\n /** Web sources */\r\n updateWebMapLayer: (state, action: PayloadAction<{\r\n layerID: string,\r\n visible: boolean\r\n }>) => {\r\n const {layerID, visible} = action.payload;\r\n const asset = getAssetByWebMapLayerID(state, layerID);\r\n if (!asset) return;\r\n\r\n const layers = (asset.data as WebMapData).layers;\r\n const layer = layers.find(x => x.id === layerID);\r\n if (!layer) return;\r\n\r\n layer.visible = visible;\r\n },\r\n\r\n /** Tag Items */\r\n createTags: (state, action: PayloadAction<{\r\n assetID: string;\r\n tags: TagItemData[];\r\n }>) => {\r\n const {assetID, tags} = action.payload;\r\n\r\n const asset = getByID(state, assetID);\r\n if (!asset) return;\r\n\r\n const items = (asset.data as TagData).items;\r\n\r\n asset.data = {\r\n ...asset.data,\r\n items: [...items, ...tags]\r\n } as TagData;\r\n\r\n // Update cloud site\r\n api.tags.create(assetID, tags);\r\n },\r\n deleteTag: (state, action: PayloadAction) => {\r\n const tagID = action.payload;\r\n const asset = getAssetByTagID(state, tagID);\r\n if (!asset) return;\r\n\r\n const items = (asset.data as TagData).items\r\n .filter(x => x.id !== tagID);\r\n\r\n asset.data = {\r\n ...asset.data,\r\n items\r\n } as TagData;\r\n\r\n // Update cloud site\r\n api.tags.delete(tagID);\r\n },\r\n updateTag: (state, action: PayloadAction<{\r\n tagID: string,\r\n name?: string,\r\n comment?: string,\r\n sceneState?: SceneCameraState\r\n }>) => {\r\n const {tagID, ...updates} = action.payload;\r\n const asset = getAssetByTagID(state, tagID);\r\n if (!asset) return;\r\n\r\n const items = (asset.data as TagData).items;\r\n const tag = items.find(tag => tag.id === tagID);\r\n if (!tag) return;\r\n\r\n for (let key in updates) {\r\n if (tag.hasOwnProperty(key)) {\r\n tag[key] = updates[key];\r\n };\r\n };\r\n\r\n // Update modified date\r\n tag.date = new Date().toISOString();\r\n\r\n // Update cloud site\r\n api.tags.update(tagID, {...updates, date: tag.date});\r\n },\r\n\r\n /** Websocket specific */\r\n wsCreateAsset: (state, action: PayloadAction) => {\r\n const asset = action.payload;\r\n if (getByID(state, asset.id)) return;\r\n\r\n state.push(asset);\r\n },\r\n wsUpdateAsset: (state, action: PayloadAction) => {\r\n const {id, ...updates} = action.payload;\r\n let asset = getByID(state, id);\r\n if (!asset) return;\r\n\r\n for (let key in updates) {\r\n if (asset.hasOwnProperty(key)) {\r\n asset[key] = updates[key];\r\n };\r\n };\r\n },\r\n wsDeleteAsset: (state, action: PayloadAction) => {\r\n const assetID = action.payload;\r\n return state.filter(asset => asset.id !== assetID);\r\n },\r\n }\r\n});\r\n\r\n/** Create new asset */\r\nexport const createAsset = (options: {\r\n name: string;\r\n folderID: string;\r\n path?: string;\r\n type: AssetType;\r\n texture: string;\r\n size: TagSize;\r\n}) => {\r\n const {name, folderID, type, path=null} = options;\r\n\r\n return async (dispatch, getState) => {\r\n\r\n let assetData;\r\n\r\n if (type === AssetType.Tag) {\r\n assetData = {\r\n size: options.size,\r\n texture: options.texture,\r\n items: []\r\n } as TagData;\r\n }\r\n\r\n dispatch(assetsSlice.actions.addAsset({\r\n folderID,\r\n name,\r\n path,\r\n type,\r\n data: assetData\r\n }));\r\n\r\n const assets = getState().assets as Asset[];\r\n const [asset] = assets.slice(-1);\r\n\r\n if (type === AssetType.Tag) {\r\n await api.tags.createCollection(folderID, asset);\r\n }\r\n\r\n return asset;\r\n };\r\n};\r\n\r\n/** Delete asset */\r\nexport const deleteAsset = (assetID: string) => {\r\n return (dispatch, getState) => {\r\n const assets = getState().assets as Asset[];\r\n const asset = assets.find(asset => asset.id === assetID);\r\n if (!asset) return;\r\n\r\n dispatch(assetsSlice.actions.deleteAsset(assetID));\r\n\r\n if (asset.type === AssetType.Tag) {\r\n api.tags.deleteCollection(assetID);\r\n }\r\n };\r\n};\r\n\r\n/** Update asset values */\r\nexport const updateAsset = (options: {\r\n assetID: string,\r\n name?: string,\r\n visible?: boolean,\r\n folderID?: string,\r\n texture?: string,\r\n size?: TagSize,\r\n enu?: boolean\r\n}) => {\r\n const {assetID, ...updates} = options;\r\n\r\n return (dispatch, getState) => {\r\n const assets = getState().assets as Asset[];\r\n const asset = assets.find(asset => asset.id === assetID);\r\n if (!asset) return;\r\n\r\n dispatch(assetsSlice.actions.updateAsset(options));\r\n\r\n if (asset.type === AssetType.Tag) {\r\n api.tags.updateCollection(assetID, updates);\r\n }\r\n };\r\n};\r\n\r\nexport default assetsSlice.reducer;\r\n\r\nexport const {\r\n wsCreateAsset,\r\n wsUpdateAsset,\r\n wsDeleteAsset,\r\n addAsset,\r\n addAssets,\r\n createTags,\r\n setVisibleAssets,\r\n updateWebMapLayer,\r\n updateModelLayer,\r\n toggleFolderVisibility,\r\n updateTag,\r\n setVisibleFolder,\r\n setSavedState,\r\n deleteTag\r\n} = assetsSlice.actions;\r\n\r\nexport const selectAllAssets = state => {\r\n return state.assets as Asset[];\r\n};\r\n\r\nexport const selectVisibleAssets = (state) : Asset[] => {\r\n return state.assets.filter(asset => asset.visible);\r\n};\r\n\r\nexport const getModelAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return (asset.type === AssetType.IFC)\r\n || (asset.type === AssetType.SHP)\r\n || (asset.type === AssetType.DXF);\r\n });\r\n};\r\n\r\nexport const getTagAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return asset.type === AssetType.Tag;\r\n });\r\n};\r\n\r\nexport const getPointCloudAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return (asset.type === AssetType.Encompass)\r\n || (asset.type === AssetType.LAS)\r\n || (asset.type === AssetType.E57Points)\r\n || (asset.type === AssetType.Potree);\r\n });\r\n};\r\n\r\nexport const getCameraFileAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return asset.type === AssetType.Panoramic\r\n || asset.type === AssetType.Planar;\r\n });\r\n};\r\n\r\nexport const getCameraListFromAssets = (assets: Asset[], checkVisible: boolean) => {\r\n const cameraAssets = getCameraFileAssets(assets);\r\n\r\n return cameraAssets.map(cameraFile => {\r\n if (checkVisible && !cameraFile.visible) return [];\r\n\r\n const items = cameraFile.data as CameraData[];\r\n\r\n return items.map(camera => {\r\n return {\r\n ...camera,\r\n csv: cameraFile.id,\r\n folder: cameraFile.folderID,\r\n assetType: cameraFile.type,\r\n saved: cameraFile.saved,\r\n };\r\n });\r\n }).flat();\r\n};\r\n\r\nexport const getOrthoAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return asset.type === AssetType.OrthoMosaic;\r\n });\r\n};\r\n\r\nexport const getLandXMLAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return asset.type === AssetType.LandXML;\r\n });\r\n};\r\n\r\nexport const getWebMapAssets = (assets: Asset[]) => {\r\n return assets.filter(asset => {\r\n return asset.type === AssetType.Webmap;\r\n });\r\n};\r\n\r\n","import { useCallback, useState } from 'react';\r\n\r\ninterface DialogController {\r\n open: boolean\r\n data?: any;\r\n handleClose: () => void;\r\n handleOpen: (data?: any) => void;\r\n}\r\n\r\ninterface DialogState {\r\n open: boolean;\r\n data: any;\r\n}\r\n\r\nexport const useDialog = (): DialogController => {\r\n const [state, setState] = useState({\r\n open: false,\r\n data: null\r\n });\r\n\r\n const handleOpen = useCallback((data = null): void => {\r\n setState({\r\n open: true,\r\n data\r\n });\r\n },[]);\r\n\r\n const handleClose = useCallback((): void => {\r\n setState({\r\n open: false,\r\n data: null\r\n });\r\n }, []);\r\n\r\n return {\r\n open: state.open,\r\n data: state.data,\r\n handleClose,\r\n handleOpen\r\n };\r\n};\r\n","import { useContext } from 'react';\r\nimport { TaskQueueContext } from '../providers';\r\n\r\nexport const useTaskQueue = () => useContext(TaskQueueContext);\r\n","import { useContext } from 'react';\r\nimport { ViewerContext } from '../providers';\r\n\r\nexport const useViewer = () => useContext(ViewerContext);\r\n","import { useContext } from 'react';\r\nimport { ActiveToolContext } from '../providers';\r\n\r\nexport const useActiveTool = () => useContext(ActiveToolContext);\r\n","import { useSelector } from \"react-redux\";\r\nimport { selectSessionID } from \"../redux/project-slice\";\r\n\r\n// eslint-disable-next-line react-hooks/rules-of-hooks\r\nexport const useUniqueProjectID = () => useSelector(selectSessionID);\r\n","import type { MutableRefObject } from 'react';\r\nimport { useCallback, useRef, useState } from 'react';\r\n\r\ninterface PopoverController {\r\n anchorRef: MutableRefObject;\r\n handleOpen: () => void;\r\n handleClose: () => void;\r\n handleToggle: () => void;\r\n open: boolean;\r\n}\r\n\r\nexport function usePopover(): PopoverController {\r\n const anchorRef = useRef(null);\r\n const [open, setOpen] = useState(false);\r\n\r\n const handleOpen = useCallback(\r\n (): void => {\r\n setOpen(true);\r\n },\r\n []\r\n );\r\n\r\n const handleClose = useCallback(\r\n (): void => {\r\n setOpen(false);\r\n },\r\n []\r\n );\r\n\r\n const handleToggle = useCallback(\r\n (): void => {\r\n setOpen((prevState) => !prevState);\r\n },\r\n []\r\n );\r\n\r\n return {\r\n anchorRef,\r\n handleClose,\r\n handleOpen,\r\n handleToggle,\r\n open\r\n };\r\n}\r\n","import { useContext } from 'react';\r\nimport { AuthContext } from '../providers';\r\n\r\nexport const useAuth = () => useContext(AuthContext);\r\n","import { useCallback, useState } from 'react';\r\n\r\ninterface ContextStateController {\r\n open: boolean;\r\n data?: any;\r\n anchorPosition: {left: number, top: number};\r\n handleClose(): void;\r\n handleOpen(event, data?): void;\r\n}\r\n\r\ninterface AnchorPosition {\r\n left: number | null;\r\n top: number | null;\r\n}\r\n\r\ninterface ContextState {\r\n open: boolean;\r\n data: any;\r\n anchorPosition: AnchorPosition;\r\n}\r\n\r\nexport const useContextMenu = (): ContextStateController => {\r\n const [state, setState] = useState({\r\n open: false,\r\n data: {},\r\n anchorPosition: undefined\r\n });\r\n\r\n const handleOpen = useCallback((event, data = {}) => {\r\n event.preventDefault();\r\n\r\n const anchorPosition = {\r\n left: event.clientX + 10,\r\n top: event.clientY - 20\r\n };\r\n\r\n setState({\r\n open: true,\r\n data,\r\n anchorPosition\r\n });\r\n },[]);\r\n\r\n const handleClose = useCallback((): void => {\r\n setState({\r\n open: false,\r\n data: {},\r\n anchorPosition: undefined\r\n });\r\n }, []);\r\n\r\n return {\r\n open: state.open,\r\n data: state.data,\r\n anchorPosition: state.anchorPosition,\r\n handleClose,\r\n handleOpen\r\n };\r\n};\r\n","import { useContext } from 'react';\r\nimport { GlobalSettingsContext } from '../providers';\r\n\r\nexport const useGlobalSettings = () => useContext(GlobalSettingsContext);\r\n","import { useContext } from 'react';\r\nimport { WebSocketContext } from '../providers';\r\n\r\nexport const useWebSockets = () => useContext(WebSocketContext);\r\n","import { useContext } from 'react';\r\nimport { BookmarksContext } from '../providers';\r\n\r\nexport const useBookmarks = () => useContext(BookmarksContext);\r\n","import {MOUSE} from \"three\";\r\n\r\nexport enum ControlType {\r\n Encompass,\r\n Reverse,\r\n Autocad\r\n}\r\n\r\nexport const ControlModes = {\r\n 0: { ORBIT: MOUSE.LEFT, ZOOM: MOUSE.MIDDLE, PAN: MOUSE.RIGHT },\r\n 1: { ORBIT: MOUSE.RIGHT, ZOOM: MOUSE.MIDDLE, PAN: MOUSE.LEFT },\r\n 2: { ORBIT: -1, ZOOM: -1, PAN: MOUSE.MIDDLE }\r\n};\r\n","import {createSlice, nanoid, PayloadAction} from '@reduxjs/toolkit';\r\n\r\nexport interface CustomURL {\r\n id: string;\r\n name: string;\r\n date: string;\r\n url: string;\r\n target: string;\r\n showInScene: boolean;\r\n showInAerial: boolean;\r\n }\r\n\r\nconst getByID = (state, linkID: string) => {\r\n return state.find(url => url.id === linkID);\r\n};\r\n\r\nexport const customLinkSlice = createSlice({\r\n name: 'custom_links',\r\n initialState: [] as CustomURL[],\r\n reducers: {\r\n createCustomLink: (state, action: PayloadAction<{\r\n name: string,\r\n url: string,\r\n target: string,\r\n showInScene: boolean,\r\n showInAerial: boolean\r\n }>) => {\r\n const attributes = action.payload;\r\n\r\n const customURL = {\r\n id: nanoid(),\r\n date: new Date().toISOString(),\r\n ...attributes\r\n };\r\n\r\n state.push(customURL);\r\n },\r\n updateCustomLink: (state, action: PayloadAction<{\r\n linkID: string,\r\n name?: string,\r\n url?: string,\r\n target?: string,\r\n showInScene?: boolean,\r\n showInAerial?: boolean\r\n }>) => {\r\n const {linkID, ...updates} = action.payload;\r\n\r\n const customURL = getByID(state, linkID);\r\n if (!customURL) return;\r\n\r\n for (let key in updates) {\r\n if (customURL.hasOwnProperty(key)) {\r\n customURL[key] = updates[key];\r\n };\r\n };\r\n\r\n // Update modified date\r\n customURL.date = new Date().toISOString();\r\n },\r\n deleteCustomLink: (state, action: PayloadAction) => {\r\n return state.filter(url => url.id !== action.payload);\r\n }\r\n }\r\n});\r\n\r\nexport default customLinkSlice.reducer;\r\n\r\nexport const {\r\n createCustomLink,\r\n updateCustomLink,\r\n deleteCustomLink\r\n} = customLinkSlice.actions;\r\n\r\nexport const selectAllCustomLinks = state => state.custom_links as CustomURL[];\r\n","import proj4 from \"proj4\";\r\nimport nudged from \"nudged\";\r\nimport {transform} from 'ol/proj';\r\nimport {Projection, Transform} from '../../redux/projections-slice';\r\nimport PCA from 'pca-js';\r\nimport { executeWithoutLogging } from \"./utilities\";\r\nimport {\r\n Euler,\r\n MathUtils,\r\n Matrix4,\r\n Quaternion,\r\n Vector3\r\n} from 'three';\r\nimport { AsyncWorkerPool } from \"./worker-pool\";\r\n\r\nconst transformCache = {};\r\n\r\nconst unitsToValue = {\r\n \"m\": 1.0,\r\n \"ft\": 0.3048,\r\n \"us-ft\": 1200.0 / 3937.0\r\n};\r\n\r\nexport const latitudeLongitude = {\r\n type: \"proj4\",\r\n name: \"latlong\",\r\n string: \"+proj=longlat +ellps=WGS84 +datum=NAD83 +no_defs\"\r\n} as Projection;\r\n\r\nexport const webMercator = {\r\n type: \"proj4\",\r\n name: \"web mercator\",\r\n string: \"+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs\"\r\n} as Projection;\r\n\r\nconst workerPool = new AsyncWorkerPool(\"reproject-points.js\");\r\n\r\n/** @private */\r\nconst verifyProjection = (info) => {\r\n const data = {\r\n type: info.type,\r\n name: info.name,\r\n string: info.string,\r\n transform: info.transform\r\n } as Projection;\r\n\r\n if (data.type === \"proj4\") {\r\n data.string = verifyProj4String(data);\r\n }\r\n\r\n data.transform = verifyTransformObject(data);\r\n\r\n return data;\r\n};\r\n\r\ninterface TransformFunction {\r\n forward(coords: number[]): number[]\r\n inverse(coords: number[]): number[]\r\n}\r\n\r\n/** @private */\r\nconst getTransform = (projectionFrom: Projection, projectionTo: Projection) => {\r\n const transformKey = `${projectionFrom.string}-${projectionTo.string}`;\r\n\r\n let transform: TransformFunction;\r\n let heightScale: number;\r\n\r\n if (transformKey in transformCache) {\r\n transform = transformCache[transformKey].transform;\r\n heightScale = transformCache[transformKey].heightScale;\r\n } else {\r\n transform = proj4(projectionFrom.string, projectionTo.string);\r\n\r\n const projToMeters1 = projectionToMeters(projectionFrom);\r\n const projToMeters2 = projectionToMeters(projectionTo);\r\n heightScale = projToMeters2 / projToMeters1;\r\n\r\n transformCache[transformKey] = {transform, heightScale};\r\n }\r\n\r\n return {transform, heightScale};\r\n};\r\n\r\n/** Calculate transform paramters given local and transformed points */\r\nexport const estimateTransform = (estimator: string, inputValues, outputValues) => {\r\n const domain = inputValues.map(value => {\r\n return {x: value[0], y: value[1]};\r\n });\r\n\r\n const range = outputValues.map(value => {\r\n return {x: value[0], y: value[1]};\r\n });\r\n\r\n if (!estimator.includes(\"T\")) {\r\n console.error(\"Translation is required for estimator\");\r\n\r\n return {\r\n transform: null,\r\n errors: null\r\n };\r\n }\r\n\r\n const estimate = nudged.estimate({estimator, domain, range});\r\n const scale = nudged.transform.getScale(estimate);\r\n const rotation = nudged.transform.getRotation(estimate);\r\n const translation = nudged.transform.getTranslation(estimate);\r\n const transformed = nudged.point.transformMany(domain, estimate);\r\n\r\n // Calculate per-point difference\r\n const errors = [];\r\n for (let i=0; i => {\r\n return new Promise(async (resolve, reject) => {\r\n const values = {\r\n positions: points,\r\n projectionFrom,\r\n projectionTo\r\n };\r\n\r\n const {success, response} = await workerPool.postMessage(values);\r\n\r\n if (success) {\r\n resolve(response);\r\n } else {\r\n console.error(response);\r\n reject(response);\r\n }\r\n });\r\n};\r\n\r\n/** @private Reproject a single point. Internal use only */\r\nconst reprojectPoint = (position, projectionFrom: Projection, projectionTo: Projection): Vector3 => {\r\n position = position.isVector3\r\n ? position.toArray()\r\n : [...position];\r\n\r\n const rotateAxis = new Vector3(0, 0, 1);\r\n\r\n // Apply initial transformation\r\n if (projectionFrom.transform) {\r\n const {translation, rotation, scale, origin} = projectionFrom.transform;\r\n const angle = MathUtils.degToRad(rotation);\r\n\r\n position = new Vector3(...position)\r\n .sub(new Vector3(...translation))\r\n .applyAxisAngle(rotateAxis, -1 * angle)\r\n .divide(new Vector3(scale, scale, 1.0))\r\n .add(new Vector3(...origin))\r\n .toArray();\r\n }\r\n\r\n // Apply point reprojection\r\n if (projectionFrom.string !== projectionTo.string) {\r\n const {transform, heightScale} = getTransform(projectionFrom, projectionTo);\r\n position = transform.forward(position);\r\n\r\n // Height scaling is not applied by library\r\n position[2] /= heightScale;\r\n }\r\n\r\n // Apply secondary transformation\r\n if (projectionTo.transform) {\r\n const {translation, rotation, scale, origin} = projectionTo.transform;\r\n const angle = MathUtils.degToRad(rotation);\r\n\r\n position = new Vector3(...position)\r\n .sub(new Vector3(...origin))\r\n .multiply(new Vector3(scale, scale, 1.0))\r\n .applyAxisAngle(rotateAxis, angle)\r\n .add(new Vector3(...translation))\r\n .toArray();\r\n }\r\n\r\n return new Vector3(...position);\r\n};\r\n\r\nexport const closestUtmZone = (lonlat: Vector3, units: string) => {\r\n const utmZone = Math.ceil((180 + lonlat.x) / 6);\r\n\r\n const projection = {\r\n type: \"proj4\",\r\n name: `UTM ${utmZone}N (${units})`,\r\n string: `+proj=utm +zone=${utmZone} +ellps=WGS84 +datum=WGS84 +units=${units}`\r\n } as Projection;\r\n\r\n return {projection, utmZone};\r\n};\r\n\r\nclass ScenePointConverter {\r\n protected _sceneShift;\r\n protected _sceneScale;\r\n protected _dataProjection: Projection;\r\n protected _viewProjection: Projection;\r\n public dataToMeters;\r\n public dataProjectionUnits;\r\n public viewProjectionUnits;\r\n private isLonLatProject;\r\n public initialized = false;\r\n\r\n get dataProjection() {\r\n return this._dataProjection;\r\n }\r\n\r\n get viewProjection() {\r\n return this._viewProjection;\r\n }\r\n\r\n get dataProjectionName() {\r\n return this.dataProjection.name;\r\n }\r\n\r\n get viewProjectionName() {\r\n return this.viewProjection.name;\r\n }\r\n\r\n get sceneOffset() {\r\n return this._sceneShift;\r\n }\r\n\r\n get sceneScale() {\r\n return this._sceneScale;\r\n }\r\n\r\n engineStyleProjection(projection: Projection) {\r\n const proj4String = projection.string;\r\n const hasTransform = projection.transform ? true : false;\r\n\r\n let results;\r\n if (hasTransform === false) {\r\n // Standard projection\r\n results = proj4String;\r\n } else {\r\n // Projection with transform (engine style projections are saved differently)\r\n const data = projection.transform;\r\n const origin = data.origin;\r\n const translation = data.translation;\r\n const rotation = data.rotation;\r\n const scale = data.scale;\r\n\r\n const transform = {\r\n origin_east: origin[0],\r\n origin_north: origin[1],\r\n origin_elevation: origin[2],\r\n translation_east: translation[0],\r\n translation_north: translation[1],\r\n translation_elevation: translation[2],\r\n rotation: rotation,\r\n scale_factor_h: scale,\r\n scale_factor_v: 1.0,\r\n };\r\n\r\n results = [proj4String, transform];\r\n }\r\n\r\n const projectionString = JSON.stringify(results);\r\n return projectionString;\r\n }\r\n\r\n isDataProjection(name) {\r\n if (!this._dataProjection) return false;\r\n return (this._dataProjection.name === name) ||\r\n (this._viewProjection.name === name);\r\n }\r\n\r\n setDataProjection(info) {\r\n this._dataProjection = verifyProjection(info);\r\n this.dataToMeters = projectionToMeters(this._dataProjection);\r\n this.dataProjectionUnits = projectionToUnits(this._dataProjection);\r\n this.isLonLatProject = isLonLatProjection(this._dataProjection);\r\n this.resetSceneShift();\r\n }\r\n\r\n setViewProjection(info) {\r\n this._viewProjection = verifyProjection(info);\r\n this.viewProjectionUnits = projectionToUnits(this._viewProjection);\r\n }\r\n\r\n resetSceneShift() {\r\n this.initialized = false;\r\n this._sceneShift = null;\r\n this._sceneScale = new Vector3(1.0, 1.0, 1.0);\r\n }\r\n\r\n checkForOffset(offset) {\r\n if (this._sceneShift) return;\r\n\r\n this.initialized = true;\r\n this._sceneShift = offset.clone();\r\n\r\n if (this.isLonLatProject) {\r\n // Create an approximate latlon --> meters mapping based on the\r\n // offset point. Be aware that the accuracy is worse the further\r\n // away from the central point that you go\r\n\r\n let dx = haversineDistance(\r\n new Vector3(offset.x, offset.y, 0),\r\n new Vector3(offset.x + 1, offset.y, 0)\r\n );\r\n\r\n let dy = haversineDistance(\r\n new Vector3(offset.x, offset.y, 0),\r\n new Vector3(offset.x, offset.y + 1, 0)\r\n );\r\n\r\n this._sceneScale = new Vector3(dx, dy, 1.0);\r\n } else {\r\n this._sceneScale = new Vector3(1.0, 1.0, 1.0);\r\n }\r\n }\r\n\r\n offsetToScene(offset) {\r\n this.checkForOffset(offset);\r\n let difference = new Vector3()\r\n .add(offset)\r\n .sub(this._sceneShift);\r\n\r\n return difference;\r\n }\r\n\r\n /** @private Convert from data projection to lonlat */\r\n _dataToLonLat(value) {\r\n return new ProjectedCoordinate(value, this._dataProjection).toLonLat();\r\n }\r\n\r\n /** @private Convert from data projection to aerial coordinates */\r\n _dataToAerial(value) {\r\n const lonLat = this._dataToLonLat(value);\r\n const mercator = reprojectPoint(lonLat, latitudeLongitude, webMercator);\r\n return mercator.toArray().slice(0,2);\r\n }\r\n\r\n /** @private Convert from scene coordinates (meters) to data projection */\r\n _sceneToData(value) {\r\n let position = new Vector3().copy(value);\r\n\r\n if (this.isLonLatProject) {\r\n position.divide(this._sceneScale);\r\n }\r\n\r\n position.add(this._sceneShift)\r\n .divideScalar(this.dataToMeters);\r\n\r\n return position;\r\n }\r\n\r\n /** @private Convert from data projection to scene coordinates (meters) */\r\n _dataToScene(value) {\r\n const position = new Vector3().copy(value)\r\n .multiplyScalar(this.dataToMeters);\r\n\r\n this.checkForOffset(position);\r\n position.sub(this._sceneShift);\r\n\r\n if (this.isLonLatProject) {\r\n position.multiply(this._sceneScale);\r\n }\r\n\r\n return new SceneCoordinate(position);\r\n }\r\n\r\n /** @private Convert from scene coordinates (meters) to web mercator */\r\n _sceneToAerial(value) {\r\n let dataProjection = this._sceneToData(value);\r\n return this._dataToAerial(dataProjection);\r\n }\r\n\r\n /** @private Convert from scene coordinates (meters) to lonlat */\r\n _sceneToLonLat(value) {\r\n let dataProjection = this._sceneToData(value);\r\n return this._dataToLonLat(dataProjection);\r\n }\r\n}\r\n\r\n/** Base Coordinate class is Vector3 with a few extras */\r\nclass Coordinate extends Vector3 {\r\n constructor(value = null) {\r\n let x = 0;\r\n let y = 0;\r\n let z = 0;\r\n\r\n if (value !== null) {\r\n if (value.isVector3 || (value instanceof Coordinate)) {\r\n x = value.x;\r\n y = value.y;\r\n z = value.z;\r\n } else {\r\n x = value[0];\r\n y = value[1];\r\n z = (value.length === 3) ? value[2] : 0;\r\n }\r\n }\r\n\r\n super(x,y,z);\r\n }\r\n\r\n get vector() {\r\n return new Vector3(this.x, this.y, this.z);\r\n }\r\n\r\n clone() {\r\n return new Vector3().copy(this);\r\n }\r\n}\r\n\r\n/** Coordinate in scene coordinates */\r\nexport class SceneCoordinate extends Coordinate {\r\n constructor(value = null) {\r\n super(value);\r\n }\r\n\r\n toAerial() {\r\n return LocalScene._sceneToAerial(this);\r\n }\r\n\r\n toLonLat() {\r\n return LocalScene._sceneToLonLat(this);\r\n }\r\n\r\n toGeocentric() {\r\n const lonlat = LocalScene._sceneToLonLat(this);\r\n return new LonLatCoordinate(lonlat).toGeocentric();\r\n }\r\n\r\n toDataProjection() {\r\n const value = LocalScene._sceneToData(this);\r\n return new DataProjectionCoordinate(value);\r\n }\r\n\r\n toViewProjection() {\r\n return this.toDataProjection().toViewProjection();\r\n }\r\n}\r\n\r\n/** Coordinate in geocentric */\r\nexport class GeocentricCoordinate extends Coordinate {\r\n constructor(value = null) {\r\n super(value);\r\n }\r\n\r\n toDataProjection() {\r\n const value = this.toProjection(LocalScene.dataProjection);\r\n return new DataProjectionCoordinate(value);\r\n }\r\n\r\n toViewProjection() {\r\n const value = this.toProjection(LocalScene.viewProjection);\r\n return new ViewProjectionCoordinate(value);\r\n }\r\n\r\n toScene() {\r\n const value = this.toProjection(LocalScene.dataProjection);\r\n return LocalScene._dataToScene(value);\r\n }\r\n\r\n toLonLat() {\r\n let x = this.x * 1.0;\r\n let y = this.y * 1.0;\r\n let z = this.z * 1.0;\r\n\r\n let a = 6378137; // wgs84\r\n let f = 1 / 298.257223563; // wgs84\r\n\r\n let b = a * (1 - f);\r\n let e = Math.sqrt((Math.pow(a, 2) - Math.pow(b, 2)) / Math.pow(a, 2));\r\n b = Math.sqrt(Math.pow(a, 2) * (1 - Math.pow(e, 2)));\r\n\r\n let ep = Math.sqrt((Math.pow(a, 2) - Math.pow(b, 2)) / Math.pow(b, 2));\r\n let p = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));\r\n let th = Math.atan2(a * z, b * p);\r\n let lon = Math.atan2(y, x);\r\n let lat = Math.atan2((z + Math.pow(ep, 2) * b * Math.pow(Math.sin(th), 3)),\r\n (p - Math.pow(e, 2) * a * Math.pow(Math.cos(th), 3)));\r\n let N = a / (Math.sqrt(1 - Math.pow(e, 2) * Math.pow(Math.sin(lat), 2)));\r\n let alt = p / Math.cos(lat) - N;\r\n lon = lon % (2 * Math.PI);\r\n\r\n if (Math.abs(x) < 1.0 && Math.abs(y) < 1.0) {\r\n alt = Math.abs(z) - b;\r\n }\r\n\r\n lon = lon * 180.0 / Math.PI;\r\n lat = lat * 180.0 / Math.PI;\r\n\r\n return new Vector3(lon, lat, alt);\r\n }\r\n\r\n toProjection(projection: Projection) {\r\n const lonlat = this.toLonLat();\r\n const value = reprojectPoint(lonlat, latitudeLongitude, projection);\r\n return new ProjectedCoordinate(value, projection);\r\n }\r\n}\r\n\r\n/** Coordinate in generic projection */\r\nexport class ProjectedCoordinate extends Coordinate {\r\n public projection: Projection;\r\n\r\n constructor(value, projection) {\r\n super(value);\r\n this.projection = projection;\r\n }\r\n\r\n toGeocentric() {\r\n const lonlat = this.toLonLat();\r\n return new LonLatCoordinate(lonlat).toGeocentric();\r\n }\r\n\r\n toLonLat() {\r\n return this.toProjection(latitudeLongitude);\r\n }\r\n\r\n toAerial() {\r\n const mercator = this.toProjection(webMercator);\r\n return mercator.toArray().slice(0,2);\r\n }\r\n\r\n toScene() {\r\n const value = this.toProjection(LocalScene.dataProjection);\r\n return LocalScene._dataToScene(value);\r\n }\r\n\r\n toProjection(projection) {\r\n const value = reprojectPoint(this, this.projection, projection);\r\n return new ProjectedCoordinate(value, projection);\r\n }\r\n\r\n toViewProjection() {\r\n const value = this.toProjection(LocalScene.viewProjection);\r\n return new ViewProjectionCoordinate(value);\r\n }\r\n\r\n toDataProjection() {\r\n const value = this.toProjection(LocalScene.dataProjection);\r\n return new DataProjectionCoordinate(value);\r\n }\r\n\r\n distanceTo(value) {\r\n if (value instanceof ProjectedCoordinate) {\r\n let isLonLat1 = isLonLatProjection(this.projection);\r\n let isLonLat2 = isLonLatProjection(value.projection);\r\n if (isLonLat1 && isLonLat2) {\r\n return haversineDistance(this, value);\r\n }\r\n\r\n return this.vector.distanceTo(value.vector);\r\n }\r\n\r\n return this.vector.distanceTo(value);\r\n }\r\n}\r\n\r\n/** Coordinate in web mercator projection */\r\nexport class AerialCoordinate extends ProjectedCoordinate {\r\n constructor(value) {\r\n super(value, webMercator);\r\n }\r\n}\r\n\r\n/** Coordinate in latitude longitude */\r\nexport class LonLatCoordinate extends Coordinate {\r\n constructor(value) {\r\n super(value);\r\n }\r\n\r\n toGeocentric() {\r\n let lon = this.x * Math.PI / 180.0;\r\n let lat = this.y * Math.PI / 180.0;\r\n let alt = this.z;\r\n\r\n let a = 6378137;\r\n let f = 1 / 298.257223563;\r\n\r\n let b = a * (1 - f);\r\n let e = Math.sqrt((Math.pow(a, 2) - Math.pow(b, 2)) / Math.pow(a, 2));\r\n\r\n let N = a / Math.sqrt(1 - Math.pow(e, 2) * Math.pow(Math.sin(lat), 2));\r\n let x = (N + alt) * Math.cos(lat) * Math.cos(lon);\r\n let y = (N + alt) * Math.cos(lat) * Math.sin(lon);\r\n let z = (N * (Math.pow(b, 2) / Math.pow(a, 2)) + alt) * Math.sin(lat);\r\n\r\n return new GeocentricCoordinate([x, y, z]);\r\n }\r\n\r\n toProjection(projection) {\r\n let ecef = this.toGeocentric();\r\n return ecef.toProjection(projection);\r\n }\r\n\r\n toDataProjection() {\r\n let ecef = this.toGeocentric();\r\n return ecef.toDataProjection();\r\n }\r\n}\r\n\r\n/** Coordinate in project data projection */\r\nexport class DataProjectionCoordinate extends ProjectedCoordinate {\r\n constructor(value = null) {\r\n super(value, LocalScene.dataProjection);\r\n }\r\n}\r\n\r\n/** Coordinate in project view projection */\r\nexport class ViewProjectionCoordinate extends ProjectedCoordinate {\r\n constructor(value = null) {\r\n super(value, LocalScene.viewProjection);\r\n }\r\n}\r\n\r\n/** Spherical position, with theta/phi in degrees */\r\nexport class SphericalPosition {\r\n public radius;\r\n private _theta;\r\n private _phi;\r\n private limits;\r\n\r\n constructor() {\r\n this.radius = 0;\r\n this._theta = 0;\r\n this._phi = 0;\r\n this.limits = [0.01, 179.9];\r\n }\r\n\r\n get theta() {\r\n return (this._theta + 360) % 360;\r\n }\r\n\r\n get phi() {\r\n return (this._phi + 360) % 360;\r\n }\r\n\r\n round(value, precision) {\r\n let divisor = Math.pow(10, precision);\r\n return Math.round(value * divisor) / divisor;\r\n }\r\n\r\n fromVectors(pivot, orbit) {\r\n let offset = new Vector3().add(orbit).sub(pivot);\r\n let radius = offset.length();\r\n\r\n let theta = Math.atan2(offset.y, offset.x);\r\n theta = MathUtils.radToDeg(theta);\r\n\r\n let dist2d = Math.sqrt(Math.pow(offset.x, 2) + Math.pow(offset.y, 2));\r\n let phi = Math.atan2(dist2d, offset.z);\r\n phi = MathUtils.radToDeg(phi);\r\n phi = Math.max(this.limits[0], phi);\r\n phi = Math.min(this.limits[1], phi);\r\n\r\n this._theta = this.round(theta, 3);\r\n this._phi = this.round(phi, 3);\r\n this.radius = this.round(radius, 3);\r\n\r\n return this;\r\n }\r\n\r\n fromValues(radius, theta, phi) {\r\n this.radius = radius;\r\n this._theta = theta;\r\n this._phi = phi;\r\n\r\n return this;\r\n }\r\n\r\n toVector3() {\r\n let theta = MathUtils.degToRad(this.theta);\r\n let phi = MathUtils.degToRad(this.phi);\r\n\r\n let x = this.radius * Math.cos(theta) * Math.sin(phi);\r\n let y = this.radius * Math.sin(theta) * Math.sin(phi);\r\n let z = this.radius * Math.cos(phi);\r\n\r\n return new Vector3(x, y, z);\r\n }\r\n}\r\n\r\n/* Utility functions */\r\nexport const isValidProjection = (projectionString) => {\r\n try {\r\n proj4(projectionString);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\nexport const getEulerInverse = (euler: Euler) => {\r\n let quaternion = new Quaternion();\r\n quaternion.setFromEuler(euler).invert();\r\n return new Euler().setFromQuaternion(quaternion);\r\n};\r\n\r\nexport const geometryToArray = (geometry, projection = null) => {\r\n let polygon = [];\r\n let coordinates = geometry.flatCoordinates;\r\n let totalPoints = coordinates.length / 2.0;\r\n\r\n for (var i = 0; i < totalPoints; i++) {\r\n let x = coordinates[2 * i + 0];\r\n let y = coordinates[2 * i + 1];\r\n let lonlat = transform([x, y, 0], 'EPSG:3857', 'EPSG:4326');\r\n let ecef = new LonLatCoordinate(lonlat).toGeocentric();\r\n\r\n if (projection) {\r\n let point = ecef.toProjection(projection);\r\n polygon.push(point.toArray());\r\n } else {\r\n polygon.push(ecef.toArray());\r\n }\r\n }\r\n\r\n return polygon;\r\n};\r\n\r\nexport const calculateEigenVectors = (vertices) => {\r\n let mean = new Vector3();\r\n vertices.forEach(vertex => {\r\n mean.add(vertex);\r\n });\r\n mean.divideScalar(vertices.length);\r\n\r\n let points = vertices.map(vertex => {\r\n return new Vector3()\r\n .add(vertex)\r\n .sub(mean)\r\n .toArray();\r\n });\r\n\r\n let eigen = executeWithoutLogging(() => {\r\n return PCA.getEigenVectors(points);\r\n });\r\n\r\n return {eigen, mean, points};\r\n};\r\n\r\nexport const calculatePointsPCA = (vertices, returnFlat) => {\r\n let {eigen, points} = calculateEigenVectors(vertices);\r\n\r\n let matrix = new Matrix4();\r\n matrix.makeBasis(\r\n new Vector3().fromArray(eigen[0].vector),\r\n new Vector3().fromArray(eigen[1].vector),\r\n new Vector3().fromArray(eigen[2].vector)\r\n );\r\n matrix.transpose();\r\n\r\n points = points.map(point => {\r\n return new Vector3()\r\n .fromArray(point).applyMatrix4(matrix);\r\n });\r\n\r\n if (returnFlat) {\r\n let pointsFlat = [];\r\n points.forEach(point => {\r\n pointsFlat = [...pointsFlat, ...point.toArray()];\r\n });\r\n points = pointsFlat;\r\n }\r\n\r\n return points;\r\n};\r\n\r\nexport const projectionToUnits = (projection: Projection) => {\r\n const unitLength = projectionToMeters(projection);\r\n\r\n let units;\r\n switch (unitLength) {\r\n case unitsToValue['m']:\r\n units = \"m\";\r\n break;\r\n case unitsToValue['ft']:\r\n units = \"ft\";\r\n break;\r\n case unitsToValue['us-ft']:\r\n units = \"sft\";\r\n break;\r\n default:\r\n units = \"m\";\r\n break;\r\n }\r\n\r\n return units;\r\n};\r\n\r\nexport const projectionToMeters = (projection: Projection) => {\r\n if (!projection) return 1.0;\r\n\r\n const proj = proj4.Proj(projection.string);\r\n\r\n if (projection.type === \"wkt\") {\r\n return proj['UNIT'].convert;\r\n } else if (\"to_meter\" in proj) {\r\n return proj['to_meter'];\r\n } else if (\"units\" in proj) {\r\n const units = proj['units'] as string;\r\n return unitsToValue[units];\r\n }\r\n\r\n return 1.0;\r\n};\r\n\r\nexport const isLonLatProjection = (projection) => {\r\n const proj = proj4.Proj(projection.string);\r\n return proj['projName'] === \"longlat\";\r\n};\r\n\r\nconst haversineDistance = (position1, position2) => {\r\n let earthRadius = 6371000;\r\n\r\n let diffLat = (position2.y - position1.y) * Math.PI / 180;\r\n let diffLng = (position2.x - position1.x) * Math.PI / 180;\r\n\r\n let arc = Math.cos(position1.y * Math.PI / 180)\r\n * Math.cos(position2.y * Math.PI / 180)\r\n * Math.sin(diffLng / 2) * Math.sin(diffLng / 2)\r\n + Math.sin(diffLat / 2) * Math.sin(diffLat / 2);\r\n let line = 2 * Math.atan2(Math.sqrt(arc), Math.sqrt(1 - arc));\r\n\r\n let distance2d = earthRadius * line;\r\n let height = position2.z - position1.z;\r\n\r\n let distance = Math.pow(distance2d, 2) + Math.pow(height, 2);\r\n distance = Math.sqrt(distance);\r\n\r\n return distance;\r\n};\r\n\r\nconst verifyTransformObject = (data) => {\r\n let transform = data.transform;\r\n if (!transform) {\r\n return null;\r\n }\r\n\r\n if (transform.hasOwnProperty('translation_north')) {\r\n return {\r\n origin: [\r\n transform.origin_east,\r\n transform.origin_north,\r\n transform.origin_elevation ? transform.origin_elevation : 0\r\n ],\r\n translation: [\r\n transform.translation_east,\r\n transform.translation_north,\r\n transform.translation_elevation\r\n ],\r\n scale: transform.scale_factor_h,\r\n rotation: transform.rotation\r\n } as Transform;\r\n }\r\n\r\n return Object.assign({}, transform);\r\n};\r\n\r\nconst verifyProj4String = (projection) => {\r\n let string = projection.string;\r\n\r\n // longlat projection is returned directly\r\n if (isLonLatProjection(projection)) {\r\n return string;\r\n }\r\n\r\n // Return EPSG codes directly\r\n if (string.toUpperCase().indexOf(\"EPSG\") === 0) {\r\n return string;\r\n }\r\n\r\n // Add missing fields\r\n if (string.indexOf(\"y_0\") === -1) {\r\n string = string + \" +y_0=0\";\r\n }\r\n\r\n if (string.indexOf(\"x_0\") === -1) {\r\n string = string + \" +x_0=0\";\r\n }\r\n\r\n if (string.indexOf(\"lon_0\") === -1) {\r\n string = string + \" +lon_0=0\";\r\n }\r\n\r\n if (string.indexOf(\"lat_0\") === -1) {\r\n string = string + \" +lat_0=0\";\r\n }\r\n\r\n string = string.split(\" +\").join(\" \");\r\n string = string.split(\" \").join(\" +\");\r\n if (string[0] !== \"+\") {\r\n string = \"+\" + string;\r\n }\r\n\r\n return string;\r\n};\r\n\r\nconst LocalScene = new ScenePointConverter();\r\nexport default LocalScene;\r\n","export class AsyncWorkerPool {\r\n private fileName: string;\r\n private numWorkers = 1;\r\n private workers = [];\r\n private queue = [];\r\n\r\n constructor(fileName: string, numWorkers=2) {\r\n this.fileName = fileName;\r\n this.numWorkers = numWorkers;\r\n this.initWorkers();\r\n }\r\n\r\n initWorkers() {\r\n const filePath = `${process.env.PUBLIC_URL}/workers/${this.fileName}`;\r\n\r\n for (let i=0; i {\r\n return new Promise(resolve => {\r\n this.queue.push({message, transfer, resolve});\r\n this.processQueue();\r\n });\r\n }\r\n\r\n /** @private */\r\n processQueue() {\r\n if (this.workers.length === 0) return;\r\n if (this.queue.length === 0) return;\r\n\r\n const worker = this.workers.shift();\r\n const {message, transfer, resolve} = this.queue.shift();\r\n\r\n worker.onmessage = event => {\r\n resolve(event.data);\r\n\r\n // Return worker to array\r\n this.workers.push(worker);\r\n\r\n // Process next item in queue\r\n this.processQueue();\r\n };\r\n\r\n worker.postMessage(message, transfer);\r\n }\r\n}","import { Vector3 } from \"three\";\r\nimport { Viewer } from \"../main\";\r\n\r\nexport class ChangeDetector {\r\n private viewer: Viewer;\r\n\r\n private oldZoom = 0;\r\n private oldFov = 0;\r\n private oldLookatVector = new Vector3();\r\n private oldCameraPosition = new Vector3();\r\n private oldUpVector = new Vector3();\r\n private oldCameraID = null;\r\n private oldHeight = 0;\r\n private oldWidth = 0;\r\n private oldOrbitState = false;\r\n\r\n // Specific changes are exposed to the public\r\n public orbitChanged = false;\r\n public cameraChanged = false;\r\n public changed = false;\r\n\r\n constructor(viewer: Viewer) {\r\n this.viewer = viewer;\r\n }\r\n\r\n get newFov() {\r\n return this.viewer.fov;\r\n }\r\n\r\n get newZoom() {\r\n return this.viewer.getAerialZoomLevel();\r\n }\r\n\r\n get newLookatVector() {\r\n return this.viewer.lookatVector;\r\n }\r\n\r\n get newUpVector() {\r\n return this.viewer.upVector;\r\n }\r\n\r\n get newCameraID() {\r\n return this.viewer.getCurrentCameraName();\r\n }\r\n\r\n get newHeight() {\r\n return this.viewer.height;\r\n }\r\n\r\n get newWidth() {\r\n return this.viewer.width;\r\n }\r\n\r\n get newOrbitState() {\r\n return this.viewer.orbitState;\r\n }\r\n\r\n get newCameraPosition() {\r\n const camera = this.viewer.camera;\r\n return camera.position.clone();\r\n }\r\n\r\n update() {\r\n this.changed = false;\r\n\r\n try {\r\n let lookatChanged = this.oldLookatVector\r\n .angleTo(this.newLookatVector) > 1e-5;\r\n let upChanged = this.oldUpVector\r\n .angleTo(this.newUpVector) > 1e-5;\r\n let positionChanged = this.oldCameraPosition\r\n .distanceTo(this.newCameraPosition) > 1e-5;\r\n let fovChanged = this.oldFov !== this.newFov;\r\n let zoomChanged = this.oldZoom !== this.newZoom;\r\n let cameraChanged = this.oldCameraID !== this.newCameraID;\r\n let heightChanged = this.oldHeight !== this.newHeight;\r\n let widthChanged = this.oldWidth !== this.newWidth;\r\n let orbitChanged = this.oldOrbitState !== this.newOrbitState;\r\n\r\n this.oldZoom = this.newZoom;\r\n this.oldFov = this.newFov;\r\n this.oldLookatVector = this.newLookatVector;\r\n this.oldCameraPosition = this.newCameraPosition;\r\n this.oldUpVector = this.newUpVector;\r\n this.oldCameraID = this.newCameraID;\r\n this.oldHeight = this.newHeight;\r\n this.oldWidth = this.newWidth;\r\n this.oldOrbitState = this.newOrbitState;\r\n\r\n this.cameraChanged = cameraChanged;\r\n this.orbitChanged = orbitChanged;\r\n\r\n this.changed = lookatChanged || upChanged || fovChanged\r\n || zoomChanged || cameraChanged || heightChanged\r\n || widthChanged || orbitChanged || positionChanged;\r\n } catch {\r\n this.changed = false;\r\n }\r\n };\r\n}","export class UnitConverter {\r\n private metresToSurveyFeetRatio = 1200 / 3937;\r\n private metresToFeetRatio = 0.3048;\r\n private allowedUnits = new Set(['ft', 'sft', 'm']);\r\n\r\n public convert(value, fromUnits, toUnits, fixedLength=null) {\r\n if (!this.allowedUnits.has(fromUnits) || !this.allowedUnits.has(toUnits)) {\r\n throw new Error('Units must either be \"m\", \"sft\", or \"ft\"');\r\n }\r\n\r\n if (isNaN(value)) {\r\n throw new Error('Value must be a number');\r\n }\r\n\r\n let convertedValue = value;\r\n\r\n if (fromUnits !== toUnits) {\r\n if (fromUnits === 'ft' || fromUnits === 'sft') {\r\n convertedValue *= (fromUnits === 'ft' ? this.metresToFeetRatio : this.metresToSurveyFeetRatio);\r\n }\r\n\r\n if (toUnits === 'ft' || toUnits === 'sft') {\r\n convertedValue /= (toUnits === 'ft' ? this.metresToFeetRatio : this.metresToSurveyFeetRatio);\r\n }\r\n }\r\n\r\n if (fixedLength !== null) {\r\n convertedValue = parseFloat(convertedValue.toFixed(fixedLength));\r\n }\r\n\r\n return convertedValue;\r\n }\r\n}\r\n","import {\r\n Vector3,\r\n MathUtils,\r\n PerspectiveCamera,\r\n Object3D\r\n} from \"three\";\r\nimport linspace from \"exact-linspace\";\r\nimport isUrl from \"is-url\";\r\n\r\nexport const isMobile = /android|webos|iphone|ipad|ipod|blackberry|playbook|BB10|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase());\r\n\r\nexport const isValidURL = (path: string) => {\r\n return isUrl(encodeURI(path));\r\n};\r\n\r\nexport const getProjFactor = (fov, distance, screenHeight) => {\r\n let projFactor = 1.0 / Math.tan(fov / 2);\r\n projFactor /= distance;\r\n projFactor *= screenHeight / 2;\r\n return projFactor;\r\n};\r\n\r\nexport const getPointScale = (camera: PerspectiveCamera, mesh: Object3D, size=50) => {\r\n const meshPosition = new Vector3();\r\n mesh.getWorldPosition(meshPosition);\r\n\r\n const fov = MathUtils.degToRad(Math.max(60, camera.fov));\r\n const distance = Math.max(1.0, meshPosition.distanceTo(camera.position));\r\n const projFactor = getProjFactor(fov, distance, window.innerHeight);\r\n return size / projFactor;\r\n};\r\n\r\nexport const toScreenPosition = (viewer, position, round) => {\r\n var vector = new Vector3();\r\n vector.set(position.x, position.y, position.z);\r\n vector.project(viewer.camera);\r\n\r\n vector.x = (vector.x + 1) * (viewer.width / 2);\r\n vector.y = (-vector.y + 1) * (viewer.height / 2);\r\n\r\n if (round) {\r\n vector.x = Math.round(vector.x);\r\n vector.y = Math.round(vector.y);\r\n }\r\n\r\n return [vector.x, vector.y];\r\n};\r\n\r\nexport const eventToPixel = (event) => {\r\n let uv = new Vector3();\r\n if (event.offsetX) {\r\n // chrome,ie,safari\r\n uv.x = event.offsetX;\r\n uv.y = event.offsetY;\r\n } else {\r\n // firefox\r\n uv.x = event.layerX;\r\n uv.y = event.layerY;\r\n }\r\n return uv;\r\n};\r\n\r\nexport const randomHexColor = () => {\r\n return \"#000000\".replace(/0/g, function() {\r\n return (~~(Math.random() * 16)).toString(16);\r\n });\r\n};\r\n\r\nexport const closestPowerOfTwo = value => {\r\n if (value === 0) {\r\n return 0;\r\n }\r\n\r\n let power = Math.ceil(Math.log(value) / Math.log(2));\r\n let result = Math.pow(2, power) - 1;\r\n return result;\r\n};\r\n\r\nexport const roundDigit = (num, digits) => {\r\n let multiplyFactor = Math.pow(10, digits);\r\n return Math.round( num * multiplyFactor + Number.EPSILON ) / multiplyFactor;\r\n};\r\n\r\nexport const executeWithoutLogging = callback => {\r\n const logger = console.log;\r\n console.log = function() {};\r\n let response = callback();\r\n console.log = logger;\r\n return response;\r\n};\r\n\r\nexport const windowSafeDateISO = () => {\r\n const date = new Date();\r\n return date.toISOString()\r\n .slice(0, 19)\r\n .replace('T', ' ')\r\n .replace(/:/g, \"-\");\r\n};\r\n\r\nexport const chunkedArray = (array, size) => {\r\n let tmp = [...array];\r\n let results = [];\r\n while (tmp.length) {\r\n results.push(tmp.splice(0, size));\r\n }\r\n return results;\r\n};\r\n\r\nexport const coordinatesToArray = (points) => {\r\n let numPoints = points.length / 2;\r\n let newPoints = [];\r\n for (let i=0;i {\r\n if (start === end) {\r\n return new Array(steps).fill(start);\r\n }\r\n\r\n return linspace(start, end, steps);\r\n};\r\n\r\nexport const toBoolean = (value: string | number) : boolean => {\r\n const integerValue = typeof value === \"number\"\r\n ? value\r\n : parseInt(value);\r\n\r\n return !!integerValue;\r\n};\r\n\r\ninterface BoundingBox {\r\n min: Vector3,\r\n max: Vector3\r\n}\r\n\r\nexport const mergeBoundingBoxes = (boundingBoxes: BoundingBox[]) => {\r\n let combined = null;\r\n\r\n boundingBoxes.forEach(bbox => {\r\n if (!bbox) return;\r\n\r\n if (combined === null) {\r\n combined = {\r\n min: bbox.min.clone(),\r\n max: bbox.max.clone()\r\n };\r\n } else {\r\n combined = {\r\n min: new Vector3(\r\n Math.min(combined.min.x, bbox.min.x),\r\n Math.min(combined.min.y, bbox.min.y),\r\n Math.min(combined.min.z, bbox.min.z)\r\n ),\r\n max: new Vector3(\r\n Math.max(combined.max.x, bbox.max.x),\r\n Math.max(combined.max.y, bbox.max.y),\r\n Math.max(combined.max.z, bbox.max.z)\r\n )\r\n };\r\n }\r\n });\r\n\r\n return combined;\r\n};\r\n\r\nexport const allIndexOf = (array, item) => {\r\n let index = array.indexOf(item);\r\n let indices = [];\r\n\r\n while (index !== -1) {\r\n indices.push(index);\r\n index = array.indexOf(item, ++index);\r\n }\r\n\r\n return indices;\r\n};\r\n","import { Plane, Vector3 } from \"three\";\r\n\r\nconst simplepolygon = require('simplepolygon');\r\n\r\nexport const pointInPolygon = (point, vertices) => {\r\n let numberOfVertices = vertices.length;\r\n let insidePolygon = false;\r\n\r\n let j = numberOfVertices - 1;\r\n for (var i = 0; i < numberOfVertices; i++) {\r\n let verti = vertices[i];\r\n let vertj = vertices[j];\r\n\r\n let dx = vertj.x - verti.x;\r\n let dy1 = point.y - verti.y;\r\n let dy2 = vertj.y - verti.y;\r\n\r\n let cond1 = (verti.y > point.y) !== (vertj.y > point.y);\r\n let cond2 = point.x < (dx * dy1 / dy2 + verti.x);\r\n\r\n // currently checks [boundMin, boundMax)\r\n\r\n if (cond1 && cond2) {\r\n insidePolygon = !insidePolygon;\r\n }\r\n j = i;\r\n }\r\n return insidePolygon;\r\n};\r\n\r\nexport const planeFromVectors = (directions) => {\r\n let normal = new Vector3();\r\n directions.forEach(vertex => {\r\n normal.add(vertex);\r\n });\r\n\r\n normal.divideScalar(directions.length);\r\n normal.setLength(1.0);\r\n\r\n return new Plane(normal);\r\n};\r\n\r\nexport const checkValidPolygon = (coordinates) => {\r\n try {\r\n // Unshifted points give false positives sometimes\r\n let origin = coordinates[0];\r\n let shifted = coordinates.map(x => {\r\n return [x[0]-origin[0], x[1]-origin[1]];\r\n });\r\n\r\n let poly = {\r\n type: \"Feature\",\r\n geometry: {\r\n type: \"Polygon\",\r\n coordinates: [shifted]\r\n }\r\n };\r\n\r\n let result = simplepolygon(poly);\r\n return result.features.length === 1;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n","import { MathUtils } from 'three';\r\nimport { transform } from 'ol/proj';\r\nimport { toast } from '../../../app';\r\nimport {\r\n AerialViewState,\r\n initialSceneState,\r\n SceneCameraState\r\n} from '../../../redux/camera-slice';\r\nimport { t } from '../../../localization';\r\n\r\nexport const parseURLParams = (url: string) => {\r\n const hash = new URL(url).hash.substring(1);\r\n if (hash === \"\") return;\r\n\r\n const urlParams = new URLSearchParams(hash);\r\n const parameters = Object.fromEntries(urlParams);\r\n\r\n return parameters;\r\n};\r\n\r\nexport const getModifiedAerialState = (aerialState: AerialViewState, params) => {\r\n let modified = {...aerialState};\r\n\r\n if ((\"lon\" in params) && (\"lat\" in params)) {\r\n const lat = parseFloat(params.lat);\r\n const lon = parseFloat(params.lon);\r\n\r\n if (isNaN(lat) || isNaN(lon)) {\r\n toast.warning(t(\"toast.parse-error-lat-lon\"));\r\n } else {\r\n modified.center = transform([lon, lat], 'EPSG:4326', 'EPSG:3857');\r\n }\r\n }\r\n\r\n if (\"zoom\" in params) {\r\n const zoom = parseInt(params.zoom);\r\n\r\n if (isNaN(zoom)) {\r\n toast.warning(t(\"toast.parse-error-aerial-zoom\"));\r\n } else {\r\n modified.zoom = zoom;\r\n }\r\n }\r\n\r\n if (\"rotation\" in params) {\r\n const rotation = parseFloat(params.rotation);\r\n\r\n if (isNaN(rotation)) {\r\n toast.warning(t(\"toast.parse-error-aerial-rotate\"));\r\n } else {\r\n modified.rotation = MathUtils.degToRad(rotation);\r\n }\r\n }\r\n\r\n return modified;\r\n};\r\n\r\nexport const getModifiedSceneState = (sceneState: SceneCameraState, params) => {\r\n let modified = {...sceneState};\r\n\r\n if ((\"px\" in params) && (\"py\" in params) && (\"pz\" in params)) {\r\n if ((\"ox\" in params) && (\"oy\" in params) && (\"oz\" in params)) {\r\n const ox = parseFloat(params.ox);\r\n const oy = parseFloat(params.oy);\r\n const oz = parseFloat(params.oz);\r\n\r\n const px = parseFloat(params.px);\r\n const py = parseFloat(params.py);\r\n const pz = parseFloat(params.pz);\r\n\r\n const hasError = isNaN(ox)\r\n || isNaN(oy)\r\n || isNaN(oz)\r\n || isNaN(px)\r\n || isNaN(py)\r\n || isNaN(pz);\r\n\r\n if (hasError) {\r\n toast.warning(t(\"toast.parse-error-3d-mode\"));\r\n } else {\r\n return {\r\n ...initialSceneState,\r\n orbit: [ox, oy, oz],\r\n pivot: [px, py, pz]\r\n };\r\n }\r\n }\r\n }\r\n\r\n if ((\"x\" in params) && (\"y\" in params) && (\"z\" in params)) {\r\n const x = parseFloat(params.x);\r\n const y = parseFloat(params.y);\r\n const z = parseFloat(params.z);\r\n\r\n const hasError = isNaN(x)\r\n || isNaN(y)\r\n || isNaN(z);\r\n\r\n if (hasError) {\r\n toast.warning(t(\"toast.parse-error-xyz\"));\r\n } else {\r\n // Clear all values and update lookat\r\n modified = {\r\n ...initialSceneState,\r\n lookat: [x,y,z]\r\n };\r\n }\r\n }\r\n\r\n if (\"cam\" in params) {\r\n // Set camera and clear orbit values\r\n modified.camera = params.cam;\r\n modified.orbit = null;\r\n modified.pivot = null;\r\n }\r\n\r\n if ((\"theta\" in params) && (\"phi\" in params)) {\r\n const theta = parseFloat(params.theta);\r\n const phi = parseFloat(params.phi);\r\n\r\n if (isNaN(theta) || isNaN(phi)) {\r\n toast.warning(t(\"toast.parse-error-angle\"));\r\n } else {\r\n modified.angles = [\r\n MathUtils.degToRad(theta),\r\n MathUtils.degToRad(phi)\r\n ];\r\n }\r\n }\r\n\r\n if (\"fov\" in params) {\r\n const fov = parseFloat(params.fov);\r\n\r\n if (isNaN(fov)) {\r\n toast.warning(t(\"toast.parse-error-camera-fov\"));\r\n } else {\r\n modified.fov = fov;\r\n }\r\n }\r\n\r\n return modified;\r\n};\r\n","import {Vector as VectorSource} from \"ol/source\";\r\nimport {Vector as VectorLayer} from \"ol/layer\";\r\nimport {Polygon} from \"ol/geom\";\r\nimport {Feature} from \"ol\";\r\nimport { SceneCoordinate } from '../projections';\r\nimport { Stroke, Style } from \"ol/style\";\r\n\r\nconst mapBoundsStyle = new Style({\r\n stroke: new Stroke({\r\n color: 'rgba(0, 0, 0, 0.5)',\r\n width: 2\r\n }),\r\n});\r\n\r\nexport const boundsToMapLayer = (boundingBox) => {\r\n // Generate polygon layer from bounding box, based on scene coordinates\r\n let {min, max} = boundingBox;\r\n\r\n const polygonPoints = [\r\n new SceneCoordinate([min.x, min.y, 0]).toAerial(),\r\n new SceneCoordinate([min.x, max.y, 0]).toAerial(),\r\n new SceneCoordinate([max.x, max.y, 0]).toAerial(),\r\n new SceneCoordinate([max.x, min.y, 0]).toAerial(),\r\n new SceneCoordinate([min.x, min.y, 0]).toAerial()\r\n ];\r\n\r\n // Creating the minimap mesh layer\r\n let vectorsource = new VectorSource({\r\n wrapX: false\r\n });\r\n\r\n let geometry = new Polygon([polygonPoints], \"XY\");\r\n let feature = new Feature(geometry);\r\n vectorsource.addFeature(feature);\r\n\r\n let layer = new VectorLayer({\r\n zIndex: 1,\r\n source: vectorsource,\r\n style: mapBoundsStyle\r\n });\r\n\r\n return layer;\r\n};\r\n","import memoizeFormatConstructor from 'intl-format-cache';\r\n\r\nconst getDateTimeFormat = memoizeFormatConstructor(Intl.DateTimeFormat);\r\n\r\nconst defaultOptions = {\r\n timeStyle: \"short\",\r\n dateStyle: \"short\"\r\n} as Intl.DateTimeFormatOptions;\r\n\r\n/**\r\n * Convert date to locale string using cached formatter.\r\n * This is much faster than Date.toLocaleString\r\n * */\r\nexport const toLocaleString = (text: string, language: string, options = defaultOptions): string => {\r\n const createdAt = new Date(text);\r\n const formatter = getDateTimeFormat(language, options);\r\n return formatter.format(createdAt);\r\n};","import React, { useEffect } from \"react\";\r\nimport { createContext, useState } from \"react\";\r\nimport { isStaticSite, isCloudSite, storage, isElectronApp } from \"../electron-modules\";\r\nimport { useAuth } from \"../hooks\";\r\nimport { ControlType } from \"../types/controls\";\r\nimport { VolumeType, SamplingRate } from \"../types/measurements\";\r\n\r\ninterface GlobalSettingsState {\r\n orthoQuality: number;\r\n orthoOpacity: number;\r\n controlType: ControlType;\r\n openQuickNav: boolean;\r\n volumeType: VolumeType;\r\n volumeSampleRate: SamplingRate;\r\n viewerBackground: string;\r\n aerialBackground: string;\r\n}\r\n\r\nexport const initialState = {\r\n orthoQuality: 0.75,\r\n orthoOpacity: 1,\r\n controlType: ControlType.Encompass,\r\n openQuickNav: true,\r\n volumeType: VolumeType.MultiPlane,\r\n volumeSampleRate: SamplingRate.Medium,\r\n viewerBackground: \"#e2d1c3\",\r\n aerialBackground: \"#444444\"\r\n} as GlobalSettingsState;\r\n\r\nexport const GlobalSettingsContext = createContext({\r\n ...initialState,\r\n update: (values: GlobalSettingsState) => {}\r\n});\r\n\r\nexport const getGlobalSettingsFromStorage = async () => {\r\n if (isElectronApp) {\r\n return storage.getSync(\"global-settings\");\r\n }\r\n\r\n const cache = Date.now();\r\n const root = isCloudSite ? window.location.pathname : \".\";\r\n const configURL = `${root}/global-settings.json?cache=${cache}`;\r\n\r\n const response = await fetch(configURL);\r\n return await response.json();\r\n};\r\n\r\nexport const GlobalSettingsProvider = (props) => {\r\n const [state, setState] = useState({...initialState});\r\n const { initialized } = useAuth();\r\n\r\n const loadFromStorage = async () => {\r\n try {\r\n const settings = await getGlobalSettingsFromStorage();\r\n const newState = {...state, ...settings};\r\n\r\n setState(newState);\r\n } catch {\r\n console.error(\"Error reading global settings\");\r\n }\r\n };\r\n\r\n const saveToStorage = (values: GlobalSettingsState) => {\r\n if (isStaticSite) return;\r\n storage.setSync(\"global-settings\", values);\r\n };\r\n\r\n const onUpdate = (values: GlobalSettingsState) => {\r\n setState({...values});\r\n saveToStorage(values);\r\n };\r\n\r\n useEffect(() => {\r\n if (!initialized) return;\r\n\r\n loadFromStorage();\r\n }, [initialized]);\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};","import React, { createContext, useState } from \"react\";\r\nimport { useDispatch } from \"react-redux\";\r\nimport { engineCloudURL } from \"../urls\";\r\nimport { io, Socket } from \"socket.io-client\";\r\nimport { isElectronApp } from \"../electron-modules\";\r\nimport {\r\n wsCreateFolder,\r\n wsDeleteFolder,\r\n wsUpdateFolder,\r\n} from \"../redux/folders-slice\";\r\nimport {\r\n wsCreateAsset,\r\n wsDeleteAsset,\r\n wsUpdateAsset,\r\n} from \"../redux/assets-slice\";\r\nimport {\r\n wsCreateBookmark,\r\n wsDeleteBookmark,\r\n wsUpdateBookmark,\r\n} from \"../redux/bookmarks-slice\";\r\n\r\nenum EventType {\r\n JoinRoom = \"join_room\",\r\n LeaveRoom = \"leave_room\",\r\n CreateObject = \"create_asset\",\r\n DeleteObject = \"delete_asset\",\r\n UpdateObject = \"update_asset\",\r\n}\r\n\r\nenum ObjectType {\r\n Assets = \"assets\",\r\n Folders = \"folders\",\r\n Bookmarks = \"bookmarks\"\r\n}\r\n\r\nexport const WebSocketContext = createContext({\r\n connect: (accessToken: string) => {},\r\n disconnect: () => {},\r\n joinRoom: (roomID: string) => {}\r\n});\r\n\r\nexport const WebSocketProvider = (props) => {\r\n const dispatch = useDispatch();\r\n\r\n const [socket, setSocket] = useState(null);\r\n const [currentRoomID, setCurrentRoomID] = useState(null);\r\n\r\n const connect = (accessToken: string) => {\r\n let extraHeaders = {};\r\n\r\n if (isElectronApp) {\r\n extraHeaders = {\r\n Authorization: `Bearer ${accessToken}`\r\n };\r\n }\r\n\r\n return new Promise(resolve => {\r\n const socket = io(engineCloudURL, {\r\n addTrailingSlash: false,\r\n extraHeaders\r\n });\r\n\r\n setSocket(socket);\r\n\r\n socket.on(\"connect\", () => {\r\n register(socket);\r\n resolve(true);\r\n });\r\n\r\n socket.on(\"connect_error\", () => {\r\n socket.disconnect();\r\n resolve(false);\r\n });\r\n });\r\n };\r\n\r\n const disconnect = () => {\r\n if (!socket?.connected) return;\r\n\r\n socket.disconnect();\r\n setSocket(null);\r\n };\r\n\r\n const onCreate = (message) => {\r\n const {type, data} = message;\r\n\r\n if (type === ObjectType.Assets) {\r\n dispatch(wsCreateAsset(data));\r\n } else if (type === ObjectType.Folders) {\r\n dispatch(wsCreateFolder(data));\r\n } else if (type === ObjectType.Bookmarks) {\r\n dispatch(wsCreateBookmark(data));\r\n }\r\n };\r\n\r\n const onUpdate = (message) => {\r\n const {type, data} = message;\r\n\r\n if (type === ObjectType.Assets) {\r\n dispatch(wsUpdateAsset(data));\r\n } else if (type === ObjectType.Folders) {\r\n dispatch(wsUpdateFolder(data));\r\n } else if (type === ObjectType.Bookmarks) {\r\n dispatch(wsUpdateBookmark(data));\r\n }\r\n };\r\n\r\n const onDelete = (message) => {\r\n const {type, objectID} = message;\r\n\r\n if (type === ObjectType.Assets) {\r\n dispatch(wsDeleteAsset(objectID));\r\n } else if (type === ObjectType.Folders) {\r\n dispatch(wsDeleteFolder(objectID));\r\n } else if (type === ObjectType.Bookmarks) {\r\n dispatch(wsDeleteBookmark(objectID));\r\n }\r\n };\r\n\r\n const register = (socket: Socket) => {\r\n socket.on(EventType.CreateObject, onCreate);\r\n socket.on(EventType.UpdateObject, onUpdate);\r\n socket.on(EventType.DeleteObject, onDelete);\r\n };\r\n\r\n const joinRoom = (roomID: string) => {\r\n if (!socket?.connected) return;\r\n\r\n if (currentRoomID) {\r\n // Leave previously joined room\r\n socket.emit(EventType.LeaveRoom, currentRoomID);\r\n }\r\n\r\n socket.emit(EventType.JoinRoom, roomID);\r\n setCurrentRoomID(roomID);\r\n };\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};","export default __webpack_public_path__ + \"static/media/classifications.24975ac9.png\";","import { t } from \"./localization\";\r\n\r\nexport const LocalizedFileFilter = (key: string, extensions: string[]) => {\r\n return [{\r\n get name() {\r\n return t(key);\r\n },\r\n extensions\r\n }];\r\n};\r\n\r\nexport const getCombinedExtension = (key, filters) => {\r\n let extensions = [];\r\n filters.forEach(filter => {\r\n if (!filter) return;\r\n filter.forEach(x => {\r\n extensions = [...extensions, ...x.extensions];\r\n });\r\n });\r\n\r\n return [{\r\n get name() {\r\n return t(key);\r\n },\r\n extensions\r\n }];\r\n};\r\n\r\nexport const lasFileFormat = \"las\";\r\nexport const encompassFileFormat = \"idx\";\r\nexport const e57FileFormat = \"e57\";\r\nexport const potreeFileFormat = \"bin\";\r\nexport const pngFileFormat = 'png';\r\n\r\nexport const pngFilter = LocalizedFileFilter(\r\n 'dialog.extension-image-files-png', [pngFileFormat]);\r\n\r\nexport const pointCloudFileFormats = [lasFileFormat,\r\n encompassFileFormat, e57FileFormat, potreeFileFormat];\r\n\r\nexport const pointCloudFilter = LocalizedFileFilter(\r\n \"dialog.extension-pointclouds\", pointCloudFileFormats);\r\n\r\nexport const configFileType = \"json\";\r\nexport const configFilter = LocalizedFileFilter(\r\n \"dialog.extension-project\", [configFileType]);\r\n\r\nexport const customURLFileType = \"json\";\r\nexport const customURLFilter = LocalizedFileFilter(\r\n \"dialog.custom-url\", [customURLFileType]);\r\n\r\nexport const imageOrthoFormat = ['tif', 'tiff'];\r\nexport const imageOrthoFilter = LocalizedFileFilter(\r\n \"dialog.extension-ortho\", imageOrthoFormat);\r\n\r\nexport const imageCSVFormat = ['csv', 'txt'];\r\nexport const imageCSVFilter = LocalizedFileFilter(\r\n \"dialog.extension-images\", imageCSVFormat);\r\n\r\nexport const projFileFormat = ['eprj'];\r\n\r\nexport const imagePlanarFormat = ['plnr'];\r\nexport const imagePlanarFilter = LocalizedFileFilter(\r\n \"dialog.extension-planar\", imagePlanarFormat);\r\n\r\nexport const csvExportFilter = LocalizedFileFilter(\r\n \"dialog.extension-csv\", [\"csv\"]);\r\n\r\nexport const cameraMatrixFilter = LocalizedFileFilter(\r\n \"dialog.extension-4x4\", [\"4x4\"]);\r\n\r\nexport const measureDataFormat = \"3dm\";\r\nexport const measureDataFilter = LocalizedFileFilter(\r\n \"dialog.measure-data\", [measureDataFormat]);\r\n\r\nexport const measureCSVFilter = LocalizedFileFilter(\r\n \"dialog.measure-csv\", ['csv']);\r\n\r\nexport const tagCSVFilter = LocalizedFileFilter(\r\n \"dialog.tag-csv\", ['csv']);\r\n\r\nexport const DXFFileFormat = \"dxf\";\r\nexport const SHPFileFormat = \"shp\";\r\nexport const IFCFileFormat = \"ifc\";\r\nexport const xmlFileFormat = \"xml\";\r\nconst zipExtension = \"zip\";\r\n\r\nconst drawingFormats = [DXFFileFormat, SHPFileFormat, zipExtension];\r\n\r\nexport const drawingFilter = LocalizedFileFilter(\r\n \"dialog.drawing-files\", drawingFormats);\r\n\r\nexport const IFCModelFilter = LocalizedFileFilter(\r\n \"dialog.extension-ifc\", [IFCFileFormat]);\r\n\r\nexport const DXFModelFilter = LocalizedFileFilter(\r\n \"dialog.extension-dxf\", [DXFFileFormat]);\r\n\r\nexport const SHPModelFilter = LocalizedFileFilter(\r\n \"dialog.extension-shp\", [SHPFileFormat]);\r\n\r\nexport const ZIPFileFilter = LocalizedFileFilter(\r\n \"dialog.extension-zip\", [zipExtension]);\r\n\r\nconst modelFormats = [DXFFileFormat, SHPFileFormat, IFCFileFormat];\r\n\r\nexport const modelFileFilter = LocalizedFileFilter(\r\n \"dialog.model-files\", modelFormats);\r\n\r\nconst labelExtension = \"3dl\";\r\nexport const labelFilter = LocalizedFileFilter(\r\n \"dialog.label-file\", [labelExtension]);\r\n\r\nconst modelExtension = \"pth\";\r\nexport const modelFilter = LocalizedFileFilter(\r\n \"dialog.model-file\", [modelExtension]);\r\n\r\nconst xmlExtension = \"xml\";\r\nexport const xmlFileFilter = LocalizedFileFilter(\r\n \"dialog.xml-file\", [xmlExtension]);\r\n\r\nexport const lasFileFilter = LocalizedFileFilter(\r\n \"dialog.extension-las\", [lasFileFormat]\r\n);\r\n","export enum VolumeType {\r\n MultiPlane,\r\n LowestPlane\r\n}\r\n\r\nexport enum SamplingRate {\r\n High=0.25,\r\n Medium=0.5,\r\n Low=1.0\r\n}\r\n\r\nexport enum MeasureType {\r\n Length=\"length\",\r\n SnapUp=\"snap-up\",\r\n SnapDown=\"snap-down\",\r\n Height=\"height\",\r\n Point=\"point\",\r\n Area=\"area\",\r\n Volume=\"volume\",\r\n Station=\"station_measurement\"\r\n}","import {createSlice, PayloadAction} from '@reduxjs/toolkit';\r\nimport {Classification, classifications} from \"../classifications\";\r\nimport {isStaticSite, storage} from \"../electron-modules\";\r\nimport {cloneDeep} from 'lodash';\r\nimport { isMobile } from '../viewer/js/utilities';\r\n\r\nexport interface Clamp {\r\n min: number;\r\n max: number;\r\n}\r\n\r\nexport type ColorMapKey = 'heat-map' | 'awesome-green' | 'pastel-shades' | 'blue-orange' |\r\n 'black-orange' | 'blue-hue' | 'blue-red' | 'jet' | 'grayscale';\r\n\r\nexport enum ColorType {\r\n Intensity,\r\n RGB,\r\n Height,\r\n Classification\r\n}\r\n\r\nexport enum MarkerNavType {\r\n Arrows,\r\n Markers,\r\n None\r\n}\r\n\r\nexport interface ClassificationSetting extends Classification {\r\n visible: boolean;\r\n available: boolean;\r\n}\r\n\r\nexport interface SettingsState {\r\n colorMap: ColorMapKey;\r\n colorType: ColorType;\r\n dynamicSize: boolean;\r\n circularPoints: boolean;\r\n arrowMarkers: MarkerNavType;\r\n drawerOpen: boolean;\r\n activeTab: number;\r\n opacity: number;\r\n heightClip: Clamp;\r\n intensityClip: Clamp;\r\n cloudScale: number;\r\n cloudMinimum: number;\r\n cloudMaxPoints: number;\r\n cloudDistance: number;\r\n tagDistance: number;\r\n classifications: ClassificationSetting[];\r\n switched: boolean;\r\n}\r\n\r\nconst defaultIntensityClip = {\r\n min: 0,\r\n max: 1\r\n};\r\n\r\nconst defaultHeightClip = {\r\n min: 0,\r\n max: 1\r\n};\r\n\r\nconst defaultClassifications = classifications.map(classification => ({\r\n visible: true,\r\n available: false,\r\n ...classification\r\n}));\r\n\r\nexport const initialSettingsState = {\r\n colorMap: 'jet',\r\n colorType: ColorType.Height,\r\n dynamicSize: true,\r\n circularPoints: true,\r\n arrowMarkers: MarkerNavType.Arrows,\r\n activeTab: 0,\r\n opacity: 0.5,\r\n cloudMaxPoints: 5,\r\n cloudDistance: 1000,\r\n cloudScale: 1.0,\r\n cloudMinimum: 2.0,\r\n tagDistance: 1000,\r\n switched: false,\r\n drawerOpen: !isMobile,\r\n heightClip: defaultHeightClip,\r\n intensityClip: defaultIntensityClip,\r\n classifications: defaultClassifications,\r\n} as SettingsState;\r\n\r\nconst loadSavedDefaults = () => {\r\n if (isStaticSite) return {};\r\n\r\n return storage.getSync(\"default-settings\");\r\n};\r\n\r\nconst saveSettingsDefaults = (state) => {\r\n if (isStaticSite) return;\r\n\r\n const copy = cloneDeep(state);\r\n\r\n // Remove anything that doesn't need defaults\r\n delete copy.classifications;\r\n delete copy.activeTab;\r\n\r\n storage.setSync(\"default-settings\", copy);\r\n};\r\n\r\nconst applySavedSettings = (state, settings) => {\r\n const keys = Object.keys(settings);\r\n keys.forEach(key => {\r\n if (state.hasOwnProperty(key)) {\r\n state[key] = settings[key];\r\n }\r\n });\r\n};\r\n\r\nexport const settingsSlice = createSlice({\r\n name: 'settings',\r\n initialState: initialSettingsState,\r\n reducers: {\r\n updateSettingsState: (state, action) => {\r\n applySavedSettings(state, action.payload);\r\n },\r\n applySavedDefaults: (state, action) => {\r\n // Apply any forced defaults\r\n state.activeTab = 0;\r\n\r\n // Apply saved defaults\r\n const defaults = loadSavedDefaults();\r\n applySavedSettings(state, defaults);\r\n },\r\n changeDefaultSettings: (state, action) => {\r\n saveSettingsDefaults(state);\r\n },\r\n changeOpacity: (state, action: PayloadAction) => {\r\n state.opacity = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeTagDistance: (state, action: PayloadAction) => {\r\n state.tagDistance = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeCloudDistance: (state, action: PayloadAction) => {\r\n state.cloudDistance = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeCloudMaxPoints: (state, action: PayloadAction) => {\r\n state.cloudMaxPoints = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeCloudScale: (state, action: PayloadAction) => {\r\n state.cloudScale = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeCloudMinimum: (state, action: PayloadAction) => {\r\n state.cloudMinimum = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeHeightClip: (state, action: PayloadAction) => {\r\n state.heightClip = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeIntensityClip: (state, action: PayloadAction) => {\r\n state.intensityClip = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeColorMap: (state, action: PayloadAction) => {\r\n state.colorMap = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeColorType: (state, action: PayloadAction) => {\r\n state.colorType = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeDynamicSize: (state, action: PayloadAction) => {\r\n state.dynamicSize = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeCircularPoints: (state, action: PayloadAction) => {\r\n state.circularPoints = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeAvailableClassifications: (state, action: PayloadAction) => {\r\n const availableClassifications = new Set(action.payload);\r\n state.classifications = state.classifications\r\n .map(classification => ({...classification, available: availableClassifications.has(classification.id)}));\r\n },\r\n changeClassificationVisibility: (state, action) => {\r\n const classification = state.classifications.find(classification => classification.id === action.payload);\r\n\r\n if (classification) {\r\n classification.visible = !classification.visible;\r\n }\r\n },\r\n changeAllClassificationVisibility: (state, action) => {\r\n state.classifications = state.classifications.map(classification => ({...classification, visible: action.payload}));\r\n },\r\n changeSwitched: (state, action: PayloadAction) => {\r\n state.switched = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeSelectedTab: (state, action: PayloadAction) => {\r\n state.activeTab = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeDrawerOpen: (state, action: PayloadAction) => {\r\n state.drawerOpen = action.payload;\r\n saveSettingsDefaults(state);\r\n },\r\n changeArrowMarkers: (state, action: PayloadAction) => {\r\n state.arrowMarkers = action.payload;\r\n saveSettingsDefaults(state);\r\n }\r\n }\r\n});\r\n\r\nexport const {\r\n changeOpacity,\r\n changeTagDistance,\r\n changeCloudDistance,\r\n changeCloudMaxPoints,\r\n changeCloudScale,\r\n changeCloudMinimum,\r\n changeHeightClip,\r\n changeIntensityClip,\r\n changeColorMap,\r\n changeColorType,\r\n changeDynamicSize,\r\n changeCircularPoints,\r\n changeAvailableClassifications,\r\n changeClassificationVisibility,\r\n changeAllClassificationVisibility,\r\n changeSwitched,\r\n changeSelectedTab,\r\n changeDrawerOpen,\r\n changeArrowMarkers,\r\n updateSettingsState\r\n} = settingsSlice.actions;\r\n\r\nexport default settingsSlice.reducer;\r\n\r\nexport const selectOpacity = state => state.settings.opacity;\r\nexport const selectTagDistance = state => state.settings.tagDistance;\r\nexport const selectCloudDistance = state => state.settings.cloudDistance;\r\nexport const selectCloudMaxPoints = state => state.settings.cloudMaxPoints;\r\nexport const selectCloudScale = state => state.settings.cloudScale;\r\nexport const selectCloudMinimum = state => state.settings.cloudMinimum;\r\nexport const selectHeightClip = state => state.settings.heightClip;\r\nexport const selectIntensityClip = state => state.settings.intensityClip;\r\nexport const selectColorMap = state => state.settings.colorMap;\r\nexport const selectColorType = state => state.settings.colorType;\r\nexport const selectDynamicSize = state => state.settings.dynamicSize;\r\nexport const selectCircularPoints = state => state.settings.circularPoints;\r\nexport const selectViewerSwitched = state => state.settings.switched;\r\nexport const selectSelectedTab = state => state.settings.activeTab;\r\nexport const selectDrawerOpen = state => state.settings.drawerOpen;\r\nexport const selectArrowMarkers = state => state.settings.arrowMarkers;\r\n\r\nexport const selectClassifications = state => state.settings.classifications;\r\n\r\nexport const getAvailableClassifications = classifications =>\r\n classifications.filter(classification => classification.available);\r\n\r\nexport const getClassificationVisibilities = classifications =>\r\n classifications.map(classification => ({\r\n visible: classification.visible,\r\n id: classification.id\r\n }));\r\n","import {isDevMode, isElectronApp} from \"./electron-modules\";\r\n\r\ninterface LinkOptions {\r\n target?: string;\r\n name?: string;\r\n}\r\n\r\nconst engineCloudURLKey = \"engineCloudURL\";\r\n\r\nexport const setEngineCloudURL = (url: string, force: boolean = false): boolean => {\r\n if (!isElectronApp) {\r\n return false;\r\n }\r\n\r\n const currentEngineCloudURL = localStorage.getItem(engineCloudURLKey);\r\n\r\n if (currentEngineCloudURL && !force) {\r\n return false;\r\n }\r\n\r\n if (currentEngineCloudURL === url) {\r\n return false;\r\n }\r\n\r\n localStorage.setItem(engineCloudURLKey, url);\r\n engineCloudURL = url;\r\n\r\n return true;\r\n};\r\n\r\nexport let engineCloudURL = (() => {\r\n if (!isElectronApp) {\r\n return window.location.origin;\r\n }\r\n\r\n const engineCloudURL = localStorage.getItem(engineCloudURLKey);\r\n\r\n if (!engineCloudURL) {\r\n return isDevMode\r\n ? \"http://127.0.0.1:3001\"\r\n : \"https://engine.solv3d.com\";\r\n }\r\n\r\n return engineCloudURL;\r\n})();\r\n\r\nexport const redirectToLogin = () => {\r\n const searchParams = new URLSearchParams({\r\n returnTo: window.location.href\r\n }).toString();\r\n\r\n window.location.href = `/login?${searchParams}`;\r\n};\r\n\r\nexport const openExternalLink = (href: string, options: LinkOptions = {}) => {\r\n let element = document.createElement('a');\r\n\r\n element.setAttribute(\"href\", href);\r\n\r\n if (options.target) {\r\n element.setAttribute(\"target\", options.target);\r\n } else {\r\n element.setAttribute(\"target\", \"_blank\");\r\n }\r\n\r\n if (options.name) {\r\n element.setAttribute('download', options.name);\r\n }\r\n\r\n element.style.display = 'none';\r\n document.body.appendChild(element);\r\n element.click();\r\n document.body.removeChild(element);\r\n};","import React, {useEffect, useState, memo} from \"react\";\r\nimport {createStyles, makeStyles} from \"@material-ui/core/styles\";\r\nimport {fs, isStaticSite} from '../electron-modules';\r\nimport {DraggableDialog, IconToolBar, ToolBarButton, ToolBarDivider} from \"../components\";\r\nimport {\r\n FormHelperText,\r\n MenuItem,\r\n Select\r\n} from \"@material-ui/core\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport {dialog} from \"../electron-modules\";\r\nimport {\r\n pngFilter\r\n} from \"../file-extensions\";\r\nimport slash from \"slash\";\r\nimport { useViewer } from \"../hooks\";\r\nimport { openExternalLink } from \"../urls\";\r\n\r\nconst useStyles = makeStyles((theme) =>\r\n createStyles({\r\n profileContainer: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\"\r\n },\r\n toolbarDropdown: {\r\n flex: 1,\r\n paddingLeft: theme.spacing(1),\r\n paddingRight: theme.spacing(1)\r\n },\r\n profileChart: {\r\n flex: 1,\r\n overflow: \"hidden\",\r\n padding: theme.spacing(2)\r\n }\r\n })\r\n);\r\n\r\nexport const PointProfile = memo((props: any) => {\r\n const {open, setOpen} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [samplingType, setSamplingType] = useState('lowest');\r\n const [displayUnits, setDisplayUnits] = useState('m');\r\n\r\n const onRefModified = (container) => {\r\n if (!container) return;\r\n viewer.initProfileContainer(samplingType, displayUnits);\r\n };\r\n\r\n const reloadPointsProfile = () => {\r\n viewer.refreshPointProfile();\r\n };\r\n\r\n const resetPointsProfileView = () => {\r\n viewer.resetPointProfileView();\r\n };\r\n\r\n const savePointProfileImage = () => {\r\n if (isStaticSite) {\r\n savePointProfileImageBrowser();\r\n } else {\r\n savePointProfileImageElectron();\r\n }\r\n };\r\n\r\n const savePointProfileImageBrowser = () => {\r\n const imageBase64 = viewer.getPointProfileImage();\r\n const name = `${viewer.projectName}.png`;\r\n openExternalLink(imageBase64, {name});\r\n };\r\n\r\n const savePointProfileImageElectron = () => {\r\n dialog.showSaveDialog({\r\n defaultPath: viewer.projectName,\r\n filters: [...pngFilter],\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n\r\n if (result.filePath) {\r\n const filePath = slash(result.filePath);\r\n const imageBase64 = viewer.getPointProfileImage();\r\n let imageBase64Data = imageBase64.replace(/^data:image\\/\\w+;base64,/, '');\r\n\r\n const imageBuffer = Buffer.from(imageBase64Data, 'base64');\r\n fs.writeFileSync(filePath, imageBuffer, {encoding: \"base64\"});\r\n console.log(`Point Profile Image saved to ${filePath}`);\r\n }\r\n }).catch(error => {\r\n console.log(error);\r\n });\r\n return;\r\n };\r\n\r\n const updateUnits = (event) => {\r\n setDisplayUnits(event.target.value);\r\n };\r\n\r\n const updateSamplingType = (event) => {\r\n setSamplingType(event.target.value);\r\n };\r\n\r\n const onClose = () => {\r\n setOpen(false);\r\n };\r\n\r\n useEffect(() => {\r\n viewer?.setPointProfileSampling(samplingType);\r\n }, [viewer, samplingType]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointProfileUnits(displayUnits);\r\n }, [viewer, displayUnits]);\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n viewer?.resetPointProfile();\r\n }, [viewer, open]);\r\n\r\n return (\r\n \r\n \r\n
\r\n\r\n \r\n\r\n
\r\n \r\n {t('units.meters')}\r\n {t('units.feet')}\r\n {t('units.survey-feet')}\r\n \r\n {t('profile.profile-units')}\r\n
\r\n\r\n
\r\n \r\n {t('profile.highest')}\r\n {t('profile.lowest')}\r\n {t('profile.all-points')}\r\n \r\n {t('profile.profile-type')}\r\n
\r\n\r\n \r\n\r\n {/* Refresh points base on view */}\r\n \r\n\r\n {/* Reset zoom and position */}\r\n \r\n\r\n {/* Download profile */}\r\n \r\n\r\n
\r\n\r\n
\r\n \r\n
\r\n\r\n
\r\n \r\n
\r\n );\r\n});","import {createSlice} from '@reduxjs/toolkit';\r\n\r\nexport interface AerialViewState {\r\n center: number[];\r\n zoom: number;\r\n rotation: number;\r\n basemap: string;\r\n}\r\n\r\nexport interface SceneCameraState {\r\n camera: string;\r\n fov: number;\r\n angles: number[];\r\n lookat: number[];\r\n orbit: number[];\r\n pivot: number[];\r\n}\r\n\r\ninterface CameraState {\r\n transform: string;\r\n adjustments: object,\r\n height: number;\r\n aerialState: AerialViewState;\r\n sceneState: SceneCameraState;\r\n forcedTagID: string;\r\n}\r\n\r\nexport const initialAerialState = {\r\n center: [0, 0],\r\n zoom: 0,\r\n rotation: 0,\r\n basemap: \"open-street-maps\"\r\n} as AerialViewState;\r\n\r\nexport const initialSceneState = {\r\n camera: null,\r\n fov: null,\r\n angles: null,\r\n lookat: null,\r\n orbit: null,\r\n pivot: null\r\n} as SceneCameraState;\r\n\r\nexport const cameraStateSlice = createSlice({\r\n name: 'camera',\r\n initialState: {\r\n transform: null,\r\n adjustments: {},\r\n height: 3.0,\r\n aerialState: initialAerialState,\r\n sceneState: initialSceneState,\r\n forcedTagID: null\r\n } as CameraState,\r\n reducers: {\r\n changeCameraTransform: (state, action) => {\r\n state.transform = action.payload;\r\n },\r\n changeCameraState: (state, action) => {\r\n state.sceneState = action.payload;\r\n },\r\n changeCameraHeight: (state, action) => {\r\n state.height = action.payload;\r\n },\r\n changeBasicAdjustments: (state, action) => {\r\n state.adjustments = action.payload;\r\n },\r\n changeSavedAerialState: (state, action) => {\r\n state.aerialState = action.payload;\r\n },\r\n }\r\n});\r\n\r\nexport const {\r\n changeCameraState,\r\n changeCameraTransform,\r\n changeCameraHeight,\r\n changeBasicAdjustments,\r\n changeSavedAerialState\r\n} = cameraStateSlice.actions;\r\n\r\nexport default cameraStateSlice.reducer;\r\n\r\nexport const selectCameraHeight = state => state.camera.height;\r\nexport const selectActiveCamera = state => state.camera.sceneState.camera;\r\nexport const selectCameraState = state => state.camera.sceneState;\r\nexport const selectCameraTransform = state => state.camera.transform;\r\nexport const selectBasicAdjustments = state => state.camera.adjustments;\r\nexport const selectSavedAerialState = state => state.camera.aerialState;\r\nexport const selectForcedTagID = state => state.camera.forcedTagID;","import {\r\n isDevMode,\r\n app,\r\n fs,\r\n fse,\r\n child,\r\n process,\r\n logDirectoryPath\r\n} from \"./electron-modules\";\r\nimport path from \"path\";\r\nimport slash from \"slash\";\r\n\r\nconst engineMessageTypeJSON = \"NODEJSJSONDATA\";\r\n\r\nconst getDevModeConfig = () => {\r\n if (!isDevMode) {\r\n return false;\r\n }\r\n\r\n const appPath = slash(app.getAppPath());\r\n const text = fs.readFileSync(`${appPath}/develop.env`);\r\n const data = JSON.parse(text);\r\n\r\n if (data.testing) {\r\n console.warn(\"Running executable in dev mode\");\r\n }\r\n\r\n return data;\r\n};\r\n\r\nconst devModeConfig = getDevModeConfig();\r\n\r\nclass Executable {\r\n public exePath: string;\r\n public exeName: string;\r\n public running: boolean;\r\n private error = false;\r\n public child;\r\n public developerKey: string;\r\n public spawnDetached: boolean;\r\n public logText = [];\r\n private showStatus = true;\r\n\r\n constructor(exePath, exeName) {\r\n this.exePath = exePath;\r\n this.exeName = exeName;\r\n this.running = false;\r\n this.error = false;\r\n this.child = null;\r\n this.spawnDetached = false;\r\n }\r\n\r\n get path() {\r\n let basePath;\r\n let appPath = slash(app.getAppPath());\r\n let executablePath;\r\n\r\n if (devModeConfig) {\r\n if (devModeConfig.testing && this instanceof PythonExecutable) {\r\n executablePath = devModeConfig['testing-python'];\r\n } else {\r\n executablePath = devModeConfig[this.developerKey];\r\n }\r\n } else {\r\n // Calculate path using root + folder and name\r\n basePath = path.dirname(appPath);\r\n basePath = path.dirname(basePath);\r\n basePath = path.dirname(basePath);\r\n executablePath = path.join(basePath, this.exePath, this.exeName);\r\n }\r\n\r\n return executablePath;\r\n }\r\n\r\n statusMessage(message) {\r\n if (!this.showStatus) return;\r\n console.log(`[pid = ${this.child.pid}]: ${message}`);\r\n }\r\n\r\n parseCommandsList(commands) {\r\n // Convert objects to modified json\r\n for (let i=0;i {\r\n return ((index % 2) === 0)\r\n ? text\r\n : `\"${text}\"`;\r\n }).join(\" \");\r\n }\r\n\r\n run(opts = {}) {\r\n if (this.running) {\r\n console.log(\"Cannot launch multiple instances\");\r\n return;\r\n }\r\n\r\n const defaults = {\r\n showStatus: true,\r\n saveLogs: false,\r\n command: null,\r\n onClose: null,\r\n onData: null,\r\n onLine: null,\r\n onLogs: null\r\n };\r\n\r\n let options = {...defaults, ...opts};\r\n\r\n this.running = true;\r\n this.error = false;\r\n this.logText = [];\r\n this.showStatus = options.showStatus;\r\n\r\n let commands = this.parseCommandsList(options.command);\r\n let executablePath = this.path;\r\n\r\n let cwd = path.dirname(executablePath);\r\n this.child = child.spawn(executablePath, commands, {\r\n cwd: cwd,\r\n env: {\r\n ...process.env,\r\n PYTHONUNBUFFERED: true,\r\n NODEJS: true\r\n },\r\n detached: this.spawnDetached\r\n });\r\n\r\n if (!this.child.pid) {\r\n console.error(`Error launching ${this.exeName} exe`);\r\n if (options.onClose) {\r\n options.onClose(true);\r\n }\r\n\r\n return;\r\n }\r\n\r\n let copyPasteCommands = this.copyableCommands(commands);\r\n this.statusMessage(`${this.path} ${copyPasteCommands}`);\r\n\r\n this.child.on('close', () => {\r\n this.statusMessage(`close`);\r\n\r\n if (options.saveLogs) {\r\n let commandIndex = commands.indexOf(\"-p\") + 1;\r\n if (commandIndex > 0) {\r\n let commandName = commands[commandIndex];\r\n saveLogs(commandName, this.logText);\r\n }\r\n }\r\n\r\n if (options.onClose) {\r\n options.onClose(this.error);\r\n }\r\n\r\n this.error = false;\r\n this.running = false;\r\n this.child = null;\r\n });\r\n\r\n if (options.onData) {\r\n this.child.stderr.on('data', (data) => {\r\n options.onData(data, engineMessageTypeJSON);\r\n });\r\n\r\n this.child.stdout.on('data', (data) => {\r\n options.onData(data, engineMessageTypeJSON);\r\n });\r\n }\r\n\r\n if (options.onLine || options.onLogs || options.saveLogs) {\r\n this.child.stderr.on('data', (data) => {\r\n this.parseLines(data, options);\r\n });\r\n\r\n this.child.stdout.on('data', (data) => {\r\n this.parseLines(data, options);\r\n });\r\n }\r\n\r\n return this.child;\r\n }\r\n\r\n /** @private */\r\n parseLines(data, opts) {\r\n let onLine = opts.onLine ? opts.onLine : () => {};\r\n let onLogs = opts.onLogs ? opts.onLogs : () => {};\r\n\r\n let dataString = data.toString();\r\n let lines = dataString.split(\"\\n\");\r\n\r\n lines.forEach(line => {\r\n line = line.trim();\r\n if (line === \"\") {\r\n return;\r\n }\r\n\r\n // Parse our response and only keep engine json response\r\n let split = line.split(\":\");\r\n let messageType = split[0].trim();\r\n let messageData = split.slice(1).join(\":\").trim();\r\n\r\n if (messageType === engineMessageTypeJSON) {\r\n try {\r\n let jsonData = JSON.parse(messageData);\r\n onLine(jsonData);\r\n } catch(err) {\r\n onLine({});\r\n }\r\n } else {\r\n onLogs(line);\r\n this.logText.push(line);\r\n }\r\n });\r\n }\r\n\r\n destroy() {\r\n if (!this.running) {\r\n return;\r\n }\r\n\r\n this.running = false;\r\n this.error = true;\r\n\r\n try {\r\n child.execSync(\r\n `(Get-WmiObject -Class Win32_Process -Filter \"ProcessId = ${this.child.pid} OR ParentProcessId = ${this.child.pid}\").Terminate()`,\r\n {shell: \"powershell.exe\"}\r\n );\r\n } catch {\r\n // Do nothing\r\n }\r\n }\r\n}\r\n\r\nexport class PythonExecutable extends Executable {\r\n constructor() {\r\n super(\"exe-engine\", \"engine.exe\");\r\n this.developerKey = \"exe-python\";\r\n window.onbeforeunload = () => {\r\n this.destroy();\r\n };\r\n }\r\n\r\n write(text) {\r\n if (!this.running) {\r\n return;\r\n }\r\n\r\n this.child.stdin.write(text);\r\n }\r\n}\r\n\r\nexport class WorkflowExecutable extends Executable {\r\n constructor() {\r\n super(\"../\", \"SOLV3D engine.exe\");\r\n this.developerKey = \"exe-main\";\r\n this.spawnDetached = true;\r\n }\r\n}\r\n\r\nconst saveLogs = async (logPrefix, logText) => {\r\n const maxLogFiles = 50;\r\n\r\n const dateString = new Date()\r\n .toISOString()\r\n .replaceAll(\":\", \"-\");\r\n\r\n const logPath = path.join(\r\n logDirectoryPath,\r\n `${logPrefix} ${dateString}.txt`\r\n );\r\n\r\n const logs = logText.join(\"\\n\");\r\n await fse.writeFile(logPath, logs);\r\n\r\n const filenames = await fse.readdir(logDirectoryPath);\r\n if (filenames.length <= maxLogFiles) {\r\n return;\r\n }\r\n\r\n let oldest = new Date();\r\n let oldestFilePath;\r\n\r\n for (let filename of filenames) {\r\n const filePath = path.join(logDirectoryPath, filename);\r\n const stats = await fse.stat(filePath);\r\n\r\n if (stats.birthtime < oldest) {\r\n oldest = stats.birthtime;\r\n oldestFilePath = filePath;\r\n }\r\n }\r\n\r\n try {\r\n await fse.remove(oldestFilePath);\r\n } catch {\r\n // Nothing\r\n }\r\n};\r\n\r\nexport const trackToolUsage = (toolName) => {\r\n if (isDevMode) return;\r\n\r\n (async () => {\r\n new PythonExecutable().run({\r\n command: ['--check-tool', toolName]\r\n });\r\n })();\r\n};","import { AssetType, WebSourceAsset } from \"../../redux/assets-slice\";\r\n\r\nexport const isModelFile = (asset) => {\r\n return (asset.type === AssetType.IFC)\r\n || (asset.type === AssetType.DXF)\r\n || (asset.type === AssetType.SHP);\r\n};\r\n\r\nexport const isStreamablePointsFile = (asset) => {\r\n return (asset.type === AssetType.Encompass)\r\n || (asset.type === AssetType.Potree);\r\n};\r\n\r\nexport const isRawPointsFile = (asset) => {\r\n return (asset.type === AssetType.LAS)\r\n || (asset.type === AssetType.E57Points);\r\n};\r\n\r\nexport const getModelLayers = (asset) => {\r\n return asset.data.map(layer => ({\r\n name: layer.name,\r\n originalId: layer.id,\r\n visible: layer.visible,\r\n color: layer.color\r\n }));\r\n};\r\n\r\nexport const getWebmapLayers = (asset: WebSourceAsset) => {\r\n return asset.data.layers.map(layer => ({\r\n originalId: layer.id,\r\n visible: layer.visible,\r\n identifier: String(layer.identifier),\r\n name: String(layer.name)\r\n }));\r\n};\r\n\r\nexport const getBaseAsset = (asset) => {\r\n return {\r\n name: asset.name,\r\n visible: asset.visible,\r\n originalId: asset.id,\r\n type: asset.type,\r\n };\r\n};\r\n\r\nexport const getTagsData = (asset) => {\r\n return asset.data.items.map(tag => {\r\n const values = {\r\n originalId: tag.id,\r\n name: tag.name,\r\n comment: tag.comment,\r\n date: tag.date,\r\n x: tag.x,\r\n y: tag.y,\r\n } as any;\r\n\r\n if (\"z\" in tag) {\r\n values.z = tag.z;\r\n }\r\n\r\n if (\"sceneState\" in tag) {\r\n values.sceneState = tag.sceneState;\r\n }\r\n\r\n return values;\r\n });\r\n};\r\n\r\nexport const getImageData = (asset) => {\r\n return asset.data.map(image => {\r\n const values = {\r\n originalId: image.id,\r\n filename: image.name,\r\n x: image.x,\r\n y: image.y,\r\n z: image.z,\r\n roll: image.roll,\r\n pitch: image.pitch,\r\n yaw: image.yaw\r\n };\r\n\r\n /** Planar images have additional information */\r\n if (asset.type === AssetType.Planar) {\r\n return {\r\n ...values,\r\n config: image.config\r\n };\r\n }\r\n\r\n return values;\r\n });\r\n};\r\n\r\ninterface ObjectProps {\r\n id: string;\r\n [key: string]: any;\r\n}\r\n\r\nexport const withOriginalID = (object: ObjectProps) => {\r\n const {id, ...other} = object;\r\n return {originalId: id, ...other};\r\n};","import {nanoid, createSlice, PayloadAction} from '@reduxjs/toolkit';\r\nimport api from '../api';\r\n\r\nexport interface Folder {\r\n name: string;\r\n id: string;\r\n date: string;\r\n default?: boolean;\r\n}\r\n\r\nexport const defaultFolderTitle = 'folder.default-folder';\r\n\r\nconst getByID = (state, folderID: string) => {\r\n return state.find(folder => folder.id === folderID);\r\n};\r\n\r\nconst generateDefaultFolder = () => {\r\n return {\r\n id: nanoid(),\r\n name: defaultFolderTitle,\r\n date: new Date().toISOString(),\r\n default: true\r\n } as Folder;\r\n};\r\n\r\nexport const foldersSlice = createSlice({\r\n name: 'folders',\r\n initialState: [\r\n generateDefaultFolder()\r\n ],\r\n reducers: {\r\n createFolder: (state, action: PayloadAction) => {\r\n const name = action.payload;\r\n\r\n const folder = {\r\n id: nanoid(),\r\n name,\r\n date: new Date().toISOString(),\r\n default: false\r\n } as Folder;\r\n\r\n state.push(folder);\r\n },\r\n updateFolder: (state, action: PayloadAction<{\r\n folderID: string,\r\n name?: string\r\n }>) => {\r\n const {folderID, ...updates} = action.payload;\r\n\r\n const folder = getByID(state, folderID);\r\n if (!folder) return;\r\n\r\n for (let key in updates) {\r\n if (folder.hasOwnProperty(key)) {\r\n folder[key] = updates[key];\r\n };\r\n };\r\n\r\n if (!folder.default) return;\r\n\r\n // Add new default folder\r\n const newDefaultFolder = generateDefaultFolder();\r\n state.push(newDefaultFolder);\r\n\r\n // Set the current folder to custom\r\n folder.default = false;\r\n },\r\n deleteFolder: (state, action: PayloadAction) => {\r\n const folderID = action.payload;\r\n\r\n return state.filter(folder => {\r\n return folder.default || (folder.id !== folderID);\r\n });\r\n },\r\n\r\n /** Websocket specific */\r\n wsCreateFolder: (state, action: PayloadAction) => {\r\n const folder = action.payload;\r\n if (getByID(state, folder.id)) return;\r\n\r\n state.push(folder);\r\n },\r\n wsUpdateFolder: (state, action: PayloadAction) => {\r\n const {id, ...updates} = action.payload;\r\n\r\n let folder = getByID(state, id);\r\n if (!folder) return;\r\n\r\n for (let key in updates) {\r\n if (folder.hasOwnProperty(key)) {\r\n folder[key] = updates[key];\r\n };\r\n };\r\n },\r\n wsDeleteFolder: (state, action: PayloadAction) => {\r\n const folderID = action.payload;\r\n\r\n return state.filter(folder => {\r\n return folder.default || (folder.id !== folderID);\r\n });\r\n },\r\n }\r\n});\r\n\r\n/** Create a new folder and return the new folderID */\r\nexport const createFolder = (name = defaultFolderTitle) => {\r\n return async (dispatch, getState) => {\r\n // Create new folder\r\n dispatch(foldersSlice.actions.createFolder(name));\r\n\r\n const folders = getState().folders as Folder[];\r\n const [folder] = folders.slice(-1);\r\n\r\n // Update cloud site\r\n await api.folders.create(folder);\r\n\r\n return folder;\r\n };\r\n};\r\n\r\nexport const {\r\n wsCreateFolder,\r\n wsUpdateFolder,\r\n wsDeleteFolder,\r\n deleteFolder,\r\n updateFolder\r\n} = foldersSlice.actions;\r\n\r\nexport default foldersSlice.reducer;\r\n\r\nexport const selectDefaultFolder = state =>\r\n state.folders.find(folder => folder.default);\r\n\r\nexport const selectAllFolders = state => state.folders;\r\n","export enum TagSize {\r\n XSmall = 0.25,\r\n Small = 0.5,\r\n Medium = 1,\r\n Large = 2,\r\n XLarge = 4,\r\n}","\r\nconst spiralParamaters = (spiral, stepDist, sigDigs) => {\r\n\r\n if (spiral.spiType !== \"clothoid\") {\r\n console.error(`Unsupported Spiral Type: ${spiral.spiType}. Only clothoid spirals detected.`);\r\n return false;\r\n }\r\n\r\n const RL = Math.pow(parseFloat(spiral.constant), 2);\r\n let reverseCurve;\r\n let partial = false;\r\n\r\n if (spiral.radiusEnd === 'INF') {\r\n reverseCurve = true;\r\n } else if (spiral.radiusStart === 'INF'){\r\n reverseCurve = false;\r\n } else {\r\n reverseCurve = (spiral.radiusEnd > spiral.radiusStart);\r\n partial = true;\r\n }\r\n\r\n const cw = spiral.rot === \"cw\";\r\n let L = spiral.length;\r\n\r\n let delta;\r\n if (cw) {//cw\r\n if (reverseCurve){ // cw reverse curve\r\n delta = spiral.dirEnd;\r\n } else { // cw forward curve\r\n delta = -spiral.dirStart;\r\n }\r\n } else {// ccw\r\n if (reverseCurve) {// ccw reverse curve\r\n delta = -spiral.dirEnd;\r\n } else {// ccw forward curve\r\n delta = spiral.dirStart;\r\n }\r\n }\r\n\r\n let a = spiral.Start[0];\r\n let b = spiral.Start[1];\r\n let c = spiral.End[0];\r\n let d = spiral.End[1];\r\n\r\n let xStart;\r\n let yStart;\r\n\r\n let xEnd;\r\n let yEnd;\r\n\r\n let xCorr=0.0;\r\n let yCorr=0.0;\r\n let deltaCorr = 0.0;\r\n\r\n let segmentMin;\r\n let segmentMax;\r\n\r\n if (partial && !reverseCurve) { //partial forward curve\r\n let ls = RL / spiral.radiusStart;\r\n L += ls;\r\n segmentMin = parseInt((ls * sigDigs).toString());\r\n segmentMax = parseInt((L * sigDigs).toString());\r\n\r\n xCorr = ls - (Math.pow(ls, 5) / (40.0 * RL * RL)) +\r\n (Math.pow(ls, 9) / (3456.0 * Math.pow(RL, 4))) -\r\n (Math.pow(ls, 13) / (599040.0 * Math.pow(RL, 6)));\r\n yCorr = (Math.pow(ls, 3) / (6 * RL)) -\r\n (Math.pow(ls, 7) / (336.0 * Math.pow(RL, 3))) +\r\n (Math.pow(ls, 11) / (42240.0 * Math.pow(RL, 5))) -\r\n (Math.pow(ls, 15) / (9676800.0 * Math.pow(RL, 7)));\r\n deltaCorr = Math.pow(ls, 2) / (2 * RL);\r\n } else if (partial && reverseCurve){\r\n let le = RL / spiral.radiusEnd;\r\n let ls = RL / spiral.radiusStart;\r\n\r\n deltaCorr = Math.pow(le, 2) / (2 * RL);\r\n xCorr = le - (Math.pow(le, 5) / (40.0 * RL * RL)) +\r\n (Math.pow(le, 9) / (3456.0 * Math.pow(RL, 4))) -\r\n (Math.pow(le, 13) / (599040.0 * Math.pow(RL, 6)));\r\n yCorr = (Math.pow(le, 3) / (6 * RL)) -\r\n (Math.pow(le, 7) / (336.0 * Math.pow(RL, 3))) +\r\n (Math.pow(le, 11) / (42240.0 * Math.pow(RL, 5))) -\r\n (Math.pow(le, 15) / (9676800.0 * Math.pow(RL, 7)));\r\n\r\n segmentMin = parseInt((le * sigDigs).toString());\r\n segmentMax = parseInt((ls * sigDigs).toString());\r\n\r\n } else{\r\n segmentMin = 0;\r\n segmentMax = parseInt((L * sigDigs).toString());\r\n }\r\n\r\n let distMin = 1000000;\r\n let deltas = [\r\n delta, delta+deltaCorr, delta-deltaCorr,\r\n -1*(delta)-deltaCorr, -1*(delta)+deltaCorr, -delta];\r\n\r\n let endPointError = true;\r\n let chosenDelta = delta;\r\n\r\n deltas.forEach(deltaTrial => {\r\n let l = segmentMax / sigDigs;\r\n let x = l - (Math.pow(l, 5) / (40.0*RL*RL)) +\r\n (Math.pow(l,9) / (3456.0 * Math.pow(RL,4))) -\r\n (Math.pow(l,13) / (599040.0*Math.pow(RL,6)));\r\n\r\n let y = (Math.pow(l, 3) / (6*RL)) -\r\n (Math.pow(l,7) / (336.0*Math.pow(RL,3))) +\r\n (Math.pow(l, 11) / (42240.0*Math.pow(RL,5))) -\r\n (Math.pow(l, 15) / (9676800.0*Math.pow(RL, 7)));\r\n\r\n x -= xCorr;\r\n y -= yCorr;\r\n\r\n let xDiff = (x * Math.cos(deltaTrial) - y * Math.sin(deltaTrial));\r\n let yDiff = (x * Math.sin(deltaTrial) + y * Math.cos(deltaTrial));\r\n\r\n // console.log(`diffs x: ${xDiff} | y: ${yDiff}`);\r\n\r\n let xRotated;\r\n let yRotated;\r\n if (!reverseCurve) {//forward curve\r\n xRotated = a + xDiff;\r\n if (!cw) {//ccw forward\r\n yRotated = b - yDiff;\r\n } else {//cw forward\r\n yRotated = b + yDiff;\r\n }\r\n let dist = Math.sqrt(Math.pow(xRotated - c, 2)\r\n + Math.pow(yRotated - d, 2));\r\n if (dist < distMin) {\r\n distMin = dist;\r\n xEnd = xRotated;\r\n yEnd = yRotated;\r\n xStart = a;\r\n yStart = b;\r\n chosenDelta = deltaTrial;\r\n }\r\n if (dist <= Math.sqrt(2)*stepDist) {\r\n endPointError = false;\r\n }\r\n } else {//reverse curve\r\n xRotated = c - xDiff;\r\n if (!cw) {//ccw reverse\r\n yRotated = d - yDiff;\r\n } else {//cw reverse\r\n yRotated = d + yDiff;\r\n }\r\n\r\n let dist = Math.sqrt(Math.pow(xRotated - a, 2)\r\n + Math.pow(yRotated - b, 2));\r\n\r\n if (dist < distMin) {\r\n distMin = dist;\r\n xEnd = c;\r\n yEnd = d;\r\n xStart = xRotated;\r\n yStart = yRotated;\r\n chosenDelta = deltaTrial;\r\n }\r\n if (dist <= Math.sqrt(2)*stepDist) {\r\n endPointError = false;\r\n }\r\n }\r\n });\r\n if (endPointError) {\r\n console.error('Error in endpoint calculation');\r\n console.log(`Datum correct data: xDiff: ${a-c} | yDiff: ${b-d}`);\r\n console.log(`${xStart} | ${yStart} | at length ${segmentMin / sigDigs} | 0`);\r\n console.log(`${xEnd} | ${yEnd} | at length ${segmentMax / sigDigs} | ${spiral.length}`);\r\n console.log(`${xStart - a} | ${yStart - b} | at length ${segmentMin / sigDigs} | ${spiral.length}`);\r\n console.log(`${xEnd - c} | ${yEnd - d} | at length ${segmentMax / sigDigs} | ${spiral.length}`);\r\n }\r\n\r\n return {chosenDelta: chosenDelta, xStart: xStart, xEnd: xEnd, yStart: yStart,\r\n yEnd: yEnd, xCorr: xCorr, yCorr:yCorr, reverseCurve: reverseCurve, partial: partial,\r\n segmentMin: segmentMin, segmentMax:segmentMax, RL:RL, cw:cw, a:a, b:b, c:c, d:d\r\n };\r\n};\r\n\r\nexport const spiralIntersect = (spiral, point) => {\r\n const stepDist = 0.01;\r\n const sigDigs = 1000000;\r\n const spiralParams = spiralParamaters(spiral, stepDist, sigDigs);\r\n if (typeof spiralParams === \"boolean\") {\r\n return false;\r\n }\r\n let segmentMin = spiralParams.segmentMin;\r\n let segmentMax = spiralParams.segmentMax;\r\n\r\n // Now that the correct rotation and position corrections have been calculated\r\n // the entire spiral can be calculated, and the closest point to the clicked point can\r\n // be estimated.\r\n let spiralCoord=null;\r\n let distAlong=null;\r\n let distAcross = null;\r\n\r\n for (;segmentMin<=segmentMax;segmentMin+=stepDist*sigDigs) {\r\n if ((segmentMin+=stepDist*sigDigs) > segmentMax){\r\n segmentMin = segmentMax;\r\n }\r\n let l = segmentMin / sigDigs;\r\n\r\n let x = l - (Math.pow(l, 5) / (40.0*spiralParams.RL*spiralParams.RL)) +\r\n (Math.pow(l,9) / (3456.0 * Math.pow(spiralParams.RL,4))) -\r\n (Math.pow(l,13) / (599040.0*Math.pow(spiralParams.RL,6)));\r\n\r\n let y = (Math.pow(l, 3) / (6*spiralParams.RL)) -\r\n (Math.pow(l,7) / (336.0*Math.pow(spiralParams.RL,3))) +\r\n (Math.pow(l, 11) / (42240.0*Math.pow(spiralParams.RL,5))) -\r\n (Math.pow(l, 15) / (9676800.0*Math.pow(spiralParams.RL, 7)));\r\n\r\n x -= spiralParams.xCorr;\r\n y -= spiralParams.yCorr;\r\n\r\n let xDiff = (x * Math.cos(spiralParams.chosenDelta)\r\n - y * Math.sin(spiralParams.chosenDelta));\r\n let yDiff = (x * Math.sin(spiralParams.chosenDelta)\r\n + y * Math.cos(spiralParams.chosenDelta));\r\n let xAtLength, yAtLength, lengthLocal;\r\n if (spiralParams.partial) {\r\n lengthLocal = l - (segmentMin/sigDigs);\r\n } else {\r\n lengthLocal = l;\r\n }\r\n\r\n if (spiralParams.reverseCurve) {\r\n lengthLocal = spiral.length - lengthLocal;\r\n }\r\n\r\n if (!spiralParams.reverseCurve) {//forward curve\r\n xAtLength = spiralParams.a + xDiff;\r\n if (!spiralParams.cw) {//ccw forward\r\n yAtLength = spiralParams.b - yDiff;\r\n } else {//cw forward\r\n yAtLength = spiralParams.b + yDiff;\r\n }\r\n } else {//reverse curve\r\n xAtLength = spiralParams.c - xDiff;\r\n if (!spiralParams.cw) {//ccw reverse\r\n yAtLength = spiralParams.d - yDiff;\r\n } else {//cw reverse\r\n yAtLength = spiralParams.d + yDiff;\r\n }\r\n }\r\n\r\n const distAcrossNew = Math.sqrt(Math.pow(point[0] - xAtLength, 2)\r\n + Math.pow(point[1] - yAtLength, 2));\r\n // console.log(distAcrossNew)\r\n if (distAcross !== null) {\r\n const update = (distAcrossNew 0 ? 'L':'R';\r\n\r\n // console.log(`across: ${distAcross} | along: ${distAlong} | side: ${sideOfLine}`);\r\n\r\n return {distAcross: distAcross, distAlong: distAlong,\r\n sideOfLine:sideOfLine, coordinates:spiralCoord};\r\n};\r\n\r\nexport const lineDist = (geometry) => {\r\n const dist = Math.sqrt(Math.pow(geometry.Start[0] - geometry.End[0], 2) +\r\n Math.pow(geometry.Start[1] - geometry.End[1], 2));\r\n return dist;\r\n};\r\n\r\nexport const curveDist = (geometry) => {\r\n const dist = lineDist(geometry);\r\n const calcAngle = Math.acos(1 - (dist * dist) /\r\n (2 * geometry.radius * geometry.radius));\r\n return geometry.radius * calcAngle;\r\n};","export default __webpack_public_path__ + \"static/media/basic-pin-large-0.75ec4490.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-1.de25c04d.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-2.23fb938d.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-3.65851ce1.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-4.9966d8be.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-5.790dd84e.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-6.a68198e2.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-7.4c3698cb.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-8.f7c1d345.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-9.a396cd2e.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-10.99e3c8ff.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-11.b8422548.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-12.d24a3926.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-13.fcd61555.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-14.6f043dcd.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-large-15.7f4dcc36.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-0.ac50d9dd.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-1.d45746d2.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-2.02ae7f5d.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-3.7751012c.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-4.edcfac5a.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-5.42c12183.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-6.542950ea.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-7.bdbb489b.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-8.dd94c859.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-9.78cbab57.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-10.1798390a.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-11.f6c044f3.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-12.5e716d0a.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-13.dca970d3.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-14.1c33bb37.png\";","export default __webpack_public_path__ + \"static/media/basic-pin-small-15.96c7fac3.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-0.959c4b2f.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-1.a4c240b1.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-2.61523e37.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-3.53684cd6.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-4.626c530e.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-5.493e3493.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-6.9025f632.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-7.be74b86d.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-8.662983fe.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-9.e8c0afd3.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-10.3c7e3c46.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-11.b0a43ba2.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-12.104ba8ac.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-13.30dbf535.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-14.e8adad8f.png\";","export default __webpack_public_path__ + \"static/media/basic-push-pin-15.1cd5a458.png\";","import icon0 from './basic-pin-large-0.png';\r\nimport icon1 from './basic-pin-large-1.png';\r\nimport icon2 from './basic-pin-large-2.png';\r\nimport icon3 from './basic-pin-large-3.png';\r\nimport icon4 from './basic-pin-large-4.png';\r\nimport icon5 from './basic-pin-large-5.png';\r\nimport icon6 from './basic-pin-large-6.png';\r\nimport icon7 from './basic-pin-large-7.png';\r\nimport icon8 from './basic-pin-large-8.png';\r\nimport icon9 from './basic-pin-large-9.png';\r\nimport icon10 from './basic-pin-large-10.png';\r\nimport icon11 from './basic-pin-large-11.png';\r\nimport icon12 from './basic-pin-large-12.png';\r\nimport icon13 from './basic-pin-large-13.png';\r\nimport icon14 from './basic-pin-large-14.png';\r\nimport icon15 from './basic-pin-large-15.png';\r\nimport icon16 from './basic-pin-small-0.png';\r\nimport icon17 from './basic-pin-small-1.png';\r\nimport icon18 from './basic-pin-small-2.png';\r\nimport icon19 from './basic-pin-small-3.png';\r\nimport icon20 from './basic-pin-small-4.png';\r\nimport icon21 from './basic-pin-small-5.png';\r\nimport icon22 from './basic-pin-small-6.png';\r\nimport icon23 from './basic-pin-small-7.png';\r\nimport icon24 from './basic-pin-small-8.png';\r\nimport icon25 from './basic-pin-small-9.png';\r\nimport icon26 from './basic-pin-small-10.png';\r\nimport icon27 from './basic-pin-small-11.png';\r\nimport icon28 from './basic-pin-small-12.png';\r\nimport icon29 from './basic-pin-small-13.png';\r\nimport icon30 from './basic-pin-small-14.png';\r\nimport icon31 from './basic-pin-small-15.png';\r\nimport icon32 from './basic-push-pin-0.png';\r\nimport icon33 from './basic-push-pin-1.png';\r\nimport icon34 from './basic-push-pin-2.png';\r\nimport icon35 from './basic-push-pin-3.png';\r\nimport icon36 from './basic-push-pin-4.png';\r\nimport icon37 from './basic-push-pin-5.png';\r\nimport icon38 from './basic-push-pin-6.png';\r\nimport icon39 from './basic-push-pin-7.png';\r\nimport icon40 from './basic-push-pin-8.png';\r\nimport icon41 from './basic-push-pin-9.png';\r\nimport icon42 from './basic-push-pin-10.png';\r\nimport icon43 from './basic-push-pin-11.png';\r\nimport icon44 from './basic-push-pin-12.png';\r\nimport icon45 from './basic-push-pin-13.png';\r\nimport icon46 from './basic-push-pin-14.png';\r\nimport icon47 from './basic-push-pin-15.png';\r\n\r\nconst textures = {\r\n 'basic-pin-large-0': icon0,\r\n 'basic-pin-large-1': icon1,\r\n 'basic-pin-large-2': icon2,\r\n 'basic-pin-large-3': icon3,\r\n 'basic-pin-large-4': icon4,\r\n 'basic-pin-large-5': icon5,\r\n 'basic-pin-large-6': icon6,\r\n 'basic-pin-large-7': icon7,\r\n 'basic-pin-large-8': icon8,\r\n 'basic-pin-large-9': icon9,\r\n 'basic-pin-large-10': icon10,\r\n 'basic-pin-large-11': icon11,\r\n 'basic-pin-large-12': icon12,\r\n 'basic-pin-large-13': icon13,\r\n 'basic-pin-large-14': icon14,\r\n 'basic-pin-large-15': icon15,\r\n 'basic-pin-small-0': icon16,\r\n 'basic-pin-small-1': icon17,\r\n 'basic-pin-small-2': icon18,\r\n 'basic-pin-small-3': icon19,\r\n 'basic-pin-small-4': icon20,\r\n 'basic-pin-small-5': icon21,\r\n 'basic-pin-small-6': icon22,\r\n 'basic-pin-small-7': icon23,\r\n 'basic-pin-small-8': icon24,\r\n 'basic-pin-small-9': icon25,\r\n 'basic-pin-small-10': icon26,\r\n 'basic-pin-small-11': icon27,\r\n 'basic-pin-small-12': icon28,\r\n 'basic-pin-small-13': icon29,\r\n 'basic-pin-small-14': icon30,\r\n 'basic-pin-small-15': icon31,\r\n 'basic-push-pin-0': icon32,\r\n 'basic-push-pin-1': icon33,\r\n 'basic-push-pin-2': icon34,\r\n 'basic-push-pin-3': icon35,\r\n 'basic-push-pin-4': icon36,\r\n 'basic-push-pin-5': icon37,\r\n 'basic-push-pin-6': icon38,\r\n 'basic-push-pin-7': icon39,\r\n 'basic-push-pin-8': icon40,\r\n 'basic-push-pin-9': icon41,\r\n 'basic-push-pin-10': icon42,\r\n 'basic-push-pin-11': icon43,\r\n 'basic-push-pin-12': icon44,\r\n 'basic-push-pin-13': icon45,\r\n 'basic-push-pin-14': icon46,\r\n 'basic-push-pin-15': icon47,\r\n};\r\n\r\nexport default textures;","export default __webpack_public_path__ + \"static/media/001-ahead only.b36dbabc.png\";","export default __webpack_public_path__ + \"static/media/002-crossroads.abff42d3.png\";","export default __webpack_public_path__ + \"static/media/003-falling rocks.daff62e3.png\";","export default __webpack_public_path__ + \"static/media/004-give way.e8421679.png\";","export default __webpack_public_path__ + \"static/media/005-hump.b663a44b.png\";","export default __webpack_public_path__ + \"static/media/006-left turn.e8bd0364.png\";","export default __webpack_public_path__ + \"static/media/007-parking.c84744cd.png\";","export default __webpack_public_path__ + \"static/media/008-level crossing.053e35fb.png\";","export default __webpack_public_path__ + \"static/media/009-speed limit.825c6624.png\";","export default __webpack_public_path__ + \"static/media/010-narrow bridge.f8bce357.png\";","export default __webpack_public_path__ + \"static/media/011-no bike.6c786d64.png\";","export default __webpack_public_path__ + \"static/media/012-no trucks.bf3b4ed9.png\";","export default __webpack_public_path__ + \"static/media/013-no alarm.c6732ce5.png\";","export default __webpack_public_path__ + \"static/media/014-no turn left.7a57b70b.png\";","export default __webpack_public_path__ + \"static/media/015-no motorcycles.e72e07b7.png\";","export default __webpack_public_path__ + \"static/media/016-speed limit.96587810.png\";","export default __webpack_public_path__ + \"static/media/017-no overtaking.e093fefa.png\";","export default __webpack_public_path__ + \"static/media/018-pedestrian.49dc27d1.png\";","export default __webpack_public_path__ + \"static/media/019-no entry.31309892.png\";","export default __webpack_public_path__ + \"static/media/020-u turn.cc1171e5.png\";","export default __webpack_public_path__ + \"static/media/021-Two way.dad656b4.png\";","export default __webpack_public_path__ + \"static/media/022-pedestrian crossing.10e3b5d0.png\";","export default __webpack_public_path__ + \"static/media/023-right turn.01949354.png\";","export default __webpack_public_path__ + \"static/media/024-road work.b9ef5c5c.png\";","export default __webpack_public_path__ + \"static/media/025-roundabout.9ba22352.png\";","export default __webpack_public_path__ + \"static/media/026-pedestrian crossing.21ccb02a.png\";","export default __webpack_public_path__ + \"static/media/027-Slippery road.cb01f1f4.png\";","export default __webpack_public_path__ + \"static/media/028-traffic lights.195911bc.png\";","export default __webpack_public_path__ + \"static/media/029-turn left.ebfb7602.png\";","export default __webpack_public_path__ + \"static/media/030-turn right.c33332ed.png\";","export default __webpack_public_path__ + \"static/media/031-uneven.b33d0f06.png\";","export default __webpack_public_path__ + \"static/media/032-maximum.b544a731.png\";","export default __webpack_public_path__ + \"static/media/033-wild animals.96a2df8b.png\";","import icon0 from './001-ahead only.png';\r\nimport icon1 from './002-crossroads.png';\r\nimport icon2 from './003-falling rocks.png';\r\nimport icon3 from './004-give way.png';\r\nimport icon4 from './005-hump.png';\r\nimport icon5 from './006-left turn.png';\r\nimport icon6 from './007-parking.png';\r\nimport icon7 from './008-level crossing.png';\r\nimport icon8 from './009-speed limit.png';\r\nimport icon9 from './010-narrow bridge.png';\r\nimport icon10 from './011-no bike.png';\r\nimport icon11 from './012-no trucks.png';\r\nimport icon12 from './013-no alarm.png';\r\nimport icon13 from './014-no turn left.png';\r\nimport icon14 from './015-no motorcycles.png';\r\nimport icon15 from './016-speed limit.png';\r\nimport icon16 from './017-no overtaking.png';\r\nimport icon17 from './018-pedestrian.png';\r\nimport icon18 from './019-no entry.png';\r\nimport icon19 from './020-u turn.png';\r\nimport icon20 from './021-Two way.png';\r\nimport icon21 from './022-pedestrian crossing.png';\r\nimport icon22 from './023-right turn.png';\r\nimport icon23 from './024-road work.png';\r\nimport icon24 from './025-roundabout.png';\r\nimport icon25 from './026-pedestrian crossing.png';\r\nimport icon26 from './027-Slippery road.png';\r\nimport icon27 from './028-traffic lights.png';\r\nimport icon28 from './029-turn left.png';\r\nimport icon29 from './030-turn right.png';\r\nimport icon30 from './031-uneven.png';\r\nimport icon31 from './032-maximum.png';\r\nimport icon32 from './033-wild animals.png';\r\n\r\nconst textures = {\r\n '001-ahead only': icon0,\r\n '002-crossroads': icon1,\r\n '003-falling rocks': icon2,\r\n '004-give way': icon3,\r\n '005-hump': icon4,\r\n '006-left turn': icon5,\r\n '007-parking': icon6,\r\n '008-level crossing': icon7,\r\n '009-speed limit': icon8,\r\n '010-narrow bridge': icon9,\r\n '011-no bike': icon10,\r\n '012-no trucks': icon11,\r\n '013-no alarm': icon12,\r\n '014-no turn left': icon13,\r\n '015-no motorcycles': icon14,\r\n '016-speed limit': icon15,\r\n '017-no overtaking': icon16,\r\n '018-pedestrian': icon17,\r\n '019-no entry': icon18,\r\n '020-u turn': icon19,\r\n '021-Two way': icon20,\r\n '022-pedestrian crossing': icon21,\r\n '023-right turn': icon22,\r\n '024-road work': icon23,\r\n '025-roundabout': icon24,\r\n '026-pedestrian crossing': icon25,\r\n '027-Slippery road': icon26,\r\n '028-traffic lights': icon27,\r\n '029-turn left': icon28,\r\n '030-turn right': icon29,\r\n '031-uneven': icon30,\r\n '032-maximum': icon31,\r\n '033-wild animals': icon32,\r\n};\r\n\r\nexport default textures;","export default __webpack_public_path__ + \"static/media/001-narrow.df856ac0.png\";","export default __webpack_public_path__ + \"static/media/002-merge.a4a30488.png\";","export default __webpack_public_path__ + \"static/media/003-curve.05546df5.png\";","export default __webpack_public_path__ + \"static/media/004-curve.8f7cd063.png\";","export default __webpack_public_path__ + \"static/media/005-Junction.4dffa6c5.png\";","export default __webpack_public_path__ + \"static/media/006-curve.e74f68f4.png\";","export default __webpack_public_path__ + \"static/media/007-crossroads.b4aeab6d.png\";","export default __webpack_public_path__ + \"static/media/008-hump.f5b1cab9.png\";","export default __webpack_public_path__ + \"static/media/009-uneven.397db48f.png\";","export default __webpack_public_path__ + \"static/media/010-roundabout.68d0ffbd.png\";","export default __webpack_public_path__ + \"static/media/011-Two way.d51a58d8.png\";","export default __webpack_public_path__ + \"static/media/012-Junction.bd60896e.png\";","export default __webpack_public_path__ + \"static/media/013-Junction.78c13ca2.png\";","export default __webpack_public_path__ + \"static/media/014-Two way.b345b22a.png\";","export default __webpack_public_path__ + \"static/media/015-level.f8296ff7.png\";","export default __webpack_public_path__ + \"static/media/016-warning.0019e601.png\";","export default __webpack_public_path__ + \"static/media/017-hump.30a7ba8f.png\";","export default __webpack_public_path__ + \"static/media/018-dock.fdf0064a.png\";","export default __webpack_public_path__ + \"static/media/019-merge.2190995c.png\";","export default __webpack_public_path__ + \"static/media/020-falling rocks.9f4df857.png\";","export default __webpack_public_path__ + \"static/media/021-speed limit.d6845db0.png\";","export default __webpack_public_path__ + \"static/media/022-speed limit.8064e31b.png\";","export default __webpack_public_path__ + \"static/media/023-speed limit.aed48e6f.png\";","export default __webpack_public_path__ + \"static/media/024-speed limit.1e362fee.png\";","export default __webpack_public_path__ + \"static/media/025-speed limit.347d7255.png\";","export default __webpack_public_path__ + \"static/media/026-speed limit.45d92974.png\";","export default __webpack_public_path__ + \"static/media/027-speed limit.980a6068.png\";","export default __webpack_public_path__ + \"static/media/028-priority.fc44147f.png\";","export default __webpack_public_path__ + \"static/media/029-no overtaking.58426286.png\";","export default __webpack_public_path__ + \"static/media/030-no turn right.acbc461d.png\";","export default __webpack_public_path__ + \"static/media/031-u turn.08809920.png\";","export default __webpack_public_path__ + \"static/media/032-no stopping.d7c7b42a.png\";","export default __webpack_public_path__ + \"static/media/033-no waiting.4e5fe72f.png\";","export default __webpack_public_path__ + \"static/media/034-ahead.58e48a36.png\";","export default __webpack_public_path__ + \"static/media/035-turn left.f545eb0c.png\";","export default __webpack_public_path__ + \"static/media/036-keep left.536a6a5c.png\";","export default __webpack_public_path__ + \"static/media/037-direction.d6d26740.png\";","export default __webpack_public_path__ + \"static/media/038-turn left.3517acec.png\";","export default __webpack_public_path__ + \"static/media/039-roundabout.e35a3904.png\";","export default __webpack_public_path__ + \"static/media/040-no entry.606b7596.png\";","export default __webpack_public_path__ + \"static/media/041-parking.2c36baed.png\";","export default __webpack_public_path__ + \"static/media/042-priority.8f2995ce.png\";","export default __webpack_public_path__ + \"static/media/043-cul de sac.1eda70a7.png\";","export default __webpack_public_path__ + \"static/media/044-countdown.cd86cb1a.png\";","export default __webpack_public_path__ + \"static/media/045-countdown.64bef15d.png\";","export default __webpack_public_path__ + \"static/media/046-countdown.7ede0d8c.png\";","export default __webpack_public_path__ + \"static/media/047-hospital.e4c63624.png\";","export default __webpack_public_path__ + \"static/media/048-information.803f80de.png\";","export default __webpack_public_path__ + \"static/media/049-speed camera.11651251.png\";","export default __webpack_public_path__ + \"static/media/050-lane.e8790c18.png\";","export default __webpack_public_path__ + \"static/media/051-end motorway.06ef8c65.png\";","export default __webpack_public_path__ + \"static/media/052-motorway.84800887.png\";","export default __webpack_public_path__ + \"static/media/053-one way.1028aeeb.png\";","export default __webpack_public_path__ + \"static/media/054-direction.ef3625e0.png\";","export default __webpack_public_path__ + \"static/media/055-stop.c8013090.png\";","export default __webpack_public_path__ + \"static/media/056-road.ae8fd707.png\";","export default __webpack_public_path__ + \"static/media/057-emergency diversion.e4fc4c07.png\";","export default __webpack_public_path__ + \"static/media/058-emergency diversion.cf3519dd.png\";","export default __webpack_public_path__ + \"static/media/059-emergency diversion.286133f6.png\";","export default __webpack_public_path__ + \"static/media/060-emergency diversion.8a4411bc.png\";","import icon0 from './001-narrow.png';\r\nimport icon1 from './002-merge.png';\r\nimport icon2 from './003-curve.png';\r\nimport icon3 from './004-curve.png';\r\nimport icon4 from './005-Junction.png';\r\nimport icon5 from './006-curve.png';\r\nimport icon6 from './007-crossroads.png';\r\nimport icon7 from './008-hump.png';\r\nimport icon8 from './009-uneven.png';\r\nimport icon9 from './010-roundabout.png';\r\nimport icon10 from './011-Two way.png';\r\nimport icon11 from './012-Junction.png';\r\nimport icon12 from './013-Junction.png';\r\nimport icon13 from './014-Two way.png';\r\nimport icon14 from './015-level.png';\r\nimport icon15 from './016-warning.png';\r\nimport icon16 from './017-hump.png';\r\nimport icon17 from './018-dock.png';\r\nimport icon18 from './019-merge.png';\r\nimport icon19 from './020-falling rocks.png';\r\nimport icon20 from './021-speed limit.png';\r\nimport icon21 from './022-speed limit.png';\r\nimport icon22 from './023-speed limit.png';\r\nimport icon23 from './024-speed limit.png';\r\nimport icon24 from './025-speed limit.png';\r\nimport icon25 from './026-speed limit.png';\r\nimport icon26 from './027-speed limit.png';\r\nimport icon27 from './028-priority.png';\r\nimport icon28 from './029-no overtaking.png';\r\nimport icon29 from './030-no turn right.png';\r\nimport icon30 from './031-u turn.png';\r\nimport icon31 from './032-no stopping.png';\r\nimport icon32 from './033-no waiting.png';\r\nimport icon33 from './034-ahead.png';\r\nimport icon34 from './035-turn left.png';\r\nimport icon35 from './036-keep left.png';\r\nimport icon36 from './037-direction.png';\r\nimport icon37 from './038-turn left.png';\r\nimport icon38 from './039-roundabout.png';\r\nimport icon39 from './040-no entry.png';\r\nimport icon40 from './041-parking.png';\r\nimport icon41 from './042-priority.png';\r\nimport icon42 from './043-cul de sac.png';\r\nimport icon43 from './044-countdown.png';\r\nimport icon44 from './045-countdown.png';\r\nimport icon45 from './046-countdown.png';\r\nimport icon46 from './047-hospital.png';\r\nimport icon47 from './048-information.png';\r\nimport icon48 from './049-speed camera.png';\r\nimport icon49 from './050-lane.png';\r\nimport icon50 from './051-end motorway.png';\r\nimport icon51 from './052-motorway.png';\r\nimport icon52 from './053-one way.png';\r\nimport icon53 from './054-direction.png';\r\nimport icon54 from './055-stop.png';\r\nimport icon55 from './056-road.png';\r\nimport icon56 from './057-emergency diversion.png';\r\nimport icon57 from './058-emergency diversion.png';\r\nimport icon58 from './059-emergency diversion.png';\r\nimport icon59 from './060-emergency diversion.png';\r\n\r\nconst textures = {\r\n '001-narrow': icon0,\r\n '002-merge': icon1,\r\n '003-curve': icon2,\r\n '004-curve': icon3,\r\n '005-Junction': icon4,\r\n '006-curve': icon5,\r\n '007-crossroads': icon6,\r\n '008-hump': icon7,\r\n '009-uneven': icon8,\r\n '010-roundabout': icon9,\r\n '011-Two way': icon10,\r\n '012-Junction': icon11,\r\n '013-Junction': icon12,\r\n '014-Two way': icon13,\r\n '015-level': icon14,\r\n '016-warning': icon15,\r\n '017-hump': icon16,\r\n '018-dock': icon17,\r\n '019-merge': icon18,\r\n '020-falling rocks': icon19,\r\n '021-speed limit': icon20,\r\n '022-speed limit': icon21,\r\n '023-speed limit': icon22,\r\n '024-speed limit': icon23,\r\n '025-speed limit': icon24,\r\n '026-speed limit': icon25,\r\n '027-speed limit': icon26,\r\n '028-priority': icon27,\r\n '029-no overtaking': icon28,\r\n '030-no turn right': icon29,\r\n '031-u turn': icon30,\r\n '032-no stopping': icon31,\r\n '033-no waiting': icon32,\r\n '034-ahead': icon33,\r\n '035-turn left': icon34,\r\n '036-keep left': icon35,\r\n '037-direction': icon36,\r\n '038-turn left': icon37,\r\n '039-roundabout': icon38,\r\n '040-no entry': icon39,\r\n '041-parking': icon40,\r\n '042-priority': icon41,\r\n '043-cul de sac': icon42,\r\n '044-countdown': icon43,\r\n '045-countdown': icon44,\r\n '046-countdown': icon45,\r\n '047-hospital': icon46,\r\n '048-information': icon47,\r\n '049-speed camera': icon48,\r\n '050-lane': icon49,\r\n '051-end motorway': icon50,\r\n '052-motorway': icon51,\r\n '053-one way': icon52,\r\n '054-direction': icon53,\r\n '055-stop': icon54,\r\n '056-road': icon55,\r\n '057-emergency diversion': icon56,\r\n '058-emergency diversion': icon57,\r\n '059-emergency diversion': icon58,\r\n '060-emergency diversion': icon59,\r\n};\r\n\r\nexport default textures;","export default __webpack_public_path__ + \"static/media/construction--barrier--temporary.c295cec2.png\";","export default __webpack_public_path__ + \"static/media/construction--flat--crosswalk-plain.3d80b1ca.png\";","export default __webpack_public_path__ + \"static/media/construction--flat--driveway.9fd50f90.png\";","export default __webpack_public_path__ + \"static/media/construction--flat--flat-driveway.dbed896e.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--arrow--left.5a8ed6fe.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--arrow--right.0c25ddcb.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--arrow--split-left-or-straight.26ea6315.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--arrow--split-right-or-straight.19848277.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--arrow--straight.c32e8693.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--crosswalk-zebra.41655dfd.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--give-way-row.d469bc27.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--give-way-single.88347f54.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--other-marking.0b3d3063.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--stop-line.926dabb3.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--symbol--bicycle.b160ff92.png\";","export default __webpack_public_path__ + \"static/media/marking--discrete--text.a473cb73.png\";","export default __webpack_public_path__ + \"static/media/object--banner.4261826e.png\";","export default __webpack_public_path__ + \"static/media/object--bench.de45c74e.png\";","export default __webpack_public_path__ + \"static/media/object--bike-rack.2d333cd5.png\";","export default __webpack_public_path__ + \"static/media/object--catch-basin.6c8a4f84.png\";","export default __webpack_public_path__ + \"static/media/object--cctv-camera.2eea74b0.png\";","export default __webpack_public_path__ + \"static/media/object--fire-hydrant.d91d17bd.png\";","export default __webpack_public_path__ + \"static/media/object--junction-box.75aae919.png\";","export default __webpack_public_path__ + \"static/media/object--mailbox.6bae4b92.png\";","export default __webpack_public_path__ + \"static/media/object--manhole.049795d8.png\";","export default __webpack_public_path__ + \"static/media/object--parking-meter.0c26ccb0.png\";","export default __webpack_public_path__ + \"static/media/object--phone-booth.b2671fc0.png\";","export default __webpack_public_path__ + \"static/media/object--sign--advertisement.1d13d128.png\";","export default __webpack_public_path__ + \"static/media/object--sign--information.88add084.png\";","export default __webpack_public_path__ + \"static/media/object--sign--store.6da73474.png\";","export default __webpack_public_path__ + \"static/media/object--street-light.99b39470.png\";","export default __webpack_public_path__ + \"static/media/object--support--pole.36dfcf46.png\";","export default __webpack_public_path__ + \"static/media/object--support--traffic-sign-frame.7bae73cd.png\";","export default __webpack_public_path__ + \"static/media/object--support--utility-pole.71ce4ba5.png\";","export default __webpack_public_path__ + \"static/media/object--traffic-cone.b0f05e52.png\";","export default __webpack_public_path__ + \"static/media/object--traffic-light.6dd482e0.png\";","export default __webpack_public_path__ + \"static/media/object--trash-can.4ba13bc2.png\";","export default __webpack_public_path__ + \"static/media/object--water-valve.848a98d0.png\";","import icon0 from './construction--barrier--temporary.png';\r\nimport icon1 from './construction--flat--crosswalk-plain.png';\r\nimport icon2 from './construction--flat--driveway.png';\r\nimport icon3 from './construction--flat--flat-driveway.png';\r\nimport icon4 from './marking--discrete--arrow--left.png';\r\nimport icon5 from './marking--discrete--arrow--right.png';\r\nimport icon6 from './marking--discrete--arrow--split-left-or-straight.png';\r\nimport icon7 from './marking--discrete--arrow--split-right-or-straight.png';\r\nimport icon8 from './marking--discrete--arrow--straight.png';\r\nimport icon9 from './marking--discrete--crosswalk-zebra.png';\r\nimport icon10 from './marking--discrete--give-way-row.png';\r\nimport icon11 from './marking--discrete--give-way-single.png';\r\nimport icon12 from './marking--discrete--other-marking.png';\r\nimport icon13 from './marking--discrete--stop-line.png';\r\nimport icon14 from './marking--discrete--symbol--bicycle.png';\r\nimport icon15 from './marking--discrete--text.png';\r\nimport icon16 from './object--banner.png';\r\nimport icon17 from './object--bench.png';\r\nimport icon18 from './object--bike-rack.png';\r\nimport icon19 from './object--catch-basin.png';\r\nimport icon20 from './object--cctv-camera.png';\r\nimport icon21 from './object--fire-hydrant.png';\r\nimport icon22 from './object--junction-box.png';\r\nimport icon23 from './object--mailbox.png';\r\nimport icon24 from './object--manhole.png';\r\nimport icon25 from './object--parking-meter.png';\r\nimport icon26 from './object--phone-booth.png';\r\nimport icon27 from './object--sign--advertisement.png';\r\nimport icon28 from './object--sign--information.png';\r\nimport icon29 from './object--sign--store.png';\r\nimport icon30 from './object--street-light.png';\r\nimport icon31 from './object--support--pole.png';\r\nimport icon32 from './object--support--traffic-sign-frame.png';\r\nimport icon33 from './object--support--utility-pole.png';\r\nimport icon34 from './object--traffic-cone.png';\r\nimport icon35 from './object--traffic-light.png';\r\nimport icon36 from './object--trash-can.png';\r\nimport icon37 from './object--water-valve.png';\r\n\r\nconst textures = {\r\n 'construction--barrier--temporary': icon0,\r\n 'construction--flat--crosswalk-plain': icon1,\r\n 'construction--flat--driveway': icon2,\r\n 'construction--flat--flat-driveway': icon3,\r\n 'marking--discrete--arrow--left': icon4,\r\n 'marking--discrete--arrow--right': icon5,\r\n 'marking--discrete--arrow--split-left-or-straight': icon6,\r\n 'marking--discrete--arrow--split-right-or-straight': icon7,\r\n 'marking--discrete--arrow--straight': icon8,\r\n 'marking--discrete--crosswalk-zebra': icon9,\r\n 'marking--discrete--give-way-row': icon10,\r\n 'marking--discrete--give-way-single': icon11,\r\n 'marking--discrete--other-marking': icon12,\r\n 'marking--discrete--stop-line': icon13,\r\n 'marking--discrete--symbol--bicycle': icon14,\r\n 'marking--discrete--text': icon15,\r\n 'object--banner': icon16,\r\n 'object--bench': icon17,\r\n 'object--bike-rack': icon18,\r\n 'object--catch-basin': icon19,\r\n 'object--cctv-camera': icon20,\r\n 'object--fire-hydrant': icon21,\r\n 'object--junction-box': icon22,\r\n 'object--mailbox': icon23,\r\n 'object--manhole': icon24,\r\n 'object--parking-meter': icon25,\r\n 'object--phone-booth': icon26,\r\n 'object--sign--advertisement': icon27,\r\n 'object--sign--information': icon28,\r\n 'object--sign--store': icon29,\r\n 'object--street-light': icon30,\r\n 'object--support--pole': icon31,\r\n 'object--support--traffic-sign-frame': icon32,\r\n 'object--support--utility-pole': icon33,\r\n 'object--traffic-cone': icon34,\r\n 'object--traffic-light': icon35,\r\n 'object--trash-can': icon36,\r\n 'object--water-valve': icon37,\r\n};\r\n\r\nexport default textures;","export default __webpack_public_path__ + \"static/media/complementary--accident-area--g1.d5411006.png\";","export default __webpack_public_path__ + \"static/media/complementary--accident-area--g2.6b892819.png\";","export default __webpack_public_path__ + \"static/media/complementary--accident-area--g3.39c5aa2d.png\";","export default __webpack_public_path__ + \"static/media/complementary--accident-area--g4.c8960430.png\";","export default __webpack_public_path__ + \"static/media/complementary--advisory-exit-or-ramp-speed--g1.d5aa6bd3.png\";","export default __webpack_public_path__ + \"static/media/complementary--bicycles--g1.e8a92988.png\";","export default __webpack_public_path__ + \"static/media/complementary--bicycles-and-pedestrians-detour--g1.dcab8b13.png\";","export default __webpack_public_path__ + \"static/media/complementary--bicycles-or-pedestrians-detour--g1.e5138d21.png\";","export default __webpack_public_path__ + \"static/media/complementary--bicycles-turn-right--g1.b50cdd8a.png\";","export default __webpack_public_path__ + \"static/media/complementary--bike-route--g1.ad85731c.png\";","export default __webpack_public_path__ + \"static/media/complementary--bike-route--g3.1a874469.png\";","export default __webpack_public_path__ + \"static/media/complementary--both-directions--g1.1eaa27e4.png\";","export default __webpack_public_path__ + \"static/media/complementary--both-directions--g2.ab7a5976.png\";","export default __webpack_public_path__ + \"static/media/complementary--buses--g1.faffc898.png\";","export default __webpack_public_path__ + \"static/media/complementary--buses-and-trucks--g1.d1b0d33f.png\";","export default __webpack_public_path__ + \"static/media/complementary--camera--g1.41a87e99.png\";","export default __webpack_public_path__ + \"static/media/complementary--camera--g2.307561d6.png\";","export default __webpack_public_path__ + \"static/media/complementary--camera--g3.859735f8.png\";","export default __webpack_public_path__ + \"static/media/complementary--camera--g4.5bcf9af2.png\";","export default __webpack_public_path__ + \"static/media/complementary--camera--g5.811530fb.png\";","export default __webpack_public_path__ + \"static/media/complementary--caravan-trailers--g2.a2b733be.png\";","export default __webpack_public_path__ + \"static/media/complementary--caravan-trailers--g3.1ed469ef.png\";","export default __webpack_public_path__ + \"static/media/complementary--caravans--g2.ce71e539.png\";","export default __webpack_public_path__ + \"static/media/complementary--carts--g1.fea12c17.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-left--g1.57ac3093.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-left--g2.6443d98c.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-left--g3.a6c83c95.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-left--g4.77777d15.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-left--g5.2f7987c9.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-right--g1.f22f39f2.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-right--g2.71ba8ac6.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-right--g3.1dd25331.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-right--g4.651efd19.png\";","export default __webpack_public_path__ + \"static/media/complementary--chevron-right--g5.7734c675.png\";","export default __webpack_public_path__ + \"static/media/complementary--dangerous-or-pollutant-good--g1.3bf88255.png\";","export default __webpack_public_path__ + \"static/media/complementary--dead-end--g1.1e58d714.png\";","export default __webpack_public_path__ + \"static/media/complementary--detour--g1.227caa6a.png\";","export default __webpack_public_path__ + \"static/media/complementary--disabled-persons--g1.359b3b95.png\";","export default __webpack_public_path__ + \"static/media/complementary--distance--g1.108230dd.png\";","export default __webpack_public_path__ + \"static/media/complementary--distance--g2.f24fae54.png\";","export default __webpack_public_path__ + \"static/media/complementary--distance--g3.2d9b5876.png\";","export default __webpack_public_path__ + \"static/media/complementary--end-of-road-works--g1.92d44f56.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-bicycles--g1.a9f8a4b1.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-bicycles--g2.64490d3f.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-buses--g1.1ba43e99.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-carts--g1.68857953.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-motorcycles--g1.1c4d4f08.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-motorcycles--g2.f66bc691.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-polluting-level-green--g1.a4a5c035.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-polluting-level-green-yellow--g1.b02fc562.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-polluting-level-green-yellow-red--g1.36e116eb.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-tractors--g1.5fffbc13.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-tractors--g2.b5eb0923.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-trailers--g1.fb401260.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-trailers--g2.915ae4eb.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-trains--g1.969b8921.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-trams--g1.68209674.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-trucks--g1.e68b7c31.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-vehicles--g1.89da1dbd.png\";","export default __webpack_public_path__ + \"static/media/complementary--except-vehicles--g2.a39aee57.png\";","export default __webpack_public_path__ + \"static/media/complementary--go-left--g1.c3874410.png\";","export default __webpack_public_path__ + \"static/media/complementary--go-right--g1.f0fa8d37.png\";","export default __webpack_public_path__ + \"static/media/complementary--go-straight-or-turn-left--g1.0a66ac06.png\";","export default __webpack_public_path__ + \"static/media/complementary--go-straight-or-turn-right--g1.bf518ff3.png\";","export default __webpack_public_path__ + \"static/media/complementary--height-limit--g1.66143aeb.png\";","export default __webpack_public_path__ + \"static/media/complementary--height-limit--g2.5f8c440f.png\";","export default __webpack_public_path__ + \"static/media/complementary--including-bicycles-and-motorcycles--g1.ee870326.png\";","export default __webpack_public_path__ + \"static/media/complementary--including-buses-vehicles--g1.03851082.png\";","export default __webpack_public_path__ + \"static/media/complementary--keep-left--g1.9f4023c8.png\";","export default __webpack_public_path__ + \"static/media/complementary--keep-right--g1.4194a29d.png\";","export default __webpack_public_path__ + \"static/media/complementary--lane-control--g1.82117f8e.png\";","export default __webpack_public_path__ + \"static/media/complementary--lane-control--g2.c5f7c989.png\";","export default __webpack_public_path__ + \"static/media/complementary--lane-control--g3.ade4dcda.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-10--g1.53abf612.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-15--g1.c67ac701.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-20--g1.d2e11200.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-25--g1.ecdfffb1.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-30--g1.df513571.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-35--g1.bf20adba.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-40--g1.8969e2c1.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-45--g1.cdce0b1d.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-50--g1.6b808783.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-55--g1.be855ff8.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-60--g1.23136090.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-65--g1.058ac585.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-70--g1.361e8a6e.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-75--g1.3fd589fc.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-80--g1.4a213736.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-85--g1.ba8d0d8b.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-90--g1.c363995e.png\";","export default __webpack_public_path__ + \"static/media/complementary--maximum-speed-limit-95--g1.a5f29207.png\";","export default __webpack_public_path__ + \"static/media/complementary--motorcycles--g1.511b5604.png\";","export default __webpack_public_path__ + \"static/media/complementary--motorcycles--g2.593b05ac.png\";","export default __webpack_public_path__ + \"static/media/complementary--motorcycles--g3.1c3e0e2b.png\";","export default __webpack_public_path__ + \"static/media/complementary--motorcycles--g4.b3d432a8.png\";","export default __webpack_public_path__ + \"static/media/complementary--obstacle-delineator--g1.2be98597.png\";","export default __webpack_public_path__ + \"static/media/complementary--obstacle-delineator--g2.1e86ca50.png\";","export default __webpack_public_path__ + \"static/media/complementary--obstacle-delineator--g3.2445aeb2.png\";","export default __webpack_public_path__ + \"static/media/complementary--one-direction-left--g1.72b7311e.png\";","export default __webpack_public_path__ + \"static/media/complementary--one-direction-right--g1.ef8aa050.png\";","export default __webpack_public_path__ + \"static/media/complementary--pass-left--g1.e63e20d4.png\";","export default __webpack_public_path__ + \"static/media/complementary--pass-right--g1.8143583a.png\";","export default __webpack_public_path__ + \"static/media/complementary--pedestrians-and-bicycles--g1.46b1b0b1.png\";","export default __webpack_public_path__ + \"static/media/complementary--pedestrians-left--g1.b56a5492.png\";","export default __webpack_public_path__ + \"static/media/complementary--pedestrians-right--g1.01475b36.png\";","export default __webpack_public_path__ + \"static/media/complementary--photo-enforced--g1.7f00dc63.png\";","export default __webpack_public_path__ + \"static/media/complementary--playground--g1.7cc32db1.png\";","export default __webpack_public_path__ + \"static/media/complementary--priority-route-at-intersection--g1.339b5f15.png\";","export default __webpack_public_path__ + \"static/media/complementary--priority-route-at-intersection--g2.0f1e5df5.png\";","export default __webpack_public_path__ + \"static/media/complementary--priority-route-at-intersection--g3.a266b74b.png\";","export default __webpack_public_path__ + \"static/media/complementary--priority-route-at-intersection--g4.fc911c8e.png\";","export default __webpack_public_path__ + \"static/media/complementary--priority-route-at-intersection--g5.472959d3.png\";","export default __webpack_public_path__ + \"static/media/complementary--priority-route-at-intersection--g6.9b72a153.png\";","export default __webpack_public_path__ + \"static/media/complementary--railroad--g1.ac072e7a.png\";","export default __webpack_public_path__ + \"static/media/complementary--railroad--g2.7ae94b03.png\";","export default __webpack_public_path__ + \"static/media/complementary--railroad--g3.3ee9fe34.png\";","export default __webpack_public_path__ + \"static/media/complementary--restriction-in-both-directions--g1.076c822f.png\";","export default __webpack_public_path__ + \"static/media/complementary--roundabout-go-left--g1.4b39fec6.png\";","export default __webpack_public_path__ + \"static/media/complementary--roundabout-go-right--g1.c4bcfb99.png\";","export default __webpack_public_path__ + \"static/media/complementary--roundabout-go-straight--g1.8374e8e8.png\";","export default __webpack_public_path__ + \"static/media/complementary--slippery-for-caravan-trailers--g1.22bf4483.png\";","export default __webpack_public_path__ + \"static/media/complementary--snow--g2.d69deef2.png\";","export default __webpack_public_path__ + \"static/media/complementary--snow--g4.767b8bcc.png\";","export default __webpack_public_path__ + \"static/media/complementary--snow--g5.9cab1800.png\";","export default __webpack_public_path__ + \"static/media/complementary--snowmobiles--g1.040ef047.png\";","export default __webpack_public_path__ + \"static/media/complementary--soft-shoulder--g1.69316d35.png\";","export default __webpack_public_path__ + \"static/media/complementary--soft-shoulder--g2.7ca975f6.png\";","export default __webpack_public_path__ + \"static/media/complementary--steep-ascent--g1.530757ce.png\";","export default __webpack_public_path__ + \"static/media/complementary--steep-descent--g1.8c7f6ee5.png\";","export default __webpack_public_path__ + \"static/media/complementary--time-restrictions--g1.26eaeae5.png\";","export default __webpack_public_path__ + \"static/media/complementary--time-restrictions--g3.4c6120b8.png\";","export default __webpack_public_path__ + \"static/media/complementary--tow-away-zone--g1.8e752887.png\";","export default __webpack_public_path__ + \"static/media/complementary--tow-away-zone--g3.22f7f3eb.png\";","export default __webpack_public_path__ + \"static/media/complementary--tractors--g1.e217db9e.png\";","export default __webpack_public_path__ + \"static/media/complementary--traffic-queues--g1.798af17a.png\";","export default __webpack_public_path__ + \"static/media/complementary--trailers--g1.f2bf02fe.png\";","export default __webpack_public_path__ + \"static/media/complementary--trailers--g2.bbd07d83.png\";","export default __webpack_public_path__ + \"static/media/complementary--trailers--g3.e99a3109.png\";","export default __webpack_public_path__ + \"static/media/complementary--trailers--g4.b351db3d.png\";","export default __webpack_public_path__ + \"static/media/complementary--trains--g1.006bb9eb.png\";","export default __webpack_public_path__ + \"static/media/complementary--trams--g1.3bfc644b.png\";","export default __webpack_public_path__ + \"static/media/complementary--trees--g1.26a10d2b.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks--g1.679a2a43.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks--g2.930ba842.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks--g3.41659ea2.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-and-trailers--g1.67787aa2.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-buses-trailers--g1.af473f66.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-go-left--g1.2884aa5c.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-go-left-ahead--g1.abe94d9d.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-go-right--g1.82ab3332.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-go-right-ahead--g1.b575da79.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-go-straight--g1.76cd0c33.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-turn-left--g1.d2ead92b.png\";","export default __webpack_public_path__ + \"static/media/complementary--trucks-turn-right--g1.f2a4dae6.png\";","export default __webpack_public_path__ + \"static/media/complementary--turn-left--g1.6d813807.png\";","export default __webpack_public_path__ + \"static/media/complementary--turn-left--g2.6fd51622.png\";","export default __webpack_public_path__ + \"static/media/complementary--turn-right--g1.88241ef1.png\";","export default __webpack_public_path__ + \"static/media/complementary--turn-right--g2.4b154bb3.png\";","export default __webpack_public_path__ + \"static/media/complementary--two-way-traffic--g1.ecba5f2b.png\";","export default __webpack_public_path__ + \"static/media/complementary--two-way-traffic--g2.45a6a7c7.png\";","export default __webpack_public_path__ + \"static/media/complementary--two-way-traffic--g3.46b191f8.png\";","export default __webpack_public_path__ + \"static/media/complementary--two-way-traffic--g4.05df5af7.png\";","export default __webpack_public_path__ + \"static/media/complementary--two-way-traffic--g5.23d82cc1.png\";","export default __webpack_public_path__ + \"static/media/complementary--vehicles--g1.3e0f8a88.png\";","export default __webpack_public_path__ + \"static/media/complementary--vehicles--g2.546a3e5a.png\";","export default __webpack_public_path__ + \"static/media/complementary--vehicles-or-buses--g1.28a800fd.png\";","export default __webpack_public_path__ + \"static/media/complementary--weekends-or-holidays--g1.75bb96df.png\";","export default __webpack_public_path__ + \"static/media/complementary--weight-limit--g1.bdc6c055.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-foggy--g1.ce7480ff.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-rainy--g1.3e9a4e29.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-rainy--g2.5743ee89.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-rainy--g3.0b5ed3f3.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-snowy--g1.eb82e32c.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-snowy--g2.b221027b.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-snowy-or-rainy--g1.af3f362e.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-snowy-or-rainy--g2.bf4655ce.png\";","export default __webpack_public_path__ + \"static/media/complementary--when-wet--g1.11ed4478.png\";","export default __webpack_public_path__ + \"static/media/complementary--width-limit--g1.cef661be.png\";","export default __webpack_public_path__ + \"static/media/complementary--working-days--g1.313bbb27.png\";","export default __webpack_public_path__ + \"static/media/information--airport--g1.73af71fe.png\";","export default __webpack_public_path__ + \"static/media/information--airport--g2.81208f16.png\";","export default __webpack_public_path__ + \"static/media/information--bicycle-lane--g1.504421c1.png\";","export default __webpack_public_path__ + \"static/media/information--bicycles-both-ways--g1.c95bbe04.png\";","export default __webpack_public_path__ + \"static/media/information--bicycles-crossing--g1.f4c114cf.png\";","export default __webpack_public_path__ + \"static/media/information--bicycles-crossing--g2.bf76e715.png\";","export default __webpack_public_path__ + \"static/media/information--bicycles-crossing--g3.6a7abeba.png\";","export default __webpack_public_path__ + \"static/media/information--bike-route--g1.62a47331.png\";","export default __webpack_public_path__ + \"static/media/information--bike-route--g2.97104997.png\";","export default __webpack_public_path__ + \"static/media/information--built-up-area--g1.ac4f16b0.png\";","export default __webpack_public_path__ + \"static/media/information--built-up-area--g2.11ebb081.png\";","export default __webpack_public_path__ + \"static/media/information--bus-lane-straight--g1.4a1a0ce3.png\";","export default __webpack_public_path__ + \"static/media/information--bus-stop--g1.a7ecbcd5.png\";","export default __webpack_public_path__ + \"static/media/information--bus-stop--g2.81775f9e.png\";","export default __webpack_public_path__ + \"static/media/information--camera--g1.a402e59a.png\";","export default __webpack_public_path__ + \"static/media/information--camera--g2.d5adb6c7.png\";","export default __webpack_public_path__ + \"static/media/information--camera--g3.44300682.png\";","export default __webpack_public_path__ + \"static/media/information--camp--g1.84c6b6d9.png\";","export default __webpack_public_path__ + \"static/media/information--camp--g2.b85f120d.png\";","export default __webpack_public_path__ + \"static/media/information--car-pool-lane--g1.2eade6ef.png\";","export default __webpack_public_path__ + \"static/media/information--caravan-parking--g1.18735370.png\";","export default __webpack_public_path__ + \"static/media/information--caravan-trailer-parking--g1.71f0f60c.png\";","export default __webpack_public_path__ + \"static/media/information--cargo-loading-zone--g1.e90c9dac.png\";","export default __webpack_public_path__ + \"static/media/information--central-lane--g1.fe7e0080.png\";","export default __webpack_public_path__ + \"static/media/information--charging-station--g1.38a12cae.png\";","export default __webpack_public_path__ + \"static/media/information--children--g1.84e33dd2.png\";","export default __webpack_public_path__ + \"static/media/information--children--g2.aede4dee.png\";","export default __webpack_public_path__ + \"static/media/information--children-crossing--g5.829b1301.png\";","export default __webpack_public_path__ + \"static/media/information--cycling-two-abreast-permitted--g1.f7b5c1af.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end--g1.337632a7.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end--g2.313e9231.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end--g3.0f065135.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end--g4.50b3a50f.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-except-bicycles--g1.00a6125f.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-except-bicycles-and-pedestrians--g1.872ecfb2.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-except-bicycles-and-pedestrians--g2.403f04e3.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-left--g1.81116d41.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-left--g2.369ad9b4.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-right--g1.b3196029.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-right--g2.92903f2b.png\";","export default __webpack_public_path__ + \"static/media/information--dead-end-right--g3.00e4000a.png\";","export default __webpack_public_path__ + \"static/media/information--directions--g1.5b231c54.png\";","export default __webpack_public_path__ + \"static/media/information--disabled-persons--g1.4bcf3f61.png\";","export default __webpack_public_path__ + \"static/media/information--disabled-persons--g2.43579fe3.png\";","export default __webpack_public_path__ + \"static/media/information--disabled-persons--g3.312f93f3.png\";","export default __webpack_public_path__ + \"static/media/information--emergency-facility--g1.5f24e4fe.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-advisory-maximum-speed-limit-20--g1.83f3bca3.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-advisory-maximum-speed-limit-40--g1.d09cf637.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-advisory-maximum-speed-limit-60--g1.cbd3a657.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-advisory-maximum-speed-limit-70--g1.a14754dc.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-advisory-maximum-speed-limit-80--g1.20280fbf.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-advisory-maximum-speed-limit-90--g1.84ad37e8.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-bicycle-lane--g1.d2b5baa9.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-built-up-area--g1.d3c1e825.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-built-up-area--g2.c2932636.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-built-up-area--g3.d59cc0fb.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-built-up-area--g4.88e9bd6b.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-car-pool-lane--g1.83bbacf0.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-limited-access-road--g1.4d253455.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-living-street--g1.b9ad088e.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-living-street--g2.edcc67c9.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-10--g1.ca614575.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-20--g1.abe33ebd.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-25--g1.43799527.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-30--g1.779efce2.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-35--g1.674a262a.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-40--g1.baa5bd2c.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-50--g1.20353c86.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-60--g1.461328dc.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-70--g1.2e31daaf.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-75--g1.4bc31e63.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-80--g1.e2f688b1.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-90--g1.49bdceb5.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-100--g1.e83e0d13.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-110--g1.719ac78c.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-120--g1.57a848ce.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-minimum-speed-130--g1.58da3ff2.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-motorway--g1.645f1476.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-overtaking-permitted-heavy-good-vehicles--g1.b36d111d.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-road-works--g1.5b7f3560.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-tunnel--g1.90fc460c.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-tunnel--g2.7ac93cff.png\";","export default __webpack_public_path__ + \"static/media/information--end-of-two-way-traffic--g1.88eeaba6.png\";","export default __webpack_public_path__ + \"static/media/information--equestrians-permitted--g1.a22f8bf3.png\";","export default __webpack_public_path__ + \"static/media/information--exit-ahead--g1.95953c4c.png\";","export default __webpack_public_path__ + \"static/media/information--exit-ahead--g2.d7e0a668.png\";","export default __webpack_public_path__ + \"static/media/information--exit-ahead--g3.36f7fe6b.png\";","export default __webpack_public_path__ + \"static/media/information--flight-port--g1.6ffedaed.png\";","export default __webpack_public_path__ + \"static/media/information--food--g1.c3a95157.png\";","export default __webpack_public_path__ + \"static/media/information--food--g2.a19e0e4d.png\";","export default __webpack_public_path__ + \"static/media/information--gas-station--g1.835ad032.png\";","export default __webpack_public_path__ + \"static/media/information--gas-station--g2.397a57fc.png\";","export default __webpack_public_path__ + \"static/media/information--gas-station--g3.d417b630.png\";","export default __webpack_public_path__ + \"static/media/information--general-speed-limit-at-city-border--g1.162d9f16.png\";","export default __webpack_public_path__ + \"static/media/information--go-left--g1.b4653a1a.png\";","export default __webpack_public_path__ + \"static/media/information--go-right--g1.fb259e79.png\";","export default __webpack_public_path__ + \"static/media/information--go-straight--g1.2b4c9d90.png\";","export default __webpack_public_path__ + \"static/media/information--go-straight-or-left--g1.61f62586.png\";","export default __webpack_public_path__ + \"static/media/information--go-straight-or-right--g1.74189079.png\";","export default __webpack_public_path__ + \"static/media/information--go-straight-or-turn-left--g1.fe58d18a.png\";","export default __webpack_public_path__ + \"static/media/information--go-straight-or-turn-right--g1.01ba2725.png\";","export default __webpack_public_path__ + \"static/media/information--hazardous-goods-vehicles-lane--g1.5d266d26.png\";","export default __webpack_public_path__ + \"static/media/information--height-limit--g1.55576056.png\";","export default __webpack_public_path__ + \"static/media/information--height-limit--g2.28706fba.png\";","export default __webpack_public_path__ + \"static/media/information--highway-directions--g1.6ab6f919.png\";","export default __webpack_public_path__ + \"static/media/information--highway-exit--g1.8693888b.png\";","export default __webpack_public_path__ + \"static/media/information--highway-interchange--g1.247302e7.png\";","export default __webpack_public_path__ + \"static/media/information--highway-interstate-route--g1.692a691b.png\";","export default __webpack_public_path__ + \"static/media/information--highway-interstate-route--g2.accf6f1f.png\";","export default __webpack_public_path__ + \"static/media/information--highway-preferential-lane--g1.46a6e511.png\";","export default __webpack_public_path__ + \"static/media/information--highway-preferential-lane--g2.00aa828a.png\";","export default __webpack_public_path__ + \"static/media/information--highway-reference-location--g1.fd97a9dc.png\";","export default __webpack_public_path__ + \"static/media/information--highway-reference-location--g2.8a376ffd.png\";","export default __webpack_public_path__ + \"static/media/information--hiking--g1.e7ebd601.png\";","export default __webpack_public_path__ + \"static/media/information--hospital--g1.df445bc6.png\";","export default __webpack_public_path__ + \"static/media/information--hurricane-evacuation-route--g1.51f3af3c.png\";","export default __webpack_public_path__ + \"static/media/information--interstate-route--g1.970c0135.png\";","export default __webpack_public_path__ + \"static/media/information--lane-control-intersections--g1.7a491f54.png\";","export default __webpack_public_path__ + \"static/media/information--lane-control-left-turn--g1.b9518417.png\";","export default __webpack_public_path__ + \"static/media/information--lane-control-multiple-lanes--g1.ea69ae2c.png\";","export default __webpack_public_path__ + \"static/media/information--lane-control-multiple-lanes--g2.c56d8bde.png\";","export default __webpack_public_path__ + \"static/media/information--lane-control-right-turn--g1.5fa2157c.png\";","export default __webpack_public_path__ + \"static/media/information--limited-access-road--g1.10cc71f3.png\";","export default __webpack_public_path__ + \"static/media/information--litter-container--g1.08c4ff13.png\";","export default __webpack_public_path__ + \"static/media/information--living-street--g1.2147c93f.png\";","export default __webpack_public_path__ + \"static/media/information--living-street--g2.9e441868.png\";","export default __webpack_public_path__ + \"static/media/information--living-street--g3.25c4364f.png\";","export default __webpack_public_path__ + \"static/media/information--lodging--g1.b607f4af.png\";","export default __webpack_public_path__ + \"static/media/information--lodging--g2.22045613.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-10--g1.3b83bdd9.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-20--g1.b0190c7b.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-25--g1.4db75e5c.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-30--g1.23729b05.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-35--g1.6e07ff1c.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-40--g1.3414f977.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-50--g1.76ed27c6.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-60--g1.212570f9.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-70--g1.c8d65d5e.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-75--g1.4939a840.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-80--g1.a7714163.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-90--g1.0b274895.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-100--g1.7102a855.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-110--g1.633ec596.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-120--g1.bce2e4ca.png\";","export default __webpack_public_path__ + \"static/media/information--minimum-speed-130--g1.c5a36eb0.png\";","export default __webpack_public_path__ + \"static/media/information--motorway--g1.a94a8e76.png\";","export default __webpack_public_path__ + \"static/media/information--motorway-exit-ahead--g1.0691dc2f.png\";","export default __webpack_public_path__ + \"static/media/information--motorway-exit-ahead--g2.b8daa7b6.png\";","export default __webpack_public_path__ + \"static/media/information--motorway-exit-ahead--g3.8af9ebcc.png\";","export default __webpack_public_path__ + \"static/media/information--overtaking-allowed-heavy-good-vehicles--g1.39e05fa4.png\";","export default __webpack_public_path__ + \"static/media/information--parallel-parking--g1.c0d4c10a.png\";","export default __webpack_public_path__ + \"static/media/information--park-and-ride--g1.b750a298.png\";","export default __webpack_public_path__ + \"static/media/information--park-and-ride--g2.c953d0be.png\";","export default __webpack_public_path__ + \"static/media/information--parking--g1.df52d553.png\";","export default __webpack_public_path__ + \"static/media/information--parking--g2.87609a48.png\";","export default __webpack_public_path__ + \"static/media/information--parking--g3.7fd2c641.png\";","export default __webpack_public_path__ + \"static/media/information--parking--g4.09eab1e8.png\";","export default __webpack_public_path__ + \"static/media/information--parking--g5.37047c3d.png\";","export default __webpack_public_path__ + \"static/media/information--parking--g6.8b6482a2.png\";","export default __webpack_public_path__ + \"static/media/information--parking-area--g1.a2bc1b0f.png\";","export default __webpack_public_path__ + \"static/media/information--parking-with-restrictions--g1.55284b47.png\";","export default __webpack_public_path__ + \"static/media/information--pass-on-either-side--g1.5bd589b7.png\";","export default __webpack_public_path__ + \"static/media/information--passenger-loading-zone--g1.ab94bd58.png\";","export default __webpack_public_path__ + \"static/media/information--pedestrians-crossing--g1.c953e4e9.png\";","export default __webpack_public_path__ + \"static/media/information--pedestrians-crossing--g2.183ef6cc.png\";","export default __webpack_public_path__ + \"static/media/information--pedestrians-crossing--g3.39fc0c2e.png\";","export default __webpack_public_path__ + \"static/media/information--pedestrians-only--g4.6947b95d.png\";","export default __webpack_public_path__ + \"static/media/information--pedestrians-permitted--g1.5f6c67bf.png\";","export default __webpack_public_path__ + \"static/media/information--perpendicular-parking--g1.5c9b6826.png\";","export default __webpack_public_path__ + \"static/media/information--picnic-site--g1.6194592a.png\";","export default __webpack_public_path__ + \"static/media/information--playground--g1.300b5c9c.png\";","export default __webpack_public_path__ + \"static/media/information--recreational-vehicle-sanitary-station--g1.e0780834.png\";","export default __webpack_public_path__ + \"static/media/information--recycle-collection-center--g1.8a0f22c1.png\";","export default __webpack_public_path__ + \"static/media/information--rest-area--g1.23aa47b9.png\";","export default __webpack_public_path__ + \"static/media/information--road-bump--g1.59ac514a.png\";","export default __webpack_public_path__ + \"static/media/information--road-skating--g1.dbd17d5a.png\";","export default __webpack_public_path__ + \"static/media/information--safety-zone--g1.8bc0bf83.png\";","export default __webpack_public_path__ + \"static/media/information--safety-zone--g2.106d3366.png\";","export default __webpack_public_path__ + \"static/media/information--safety-zone--g3.82f31562.png\";","export default __webpack_public_path__ + \"static/media/information--shared-path-vehicles-and-motorcycles--g1.50a9ff18.png\";","export default __webpack_public_path__ + \"static/media/information--stairs--g1.71f0a107.png\";","export default __webpack_public_path__ + \"static/media/information--stairs--g2.17a18300.png\";","export default __webpack_public_path__ + \"static/media/information--stairs--g3.af1160fa.png\";","export default __webpack_public_path__ + \"static/media/information--stairs--g4.64156853.png\";","export default __webpack_public_path__ + \"static/media/information--stop-line--g1.e9808c91.png\";","export default __webpack_public_path__ + \"static/media/information--stop-permitted--g1.686135de.png\";","export default __webpack_public_path__ + \"static/media/information--street-name-one-line--g1.94494101.png\";","export default __webpack_public_path__ + \"static/media/information--street-name-three-lines--g1.80615ed6.png\";","export default __webpack_public_path__ + \"static/media/information--street-name-two-lines--g1.9fdf4282.png\";","export default __webpack_public_path__ + \"static/media/information--subway--g1.11a232ac.png\";","export default __webpack_public_path__ + \"static/media/information--telephone--g1.f3e76f2a.png\";","export default __webpack_public_path__ + \"static/media/information--telephone--g2.e30d7202.png\";","export default __webpack_public_path__ + \"static/media/information--telephone-device-for-the-deaf--g1.3dd43d70.png\";","export default __webpack_public_path__ + \"static/media/information--toll-station--g1.b1ef927a.png\";","export default __webpack_public_path__ + \"static/media/information--tourism-information--g1.e4c2c0fd.png\";","export default __webpack_public_path__ + \"static/media/information--tourist-attraction--g1.9aad0dc2.png\";","export default __webpack_public_path__ + \"static/media/information--traffic-merges-left--g1.3bc6a9de.png\";","export default __webpack_public_path__ + \"static/media/information--traffic-merges-right--g1.53636e9b.png\";","export default __webpack_public_path__ + \"static/media/information--trail-crossing--g1.65ee67cc.png\";","export default __webpack_public_path__ + \"static/media/information--trail-crossing--g2.9e0a8068.png\";","export default __webpack_public_path__ + \"static/media/information--trail-crossing--g3.9ee9d069.png\";","export default __webpack_public_path__ + \"static/media/information--trailer-camping--g1.742fd848.png\";","export default __webpack_public_path__ + \"static/media/information--train-or-light-rail-station--g1.1137babb.png\";","export default __webpack_public_path__ + \"static/media/information--tram-bus-stop--g1.840fc7f4.png\";","export default __webpack_public_path__ + \"static/media/information--tram-bus-stop--g2.742fb913.png\";","export default __webpack_public_path__ + \"static/media/information--trams-crossing--g1.a0f36a2d.png\";","export default __webpack_public_path__ + \"static/media/information--truck-lane-left--g1.c1c84eec.png\";","export default __webpack_public_path__ + \"static/media/information--truck-parking--g1.344e6e89.png\";","export default __webpack_public_path__ + \"static/media/information--truck-trailer-lane-right--g1.78d4967c.png\";","export default __webpack_public_path__ + \"static/media/information--truck-trailer-lane-straight--g1.5347b556.png\";","export default __webpack_public_path__ + \"static/media/information--trucks-both-ways--g1.e3ecbd84.png\";","export default __webpack_public_path__ + \"static/media/information--trucks-only--g1.979028f2.png\";","export default __webpack_public_path__ + \"static/media/information--tsunami-evacuation_route--g1.7ae34865.png\";","export default __webpack_public_path__ + \"static/media/information--tunnel--g1.03be4883.png\";","export default __webpack_public_path__ + \"static/media/information--tunnel--g2.7b559e17.png\";","export default __webpack_public_path__ + \"static/media/information--tunnel--g3.d2ceeebb.png\";","export default __webpack_public_path__ + \"static/media/information--tunnel-ahead--g1.546aa975.png\";","export default __webpack_public_path__ + \"static/media/information--turn-left--g1.f8929d0b.png\";","export default __webpack_public_path__ + \"static/media/information--turn-left-ahead--g1.1f03050a.png\";","export default __webpack_public_path__ + \"static/media/information--turn-right--g1.eb673195.png\";","export default __webpack_public_path__ + \"static/media/information--turn-right-ahead--g1.35a96c2a.png\";","export default __webpack_public_path__ + \"static/media/information--urban-area--g1.6b606baf.png\";","export default __webpack_public_path__ + \"static/media/information--vehicles-on-rails--g1.4a371ce8.png\";","export default __webpack_public_path__ + \"static/media/information--water-protection-zone--g1.44b0f53a.png\";","export default __webpack_public_path__ + \"static/media/information--weight-and-height-limit--g1.bc56d483.png\";","export default __webpack_public_path__ + \"static/media/information--weight-limit--g1.20f54728.png\";","export default __webpack_public_path__ + \"static/media/information--wireless-internet--g1.75122a71.png\";","export default __webpack_public_path__ + \"static/media/regulatory--advisory-maximum-speed-limit--g1.86b85613.png\";","export default __webpack_public_path__ + \"static/media/regulatory--all-directions-permitted--g1.e567ddaa.png\";","export default __webpack_public_path__ + \"static/media/regulatory--all-way--g1.1a3b2b2a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--atvs-permitted--g1.d5fe6ec3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--axle-limit--g1.8eb43884.png\";","export default __webpack_public_path__ + \"static/media/regulatory--axle-limit--g2.3974d220.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycle-lane-left--g1.4ca4b400.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycle-parking--g1.16ba1f72.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-and-buses-only--g1.148faf66.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-only--g1.440e2032.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-only--g2.1e88f01e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-only--g3.bcfb72cc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-only--g4.0de1b0cb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-push-button--g1.1364f84e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-push-button--g2.e86fdf7f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-stop-on-red--g1.1cda5add.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-wrong-way--g1.135ae71c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bicycles-yield-or-use-signal--g1.1f65e157.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bike-route--g1.10d044ee.png\";","export default __webpack_public_path__ + \"static/media/regulatory--building-direction--g1.fc70d3c5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--bus-priority-lane--g1.2ae10a51.png\";","export default __webpack_public_path__ + \"static/media/regulatory--buses-and-taxi-only--g1.b3d80414.png\";","export default __webpack_public_path__ + \"static/media/regulatory--buses-only--g1.5305590b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--buses-only--g2.38b5f21e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--circular-intersection--g1.e8f98101.png\";","export default __webpack_public_path__ + \"static/media/regulatory--circular-intersection--g2.364f2ae2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--circular-intersection--g3.08fdea2e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--circular-intersection--g4.daf2c245.png\";","export default __webpack_public_path__ + \"static/media/regulatory--cross-only-on-green--g1.1f626d4e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--cross-only-on-pedestrian-signal--g1.a36a6a28.png\";","export default __webpack_public_path__ + \"static/media/regulatory--crosswalk-stop-on-red--g1.39942771.png\";","export default __webpack_public_path__ + \"static/media/regulatory--cycling-restriction--g1.1b19c2a9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--cyclists-dismount-and-walk--g1.85523214.png\";","export default __webpack_public_path__ + \"static/media/regulatory--detour-left--g1.65da6dd7.png\";","export default __webpack_public_path__ + \"static/media/regulatory--detour-right--g1.ad60dd21.png\";","export default __webpack_public_path__ + \"static/media/regulatory--divided-highway-crossing--g1.f45cc71a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--divided-highway-ends--g1.c6006e84.png\";","export default __webpack_public_path__ + \"static/media/regulatory--divided-highway-starts--g1.846d4a16.png\";","export default __webpack_public_path__ + \"static/media/regulatory--do-not-block-intersection--g1.18bccc47.png\";","export default __webpack_public_path__ + \"static/media/regulatory--do-not-pass--g1.7f484967.png\";","export default __webpack_public_path__ + \"static/media/regulatory--do-not-stop-on-tracks--g1.f252110f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-all-directions-on-left--g1.39024df2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-all-directions-on-right--g1.25fcfc3e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-bicyclists-and-pedestrians--g1.b3dad17b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-go-left-or-right--g1.20dace34.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-go-straight-on-left--g1.644f5631.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-go-straight-on-right--g1.a4728fe2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-turn-left--g1.27ff5c95.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-turn-left-no-u-turn--g1.e566a2e4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-turn-left-or-straight--g1.042176f8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-lanes-turn-right-or-straight--g1.bb64e50c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-bicycles-and-pedestrians--g1.02ec2d5e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-bicycles-and-pedestrians--g2.5c75e267.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-bicycles-and-pedestrians--g3.4194fc44.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-equestrians-and-pedestrians--g1.5c1b32ad.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-equestrians-and-pedestrians-bicycles--g1.2c4013b0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-pedestrians-and-bicycles--g1.4dad084e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-pedestrians-and-bicycles--g2.5ffa4776.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-pedestrians-and-equestrians--g1.02f7d7a1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-path-pedestrians-bicycles-and-equestrians--g1.44369e6c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-speed-limits--g1.6752afbb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--dual-speed-limits--g2.4ac2d6f3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-bicycles-only--g1.afcf1e7b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-bicycles-only--g2.097b77a9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-bus-and-taxi-only--g1.95ed8ca1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-buses-only--g1.0201ae54.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-buses-only--g2.5f50ea96.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-cycling-restriction--g1.7b7df3dd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-dual-path-bicycles-and-pedestrians--g1.26b235af.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-dual-path-pedestrians-and-bicycles--g1.23e796cf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-equestrians-only--g1.0a1542f3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-low-beam-headlights--g1.91c69fc1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-10--g1.5ac21e5b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-10--g2.8db154ac.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-20--g1.7024c379.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-20--g2.ff6c8dc5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-25--g1.75e6cd18.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-25--g2.3fc08b6f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-30--g1.eb45f997.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-30--g2.bb4809fd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-35--g1.5f8ce558.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-35--g2.8d261d69.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-40--g1.85c54762.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-40--g2.c378a358.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-50--g1.8a58a37b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-50--g2.32f875a5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-60--g1.2f34a92d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-60--g2.0632d23d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-65--g1.b14098fd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-65--g2.a5254cbb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-70--g1.9fb8a3e9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-70--g2.a93c14f1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-75--g1.9d1b9782.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-75--g2.a0124c7a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-80--g1.8e331512.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-80--g2.e45f6301.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-90--g1.f7dbc484.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-90--g2.8c5d1def.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-100--g1.10cc7dd9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-100--g2.d22c2e70.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-110--g1.7c47334c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-110--g2.3a94b5b1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-120--g1.47e0a468.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-120--g2.ba84c756.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-130--g1.3edebaf2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit-130--g2.28b38021.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-maximum-speed-limit--g1.008d8f7c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-mopeds-and-bicycles-only--g1.b669ee49.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-heavy-goods-vehicles--g1.11347c2b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-horn--g1.38488514.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking--g1.f711db78.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking--g2.da883c93.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking--g3.66135c03.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking--g4.11329ed0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking--g5.4aa03694.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g1.ff79e44a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g2.16e2a814.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-overtaking-by-motorcycles--g1.a23aae0c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-parking--g1.c771dc80.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-parking--g2.8c4dba58.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-no-parking-or-stopping--g1.9448279b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-one-way-straight--g1.2ed363d3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-parking-zone--g1.cfb44d95.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-parking-zone--g2.96af1a66.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-pedestrians-only--g1.3091680c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-pedestrians-only--g2.55157960.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-pedestrians-only--g3.afe96de1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-pedestrians-only--g4.74b84e48.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-priority-road--g1.12c706be.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-prohibition--g1.24827b34.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-school-zone--g1.f865537a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-shared-path-bicycles-and-pedestrians--g1.f9807b65.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-shared-path-pedestrians-and-bicycles--g1.04370a0f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-snow-chains--g1.5a7931f2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-snow-chains--g2.7382850a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-snowmobiles-only--g1.d682bc63.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-speed-limit-zone--g1.15e8b883.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-speed-limit-zone--g2.300add15.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-speed-limit-zone--g3.a50f1e4d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-tractors-only--g1.bbb8849f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-trams-and-buses-only--g1.25dd9871.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-trams-only--g1.85ec27f9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-trucks-and-buses-only--g1.8a6ab26d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-trucks-only--g1.3dcb28f4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--end-of-trucks-only--g2.4e55b939.png\";","export default __webpack_public_path__ + \"static/media/regulatory--equestrians-only--g1.d64c6020.png\";","export default __webpack_public_path__ + \"static/media/regulatory--except-railroad-crossing--g1.eacd41fa.png\";","export default __webpack_public_path__ + \"static/media/regulatory--fine-for-littering--g1.dfa21d74.png\";","export default __webpack_public_path__ + \"static/media/regulatory--give-way-to-bicycles--g1.c339dedb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--give-way-to-oncoming-traffic--g1.d53ac85f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--give-way-to-oncoming-traffic--g2.51aed85b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-left-bicycles--g1.912457bf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-right-bicycles--g1.51e745f5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight--g1.ed3c15a6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight--g3.478e2d96.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-bicycles--g1.d41deae5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-or-turn-left--g1.78963e27.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-or-turn-left--g2.ad96042c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-or-turn-left--g3.5536a26a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-or-turn-right--g1.f11738ef.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-or-turn-right--g2.75a12caf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--go-straight-or-turn-right--g3.dcac6907.png\";","export default __webpack_public_path__ + \"static/media/regulatory--heavy-goods-vehicles-permitted--g1.9cdb128c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--height-limit--g1.98af1a7f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--high-beam-headlights--g1.e09c5b20.png\";","export default __webpack_public_path__ + \"static/media/regulatory--horn--g1.77ed51fc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--in-street-pedestrian-crossing--g1.e30c31dd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g1.679b6bd3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g2.c7dbfe8e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g3.8d435d1e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g4.0a18f6ba.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g5.83797d4a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g6.7c4481c4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-left--g7.8a94453c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g1.0a5be37f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g2.26ef1c48.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g3.0bf791e6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g4.cac2f808.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g5.f2e202d8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g6.3f2cfd3a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g7.102f84fe.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g8.2f374fc8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--keep-right--g9.19cca104.png\";","export default __webpack_public_path__ + \"static/media/regulatory--lane-control--g1.ebf113b6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--left-turn-yield-on-green--g1.103fabdc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--length-limit--g1.e26aac53.png\";","export default __webpack_public_path__ + \"static/media/regulatory--length-limit--g2.8ef7d18d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--light-rail-divided-highway--g1.db3927c2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--light-rail-do-not-pass--g1.a6efedce.png\";","export default __webpack_public_path__ + \"static/media/regulatory--light-rail-only--g1.254cad9a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--look--g1.25116d7f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--low-beam-headlights--g1.f0dfd718.png\";","export default __webpack_public_path__ + \"static/media/regulatory--low-beam-headlights--g2.d3ac6fa0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--low-beam-headlights--g3.27cdd23a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--low-speed-vehicle-permitted--g1.30c92b2d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-5--g1.12cfb1dc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-5--g3.206e7744.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-10--g1.f5f022da.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-10--g3.483cdc98.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-15--g1.c0560e73.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-15--g3.c766b7e0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-20--g1.3fb8b849.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-20--g3.f2750244.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-25--g1.00b372a9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-25--g2.3651694f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-30--g1.957a1971.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-30--g3.f035f7be.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-35--g1.176ca1fe.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-35--g2.bb66847f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-40--g1.44aeea27.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-40--g3.96779eaf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-45--g1.908b0551.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-45--g3.aafdb64d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-50--g1.265cb52e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-50--g3.f7bdf367.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-55--g2.112a3663.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-60--g1.ea23c09b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-60--g3.a3ea0058.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-65--g1.3903f621.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-65--g2.bb77e2c1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-70--g1.1896271e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-70--g3.b28c86fe.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-75--g2.1b34ed25.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-80--g1.a5644650.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-80--g3.026ebd10.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-85--g2.8c86c640.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-90--g1.bd9729a9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-90--g3.0b6fd891.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-100--g1.eeb7acc1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-100--g3.cdf80f0f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-110--g1.09c32e32.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-110--g3.bad7b480.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-120--g1.343b1010.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-120--g3.546873db.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-130--g1.7ffeb59e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-130--g3.bf38e05c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-5--g2.ebce1f01.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-5--g3.3af8efb4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-10--g1.8a5c0115.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-10--g2.ad5f7d90.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-10--g3.a82bcf90.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-15--g2.aca06df6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-15--g3.53994d0a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-20--g1.af9e4293.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-20--g2.9e88edec.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-20--g3.11d7d1c0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-25--g1.cc37b6a2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-25--g2.9a69ae6f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-25--g3.f1b81b62.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-30--g1.bba5d38c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-30--g2.24d963f4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-30--g3.62f401a5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-35--g1.45228792.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-35--g2.95331a23.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-35--g3.ad302825.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-40--g1.580d8dba.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-40--g2.ef8144ed.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-40--g3.40ecba48.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-45--g2.f41b3db9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-45--g3.62b6fde1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-50--g1.4657ea06.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-50--g2.b09b7508.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-50--g3.0aa73207.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-55--g2.7d194fac.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-55--g3.ed0a2e22.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-60--g1.58e5908a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-60--g2.aed4f160.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-60--g3.ea9c8fdb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-65--g2.54e6c1f0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-65--g3.4792115d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-70--g1.aa082679.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-70--g2.84465687.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-70--g3.ff4bfb81.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-75--g1.96dc879a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-75--g2.62c37706.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-75--g3.77267ab5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-80--g1.49dbc461.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-80--g2.7377246c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-80--g3.b35b5a61.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-85--g2.6c4b570d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-85--g3.d67b71de.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-90--g1.be1d5ec8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-100--g1.208820d6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-110--g1.2a1a5bb0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-120--g1.f5162198.png\";","export default __webpack_public_path__ + \"static/media/regulatory--maximum-speed-limit-led-130--g1.ab836ce5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--minimum-safe-distance--g1.e2f1a969.png\";","export default __webpack_public_path__ + \"static/media/regulatory--minimum-safe-distance--g2.f81b7cf1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--mopeds-and-bicycles-only--g1.6a32c318.png\";","export default __webpack_public_path__ + \"static/media/regulatory--motorcycles-and-bicycles-only--g1.5be11f05.png\";","export default __webpack_public_path__ + \"static/media/regulatory--motorcycles-only--g1.3599617f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--motorcycles-only--g2.1e5763c9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-5--g1.2d471622.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-10--g1.e49f6633.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-15--g1.74d7f0eb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-20--g1.e923f062.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-25--g1.1eee3953.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-30--g1.de686fba.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-35--g1.3a039535.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-40--g1.ed13d478.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-45--g1.13e9c312.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-50--g1.f36e3f30.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-55--g1.eda1a245.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-60--g1.d401082f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-65--g1.b036b665.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-70--g1.5dbee8eb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-75--g1.02809bff.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-80--g1.60f65bd6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--night-speed-limit-85--g1.bfca22ba.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-abnormal-vehicles--g1.9a1ba76a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-atvs--g1.351b1213.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles--g1.fbfdb4d6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles--g2.10ba3fba.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles--g3.aef27aee.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles-carts-or-hand-carts--g1.0980edb5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles-mopeds-or-motorcycles--g1.6deac529.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles-mopeds-or-motorcycles--g2.47379579.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles-or-hand-carts--g1.b307cb32.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles-or-motorcycles--g1.115b2e72.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-bicycles-tractors-or-carts--g1.c9248372.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-buses--g1.67236178.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-buses--g2.579a2458.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-buses--g3.6b590d19.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-caravan-trailers--g1.f42a260f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-caravans--g1.941fa0cc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-caravans-or-caravan-trailers--g1.ee733d20.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-cargo-loading--g1.1b0eeb2b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-carts--g1.928af1c6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-carts--g2.b6f19e6f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-carts--g3.74460970.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-carts-or-tractors--g1.9d3bbf40.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-construction-vehicles--g1.28ffa65d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-entry--g1.c657fa8f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-equestrians--g1.81627a3a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-go-straight-or-turn-left--g1.ba71ea9f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-go-straight-or-turn-right--g1.bf8a6fa3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-good-trailers--g2.bad20402.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-goods-vehicle-trailers--g1.764e3efc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-hand-carts--g1.7e3449ab.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-hand-carts--g2.19c3e969.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-hand-carts-or-bicycles--g1.0279d73d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-hawkers--g1.1e14d7e1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles--g1.8a560f33.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles--g2.9fff7565.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles--g3.91da44ae.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles--g4.216491f1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles--g5.959f1c6d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g1.37078248.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g2.2e3a18ee.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles-or-buses--g1.05787c73.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles-or-tractors--g1.a3d74207.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-heavy-goods-vehicles-or-trailers--g1.0e4821b9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-horizontal-turn--g1.ab7eda4b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-horn--g1.2695a31e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-horn--g2.5841efbd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-lane-change-to-left--g1.c3b5e313.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-lane-change-to-right--g1.65211254.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-learner-drivers--g1.3ebd3c5a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-left-or-u-turn--g1.b309afb9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-left-turn--g1.b330753f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-left-turn--g2.3a06039e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-left-turn--g3.34218609.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-left-turn--g4.f2416352.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-left-turn--g5.c53c6486.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-low-speed-vehicles--g1.4b08326a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-mopeds-or-bicycles--g1.72ce756c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicle-trailers--g1.db1f891e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles--g1.2bd757f6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles--g3.b3120ac6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles--g4.5e81bd00.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles--g5.d88792f9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles--g6.44fb91e7.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles--g7.2c8ec64f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles-except-motorcycles--g1.5af55863.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles-except-motorcycles--g2.7d175930.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles-except-motorcycles--g3.a4448c41.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles-or-bicycles--g1.317ebe25.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles-or-buses--g1.8e58f8bf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motor-vehicles-or-carts--g1.39349e1f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motorcycles--g1.f9dc81e3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-motorcycles--g2.65414d33.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking--g1.d876c125.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking--g2.2b83574c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking--g4.22b05cd4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking--g5.6b8e21fc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking--g6.dc77c0cd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking--g7.30b8ee6b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking-atvs--g1.6dd58589.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-overtaking-by-heavy-goods-vehicles--g1.f97c589c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g1.4ca5a89f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g2.a3c63e81.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g3.ced5e03c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g4.4c779b9c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g5.48af12a8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g6.6db7b740.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g7.da720b8d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g8.8a640aed.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking--g9.b969233b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-bicycles-or-motorcycles--g1.932ed75c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-bus-stop--g1.d790c322.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-or-no-stopping--g1.32cc0e7c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-or-no-stopping--g2.cbe40936.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-or-no-stopping--g3.f817e11a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-or-no-stopping--g4.8a3143db.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-parking-or-no-stopping--g5.c5a471d8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-passenger-loading--g1.9272ff3b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians--g1.654534fc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians--g2.c1cbab61.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians--g3.db9ef7ad.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians--g4.7f4a3d27.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians--g5.02c0c663.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians--g6.4d3714e7.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians-bicycles-animals-or-hand-carts--g1.e4fc9208.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians-or-bicycles--g1.4a8441a7.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians-or-bicycles--g2.0366930c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-pedestrians-or-bicycles--g3.426675bf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-rickshaws--g1.fc782f2c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-rickshaws--g2.61c13947.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-rickshaws--g3.ac5bec9d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-right-turn--g1.6e467745.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-right-turn--g2.97edc91d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-right-turn--g3.63dc1b44.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-right-turn-on-red--g1.f6ea7f5c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-skiing--g1.655b7641.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-snowmobiles--g1.cfa8001f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-snowmobiles--g2.2e3d9be1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-snowmobiles-or-atvs--g1.1bf91012.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping--g1.4fd0a542.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping--g2.22eabfcc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping--g3.60647b5f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping--g5.9c7f0f1e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping--g6.a5c23b68.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping--g7.349246a0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-stopping-on-pavement--g1.4ad4966b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-straight-through--g1.6fe4bf6d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-straight-through--g2.9e890383.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-studded-snow-chains--g1.788d151e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-through-trucks--g1.bad0c928.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-tour-buses--g1.fa7322d5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-tractors--g1.a2437580.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-tractors-mopeds-or-bicycles--g1.102563a8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-tractors-or-carts--g1.3829cc65.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-trailers--g1.309aba75.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-tricycles--g1.fa034d03.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-tricycles-or-hand-carts--g1.eafc4e68.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-turn-on-red--g1.d126fe1a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-turn-on-red--g2.b82499bd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-turn-on-red--g3.9040df5f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-turns--g1.32fc69c3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-turns--g2.0414b2fe.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-two-stage-right-turn-for-mopeds--g1.6b816a0e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-u-turn--g1.18b5ecf1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-u-turn--g2.7911ab30.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-u-turn--g3.d7392ba4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-dangerous-goods--g1.794908c9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-dangerous-goods--g2.b8c733f6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-dangerous-goods--g3.eed2c264.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-dangerous-goods--g4.5511e61f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-dangerous-water-pollutants--g1.988e8514.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-dangerous-water-pollutants--g2.93eebcbf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-explosives--g1.0565ddd2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--no-vehicles-carrying-explosives-or-dangerous-water-pollutants--g1.7a3c82c6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-left--g1.b090ec6f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-left--g2.50ea813a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-left--g3.0113405a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-right--g1.791c0a85.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-right--g2.8585b78c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-right--g3.9cdca710.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-straight--g1.47ea933f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--one-way-straight--g3.01f68d4b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--parking-fee-station--g1.70710155.png\";","export default __webpack_public_path__ + \"static/media/regulatory--parking-restrictions--g1.2b92b8a8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--parking-restrictions--g2.231db037.png\";","export default __webpack_public_path__ + \"static/media/regulatory--parking-restrictions--g3.4e6ef760.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pass-on-either-side--g1.ff7956d3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pass-on-either-side--g2.9dec1fee.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pass-on-either-side--g3.d1ffedcd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pass-with-care--g1.75f3b466.png\";","export default __webpack_public_path__ + \"static/media/regulatory--passing-lane-ahead--g1.f3e273fd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-bicycles-permitted--g1.3d105bf0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-keep-left--g1.674c2d80.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-only--g1.1fc71024.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-only--g2.4bfe3f3f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-only--g3.76d6977a.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-priority-zone--g1.a5b6727e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-push-button--g1.4e8319dc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--pedestrians-push-button--g2.fcfd976d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--priority-over-oncoming-vehicles--g1.db6faf10.png\";","export default __webpack_public_path__ + \"static/media/regulatory--priority-over-oncoming-vehicles--g2.7de31d11.png\";","export default __webpack_public_path__ + \"static/media/regulatory--priority-road--g1.a9c3ba8b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--priority-road--g2.922fe884.png\";","export default __webpack_public_path__ + \"static/media/regulatory--radar-enforced--g1.d785a081.png\";","export default __webpack_public_path__ + \"static/media/regulatory--reserved-parking--g1.3ad03559.png\";","export default __webpack_public_path__ + \"static/media/regulatory--reversible-lanes--g1.9fb06219.png\";","export default __webpack_public_path__ + \"static/media/regulatory--reversible-lanes--g2.969c0d44.png\";","export default __webpack_public_path__ + \"static/media/regulatory--road-closed--g1.9e903e6d.png\";","export default __webpack_public_path__ + \"static/media/regulatory--road-closed--g2.dda11416.png\";","export default __webpack_public_path__ + \"static/media/regulatory--road-closed-to-vehicles--g1.dca51279.png\";","export default __webpack_public_path__ + \"static/media/regulatory--road-closed-to-vehicles--g3.b3970891.png\";","export default __webpack_public_path__ + \"static/media/regulatory--roundabout--g1.8433aefc.png\";","export default __webpack_public_path__ + \"static/media/regulatory--roundabout--g2.50727331.png\";","export default __webpack_public_path__ + \"static/media/regulatory--roundabout--g3.2d0882dd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--shared-path-bicycles-and-pedestrians--g1.72464b6b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--shared-path-pedestrians-and-bicycles--g1.bf20db10.png\";","export default __webpack_public_path__ + \"static/media/regulatory--sidewalk-closed--g1.e4dd968e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--slanted-parking--g1.2c69ce1c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--snow-chains--g1.a656672c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--snow-chains--g2.84dc0228.png\";","export default __webpack_public_path__ + \"static/media/regulatory--snow-chains--g3.a156dd58.png\";","export default __webpack_public_path__ + \"static/media/regulatory--snowmobiles-only--g1.1dde78d9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--snowmobiles-permitted--g1.27015a7f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--speed-limit-zone--g1.981aeede.png\";","export default __webpack_public_path__ + \"static/media/regulatory--speeding-fines-increased--g1.31b9fc1b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--state-route--g1.721042d7.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stay-in-lane--g1.56d686b0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g1.7d97baab.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g2.483334d1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g3.4d1e72e1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g4.ee770dce.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g5.2a819d8f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g6.de739f11.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g7.9490caa4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g8.722f4b38.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g9.06825e07.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop--g10.505ed820.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop-here-on-red-or-flashing-light--g1.2e18bf3f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop-here-on-red-or-flashing-light--g2.1407c908.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop-signals--g1.9b8c0d01.png\";","export default __webpack_public_path__ + \"static/media/regulatory--stop-signals--g2.7cea9e75.png\";","export default __webpack_public_path__ + \"static/media/regulatory--tanks-only--g1.46e2c223.png\";","export default __webpack_public_path__ + \"static/media/regulatory--taxi-only--g1.77097a52.png\";","export default __webpack_public_path__ + \"static/media/regulatory--text--g1.14bfe577.png\";","export default __webpack_public_path__ + \"static/media/regulatory--text--g2.12b5de42.png\";","export default __webpack_public_path__ + \"static/media/regulatory--toll-pass-only--g1.971da401.png\";","export default __webpack_public_path__ + \"static/media/regulatory--tractors-only--g1.ea2f343e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--traffic-signal-photo-enforced--g1.f6a31551.png\";","export default __webpack_public_path__ + \"static/media/regulatory--trams-and-buses-only--g1.9d082cd5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--trams-only--g1.5a5684c6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--triple-lanes--g1.5f11c2cf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--triple-lanes-go-straight-center-lane--g1.e11d6237.png\";","export default __webpack_public_path__ + \"static/media/regulatory--triple-lanes-turn-left-center-lane--g1.e4a2f108.png\";","export default __webpack_public_path__ + \"static/media/regulatory--triple-lanes-turn-right-center-lane--g1.d4df745b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-route--g1.630b0b24.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-5--g1.29df11b6.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-10--g1.e7d67cd1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-15--g1.f67bb65f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-20--g1.d81afa41.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-25--g1.96be34eb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-30--g1.9df85672.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-35--g1.9a883455.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-40--g1.9800dbf8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-45--g1.69fdca3f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-50--g1.70f43e41.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-55--g1.1656c6f2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-60--g1.d6cf88aa.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-65--g1.b46b4bbd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-70--g1.b20a87d2.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-75--g1.d658980b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-80--g1.c243996e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--truck-speed-limit-85--g1.6125756c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--trucks-and-buses-only--g1.a55e77aa.png\";","export default __webpack_public_path__ + \"static/media/regulatory--trucks-on-right--g1.5ad11e57.png\";","export default __webpack_public_path__ + \"static/media/regulatory--trucks-only--g1.2caa4b16.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left--g1.12ef941b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left--g2.01af6a90.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left--g3.7a1a0373.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left-ahead--g1.35b3766c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left-ahead--g2.fd4eb44f.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left-or-right--g1.89ad6968.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left-or-right--g2.6eca1c7b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left-or-right--g3.0bee4d0c.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-left-or-u-turn--g1.8f5028c9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-right--g1.8b3bf63e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-right--g2.bfc39dfd.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-right--g3.1d726512.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-right-ahead--g1.76f304e8.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turn-right-ahead--g2.7774ded9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--turning-vehicles-yield-to-pedestrians--g1.99692a47.png\";","export default __webpack_public_path__ + \"static/media/regulatory--two-stage-right-turn-for-mopeds--g1.8d55bffb.png\";","export default __webpack_public_path__ + \"static/media/regulatory--two-way--g1.b64bf0c5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--u-turn--g1.c3a04a95.png\";","export default __webpack_public_path__ + \"static/media/regulatory--u-turn--g2.4e33c845.png\";","export default __webpack_public_path__ + \"static/media/regulatory--u-turn--g3.9d07cd2e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--use-crosswalk--g1.4941d3c3.png\";","export default __webpack_public_path__ + \"static/media/regulatory--vehicles-carrying-dangerous-goods-only--g1.3a569021.png\";","export default __webpack_public_path__ + \"static/media/regulatory--vehicles-carrying-dangerous-goods-permitted--g1.41785cc4.png\";","export default __webpack_public_path__ + \"static/media/regulatory--vehicles-carrying-explosives-only--g1.1ecbe4c0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--vehicles-carrying-hazardous-goods-permitted--g1.e45be8b9.png\";","export default __webpack_public_path__ + \"static/media/regulatory--vehicles-only--g1.de6ad106.png\";","export default __webpack_public_path__ + \"static/media/regulatory--wear-seat-belt--g1.f47a44cf.png\";","export default __webpack_public_path__ + \"static/media/regulatory--wear-seat-belt--g2.f386bc69.png\";","export default __webpack_public_path__ + \"static/media/regulatory--wear-seat-belt--g3.4cdb1888.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g1.817038a1.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g2.e1500a68.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g3.19d1b90e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g4.0d1fcb42.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g5.71d3ad85.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g6.c9ce9e57.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit--g7.11b45bd0.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit-per-axle--g1.d05b072b.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit-per-tandem-axle--g1.e1fb3ce7.png\";","export default __webpack_public_path__ + \"static/media/regulatory--weight-limit-with-trucks--g1.c0fc507e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--width-limit--g1.e94fb0a5.png\";","export default __webpack_public_path__ + \"static/media/regulatory--wrong-way--g1.4c1aec61.png\";","export default __webpack_public_path__ + \"static/media/regulatory--yield--g1.00724e2e.png\";","export default __webpack_public_path__ + \"static/media/regulatory--yield-or-stop-for-pedestrians--g1.bf8555de.png\";","export default __webpack_public_path__ + \"static/media/regulatory--your-speed--g1.354c97cb.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g1.a6065411.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g2.20400c8d.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g3.8f08b131.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g4.e39b418a.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g5.78034bb3.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g6.271d6630.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g7.7f6c0b7f.png\";","export default __webpack_public_path__ + \"static/media/warning--accident-area--g8.a06f3807.png\";","export default __webpack_public_path__ + \"static/media/warning--added-lane-from-entering-roadway--g1.bbd50002.png\";","export default __webpack_public_path__ + \"static/media/warning--added-lane-from-entering-roadway--g2.6c2e69cb.png\";","export default __webpack_public_path__ + \"static/media/warning--added-lane-left--g1.a8c7833e.png\";","export default __webpack_public_path__ + \"static/media/warning--added-lane-right--g1.d5032345.png\";","export default __webpack_public_path__ + \"static/media/warning--animal-drawn-vehicles--g1.38f47feb.png\";","export default __webpack_public_path__ + \"static/media/warning--arch-bridge--g1.5cc463ff.png\";","export default __webpack_public_path__ + \"static/media/warning--atv-and-snowmobiles--g1.6e6cfa37.png\";","export default __webpack_public_path__ + \"static/media/warning--atv-crossing--g1.627f932d.png\";","export default __webpack_public_path__ + \"static/media/warning--atv-crossing--g2.4048703b.png\";","export default __webpack_public_path__ + \"static/media/warning--axle-restriction--g1.37ac1b3c.png\";","export default __webpack_public_path__ + \"static/media/warning--bear-crossing--g1.5e1d24c8.png\";","export default __webpack_public_path__ + \"static/media/warning--bear-crossing--g2.cddc2568.png\";","export default __webpack_public_path__ + \"static/media/warning--bicycles-and-others--g1.64fe6c90.png\";","export default __webpack_public_path__ + \"static/media/warning--bicycles-caution-on-rail-tracks--g1.24127b37.png\";","export default __webpack_public_path__ + \"static/media/warning--bicycles-crossing--g1.742a95b5.png\";","export default __webpack_public_path__ + \"static/media/warning--bicycles-crossing--g2.aef0fc8a.png\";","export default __webpack_public_path__ + \"static/media/warning--bicycles-crossing--g3.6f7cbdff.png\";","export default __webpack_public_path__ + \"static/media/warning--bicycles-crossing--g4.bc459af3.png\";","export default __webpack_public_path__ + \"static/media/warning--bollard--g1.92dd9345.png\";","export default __webpack_public_path__ + \"static/media/warning--bridge--g1.5beed47f.png\";","export default __webpack_public_path__ + \"static/media/warning--bridge--g2.be0cc144.png\";","export default __webpack_public_path__ + \"static/media/warning--bus-stop-ahead--g1.d2042d63.png\";","export default __webpack_public_path__ + \"static/media/warning--bus-stop-ahead--g2.7fa78816.png\";","export default __webpack_public_path__ + \"static/media/warning--bus-stop-ahead--g3.0a2abcae.png\";","export default __webpack_public_path__ + \"static/media/warning--camel-crossing--g1.0fc63ebb.png\";","export default __webpack_public_path__ + \"static/media/warning--camel-crossing--g2.fe1abca3.png\";","export default __webpack_public_path__ + \"static/media/warning--camera--g1.97e5cab0.png\";","export default __webpack_public_path__ + \"static/media/warning--camera--g2.bf3bf685.png\";","export default __webpack_public_path__ + \"static/media/warning--carts--g1.2088f796.png\";","export default __webpack_public_path__ + \"static/media/warning--carts--g2.0188153d.png\";","export default __webpack_public_path__ + \"static/media/warning--checkpoint--g1.ee5447d8.png\";","export default __webpack_public_path__ + \"static/media/warning--children--g1.be722cbc.png\";","export default __webpack_public_path__ + \"static/media/warning--children--g2.802736a3.png\";","export default __webpack_public_path__ + \"static/media/warning--children--g3.7d28f751.png\";","export default __webpack_public_path__ + \"static/media/warning--children--g4.1e204dc8.png\";","export default __webpack_public_path__ + \"static/media/warning--children--g6.52ca9670.png\";","export default __webpack_public_path__ + \"static/media/warning--cliff--g1.a5923913.png\";","export default __webpack_public_path__ + \"static/media/warning--cliff--g2.b11bf115.png\";","export default __webpack_public_path__ + \"static/media/warning--closed-lane-in-triple-lanes--g1.5e11cdf9.png\";","export default __webpack_public_path__ + \"static/media/warning--closed-lane-in-triple-lanes--g2.478e5f17.png\";","export default __webpack_public_path__ + \"static/media/warning--construction-ahead--g1.c57e1e5e.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads--g1.14d61769.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads--g2.d93cf962.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads--g3.522ca193.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads--g4.1280a5a4.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads--g5.0af73743.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads--g6.50b62775.png\";","export default __webpack_public_path__ + \"static/media/warning--crossroads-with-priority-to-the-right--g1.7597a71a.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-left--g1.fc958342.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-left--g2.1b916c62.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-left--g3.a2b64322.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-left-with-junction--g1.0bd6a7a9.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-out-intersection-left--g1.e1afa97c.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-out-intersection-right--g1.b5a17894.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-right--g1.e03eb082.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-right--g2.b7f5e2a8.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-right--g3.9f2c56e1.png\";","export default __webpack_public_path__ + \"static/media/warning--curve-right-with-junction--g1.a3d85594.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-left--g1.4728c562.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-left--g2.c8bf2f3a.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-left--g4.69cf0606.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-right--g1.ab4c438d.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-right--g2.040eb808.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-right--g3.74a9268a.png\";","export default __webpack_public_path__ + \"static/media/warning--dangerous-crosswinds-right--g4.140e8377.png\";","export default __webpack_public_path__ + \"static/media/warning--dead-end--g1.822dc654.png\";","export default __webpack_public_path__ + \"static/media/warning--dead-end--g2.c8837f3e.png\";","export default __webpack_public_path__ + \"static/media/warning--dead-end--g3.b4178c04.png\";","export default __webpack_public_path__ + \"static/media/warning--dead-end-go-left--g1.e34e1902.png\";","export default __webpack_public_path__ + \"static/media/warning--dead-end-go-right--g1.b71f819e.png\";","export default __webpack_public_path__ + \"static/media/warning--descent-or-climbing-lanes-in-triple-lanes--g1.f42d15ba.png\";","export default __webpack_public_path__ + \"static/media/warning--detour-ahead--g1.62e99e19.png\";","export default __webpack_public_path__ + \"static/media/warning--detour-or-construction-ahead--g1.0dad4882.png\";","export default __webpack_public_path__ + \"static/media/warning--dip--g1.066fd9ff.png\";","export default __webpack_public_path__ + \"static/media/warning--dip--g2.149643b1.png\";","export default __webpack_public_path__ + \"static/media/warning--disabled-persons-crossing--g1.501e3c12.png\";","export default __webpack_public_path__ + \"static/media/warning--disabled-persons-crossing--g2.1097238b.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g1.4e234f74.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g2.c8b40ab4.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g3.3669f7f2.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g4.88ebcd8f.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g5.f5e120c6.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g6.dea45011.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g7.0a7f27b4.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g8.c97f56db.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway--g9.27d2fae7.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-ends--g1.236372f1.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-ends--g2.d64d1f97.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-ends--g3.6ae2c6c2.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-ends--g4.3c3eab12.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-on-left--g1.b83e1490.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-on-left--g2.a464ead0.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-on-right--g1.38f23cbf.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-on-right--g2.67b00901.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-to-left--g1.789096ef.png\";","export default __webpack_public_path__ + \"static/media/warning--divided-highway-to-right--g1.b48c54ce.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g1.b5ee6b47.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g2.1c50b229.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g3.ff1fdd4d.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g4.b8240120.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g5.59bfd681.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g6.d8382f60.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g7.e8a76726.png\";","export default __webpack_public_path__ + \"static/media/warning--domestic-animals--g8.3a90a31b.png\";","export default __webpack_public_path__ + \"static/media/warning--double-curve-first-left--g1.6eb7ea5d.png\";","export default __webpack_public_path__ + \"static/media/warning--double-curve-first-left--g2.f33a8be0.png\";","export default __webpack_public_path__ + \"static/media/warning--double-curve-first-right--g1.a3423d11.png\";","export default __webpack_public_path__ + \"static/media/warning--double-curve-first-right--g2.0c1c9b73.png\";","export default __webpack_public_path__ + \"static/media/warning--double-descent--g1.4470eef4.png\";","export default __webpack_public_path__ + \"static/media/warning--double-reverse-curve-left--g1.404c39b1.png\";","export default __webpack_public_path__ + \"static/media/warning--double-reverse-curve-left--g2.9913da77.png\";","export default __webpack_public_path__ + \"static/media/warning--double-reverse-curve-right--g1.ce6cc21b.png\";","export default __webpack_public_path__ + \"static/media/warning--double-reverse-curve-right--g2.220ae800.png\";","export default __webpack_public_path__ + \"static/media/warning--double-side-roads-left--g1.25faddb2.png\";","export default __webpack_public_path__ + \"static/media/warning--double-side-roads-left--g3.90e3a23d.png\";","export default __webpack_public_path__ + \"static/media/warning--double-side-roads-right--g1.d5e87954.png\";","export default __webpack_public_path__ + \"static/media/warning--double-side-roads-right--g3.f828d2c5.png\";","export default __webpack_public_path__ + \"static/media/warning--double-turn-first-left--g1.be7aa3be.png\";","export default __webpack_public_path__ + \"static/media/warning--double-turn-first-right--g1.98471837.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-all-directions-on-left--g1.c3148502.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-all-directions-on-right--g1.e1524300.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-go-straight-or-turn-left--g1.72412f1e.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-go-straight-or-turn-right--g1.2b80e972.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-left-turn--g1.a0868b18.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-left-turn-or-go-straight--g1.35661ca4.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-right-turn--g1.6eb106ff.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-right-turn-or-go-straight--g1.d9341e1a.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-turn-left--g1.bf236e41.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-turn-left-or-right--g1.920cce95.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-turn-left-or-right--g2.f9d846fa.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-turn-left-or-right--g3.bf437251.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-turn-left-or-right--g4.15fdd3ad.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-lanes-turn-right--g1.24e2dfad.png\";","export default __webpack_public_path__ + \"static/media/warning--dual-path-cyclists-and-pedestrians--g1.c641917c.png\";","export default __webpack_public_path__ + \"static/media/warning--electricity--g1.e43834b5.png\";","export default __webpack_public_path__ + \"static/media/warning--electricity--g2.f309d9d6.png\";","export default __webpack_public_path__ + \"static/media/warning--elephant-crossing--g1.1d0a5289.png\";","export default __webpack_public_path__ + \"static/media/warning--emergency-vehicles--g1.11cfb237.png\";","export default __webpack_public_path__ + \"static/media/warning--emu-crossing--g1.52d9cf04.png\";","export default __webpack_public_path__ + \"static/media/warning--emu-crossing--g2.fee7dc08.png\";","export default __webpack_public_path__ + \"static/media/warning--entering-roadway-merge--g1.332dc1ff.png\";","export default __webpack_public_path__ + \"static/media/warning--entering-roadway-merge--g2.86b6aca3.png\";","export default __webpack_public_path__ + \"static/media/warning--equestrians-crossing--g1.19b9300d.png\";","export default __webpack_public_path__ + \"static/media/warning--equestrians-crossing--g2.d8fe8c9d.png\";","export default __webpack_public_path__ + \"static/media/warning--expressway--g1.5cdf1e31.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-left--g1.ba33de2a.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-left--g2.3de84b6f.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-left--g3.092e6480.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-left--g4.21007872.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-right--g1.e3a61a97.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-right--g2.d134cc6d.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-right--g3.159ce905.png\";","export default __webpack_public_path__ + \"static/media/warning--falling-rocks-or-debris-right--g4.84a6e30d.png\";","export default __webpack_public_path__ + \"static/media/warning--ferry--g1.0879199d.png\";","export default __webpack_public_path__ + \"static/media/warning--flaggers-in-road--g1.46677e39.png\";","export default __webpack_public_path__ + \"static/media/warning--flaggers-in-road--g2.4b786672.png\";","export default __webpack_public_path__ + \"static/media/warning--foggy-road--g1.b2ea0888.png\";","export default __webpack_public_path__ + \"static/media/warning--foggy-road--g2.4e58a69c.png\";","export default __webpack_public_path__ + \"static/media/warning--ford--g1.a4e7c139.png\";","export default __webpack_public_path__ + \"static/media/warning--forest--g1.e558de15.png\";","export default __webpack_public_path__ + \"static/media/warning--fresh-oil--g1.2aa89129.png\";","export default __webpack_public_path__ + \"static/media/warning--frog-crossing--g1.cc552a98.png\";","export default __webpack_public_path__ + \"static/media/warning--gate--g1.ef474cd4.png\";","export default __webpack_public_path__ + \"static/media/warning--gate--g2.7393d775.png\";","export default __webpack_public_path__ + \"static/media/warning--gate-left--g1.060d16fa.png\";","export default __webpack_public_path__ + \"static/media/warning--gate-right--g1.a3c3be2f.png\";","export default __webpack_public_path__ + \"static/media/warning--go-left--g1.f419ee5e.png\";","export default __webpack_public_path__ + \"static/media/warning--go-right--g1.39eb9a50.png\";","export default __webpack_public_path__ + \"static/media/warning--golf-carts-crossing--g1.6d3a5336.png\";","export default __webpack_public_path__ + \"static/media/warning--gravel-road-surface--g1.53217d4e.png\";","export default __webpack_public_path__ + \"static/media/warning--hairpin-curve-left--g1.edb73aef.png\";","export default __webpack_public_path__ + \"static/media/warning--hairpin-curve-left--g2.afaea372.png\";","export default __webpack_public_path__ + \"static/media/warning--hairpin-curve-left--g3.6f0b4e07.png\";","export default __webpack_public_path__ + \"static/media/warning--hairpin-curve-right--g1.7379cbcd.png\";","export default __webpack_public_path__ + \"static/media/warning--hairpin-curve-right--g3.193a361e.png\";","export default __webpack_public_path__ + \"static/media/warning--height-restriction--g2.338e63be.png\";","export default __webpack_public_path__ + \"static/media/warning--height-restriction--g3.71fa9500.png\";","export default __webpack_public_path__ + \"static/media/warning--height-restriction--g4.32ae1bcd.png\";","export default __webpack_public_path__ + \"static/media/warning--height-restriction--g5.079c301b.png\";","export default __webpack_public_path__ + \"static/media/warning--horizontal-alignment-left--g1.5f4578ae.png\";","export default __webpack_public_path__ + \"static/media/warning--horizontal-alignment-left--g3.fa116178.png\";","export default __webpack_public_path__ + \"static/media/warning--horizontal-alignment-right--g1.e52240f3.png\";","export default __webpack_public_path__ + \"static/media/warning--horizontal-alignment-right--g3.4a7db298.png\";","export default __webpack_public_path__ + \"static/media/warning--horse-crossing--g1.d3216891.png\";","export default __webpack_public_path__ + \"static/media/warning--icy-road--g1.c497dd9c.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-acute-left--g1.701ef67e.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-acute-left--g2.aed0430a.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-acute-right--g1.97f3099c.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-acute-right--g2.868e5834.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-left--g1.9d8f0946.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-left--g2.4142c0b3.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-left--g3.ac6cedd7.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-left--g4.64bbd277.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-right--g1.c806e5b6.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-right--g2.42f22c1e.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-right--g3.928aa62d.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-a-side-road-perpendicular-right--g4.956d6e55.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-merge-from-left--g1.bf9a8c4e.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-merge-from-right--g1.9d27fd5a.png\";","export default __webpack_public_path__ + \"static/media/warning--junction-with-side-roads--g1.266339ad.png\";","export default __webpack_public_path__ + \"static/media/warning--kangaloo-crossing--g1.f937c5b4.png\";","export default __webpack_public_path__ + \"static/media/warning--keep-distance--g1.18012af6.png\";","export default __webpack_public_path__ + \"static/media/warning--keep-left--g1.b5f34133.png\";","export default __webpack_public_path__ + \"static/media/warning--keep-right--g1.9eb6188b.png\";","export default __webpack_public_path__ + \"static/media/warning--kiwi-crossing--g1.1d1fffc2.png\";","export default __webpack_public_path__ + \"static/media/warning--kiwi-crossing--g2.31b4982f.png\";","export default __webpack_public_path__ + \"static/media/warning--koala-crossing--g1.c49ced4a.png\";","export default __webpack_public_path__ + \"static/media/warning--koala-crossing--g2.89b90763.png\";","export default __webpack_public_path__ + \"static/media/warning--koala-crossing--g3.31ba34fb.png\";","export default __webpack_public_path__ + \"static/media/warning--koala-crossing--g4.f4a67cc8.png\";","export default __webpack_public_path__ + \"static/media/warning--lane-closed-in-dual-lanes-left--g1.7624de03.png\";","export default __webpack_public_path__ + \"static/media/warning--lane-closed-in-dual-lanes-left--g2.3509b0fc.png\";","export default __webpack_public_path__ + \"static/media/warning--lane-closed-in-dual-lanes-right--g1.2df26f89.png\";","export default __webpack_public_path__ + \"static/media/warning--lane-closed-in-dual-lanes-right--g2.7bbfbdf6.png\";","export default __webpack_public_path__ + \"static/media/warning--length-restriction--g1.883f897f.png\";","export default __webpack_public_path__ + \"static/media/warning--length-restriction--g2.82aa1857.png\";","export default __webpack_public_path__ + \"static/media/warning--light-rail-transit-vehicles--g1.18a56f76.png\";","export default __webpack_public_path__ + \"static/media/warning--limited-lighting-under-trees--g1.12866256.png\";","export default __webpack_public_path__ + \"static/media/warning--logging-vehicles--g1.78031a98.png\";","export default __webpack_public_path__ + \"static/media/warning--loop-270-degree--g1.2e953561.png\";","export default __webpack_public_path__ + \"static/media/warning--loop-pretzel--g1.ec181bb6.png\";","export default __webpack_public_path__ + \"static/media/warning--loose-road-surface--g1.9cae8688.png\";","export default __webpack_public_path__ + \"static/media/warning--loose-road-surface--g2.1f8298ec.png\";","export default __webpack_public_path__ + \"static/media/warning--loose-road-surface--g3.aa246e46.png\";","export default __webpack_public_path__ + \"static/media/warning--loose-road-surface--g4.5d211f2c.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g1.28089b2a.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g2.5cf5bdc9.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g3.dd69f808.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g4.fc3dd88f.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g5.1f6f2725.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g6.7aba7310.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g7.0ae82c4d.png\";","export default __webpack_public_path__ + \"static/media/warning--low-flying-aircraft--g8.15694dc5.png\";","export default __webpack_public_path__ + \"static/media/warning--low-ground-clearance--g1.ffa6da01.png\";","export default __webpack_public_path__ + \"static/media/warning--low-ground-clearance--g2.3e54bb51.png\";","export default __webpack_public_path__ + \"static/media/warning--low-ground-clearance--g3.ce30c364.png\";","export default __webpack_public_path__ + \"static/media/warning--monkey-crossing--g1.f226862a.png\";","export default __webpack_public_path__ + \"static/media/warning--motorcycles-crossing--g1.afd3f593.png\";","export default __webpack_public_path__ + \"static/media/warning--narrow-bridge--g1.e80d13e1.png\";","export default __webpack_public_path__ + \"static/media/warning--narrow-bridge--g2.eb66e49c.png\";","export default __webpack_public_path__ + \"static/media/warning--narrow-bridge--g3.2ba8e460.png\";","export default __webpack_public_path__ + \"static/media/warning--no-passing-zone--g1.4c1a1d05.png\";","export default __webpack_public_path__ + \"static/media/warning--no-passing-zone--g2.d2c6f7ce.png\";","export default __webpack_public_path__ + \"static/media/warning--occupied-lanes--g1.a3fb4526.png\";","export default __webpack_public_path__ + \"static/media/warning--offset-roads--g1.b417a496.png\";","export default __webpack_public_path__ + \"static/media/warning--offset-roads--g2.935e20ba.png\";","export default __webpack_public_path__ + \"static/media/warning--offset-roads--g3.faa03178.png\";","export default __webpack_public_path__ + \"static/media/warning--offset-roads--g4.353ab25e.png\";","export default __webpack_public_path__ + \"static/media/warning--opening-or-swing-bridge--g1.1fb27ae9.png\";","export default __webpack_public_path__ + \"static/media/warning--opening-or-swing-bridge--g2.1a1a0f21.png\";","export default __webpack_public_path__ + \"static/media/warning--other-danger--g1.3188ed01.png\";","export default __webpack_public_path__ + \"static/media/warning--other-danger--g2.7e8cac18.png\";","export default __webpack_public_path__ + \"static/media/warning--other-danger--g3.1ee8a971.png\";","export default __webpack_public_path__ + \"static/media/warning--panda-crossing--g1.e2bdb7b5.png\";","export default __webpack_public_path__ + \"static/media/warning--pass-left-or-right--g1.7d7f601f.png\";","export default __webpack_public_path__ + \"static/media/warning--pass-left-or-right--g2.b55dff44.png\";","export default __webpack_public_path__ + \"static/media/warning--pass-left-or-right--g3.f01eab62.png\";","export default __webpack_public_path__ + \"static/media/warning--pavement-ahead--g1.7a325168.png\";","export default __webpack_public_path__ + \"static/media/warning--pavement-ends--g1.150a9eb6.png\";","export default __webpack_public_path__ + \"static/media/warning--pavement-ends--g2.4aa4c794.png\";","export default __webpack_public_path__ + \"static/media/warning--pavement-ends--g3.95da7c5c.png\";","export default __webpack_public_path__ + \"static/media/warning--pavement-ends--g4.2a4100fb.png\";","export default __webpack_public_path__ + \"static/media/warning--pavement-ends--g5.3aa58447.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g1.3b874634.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g4.5c84a724.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g5.b0b6f57d.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g6.116c592a.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g7.9ef22005.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g8.04317383.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g9.8def020a.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g10.f15c17b4.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g11.d4d8802a.png\";","export default __webpack_public_path__ + \"static/media/warning--pedestrians-crossing--g12.d6a9a05d.png\";","export default __webpack_public_path__ + \"static/media/warning--playground--g1.d27fa8a1.png\";","export default __webpack_public_path__ + \"static/media/warning--playground--g3.030a0910.png\";","export default __webpack_public_path__ + \"static/media/warning--polar-bear-crossing--g1.83f48f13.png\";","export default __webpack_public_path__ + \"static/media/warning--quay-or-river-bank--g1.06042e51.png\";","export default __webpack_public_path__ + \"static/media/warning--quay-or-river-bank--g2.f72ff26e.png\";","export default __webpack_public_path__ + \"static/media/warning--quay-or-river-bank--g3.115341dd.png\";","export default __webpack_public_path__ + \"static/media/warning--quay-or-river-bank--g4.ddcd4717.png\";","export default __webpack_public_path__ + \"static/media/warning--rabbit-crossing--g1.078f403a.png\";","export default __webpack_public_path__ + \"static/media/warning--raccoon-crossing--g1.1668b542.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing--g1.e669ea31.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing--g2.02fde72b.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing--g3.8750f7fe.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing--g4.7ca3c9a3.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g1.10b1d9f7.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g2.1e0850d8.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g3.6e3df1bf.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g4.ee65577f.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g5.489d5280.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g6.692ef82e.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-with-barriers--g7.a1fba766.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-without-barriers--g1.56e6bc9c.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-without-barriers--g2.4806262d.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-without-barriers--g3.0a195b24.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-without-barriers--g4.2ef1f5ca.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-without-barriers--g5.26a5cfe8.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-crossing-without-barriers--g6.cc1a10b5.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g1.e91d23c6.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g2.4e7c41ae.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g3.025e4551.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g4.7f8bcdfd.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g5.ff21b221.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g6.3e6b2b59.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g7.0191ef0a.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g8.0b49d7a0.png\";","export default __webpack_public_path__ + \"static/media/warning--railroad-intersection--g9.e91cfdd5.png\";","export default __webpack_public_path__ + \"static/media/warning--ramp-closed--g1.b7091862.png\";","export default __webpack_public_path__ + \"static/media/warning--reduced-maximum-speed-limit--g1.e37bae32.png\";","export default __webpack_public_path__ + \"static/media/warning--reserved-lane--g1.8d676894.png\";","export default __webpack_public_path__ + \"static/media/warning--restricted-zone--g1.4c3bdaf7.png\";","export default __webpack_public_path__ + \"static/media/warning--reversible-lanes--g1.1aa1f3d9.png\";","export default __webpack_public_path__ + \"static/media/warning--reversible-lanes--g2.8e1063e0.png\";","export default __webpack_public_path__ + \"static/media/warning--rickshaws-crossing--g1.57f86968.png\";","export default __webpack_public_path__ + \"static/media/warning--road-blocks--g1.b88715e8.png\";","export default __webpack_public_path__ + \"static/media/warning--road-bump--g1.33610537.png\";","export default __webpack_public_path__ + \"static/media/warning--road-bump--g2.82cf40b3.png\";","export default __webpack_public_path__ + \"static/media/warning--road-bump--g3.a44b2601.png\";","export default __webpack_public_path__ + \"static/media/warning--road-bump-with-speed-limit--g1.7be1fee6.png\";","export default __webpack_public_path__ + \"static/media/warning--road-closed--g3.c3c7cc6d.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows--g1.77f6e5cb.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows--g2.401c3994.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows-left--g1.95c7edf0.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows-left--g2.44b45332.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows-left-ahead--g1.fd5aa709.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows-right--g1.65ee547e.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows-right--g2.87bc2427.png\";","export default __webpack_public_path__ + \"static/media/warning--road-narrows-right-ahead--g1.400397d6.png\";","export default __webpack_public_path__ + \"static/media/warning--road-toll-ahead--g1.6d55961a.png\";","export default __webpack_public_path__ + \"static/media/warning--road-widens--g1.c796ef79.png\";","export default __webpack_public_path__ + \"static/media/warning--road-widens-left--g1.ad78bfd0.png\";","export default __webpack_public_path__ + \"static/media/warning--road-widens-right--g1.0c6d1992.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g1.547c259b.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g2.1be718e9.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g3.2add7320.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g5.e61ab484.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g6.a04ce9d6.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g8.eb9766c2.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g9.f504fc37.png\";","import icon0 from './complementary--accident-area--g1.png';\r\nimport icon1 from './complementary--accident-area--g2.png';\r\nimport icon2 from './complementary--accident-area--g3.png';\r\nimport icon3 from './complementary--accident-area--g4.png';\r\nimport icon4 from './complementary--advisory-exit-or-ramp-speed--g1.png';\r\nimport icon5 from './complementary--bicycles--g1.png';\r\nimport icon6 from './complementary--bicycles-and-pedestrians-detour--g1.png';\r\nimport icon7 from './complementary--bicycles-or-pedestrians-detour--g1.png';\r\nimport icon8 from './complementary--bicycles-turn-right--g1.png';\r\nimport icon9 from './complementary--bike-route--g1.png';\r\nimport icon10 from './complementary--bike-route--g3.png';\r\nimport icon11 from './complementary--both-directions--g1.png';\r\nimport icon12 from './complementary--both-directions--g2.png';\r\nimport icon13 from './complementary--buses--g1.png';\r\nimport icon14 from './complementary--buses-and-trucks--g1.png';\r\nimport icon15 from './complementary--camera--g1.png';\r\nimport icon16 from './complementary--camera--g2.png';\r\nimport icon17 from './complementary--camera--g3.png';\r\nimport icon18 from './complementary--camera--g4.png';\r\nimport icon19 from './complementary--camera--g5.png';\r\nimport icon20 from './complementary--caravan-trailers--g2.png';\r\nimport icon21 from './complementary--caravan-trailers--g3.png';\r\nimport icon22 from './complementary--caravans--g2.png';\r\nimport icon23 from './complementary--carts--g1.png';\r\nimport icon24 from './complementary--chevron-left--g1.png';\r\nimport icon25 from './complementary--chevron-left--g2.png';\r\nimport icon26 from './complementary--chevron-left--g3.png';\r\nimport icon27 from './complementary--chevron-left--g4.png';\r\nimport icon28 from './complementary--chevron-left--g5.png';\r\nimport icon29 from './complementary--chevron-right--g1.png';\r\nimport icon30 from './complementary--chevron-right--g2.png';\r\nimport icon31 from './complementary--chevron-right--g3.png';\r\nimport icon32 from './complementary--chevron-right--g4.png';\r\nimport icon33 from './complementary--chevron-right--g5.png';\r\nimport icon34 from './complementary--dangerous-or-pollutant-good--g1.png';\r\nimport icon35 from './complementary--dead-end--g1.png';\r\nimport icon36 from './complementary--detour--g1.png';\r\nimport icon37 from './complementary--disabled-persons--g1.png';\r\nimport icon38 from './complementary--distance--g1.png';\r\nimport icon39 from './complementary--distance--g2.png';\r\nimport icon40 from './complementary--distance--g3.png';\r\nimport icon41 from './complementary--end-of-road-works--g1.png';\r\nimport icon42 from './complementary--except-bicycles--g1.png';\r\nimport icon43 from './complementary--except-bicycles--g2.png';\r\nimport icon44 from './complementary--except-buses--g1.png';\r\nimport icon45 from './complementary--except-carts--g1.png';\r\nimport icon46 from './complementary--except-motorcycles--g1.png';\r\nimport icon47 from './complementary--except-motorcycles--g2.png';\r\nimport icon48 from './complementary--except-polluting-level-green--g1.png';\r\nimport icon49 from './complementary--except-polluting-level-green-yellow--g1.png';\r\nimport icon50 from './complementary--except-polluting-level-green-yellow-red--g1.png';\r\nimport icon51 from './complementary--except-tractors--g1.png';\r\nimport icon52 from './complementary--except-tractors--g2.png';\r\nimport icon53 from './complementary--except-trailers--g1.png';\r\nimport icon54 from './complementary--except-trailers--g2.png';\r\nimport icon55 from './complementary--except-trains--g1.png';\r\nimport icon56 from './complementary--except-trams--g1.png';\r\nimport icon57 from './complementary--except-trucks--g1.png';\r\nimport icon58 from './complementary--except-vehicles--g1.png';\r\nimport icon59 from './complementary--except-vehicles--g2.png';\r\nimport icon60 from './complementary--go-left--g1.png';\r\nimport icon61 from './complementary--go-right--g1.png';\r\nimport icon62 from './complementary--go-straight-or-turn-left--g1.png';\r\nimport icon63 from './complementary--go-straight-or-turn-right--g1.png';\r\nimport icon64 from './complementary--height-limit--g1.png';\r\nimport icon65 from './complementary--height-limit--g2.png';\r\nimport icon66 from './complementary--including-bicycles-and-motorcycles--g1.png';\r\nimport icon67 from './complementary--including-buses-vehicles--g1.png';\r\nimport icon68 from './complementary--keep-left--g1.png';\r\nimport icon69 from './complementary--keep-right--g1.png';\r\nimport icon70 from './complementary--lane-control--g1.png';\r\nimport icon71 from './complementary--lane-control--g2.png';\r\nimport icon72 from './complementary--lane-control--g3.png';\r\nimport icon73 from './complementary--maximum-speed-limit-10--g1.png';\r\nimport icon74 from './complementary--maximum-speed-limit-15--g1.png';\r\nimport icon75 from './complementary--maximum-speed-limit-20--g1.png';\r\nimport icon76 from './complementary--maximum-speed-limit-25--g1.png';\r\nimport icon77 from './complementary--maximum-speed-limit-30--g1.png';\r\nimport icon78 from './complementary--maximum-speed-limit-35--g1.png';\r\nimport icon79 from './complementary--maximum-speed-limit-40--g1.png';\r\nimport icon80 from './complementary--maximum-speed-limit-45--g1.png';\r\nimport icon81 from './complementary--maximum-speed-limit-50--g1.png';\r\nimport icon82 from './complementary--maximum-speed-limit-55--g1.png';\r\nimport icon83 from './complementary--maximum-speed-limit-60--g1.png';\r\nimport icon84 from './complementary--maximum-speed-limit-65--g1.png';\r\nimport icon85 from './complementary--maximum-speed-limit-70--g1.png';\r\nimport icon86 from './complementary--maximum-speed-limit-75--g1.png';\r\nimport icon87 from './complementary--maximum-speed-limit-80--g1.png';\r\nimport icon88 from './complementary--maximum-speed-limit-85--g1.png';\r\nimport icon89 from './complementary--maximum-speed-limit-90--g1.png';\r\nimport icon90 from './complementary--maximum-speed-limit-95--g1.png';\r\nimport icon91 from './complementary--motorcycles--g1.png';\r\nimport icon92 from './complementary--motorcycles--g2.png';\r\nimport icon93 from './complementary--motorcycles--g3.png';\r\nimport icon94 from './complementary--motorcycles--g4.png';\r\nimport icon95 from './complementary--obstacle-delineator--g1.png';\r\nimport icon96 from './complementary--obstacle-delineator--g2.png';\r\nimport icon97 from './complementary--obstacle-delineator--g3.png';\r\nimport icon98 from './complementary--one-direction-left--g1.png';\r\nimport icon99 from './complementary--one-direction-right--g1.png';\r\nimport icon100 from './complementary--pass-left--g1.png';\r\nimport icon101 from './complementary--pass-right--g1.png';\r\nimport icon102 from './complementary--pedestrians-and-bicycles--g1.png';\r\nimport icon103 from './complementary--pedestrians-left--g1.png';\r\nimport icon104 from './complementary--pedestrians-right--g1.png';\r\nimport icon105 from './complementary--photo-enforced--g1.png';\r\nimport icon106 from './complementary--playground--g1.png';\r\nimport icon107 from './complementary--priority-route-at-intersection--g1.png';\r\nimport icon108 from './complementary--priority-route-at-intersection--g2.png';\r\nimport icon109 from './complementary--priority-route-at-intersection--g3.png';\r\nimport icon110 from './complementary--priority-route-at-intersection--g4.png';\r\nimport icon111 from './complementary--priority-route-at-intersection--g5.png';\r\nimport icon112 from './complementary--priority-route-at-intersection--g6.png';\r\nimport icon113 from './complementary--railroad--g1.png';\r\nimport icon114 from './complementary--railroad--g2.png';\r\nimport icon115 from './complementary--railroad--g3.png';\r\nimport icon116 from './complementary--restriction-in-both-directions--g1.png';\r\nimport icon117 from './complementary--roundabout-go-left--g1.png';\r\nimport icon118 from './complementary--roundabout-go-right--g1.png';\r\nimport icon119 from './complementary--roundabout-go-straight--g1.png';\r\nimport icon120 from './complementary--slippery-for-caravan-trailers--g1.png';\r\nimport icon121 from './complementary--snow--g2.png';\r\nimport icon122 from './complementary--snow--g4.png';\r\nimport icon123 from './complementary--snow--g5.png';\r\nimport icon124 from './complementary--snowmobiles--g1.png';\r\nimport icon125 from './complementary--soft-shoulder--g1.png';\r\nimport icon126 from './complementary--soft-shoulder--g2.png';\r\nimport icon127 from './complementary--steep-ascent--g1.png';\r\nimport icon128 from './complementary--steep-descent--g1.png';\r\nimport icon129 from './complementary--time-restrictions--g1.png';\r\nimport icon130 from './complementary--time-restrictions--g3.png';\r\nimport icon131 from './complementary--tow-away-zone--g1.png';\r\nimport icon132 from './complementary--tow-away-zone--g3.png';\r\nimport icon133 from './complementary--tractors--g1.png';\r\nimport icon134 from './complementary--traffic-queues--g1.png';\r\nimport icon135 from './complementary--trailers--g1.png';\r\nimport icon136 from './complementary--trailers--g2.png';\r\nimport icon137 from './complementary--trailers--g3.png';\r\nimport icon138 from './complementary--trailers--g4.png';\r\nimport icon139 from './complementary--trains--g1.png';\r\nimport icon140 from './complementary--trams--g1.png';\r\nimport icon141 from './complementary--trees--g1.png';\r\nimport icon142 from './complementary--trucks--g1.png';\r\nimport icon143 from './complementary--trucks--g2.png';\r\nimport icon144 from './complementary--trucks--g3.png';\r\nimport icon145 from './complementary--trucks-and-trailers--g1.png';\r\nimport icon146 from './complementary--trucks-buses-trailers--g1.png';\r\nimport icon147 from './complementary--trucks-go-left--g1.png';\r\nimport icon148 from './complementary--trucks-go-left-ahead--g1.png';\r\nimport icon149 from './complementary--trucks-go-right--g1.png';\r\nimport icon150 from './complementary--trucks-go-right-ahead--g1.png';\r\nimport icon151 from './complementary--trucks-go-straight--g1.png';\r\nimport icon152 from './complementary--trucks-turn-left--g1.png';\r\nimport icon153 from './complementary--trucks-turn-right--g1.png';\r\nimport icon154 from './complementary--turn-left--g1.png';\r\nimport icon155 from './complementary--turn-left--g2.png';\r\nimport icon156 from './complementary--turn-right--g1.png';\r\nimport icon157 from './complementary--turn-right--g2.png';\r\nimport icon158 from './complementary--two-way-traffic--g1.png';\r\nimport icon159 from './complementary--two-way-traffic--g2.png';\r\nimport icon160 from './complementary--two-way-traffic--g3.png';\r\nimport icon161 from './complementary--two-way-traffic--g4.png';\r\nimport icon162 from './complementary--two-way-traffic--g5.png';\r\nimport icon163 from './complementary--vehicles--g1.png';\r\nimport icon164 from './complementary--vehicles--g2.png';\r\nimport icon165 from './complementary--vehicles-or-buses--g1.png';\r\nimport icon166 from './complementary--weekends-or-holidays--g1.png';\r\nimport icon167 from './complementary--weight-limit--g1.png';\r\nimport icon168 from './complementary--when-foggy--g1.png';\r\nimport icon169 from './complementary--when-rainy--g1.png';\r\nimport icon170 from './complementary--when-rainy--g2.png';\r\nimport icon171 from './complementary--when-rainy--g3.png';\r\nimport icon172 from './complementary--when-snowy--g1.png';\r\nimport icon173 from './complementary--when-snowy--g2.png';\r\nimport icon174 from './complementary--when-snowy-or-rainy--g1.png';\r\nimport icon175 from './complementary--when-snowy-or-rainy--g2.png';\r\nimport icon176 from './complementary--when-wet--g1.png';\r\nimport icon177 from './complementary--width-limit--g1.png';\r\nimport icon178 from './complementary--working-days--g1.png';\r\nimport icon179 from './information--airport--g1.png';\r\nimport icon180 from './information--airport--g2.png';\r\nimport icon181 from './information--bicycle-lane--g1.png';\r\nimport icon182 from './information--bicycles-both-ways--g1.png';\r\nimport icon183 from './information--bicycles-crossing--g1.png';\r\nimport icon184 from './information--bicycles-crossing--g2.png';\r\nimport icon185 from './information--bicycles-crossing--g3.png';\r\nimport icon186 from './information--bike-route--g1.png';\r\nimport icon187 from './information--bike-route--g2.png';\r\nimport icon188 from './information--built-up-area--g1.png';\r\nimport icon189 from './information--built-up-area--g2.png';\r\nimport icon190 from './information--bus-lane-straight--g1.png';\r\nimport icon191 from './information--bus-stop--g1.png';\r\nimport icon192 from './information--bus-stop--g2.png';\r\nimport icon193 from './information--camera--g1.png';\r\nimport icon194 from './information--camera--g2.png';\r\nimport icon195 from './information--camera--g3.png';\r\nimport icon196 from './information--camp--g1.png';\r\nimport icon197 from './information--camp--g2.png';\r\nimport icon198 from './information--car-pool-lane--g1.png';\r\nimport icon199 from './information--caravan-parking--g1.png';\r\nimport icon200 from './information--caravan-trailer-parking--g1.png';\r\nimport icon201 from './information--cargo-loading-zone--g1.png';\r\nimport icon202 from './information--central-lane--g1.png';\r\nimport icon203 from './information--charging-station--g1.png';\r\nimport icon204 from './information--children--g1.png';\r\nimport icon205 from './information--children--g2.png';\r\nimport icon206 from './information--children-crossing--g5.png';\r\nimport icon207 from './information--cycling-two-abreast-permitted--g1.png';\r\nimport icon208 from './information--dead-end--g1.png';\r\nimport icon209 from './information--dead-end--g2.png';\r\nimport icon210 from './information--dead-end--g3.png';\r\nimport icon211 from './information--dead-end--g4.png';\r\nimport icon212 from './information--dead-end-except-bicycles--g1.png';\r\nimport icon213 from './information--dead-end-except-bicycles-and-pedestrians--g1.png';\r\nimport icon214 from './information--dead-end-except-bicycles-and-pedestrians--g2.png';\r\nimport icon215 from './information--dead-end-left--g1.png';\r\nimport icon216 from './information--dead-end-left--g2.png';\r\nimport icon217 from './information--dead-end-right--g1.png';\r\nimport icon218 from './information--dead-end-right--g2.png';\r\nimport icon219 from './information--dead-end-right--g3.png';\r\nimport icon220 from './information--directions--g1.png';\r\nimport icon221 from './information--disabled-persons--g1.png';\r\nimport icon222 from './information--disabled-persons--g2.png';\r\nimport icon223 from './information--disabled-persons--g3.png';\r\nimport icon224 from './information--emergency-facility--g1.png';\r\nimport icon225 from './information--end-of-advisory-maximum-speed-limit-20--g1.png';\r\nimport icon226 from './information--end-of-advisory-maximum-speed-limit-40--g1.png';\r\nimport icon227 from './information--end-of-advisory-maximum-speed-limit-60--g1.png';\r\nimport icon228 from './information--end-of-advisory-maximum-speed-limit-70--g1.png';\r\nimport icon229 from './information--end-of-advisory-maximum-speed-limit-80--g1.png';\r\nimport icon230 from './information--end-of-advisory-maximum-speed-limit-90--g1.png';\r\nimport icon231 from './information--end-of-bicycle-lane--g1.png';\r\nimport icon232 from './information--end-of-built-up-area--g1.png';\r\nimport icon233 from './information--end-of-built-up-area--g2.png';\r\nimport icon234 from './information--end-of-built-up-area--g3.png';\r\nimport icon235 from './information--end-of-built-up-area--g4.png';\r\nimport icon236 from './information--end-of-car-pool-lane--g1.png';\r\nimport icon237 from './information--end-of-limited-access-road--g1.png';\r\nimport icon238 from './information--end-of-living-street--g1.png';\r\nimport icon239 from './information--end-of-living-street--g2.png';\r\nimport icon240 from './information--end-of-minimum-speed-10--g1.png';\r\nimport icon241 from './information--end-of-minimum-speed-20--g1.png';\r\nimport icon242 from './information--end-of-minimum-speed-25--g1.png';\r\nimport icon243 from './information--end-of-minimum-speed-30--g1.png';\r\nimport icon244 from './information--end-of-minimum-speed-35--g1.png';\r\nimport icon245 from './information--end-of-minimum-speed-40--g1.png';\r\nimport icon246 from './information--end-of-minimum-speed-50--g1.png';\r\nimport icon247 from './information--end-of-minimum-speed-60--g1.png';\r\nimport icon248 from './information--end-of-minimum-speed-70--g1.png';\r\nimport icon249 from './information--end-of-minimum-speed-75--g1.png';\r\nimport icon250 from './information--end-of-minimum-speed-80--g1.png';\r\nimport icon251 from './information--end-of-minimum-speed-90--g1.png';\r\nimport icon252 from './information--end-of-minimum-speed-100--g1.png';\r\nimport icon253 from './information--end-of-minimum-speed-110--g1.png';\r\nimport icon254 from './information--end-of-minimum-speed-120--g1.png';\r\nimport icon255 from './information--end-of-minimum-speed-130--g1.png';\r\nimport icon256 from './information--end-of-motorway--g1.png';\r\nimport icon257 from './information--end-of-overtaking-permitted-heavy-good-vehicles--g1.png';\r\nimport icon258 from './information--end-of-road-works--g1.png';\r\nimport icon259 from './information--end-of-tunnel--g1.png';\r\nimport icon260 from './information--end-of-tunnel--g2.png';\r\nimport icon261 from './information--end-of-two-way-traffic--g1.png';\r\nimport icon262 from './information--equestrians-permitted--g1.png';\r\nimport icon263 from './information--exit-ahead--g1.png';\r\nimport icon264 from './information--exit-ahead--g2.png';\r\nimport icon265 from './information--exit-ahead--g3.png';\r\nimport icon266 from './information--flight-port--g1.png';\r\nimport icon267 from './information--food--g1.png';\r\nimport icon268 from './information--food--g2.png';\r\nimport icon269 from './information--gas-station--g1.png';\r\nimport icon270 from './information--gas-station--g2.png';\r\nimport icon271 from './information--gas-station--g3.png';\r\nimport icon272 from './information--general-speed-limit-at-city-border--g1.png';\r\nimport icon273 from './information--go-left--g1.png';\r\nimport icon274 from './information--go-right--g1.png';\r\nimport icon275 from './information--go-straight--g1.png';\r\nimport icon276 from './information--go-straight-or-left--g1.png';\r\nimport icon277 from './information--go-straight-or-right--g1.png';\r\nimport icon278 from './information--go-straight-or-turn-left--g1.png';\r\nimport icon279 from './information--go-straight-or-turn-right--g1.png';\r\nimport icon280 from './information--hazardous-goods-vehicles-lane--g1.png';\r\nimport icon281 from './information--height-limit--g1.png';\r\nimport icon282 from './information--height-limit--g2.png';\r\nimport icon283 from './information--highway-directions--g1.png';\r\nimport icon284 from './information--highway-exit--g1.png';\r\nimport icon285 from './information--highway-interchange--g1.png';\r\nimport icon286 from './information--highway-interstate-route--g1.png';\r\nimport icon287 from './information--highway-interstate-route--g2.png';\r\nimport icon288 from './information--highway-preferential-lane--g1.png';\r\nimport icon289 from './information--highway-preferential-lane--g2.png';\r\nimport icon290 from './information--highway-reference-location--g1.png';\r\nimport icon291 from './information--highway-reference-location--g2.png';\r\nimport icon292 from './information--hiking--g1.png';\r\nimport icon293 from './information--hospital--g1.png';\r\nimport icon294 from './information--hurricane-evacuation-route--g1.png';\r\nimport icon295 from './information--interstate-route--g1.png';\r\nimport icon296 from './information--lane-control-intersections--g1.png';\r\nimport icon297 from './information--lane-control-left-turn--g1.png';\r\nimport icon298 from './information--lane-control-multiple-lanes--g1.png';\r\nimport icon299 from './information--lane-control-multiple-lanes--g2.png';\r\nimport icon300 from './information--lane-control-right-turn--g1.png';\r\nimport icon301 from './information--limited-access-road--g1.png';\r\nimport icon302 from './information--litter-container--g1.png';\r\nimport icon303 from './information--living-street--g1.png';\r\nimport icon304 from './information--living-street--g2.png';\r\nimport icon305 from './information--living-street--g3.png';\r\nimport icon306 from './information--lodging--g1.png';\r\nimport icon307 from './information--lodging--g2.png';\r\nimport icon308 from './information--minimum-speed-10--g1.png';\r\nimport icon309 from './information--minimum-speed-20--g1.png';\r\nimport icon310 from './information--minimum-speed-25--g1.png';\r\nimport icon311 from './information--minimum-speed-30--g1.png';\r\nimport icon312 from './information--minimum-speed-35--g1.png';\r\nimport icon313 from './information--minimum-speed-40--g1.png';\r\nimport icon314 from './information--minimum-speed-50--g1.png';\r\nimport icon315 from './information--minimum-speed-60--g1.png';\r\nimport icon316 from './information--minimum-speed-70--g1.png';\r\nimport icon317 from './information--minimum-speed-75--g1.png';\r\nimport icon318 from './information--minimum-speed-80--g1.png';\r\nimport icon319 from './information--minimum-speed-90--g1.png';\r\nimport icon320 from './information--minimum-speed-100--g1.png';\r\nimport icon321 from './information--minimum-speed-110--g1.png';\r\nimport icon322 from './information--minimum-speed-120--g1.png';\r\nimport icon323 from './information--minimum-speed-130--g1.png';\r\nimport icon324 from './information--motorway--g1.png';\r\nimport icon325 from './information--motorway-exit-ahead--g1.png';\r\nimport icon326 from './information--motorway-exit-ahead--g2.png';\r\nimport icon327 from './information--motorway-exit-ahead--g3.png';\r\nimport icon328 from './information--overtaking-allowed-heavy-good-vehicles--g1.png';\r\nimport icon329 from './information--parallel-parking--g1.png';\r\nimport icon330 from './information--park-and-ride--g1.png';\r\nimport icon331 from './information--park-and-ride--g2.png';\r\nimport icon332 from './information--parking--g1.png';\r\nimport icon333 from './information--parking--g2.png';\r\nimport icon334 from './information--parking--g3.png';\r\nimport icon335 from './information--parking--g4.png';\r\nimport icon336 from './information--parking--g5.png';\r\nimport icon337 from './information--parking--g6.png';\r\nimport icon338 from './information--parking-area--g1.png';\r\nimport icon339 from './information--parking-with-restrictions--g1.png';\r\nimport icon340 from './information--pass-on-either-side--g1.png';\r\nimport icon341 from './information--passenger-loading-zone--g1.png';\r\nimport icon342 from './information--pedestrians-crossing--g1.png';\r\nimport icon343 from './information--pedestrians-crossing--g2.png';\r\nimport icon344 from './information--pedestrians-crossing--g3.png';\r\nimport icon345 from './information--pedestrians-only--g4.png';\r\nimport icon346 from './information--pedestrians-permitted--g1.png';\r\nimport icon347 from './information--perpendicular-parking--g1.png';\r\nimport icon348 from './information--picnic-site--g1.png';\r\nimport icon349 from './information--playground--g1.png';\r\nimport icon350 from './information--recreational-vehicle-sanitary-station--g1.png';\r\nimport icon351 from './information--recycle-collection-center--g1.png';\r\nimport icon352 from './information--rest-area--g1.png';\r\nimport icon353 from './information--road-bump--g1.png';\r\nimport icon354 from './information--road-skating--g1.png';\r\nimport icon355 from './information--safety-zone--g1.png';\r\nimport icon356 from './information--safety-zone--g2.png';\r\nimport icon357 from './information--safety-zone--g3.png';\r\nimport icon358 from './information--shared-path-vehicles-and-motorcycles--g1.png';\r\nimport icon359 from './information--stairs--g1.png';\r\nimport icon360 from './information--stairs--g2.png';\r\nimport icon361 from './information--stairs--g3.png';\r\nimport icon362 from './information--stairs--g4.png';\r\nimport icon363 from './information--stop-line--g1.png';\r\nimport icon364 from './information--stop-permitted--g1.png';\r\nimport icon365 from './information--street-name-one-line--g1.png';\r\nimport icon366 from './information--street-name-three-lines--g1.png';\r\nimport icon367 from './information--street-name-two-lines--g1.png';\r\nimport icon368 from './information--subway--g1.png';\r\nimport icon369 from './information--telephone--g1.png';\r\nimport icon370 from './information--telephone--g2.png';\r\nimport icon371 from './information--telephone-device-for-the-deaf--g1.png';\r\nimport icon372 from './information--toll-station--g1.png';\r\nimport icon373 from './information--tourism-information--g1.png';\r\nimport icon374 from './information--tourist-attraction--g1.png';\r\nimport icon375 from './information--traffic-merges-left--g1.png';\r\nimport icon376 from './information--traffic-merges-right--g1.png';\r\nimport icon377 from './information--trail-crossing--g1.png';\r\nimport icon378 from './information--trail-crossing--g2.png';\r\nimport icon379 from './information--trail-crossing--g3.png';\r\nimport icon380 from './information--trailer-camping--g1.png';\r\nimport icon381 from './information--train-or-light-rail-station--g1.png';\r\nimport icon382 from './information--tram-bus-stop--g1.png';\r\nimport icon383 from './information--tram-bus-stop--g2.png';\r\nimport icon384 from './information--trams-crossing--g1.png';\r\nimport icon385 from './information--truck-lane-left--g1.png';\r\nimport icon386 from './information--truck-parking--g1.png';\r\nimport icon387 from './information--truck-trailer-lane-right--g1.png';\r\nimport icon388 from './information--truck-trailer-lane-straight--g1.png';\r\nimport icon389 from './information--trucks-both-ways--g1.png';\r\nimport icon390 from './information--trucks-only--g1.png';\r\nimport icon391 from './information--tsunami-evacuation_route--g1.png';\r\nimport icon392 from './information--tunnel--g1.png';\r\nimport icon393 from './information--tunnel--g2.png';\r\nimport icon394 from './information--tunnel--g3.png';\r\nimport icon395 from './information--tunnel-ahead--g1.png';\r\nimport icon396 from './information--turn-left--g1.png';\r\nimport icon397 from './information--turn-left-ahead--g1.png';\r\nimport icon398 from './information--turn-right--g1.png';\r\nimport icon399 from './information--turn-right-ahead--g1.png';\r\nimport icon400 from './information--urban-area--g1.png';\r\nimport icon401 from './information--vehicles-on-rails--g1.png';\r\nimport icon402 from './information--water-protection-zone--g1.png';\r\nimport icon403 from './information--weight-and-height-limit--g1.png';\r\nimport icon404 from './information--weight-limit--g1.png';\r\nimport icon405 from './information--wireless-internet--g1.png';\r\nimport icon406 from './regulatory--advisory-maximum-speed-limit--g1.png';\r\nimport icon407 from './regulatory--all-directions-permitted--g1.png';\r\nimport icon408 from './regulatory--all-way--g1.png';\r\nimport icon409 from './regulatory--atvs-permitted--g1.png';\r\nimport icon410 from './regulatory--axle-limit--g1.png';\r\nimport icon411 from './regulatory--axle-limit--g2.png';\r\nimport icon412 from './regulatory--bicycle-lane-left--g1.png';\r\nimport icon413 from './regulatory--bicycle-parking--g1.png';\r\nimport icon414 from './regulatory--bicycles-and-buses-only--g1.png';\r\nimport icon415 from './regulatory--bicycles-only--g1.png';\r\nimport icon416 from './regulatory--bicycles-only--g2.png';\r\nimport icon417 from './regulatory--bicycles-only--g3.png';\r\nimport icon418 from './regulatory--bicycles-only--g4.png';\r\nimport icon419 from './regulatory--bicycles-push-button--g1.png';\r\nimport icon420 from './regulatory--bicycles-push-button--g2.png';\r\nimport icon421 from './regulatory--bicycles-stop-on-red--g1.png';\r\nimport icon422 from './regulatory--bicycles-wrong-way--g1.png';\r\nimport icon423 from './regulatory--bicycles-yield-or-use-signal--g1.png';\r\nimport icon424 from './regulatory--bike-route--g1.png';\r\nimport icon425 from './regulatory--building-direction--g1.png';\r\nimport icon426 from './regulatory--bus-priority-lane--g1.png';\r\nimport icon427 from './regulatory--buses-and-taxi-only--g1.png';\r\nimport icon428 from './regulatory--buses-only--g1.png';\r\nimport icon429 from './regulatory--buses-only--g2.png';\r\nimport icon430 from './regulatory--circular-intersection--g1.png';\r\nimport icon431 from './regulatory--circular-intersection--g2.png';\r\nimport icon432 from './regulatory--circular-intersection--g3.png';\r\nimport icon433 from './regulatory--circular-intersection--g4.png';\r\nimport icon434 from './regulatory--cross-only-on-green--g1.png';\r\nimport icon435 from './regulatory--cross-only-on-pedestrian-signal--g1.png';\r\nimport icon436 from './regulatory--crosswalk-stop-on-red--g1.png';\r\nimport icon437 from './regulatory--cycling-restriction--g1.png';\r\nimport icon438 from './regulatory--cyclists-dismount-and-walk--g1.png';\r\nimport icon439 from './regulatory--detour-left--g1.png';\r\nimport icon440 from './regulatory--detour-right--g1.png';\r\nimport icon441 from './regulatory--divided-highway-crossing--g1.png';\r\nimport icon442 from './regulatory--divided-highway-ends--g1.png';\r\nimport icon443 from './regulatory--divided-highway-starts--g1.png';\r\nimport icon444 from './regulatory--do-not-block-intersection--g1.png';\r\nimport icon445 from './regulatory--do-not-pass--g1.png';\r\nimport icon446 from './regulatory--do-not-stop-on-tracks--g1.png';\r\nimport icon447 from './regulatory--dual-lanes-all-directions-on-left--g1.png';\r\nimport icon448 from './regulatory--dual-lanes-all-directions-on-right--g1.png';\r\nimport icon449 from './regulatory--dual-lanes-bicyclists-and-pedestrians--g1.png';\r\nimport icon450 from './regulatory--dual-lanes-go-left-or-right--g1.png';\r\nimport icon451 from './regulatory--dual-lanes-go-straight-on-left--g1.png';\r\nimport icon452 from './regulatory--dual-lanes-go-straight-on-right--g1.png';\r\nimport icon453 from './regulatory--dual-lanes-turn-left--g1.png';\r\nimport icon454 from './regulatory--dual-lanes-turn-left-no-u-turn--g1.png';\r\nimport icon455 from './regulatory--dual-lanes-turn-left-or-straight--g1.png';\r\nimport icon456 from './regulatory--dual-lanes-turn-right-or-straight--g1.png';\r\nimport icon457 from './regulatory--dual-path-bicycles-and-pedestrians--g1.png';\r\nimport icon458 from './regulatory--dual-path-bicycles-and-pedestrians--g2.png';\r\nimport icon459 from './regulatory--dual-path-bicycles-and-pedestrians--g3.png';\r\nimport icon460 from './regulatory--dual-path-equestrians-and-pedestrians--g1.png';\r\nimport icon461 from './regulatory--dual-path-equestrians-and-pedestrians-bicycles--g1.png';\r\nimport icon462 from './regulatory--dual-path-pedestrians-and-bicycles--g1.png';\r\nimport icon463 from './regulatory--dual-path-pedestrians-and-bicycles--g2.png';\r\nimport icon464 from './regulatory--dual-path-pedestrians-and-equestrians--g1.png';\r\nimport icon465 from './regulatory--dual-path-pedestrians-bicycles-and-equestrians--g1.png';\r\nimport icon466 from './regulatory--dual-speed-limits--g1.png';\r\nimport icon467 from './regulatory--dual-speed-limits--g2.png';\r\nimport icon468 from './regulatory--end-of-bicycles-only--g1.png';\r\nimport icon469 from './regulatory--end-of-bicycles-only--g2.png';\r\nimport icon470 from './regulatory--end-of-bus-and-taxi-only--g1.png';\r\nimport icon471 from './regulatory--end-of-buses-only--g1.png';\r\nimport icon472 from './regulatory--end-of-buses-only--g2.png';\r\nimport icon473 from './regulatory--end-of-cycling-restriction--g1.png';\r\nimport icon474 from './regulatory--end-of-dual-path-bicycles-and-pedestrians--g1.png';\r\nimport icon475 from './regulatory--end-of-dual-path-pedestrians-and-bicycles--g1.png';\r\nimport icon476 from './regulatory--end-of-equestrians-only--g1.png';\r\nimport icon477 from './regulatory--end-of-low-beam-headlights--g1.png';\r\nimport icon478 from './regulatory--end-of-maximum-speed-limit-10--g1.png';\r\nimport icon479 from './regulatory--end-of-maximum-speed-limit-10--g2.png';\r\nimport icon480 from './regulatory--end-of-maximum-speed-limit-20--g1.png';\r\nimport icon481 from './regulatory--end-of-maximum-speed-limit-20--g2.png';\r\nimport icon482 from './regulatory--end-of-maximum-speed-limit-25--g1.png';\r\nimport icon483 from './regulatory--end-of-maximum-speed-limit-25--g2.png';\r\nimport icon484 from './regulatory--end-of-maximum-speed-limit-30--g1.png';\r\nimport icon485 from './regulatory--end-of-maximum-speed-limit-30--g2.png';\r\nimport icon486 from './regulatory--end-of-maximum-speed-limit-35--g1.png';\r\nimport icon487 from './regulatory--end-of-maximum-speed-limit-35--g2.png';\r\nimport icon488 from './regulatory--end-of-maximum-speed-limit-40--g1.png';\r\nimport icon489 from './regulatory--end-of-maximum-speed-limit-40--g2.png';\r\nimport icon490 from './regulatory--end-of-maximum-speed-limit-50--g1.png';\r\nimport icon491 from './regulatory--end-of-maximum-speed-limit-50--g2.png';\r\nimport icon492 from './regulatory--end-of-maximum-speed-limit-60--g1.png';\r\nimport icon493 from './regulatory--end-of-maximum-speed-limit-60--g2.png';\r\nimport icon494 from './regulatory--end-of-maximum-speed-limit-65--g1.png';\r\nimport icon495 from './regulatory--end-of-maximum-speed-limit-65--g2.png';\r\nimport icon496 from './regulatory--end-of-maximum-speed-limit-70--g1.png';\r\nimport icon497 from './regulatory--end-of-maximum-speed-limit-70--g2.png';\r\nimport icon498 from './regulatory--end-of-maximum-speed-limit-75--g1.png';\r\nimport icon499 from './regulatory--end-of-maximum-speed-limit-75--g2.png';\r\nimport icon500 from './regulatory--end-of-maximum-speed-limit-80--g1.png';\r\nimport icon501 from './regulatory--end-of-maximum-speed-limit-80--g2.png';\r\nimport icon502 from './regulatory--end-of-maximum-speed-limit-90--g1.png';\r\nimport icon503 from './regulatory--end-of-maximum-speed-limit-90--g2.png';\r\nimport icon504 from './regulatory--end-of-maximum-speed-limit-100--g1.png';\r\nimport icon505 from './regulatory--end-of-maximum-speed-limit-100--g2.png';\r\nimport icon506 from './regulatory--end-of-maximum-speed-limit-110--g1.png';\r\nimport icon507 from './regulatory--end-of-maximum-speed-limit-110--g2.png';\r\nimport icon508 from './regulatory--end-of-maximum-speed-limit-120--g1.png';\r\nimport icon509 from './regulatory--end-of-maximum-speed-limit-120--g2.png';\r\nimport icon510 from './regulatory--end-of-maximum-speed-limit-130--g1.png';\r\nimport icon511 from './regulatory--end-of-maximum-speed-limit-130--g2.png';\r\nimport icon512 from './regulatory--end-of-maximum-speed-limit--g1.png';\r\nimport icon513 from './regulatory--end-of-mopeds-and-bicycles-only--g1.png';\r\nimport icon514 from './regulatory--end-of-no-heavy-goods-vehicles--g1.png';\r\nimport icon515 from './regulatory--end-of-no-horn--g1.png';\r\nimport icon516 from './regulatory--end-of-no-overtaking--g1.png';\r\nimport icon517 from './regulatory--end-of-no-overtaking--g2.png';\r\nimport icon518 from './regulatory--end-of-no-overtaking--g3.png';\r\nimport icon519 from './regulatory--end-of-no-overtaking--g4.png';\r\nimport icon520 from './regulatory--end-of-no-overtaking--g5.png';\r\nimport icon521 from './regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g1.png';\r\nimport icon522 from './regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g2.png';\r\nimport icon523 from './regulatory--end-of-no-overtaking-by-motorcycles--g1.png';\r\nimport icon524 from './regulatory--end-of-no-parking--g1.png';\r\nimport icon525 from './regulatory--end-of-no-parking--g2.png';\r\nimport icon526 from './regulatory--end-of-no-parking-or-stopping--g1.png';\r\nimport icon527 from './regulatory--end-of-one-way-straight--g1.png';\r\nimport icon528 from './regulatory--end-of-parking-zone--g1.png';\r\nimport icon529 from './regulatory--end-of-parking-zone--g2.png';\r\nimport icon530 from './regulatory--end-of-pedestrians-only--g1.png';\r\nimport icon531 from './regulatory--end-of-pedestrians-only--g2.png';\r\nimport icon532 from './regulatory--end-of-pedestrians-only--g3.png';\r\nimport icon533 from './regulatory--end-of-pedestrians-only--g4.png';\r\nimport icon534 from './regulatory--end-of-priority-road--g1.png';\r\nimport icon535 from './regulatory--end-of-prohibition--g1.png';\r\nimport icon536 from './regulatory--end-of-school-zone--g1.png';\r\nimport icon537 from './regulatory--end-of-shared-path-bicycles-and-pedestrians--g1.png';\r\nimport icon538 from './regulatory--end-of-shared-path-pedestrians-and-bicycles--g1.png';\r\nimport icon539 from './regulatory--end-of-snow-chains--g1.png';\r\nimport icon540 from './regulatory--end-of-snow-chains--g2.png';\r\nimport icon541 from './regulatory--end-of-snowmobiles-only--g1.png';\r\nimport icon542 from './regulatory--end-of-speed-limit-zone--g1.png';\r\nimport icon543 from './regulatory--end-of-speed-limit-zone--g2.png';\r\nimport icon544 from './regulatory--end-of-speed-limit-zone--g3.png';\r\nimport icon545 from './regulatory--end-of-tractors-only--g1.png';\r\nimport icon546 from './regulatory--end-of-trams-and-buses-only--g1.png';\r\nimport icon547 from './regulatory--end-of-trams-only--g1.png';\r\nimport icon548 from './regulatory--end-of-trucks-and-buses-only--g1.png';\r\nimport icon549 from './regulatory--end-of-trucks-only--g1.png';\r\nimport icon550 from './regulatory--end-of-trucks-only--g2.png';\r\nimport icon551 from './regulatory--equestrians-only--g1.png';\r\nimport icon552 from './regulatory--except-railroad-crossing--g1.png';\r\nimport icon553 from './regulatory--fine-for-littering--g1.png';\r\nimport icon554 from './regulatory--give-way-to-bicycles--g1.png';\r\nimport icon555 from './regulatory--give-way-to-oncoming-traffic--g1.png';\r\nimport icon556 from './regulatory--give-way-to-oncoming-traffic--g2.png';\r\nimport icon557 from './regulatory--go-left-bicycles--g1.png';\r\nimport icon558 from './regulatory--go-right-bicycles--g1.png';\r\nimport icon559 from './regulatory--go-straight--g1.png';\r\nimport icon560 from './regulatory--go-straight--g3.png';\r\nimport icon561 from './regulatory--go-straight-bicycles--g1.png';\r\nimport icon562 from './regulatory--go-straight-or-turn-left--g1.png';\r\nimport icon563 from './regulatory--go-straight-or-turn-left--g2.png';\r\nimport icon564 from './regulatory--go-straight-or-turn-left--g3.png';\r\nimport icon565 from './regulatory--go-straight-or-turn-right--g1.png';\r\nimport icon566 from './regulatory--go-straight-or-turn-right--g2.png';\r\nimport icon567 from './regulatory--go-straight-or-turn-right--g3.png';\r\nimport icon568 from './regulatory--heavy-goods-vehicles-permitted--g1.png';\r\nimport icon569 from './regulatory--height-limit--g1.png';\r\nimport icon570 from './regulatory--high-beam-headlights--g1.png';\r\nimport icon571 from './regulatory--horn--g1.png';\r\nimport icon572 from './regulatory--in-street-pedestrian-crossing--g1.png';\r\nimport icon573 from './regulatory--keep-left--g1.png';\r\nimport icon574 from './regulatory--keep-left--g2.png';\r\nimport icon575 from './regulatory--keep-left--g3.png';\r\nimport icon576 from './regulatory--keep-left--g4.png';\r\nimport icon577 from './regulatory--keep-left--g5.png';\r\nimport icon578 from './regulatory--keep-left--g6.png';\r\nimport icon579 from './regulatory--keep-left--g7.png';\r\nimport icon580 from './regulatory--keep-right--g1.png';\r\nimport icon581 from './regulatory--keep-right--g2.png';\r\nimport icon582 from './regulatory--keep-right--g3.png';\r\nimport icon583 from './regulatory--keep-right--g4.png';\r\nimport icon584 from './regulatory--keep-right--g5.png';\r\nimport icon585 from './regulatory--keep-right--g6.png';\r\nimport icon586 from './regulatory--keep-right--g7.png';\r\nimport icon587 from './regulatory--keep-right--g8.png';\r\nimport icon588 from './regulatory--keep-right--g9.png';\r\nimport icon589 from './regulatory--lane-control--g1.png';\r\nimport icon590 from './regulatory--left-turn-yield-on-green--g1.png';\r\nimport icon591 from './regulatory--length-limit--g1.png';\r\nimport icon592 from './regulatory--length-limit--g2.png';\r\nimport icon593 from './regulatory--light-rail-divided-highway--g1.png';\r\nimport icon594 from './regulatory--light-rail-do-not-pass--g1.png';\r\nimport icon595 from './regulatory--light-rail-only--g1.png';\r\nimport icon596 from './regulatory--look--g1.png';\r\nimport icon597 from './regulatory--low-beam-headlights--g1.png';\r\nimport icon598 from './regulatory--low-beam-headlights--g2.png';\r\nimport icon599 from './regulatory--low-beam-headlights--g3.png';\r\nimport icon600 from './regulatory--low-speed-vehicle-permitted--g1.png';\r\nimport icon601 from './regulatory--maximum-speed-limit-5--g1.png';\r\nimport icon602 from './regulatory--maximum-speed-limit-5--g3.png';\r\nimport icon603 from './regulatory--maximum-speed-limit-10--g1.png';\r\nimport icon604 from './regulatory--maximum-speed-limit-10--g3.png';\r\nimport icon605 from './regulatory--maximum-speed-limit-15--g1.png';\r\nimport icon606 from './regulatory--maximum-speed-limit-15--g3.png';\r\nimport icon607 from './regulatory--maximum-speed-limit-20--g1.png';\r\nimport icon608 from './regulatory--maximum-speed-limit-20--g3.png';\r\nimport icon609 from './regulatory--maximum-speed-limit-25--g1.png';\r\nimport icon610 from './regulatory--maximum-speed-limit-25--g2.png';\r\nimport icon611 from './regulatory--maximum-speed-limit-30--g1.png';\r\nimport icon612 from './regulatory--maximum-speed-limit-30--g3.png';\r\nimport icon613 from './regulatory--maximum-speed-limit-35--g1.png';\r\nimport icon614 from './regulatory--maximum-speed-limit-35--g2.png';\r\nimport icon615 from './regulatory--maximum-speed-limit-40--g1.png';\r\nimport icon616 from './regulatory--maximum-speed-limit-40--g3.png';\r\nimport icon617 from './regulatory--maximum-speed-limit-45--g1.png';\r\nimport icon618 from './regulatory--maximum-speed-limit-45--g3.png';\r\nimport icon619 from './regulatory--maximum-speed-limit-50--g1.png';\r\nimport icon620 from './regulatory--maximum-speed-limit-50--g3.png';\r\nimport icon621 from './regulatory--maximum-speed-limit-55--g2.png';\r\nimport icon622 from './regulatory--maximum-speed-limit-60--g1.png';\r\nimport icon623 from './regulatory--maximum-speed-limit-60--g3.png';\r\nimport icon624 from './regulatory--maximum-speed-limit-65--g1.png';\r\nimport icon625 from './regulatory--maximum-speed-limit-65--g2.png';\r\nimport icon626 from './regulatory--maximum-speed-limit-70--g1.png';\r\nimport icon627 from './regulatory--maximum-speed-limit-70--g3.png';\r\nimport icon628 from './regulatory--maximum-speed-limit-75--g2.png';\r\nimport icon629 from './regulatory--maximum-speed-limit-80--g1.png';\r\nimport icon630 from './regulatory--maximum-speed-limit-80--g3.png';\r\nimport icon631 from './regulatory--maximum-speed-limit-85--g2.png';\r\nimport icon632 from './regulatory--maximum-speed-limit-90--g1.png';\r\nimport icon633 from './regulatory--maximum-speed-limit-90--g3.png';\r\nimport icon634 from './regulatory--maximum-speed-limit-100--g1.png';\r\nimport icon635 from './regulatory--maximum-speed-limit-100--g3.png';\r\nimport icon636 from './regulatory--maximum-speed-limit-110--g1.png';\r\nimport icon637 from './regulatory--maximum-speed-limit-110--g3.png';\r\nimport icon638 from './regulatory--maximum-speed-limit-120--g1.png';\r\nimport icon639 from './regulatory--maximum-speed-limit-120--g3.png';\r\nimport icon640 from './regulatory--maximum-speed-limit-130--g1.png';\r\nimport icon641 from './regulatory--maximum-speed-limit-130--g3.png';\r\nimport icon642 from './regulatory--maximum-speed-limit-led-5--g2.png';\r\nimport icon643 from './regulatory--maximum-speed-limit-led-5--g3.png';\r\nimport icon644 from './regulatory--maximum-speed-limit-led-10--g1.png';\r\nimport icon645 from './regulatory--maximum-speed-limit-led-10--g2.png';\r\nimport icon646 from './regulatory--maximum-speed-limit-led-10--g3.png';\r\nimport icon647 from './regulatory--maximum-speed-limit-led-15--g2.png';\r\nimport icon648 from './regulatory--maximum-speed-limit-led-15--g3.png';\r\nimport icon649 from './regulatory--maximum-speed-limit-led-20--g1.png';\r\nimport icon650 from './regulatory--maximum-speed-limit-led-20--g2.png';\r\nimport icon651 from './regulatory--maximum-speed-limit-led-20--g3.png';\r\nimport icon652 from './regulatory--maximum-speed-limit-led-25--g1.png';\r\nimport icon653 from './regulatory--maximum-speed-limit-led-25--g2.png';\r\nimport icon654 from './regulatory--maximum-speed-limit-led-25--g3.png';\r\nimport icon655 from './regulatory--maximum-speed-limit-led-30--g1.png';\r\nimport icon656 from './regulatory--maximum-speed-limit-led-30--g2.png';\r\nimport icon657 from './regulatory--maximum-speed-limit-led-30--g3.png';\r\nimport icon658 from './regulatory--maximum-speed-limit-led-35--g1.png';\r\nimport icon659 from './regulatory--maximum-speed-limit-led-35--g2.png';\r\nimport icon660 from './regulatory--maximum-speed-limit-led-35--g3.png';\r\nimport icon661 from './regulatory--maximum-speed-limit-led-40--g1.png';\r\nimport icon662 from './regulatory--maximum-speed-limit-led-40--g2.png';\r\nimport icon663 from './regulatory--maximum-speed-limit-led-40--g3.png';\r\nimport icon664 from './regulatory--maximum-speed-limit-led-45--g2.png';\r\nimport icon665 from './regulatory--maximum-speed-limit-led-45--g3.png';\r\nimport icon666 from './regulatory--maximum-speed-limit-led-50--g1.png';\r\nimport icon667 from './regulatory--maximum-speed-limit-led-50--g2.png';\r\nimport icon668 from './regulatory--maximum-speed-limit-led-50--g3.png';\r\nimport icon669 from './regulatory--maximum-speed-limit-led-55--g2.png';\r\nimport icon670 from './regulatory--maximum-speed-limit-led-55--g3.png';\r\nimport icon671 from './regulatory--maximum-speed-limit-led-60--g1.png';\r\nimport icon672 from './regulatory--maximum-speed-limit-led-60--g2.png';\r\nimport icon673 from './regulatory--maximum-speed-limit-led-60--g3.png';\r\nimport icon674 from './regulatory--maximum-speed-limit-led-65--g2.png';\r\nimport icon675 from './regulatory--maximum-speed-limit-led-65--g3.png';\r\nimport icon676 from './regulatory--maximum-speed-limit-led-70--g1.png';\r\nimport icon677 from './regulatory--maximum-speed-limit-led-70--g2.png';\r\nimport icon678 from './regulatory--maximum-speed-limit-led-70--g3.png';\r\nimport icon679 from './regulatory--maximum-speed-limit-led-75--g1.png';\r\nimport icon680 from './regulatory--maximum-speed-limit-led-75--g2.png';\r\nimport icon681 from './regulatory--maximum-speed-limit-led-75--g3.png';\r\nimport icon682 from './regulatory--maximum-speed-limit-led-80--g1.png';\r\nimport icon683 from './regulatory--maximum-speed-limit-led-80--g2.png';\r\nimport icon684 from './regulatory--maximum-speed-limit-led-80--g3.png';\r\nimport icon685 from './regulatory--maximum-speed-limit-led-85--g2.png';\r\nimport icon686 from './regulatory--maximum-speed-limit-led-85--g3.png';\r\nimport icon687 from './regulatory--maximum-speed-limit-led-90--g1.png';\r\nimport icon688 from './regulatory--maximum-speed-limit-led-100--g1.png';\r\nimport icon689 from './regulatory--maximum-speed-limit-led-110--g1.png';\r\nimport icon690 from './regulatory--maximum-speed-limit-led-120--g1.png';\r\nimport icon691 from './regulatory--maximum-speed-limit-led-130--g1.png';\r\nimport icon692 from './regulatory--minimum-safe-distance--g1.png';\r\nimport icon693 from './regulatory--minimum-safe-distance--g2.png';\r\nimport icon694 from './regulatory--mopeds-and-bicycles-only--g1.png';\r\nimport icon695 from './regulatory--motorcycles-and-bicycles-only--g1.png';\r\nimport icon696 from './regulatory--motorcycles-only--g1.png';\r\nimport icon697 from './regulatory--motorcycles-only--g2.png';\r\nimport icon698 from './regulatory--night-speed-limit-5--g1.png';\r\nimport icon699 from './regulatory--night-speed-limit-10--g1.png';\r\nimport icon700 from './regulatory--night-speed-limit-15--g1.png';\r\nimport icon701 from './regulatory--night-speed-limit-20--g1.png';\r\nimport icon702 from './regulatory--night-speed-limit-25--g1.png';\r\nimport icon703 from './regulatory--night-speed-limit-30--g1.png';\r\nimport icon704 from './regulatory--night-speed-limit-35--g1.png';\r\nimport icon705 from './regulatory--night-speed-limit-40--g1.png';\r\nimport icon706 from './regulatory--night-speed-limit-45--g1.png';\r\nimport icon707 from './regulatory--night-speed-limit-50--g1.png';\r\nimport icon708 from './regulatory--night-speed-limit-55--g1.png';\r\nimport icon709 from './regulatory--night-speed-limit-60--g1.png';\r\nimport icon710 from './regulatory--night-speed-limit-65--g1.png';\r\nimport icon711 from './regulatory--night-speed-limit-70--g1.png';\r\nimport icon712 from './regulatory--night-speed-limit-75--g1.png';\r\nimport icon713 from './regulatory--night-speed-limit-80--g1.png';\r\nimport icon714 from './regulatory--night-speed-limit-85--g1.png';\r\nimport icon715 from './regulatory--no-abnormal-vehicles--g1.png';\r\nimport icon716 from './regulatory--no-atvs--g1.png';\r\nimport icon717 from './regulatory--no-bicycles--g1.png';\r\nimport icon718 from './regulatory--no-bicycles--g2.png';\r\nimport icon719 from './regulatory--no-bicycles--g3.png';\r\nimport icon720 from './regulatory--no-bicycles-carts-or-hand-carts--g1.png';\r\nimport icon721 from './regulatory--no-bicycles-mopeds-or-motorcycles--g1.png';\r\nimport icon722 from './regulatory--no-bicycles-mopeds-or-motorcycles--g2.png';\r\nimport icon723 from './regulatory--no-bicycles-or-hand-carts--g1.png';\r\nimport icon724 from './regulatory--no-bicycles-or-motorcycles--g1.png';\r\nimport icon725 from './regulatory--no-bicycles-tractors-or-carts--g1.png';\r\nimport icon726 from './regulatory--no-buses--g1.png';\r\nimport icon727 from './regulatory--no-buses--g2.png';\r\nimport icon728 from './regulatory--no-buses--g3.png';\r\nimport icon729 from './regulatory--no-caravan-trailers--g1.png';\r\nimport icon730 from './regulatory--no-caravans--g1.png';\r\nimport icon731 from './regulatory--no-caravans-or-caravan-trailers--g1.png';\r\nimport icon732 from './regulatory--no-cargo-loading--g1.png';\r\nimport icon733 from './regulatory--no-carts--g1.png';\r\nimport icon734 from './regulatory--no-carts--g2.png';\r\nimport icon735 from './regulatory--no-carts--g3.png';\r\nimport icon736 from './regulatory--no-carts-or-tractors--g1.png';\r\nimport icon737 from './regulatory--no-construction-vehicles--g1.png';\r\nimport icon738 from './regulatory--no-entry--g1.png';\r\nimport icon739 from './regulatory--no-equestrians--g1.png';\r\nimport icon740 from './regulatory--no-go-straight-or-turn-left--g1.png';\r\nimport icon741 from './regulatory--no-go-straight-or-turn-right--g1.png';\r\nimport icon742 from './regulatory--no-good-trailers--g2.png';\r\nimport icon743 from './regulatory--no-goods-vehicle-trailers--g1.png';\r\nimport icon744 from './regulatory--no-hand-carts--g1.png';\r\nimport icon745 from './regulatory--no-hand-carts--g2.png';\r\nimport icon746 from './regulatory--no-hand-carts-or-bicycles--g1.png';\r\nimport icon747 from './regulatory--no-hawkers--g1.png';\r\nimport icon748 from './regulatory--no-heavy-goods-vehicles--g1.png';\r\nimport icon749 from './regulatory--no-heavy-goods-vehicles--g2.png';\r\nimport icon750 from './regulatory--no-heavy-goods-vehicles--g3.png';\r\nimport icon751 from './regulatory--no-heavy-goods-vehicles--g4.png';\r\nimport icon752 from './regulatory--no-heavy-goods-vehicles--g5.png';\r\nimport icon753 from './regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g1.png';\r\nimport icon754 from './regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g2.png';\r\nimport icon755 from './regulatory--no-heavy-goods-vehicles-or-buses--g1.png';\r\nimport icon756 from './regulatory--no-heavy-goods-vehicles-or-tractors--g1.png';\r\nimport icon757 from './regulatory--no-heavy-goods-vehicles-or-trailers--g1.png';\r\nimport icon758 from './regulatory--no-horizontal-turn--g1.png';\r\nimport icon759 from './regulatory--no-horn--g1.png';\r\nimport icon760 from './regulatory--no-horn--g2.png';\r\nimport icon761 from './regulatory--no-lane-change-to-left--g1.png';\r\nimport icon762 from './regulatory--no-lane-change-to-right--g1.png';\r\nimport icon763 from './regulatory--no-learner-drivers--g1.png';\r\nimport icon764 from './regulatory--no-left-or-u-turn--g1.png';\r\nimport icon765 from './regulatory--no-left-turn--g1.png';\r\nimport icon766 from './regulatory--no-left-turn--g2.png';\r\nimport icon767 from './regulatory--no-left-turn--g3.png';\r\nimport icon768 from './regulatory--no-left-turn--g4.png';\r\nimport icon769 from './regulatory--no-left-turn--g5.png';\r\nimport icon770 from './regulatory--no-low-speed-vehicles--g1.png';\r\nimport icon771 from './regulatory--no-mopeds-or-bicycles--g1.png';\r\nimport icon772 from './regulatory--no-motor-vehicle-trailers--g1.png';\r\nimport icon773 from './regulatory--no-motor-vehicles--g1.png';\r\nimport icon774 from './regulatory--no-motor-vehicles--g3.png';\r\nimport icon775 from './regulatory--no-motor-vehicles--g4.png';\r\nimport icon776 from './regulatory--no-motor-vehicles--g5.png';\r\nimport icon777 from './regulatory--no-motor-vehicles--g6.png';\r\nimport icon778 from './regulatory--no-motor-vehicles--g7.png';\r\nimport icon779 from './regulatory--no-motor-vehicles-except-motorcycles--g1.png';\r\nimport icon780 from './regulatory--no-motor-vehicles-except-motorcycles--g2.png';\r\nimport icon781 from './regulatory--no-motor-vehicles-except-motorcycles--g3.png';\r\nimport icon782 from './regulatory--no-motor-vehicles-or-bicycles--g1.png';\r\nimport icon783 from './regulatory--no-motor-vehicles-or-buses--g1.png';\r\nimport icon784 from './regulatory--no-motor-vehicles-or-carts--g1.png';\r\nimport icon785 from './regulatory--no-motorcycles--g1.png';\r\nimport icon786 from './regulatory--no-motorcycles--g2.png';\r\nimport icon787 from './regulatory--no-overtaking--g1.png';\r\nimport icon788 from './regulatory--no-overtaking--g2.png';\r\nimport icon789 from './regulatory--no-overtaking--g4.png';\r\nimport icon790 from './regulatory--no-overtaking--g5.png';\r\nimport icon791 from './regulatory--no-overtaking--g6.png';\r\nimport icon792 from './regulatory--no-overtaking--g7.png';\r\nimport icon793 from './regulatory--no-overtaking-atvs--g1.png';\r\nimport icon794 from './regulatory--no-overtaking-by-heavy-goods-vehicles--g1.png';\r\nimport icon795 from './regulatory--no-parking--g1.png';\r\nimport icon796 from './regulatory--no-parking--g2.png';\r\nimport icon797 from './regulatory--no-parking--g3.png';\r\nimport icon798 from './regulatory--no-parking--g4.png';\r\nimport icon799 from './regulatory--no-parking--g5.png';\r\nimport icon800 from './regulatory--no-parking--g6.png';\r\nimport icon801 from './regulatory--no-parking--g7.png';\r\nimport icon802 from './regulatory--no-parking--g8.png';\r\nimport icon803 from './regulatory--no-parking--g9.png';\r\nimport icon804 from './regulatory--no-parking-bicycles-or-motorcycles--g1.png';\r\nimport icon805 from './regulatory--no-parking-bus-stop--g1.png';\r\nimport icon806 from './regulatory--no-parking-or-no-stopping--g1.png';\r\nimport icon807 from './regulatory--no-parking-or-no-stopping--g2.png';\r\nimport icon808 from './regulatory--no-parking-or-no-stopping--g3.png';\r\nimport icon809 from './regulatory--no-parking-or-no-stopping--g4.png';\r\nimport icon810 from './regulatory--no-parking-or-no-stopping--g5.png';\r\nimport icon811 from './regulatory--no-passenger-loading--g1.png';\r\nimport icon812 from './regulatory--no-pedestrians--g1.png';\r\nimport icon813 from './regulatory--no-pedestrians--g2.png';\r\nimport icon814 from './regulatory--no-pedestrians--g3.png';\r\nimport icon815 from './regulatory--no-pedestrians--g4.png';\r\nimport icon816 from './regulatory--no-pedestrians--g5.png';\r\nimport icon817 from './regulatory--no-pedestrians--g6.png';\r\nimport icon818 from './regulatory--no-pedestrians-bicycles-animals-or-hand-carts--g1.png';\r\nimport icon819 from './regulatory--no-pedestrians-or-bicycles--g1.png';\r\nimport icon820 from './regulatory--no-pedestrians-or-bicycles--g2.png';\r\nimport icon821 from './regulatory--no-pedestrians-or-bicycles--g3.png';\r\nimport icon822 from './regulatory--no-rickshaws--g1.png';\r\nimport icon823 from './regulatory--no-rickshaws--g2.png';\r\nimport icon824 from './regulatory--no-rickshaws--g3.png';\r\nimport icon825 from './regulatory--no-right-turn--g1.png';\r\nimport icon826 from './regulatory--no-right-turn--g2.png';\r\nimport icon827 from './regulatory--no-right-turn--g3.png';\r\nimport icon828 from './regulatory--no-right-turn-on-red--g1.png';\r\nimport icon829 from './regulatory--no-skiing--g1.png';\r\nimport icon830 from './regulatory--no-snowmobiles--g1.png';\r\nimport icon831 from './regulatory--no-snowmobiles--g2.png';\r\nimport icon832 from './regulatory--no-snowmobiles-or-atvs--g1.png';\r\nimport icon833 from './regulatory--no-stopping--g1.png';\r\nimport icon834 from './regulatory--no-stopping--g2.png';\r\nimport icon835 from './regulatory--no-stopping--g3.png';\r\nimport icon836 from './regulatory--no-stopping--g5.png';\r\nimport icon837 from './regulatory--no-stopping--g6.png';\r\nimport icon838 from './regulatory--no-stopping--g7.png';\r\nimport icon839 from './regulatory--no-stopping-on-pavement--g1.png';\r\nimport icon840 from './regulatory--no-straight-through--g1.png';\r\nimport icon841 from './regulatory--no-straight-through--g2.png';\r\nimport icon842 from './regulatory--no-studded-snow-chains--g1.png';\r\nimport icon843 from './regulatory--no-through-trucks--g1.png';\r\nimport icon844 from './regulatory--no-tour-buses--g1.png';\r\nimport icon845 from './regulatory--no-tractors--g1.png';\r\nimport icon846 from './regulatory--no-tractors-mopeds-or-bicycles--g1.png';\r\nimport icon847 from './regulatory--no-tractors-or-carts--g1.png';\r\nimport icon848 from './regulatory--no-trailers--g1.png';\r\nimport icon849 from './regulatory--no-tricycles--g1.png';\r\nimport icon850 from './regulatory--no-tricycles-or-hand-carts--g1.png';\r\nimport icon851 from './regulatory--no-turn-on-red--g1.png';\r\nimport icon852 from './regulatory--no-turn-on-red--g2.png';\r\nimport icon853 from './regulatory--no-turn-on-red--g3.png';\r\nimport icon854 from './regulatory--no-turns--g1.png';\r\nimport icon855 from './regulatory--no-turns--g2.png';\r\nimport icon856 from './regulatory--no-two-stage-right-turn-for-mopeds--g1.png';\r\nimport icon857 from './regulatory--no-u-turn--g1.png';\r\nimport icon858 from './regulatory--no-u-turn--g2.png';\r\nimport icon859 from './regulatory--no-u-turn--g3.png';\r\nimport icon860 from './regulatory--no-vehicles-carrying-dangerous-goods--g1.png';\r\nimport icon861 from './regulatory--no-vehicles-carrying-dangerous-goods--g2.png';\r\nimport icon862 from './regulatory--no-vehicles-carrying-dangerous-goods--g3.png';\r\nimport icon863 from './regulatory--no-vehicles-carrying-dangerous-goods--g4.png';\r\nimport icon864 from './regulatory--no-vehicles-carrying-dangerous-water-pollutants--g1.png';\r\nimport icon865 from './regulatory--no-vehicles-carrying-dangerous-water-pollutants--g2.png';\r\nimport icon866 from './regulatory--no-vehicles-carrying-explosives--g1.png';\r\nimport icon867 from './regulatory--no-vehicles-carrying-explosives-or-dangerous-water-pollutants--g1.png';\r\nimport icon868 from './regulatory--one-way-left--g1.png';\r\nimport icon869 from './regulatory--one-way-left--g2.png';\r\nimport icon870 from './regulatory--one-way-left--g3.png';\r\nimport icon871 from './regulatory--one-way-right--g1.png';\r\nimport icon872 from './regulatory--one-way-right--g2.png';\r\nimport icon873 from './regulatory--one-way-right--g3.png';\r\nimport icon874 from './regulatory--one-way-straight--g1.png';\r\nimport icon875 from './regulatory--one-way-straight--g3.png';\r\nimport icon876 from './regulatory--parking-fee-station--g1.png';\r\nimport icon877 from './regulatory--parking-restrictions--g1.png';\r\nimport icon878 from './regulatory--parking-restrictions--g2.png';\r\nimport icon879 from './regulatory--parking-restrictions--g3.png';\r\nimport icon880 from './regulatory--pass-on-either-side--g1.png';\r\nimport icon881 from './regulatory--pass-on-either-side--g2.png';\r\nimport icon882 from './regulatory--pass-on-either-side--g3.png';\r\nimport icon883 from './regulatory--pass-with-care--g1.png';\r\nimport icon884 from './regulatory--passing-lane-ahead--g1.png';\r\nimport icon885 from './regulatory--pedestrians-bicycles-permitted--g1.png';\r\nimport icon886 from './regulatory--pedestrians-keep-left--g1.png';\r\nimport icon887 from './regulatory--pedestrians-only--g1.png';\r\nimport icon888 from './regulatory--pedestrians-only--g2.png';\r\nimport icon889 from './regulatory--pedestrians-only--g3.png';\r\nimport icon890 from './regulatory--pedestrians-priority-zone--g1.png';\r\nimport icon891 from './regulatory--pedestrians-push-button--g1.png';\r\nimport icon892 from './regulatory--pedestrians-push-button--g2.png';\r\nimport icon893 from './regulatory--priority-over-oncoming-vehicles--g1.png';\r\nimport icon894 from './regulatory--priority-over-oncoming-vehicles--g2.png';\r\nimport icon895 from './regulatory--priority-road--g1.png';\r\nimport icon896 from './regulatory--priority-road--g2.png';\r\nimport icon897 from './regulatory--radar-enforced--g1.png';\r\nimport icon898 from './regulatory--reserved-parking--g1.png';\r\nimport icon899 from './regulatory--reversible-lanes--g1.png';\r\nimport icon900 from './regulatory--reversible-lanes--g2.png';\r\nimport icon901 from './regulatory--road-closed--g1.png';\r\nimport icon902 from './regulatory--road-closed--g2.png';\r\nimport icon903 from './regulatory--road-closed-to-vehicles--g1.png';\r\nimport icon904 from './regulatory--road-closed-to-vehicles--g3.png';\r\nimport icon905 from './regulatory--roundabout--g1.png';\r\nimport icon906 from './regulatory--roundabout--g2.png';\r\nimport icon907 from './regulatory--roundabout--g3.png';\r\nimport icon908 from './regulatory--shared-path-bicycles-and-pedestrians--g1.png';\r\nimport icon909 from './regulatory--shared-path-pedestrians-and-bicycles--g1.png';\r\nimport icon910 from './regulatory--sidewalk-closed--g1.png';\r\nimport icon911 from './regulatory--slanted-parking--g1.png';\r\nimport icon912 from './regulatory--snow-chains--g1.png';\r\nimport icon913 from './regulatory--snow-chains--g2.png';\r\nimport icon914 from './regulatory--snow-chains--g3.png';\r\nimport icon915 from './regulatory--snowmobiles-only--g1.png';\r\nimport icon916 from './regulatory--snowmobiles-permitted--g1.png';\r\nimport icon917 from './regulatory--speed-limit-zone--g1.png';\r\nimport icon918 from './regulatory--speeding-fines-increased--g1.png';\r\nimport icon919 from './regulatory--state-route--g1.png';\r\nimport icon920 from './regulatory--stay-in-lane--g1.png';\r\nimport icon921 from './regulatory--stop--g1.png';\r\nimport icon922 from './regulatory--stop--g2.png';\r\nimport icon923 from './regulatory--stop--g3.png';\r\nimport icon924 from './regulatory--stop--g4.png';\r\nimport icon925 from './regulatory--stop--g5.png';\r\nimport icon926 from './regulatory--stop--g6.png';\r\nimport icon927 from './regulatory--stop--g7.png';\r\nimport icon928 from './regulatory--stop--g8.png';\r\nimport icon929 from './regulatory--stop--g9.png';\r\nimport icon930 from './regulatory--stop--g10.png';\r\nimport icon931 from './regulatory--stop-here-on-red-or-flashing-light--g1.png';\r\nimport icon932 from './regulatory--stop-here-on-red-or-flashing-light--g2.png';\r\nimport icon933 from './regulatory--stop-signals--g1.png';\r\nimport icon934 from './regulatory--stop-signals--g2.png';\r\nimport icon935 from './regulatory--tanks-only--g1.png';\r\nimport icon936 from './regulatory--taxi-only--g1.png';\r\nimport icon937 from './regulatory--text--g1.png';\r\nimport icon938 from './regulatory--text--g2.png';\r\nimport icon939 from './regulatory--toll-pass-only--g1.png';\r\nimport icon940 from './regulatory--tractors-only--g1.png';\r\nimport icon941 from './regulatory--traffic-signal-photo-enforced--g1.png';\r\nimport icon942 from './regulatory--trams-and-buses-only--g1.png';\r\nimport icon943 from './regulatory--trams-only--g1.png';\r\nimport icon944 from './regulatory--triple-lanes--g1.png';\r\nimport icon945 from './regulatory--triple-lanes-go-straight-center-lane--g1.png';\r\nimport icon946 from './regulatory--triple-lanes-turn-left-center-lane--g1.png';\r\nimport icon947 from './regulatory--triple-lanes-turn-right-center-lane--g1.png';\r\nimport icon948 from './regulatory--truck-route--g1.png';\r\nimport icon949 from './regulatory--truck-speed-limit-5--g1.png';\r\nimport icon950 from './regulatory--truck-speed-limit-10--g1.png';\r\nimport icon951 from './regulatory--truck-speed-limit-15--g1.png';\r\nimport icon952 from './regulatory--truck-speed-limit-20--g1.png';\r\nimport icon953 from './regulatory--truck-speed-limit-25--g1.png';\r\nimport icon954 from './regulatory--truck-speed-limit-30--g1.png';\r\nimport icon955 from './regulatory--truck-speed-limit-35--g1.png';\r\nimport icon956 from './regulatory--truck-speed-limit-40--g1.png';\r\nimport icon957 from './regulatory--truck-speed-limit-45--g1.png';\r\nimport icon958 from './regulatory--truck-speed-limit-50--g1.png';\r\nimport icon959 from './regulatory--truck-speed-limit-55--g1.png';\r\nimport icon960 from './regulatory--truck-speed-limit-60--g1.png';\r\nimport icon961 from './regulatory--truck-speed-limit-65--g1.png';\r\nimport icon962 from './regulatory--truck-speed-limit-70--g1.png';\r\nimport icon963 from './regulatory--truck-speed-limit-75--g1.png';\r\nimport icon964 from './regulatory--truck-speed-limit-80--g1.png';\r\nimport icon965 from './regulatory--truck-speed-limit-85--g1.png';\r\nimport icon966 from './regulatory--trucks-and-buses-only--g1.png';\r\nimport icon967 from './regulatory--trucks-on-right--g1.png';\r\nimport icon968 from './regulatory--trucks-only--g1.png';\r\nimport icon969 from './regulatory--turn-left--g1.png';\r\nimport icon970 from './regulatory--turn-left--g2.png';\r\nimport icon971 from './regulatory--turn-left--g3.png';\r\nimport icon972 from './regulatory--turn-left-ahead--g1.png';\r\nimport icon973 from './regulatory--turn-left-ahead--g2.png';\r\nimport icon974 from './regulatory--turn-left-or-right--g1.png';\r\nimport icon975 from './regulatory--turn-left-or-right--g2.png';\r\nimport icon976 from './regulatory--turn-left-or-right--g3.png';\r\nimport icon977 from './regulatory--turn-left-or-u-turn--g1.png';\r\nimport icon978 from './regulatory--turn-right--g1.png';\r\nimport icon979 from './regulatory--turn-right--g2.png';\r\nimport icon980 from './regulatory--turn-right--g3.png';\r\nimport icon981 from './regulatory--turn-right-ahead--g1.png';\r\nimport icon982 from './regulatory--turn-right-ahead--g2.png';\r\nimport icon983 from './regulatory--turning-vehicles-yield-to-pedestrians--g1.png';\r\nimport icon984 from './regulatory--two-stage-right-turn-for-mopeds--g1.png';\r\nimport icon985 from './regulatory--two-way--g1.png';\r\nimport icon986 from './regulatory--u-turn--g1.png';\r\nimport icon987 from './regulatory--u-turn--g2.png';\r\nimport icon988 from './regulatory--u-turn--g3.png';\r\nimport icon989 from './regulatory--use-crosswalk--g1.png';\r\nimport icon990 from './regulatory--vehicles-carrying-dangerous-goods-only--g1.png';\r\nimport icon991 from './regulatory--vehicles-carrying-dangerous-goods-permitted--g1.png';\r\nimport icon992 from './regulatory--vehicles-carrying-explosives-only--g1.png';\r\nimport icon993 from './regulatory--vehicles-carrying-hazardous-goods-permitted--g1.png';\r\nimport icon994 from './regulatory--vehicles-only--g1.png';\r\nimport icon995 from './regulatory--wear-seat-belt--g1.png';\r\nimport icon996 from './regulatory--wear-seat-belt--g2.png';\r\nimport icon997 from './regulatory--wear-seat-belt--g3.png';\r\nimport icon998 from './regulatory--weight-limit--g1.png';\r\nimport icon999 from './regulatory--weight-limit--g2.png';\r\nimport icon1000 from './regulatory--weight-limit--g3.png';\r\nimport icon1001 from './regulatory--weight-limit--g4.png';\r\nimport icon1002 from './regulatory--weight-limit--g5.png';\r\nimport icon1003 from './regulatory--weight-limit--g6.png';\r\nimport icon1004 from './regulatory--weight-limit--g7.png';\r\nimport icon1005 from './regulatory--weight-limit-per-axle--g1.png';\r\nimport icon1006 from './regulatory--weight-limit-per-tandem-axle--g1.png';\r\nimport icon1007 from './regulatory--weight-limit-with-trucks--g1.png';\r\nimport icon1008 from './regulatory--width-limit--g1.png';\r\nimport icon1009 from './regulatory--wrong-way--g1.png';\r\nimport icon1010 from './regulatory--yield--g1.png';\r\nimport icon1011 from './regulatory--yield-or-stop-for-pedestrians--g1.png';\r\nimport icon1012 from './regulatory--your-speed--g1.png';\r\nimport icon1013 from './warning--accident-area--g1.png';\r\nimport icon1014 from './warning--accident-area--g2.png';\r\nimport icon1015 from './warning--accident-area--g3.png';\r\nimport icon1016 from './warning--accident-area--g4.png';\r\nimport icon1017 from './warning--accident-area--g5.png';\r\nimport icon1018 from './warning--accident-area--g6.png';\r\nimport icon1019 from './warning--accident-area--g7.png';\r\nimport icon1020 from './warning--accident-area--g8.png';\r\nimport icon1021 from './warning--added-lane-from-entering-roadway--g1.png';\r\nimport icon1022 from './warning--added-lane-from-entering-roadway--g2.png';\r\nimport icon1023 from './warning--added-lane-left--g1.png';\r\nimport icon1024 from './warning--added-lane-right--g1.png';\r\nimport icon1025 from './warning--animal-drawn-vehicles--g1.png';\r\nimport icon1026 from './warning--arch-bridge--g1.png';\r\nimport icon1027 from './warning--atv-and-snowmobiles--g1.png';\r\nimport icon1028 from './warning--atv-crossing--g1.png';\r\nimport icon1029 from './warning--atv-crossing--g2.png';\r\nimport icon1030 from './warning--axle-restriction--g1.png';\r\nimport icon1031 from './warning--bear-crossing--g1.png';\r\nimport icon1032 from './warning--bear-crossing--g2.png';\r\nimport icon1033 from './warning--bicycles-and-others--g1.png';\r\nimport icon1034 from './warning--bicycles-caution-on-rail-tracks--g1.png';\r\nimport icon1035 from './warning--bicycles-crossing--g1.png';\r\nimport icon1036 from './warning--bicycles-crossing--g2.png';\r\nimport icon1037 from './warning--bicycles-crossing--g3.png';\r\nimport icon1038 from './warning--bicycles-crossing--g4.png';\r\nimport icon1039 from './warning--bollard--g1.png';\r\nimport icon1040 from './warning--bridge--g1.png';\r\nimport icon1041 from './warning--bridge--g2.png';\r\nimport icon1042 from './warning--bus-stop-ahead--g1.png';\r\nimport icon1043 from './warning--bus-stop-ahead--g2.png';\r\nimport icon1044 from './warning--bus-stop-ahead--g3.png';\r\nimport icon1045 from './warning--camel-crossing--g1.png';\r\nimport icon1046 from './warning--camel-crossing--g2.png';\r\nimport icon1047 from './warning--camera--g1.png';\r\nimport icon1048 from './warning--camera--g2.png';\r\nimport icon1049 from './warning--carts--g1.png';\r\nimport icon1050 from './warning--carts--g2.png';\r\nimport icon1051 from './warning--checkpoint--g1.png';\r\nimport icon1052 from './warning--children--g1.png';\r\nimport icon1053 from './warning--children--g2.png';\r\nimport icon1054 from './warning--children--g3.png';\r\nimport icon1055 from './warning--children--g4.png';\r\nimport icon1056 from './warning--children--g6.png';\r\nimport icon1057 from './warning--cliff--g1.png';\r\nimport icon1058 from './warning--cliff--g2.png';\r\nimport icon1059 from './warning--closed-lane-in-triple-lanes--g1.png';\r\nimport icon1060 from './warning--closed-lane-in-triple-lanes--g2.png';\r\nimport icon1061 from './warning--construction-ahead--g1.png';\r\nimport icon1062 from './warning--crossroads--g1.png';\r\nimport icon1063 from './warning--crossroads--g2.png';\r\nimport icon1064 from './warning--crossroads--g3.png';\r\nimport icon1065 from './warning--crossroads--g4.png';\r\nimport icon1066 from './warning--crossroads--g5.png';\r\nimport icon1067 from './warning--crossroads--g6.png';\r\nimport icon1068 from './warning--crossroads-with-priority-to-the-right--g1.png';\r\nimport icon1069 from './warning--curve-left--g1.png';\r\nimport icon1070 from './warning--curve-left--g2.png';\r\nimport icon1071 from './warning--curve-left--g3.png';\r\nimport icon1072 from './warning--curve-left-with-junction--g1.png';\r\nimport icon1073 from './warning--curve-out-intersection-left--g1.png';\r\nimport icon1074 from './warning--curve-out-intersection-right--g1.png';\r\nimport icon1075 from './warning--curve-right--g1.png';\r\nimport icon1076 from './warning--curve-right--g2.png';\r\nimport icon1077 from './warning--curve-right--g3.png';\r\nimport icon1078 from './warning--curve-right-with-junction--g1.png';\r\nimport icon1079 from './warning--dangerous-crosswinds-left--g1.png';\r\nimport icon1080 from './warning--dangerous-crosswinds-left--g2.png';\r\nimport icon1081 from './warning--dangerous-crosswinds-left--g4.png';\r\nimport icon1082 from './warning--dangerous-crosswinds-right--g1.png';\r\nimport icon1083 from './warning--dangerous-crosswinds-right--g2.png';\r\nimport icon1084 from './warning--dangerous-crosswinds-right--g3.png';\r\nimport icon1085 from './warning--dangerous-crosswinds-right--g4.png';\r\nimport icon1086 from './warning--dead-end--g1.png';\r\nimport icon1087 from './warning--dead-end--g2.png';\r\nimport icon1088 from './warning--dead-end--g3.png';\r\nimport icon1089 from './warning--dead-end-go-left--g1.png';\r\nimport icon1090 from './warning--dead-end-go-right--g1.png';\r\nimport icon1091 from './warning--descent-or-climbing-lanes-in-triple-lanes--g1.png';\r\nimport icon1092 from './warning--detour-ahead--g1.png';\r\nimport icon1093 from './warning--detour-or-construction-ahead--g1.png';\r\nimport icon1094 from './warning--dip--g1.png';\r\nimport icon1095 from './warning--dip--g2.png';\r\nimport icon1096 from './warning--disabled-persons-crossing--g1.png';\r\nimport icon1097 from './warning--disabled-persons-crossing--g2.png';\r\nimport icon1098 from './warning--divided-highway--g1.png';\r\nimport icon1099 from './warning--divided-highway--g2.png';\r\nimport icon1100 from './warning--divided-highway--g3.png';\r\nimport icon1101 from './warning--divided-highway--g4.png';\r\nimport icon1102 from './warning--divided-highway--g5.png';\r\nimport icon1103 from './warning--divided-highway--g6.png';\r\nimport icon1104 from './warning--divided-highway--g7.png';\r\nimport icon1105 from './warning--divided-highway--g8.png';\r\nimport icon1106 from './warning--divided-highway--g9.png';\r\nimport icon1107 from './warning--divided-highway-ends--g1.png';\r\nimport icon1108 from './warning--divided-highway-ends--g2.png';\r\nimport icon1109 from './warning--divided-highway-ends--g3.png';\r\nimport icon1110 from './warning--divided-highway-ends--g4.png';\r\nimport icon1111 from './warning--divided-highway-on-left--g1.png';\r\nimport icon1112 from './warning--divided-highway-on-left--g2.png';\r\nimport icon1113 from './warning--divided-highway-on-right--g1.png';\r\nimport icon1114 from './warning--divided-highway-on-right--g2.png';\r\nimport icon1115 from './warning--divided-highway-to-left--g1.png';\r\nimport icon1116 from './warning--divided-highway-to-right--g1.png';\r\nimport icon1117 from './warning--domestic-animals--g1.png';\r\nimport icon1118 from './warning--domestic-animals--g2.png';\r\nimport icon1119 from './warning--domestic-animals--g3.png';\r\nimport icon1120 from './warning--domestic-animals--g4.png';\r\nimport icon1121 from './warning--domestic-animals--g5.png';\r\nimport icon1122 from './warning--domestic-animals--g6.png';\r\nimport icon1123 from './warning--domestic-animals--g7.png';\r\nimport icon1124 from './warning--domestic-animals--g8.png';\r\nimport icon1125 from './warning--double-curve-first-left--g1.png';\r\nimport icon1126 from './warning--double-curve-first-left--g2.png';\r\nimport icon1127 from './warning--double-curve-first-right--g1.png';\r\nimport icon1128 from './warning--double-curve-first-right--g2.png';\r\nimport icon1129 from './warning--double-descent--g1.png';\r\nimport icon1130 from './warning--double-reverse-curve-left--g1.png';\r\nimport icon1131 from './warning--double-reverse-curve-left--g2.png';\r\nimport icon1132 from './warning--double-reverse-curve-right--g1.png';\r\nimport icon1133 from './warning--double-reverse-curve-right--g2.png';\r\nimport icon1134 from './warning--double-side-roads-left--g1.png';\r\nimport icon1135 from './warning--double-side-roads-left--g3.png';\r\nimport icon1136 from './warning--double-side-roads-right--g1.png';\r\nimport icon1137 from './warning--double-side-roads-right--g3.png';\r\nimport icon1138 from './warning--double-turn-first-left--g1.png';\r\nimport icon1139 from './warning--double-turn-first-right--g1.png';\r\nimport icon1140 from './warning--dual-lanes-all-directions-on-left--g1.png';\r\nimport icon1141 from './warning--dual-lanes-all-directions-on-right--g1.png';\r\nimport icon1142 from './warning--dual-lanes-go-straight-or-turn-left--g1.png';\r\nimport icon1143 from './warning--dual-lanes-go-straight-or-turn-right--g1.png';\r\nimport icon1144 from './warning--dual-lanes-left-turn--g1.png';\r\nimport icon1145 from './warning--dual-lanes-left-turn-or-go-straight--g1.png';\r\nimport icon1146 from './warning--dual-lanes-right-turn--g1.png';\r\nimport icon1147 from './warning--dual-lanes-right-turn-or-go-straight--g1.png';\r\nimport icon1148 from './warning--dual-lanes-turn-left--g1.png';\r\nimport icon1149 from './warning--dual-lanes-turn-left-or-right--g1.png';\r\nimport icon1150 from './warning--dual-lanes-turn-left-or-right--g2.png';\r\nimport icon1151 from './warning--dual-lanes-turn-left-or-right--g3.png';\r\nimport icon1152 from './warning--dual-lanes-turn-left-or-right--g4.png';\r\nimport icon1153 from './warning--dual-lanes-turn-right--g1.png';\r\nimport icon1154 from './warning--dual-path-cyclists-and-pedestrians--g1.png';\r\nimport icon1155 from './warning--electricity--g1.png';\r\nimport icon1156 from './warning--electricity--g2.png';\r\nimport icon1157 from './warning--elephant-crossing--g1.png';\r\nimport icon1158 from './warning--emergency-vehicles--g1.png';\r\nimport icon1159 from './warning--emu-crossing--g1.png';\r\nimport icon1160 from './warning--emu-crossing--g2.png';\r\nimport icon1161 from './warning--entering-roadway-merge--g1.png';\r\nimport icon1162 from './warning--entering-roadway-merge--g2.png';\r\nimport icon1163 from './warning--equestrians-crossing--g1.png';\r\nimport icon1164 from './warning--equestrians-crossing--g2.png';\r\nimport icon1165 from './warning--expressway--g1.png';\r\nimport icon1166 from './warning--falling-rocks-or-debris-left--g1.png';\r\nimport icon1167 from './warning--falling-rocks-or-debris-left--g2.png';\r\nimport icon1168 from './warning--falling-rocks-or-debris-left--g3.png';\r\nimport icon1169 from './warning--falling-rocks-or-debris-left--g4.png';\r\nimport icon1170 from './warning--falling-rocks-or-debris-right--g1.png';\r\nimport icon1171 from './warning--falling-rocks-or-debris-right--g2.png';\r\nimport icon1172 from './warning--falling-rocks-or-debris-right--g3.png';\r\nimport icon1173 from './warning--falling-rocks-or-debris-right--g4.png';\r\nimport icon1174 from './warning--ferry--g1.png';\r\nimport icon1175 from './warning--flaggers-in-road--g1.png';\r\nimport icon1176 from './warning--flaggers-in-road--g2.png';\r\nimport icon1177 from './warning--foggy-road--g1.png';\r\nimport icon1178 from './warning--foggy-road--g2.png';\r\nimport icon1179 from './warning--ford--g1.png';\r\nimport icon1180 from './warning--forest--g1.png';\r\nimport icon1181 from './warning--fresh-oil--g1.png';\r\nimport icon1182 from './warning--frog-crossing--g1.png';\r\nimport icon1183 from './warning--gate--g1.png';\r\nimport icon1184 from './warning--gate--g2.png';\r\nimport icon1185 from './warning--gate-left--g1.png';\r\nimport icon1186 from './warning--gate-right--g1.png';\r\nimport icon1187 from './warning--go-left--g1.png';\r\nimport icon1188 from './warning--go-right--g1.png';\r\nimport icon1189 from './warning--golf-carts-crossing--g1.png';\r\nimport icon1190 from './warning--gravel-road-surface--g1.png';\r\nimport icon1191 from './warning--hairpin-curve-left--g1.png';\r\nimport icon1192 from './warning--hairpin-curve-left--g2.png';\r\nimport icon1193 from './warning--hairpin-curve-left--g3.png';\r\nimport icon1194 from './warning--hairpin-curve-right--g1.png';\r\nimport icon1195 from './warning--hairpin-curve-right--g3.png';\r\nimport icon1196 from './warning--height-restriction--g2.png';\r\nimport icon1197 from './warning--height-restriction--g3.png';\r\nimport icon1198 from './warning--height-restriction--g4.png';\r\nimport icon1199 from './warning--height-restriction--g5.png';\r\nimport icon1200 from './warning--horizontal-alignment-left--g1.png';\r\nimport icon1201 from './warning--horizontal-alignment-left--g3.png';\r\nimport icon1202 from './warning--horizontal-alignment-right--g1.png';\r\nimport icon1203 from './warning--horizontal-alignment-right--g3.png';\r\nimport icon1204 from './warning--horse-crossing--g1.png';\r\nimport icon1205 from './warning--icy-road--g1.png';\r\nimport icon1206 from './warning--junction-with-a-side-road-acute-left--g1.png';\r\nimport icon1207 from './warning--junction-with-a-side-road-acute-left--g2.png';\r\nimport icon1208 from './warning--junction-with-a-side-road-acute-right--g1.png';\r\nimport icon1209 from './warning--junction-with-a-side-road-acute-right--g2.png';\r\nimport icon1210 from './warning--junction-with-a-side-road-perpendicular-left--g1.png';\r\nimport icon1211 from './warning--junction-with-a-side-road-perpendicular-left--g2.png';\r\nimport icon1212 from './warning--junction-with-a-side-road-perpendicular-left--g3.png';\r\nimport icon1213 from './warning--junction-with-a-side-road-perpendicular-left--g4.png';\r\nimport icon1214 from './warning--junction-with-a-side-road-perpendicular-right--g1.png';\r\nimport icon1215 from './warning--junction-with-a-side-road-perpendicular-right--g2.png';\r\nimport icon1216 from './warning--junction-with-a-side-road-perpendicular-right--g3.png';\r\nimport icon1217 from './warning--junction-with-a-side-road-perpendicular-right--g4.png';\r\nimport icon1218 from './warning--junction-with-merge-from-left--g1.png';\r\nimport icon1219 from './warning--junction-with-merge-from-right--g1.png';\r\nimport icon1220 from './warning--junction-with-side-roads--g1.png';\r\nimport icon1221 from './warning--kangaloo-crossing--g1.png';\r\nimport icon1222 from './warning--keep-distance--g1.png';\r\nimport icon1223 from './warning--keep-left--g1.png';\r\nimport icon1224 from './warning--keep-right--g1.png';\r\nimport icon1225 from './warning--kiwi-crossing--g1.png';\r\nimport icon1226 from './warning--kiwi-crossing--g2.png';\r\nimport icon1227 from './warning--koala-crossing--g1.png';\r\nimport icon1228 from './warning--koala-crossing--g2.png';\r\nimport icon1229 from './warning--koala-crossing--g3.png';\r\nimport icon1230 from './warning--koala-crossing--g4.png';\r\nimport icon1231 from './warning--lane-closed-in-dual-lanes-left--g1.png';\r\nimport icon1232 from './warning--lane-closed-in-dual-lanes-left--g2.png';\r\nimport icon1233 from './warning--lane-closed-in-dual-lanes-right--g1.png';\r\nimport icon1234 from './warning--lane-closed-in-dual-lanes-right--g2.png';\r\nimport icon1235 from './warning--length-restriction--g1.png';\r\nimport icon1236 from './warning--length-restriction--g2.png';\r\nimport icon1237 from './warning--light-rail-transit-vehicles--g1.png';\r\nimport icon1238 from './warning--limited-lighting-under-trees--g1.png';\r\nimport icon1239 from './warning--logging-vehicles--g1.png';\r\nimport icon1240 from './warning--loop-270-degree--g1.png';\r\nimport icon1241 from './warning--loop-pretzel--g1.png';\r\nimport icon1242 from './warning--loose-road-surface--g1.png';\r\nimport icon1243 from './warning--loose-road-surface--g2.png';\r\nimport icon1244 from './warning--loose-road-surface--g3.png';\r\nimport icon1245 from './warning--loose-road-surface--g4.png';\r\nimport icon1246 from './warning--low-flying-aircraft--g1.png';\r\nimport icon1247 from './warning--low-flying-aircraft--g2.png';\r\nimport icon1248 from './warning--low-flying-aircraft--g3.png';\r\nimport icon1249 from './warning--low-flying-aircraft--g4.png';\r\nimport icon1250 from './warning--low-flying-aircraft--g5.png';\r\nimport icon1251 from './warning--low-flying-aircraft--g6.png';\r\nimport icon1252 from './warning--low-flying-aircraft--g7.png';\r\nimport icon1253 from './warning--low-flying-aircraft--g8.png';\r\nimport icon1254 from './warning--low-ground-clearance--g1.png';\r\nimport icon1255 from './warning--low-ground-clearance--g2.png';\r\nimport icon1256 from './warning--low-ground-clearance--g3.png';\r\nimport icon1257 from './warning--monkey-crossing--g1.png';\r\nimport icon1258 from './warning--motorcycles-crossing--g1.png';\r\nimport icon1259 from './warning--narrow-bridge--g1.png';\r\nimport icon1260 from './warning--narrow-bridge--g2.png';\r\nimport icon1261 from './warning--narrow-bridge--g3.png';\r\nimport icon1262 from './warning--no-passing-zone--g1.png';\r\nimport icon1263 from './warning--no-passing-zone--g2.png';\r\nimport icon1264 from './warning--occupied-lanes--g1.png';\r\nimport icon1265 from './warning--offset-roads--g1.png';\r\nimport icon1266 from './warning--offset-roads--g2.png';\r\nimport icon1267 from './warning--offset-roads--g3.png';\r\nimport icon1268 from './warning--offset-roads--g4.png';\r\nimport icon1269 from './warning--opening-or-swing-bridge--g1.png';\r\nimport icon1270 from './warning--opening-or-swing-bridge--g2.png';\r\nimport icon1271 from './warning--other-danger--g1.png';\r\nimport icon1272 from './warning--other-danger--g2.png';\r\nimport icon1273 from './warning--other-danger--g3.png';\r\nimport icon1274 from './warning--panda-crossing--g1.png';\r\nimport icon1275 from './warning--pass-left-or-right--g1.png';\r\nimport icon1276 from './warning--pass-left-or-right--g2.png';\r\nimport icon1277 from './warning--pass-left-or-right--g3.png';\r\nimport icon1278 from './warning--pavement-ahead--g1.png';\r\nimport icon1279 from './warning--pavement-ends--g1.png';\r\nimport icon1280 from './warning--pavement-ends--g2.png';\r\nimport icon1281 from './warning--pavement-ends--g3.png';\r\nimport icon1282 from './warning--pavement-ends--g4.png';\r\nimport icon1283 from './warning--pavement-ends--g5.png';\r\nimport icon1284 from './warning--pedestrians-crossing--g1.png';\r\nimport icon1285 from './warning--pedestrians-crossing--g4.png';\r\nimport icon1286 from './warning--pedestrians-crossing--g5.png';\r\nimport icon1287 from './warning--pedestrians-crossing--g6.png';\r\nimport icon1288 from './warning--pedestrians-crossing--g7.png';\r\nimport icon1289 from './warning--pedestrians-crossing--g8.png';\r\nimport icon1290 from './warning--pedestrians-crossing--g9.png';\r\nimport icon1291 from './warning--pedestrians-crossing--g10.png';\r\nimport icon1292 from './warning--pedestrians-crossing--g11.png';\r\nimport icon1293 from './warning--pedestrians-crossing--g12.png';\r\nimport icon1294 from './warning--playground--g1.png';\r\nimport icon1295 from './warning--playground--g3.png';\r\nimport icon1296 from './warning--polar-bear-crossing--g1.png';\r\nimport icon1297 from './warning--quay-or-river-bank--g1.png';\r\nimport icon1298 from './warning--quay-or-river-bank--g2.png';\r\nimport icon1299 from './warning--quay-or-river-bank--g3.png';\r\nimport icon1300 from './warning--quay-or-river-bank--g4.png';\r\nimport icon1301 from './warning--rabbit-crossing--g1.png';\r\nimport icon1302 from './warning--raccoon-crossing--g1.png';\r\nimport icon1303 from './warning--railroad-crossing--g1.png';\r\nimport icon1304 from './warning--railroad-crossing--g2.png';\r\nimport icon1305 from './warning--railroad-crossing--g3.png';\r\nimport icon1306 from './warning--railroad-crossing--g4.png';\r\nimport icon1307 from './warning--railroad-crossing-with-barriers--g1.png';\r\nimport icon1308 from './warning--railroad-crossing-with-barriers--g2.png';\r\nimport icon1309 from './warning--railroad-crossing-with-barriers--g3.png';\r\nimport icon1310 from './warning--railroad-crossing-with-barriers--g4.png';\r\nimport icon1311 from './warning--railroad-crossing-with-barriers--g5.png';\r\nimport icon1312 from './warning--railroad-crossing-with-barriers--g6.png';\r\nimport icon1313 from './warning--railroad-crossing-with-barriers--g7.png';\r\nimport icon1314 from './warning--railroad-crossing-without-barriers--g1.png';\r\nimport icon1315 from './warning--railroad-crossing-without-barriers--g2.png';\r\nimport icon1316 from './warning--railroad-crossing-without-barriers--g3.png';\r\nimport icon1317 from './warning--railroad-crossing-without-barriers--g4.png';\r\nimport icon1318 from './warning--railroad-crossing-without-barriers--g5.png';\r\nimport icon1319 from './warning--railroad-crossing-without-barriers--g6.png';\r\nimport icon1320 from './warning--railroad-intersection--g1.png';\r\nimport icon1321 from './warning--railroad-intersection--g2.png';\r\nimport icon1322 from './warning--railroad-intersection--g3.png';\r\nimport icon1323 from './warning--railroad-intersection--g4.png';\r\nimport icon1324 from './warning--railroad-intersection--g5.png';\r\nimport icon1325 from './warning--railroad-intersection--g6.png';\r\nimport icon1326 from './warning--railroad-intersection--g7.png';\r\nimport icon1327 from './warning--railroad-intersection--g8.png';\r\nimport icon1328 from './warning--railroad-intersection--g9.png';\r\nimport icon1329 from './warning--ramp-closed--g1.png';\r\nimport icon1330 from './warning--reduced-maximum-speed-limit--g1.png';\r\nimport icon1331 from './warning--reserved-lane--g1.png';\r\nimport icon1332 from './warning--restricted-zone--g1.png';\r\nimport icon1333 from './warning--reversible-lanes--g1.png';\r\nimport icon1334 from './warning--reversible-lanes--g2.png';\r\nimport icon1335 from './warning--rickshaws-crossing--g1.png';\r\nimport icon1336 from './warning--road-blocks--g1.png';\r\nimport icon1337 from './warning--road-bump--g1.png';\r\nimport icon1338 from './warning--road-bump--g2.png';\r\nimport icon1339 from './warning--road-bump--g3.png';\r\nimport icon1340 from './warning--road-bump-with-speed-limit--g1.png';\r\nimport icon1341 from './warning--road-closed--g3.png';\r\nimport icon1342 from './warning--road-narrows--g1.png';\r\nimport icon1343 from './warning--road-narrows--g2.png';\r\nimport icon1344 from './warning--road-narrows-left--g1.png';\r\nimport icon1345 from './warning--road-narrows-left--g2.png';\r\nimport icon1346 from './warning--road-narrows-left-ahead--g1.png';\r\nimport icon1347 from './warning--road-narrows-right--g1.png';\r\nimport icon1348 from './warning--road-narrows-right--g2.png';\r\nimport icon1349 from './warning--road-narrows-right-ahead--g1.png';\r\nimport icon1350 from './warning--road-toll-ahead--g1.png';\r\nimport icon1351 from './warning--road-widens--g1.png';\r\nimport icon1352 from './warning--road-widens-left--g1.png';\r\nimport icon1353 from './warning--road-widens-right--g1.png';\r\nimport icon1354 from './warning--roadworks--g1.png';\r\nimport icon1355 from './warning--roadworks--g2.png';\r\nimport icon1356 from './warning--roadworks--g3.png';\r\nimport icon1357 from './warning--roadworks--g5.png';\r\nimport icon1358 from './warning--roadworks--g6.png';\r\nimport icon1359 from './warning--roadworks--g8.png';\r\nimport icon1360 from './warning--roadworks--g9.png';\r\nimport icon1361 from './warning--roadworks--g10.png';\r\nimport icon1362 from './warning--roadworks--g11.png';\r\nimport icon1363 from './warning--roadworks-go-left-or-straight--g1.png';\r\nimport icon1364 from './warning--roadworks-go-right-or-straight--g1.png';\r\nimport icon1365 from './warning--roundabout--g1.png';\r\nimport icon1366 from './warning--roundabout--g2.png';\r\nimport icon1367 from './warning--roundabout--g3.png';\r\nimport icon1368 from './warning--roundabout--g4.png';\r\nimport icon1369 from './warning--roundabout--g5.png';\r\nimport icon1370 from './warning--roundabout--g6.png';\r\nimport icon1371 from './warning--roundabout--g7.png';\r\nimport icon1372 from './warning--ruts--g1.png';\r\nimport icon1373 from './warning--sand--g1.png';\r\nimport icon1374 from './warning--sand-drift--g1.png';\r\nimport icon1375 from './warning--school-zone--g2.png';\r\nimport icon1376 from './warning--severe-weather--g1.png';\r\nimport icon1377 from './warning--shared-lane-motorcycles-bicycles--g1.png';\r\nimport icon1378 from './warning--sharp-turn--g1.png';\r\nimport icon1379 from './warning--single-reverse-curve--g1.png';\r\nimport icon1380 from './warning--skewed-t-roads-left--g1.png';\r\nimport icon1381 from './warning--skewed-t-roads-left--g2.png';\r\nimport icon1382 from './warning--skewed-t-roads-left--g3.png';\r\nimport icon1383 from './warning--skewed-t-roads-right--g1.png';\r\nimport icon1384 from './warning--skewed-t-roads-right--g2.png';\r\nimport icon1385 from './warning--skewed-t-roads-right--g3.png';\r\nimport icon1386 from './warning--skiers--g1.png';\r\nimport icon1387 from './warning--skiers--g2.png';\r\nimport icon1388 from './warning--skiers--g3.png';\r\nimport icon1389 from './warning--slippery-bicycles--g1.png';\r\nimport icon1390 from './warning--slippery-motorcycles--g1.png';\r\nimport icon1391 from './warning--slippery-motorcycles--g2.png';\r\nimport icon1392 from './warning--slippery-road-surface--g1.png';\r\nimport icon1393 from './warning--slippery-road-surface--g2.png';\r\nimport icon1394 from './warning--slow--g1.png';\r\nimport icon1395 from './warning--snow-tractors--g1.png';\r\nimport icon1396 from './warning--snowmobiles--g1.png';\r\nimport icon1397 from './warning--snowmobiles--g2.png';\r\nimport icon1398 from './warning--snowmobiles--g3.png';\r\nimport icon1399 from './warning--snowmobiles-and-others--g1.png';\r\nimport icon1400 from './warning--soft-road-surface--g1.png';\r\nimport icon1401 from './warning--soft-road-surface--g2.png';\r\nimport icon1402 from './warning--soft-shoulder--g1.png';\r\nimport icon1403 from './warning--soft-shoulder--g2.png';\r\nimport icon1404 from './warning--soft-shoulder--g3.png';\r\nimport icon1405 from './warning--soft-shoulder--g4.png';\r\nimport icon1406 from './warning--speed-camera--g1.png';\r\nimport icon1407 from './warning--steep-ascent--g1.png';\r\nimport icon1408 from './warning--steep-ascent--g2.png';\r\nimport icon1409 from './warning--steep-ascent--g3.png';\r\nimport icon1410 from './warning--steep-ascent--g4.png';\r\nimport icon1411 from './warning--steep-ascent-and-descent--g1.png';\r\nimport icon1412 from './warning--steep-descent--g1.png';\r\nimport icon1413 from './warning--steep-descent--g2.png';\r\nimport icon1414 from './warning--steep-descent--g3.png';\r\nimport icon1415 from './warning--steep-descent--g4.png';\r\nimport icon1416 from './warning--steep-descent--g5.png';\r\nimport icon1417 from './warning--steep-descent--g6.png';\r\nimport icon1418 from './warning--stop-ahead--g1.png';\r\nimport icon1419 from './warning--stop-ahead--g3.png';\r\nimport icon1420 from './warning--stop-ahead--g4.png';\r\nimport icon1421 from './warning--stop-ahead--g5.png';\r\nimport icon1422 from './warning--stop-ahead--g6.png';\r\nimport icon1423 from './warning--t-roads--g1.png';\r\nimport icon1424 from './warning--t-roads--g2.png';\r\nimport icon1425 from './warning--tanks-crossing--g1.png';\r\nimport icon1426 from './warning--tanks-crossing--g2.png';\r\nimport icon1427 from './warning--texts--g1.png';\r\nimport icon1428 from './warning--texts--g2.png';\r\nimport icon1429 from './warning--texts--g3.png';\r\nimport icon1430 from './warning--towing--g1.png';\r\nimport icon1431 from './warning--tractors--g1.png';\r\nimport icon1432 from './warning--tractors--g2.png';\r\nimport icon1433 from './warning--tractors--g3.png';\r\nimport icon1434 from './warning--tractors--g4.png';\r\nimport icon1435 from './warning--tractors--g5.png';\r\nimport icon1436 from './warning--tractors--g6.png';\r\nimport icon1437 from './warning--tractors--g7.png';\r\nimport icon1438 from './warning--traffic-merges-at-signalized-intersections--g1.png';\r\nimport icon1439 from './warning--traffic-merges-left--g1.png';\r\nimport icon1440 from './warning--traffic-merges-left--g2.png';\r\nimport icon1441 from './warning--traffic-merges-left--g3.png';\r\nimport icon1442 from './warning--traffic-merges-left--g4.png';\r\nimport icon1443 from './warning--traffic-merges-left-and-right--g1.png';\r\nimport icon1444 from './warning--traffic-merges-left-buses--g1.png';\r\nimport icon1445 from './warning--traffic-merges-right--g1.png';\r\nimport icon1446 from './warning--traffic-merges-right--g2.png';\r\nimport icon1447 from './warning--traffic-merges-right--g3.png';\r\nimport icon1448 from './warning--traffic-merges-right-buses--g1.png';\r\nimport icon1449 from './warning--traffic-queues-likely--g1.png';\r\nimport icon1450 from './warning--traffic-queues-likely--g2.png';\r\nimport icon1451 from './warning--traffic-queues-likely--g3.png';\r\nimport icon1452 from './warning--traffic-queues-likely--g4.png';\r\nimport icon1453 from './warning--traffic-queues-likely--g5.png';\r\nimport icon1454 from './warning--traffic-signals--g1.png';\r\nimport icon1455 from './warning--traffic-signals--g2.png';\r\nimport icon1456 from './warning--traffic-signals--g3.png';\r\nimport icon1457 from './warning--traffic-signals--g4.png';\r\nimport icon1458 from './warning--traffic-signals--g5.png';\r\nimport icon1459 from './warning--traffic-signals--g6.png';\r\nimport icon1460 from './warning--traffic-slow--g1.png';\r\nimport icon1461 from './warning--trail-crossing--g1.png';\r\nimport icon1462 from './warning--trail-crossing--g2.png';\r\nimport icon1463 from './warning--trail-crossing--g3.png';\r\nimport icon1464 from './warning--trail-crossing--g4.png';\r\nimport icon1465 from './warning--trail-crossing--g5.png';\r\nimport icon1466 from './warning--trail-crossing--g6.png';\r\nimport icon1467 from './warning--trams-crossing--g1.png';\r\nimport icon1468 from './warning--trams-crossing--g2.png';\r\nimport icon1469 from './warning--triple-curve-left--g1.png';\r\nimport icon1470 from './warning--triple-curve-right--g1.png';\r\nimport icon1471 from './warning--triple-lanes-left-turn--g1.png';\r\nimport icon1472 from './warning--triple-lanes-left-turn-or-go-straight--g1.png';\r\nimport icon1473 from './warning--triple-lanes-right-turn--g1.png';\r\nimport icon1474 from './warning--triple-lanes-right-turn-or-go-straight--g1.png';\r\nimport icon1475 from './warning--triple-lanes-with-directions--g1.png';\r\nimport icon1476 from './warning--triple-reverse-curve-left--g1.png';\r\nimport icon1477 from './warning--triple-reverse-curve-right--g1.png';\r\nimport icon1478 from './warning--trucks-crossing--g1.png';\r\nimport icon1479 from './warning--trucks-crossing--g2.png';\r\nimport icon1480 from './warning--trucks-rollover--g1.png';\r\nimport icon1481 from './warning--trucks-rollover--g2.png';\r\nimport icon1482 from './warning--trucks-rollover--g3.png';\r\nimport icon1483 from './warning--trucks-rollover--g4.png';\r\nimport icon1484 from './warning--trucks-rollover--g5.png';\r\nimport icon1485 from './warning--tunnel--g1.png';\r\nimport icon1486 from './warning--tunnel--g2.png';\r\nimport icon1487 from './warning--tunnel--g3.png';\r\nimport icon1488 from './warning--tunnel--g4.png';\r\nimport icon1489 from './warning--tunnel--g5.png';\r\nimport icon1490 from './warning--tunnel--g6.png';\r\nimport icon1491 from './warning--tunnel--g7.png';\r\nimport icon1492 from './warning--turn-left--g1.png';\r\nimport icon1493 from './warning--turn-left--g2.png';\r\nimport icon1494 from './warning--turn-left--g3.png';\r\nimport icon1495 from './warning--turn-left-or-right--g1.png';\r\nimport icon1496 from './warning--turn-right--g1.png';\r\nimport icon1497 from './warning--turn-right--g2.png';\r\nimport icon1498 from './warning--turn-right--g3.png';\r\nimport icon1499 from './warning--two-way-traffic--g1.png';\r\nimport icon1500 from './warning--two-way-traffic--g2.png';\r\nimport icon1501 from './warning--two-way-traffic--g3.png';\r\nimport icon1502 from './warning--two-way-traffic--g4.png';\r\nimport icon1503 from './warning--two-way-traffic--g5.png';\r\nimport icon1504 from './warning--two-way-traffic--g6.png';\r\nimport icon1505 from './warning--u-turn--g1.png';\r\nimport icon1506 from './warning--u-turn--g2.png';\r\nimport icon1507 from './warning--uneven-road--g1.png';\r\nimport icon1508 from './warning--uneven-road--g2.png';\r\nimport icon1509 from './warning--uneven-roads-ahead--g1.png';\r\nimport icon1510 from './warning--vehicles-and-others--g1.png';\r\nimport icon1511 from './warning--vehicles-crossing--g1.png';\r\nimport icon1512 from './warning--village--g1.png';\r\nimport icon1513 from './warning--weight-limit--g5.png';\r\nimport icon1514 from './warning--weight-limit-per-tandem-axle--g1.png';\r\nimport icon1515 from './warning--width-restriction--g1.png';\r\nimport icon1516 from './warning--width-restriction--g2.png';\r\nimport icon1517 from './warning--width-restriction--g3.png';\r\nimport icon1518 from './warning--width-restriction--g4.png';\r\nimport icon1519 from './warning--wild-animals--g1.png';\r\nimport icon1520 from './warning--wild-animals--g2.png';\r\nimport icon1521 from './warning--wild-animals--g3.png';\r\nimport icon1522 from './warning--wild-animals--g4.png';\r\nimport icon1523 from './warning--wild-animals--g5.png';\r\nimport icon1524 from './warning--wild-animals--g6.png';\r\nimport icon1525 from './warning--wild-animals--g7.png';\r\nimport icon1526 from './warning--wild-animals--g8.png';\r\nimport icon1527 from './warning--wind--g1.png';\r\nimport icon1528 from './warning--winding-road--g1.png';\r\nimport icon1529 from './warning--winding-road-first-left--g1.png';\r\nimport icon1530 from './warning--winding-road-first-left--g2.png';\r\nimport icon1531 from './warning--winding-road-first-left--g3.png';\r\nimport icon1532 from './warning--winding-road-first-right--g1.png';\r\nimport icon1533 from './warning--winding-road-first-right--g2.png';\r\nimport icon1534 from './warning--winding-road-first-right--g3.png';\r\nimport icon1535 from './warning--winding-road-first-right--g4.png';\r\nimport icon1536 from './warning--winding-road-to-left--g1.png';\r\nimport icon1537 from './warning--winding-road-to-right--g1.png';\r\nimport icon1538 from './warning--wombat-crossing--g1.png';\r\nimport icon1539 from './warning--y-roads--g1.png';\r\nimport icon1540 from './warning--y-roads--g2.png';\r\nimport icon1541 from './warning--yield-ahead--g1.png';\r\nimport icon1542 from './warning--yield-ahead--g3.png';\r\n\r\nconst textures = {\r\n 'complementary--accident-area--g1': icon0,\r\n 'complementary--accident-area--g2': icon1,\r\n 'complementary--accident-area--g3': icon2,\r\n 'complementary--accident-area--g4': icon3,\r\n 'complementary--advisory-exit-or-ramp-speed--g1': icon4,\r\n 'complementary--bicycles--g1': icon5,\r\n 'complementary--bicycles-and-pedestrians-detour--g1': icon6,\r\n 'complementary--bicycles-or-pedestrians-detour--g1': icon7,\r\n 'complementary--bicycles-turn-right--g1': icon8,\r\n 'complementary--bike-route--g1': icon9,\r\n 'complementary--bike-route--g3': icon10,\r\n 'complementary--both-directions--g1': icon11,\r\n 'complementary--both-directions--g2': icon12,\r\n 'complementary--buses--g1': icon13,\r\n 'complementary--buses-and-trucks--g1': icon14,\r\n 'complementary--camera--g1': icon15,\r\n 'complementary--camera--g2': icon16,\r\n 'complementary--camera--g3': icon17,\r\n 'complementary--camera--g4': icon18,\r\n 'complementary--camera--g5': icon19,\r\n 'complementary--caravan-trailers--g2': icon20,\r\n 'complementary--caravan-trailers--g3': icon21,\r\n 'complementary--caravans--g2': icon22,\r\n 'complementary--carts--g1': icon23,\r\n 'complementary--chevron-left--g1': icon24,\r\n 'complementary--chevron-left--g2': icon25,\r\n 'complementary--chevron-left--g3': icon26,\r\n 'complementary--chevron-left--g4': icon27,\r\n 'complementary--chevron-left--g5': icon28,\r\n 'complementary--chevron-right--g1': icon29,\r\n 'complementary--chevron-right--g2': icon30,\r\n 'complementary--chevron-right--g3': icon31,\r\n 'complementary--chevron-right--g4': icon32,\r\n 'complementary--chevron-right--g5': icon33,\r\n 'complementary--dangerous-or-pollutant-good--g1': icon34,\r\n 'complementary--dead-end--g1': icon35,\r\n 'complementary--detour--g1': icon36,\r\n 'complementary--disabled-persons--g1': icon37,\r\n 'complementary--distance--g1': icon38,\r\n 'complementary--distance--g2': icon39,\r\n 'complementary--distance--g3': icon40,\r\n 'complementary--end-of-road-works--g1': icon41,\r\n 'complementary--except-bicycles--g1': icon42,\r\n 'complementary--except-bicycles--g2': icon43,\r\n 'complementary--except-buses--g1': icon44,\r\n 'complementary--except-carts--g1': icon45,\r\n 'complementary--except-motorcycles--g1': icon46,\r\n 'complementary--except-motorcycles--g2': icon47,\r\n 'complementary--except-polluting-level-green--g1': icon48,\r\n 'complementary--except-polluting-level-green-yellow--g1': icon49,\r\n 'complementary--except-polluting-level-green-yellow-red--g1': icon50,\r\n 'complementary--except-tractors--g1': icon51,\r\n 'complementary--except-tractors--g2': icon52,\r\n 'complementary--except-trailers--g1': icon53,\r\n 'complementary--except-trailers--g2': icon54,\r\n 'complementary--except-trains--g1': icon55,\r\n 'complementary--except-trams--g1': icon56,\r\n 'complementary--except-trucks--g1': icon57,\r\n 'complementary--except-vehicles--g1': icon58,\r\n 'complementary--except-vehicles--g2': icon59,\r\n 'complementary--go-left--g1': icon60,\r\n 'complementary--go-right--g1': icon61,\r\n 'complementary--go-straight-or-turn-left--g1': icon62,\r\n 'complementary--go-straight-or-turn-right--g1': icon63,\r\n 'complementary--height-limit--g1': icon64,\r\n 'complementary--height-limit--g2': icon65,\r\n 'complementary--including-bicycles-and-motorcycles--g1': icon66,\r\n 'complementary--including-buses-vehicles--g1': icon67,\r\n 'complementary--keep-left--g1': icon68,\r\n 'complementary--keep-right--g1': icon69,\r\n 'complementary--lane-control--g1': icon70,\r\n 'complementary--lane-control--g2': icon71,\r\n 'complementary--lane-control--g3': icon72,\r\n 'complementary--maximum-speed-limit-10--g1': icon73,\r\n 'complementary--maximum-speed-limit-15--g1': icon74,\r\n 'complementary--maximum-speed-limit-20--g1': icon75,\r\n 'complementary--maximum-speed-limit-25--g1': icon76,\r\n 'complementary--maximum-speed-limit-30--g1': icon77,\r\n 'complementary--maximum-speed-limit-35--g1': icon78,\r\n 'complementary--maximum-speed-limit-40--g1': icon79,\r\n 'complementary--maximum-speed-limit-45--g1': icon80,\r\n 'complementary--maximum-speed-limit-50--g1': icon81,\r\n 'complementary--maximum-speed-limit-55--g1': icon82,\r\n 'complementary--maximum-speed-limit-60--g1': icon83,\r\n 'complementary--maximum-speed-limit-65--g1': icon84,\r\n 'complementary--maximum-speed-limit-70--g1': icon85,\r\n 'complementary--maximum-speed-limit-75--g1': icon86,\r\n 'complementary--maximum-speed-limit-80--g1': icon87,\r\n 'complementary--maximum-speed-limit-85--g1': icon88,\r\n 'complementary--maximum-speed-limit-90--g1': icon89,\r\n 'complementary--maximum-speed-limit-95--g1': icon90,\r\n 'complementary--motorcycles--g1': icon91,\r\n 'complementary--motorcycles--g2': icon92,\r\n 'complementary--motorcycles--g3': icon93,\r\n 'complementary--motorcycles--g4': icon94,\r\n 'complementary--obstacle-delineator--g1': icon95,\r\n 'complementary--obstacle-delineator--g2': icon96,\r\n 'complementary--obstacle-delineator--g3': icon97,\r\n 'complementary--one-direction-left--g1': icon98,\r\n 'complementary--one-direction-right--g1': icon99,\r\n 'complementary--pass-left--g1': icon100,\r\n 'complementary--pass-right--g1': icon101,\r\n 'complementary--pedestrians-and-bicycles--g1': icon102,\r\n 'complementary--pedestrians-left--g1': icon103,\r\n 'complementary--pedestrians-right--g1': icon104,\r\n 'complementary--photo-enforced--g1': icon105,\r\n 'complementary--playground--g1': icon106,\r\n 'complementary--priority-route-at-intersection--g1': icon107,\r\n 'complementary--priority-route-at-intersection--g2': icon108,\r\n 'complementary--priority-route-at-intersection--g3': icon109,\r\n 'complementary--priority-route-at-intersection--g4': icon110,\r\n 'complementary--priority-route-at-intersection--g5': icon111,\r\n 'complementary--priority-route-at-intersection--g6': icon112,\r\n 'complementary--railroad--g1': icon113,\r\n 'complementary--railroad--g2': icon114,\r\n 'complementary--railroad--g3': icon115,\r\n 'complementary--restriction-in-both-directions--g1': icon116,\r\n 'complementary--roundabout-go-left--g1': icon117,\r\n 'complementary--roundabout-go-right--g1': icon118,\r\n 'complementary--roundabout-go-straight--g1': icon119,\r\n 'complementary--slippery-for-caravan-trailers--g1': icon120,\r\n 'complementary--snow--g2': icon121,\r\n 'complementary--snow--g4': icon122,\r\n 'complementary--snow--g5': icon123,\r\n 'complementary--snowmobiles--g1': icon124,\r\n 'complementary--soft-shoulder--g1': icon125,\r\n 'complementary--soft-shoulder--g2': icon126,\r\n 'complementary--steep-ascent--g1': icon127,\r\n 'complementary--steep-descent--g1': icon128,\r\n 'complementary--time-restrictions--g1': icon129,\r\n 'complementary--time-restrictions--g3': icon130,\r\n 'complementary--tow-away-zone--g1': icon131,\r\n 'complementary--tow-away-zone--g3': icon132,\r\n 'complementary--tractors--g1': icon133,\r\n 'complementary--traffic-queues--g1': icon134,\r\n 'complementary--trailers--g1': icon135,\r\n 'complementary--trailers--g2': icon136,\r\n 'complementary--trailers--g3': icon137,\r\n 'complementary--trailers--g4': icon138,\r\n 'complementary--trains--g1': icon139,\r\n 'complementary--trams--g1': icon140,\r\n 'complementary--trees--g1': icon141,\r\n 'complementary--trucks--g1': icon142,\r\n 'complementary--trucks--g2': icon143,\r\n 'complementary--trucks--g3': icon144,\r\n 'complementary--trucks-and-trailers--g1': icon145,\r\n 'complementary--trucks-buses-trailers--g1': icon146,\r\n 'complementary--trucks-go-left--g1': icon147,\r\n 'complementary--trucks-go-left-ahead--g1': icon148,\r\n 'complementary--trucks-go-right--g1': icon149,\r\n 'complementary--trucks-go-right-ahead--g1': icon150,\r\n 'complementary--trucks-go-straight--g1': icon151,\r\n 'complementary--trucks-turn-left--g1': icon152,\r\n 'complementary--trucks-turn-right--g1': icon153,\r\n 'complementary--turn-left--g1': icon154,\r\n 'complementary--turn-left--g2': icon155,\r\n 'complementary--turn-right--g1': icon156,\r\n 'complementary--turn-right--g2': icon157,\r\n 'complementary--two-way-traffic--g1': icon158,\r\n 'complementary--two-way-traffic--g2': icon159,\r\n 'complementary--two-way-traffic--g3': icon160,\r\n 'complementary--two-way-traffic--g4': icon161,\r\n 'complementary--two-way-traffic--g5': icon162,\r\n 'complementary--vehicles--g1': icon163,\r\n 'complementary--vehicles--g2': icon164,\r\n 'complementary--vehicles-or-buses--g1': icon165,\r\n 'complementary--weekends-or-holidays--g1': icon166,\r\n 'complementary--weight-limit--g1': icon167,\r\n 'complementary--when-foggy--g1': icon168,\r\n 'complementary--when-rainy--g1': icon169,\r\n 'complementary--when-rainy--g2': icon170,\r\n 'complementary--when-rainy--g3': icon171,\r\n 'complementary--when-snowy--g1': icon172,\r\n 'complementary--when-snowy--g2': icon173,\r\n 'complementary--when-snowy-or-rainy--g1': icon174,\r\n 'complementary--when-snowy-or-rainy--g2': icon175,\r\n 'complementary--when-wet--g1': icon176,\r\n 'complementary--width-limit--g1': icon177,\r\n 'complementary--working-days--g1': icon178,\r\n 'information--airport--g1': icon179,\r\n 'information--airport--g2': icon180,\r\n 'information--bicycle-lane--g1': icon181,\r\n 'information--bicycles-both-ways--g1': icon182,\r\n 'information--bicycles-crossing--g1': icon183,\r\n 'information--bicycles-crossing--g2': icon184,\r\n 'information--bicycles-crossing--g3': icon185,\r\n 'information--bike-route--g1': icon186,\r\n 'information--bike-route--g2': icon187,\r\n 'information--built-up-area--g1': icon188,\r\n 'information--built-up-area--g2': icon189,\r\n 'information--bus-lane-straight--g1': icon190,\r\n 'information--bus-stop--g1': icon191,\r\n 'information--bus-stop--g2': icon192,\r\n 'information--camera--g1': icon193,\r\n 'information--camera--g2': icon194,\r\n 'information--camera--g3': icon195,\r\n 'information--camp--g1': icon196,\r\n 'information--camp--g2': icon197,\r\n 'information--car-pool-lane--g1': icon198,\r\n 'information--caravan-parking--g1': icon199,\r\n 'information--caravan-trailer-parking--g1': icon200,\r\n 'information--cargo-loading-zone--g1': icon201,\r\n 'information--central-lane--g1': icon202,\r\n 'information--charging-station--g1': icon203,\r\n 'information--children--g1': icon204,\r\n 'information--children--g2': icon205,\r\n 'information--children-crossing--g5': icon206,\r\n 'information--cycling-two-abreast-permitted--g1': icon207,\r\n 'information--dead-end--g1': icon208,\r\n 'information--dead-end--g2': icon209,\r\n 'information--dead-end--g3': icon210,\r\n 'information--dead-end--g4': icon211,\r\n 'information--dead-end-except-bicycles--g1': icon212,\r\n 'information--dead-end-except-bicycles-and-pedestrians--g1': icon213,\r\n 'information--dead-end-except-bicycles-and-pedestrians--g2': icon214,\r\n 'information--dead-end-left--g1': icon215,\r\n 'information--dead-end-left--g2': icon216,\r\n 'information--dead-end-right--g1': icon217,\r\n 'information--dead-end-right--g2': icon218,\r\n 'information--dead-end-right--g3': icon219,\r\n 'information--directions--g1': icon220,\r\n 'information--disabled-persons--g1': icon221,\r\n 'information--disabled-persons--g2': icon222,\r\n 'information--disabled-persons--g3': icon223,\r\n 'information--emergency-facility--g1': icon224,\r\n 'information--end-of-advisory-maximum-speed-limit-20--g1': icon225,\r\n 'information--end-of-advisory-maximum-speed-limit-40--g1': icon226,\r\n 'information--end-of-advisory-maximum-speed-limit-60--g1': icon227,\r\n 'information--end-of-advisory-maximum-speed-limit-70--g1': icon228,\r\n 'information--end-of-advisory-maximum-speed-limit-80--g1': icon229,\r\n 'information--end-of-advisory-maximum-speed-limit-90--g1': icon230,\r\n 'information--end-of-bicycle-lane--g1': icon231,\r\n 'information--end-of-built-up-area--g1': icon232,\r\n 'information--end-of-built-up-area--g2': icon233,\r\n 'information--end-of-built-up-area--g3': icon234,\r\n 'information--end-of-built-up-area--g4': icon235,\r\n 'information--end-of-car-pool-lane--g1': icon236,\r\n 'information--end-of-limited-access-road--g1': icon237,\r\n 'information--end-of-living-street--g1': icon238,\r\n 'information--end-of-living-street--g2': icon239,\r\n 'information--end-of-minimum-speed-10--g1': icon240,\r\n 'information--end-of-minimum-speed-20--g1': icon241,\r\n 'information--end-of-minimum-speed-25--g1': icon242,\r\n 'information--end-of-minimum-speed-30--g1': icon243,\r\n 'information--end-of-minimum-speed-35--g1': icon244,\r\n 'information--end-of-minimum-speed-40--g1': icon245,\r\n 'information--end-of-minimum-speed-50--g1': icon246,\r\n 'information--end-of-minimum-speed-60--g1': icon247,\r\n 'information--end-of-minimum-speed-70--g1': icon248,\r\n 'information--end-of-minimum-speed-75--g1': icon249,\r\n 'information--end-of-minimum-speed-80--g1': icon250,\r\n 'information--end-of-minimum-speed-90--g1': icon251,\r\n 'information--end-of-minimum-speed-100--g1': icon252,\r\n 'information--end-of-minimum-speed-110--g1': icon253,\r\n 'information--end-of-minimum-speed-120--g1': icon254,\r\n 'information--end-of-minimum-speed-130--g1': icon255,\r\n 'information--end-of-motorway--g1': icon256,\r\n 'information--end-of-overtaking-permitted-heavy-good-vehicles--g1': icon257,\r\n 'information--end-of-road-works--g1': icon258,\r\n 'information--end-of-tunnel--g1': icon259,\r\n 'information--end-of-tunnel--g2': icon260,\r\n 'information--end-of-two-way-traffic--g1': icon261,\r\n 'information--equestrians-permitted--g1': icon262,\r\n 'information--exit-ahead--g1': icon263,\r\n 'information--exit-ahead--g2': icon264,\r\n 'information--exit-ahead--g3': icon265,\r\n 'information--flight-port--g1': icon266,\r\n 'information--food--g1': icon267,\r\n 'information--food--g2': icon268,\r\n 'information--gas-station--g1': icon269,\r\n 'information--gas-station--g2': icon270,\r\n 'information--gas-station--g3': icon271,\r\n 'information--general-speed-limit-at-city-border--g1': icon272,\r\n 'information--go-left--g1': icon273,\r\n 'information--go-right--g1': icon274,\r\n 'information--go-straight--g1': icon275,\r\n 'information--go-straight-or-left--g1': icon276,\r\n 'information--go-straight-or-right--g1': icon277,\r\n 'information--go-straight-or-turn-left--g1': icon278,\r\n 'information--go-straight-or-turn-right--g1': icon279,\r\n 'information--hazardous-goods-vehicles-lane--g1': icon280,\r\n 'information--height-limit--g1': icon281,\r\n 'information--height-limit--g2': icon282,\r\n 'information--highway-directions--g1': icon283,\r\n 'information--highway-exit--g1': icon284,\r\n 'information--highway-interchange--g1': icon285,\r\n 'information--highway-interstate-route--g1': icon286,\r\n 'information--highway-interstate-route--g2': icon287,\r\n 'information--highway-preferential-lane--g1': icon288,\r\n 'information--highway-preferential-lane--g2': icon289,\r\n 'information--highway-reference-location--g1': icon290,\r\n 'information--highway-reference-location--g2': icon291,\r\n 'information--hiking--g1': icon292,\r\n 'information--hospital--g1': icon293,\r\n 'information--hurricane-evacuation-route--g1': icon294,\r\n 'information--interstate-route--g1': icon295,\r\n 'information--lane-control-intersections--g1': icon296,\r\n 'information--lane-control-left-turn--g1': icon297,\r\n 'information--lane-control-multiple-lanes--g1': icon298,\r\n 'information--lane-control-multiple-lanes--g2': icon299,\r\n 'information--lane-control-right-turn--g1': icon300,\r\n 'information--limited-access-road--g1': icon301,\r\n 'information--litter-container--g1': icon302,\r\n 'information--living-street--g1': icon303,\r\n 'information--living-street--g2': icon304,\r\n 'information--living-street--g3': icon305,\r\n 'information--lodging--g1': icon306,\r\n 'information--lodging--g2': icon307,\r\n 'information--minimum-speed-10--g1': icon308,\r\n 'information--minimum-speed-20--g1': icon309,\r\n 'information--minimum-speed-25--g1': icon310,\r\n 'information--minimum-speed-30--g1': icon311,\r\n 'information--minimum-speed-35--g1': icon312,\r\n 'information--minimum-speed-40--g1': icon313,\r\n 'information--minimum-speed-50--g1': icon314,\r\n 'information--minimum-speed-60--g1': icon315,\r\n 'information--minimum-speed-70--g1': icon316,\r\n 'information--minimum-speed-75--g1': icon317,\r\n 'information--minimum-speed-80--g1': icon318,\r\n 'information--minimum-speed-90--g1': icon319,\r\n 'information--minimum-speed-100--g1': icon320,\r\n 'information--minimum-speed-110--g1': icon321,\r\n 'information--minimum-speed-120--g1': icon322,\r\n 'information--minimum-speed-130--g1': icon323,\r\n 'information--motorway--g1': icon324,\r\n 'information--motorway-exit-ahead--g1': icon325,\r\n 'information--motorway-exit-ahead--g2': icon326,\r\n 'information--motorway-exit-ahead--g3': icon327,\r\n 'information--overtaking-allowed-heavy-good-vehicles--g1': icon328,\r\n 'information--parallel-parking--g1': icon329,\r\n 'information--park-and-ride--g1': icon330,\r\n 'information--park-and-ride--g2': icon331,\r\n 'information--parking--g1': icon332,\r\n 'information--parking--g2': icon333,\r\n 'information--parking--g3': icon334,\r\n 'information--parking--g4': icon335,\r\n 'information--parking--g5': icon336,\r\n 'information--parking--g6': icon337,\r\n 'information--parking-area--g1': icon338,\r\n 'information--parking-with-restrictions--g1': icon339,\r\n 'information--pass-on-either-side--g1': icon340,\r\n 'information--passenger-loading-zone--g1': icon341,\r\n 'information--pedestrians-crossing--g1': icon342,\r\n 'information--pedestrians-crossing--g2': icon343,\r\n 'information--pedestrians-crossing--g3': icon344,\r\n 'information--pedestrians-only--g4': icon345,\r\n 'information--pedestrians-permitted--g1': icon346,\r\n 'information--perpendicular-parking--g1': icon347,\r\n 'information--picnic-site--g1': icon348,\r\n 'information--playground--g1': icon349,\r\n 'information--recreational-vehicle-sanitary-station--g1': icon350,\r\n 'information--recycle-collection-center--g1': icon351,\r\n 'information--rest-area--g1': icon352,\r\n 'information--road-bump--g1': icon353,\r\n 'information--road-skating--g1': icon354,\r\n 'information--safety-zone--g1': icon355,\r\n 'information--safety-zone--g2': icon356,\r\n 'information--safety-zone--g3': icon357,\r\n 'information--shared-path-vehicles-and-motorcycles--g1': icon358,\r\n 'information--stairs--g1': icon359,\r\n 'information--stairs--g2': icon360,\r\n 'information--stairs--g3': icon361,\r\n 'information--stairs--g4': icon362,\r\n 'information--stop-line--g1': icon363,\r\n 'information--stop-permitted--g1': icon364,\r\n 'information--street-name-one-line--g1': icon365,\r\n 'information--street-name-three-lines--g1': icon366,\r\n 'information--street-name-two-lines--g1': icon367,\r\n 'information--subway--g1': icon368,\r\n 'information--telephone--g1': icon369,\r\n 'information--telephone--g2': icon370,\r\n 'information--telephone-device-for-the-deaf--g1': icon371,\r\n 'information--toll-station--g1': icon372,\r\n 'information--tourism-information--g1': icon373,\r\n 'information--tourist-attraction--g1': icon374,\r\n 'information--traffic-merges-left--g1': icon375,\r\n 'information--traffic-merges-right--g1': icon376,\r\n 'information--trail-crossing--g1': icon377,\r\n 'information--trail-crossing--g2': icon378,\r\n 'information--trail-crossing--g3': icon379,\r\n 'information--trailer-camping--g1': icon380,\r\n 'information--train-or-light-rail-station--g1': icon381,\r\n 'information--tram-bus-stop--g1': icon382,\r\n 'information--tram-bus-stop--g2': icon383,\r\n 'information--trams-crossing--g1': icon384,\r\n 'information--truck-lane-left--g1': icon385,\r\n 'information--truck-parking--g1': icon386,\r\n 'information--truck-trailer-lane-right--g1': icon387,\r\n 'information--truck-trailer-lane-straight--g1': icon388,\r\n 'information--trucks-both-ways--g1': icon389,\r\n 'information--trucks-only--g1': icon390,\r\n 'information--tsunami-evacuation_route--g1': icon391,\r\n 'information--tunnel--g1': icon392,\r\n 'information--tunnel--g2': icon393,\r\n 'information--tunnel--g3': icon394,\r\n 'information--tunnel-ahead--g1': icon395,\r\n 'information--turn-left--g1': icon396,\r\n 'information--turn-left-ahead--g1': icon397,\r\n 'information--turn-right--g1': icon398,\r\n 'information--turn-right-ahead--g1': icon399,\r\n 'information--urban-area--g1': icon400,\r\n 'information--vehicles-on-rails--g1': icon401,\r\n 'information--water-protection-zone--g1': icon402,\r\n 'information--weight-and-height-limit--g1': icon403,\r\n 'information--weight-limit--g1': icon404,\r\n 'information--wireless-internet--g1': icon405,\r\n 'regulatory--advisory-maximum-speed-limit--g1': icon406,\r\n 'regulatory--all-directions-permitted--g1': icon407,\r\n 'regulatory--all-way--g1': icon408,\r\n 'regulatory--atvs-permitted--g1': icon409,\r\n 'regulatory--axle-limit--g1': icon410,\r\n 'regulatory--axle-limit--g2': icon411,\r\n 'regulatory--bicycle-lane-left--g1': icon412,\r\n 'regulatory--bicycle-parking--g1': icon413,\r\n 'regulatory--bicycles-and-buses-only--g1': icon414,\r\n 'regulatory--bicycles-only--g1': icon415,\r\n 'regulatory--bicycles-only--g2': icon416,\r\n 'regulatory--bicycles-only--g3': icon417,\r\n 'regulatory--bicycles-only--g4': icon418,\r\n 'regulatory--bicycles-push-button--g1': icon419,\r\n 'regulatory--bicycles-push-button--g2': icon420,\r\n 'regulatory--bicycles-stop-on-red--g1': icon421,\r\n 'regulatory--bicycles-wrong-way--g1': icon422,\r\n 'regulatory--bicycles-yield-or-use-signal--g1': icon423,\r\n 'regulatory--bike-route--g1': icon424,\r\n 'regulatory--building-direction--g1': icon425,\r\n 'regulatory--bus-priority-lane--g1': icon426,\r\n 'regulatory--buses-and-taxi-only--g1': icon427,\r\n 'regulatory--buses-only--g1': icon428,\r\n 'regulatory--buses-only--g2': icon429,\r\n 'regulatory--circular-intersection--g1': icon430,\r\n 'regulatory--circular-intersection--g2': icon431,\r\n 'regulatory--circular-intersection--g3': icon432,\r\n 'regulatory--circular-intersection--g4': icon433,\r\n 'regulatory--cross-only-on-green--g1': icon434,\r\n 'regulatory--cross-only-on-pedestrian-signal--g1': icon435,\r\n 'regulatory--crosswalk-stop-on-red--g1': icon436,\r\n 'regulatory--cycling-restriction--g1': icon437,\r\n 'regulatory--cyclists-dismount-and-walk--g1': icon438,\r\n 'regulatory--detour-left--g1': icon439,\r\n 'regulatory--detour-right--g1': icon440,\r\n 'regulatory--divided-highway-crossing--g1': icon441,\r\n 'regulatory--divided-highway-ends--g1': icon442,\r\n 'regulatory--divided-highway-starts--g1': icon443,\r\n 'regulatory--do-not-block-intersection--g1': icon444,\r\n 'regulatory--do-not-pass--g1': icon445,\r\n 'regulatory--do-not-stop-on-tracks--g1': icon446,\r\n 'regulatory--dual-lanes-all-directions-on-left--g1': icon447,\r\n 'regulatory--dual-lanes-all-directions-on-right--g1': icon448,\r\n 'regulatory--dual-lanes-bicyclists-and-pedestrians--g1': icon449,\r\n 'regulatory--dual-lanes-go-left-or-right--g1': icon450,\r\n 'regulatory--dual-lanes-go-straight-on-left--g1': icon451,\r\n 'regulatory--dual-lanes-go-straight-on-right--g1': icon452,\r\n 'regulatory--dual-lanes-turn-left--g1': icon453,\r\n 'regulatory--dual-lanes-turn-left-no-u-turn--g1': icon454,\r\n 'regulatory--dual-lanes-turn-left-or-straight--g1': icon455,\r\n 'regulatory--dual-lanes-turn-right-or-straight--g1': icon456,\r\n 'regulatory--dual-path-bicycles-and-pedestrians--g1': icon457,\r\n 'regulatory--dual-path-bicycles-and-pedestrians--g2': icon458,\r\n 'regulatory--dual-path-bicycles-and-pedestrians--g3': icon459,\r\n 'regulatory--dual-path-equestrians-and-pedestrians--g1': icon460,\r\n 'regulatory--dual-path-equestrians-and-pedestrians-bicycles--g1': icon461,\r\n 'regulatory--dual-path-pedestrians-and-bicycles--g1': icon462,\r\n 'regulatory--dual-path-pedestrians-and-bicycles--g2': icon463,\r\n 'regulatory--dual-path-pedestrians-and-equestrians--g1': icon464,\r\n 'regulatory--dual-path-pedestrians-bicycles-and-equestrians--g1': icon465,\r\n 'regulatory--dual-speed-limits--g1': icon466,\r\n 'regulatory--dual-speed-limits--g2': icon467,\r\n 'regulatory--end-of-bicycles-only--g1': icon468,\r\n 'regulatory--end-of-bicycles-only--g2': icon469,\r\n 'regulatory--end-of-bus-and-taxi-only--g1': icon470,\r\n 'regulatory--end-of-buses-only--g1': icon471,\r\n 'regulatory--end-of-buses-only--g2': icon472,\r\n 'regulatory--end-of-cycling-restriction--g1': icon473,\r\n 'regulatory--end-of-dual-path-bicycles-and-pedestrians--g1': icon474,\r\n 'regulatory--end-of-dual-path-pedestrians-and-bicycles--g1': icon475,\r\n 'regulatory--end-of-equestrians-only--g1': icon476,\r\n 'regulatory--end-of-low-beam-headlights--g1': icon477,\r\n 'regulatory--end-of-maximum-speed-limit-10--g1': icon478,\r\n 'regulatory--end-of-maximum-speed-limit-10--g2': icon479,\r\n 'regulatory--end-of-maximum-speed-limit-20--g1': icon480,\r\n 'regulatory--end-of-maximum-speed-limit-20--g2': icon481,\r\n 'regulatory--end-of-maximum-speed-limit-25--g1': icon482,\r\n 'regulatory--end-of-maximum-speed-limit-25--g2': icon483,\r\n 'regulatory--end-of-maximum-speed-limit-30--g1': icon484,\r\n 'regulatory--end-of-maximum-speed-limit-30--g2': icon485,\r\n 'regulatory--end-of-maximum-speed-limit-35--g1': icon486,\r\n 'regulatory--end-of-maximum-speed-limit-35--g2': icon487,\r\n 'regulatory--end-of-maximum-speed-limit-40--g1': icon488,\r\n 'regulatory--end-of-maximum-speed-limit-40--g2': icon489,\r\n 'regulatory--end-of-maximum-speed-limit-50--g1': icon490,\r\n 'regulatory--end-of-maximum-speed-limit-50--g2': icon491,\r\n 'regulatory--end-of-maximum-speed-limit-60--g1': icon492,\r\n 'regulatory--end-of-maximum-speed-limit-60--g2': icon493,\r\n 'regulatory--end-of-maximum-speed-limit-65--g1': icon494,\r\n 'regulatory--end-of-maximum-speed-limit-65--g2': icon495,\r\n 'regulatory--end-of-maximum-speed-limit-70--g1': icon496,\r\n 'regulatory--end-of-maximum-speed-limit-70--g2': icon497,\r\n 'regulatory--end-of-maximum-speed-limit-75--g1': icon498,\r\n 'regulatory--end-of-maximum-speed-limit-75--g2': icon499,\r\n 'regulatory--end-of-maximum-speed-limit-80--g1': icon500,\r\n 'regulatory--end-of-maximum-speed-limit-80--g2': icon501,\r\n 'regulatory--end-of-maximum-speed-limit-90--g1': icon502,\r\n 'regulatory--end-of-maximum-speed-limit-90--g2': icon503,\r\n 'regulatory--end-of-maximum-speed-limit-100--g1': icon504,\r\n 'regulatory--end-of-maximum-speed-limit-100--g2': icon505,\r\n 'regulatory--end-of-maximum-speed-limit-110--g1': icon506,\r\n 'regulatory--end-of-maximum-speed-limit-110--g2': icon507,\r\n 'regulatory--end-of-maximum-speed-limit-120--g1': icon508,\r\n 'regulatory--end-of-maximum-speed-limit-120--g2': icon509,\r\n 'regulatory--end-of-maximum-speed-limit-130--g1': icon510,\r\n 'regulatory--end-of-maximum-speed-limit-130--g2': icon511,\r\n 'regulatory--end-of-maximum-speed-limit--g1': icon512,\r\n 'regulatory--end-of-mopeds-and-bicycles-only--g1': icon513,\r\n 'regulatory--end-of-no-heavy-goods-vehicles--g1': icon514,\r\n 'regulatory--end-of-no-horn--g1': icon515,\r\n 'regulatory--end-of-no-overtaking--g1': icon516,\r\n 'regulatory--end-of-no-overtaking--g2': icon517,\r\n 'regulatory--end-of-no-overtaking--g3': icon518,\r\n 'regulatory--end-of-no-overtaking--g4': icon519,\r\n 'regulatory--end-of-no-overtaking--g5': icon520,\r\n 'regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g1': icon521,\r\n 'regulatory--end-of-no-overtaking-by-heavy-goods-vehicles--g2': icon522,\r\n 'regulatory--end-of-no-overtaking-by-motorcycles--g1': icon523,\r\n 'regulatory--end-of-no-parking--g1': icon524,\r\n 'regulatory--end-of-no-parking--g2': icon525,\r\n 'regulatory--end-of-no-parking-or-stopping--g1': icon526,\r\n 'regulatory--end-of-one-way-straight--g1': icon527,\r\n 'regulatory--end-of-parking-zone--g1': icon528,\r\n 'regulatory--end-of-parking-zone--g2': icon529,\r\n 'regulatory--end-of-pedestrians-only--g1': icon530,\r\n 'regulatory--end-of-pedestrians-only--g2': icon531,\r\n 'regulatory--end-of-pedestrians-only--g3': icon532,\r\n 'regulatory--end-of-pedestrians-only--g4': icon533,\r\n 'regulatory--end-of-priority-road--g1': icon534,\r\n 'regulatory--end-of-prohibition--g1': icon535,\r\n 'regulatory--end-of-school-zone--g1': icon536,\r\n 'regulatory--end-of-shared-path-bicycles-and-pedestrians--g1': icon537,\r\n 'regulatory--end-of-shared-path-pedestrians-and-bicycles--g1': icon538,\r\n 'regulatory--end-of-snow-chains--g1': icon539,\r\n 'regulatory--end-of-snow-chains--g2': icon540,\r\n 'regulatory--end-of-snowmobiles-only--g1': icon541,\r\n 'regulatory--end-of-speed-limit-zone--g1': icon542,\r\n 'regulatory--end-of-speed-limit-zone--g2': icon543,\r\n 'regulatory--end-of-speed-limit-zone--g3': icon544,\r\n 'regulatory--end-of-tractors-only--g1': icon545,\r\n 'regulatory--end-of-trams-and-buses-only--g1': icon546,\r\n 'regulatory--end-of-trams-only--g1': icon547,\r\n 'regulatory--end-of-trucks-and-buses-only--g1': icon548,\r\n 'regulatory--end-of-trucks-only--g1': icon549,\r\n 'regulatory--end-of-trucks-only--g2': icon550,\r\n 'regulatory--equestrians-only--g1': icon551,\r\n 'regulatory--except-railroad-crossing--g1': icon552,\r\n 'regulatory--fine-for-littering--g1': icon553,\r\n 'regulatory--give-way-to-bicycles--g1': icon554,\r\n 'regulatory--give-way-to-oncoming-traffic--g1': icon555,\r\n 'regulatory--give-way-to-oncoming-traffic--g2': icon556,\r\n 'regulatory--go-left-bicycles--g1': icon557,\r\n 'regulatory--go-right-bicycles--g1': icon558,\r\n 'regulatory--go-straight--g1': icon559,\r\n 'regulatory--go-straight--g3': icon560,\r\n 'regulatory--go-straight-bicycles--g1': icon561,\r\n 'regulatory--go-straight-or-turn-left--g1': icon562,\r\n 'regulatory--go-straight-or-turn-left--g2': icon563,\r\n 'regulatory--go-straight-or-turn-left--g3': icon564,\r\n 'regulatory--go-straight-or-turn-right--g1': icon565,\r\n 'regulatory--go-straight-or-turn-right--g2': icon566,\r\n 'regulatory--go-straight-or-turn-right--g3': icon567,\r\n 'regulatory--heavy-goods-vehicles-permitted--g1': icon568,\r\n 'regulatory--height-limit--g1': icon569,\r\n 'regulatory--high-beam-headlights--g1': icon570,\r\n 'regulatory--horn--g1': icon571,\r\n 'regulatory--in-street-pedestrian-crossing--g1': icon572,\r\n 'regulatory--keep-left--g1': icon573,\r\n 'regulatory--keep-left--g2': icon574,\r\n 'regulatory--keep-left--g3': icon575,\r\n 'regulatory--keep-left--g4': icon576,\r\n 'regulatory--keep-left--g5': icon577,\r\n 'regulatory--keep-left--g6': icon578,\r\n 'regulatory--keep-left--g7': icon579,\r\n 'regulatory--keep-right--g1': icon580,\r\n 'regulatory--keep-right--g2': icon581,\r\n 'regulatory--keep-right--g3': icon582,\r\n 'regulatory--keep-right--g4': icon583,\r\n 'regulatory--keep-right--g5': icon584,\r\n 'regulatory--keep-right--g6': icon585,\r\n 'regulatory--keep-right--g7': icon586,\r\n 'regulatory--keep-right--g8': icon587,\r\n 'regulatory--keep-right--g9': icon588,\r\n 'regulatory--lane-control--g1': icon589,\r\n 'regulatory--left-turn-yield-on-green--g1': icon590,\r\n 'regulatory--length-limit--g1': icon591,\r\n 'regulatory--length-limit--g2': icon592,\r\n 'regulatory--light-rail-divided-highway--g1': icon593,\r\n 'regulatory--light-rail-do-not-pass--g1': icon594,\r\n 'regulatory--light-rail-only--g1': icon595,\r\n 'regulatory--look--g1': icon596,\r\n 'regulatory--low-beam-headlights--g1': icon597,\r\n 'regulatory--low-beam-headlights--g2': icon598,\r\n 'regulatory--low-beam-headlights--g3': icon599,\r\n 'regulatory--low-speed-vehicle-permitted--g1': icon600,\r\n 'regulatory--maximum-speed-limit-5--g1': icon601,\r\n 'regulatory--maximum-speed-limit-5--g3': icon602,\r\n 'regulatory--maximum-speed-limit-10--g1': icon603,\r\n 'regulatory--maximum-speed-limit-10--g3': icon604,\r\n 'regulatory--maximum-speed-limit-15--g1': icon605,\r\n 'regulatory--maximum-speed-limit-15--g3': icon606,\r\n 'regulatory--maximum-speed-limit-20--g1': icon607,\r\n 'regulatory--maximum-speed-limit-20--g3': icon608,\r\n 'regulatory--maximum-speed-limit-25--g1': icon609,\r\n 'regulatory--maximum-speed-limit-25--g2': icon610,\r\n 'regulatory--maximum-speed-limit-30--g1': icon611,\r\n 'regulatory--maximum-speed-limit-30--g3': icon612,\r\n 'regulatory--maximum-speed-limit-35--g1': icon613,\r\n 'regulatory--maximum-speed-limit-35--g2': icon614,\r\n 'regulatory--maximum-speed-limit-40--g1': icon615,\r\n 'regulatory--maximum-speed-limit-40--g3': icon616,\r\n 'regulatory--maximum-speed-limit-45--g1': icon617,\r\n 'regulatory--maximum-speed-limit-45--g3': icon618,\r\n 'regulatory--maximum-speed-limit-50--g1': icon619,\r\n 'regulatory--maximum-speed-limit-50--g3': icon620,\r\n 'regulatory--maximum-speed-limit-55--g2': icon621,\r\n 'regulatory--maximum-speed-limit-60--g1': icon622,\r\n 'regulatory--maximum-speed-limit-60--g3': icon623,\r\n 'regulatory--maximum-speed-limit-65--g1': icon624,\r\n 'regulatory--maximum-speed-limit-65--g2': icon625,\r\n 'regulatory--maximum-speed-limit-70--g1': icon626,\r\n 'regulatory--maximum-speed-limit-70--g3': icon627,\r\n 'regulatory--maximum-speed-limit-75--g2': icon628,\r\n 'regulatory--maximum-speed-limit-80--g1': icon629,\r\n 'regulatory--maximum-speed-limit-80--g3': icon630,\r\n 'regulatory--maximum-speed-limit-85--g2': icon631,\r\n 'regulatory--maximum-speed-limit-90--g1': icon632,\r\n 'regulatory--maximum-speed-limit-90--g3': icon633,\r\n 'regulatory--maximum-speed-limit-100--g1': icon634,\r\n 'regulatory--maximum-speed-limit-100--g3': icon635,\r\n 'regulatory--maximum-speed-limit-110--g1': icon636,\r\n 'regulatory--maximum-speed-limit-110--g3': icon637,\r\n 'regulatory--maximum-speed-limit-120--g1': icon638,\r\n 'regulatory--maximum-speed-limit-120--g3': icon639,\r\n 'regulatory--maximum-speed-limit-130--g1': icon640,\r\n 'regulatory--maximum-speed-limit-130--g3': icon641,\r\n 'regulatory--maximum-speed-limit-led-5--g2': icon642,\r\n 'regulatory--maximum-speed-limit-led-5--g3': icon643,\r\n 'regulatory--maximum-speed-limit-led-10--g1': icon644,\r\n 'regulatory--maximum-speed-limit-led-10--g2': icon645,\r\n 'regulatory--maximum-speed-limit-led-10--g3': icon646,\r\n 'regulatory--maximum-speed-limit-led-15--g2': icon647,\r\n 'regulatory--maximum-speed-limit-led-15--g3': icon648,\r\n 'regulatory--maximum-speed-limit-led-20--g1': icon649,\r\n 'regulatory--maximum-speed-limit-led-20--g2': icon650,\r\n 'regulatory--maximum-speed-limit-led-20--g3': icon651,\r\n 'regulatory--maximum-speed-limit-led-25--g1': icon652,\r\n 'regulatory--maximum-speed-limit-led-25--g2': icon653,\r\n 'regulatory--maximum-speed-limit-led-25--g3': icon654,\r\n 'regulatory--maximum-speed-limit-led-30--g1': icon655,\r\n 'regulatory--maximum-speed-limit-led-30--g2': icon656,\r\n 'regulatory--maximum-speed-limit-led-30--g3': icon657,\r\n 'regulatory--maximum-speed-limit-led-35--g1': icon658,\r\n 'regulatory--maximum-speed-limit-led-35--g2': icon659,\r\n 'regulatory--maximum-speed-limit-led-35--g3': icon660,\r\n 'regulatory--maximum-speed-limit-led-40--g1': icon661,\r\n 'regulatory--maximum-speed-limit-led-40--g2': icon662,\r\n 'regulatory--maximum-speed-limit-led-40--g3': icon663,\r\n 'regulatory--maximum-speed-limit-led-45--g2': icon664,\r\n 'regulatory--maximum-speed-limit-led-45--g3': icon665,\r\n 'regulatory--maximum-speed-limit-led-50--g1': icon666,\r\n 'regulatory--maximum-speed-limit-led-50--g2': icon667,\r\n 'regulatory--maximum-speed-limit-led-50--g3': icon668,\r\n 'regulatory--maximum-speed-limit-led-55--g2': icon669,\r\n 'regulatory--maximum-speed-limit-led-55--g3': icon670,\r\n 'regulatory--maximum-speed-limit-led-60--g1': icon671,\r\n 'regulatory--maximum-speed-limit-led-60--g2': icon672,\r\n 'regulatory--maximum-speed-limit-led-60--g3': icon673,\r\n 'regulatory--maximum-speed-limit-led-65--g2': icon674,\r\n 'regulatory--maximum-speed-limit-led-65--g3': icon675,\r\n 'regulatory--maximum-speed-limit-led-70--g1': icon676,\r\n 'regulatory--maximum-speed-limit-led-70--g2': icon677,\r\n 'regulatory--maximum-speed-limit-led-70--g3': icon678,\r\n 'regulatory--maximum-speed-limit-led-75--g1': icon679,\r\n 'regulatory--maximum-speed-limit-led-75--g2': icon680,\r\n 'regulatory--maximum-speed-limit-led-75--g3': icon681,\r\n 'regulatory--maximum-speed-limit-led-80--g1': icon682,\r\n 'regulatory--maximum-speed-limit-led-80--g2': icon683,\r\n 'regulatory--maximum-speed-limit-led-80--g3': icon684,\r\n 'regulatory--maximum-speed-limit-led-85--g2': icon685,\r\n 'regulatory--maximum-speed-limit-led-85--g3': icon686,\r\n 'regulatory--maximum-speed-limit-led-90--g1': icon687,\r\n 'regulatory--maximum-speed-limit-led-100--g1': icon688,\r\n 'regulatory--maximum-speed-limit-led-110--g1': icon689,\r\n 'regulatory--maximum-speed-limit-led-120--g1': icon690,\r\n 'regulatory--maximum-speed-limit-led-130--g1': icon691,\r\n 'regulatory--minimum-safe-distance--g1': icon692,\r\n 'regulatory--minimum-safe-distance--g2': icon693,\r\n 'regulatory--mopeds-and-bicycles-only--g1': icon694,\r\n 'regulatory--motorcycles-and-bicycles-only--g1': icon695,\r\n 'regulatory--motorcycles-only--g1': icon696,\r\n 'regulatory--motorcycles-only--g2': icon697,\r\n 'regulatory--night-speed-limit-5--g1': icon698,\r\n 'regulatory--night-speed-limit-10--g1': icon699,\r\n 'regulatory--night-speed-limit-15--g1': icon700,\r\n 'regulatory--night-speed-limit-20--g1': icon701,\r\n 'regulatory--night-speed-limit-25--g1': icon702,\r\n 'regulatory--night-speed-limit-30--g1': icon703,\r\n 'regulatory--night-speed-limit-35--g1': icon704,\r\n 'regulatory--night-speed-limit-40--g1': icon705,\r\n 'regulatory--night-speed-limit-45--g1': icon706,\r\n 'regulatory--night-speed-limit-50--g1': icon707,\r\n 'regulatory--night-speed-limit-55--g1': icon708,\r\n 'regulatory--night-speed-limit-60--g1': icon709,\r\n 'regulatory--night-speed-limit-65--g1': icon710,\r\n 'regulatory--night-speed-limit-70--g1': icon711,\r\n 'regulatory--night-speed-limit-75--g1': icon712,\r\n 'regulatory--night-speed-limit-80--g1': icon713,\r\n 'regulatory--night-speed-limit-85--g1': icon714,\r\n 'regulatory--no-abnormal-vehicles--g1': icon715,\r\n 'regulatory--no-atvs--g1': icon716,\r\n 'regulatory--no-bicycles--g1': icon717,\r\n 'regulatory--no-bicycles--g2': icon718,\r\n 'regulatory--no-bicycles--g3': icon719,\r\n 'regulatory--no-bicycles-carts-or-hand-carts--g1': icon720,\r\n 'regulatory--no-bicycles-mopeds-or-motorcycles--g1': icon721,\r\n 'regulatory--no-bicycles-mopeds-or-motorcycles--g2': icon722,\r\n 'regulatory--no-bicycles-or-hand-carts--g1': icon723,\r\n 'regulatory--no-bicycles-or-motorcycles--g1': icon724,\r\n 'regulatory--no-bicycles-tractors-or-carts--g1': icon725,\r\n 'regulatory--no-buses--g1': icon726,\r\n 'regulatory--no-buses--g2': icon727,\r\n 'regulatory--no-buses--g3': icon728,\r\n 'regulatory--no-caravan-trailers--g1': icon729,\r\n 'regulatory--no-caravans--g1': icon730,\r\n 'regulatory--no-caravans-or-caravan-trailers--g1': icon731,\r\n 'regulatory--no-cargo-loading--g1': icon732,\r\n 'regulatory--no-carts--g1': icon733,\r\n 'regulatory--no-carts--g2': icon734,\r\n 'regulatory--no-carts--g3': icon735,\r\n 'regulatory--no-carts-or-tractors--g1': icon736,\r\n 'regulatory--no-construction-vehicles--g1': icon737,\r\n 'regulatory--no-entry--g1': icon738,\r\n 'regulatory--no-equestrians--g1': icon739,\r\n 'regulatory--no-go-straight-or-turn-left--g1': icon740,\r\n 'regulatory--no-go-straight-or-turn-right--g1': icon741,\r\n 'regulatory--no-good-trailers--g2': icon742,\r\n 'regulatory--no-goods-vehicle-trailers--g1': icon743,\r\n 'regulatory--no-hand-carts--g1': icon744,\r\n 'regulatory--no-hand-carts--g2': icon745,\r\n 'regulatory--no-hand-carts-or-bicycles--g1': icon746,\r\n 'regulatory--no-hawkers--g1': icon747,\r\n 'regulatory--no-heavy-goods-vehicles--g1': icon748,\r\n 'regulatory--no-heavy-goods-vehicles--g2': icon749,\r\n 'regulatory--no-heavy-goods-vehicles--g3': icon750,\r\n 'regulatory--no-heavy-goods-vehicles--g4': icon751,\r\n 'regulatory--no-heavy-goods-vehicles--g5': icon752,\r\n 'regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g1': icon753,\r\n 'regulatory--no-heavy-goods-vehicles-motorcycles-or-bicycles--g2': icon754,\r\n 'regulatory--no-heavy-goods-vehicles-or-buses--g1': icon755,\r\n 'regulatory--no-heavy-goods-vehicles-or-tractors--g1': icon756,\r\n 'regulatory--no-heavy-goods-vehicles-or-trailers--g1': icon757,\r\n 'regulatory--no-horizontal-turn--g1': icon758,\r\n 'regulatory--no-horn--g1': icon759,\r\n 'regulatory--no-horn--g2': icon760,\r\n 'regulatory--no-lane-change-to-left--g1': icon761,\r\n 'regulatory--no-lane-change-to-right--g1': icon762,\r\n 'regulatory--no-learner-drivers--g1': icon763,\r\n 'regulatory--no-left-or-u-turn--g1': icon764,\r\n 'regulatory--no-left-turn--g1': icon765,\r\n 'regulatory--no-left-turn--g2': icon766,\r\n 'regulatory--no-left-turn--g3': icon767,\r\n 'regulatory--no-left-turn--g4': icon768,\r\n 'regulatory--no-left-turn--g5': icon769,\r\n 'regulatory--no-low-speed-vehicles--g1': icon770,\r\n 'regulatory--no-mopeds-or-bicycles--g1': icon771,\r\n 'regulatory--no-motor-vehicle-trailers--g1': icon772,\r\n 'regulatory--no-motor-vehicles--g1': icon773,\r\n 'regulatory--no-motor-vehicles--g3': icon774,\r\n 'regulatory--no-motor-vehicles--g4': icon775,\r\n 'regulatory--no-motor-vehicles--g5': icon776,\r\n 'regulatory--no-motor-vehicles--g6': icon777,\r\n 'regulatory--no-motor-vehicles--g7': icon778,\r\n 'regulatory--no-motor-vehicles-except-motorcycles--g1': icon779,\r\n 'regulatory--no-motor-vehicles-except-motorcycles--g2': icon780,\r\n 'regulatory--no-motor-vehicles-except-motorcycles--g3': icon781,\r\n 'regulatory--no-motor-vehicles-or-bicycles--g1': icon782,\r\n 'regulatory--no-motor-vehicles-or-buses--g1': icon783,\r\n 'regulatory--no-motor-vehicles-or-carts--g1': icon784,\r\n 'regulatory--no-motorcycles--g1': icon785,\r\n 'regulatory--no-motorcycles--g2': icon786,\r\n 'regulatory--no-overtaking--g1': icon787,\r\n 'regulatory--no-overtaking--g2': icon788,\r\n 'regulatory--no-overtaking--g4': icon789,\r\n 'regulatory--no-overtaking--g5': icon790,\r\n 'regulatory--no-overtaking--g6': icon791,\r\n 'regulatory--no-overtaking--g7': icon792,\r\n 'regulatory--no-overtaking-atvs--g1': icon793,\r\n 'regulatory--no-overtaking-by-heavy-goods-vehicles--g1': icon794,\r\n 'regulatory--no-parking--g1': icon795,\r\n 'regulatory--no-parking--g2': icon796,\r\n 'regulatory--no-parking--g3': icon797,\r\n 'regulatory--no-parking--g4': icon798,\r\n 'regulatory--no-parking--g5': icon799,\r\n 'regulatory--no-parking--g6': icon800,\r\n 'regulatory--no-parking--g7': icon801,\r\n 'regulatory--no-parking--g8': icon802,\r\n 'regulatory--no-parking--g9': icon803,\r\n 'regulatory--no-parking-bicycles-or-motorcycles--g1': icon804,\r\n 'regulatory--no-parking-bus-stop--g1': icon805,\r\n 'regulatory--no-parking-or-no-stopping--g1': icon806,\r\n 'regulatory--no-parking-or-no-stopping--g2': icon807,\r\n 'regulatory--no-parking-or-no-stopping--g3': icon808,\r\n 'regulatory--no-parking-or-no-stopping--g4': icon809,\r\n 'regulatory--no-parking-or-no-stopping--g5': icon810,\r\n 'regulatory--no-passenger-loading--g1': icon811,\r\n 'regulatory--no-pedestrians--g1': icon812,\r\n 'regulatory--no-pedestrians--g2': icon813,\r\n 'regulatory--no-pedestrians--g3': icon814,\r\n 'regulatory--no-pedestrians--g4': icon815,\r\n 'regulatory--no-pedestrians--g5': icon816,\r\n 'regulatory--no-pedestrians--g6': icon817,\r\n 'regulatory--no-pedestrians-bicycles-animals-or-hand-carts--g1': icon818,\r\n 'regulatory--no-pedestrians-or-bicycles--g1': icon819,\r\n 'regulatory--no-pedestrians-or-bicycles--g2': icon820,\r\n 'regulatory--no-pedestrians-or-bicycles--g3': icon821,\r\n 'regulatory--no-rickshaws--g1': icon822,\r\n 'regulatory--no-rickshaws--g2': icon823,\r\n 'regulatory--no-rickshaws--g3': icon824,\r\n 'regulatory--no-right-turn--g1': icon825,\r\n 'regulatory--no-right-turn--g2': icon826,\r\n 'regulatory--no-right-turn--g3': icon827,\r\n 'regulatory--no-right-turn-on-red--g1': icon828,\r\n 'regulatory--no-skiing--g1': icon829,\r\n 'regulatory--no-snowmobiles--g1': icon830,\r\n 'regulatory--no-snowmobiles--g2': icon831,\r\n 'regulatory--no-snowmobiles-or-atvs--g1': icon832,\r\n 'regulatory--no-stopping--g1': icon833,\r\n 'regulatory--no-stopping--g2': icon834,\r\n 'regulatory--no-stopping--g3': icon835,\r\n 'regulatory--no-stopping--g5': icon836,\r\n 'regulatory--no-stopping--g6': icon837,\r\n 'regulatory--no-stopping--g7': icon838,\r\n 'regulatory--no-stopping-on-pavement--g1': icon839,\r\n 'regulatory--no-straight-through--g1': icon840,\r\n 'regulatory--no-straight-through--g2': icon841,\r\n 'regulatory--no-studded-snow-chains--g1': icon842,\r\n 'regulatory--no-through-trucks--g1': icon843,\r\n 'regulatory--no-tour-buses--g1': icon844,\r\n 'regulatory--no-tractors--g1': icon845,\r\n 'regulatory--no-tractors-mopeds-or-bicycles--g1': icon846,\r\n 'regulatory--no-tractors-or-carts--g1': icon847,\r\n 'regulatory--no-trailers--g1': icon848,\r\n 'regulatory--no-tricycles--g1': icon849,\r\n 'regulatory--no-tricycles-or-hand-carts--g1': icon850,\r\n 'regulatory--no-turn-on-red--g1': icon851,\r\n 'regulatory--no-turn-on-red--g2': icon852,\r\n 'regulatory--no-turn-on-red--g3': icon853,\r\n 'regulatory--no-turns--g1': icon854,\r\n 'regulatory--no-turns--g2': icon855,\r\n 'regulatory--no-two-stage-right-turn-for-mopeds--g1': icon856,\r\n 'regulatory--no-u-turn--g1': icon857,\r\n 'regulatory--no-u-turn--g2': icon858,\r\n 'regulatory--no-u-turn--g3': icon859,\r\n 'regulatory--no-vehicles-carrying-dangerous-goods--g1': icon860,\r\n 'regulatory--no-vehicles-carrying-dangerous-goods--g2': icon861,\r\n 'regulatory--no-vehicles-carrying-dangerous-goods--g3': icon862,\r\n 'regulatory--no-vehicles-carrying-dangerous-goods--g4': icon863,\r\n 'regulatory--no-vehicles-carrying-dangerous-water-pollutants--g1': icon864,\r\n 'regulatory--no-vehicles-carrying-dangerous-water-pollutants--g2': icon865,\r\n 'regulatory--no-vehicles-carrying-explosives--g1': icon866,\r\n 'regulatory--no-vehicles-carrying-explosives-or-dangerous-water-pollutants--g1': icon867,\r\n 'regulatory--one-way-left--g1': icon868,\r\n 'regulatory--one-way-left--g2': icon869,\r\n 'regulatory--one-way-left--g3': icon870,\r\n 'regulatory--one-way-right--g1': icon871,\r\n 'regulatory--one-way-right--g2': icon872,\r\n 'regulatory--one-way-right--g3': icon873,\r\n 'regulatory--one-way-straight--g1': icon874,\r\n 'regulatory--one-way-straight--g3': icon875,\r\n 'regulatory--parking-fee-station--g1': icon876,\r\n 'regulatory--parking-restrictions--g1': icon877,\r\n 'regulatory--parking-restrictions--g2': icon878,\r\n 'regulatory--parking-restrictions--g3': icon879,\r\n 'regulatory--pass-on-either-side--g1': icon880,\r\n 'regulatory--pass-on-either-side--g2': icon881,\r\n 'regulatory--pass-on-either-side--g3': icon882,\r\n 'regulatory--pass-with-care--g1': icon883,\r\n 'regulatory--passing-lane-ahead--g1': icon884,\r\n 'regulatory--pedestrians-bicycles-permitted--g1': icon885,\r\n 'regulatory--pedestrians-keep-left--g1': icon886,\r\n 'regulatory--pedestrians-only--g1': icon887,\r\n 'regulatory--pedestrians-only--g2': icon888,\r\n 'regulatory--pedestrians-only--g3': icon889,\r\n 'regulatory--pedestrians-priority-zone--g1': icon890,\r\n 'regulatory--pedestrians-push-button--g1': icon891,\r\n 'regulatory--pedestrians-push-button--g2': icon892,\r\n 'regulatory--priority-over-oncoming-vehicles--g1': icon893,\r\n 'regulatory--priority-over-oncoming-vehicles--g2': icon894,\r\n 'regulatory--priority-road--g1': icon895,\r\n 'regulatory--priority-road--g2': icon896,\r\n 'regulatory--radar-enforced--g1': icon897,\r\n 'regulatory--reserved-parking--g1': icon898,\r\n 'regulatory--reversible-lanes--g1': icon899,\r\n 'regulatory--reversible-lanes--g2': icon900,\r\n 'regulatory--road-closed--g1': icon901,\r\n 'regulatory--road-closed--g2': icon902,\r\n 'regulatory--road-closed-to-vehicles--g1': icon903,\r\n 'regulatory--road-closed-to-vehicles--g3': icon904,\r\n 'regulatory--roundabout--g1': icon905,\r\n 'regulatory--roundabout--g2': icon906,\r\n 'regulatory--roundabout--g3': icon907,\r\n 'regulatory--shared-path-bicycles-and-pedestrians--g1': icon908,\r\n 'regulatory--shared-path-pedestrians-and-bicycles--g1': icon909,\r\n 'regulatory--sidewalk-closed--g1': icon910,\r\n 'regulatory--slanted-parking--g1': icon911,\r\n 'regulatory--snow-chains--g1': icon912,\r\n 'regulatory--snow-chains--g2': icon913,\r\n 'regulatory--snow-chains--g3': icon914,\r\n 'regulatory--snowmobiles-only--g1': icon915,\r\n 'regulatory--snowmobiles-permitted--g1': icon916,\r\n 'regulatory--speed-limit-zone--g1': icon917,\r\n 'regulatory--speeding-fines-increased--g1': icon918,\r\n 'regulatory--state-route--g1': icon919,\r\n 'regulatory--stay-in-lane--g1': icon920,\r\n 'regulatory--stop--g1': icon921,\r\n 'regulatory--stop--g2': icon922,\r\n 'regulatory--stop--g3': icon923,\r\n 'regulatory--stop--g4': icon924,\r\n 'regulatory--stop--g5': icon925,\r\n 'regulatory--stop--g6': icon926,\r\n 'regulatory--stop--g7': icon927,\r\n 'regulatory--stop--g8': icon928,\r\n 'regulatory--stop--g9': icon929,\r\n 'regulatory--stop--g10': icon930,\r\n 'regulatory--stop-here-on-red-or-flashing-light--g1': icon931,\r\n 'regulatory--stop-here-on-red-or-flashing-light--g2': icon932,\r\n 'regulatory--stop-signals--g1': icon933,\r\n 'regulatory--stop-signals--g2': icon934,\r\n 'regulatory--tanks-only--g1': icon935,\r\n 'regulatory--taxi-only--g1': icon936,\r\n 'regulatory--text--g1': icon937,\r\n 'regulatory--text--g2': icon938,\r\n 'regulatory--toll-pass-only--g1': icon939,\r\n 'regulatory--tractors-only--g1': icon940,\r\n 'regulatory--traffic-signal-photo-enforced--g1': icon941,\r\n 'regulatory--trams-and-buses-only--g1': icon942,\r\n 'regulatory--trams-only--g1': icon943,\r\n 'regulatory--triple-lanes--g1': icon944,\r\n 'regulatory--triple-lanes-go-straight-center-lane--g1': icon945,\r\n 'regulatory--triple-lanes-turn-left-center-lane--g1': icon946,\r\n 'regulatory--triple-lanes-turn-right-center-lane--g1': icon947,\r\n 'regulatory--truck-route--g1': icon948,\r\n 'regulatory--truck-speed-limit-5--g1': icon949,\r\n 'regulatory--truck-speed-limit-10--g1': icon950,\r\n 'regulatory--truck-speed-limit-15--g1': icon951,\r\n 'regulatory--truck-speed-limit-20--g1': icon952,\r\n 'regulatory--truck-speed-limit-25--g1': icon953,\r\n 'regulatory--truck-speed-limit-30--g1': icon954,\r\n 'regulatory--truck-speed-limit-35--g1': icon955,\r\n 'regulatory--truck-speed-limit-40--g1': icon956,\r\n 'regulatory--truck-speed-limit-45--g1': icon957,\r\n 'regulatory--truck-speed-limit-50--g1': icon958,\r\n 'regulatory--truck-speed-limit-55--g1': icon959,\r\n 'regulatory--truck-speed-limit-60--g1': icon960,\r\n 'regulatory--truck-speed-limit-65--g1': icon961,\r\n 'regulatory--truck-speed-limit-70--g1': icon962,\r\n 'regulatory--truck-speed-limit-75--g1': icon963,\r\n 'regulatory--truck-speed-limit-80--g1': icon964,\r\n 'regulatory--truck-speed-limit-85--g1': icon965,\r\n 'regulatory--trucks-and-buses-only--g1': icon966,\r\n 'regulatory--trucks-on-right--g1': icon967,\r\n 'regulatory--trucks-only--g1': icon968,\r\n 'regulatory--turn-left--g1': icon969,\r\n 'regulatory--turn-left--g2': icon970,\r\n 'regulatory--turn-left--g3': icon971,\r\n 'regulatory--turn-left-ahead--g1': icon972,\r\n 'regulatory--turn-left-ahead--g2': icon973,\r\n 'regulatory--turn-left-or-right--g1': icon974,\r\n 'regulatory--turn-left-or-right--g2': icon975,\r\n 'regulatory--turn-left-or-right--g3': icon976,\r\n 'regulatory--turn-left-or-u-turn--g1': icon977,\r\n 'regulatory--turn-right--g1': icon978,\r\n 'regulatory--turn-right--g2': icon979,\r\n 'regulatory--turn-right--g3': icon980,\r\n 'regulatory--turn-right-ahead--g1': icon981,\r\n 'regulatory--turn-right-ahead--g2': icon982,\r\n 'regulatory--turning-vehicles-yield-to-pedestrians--g1': icon983,\r\n 'regulatory--two-stage-right-turn-for-mopeds--g1': icon984,\r\n 'regulatory--two-way--g1': icon985,\r\n 'regulatory--u-turn--g1': icon986,\r\n 'regulatory--u-turn--g2': icon987,\r\n 'regulatory--u-turn--g3': icon988,\r\n 'regulatory--use-crosswalk--g1': icon989,\r\n 'regulatory--vehicles-carrying-dangerous-goods-only--g1': icon990,\r\n 'regulatory--vehicles-carrying-dangerous-goods-permitted--g1': icon991,\r\n 'regulatory--vehicles-carrying-explosives-only--g1': icon992,\r\n 'regulatory--vehicles-carrying-hazardous-goods-permitted--g1': icon993,\r\n 'regulatory--vehicles-only--g1': icon994,\r\n 'regulatory--wear-seat-belt--g1': icon995,\r\n 'regulatory--wear-seat-belt--g2': icon996,\r\n 'regulatory--wear-seat-belt--g3': icon997,\r\n 'regulatory--weight-limit--g1': icon998,\r\n 'regulatory--weight-limit--g2': icon999,\r\n 'regulatory--weight-limit--g3': icon1000,\r\n 'regulatory--weight-limit--g4': icon1001,\r\n 'regulatory--weight-limit--g5': icon1002,\r\n 'regulatory--weight-limit--g6': icon1003,\r\n 'regulatory--weight-limit--g7': icon1004,\r\n 'regulatory--weight-limit-per-axle--g1': icon1005,\r\n 'regulatory--weight-limit-per-tandem-axle--g1': icon1006,\r\n 'regulatory--weight-limit-with-trucks--g1': icon1007,\r\n 'regulatory--width-limit--g1': icon1008,\r\n 'regulatory--wrong-way--g1': icon1009,\r\n 'regulatory--yield--g1': icon1010,\r\n 'regulatory--yield-or-stop-for-pedestrians--g1': icon1011,\r\n 'regulatory--your-speed--g1': icon1012,\r\n 'warning--accident-area--g1': icon1013,\r\n 'warning--accident-area--g2': icon1014,\r\n 'warning--accident-area--g3': icon1015,\r\n 'warning--accident-area--g4': icon1016,\r\n 'warning--accident-area--g5': icon1017,\r\n 'warning--accident-area--g6': icon1018,\r\n 'warning--accident-area--g7': icon1019,\r\n 'warning--accident-area--g8': icon1020,\r\n 'warning--added-lane-from-entering-roadway--g1': icon1021,\r\n 'warning--added-lane-from-entering-roadway--g2': icon1022,\r\n 'warning--added-lane-left--g1': icon1023,\r\n 'warning--added-lane-right--g1': icon1024,\r\n 'warning--animal-drawn-vehicles--g1': icon1025,\r\n 'warning--arch-bridge--g1': icon1026,\r\n 'warning--atv-and-snowmobiles--g1': icon1027,\r\n 'warning--atv-crossing--g1': icon1028,\r\n 'warning--atv-crossing--g2': icon1029,\r\n 'warning--axle-restriction--g1': icon1030,\r\n 'warning--bear-crossing--g1': icon1031,\r\n 'warning--bear-crossing--g2': icon1032,\r\n 'warning--bicycles-and-others--g1': icon1033,\r\n 'warning--bicycles-caution-on-rail-tracks--g1': icon1034,\r\n 'warning--bicycles-crossing--g1': icon1035,\r\n 'warning--bicycles-crossing--g2': icon1036,\r\n 'warning--bicycles-crossing--g3': icon1037,\r\n 'warning--bicycles-crossing--g4': icon1038,\r\n 'warning--bollard--g1': icon1039,\r\n 'warning--bridge--g1': icon1040,\r\n 'warning--bridge--g2': icon1041,\r\n 'warning--bus-stop-ahead--g1': icon1042,\r\n 'warning--bus-stop-ahead--g2': icon1043,\r\n 'warning--bus-stop-ahead--g3': icon1044,\r\n 'warning--camel-crossing--g1': icon1045,\r\n 'warning--camel-crossing--g2': icon1046,\r\n 'warning--camera--g1': icon1047,\r\n 'warning--camera--g2': icon1048,\r\n 'warning--carts--g1': icon1049,\r\n 'warning--carts--g2': icon1050,\r\n 'warning--checkpoint--g1': icon1051,\r\n 'warning--children--g1': icon1052,\r\n 'warning--children--g2': icon1053,\r\n 'warning--children--g3': icon1054,\r\n 'warning--children--g4': icon1055,\r\n 'warning--children--g6': icon1056,\r\n 'warning--cliff--g1': icon1057,\r\n 'warning--cliff--g2': icon1058,\r\n 'warning--closed-lane-in-triple-lanes--g1': icon1059,\r\n 'warning--closed-lane-in-triple-lanes--g2': icon1060,\r\n 'warning--construction-ahead--g1': icon1061,\r\n 'warning--crossroads--g1': icon1062,\r\n 'warning--crossroads--g2': icon1063,\r\n 'warning--crossroads--g3': icon1064,\r\n 'warning--crossroads--g4': icon1065,\r\n 'warning--crossroads--g5': icon1066,\r\n 'warning--crossroads--g6': icon1067,\r\n 'warning--crossroads-with-priority-to-the-right--g1': icon1068,\r\n 'warning--curve-left--g1': icon1069,\r\n 'warning--curve-left--g2': icon1070,\r\n 'warning--curve-left--g3': icon1071,\r\n 'warning--curve-left-with-junction--g1': icon1072,\r\n 'warning--curve-out-intersection-left--g1': icon1073,\r\n 'warning--curve-out-intersection-right--g1': icon1074,\r\n 'warning--curve-right--g1': icon1075,\r\n 'warning--curve-right--g2': icon1076,\r\n 'warning--curve-right--g3': icon1077,\r\n 'warning--curve-right-with-junction--g1': icon1078,\r\n 'warning--dangerous-crosswinds-left--g1': icon1079,\r\n 'warning--dangerous-crosswinds-left--g2': icon1080,\r\n 'warning--dangerous-crosswinds-left--g4': icon1081,\r\n 'warning--dangerous-crosswinds-right--g1': icon1082,\r\n 'warning--dangerous-crosswinds-right--g2': icon1083,\r\n 'warning--dangerous-crosswinds-right--g3': icon1084,\r\n 'warning--dangerous-crosswinds-right--g4': icon1085,\r\n 'warning--dead-end--g1': icon1086,\r\n 'warning--dead-end--g2': icon1087,\r\n 'warning--dead-end--g3': icon1088,\r\n 'warning--dead-end-go-left--g1': icon1089,\r\n 'warning--dead-end-go-right--g1': icon1090,\r\n 'warning--descent-or-climbing-lanes-in-triple-lanes--g1': icon1091,\r\n 'warning--detour-ahead--g1': icon1092,\r\n 'warning--detour-or-construction-ahead--g1': icon1093,\r\n 'warning--dip--g1': icon1094,\r\n 'warning--dip--g2': icon1095,\r\n 'warning--disabled-persons-crossing--g1': icon1096,\r\n 'warning--disabled-persons-crossing--g2': icon1097,\r\n 'warning--divided-highway--g1': icon1098,\r\n 'warning--divided-highway--g2': icon1099,\r\n 'warning--divided-highway--g3': icon1100,\r\n 'warning--divided-highway--g4': icon1101,\r\n 'warning--divided-highway--g5': icon1102,\r\n 'warning--divided-highway--g6': icon1103,\r\n 'warning--divided-highway--g7': icon1104,\r\n 'warning--divided-highway--g8': icon1105,\r\n 'warning--divided-highway--g9': icon1106,\r\n 'warning--divided-highway-ends--g1': icon1107,\r\n 'warning--divided-highway-ends--g2': icon1108,\r\n 'warning--divided-highway-ends--g3': icon1109,\r\n 'warning--divided-highway-ends--g4': icon1110,\r\n 'warning--divided-highway-on-left--g1': icon1111,\r\n 'warning--divided-highway-on-left--g2': icon1112,\r\n 'warning--divided-highway-on-right--g1': icon1113,\r\n 'warning--divided-highway-on-right--g2': icon1114,\r\n 'warning--divided-highway-to-left--g1': icon1115,\r\n 'warning--divided-highway-to-right--g1': icon1116,\r\n 'warning--domestic-animals--g1': icon1117,\r\n 'warning--domestic-animals--g2': icon1118,\r\n 'warning--domestic-animals--g3': icon1119,\r\n 'warning--domestic-animals--g4': icon1120,\r\n 'warning--domestic-animals--g5': icon1121,\r\n 'warning--domestic-animals--g6': icon1122,\r\n 'warning--domestic-animals--g7': icon1123,\r\n 'warning--domestic-animals--g8': icon1124,\r\n 'warning--double-curve-first-left--g1': icon1125,\r\n 'warning--double-curve-first-left--g2': icon1126,\r\n 'warning--double-curve-first-right--g1': icon1127,\r\n 'warning--double-curve-first-right--g2': icon1128,\r\n 'warning--double-descent--g1': icon1129,\r\n 'warning--double-reverse-curve-left--g1': icon1130,\r\n 'warning--double-reverse-curve-left--g2': icon1131,\r\n 'warning--double-reverse-curve-right--g1': icon1132,\r\n 'warning--double-reverse-curve-right--g2': icon1133,\r\n 'warning--double-side-roads-left--g1': icon1134,\r\n 'warning--double-side-roads-left--g3': icon1135,\r\n 'warning--double-side-roads-right--g1': icon1136,\r\n 'warning--double-side-roads-right--g3': icon1137,\r\n 'warning--double-turn-first-left--g1': icon1138,\r\n 'warning--double-turn-first-right--g1': icon1139,\r\n 'warning--dual-lanes-all-directions-on-left--g1': icon1140,\r\n 'warning--dual-lanes-all-directions-on-right--g1': icon1141,\r\n 'warning--dual-lanes-go-straight-or-turn-left--g1': icon1142,\r\n 'warning--dual-lanes-go-straight-or-turn-right--g1': icon1143,\r\n 'warning--dual-lanes-left-turn--g1': icon1144,\r\n 'warning--dual-lanes-left-turn-or-go-straight--g1': icon1145,\r\n 'warning--dual-lanes-right-turn--g1': icon1146,\r\n 'warning--dual-lanes-right-turn-or-go-straight--g1': icon1147,\r\n 'warning--dual-lanes-turn-left--g1': icon1148,\r\n 'warning--dual-lanes-turn-left-or-right--g1': icon1149,\r\n 'warning--dual-lanes-turn-left-or-right--g2': icon1150,\r\n 'warning--dual-lanes-turn-left-or-right--g3': icon1151,\r\n 'warning--dual-lanes-turn-left-or-right--g4': icon1152,\r\n 'warning--dual-lanes-turn-right--g1': icon1153,\r\n 'warning--dual-path-cyclists-and-pedestrians--g1': icon1154,\r\n 'warning--electricity--g1': icon1155,\r\n 'warning--electricity--g2': icon1156,\r\n 'warning--elephant-crossing--g1': icon1157,\r\n 'warning--emergency-vehicles--g1': icon1158,\r\n 'warning--emu-crossing--g1': icon1159,\r\n 'warning--emu-crossing--g2': icon1160,\r\n 'warning--entering-roadway-merge--g1': icon1161,\r\n 'warning--entering-roadway-merge--g2': icon1162,\r\n 'warning--equestrians-crossing--g1': icon1163,\r\n 'warning--equestrians-crossing--g2': icon1164,\r\n 'warning--expressway--g1': icon1165,\r\n 'warning--falling-rocks-or-debris-left--g1': icon1166,\r\n 'warning--falling-rocks-or-debris-left--g2': icon1167,\r\n 'warning--falling-rocks-or-debris-left--g3': icon1168,\r\n 'warning--falling-rocks-or-debris-left--g4': icon1169,\r\n 'warning--falling-rocks-or-debris-right--g1': icon1170,\r\n 'warning--falling-rocks-or-debris-right--g2': icon1171,\r\n 'warning--falling-rocks-or-debris-right--g3': icon1172,\r\n 'warning--falling-rocks-or-debris-right--g4': icon1173,\r\n 'warning--ferry--g1': icon1174,\r\n 'warning--flaggers-in-road--g1': icon1175,\r\n 'warning--flaggers-in-road--g2': icon1176,\r\n 'warning--foggy-road--g1': icon1177,\r\n 'warning--foggy-road--g2': icon1178,\r\n 'warning--ford--g1': icon1179,\r\n 'warning--forest--g1': icon1180,\r\n 'warning--fresh-oil--g1': icon1181,\r\n 'warning--frog-crossing--g1': icon1182,\r\n 'warning--gate--g1': icon1183,\r\n 'warning--gate--g2': icon1184,\r\n 'warning--gate-left--g1': icon1185,\r\n 'warning--gate-right--g1': icon1186,\r\n 'warning--go-left--g1': icon1187,\r\n 'warning--go-right--g1': icon1188,\r\n 'warning--golf-carts-crossing--g1': icon1189,\r\n 'warning--gravel-road-surface--g1': icon1190,\r\n 'warning--hairpin-curve-left--g1': icon1191,\r\n 'warning--hairpin-curve-left--g2': icon1192,\r\n 'warning--hairpin-curve-left--g3': icon1193,\r\n 'warning--hairpin-curve-right--g1': icon1194,\r\n 'warning--hairpin-curve-right--g3': icon1195,\r\n 'warning--height-restriction--g2': icon1196,\r\n 'warning--height-restriction--g3': icon1197,\r\n 'warning--height-restriction--g4': icon1198,\r\n 'warning--height-restriction--g5': icon1199,\r\n 'warning--horizontal-alignment-left--g1': icon1200,\r\n 'warning--horizontal-alignment-left--g3': icon1201,\r\n 'warning--horizontal-alignment-right--g1': icon1202,\r\n 'warning--horizontal-alignment-right--g3': icon1203,\r\n 'warning--horse-crossing--g1': icon1204,\r\n 'warning--icy-road--g1': icon1205,\r\n 'warning--junction-with-a-side-road-acute-left--g1': icon1206,\r\n 'warning--junction-with-a-side-road-acute-left--g2': icon1207,\r\n 'warning--junction-with-a-side-road-acute-right--g1': icon1208,\r\n 'warning--junction-with-a-side-road-acute-right--g2': icon1209,\r\n 'warning--junction-with-a-side-road-perpendicular-left--g1': icon1210,\r\n 'warning--junction-with-a-side-road-perpendicular-left--g2': icon1211,\r\n 'warning--junction-with-a-side-road-perpendicular-left--g3': icon1212,\r\n 'warning--junction-with-a-side-road-perpendicular-left--g4': icon1213,\r\n 'warning--junction-with-a-side-road-perpendicular-right--g1': icon1214,\r\n 'warning--junction-with-a-side-road-perpendicular-right--g2': icon1215,\r\n 'warning--junction-with-a-side-road-perpendicular-right--g3': icon1216,\r\n 'warning--junction-with-a-side-road-perpendicular-right--g4': icon1217,\r\n 'warning--junction-with-merge-from-left--g1': icon1218,\r\n 'warning--junction-with-merge-from-right--g1': icon1219,\r\n 'warning--junction-with-side-roads--g1': icon1220,\r\n 'warning--kangaloo-crossing--g1': icon1221,\r\n 'warning--keep-distance--g1': icon1222,\r\n 'warning--keep-left--g1': icon1223,\r\n 'warning--keep-right--g1': icon1224,\r\n 'warning--kiwi-crossing--g1': icon1225,\r\n 'warning--kiwi-crossing--g2': icon1226,\r\n 'warning--koala-crossing--g1': icon1227,\r\n 'warning--koala-crossing--g2': icon1228,\r\n 'warning--koala-crossing--g3': icon1229,\r\n 'warning--koala-crossing--g4': icon1230,\r\n 'warning--lane-closed-in-dual-lanes-left--g1': icon1231,\r\n 'warning--lane-closed-in-dual-lanes-left--g2': icon1232,\r\n 'warning--lane-closed-in-dual-lanes-right--g1': icon1233,\r\n 'warning--lane-closed-in-dual-lanes-right--g2': icon1234,\r\n 'warning--length-restriction--g1': icon1235,\r\n 'warning--length-restriction--g2': icon1236,\r\n 'warning--light-rail-transit-vehicles--g1': icon1237,\r\n 'warning--limited-lighting-under-trees--g1': icon1238,\r\n 'warning--logging-vehicles--g1': icon1239,\r\n 'warning--loop-270-degree--g1': icon1240,\r\n 'warning--loop-pretzel--g1': icon1241,\r\n 'warning--loose-road-surface--g1': icon1242,\r\n 'warning--loose-road-surface--g2': icon1243,\r\n 'warning--loose-road-surface--g3': icon1244,\r\n 'warning--loose-road-surface--g4': icon1245,\r\n 'warning--low-flying-aircraft--g1': icon1246,\r\n 'warning--low-flying-aircraft--g2': icon1247,\r\n 'warning--low-flying-aircraft--g3': icon1248,\r\n 'warning--low-flying-aircraft--g4': icon1249,\r\n 'warning--low-flying-aircraft--g5': icon1250,\r\n 'warning--low-flying-aircraft--g6': icon1251,\r\n 'warning--low-flying-aircraft--g7': icon1252,\r\n 'warning--low-flying-aircraft--g8': icon1253,\r\n 'warning--low-ground-clearance--g1': icon1254,\r\n 'warning--low-ground-clearance--g2': icon1255,\r\n 'warning--low-ground-clearance--g3': icon1256,\r\n 'warning--monkey-crossing--g1': icon1257,\r\n 'warning--motorcycles-crossing--g1': icon1258,\r\n 'warning--narrow-bridge--g1': icon1259,\r\n 'warning--narrow-bridge--g2': icon1260,\r\n 'warning--narrow-bridge--g3': icon1261,\r\n 'warning--no-passing-zone--g1': icon1262,\r\n 'warning--no-passing-zone--g2': icon1263,\r\n 'warning--occupied-lanes--g1': icon1264,\r\n 'warning--offset-roads--g1': icon1265,\r\n 'warning--offset-roads--g2': icon1266,\r\n 'warning--offset-roads--g3': icon1267,\r\n 'warning--offset-roads--g4': icon1268,\r\n 'warning--opening-or-swing-bridge--g1': icon1269,\r\n 'warning--opening-or-swing-bridge--g2': icon1270,\r\n 'warning--other-danger--g1': icon1271,\r\n 'warning--other-danger--g2': icon1272,\r\n 'warning--other-danger--g3': icon1273,\r\n 'warning--panda-crossing--g1': icon1274,\r\n 'warning--pass-left-or-right--g1': icon1275,\r\n 'warning--pass-left-or-right--g2': icon1276,\r\n 'warning--pass-left-or-right--g3': icon1277,\r\n 'warning--pavement-ahead--g1': icon1278,\r\n 'warning--pavement-ends--g1': icon1279,\r\n 'warning--pavement-ends--g2': icon1280,\r\n 'warning--pavement-ends--g3': icon1281,\r\n 'warning--pavement-ends--g4': icon1282,\r\n 'warning--pavement-ends--g5': icon1283,\r\n 'warning--pedestrians-crossing--g1': icon1284,\r\n 'warning--pedestrians-crossing--g4': icon1285,\r\n 'warning--pedestrians-crossing--g5': icon1286,\r\n 'warning--pedestrians-crossing--g6': icon1287,\r\n 'warning--pedestrians-crossing--g7': icon1288,\r\n 'warning--pedestrians-crossing--g8': icon1289,\r\n 'warning--pedestrians-crossing--g9': icon1290,\r\n 'warning--pedestrians-crossing--g10': icon1291,\r\n 'warning--pedestrians-crossing--g11': icon1292,\r\n 'warning--pedestrians-crossing--g12': icon1293,\r\n 'warning--playground--g1': icon1294,\r\n 'warning--playground--g3': icon1295,\r\n 'warning--polar-bear-crossing--g1': icon1296,\r\n 'warning--quay-or-river-bank--g1': icon1297,\r\n 'warning--quay-or-river-bank--g2': icon1298,\r\n 'warning--quay-or-river-bank--g3': icon1299,\r\n 'warning--quay-or-river-bank--g4': icon1300,\r\n 'warning--rabbit-crossing--g1': icon1301,\r\n 'warning--raccoon-crossing--g1': icon1302,\r\n 'warning--railroad-crossing--g1': icon1303,\r\n 'warning--railroad-crossing--g2': icon1304,\r\n 'warning--railroad-crossing--g3': icon1305,\r\n 'warning--railroad-crossing--g4': icon1306,\r\n 'warning--railroad-crossing-with-barriers--g1': icon1307,\r\n 'warning--railroad-crossing-with-barriers--g2': icon1308,\r\n 'warning--railroad-crossing-with-barriers--g3': icon1309,\r\n 'warning--railroad-crossing-with-barriers--g4': icon1310,\r\n 'warning--railroad-crossing-with-barriers--g5': icon1311,\r\n 'warning--railroad-crossing-with-barriers--g6': icon1312,\r\n 'warning--railroad-crossing-with-barriers--g7': icon1313,\r\n 'warning--railroad-crossing-without-barriers--g1': icon1314,\r\n 'warning--railroad-crossing-without-barriers--g2': icon1315,\r\n 'warning--railroad-crossing-without-barriers--g3': icon1316,\r\n 'warning--railroad-crossing-without-barriers--g4': icon1317,\r\n 'warning--railroad-crossing-without-barriers--g5': icon1318,\r\n 'warning--railroad-crossing-without-barriers--g6': icon1319,\r\n 'warning--railroad-intersection--g1': icon1320,\r\n 'warning--railroad-intersection--g2': icon1321,\r\n 'warning--railroad-intersection--g3': icon1322,\r\n 'warning--railroad-intersection--g4': icon1323,\r\n 'warning--railroad-intersection--g5': icon1324,\r\n 'warning--railroad-intersection--g6': icon1325,\r\n 'warning--railroad-intersection--g7': icon1326,\r\n 'warning--railroad-intersection--g8': icon1327,\r\n 'warning--railroad-intersection--g9': icon1328,\r\n 'warning--ramp-closed--g1': icon1329,\r\n 'warning--reduced-maximum-speed-limit--g1': icon1330,\r\n 'warning--reserved-lane--g1': icon1331,\r\n 'warning--restricted-zone--g1': icon1332,\r\n 'warning--reversible-lanes--g1': icon1333,\r\n 'warning--reversible-lanes--g2': icon1334,\r\n 'warning--rickshaws-crossing--g1': icon1335,\r\n 'warning--road-blocks--g1': icon1336,\r\n 'warning--road-bump--g1': icon1337,\r\n 'warning--road-bump--g2': icon1338,\r\n 'warning--road-bump--g3': icon1339,\r\n 'warning--road-bump-with-speed-limit--g1': icon1340,\r\n 'warning--road-closed--g3': icon1341,\r\n 'warning--road-narrows--g1': icon1342,\r\n 'warning--road-narrows--g2': icon1343,\r\n 'warning--road-narrows-left--g1': icon1344,\r\n 'warning--road-narrows-left--g2': icon1345,\r\n 'warning--road-narrows-left-ahead--g1': icon1346,\r\n 'warning--road-narrows-right--g1': icon1347,\r\n 'warning--road-narrows-right--g2': icon1348,\r\n 'warning--road-narrows-right-ahead--g1': icon1349,\r\n 'warning--road-toll-ahead--g1': icon1350,\r\n 'warning--road-widens--g1': icon1351,\r\n 'warning--road-widens-left--g1': icon1352,\r\n 'warning--road-widens-right--g1': icon1353,\r\n 'warning--roadworks--g1': icon1354,\r\n 'warning--roadworks--g2': icon1355,\r\n 'warning--roadworks--g3': icon1356,\r\n 'warning--roadworks--g5': icon1357,\r\n 'warning--roadworks--g6': icon1358,\r\n 'warning--roadworks--g8': icon1359,\r\n 'warning--roadworks--g9': icon1360,\r\n 'warning--roadworks--g10': icon1361,\r\n 'warning--roadworks--g11': icon1362,\r\n 'warning--roadworks-go-left-or-straight--g1': icon1363,\r\n 'warning--roadworks-go-right-or-straight--g1': icon1364,\r\n 'warning--roundabout--g1': icon1365,\r\n 'warning--roundabout--g2': icon1366,\r\n 'warning--roundabout--g3': icon1367,\r\n 'warning--roundabout--g4': icon1368,\r\n 'warning--roundabout--g5': icon1369,\r\n 'warning--roundabout--g6': icon1370,\r\n 'warning--roundabout--g7': icon1371,\r\n 'warning--ruts--g1': icon1372,\r\n 'warning--sand--g1': icon1373,\r\n 'warning--sand-drift--g1': icon1374,\r\n 'warning--school-zone--g2': icon1375,\r\n 'warning--severe-weather--g1': icon1376,\r\n 'warning--shared-lane-motorcycles-bicycles--g1': icon1377,\r\n 'warning--sharp-turn--g1': icon1378,\r\n 'warning--single-reverse-curve--g1': icon1379,\r\n 'warning--skewed-t-roads-left--g1': icon1380,\r\n 'warning--skewed-t-roads-left--g2': icon1381,\r\n 'warning--skewed-t-roads-left--g3': icon1382,\r\n 'warning--skewed-t-roads-right--g1': icon1383,\r\n 'warning--skewed-t-roads-right--g2': icon1384,\r\n 'warning--skewed-t-roads-right--g3': icon1385,\r\n 'warning--skiers--g1': icon1386,\r\n 'warning--skiers--g2': icon1387,\r\n 'warning--skiers--g3': icon1388,\r\n 'warning--slippery-bicycles--g1': icon1389,\r\n 'warning--slippery-motorcycles--g1': icon1390,\r\n 'warning--slippery-motorcycles--g2': icon1391,\r\n 'warning--slippery-road-surface--g1': icon1392,\r\n 'warning--slippery-road-surface--g2': icon1393,\r\n 'warning--slow--g1': icon1394,\r\n 'warning--snow-tractors--g1': icon1395,\r\n 'warning--snowmobiles--g1': icon1396,\r\n 'warning--snowmobiles--g2': icon1397,\r\n 'warning--snowmobiles--g3': icon1398,\r\n 'warning--snowmobiles-and-others--g1': icon1399,\r\n 'warning--soft-road-surface--g1': icon1400,\r\n 'warning--soft-road-surface--g2': icon1401,\r\n 'warning--soft-shoulder--g1': icon1402,\r\n 'warning--soft-shoulder--g2': icon1403,\r\n 'warning--soft-shoulder--g3': icon1404,\r\n 'warning--soft-shoulder--g4': icon1405,\r\n 'warning--speed-camera--g1': icon1406,\r\n 'warning--steep-ascent--g1': icon1407,\r\n 'warning--steep-ascent--g2': icon1408,\r\n 'warning--steep-ascent--g3': icon1409,\r\n 'warning--steep-ascent--g4': icon1410,\r\n 'warning--steep-ascent-and-descent--g1': icon1411,\r\n 'warning--steep-descent--g1': icon1412,\r\n 'warning--steep-descent--g2': icon1413,\r\n 'warning--steep-descent--g3': icon1414,\r\n 'warning--steep-descent--g4': icon1415,\r\n 'warning--steep-descent--g5': icon1416,\r\n 'warning--steep-descent--g6': icon1417,\r\n 'warning--stop-ahead--g1': icon1418,\r\n 'warning--stop-ahead--g3': icon1419,\r\n 'warning--stop-ahead--g4': icon1420,\r\n 'warning--stop-ahead--g5': icon1421,\r\n 'warning--stop-ahead--g6': icon1422,\r\n 'warning--t-roads--g1': icon1423,\r\n 'warning--t-roads--g2': icon1424,\r\n 'warning--tanks-crossing--g1': icon1425,\r\n 'warning--tanks-crossing--g2': icon1426,\r\n 'warning--texts--g1': icon1427,\r\n 'warning--texts--g2': icon1428,\r\n 'warning--texts--g3': icon1429,\r\n 'warning--towing--g1': icon1430,\r\n 'warning--tractors--g1': icon1431,\r\n 'warning--tractors--g2': icon1432,\r\n 'warning--tractors--g3': icon1433,\r\n 'warning--tractors--g4': icon1434,\r\n 'warning--tractors--g5': icon1435,\r\n 'warning--tractors--g6': icon1436,\r\n 'warning--tractors--g7': icon1437,\r\n 'warning--traffic-merges-at-signalized-intersections--g1': icon1438,\r\n 'warning--traffic-merges-left--g1': icon1439,\r\n 'warning--traffic-merges-left--g2': icon1440,\r\n 'warning--traffic-merges-left--g3': icon1441,\r\n 'warning--traffic-merges-left--g4': icon1442,\r\n 'warning--traffic-merges-left-and-right--g1': icon1443,\r\n 'warning--traffic-merges-left-buses--g1': icon1444,\r\n 'warning--traffic-merges-right--g1': icon1445,\r\n 'warning--traffic-merges-right--g2': icon1446,\r\n 'warning--traffic-merges-right--g3': icon1447,\r\n 'warning--traffic-merges-right-buses--g1': icon1448,\r\n 'warning--traffic-queues-likely--g1': icon1449,\r\n 'warning--traffic-queues-likely--g2': icon1450,\r\n 'warning--traffic-queues-likely--g3': icon1451,\r\n 'warning--traffic-queues-likely--g4': icon1452,\r\n 'warning--traffic-queues-likely--g5': icon1453,\r\n 'warning--traffic-signals--g1': icon1454,\r\n 'warning--traffic-signals--g2': icon1455,\r\n 'warning--traffic-signals--g3': icon1456,\r\n 'warning--traffic-signals--g4': icon1457,\r\n 'warning--traffic-signals--g5': icon1458,\r\n 'warning--traffic-signals--g6': icon1459,\r\n 'warning--traffic-slow--g1': icon1460,\r\n 'warning--trail-crossing--g1': icon1461,\r\n 'warning--trail-crossing--g2': icon1462,\r\n 'warning--trail-crossing--g3': icon1463,\r\n 'warning--trail-crossing--g4': icon1464,\r\n 'warning--trail-crossing--g5': icon1465,\r\n 'warning--trail-crossing--g6': icon1466,\r\n 'warning--trams-crossing--g1': icon1467,\r\n 'warning--trams-crossing--g2': icon1468,\r\n 'warning--triple-curve-left--g1': icon1469,\r\n 'warning--triple-curve-right--g1': icon1470,\r\n 'warning--triple-lanes-left-turn--g1': icon1471,\r\n 'warning--triple-lanes-left-turn-or-go-straight--g1': icon1472,\r\n 'warning--triple-lanes-right-turn--g1': icon1473,\r\n 'warning--triple-lanes-right-turn-or-go-straight--g1': icon1474,\r\n 'warning--triple-lanes-with-directions--g1': icon1475,\r\n 'warning--triple-reverse-curve-left--g1': icon1476,\r\n 'warning--triple-reverse-curve-right--g1': icon1477,\r\n 'warning--trucks-crossing--g1': icon1478,\r\n 'warning--trucks-crossing--g2': icon1479,\r\n 'warning--trucks-rollover--g1': icon1480,\r\n 'warning--trucks-rollover--g2': icon1481,\r\n 'warning--trucks-rollover--g3': icon1482,\r\n 'warning--trucks-rollover--g4': icon1483,\r\n 'warning--trucks-rollover--g5': icon1484,\r\n 'warning--tunnel--g1': icon1485,\r\n 'warning--tunnel--g2': icon1486,\r\n 'warning--tunnel--g3': icon1487,\r\n 'warning--tunnel--g4': icon1488,\r\n 'warning--tunnel--g5': icon1489,\r\n 'warning--tunnel--g6': icon1490,\r\n 'warning--tunnel--g7': icon1491,\r\n 'warning--turn-left--g1': icon1492,\r\n 'warning--turn-left--g2': icon1493,\r\n 'warning--turn-left--g3': icon1494,\r\n 'warning--turn-left-or-right--g1': icon1495,\r\n 'warning--turn-right--g1': icon1496,\r\n 'warning--turn-right--g2': icon1497,\r\n 'warning--turn-right--g3': icon1498,\r\n 'warning--two-way-traffic--g1': icon1499,\r\n 'warning--two-way-traffic--g2': icon1500,\r\n 'warning--two-way-traffic--g3': icon1501,\r\n 'warning--two-way-traffic--g4': icon1502,\r\n 'warning--two-way-traffic--g5': icon1503,\r\n 'warning--two-way-traffic--g6': icon1504,\r\n 'warning--u-turn--g1': icon1505,\r\n 'warning--u-turn--g2': icon1506,\r\n 'warning--uneven-road--g1': icon1507,\r\n 'warning--uneven-road--g2': icon1508,\r\n 'warning--uneven-roads-ahead--g1': icon1509,\r\n 'warning--vehicles-and-others--g1': icon1510,\r\n 'warning--vehicles-crossing--g1': icon1511,\r\n 'warning--village--g1': icon1512,\r\n 'warning--weight-limit--g5': icon1513,\r\n 'warning--weight-limit-per-tandem-axle--g1': icon1514,\r\n 'warning--width-restriction--g1': icon1515,\r\n 'warning--width-restriction--g2': icon1516,\r\n 'warning--width-restriction--g3': icon1517,\r\n 'warning--width-restriction--g4': icon1518,\r\n 'warning--wild-animals--g1': icon1519,\r\n 'warning--wild-animals--g2': icon1520,\r\n 'warning--wild-animals--g3': icon1521,\r\n 'warning--wild-animals--g4': icon1522,\r\n 'warning--wild-animals--g5': icon1523,\r\n 'warning--wild-animals--g6': icon1524,\r\n 'warning--wild-animals--g7': icon1525,\r\n 'warning--wild-animals--g8': icon1526,\r\n 'warning--wind--g1': icon1527,\r\n 'warning--winding-road--g1': icon1528,\r\n 'warning--winding-road-first-left--g1': icon1529,\r\n 'warning--winding-road-first-left--g2': icon1530,\r\n 'warning--winding-road-first-left--g3': icon1531,\r\n 'warning--winding-road-first-right--g1': icon1532,\r\n 'warning--winding-road-first-right--g2': icon1533,\r\n 'warning--winding-road-first-right--g3': icon1534,\r\n 'warning--winding-road-first-right--g4': icon1535,\r\n 'warning--winding-road-to-left--g1': icon1536,\r\n 'warning--winding-road-to-right--g1': icon1537,\r\n 'warning--wombat-crossing--g1': icon1538,\r\n 'warning--y-roads--g1': icon1539,\r\n 'warning--y-roads--g2': icon1540,\r\n 'warning--yield-ahead--g1': icon1541,\r\n 'warning--yield-ahead--g3': icon1542,\r\n};\r\n\r\nexport default textures;","export default __webpack_public_path__ + \"static/media/warning--roadworks--g10.1e4a14ca.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks--g11.65f561a7.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks-go-left-or-straight--g1.2206c5f2.png\";","export default __webpack_public_path__ + \"static/media/warning--roadworks-go-right-or-straight--g1.f4293c9a.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g1.363f83bb.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g2.c8ee3ec5.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g3.596a7a10.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g4.2102530e.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g5.ac2266ff.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g6.73900945.png\";","export default __webpack_public_path__ + \"static/media/warning--roundabout--g7.5c72c830.png\";","export default __webpack_public_path__ + \"static/media/warning--ruts--g1.01bce4e7.png\";","export default __webpack_public_path__ + \"static/media/warning--sand--g1.93715f38.png\";","export default __webpack_public_path__ + \"static/media/warning--sand-drift--g1.aaccd3fd.png\";","export default __webpack_public_path__ + \"static/media/warning--school-zone--g2.3c1c4bdf.png\";","export default __webpack_public_path__ + \"static/media/warning--severe-weather--g1.84f2d524.png\";","export default __webpack_public_path__ + \"static/media/warning--shared-lane-motorcycles-bicycles--g1.969c6687.png\";","export default __webpack_public_path__ + \"static/media/warning--sharp-turn--g1.9911721d.png\";","export default __webpack_public_path__ + \"static/media/warning--single-reverse-curve--g1.8219bd1a.png\";","export default __webpack_public_path__ + \"static/media/warning--skewed-t-roads-left--g1.b3a5ef81.png\";","export default __webpack_public_path__ + \"static/media/warning--skewed-t-roads-left--g2.57907e78.png\";","export default __webpack_public_path__ + \"static/media/warning--skewed-t-roads-left--g3.8810e2d3.png\";","export default __webpack_public_path__ + \"static/media/warning--skewed-t-roads-right--g1.48a80ba7.png\";","export default __webpack_public_path__ + \"static/media/warning--skewed-t-roads-right--g2.733f022e.png\";","export default __webpack_public_path__ + \"static/media/warning--skewed-t-roads-right--g3.544ec832.png\";","export default __webpack_public_path__ + \"static/media/warning--skiers--g1.e4cb5a02.png\";","export default __webpack_public_path__ + \"static/media/warning--skiers--g2.e0e46119.png\";","export default __webpack_public_path__ + \"static/media/warning--skiers--g3.7c53d442.png\";","export default __webpack_public_path__ + \"static/media/warning--slippery-bicycles--g1.44fe2519.png\";","export default __webpack_public_path__ + \"static/media/warning--slippery-motorcycles--g1.55df543d.png\";","export default __webpack_public_path__ + \"static/media/warning--slippery-motorcycles--g2.d5a4c642.png\";","export default __webpack_public_path__ + \"static/media/warning--slippery-road-surface--g1.be37c309.png\";","export default __webpack_public_path__ + \"static/media/warning--slippery-road-surface--g2.cc75b2dd.png\";","export default __webpack_public_path__ + \"static/media/warning--slow--g1.5f3c1df0.png\";","export default __webpack_public_path__ + \"static/media/warning--snow-tractors--g1.bb82eff0.png\";","export default __webpack_public_path__ + \"static/media/warning--snowmobiles--g1.d6ea0469.png\";","export default __webpack_public_path__ + \"static/media/warning--snowmobiles--g2.0f139051.png\";","export default __webpack_public_path__ + \"static/media/warning--snowmobiles--g3.7abe7cc6.png\";","export default __webpack_public_path__ + \"static/media/warning--snowmobiles-and-others--g1.8d956ed3.png\";","export default __webpack_public_path__ + \"static/media/warning--soft-road-surface--g1.85e53a3f.png\";","export default __webpack_public_path__ + \"static/media/warning--soft-road-surface--g2.31a8fbb4.png\";","export default __webpack_public_path__ + \"static/media/warning--soft-shoulder--g1.048f3f53.png\";","export default __webpack_public_path__ + \"static/media/warning--soft-shoulder--g2.f70869d1.png\";","export default __webpack_public_path__ + \"static/media/warning--soft-shoulder--g3.993109d1.png\";","export default __webpack_public_path__ + \"static/media/warning--soft-shoulder--g4.6b309255.png\";","export default __webpack_public_path__ + \"static/media/warning--speed-camera--g1.c247454b.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-ascent--g1.69baab13.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-ascent--g2.f04136e9.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-ascent--g3.ac4d27d9.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-ascent--g4.ab1d5bee.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-ascent-and-descent--g1.127e8fa0.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-descent--g1.1af3c7de.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-descent--g2.84c43533.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-descent--g3.dbc8ed30.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-descent--g4.fe8bc6de.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-descent--g5.53695588.png\";","export default __webpack_public_path__ + \"static/media/warning--steep-descent--g6.124238e6.png\";","export default __webpack_public_path__ + \"static/media/warning--stop-ahead--g1.19311854.png\";","export default __webpack_public_path__ + \"static/media/warning--stop-ahead--g3.f1875ba8.png\";","export default __webpack_public_path__ + \"static/media/warning--stop-ahead--g4.5c3b7c40.png\";","export default __webpack_public_path__ + \"static/media/warning--stop-ahead--g5.9f5a1393.png\";","export default __webpack_public_path__ + \"static/media/warning--stop-ahead--g6.78751205.png\";","export default __webpack_public_path__ + \"static/media/warning--t-roads--g1.02138011.png\";","export default __webpack_public_path__ + \"static/media/warning--t-roads--g2.056984e6.png\";","export default __webpack_public_path__ + \"static/media/warning--tanks-crossing--g1.ff076d31.png\";","export default __webpack_public_path__ + \"static/media/warning--tanks-crossing--g2.7f43e52c.png\";","export default __webpack_public_path__ + \"static/media/warning--texts--g1.f8515b5d.png\";","export default __webpack_public_path__ + \"static/media/warning--texts--g2.d6d56c78.png\";","export default __webpack_public_path__ + \"static/media/warning--texts--g3.14da2898.png\";","export default __webpack_public_path__ + \"static/media/warning--towing--g1.e4f069b4.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g1.6ebffbec.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g2.12c05fcc.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g3.bc827995.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g4.ca6b9ca8.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g5.c35fe753.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g6.80093d62.png\";","export default __webpack_public_path__ + \"static/media/warning--tractors--g7.c9d9396b.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-at-signalized-intersections--g1.15593cdb.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-left--g1.ad031968.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-left--g2.35d525d5.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-left--g3.aa5ed805.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-left--g4.b2ac0c8b.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-left-and-right--g1.b5ae91c4.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-left-buses--g1.bafa36cd.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-right--g1.09a3ead4.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-right--g2.3201b3fd.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-right--g3.c7ea5315.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-merges-right-buses--g1.dd325625.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-queues-likely--g1.2c06f6f5.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-queues-likely--g2.67e4ca2f.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-queues-likely--g3.85ad3584.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-queues-likely--g4.341dcd8c.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-queues-likely--g5.67bac08b.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-signals--g1.0847859b.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-signals--g2.da23a41a.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-signals--g3.675ee0a1.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-signals--g4.9b34ae82.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-signals--g5.3b152c9a.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-signals--g6.89426955.png\";","export default __webpack_public_path__ + \"static/media/warning--traffic-slow--g1.169e23bf.png\";","export default __webpack_public_path__ + \"static/media/warning--trail-crossing--g1.e429d378.png\";","export default __webpack_public_path__ + \"static/media/warning--trail-crossing--g2.8a7ddab9.png\";","export default __webpack_public_path__ + \"static/media/warning--trail-crossing--g3.67219fd7.png\";","export default __webpack_public_path__ + \"static/media/warning--trail-crossing--g4.07b92d0e.png\";","export default __webpack_public_path__ + \"static/media/warning--trail-crossing--g5.10b83374.png\";","export default __webpack_public_path__ + \"static/media/warning--trail-crossing--g6.5ae959ad.png\";","export default __webpack_public_path__ + \"static/media/warning--trams-crossing--g1.c211e5c2.png\";","export default __webpack_public_path__ + \"static/media/warning--trams-crossing--g2.10027951.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-curve-left--g1.2b1378be.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-curve-right--g1.2d533c31.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-lanes-left-turn--g1.8bf1c712.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-lanes-left-turn-or-go-straight--g1.f5c35777.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-lanes-right-turn--g1.c58a09f1.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-lanes-right-turn-or-go-straight--g1.4eea8ba7.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-lanes-with-directions--g1.586f9802.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-reverse-curve-left--g1.4cbc4d04.png\";","export default __webpack_public_path__ + \"static/media/warning--triple-reverse-curve-right--g1.0a1464ca.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-crossing--g1.14771128.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-crossing--g2.8ba4f009.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-rollover--g1.9615c47b.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-rollover--g2.a08fc624.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-rollover--g3.c0f762d7.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-rollover--g4.b6d137b4.png\";","export default __webpack_public_path__ + \"static/media/warning--trucks-rollover--g5.44727700.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g1.e271c799.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g2.1ac74efb.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g3.0d46880c.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g4.55d1ddf2.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g5.598ceb68.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g6.db4d3d0f.png\";","export default __webpack_public_path__ + \"static/media/warning--tunnel--g7.cdca6a34.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-left--g1.1d607064.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-left--g2.2a658ee0.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-left--g3.f55b92bb.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-left-or-right--g1.386986eb.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-right--g1.acd9d2dc.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-right--g2.71999a1f.png\";","export default __webpack_public_path__ + \"static/media/warning--turn-right--g3.df561544.png\";","export default __webpack_public_path__ + \"static/media/warning--two-way-traffic--g1.f6b90cf6.png\";","export default __webpack_public_path__ + \"static/media/warning--two-way-traffic--g2.d18e37c9.png\";","export default __webpack_public_path__ + \"static/media/warning--two-way-traffic--g3.04d6746c.png\";","export default __webpack_public_path__ + \"static/media/warning--two-way-traffic--g4.57cdc063.png\";","export default __webpack_public_path__ + \"static/media/warning--two-way-traffic--g5.1d4d5701.png\";","export default __webpack_public_path__ + \"static/media/warning--two-way-traffic--g6.444c4349.png\";","export default __webpack_public_path__ + \"static/media/warning--u-turn--g1.c962ec41.png\";","export default __webpack_public_path__ + \"static/media/warning--u-turn--g2.997231ed.png\";","export default __webpack_public_path__ + \"static/media/warning--uneven-road--g1.7ee9ceaa.png\";","export default __webpack_public_path__ + \"static/media/warning--uneven-road--g2.2107fedc.png\";","export default __webpack_public_path__ + \"static/media/warning--uneven-roads-ahead--g1.4444a9a8.png\";","export default __webpack_public_path__ + \"static/media/warning--vehicles-and-others--g1.5639870f.png\";","export default __webpack_public_path__ + \"static/media/warning--vehicles-crossing--g1.9f54b48e.png\";","export default __webpack_public_path__ + \"static/media/warning--village--g1.186803fe.png\";","export default __webpack_public_path__ + \"static/media/warning--weight-limit--g5.07efdfea.png\";","export default __webpack_public_path__ + \"static/media/warning--weight-limit-per-tandem-axle--g1.bce254f9.png\";","export default __webpack_public_path__ + \"static/media/warning--width-restriction--g1.4ce617a5.png\";","export default __webpack_public_path__ + \"static/media/warning--width-restriction--g2.3c708099.png\";","export default __webpack_public_path__ + \"static/media/warning--width-restriction--g3.8a82e40c.png\";","export default __webpack_public_path__ + \"static/media/warning--width-restriction--g4.88608eb2.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g1.c0f70fcd.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g2.76bbe024.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g3.ed95b4b7.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g4.85a2983f.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g5.5e9cdace.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g6.cdc986a1.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g7.e116de1f.png\";","export default __webpack_public_path__ + \"static/media/warning--wild-animals--g8.c9822743.png\";","export default __webpack_public_path__ + \"static/media/warning--wind--g1.cbfbcd99.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road--g1.f80521c5.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-left--g1.ece0736d.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-left--g2.3b2df358.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-left--g3.6e45aecc.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-right--g1.39cf401f.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-right--g2.53376994.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-right--g3.2a1fde3f.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-first-right--g4.0c7093c2.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-to-left--g1.896aa6f8.png\";","export default __webpack_public_path__ + \"static/media/warning--winding-road-to-right--g1.6a71c0d8.png\";","export default __webpack_public_path__ + \"static/media/warning--wombat-crossing--g1.633523a4.png\";","export default __webpack_public_path__ + \"static/media/warning--y-roads--g1.1dc031ba.png\";","export default __webpack_public_path__ + \"static/media/warning--y-roads--g2.8994d575.png\";","export default __webpack_public_path__ + \"static/media/warning--yield-ahead--g1.798e142c.png\";","export default __webpack_public_path__ + \"static/media/warning--yield-ahead--g3.1cad1ee2.png\";","import icon0 from './beginn schiessuebungsraum.png';\r\nimport icon1 from './beginn schiessuebungsstrecke.png';\r\nimport icon2 from './doppelrhombus.png';\r\nimport icon3 from './doppelwinkel.png';\r\nimport icon4 from './ende schiessuebungsraum.png';\r\nimport icon5 from './ende schiessuebungsstrecke.png';\r\nimport icon6 from './rhombus.png';\r\nimport icon7 from './stellung feuerhalt.png';\r\nimport icon8 from './winkel.png';\r\n\r\nconst textures = {\r\n 'beginn schiessuebungsraum': icon0,\r\n 'beginn schiessuebungsstrecke': icon1,\r\n 'doppelrhombus': icon2,\r\n 'doppelwinkel': icon3,\r\n 'ende schiessuebungsraum': icon4,\r\n 'ende schiessuebungsstrecke': icon5,\r\n 'rhombus': icon6,\r\n 'stellung feuerhalt': icon7,\r\n 'winkel': icon8,\r\n};\r\n\r\nexport default textures;","export default __webpack_public_path__ + \"static/media/beginn schiessuebungsraum.461cbd1c.png\";","export default __webpack_public_path__ + \"static/media/beginn schiessuebungsstrecke.b0de6080.png\";","export default __webpack_public_path__ + \"static/media/doppelrhombus.0d62fd3b.png\";","export default __webpack_public_path__ + \"static/media/doppelwinkel.1256e63e.png\";","export default __webpack_public_path__ + \"static/media/ende schiessuebungsraum.1209f377.png\";","export default __webpack_public_path__ + \"static/media/ende schiessuebungsstrecke.27c37067.png\";","export default __webpack_public_path__ + \"static/media/rhombus.05d7f59c.png\";","export default __webpack_public_path__ + \"static/media/stellung feuerhalt.10b48150.png\";","export default __webpack_public_path__ + \"static/media/winkel.943a1586.png\";","import basicPins from './basic-pins';\r\nimport trafficSigns from './traffic-signs';\r\nimport UKRoadSigns from './uk-road-signs';\r\nimport packageObjects from './package_objects';\r\nimport packageSigns from './package_signs';\r\nimport allterra from './allterra';\r\n\r\nconst tagTextures = {\r\n ...basicPins,\r\n ...trafficSigns,\r\n ...UKRoadSigns,\r\n ...packageObjects,\r\n ...packageSigns,\r\n ...allterra\r\n};\r\n\r\nexport const defaultTagTexture = Object.keys(tagTextures)[0];\r\n\r\nexport const getTagTexturePath = (key) => {\r\n return tagTextures[key];\r\n};\r\n\r\nexport default tagTextures;\r\n","import {\r\n addAsset,\r\n addAssets,\r\n AssetInfo,\r\n AssetType,\r\n pointCloudType,\r\n CameraData,\r\n OrthoData,\r\n LineworkLayerData,\r\n XMLData,\r\n TagItemData,\r\n WebMapData,\r\n createAsset,\r\n createTags\r\n} from \"../redux/assets-slice\";\r\nimport {Parser} from 'xml2js';\r\nimport {dialog, fse, getTemporaryFile, glob, isStaticSite} from \"../electron-modules\";\r\nimport path from 'path';\r\nimport slash from 'slash';\r\nimport {hideBackdrop, showBackdrop, toast} from \"../app\";\r\nimport {PythonExecutable} from \"../executable\";\r\nimport LocalScene, { isValidProjection } from \"../viewer/js/projections\";\r\nimport { chunkedArray } from \"../viewer/js/utilities\";\r\nimport { loadProjectFile } from \".\";\r\nimport {\r\n IFCFileFormat,\r\n imageCSVFormat,\r\n imageOrthoFormat,\r\n imagePlanarFormat,\r\n pointCloudFileFormats,\r\n configFileType,\r\n SHPFileFormat,\r\n DXFFileFormat,\r\n xmlFileFormat,\r\n projFileFormat\r\n} from \"../file-extensions\";\r\nimport { t } from \"../localization\";\r\nimport { readFileBuffer, readFileText } from \"../viewer/js/file-system-loader\";\r\nimport { Dispatch, nanoid } from \"@reduxjs/toolkit\";\r\nimport {curveDist, lineDist} from \"../viewer/js/measurements/land-xml-calculation\";\r\nimport { defaultTagTexture } from \"../viewer/textures/tag-icons\";\r\nimport { TagSize } from \"../types/tags\";\r\nimport { useDispatch } from \"react-redux\";\r\nimport { useGlobalSettings } from \"../hooks\";\r\nimport { openExternalLink } from \"../urls\";\r\nimport { updateDataProjection, updateViewProjection } from \"../redux/projections-slice\";\r\n\r\ninterface ImageDetectResults {\r\n readonly pathFound: boolean;\r\n readonly imagePath: string;\r\n readonly imageExt: string;\r\n readonly hasImageExt: boolean;\r\n}\r\n\r\nconst DEFAULT_LAYER_COLOR = \"#FF0000\";\r\n\r\nexport const useAssetTools = () => {\r\n const dispatch = useDispatch();\r\n const {orthoQuality} = useGlobalSettings();\r\n\r\n const addAssetPaths = async (assetPaths: string[], folderID: string) => {\r\n const cloudPaths = assetPaths.filter(isPointCloudFile);\r\n const cameraPaths = assetPaths.filter(isCameraFile);\r\n const modelPaths = assetPaths.filter(isModelFile);\r\n const orthoPaths = assetPaths.filter(isOrthomosaicFile);\r\n const planarPaths = assetPaths.filter(isPlanarFile);\r\n const xmlPaths = assetPaths.filter(isXmlFile);\r\n\r\n const numClouds = cloudPaths.length;\r\n const numModels = modelPaths.length;\r\n const numImageFiles = cameraPaths.length\r\n + orthoPaths.length\r\n + planarPaths.length;\r\n const numXmlFiles = xmlPaths.length;\r\n\r\n // Nothing to add, exit early\r\n if (numClouds === 0 && numImageFiles === 0 && numModels === 0 && numXmlFiles === 0) {\r\n return;\r\n }\r\n\r\n // Add all planar data\r\n const planarFilesAdded = await addPlanarFiles(planarPaths, folderID);\r\n\r\n // Add all panoramic data\r\n const csvFilesAdded = await addCSVFiles(cameraPaths, folderID);\r\n\r\n // Add all pointclouds\r\n const pointsAdded = addPointCloudFiles(cloudPaths, folderID);\r\n\r\n // Add orthomosaic data\r\n const orthosAdded = await addOrthoFiles(orthoPaths, folderID);\r\n\r\n // Add model files\r\n const modelsAdded = await addModelFiles(modelPaths, folderID);\r\n\r\n //Add xml files\r\n const xmlAdded = await addXMLFiles(xmlPaths, folderID);\r\n\r\n const totalAdded = pointsAdded\r\n + csvFilesAdded\r\n + planarFilesAdded\r\n + orthosAdded\r\n + modelsAdded\r\n + xmlAdded;\r\n\r\n if (totalAdded === 0) {\r\n return;\r\n }\r\n\r\n toast.success(t(\"toast.added-project-files\", {\r\n count: totalAdded\r\n }));\r\n };\r\n\r\n const addFilePaths = (filePaths: string[], folderID: string) => {\r\n if (!filePaths || filePaths.length === 0) return;\r\n\r\n const configs = filePaths.filter(isConfigFile);\r\n const assetPaths = filePaths.filter(isAssetFile);\r\n const projections = filePaths.filter(isProjectionFile);\r\n\r\n if (configs.length > 0) {\r\n // Load first config file (ignore other files)\r\n const success = loadProjectFile(configs[0]);\r\n if (success) {\r\n toast.success(t(\"toast.load-config-file\"));\r\n }\r\n return;\r\n }\r\n\r\n if (projections.length > 0) {\r\n // Read projection from solv3d projection file\r\n const projectionPath = projections[0];\r\n const text = fse.readFileSync(projectionPath);\r\n const projection = JSON.parse(text);\r\n\r\n if (isValidProjection(projection.string)) {\r\n dispatch(updateDataProjection(projection));\r\n dispatch(updateViewProjection(projection));\r\n } else {\r\n toast.error(\"Invalid projection file\");\r\n }\r\n }\r\n\r\n if (assetPaths.length > 0) {\r\n // Add new assets\r\n addAssetPaths(assetPaths, folderID);\r\n }\r\n };\r\n\r\n const addWebSource = (name: string, data: WebMapData, folderID: string) => {\r\n dispatch(addAsset({\r\n folderID,\r\n name,\r\n path: null,\r\n type: AssetType.Webmap,\r\n data\r\n }));\r\n };\r\n\r\n const addModelFiles = async (assetPaths: string[], folderID: string) => {\r\n const ifcPaths = assetPaths.filter(isIFCFile);\r\n const shpPaths = assetPaths.filter(isSHPFile);\r\n const dxfPaths = assetPaths.filter(isDXFFile);\r\n\r\n let modelsAdded = 0;\r\n modelsAdded += await addIFCFiles(dispatch, ifcPaths, folderID);\r\n modelsAdded += await addSHPFiles(dispatch, shpPaths, folderID);\r\n modelsAdded += await addDXFFiles(dispatch, dxfPaths, folderID);\r\n\r\n return modelsAdded;\r\n };\r\n\r\n const addPointCloudFiles = (assetPaths: string[], folderID: string) => {\r\n let assetsList = [] as AssetInfo[];\r\n\r\n assetPaths.forEach(pointPath => {\r\n const extension = path.extname(pointPath).slice(1);\r\n const type = pointCloudType(extension);\r\n const fileName = path.basename(pointPath);\r\n\r\n if (type === AssetType.Encompass) {\r\n pointPath = path.dirname(pointPath);\r\n if (fileName !== \"r.idx\") {\r\n toast.error(\"Error loading points. Expected filename is r.idx\");\r\n return;\r\n }\r\n }\r\n\r\n if (type === AssetType.Potree) {\r\n pointPath = path.dirname(pointPath);\r\n if (fileName !== \"octree.bin\") {\r\n toast.error(\"Error loading points. Expected filename is octree.bin\");\r\n return;\r\n }\r\n }\r\n\r\n assetsList.push({\r\n folderID,\r\n name: fileName,\r\n path: pointPath,\r\n type\r\n });\r\n });\r\n\r\n dispatch(addAssets(assetsList));\r\n return assetPaths.length;\r\n };\r\n\r\n const addOrthoFiles = async (assetPaths: string[], folderID: string) => {\r\n showBackdrop();\r\n\r\n let numAdded = await addOrthoBatch(dispatch,\r\n assetPaths, folderID, orthoQuality);\r\n\r\n hideBackdrop();\r\n\r\n return numAdded;\r\n };\r\n\r\n const addCSVFiles = async (assetPaths: string[], folderID: string) => {\r\n showBackdrop();\r\n\r\n let numAdded = 0;\r\n\r\n for (const assetPath of assetPaths) {\r\n try {\r\n await addCameraFile(dispatch, assetPath, folderID);\r\n numAdded++;\r\n continue;\r\n } catch {}\r\n\r\n try {\r\n await addTagCSV(dispatch, assetPath, folderID);\r\n numAdded++;\r\n continue;\r\n } catch {}\r\n }\r\n\r\n hideBackdrop();\r\n\r\n return numAdded;\r\n };\r\n\r\n const addTagCSVs = async (assetPaths: string[], folderID: string) => {\r\n showBackdrop();\r\n\r\n let numAdded = 0;\r\n\r\n for (const assetPath of assetPaths) {\r\n try {\r\n const tags = await addTagCSV(dispatch, assetPath, folderID);\r\n numAdded += 1;\r\n toast.success(t(\"toast.added-new-tags\", {\r\n count: tags.length\r\n }));\r\n } catch (result) {\r\n const filename = path.basename(assetPath);\r\n const {reason, data} = result;\r\n\r\n if (reason === 'missing_headers') {\r\n toast.error(t(\"toast.tag-missing-header\", {\r\n filename,\r\n missingHeaders: data.join(', ')\r\n }));\r\n } else if (reason === 'invalid_rows') {\r\n toast.error(t(\"toast.tag-invalid-row\", {\r\n filename,\r\n lineNumber: data[0].row_number,\r\n lineText: data[0].data\r\n }));\r\n } else if (reason === 'no_data') {\r\n toast.error(t(\"toast.tag-no-data\", {\r\n filename\r\n }));\r\n }\r\n }\r\n }\r\n\r\n hideBackdrop();\r\n\r\n return numAdded;\r\n };\r\n\r\n const addCameraFiles = async (assetPaths: string[], folderID: string) => {\r\n showBackdrop();\r\n\r\n let numAdded = 0;\r\n\r\n for (const assetPath of assetPaths) {\r\n try {\r\n await addCameraFile(dispatch, assetPath, folderID);\r\n numAdded += 1;\r\n } catch (event) {\r\n const fileName = path.basename(assetPath);\r\n\r\n if (event.pathError) {\r\n toast.error(t(\"toast.import-csv-path-error\", {\r\n path: fileName\r\n }));\r\n } else {\r\n toast.error(t(\"toast.import-csv-parse-error\", {\r\n path: fileName\r\n }));\r\n }\r\n }\r\n }\r\n\r\n hideBackdrop();\r\n\r\n return numAdded;\r\n };\r\n\r\n const addPlanarFiles = async (assetPaths: string[], folderID: string) => {\r\n showBackdrop();\r\n\r\n let numAdded = 0;\r\n for (const assetPath of assetPaths) {\r\n const added = await addPlanarFile(dispatch, assetPath, folderID);\r\n if (added) {\r\n numAdded += 1;\r\n } else {\r\n const fileName = path.basename(assetPath);\r\n toast.error(t(\"toast.import-planar-error\", {\r\n path: fileName\r\n }));\r\n }\r\n }\r\n\r\n hideBackdrop();\r\n\r\n return numAdded;\r\n };\r\n\r\n const addXMLFiles = async (assetPaths: string[], folderID: string) => {\r\n showBackdrop();\r\n\r\n let numAdded = 0;\r\n\r\n for (const assetPath of assetPaths) {\r\n const added = await addXMLFile(dispatch, assetPath, folderID);\r\n if (added) {\r\n numAdded++;\r\n }\r\n }\r\n\r\n hideBackdrop();\r\n\r\n return numAdded;\r\n };\r\n\r\n return {\r\n addAssetPaths,\r\n addFilePaths,\r\n addModelFiles,\r\n addPointCloudFiles,\r\n addOrthoFiles,\r\n addCSVFiles,\r\n addTagCSVs,\r\n addCameraFiles,\r\n addPlanarFiles,\r\n addXMLFiles,\r\n addWebSource\r\n };\r\n};\r\n\r\n/** Save a file based on name. Works for website and compiled exe */\r\nexport const downloadFile = async (name: string, data, fileType: string, fileFilter) => {\r\n if (isStaticSite) {\r\n const contentType = `data:text/${fileType};charset=utf-8`;\r\n const content = `${contentType},${encodeURIComponent(data)}`;\r\n openExternalLink(content, {name});\r\n } else {\r\n try {\r\n const savePath = await getPathFromDialog(name, fileFilter);\r\n if (!savePath) return false;\r\n\r\n await fse.writeFile(savePath, data);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n};\r\n\r\nconst getPathFromDialog = async (name, filter) => {\r\n const result = await dialog.showSaveDialog({\r\n defaultPath: name,\r\n filters: filter,\r\n });\r\n\r\n const {filePath, canceled} = result;\r\n if (canceled || !filePath) return;\r\n\r\n const savePath = slash(filePath);\r\n return savePath;\r\n};\r\n\r\nexport const pathWithExtension = (filename, extension) => {\r\n const basename = filename.replace(/\\.[^.$]+$/, '');\r\n return `${basename}.${extension}`;\r\n};\r\n\r\nexport const isAssetFile = (filename) => {\r\n return isPanoramicFile(filename)\r\n || isPlanarFile(filename)\r\n || isPointCloudFile(filename)\r\n || isOrthomosaicFile(filename)\r\n || isModelFile(filename)\r\n || isXmlFile(filename);\r\n};\r\n\r\nexport const isModelFile = (filename) => {\r\n return isIFCFile(filename)\r\n || isSHPFile(filename)\r\n || isDXFFile(filename);\r\n};\r\n\r\nexport const isCameraFile = (filename) => {\r\n return isCSVFile(filename)\r\n || isTXTFile(filename);\r\n};\r\n\r\nexport const isCSVFile = filename => {\r\n return path.extname(filename) === '.csv';\r\n};\r\n\r\nexport const isTXTFile = filename => {\r\n return path.extname(filename) === '.txt';\r\n};\r\n\r\nexport const isIFCFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return extension === IFCFileFormat;\r\n};\r\n\r\nexport const isSHPFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return extension === SHPFileFormat;\r\n};\r\n\r\nexport const isDXFFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return extension === DXFFileFormat;\r\n};\r\n\r\nexport const isConfigFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return extension === configFileType;\r\n};\r\n\r\nexport const isPanoramicFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return imageCSVFormat.indexOf(extension) !== -1;\r\n};\r\n\r\nexport const isProjectionFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return projFileFormat.indexOf(extension) !== -1;\r\n};\r\n\r\nexport const isPlanarFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return imagePlanarFormat.indexOf(extension) !== -1;\r\n};\r\n\r\nexport const isPointCloudFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return pointCloudFileFormats.indexOf(extension) !== -1;\r\n};\r\n\r\nexport const isOrthomosaicFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return imageOrthoFormat.indexOf(extension) !== -1;\r\n};\r\n\r\nexport const isXmlFile = (filename) => {\r\n const extension = path.extname(filename).slice(1);\r\n return extension === xmlFileFormat;\r\n};\r\n\r\nconst getDXFLayerNames = (text): Promise<{name: string, color: string}[]> => {\r\n return new Promise((resolve, reject) => {\r\n const workerURL = \"workers/dxf-reader.js\";\r\n let worker = new Worker(`${process.env.PUBLIC_URL}/${workerURL}`);\r\n\r\n worker.onmessage = event => {\r\n const {success, response} = event.data;\r\n\r\n if (success) {\r\n resolve(response);\r\n } else {\r\n console.error(response);\r\n reject(response);\r\n }\r\n };\r\n\r\n const data = {text, type: \"layers\"};\r\n worker.postMessage(data);\r\n });\r\n};\r\n\r\nconst getSHPLayerNames = (buffer) : Promise => {\r\n return new Promise((resolve, reject) => {\r\n const workerURL = \"workers/shp-reader.js\";\r\n let worker = new Worker(`${process.env.PUBLIC_URL}/${workerURL}`);\r\n\r\n worker.onmessage = event => {\r\n const {success, response} = event.data;\r\n\r\n if (success) {\r\n resolve(response);\r\n } else {\r\n console.error(response);\r\n reject(response);\r\n }\r\n };\r\n\r\n const data = {dbf: buffer, type: \"layers\"};\r\n worker.postMessage(data, [data.dbf]);\r\n });\r\n};\r\n\r\nconst addIFCFiles = async (dispatch: Dispatch, assetPaths: string[], folderID: string) => {\r\n let assetsList = [] as AssetInfo[];\r\n\r\n assetPaths.forEach(assetPath => {\r\n assetsList.push({\r\n folderID,\r\n name: path.basename(assetPath),\r\n path: assetPath,\r\n type: AssetType.IFC\r\n });\r\n });\r\n\r\n dispatch(addAssets(assetsList));\r\n return assetPaths.length;\r\n};\r\n\r\nconst addDXFFiles = async (dispatch: Dispatch, assetPaths: string[], folderID: string) => {\r\n let assetsList = [] as AssetInfo[];\r\n\r\n showBackdrop();\r\n\r\n for (let assetPath of assetPaths) {\r\n const fileName = path.basename(assetPath);\r\n\r\n try {\r\n const text = await readFileText(assetPath);\r\n const layers = await getDXFLayerNames(text);\r\n\r\n const layerData = layers.map(layer => {\r\n return {\r\n id: nanoid(),\r\n name: layer.name,\r\n visible: true,\r\n color: layer.color\r\n };\r\n }) as LineworkLayerData[];\r\n\r\n assetsList.push({\r\n folderID,\r\n name: fileName,\r\n path: assetPath,\r\n data: layerData,\r\n type: AssetType.DXF\r\n });\r\n } catch(err) {\r\n\r\n toast.error(t(\"toast.import-dxf-error\", {\r\n path: fileName\r\n }));\r\n }\r\n }\r\n\r\n hideBackdrop();\r\n\r\n dispatch(addAssets(assetsList));\r\n return assetsList.length;\r\n};\r\n\r\nconst addSHPFiles = async (dispatch: Dispatch, assetPaths: string[], folderID: string) => {\r\n let assetsList = [] as AssetInfo[];\r\n\r\n showBackdrop();\r\n\r\n for (let assetPath of assetPaths) {\r\n const fileName = path.basename(assetPath);\r\n\r\n try {\r\n const dbfPath = pathWithExtension(assetPath, \"dbf\");\r\n const buffer = await readFileBuffer(dbfPath);\r\n const layers = await getSHPLayerNames(buffer);\r\n\r\n const layerData = layers.map(layer => {\r\n return {\r\n id: nanoid(),\r\n name: layer,\r\n visible: true,\r\n color: DEFAULT_LAYER_COLOR\r\n };\r\n }) as LineworkLayerData[];\r\n\r\n assetsList.push({\r\n folderID,\r\n name: fileName,\r\n path: assetPath,\r\n data: layerData,\r\n type: AssetType.SHP\r\n });\r\n } catch(err) {\r\n\r\n toast.error(t(\"toast.import-shp-error\", {\r\n path: fileName\r\n }));\r\n }\r\n }\r\n\r\n hideBackdrop();\r\n\r\n dispatch(addAssets(assetsList));\r\n return assetsList.length;\r\n};\r\n\r\nconst addOrthoBatch = async (dispatch: Dispatch, assetPaths: string[], folderID: string, orthoQuality: number): Promise => {\r\n if (assetPaths.length === 0) {\r\n return 0;\r\n }\r\n\r\n return new Promise(async resolve => {\r\n const exe = new PythonExecutable();\r\n\r\n let response;\r\n let commands = [\r\n \"-p\", \"convert_geotiff\",\r\n \"--image_paths\", assetPaths,\r\n \"--output_scale\", orthoQuality\r\n ];\r\n\r\n let numAdded = 0;\r\n\r\n exe.run({\r\n command: commands,\r\n onLine: jsonData => {\r\n if (jsonData) {\r\n response = jsonData;\r\n }\r\n },\r\n onClose: () => {\r\n if (!response) {\r\n response = [];\r\n }\r\n\r\n let assetsList = [] as AssetInfo[];\r\n\r\n response.forEach(geotiff => {\r\n const assetPath = slash(geotiff.file_path);\r\n const fileName = path.basename(assetPath);\r\n\r\n if (geotiff.error) {\r\n toast.error(t(`toast.${geotiff.error}`, {\r\n path: fileName\r\n }));\r\n return;\r\n }\r\n\r\n const {corners, base64, width, height, base64_split,\r\n scale_x, scale_y, width_original, height_original} = geotiff;\r\n\r\n const orthoData = {\r\n imageBounds: corners,\r\n imageDataSplit: base64_split,\r\n imageData: base64,\r\n imageSize: [width, height],\r\n imageSizeOriginal: [width_original, height_original],\r\n imagePath: assetPath,\r\n scaleX: scale_x,\r\n scaleY: scale_y,\r\n } as OrthoData;\r\n\r\n assetsList.push({\r\n folderID,\r\n name: fileName,\r\n path: assetPath,\r\n type: AssetType.OrthoMosaic,\r\n data: orthoData\r\n });\r\n\r\n numAdded += 1;\r\n });\r\n\r\n dispatch(addAssets(assetsList));\r\n resolve(numAdded);\r\n }\r\n });\r\n });\r\n};\r\n\r\nconst addPlanarFile = (dispatch: Dispatch, assetPath: string, folderID: string): Promise => {\r\n return new Promise(async resolve => {\r\n const text = await fse.readFile(assetPath, {encoding: 'utf8'});\r\n\r\n let config;\r\n let cameras;\r\n\r\n try {\r\n let decoded = JSON.parse(text);\r\n config = decoded.config;\r\n cameras = decoded.data;\r\n } catch {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n const numCameras = cameras.length;\r\n if (numCameras === 0) {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n let cameraNames = cameras.map(x => x[0]);\r\n let {pathFound, imagePath, imageExt, hasImageExt}\r\n = await detectImagePath(assetPath, cameraNames);\r\n\r\n if (!pathFound) {\r\n resolve(false);\r\n return;\r\n }\r\n\r\n let cameraData: CameraData[] = [];\r\n\r\n for (let i=0;i => {\r\n return new Promise((resolve, reject) => {\r\n const exe = new PythonExecutable();\r\n\r\n let response;\r\n const inputPath = assetPath;\r\n const outputPath = getTemporaryFile(\"csv\");\r\n const projection = LocalScene.engineStyleProjection(LocalScene.dataProjection);\r\n\r\n let commands = [\r\n \"-p\", \"convert_encompass_csv\",\r\n \"--input_file\", inputPath,\r\n \"--output_file\", outputPath,\r\n \"--projection\", projection\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n onLine: jsonData => {\r\n response = jsonData;\r\n },\r\n onClose: async () => {\r\n if (!response) {\r\n reject({pathError: false});\r\n return;\r\n }\r\n\r\n let cameraData: CameraData[] = [];\r\n\r\n const cameras = response.csv_data;\r\n const estimatedPath = response.estimated_path;\r\n\r\n const numCameras = cameras.length;\r\n if (numCameras === 0) {\r\n reject({pathError: false});\r\n return;\r\n }\r\n\r\n let cameraNames = cameras.map(x => x.name);\r\n let {pathFound, imagePath, imageExt, hasImageExt}\r\n = await detectImagePath(assetPath, cameraNames, estimatedPath);\r\n\r\n if (!pathFound) {\r\n reject({pathError: true});\r\n return;\r\n }\r\n\r\n // Update final camera data path / filenames\r\n for (let i=0;i {\r\n const parser = new Parser({\r\n explicitChildren:true,\r\n preserveChildrenOrder: true\r\n });\r\n\r\n let text = await fse.readFile(assetPath, {encoding: 'utf8'});\r\n let textAll = String(text);\r\n let encoding = textAll.split('?>')[0].split('encoding=\"')[1].split('\"')[0];\r\n\r\n if (encoding !== 'utf-8') {\r\n if (encoding === 'iso-8859-1') {\r\n text = await fse.readFile(assetPath, {encoding: 'latin1'});\r\n } else {\r\n toast.error(t(\"dialog.xml-file-encoding-error\"));\r\n return false;\r\n }\r\n }\r\n\r\n try {\r\n let xmlJSON = await parser.parseStringPromise(text);\r\n if (!(\"LandXML\" in xmlJSON)) {\r\n toast.error(t(\"dialog.xml-file-load-error\"));\r\n return false;\r\n }\r\n\r\n xmlJSON = xmlJSON.LandXML;\r\n\r\n let xmlData = {\r\n info: xmlJSON.$,\r\n units: xmlJSON.Units[0].$$[0].$,\r\n alignments: [],\r\n enu: false\r\n } as XMLData;\r\n\r\n xmlJSON.Alignments[0].Alignment.forEach(alignment => {\r\n let alignObject = {\r\n id: nanoid(),\r\n name: alignment.$.name,\r\n length: parseFloat(alignment.$.length),\r\n staStart: parseFloat(alignment.$.staStart),\r\n about: alignment.$.desc,\r\n geometry: []\r\n };\r\n\r\n let geometry = alignment.CoordGeom[0].$$;\r\n\r\n if (Array.isArray(geometry)) {\r\n geometry.forEach(geom => {\r\n let geometryElement = {shapeType: geom['#name']};\r\n let dollarSignKeys = Object.keys(geom.$);\r\n let featureKeys = Object.keys(geom).filter(\r\n key=> ((key !== '$') && (key !== '$$') && (key !== '#name')));\r\n dollarSignKeys.forEach(key$ => {\r\n let aboutValue = geom.$[key$];\r\n aboutValue = !isNaN(parseFloat(aboutValue))\r\n ? parseFloat(aboutValue)\r\n : aboutValue;\r\n\r\n geometryElement[key$] = aboutValue;\r\n });\r\n\r\n featureKeys.forEach(fKey => {\r\n let coordValue = geom[fKey];\r\n let splitCoordValue;\r\n let tempValue;\r\n if (Object.keys(coordValue[0]).includes('$')) {\r\n tempValue = String(coordValue[0]['_']);\r\n } else {\r\n tempValue = String(coordValue[0]);\r\n }\r\n\r\n let newLineSep = tempValue.split('\\n');\r\n let recombine = newLineSep.join(' ');\r\n splitCoordValue = recombine.split(' ');\r\n let coordValueCorrected = [];\r\n splitCoordValue.forEach(scv=> {\r\n if (!isNaN(parseFloat(scv))) {\r\n coordValueCorrected.push(parseFloat(scv));\r\n }\r\n });\r\n if (coordValueCorrected.length > 0) {\r\n geometryElement[fKey] = coordValueCorrected;\r\n }\r\n });\r\n alignObject.geometry.push(geometryElement);\r\n });\r\n }\r\n\r\n xmlData.alignments.push(alignObject);\r\n });\r\n\r\n // Checks to see if length and staStart attributes were correctly added in\r\n // xml file, and if not, manually calculates them.\r\n\r\n let overwriteLength = false;\r\n let overwriteStaStart = false;\r\n\r\n xmlData.alignments.forEach(alignment => {\r\n let staStart = alignment.staStart;\r\n alignment.geometry.forEach(geom => {\r\n let keys = Object.keys(geom);\r\n if (!keys.includes(\"staStart\") || overwriteStaStart) {\r\n geom['staStart'] = staStart;\r\n overwriteStaStart = true;\r\n let length = 0;\r\n if (!keys.includes(\"length\") || overwriteLength) {\r\n overwriteLength = true;\r\n if (geom['shapeType'] === \"Line\") {\r\n length = lineDist(geom);\r\n } else if (geom['shapeType'] === \"Curve\") {\r\n length = curveDist(geom);\r\n }\r\n }\r\n if (overwriteLength) {\r\n geom['length'] = length;\r\n }\r\n if (overwriteStaStart) {\r\n staStart += length;\r\n }\r\n }\r\n geom['checked'] = 1;\r\n });\r\n });\r\n\r\n dispatch(addAsset({\r\n folderID,\r\n name: path.basename(assetPath),\r\n path: assetPath,\r\n type: AssetType.LandXML,\r\n data: xmlData\r\n }));\r\n\r\n return true;\r\n } catch {\r\n toast.error(t(\"dialog.xml-file-load-error\"));\r\n return false;\r\n }\r\n};\r\n\r\nconst addTagCSV = async (dispatch, assetPath: string, folderID: string) : Promise => {\r\n return new Promise((resolve, reject) => {\r\n let results = {\r\n valid_tags: [],\r\n invalid_rows: [],\r\n missing_headers: []\r\n };\r\n\r\n new PythonExecutable().run({\r\n command: ['-p', 'parse_tag_csv', '--path', assetPath],\r\n onLine: data => {\r\n if (data) {\r\n results = data;\r\n }\r\n },\r\n onClose: async () => {\r\n if (results.valid_tags.length === 0) {\r\n reject({reason: 'missing_headers', data: results.missing_headers});\r\n } else if (results.invalid_rows.length > 0) {\r\n reject({reason: 'invalid_rows', data: results.invalid_rows});\r\n } else if (results.missing_headers.length > 0) {\r\n reject({reason: 'no_data'});\r\n } else {\r\n const newTags = results.valid_tags.map(data => {\r\n const {name, comment, x, y} = data;\r\n\r\n const tag = {\r\n id: nanoid(),\r\n name,\r\n comment,\r\n x,\r\n y,\r\n date: new Date().toISOString(),\r\n sceneState: null\r\n } as TagItemData;\r\n\r\n if (\"z\" in data) {\r\n tag.z = data.z;\r\n }\r\n\r\n return tag;\r\n });\r\n\r\n // Create new tag collection\r\n const asset = await dispatch(createAsset({\r\n folderID,\r\n name: path.basename(assetPath),\r\n path: assetPath,\r\n type: AssetType.Tag,\r\n size: TagSize.Medium,\r\n texture: defaultTagTexture\r\n }));\r\n\r\n // Add new tags to collection\r\n await dispatch(createTags({\r\n assetID: asset.id,\r\n tags: newTags\r\n }));\r\n\r\n resolve(results.valid_tags);\r\n }\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport const openDialogMulti = (filter): Promise => {\r\n return dialog.showOpenDialog( {\r\n filters: filter,\r\n properties: ['openFile', 'multiSelections']\r\n }).then(result => {\r\n if (result.canceled) {\r\n return [];\r\n }\r\n\r\n const filePaths = result.filePaths.map(path => slash(path));\r\n return filePaths;\r\n }).catch(() => {\r\n dialog.showErrorBox(t(\"dialog.general-error-title\"), t(\"dialog.file-load-error\"));\r\n return [];\r\n });\r\n};\r\n\r\nexport const openDialogFile = (filter): Promise => {\r\n return dialog.showOpenDialog( {\r\n filters: filter,\r\n properties: ['openFile']\r\n }).then(result => {\r\n if (result.canceled) {\r\n return null;\r\n }\r\n\r\n const filePath = slash(result.filePaths[0]);\r\n return filePath;\r\n }).catch(() => {\r\n dialog.showErrorBox(t(\"dialog.general-error-title\"), t(\"dialog.file-load-error\"));\r\n return null;\r\n });\r\n};\r\n\r\nexport const openDialogFolder = (): Promise<{directoryPath: string, filePaths: string[]}> => {\r\n return new Promise((resolve) => {\r\n\r\n dialog.showOpenDialog({\r\n properties: ['openDirectory']\r\n }).then(async result => {\r\n if (result.canceled) {\r\n resolve({\r\n directoryPath: '',\r\n filePaths: []\r\n });\r\n\r\n return;\r\n }\r\n\r\n const filePath = slash(result.filePaths[0]);\r\n const filePaths = await parseDirectory(filePath);\r\n\r\n resolve({\r\n directoryPath: filePath,\r\n filePaths: filePaths\r\n });\r\n }).catch(() => {\r\n dialog.showErrorBox(t(\"dialog.general-error-title\"), t(\"dialog.file-load-error\"));\r\n return null;\r\n });\r\n });\r\n};\r\n\r\nexport const openDirectory = (): Promise => {\r\n return dialog.showOpenDialog({\r\n properties: [\"openDirectory\"]\r\n }).then(result => {\r\n if (result.canceled) {\r\n return null;\r\n }\r\n if (result.filePaths) {\r\n const outputFolder = slash(result.filePaths[0]);\r\n return outputFolder;\r\n }\r\n\r\n return null;\r\n });\r\n};\r\n\r\nconst parseDirectory = async (directoryPath: string): Promise => {\r\n const entries = await fse.readdir(directoryPath, {withFileTypes: true});\r\n\r\n const files = entries\r\n .filter(entry => entry.isFile())\r\n .map(file => path.join(directoryPath, file.name));\r\n\r\n const directories = entries\r\n .filter(entry => entry.isDirectory())\r\n .map(directory => path.join(directoryPath, directory.name));\r\n\r\n for (let folder of directories) {\r\n files.push(...await parseDirectory(folder));\r\n }\r\n\r\n return files;\r\n};\r\n\r\nconst checkImagePath = (directory, filenames, suffix, searchDepth = 3) => {\r\n const results = {\r\n success: false,\r\n duplicate: false,\r\n imagePath: null,\r\n imageExt: null\r\n };\r\n\r\n const singleFolderSearch = searchDepth === 1;\r\n\r\n let dirSeperator = \"\";\r\n for (let depth = 0; depth < searchDepth; depth++) {\r\n if (depth > 0) {\r\n dirSeperator += \"/*\";\r\n }\r\n\r\n let paths;\r\n\r\n if (singleFolderSearch && (filenames.length > 1)) {\r\n for (let subset of chunkedArray(filenames, 500)) {\r\n const filenameQuery = `{${subset.join(\",\")}}`;\r\n const globPath = `${dirSeperator}/${filenameQuery}${suffix}`;\r\n paths = glob.sync(globPath, {\r\n cwd: directory,\r\n root: directory\r\n });\r\n\r\n if (paths.length > 0) {\r\n break;\r\n }\r\n }\r\n } else {\r\n const globPath = `${dirSeperator}/${filenames[0]}${suffix}`;\r\n paths = glob.sync(globPath, {\r\n cwd: directory,\r\n root: directory\r\n });\r\n }\r\n\r\n let singleImageValid = paths.length === 1;\r\n let multiImageValid = singleFolderSearch && (paths.length > 0);\r\n\r\n if (singleImageValid || multiImageValid) {\r\n results.success = true;\r\n results.imagePath = path.dirname(paths[0]);\r\n results.imageExt = path.extname(paths[0]);\r\n return results;\r\n } else if (paths.length >= 2) {\r\n results.duplicate = true;\r\n }\r\n\r\n }\r\n\r\n return results;\r\n};\r\n\r\nexport const buildFilePath = (imagePath, filename, imageExt, hasImageExt) => {\r\n let filePath = hasImageExt ?\r\n path.join(imagePath, filename) :\r\n path.join(imagePath, `${filename}${imageExt}`);\r\n\r\n // Fix for windows UNC paths\r\n const isNetworkPath = imagePath.indexOf(\"//\") === 0;\r\n if (isNetworkPath) {\r\n filePath = `/${filePath}`;\r\n }\r\n\r\n return filePath;\r\n};\r\n\r\nexport const detectImagePath = async (assetPath: string, imageNames: string[], estimatedPath=null): Promise => {\r\n const directory = path.dirname(assetPath);\r\n const testImageExt = path.extname(imageNames[0]).toLowerCase();\r\n const hasImageExt = [\".jpg\", \".png\", \".jpeg\"].includes(testImageExt);\r\n const suffix = hasImageExt ? \"\" : \".{png,jpg,jpeg}\";\r\n\r\n let response = {\r\n pathFound: false,\r\n imagePath: null,\r\n imageExt: null,\r\n hasImageExt\r\n };\r\n\r\n // Search for image directory using csv path (or use pre-calculated estimated path)\r\n let {success, duplicate, imagePath, imageExt} = estimatedPath\r\n ? estimatedPath\r\n : checkImagePath(directory, imageNames, suffix);\r\n\r\n // Update response values\r\n response.pathFound = success;\r\n response.imagePath = imagePath;\r\n response.imageExt = imageExt;\r\n\r\n console.log(\"Detected image path: \", imagePath);\r\n\r\n if (!response.pathFound) {\r\n if (duplicate) {\r\n dialog.showErrorBox(assetPath, t(\"dialog.multiple-path-error\")\r\n );\r\n } else {\r\n dialog.showErrorBox(assetPath, t(\"dialog.missing-path-error\"));\r\n }\r\n\r\n const results = dialog.showOpenDialogSync({\r\n title: t(\"dialog.select-image-path\"),\r\n properties: ['openDirectory']\r\n });\r\n\r\n if (results) {\r\n // Search for image directory using selected folder\r\n imagePath = slash(results[0]);\r\n let manual = checkImagePath(imagePath, imageNames, suffix, 1);\r\n\r\n // Update response values\r\n response.pathFound = manual.success;\r\n response.imagePath = imagePath;\r\n response.imageExt = manual.imageExt;\r\n\r\n if (!manual.success) {\r\n dialog.showErrorBox(imagePath, t(\"dialog.manual-path-error\"));\r\n }\r\n }\r\n }\r\n\r\n return response;\r\n};","import {\r\n dialog,\r\n fs,\r\n} from \"../electron-modules\";\r\nimport slash from 'slash';\r\nimport { toast } from \"../app\";\r\nimport { cameraMatrixFilter } from \"../file-extensions\";\r\nimport { t } from \"../localization\";\r\nimport { Euler, Matrix4, Vector3 } from \"three\";\r\nimport { readFileText } from \"../viewer/js/file-system-loader\";\r\n\r\ninterface TransformResponse {\r\n success: Boolean,\r\n content: number[]\r\n}\r\n\r\nexport const saveMatrixFile = (cameraTransformPath) => {\r\n dialog.showSaveDialog({\r\n filters: cameraMatrixFilter,\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n if (result.filePath) {\r\n const savePath = slash(result.filePath);\r\n fs.copyFile(cameraTransformPath, savePath, (err) => {\r\n if (err) {\r\n toast.error(t(\"toast.correction-matrix-failed\"));\r\n } else {\r\n toast.success(t(\"toast.correction-matrix-saved\"));\r\n }\r\n });\r\n }\r\n });\r\n};\r\n\r\nexport const readTransformFile = (path: string): Promise => {\r\n return new Promise(async resolve => {\r\n const errorResponse = {\r\n success: false,\r\n content: null\r\n };\r\n\r\n if (!path) {\r\n resolve(errorResponse);\r\n return;\r\n }\r\n\r\n try {\r\n const data = await readFileText(path);\r\n\r\n let arr = [];\r\n let valid = true;\r\n\r\n const rows = data.split(\"\\n\");\r\n rows.forEach(row => {\r\n row = row.trim();\r\n if (row.length === 0) {\r\n return;\r\n }\r\n\r\n let cols = row.split(\" \");\r\n if (cols.length !== 4) {\r\n valid = false;\r\n }\r\n\r\n cols.forEach((col: any) => {\r\n if (isNaN(col)) {\r\n valid = false;\r\n }\r\n arr.push(parseFloat(col));\r\n });\r\n });\r\n\r\n if (arr.length !== 16) {\r\n valid = false;\r\n }\r\n\r\n if (!valid) {\r\n resolve(errorResponse);\r\n return;\r\n }\r\n\r\n const successResponse = {\r\n success: true,\r\n content: arr\r\n };\r\n\r\n resolve(successResponse);\r\n return;\r\n } catch {\r\n resolve(errorResponse);\r\n return;\r\n }\r\n });\r\n};\r\n\r\nexport const getMatrixValues = async (path: string) => {\r\n const {success, content} = await readTransformFile(path);\r\n\r\n if (!success) {\r\n return {success, rotation: null, offset: null};\r\n }\r\n\r\n const matrix = new Matrix4().fromArray(content);\r\n\r\n const transpose = new Matrix4().copy(matrix).transpose();\r\n const offset = new Vector3().setFromMatrixPosition(transpose);\r\n\r\n matrix.setPosition(0,0,0);\r\n const rotation = new Euler()\r\n .setFromRotationMatrix(matrix)\r\n .toVector3()\r\n .multiplyScalar(180 / Math.PI)\r\n .multiplyScalar(-1);\r\n\r\n return {success, rotation, offset};\r\n};\r\n","import { getConfigVersion } from \"../utilities\";\r\nimport { defaultTagTexture } from \"../viewer/textures/tag-icons\";\r\nimport { AssetType, CameraData } from \"./assets-slice\";\r\nimport { initialAerialState, initialSceneState } from \"./camera-slice\";\r\nimport { currentConfigVersion } from \"./project-slice\";\r\nimport semver from \"semver\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { ProjectType } from \"../types/project\";\r\nimport { TagSize } from \"../types/tags\";\r\n\r\nconst isCameraOrTag = (type) => {\r\n return (type === AssetType.Tag)\r\n || (type === AssetType.Planar)\r\n || (type === AssetType.Panoramic);\r\n};\r\n\r\nexport const upgradeConfig = (config) => {\r\n config = upgradeVersion34(config);\r\n config = upgradeVersion35(config);\r\n config = upgradeVersion36(config);\r\n config = upgradeVersion37(config);\r\n config = upgradeVersion38(config);\r\n config = upgradeVersion39(config);\r\n config = upgradeVersion310(config);\r\n config = upgradeVersion311(config);\r\n config = upgradeVersion312(config);\r\n config = upgradeVersion313(config);\r\n config = upgradeVersion314(config);\r\n config = upgradeVersion315(config);\r\n config = upgradeVersion316(config);\r\n config = upgradeVersion317(config);\r\n config = upgradeVersion318(config);\r\n config = upgradeVersion319(config);\r\n config = upgradeVersion320(config);\r\n config = upgradeVersion321(config);\r\n\r\n /** Additional upgrades go here */\r\n\r\n // Project config should now be at the latest version\r\n config.project.configVersion = currentConfigVersion;\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion321 = (config) => {\r\n const oldVersion = \"3.21.0\";\r\n const newVersion = \"3.22.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Add \"#\" to colors in dxf/shp layer data\r\n config.assets = config.assets.map(asset => {\r\n if ((asset.type === AssetType.DXF) || (asset.type === AssetType.SHP)) {\r\n asset.data = asset.data.map(layer => {\r\n if (layer.color[0] !== \"#\") {\r\n layer.color = `#${layer.color}`;\r\n }\r\n\r\n return layer;\r\n });\r\n }\r\n\r\n return asset;\r\n });\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion320 = (config) => {\r\n const oldVersion = \"3.20.0\";\r\n const newVersion = \"3.21.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Add scene state and date to each tag item\r\n config.assets = config.assets.map(asset => {\r\n if (asset.type === AssetType.Tag) {\r\n const items = asset.data.items.map(item => {\r\n delete item.camera;\r\n\r\n return {\r\n ...item,\r\n date: new Date().toISOString(),\r\n sceneState: null\r\n };\r\n });\r\n\r\n asset.data = {\r\n ...asset.data,\r\n items\r\n };\r\n }\r\n\r\n return asset;\r\n });\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion319 = (config) => {\r\n const oldVersion = \"3.19.0\";\r\n const newVersion = \"3.20.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n config.custom_links = config.links;\r\n delete config.links;\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion318 = (config) => {\r\n const oldVersion = \"3.18.0\";\r\n const newVersion = \"3.19.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Add tag draw distance\r\n config.settings.tagDistance = 1000;\r\n\r\n // Update old style camera ids\r\n const mappedCamerasIDs = {};\r\n config.assets.forEach(asset => {\r\n if ((asset.type === AssetType.Panoramic) || (asset.type === AssetType.Planar)) {\r\n const cameras = asset.data as CameraData[];\r\n cameras.forEach(camera => {\r\n const oldCameraID = `${asset.id}-${camera.name}`;\r\n mappedCamerasIDs[oldCameraID] = camera.id;\r\n });\r\n }\r\n });\r\n\r\n if (config.camera.sceneState.camera) {\r\n try {\r\n let newCameraID = mappedCamerasIDs[config.camera.sceneState.camera];\r\n if (newCameraID) {\r\n config.camera.sceneState.camera = newCameraID;\r\n }\r\n } catch {\r\n console.log(\"Error updating camera id (camera state)\");\r\n }\r\n }\r\n\r\n config.bookmarks = config.bookmarks.map(bookmark => {\r\n bookmark.settings.tagDistance = 1000;\r\n\r\n if (bookmark.sceneState.camera) {\r\n try {\r\n let newCameraID = mappedCamerasIDs[bookmark.sceneState.camera];\r\n if (newCameraID) {\r\n bookmark.sceneState.camera = newCameraID;\r\n }\r\n } catch {\r\n console.log(\"Error updating camera id (bookmark)\");\r\n }\r\n }\r\n\r\n return bookmark;\r\n });\r\n\r\n // Add size and camera id field for tags\r\n config.assets = config.assets.map(asset => {\r\n if (asset.type === AssetType.Tag) {\r\n const items = asset.data.items.map(item => {\r\n return {\r\n ...item,\r\n camera: null\r\n };\r\n });\r\n\r\n asset.data = {\r\n ...asset.data,\r\n size: TagSize.Medium,\r\n items\r\n };\r\n }\r\n\r\n return asset;\r\n });\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion317 = (config) => {\r\n const oldVersion = \"3.17.0\";\r\n const newVersion = \"3.18.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n if (\"overrideSettings\" in config.settings) {\r\n delete config.settings.overrideSettings;\r\n }\r\n\r\n config.assets = config.assets.map(asset => {\r\n asset.saved = asset.fromJSON;\r\n asset.cloud = false;\r\n delete asset.fromJSON;\r\n return asset;\r\n });\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion316 = (config) => {\r\n const oldVersion = \"3.16.0\";\r\n const newVersion = \"3.17.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n config.project.type = ProjectType.Standard;\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion315 = (config) => {\r\n const oldVersion = \"3.15.0\";\r\n const newVersion = \"3.16.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n if (\"newProject\" in config.project) {\r\n delete config.project.newProject;\r\n }\r\n\r\n if (\"modified\" in config.project) {\r\n delete config.project.modified;\r\n }\r\n\r\n config.project.uniqueSession = nanoid();\r\n config.project.id = nanoid();\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion314 = (config) => {\r\n const oldVersion = \"3.14.0\";\r\n const newVersion = \"3.15.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Change from folder.isDefault to folder.default\r\n config.folders = config.folders.map(folder => {\r\n if (folder.hasOwnProperty('isDefault')) {\r\n folder.default = folder.isDefault;\r\n delete folder.isDefault;\r\n }\r\n\r\n return folder;\r\n });\r\n\r\n // Move tag texture string from asset.texture to asset.data.texture\r\n config.assets = config.assets.map(asset => {\r\n if (asset.type !== AssetType.Tag) return asset;\r\n\r\n asset.data = {\r\n texture: asset.texture,\r\n items: asset.data\r\n };\r\n\r\n delete asset['texture'];\r\n return asset;\r\n });\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion313 = (config) => {\r\n const oldVersion = \"3.13.0\";\r\n const newVersion = \"3.14.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n config.assets = config.assets.map(asset => {\r\n let filePath = asset.data.path;\r\n\r\n if (filePath) {\r\n asset.path = filePath;\r\n delete asset.data;\r\n } else {\r\n asset.path = null;\r\n }\r\n\r\n return asset;\r\n });\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion312 = (config) => {\r\n const oldVersion = \"3.12.0\";\r\n const newVersion = \"3.13.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n config.settings.overrideSettings = true;\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion311 = (config) => {\r\n const oldVersion = \"3.11.0\";\r\n const newVersion = \"3.12.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Convert from cloudSize to cloudScale + cloudMinimum\r\n const cloudSize = config.settings.cloudSize;\r\n config.settings.cloudScale = Math.min(3.0, cloudSize);\r\n config.settings.cloudMinimum = 2.0;\r\n delete config.settings.cloudSize;\r\n\r\n return config;\r\n};\r\n\r\nconst upgradeVersion310 = (config) => {\r\n const oldVersion = \"3.10.0\";\r\n const newVersion = \"3.11.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n config.assets = config.assets.map(asset => {\r\n // Add unique ID to cameras and tags\r\n if (isCameraOrTag(asset.type)) {\r\n asset.data = asset.data.map(tag => {\r\n return {\r\n id: nanoid(),\r\n ...tag\r\n };\r\n });\r\n }\r\n\r\n // Add comments field for tags\r\n if (asset.type === AssetType.Tag) {\r\n asset.data = asset.data.map(tag => {\r\n return {\r\n ...tag,\r\n comment: \"\"\r\n };\r\n });\r\n }\r\n\r\n return asset;\r\n });\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\nconst upgradeVersion39 = (config) => {\r\n const oldVersion = \"3.9.0\";\r\n const newVersion = \"3.10.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n const extent = config.camera.aerialState.extent;\r\n const resolution = config.camera.aerialState.resolution;\r\n\r\n // Update camera state\r\n config.camera.sceneState = {\r\n ...initialSceneState,\r\n ...config.camera.sceneState\r\n };\r\n\r\n // Update aerial state\r\n config.camera.aerialState = {\r\n ...initialAerialState,\r\n ...config.camera.aerialState\r\n };\r\n\r\n // Convert resolution to zoom\r\n if (resolution) {\r\n const zoom = Math.log2(156543.03390625) - Math.log2(resolution);\r\n config.camera.aerialState.zoom = zoom;\r\n }\r\n\r\n // Convert extent to center\r\n if (extent) {\r\n config.camera.aerialState.center = [\r\n (extent[0] + extent[2]) / 2,\r\n (extent[1] + extent[3]) / 2\r\n ];\r\n }\r\n\r\n delete config.camera.aerialState.resolution;\r\n delete config.camera.aerialState.extent;\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\nconst upgradeVersion38 = (config) => {\r\n const oldVersion = \"3.8.0\";\r\n const newVersion = \"3.9.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Add default texture for tags\r\n config.assets = config.assets.map(asset => {\r\n asset.texture = (asset.type === AssetType.Tag) ? defaultTagTexture : undefined;\r\n return asset;\r\n });\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\nconst upgradeVersion37 = (config) => {\r\n const oldVersion = \"3.7.0\";\r\n const newVersion = \"3.8.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Apply upgrades\r\n delete config.settings.orthoOpacity;\r\n delete config.settings.orthoQuality;\r\n delete config.settings.controlType;\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\nconst upgradeVersion36 = (config) => {\r\n const oldVersion = \"3.6.0\";\r\n const newVersion = \"3.7.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // NOTE: Upgrades removed because of refactoring\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\nconst upgradeVersion35 = (config) => {\r\n const oldVersion = \"3.5.0\";\r\n const newVersion = \"3.6.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // Apply upgrades\r\n config.settings.cloudMaxPoints = config.settings.cloudMaxPoints/1000000;\r\n config.settings.cloudDistance = config.settings.cloudDistance * 10;\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\nconst upgradeVersion34 = (config) => {\r\n const oldVersion = \"3.4.0\";\r\n const newVersion = \"3.5.0\";\r\n\r\n if (semver.gt(getConfigVersion(config), oldVersion)) {\r\n return config;\r\n }\r\n\r\n console.log(`Upgrade configuration file: ${oldVersion} --> ${newVersion}`);\r\n\r\n // NOTE: Upgrades removed because of refactoring\r\n\r\n config.project.configVersion = newVersion;\r\n return config;\r\n};\r\n\r\n","import {store} from '../redux/store';\r\nimport {\r\n defaultProjectTitle,\r\n updateProjectName,\r\n changePath,\r\n currentConfigVersion,\r\n minimumConfigVersion\r\n} from '../redux/project-slice';\r\nimport {\r\n dialog,\r\n fs,\r\n app,\r\n registerEvent,\r\n isElectronApp\r\n} from '../electron-modules';\r\nimport slash from 'slash';\r\nimport path from 'path';\r\nimport {isEqual} from 'lodash';\r\nimport { upgradeConfig } from '../redux/config-upgrade';\r\nimport { configFilter } from '../file-extensions';\r\nimport semver from \"semver\";\r\nimport { t } from '../localization';\r\nimport { Projection } from '../redux/projections-slice';\r\nimport { defaultFolderTitle } from '../redux/folders-slice';\r\nimport { ProjectType } from '../types/project';\r\n\r\n/** Return the localized folder name for default project names,\r\n * and the saved name for everything else */\r\nexport const getLocalizedProjectName = (name: string) => {\r\n return name === defaultProjectTitle ? t(name) : name;\r\n};\r\n\r\n/** Return the localized projection name for default projections,\r\n * and the saved name for everything else */\r\nexport const getLocalizedProjectionName = (projection: Projection, units: string) => {\r\n return projection.default\r\n ? t(`projections.default-projection`, {units})\r\n : projection.name;\r\n};\r\n\r\n/** Return the localized folder name for default folders,\r\n * and the saved name for everything else */\r\nexport const getLocalizedFolderName = (name: string) => {\r\n return name === defaultFolderTitle ? t(name) : name;\r\n};\r\n\r\nexport const saveProjectAs = () => {\r\n const projectName = store.getState().project.name;\r\n const localizedProjectName = getLocalizedProjectName(projectName);\r\n const defaultPath = `${localizedProjectName}.json`;\r\n\r\n return dialog.showSaveDialog({\r\n title: t(\"dialog.save-project\"),\r\n defaultPath,\r\n filters: configFilter,\r\n }).then((result) => {\r\n if (result.canceled) {\r\n return false;\r\n }\r\n\r\n const savePath = slash(result.filePath);\r\n store.dispatch(changePath(savePath));\r\n\r\n // Update the title of the project to be the filename\r\n if (projectName === defaultProjectTitle) {\r\n const fileName = path.basename(savePath);\r\n const extension = path.extname(savePath);\r\n const nameWithoutExt = path.basename(fileName, extension);\r\n store.dispatch(updateProjectName(nameWithoutExt));\r\n }\r\n\r\n writeProject(store);\r\n return true;\r\n }).catch(() => {\r\n dialog.showErrorBox(t(\"dialog.project-save-title\"),\r\n t(\"dialog.project-save-message\"));\r\n return false;\r\n });\r\n};\r\n\r\nexport const saveProject = (allowSaveAs = true) => {\r\n return new Promise(resolve => {\r\n let state = store.getState();\r\n\r\n if (state.project.path === '') {\r\n if (allowSaveAs) {\r\n saveProjectAs().then(result => {\r\n resolve(result);\r\n });\r\n }\r\n return;\r\n } else {\r\n writeProject(store);\r\n resolve(true);\r\n }\r\n });\r\n};\r\n\r\nexport const loadProjectJSON = (projectJSON, parameters = {}) => {\r\n store.dispatch({\r\n type: 'LOAD',\r\n payload: {projectJSON, parameters}\r\n });\r\n};\r\n\r\nexport const getConfigVersion = (config) => {\r\n let version = config.project.configVersion;\r\n if (typeof version === \"number\") {\r\n version = `${String(version)}.0`;\r\n }\r\n\r\n return version;\r\n};\r\n\r\nexport const setWindowHash = (hash) => {\r\n window.history.pushState({}, '', \"#\" + hash);\r\n};\r\n\r\nexport const clearWindowHash = () => {\r\n window.location.hash = \"\";\r\n};\r\n\r\nexport const loadProjectFile = (filePath) => {\r\n try {\r\n const data = fs.readFileSync(filePath, 'utf8');\r\n\r\n // Update json path based on where the json was loaded from\r\n let projectJSON = JSON.parse(data);\r\n projectJSON.project.path = filePath;\r\n\r\n let configVersion = getConfigVersion(projectJSON);\r\n\r\n // Very old versions can't be upgraded\r\n if (semver.lt(configVersion, minimumConfigVersion)) {\r\n dialog.showErrorBox(t(\"dialog.general-error-title\"),\r\n t(\"dialog.legacy-version-error\", {version: configVersion}));\r\n return false;\r\n }\r\n\r\n // Upgrade project configuration to the most recent version\r\n if (semver.lt(configVersion, currentConfigVersion)) {\r\n projectJSON = upgradeConfig(projectJSON);\r\n }\r\n\r\n clearWindowHash();\r\n loadProjectJSON(projectJSON);\r\n return true;\r\n } catch (err) {\r\n dialog.showErrorBox(t(\"dialog.general-error-title\"),\r\n t(\"dialog.project-load-message\"));\r\n return false;\r\n }\r\n};\r\n\r\nexport const loadProject = () => {\r\n dialog.showOpenDialog({\r\n properties: ['openFile'],\r\n filters: configFilter\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n\r\n const filePath = slash(result.filePaths[0]);\r\n loadProjectFile(filePath);\r\n }).catch(error => {\r\n console.log(error);\r\n });\r\n};\r\n\r\nexport const newProject = () => {\r\n dialog.showMessageBox({\r\n type: 'question',\r\n title: t(\"dialog.new-project-title\"),\r\n message: t(\"dialog.new-project-unsaved\"),\r\n buttons: [\r\n t(\"buttons.cancel\"),\r\n t(\"buttons.new-project\")\r\n ],\r\n noLink: true\r\n })\r\n .then(result => {\r\n if (result.response === 0) return;\r\n store.dispatch({type: 'NEW'});\r\n });\r\n};\r\n\r\nconst writeProject = (store) => {\r\n // Update saved state for all assets\r\n store.dispatch({\r\n type: \"assets/setSavedState\",\r\n payload: null\r\n });\r\n\r\n const state = store.getState();\r\n const name = state.project.path;\r\n const string = JSON.stringify(state, null, 2);\r\n\r\n fs.writeFile(name, string, (err) => {\r\n if (err) {\r\n throw Error('an error occurred while saving the project');\r\n }\r\n });\r\n};\r\n\r\nconst exitWithChanges = async () => {\r\n const state = store.getState();\r\n\r\n // Cloud projects always exit immediately\r\n if (state.project.type === ProjectType.Cloud) {\r\n app.exit();\r\n return;\r\n }\r\n\r\n let hasChanged;\r\n if (state.project.path !== \"\") {\r\n // Compare current state to saved json state\r\n const data = fs.readFileSync(state.project.path, \"utf8\");\r\n let projectJSON = JSON.parse(data);\r\n\r\n const originalState = {...projectJSON};\r\n const modifiedState = JSON.parse(JSON.stringify(state));\r\n\r\n // Our session ID changes every time we load the file,\r\n // so it needs to be removed before we can compare states\r\n delete originalState.project.uniqueSession;\r\n delete modifiedState.project.uniqueSession;\r\n\r\n hasChanged = !isEqual(originalState, modifiedState);\r\n } else {\r\n // Dont prompt user unless assets are loaded\r\n hasChanged = state.assets.length !== 0;\r\n }\r\n\r\n if (!hasChanged) {\r\n app.exit();\r\n return;\r\n }\r\n\r\n const result = await dialog.showMessageBox({\r\n type: \"question\",\r\n message: t(\"dialog.exit-save-changes\"),\r\n buttons: [\r\n t(\"buttons.save\"),\r\n t(\"buttons.dont-save\")\r\n ],\r\n defaultId: 2,\r\n noLink: true\r\n });\r\n\r\n if (result.response === 1) {\r\n app.exit();\r\n } else if (result.response === 0) {\r\n await saveProject();\r\n app.exit();\r\n }\r\n};\r\n\r\nif (isElectronApp) {\r\n registerEvent(\"new-project\", newProject);\r\n registerEvent(\"load-project\", loadProject);\r\n registerEvent(\"save-project\", saveProject);\r\n registerEvent(\"save-project-as\", saveProjectAs);\r\n registerEvent(\"exit-with-changes\", exitWithChanges);\r\n}","import React, { useState, useEffect } from \"react\";\r\nimport {\r\n createStyles,\r\n makeStyles,\r\n Theme,\r\n Grid,\r\n Typography\r\n} from \"@material-ui/core\";\r\nimport { useDispatch } from \"react-redux\";\r\nimport { toast } from \"../../app\";\r\nimport {\r\n CheckboxWithLabel,\r\n DropdownWithLabel,\r\n FolderWithLabel,\r\n SimpleDialog,\r\n memoWithOpen\r\n} from \"../../components\";\r\nimport { fse, getTemporaryFile } from \"../../electron-modules\";\r\nimport { deleteAsset } from \"../../redux/assets-slice\";\r\nimport path from \"path\";\r\nimport { useTaskQueue, useViewer } from \"../../hooks\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAssetTools } from \"../../utilities\";\r\nimport { writeToString } from \"fast-csv\";\r\n\r\nenum DetectionType {\r\n VehiclesAndPeople=\"vehicles_and_people\",\r\n Vehicles=\"vehicles\",\r\n People=\"people\"\r\n}\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n mixedDataWarning: {\r\n padding: theme.spacing(1.0),\r\n color: theme.palette.warning.main,\r\n textAlign: \"center\"\r\n }\r\n }),\r\n);\r\n\r\nexport const BlurVehiclesPeople = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {addRunningTask} = useTaskQueue();\r\n const {addAssetPaths} = useAssetTools();\r\n const {t} = useTranslation();\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [detectionType, setDetectionType] = useState(DetectionType.VehiclesAndPeople);\r\n const [blurStrength, setBlurStrength] = useState(10);\r\n const [accuracy, setAccuracy] = useState(0.5);\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n };\r\n\r\n const handleSubmit = async () => {\r\n const pythonName = \"blur_vehicles_people\";\r\n\r\n const tempImagePath = getTemporaryFile(\"json\");\r\n const imagesCSVPath = path.join(outputPath, \"blurred-images.csv\");\r\n\r\n try {\r\n const cameras = viewer.getCamerasForCSV(asset.id);\r\n const cameraData = cameras.map(x => x.path);\r\n const pathsJSON = JSON.stringify(cameraData, null, 4);\r\n await fse.writeFile(tempImagePath, pathsJSON);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t('functions.error_running_function'));\r\n return;\r\n }\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--input_path\", tempImagePath,\r\n \"--output_path\", outputPath,\r\n \"--blur_options\", detectionType,\r\n \"--blur_level\", blurStrength,\r\n \"--detection-accuracy\", accuracy\r\n ];\r\n\r\n const onFinish = async () => {\r\n if (!importResult) return;\r\n\r\n try {\r\n // Generate camera csv in output folder\r\n const cameras = viewer.getCamerasForCSV(asset.id);\r\n const rows = viewer.getCameraRowsCSV(cameras);\r\n const content = await writeToString(rows);\r\n await fse.writeFile(imagesCSVPath, content);\r\n } catch {\r\n return;\r\n }\r\n\r\n // Remove old camera csv\r\n dispatch(deleteAsset(asset.id));\r\n\r\n // Add new camera csv\r\n await addAssetPaths([imagesCSVPath], asset.folderID);\r\n };\r\n\r\n onClose();\r\n addRunningTask(commands, onFinish);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const cameras = asset ? viewer.getCamerasForCSV(asset.id) : [];\r\n const folders = viewer.getCameraFolders(cameras);\r\n const inputFolders = new Set([...folders]);\r\n const pathOverlap = inputFolders.has(outputPath);\r\n const canSubmit = !pathOverlap && (outputPath !== null);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {pathOverlap && (\r\n \r\n {t('point-markup.output-folder-must-be-different')}\r\n \r\n )}\r\n\r\n {/** Detection Type */}\r\n \r\n \r\n \r\n\r\n {/** Detection Accuracy */}\r\n \r\n {\r\n const value = (index+1)/10;\r\n const text = `${(index+1)*10}%`;\r\n return [value, text];\r\n })\r\n }\r\n />\r\n \r\n\r\n {/** Blur Level */}\r\n \r\n {\r\n const value = index+1;\r\n const text = `${index+1}`;\r\n return [value, text];\r\n })\r\n }\r\n />\r\n \r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n {/** Output folder */}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n});\r\n","export * from \"./assets\";\r\nexport * from \"./camera\";\r\nexport * from \"./project\";\r\nexport * from \"./dates\";\r\n\r\nexport const asyncTimeout = (ms) => {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n};\r\n\r\n","import {\r\n CheckboxWithLabel, DropdownWithLabel,\r\n memoWithOpen,\r\n FileWithLabel,\r\n SimpleDialog\r\n} from \"../../components\";\r\nimport React, {useEffect, useMemo, useState} from \"react\";\r\nimport {useDispatch} from \"react-redux\";\r\nimport {useTaskQueue, useViewer} from \"../../hooks\";\r\nimport {\r\n Checkbox,\r\n createStyles,\r\n Grid,\r\n InputLabel, ListItemText,\r\n makeStyles,\r\n MenuItem,\r\n Select,\r\n Theme,\r\n Typography\r\n} from \"@material-ui/core\";\r\nimport {lasFileFilter} from \"../../file-extensions\";\r\nimport {deleteAsset} from \"../../redux/assets-slice\";\r\nimport clsx from \"clsx\";\r\nimport {classifications} from \"../../classifications\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAssetTools } from \"../../utilities\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n flexibleHeight: {\r\n height: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"space-between\",\r\n \"& span\": {\r\n flex: 1\r\n }\r\n },\r\n multipleSelectWithLabel: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n justifyContent: \"space-between\",\r\n \"& span\": {\r\n flex: 1\r\n }\r\n },\r\n paddingBottom: {\r\n paddingBottom: `${theme.spacing(1)}px !important`,\r\n },\r\n inputParent: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n minHeight: theme.spacing(3),\r\n paddingBottom: theme.spacing(0.5)\r\n }\r\n })\r\n);\r\n\r\nenum OperationTypes {\r\n Include = \"include\",\r\n Exclude = \"exclude\"\r\n}\r\n\r\nexport const ClassifyExport = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n const {viewer} = useViewer();\r\n const dispatch = useDispatch();\r\n const classes = useStyles();\r\n const {addRunningTask} = useTaskQueue();\r\n const {addAssetPaths} = useAssetTools();\r\n const {t} = useTranslation();\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [operationType, setOperationType] = useState(OperationTypes.Include);\r\n const [classValues, setClassValues] = useState([]);\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n const classList = useMemo(() => {\r\n if (!open || !asset) return new Set();\r\n const pointCloud = viewer.pointclouds.getByID(asset.id);\r\n return pointCloud.uniqueClassifications;\r\n }, [open, asset]);\r\n\r\n const canSubmit = (outputPath !== null)\r\n && (operationType !== null)\r\n && (classValues.length > 0);\r\n\r\n const handleSubmit = () => {\r\n const pythonName = \"classify_export\";\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--inputlas\", asset.path,\r\n \"--outputlas\", outputPath,\r\n \"--operation\", operationType,\r\n \"--classes\", classValues.toString()\r\n ];\r\n\r\n const afterClose = async () => {\r\n if (!importResult) return;\r\n\r\n // Remove old LAS\r\n dispatch(deleteAsset(asset.id));\r\n\r\n // Add new thinned LAS\r\n await addAssetPaths([outputPath], asset.folderID);\r\n };\r\n onClose();\r\n addRunningTask(commands, afterClose);\r\n };\r\n\r\n const handleClassChange = (event) => {\r\n setClassValues(event.target.value);\r\n };\r\n\r\n // Function of how the classes vals are rendered and shown in dropdown\r\n const renderClasses = (selected) => {\r\n const renderedClasses = [];\r\n selected.forEach((classVal) => {\r\n renderedClasses.push(formatClassValue(classVal));\r\n });\r\n return renderedClasses.join(\" ,\");\r\n };\r\n\r\n const formatClassValue = (classValue) => {\r\n return classifications[classValue].name + ` (${classValue})`;\r\n };\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n setOperationType(OperationTypes.Include);\r\n setClassValues([]);\r\n setImportResult(true);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Operation Type */}\r\n \r\n \r\n \r\n\r\n {/** Classes */}\r\n \r\n
\r\n
\r\n \r\n {t('functions.classify_export.classes')}\r\n \r\n
\r\n\r\n \r\n {t('functions.classify_export.classes_description')}\r\n \r\n\r\n \r\n {Array.from(classList.values()).map((classValue) => {\r\n return (\r\n \r\n -1} />\r\n \r\n \r\n );\r\n })}\r\n \r\n
\r\n
\r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n {/** Output LAS */}\r\n \r\n \r\n \r\n\r\n
\r\n \r\n
\r\n );\r\n});\r\n","import React, { useState, useEffect } from \"react\";\r\nimport {\r\n createStyles,\r\n FormHelperText,\r\n Grid,\r\n makeStyles,\r\n Theme\r\n} from \"@material-ui/core\";\r\nimport {\r\n CheckboxWithLabel,\r\n DropdownWithLabel,\r\n FolderWithLabel,\r\n NumberFieldWithLabel,\r\n SimpleDialog,\r\n memoWithOpen,\r\n} from \"../../components\";\r\nimport { pathWithExtension, useAssetTools } from \"../../utilities\";\r\nimport path from \"path\";\r\nimport LocalScene from \"../../viewer/js/projections\";\r\nimport { useTaskQueue } from \"../../hooks\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\nenum ChannelType {\r\n Empty=\"empty\",\r\n Red=\"red\",\r\n Green=\"green\",\r\n Blue=\"blue\",\r\n Linearity=\"linearity\",\r\n Planarity=\"planarity\",\r\n Scattering=\"scattering\",\r\n Normal=\"normal\",\r\n Intensity=\"intensity\",\r\n NumReturns=\"num_returns\",\r\n ReturnNumber=\"return_number\",\r\n Classification=\"classification\"\r\n}\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n helperText: {\r\n textAlign: \"center\",\r\n paddingTop: theme.spacing(2)\r\n }\r\n }),\r\n);\r\n\r\nconst ChannelSelector = (props) => {\r\n const {t} = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport const LasToOrthomosaic = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n\r\n const classes = useStyles();\r\n const {addRunningTask} = useTaskQueue();\r\n const {addAssetPaths} = useAssetTools();\r\n const {t} = useTranslation();\r\n\r\n const defaultPixelSize = {value: 0.1, error: false};\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [channelOne, setChannelOne] = useState(ChannelType.Empty);\r\n const [channelTwo, setChannelTwo] = useState(ChannelType.Empty);\r\n const [channelThree, setChannelThree] = useState(ChannelType.Empty);\r\n const [pixelSize, setPixelSize] = useState(defaultPixelSize);\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n };\r\n\r\n const handleSubmit = () => {\r\n const pythonName = \"las_to_orthomosaic\";\r\n const tifPath = pathWithExtension(\r\n path.join(outputPath, asset.name), \"tif\");\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--input_path\", asset.path,\r\n \"--output_path\", outputPath,\r\n \"--channel_1\", channelOne,\r\n \"--channel_2\", channelTwo,\r\n \"--channel_3\", channelThree,\r\n \"--pixel_size\", pixelSize.value,\r\n \"--units\", LocalScene.dataProjectionUnits\r\n ];\r\n\r\n const onFinish = async () => {\r\n if (!importResult) return;\r\n\r\n // Add new orthmosaic\r\n await addAssetPaths([tifPath], asset.folderID);\r\n };\r\n\r\n onClose();\r\n addRunningTask(commands, onFinish);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const emptyChannels = (channelOne === ChannelType.Empty)\r\n && (channelTwo === ChannelType.Empty)\r\n && (channelThree === ChannelType.Empty);\r\n\r\n const canSubmit = (outputPath !== null)\r\n && !pixelSize.error\r\n && !emptyChannels;\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Channel 1 color */}\r\n \r\n \r\n \r\n\r\n {/** Channel 2 color */}\r\n \r\n \r\n \r\n\r\n {/** Channel 3 color */}\r\n \r\n \r\n \r\n\r\n {/** Pixel size */}\r\n \r\n \r\n \r\n\r\n {/** Output folder */}\r\n \r\n \r\n \r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n \r\n\r\n {emptyChannels && \r\n {t('functions.las_to_orthomosaic.at_least_one_channel_must_be')}\r\n }\r\n \r\n \r\n );\r\n});\r\n","import {\r\n CheckboxWithLabel, DropdownWithLabel,\r\n memoWithOpen,\r\n SimpleDialog,\r\n TextWithLabel\r\n} from \"../../components\";\r\nimport React, {useEffect, useState} from \"react\";\r\nimport {useDispatch} from \"react-redux\";\r\nimport {useTaskQueue} from \"../../hooks\";\r\nimport {createStyles, FormHelperText, Grid, makeStyles, Theme} from \"@material-ui/core\";\r\nimport {deleteAsset} from \"../../redux/assets-slice\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAssetTools } from \"../../utilities\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n helperText: {\r\n textAlign: \"center\",\r\n paddingTop: theme.spacing(2)\r\n },\r\n savedLocation: {\r\n wordWrap: \"break-word\"\r\n }\r\n }),\r\n);\r\n\r\nexport const ConvertUnits = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n const dispatch = useDispatch();\r\n const {addRunningTask} = useTaskQueue();\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n const {addAssetPaths} = useAssetTools();\r\n\r\n const [inputUnits, setInputUnits] = useState('m');\r\n const [outputUnits, setOutputUnits] = useState('ft');\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n const nullUnits = inputUnits === '' || outputUnits === '';\r\n const sameUnits = (inputUnits === outputUnits && !nullUnits);\r\n const canSubmit = (!sameUnits && !nullUnits);\r\n\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n // Get name of saved file for display\r\n const basename = asset.name.replace(/\\.[^/.]+$/, \"\");\r\n const pathNameNoExt = asset.path.replace(/\\.[^/.]+$/, \"\");\r\n const outputName = `${basename}_${inputUnits}_to_${outputUnits}.las`;\r\n const outputPath = `${pathNameNoExt}_${inputUnits}_to_${outputUnits}.las`;\r\n\r\n const handleSubmit = () => {\r\n const pythonName = \"convert_units\";\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--inputlas\", asset.path,\r\n \"--input_units\", inputUnits,\r\n \"--output_units\", outputUnits\r\n ];\r\n\r\n const onFinish = async () => {\r\n if (!importResult) return;\r\n\r\n // Remove old LAS\r\n dispatch(deleteAsset(asset.id));\r\n\r\n // Add new thinned LAS\r\n await addAssetPaths([outputPath], asset.folderID);\r\n };\r\n\r\n onClose();\r\n addRunningTask(commands, onFinish);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setInputUnits('m');\r\n setOutputUnits('ft');\r\n setImportResult(true);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Input Units */}\r\n \r\n \r\n \r\n\r\n {/** Output Units */}\r\n \r\n \r\n \r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n {/** Output Path Display */}\r\n {canSubmit && \r\n \r\n }\r\n\r\n \r\n {sameUnits && \r\n {t('functions.convert_units.same_units_error')}\r\n }\r\n \r\n \r\n );\r\n});\r\n","import React, {useEffect, useState} from \"react\";\r\nimport {\r\n createStyles,\r\n FormHelperText,\r\n Grid, makeStyles, Theme\r\n} from \"@material-ui/core\";\r\nimport { useDispatch } from \"react-redux\";\r\nimport {\r\n CheckboxWithLabel,\r\n DropdownWithLabel,\r\n FileWithLabel,\r\n NumberFieldWithLabel,\r\n SimpleDialog,\r\n memoWithOpen,\r\n} from \"../../components\";\r\nimport {useTaskQueue} from \"../../hooks\";\r\nimport {deleteAsset} from \"../../redux/assets-slice\";\r\nimport {lasFileFilter} from \"../../file-extensions\";\r\nimport {tempDirectoryPath} from \"../../electron-modules\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAssetTools } from \"../../utilities\";\r\n\r\nenum ThinTechniques {\r\n Highest = \"highest\",\r\n Lowest = \"lowest\",\r\n Average = \"average\"\r\n};\r\n\r\nenum ThinDimensions {\r\n Two = 2,\r\n Three = 3,\r\n};\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n invalidThinningError: {\r\n padding: theme.spacing(1.0),\r\n color: theme.palette.warning.main,\r\n textAlign: \"center\"\r\n }\r\n }),\r\n);\r\n\r\nexport const ThinLas = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n\r\n const dispatch = useDispatch();\r\n const {addRunningTask} = useTaskQueue();\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const {addAssetPaths} = useAssetTools();\r\n\r\n const defaultThinningOptions = {\r\n value: 0.1,\r\n error: false\r\n };\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [thinTechnique, setThinTechnique] = useState(ThinTechniques.Lowest);\r\n const [thinDimension, setThinDimension] = useState(ThinDimensions.Two);\r\n const [thinning, setThinning] = useState(defaultThinningOptions);\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n const inValidThinningValue = thinning.value <= 0;\r\n const canSubmit = (outputPath !== null && !thinning.error && thinDimension && thinTechnique && !inValidThinningValue);\r\n\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n const handleSubmit = () => {\r\n const pythonName = \"thin\";\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--inputlas\", asset.path,\r\n \"--outputlas\", outputPath,\r\n \"--precision\", thinning.value,\r\n \"--keepvalue\", thinTechnique,\r\n \"--temp\", tempDirectoryPath,\r\n \"--dim\", thinDimension\r\n ];\r\n\r\n const onFinish = async () => {\r\n if (!importResult) return;\r\n\r\n // Remove old LAS\r\n dispatch(deleteAsset(asset.id));\r\n\r\n // Add new thinned LAS\r\n await addAssetPaths([outputPath], asset.folderID);\r\n };\r\n\r\n onClose();\r\n addRunningTask(commands, onFinish);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n setThinTechnique(ThinTechniques.Lowest);\r\n setThinDimension(ThinDimensions.Two);\r\n setThinning(defaultThinningOptions);\r\n setImportResult(true);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Output thinning */}\r\n \r\n \r\n \r\n\r\n {/** Thin Technique */}\r\n \r\n \r\n \r\n\r\n {/** Thin Dimension */}\r\n \r\n \r\n \r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n {/** Output LAS */}\r\n \r\n \r\n \r\n \r\n\r\n {inValidThinningValue && \r\n {t('functions.thin_las.invalid_thinning_value')}\r\n }\r\n\r\n \r\n \r\n );\r\n});\r\n\r\n\r\n","import React, {useEffect, useState} from \"react\";\r\nimport {\r\n Grid\r\n} from \"@material-ui/core\";\r\nimport { useDispatch } from \"react-redux\";\r\nimport {\r\n CheckboxWithLabel,\r\n FolderWithLabel,\r\n SimpleDialog,\r\n memoWithOpen,\r\n} from \"../../components\";\r\nimport {pathWithExtension, useAssetTools} from \"../../utilities\";\r\nimport path from \"path\";\r\nimport {useTaskQueue} from \"../../hooks\";\r\nimport {deleteAsset} from \"../../redux/assets-slice\";\r\nimport LocalScene from \"../../viewer/js/projections\";\r\nimport { useTranslation } from \"react-i18next\";\r\n\r\nexport const LasToSolv3dStreamable = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n const dispatch = useDispatch();\r\n const {addRunningTask} = useTaskQueue();\r\n const {addAssetPaths} = useAssetTools();\r\n const {t} = useTranslation();\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [isSingleFile, setSingleFile] = useState(true);\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n const canSubmit = (outputPath !== null);\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n const handleSubmit = () => {\r\n const pythonName = \"process_las\";\r\n const binPath = pathWithExtension(\r\n path.join(outputPath, \"octree\"), \"bin\");\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--input_path\", asset.path,\r\n \"--output_folder\", outputPath,\r\n \"--single_file\", isSingleFile,\r\n \"--units\", LocalScene.dataProjectionUnits\r\n ];\r\n\r\n const onFinish = async () => {\r\n if (!importResult) return;\r\n\r\n // Remove old LAS\r\n dispatch(deleteAsset(asset.id));\r\n\r\n // Add new streamable point cloud\r\n await addAssetPaths([binPath], asset.folderID);\r\n };\r\n\r\n onClose();\r\n addRunningTask(commands, onFinish);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n setImportResult(true);\r\n setSingleFile(true);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Single File */}\r\n \r\n \r\n \r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n {/** Output folder */}\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n});\r\n\r\n\r\n","import {\r\n CheckboxWithLabel,\r\n FileWithLabel,\r\n memoWithOpen,\r\n NumberFieldWithLabel,\r\n SimpleDialog\r\n} from \"../../components\";\r\nimport React, {useEffect, useState} from \"react\";\r\nimport {useDispatch} from \"react-redux\";\r\nimport {useTaskQueue} from \"../../hooks\";\r\nimport {Grid} from \"@material-ui/core\";\r\nimport {lasFileFilter} from \"../../file-extensions\";\r\nimport {deleteAsset} from \"../../redux/assets-slice\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAssetTools } from \"../../utilities\";\r\n\r\nexport const Sampling = memoWithOpen((props) => {\r\n const {assets, open, onClose} = props;\r\n const dispatch = useDispatch();\r\n const {addRunningTask} = useTaskQueue();\r\n const {addAssetPaths} = useAssetTools();\r\n const {t} = useTranslation();\r\n\r\n const defaultSamplingRateOptions = {\r\n value: 40,\r\n error: false\r\n };\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [samplingRate, setSamplingRate] = useState(defaultSamplingRateOptions);\r\n const [importResult, setImportResult] = useState(true);\r\n\r\n const validSampling = samplingRate.error === false && samplingRate.value !== null;\r\n const canSubmit = (outputPath !== null && validSampling);\r\n\r\n // TODO: actually handle multiple inputs (sent multiple exe commands to processing queue)\r\n const asset = assets ? assets[0] : undefined;\r\n\r\n const handleSubmit = () => {\r\n const pythonName = \"sampling\";\r\n const decimalSamplingRate = samplingRate.value/100;\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--inputlas\", asset.path,\r\n \"--outputlas\", outputPath,\r\n \"--rate\", decimalSamplingRate\r\n ];\r\n\r\n const onFinish = async () => {\r\n if (!importResult) return;\r\n\r\n // Remove old LAS\r\n dispatch(deleteAsset(asset.id));\r\n\r\n // Add new sampled LAS\r\n await addAssetPaths([outputPath], asset.folderID);\r\n };\r\n\r\n onClose();\r\n addRunningTask(commands, onFinish);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n setSamplingRate(defaultSamplingRateOptions);\r\n setImportResult(true);\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Sampling Rate */}\r\n \r\n \r\n \r\n\r\n {/** Import results */}\r\n \r\n \r\n \r\n\r\n {/** Output LAS */}\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n});\r\n","export enum ServerType {\r\n ArcGISMapServer = 0,\r\n ArcGISFeatureServer = 1,\r\n ArcGISImageServer = 2,\r\n ArcGISOnline = 3,\r\n OGCWMS = 4,\r\n OGCWMTS = 5,\r\n OGCWFS = 6,\r\n TileServer = 7\r\n}","import React from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { MenuItem, Typography } from \"@material-ui/core\";\r\nimport FunctionsIcon from '@material-ui/icons/Functions';\r\nimport { NestedMenu } from \"../components\";\r\nimport {\r\n BlurVehiclesPeople,\r\n ClassifyExport,\r\n ConvertUnits,\r\n LasToOrthomosaic,\r\n LasToSolv3dStreamable,\r\n Sampling,\r\n ThinLas\r\n} from \"./definitions\";\r\nimport { AssetType } from \"../redux/assets-slice\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { useDialog } from \"../hooks\";\r\n\r\nconst generateFunctionData = (title, condition, onClick) => {\r\n return {\r\n name: title,\r\n condition: condition,\r\n component: (\r\n \r\n {title}\r\n \r\n )\r\n };\r\n};\r\n\r\nexport const FunctionsMenu = React.forwardRef((props: any, ref) => {\r\n const {assets, contextOpen, closeContextMenu} = props;\r\n\r\n const {t} = useTranslation();\r\n const blurVehiclesPeopleDialog = useDialog();\r\n const lasToOrthomosaicDialog = useDialog();\r\n const lasToSolv3dStreamableDialog = useDialog();\r\n const thinLasDialog = useDialog();\r\n const samplingDialog = useDialog();\r\n const classifyExportDialog = useDialog();\r\n const convertUnitsDialog = useDialog();\r\n\r\n const LASFiles = assets\r\n .filter(x => x.type === AssetType.LAS);\r\n\r\n const cameraFiles = assets\r\n .filter(x => x.type === AssetType.Panoramic);\r\n\r\n const hasLASFiles = LASFiles.length > 0;\r\n const hasCameraFiles = cameraFiles.length > 0;\r\n\r\n const handleBlurVehiclesPeople = () => {\r\n closeContextMenu();\r\n blurVehiclesPeopleDialog.handleOpen();\r\n };\r\n\r\n const handleLasToOrthomosaic = () => {\r\n closeContextMenu();\r\n lasToOrthomosaicDialog.handleOpen();\r\n };\r\n\r\n const handleLasToSolv3dStreamable = () => {\r\n closeContextMenu();\r\n lasToSolv3dStreamableDialog.handleOpen();\r\n };\r\n\r\n const handleThinLas = () => {\r\n closeContextMenu();\r\n thinLasDialog.handleOpen();\r\n };\r\n\r\n const handleSampling = () => {\r\n closeContextMenu();\r\n samplingDialog.handleOpen();\r\n };\r\n\r\n const handleClassifyExport = () => {\r\n closeContextMenu();\r\n classifyExportDialog.handleOpen();\r\n };\r\n\r\n const handleConvertUnits = () => {\r\n closeContextMenu();\r\n convertUnitsDialog.handleOpen();\r\n };\r\n\r\n const getMenuItems = () => {\r\n if (!contextOpen) return [];\r\n\r\n const data = [\r\n generateFunctionData(\r\n t('functions.blur_vehicles_people.title'),\r\n hasCameraFiles,\r\n handleBlurVehiclesPeople\r\n ),\r\n generateFunctionData(\r\n t('functions.las_to_orthomosaic.title'),\r\n hasLASFiles,\r\n handleLasToOrthomosaic\r\n ),\r\n generateFunctionData(\r\n t('functions.las_to_solv3d_streamable.title'),\r\n hasLASFiles,\r\n handleLasToSolv3dStreamable\r\n ),\r\n generateFunctionData(\r\n t('functions.thin_las.title'),\r\n hasLASFiles,\r\n handleThinLas\r\n ),\r\n generateFunctionData(\r\n t('functions.sampling.title'),\r\n hasLASFiles,\r\n handleSampling\r\n ),\r\n generateFunctionData(\r\n t('functions.classify_export.title'),\r\n hasLASFiles,\r\n handleClassifyExport\r\n ),\r\n generateFunctionData(\r\n t('functions.convert_units.title'),\r\n hasLASFiles,\r\n handleConvertUnits\r\n )\r\n ];\r\n\r\n let filtered = data\r\n .filter(x => x.condition)\r\n .sort((a, b) => a.name.localeCompare(b.name))\r\n .map(x => x.component);\r\n\r\n if (filtered.length === 0) {\r\n return (\r\n \r\n \r\n {t('functions.no_functions_available')}\r\n \r\n \r\n );\r\n }\r\n\r\n return filtered;\r\n };\r\n\r\n return (\r\n \r\n }\r\n parentMenuOpen={contextOpen}\r\n >\r\n {getMenuItems()}\r\n \r\n\r\n {hasCameraFiles && \r\n\r\n {/** Blur vehicles and people */}\r\n \r\n\r\n }\r\n\r\n {hasLASFiles && \r\n\r\n {/** LAS to Orthomosaic */}\r\n \r\n\r\n {/** LAS to Solv3D Streamable Point Cloud */}\r\n \r\n\r\n {/** Thin Las */}\r\n \r\n\r\n {/** Sampling */}\r\n \r\n\r\n {/** Sampling */}\r\n \r\n\r\n {/** Convert Units */}\r\n \r\n\r\n }\r\n\r\n \r\n );\r\n});\r\n","import React, {useEffect, useState, memo, useCallback, useMemo} from \"react\";\r\nimport {isCloudSite, isElectronApp} from '../electron-modules';\r\nimport ListItem from \"@material-ui/core/ListItem\";\r\nimport CloudIcon from \"@material-ui/icons/Cloud\";\r\nimport InfoIcon from \"@material-ui/icons/Info\";\r\nimport PanoramaIcon from '@material-ui/icons/Panorama';\r\nimport PanoramaOutlinedIcon from '@material-ui/icons/PanoramaOutlined';\r\nimport ListItemText from \"@material-ui/core/ListItemText\";\r\nimport PublicIcon from '@material-ui/icons/Public';\r\nimport {\r\n Avatar,\r\n Checkbox,\r\n DialogContent,\r\n ListItemSecondaryAction,\r\n MenuItem,\r\n Typography\r\n} from \"@material-ui/core\";\r\nimport EditIcon from \"@material-ui/icons/Edit\";\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport ErrorIcon from '@material-ui/icons/Error';\r\nimport PhotoLibraryIcon from '@material-ui/icons/PhotoLibrary';\r\nimport SwapHorizIcon from '@material-ui/icons/SwapHoriz';\r\nimport WarningIcon from '@material-ui/icons/Warning';\r\nimport ImportExportIcon from '@material-ui/icons/ImportExport';\r\nimport Satellite from '@material-ui/icons/Satellite';\r\nimport {\r\n DenseMenu,\r\n DraggableDialog,\r\n DropDownDialog,\r\n LinearProgressWithLabel,\r\n MenuDivider,\r\n PromptDialog,\r\n TextDialog\r\n} from \"../components\";\r\nimport {createStyles, makeStyles, Theme} from \"@material-ui/core/styles\";\r\nimport {\r\n AssetType,\r\n updateAsset,\r\n deleteAsset,\r\n Asset,\r\n CameraData,\r\n TagData,\r\n XMLData,\r\n WebMapData\r\n} from \"../redux/assets-slice\";\r\nimport {useDispatch} from 'react-redux';\r\nimport { downloadFile } from '../utilities';\r\nimport {\r\n DenseIcon,\r\n FontAwesomeIcon,\r\n ArrowTooltip\r\n} from '../components';\r\nimport clsx from 'clsx';\r\nimport {toast} from \"../app\";\r\nimport {\r\n TagItemsDialog,\r\n TagIconDialog,\r\n ModelLayerDialog,\r\n WebSourceLayerDialog\r\n} from \".\";\r\nimport { getTagTexturePath } from \"../viewer/textures/tag-icons\";\r\nimport { isEqual } from 'lodash';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { FunctionsMenu } from \"../functions\";\r\nimport { useAuth, useContextMenu, useDialog, useViewer } from \"../hooks\";\r\nimport { ServerType } from \"../types/web-sources\";\r\nimport { csvExportFilter } from \"../file-extensions\";\r\nimport { writeToString } from \"fast-csv\";\r\n\r\nconst updateInterval = 200;\r\n\r\ninterface AssetState {\r\n assetPercent: number\r\n assetError: boolean\r\n assetIsLarge: boolean\r\n}\r\n\r\nconst initialAssetState = {\r\n assetPercent: 0,\r\n assetError: false,\r\n assetIsLarge: false,\r\n};\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n floatRight: {\r\n float: \"right\"\r\n },\r\n itemList: {\r\n paddingLeft: theme.spacing(4),\r\n display: \"inline-block\"\r\n },\r\n itemText: {\r\n wordBreak: \"break-all\",\r\n overflow: \"hidden\"\r\n },\r\n assetMargins: {\r\n margin: '0px 20px 0px 0px'\r\n },\r\n assetError: {\r\n color: theme.palette.error.main,\r\n fontWeight: \"bold\"\r\n },\r\n assetWarning: {\r\n color: theme.palette.warning.main,\r\n fontWeight: \"bold\"\r\n },\r\n assetInfo: {\r\n display: 'flex',\r\n margin: '0px'\r\n },\r\n assetCheckbox: {\r\n position: \"relative\",\r\n transform: \"translateY(0%)\",\r\n },\r\n checkboxParent: {\r\n padding: \"0px\",\r\n height: \"100%\"\r\n },\r\n percentLabel: {\r\n textAlign: \"right\"\r\n },\r\n fileInfoHeading: {\r\n paddingTop: theme.spacing(2.0)\r\n },\r\n fileInfoText: {\r\n display: \"block\"\r\n },\r\n tagAvatar: {\r\n width: \"20px\",\r\n height: \"20px\",\r\n borderRadius: theme.spacing(0)\r\n },\r\n titleClose: {\r\n position: 'absolute',\r\n right: theme.spacing(0),\r\n color: theme.palette.grey[500],\r\n },\r\n remoteAssetIcon: {\r\n fontSize: \"0.8rem\",\r\n marginRight: \"-0.8rem\", // must match font size\r\n position: \"relative\",\r\n left: \"-8px\",\r\n bottom: \"-5px\",\r\n opacity: \"1.0\",\r\n color: \"lightgray\",\r\n filter: \"drop-shadow(2px 2px 1px darkgray)\"\r\n }\r\n }),\r\n);\r\n\r\nconst LasFileInfoDialog = (props) => {\r\n const asset = props.asset as Asset;\r\n const {open, onClose, data} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const hasVLRSData = data.vlrs_data;\r\n\r\n let vlrsKeys = null;\r\n if (hasVLRSData) {\r\n vlrsKeys = Object.keys(data.vlrs_data);\r\n vlrsKeys.sort();\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n {t('asset.general-attributes')}\r\n \r\n\r\n \r\n {t('asset.file-name')}: {asset.name}\r\n \r\n\r\n \r\n {t('asset.point-information')}\r\n \r\n \r\n {t('asset.point-count')}: {data.points.count}\r\n \r\n \r\n {t('asset.x-range')}: [{data.points.x_min.toFixed(2)}, {data.points.x_max.toFixed(2)}]\r\n \r\n \r\n {t('asset.y-range')}: [{data.points.y_min.toFixed(2)}, {data.points.y_max.toFixed(2)}]\r\n \r\n \r\n {t('asset.z-range')}: [{data.points.z_min.toFixed(2)}, {data.points.z_max.toFixed(2)}]\r\n \r\n\r\n \r\n {t('asset.data-format')}\r\n \r\n \r\n {t('asset.las-version')}: {data.attributes.version}\r\n \r\n \r\n {t('asset.record-id')}: {data.attributes.record_id}\r\n \r\n \r\n {t('asset.contains-timestamp')}: {data.attributes.has_time_stamp ? t('general.yes') : t('general.no')}\r\n \r\n \r\n {t('asset.contains-rgb')}: {data.attributes.has_rgb ? t('general.yes') : t('general.no')}\r\n \r\n \r\n {t('asset.contains-intensity')}: {data.attributes.has_intensity ? t('general.yes') : t('general.no')}\r\n \r\n\r\n \r\n {t('asset.vlrs-metadata')}\r\n \r\n\r\n {hasVLRSData && (\r\n {vlrsKeys.map((key, index) => {\r\n return (\r\n \r\n {key}: {data.vlrs_data[key]}\r\n \r\n );\r\n })}\r\n )}\r\n\r\n {/* Nothing found in VLRS */}\r\n {!hasVLRSData && (\r\n \r\n {t('asset.no-data-found')}\r\n \r\n )}\r\n\r\n \r\n \r\n );\r\n};\r\n\r\ninterface AssetItemProps {\r\n asset: Asset,\r\n setDraggingAsset: Function\r\n}\r\n\r\nexport const AssetItem = memo((props: AssetItemProps) => {\r\n const {asset, setDraggingAsset} = props;\r\n\r\n const dispatch = useDispatch();\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const contextMenu = useContextMenu();\r\n const fileInfoDialog = useDialog();\r\n const detailsDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n const renameDialog = useDialog();\r\n const iconUpdateDialog = useDialog();\r\n const modelLayersDialog = useDialog();\r\n const webmapLayersDialog = useDialog();\r\n const landXMLDialog = useDialog();\r\n const {permissions} = useAuth();\r\n\r\n const [fileInfo, setFileInfo] = useState(null);\r\n const [assetState, setAssetState] = useState({\r\n ...initialAssetState\r\n });\r\n\r\n\r\n const isPanoramic = asset.type === AssetType.Panoramic;\r\n const isPlanar = asset.type === AssetType.Planar;\r\n const isEncompassCloud = asset.type === AssetType.Encompass;\r\n const isPotreeCloud = asset.type === AssetType.Potree;\r\n const isLASFile = asset.type === AssetType.LAS;\r\n const isE57File = asset.type === AssetType.E57Points;\r\n const isOrtho = asset.type === AssetType.OrthoMosaic;\r\n const isTag = asset.type === AssetType.Tag;\r\n const isIFC = asset.type === AssetType.IFC;\r\n const isSHP = asset.type === AssetType.SHP;\r\n const isDXF = asset.type === AssetType.DXF;\r\n const isLandXML = asset.type === AssetType.LandXML;\r\n const isWebMap = asset.type === AssetType.Webmap;\r\n\r\n const isModelFile = isIFC || isSHP || isDXF;\r\n const isCamera = isPanoramic || isPlanar;\r\n const isPointCloud = isLASFile || isEncompassCloud || isE57File || isPotreeCloud;\r\n\r\n const canEditLayers = useMemo(() => {\r\n if (isSHP || isDXF) {\r\n return true;\r\n }\r\n\r\n if (isWebMap) {\r\n const type = (asset.data as WebMapData).type;\r\n return (type !== ServerType.ArcGISImageServer)\r\n && (type !== ServerType.TileServer);\r\n }\r\n\r\n return false;\r\n }, [asset.type]);\r\n\r\n /** Handle asset percentage / state changes */\r\n useEffect(() => {\r\n // Create interval to update state\r\n const interval = setInterval(() => {\r\n updateAssetState();\r\n }, updateInterval);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }, [viewer, assetState]);\r\n\r\n useEffect(() => {\r\n // Update initial state\r\n updateAssetState();\r\n }, []);\r\n\r\n const updateAssetState = () => {\r\n if (!viewer) return;\r\n\r\n let newAssetState = {} as AssetState;\r\n\r\n if (isPointCloud) {\r\n newAssetState = viewer.getCloudStatus(asset.id);\r\n } else if (isModelFile) {\r\n newAssetState = viewer.getModelStatus(asset.id);\r\n }\r\n\r\n if (isEqual(assetState, newAssetState)) return;\r\n setAssetState(newAssetState);\r\n };\r\n\r\n const handleRenameSubmit = (name: string) => {\r\n dispatch(updateAsset({\r\n assetID: asset.id,\r\n name: name\r\n }));\r\n\r\n renameDialog.handleClose();\r\n };\r\n\r\n const handleRenameClick = () => {\r\n contextMenu.handleClose();\r\n renameDialog.handleOpen();\r\n };\r\n\r\n const handleDeleteClick = () => {\r\n contextMenu.handleClose();\r\n deleteDialog.handleOpen();\r\n };\r\n\r\n const handleIconChangeClick = () => {\r\n contextMenu.handleClose();\r\n iconUpdateDialog.handleOpen();\r\n };\r\n\r\n const handleOrderingClick = () => {\r\n contextMenu.handleClose();\r\n landXMLDialog.handleOpen();\r\n };\r\n\r\n const handleOrderingClose = (state: boolean) => {\r\n contextMenu.handleClose();\r\n landXMLDialog.handleClose();\r\n\r\n dispatch(updateAsset({\r\n assetID: asset.id,\r\n enu: state\r\n }));\r\n };\r\n\r\n const handleTagCSVExport = async (asset) => {\r\n contextMenu.handleClose();\r\n const tags = viewer.getTagsForCSV(asset.id);\r\n const rows = viewer.getTagRowsCSV(tags);\r\n const content = await writeToString(rows);\r\n downloadFile(asset.name, content, \"csv\", csvExportFilter);\r\n };\r\n\r\n const handleImageCSVExport = async (asset) => {\r\n contextMenu.handleClose();\r\n const cameras = viewer.getCamerasForCSV(asset.id);\r\n const rows = viewer.getCameraRowsCSV(cameras);\r\n const content = await writeToString(rows);\r\n downloadFile(asset.name, content, \"csv\", csvExportFilter);\r\n };\r\n\r\n const handleModelLayersClick = () => {\r\n contextMenu.handleClose();\r\n modelLayersDialog.handleOpen();\r\n };\r\n\r\n const handleWebmapLayersClick = () => {\r\n contextMenu.handleClose();\r\n webmapLayersDialog.handleOpen();\r\n };\r\n\r\n const onAssetDelete = () => {\r\n dispatch(deleteAsset(asset.id));\r\n };\r\n\r\n const handleAssetClick = (event) => {\r\n const isCheckBox = (event.target.type === \"checkbox\");\r\n if (isCheckBox) return;\r\n\r\n if (isOrtho) {\r\n viewer?.snapToOrtho(asset.id);\r\n } else if (isPointCloud) {\r\n viewer?.snapToPointCloud(asset.id);\r\n } else if (isCamera) {\r\n viewer?.snapToImages(asset.id);\r\n } else if (isTag) {\r\n detailsDialog.handleOpen();\r\n } else if (isModelFile) {\r\n viewer?.snapToModel(asset.id);\r\n }\r\n };\r\n\r\n const handleDragStart = () => {\r\n setDraggingAsset(asset.id);\r\n };\r\n\r\n const handleDragEnd = () => {\r\n setDraggingAsset(null);\r\n };\r\n\r\n const handleVisibilityClick = () => {\r\n dispatch(updateAsset({\r\n assetID: asset.id,\r\n visible: !asset.visible\r\n }));\r\n };\r\n\r\n const handleFileInfoClick = () => {\r\n contextMenu.handleClose();\r\n\r\n if (fileInfo) {\r\n fileInfoDialog.handleOpen();\r\n return;\r\n };\r\n\r\n let info = viewer.getLasFileInfo(asset.id);\r\n if (!info) {\r\n toast.warning(t(\"toast.file-info-missing\"));\r\n return;\r\n }\r\n\r\n setFileInfo(info);\r\n fileInfoDialog.handleOpen();\r\n };\r\n\r\n const getAssetText = () => {\r\n if (isCamera) {\r\n let items = asset.data as CameraData[];\r\n return `(${items.length}) ${asset.name}`;\r\n } else if (isTag) {\r\n let {items} = asset.data as TagData;\r\n return `(${items.length}) ${asset.name}`;\r\n }\r\n\r\n return asset.name;\r\n };\r\n\r\n const getTagAttributes = () => {\r\n if (!isTag) return {\r\n tagTexture: undefined,\r\n tagSize: undefined\r\n };\r\n\r\n const {texture, size} = (asset.data as TagData);\r\n\r\n return {\r\n tagTexture: texture,\r\n tagSize: size\r\n };\r\n };\r\n\r\n const submitTagIcon = useCallback((texture: string, size: number) => {\r\n dispatch(updateAsset({\r\n assetID: asset.id,\r\n texture: texture,\r\n size: size\r\n }));\r\n\r\n iconUpdateDialog.handleClose();\r\n }, [asset]);\r\n\r\n const {assetPercent, assetError, assetIsLarge} = assetState;\r\n\r\n const isLargeCloud = isPointCloud\r\n && assetIsLarge\r\n && (assetPercent < 100)\r\n && !assetError;\r\n\r\n const showPercent = (isLASFile || isE57File || isModelFile)\r\n && asset.visible\r\n && (assetPercent < 100);\r\n\r\n const assetText = getAssetText();\r\n const {tagTexture, tagSize} = getTagAttributes();\r\n const isRemoteAsset = asset.cloud && !isCloudSite;\r\n\r\n // Right now we only officially support editing/deleting\r\n // tag collections for the cloud site\r\n const canDeleteAsset = isElectronApp || (permissions.delete && isTag);\r\n const canEditAsset = isElectronApp || (permissions.edit && isTag);\r\n\r\n return (\r\n
\r\n \r\n
\r\n \r\n \r\n {/* Panoramic File */}\r\n {(isPanoramic) && ()}\r\n\r\n {/* Planar File */}\r\n {(isPlanar) && ()}\r\n\r\n {/* Tag File */}\r\n {isTag && ()}\r\n\r\n {/* Orthomosaic File */}\r\n {(isOrtho) && ()}\r\n\r\n {/* LandXML File */}\r\n {(isLandXML) && }\r\n\r\n {/* Webmap */}\r\n {(isWebMap) && }\r\n\r\n {/* Model File */}\r\n {isModelFile && \r\n {!assetError && (\r\n \r\n )}\r\n\r\n {assetError && (\r\n \r\n \r\n \r\n )}\r\n }\r\n\r\n {/* Pointcloud File */}\r\n {isPointCloud && \r\n {(!assetError && !isLargeCloud) && (\r\n \r\n )}\r\n\r\n {assetError && (\r\n \r\n \r\n \r\n )}\r\n\r\n {(isLargeCloud) && (\r\n \r\n \r\n \r\n )}\r\n }\r\n\r\n {isRemoteAsset && \r\n \r\n \r\n \r\n }\r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n
\r\n\r\n {/* File load percent */}\r\n {showPercent && (
\r\n \r\n
)}\r\n\r\n \r\n\r\n \r\n {/** Functions submenu */}\r\n {isElectronApp && }\r\n\r\n {isElectronApp && }\r\n\r\n {/** Export image csv */}\r\n {isPanoramic && {\r\n handleImageCSVExport(asset);\r\n }}>\r\n \r\n \r\n \r\n \r\n {t('asset.export-corrected-csv')}\r\n \r\n }\r\n\r\n {/** Export tag csv */}\r\n {isTag && {\r\n handleTagCSVExport(asset);\r\n }}>\r\n \r\n \r\n \r\n \r\n {t('asset.export-tag-csv')}\r\n \r\n }\r\n\r\n {/** Get LAS information */}\r\n {isLASFile && (\r\n \r\n \r\n \r\n \r\n {t('asset.file-info')}\r\n \r\n )}\r\n\r\n {/** Update tag icon */}\r\n {isTag && permissions.edit &&\r\n \r\n \r\n \r\n \r\n \r\n {t('asset.update-tag-icon')}\r\n \r\n \r\n }\r\n\r\n {/** Manage webmap layers */}\r\n {isWebMap && canEditLayers && (\r\n \r\n \r\n \r\n \r\n \r\n {t('asset.manage_layers')}\r\n \r\n \r\n )}\r\n\r\n {/** Manage model layers */}\r\n {isModelFile && canEditLayers && (\r\n \r\n \r\n \r\n \r\n \r\n {\"Manage Layers\"}\r\n \r\n \r\n )}\r\n\r\n {/** LandXML ordering */}\r\n {isLandXML && isElectronApp && (\r\n \r\n \r\n \r\n \r\n \r\n {t('asset.landxml-ordering')}\r\n \r\n \r\n )}\r\n\r\n {/** Rename asset */}\r\n \r\n \r\n \r\n \r\n \r\n {t('asset.rename')}\r\n \r\n \r\n\r\n {/** Delete asset */}\r\n \r\n \r\n \r\n \r\n \r\n {t('asset.delete')}\r\n \r\n \r\n \r\n\r\n {isTag && ()}\r\n\r\n {isWebMap && canEditLayers && ()}\r\n\r\n {isModelFile && canEditLayers && ()}\r\n\r\n {/* Discard measurements dialog */}\r\n {\r\n onAssetDelete();\r\n }}\r\n title={t('asset.delete-title')}\r\n prompt={t('asset.delete-prompt', {\r\n name: asset.name\r\n })}\r\n button={t(\"buttons.delete\")}\r\n />\r\n\r\n {/* Rename Dialog */}\r\n \r\n\r\n {/* LAS file info Dialog */}\r\n {fileInfo && ()}\r\n\r\n {/* Tag info dialog */}\r\n {isTag && }\r\n\r\n\r\n {isLandXML && }\r\n\r\n
\r\n );\r\n});\r\n","export const sendCustomEvent = (type, detail) => {\r\n const event = new CustomEvent(type, {detail});\r\n document.dispatchEvent(event);\r\n};","import React, {memo, useCallback, useEffect, useMemo, useState} from \"react\";\r\nimport {useSelector, useDispatch} from 'react-redux';\r\nimport {createStyles, makeStyles, Theme, useTheme} from \"@material-ui/core/styles\";\r\nimport tagTextures, { defaultTagTexture, getTagTexturePath } from \"../viewer/textures/tag-icons\";\r\nimport Pagination from \"@material-ui/lab/Pagination/Pagination\";\r\nimport LinkIcon from '@material-ui/icons/Link';\r\nimport ZoomInIcon from '@material-ui/icons/ZoomIn';\r\nimport CheckCircleIcon from '@material-ui/icons/CheckCircle';\r\nimport FileCopyIcon from '@material-ui/icons/FileCopy';\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport {\r\n createTags,\r\n updateTag,\r\n deleteTag,\r\n getTagAssets,\r\n selectAllAssets,\r\n TagData,\r\n TagItemData,\r\n Asset,\r\n createAsset,\r\n AssetType\r\n} from \"../redux/assets-slice\";\r\nimport {createFolder, selectAllFolders} from '../redux/folders-slice';\r\nimport {\r\n DialogContent,\r\n InputLabel,\r\n TextField,\r\n Avatar,\r\n Grid,\r\n Collapse,\r\n} from \"@material-ui/core\";\r\nimport clsx from 'clsx';\r\nimport {\r\n DraggableDialog,\r\n PromptDialog,\r\n EnhancedTable,\r\n SimpleDialog,\r\n InputWithLabel,\r\n DropdownWithLabel,\r\n DenseDivider,\r\n TextWithLabel,\r\n DividerWithText\r\n} from \"../components\";\r\nimport { toast } from \"../app\";\r\nimport { getLocalizedFolderName } from \"../utilities\";\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { isStaticSite } from \"../electron-modules\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { useAuth, useDialog, useUniqueProjectID, useViewer } from \"../hooks\";\r\nimport { TagSize } from \"../types/tags\";\r\nimport { sendCustomEvent } from \"../events\";\r\nimport { useTableState } from \"../hooks/use-table-state\";\r\nimport { useAppDispatch } from \"../redux/store\";\r\nimport copyTextToClipboard from \"copy-to-clipboard\";\r\n\r\nexport const tagIconsPerRow = 8;\r\nexport const tagRowsPerPage = 3;\r\n\r\nconst NEW_CSV_ID = \"__new_csv__\";\r\nconst NEW_FOLDER_ID = \"__new_folder__\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n textField: {\r\n marginBottom: theme.spacing(3)\r\n },\r\n selectDivider: {\r\n margin: theme.spacing(0.5),\r\n opacity: 0.2\r\n },\r\n asterisk: {\r\n \"&:after\": {\r\n content:'\"*\"',\r\n color: \"red\",\r\n paddingLeft: theme.spacing(0.5)\r\n }\r\n },\r\n avatarParent: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n paddingTop: theme.spacing(2)\r\n },\r\n tagAvatar: {\r\n width: \"24px\",\r\n height: \"24px\",\r\n cursor: \"pointer\",\r\n \"&:hover\": {\r\n width: \"26px\",\r\n height: \"26px\",\r\n margin: \"-1px\"\r\n }\r\n },\r\n tagIconPagination: {\r\n paddingBottom: theme.spacing(2)\r\n },\r\n tagIconSearchParent: {\r\n textAlign: \"right\",\r\n paddingRight: theme.spacing(2),\r\n paddingBottom: theme.spacing(1)\r\n },\r\n tagIconPageParent: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"row-reverse\"\r\n },\r\n tagIconParent: {\r\n position: \"relative\",\r\n display: \"inline-block\",\r\n width: `calc(${100/tagIconsPerRow}% - ${theme.spacing(2)}px)`,\r\n padding: theme.spacing(1)\r\n },\r\n tagIconCheck: {\r\n userSelect: \"none\",\r\n bottom: theme.spacing(1),\r\n right: theme.spacing(1),\r\n position: \"absolute\",\r\n color: \"green\",\r\n backgroundColor: \"white\",\r\n borderRadius: \"50%\"\r\n },\r\n tagIconImage: {\r\n width: `calc(100% - ${theme.spacing(1)}px)`,\r\n height: `calc(100% - ${theme.spacing(1)}px)`,\r\n margin: theme.spacing(0.5),\r\n cursor: \"pointer\",\r\n \"&:hover\": {\r\n width: \"100%\",\r\n height: \"100%\",\r\n margin: \"0px\",\r\n }\r\n },\r\n content: {\r\n padding: theme.spacing(0),\r\n paddingTop: \"0px !important\"\r\n }\r\n }),\r\n);\r\n\r\ninterface TagIconDialogProps {\r\n open: boolean\r\n onSubmit(texture: string, size: number): void\r\n onClose(): void\r\n currentTexture: string\r\n currentSize: number\r\n}\r\n\r\nexport const TagIconDialog = memo((props: TagIconDialogProps) => {\r\n const {open, onSubmit, onClose, currentTexture, currentSize} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [page, setPage] = useState(1);\r\n const [search, setSearch] = useState(\"\");\r\n const [tagTexture, setTagTexture] = useState(\"\");\r\n const [tagSize, setTagSize] = useState(0);\r\n\r\n const handleIconClick = (texture) => {\r\n setTagTexture(texture);\r\n };\r\n\r\n const onSearch = (event) => {\r\n setPage(1);\r\n setSearch(event.target.value as string);\r\n };\r\n\r\n const onPageChange = (event, page: number) => {\r\n setPage(page);\r\n };\r\n\r\n const resetDefaults = () => {\r\n let selectedPage = Math.floor(\r\n textures.indexOf(currentTexture) / tagsPerPage) + 1;\r\n\r\n setSearch(\"\");\r\n setTagTexture(currentTexture);\r\n setTagSize(currentSize);\r\n setPage(selectedPage);\r\n };\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const textures = useMemo(() => {\r\n const searchText = search.toLowerCase().trim();\r\n const searchTerms = searchText.split(\" \");\r\n\r\n if (searchText === \"\") {\r\n return Object.keys(tagTextures);\r\n }\r\n\r\n return Object.keys(tagTextures)\r\n .map(key => {\r\n const itemText = key.toLowerCase();\r\n const matches = searchTerms.filter(x => itemText.includes(x)).length;\r\n return {key, matches};\r\n })\r\n .filter(x => x.matches >= searchTerms.length)\r\n .map(x => x.key);\r\n }, [search]);\r\n\r\n const iconChanged = (tagTexture !== currentTexture);\r\n const sizeChanged = (tagSize !== currentSize);\r\n\r\n const tagsPerPage = tagIconsPerRow * tagRowsPerPage;\r\n const numPages = Math.ceil(textures.length / tagsPerPage);\r\n\r\n const texturesForPage = textures.slice(\r\n (page-1) * tagsPerPage,\r\n page * tagsPerPage\r\n );\r\n\r\n return (\r\n {\r\n onSubmit(tagTexture, tagSize);\r\n }}\r\n button={t(\"buttons.apply-changes\")}\r\n >\r\n
\r\n \r\n
\r\n\r\n
\r\n {texturesForPage.map(texture => (\r\n
\r\n {\r\n handleIconClick(texture);\r\n }}\r\n />\r\n\r\n {(texture === tagTexture) && ()}\r\n
\r\n ))}\r\n
\r\n\r\n
\r\n \r\n
\r\n\r\n \r\n\r\n
\r\n \r\n\r\n {/** Icon Size */}\r\n \r\n \r\n \r\n
\r\n\r\n \r\n );\r\n});\r\n\r\ninterface TagItemsDialogProps {\r\n asset: Asset\r\n open: boolean;\r\n title: string;\r\n onClose(): void;\r\n}\r\n\r\nexport const TagItemsDialog = (props: TagItemsDialogProps) => {\r\n const {asset, open, title, onClose} = props;\r\n\r\n const {viewer} = useViewer();\r\n const dispatch = useDispatch();\r\n const {i18n, t} = useTranslation();\r\n\r\n const deleteDialog = useDialog();\r\n const {permissions} = useAuth();\r\n const tableState = useTableState({defaultSort: \"name\"});\r\n\r\n const formatter = viewer.getMeasurementFormatter();\r\n const precision = formatter.getVectorPrecision(LocalScene.viewProjection);\r\n\r\n const onEdit = (row) => {\r\n showTagDetails(row.tagID, true);\r\n };\r\n\r\n const onDelete = (row) => {\r\n dispatch(deleteTag(row.tagID));\r\n };\r\n\r\n const onRowClick = (row, index) => {\r\n if (index > 2) return;\r\n viewer.jumpToTag(row.tagID);\r\n };\r\n\r\n const getRows = (items) => {\r\n return items.map((tag, index) => {\r\n const isAerialTag = !(\"z\" in tag);\r\n const x = tag.x.toFixed(precision.x);\r\n const y = tag.y.toFixed(precision.y);\r\n const z = isAerialTag ? \"N/A\" : tag.z.toFixed(precision.z);\r\n\r\n const coordinate = isAerialTag\r\n ? `(${x}, ${y})`\r\n : `(${x}, ${y}, ${z})`;\r\n\r\n const position = isAerialTag\r\n ? [tag.x, tag.y]\r\n : [tag.x, tag.y, tag.z];\r\n\r\n let rowData = {\r\n id: `TagTableRow_${tag.id}`,\r\n tagID: tag.id,\r\n tag: index + 1,\r\n modified: tag.date,\r\n name: tag.name,\r\n comment: tag.comment,\r\n coordinate,\r\n position\r\n };\r\n\r\n return rowData;\r\n });\r\n };\r\n\r\n const tagItems = (asset.data as TagData).items;\r\n\r\n const actions = useMemo(() => {\r\n const zoomToTag = {\r\n title: t('tags.move_to_tag'),\r\n icon: ,\r\n onClick: (row) => {\r\n viewer.jumpToTag(row.tagID);\r\n }\r\n };\r\n\r\n const copyPosition = {\r\n title: t(\"tags.copy-to-clipboard\"),\r\n icon: ,\r\n onClick: (row) => {\r\n // Copy position to clipboard\r\n copyTextToClipboard(row.coordinate);\r\n toast.success(t(\"toast.copied-to-clipboard\"));\r\n }\r\n };\r\n\r\n const copyURL = {\r\n title: t('tags.copy_tag_url'),\r\n icon: ,\r\n onClick: (row) => {\r\n // Copy url to clipboard\r\n const url = new URL(window.location as any);\r\n url.hash = `tag=${row.tagID}`;\r\n copyTextToClipboard(url.href);\r\n toast.success(t(\"toast.copied-to-clipboard\"));\r\n }\r\n };\r\n\r\n const deleteRow = {\r\n title: t(\"buttons.delete\"),\r\n icon: ,\r\n onClick: (row) => {\r\n deleteDialog.handleOpen(row);\r\n }\r\n };\r\n\r\n const editRow = {\r\n title: t(\"buttons.edit\"),\r\n icon: ,\r\n onClick: onEdit\r\n };\r\n\r\n let actions = [];\r\n actions.push(zoomToTag);\r\n actions.push(copyPosition);\r\n\r\n if (isStaticSite) {\r\n actions.push(copyURL);\r\n }\r\n\r\n if (permissions.edit) {\r\n actions.push(editRow);\r\n }\r\n\r\n if (permissions.delete) {\r\n actions.push(deleteRow);\r\n }\r\n\r\n return actions;\r\n }, [i18n.language, permissions, isStaticSite]);\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t(\"tags.table-name\"),\r\n wordBreak: true,\r\n searchable: true\r\n },\r\n {\r\n id: 'comment',\r\n label: t(\"tags.table-comments\"),\r\n wordBreak: true,\r\n searchable: true\r\n },\r\n {\r\n id: 'modified',\r\n label: t(\"tags.table-date\"),\r\n date: true\r\n },\r\n ];\r\n\r\n const rows = useMemo(() => {\r\n return getRows(tagItems);\r\n }, [tagItems]);\r\n\r\n let deletePrompt = \"\";\r\n if (deleteDialog.open) {\r\n deletePrompt = t('tags.do_you_want_to_delete_this_tag_row_name', {\r\n name: deleteDialog.data.name\r\n });\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* Delete Dialog */}\r\n {\r\n onDelete(deleteDialog.data);\r\n deleteDialog.handleClose();\r\n }}\r\n title={t(\"enhanced-table.prompt-delete-title\")}\r\n prompt={deletePrompt}\r\n button={t('buttons.delete')}\r\n />\r\n \r\n );\r\n};\r\n\r\ninterface TagDeleteDialogProps {\r\n open: boolean;\r\n onClose(): void;\r\n toDelete: string[];\r\n}\r\n\r\nexport const TagDeleteDialog = (props: TagDeleteDialogProps) => {\r\n const {open, onClose, toDelete = []} = props;\r\n\r\n const dispatch = useDispatch();\r\n const {t} = useTranslation();\r\n\r\n const onSubmit = () => {\r\n toDelete.forEach(tagID => {\r\n dispatch(deleteTag(tagID));\r\n });\r\n\r\n onClose();\r\n toast.success(t(\"toast.tag-removed\", {\r\n count: numTagsToDelete\r\n }));\r\n };\r\n\r\n const numTagsToDelete = toDelete.length;\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport const TagDetailsDialog = () => {\r\n const dispatch = useDispatch();\r\n const {t} = useTranslation();\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const tagAssets = getTagAssets(assets);\r\n const uniqueProjectID = useUniqueProjectID();\r\n const tagDetailsDialog = useDialog();\r\n const {permissions} = useAuth();\r\n\r\n const [title, setTitle] = useState(\"\");\r\n const [comment, setComment] = useState(\"\");\r\n const [tagToEdit, setTagToEdit] = useState(null);\r\n const [editing, setEditing] = useState(false);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n onClose();\r\n }, [uniqueProjectID]);\r\n\r\n /** Tag details event listener */\r\n useEffect(() => {\r\n const callback = (event) => {\r\n const {tagID, editing} = event.detail;\r\n setTagToEdit(tagID);\r\n setEditing(editing);\r\n };\r\n\r\n document.addEventListener(\"tag-details\", callback);\r\n\r\n return () => {\r\n document.removeEventListener(\"tag-details\", callback);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n const allTags = tagAssets.map(asset => (asset.data as TagData).items).flat();\r\n const tag = allTags.find(x => x.id === tagToEdit);\r\n if (!tag) return;\r\n\r\n setTitle(tag.name);\r\n setComment(tag.comment);\r\n tagDetailsDialog.handleOpen();\r\n }, [tagToEdit]);\r\n\r\n const onClose = () => {\r\n setTagToEdit(null);\r\n tagDetailsDialog.handleClose();\r\n };\r\n\r\n const onEdit = () => {\r\n setEditing(true);\r\n };\r\n\r\n const onSubmit = () => {\r\n\r\n dispatch(updateTag({\r\n tagID: tagToEdit,\r\n name: title,\r\n comment: comment\r\n }));\r\n\r\n onClose();\r\n toast.success(t(\"toast.tag-details-update\"));\r\n };\r\n\r\n const titleMissing = title.trim() === \"\";\r\n const canSubmit = !titleMissing;\r\n const canEdit = permissions.edit && !editing;\r\n\r\n return (\r\n \r\n \r\n\r\n {editing && \r\n {/** Title */}\r\n \r\n \r\n \r\n\r\n {/** Comments */}\r\n \r\n \r\n \r\n }\r\n\r\n {!editing && \r\n {/** Title */}\r\n \r\n \r\n \r\n\r\n {/** Comments */}\r\n \r\n \r\n \r\n }\r\n\r\n \r\n \r\n );\r\n};\r\n\r\ninterface TagCreateDialogProps {\r\n open: boolean;\r\n onClose(): void;\r\n coordinate: number[];\r\n}\r\n\r\nexport const TagCreateDialog = memo((props: TagCreateDialogProps) => {\r\n const {open, onClose, coordinate} = props;\r\n\r\n const classes = useStyles();\r\n const theme = useTheme();\r\n const dispatch = useAppDispatch();\r\n const {t} = useTranslation();\r\n const iconUpdateDialog = useDialog();\r\n const {viewer} = useViewer();\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const tagAssets = getTagAssets(assets);\r\n const folders = useSelector(selectAllFolders);\r\n\r\n const [title, setTitle] = useState(\"\");\r\n const [comment, setComment] = useState(\"\");\r\n const [collectionID, setCollectionID] = useState(\"\");\r\n const [collectionName, setCollectionName] = useState(\"\");\r\n const [folderID, setFolderID] = useState(NEW_FOLDER_ID);\r\n const [tagTexture, setTagTexture] = useState(defaultTagTexture);\r\n const [tagSize, setTagSize] = useState(TagSize.Medium);\r\n\r\n const onSubmit = async () => {\r\n onClose();\r\n\r\n const newTag = {\r\n id: nanoid(),\r\n name: title,\r\n comment: comment,\r\n date: new Date().toISOString(),\r\n x: coordinate[0],\r\n y: coordinate[1],\r\n } as TagItemData;\r\n\r\n if (coordinate.length === 3) {\r\n newTag.z = coordinate[2];\r\n newTag.sceneState = viewer.sceneState;\r\n }\r\n\r\n let tagFolderID;\r\n\r\n if (createNewFolder) {\r\n // Create new folder\r\n const folder = await dispatch(createFolder());\r\n tagFolderID = folder.id;\r\n } else {\r\n tagFolderID = folderID;\r\n }\r\n\r\n let tagCollectionID;\r\n\r\n if (createNewFile) {\r\n // Create new tag collection\r\n const asset = await dispatch(createAsset({\r\n folderID: tagFolderID,\r\n name: collectionName,\r\n type: AssetType.Tag,\r\n texture: tagTexture,\r\n size: tagSize\r\n }));\r\n\r\n tagCollectionID = asset.id;\r\n } else {\r\n tagCollectionID = collectionID;\r\n }\r\n\r\n // Add new tag to collection\r\n await dispatch(createTags({\r\n assetID: tagCollectionID,\r\n tags: [newTag]\r\n }));\r\n\r\n toast.success(t(\"toast.tag-added\"));\r\n };\r\n\r\n const resetDefaultValues = () => {\r\n setTitle(\"\");\r\n setComment(\"\");\r\n setCollectionName(\"\");\r\n setTagTexture(defaultTagTexture);\r\n\r\n iconUpdateDialog.handleClose();\r\n\r\n if (hasExistingFolders) {\r\n setFolderID(folders[0].id);\r\n } else {\r\n setFolderID(NEW_FOLDER_ID);\r\n }\r\n\r\n if (hasExistingCSVs) {\r\n setCollectionID(tagAssets[0].id);\r\n } else {\r\n setCollectionID(\"\");\r\n }\r\n };\r\n\r\n const submitTagIcon = useCallback((texture: string, size: number) => {\r\n setTagTexture(texture);\r\n setTagSize(size);\r\n iconUpdateDialog.handleClose();\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n resetDefaultValues();\r\n }, [open]);\r\n\r\n const hasExistingCSVs = tagAssets.length > 0;\r\n const hasExistingFolders = folders.length > 0;\r\n const createNewFile = collectionID === NEW_CSV_ID;\r\n const createNewFolder = folderID === NEW_FOLDER_ID;\r\n\r\n /* Determine valid state for new tag */\r\n let canSubmit = true;\r\n const titleMissing = title.trim() === \"\";\r\n const nameMissing = collectionName.trim() === \"\";\r\n canSubmit = canSubmit && !titleMissing;\r\n canSubmit = canSubmit && !(nameMissing && createNewFile);\r\n\r\n // Folder is used if it is user made or if it contains assets\r\n const folderOptions = folders.filter(folder => {\r\n const items = assets.filter(x => x.folderID === folder.id);\r\n return folder.default ? items.length > 0 : true;\r\n });\r\n\r\n return (\r\n \r\n {/* New tag dialog */}\r\n \r\n \r\n\r\n {/** Title */}\r\n \r\n \r\n \r\n\r\n {/** Comments */}\r\n \r\n \r\n \r\n\r\n \r\n [tagCSV.id, tagCSV.name])\r\n ] as any}\r\n />\r\n \r\n\r\n
\r\n \r\n \r\n\r\n {/** Tag collection name */}\r\n \r\n \r\n \r\n\r\n {/** Tag collection folder */}\r\n \r\n {\r\n const localizedFolderName = getLocalizedFolderName(folder.name);\r\n return [folder.id, localizedFolderName];\r\n })\r\n ]}\r\n />\r\n \r\n\r\n {/** Default Icon */}\r\n \r\n
\r\n \r\n {t('tags.collection_icon')}\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n \r\n\r\n {/* Tag Icon */}\r\n \r\n
\r\n );\r\n});\r\n\r\nexport const showTagDetails = (tagID: string, editing: boolean) => {\r\n sendCustomEvent(\"tag-details\", {tagID, editing});\r\n};\r\n","import React, {useState, memo} from \"react\";\r\nimport ListItem from \"@material-ui/core/ListItem\";\r\nimport FolderIcon from \"@material-ui/icons/Folder\";\r\nimport ListItemText from \"@material-ui/core/ListItemText\";\r\nimport {Checkbox} from \"@material-ui/core\";\r\nimport {\r\n Asset,\r\n deleteAsset,\r\n toggleFolderVisibility,\r\n updateAsset\r\n} from \"../redux/assets-slice\";\r\nimport ExpandLess from \"@material-ui/icons/ExpandLess\";\r\nimport ExpandMore from \"@material-ui/icons/ExpandMore\";\r\nimport List from \"@material-ui/core/List\";\r\nimport {AddAssetList, AssetItem} from \".\";\r\nimport {useDispatch} from 'react-redux';\r\nimport {\r\n DenseIcon,\r\n DenseMenu,\r\n MenuDivider,\r\n NestedMenu,\r\n PromptDialog,\r\n TextDialog\r\n} from '../components';\r\nimport {MenuItem, Typography} from \"@material-ui/core\";\r\nimport EditIcon from \"@material-ui/icons/Edit\";\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport AddIcon from '@material-ui/icons/Add';\r\nimport {deleteFolder, Folder, updateFolder} from '../redux/folders-slice';\r\nimport { isElectronApp, isStaticSite } from \"../electron-modules\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { getLocalizedFolderName, isAssetFile, useAssetTools } from \"../utilities\";\r\nimport slash from \"slash\";\r\nimport { useContextMenu, useDialog } from \"../hooks\";\r\n\r\nexport const assetFolderClass = \"asset-folder\";\r\n\r\nexport const AssetFolder = memo((props: any) => {\r\n const folder = props.folder as Folder;\r\n const assets = props.assets as Asset[];\r\n\r\n const {draggingAsset, setDraggingAsset} = props;\r\n\r\n const dispatch = useDispatch();\r\n const {t} = useTranslation();\r\n const {addAssetPaths} = useAssetTools();\r\n const contextMenu = useContextMenu();\r\n const deleteDialog = useDialog();\r\n const renameDialog = useDialog();\r\n\r\n const [expanded, setExpanded] = useState(true);\r\n const [dragDropHover, setDragDropHover] = useState(false);\r\n\r\n const updateAssetFolder = (assetID) => {\r\n dispatch(updateAsset({\r\n assetID,\r\n folderID: folder.id\r\n }));\r\n };\r\n\r\n const addAssetsToFolder = (event) => {\r\n const assetPaths = [...event.dataTransfer.files]\r\n .map(file => slash(file.path))\r\n .filter(isAssetFile);\r\n\r\n addAssetPaths(assetPaths, folder.id);\r\n };\r\n\r\n const handleClick = (event) => {\r\n const isCheckBox = (event.target.type === \"checkbox\");\r\n if (isCheckBox) return;\r\n\r\n setExpanded(!expanded);\r\n };\r\n\r\n const handleDragOver = (event) => {\r\n event.preventDefault();\r\n setDragDropHover(true);\r\n };\r\n\r\n const handleDragLeave = (event) => {\r\n setDragDropHover(false);\r\n };\r\n\r\n const handleDrop = (event) => {\r\n if (isStaticSite) return;\r\n\r\n setDragDropHover(false);\r\n\r\n if (draggingAsset) {\r\n updateAssetFolder(draggingAsset);\r\n } else {\r\n addAssetsToFolder(event);\r\n }\r\n };\r\n\r\n const handleRenameSubmit = name => {\r\n renameDialog.handleClose();\r\n dispatch(updateFolder({\r\n folderID: folder.id,\r\n name\r\n }));\r\n };\r\n\r\n const handleDeleteSubmit = () => {\r\n deleteDialog.handleClose();\r\n\r\n for (let asset of assets) {\r\n dispatch(deleteAsset(asset.id));\r\n }\r\n\r\n dispatch(deleteFolder(folder.id));\r\n };\r\n\r\n const handleDeleteClick = () => {\r\n contextMenu.handleClose();\r\n deleteDialog.handleOpen();\r\n };\r\n\r\n const handleRenameClick = () => {\r\n contextMenu.handleClose();\r\n renameDialog.handleOpen();\r\n };\r\n\r\n const toggleCheckboxes = () => {\r\n let newVisibility;\r\n if (numVisible > 0 && numHidden > 0) {\r\n newVisibility = true;\r\n } else if (numVisible > 0) {\r\n newVisibility = false;\r\n } else {\r\n newVisibility = true;\r\n }\r\n\r\n dispatch(toggleFolderVisibility({\r\n folderID: folder.id,\r\n visible: newVisibility\r\n }));\r\n };\r\n\r\n const numVisible = assets.filter(x => x.visible).length;\r\n const numHidden = assets.filter(x => !x.visible).length;\r\n\r\n // Folder is visible if it is user made or if it contains assets\r\n const visible = folder.default ? assets.length > 0 : true;\r\n\r\n const localizedFolderName = getLocalizedFolderName(folder.name);\r\n\r\n return (\r\n \r\n {visible && (\r\n \r\n \r\n \r\n \r\n \r\n\r\n {(assets.length > 0) && (\r\n {/* Show / hide contents */}\r\n {expanded ? : }\r\n\r\n {/* Toggle all folder assets */}\r\n 0}\r\n onChange={toggleCheckboxes}\r\n indeterminate={numVisible > 0 && numHidden > 0}\r\n />\r\n )}\r\n\r\n \r\n )}\r\n\r\n {visible && expanded && (\r\n \r\n {assets.map(asset => )}\r\n \r\n )}\r\n\r\n \r\n {/** New asset submenu */}\r\n }\r\n parentMenuOpen={contextMenu.open}\r\n >\r\n \r\n \r\n\r\n {/** Functions submenu */}\r\n {/*\r\n {}\r\n */}\r\n\r\n {isElectronApp && }\r\n\r\n {/** Rename folder */}\r\n \r\n \r\n \r\n \r\n \r\n {t(\"folder.rename\")}\r\n \r\n \r\n\r\n {/** Delete folder */}\r\n \r\n \r\n \r\n \r\n \r\n {t(\"folder.delete\")}\r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n\r\n \r\n );\r\n});\r\n","import { useTheme, Grid, Typography, DialogContent, Checkbox } from \"@material-ui/core\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport React, { useState, useMemo, useEffect } from \"react\";\r\nimport toast from \"react-hot-toast\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { SimpleDialog, DropdownWithLabel, InputWithLabel, DraggableDialog, EnhancedTable, EnhancedTableCheckboxHead } from \"../components\";\r\nimport { Asset, updateWebMapLayer, WebMapData, WebMapLayerData } from \"../redux/assets-slice\";\r\nimport { ServerType } from \"../types/web-sources\";\r\nimport { useAssetTools } from \"../utilities\";\r\nimport {Parser as XMLParser} from 'xml2js';\r\nimport WMTSCapabilities from 'ol/format/WMTSCapabilities.js';\r\nimport WMSCapabilities from 'ol/format/WMSCapabilities.js';\r\nimport { useTableState } from \"../hooks/use-table-state\";\r\nimport { useDispatch } from \"react-redux\";\r\n\r\ninterface WebSourceDialogProps {\r\n open: boolean;\r\n onClose(): void;\r\n folderID: string;\r\n}\r\n\r\nexport const WebSourceDialog = (props: WebSourceDialogProps) => {\r\n const {open, onClose, folderID} = props;\r\n\r\n const theme = useTheme();\r\n const {t} = useTranslation();\r\n const {addWebSource} = useAssetTools();\r\n\r\n const [serverURL, setServerURL] = useState(\"\");\r\n const [serverName, setServerName] = useState(\"\");\r\n const [serverType, setServerType] = useState(ServerType.ArcGISMapServer);\r\n const [submitting, setSubmitting] = useState(false);\r\n\r\n const onSubmit = async () => {\r\n setSubmitting(true);\r\n\r\n try {\r\n const webmapData = {\r\n url: serverURL,\r\n type: serverType,\r\n public: true,\r\n layers: await getMapLayers(serverURL, serverType)\r\n };\r\n\r\n await addWebSource(serverName, webmapData, folderID);\r\n\r\n setSubmitting(false);\r\n onClose();\r\n } catch {\r\n toast.error(\"Error grabbing layers from URL\");\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n const getMapServerLayers = async (baseURL: string) => {\r\n const url = new URL(baseURL);\r\n url.searchParams.set('f', \"json\");\r\n url.searchParams.set('pretty', \"true\");\r\n\r\n const response = await fetch(url.href);\r\n const data = await response.json();\r\n const layers = data.layers as any[];\r\n\r\n return layers.map(layer => {\r\n return {\r\n id: nanoid(),\r\n visible: true,\r\n identifier: layer.id,\r\n name: layer.name,\r\n };\r\n });\r\n };\r\n\r\n const getFeatureServerLayers = async (baseURL: string) => {\r\n const url = new URL(baseURL);\r\n url.searchParams.set('f', \"json\");\r\n url.searchParams.set('pretty', \"true\");\r\n\r\n const response = await fetch(url.href);\r\n const data = await response.json();\r\n const layers = data.layers as any[];\r\n\r\n return layers.map(layer => {\r\n return {\r\n id: nanoid(),\r\n visible: true,\r\n identifier: layer.id,\r\n name: layer.name,\r\n };\r\n });\r\n };\r\n\r\n const getImageServerLayers = async (baseURL: string) => {\r\n const url = new URL(baseURL);\r\n url.searchParams.set('f', \"json\");\r\n url.searchParams.set('pretty', \"true\");\r\n\r\n const response = await fetch(url.href);\r\n if (!response.ok) {\r\n throw new Error(\"Error verifying image server URL\");\r\n }\r\n\r\n // No layers for this server type\r\n return [];\r\n };\r\n\r\n const getWMSLayers = async (baseURL: string) => {\r\n const url = new URL(baseURL);\r\n url.searchParams.set('SERVICE', \"WMS\");\r\n url.searchParams.set('REQUEST', \"GetCapabilities\");\r\n\r\n const response = await fetch(url.href);\r\n const text = await response.text();\r\n\r\n const parser = new WMSCapabilities();\r\n const capabilities = parser.read(text);\r\n const layers = capabilities.Capability.Layer.Layer as any[];\r\n\r\n return layers.map(layer => {\r\n return {\r\n id: nanoid(),\r\n visible: true,\r\n identifier: layer.Name,\r\n name: layer.Title\r\n };\r\n });\r\n };\r\n\r\n const getWFSLayers = async (baseURL: string) => {\r\n const url = new URL(baseURL);\r\n url.searchParams.set('SERVICE', \"WFS\");\r\n url.searchParams.set('REQUEST', \"GetCapabilities\");\r\n\r\n const response = await fetch(url.href);\r\n const text = await response.text();\r\n\r\n const parser = new XMLParser({\r\n explicitChildren:true,\r\n preserveChildrenOrder: true\r\n });\r\n\r\n const xmlJSON = await parser.parseStringPromise(text);\r\n const capabilities = xmlJSON['wfs:WFS_Capabilities'];\r\n const featureTypeList = capabilities.FeatureTypeList[0];\r\n const features = featureTypeList.FeatureType as any[];\r\n\r\n return features.map(layer => {\r\n return {\r\n id: nanoid(),\r\n visible: true,\r\n identifier: layer.Name[0],\r\n name: layer.Title[0]\r\n };\r\n });\r\n };\r\n\r\n const getWMTSLayers = async (baseURL: string) => {\r\n const url = new URL(baseURL);\r\n url.pathname = `${url.pathname}/1.0.0/WMTSCapabilities.xml`;\r\n\r\n const response = await fetch(url.href);\r\n const text = await response.text();\r\n\r\n const parser = new WMTSCapabilities();\r\n const capabilities = parser.read(text);\r\n const layers = capabilities.Contents.Layer as any[];\r\n\r\n return layers.map(layer => {\r\n return {\r\n id: nanoid(),\r\n visible: true,\r\n identifier: layer.Identifier,\r\n name: layer.Title\r\n };\r\n });\r\n };\r\n\r\n const getTileServerLayers = async (baseURL: string) => {\r\n // No layers for this server type\r\n return [];\r\n };\r\n\r\n const getMapLayers = (url, type) : Promise => {\r\n switch (type) {\r\n case ServerType.ArcGISMapServer:\r\n return getMapServerLayers(url);\r\n case ServerType.ArcGISImageServer:\r\n return getImageServerLayers(url);\r\n case ServerType.ArcGISFeatureServer:\r\n return getFeatureServerLayers(url);\r\n case ServerType.OGCWMS:\r\n return getWMSLayers(url);\r\n case ServerType.OGCWFS:\r\n return getWFSLayers(url);\r\n case ServerType.OGCWMTS:\r\n return getWMTSLayers(url);\r\n case ServerType.TileServer:\r\n return getTileServerLayers(url);\r\n default:\r\n throw new Error(\"Error grabbing map layers\");\r\n }\r\n };\r\n\r\n const resetDefaults = () => {\r\n setServerURL(\"\");\r\n setServerName(\"\");\r\n setSubmitting(false);\r\n setServerType(ServerType.ArcGISMapServer);\r\n };\r\n\r\n const isSecureURL = useMemo(() => {\r\n try {\r\n const url = new URL(serverURL);\r\n return url.protocol === \"https:\";\r\n } catch {\r\n return false;\r\n }\r\n }, [serverURL]);\r\n\r\n /** Check url to make sure it matches the required syntax */\r\n const isValidURL = useMemo(() => {\r\n const isArcGISServer = (serverType === ServerType.ArcGISMapServer)\r\n || (serverType === ServerType.ArcGISImageServer)\r\n || (serverType === ServerType.ArcGISFeatureServer);\r\n\r\n if (isArcGISServer) {\r\n try {\r\n const testURL = new URL(serverURL);\r\n const mapType = testURL.pathname\r\n .split(\"/\")\r\n .pop()\r\n .toLowerCase();\r\n\r\n if (serverType === ServerType.ArcGISMapServer) {\r\n return mapType === \"mapserver\";\r\n } else if (serverType === ServerType.ArcGISImageServer) {\r\n return mapType === \"imageserver\";\r\n } else if (serverType === ServerType.ArcGISFeatureServer) {\r\n return mapType === \"featureserver\";\r\n }\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n if (serverType === ServerType.TileServer) {\r\n const hasX = serverURL.includes(\"{x}\")\r\n || serverURL.includes(\"{col}\");\r\n\r\n const hasY = serverURL.includes(\"{y}\")\r\n || serverURL.includes(\"{-y}\")\r\n || serverURL.includes(\"{row}\");\r\n\r\n const hasZ = serverURL.includes(\"{z}\")\r\n || serverURL.includes(\"{level}\")\r\n || serverURL.includes(\"{zoom}\");\r\n\r\n return hasX && hasY && hasZ;\r\n }\r\n\r\n return true;\r\n }, [serverURL, serverType]);\r\n\r\n const placeholder = useMemo(() => {\r\n switch (serverType) {\r\n case ServerType.ArcGISMapServer:\r\n return \"https://server.arcgisonline.com/..../MapServer\";\r\n case ServerType.ArcGISFeatureServer:\r\n return \"https://server.arcgisonline.com/..../FeatureServer/\";\r\n case ServerType.ArcGISImageServer:\r\n return \"https://server.arcgisonline.com/..../ImageServer/\";\r\n case ServerType.ArcGISOnline:\r\n return \"https://arcgis.com/home/webmap/viewer.html?webmap=MAPID\";\r\n case ServerType.OGCWMS:\r\n return \"https://example.server.com/wms\";\r\n case ServerType.OGCWMTS:\r\n return \"https://example.server.com/wmts\";\r\n case ServerType.OGCWFS:\r\n return \"https://example.server.com/wfs\";\r\n case ServerType.TileServer:\r\n return \"https://custom.server.com/tiles/{z}/{x}/{y}.png\";\r\n default:\r\n return;\r\n }\r\n }, [serverType]);\r\n\r\n const label = useMemo(() => {\r\n const warnings = [];\r\n\r\n if (!isSecureURL) {\r\n warnings.push(t('websources.only_secure_urls_https_are_supported'));\r\n }\r\n\r\n if (!isValidURL) {\r\n warnings.push(t('websources.invalid_url_for_this_server_type'));\r\n }\r\n\r\n return warnings.join(\" \");\r\n }, [isSecureURL, isValidURL]);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const showEsriWarning = (serverType === ServerType.ArcGISFeatureServer)\r\n || (serverType === ServerType.ArcGISImageServer)\r\n || (serverType === ServerType.ArcGISMapServer)\r\n || (serverType === ServerType.ArcGISOnline);\r\n\r\n const error = !isSecureURL\r\n || !isValidURL;\r\n\r\n const canSubmit = isSecureURL\r\n && isValidURL\r\n && !!serverName\r\n && !submitting;\r\n\r\n return (\r\n \r\n \r\n {/** Icon Size */}\r\n \r\n \r\n \r\n\r\n {/** Name */}\r\n \r\n \r\n \r\n\r\n {/** URL */}\r\n \r\n \r\n \r\n\r\n {showEsriWarning && (\r\n {t('websources.all_arcgis_maps_must_be_public')}\r\n )}\r\n\r\n \r\n \r\n );\r\n};\r\n\r\ninterface WebSourceLayerCheckboxProps {\r\n layerID: string;\r\n visible: boolean;\r\n}\r\n\r\nconst WebSourceLayerCheckbox = (props: WebSourceLayerCheckboxProps) => {\r\n const {layerID, visible} = props;\r\n\r\n const dispatch = useDispatch();\r\n\r\n const onVisibilityChange = (visible: boolean) => {\r\n dispatch(updateWebMapLayer({\r\n layerID,\r\n visible\r\n }));\r\n };\r\n\r\n return (\r\n {\r\n const checked = event.target.checked;\r\n onVisibilityChange(checked);\r\n }}\r\n />\r\n );\r\n};\r\n\r\ninterface WebSourceLayerDialogProps {\r\n open: boolean;\r\n onClose(): void;\r\n asset: Asset;\r\n}\r\n\r\nexport const WebSourceLayerDialog = (props: WebSourceLayerDialogProps) => {\r\n const {open, onClose, asset} = props;\r\n\r\n const dispatch = useDispatch();\r\n const {t} = useTranslation();\r\n\r\n const tableState = useTableState({\r\n defaultSort: \"name\",\r\n rowPropertyMap: {\r\n visible_checkbox: \"visible_sortable\"\r\n }\r\n });\r\n\r\n const layers = useMemo(() => {\r\n return (asset.data as WebMapData).layers;\r\n }, [asset.data]);\r\n\r\n const getRows = (layers: WebMapLayerData[]) => {\r\n return layers.map(layer => {\r\n return {\r\n id: `WebSourceLayerTableRow_${layer.id}`,\r\n name: layer.name,\r\n visible_sortable: layer.visible ? 1 : 0,\r\n visible_checkbox: \r\n };\r\n });\r\n };\r\n\r\n const rows = useMemo(() => {\r\n return getRows(layers);\r\n }, [layers]);\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t('websources.layer_name'),\r\n wordBreak: true,\r\n searchable: true\r\n },\r\n {\r\n id: 'visible_checkbox',\r\n label: x.visible)}\r\n onChange={(checked) => {\r\n layers.forEach(layer => {\r\n dispatch(updateWebMapLayer({\r\n layerID: layer.id,\r\n visible: checked\r\n }));\r\n });\r\n }}\r\n />,\r\n center: true\r\n }\r\n ];\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {t('asset.file-name')}: {asset.name}\r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n","import React, {useState, memo, useCallback} from 'react';\r\nimport List from '@material-ui/core/List';\r\nimport ListItem from '@material-ui/core/ListItem';\r\nimport ListItemText from '@material-ui/core/ListItemText';\r\nimport {MenuItem, Typography} from \"@material-ui/core\";\r\nimport AddIcon from '@material-ui/icons/Add';\r\nimport CreateNewFolderIcon from '@material-ui/icons/CreateNewFolder';\r\nimport PanoramaIcon from '@material-ui/icons/Panorama';\r\nimport PermMediaIcon from '@material-ui/icons/PermMedia';\r\nimport PublicIcon from '@material-ui/icons/Public';\r\nimport {\r\n openDialogFile,\r\n openDialogFolder,\r\n openDialogMulti,\r\n useAssetTools\r\n} from '../utilities';\r\nimport {\r\n modelFileFilter,\r\n imageCSVFilter,\r\n imageOrthoFilter,\r\n imagePlanarFilter,\r\n pointCloudFilter,\r\n tagCSVFilter,\r\n xmlFileFilter\r\n} from '../file-extensions';\r\nimport {AssetFolder} from \"./folder\";\r\nimport {createFolder, selectDefaultFolder, selectAllFolders} from '../redux/folders-slice';\r\nimport {selectAllAssets} from '../redux/assets-slice';\r\nimport {useSelector} from 'react-redux';\r\nimport {\r\n TextDialog,\r\n DenseIcon,\r\n DenseDivider,\r\n SlimScrollbar,\r\n FontAwesomeIcon,\r\n DenseMenu\r\n} from '../components';\r\nimport path from 'path';\r\nimport { isElectronApp } from '../electron-modules';\r\nimport {toast} from '../app';\r\nimport { useTranslation } from 'react-i18next';\r\nimport CloudIcon from \"@material-ui/icons/Cloud\";\r\nimport RoomIcon from \"@material-ui/icons/Room\";\r\nimport PanoramaOutlinedIcon from \"@material-ui/icons/PanoramaOutlined\";\r\nimport SatelliteIcon from \"@material-ui/icons/Satellite\";\r\nimport { useContextMenu, useDialog } from '../hooks';\r\nimport { WebSourceDialog } from './web-sources';\r\nimport { useAppDispatch } from '../redux/store';\r\n\r\ninterface AddAssetListProps {\r\n folderID: string;\r\n closeContextMenu(): void;\r\n}\r\n\r\nexport const AddAssetList = (props: AddAssetListProps) => {\r\n const {folderID, closeContextMenu} = props;\r\n\r\n const {t} = useTranslation();\r\n\r\n const webmapDialog = useDialog();\r\n\r\n const {\r\n addModelFiles, addPointCloudFiles, addOrthoFiles,\r\n addCameraFiles, addPlanarFiles, addXMLFiles,\r\n addTagCSVs\r\n } = useAssetTools();\r\n\r\n const handleAddModels = async () => {\r\n closeContextMenu();\r\n\r\n const assetPaths = await openDialogMulti(modelFileFilter);\r\n if (assetPaths.length === 0) return;\r\n\r\n addModelFiles(assetPaths, folderID);\r\n };\r\n\r\n const handleAddPoints = async () => {\r\n closeContextMenu();\r\n\r\n const assetPaths = await openDialogMulti(pointCloudFilter);\r\n if (assetPaths.length === 0) return;\r\n\r\n addPointCloudFiles(assetPaths, folderID);\r\n };\r\n\r\n const handleAddOrtho = async () => {\r\n closeContextMenu();\r\n\r\n const assetPaths = await openDialogMulti(imageOrthoFilter);\r\n if (assetPaths.length === 0) return;\r\n\r\n addOrthoFiles(assetPaths, folderID);\r\n };\r\n\r\n const handleAddPanoramics = async () => {\r\n closeContextMenu();\r\n\r\n const assetPaths = await openDialogMulti(imageCSVFilter);\r\n if (assetPaths.length === 0) return;\r\n\r\n addCameraFiles(assetPaths, folderID);\r\n };\r\n\r\n const handleAddTags = async () => {\r\n closeContextMenu();\r\n\r\n const assetPaths = await openDialogMulti(tagCSVFilter);\r\n if (assetPaths.length === 0) return;\r\n\r\n addTagCSVs(assetPaths, folderID);\r\n };\r\n\r\n const handleAddPlanars = async () => {\r\n closeContextMenu();\r\n\r\n const assetPath = await openDialogFile(imagePlanarFilter);\r\n if (!assetPath) return;\r\n\r\n addPlanarFiles([assetPath], folderID);\r\n };\r\n\r\n const handleAddXML = async () => {\r\n closeContextMenu();\r\n\r\n const assetPath = await openDialogFile(xmlFileFilter);\r\n if (!assetPath) return;\r\n\r\n try {\r\n await addXMLFiles([assetPath], folderID);\r\n toast.success(t(\"toast.added-new-xml\"));\r\n } catch {\r\n const fileName = path.basename(assetPath);\r\n toast.error(t(\"toast.import-xml-error\", {\r\n path: fileName\r\n }));\r\n }\r\n };\r\n\r\n const handleAddWebMap = useCallback(() => {\r\n closeContextMenu();\r\n webmapDialog.handleOpen();\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-point-cloud\")}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-panoramic-csv\")}\r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-tag-csv\")}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-planar-images\")}\r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-orthomosaic\")}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-model-file\")}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('folder-list.add-landxml-file')}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('folder-list.add-web-source')}\r\n \r\n\r\n \r\n \r\n );\r\n};\r\n\r\nexport const FolderList = memo(() => {\r\n const dispatch = useAppDispatch();\r\n const {t} = useTranslation();\r\n const contextMenu = useContextMenu();\r\n const newFolderDialog = useDialog();\r\n const {addFilePaths} = useAssetTools();\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const defaultFolder = useSelector(selectDefaultFolder);\r\n const folders = useSelector(selectAllFolders);\r\n\r\n const [draggingAsset, setDraggingAsset] = useState(null);\r\n\r\n const handleSubmit = async (name: string) => {\r\n dispatch(createFolder(name));\r\n newFolderDialog.handleClose();\r\n };\r\n\r\n const handleAddFolder = async () => {\r\n contextMenu.handleClose();\r\n\r\n const {directoryPath, filePaths} = await openDialogFolder();\r\n if (filePaths.length === 0) return;\r\n\r\n const name = path.basename(directoryPath);\r\n const folder = await dispatch(createFolder(name));\r\n addFilePaths(filePaths, folder.id);\r\n };\r\n\r\n const handleNewFolder = () => {\r\n contextMenu.handleClose();\r\n newFolderDialog.handleOpen();\r\n };\r\n\r\n return (\r\n \r\n {/* Add item button */}\r\n {isElectronApp && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n )}\r\n\r\n \r\n \r\n {folders.map(folder =>\r\n x.folderID === folder.id)}\r\n draggingAsset={draggingAsset}\r\n setDraggingAsset={setDraggingAsset}\r\n />)}\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n {t(\"folder-list.create-new-folder\")}\r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"folder-list.add-folder-contents\")}\r\n \r\n \r\n \r\n );\r\n});\r\n","import { Checkbox, DialogContent, Typography } from \"@material-ui/core\";\r\nimport React, { useMemo } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useDispatch } from \"react-redux\";\r\nimport { ColorPicker, DraggableDialog, EnhancedTable, EnhancedTableCheckboxHead } from \"../components\";\r\nimport { useTableState } from \"../hooks/use-table-state\";\r\nimport { Asset, LineworkLayerData, updateModelLayer } from \"../redux/assets-slice\";\r\n\r\ninterface ModelLayerCheckboxProps {\r\n layerID: string;\r\n visible: boolean;\r\n}\r\n\r\nconst ModelLayerCheckbox = (props: ModelLayerCheckboxProps) => {\r\n const {layerID, visible} = props;\r\n\r\n const dispatch = useDispatch();\r\n\r\n const onVisibilityChange = (visible: boolean) => {\r\n dispatch(updateModelLayer({\r\n layerID,\r\n visible\r\n }));\r\n };\r\n\r\n return (\r\n {\r\n const checked = event.target.checked;\r\n onVisibilityChange(checked);\r\n }}\r\n />\r\n );\r\n};\r\n\r\ninterface ModelLayerColorProps {\r\n layerID: string;\r\n color: string;\r\n}\r\n\r\nconst ModelLayerColor = (props: ModelLayerColorProps) => {\r\n const {layerID, color} = props;\r\n\r\n const dispatch = useDispatch();\r\n\r\n const onColorChange = (color: string) => {\r\n dispatch(updateModelLayer({\r\n layerID,\r\n color\r\n }));\r\n };\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\ninterface ModelLayerDialogProps {\r\n open: boolean;\r\n onClose(): void;\r\n asset: Asset;\r\n}\r\n\r\nexport const ModelLayerDialog = (props: ModelLayerDialogProps) => {\r\n const {open, onClose, asset} = props;\r\n\r\n const {t} = useTranslation();\r\n const dispatch = useDispatch();\r\n\r\n const tableState = useTableState({\r\n defaultSort: \"name\",\r\n rowPropertyMap: {\r\n visible_checkbox: \"visible_sortable\"\r\n }\r\n });\r\n\r\n const layers = useMemo(() => {\r\n return asset.data as LineworkLayerData[];\r\n }, [asset.data]);\r\n\r\n const getRows = (layers: LineworkLayerData[]) => {\r\n return layers.map(layer => {\r\n return {\r\n id: `WebSourceLayerTableRow_${layer.id}`,\r\n name: layer.name,\r\n visible_sortable: layer.visible ? 1 : 0,\r\n visible_checkbox: ,\r\n color_picker: \r\n };\r\n });\r\n };\r\n\r\n const rows = useMemo(() => {\r\n return getRows(layers);\r\n }, [layers]);\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t('models.layer_name'),\r\n wordBreak: true,\r\n searchable: true\r\n },\r\n {\r\n id: 'color_picker',\r\n label: t('models.layer_color'),\r\n center: true,\r\n sortable: false\r\n },\r\n {\r\n id: 'visible_checkbox',\r\n label: x.visible)}\r\n onChange={(checked) => {\r\n layers.forEach(layer => {\r\n dispatch(updateModelLayer({\r\n layerID: layer.id,\r\n visible: checked\r\n }));\r\n });\r\n }}\r\n />,\r\n center: true\r\n }\r\n ];\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {t('asset.file-name')}: {asset.name}\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n );\r\n};\r\n","import React, { useState } from \"react\";\r\nimport {createStyles, makeStyles, Theme} from '@material-ui/core/styles';\r\nimport {\r\n Checkbox,\r\n List,\r\n ListItem,\r\n ListItemText,\r\n MenuItem,\r\n Typography,\r\n} from \"@material-ui/core\";\r\nimport {\r\n DenseDivider,\r\n DenseIcon,\r\n DenseMenu,\r\n PromptDialog,\r\n SlimScrollbar,\r\n TextDialog\r\n} from \"../components\";\r\nimport AddIcon from '@material-ui/icons/Add';\r\nimport { useDispatch, useSelector } from 'react-redux';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { BookmarkItem } from \".\";\r\nimport BookmarksIcon from '@material-ui/icons/Bookmarks';\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport ExpandLess from \"@material-ui/icons/ExpandLess\";\r\nimport ExpandMore from \"@material-ui/icons/ExpandMore\";\r\nimport {\r\n createBookmark,\r\n updateBookmark,\r\n deleteBookmark\r\n} from \"../redux/bookmarks-slice\";\r\nimport { store } from \"../redux/store\";\r\nimport { toast } from \"../app\";\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport { useAuth, useBookmarks, useContextMenu, useDialog, useViewer } from \"../hooks\";\r\nimport { AerialViewState, SceneCameraState } from \"../redux/camera-slice\";\r\nimport { SettingsState } from \"../redux/settings-slice\";\r\nimport { selectVisibleAssets } from \"../redux/assets-slice\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n addItem: {\r\n paddingTop: \"0px\",\r\n paddingBottom: \"0px\"\r\n },\r\n footerDiv: {\r\n width: \"100%\",\r\n boxShadow: \"0px 10px 10px 2px\",\r\n zIndex: 1,\r\n textAlign: \"center\"\r\n },\r\n footerCheckbox: {\r\n padding: theme.spacing(0.5),\r\n marginRight: theme.spacing(0.5)\r\n }\r\n })\r\n);\r\n\r\nexport const getStoredState = () => {\r\n const state = store.getState();\r\n\r\n const settings = {...state.settings} as SettingsState;\r\n const aerialState = state.camera.aerialState as AerialViewState;\r\n const sceneState = state.camera.sceneState as SceneCameraState;\r\n\r\n return {settings, aerialState, sceneState};\r\n};\r\n\r\nexport const BookmarkList = () => {\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {permissions} = useAuth();\r\n const {t} = useTranslation();\r\n const contextMenu = useContextMenu();\r\n const bookmarkDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n const {bookmarks} = useBookmarks();\r\n\r\n const visibleAssets = useSelector(selectVisibleAssets);\r\n\r\n const [expanded, setExpanded] = useState(true);\r\n\r\n const handleSubmit = (name: string) => {\r\n bookmarkDialog.handleClose();\r\n\r\n if (!LocalScene.initialized) {\r\n toast.warning(t('bookmarks.invalid_position'));\r\n return;\r\n }\r\n\r\n const position = viewer.getCameraPosition().toArray();\r\n const {settings, aerialState, sceneState} = getStoredState();\r\n const visibleAssetIDs = visibleAssets.map(asset => asset.id);\r\n\r\n dispatch(createBookmark({\r\n name,\r\n position,\r\n settings,\r\n visibleAssets: visibleAssetIDs,\r\n aerialState,\r\n sceneState\r\n }));\r\n };\r\n\r\n const handleClick = (event) => {\r\n const isCheckBox = (event.target.type === \"checkbox\");\r\n if (isCheckBox) return;\r\n\r\n setExpanded(!expanded);\r\n };\r\n\r\n const toggleCheckboxes = () => {\r\n let newVisibility;\r\n if (numVisible > 0 && numHidden > 0) {\r\n newVisibility = true;\r\n } else if (numVisible > 0) {\r\n newVisibility = false;\r\n } else {\r\n newVisibility = true;\r\n }\r\n\r\n for (let bookmark of bookmarks) {\r\n dispatch(updateBookmark({\r\n bookmarkID: bookmark.id,\r\n visible: newVisibility\r\n }));\r\n }\r\n };\r\n\r\n const handleDeleteSubmit = () => {\r\n for (let bookmark of bookmarks) {\r\n dispatch(deleteBookmark(bookmark.id));\r\n }\r\n deleteDialog.handleClose();\r\n };\r\n\r\n const handleDeleteClick = () => {\r\n deleteDialog.handleOpen();\r\n contextMenu.handleClose();\r\n };\r\n\r\n const numVisible = bookmarks.filter(x => x.visible).length;\r\n const numHidden = bookmarks.filter(x => !x.visible).length;\r\n\r\n return (\r\n \r\n\r\n {/* Add item button */}\r\n {permissions.create && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n )}\r\n\r\n {/* Bookmarks list */}\r\n \r\n {(bookmarks.length > 0) && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {(bookmarks.length > 0) && (\r\n {/* Show / hide contents */}\r\n {expanded ? : }\r\n\r\n {/* Toggle all folder assets */}\r\n 0}\r\n onChange={toggleCheckboxes}\r\n indeterminate={numVisible > 0 && numHidden > 0}\r\n />\r\n )}\r\n\r\n \r\n\r\n {expanded && (\r\n \r\n {bookmarks.map(bookmark =>\r\n \r\n )}\r\n \r\n )}\r\n\r\n \r\n )}\r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n {t('buttons.delete')}\r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n );\r\n};\r\n","import React from \"react\";\r\nimport {createStyles, makeStyles, Theme} from '@material-ui/core/styles';\r\nimport {useDispatch, useSelector} from 'react-redux';\r\nimport {\r\n Checkbox,\r\n ListItem,\r\n ListItemSecondaryAction,\r\n ListItemText,\r\n MenuItem,\r\n Typography\r\n} from \"@material-ui/core\";\r\nimport {\r\n DenseIcon,\r\n DenseMenu,\r\n PromptDialog,\r\n TextDialog\r\n} from \"../components\";\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport EditIcon from \"@material-ui/icons/Edit\";\r\nimport BookmarkIcon from '@material-ui/icons/Bookmark';\r\nimport SyncIcon from '@material-ui/icons/Sync';\r\nimport LinkIcon from '@material-ui/icons/Link';\r\nimport {\r\n deleteBookmark,\r\n updateBookmark,\r\n Bookmark\r\n} from \"../redux/bookmarks-slice\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { toast } from \"../app\";\r\nimport { getStoredState } from \".\";\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport { useAuth, useBookmarks, useContextMenu, useDialog, useViewer } from \"../hooks\";\r\nimport copyTextToClipboard from \"copy-to-clipboard\";\r\nimport { isStaticSite } from \"../electron-modules\";\r\nimport { selectVisibleAssets } from \"../redux/assets-slice\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n itemList: {\r\n paddingLeft: theme.spacing(4),\r\n display: \"inline-block\"\r\n },\r\n assetInfo: {\r\n display: 'flex',\r\n margin: '0px'\r\n },\r\n itemText: {\r\n wordBreak: \"break-word\",\r\n overflow: \"hidden\"\r\n },\r\n checkboxParent: {\r\n padding: \"0px\",\r\n height: \"100%\"\r\n },\r\n assetCheckbox: {\r\n position: \"relative\",\r\n transform: \"translateY(0%)\",\r\n }\r\n })\r\n);\r\n\r\ninterface BookmarkItemProps {\r\n bookmark: Bookmark;\r\n}\r\n\r\nexport const BookmarkItem = (props: BookmarkItemProps) => {\r\n const {bookmark} = props;\r\n\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {permissions} = useAuth();\r\n const {t} = useTranslation();\r\n const contextMenu = useContextMenu();\r\n const renameDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n const updateDialog = useDialog();\r\n const {loadBookmark} = useBookmarks();\r\n\r\n const visibleAssets = useSelector(selectVisibleAssets);\r\n\r\n const handleBookmarkClick = (event) => {\r\n const isCheckBox = (event.target.type === \"checkbox\");\r\n if (isCheckBox) return;\r\n\r\n loadBookmark(bookmark.id);\r\n };\r\n\r\n const handleVisibilityClick = () => {\r\n dispatch(updateBookmark({\r\n bookmarkID: bookmark.id,\r\n visible: !bookmark.visible\r\n }));\r\n };\r\n\r\n const handleDeleteSubmit = () => {\r\n dispatch(deleteBookmark(bookmark.id));\r\n deleteDialog.handleClose();\r\n };\r\n\r\n const handleDeleteClick = () => {\r\n contextMenu.handleClose();\r\n deleteDialog.handleOpen();\r\n };\r\n\r\n const handleRenameSubmit = name => {\r\n dispatch(updateBookmark({\r\n bookmarkID: bookmark.id,\r\n name\r\n }));\r\n\r\n renameDialog.handleClose();\r\n };\r\n\r\n const handleRenameClick = () => {\r\n contextMenu.handleClose();\r\n renameDialog.handleOpen();\r\n };\r\n\r\n const handleUpdateSubmit = () => {\r\n updateDialog.handleClose();\r\n\r\n if (!LocalScene.initialized) {\r\n toast.warning(t('bookmarks.invalid_position'));\r\n return;\r\n }\r\n\r\n const position = viewer.getCameraPosition().toArray();\r\n const {settings, aerialState, sceneState} = getStoredState();\r\n const visibleAssetIDs = visibleAssets.map(asset => asset.id);\r\n\r\n dispatch(updateBookmark({\r\n bookmarkID: bookmark.id,\r\n position,\r\n settings,\r\n visibleAssets: visibleAssetIDs,\r\n aerialState,\r\n sceneState\r\n }));\r\n\r\n toast.success(t('bookmarks.updated_bookmark'));\r\n };\r\n\r\n const handleUpdateClick = () => {\r\n contextMenu.handleClose();\r\n updateDialog.handleOpen();\r\n };\r\n\r\n const handleCopyClick = () => {\r\n contextMenu.handleClose();\r\n\r\n // Copy url to clipboard\r\n const url = new URL(window.location as any);\r\n url.hash = `bookmark=${bookmark.id}`;\r\n copyTextToClipboard(url.href);\r\n toast.success(t(\"toast.copied-to-clipboard\"));\r\n };\r\n\r\n return (\r\n \r\n \r\n
\r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n\r\n
\r\n \r\n\r\n \r\n {isStaticSite && \r\n \r\n \r\n \r\n {t('bookmarks.copy_bookmark_url')}\r\n }\r\n\r\n \r\n \r\n \r\n \r\n {t('buttons.rename')}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('buttons.update')}\r\n \r\n\r\n \r\n \r\n \r\n \r\n {t('buttons.delete')}\r\n \r\n\r\n \r\n\r\n {/* Rename Dialog */}\r\n \r\n\r\n {/* Update Dialog */}\r\n \r\n\r\n {/* Delete Dialog */}\r\n \r\n
\r\n );\r\n};","import IconButton from \"@material-ui/core/IconButton\";\r\nimport ChevronLeftIcon from \"@material-ui/icons/ChevronLeft\";\r\nimport ChevronRightIcon from \"@material-ui/icons/ChevronRight\";\r\nimport {FolderList} from \"./folder\";\r\nimport Drawer from \"@material-ui/core/Drawer\";\r\nimport React, {useEffect, useState, memo} from \"react\";\r\nimport {createStyles, makeStyles, Theme, useTheme} from \"@material-ui/core/styles\";\r\nimport { AppBar, Box, Tab } from \"@material-ui/core\";\r\nimport {\r\n PanelProps,\r\n TabPanel,\r\n TabProps,\r\n} from \"./components\";\r\nimport {\r\n changeDrawerOpen,\r\n changeSelectedTab,\r\n selectSelectedTab,\r\n} from \"./redux/settings-slice\";\r\nimport Tabs from \"@material-ui/core/Tabs/Tabs\";\r\nimport { useTranslation } from 'react-i18next';\r\nimport { BookmarkList } from \"./bookmarks\";\r\nimport { useDispatch, useSelector } from 'react-redux';\r\nimport { Bookmark } from \"./redux/bookmarks-slice\";\r\nimport { useBookmarks, useViewer } from \"./hooks\";\r\n\r\nexport const assetDrawerWidth = 280;\r\nexport const assetDrawerHeight = 75;\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n backdrop: {\r\n display: \"none\"\r\n },\r\n inside: {\r\n height: `${assetDrawerHeight}%`,\r\n display: \"flex\",\r\n overflow: \"hidden\",\r\n flexDirection: \"column\"\r\n },\r\n drawer: {\r\n width: 0,\r\n },\r\n drawerPaper: {\r\n width: assetDrawerWidth,\r\n },\r\n root: {\r\n \"z-index\": `${theme.zIndex.modal - 1} !important`\r\n },\r\n tab: {\r\n minWidth: \"0px !important\",\r\n flexBasis: \"unset\",\r\n flexShrink: \"unset\"\r\n },\r\n box: {\r\n padding: \"10px 0px 0px 0px !important\",\r\n height: \"calc(100% - 10px)\",\r\n overflow: \"auto\",\r\n display: \"flex\",\r\n flexDirection: \"column\"\r\n },\r\n tabGrow: {\r\n \"flex-grow\": 1\r\n },\r\n panel: {\r\n flex: 1,\r\n overflow: \"hidden\"\r\n },\r\n toggleDrawer: {\r\n color: \"white\"\r\n }\r\n }),\r\n);\r\n\r\ninterface AssetDrawerProps {\r\n assetDrawerState: boolean;\r\n}\r\n\r\nexport const AssetDrawer = memo((props: AssetDrawerProps) => {\r\n const {assetDrawerState} = props;\r\n\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const {bookmarks, loadBookmark} = useBookmarks();\r\n\r\n const projectActiveTab = useSelector(selectSelectedTab);\r\n\r\n const [activeTab, setSelectedTab] = useState(0);\r\n\r\n const setActiveTab = (event, value) => {\r\n dispatch(changeSelectedTab(value));\r\n };\r\n\r\n const handleDrawerClose = () => {\r\n dispatch(changeDrawerOpen(false));\r\n };\r\n\r\n useEffect(() => {\r\n setSelectedTab(projectActiveTab);\r\n }, [projectActiveTab]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n const newAnnotations = [];\r\n\r\n bookmarks.forEach((bookmark: Bookmark) => {\r\n if (!bookmark.visible) return;\r\n\r\n const onClick = () => {\r\n loadBookmark(bookmark.id);\r\n };\r\n\r\n const {name, position} = bookmark;\r\n const annotation = viewer.addAnnotation(name, position, onClick);\r\n newAnnotations.push(annotation);\r\n });\r\n\r\n viewer.updateAnnotations();\r\n\r\n return () => {\r\n newAnnotations.forEach(annotation => {\r\n viewer.removeAnnotation(annotation);\r\n });\r\n\r\n viewer.updateAnnotations();\r\n };\r\n }, [viewer, bookmarks]);\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {theme.direction === 'ltr' ? : }\r\n \r\n \r\n \r\n\r\n {/* Assets */}\r\n \r\n \r\n \r\n\r\n {/* Bookmarks */}\r\n \r\n \r\n \r\n
\r\n \r\n );\r\n});\r\n","import React, {useEffect, useState} from \"react\";\r\nimport {isElectronApp, registerEvent} from \"../electron-modules\";\r\nimport {\r\n FormControl,\r\n List,\r\n ListItem,\r\n MenuItem,\r\n Select,\r\n Switch, TextField\r\n} from \"@material-ui/core\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport {createStyles, makeStyles, Theme} from \"@material-ui/core/styles\";\r\nimport { SingleSlider } from \".\";\r\nimport clsx from 'clsx';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { ColorPicker, SimpleDialog } from \"../components\";\r\nimport {useAuth, useDialog, useGlobalSettings} from \"../hooks\";\r\nimport { ControlType } from \"../types/controls\";\r\nimport { SamplingRate, VolumeType } from \"../types/measurements\";\r\nimport {engineCloudURL as globalEngineCloudURL, setEngineCloudURL as setGlobalEngineCloudURL} from \"../urls\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n header: {\r\n marginTop: theme.spacing(1)\r\n },\r\n sectionTitle: {\r\n fontWeight: 'bold',\r\n display: \"inline-block\",\r\n fontSize: '0.9em'\r\n },\r\n slider: {\r\n width: \"100%\"\r\n },\r\n dropdown: {\r\n width: \"40%\"\r\n },\r\n checkBoxWithLabel: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n },\r\n dropdownWithLabel: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n }\r\n })\r\n);\r\n\r\nexport const GlobalSettings = () => {\r\n const {signOut} = useAuth();\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const settingsDialog = useDialog();\r\n const globalSettings = useGlobalSettings();\r\n\r\n const [openQuickNav, setOpenQuickNav] = useState(false);\r\n const [orthoQuality, setOrthoQuality] = useState(null);\r\n const [orthoOpacity, setOrthoOpacity] = useState(null);\r\n const [controlType, setControlType] = useState(null);\r\n const [volumeType, setVolumeType] = useState(null);\r\n const [volumeSampleRate, setVolumeSampleRate] = useState(null);\r\n const [viewerBackground, setViewerBackground] = useState(\"#00000\");\r\n const [aerialBackground, setAerialBackground] = useState(\"#00000\");\r\n\r\n const [engineCloudURL, setEngineCloudURL] = useState(\"\");\r\n\r\n const onSubmit = () => {\r\n globalSettings.update({\r\n orthoQuality,\r\n orthoOpacity,\r\n controlType,\r\n openQuickNav,\r\n volumeType,\r\n volumeSampleRate,\r\n viewerBackground,\r\n aerialBackground\r\n });\r\n\r\n if (isElectronApp) {\r\n const modified = setGlobalEngineCloudURL(engineCloudURL, true);\r\n\r\n if (modified) {\r\n signOut();\r\n }\r\n }\r\n\r\n settingsDialog.handleClose();\r\n };\r\n\r\n useEffect(() => {\r\n if (!settingsDialog.open) {\r\n return;\r\n }\r\n\r\n // Load current state from global settings context\r\n setOrthoQuality(globalSettings.orthoQuality);\r\n setOrthoOpacity(globalSettings.orthoOpacity);\r\n setControlType(globalSettings.controlType);\r\n setVolumeType(globalSettings.volumeType);\r\n setVolumeSampleRate(globalSettings.volumeSampleRate);\r\n setViewerBackground(globalSettings.viewerBackground);\r\n setAerialBackground(globalSettings.aerialBackground);\r\n setOpenQuickNav(globalSettings.openQuickNav);\r\n\r\n if (isElectronApp) {\r\n setEngineCloudURL(globalEngineCloudURL);\r\n }\r\n }, [settingsDialog.open]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-global-settings\", () => {\r\n settingsDialog.handleOpen();\r\n });\r\n }, []);\r\n\r\n return (\r\n \r\n {/* Global Settings */}\r\n \r\n\r\n {/** General setting header */}\r\n \r\n \r\n {t('global-settings.general_settings')}\r\n \r\n \r\n\r\n {/* Viewer background */}\r\n \r\n \r\n {\"Viewer Background\"}\r\n \r\n\r\n \r\n \r\n\r\n {/* Aerial background */}\r\n \r\n \r\n {\"Aerial Background\"}\r\n \r\n\r\n \r\n \r\n\r\n {/* Control Type */}\r\n \r\n \r\n {t(\"global-settings.control-type\")}\r\n \r\n\r\n \r\n {\r\n const value = Number(event.target.value);\r\n setControlType(value);\r\n }}\r\n >\r\n \r\n {t(\"control-type.default\")}\r\n \r\n \r\n {t(\"control-type.reverse\")}\r\n \r\n \r\n {t(\"control-type.autocad\")}\r\n \r\n \r\n \r\n \r\n\r\n {/* Quick navigation */}\r\n \r\n \r\n {t('global-settings.allow_quick_navigation_menu')}\r\n \r\n\r\n setOpenQuickNav(!openQuickNav)}\r\n name=\"openQuickNav\"\r\n />\r\n \r\n\r\n {/** Measurement header */}\r\n \r\n \r\n {t('global-settings.measurement_settings')}\r\n \r\n \r\n\r\n {/* Volume Calculation */}\r\n \r\n \r\n {t('global-settings.volume_calculation')}\r\n \r\n\r\n \r\n {\r\n const value = Number(event.target.value);\r\n setVolumeType(value);\r\n }}\r\n >\r\n \r\n {t('measure.volume_multi_plane')}\r\n \r\n \r\n {t('measure.volume_lowest_plane')}\r\n \r\n \r\n \r\n \r\n\r\n {/* Volume Sampling */}\r\n \r\n \r\n {t('global-settings.volume_sample_rate')}\r\n \r\n\r\n \r\n {\r\n const value = Number(event.target.value);\r\n setVolumeSampleRate(value);\r\n }}\r\n >\r\n \r\n {t('general.high')}\r\n \r\n \r\n {t('general.medium')}\r\n \r\n \r\n {t('general.low')}\r\n \r\n \r\n \r\n \r\n\r\n {/** Orthomoaic header */}\r\n \r\n \r\n {t(\"global-settings.orthomosaic-settings\")}\r\n \r\n \r\n\r\n {/* Orthomoaic opacity */}\r\n \r\n
\r\n \r\n {t(\"global-settings.orthomosaic-opacity\")}\r\n \r\n \r\n
\r\n
\r\n\r\n {/* Orthomoaic quality */}\r\n \r\n
\r\n \r\n {t(\"global-settings.orthomosaic-quality\")}\r\n \r\n \r\n
\r\n
\r\n\r\n {/** General setting header */}\r\n \r\n \r\n {t(\"global-settings.engine_cloud_settings\")}\r\n \r\n \r\n\r\n {/* Engine Cloud URL */}\r\n \r\n \r\n {t(\"global-settings.engine_cloud_url\")}\r\n \r\n\r\n \r\n {\r\n setEngineCloudURL(event.target.value);\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n
\r\n \r\n );\r\n};\r\n","export default __webpack_public_path__ + \"static/media/awesome-green.32dfeafe.png\";","export default __webpack_public_path__ + \"static/media/black-orange.62f427fb.png\";","export default __webpack_public_path__ + \"static/media/blue-hue.15284809.png\";","export default __webpack_public_path__ + \"static/media/blue-orange.19c7779d.png\";","export default __webpack_public_path__ + \"static/media/blue-red.d938a92d.png\";","export default __webpack_public_path__ + \"static/media/grayscale.416ab034.png\";","export default __webpack_public_path__ + \"static/media/heat-map.100d3bd6.png\";","export default __webpack_public_path__ + \"static/media/jet.e5269d83.png\";","export default __webpack_public_path__ + \"static/media/pastel-shades.1cd9b941.png\";","import awesomeGreen from './awesome-green.png';\r\nimport blackOrange from './black-orange.png';\r\nimport blueHue from './blue-hue.png';\r\nimport blueOrange from './blue-orange.png';\r\nimport blueRed from './blue-red.png';\r\nimport grayScale from './grayscale.png';\r\nimport heatMap from './heat-map.png';\r\nimport jet from './jet.png';\r\nimport pastelShades from './pastel-shades.png';\r\nimport {ColorMapKey} from \"../../../redux/settings-slice\";\r\nimport {t} from '../../../localization';\r\n\r\nclass ColorMap {\r\n public id: ColorMapKey;\r\n public image: string;\r\n\r\n constructor(id, image) {\r\n this.id = id;\r\n this.image = image;\r\n }\r\n\r\n get name() {\r\n return t(`color-map.${this.id}`);\r\n }\r\n}\r\n\r\nexport const colorMaps: ColorMap[] = [\r\n new ColorMap(\"heat-map\", heatMap),\r\n new ColorMap(\"awesome-green\", awesomeGreen),\r\n new ColorMap(\"pastel-shades\", pastelShades),\r\n new ColorMap(\"blue-orange\", blueOrange),\r\n new ColorMap(\"black-orange\", blackOrange),\r\n new ColorMap(\"blue-hue\", blueHue),\r\n new ColorMap(\"blue-red\", blueRed),\r\n new ColorMap(\"jet\", jet),\r\n new ColorMap(\"grayscale\", grayScale)\r\n];\r\n\r\nexport const getColorMap = (id) => {\r\n return colorMaps.find(colorMap => colorMap.id === id);\r\n};\r\n","import React, {useCallback, useEffect, useMemo, useState} from 'react';\r\nimport {createStyles, makeStyles, Theme} from '@material-ui/core/styles';\r\nimport Drawer from '@material-ui/core/Drawer';\r\nimport { throttle, debounce } from 'throttle-debounce';\r\nimport {\r\n Avatar,\r\n FormControl,\r\n InputAdornment,\r\n InputLabel,\r\n List,\r\n ListItem,\r\n MenuItem,\r\n Select,\r\n Switch,\r\n withStyles,\r\n} from \"@material-ui/core\";\r\nimport IconButton from \"@material-ui/core/IconButton\";\r\nimport CloseIcon from \"@material-ui/icons/Close\";\r\nimport Divider from \"@material-ui/core/Divider\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport Slider from \"@material-ui/core/Slider\";\r\nimport Input from \"@material-ui/core/Input\";\r\nimport {useSelector, useDispatch} from 'react-redux';\r\nimport {\r\n ColorMapKey, ColorType,\r\n selectCloudDistance, changeCloudDistance,\r\n selectOpacity, changeOpacity,\r\n selectCloudScale, changeCloudScale,\r\n selectCloudMinimum, changeCloudMinimum,\r\n selectHeightClip, changeHeightClip,\r\n selectIntensityClip, changeIntensityClip,\r\n selectColorMap, changeColorMap,\r\n selectColorType, changeColorType,\r\n selectDynamicSize, changeDynamicSize,\r\n changeClassificationVisibility,\r\n changeAllClassificationVisibility,\r\n changeCircularPoints, selectCircularPoints,\r\n changeArrowMarkers, selectArrowMarkers, MarkerNavType,\r\n selectCloudMaxPoints, changeCloudMaxPoints,\r\n selectClassifications,\r\n getAvailableClassifications,\r\n getClassificationVisibilities,\r\n changeAvailableClassifications,\r\n changeTagDistance,\r\n selectTagDistance\r\n} from '../redux/settings-slice';\r\nimport {colorMaps, getColorMap} from \"../viewer/textures/colormaps\";\r\nimport { getClassificationColors } from \"../classifications\";\r\nimport { isDevMode } from '../electron-modules';\r\nimport { ArrowTooltip, SlimScrollbar } from '../components';\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport { UnitConverter } from \"../viewer/js/utilities\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { KeyboardArrowDown, KeyboardArrowUp } from '@material-ui/icons';\r\nimport {isEqual} from 'lodash';\r\nimport { headerHeight } from '../app';\r\nimport { nanoid } from '@reduxjs/toolkit';\r\nimport clsx from 'clsx';\r\nimport { useViewer } from '../hooks';\r\nimport { corporate } from '../theme';\r\n\r\nexport const settingsDrawerWidth = 280;\r\n\r\nconst converter = new UnitConverter();\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n backdrop: {\r\n display: \"none\"\r\n },\r\n drawer: {\r\n width: 0,\r\n \"z-index\": `${theme.zIndex.appBar - 1} !important`,\r\n },\r\n drawerPaper: {\r\n width: settingsDrawerWidth,\r\n paddingTop: `${headerHeight}px`,\r\n height: `calc(100% - ${headerHeight}px)`,\r\n },\r\n asterisk: {\r\n \"&:after\": {\r\n content:'\"*\"',\r\n color: \"red\",\r\n paddingLeft: theme.spacing(0.5)\r\n }\r\n },\r\n drawerHeader: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n padding: theme.spacing(0, 1),\r\n // necessary for content to be below app bar\r\n ...theme.mixins.toolbar,\r\n justifyContent: 'flex-start',\r\n minHeight: `${headerHeight}px`\r\n },\r\n list: {\r\n width: '100%',\r\n maxWidth: 360,\r\n backgroundColor: theme.palette.background.paper,\r\n },\r\n listItem: {\r\n width: '100%',\r\n marginBottom: theme.spacing(0.5)\r\n },\r\n formControl: {\r\n width: '100%',\r\n marginBottom: theme.spacing(1)\r\n },\r\n switch: {\r\n marginLeft: 0\r\n },\r\n colorPreview: {\r\n height: theme.spacing(3),\r\n width: theme.spacing(3),\r\n marginRight: theme.spacing(1),\r\n },\r\n img: {\r\n objectFit: 'fill',\r\n transform: 'rotate(-90deg)'\r\n },\r\n classificationPreview: {\r\n height: theme.spacing(1.25),\r\n width: theme.spacing(1.25),\r\n backgroundColor: '#bbb',\r\n borderRadius: '50%',\r\n borderColor: '#000000',\r\n borderStyle: 'solid',\r\n borderWidth: '1px',\r\n marginRight: theme.spacing(1),\r\n display: 'inline-block'\r\n },\r\n switchLabel: {\r\n display: \"inline-block\",\r\n maxWidth: \"calc(100% - 50px)\"\r\n },\r\n switchElement: {\r\n float: \"right\"\r\n },\r\n inputText: {\r\n float: \"right\",\r\n paddingRight: \"10px\"\r\n },\r\n inputPropDiv: {\r\n display: \"flex\",\r\n zoom: \"0.85\",\r\n padding: \"6px 12px\",\r\n marginLeft: \"12px\",\r\n marginRight: \"calc(28px + 12px)\",\r\n marginTop: \"3px\"\r\n },\r\n sliderInputText: {\r\n whiteSpace: \"nowrap\",\r\n margin: \"auto 12px auto 0px\"\r\n },\r\n title: {\r\n flex: 1,\r\n margin: theme.spacing(0)\r\n },\r\n boldTitleTypography: {\r\n fontWeight: 'bold',\r\n fontSize: '1em'\r\n },\r\n sectionTitle: {\r\n display: \"inline-block\",\r\n fontWeight: 'bold',\r\n fontSize: '0.95em'\r\n },\r\n rightInput: {\r\n marginRight: \"4px\"\r\n },\r\n sliderInputParent: {\r\n display: \"flex\",\r\n paddingTop: theme.spacing(1.0)\r\n },\r\n sliderInputToggle: {\r\n padding: \"0px\",\r\n margin: \"9px 0px 0px 6px\"\r\n }\r\n }),\r\n);\r\n\r\nconst updateValueInterval = 50;\r\nconst saveDispatchInterval = 1000;\r\nconst classificationInterval = 200;\r\n\r\nconst InputSlider = (props) => {\r\n const {value, type, onChange, onFinish, labelFunction} = props;\r\n\r\n const magnitude = props.magnitude || 1.0;\r\n const units = props.units || \"m\";\r\n const adornment = props.endAdornment || \"\";\r\n\r\n const min = converter.convert(props.min * magnitude, \"m\", units);\r\n const max = converter.convert(props.max * magnitude, \"m\", units);\r\n const step = props.step * magnitude;\r\n\r\n const classes = useStyles();\r\n\r\n const isRangeType = type === \"range\";\r\n const inputProps = {min, max, step};\r\n\r\n const defaultLabel = value => {\r\n return `${+Number(value).toFixed(2)}${adornment}`;\r\n };\r\n\r\n const labelFormat = labelFunction\r\n ? labelFunction\r\n : defaultLabel;\r\n\r\n const marks = [{\r\n value: min,\r\n label: labelFormat(min)\r\n }, {\r\n value: max,\r\n label: labelFormat(max)\r\n }];\r\n\r\n const [openState, setOpen] = useState(false);\r\n const [sliderValue, setSliderValue] = useState(null);\r\n\r\n const roundToStep = (value) => {\r\n return +Number((Math.round(value/step) * step).toFixed(2));\r\n };\r\n\r\n const toInput = (value) => {\r\n if (isRangeType) {\r\n const min = converter.convert(value.min * magnitude, \"m\", units);\r\n const max = converter.convert(value.max * magnitude, \"m\", units);\r\n\r\n return [roundToStep(min), roundToStep(max)];\r\n }\r\n\r\n const out = converter.convert(value * magnitude, \"m\", units);\r\n return roundToStep(out);\r\n };\r\n\r\n const fromInput = (value) => {\r\n if (isRangeType) {\r\n return {\r\n min: converter.convert(value[0], units, \"m\") / magnitude,\r\n max: converter.convert(value[1], units, \"m\") / magnitude\r\n };\r\n }\r\n\r\n return converter.convert(value, units, \"m\") / magnitude;\r\n };\r\n\r\n // Throttle update function\r\n const changeCallback = useCallback(\r\n throttle(updateValueInterval, (value) => {\r\n onChange(value);\r\n }), []);\r\n\r\n // Debounce save function\r\n const finishCallback = useCallback(\r\n debounce(saveDispatchInterval, (value) => {\r\n if (!onFinish) return;\r\n onFinish(value);\r\n }), []);\r\n\r\n useEffect(() => {\r\n let scaledValue = toInput(value);\r\n\r\n /** NOTE: react will never return equal for arrays, so lodash is used */\r\n if (isEqual(sliderValue, scaledValue)) return;\r\n setSliderValue(scaledValue);\r\n }, [value, units]);\r\n\r\n useEffect(() => {\r\n if (sliderValue === null) return;\r\n\r\n // Trigger update and change callbacks\r\n const saveValue = fromInput(sliderValue);\r\n changeCallback(saveValue);\r\n finishCallback(saveValue);\r\n }, [sliderValue]);\r\n\r\n const handleClick = () => {\r\n setOpen(!openState);\r\n };\r\n\r\n return (\r\n \r\n
\r\n {\r\n setSliderValue(value);\r\n }}\r\n aria-labelledby=\"input-slider\"\r\n />\r\n\r\n {\r\n event.stopPropagation();\r\n handleClick();\r\n }}\r\n >\r\n {openState ? : }\r\n \r\n
\r\n\r\n {openState && (
\r\n {isRangeType && ()}\r\n\r\n {!isRangeType && ()}\r\n
)}\r\n
\r\n );\r\n};\r\n\r\nconst StyledSlider = withStyles({\r\n root: {\r\n marginBottom: \"0px\",\r\n marginLeft: \"12px\",\r\n marginRight: \"12px\"\r\n },\r\n rail: {\r\n height: \"12px\",\r\n borderRadius: \"4px\"\r\n },\r\n track: {\r\n height: \"12px\",\r\n borderRadius: \"0px\",\r\n borderTopLeftRadius: \"4px\",\r\n borderBottomLeftRadius: \"4px\"\r\n },\r\n thumb: {\r\n height: \"18px\",\r\n width: \"2px\",\r\n marginTop: \"-3px\",\r\n marginLeft: \"0px\",\r\n borderRadius: \"0px\",\r\n '&:focus, &:hover, &$active': {\r\n boxShadow: 'inherit',\r\n },\r\n },\r\n valueLabel: {\r\n top: '-8px',\r\n left: 'calc(-50% - 18px)',\r\n height: '18px',\r\n width: '40px',\r\n '& *': {\r\n transform: 'rotate(0)',\r\n borderRadius: '4px',\r\n height: 'auto',\r\n width: '40px',\r\n textAlign: 'center'\r\n },\r\n '&::after': {\r\n position: \"absolute\",\r\n display: \"block\",\r\n content: '\"\"',\r\n bottom: \"-2px\",\r\n left: \"50%\",\r\n width: \"0\",\r\n height: \"0\",\r\n marginLeft: \"-3px\",\r\n overflow: \"hidden\",\r\n border: \"3px solid transparent\",\r\n borderTopColor: corporate.red\r\n }\r\n },\r\n mark: {\r\n opacity: 0,\r\n },\r\n markLabel: {\r\n top: \"-8px\",\r\n fontSize: \"0.75em\",\r\n width: \"32px\",\r\n height: \"14px\",\r\n textAlign: \"center\",\r\n backgroundColor: \"rgba(0,0,0,0.2)\",\r\n borderRadius: \"4px\",\r\n opacity: 0.5\r\n },\r\n markLabelActive: {\r\n opacity: 0.5\r\n },\r\n active: {}\r\n})(Slider);\r\n\r\nconst SingleInputProp = (props) => {\r\n const {value, setValue, inputProps, adornment} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [inputValue, setInputValue] = useState(0);\r\n const [inputError, setInputError] = useState(false);\r\n\r\n useEffect(() => {\r\n setInputValue(+Number(value).toFixed(2));\r\n setInputError(false);\r\n }, [value]);\r\n\r\n const hasError = (value) => {\r\n return (value === \"\")\r\n || isNaN(value)\r\n || (parseFloat(value) < inputProps.min)\r\n || (parseFloat(value) > inputProps.max);\r\n };\r\n\r\n return (\r\n
\r\n \r\n {t(\"user-settings.slider-value\")}:\r\n \r\n\r\n {\r\n // Check for general error\r\n let error = hasError(value);\r\n setInputValue(value);\r\n setInputError(error);\r\n if (error) return;\r\n\r\n // Update slider value\r\n value = parseFloat(value);\r\n setValue(value);\r\n }}\r\n />\r\n
\r\n );\r\n};\r\n\r\nconst RangeInputProp = (props) => {\r\n const {values, setValues, inputProps, adornment} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [minValue, setMinValue] = useState(0);\r\n const [maxValue, setMaxValue] = useState(0);\r\n\r\n const [minError, setMinError] = useState(false);\r\n const [maxError, setMaxError] = useState(false);\r\n\r\n useEffect(() => {\r\n setMinValue(+Number(values[0]).toFixed(2));\r\n setMaxValue(+Number(values[1]).toFixed(2));\r\n\r\n setMinError(false);\r\n setMaxError(false);\r\n }, [values]);\r\n\r\n const hasError = (value) => {\r\n return (value === \"\")\r\n || isNaN(value)\r\n || (parseFloat(value) < inputProps.min)\r\n || (parseFloat(value) > inputProps.max);\r\n };\r\n\r\n return (\r\n \r\n
\r\n \r\n {t(\"user-settings.slider-minimum-value\")}:\r\n \r\n\r\n {\r\n // Check for general error\r\n let error = hasError(value);\r\n setMinValue(value);\r\n setMinError(error);\r\n if (error) return;\r\n\r\n value = parseFloat(value);\r\n\r\n // Make sure min is less than max\r\n if (value > maxValue) {\r\n setMinError(true);\r\n return;\r\n }\r\n\r\n // Update slider values\r\n setValues([value, maxValue]);\r\n }}\r\n />\r\n
\r\n\r\n
\r\n \r\n {t(\"user-settings.slider-maximum-value\")}:\r\n \r\n\r\n {\r\n // Check for general error\r\n let error = hasError(value);\r\n setMaxValue(value);\r\n setMaxError(error);\r\n if (error) return;\r\n\r\n value = parseFloat(value);\r\n\r\n // Make sure max is more than min\r\n if (value < minValue) {\r\n setMaxError(true);\r\n return;\r\n }\r\n\r\n // Update slider values\r\n setValues([minValue, value]);\r\n }}\r\n />\r\n\r\n
\r\n
\r\n );\r\n};\r\n\r\nconst InputField = (props) => {\r\n const {value, inputProps, onChange, adornment, errorState} = props;\r\n\r\n return (\r\n {adornment}}\r\n onChange={(event) => {\r\n onChange(event.target.value);\r\n }}\r\n />\r\n );\r\n};\r\n\r\nexport const SingleSlider = (props) => {\r\n return ;\r\n};\r\n\r\nexport const RangeSlider = (props) => {\r\n return ;\r\n};\r\n\r\nconst ClassificationList = (props) => {\r\n const {classifications} = props;\r\n\r\n const dispatch = useDispatch();\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [classificationColors, setClassificationColors] = useState(\r\n Array(256).fill('#ffffff'));\r\n\r\n useEffect(() => {\r\n const updateColorsList = async () => {\r\n const colors = await getClassificationColors();\r\n setClassificationColors(colors);\r\n };\r\n\r\n updateColorsList();\r\n }, []);\r\n\r\n const hasClassifications = classifications.length > 0;\r\n\r\n return (\r\n \r\n {!hasClassifications && (\r\n
\r\n \r\n \r\n {t(\"user-settings.no-points-loaded\")}\r\n \r\n \r\n
\r\n )}\r\n\r\n {hasClassifications && (\r\n classifications.map(classification => (\r\n \r\n
\r\n
\r\n \r\n\r\n \r\n {`${classification.name} (${classification.id})`}\r\n \r\n\r\n {\r\n dispatch(changeClassificationVisibility(classification.id));\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n ))\r\n )}\r\n\r\n
\r\n );\r\n};\r\n\r\nexport const SettingsDrawer = (props) => {\r\n const {open, handleClose} = props;\r\n\r\n const dispatch = useDispatch();\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const classifications = useSelector(selectClassifications);\r\n\r\n /** Checkbox selectors (uses redux value directly) */\r\n const savedColorMap = useSelector(selectColorMap);\r\n const savedColorType = useSelector(selectColorType);\r\n const savedDynamicSize = useSelector(selectDynamicSize);\r\n const savedCircularPoints = useSelector(selectCircularPoints);\r\n const savedArrowMarkers = useSelector(selectArrowMarkers);\r\n\r\n /** Developer only toggles */\r\n const [pickerDebug, setPickerDebug] = useState(false);\r\n const [boundsVisible, setBoundsVisible] = useState(false);\r\n const [renderPaused, setRenderPaused] = useState(false);\r\n\r\n /** Slider selectors (uses throttled save callback) */\r\n const savedOpacity = useSelector(selectOpacity);\r\n const savedTagDistance = useSelector(selectTagDistance);\r\n const savedCloudDistance = useSelector(selectCloudDistance);\r\n const savedCloudScale = useSelector(selectCloudScale);\r\n const savedCloudMinimum = useSelector(selectCloudMinimum);\r\n const savedMaxPoints = useSelector(selectCloudMaxPoints);\r\n const savedHeightClip = useSelector(selectHeightClip);\r\n const savedIntensityClip = useSelector(selectIntensityClip);\r\n\r\n const paperPropID = useState(nanoid())[0];\r\n\r\n const savedAvailableClassifications = useMemo(() => {\r\n return getAvailableClassifications(classifications);\r\n }, [classifications]);\r\n\r\n const savedClassificationVisibilities = useMemo(() => {\r\n return getClassificationVisibilities(classifications);\r\n }, [classifications]);\r\n\r\n const units = LocalScene.viewProjectionUnits;\r\n\r\n /** Handle classification updates */\r\n useEffect(() => {\r\n const interval = setInterval(() => {\r\n if (!viewer) return;\r\n\r\n const newClasses = viewer.getAvailableClassifications();\r\n const oldClasses = savedAvailableClassifications.map(x => x.id);\r\n\r\n // NOTE: Sorting is important for equality check\r\n newClasses.sort();\r\n oldClasses.sort();\r\n\r\n if (isEqual(newClasses, oldClasses)) return;\r\n\r\n dispatch(changeAvailableClassifications(newClasses));\r\n }, classificationInterval);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }, [viewer, classifications]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudOpacity(savedOpacity);\r\n }, [viewer, savedOpacity]);\r\n\r\n useEffect(() => {\r\n viewer?.setTagDistance(savedTagDistance);\r\n }, [viewer, savedTagDistance]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudDistance(savedCloudDistance);\r\n }, [viewer, savedCloudDistance]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudScale(savedCloudScale);\r\n }, [viewer, savedCloudScale]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudMinimum(savedCloudMinimum);\r\n }, [viewer, savedCloudMinimum]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudMaxPoints(savedMaxPoints);\r\n }, [viewer, savedMaxPoints]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudHeightClip(savedHeightClip);\r\n }, [viewer, savedHeightClip]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudIntensityClip(savedIntensityClip);\r\n }, [viewer, savedIntensityClip]);\r\n\r\n useEffect(() => {\r\n viewer?.setVisibleClassifications(savedClassificationVisibilities);\r\n }, [viewer, savedClassificationVisibilities]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudColorMap(savedColorMap);\r\n }, [viewer, savedColorMap]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudColorType(savedColorType);\r\n }, [viewer, savedColorType]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudDynamicSize(savedDynamicSize);\r\n }, [viewer, savedDynamicSize]);\r\n\r\n useEffect(() => {\r\n viewer?.setPointCloudCircularPoints(savedCircularPoints);\r\n }, [viewer, savedCircularPoints]);\r\n\r\n useEffect(() => {\r\n viewer?.setNavigationType(savedArrowMarkers);\r\n }, [viewer, savedArrowMarkers]);\r\n\r\n const isIntensity = savedColorType === 0;\r\n const isHeightmap = savedColorType === 2;\r\n const colorMapRequired = isIntensity || isHeightmap;\r\n\r\n return (\r\n {\r\n /** Remove tabindex from paper to stop drag/drop issues */\r\n let element = document.getElementById(paperPropID);\r\n element?.removeAttribute(\"tabindex\");\r\n }}\r\n classes={{\r\n paper: classes.drawerPaper,\r\n }}\r\n BackdropProps={{\r\n classes: {\r\n root: classes.backdrop\r\n },\r\n }}\r\n PaperProps={{\r\n id: paperPropID\r\n }}\r\n >\r\n \r\n\r\n \r\n \r\n \r\n {t('user-settings.project_settings')}\r\n \r\n\r\n {/* Close button */}\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* Developer Controls */}\r\n {isDevMode && (\r\n \r\n \r\n \r\n {t('user-settings.developer-debug')}\r\n \r\n \r\n\r\n {/* Picker Debug */}\r\n \r\n
\r\n \r\n {t(\"user-settings.gpu-picker\")}\r\n \r\n\r\n {\r\n viewer?.togglePickerDebug(checked);\r\n setPickerDebug(checked);\r\n }}\r\n />\r\n
\r\n
\r\n\r\n {/* Points render toggle */}\r\n \r\n
\r\n \r\n {t('user-settings.pause-points-rendering')}\r\n \r\n\r\n {\r\n viewer?.setPointsShouldUpdate(!checked);\r\n setRenderPaused(checked);\r\n }}\r\n />\r\n
\r\n
\r\n\r\n {/* Point Bounds Debug */}\r\n \r\n
\r\n \r\n {t('user-settings.visible-point-bounds')}\r\n \r\n\r\n {\r\n viewer?.setPointBoundsVisible(checked);\r\n setBoundsVisible(checked);\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n\r\n \r\n
)}\r\n\r\n {/* Point Cloud Controls */}\r\n \r\n \r\n \r\n {t(\"user-settings.point-cloud-controls\")}\r\n \r\n \r\n\r\n {/* Color type */}\r\n \r\n
\r\n \r\n {t(\"user-settings.color-type\")}\r\n \r\n \r\n {\r\n const value = event.target.value as ColorType;\r\n dispatch(changeColorType(value));\r\n }}\r\n >\r\n \r\n {t(\"color-type.intensity\")}\r\n \r\n \r\n {t(\"color-type.color\")}\r\n \r\n \r\n {t(\"color-type.height\")}\r\n \r\n \r\n {t(\"color-type.classification\")}\r\n \r\n \r\n \r\n
\r\n
\r\n\r\n {/* Color maps */}\r\n {colorMapRequired && (\r\n \r\n
\r\n \r\n {t(\"user-settings.color-map\")}\r\n \r\n \r\n {\r\n return getColorMap(value).name;\r\n }}\r\n onChange={(event) => {\r\n const value = event.target.value as ColorMapKey;\r\n dispatch(changeColorMap(value));\r\n }}\r\n >\r\n {colorMaps.map((colorMap) => (\r\n \r\n \r\n {colorMap.name}\r\n \r\n ))}\r\n \r\n \r\n
\r\n
\r\n )}\r\n\r\n {/* Arrow Markers */}\r\n \r\n
\r\n \r\n {t(\"user-settings.navigation-type\")}\r\n \r\n \r\n {\r\n let value = event.target.value as MarkerNavType;\r\n dispatch(changeArrowMarkers(value));\r\n }}\r\n >\r\n \r\n {t(\"navigation-type.arrows\")}\r\n \r\n \r\n {t(\"navigation-type.markers\")}\r\n \r\n \r\n {t(\"navigation-type.none\")}\r\n \r\n \r\n \r\n
\r\n
\r\n\r\n {/* Cloud Opacity */}\r\n \r\n
\r\n \r\n {t(\"user-settings.point-visibility\")}\r\n \r\n {\r\n viewer?.setPointCloudOpacity(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeOpacity(value));\r\n }}\r\n min={0}\r\n max={1}\r\n step={0.01}\r\n magnitude={100}\r\n color={\"secondary\"}\r\n endAdornment={\"%\"}\r\n />\r\n
\r\n
\r\n\r\n {/* Cloud Max Points */}\r\n \r\n
\r\n \r\n {t(\"user-settings.max-visible-points\")}\r\n \r\n {\r\n viewer?.setPointCloudMaxPoints(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeCloudMaxPoints(value));\r\n }}\r\n min={0}\r\n max={10}\r\n step={0.05}\r\n endAdornment={\"M\"}\r\n />\r\n
\r\n
\r\n\r\n {/* Cloud Distance */}\r\n \r\n
\r\n \r\n {t(\"user-settings.point-distance\")}\r\n \r\n {\r\n viewer?.setPointCloudDistance(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeCloudDistance(value));\r\n }}\r\n min={0}\r\n max={1000}\r\n step={5}\r\n units={units}\r\n endAdornment={units}\r\n labelFunction={(value) => {\r\n const maxValue = converter.convert(999, \"m\", units);\r\n return (value > maxValue) ? \"∞\" : `${value}${units}`;\r\n }}\r\n />\r\n
\r\n
\r\n\r\n {/* Height range */}\r\n {isHeightmap && (\r\n \r\n
\r\n \r\n {t(\"user-settings.height-range\")}\r\n \r\n {\r\n viewer?.setPointCloudHeightClip(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeHeightClip(value));\r\n }}\r\n min={-0.5}\r\n max={1.5}\r\n step={0.01}\r\n magnitude={100}\r\n color={\"secondary\"}\r\n endAdornment={\"%\"}\r\n valueLabelDisplay=\"on\"\r\n />\r\n
\r\n
\r\n )}\r\n\r\n {/* Intensity range */}\r\n {isIntensity && (\r\n \r\n
\r\n \r\n {t(\"user-settings.intensity-range\")}\r\n \r\n {\r\n viewer?.setPointCloudIntensityClip(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeIntensityClip(value));\r\n }}\r\n min={-0.5}\r\n max={1.5}\r\n step={0.01}\r\n magnitude={100}\r\n color={\"secondary\"}\r\n endAdornment={\"%\"}\r\n valueLabelDisplay=\"on\"\r\n />\r\n
\r\n
\r\n )}\r\n\r\n {/* Circular Points */}\r\n \r\n
\r\n \r\n {t(\"user-settings.circular-points\")}\r\n \r\n\r\n {\r\n dispatch(changeCircularPoints(checked));\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n\r\n \r\n\r\n {/* Point Cloud Size */}\r\n \r\n \r\n \r\n {t('user-settings.point-cloud-sizing')}\r\n \r\n \r\n\r\n {/* Point cloud scale */}\r\n \r\n
\r\n \r\n {t(\"user-settings.point-size\")}\r\n \r\n {\r\n viewer?.setPointCloudScale(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeCloudScale(value));\r\n }}\r\n min={0}\r\n max={3}\r\n step={0.1}\r\n />\r\n
\r\n
\r\n\r\n {/* Minimum point size */}\r\n \r\n
\r\n \r\n {t('user-settings.minimum-point-size')}\r\n \r\n {\r\n viewer?.setPointCloudMinimum(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeCloudMinimum(value));\r\n }}\r\n min={0}\r\n max={3}\r\n step={0.1}\r\n />\r\n
\r\n
\r\n\r\n {/* Adaptive point sizing */}\r\n \r\n
\r\n \r\n \r\n {t(\"user-settings.dynamic-point-sizing\")}\r\n \r\n \r\n\r\n {\r\n dispatch(changeDynamicSize(checked));\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n\r\n {/* Asset controls */}\r\n \r\n \r\n \r\n {\"Tag Controls\"}\r\n \r\n \r\n\r\n {/* Tag Distance */}\r\n \r\n
\r\n \r\n {t(\"user-settings.tag-distance\")}\r\n \r\n {\r\n viewer?.setTagDistance(value);\r\n }}\r\n onFinish={(value) => {\r\n dispatch(changeTagDistance(value));\r\n }}\r\n min={0}\r\n max={1000}\r\n step={5}\r\n units={units}\r\n endAdornment={units}\r\n labelFunction={(value) => {\r\n const maxValue = converter.convert(999, \"m\", units);\r\n return (value > maxValue) ? \"∞\" : `${value}${units}`;\r\n }}\r\n />\r\n
\r\n
\r\n
\r\n\r\n\r\n \r\n\r\n {/* Classifications */}\r\n \r\n \r\n
\r\n \r\n {t(\"user-settings.classifications\")}\r\n \r\n\r\n {savedAvailableClassifications.length > 0 && (\r\n \r\n classification.visible\r\n )}\r\n className={classes.switchElement}\r\n size=\"small\"\r\n color=\"secondary\"\r\n onChange={(_, checked) => {\r\n dispatch(changeAllClassificationVisibility(checked));\r\n }}\r\n />\r\n \r\n )}\r\n
\r\n
\r\n\r\n \r\n\r\n
\r\n\r\n
\r\n \r\n );\r\n};","import React, {memo, useEffect, useState} from 'react';\r\nimport {makeStyles, Theme, createStyles} from '@material-ui/core/styles';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport MenuIcon from '@material-ui/icons/Menu';\r\nimport MeasureIcon from '@material-ui/icons/SquareFoot';\r\nimport LinkIcon from '@material-ui/icons/Link';\r\nimport SettingsIcon from '@material-ui/icons/Settings';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport HomeIcon from '@material-ui/icons/Home';\r\nimport {\r\n updateProjectName,\r\n selectProjectName\r\n} from \"./redux/project-slice\";\r\nimport {useSelector, useDispatch} from 'react-redux';\r\nimport {\r\n Projection,\r\n updateDataProjection,\r\n updateViewProjection,\r\n selectDataProjection\r\n} from './redux/projections-slice';\r\nimport {\r\n userProjections,\r\n uniqueProjectionID,\r\n unknownProjectionFeet,\r\n unknownProjectionMeters\r\n} from './projections';\r\nimport {\r\n Button,\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n DialogContentText,\r\n DialogTitle,\r\n FormControl,\r\n FormHelperText,\r\n InputLabel,\r\n ListSubheader,\r\n MenuItem,\r\n TextField\r\n} from '@material-ui/core';\r\nimport {assetDrawerWidth} from './asset-drawer';\r\nimport LocalScene, {\r\n projectionToMeters,\r\n projectionToUnits,\r\n SceneCoordinate\r\n} from './viewer/js/projections';\r\nimport {isCloudSite, isElectronApp} from \"./electron-modules\";\r\nimport {\r\n changeBasicAdjustments,\r\n changeCameraHeight,\r\n changeCameraTransform,\r\n selectBasicAdjustments,\r\n selectCameraHeight,\r\n selectCameraTransform\r\n} from './redux/camera-slice';\r\nimport {\r\n asyncTimeout,\r\n getLocalizedProjectionName,\r\n getLocalizedProjectName,\r\n getMatrixValues,\r\n openDialogFile,\r\n saveMatrixFile\r\n} from \"./utilities\";\r\nimport {cameraMatrixFilter} from \"./file-extensions\";\r\nimport clsx from 'clsx';\r\nimport { ArrowTooltip, LanguageSwitch, AccountButton } from './components';\r\nimport {headerHeight, toast} from './app';\r\nimport {settingsDrawerWidth} from \"./settings\";\r\nimport { sendCustomEvent } from './events';\r\nimport { Vector3 } from 'three';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { getLocalizedURL } from './localization';\r\nimport { changeDrawerOpen, changeSelectedTab } from './redux/settings-slice';\r\nimport { UnitConverter } from './viewer/js/utilities';\r\nimport {isEqual} from 'lodash';\r\nimport {\r\n useDialog,\r\n useViewer,\r\n useActiveTool,\r\n useAuth,\r\n useBookmarks\r\n} from './hooks';\r\n\r\nconst converter = new UnitConverter();\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n disabled: {\r\n opacity: 0.3\r\n },\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n menuButton: {\r\n marginRight: theme.spacing(2),\r\n },\r\n title: {\r\n flexGrow: 1,\r\n },\r\n projectName: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n padding: theme.spacing(0, 1),\r\n // necessary for content to be below app bar\r\n ...theme.mixins.toolbar,\r\n justifyContent: 'flex-start',\r\n flexGrow: 1\r\n },\r\n projectionText: {\r\n paddingTop: theme.spacing(0),\r\n marginTop: \"-5px\",\r\n color: \"white\"\r\n },\r\n marginTop: {\r\n marginTop: theme.spacing(2),\r\n marginBottom: theme.spacing(1)\r\n },\r\n buttonDiv: {\r\n textAlign: \"right\"\r\n },\r\n footerCoords: {\r\n fontSize: \"0.95rem\",\r\n paddingRight: theme.spacing(1.5),\r\n textShadow: \"1px 1px 2px black, 0px 0px 2px black\"\r\n },\r\n footerOffset: {\r\n marginRight: settingsDrawerWidth\r\n },\r\n footer: {\r\n boxShadow: \"none\",\r\n background: \"transparent\",\r\n pointerEvents: \"none\"\r\n },\r\n coordinates: {\r\n width: \"100%\",\r\n display: \"flex\",\r\n justifyContent: \"flex-end\"\r\n },\r\n button: {\r\n marginTop: theme.spacing(2),\r\n marginLeft: theme.spacing(1)\r\n },\r\n slimButton: {\r\n marginTop: theme.spacing(1)\r\n },\r\n dropdown: {\r\n minWidth: 200,\r\n },\r\n offset: {\r\n marginLeft: assetDrawerWidth - 60\r\n },\r\n textField: {\r\n paddingBottom: theme.spacing(3)\r\n },\r\n matrixValuesParent: {\r\n display: \"flex\",\r\n paddingTop: theme.spacing(2),\r\n justifyContent: \"space-evenly\"\r\n },\r\n matrixValues: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n textAlign: \"center\"\r\n },\r\n matrixButtons: {\r\n display: \"flex\",\r\n justifyContent: \"center\"\r\n }\r\n }),\r\n);\r\n\r\nconst ProjectDetails = (props) => {\r\n const {viewer} = useViewer();\r\n const {assetDrawerState} = props;\r\n\r\n const dispatch = useDispatch();\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n const projectDialog = useDialog();\r\n const warnDialog = useDialog();\r\n\r\n const [name, setName] = useState(\"\");\r\n const [height, setHeight] = useState(0);\r\n const [proj, setProj] = useState(\"\");\r\n const [matchedProjection, setMatchedProjection] = useState(null);\r\n const [imported, setImported] = useState(null);\r\n const [projections, setProjections] = useState([]);\r\n const {deleteBookmarks} = useBookmarks();\r\n\r\n const [cameraTransform, setCameraTransform] = useState({\r\n path: null,\r\n rotation: null,\r\n offset: null\r\n });\r\n\r\n const [errors, setErrors] = useState({\r\n name: false,\r\n height: false,\r\n projection: false,\r\n correction: false\r\n });\r\n\r\n const projectName = useSelector(selectProjectName);\r\n const projectHeight = useSelector(selectCameraHeight);\r\n const cameraTransformPath = useSelector(selectCameraTransform);\r\n const dataProjection = useSelector(selectDataProjection);\r\n const basicAdjustments = useSelector(selectBasicAdjustments);\r\n\r\n const unknownTextMeters = unknownProjectionMeters.name;\r\n const unknownTextFeet = unknownProjectionFeet.name;\r\n\r\n const getNewProjection = () => {\r\n let newProjection = null;\r\n\r\n if (proj === unknownTextMeters) {\r\n newProjection = unknownProjectionMeters;\r\n } else if (proj === unknownTextFeet) {\r\n newProjection = unknownProjectionFeet;\r\n } else if (imported && (proj === imported.name)) {\r\n newProjection = imported;\r\n } else {\r\n const results = projections.filter(x => x.name === proj);\r\n if (results.length !== 1) {\r\n return;\r\n }\r\n newProjection = results[0];\r\n }\r\n\r\n return newProjection;\r\n };\r\n\r\n const updateName = (event) => {\r\n const value = event.target.value;\r\n setErrors({...errors, name: false});\r\n setName(value);\r\n };\r\n\r\n const updateHeight = (event) => {\r\n const value = event.target.value;\r\n setErrors({...errors, height: false});\r\n setHeight(value);\r\n };\r\n\r\n const updateProj = (event) => {\r\n const value = event.target.value;\r\n if (!value) {\r\n return;\r\n }\r\n\r\n setErrors({...errors, projection: false});\r\n setProj(value);\r\n };\r\n\r\n const onSubmit = async () => {\r\n const trimmedName = name.trim();\r\n const emptyName = trimmedName === \"\";\r\n const emptyHeight = (height as any) === \"\";\r\n const emptyProjection = proj === \"\";\r\n\r\n setErrors({\r\n name: emptyName,\r\n height: emptyHeight,\r\n projection: emptyProjection,\r\n correction: false\r\n });\r\n\r\n if (emptyName || emptyProjection || emptyHeight) {\r\n return;\r\n }\r\n\r\n const heightInMeters = height * toMeters;\r\n\r\n projectDialog.handleClose();\r\n toast.success(t(\"toast.project-details-updated\"));\r\n\r\n await asyncTimeout(100);\r\n\r\n dispatch(updateProjectName(trimmedName));\r\n dispatch(changeCameraHeight(heightInMeters));\r\n dispatch(changeCameraTransform(cameraTransform.path));\r\n\r\n // Projection change requires a more strict check before dispatch\r\n const projectionName = selectedProjection.name;\r\n const projectionChanged = !LocalScene.isDataProjection(projectionName);\r\n\r\n if (!projectionChanged) return;\r\n\r\n viewer.setInitialStateFlag(false); // Reset initial zoom\r\n dispatch(changeSelectedTab(0)); // Reset to manage tab\r\n\r\n // Clear all bookmarks. TODO: update values instead of clearing(?)\r\n deleteBookmarks();\r\n\r\n dispatch(updateDataProjection(selectedProjection));\r\n dispatch(updateViewProjection(selectedProjection));\r\n };\r\n\r\n const handleImported = () => {\r\n const name = dataProjection.name;\r\n\r\n // Special case for default projections\r\n if ((name === unknownTextFeet) || (name === unknownTextMeters)) {\r\n setImported(null);\r\n return;\r\n }\r\n\r\n // Check to see if this projection existed in the users defined projections\r\n const matchedProjection = userProjections.data\r\n .find(x => x.name === name);\r\n\r\n if (matchedProjection) {\r\n const importedProjection = JSON.parse(JSON.stringify(dataProjection));\r\n const userProjection = JSON.parse(JSON.stringify(matchedProjection));\r\n\r\n if (isEqual(importedProjection, userProjection)) {\r\n // Projections match, so we use the locally defined one\r\n setImported(null);\r\n } else {\r\n // Projections are different, so we warn\r\n // the user and use the imported one\r\n setImported({...dataProjection});\r\n warnDialog.handleOpen();\r\n }\r\n } else {\r\n // Projection is not found in the users defined\r\n // projections so we mark it as imported\r\n setImported({...dataProjection});\r\n }\r\n };\r\n\r\n const onCorrectionSelect = async () => {\r\n const filePath = await openDialogFile(cameraMatrixFilter);\r\n if (!filePath) return;\r\n\r\n const {success, rotation, offset} = await getMatrixValues(filePath);\r\n\r\n if (!success) {\r\n toast.error(t(\"toast.correction-matrix-error\"));\r\n return;\r\n }\r\n\r\n setCameraTransform({path: filePath, rotation, offset});\r\n };\r\n\r\n const onMatrixChange = async (filePath: string) => {\r\n const {success, rotation, offset} = await getMatrixValues(filePath);\r\n\r\n if (success) {\r\n setCameraTransform({path: filePath, rotation, offset});\r\n } else {\r\n onCorrectionRemove();\r\n }\r\n };\r\n\r\n const onCorrectionRemove = () => {\r\n setCameraTransform({\r\n path: null,\r\n rotation: null,\r\n offset: null\r\n });\r\n };\r\n\r\n const updateTitle = (title) => {\r\n document.title = `SOLV3D engine viewer : ${title}`;\r\n };\r\n\r\n const clearBasicAlignment = () => {\r\n dispatch(changeBasicAdjustments({}));\r\n viewer?.resetBasicAlignerCamera();\r\n };\r\n\r\n const getTransformValues = () => {\r\n let rotation = [0,0,0];\r\n let offset = [0,0,0];\r\n\r\n if (cameraTransform.offset) {\r\n offset = [\r\n converter.convert(cameraTransform.offset.x, \"m\", units, 2),\r\n converter.convert(cameraTransform.offset.y, \"m\", units, 2),\r\n converter.convert(cameraTransform.offset.z, \"m\", units, 2)\r\n ];\r\n }\r\n\r\n if (cameraTransform.rotation) {\r\n rotation = [\r\n cameraTransform.rotation.x.toFixed(2),\r\n cameraTransform.rotation.y.toFixed(2),\r\n cameraTransform.rotation.z.toFixed(2)\r\n ];\r\n }\r\n\r\n return {rotation, offset};\r\n };\r\n\r\n const resetDefaults = () => {\r\n const height = projectHeight / projectionToMeters(dataProjection);\r\n setHeight(height);\r\n\r\n const localizedProjectName = getLocalizedProjectName(projectName);\r\n setName(localizedProjectName);\r\n\r\n setProj(dataProjection.name);\r\n };\r\n\r\n useEffect(() => {\r\n onMatrixChange(cameraTransformPath);\r\n }, [cameraTransformPath]);\r\n\r\n useEffect(() => {\r\n if (!projectDialog.open) return;\r\n\r\n resetDefaults();\r\n handleImported();\r\n userProjections.load();\r\n\r\n // Get a sorted list of projections\r\n const sortedProjections = userProjections.data.sort((a, b) => {\r\n const name1 = a.name.toLowerCase();\r\n const name2 = b.name.toLowerCase();\r\n return (name1 < name2) ? -1 : ((name2 > name1) ? 1 : 0);\r\n });\r\n\r\n // Find the current projection\r\n const matchedProjection = sortedProjections.filter(\r\n x => x.name === dataProjection.name)[0];\r\n\r\n setProjections(sortedProjections);\r\n setMatchedProjection(matchedProjection);\r\n }, [projectDialog.open, dataProjection]);\r\n\r\n const selectedProjection = getNewProjection();\r\n const units = projectionToUnits(selectedProjection);\r\n const toMeters = projectionToMeters(selectedProjection);\r\n const hasBasicAlignment = Object.keys(basicAdjustments).length !== 0;\r\n\r\n const isDefaultProjection = dataProjection.default;\r\n const localizedProjectionName = getLocalizedProjectionName(dataProjection, units);\r\n const localizedProjectName = getLocalizedProjectName(projectName);\r\n\r\n const {rotation, offset} = getTransformValues();\r\n const hasUserProjections = projections.length > 0;\r\n updateTitle(localizedProjectName);\r\n\r\n return (\r\n
\r\n \r\n \r\n {localizedProjectName}\r\n \r\n \r\n {localizedProjectionName}\r\n \r\n \r\n\r\n {isElectronApp && (\r\n \r\n \r\n \r\n )}\r\n\r\n \r\n \r\n {t('project-settings.project-information')}\r\n \r\n \r\n\r\n {/* Project display title */}\r\n \r\n {t('project-settings.project-title')}\r\n \r\n\r\n \r\n {t('project-settings.project-title-description')}\r\n \r\n \r\n\r\n {/* Camera height */}\r\n \r\n {t('project-settings.camera-height', {units})}\r\n \r\n \r\n {t('project-settings.camera-height-description')}\r\n \r\n \r\n\r\n {/* Projection dropdown */}\r\n \r\n {t('project-settings.data-projection')}\r\n \r\n \r\n {t('project-settings.data-projection-description')}\r\n \r\n \r\n {imported && (\r\n {t('project-settings.imported-projections')}\r\n )}\r\n\r\n {imported && ({imported.name})}\r\n\r\n \r\n {t('project-settings.generic-projections')}\r\n \r\n\r\n {t(\"projections.default-projection\", {units: \"m\"})}\r\n\r\n {t(\"projections.default-projection\", {units: \"ft\"})}\r\n\r\n {hasUserProjections && \r\n {t('project-settings.user-projections')}\r\n }\r\n\r\n {projections.map(row => {\r\n const conflict = imported\r\n ? imported.name === row.name\r\n : false;\r\n\r\n const suffix = conflict\r\n ? \"__conflict\"\r\n : \"\";\r\n\r\n return ({row.name});\r\n })}\r\n \r\n\r\n {/* Camera Correction Matrix */}\r\n
\r\n \r\n {t('project-settings.camera-correction')}\r\n \r\n\r\n {(!hasBasicAlignment) && (\r\n {t('project-settings.camera-correction-description')}\r\n )}\r\n\r\n {(hasBasicAlignment) && (
\r\n \r\n {t('project-settings.camera-correction-warning')}\r\n \r\n
)}\r\n\r\n
\r\n {cameraTransform.path &&
\r\n \r\n {t('project-settings.matrix_offset_units', {units})}: [{offset[0]}, {offset[1]}, {offset[2]}]\r\n \r\n\r\n \r\n {t('project-settings.matrix_rotation')}: [{rotation[0]}, {rotation[1]}, {rotation[2]}]\r\n \r\n
}\r\n\r\n
\r\n {/* Save matrix file */}\r\n {(cameraTransform.path) && (saveMatrixFile(cameraTransform.path)}\r\n className={clsx(classes.button, classes.slimButton)}\r\n color=\"primary\"\r\n >\r\n {t('buttons.save-file')}\r\n )}\r\n\r\n {/* Remove matrix file */}\r\n {cameraTransform.path && (\r\n {t('buttons.remove-file')}\r\n )}\r\n\r\n {/* Upload matrix file */}\r\n {(!hasBasicAlignment) && (\r\n {t('buttons.upload-file')}\r\n )}\r\n\r\n {/* Cancel basic alignment */}\r\n {(hasBasicAlignment) && (\r\n {t('buttons.clear-file')}\r\n )}\r\n
\r\n
\r\n\r\n
\r\n\r\n
\r\n \r\n {t('buttons.cancel')}\r\n \r\n\r\n \r\n {t('buttons.update-project')}\r\n \r\n
\r\n
\r\n \r\n\r\n {/* Warning message for projection mismatch */}\r\n \r\n \r\n {t('project-settings.projection-mismatch')}\r\n \r\n \r\n \r\n {t('project-settings.projection-mismatch-description', {name: dataProjection.name})}\r\n \r\n\r\n \r\n {t('project-settings.imported-projection')}\r\n

\r\n \"{dataProjection.string}\"\r\n
\r\n\r\n \r\n {t('project-settings.existing-projection')}\r\n

\r\n \"{matchedProjection?.string}\"\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n\r\nexport const MainAppBar = memo((props: any) => {\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {t, i18n} = useTranslation();\r\n\r\n const {settingsDrawerState, setSettingsDrawerState,\r\n assetDrawerState, measurementsDialog, customURLDialog} = props;\r\n\r\n const { activeToolOpen } = useActiveTool();\r\n const { loggedIn } = useAuth();\r\n\r\n const handleDrawerOpen = () => {\r\n dispatch(changeDrawerOpen(true));\r\n };\r\n\r\n return (\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n\r\n {/** Language selector */}\r\n \r\n\r\n {/** Custom Links */}\r\n {isElectronApp && \r\n \r\n \r\n \r\n }\r\n\r\n {/** Measurements */}\r\n \r\n {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n measurementsDialog.handleOpen();\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n {/** Home Icon */}\r\n {isCloudSite && loggedIn && \r\n \r\n \r\n \r\n }\r\n\r\n {/** User profile */}\r\n {(isCloudSite || isElectronApp) && }\r\n\r\n {/** Project Settings */}\r\n \r\n {\r\n setSettingsDrawerState(true);\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n \r\n \r\n );\r\n});\r\n\r\nexport const MainAppFooter = memo((props: any) => {\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n\r\n const {settingsDrawerState} = props;\r\n\r\n const [mouseCoords, setMouseCoords] = useState(null);\r\n const [coordData, setCoordData] = useState({});\r\n const formatter = viewer?.getMeasurementFormatter();\r\n\r\n useEffect(() => {\r\n setCoordinates();\r\n }, [mouseCoords]);\r\n\r\n /** Mouse coordinate event listener */\r\n useEffect(() => {\r\n const callback = (event) => {\r\n const {coords} = event.detail;\r\n setMouseCoords(coords);\r\n };\r\n\r\n document.addEventListener(\"update-mouse-coords\", callback);\r\n\r\n return () => {\r\n document.removeEventListener(\"update-mouse-coords\", callback);\r\n };\r\n }, []);\r\n\r\n const setCoordinates = () => {\r\n if (!mouseCoords || !LocalScene.initialized) {\r\n setCoordData({});\r\n return;\r\n }\r\n\r\n const precision = formatter.getVectorPrecision(LocalScene.viewProjection);\r\n const coordinate = new SceneCoordinate(mouseCoords)\r\n .toViewProjection();\r\n\r\n const x = coordinate.x.toFixed(precision.x);\r\n const y = coordinate.y.toFixed(precision.y);\r\n const z = coordinate.z.toFixed(precision.z);\r\n\r\n setCoordData({x, y, z});\r\n };\r\n\r\n return (\r\n \r\n \r\n
\r\n {Object.keys(coordData).map((key) => (\r\n \r\n {`${key.toUpperCase()}:`} {coordData[key]}\r\n \r\n ))\r\n }\r\n
\r\n
\r\n
\r\n );\r\n});\r\n\r\nexport const updateMouseCoords = (coords: Vector3) => {\r\n sendCustomEvent(\"update-mouse-coords\", {coords});\r\n};","import { NearestFilter, TextureLoader } from 'three';\r\nimport classifications from '../textures/colormaps/classifications.png';\r\n\r\n// Load classification texture\r\nconst loader = new TextureLoader();\r\n\r\nexport const classificationTexture =\r\n loader.load(classifications, texture => {\r\n texture.minFilter = NearestFilter;\r\n texture.magFilter = NearestFilter;\r\n });\r\n","/* eslint-disable import/no-webpack-loader-syntax */\r\n\r\nimport edlFragmentShader from \"!!raw-loader!./edl.frag\";\r\nimport edlVertexShader from \"!!raw-loader!./edl.vert\";\r\nimport opacityFragmentShader from \"!!raw-loader!./opacity.frag\";\r\nimport opacityVertexShader from \"!!raw-loader!./opacity.vert\";\r\nimport pointCloudFragmentShader from \"!!raw-loader!./pointcloud.frag\";\r\nimport pointCloudVertexShader from \"!!raw-loader!./pointcloud.vert\";\r\nimport panoramicFragmentShader from \"!!raw-loader!./panoramic.frag\";\r\nimport panoramicVertexShader from \"!!raw-loader!./panoramic.vert\";\r\nimport planarFragmentShader from \"!!raw-loader!./planar.frag\";\r\nimport planarVertexShader from \"!!raw-loader!./planar.vert\";\r\nimport imageFragmentShader from \"!!raw-loader!./image.frag\";\r\nimport imageVertexShader from \"!!raw-loader!./image.vert\";\r\nimport markersFragmentShader from \"!!raw-loader!./markers.frag\";\r\nimport markersVertexShader from \"!!raw-loader!./markers.vert\";\r\nimport utilitiesVertexShader from \"!!raw-loader!./utilities.vert\";\r\nimport utilitiesFragmentShader from \"!!raw-loader!./utilities.frag\";\r\nimport gpuPickerFragmentShader from \"!!raw-loader!./gpu_picker.frag\";\r\nimport gpuPickerVertexShader from \"!!raw-loader!./gpu_picker.vert\";\r\nimport texturePackVertexShader from \"!!raw-loader!./texture_pack.vert\";\r\nimport tagsFragmentShader from \"!!raw-loader!./tags.frag\";\r\nimport tagsVertexShader from \"!!raw-loader!./tags.vert\";\r\nimport basicPickerFragmentShader from \"!!raw-loader!./picker_basic.frag\";\r\nimport basicPickerVertexShader from \"!!raw-loader!./picker_basic.vert\";\r\nimport spriteFragmentShader from \"!!raw-loader!./sprite.frag\";\r\nimport spriteVertexShader from \"!!raw-loader!./sprite.vert\";\r\n\r\nconst shaders = {\r\n pointcloud: {\r\n vert: pointCloudVertexShader,\r\n frag: pointCloudFragmentShader\r\n },\r\n panoramic: {\r\n vert: panoramicVertexShader,\r\n frag: panoramicFragmentShader\r\n },\r\n planar: {\r\n vert: planarVertexShader,\r\n frag: planarFragmentShader\r\n },\r\n edl: {\r\n vert: edlVertexShader,\r\n frag: edlFragmentShader\r\n },\r\n opacity: {\r\n vert: opacityVertexShader,\r\n frag: opacityFragmentShader\r\n },\r\n image: {\r\n vert: imageVertexShader,\r\n frag: imageFragmentShader\r\n },\r\n markers: {\r\n vert: markersVertexShader,\r\n frag: markersFragmentShader\r\n },\r\n utilities: {\r\n vert: utilitiesVertexShader,\r\n frag: utilitiesFragmentShader\r\n },\r\n basic_picker: {\r\n vert: basicPickerVertexShader,\r\n frag: basicPickerFragmentShader\r\n },\r\n gpu_picker: {\r\n vert: gpuPickerVertexShader,\r\n frag: gpuPickerFragmentShader\r\n },\r\n texture_packer: {\r\n vert: texturePackVertexShader\r\n },\r\n tags: {\r\n vert: tagsVertexShader,\r\n frag: tagsFragmentShader\r\n },\r\n sprite: {\r\n vert: spriteVertexShader,\r\n frag: spriteFragmentShader\r\n }\r\n};\r\n\r\nexport default shaders;","export default \"\\r\\n#define DISTANCE_FROM_PLANE 0.5\\r\\n\\r\\nattribute float intensity;\\r\\nattribute float classification;\\r\\nattribute vec3 rgb;\\r\\n\\r\\nuniform bool gpuPicker;\\r\\nuniform float pratio;\\r\\nuniform float size;\\r\\nuniform float alpha;\\r\\nuniform float distance;\\r\\nuniform vec3 currentCameraTarget;\\r\\nuniform float screenHeight;\\r\\nuniform float fov;\\r\\nuniform float minSize;\\r\\nuniform float maxSize;\\r\\nuniform float octreeSize;\\r\\nuniform vec3 octreeCorner;\\r\\nuniform float octreeSpacing;\\r\\n\\r\\nuniform sampler2D colorMap;\\r\\nuniform float colorType;\\r\\nuniform bool adaptiveSize;\\r\\nuniform bool isOctreeCloud;\\r\\nuniform bool isPotreeCloud;\\r\\nuniform vec2 heightRange;\\r\\nuniform vec2 heightClamp;\\r\\nuniform vec2 intensityRange;\\r\\nuniform vec2 intensityClamp;\\r\\nuniform float rgbMax;\\r\\n\\r\\nuniform float crossSectionWidth;\\r\\nuniform vec3 crossSectionStart;\\r\\nuniform vec3 crossSectionEnd;\\r\\n\\r\\nuniform sampler2D clipPolygonData;\\r\\n\\r\\nuniform sampler2D visibleNodes;\\r\\nuniform sampler2D classificationData;\\r\\nuniform sampler2D classificationVisible;\\r\\nuniform sampler2D areaTriangleData;\\r\\n\\r\\nflat varying vec3 vColor;\\r\\nflat varying float vHidden;\\r\\n\\r\\nvec3 pointOnPlane(vec3 origin, vec3 point, vec3 normal) {\\r\\n return point - dot(point - origin, normal) * normal;\\r\\n}\\r\\n\\r\\nfloat distanceFromPlane(vec3 origin, vec3 point, vec3 normal) {\\r\\n return abs(dot(origin - point, normal));\\r\\n}\\r\\n\\r\\nbool classificationIsHidden(float classification) {\\r\\n float x = (classification + 0.1) / float(NUMBER_OF_CLASSIFICATIONS);\\r\\n vec4 value = texture2D(classificationVisible, vec2(x, 0.5));\\r\\n return value.a < 0.5;\\r\\n}\\r\\n\\r\\nvec3 classificationColor(float classification) {\\r\\n float x = (classification + 0.1) / float(NUMBER_OF_CLASSIFICATIONS);\\r\\n vec4 value = texture2D(classificationData, vec2(x, 0.5));\\r\\n return value.rgb;\\r\\n}\\r\\n\\r\\nfloat clampedValue(float data, vec2 dataRange, vec2 dataClamp) {\\r\\n float scaled = (data - dataRange.x) / (dataRange.y - dataRange.x);\\r\\n float clamped = (scaled - dataClamp.x) / (dataClamp.y - dataClamp.x);\\r\\n return clamped;\\r\\n}\\r\\n\\r\\nvec3 calculateOppositeColor(float colorType, vec3 colorValue){\\r\\n vec3 result;\\r\\n vec3 opp = vec3(1.0, 1.0, 1.0);\\r\\n opp = opp - colorValue;\\r\\n\\r\\n bool isIntensity = compareFloat(colorType, 0.0);\\r\\n bool isRGB = compareFloat(colorType, 1.0);\\r\\n bool isHeight = compareFloat(colorType, 2.0);\\r\\n bool isClassification = compareFloat(colorType, 3.0);\\r\\n\\r\\n if (isHeight) {\\r\\n result = opp;\\r\\n } else if (isIntensity) {\\r\\n result = vec3(1.0, 0.0, 0.0);\\r\\n } else if (isClassification) {\\r\\n result = vec3(1.0, 0.0, 0.0);\\r\\n } else if (isRGB) {\\r\\n result = vec3(1.0, 0.0, 0.0);\\r\\n } else {\\r\\n result = opp;\\r\\n }\\r\\n\\r\\n return result;\\r\\n}\\r\\n\\r\\nvec3 getCloudColor(float colorType, vec3 posWorld) {\\r\\n // Default color for invalid color types\\r\\n vec3 color = vec3(0.0, 0.0, 0.0);\\r\\n\\r\\n bool isIntensity = compareFloat(colorType, 0.0);\\r\\n bool isRGB = compareFloat(colorType, 1.0);\\r\\n bool isHeight = compareFloat(colorType, 2.0);\\r\\n bool isClassification = compareFloat(colorType, 3.0);\\r\\n\\r\\n if (isRGB) {\\r\\n // Color by RGB values\\r\\n color = rgb / rgbMax;\\r\\n } else if (isIntensity) {\\r\\n // Intensity colors with clamping\\r\\n float cloudIntensity = clampedValue(intensity, intensityRange, intensityClamp);\\r\\n color = texture2D(colorMap, vec2(cloudIntensity, 0.5)).rgb;\\r\\n } else if (isHeight) {\\r\\n // Height based coloring with clamping\\r\\n float cloudHeight = clampedValue(posWorld.z, heightRange, heightClamp);\\r\\n color = texture2D(colorMap, vec2(cloudHeight, 0.5)).rgb;\\r\\n } else if (isClassification) {\\r\\n color = classificationColor(classification);\\r\\n }\\r\\n\\r\\n return color;\\r\\n}\\r\\n\\r\\nint roundFloat(float number){\\r\\n\\treturn int(floor(number + 0.5));\\r\\n}\\r\\n\\r\\nbool isBitSet(int number, int index){\\r\\n int powi = roundFloat(pow(2.0, float(index)));\\r\\n\\tint ndp = number / powi;\\r\\n float remainder = mod(float(ndp), 2.0);\\r\\n\\treturn !compareFloat(remainder, 0.0);\\r\\n}\\r\\n\\r\\nint numberOfOnes(int number, int index){\\r\\n\\tint numOnes = 0;\\r\\n\\tint tmp = 128;\\r\\n\\tfor(int i = 7; i >= 0; i--){\\r\\n\\t\\tif(number >= tmp){\\r\\n\\t\\t\\tnumber = number - tmp;\\r\\n\\t\\t\\tif(i <= index){\\r\\n\\t\\t\\t\\tnumOnes++;\\r\\n\\t\\t\\t}\\r\\n\\t\\t}\\r\\n\\t\\ttmp = tmp / 2;\\r\\n\\t}\\r\\n\\treturn numOnes;\\r\\n}\\r\\n\\r\\nint getChildIndexPotree(vec3 index3d) {\\r\\n return roundFloat((4.0 * index3d.x) + (2.0 * index3d.y) + index3d.z);\\r\\n}\\r\\n\\r\\nint getChildIndexEncompass(vec3 index3d) {\\r\\n return roundFloat(index3d.x + (2.0 * index3d.y) + (4.0 * index3d.z));\\r\\n}\\r\\n\\r\\nfloat getLocalTreeDepth(vec3 positionOctree){\\r\\n int iOffset = 0;\\r\\n\\tfloat depth = 0.0;\\r\\n vec3 offset = vec3(0.0, 0.0, 0.0);\\r\\n\\r\\n\\tfor(float i = 0.0; i <= 30.0; i++) {\\r\\n\\t\\tfloat nodeSizeAtLevel = octreeSize / pow(2.0, i);\\r\\n\\r\\n vec3 index3d = (positionOctree - offset) / nodeSizeAtLevel;\\r\\n\\t\\tindex3d = floor(index3d + 0.5);\\r\\n int index = isPotreeCloud\\r\\n ? getChildIndexPotree(index3d)\\r\\n : getChildIndexEncompass(index3d);\\r\\n\\r\\n float x = float(iOffset) / float(VISIBLE_NODES_WIDTH);\\r\\n\\t\\tvec4 value = texture2D(visibleNodes, vec2(x, 0.0));\\r\\n int mask = int(round(value.r * 255.0));\\r\\n bool childExists = isBitSet(mask, index);\\r\\n\\r\\n if(childExists){\\r\\n\\t\\t\\t// There are more visible child nodes at this position\\r\\n\\t\\t\\tint advanceG = int(round(value.g * 255.0)) * 256;\\r\\n\\t\\t\\tint advanceB = int(round(value.b * 255.0));\\r\\n\\t\\t\\tint advanceChild = numberOfOnes(mask, index - 1);\\r\\n\\t\\t\\tint advance = advanceG + advanceB + advanceChild;\\r\\n\\t\\t\\tiOffset = iOffset + advance;\\r\\n\\t\\t\\tdepth++;\\r\\n\\t\\t} else {\\r\\n\\t\\t\\t// No more visible child nodes at this position\\r\\n\\t\\t\\tfloat lodOffset = (255.0 * value.a) / 10.0 - 10.0;\\r\\n\\t\\t\\treturn depth + lodOffset;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\toffset = offset + (vec3(1.0, 1.0, 1.0) * nodeSizeAtLevel * 0.5) * index3d;\\r\\n\\t}\\r\\n\\r\\n\\treturn depth;\\r\\n}\\r\\n\\r\\nfloat getPointSizeAttenuation(vec3 posWorld) {\\r\\n vec3 positionOctree = posWorld - octreeCorner;\\r\\n\\treturn pow(2.0, getLocalTreeDepth(positionOctree));\\r\\n}\\r\\n\\r\\nfloat getClipBoxData(int xIndex, int yIndex) {\\r\\n return unpackTextureData(\\r\\n clipPolygonData,\\r\\n xIndex,\\r\\n yIndex,\\r\\n CLIP_TEXTURE_WIDTH,\\r\\n CLIP_TEXTURE_HEIGHT\\r\\n );\\r\\n}\\r\\n\\r\\nfloat getAreaTriangleData(int xIndex, int yIndex) {\\r\\n return unpackTextureData(\\r\\n areaTriangleData,\\r\\n xIndex,\\r\\n yIndex,\\r\\n AREA_TEXTURE_WIDTH,\\r\\n AREA_TEXTURE_HEIGHT\\r\\n );\\r\\n}\\r\\n\\r\\n// Point in 2d triangle: https://stackoverflow.com/a/2049593\\r\\nfloat triangleSign(vec3 p1, vec3 p2, vec3 p3) {\\r\\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\\r\\n}\\r\\n\\r\\n// Point in 2d triangle: https://stackoverflow.com/a/2049593\\r\\nbool pointInTriangle(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {\\r\\n float d1 = triangleSign(p4, p1, p2);\\r\\n float d2 = triangleSign(p4, p2, p3);\\r\\n float d3 = triangleSign(p4, p3, p1);\\r\\n\\r\\n bool isNegative = (d1 < 0.0) || (d2 < 0.0) || (d3 < 0.0);\\r\\n bool isPositive = (d1 > 0.0) || (d2 > 0.0) || (d3 > 0.0);\\r\\n bool insideTriangle = !(isNegative && isPositive);\\r\\n\\r\\n return insideTriangle;\\r\\n}\\r\\n\\r\\nvec2 checkPointInArea(vec3 point) {\\r\\n // return vec2(\\r\\n // float insidePolygon,\\r\\n // float volumeEnabled\\r\\n // )\\r\\n\\r\\n #if defined NUM_AREA_TRIANGLES\\r\\n for (int i=0; i 0.5;\\r\\n bool volumeCalculated = compareFloat(volumeStatus, 2.0);\\r\\n\\r\\n // vertex #1\\r\\n vec3 v1 = vec3(\\r\\n getAreaTriangleData(i, 1),\\r\\n getAreaTriangleData(i, 2),\\r\\n getAreaTriangleData(i, 3)\\r\\n );\\r\\n\\r\\n // vertex #2\\r\\n vec3 v2 = vec3(\\r\\n getAreaTriangleData(i, 4),\\r\\n getAreaTriangleData(i, 5),\\r\\n getAreaTriangleData(i, 6)\\r\\n );\\r\\n\\r\\n // vertex #3\\r\\n vec3 v3 = vec3(\\r\\n getAreaTriangleData(i, 7),\\r\\n getAreaTriangleData(i, 8),\\r\\n getAreaTriangleData(i, 9)\\r\\n );\\r\\n\\r\\n vec3 N = cross(v2 - v1, v3 - v1);\\r\\n N = N / length(N);\\r\\n\\r\\n vec3 v1p = v1;\\r\\n vec3 v2p = v2;\\r\\n vec3 v3p = v3;\\r\\n vec3 pointP = point;\\r\\n\\r\\n if (isVolumeType == false) {\\r\\n // Check distance from plane\\r\\n float pointHeight = distanceFromPlane(v1, point, N);\\r\\n if (pointHeight > DISTANCE_FROM_PLANE) {\\r\\n continue;\\r\\n }\\r\\n\\r\\n // Project point to plane\\r\\n v1p = pointOnPlane(v1, v1, N);\\r\\n v2p = pointOnPlane(v1, v2, N);\\r\\n v3p = pointOnPlane(v1, v3, N);\\r\\n pointP = pointOnPlane(v1, point, N);\\r\\n }\\r\\n\\r\\n bool insideTriangle = pointInTriangle(v1p, v2p, v3p, pointP);\\r\\n if (insideTriangle == false) {\\r\\n continue;\\r\\n }\\r\\n\\r\\n if (volumeCalculated) {\\r\\n return vec2(1.0, 1.0);\\r\\n } else {\\r\\n return vec2(1.0, 0.0);\\r\\n }\\r\\n }\\r\\n #endif\\r\\n\\r\\n return vec2(0.0, 0.0);\\r\\n}\\r\\n\\r\\nvec4 checkPointInBox(vec3 point, float classification) {\\r\\n bool insideBox = false;\\r\\n bool newVisibility = true;\\r\\n bool reclassifyPoints = false;\\r\\n float finalClassification = -1.0;\\r\\n\\r\\n #if defined NUM_CLIP_BOXES\\r\\n for (int i=0; i 0.0);\\r\\n}\\r\\n\\r\\nbool pointInCrossSection(vec3 point) {\\r\\n vec3 p1 = crossSectionStart;\\r\\n vec3 p2 = crossSectionEnd;\\r\\n vec3 p3 = point;\\r\\n\\r\\n // force everything to 2d\\r\\n p1.z = 0.0;\\r\\n p2.z = 0.0;\\r\\n p3.z = 0.0;\\r\\n\\r\\n float lineLength = length(p1 - p2);\\r\\n if (compareFloat(lineLength, 0.0)) {\\r\\n return false;\\r\\n }\\r\\n\\r\\n // calculate distance from line\\r\\n float p1p3x = p1.x - p3.x;\\r\\n float p1p3y = p1.y - p3.y;\\r\\n float p2p1x = p2.x - p1.x;\\r\\n float p2p1y = p2.y - p1.y;\\r\\n float dAcrossAxis = abs(p2p1x*p1p3y - p1p3x*p2p1y) / lineLength;\\r\\n\\r\\n // calculate signed distance along line\\r\\n float dHypotenuse = length(p1 - p3);\\r\\n float dAlongAxis = sqrt(dHypotenuse*dHypotenuse - dAcrossAxis*dAcrossAxis);\\r\\n bool infront = isInFront(p1, p2, p3);\\r\\n if (infront == false) {\\r\\n dAlongAxis = -1.0 * dAlongAxis;\\r\\n }\\r\\n\\r\\n return (dAlongAxis >= 0.0)\\r\\n && (dAlongAxis <= lineLength)\\r\\n && (dAcrossAxis < (crossSectionWidth/2.0));\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n // Update colors for GPU picker\\r\\n updateGPUPickerColors();\\r\\n bool isHidden = false;\\r\\n\\r\\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\\r\\n vec3 viewPosition = -mvPosition.xyz;\\r\\n gl_Position = projectionMatrix * mvPosition;\\r\\n\\r\\n // Position in viewer coordinates (including offset)\\r\\n\\tvec3 posWorld = (modelMatrix * vec4( position, 1.0 )).xyz;\\r\\n\\r\\n // Hide based on distance (2D)\\r\\n float distance2D = getDistance2D(posWorld, currentCameraTarget);\\r\\n if (distance2D > distance) {\\r\\n isHidden = true;\\r\\n }\\r\\n\\r\\n // Check if classification is hidden\\r\\n if (classificationIsHidden(classification)) {\\r\\n isHidden = true;\\r\\n }\\r\\n\\r\\n // ---------------------\\r\\n\\t// POINT SIZE\\r\\n\\t// ---------------------\\r\\n float pointSize = 1.0;\\r\\n float projFactor = getProjFactor(fov, screenHeight, viewPosition.z);\\r\\n float r = octreeSpacing * sqrt(3.0);\\r\\n\\r\\n if (isOctreeCloud && adaptiveSize) {\\r\\n // Adaptive point sizing\\r\\n float pointAttenuation = getPointSizeAttenuation(posWorld);\\r\\n float worldSpaceSize = size * (r / pointAttenuation);\\r\\n pointSize = 1.0 * worldSpaceSize * projFactor;\\r\\n } else {\\r\\n // Attenuated point size\\r\\n pointSize = 0.15 * size * projFactor;\\r\\n }\\r\\n\\r\\n pointSize = max(minSize, pointSize);\\r\\n pointSize = min(maxSize, pointSize);\\r\\n\\r\\n // ---------------------\\r\\n\\t// POINT COLOR\\r\\n\\t// ---------------------\\r\\n vColor = getCloudColor(colorType, posWorld);\\r\\n\\r\\n // ---------------------\\r\\n // CROSS SECTION\\r\\n // ---------------------\\r\\n bool inCrossSection = pointInCrossSection(posWorld.xyz);\\r\\n\\r\\n // ---------------------\\r\\n // MEASUREMENT AREA/VOLUME\\r\\n // ---------------------\\r\\n vec2 areaReturnValue = checkPointInArea(posWorld.xyz);\\r\\n bool insidePolygon = floatToBool(areaReturnValue.x);\\r\\n bool volumeEnabled = floatToBool(areaReturnValue.y);\\r\\n\\r\\n // ---------------------\\r\\n // CLIPPING BOXES\\r\\n // ---------------------\\r\\n vec4 clipReturnValue = checkPointInBox(posWorld.xyz, classification);\\r\\n bool insideClip = floatToBool(clipReturnValue.x);\\r\\n bool clipVisible = floatToBool(clipReturnValue.y);\\r\\n bool reclassify = floatToBool(clipReturnValue.z);\\r\\n float newClassification = clipReturnValue.w;\\r\\n\\r\\n if (inCrossSection || insidePolygon || insideClip) {\\r\\n vColor = calculateOppositeColor(colorType, vColor);\\r\\n }\\r\\n\\r\\n // Delete points\\r\\n if (!clipVisible) {\\r\\n isHidden = true;\\r\\n }\\r\\n\\r\\n // Reclassify points\\r\\n if (insideClip && reclassify) {\\r\\n vColor = classificationColor(newClassification);\\r\\n }\\r\\n\\r\\n // Reduce point size if volume is calculated\\r\\n if (volumeEnabled) {\\r\\n pointSize = pointSize * 0.5;\\r\\n }\\r\\n\\r\\n if (gpuPicker) {\\r\\n // gpu picker points are 10% larger than normal\\r\\n pointSize = pointSize * 1.10;\\r\\n }\\r\\n\\r\\n // Set OpenGL parameters\\r\\n vHidden = boolToFloat(isHidden);\\r\\n gl_PointSize = pointSize;\\r\\n}\";","export default \"#define PRECISION 0.0001\\r\\n\\r\\nuniform bool gpuPicker;\\r\\nuniform bool circularPoints;\\r\\n\\r\\nflat varying vec3 vColor;\\r\\nflat varying float vHidden;\\r\\n\\r\\nvoid main(void) {\\r\\n bool hidden = floatToBool(vHidden);\\r\\n if (hidden) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n // Circular points\\r\\n if (circularPoints) {\\r\\n float u = 2.0 * gl_PointCoord.x - 1.0;\\r\\n float v = 2.0 * gl_PointCoord.y - 1.0;\\r\\n float cc = u*u + v*v;\\r\\n if(cc > 1.0){\\r\\n discard;\\r\\n }\\r\\n }\\r\\n\\r\\n vec4 final;\\r\\n if (gpuPicker) {\\r\\n final = vGPUColor;\\r\\n } else {\\r\\n final = vec4(vColor, 1.0);\\r\\n }\\r\\n\\r\\n gl_FragColor = final;\\r\\n}\";","export default \"varying vec3 vPosition;\\r\\n\\r\\nvoid main() {\\r\\n vPosition = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\r\\n}\\r\\n\";","export default \"#define RECIPROCAL_PI 0.3183098861837907\\r\\n#define RECIPROCAL_PI2 0.15915494309189535\\r\\n\\r\\nuniform sampler2D tImage;\\r\\nvarying vec3 vPosition;\\r\\n\\r\\nvec2 equirectUv( in vec3 dir ) {\\r\\n\\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\\r\\n\\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\\r\\n\\treturn vec2( u, v );\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 direction = vec3(vPosition.x, vPosition.z, -vPosition.y);\\r\\n direction = normalize(direction);\\r\\n\\r\\n vec2 sampleUV = equirectUv( direction );\\r\\n gl_FragColor = texture2D( tImage, sampleUV );\\r\\n}\\r\\n\";","export default \"varying vec3 vPosition;\\r\\n\\r\\nvoid main() {\\r\\n vPosition = position;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\r\\n}\\r\\n\";","export default \"uniform sampler2D tImage;\\r\\nuniform float imageHeight;\\r\\nuniform float imageWidth;\\r\\nuniform float fx;\\r\\nuniform float fy;\\r\\nuniform float cx;\\r\\nuniform float cy;\\r\\n\\r\\nvarying vec3 vPosition;\\r\\n\\r\\nvoid main() {\\r\\n vec3 direction = normalize(vPosition);\\r\\n\\r\\n float dist = -direction.z;\\r\\n if (dist <= 0.0) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n vec3 vec = direction / dist;\\r\\n\\r\\n float u = ((vec.x * fx) + cx) / imageWidth;\\r\\n if ((u < 0.0) || (u >= 1.0)) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n float v = ((-vec.y * fy) + cy) / imageHeight;\\r\\n if ((v <= 0.0) || (v > 1.0)) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n gl_FragColor = texture2D(tImage, vec2(u, 1.0 - v));\\r\\n}\\r\\n\";","export default \"varying vec2 vUv;\\r\\nvoid main() {\\r\\n\\tvUv = uv;\\r\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\r\\n}\\r\\n\";","export default \"#include \\r\\n#define PRECISION 0.0001\\r\\n\\r\\nuniform sampler2D colorMap;\\r\\nuniform sampler2D tDepth;\\r\\n\\r\\nuniform float opacity;\\r\\nuniform float screenWidth;\\r\\nuniform float screenHeight;\\r\\nuniform float near;\\r\\nuniform float far;\\r\\nuniform vec2 neighbours[NEIGHBOUR_COUNT];\\r\\nuniform vec3 lightDir;\\r\\nuniform float edlStrength;\\r\\nuniform float radius;\\r\\n\\r\\nvarying vec2 vUv;\\r\\n\\r\\nfloat linearDepth(sampler2D depthSampler, vec2 coord) {\\r\\n float z_b = texture2D(depthSampler, coord).x;\\r\\n float z_n = 2.0 * z_b - 1.0;\\r\\n float z_e = 2.0 * near * far / (far + near - z_n * (far - near));\\r\\n return z_e;\\r\\n}\\r\\n\\r\\nfloat readDepth(sampler2D depthSampler, vec2 coord) {\\r\\n float depth = log2(linearDepth(depthSampler, coord));\\r\\n return (depth == 1.0) ? 0.0 : depth;\\r\\n}\\r\\n\\r\\nfloat response(float depth){\\r\\n\\tvec2 uvRadius = radius / vec2(screenWidth, screenHeight);\\r\\n\\r\\n\\tfloat sum = 0.0;\\r\\n\\tfor(int i = 0; i < NEIGHBOUR_COUNT; i++){\\r\\n\\t\\tvec2 uvNeighbor = vUv + uvRadius * neighbours[i];\\r\\n\\t\\tfloat neighbourDepth = readDepth(tDepth, uvNeighbor);\\r\\n\\r\\n\\t\\tif(neighbourDepth != 0.0){\\r\\n if (depth == 0.0) {\\r\\n sum += 100.0;\\r\\n } else{\\r\\n sum += max(0.0, depth - neighbourDepth);\\r\\n }\\r\\n\\t\\t}\\r\\n\\t}\\r\\n\\r\\n\\treturn sum / float(NEIGHBOUR_COUNT);\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = texture2D(colorMap, vUv);\\r\\n float alpha = color.a * opacity;\\r\\n\\r\\n float depth = readDepth(tDepth, vUv);\\r\\n float res = response(depth);\\r\\n\\tfloat shade = exp(-res * 10.0 * edlStrength);\\r\\n\\r\\n if (color.a <= PRECISION) {\\r\\n if (res <= PRECISION) discard;\\r\\n alpha = opacity;\\r\\n }\\r\\n\\r\\n gl_FragColor = vec4(color.rgb*shade, alpha);\\r\\n\\r\\n}\\r\\n\";","export default \"varying vec2 vUv;\\r\\n\\r\\nvoid main() {\\r\\n\\tvUv = uv;\\r\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\r\\n}\\r\\n\";","export default \"uniform sampler2D colorMap;\\r\\nuniform float opacity;\\r\\n\\r\\nvarying vec2 vUv;\\r\\n\\r\\nvoid main() {\\r\\n vec4 color = texture2D( colorMap, vUv );\\r\\n float alpha = color.a * opacity;\\r\\n gl_FragColor = vec4(color.rgb, alpha);\\r\\n}\\r\\n\";","export default \"varying vec2 vUv;\\r\\nvoid main() {\\r\\n\\tvUv = uv;\\r\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\r\\n}\\r\\n\";","export default \"uniform sampler2D colorMap;\\r\\nuniform float brightness;\\r\\nuniform float contrast;\\r\\n\\r\\nvarying vec2 vUv;\\r\\n\\r\\nvoid main() {\\r\\n\\r\\n\\tgl_FragColor = texture2D( colorMap, vUv );\\r\\n\\r\\n\\tgl_FragColor.rgb += brightness;\\r\\n\\r\\n\\tif (contrast > 0.0) {\\r\\n\\t\\tgl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;\\r\\n\\t}\\r\\n\\telse {\\r\\n\\t\\tgl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;\\r\\n\\t}\\r\\n\\r\\n}\\r\\n\";","export default \"#define MIN_CAMERA_DIST 0.5\\r\\n\\r\\nattribute float selected;\\r\\nattribute int camera_index;\\r\\nattribute float visible;\\r\\nattribute float marker_shape;\\r\\n\\r\\nuniform float scale;\\r\\nuniform vec3 currentCameraRotation;\\r\\nuniform vec3 currentCameraPosition;\\r\\nuniform bool orbitMode;\\r\\nuniform bool initialCameraLoading;\\r\\nuniform float windowHeight;\\r\\nuniform int currentIndex;\\r\\nuniform float fov;\\r\\n\\r\\nvarying vec2 vUv;\\r\\nvarying float vSelected;\\r\\nvarying float vHidden;\\r\\nvarying float vVisible;\\r\\nvarying float vMarkerShape;\\r\\n\\r\\nvoid main() {\\r\\n // Update colors for GPU picker\\r\\n updateGPUPickerColors();\\r\\n\\r\\n vUv = uv;\\r\\n vSelected = selected;\\r\\n vVisible = visible;\\r\\n vMarkerShape = marker_shape;\\r\\n\\r\\n float hidden = 0.0;\\r\\n\\r\\n bool isSelected = compareFloat(vSelected, 1.0);\\r\\n float selectedScale = 0.9;\\r\\n if (isSelected) {\\r\\n selectedScale = 1.0;\\r\\n }\\r\\n\\r\\n float x = position.x - (uv.x-0.5);\\r\\n float y = position.y - (uv.y-0.5);\\r\\n float z = position.z;\\r\\n vec3 offset = vec3(x,y,z);\\r\\n\\r\\n float distance3D = getDistance3D(offset, currentCameraPosition);\\r\\n float height = abs(offset.z - currentCameraPosition.z);\\r\\n\\r\\n float projFactor = getProjFactor(fov, windowHeight, height);\\r\\n float markerSize = 30.0 / projFactor;\\r\\n\\r\\n markerSize = clamp(markerSize, 1.0, 10.0);\\r\\n markerSize *= scale;\\r\\n\\r\\n if (initialCameraLoading) {\\r\\n hidden = 1.0;\\r\\n }\\r\\n\\r\\n // Hide marker based on distance\\r\\n if (distance3D < MIN_CAMERA_DIST) {\\r\\n hidden = 1.0;\\r\\n }\\r\\n\\r\\n // Hide the current camera if we arent in orbit mode\\r\\n bool currentCamera = currentIndex == camera_index;\\r\\n if ((orbitMode == false) && currentCamera) {\\r\\n hidden = 1.0;\\r\\n }\\r\\n\\r\\n // Move position to center of marker\\r\\n vec3 pos_offset = position - offset;\\r\\n\\r\\n // Rotate using camera rotation\\r\\n mat3 rot = eulerMatrix(currentCameraRotation);\\r\\n vec3 pos_rotated = pos_offset * rot;\\r\\n\\r\\n // Apply scaling based on selected or not\\r\\n mat3 scale_matrix = scaleMatrix(markerSize * selectedScale);\\r\\n vec3 pos_scaled = pos_rotated * scale_matrix;\\r\\n\\r\\n // Add back our offset values\\r\\n vec3 pos_real = pos_scaled + offset;\\r\\n\\r\\n // Apply final position\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos_real, 1.0);\\r\\n\\r\\n // We hide the marker for various reasons\\r\\n vHidden = hidden;\\r\\n}\\r\\n\";","export default \"uniform bool gpuPicker;\\r\\n\\r\\nvarying vec2 vUv;\\r\\nvarying float vSelected;\\r\\nvarying float vHidden;\\r\\nvarying float vVisible;\\r\\nvarying float vMarkerShape;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n vec2 uv = vUv;\\r\\n uv = 2.0 * uv - 1.0;\\r\\n\\r\\n bool isHidden = compareFloat(vHidden, 1.0);\\r\\n bool isSelected = compareFloat(vSelected, 1.0);\\r\\n bool isVisible = compareFloat(vVisible, 1.0);\\r\\n bool isCircle = compareFloat(vMarkerShape, 0.0);\\r\\n bool isSquare = compareFloat(vMarkerShape, 1.0);\\r\\n\\r\\n if (isHidden) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n if (!isVisible) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n // All markers are gray-ish\\r\\n vec4 colorStandard = vec4(255, 255, 255, 255) / 255.0;\\r\\n vec4 colorSelected = vec4(255, 195, 0, 255) / 255.0;\\r\\n float border_thickness = 0.1;\\r\\n\\r\\n vec4 final;\\r\\n if (gpuPicker) {\\r\\n final = vGPUColor;\\r\\n } else {\\r\\n if (isSelected) {\\r\\n final = colorSelected;\\r\\n }\\r\\n else {\\r\\n final = colorStandard;\\r\\n }\\r\\n }\\r\\n\\r\\n // Circular markers\\r\\n if (isCircle) {\\r\\n // Circle shape\\r\\n float circle = sqrt(uv.x * uv.x + uv.y * uv.y);\\r\\n float circle_bounds = 1.0;\\r\\n if (circle > circle_bounds){\\r\\n discard;\\r\\n }\\r\\n\\r\\n if (!gpuPicker) {\\r\\n // Black outline\\r\\n float edge = circle_bounds - border_thickness;\\r\\n if ((circle <= circle_bounds) && (circle > edge)){\\r\\n final.rgb = vec3(0.0, 0.0, 0.0);\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n // Square with rounded corners\\r\\n if (isSquare) {\\r\\n float circle = sqrt(uv.x * uv.x + uv.y * uv.y);\\r\\n float circle_bounds = sqrt(2.0) * 0.95;\\r\\n if (circle > circle_bounds){\\r\\n discard;\\r\\n }\\r\\n\\r\\n if (!gpuPicker) {\\r\\n // Black outline\\r\\n float edge1 = circle_bounds - border_thickness;\\r\\n float edge2 = 1.0 - border_thickness;\\r\\n if ((circle > edge1) || (abs(uv.x) > edge2) || (abs(uv.y) > edge2)) {\\r\\n final.rgb = vec3(0.0, 0.0, 0.0);\\r\\n }\\r\\n }\\r\\n }\\r\\n\\r\\n if (!gpuPicker) {\\r\\n if (final.a < PRECISION) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n final.a = 1.0;\\r\\n }\\r\\n\\r\\n gl_FragColor = final;\\r\\n}\\r\\n\";","export default \"#define PRECISION 0.0001\\r\\n\\r\\nfloat getProjFactor(float fov, float screenHeight, float distance) {\\r\\n float projFactor = 1.0 / tan(fov / 2.0);\\r\\n projFactor /= distance;\\r\\n projFactor *= screenHeight / 2.0;\\r\\n return projFactor;\\r\\n}\\r\\n\\r\\nbool compareFloat(float floatOne, float floatTwo) {\\r\\n return abs(floatOne - floatTwo) < PRECISION;\\r\\n}\\r\\n\\r\\nbool floatToBool(float value) {\\r\\n return value > 0.5;\\r\\n}\\r\\n\\r\\nfloat boolToFloat(bool value) {\\r\\n if (value) {\\r\\n return 1.0;\\r\\n } else {\\r\\n return 0.0;\\r\\n }\\r\\n}\\r\\n\\r\\nmat3 rotateX(float theta) {\\r\\n float c = cos(theta);\\r\\n float s = sin(theta);\\r\\n return mat3(\\r\\n vec3(1, 0, 0),\\r\\n vec3(0, c, -s),\\r\\n vec3(0, s, c)\\r\\n );\\r\\n}\\r\\n\\r\\nmat3 rotateY(float theta) {\\r\\n float c = cos(theta);\\r\\n float s = sin(theta);\\r\\n return mat3(\\r\\n vec3(c, 0, s),\\r\\n vec3(0, 1, 0),\\r\\n vec3(-s, 0, c)\\r\\n );\\r\\n}\\r\\n\\r\\nmat3 rotateZ(float theta) {\\r\\n float c = cos(theta);\\r\\n float s = sin(theta);\\r\\n return mat3(\\r\\n vec3(c, -s, 0),\\r\\n vec3(s, c, 0),\\r\\n vec3(0, 0, 1)\\r\\n );\\r\\n}\\r\\n\\r\\nmat3 eulerMatrix(vec3 rotation) {\\r\\n mat3 rotX = rotateX(rotation.x);\\r\\n mat3 rotY = rotateY(rotation.y);\\r\\n mat3 rotZ = rotateZ(rotation.z);\\r\\n\\r\\n return rotZ * rotY * rotX;\\r\\n}\\r\\n\\r\\nmat3 scaleMatrix(float scale) {\\r\\n return mat3(\\r\\n vec3(scale, 0.0, 0.0),\\r\\n vec3(0.0, scale, 0.0),\\r\\n vec3(0.0, 0.0, scale)\\r\\n );\\r\\n}\\r\\n\\r\\nfloat getDistance2D(vec3 offset, vec3 camera) {\\r\\n float dX = offset.x - camera.x;\\r\\n float dY = offset.y - camera.y;\\r\\n return sqrt(dX*dX + dY*dY);\\r\\n}\\r\\n\\r\\nfloat getDistance3D(vec3 offset, vec3 camera) {\\r\\n float dX = offset.x - camera.x;\\r\\n float dY = offset.y - camera.y;\\r\\n float dZ = offset.z - camera.z;\\r\\n return sqrt(dX*dX + dY*dY + dZ*dZ);\\r\\n}\";","export default \"#define PRECISION 0.0001\\r\\n#define ALPHA_PRECISION 0.5\\r\\n\\r\\nbool compareFloat(float floatOne, float floatTwo) {\\r\\n return abs(floatOne - floatTwo) < PRECISION;\\r\\n}\\r\\n\\r\\nbool floatToBool(float value) {\\r\\n return value > 0.5;\\r\\n}\\r\\n\\r\\nfloat boolToFloat(bool value) {\\r\\n if (value) {\\r\\n return 1.0;\\r\\n } else {\\r\\n return 0.0;\\r\\n }\\r\\n}\\r\\n\";","export default \"void main() {\\r\\n updateGPUPickerColors();\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\r\\n}\\r\\n\";","export default \"void main() {\\r\\n gl_FragColor = vGPUColor;\\r\\n}\\r\\n\";","export default \"#define COLOR_PRECISION 0.05\\r\\n\\r\\nattribute int gpu_index;\\r\\n\\r\\nflat varying vec4 vGPUColor;\\r\\n\\r\\nvoid updateGPUPickerColors() {\\r\\n vec4 encoded_index = vec4(\\r\\n float(gpu_index >> 24 & 255),\\r\\n float(gpu_index >> 16 & 255),\\r\\n float(gpu_index >> 8 & 255),\\r\\n float(gpu_index & 255)\\r\\n );\\r\\n\\r\\n vGPUColor = (encoded_index + COLOR_PRECISION) / 255.0;\\r\\n}\\r\\n\";","export default \"flat varying vec4 vGPUColor;\";","export default \"float unpackTextureData(sampler2D data_texture, int xIndex, int yIndex, int width, int height) {\\r\\n float u = (float(xIndex) + 0.5) /float(width);\\r\\n float v = (float(yIndex) + 0.5) /float(height);\\r\\n\\r\\n vec4 data = texture2D(data_texture, vec2(u, v));\\r\\n\\r\\n int unpacked = (int(data.r*255.0) << 24)\\r\\n + (int(data.g*255.0) << 16)\\r\\n + (int(data.b*255.0) << 8)\\r\\n + int(data.a*255.0);\\r\\n\\r\\n return float(unpacked) * PACKED_TEXTURE_SCALE;\\r\\n}\\r\\n\";","export default \"#define MIN_CAMERA_DIST 0.5\\r\\n\\r\\nattribute float visible;\\r\\nattribute float selected;\\r\\n\\r\\nuniform float scale;\\r\\nuniform vec3 currentCameraRotation;\\r\\nuniform vec3 currentCameraPosition;\\r\\nuniform vec3 currentCameraTarget;\\r\\nuniform bool initialCameraLoading;\\r\\nuniform float windowHeight;\\r\\nuniform float fov;\\r\\nuniform float distance;\\r\\n\\r\\nvarying vec2 vUv;\\r\\nvarying float vHidden;\\r\\nvarying float vVisible;\\r\\n\\r\\nvoid main() {\\r\\n updateGPUPickerColors();\\r\\n bool isHidden = false;\\r\\n\\r\\n vUv = uv;\\r\\n vVisible = visible;\\r\\n\\r\\n bool isSelected = compareFloat(selected, 1.0);\\r\\n float selectedScale = 0.8;\\r\\n if (isSelected) {\\r\\n selectedScale = 1.0;\\r\\n }\\r\\n\\r\\n if (initialCameraLoading) {\\r\\n isHidden = true;\\r\\n }\\r\\n\\r\\n float x = position.x - (uv.x - 0.5);\\r\\n float y = position.y - (uv.y - 0.5);\\r\\n float z = position.z;\\r\\n vec3 offset = vec3(x, y, z);\\r\\n\\r\\n // Hide based on distance (2D)\\r\\n float distance2D = getDistance2D(offset, currentCameraTarget);\\r\\n if (distance2D > distance) {\\r\\n isHidden = true;\\r\\n }\\r\\n\\r\\n // Resize based on distance (3D)\\r\\n float distance3D = getDistance3D(offset, cameraPosition);\\r\\n float projFactor = getProjFactor(fov, windowHeight, distance3D);\\r\\n float tagSize = 30.0 / projFactor;\\r\\n\\r\\n tagSize = clamp(tagSize, 1.0, 10.0);\\r\\n tagSize *= scale;\\r\\n\\r\\n // Move position to center of marker\\r\\n vec3 pos_offset = position - offset;\\r\\n\\r\\n // Rotate using camera rotation\\r\\n mat3 rot = eulerMatrix(currentCameraRotation);\\r\\n vec3 pos_rotated = pos_offset * rot;\\r\\n\\r\\n mat3 scale_matrix = scaleMatrix(tagSize * selectedScale);\\r\\n vec3 pos_scaled = pos_rotated * scale_matrix;\\r\\n\\r\\n // Add back our offset values\\r\\n vec3 pos_real = pos_scaled + offset;\\r\\n\\r\\n // Add height based on tag size\\r\\n pos_real.z += (0.5 * tagSize);\\r\\n\\r\\n vHidden = boolToFloat(isHidden);\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos_real, 1.0);\\r\\n}\";","export default \"uniform sampler2D imageTexture;\\r\\nuniform bool gpuPicker;\\r\\n\\r\\nvarying vec2 vUv;\\r\\nvarying float vHidden;\\r\\nvarying float vVisible;\\r\\n\\r\\nvoid main() {\\r\\n bool isHidden = compareFloat(vHidden, 1.0);\\r\\n bool isVisible = compareFloat(vVisible, 1.0);\\r\\n\\r\\n if (isHidden) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n if (!isVisible) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n vec4 color = texture2D(imageTexture, vUv);\\r\\n if (color.a < ALPHA_PRECISION) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n if (gpuPicker) {\\r\\n gl_FragColor = vGPUColor;\\r\\n } else {\\r\\n gl_FragColor = vec4(color.rgb, 1.0);\\r\\n }\\r\\n}\";","export default \"uniform float screenHeight;\\r\\nuniform float fov;\\r\\nuniform float size;\\r\\nuniform bool gpuPicker;\\r\\n\\r\\nvoid main() {\\r\\n updateGPUPickerColors();\\r\\n\\r\\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\\r\\n vec3 viewPosition = -mvPosition.xyz;\\r\\n gl_Position = projectionMatrix * mvPosition;\\r\\n\\r\\n float projFactor = getProjFactor(fov, screenHeight, viewPosition.z);\\r\\n float spriteSize = size * projFactor;\\r\\n gl_PointSize = spriteSize;\\r\\n}\\r\\n\";","export default \"uniform sampler2D imageTexture;\\r\\nuniform bool gpuPicker;\\r\\nuniform vec3 color;\\r\\n\\r\\nvoid main() {\\r\\n vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);\\r\\n vec4 textureColor = texture2D(imageTexture, uv);\\r\\n if (textureColor.a < ALPHA_PRECISION) {\\r\\n discard;\\r\\n }\\r\\n\\r\\n if (gpuPicker) {\\r\\n gl_FragColor = vGPUColor;\\r\\n } else {\\r\\n vec3 finalColor = textureColor.xyz * color;\\r\\n gl_FragColor = vec4(finalColor, 1.0);\\r\\n }\\r\\n}\\r\\n\";","import {classificationTexture} from '../classifications';\r\nimport shaders from '../shaders';\r\nimport { getColorMap } from '../../textures/colormaps';\r\nimport {Viewer} from \"../main\";\r\nimport {numberOfClassifications} from \"../../../classifications\";\r\nimport {\r\n Color,\r\n DataTexture,\r\n NearestFilter,\r\n DoubleSide,\r\n RGBAFormat,\r\n RGBFormat,\r\n ShaderMaterial,\r\n Uniform,\r\n Vector2,\r\n Vector3,\r\n TextureLoader,\r\n Texture,\r\n} from \"three\";\r\nimport { getTagTexturePath } from '../../textures/tag-icons';\r\nimport { PlanarConfig } from '../../../redux/assets-slice';\r\n\r\nconst packedTextureScale = 0.00025;\r\n\r\nexport const assignPackedData = (texture, xIndex, yIndex, value) => {\r\n if (typeof value == \"boolean\") {\r\n value = value ? 1.0 : 0.0;\r\n }\r\n\r\n const valueInt = Math.floor(value / packedTextureScale);\r\n let data = texture.image.data;\r\n let height = texture.image.height;\r\n let width = texture.image.width;\r\n let channels = texture.image.data.length / (width*height);\r\n let index = channels*(xIndex + yIndex*width);\r\n\r\n data[index + 0] = (valueInt >> 24) & 255;\r\n data[index + 1] = (valueInt >> 16) & 255;\r\n data[index + 2] = (valueInt >> 8) & 255;\r\n data[index + 3] = (valueInt) & 255;\r\n};\r\n\r\nconst generateDataTexture = (width: number, height: number, channels, color: Color = new Color(0xffffff)) => {\r\n let size = width * height;\r\n let data = new Uint8Array(channels * width * height);\r\n\r\n let r = Math.floor(color.r * 255);\r\n let g = Math.floor(color.g * 255);\r\n let b = Math.floor(color.b * 255);\r\n\r\n for (let i = 0; i < size; i++) {\r\n data[i * channels] = r;\r\n data[i * channels + 1] = g;\r\n data[i * channels + 2] = b;\r\n\r\n if (channels === 4) {\r\n data[i * channels + 3] = 255;\r\n }\r\n }\r\n\r\n let format = channels === 3 ? RGBFormat : RGBAFormat;\r\n let texture = new DataTexture(data, width, height, format);\r\n texture.minFilter = NearestFilter;\r\n texture.magFilter = NearestFilter;\r\n texture.needsUpdate = true;\r\n\r\n return texture;\r\n};\r\n\r\nexport interface PointCloudMaterialParams {\r\n minSize: number\r\n maxSize: number\r\n heightClamp: Vector2\r\n intensityClamp: Vector2\r\n dynamicSize: boolean\r\n circularPoints: boolean\r\n colorType: number\r\n distance: number\r\n size: number\r\n colorMap: string\r\n classifications: {[id: string]: boolean}\r\n}\r\n\r\n/** Shader Materials */\r\n\r\nexport class BaseMaterial extends ShaderMaterial {\r\n constructor() {\r\n super();\r\n }\r\n\r\n updateValues(parameters) {\r\n for (const key in parameters) {\r\n this[key] = parameters[key];\r\n }\r\n }\r\n\r\n initProperties() {\r\n let keys = Object.keys(this.uniforms);\r\n keys.forEach(key => {\r\n this.defineProperty(key);\r\n });\r\n }\r\n\r\n defineProperty(key) {\r\n Object.defineProperty(this, key, {\r\n get: () => {\r\n return (this.uniforms[key].value);\r\n },\r\n set: value => {\r\n this.uniforms[key].value = value;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport class PointCloudMaterial extends BaseMaterial {\r\n public gpuPicker;\r\n public size;\r\n public minSize;\r\n public distance;\r\n public colorMap;\r\n public colorType;\r\n public adaptiveSize;\r\n public circularPoints;\r\n public isOctreeCloud: boolean;\r\n public isPotreeCloud: boolean;\r\n public currentCameraTarget: Vector3\r\n public screenHeight: number;\r\n public screenwidth: number;\r\n public fov: number;\r\n public octreeSpacing;\r\n public octreeSize: number;\r\n public octreeCorner: Vector3;\r\n public intensityRange: Vector2;\r\n public rgbMax: number;\r\n public heightRange: Vector2;\r\n public timeStamp;\r\n public classificationVisible;\r\n\r\n private visibleClassTexture: DataTexture;\r\n\r\n public crossSectionWidth: number;\r\n public crossSectionStart: Vector3;\r\n public crossSectionEnd: Vector3;\r\n\r\n public clipBoxTexture: DataTexture;\r\n public areaTriangleTexture: DataTexture;\r\n public visibleNodesTexture: DataTexture;\r\n\r\n public numClippingBoxes = 0;\r\n public numAreaTriangles = 0;\r\n\r\n constructor(viewer: Viewer, params: PointCloudMaterialParams, gpuPicker) {\r\n super();\r\n\r\n this.gpuPicker = gpuPicker;\r\n\r\n // Node depth texture for dynamic sizing\r\n const visibleNodesWidth = 2048;\r\n const visibleNodesHeight = 1;\r\n this.visibleNodesTexture = generateDataTexture(\r\n visibleNodesWidth, visibleNodesHeight, 4);\r\n\r\n // Clip polygon texture (4 attribute + 3x3 coordinates)\r\n const clipTextureWidth = 1024;\r\n const clipTextureHeight = 4 + 9;\r\n this.clipBoxTexture = generateDataTexture(\r\n clipTextureWidth, clipTextureHeight, 4);\r\n\r\n // Area/volume texture (1 attribute + 3x3 coordinates)\r\n const areaTextureWidth = 1024;\r\n const areaTextureHeight = 1 + 9;\r\n this.areaTriangleTexture = generateDataTexture(\r\n areaTextureWidth, areaTextureHeight, 4);\r\n\r\n // Load initial colormap texture\r\n const loader = new TextureLoader();\r\n const image = getColorMap(params.colorMap).image;\r\n const colorMapTexture = loader.load(image);\r\n\r\n // Generate classification visibility array\r\n this.visibleClassTexture = generateDataTexture(\r\n numberOfClassifications, 1, 4);\r\n\r\n this.updateVisibleClassifications(params);\r\n\r\n let uniforms = {\r\n gpuPicker: new Uniform(gpuPicker),\r\n circularPoints: new Uniform(params.circularPoints),\r\n depth: new Uniform(1.0),\r\n currentCameraTarget: new Uniform(new Vector3()),\r\n size: new Uniform(params.size),\r\n minSize: new Uniform(params.minSize),\r\n maxSize: new Uniform(params.maxSize),\r\n fov: new Uniform(viewer.camera.fov * Math.PI / 180.0),\r\n screenHeight: new Uniform(viewer.height),\r\n screenwidth: new Uniform(viewer.width),\r\n distance: new Uniform(params.distance),\r\n octreeSize: new Uniform(0.0),\r\n octreeSpacing: new Uniform(0.0),\r\n octreeCorner: new Uniform(new Vector3()),\r\n colorType: new Uniform(params.colorType),\r\n heightRange: new Uniform(new Vector2(0, 1)),\r\n heightClamp: new Uniform(params.heightClamp),\r\n intensityRange: new Uniform(new Vector2(0, 1)),\r\n intensityClamp: new Uniform(params.intensityClamp),\r\n rgbMax: new Uniform(0),\r\n colorMap: new Uniform(colorMapTexture),\r\n adaptiveSize: new Uniform(params.dynamicSize),\r\n isOctreeCloud: new Uniform(false),\r\n isPotreeCloud: new Uniform(false),\r\n classificationData: new Uniform(classificationTexture),\r\n classificationVisible: new Uniform(this.visibleClassTexture),\r\n visibleNodes: new Uniform(this.visibleNodesTexture),\r\n areaTriangleData: new Uniform(this.areaTriangleTexture),\r\n clipPolygonData: new Uniform(this.clipBoxTexture),\r\n crossSectionWidth: new Uniform(0),\r\n crossSectionStart: new Uniform(new Vector3(0, 0, 0)),\r\n crossSectionEnd: new Uniform(new Vector3(0, 0, 0))\r\n };\r\n\r\n let defines = {\r\n NUMBER_OF_CLASSIFICATIONS: numberOfClassifications,\r\n CLIP_TEXTURE_WIDTH: clipTextureWidth,\r\n CLIP_TEXTURE_HEIGHT: clipTextureHeight,\r\n AREA_TEXTURE_WIDTH: areaTextureWidth,\r\n AREA_TEXTURE_HEIGHT: areaTextureHeight,\r\n VISIBLE_NODES_WIDTH: visibleNodesWidth,\r\n PACKED_TEXTURE_SCALE: packedTextureScale\r\n };\r\n\r\n let fragmentShader = [\r\n shaders.utilities.frag,\r\n shaders.gpu_picker.frag,\r\n shaders.pointcloud.frag\r\n ].join(\"\\n\");\r\n\r\n let vertexShader = [\r\n shaders.utilities.vert,\r\n shaders.gpu_picker.vert,\r\n shaders.texture_packer.vert,\r\n shaders.pointcloud.vert\r\n ].join(\"\\n\");\r\n\r\n this.setValues({\r\n defines,\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n vertexColors: true,\r\n transparent: true,\r\n depthWrite: true\r\n });\r\n\r\n this.initProperties();\r\n }\r\n\r\n updateVisibleClassifications(params: PointCloudMaterialParams) {\r\n let classifications = params.classifications;\r\n let texture = this.visibleClassTexture;\r\n let data = texture.image.data;\r\n\r\n Object.keys(classifications).forEach(id => {\r\n const visible = classifications[id];\r\n const index = parseInt(id) * 4 + 3;\r\n data[index] = visible ? 255 : 0;\r\n });\r\n\r\n texture.needsUpdate = true;\r\n }\r\n\r\n updateNumClippingBoxes(value) {\r\n if (value === this.numClippingBoxes) {\r\n return;\r\n }\r\n\r\n this.numClippingBoxes = value;\r\n\r\n if (value === 0) {\r\n delete this.defines.NUM_CLIP_BOXES;\r\n } else {\r\n this.defines.NUM_CLIP_BOXES = value;\r\n }\r\n\r\n this.needsUpdate = true;\r\n }\r\n\r\n updateNumAreaTriangles(value) {\r\n if (value === this.numAreaTriangles) {\r\n return;\r\n }\r\n\r\n this.numAreaTriangles = value;\r\n\r\n if (value === 0) {\r\n delete this.defines.NUM_AREA_TRIANGLES;\r\n } else {\r\n this.defines.NUM_AREA_TRIANGLES = value;\r\n }\r\n\r\n this.needsUpdate = true;\r\n }\r\n}\r\n\r\nexport class EDLMaterial extends BaseMaterial {\r\n public screenWidth;\r\n public screenHeight;\r\n public edlStrength;\r\n public far;\r\n\r\n constructor(width, height, near, far, pixelRatio = 1.0) {\r\n super();\r\n\r\n let vertexShader = shaders.edl.vert;\r\n let fragmentShader = shaders.edl.frag;\r\n\r\n let neighbourCount = 8;\r\n let neighbours = new Float32Array(neighbourCount * 2);\r\n for (let i = 0; i < neighbourCount; i++) {\r\n let value = 2 * i * Math.PI / neighbourCount;\r\n neighbours[2 * i] = Math.cos(value);\r\n neighbours[2 * i + 1] = Math.sin(value);\r\n }\r\n\r\n let defines = {\r\n NEIGHBOUR_COUNT: neighbourCount,\r\n };\r\n\r\n let uniforms = {\r\n screenWidth: new Uniform(width),\r\n screenHeight: new Uniform(height),\r\n near: new Uniform(near),\r\n far: new Uniform(far),\r\n opacity: new Uniform(1.0),\r\n edlStrength: new Uniform(1.0),\r\n radius: new Uniform(1.0 / pixelRatio),\r\n neighbours: new Uniform(neighbours),\r\n colorMap: new Uniform(null),\r\n tDepth: new Uniform(null)\r\n };\r\n\r\n this.setValues({\r\n defines,\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n transparent: true\r\n });\r\n\r\n this.initProperties();\r\n }\r\n}\r\n\r\nexport class OpacityMaterial extends BaseMaterial {\r\n constructor() {\r\n super();\r\n\r\n let vertexShader = shaders.opacity.vert;\r\n let fragmentShader = shaders.opacity.frag;\r\n\r\n let uniforms = {\r\n \"colorMap\": {type: \"t\", value: null},\r\n \"opacity\": {type: \"f\", value: 1.0}\r\n };\r\n\r\n this.setValues({\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n transparent: true\r\n });\r\n\r\n this.initProperties();\r\n }\r\n}\r\n\r\nexport class ImageMaterial extends BaseMaterial {\r\n constructor() {\r\n super();\r\n\r\n let vertexShader = shaders.image.vert;\r\n let fragmentShader = shaders.image.frag;\r\n\r\n let uniforms = {\r\n \"colorMap\": {type: \"t\",value: null},\r\n \"brightness\": {type: \"f\", value: 0},\r\n \"contrast\": {type: \"f\", value: 0}\r\n };\r\n\r\n this.setValues({\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n side: DoubleSide\r\n });\r\n\r\n this.initProperties();\r\n }\r\n}\r\n\r\nexport class TagMaterial extends BaseMaterial {\r\n public currentCameraPosition: Vector3\r\n public currentCameraRotation: Vector3\r\n public currentCameraTarget: Vector3\r\n public windowHeight\r\n public initialCameraLoading\r\n public distance\r\n public fov\r\n\r\n constructor(texture: string, scale: number, gpuPicker: boolean) {\r\n super();\r\n\r\n const texturePath = getTagTexturePath(texture);\r\n const textureData = new TextureLoader().load(texturePath);\r\n\r\n const fragmentShader = [\r\n shaders.gpu_picker.frag,\r\n shaders.utilities.frag,\r\n shaders.tags.frag\r\n ].join(\"\\n\");\r\n\r\n const vertexShader = [\r\n shaders.gpu_picker.vert,\r\n shaders.utilities.vert,\r\n shaders.tags.vert\r\n ].join(\"\\n\");\r\n\r\n const uniform = {\r\n scale: new Uniform(scale),\r\n gpuPicker: new Uniform(gpuPicker),\r\n currentCameraRotation: new Uniform(new Vector3()),\r\n currentCameraPosition: new Uniform(new Vector3()),\r\n currentCameraTarget: new Uniform(new Vector3()),\r\n fov: new Uniform(0),\r\n distance: new Uniform(0),\r\n initialCameraLoading: new Uniform(false),\r\n windowHeight: new Uniform(0),\r\n imageTexture: {\r\n type: 't',\r\n value: textureData\r\n }\r\n };\r\n\r\n this.setValues({\r\n uniforms: uniform,\r\n vertexShader: vertexShader,\r\n fragmentShader: fragmentShader,\r\n side: DoubleSide\r\n });\r\n\r\n this.initProperties();\r\n }\r\n}\r\n\r\nexport class PanoramicImageMaterial extends BaseMaterial {\r\n constructor() {\r\n super();\r\n\r\n let vertexShader = shaders.panoramic.vert;\r\n let fragmentShader = shaders.panoramic.frag;\r\n\r\n let uniforms = {\r\n tImage: {type: \"t\", value: null},\r\n };\r\n\r\n this.setValues({\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n side: DoubleSide\r\n });\r\n\r\n this.initProperties();\r\n }\r\n\r\n setTexture(texture) {\r\n this.uniforms.tImage.value = texture;\r\n }\r\n}\r\n\r\nexport class PlanarImageMaterial extends BaseMaterial {\r\n constructor(config: PlanarConfig) {\r\n super();\r\n\r\n let vertexShader = shaders.planar.vert;\r\n let fragmentShader = shaders.planar.frag;\r\n\r\n let uniforms = {\r\n tImage: {type: \"t\", value: null},\r\n imageWidth: new Uniform(config.width),\r\n imageHeight: new Uniform(config.height),\r\n fx: new Uniform(config.fx),\r\n fy: new Uniform(config.fy),\r\n cx: new Uniform(config.cx),\r\n cy: new Uniform(config.cy),\r\n };\r\n\r\n this.setValues({\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n side: DoubleSide\r\n });\r\n\r\n this.initProperties();\r\n }\r\n\r\n setTexture(texture) {\r\n this.uniforms.tImage.value = texture;\r\n }\r\n}\r\n\r\nexport class MarkerMaterial extends BaseMaterial {\r\n public currentCameraRotation: Vector3;\r\n public currentCameraPosition: Vector3;\r\n public windowHeight: number;\r\n public initialCameraLoading: boolean;\r\n public currentIndex: number;\r\n public orbitMode: Boolean;\r\n public fov: number;\r\n\r\n constructor(gpuPicker) {\r\n super();\r\n\r\n let fragmentShader = [\r\n shaders.utilities.frag,\r\n shaders.gpu_picker.frag,\r\n shaders.markers.frag\r\n ].join(\"\\n\");\r\n\r\n let vertexShader = [\r\n shaders.utilities.vert,\r\n shaders.gpu_picker.vert,\r\n shaders.markers.vert\r\n ].join(\"\\n\");\r\n\r\n let uniforms = {\r\n scale: new Uniform(0.5),\r\n gpuPicker: new Uniform(gpuPicker),\r\n orbitMode: new Uniform(false),\r\n currentCameraRotation: new Uniform(new Vector3()),\r\n currentCameraPosition: new Uniform(new Vector3()),\r\n fov: new Uniform(0),\r\n initialCameraLoading: new Uniform(false),\r\n windowHeight: new Uniform(0),\r\n currentIndex: new Uniform(0)\r\n };\r\n\r\n this.setValues({\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n side: DoubleSide\r\n });\r\n\r\n this.initProperties();\r\n }\r\n}\r\n\r\nexport class CustomSpriteMaterial extends BaseMaterial {\r\n public screenHeight;\r\n public fov;\r\n public map: Texture;\r\n public size = 1.0;\r\n public gpuPicker = false;\r\n public color = new Color(0xffffff);\r\n\r\n constructor(parameters) {\r\n super();\r\n\r\n this.updateValues(parameters);\r\n\r\n let fragmentShader = [\r\n shaders.utilities.frag,\r\n shaders.gpu_picker.frag,\r\n shaders.sprite.frag\r\n ].join(\"\\n\");\r\n\r\n let vertexShader = [\r\n shaders.utilities.vert,\r\n shaders.gpu_picker.vert,\r\n shaders.sprite.vert\r\n ].join(\"\\n\");\r\n\r\n let uniforms = {\r\n color: new Uniform(this.color),\r\n imageTexture: {type: \"t\", value: this.map},\r\n gpuPicker: new Uniform(this.gpuPicker),\r\n size: new Uniform(this.size),\r\n fov: new Uniform(0),\r\n screenHeight: new Uniform(0),\r\n };\r\n\r\n this.setValues({\r\n uniforms,\r\n vertexShader,\r\n fragmentShader,\r\n side: DoubleSide\r\n });\r\n\r\n this.initProperties();\r\n }\r\n}\r\n\r\n/** Generic material for gpu picker objects */\r\nexport class BasicPickerMaterial extends BaseMaterial {\r\n constructor(side = DoubleSide) {\r\n super();\r\n\r\n let vertexShader = [\r\n shaders.gpu_picker.vert,\r\n shaders.basic_picker.vert\r\n ].join(\"\\n\");\r\n\r\n let fragmentShader = [\r\n shaders.gpu_picker.frag,\r\n shaders.basic_picker.frag\r\n ].join(\"\\n\");\r\n\r\n this.setValues({vertexShader, fragmentShader, side});\r\n this.initProperties();\r\n }\r\n}\r\n","import {\r\n NearestFilter,\r\n RGBAFormat,\r\n RGBFormat,\r\n WebGLRenderTarget,\r\n LinearFilter,\r\n DepthTexture,\r\n UnsignedIntType,\r\n FloatType\r\n} from \"three\";\r\n\r\nexport class BasicRenderTarget extends WebGLRenderTarget {\r\n constructor(width, height, hasAlpha=false) {\r\n super(width, height, {\r\n minFilter: LinearFilter,\r\n magFilter: LinearFilter,\r\n format: hasAlpha ? RGBAFormat : RGBFormat,\r\n stencilBuffer: false\r\n });\r\n }\r\n}\r\n\r\nexport class EDLRenderTarget extends WebGLRenderTarget {\r\n constructor(width, height, isWebGL2) {\r\n super(width, height, {\r\n format: RGBAFormat,\r\n minFilter: NearestFilter,\r\n magFilter: NearestFilter,\r\n generateMipmaps: false,\r\n stencilBuffer: false,\r\n depthBuffer: true\r\n });\r\n\r\n this.depthTexture = new DepthTexture(width, height);\r\n this.depthTexture.type = isWebGL2 ? FloatType : UnsignedIntType;\r\n }\r\n}\r\n\r\nexport class OpacityRenderTarget extends WebGLRenderTarget {\r\n constructor(width, height) {\r\n super(width, height, {\r\n format: RGBAFormat,\r\n minFilter: NearestFilter,\r\n magFilter: NearestFilter,\r\n stencilBuffer: false\r\n });\r\n }\r\n}","import {\r\n EDLMaterial,\r\n OpacityMaterial,\r\n EDLRenderTarget,\r\n OpacityRenderTarget\r\n} from \".\";\r\nimport {\r\n Camera,\r\n Mesh,\r\n MeshBasicMaterial,\r\n PerspectiveCamera,\r\n PlaneBufferGeometry,\r\n Scene,\r\n Vector2,\r\n WebGLRenderer,\r\n WebGLRenderTarget\r\n} from \"three\";\r\n\r\nexport class RenderPass {\r\n private readonly screenScene: Scene;\r\n private readonly screenQuad: Mesh;\r\n private readonly camera: Camera;\r\n\r\n constructor() {\r\n const geometry = new PlaneBufferGeometry(2, 2);\r\n const material = new MeshBasicMaterial({\r\n depthTest: true,\r\n depthWrite: true,\r\n transparent: true\r\n });\r\n\r\n this.screenScene = new Scene();\r\n this.screenQuad = new Mesh(geometry, material);\r\n this.screenScene.add(this.screenQuad);\r\n this.camera = new Camera();\r\n }\r\n\r\n /** Render to screen. Note that our render target is changed after using this function */\r\n render(renderer, material, target = null) {\r\n this.screenQuad.material = material;\r\n renderer.setRenderTarget(target);\r\n renderer.render(this.screenScene, this.camera);\r\n }\r\n}\r\n\r\nexport class RenderUtils {\r\n private renderer: WebGLRenderer;\r\n private camera: PerspectiveCamera;\r\n private screenPass = new RenderPass()\r\n private targets: WebGLRenderTarget[] = [];\r\n private pixelRatio;\r\n private opacityMaterial: OpacityMaterial;\r\n private opacityRenderTarget: OpacityRenderTarget;\r\n private EDLMaterial: EDLMaterial;\r\n private EDLRenderTarget: EDLRenderTarget;\r\n\r\n constructor(renderer, camera, pixelRatio=1.0) {\r\n this.renderer = renderer;\r\n this.camera = camera;\r\n this.pixelRatio = pixelRatio;\r\n\r\n this.initTargets();\r\n }\r\n\r\n get renderTargetAttrs() {\r\n return {\r\n tDepth: this.renderTarget.depthTexture,\r\n colorMap: this.renderTarget.texture,\r\n };\r\n }\r\n\r\n get EDLSupport() : boolean {\r\n let capabilities = this.renderer.capabilities;\r\n let supported = (capabilities.maxVaryings > 8)\r\n && capabilities.floatFragmentTextures;\r\n\r\n return supported;\r\n }\r\n\r\n get renderTarget() {\r\n return this.EDLSupport\r\n ? this.EDLRenderTarget\r\n : this.opacityRenderTarget;\r\n }\r\n\r\n get renderMaterial() {\r\n return this.EDLSupport\r\n ? this.EDLMaterial\r\n : this.opacityMaterial;\r\n }\r\n\r\n get isWebGL2() {\r\n let capabilities = this.renderer.capabilities;\r\n return capabilities.isWebGL2;\r\n }\r\n\r\n get width() {\r\n let renderSize = new Vector2();\r\n this.renderer.getSize(renderSize);\r\n return renderSize.x;\r\n }\r\n\r\n get height() {\r\n let renderSize = new Vector2();\r\n this.renderer.getSize(renderSize);\r\n return renderSize.y;\r\n }\r\n\r\n initTargets() {\r\n this.opacityMaterial = new OpacityMaterial();\r\n this.opacityRenderTarget = new OpacityRenderTarget(this.width, this.height);\r\n this.addTarget(this.opacityRenderTarget);\r\n\r\n if (this.EDLSupport) {\r\n this.EDLMaterial = new EDLMaterial(\r\n this.width,\r\n this.height,\r\n this.camera.near,\r\n this.camera.far,\r\n this.pixelRatio\r\n );\r\n\r\n this.EDLRenderTarget = new EDLRenderTarget(this.width, this.height,\r\n this.isWebGL2);\r\n this.addTarget(this.EDLRenderTarget);\r\n } else {\r\n this.EDLMaterial = null;\r\n this.EDLRenderTarget = null;\r\n\r\n console.log(\"EDL Not Supported\");\r\n }\r\n }\r\n\r\n update() {\r\n this.updateEDLValues();\r\n this.resizeTextures();\r\n this.renderer.clear();\r\n }\r\n\r\n addTarget(target) {\r\n this.targets.push(target);\r\n }\r\n\r\n setCamera(camera) {\r\n this.camera = camera;\r\n }\r\n\r\n /** @private */\r\n resizeTextures() {\r\n let width = this.width;\r\n let height = this.height;\r\n\r\n this.targets.forEach(target => {\r\n if (!target) {\r\n return;\r\n }\r\n\r\n let w = target.width;\r\n let h = target.height;\r\n if ((w !== width) || (h !== height)) {\r\n target.dispose();\r\n target.setSize(width, height);\r\n }\r\n });\r\n }\r\n\r\n /** @private */\r\n updateEDLValues() {\r\n if (!this.EDLMaterial) {\r\n return;\r\n }\r\n\r\n this.EDLMaterial.far = this.camera.far;\r\n this.EDLMaterial.screenWidth = this.width;\r\n this.EDLMaterial.screenHeight = this.height;\r\n }\r\n\r\n updateMaterial(material, values) {\r\n let keys = Object.keys(values);\r\n keys.forEach(key => {\r\n material[key] = values[key];\r\n });\r\n }\r\n\r\n setRenderTarget(target, clear = false) {\r\n this.renderer.setRenderTarget(target);\r\n if (clear) {\r\n this.renderer.clear();\r\n }\r\n }\r\n\r\n renderToScreen(material, target = null) {\r\n this.screenPass.render(this.renderer, material, target);\r\n }\r\n\r\n renderScenes(scenes, opacity, clear=true) {\r\n const toRender = scenes.filter(scene => scene !== null);\r\n this.setRenderTarget(this.renderTarget, clear);\r\n\r\n toRender.forEach(scene => {\r\n this.renderer.render(scene, this.camera);\r\n });\r\n\r\n this.updateMaterial(this.renderMaterial, {\r\n ...this.renderTargetAttrs, opacity: opacity\r\n });\r\n\r\n this.renderToScreen(this.renderMaterial);\r\n }\r\n}","import {\r\n Box3,\r\n BoxGeometry,\r\n BufferAttribute,\r\n BufferGeometry,\r\n EdgesGeometry,\r\n LineBasicMaterial,\r\n LineSegments,\r\n Points,\r\n Scene,\r\n Sphere,\r\n Vector3\r\n} from 'three';\r\nimport { isDevMode } from '../../../electron-modules';\r\nimport { PointCloudMaterial } from '../rendering';\r\nimport { PointCloudManager } from '.';\r\nimport { closestPowerOfTwo, mergeBoundingBoxes, randomHexColor } from '../utilities';\r\nimport GPUPicker from '../gpu-picker';\r\n\r\n/** Base class for all pointcloud nodes */\r\nexport class PointCloudNode {\r\n public cloud: PointCloud\r\n public parent: PointCloudNode\r\n\r\n public pointsScene: Points;\r\n public pointsPicker: Points;\r\n protected boundingBoxMesh: LineSegments;\r\n protected geometry: BufferGeometry;\r\n protected _bounding_sphere: Sphere;\r\n protected _bounding_box: Box3;\r\n\r\n public name: string;\r\n protected size: number;\r\n protected data;\r\n protected nodeCenter: Vector3;\r\n public numPoints = 0;\r\n public children: PointCloudNode[] = []\r\n public density: number;\r\n\r\n public visible = false;\r\n public loaded = false;\r\n public loading = false;\r\n\r\n get scene(): Scene {\r\n return this.cloud.scene;\r\n }\r\n\r\n get picker(): GPUPicker {\r\n return this.cloud.picker;\r\n }\r\n\r\n /** Bounding sphere in viewer coordinates */\r\n get boundingSphere() {\r\n if (!this._bounding_sphere) {\r\n this._bounding_sphere = new Sphere(this.center, this.radius);\r\n }\r\n\r\n return this._bounding_sphere;\r\n }\r\n\r\n /** Bounding box in viewer coordinates */\r\n get boundingBox() {\r\n if (!this._bounding_box) {\r\n const min = new Vector3()\r\n .add(this.center)\r\n .subScalar(this.size/2);\r\n\r\n const max = new Vector3()\r\n .add(this.center)\r\n .addScalar(this.size/2);\r\n\r\n this._bounding_box = new Box3(min, max);\r\n }\r\n\r\n return this._bounding_box;\r\n }\r\n\r\n get shift() {\r\n return new Vector3();\r\n }\r\n\r\n /** Node center in viewer coordinates */\r\n get center() {\r\n return new Vector3()\r\n .add(this.nodeCenter)\r\n .add(this.shift);\r\n }\r\n\r\n /** Bounding sphere radius */\r\n get radius() {\r\n return Math.sqrt(3) * (this.size / 2.0);\r\n }\r\n\r\n get isGeometryNode() {\r\n return !this.pointsScene;\r\n }\r\n\r\n get isTreeNode() {\r\n return !!this.pointsScene;\r\n }\r\n\r\n addToScene() {\r\n console.warn(\"Not implemented\");\r\n }\r\n\r\n addChildNode(node) {\r\n this.children.push(node);\r\n }\r\n\r\n clearChildNodes() {\r\n this.children.forEach(child => child = null);\r\n this.children = [];\r\n }\r\n\r\n removeChildNode(node) {\r\n let index = this.children.indexOf(node);\r\n if (index !== -1) {\r\n this.children.splice(index, 1);\r\n }\r\n\r\n node.clearChildNodes();\r\n node = null;\r\n }\r\n\r\n removeFromScene(item) {\r\n if (!item) return;\r\n this.scene.remove(item);\r\n }\r\n\r\n disposeGeometry(item) {\r\n if (!item) {\r\n return;\r\n }\r\n\r\n item.geometry.dispose();\r\n item.material.dispose();\r\n }\r\n\r\n dispose() {\r\n this.removeFromScene(this.pointsScene);\r\n this.disposeGeometry(this.pointsScene);\r\n this.pointsScene = null;\r\n\r\n this.picker.remove(this.pointsPicker);\r\n this.disposeGeometry(this.pointsPicker);\r\n this.pointsPicker = null;\r\n\r\n if (this.boundingBoxMesh) {\r\n this.removeFromScene(this.boundingBoxMesh);\r\n this.disposeGeometry(this.boundingBoxMesh);\r\n this.boundingBoxMesh = null;\r\n }\r\n\r\n if (this.geometry) {\r\n this.geometry.dispose();\r\n }\r\n this.geometry = null;\r\n\r\n this.loaded = false;\r\n this.loading = false;\r\n\r\n // console.log(`Dispose node: ${this.name}`);\r\n }\r\n\r\n setVisibility(visible, boundingBoxVisibility) {\r\n if (this.pointsPicker) {\r\n this.pointsPicker.visible = visible;\r\n }\r\n\r\n if (this.pointsScene) {\r\n this.pointsScene.visible = visible;\r\n }\r\n\r\n if (this.boundingBoxMesh) {\r\n this.boundingBoxMesh.visible = boundingBoxVisibility;\r\n }\r\n\r\n this.visible = visible;\r\n }\r\n\r\n setGeometry(data) {\r\n let geometry = new BufferGeometry();\r\n geometry.setAttribute('position', new BufferAttribute(data.positions, 3));\r\n geometry.setAttribute('intensity', new BufferAttribute(data.intensity, 1));\r\n geometry.setAttribute('classification', new BufferAttribute(data.classification, 1));\r\n geometry.setAttribute('rgb', new BufferAttribute(data.colors, 3));\r\n geometry.setAttribute('gpu_index', new BufferAttribute(data.gpu_index, 1));\r\n geometry.computeBoundingBox();\r\n this.geometry = geometry;\r\n }\r\n\r\n addCloudData(pointsPicker, pointsScene, boundingBox) {\r\n // Add our global shift to line up with previous data\r\n pointsScene.position.copy(this.shift);\r\n pointsPicker.position.copy(this.shift);\r\n\r\n // Add our new objects\r\n this.pointsPicker = pointsPicker;\r\n this.pointsScene = pointsScene;\r\n\r\n this.scene.add(this.pointsScene);\r\n this.picker.add(this.pointsPicker);\r\n\r\n if (boundingBox) {\r\n // Bounding box is for dev mode only\r\n boundingBox.position.copy(this.center);\r\n this.boundingBoxMesh = boundingBox;\r\n this.scene.add(this.boundingBoxMesh);\r\n }\r\n }\r\n}\r\n\r\n/** Base class for all pointclouds */\r\nexport class PointCloud {\r\n public uniqueClassifications: Set;\r\n private readonly rgbArray = [];\r\n public maxColor = null;\r\n public intensityRange = null;\r\n public identifier = null;\r\n public error = false;\r\n protected enabled = true;\r\n private name = \"\";\r\n public visible = true;\r\n public materialScene: PointCloudMaterial = null;\r\n public materialPicker: PointCloudMaterial = null;\r\n public materials: PointCloudMaterial[];\r\n public root = null;\r\n protected pointclouds: PointCloudManager;\r\n protected _tightBoundingBox = null;\r\n\r\n constructor(pointclouds: PointCloudManager) {\r\n this.pointclouds = pointclouds;\r\n this.uniqueClassifications = new Set();\r\n\r\n this.materialScene = new PointCloudMaterial(this.viewer,\r\n this.pointclouds.materialDefaults, false);\r\n\r\n this.materialPicker = new PointCloudMaterial(this.viewer,\r\n this.pointclouds.materialDefaults, true);\r\n\r\n this.materials = [\r\n this.materialScene,\r\n this.materialPicker\r\n ];\r\n }\r\n\r\n get shift() {\r\n return new Vector3();\r\n }\r\n\r\n get size() {\r\n return 0;\r\n }\r\n\r\n get viewer() {\r\n return this.pointclouds.viewer;\r\n }\r\n\r\n get scene() {\r\n return this.pointclouds.scene;\r\n }\r\n\r\n get picker() {\r\n return this.viewer.gpuPickers.default;\r\n }\r\n\r\n /** Get bounding box with global shift applied */\r\n get tightBoundingBox() {\r\n let bbox = this._tightBoundingBox;\r\n if (!bbox) return null;\r\n\r\n let boundingBox = {\r\n min: new Vector3().add(bbox.min).add(this.shift),\r\n max: new Vector3().add(bbox.max).add(this.shift)\r\n };\r\n\r\n return boundingBox;\r\n }\r\n\r\n setName(name) {\r\n this.name = name;\r\n }\r\n\r\n setState(state) {\r\n this.enabled = state;\r\n }\r\n\r\n setVisibility(visible) {\r\n const changed = this.visible !== visible;\r\n this.visible = visible;\r\n if (changed) {\r\n this.pointclouds.updateMinimapExtent();\r\n }\r\n }\r\n\r\n setIdentifier(identifier) {\r\n // console.log(`Added pointcloud [id = ${identifier}]`);\r\n identifier = identifier === undefined ? null : identifier;\r\n this.identifier = identifier;\r\n }\r\n\r\n dispose() {\r\n this.setState(false);\r\n this.disposeNodes();\r\n }\r\n\r\n disposeNodes() {\r\n const nodes = this.getVisibleNodes();\r\n nodes.forEach(node => {\r\n node.visible = false;\r\n node.dispose();\r\n });\r\n }\r\n\r\n getVisibleNodes(condition?) : PointCloudNode[] {\r\n console.warn(\"Not implemented\");\r\n return [];\r\n }\r\n\r\n updateBoundingBox(boundingBox) {\r\n let combined = mergeBoundingBoxes([\r\n this._tightBoundingBox,\r\n boundingBox\r\n ]);\r\n\r\n this._tightBoundingBox = combined;\r\n }\r\n\r\n updateIntensityRange(intensityMin, intensityMax) {\r\n if (this.intensityRange === null) {\r\n this.intensityRange = {\r\n min: intensityMin,\r\n max: intensityMax\r\n };\r\n }\r\n\r\n this.intensityRange.min = Math.min(intensityMin, this.intensityRange.min);\r\n this.intensityRange.max = Math.max(intensityMax, this.intensityRange.max);\r\n }\r\n\r\n updateColorLimits(rgbMax) {\r\n let closestValue = closestPowerOfTwo(rgbMax);\r\n this.rgbArray.push(closestValue);\r\n this.rgbArray.sort();\r\n\r\n let arrMax = Math.max(...this.rgbArray);\r\n let arrMin = Math.min(...this.rgbArray);\r\n let diff = arrMax - arrMin;\r\n if (diff === 0) {\r\n this.maxColor = arrMax;\r\n return;\r\n }\r\n\r\n // Grab the middle value instead\r\n let midpoint = this.rgbArray.length / 2.0;\r\n midpoint = Math.ceil(midpoint);\r\n this.maxColor = this.rgbArray[midpoint];\r\n }\r\n\r\n updateClassifications(classification) {\r\n classification = new Set(classification);\r\n classification.forEach(item => {\r\n this.uniqueClassifications.add(item);\r\n });\r\n }\r\n\r\n generateEdgeMesh = (size) => {\r\n if (!isDevMode) return null;\r\n\r\n const color = randomHexColor();\r\n const boxGeometry = new BoxGeometry(size, size, size);\r\n const edgeGeometry = new EdgesGeometry(boxGeometry);\r\n const boxMaterial = new LineBasicMaterial({color});\r\n const boundingBox = new LineSegments(edgeGeometry, boxMaterial);\r\n boundingBox.visible = false;\r\n\r\n return boundingBox;\r\n }\r\n}\r\n","// Binary heap implementation from:\r\n// http://eloquentjavascript.net/appendix2.html\r\n\r\nexport class BinaryHeap {\r\n private scoreFunction;\r\n private content = [];\r\n\r\n constructor(scoreFunction) {\r\n this.scoreFunction = scoreFunction;\r\n }\r\n\r\n get size() {\r\n return this.content.length;\r\n }\r\n\r\n push(element) {\r\n // Add the new element to the end of the array.\r\n this.content.push(element);\r\n // Allow it to bubble up.\r\n this.bubbleUp(this.content.length - 1);\r\n }\r\n\r\n pop() {\r\n // Store the first element so we can return it later.\r\n var result = this.content[0];\r\n // Get the element at the end of the array.\r\n var end = this.content.pop();\r\n // If there are any elements left, put the end element at the\r\n // start, and let it sink down.\r\n if (this.content.length > 0) {\r\n this.content[0] = end;\r\n this.sinkDown(0);\r\n }\r\n return result;\r\n }\r\n\r\n peek() {\r\n return this.content[0];\r\n }\r\n\r\n remove(node) {\r\n var length = this.content.length;\r\n // To remove a value, we must search through the array to find\r\n // it.\r\n for (var i = 0; i < length; i++) {\r\n if (this.content[i] !== node) continue;\r\n // When it is found, the process seen in 'pop' is repeated\r\n // to fill up the hole.\r\n var end = this.content.pop();\r\n // If the element we popped was the one we needed to remove,\r\n // we're done.\r\n if (i === length - 1) break;\r\n // Otherwise, we replace the removed element with the popped\r\n // one, and allow it to float up or sink down as appropriate.\r\n this.content[i] = end;\r\n this.bubbleUp(i);\r\n this.sinkDown(i);\r\n break;\r\n }\r\n }\r\n\r\n bubbleUp(n) {\r\n // Fetch the element that has to be moved.\r\n var element = this.content[n];\r\n var score = this.scoreFunction(element);\r\n // When at 0, an element can not go up any further.\r\n while (n > 0) {\r\n // Compute the parent element's index, and fetch it.\r\n var parentN = Math.floor((n + 1) / 2) - 1;\r\n var parent = this.content[parentN];\r\n // If the parent has a lesser score, things are in order and we\r\n // are done.\r\n if (score >= this.scoreFunction(parent)) {\r\n break;\r\n }\r\n\r\n // Otherwise, swap the parent with the current element and\r\n // continue.\r\n this.content[parentN] = element;\r\n this.content[n] = parent;\r\n n = parentN;\r\n }\r\n }\r\n\r\n sinkDown(n) {\r\n // Look up the target element and its score.\r\n var length = this.content.length;\r\n var element = this.content[n];\r\n var elemScore = this.scoreFunction(element);\r\n\r\n while (true) {\r\n // Compute the indices of the child elements.\r\n var child2N = (n + 1) * 2;\r\n var child1N = child2N - 1;\r\n // This is used to store the new position of the element,\r\n // if any.\r\n var swap = null;\r\n // If the first child exists (is inside the array)...\r\n if (child1N < length) {\r\n // Look it up and compute its score.\r\n var child1 = this.content[child1N];\r\n var child1Score = this.scoreFunction(child1);\r\n // If the score is less than our element's, we need to swap.\r\n if (child1Score < elemScore) {\r\n swap = child1N;\r\n }\r\n }\r\n // Do the same checks for the other child.\r\n if (child2N < length) {\r\n var child2 = this.content[child2N];\r\n var child2Score = this.scoreFunction(child2);\r\n if (child2Score < (swap == null ? elemScore : child1Score)) {\r\n swap = child2N;\r\n }\r\n }\r\n\r\n // No need to swap further, we are done.\r\n if (swap == null) break;\r\n\r\n // Otherwise, swap and continue.\r\n this.content[n] = this.content[swap];\r\n this.content[swap] = element;\r\n n = swap;\r\n }\r\n }\r\n}","import {\r\n EncompassPointCloud,\r\n PointCloud,\r\n PotreePointCloud,\r\n GenericPointCloud,\r\n StreamablePointCloud,\r\n StreamablePointCloudNode\r\n} from \".\";\r\nimport {\r\n assignPackedData,\r\n PointCloudMaterial,\r\n PointCloudMaterialParams\r\n} from \"../rendering\";\r\nimport {Viewer} from \"../main\";\r\nimport {\r\n boundsToMapLayer,\r\n closestPowerOfTwo,\r\n getProjFactor,\r\n mergeBoundingBoxes\r\n} from \"../utilities\";\r\nimport { pointInPolygon } from \"../utilities\";\r\nimport {\r\n AmbientLight,\r\n BufferGeometry,\r\n Frustum,\r\n MathUtils,\r\n Matrix4,\r\n Points,\r\n Scene,\r\n Vector2,\r\n Vector3\r\n} from \"three\";\r\nimport { Vector as VectorLayer } from \"ol/layer\";\r\nimport { isStaticSite } from \"../../../electron-modules\";\r\nimport LocalScene, { getEulerInverse } from \"../projections\";\r\nimport slash from \"slash\";\r\nimport { AssetType } from \"../../../redux/assets-slice\";\r\nimport { BinaryHeap } from \"../binary-heap\";\r\n\r\nexport class PointCloudManager {\r\n public viewer: Viewer;\r\n public scene: Scene;\r\n private layer: VectorLayer;\r\n public materialDefaults: PointCloudMaterialParams;\r\n public clouds: (GenericPointCloud | StreamablePointCloud)[] = [];\r\n public visiblePointsTarget = 0;\r\n private maxUnloadedNodes = 2;\r\n private unloadedGeometry = [];\r\n private maxUnloadedClouds = 2;\r\n private maxloadedToGPUPerFrame = 2;\r\n private loadedToGPUThisFrame = 0;\r\n private nodeCacheSize = 500;\r\n private exeLaunchTimeout = 1000;\r\n private lastExeLaunched = performance.now();\r\n public numLoadedPoints = 0;\r\n public numVisiblePoints = 0;\r\n public numSceneNodesVisible = 0;\r\n private minPixelPercent = 0.20;\r\n public boundsVisible = false;\r\n public transparency = 1.0;\r\n public rawJsonResponse = [];\r\n public shouldUpdate = true;\r\n\r\n\r\n\r\n constructor(parent: Viewer) {\r\n this.viewer = parent;\r\n\r\n // Material defaults\r\n this.materialDefaults = {\r\n size: 1.0,\r\n minSize: 2.0,\r\n maxSize: 50.0,\r\n colorMap: \"heat-map\",\r\n colorType: 2,\r\n distance: this.viewer.far,\r\n dynamicSize: true,\r\n circularPoints: true,\r\n classifications: {},\r\n heightClamp: new Vector2(0, 1),\r\n intensityClamp: new Vector2(0, 1),\r\n };\r\n\r\n this.initScene();\r\n }\r\n\r\n get cameraList() {\r\n return this.viewer.cameraList;\r\n }\r\n\r\n get minimap() {\r\n return this.viewer.minimap;\r\n }\r\n\r\n get controls() {\r\n return this.viewer.controls;\r\n }\r\n\r\n get uniqueClassifications(): number[] {\r\n let uniqueClassifications = new Set();\r\n this.clouds.forEach(cloud => {\r\n cloud.uniqueClassifications.forEach((item: number) => {\r\n uniqueClassifications.add(item);\r\n });\r\n });\r\n return Array.from(uniqueClassifications) as number[];\r\n }\r\n\r\n get combinedBoundingBox() {\r\n const boundingBoxes = this.clouds.map(cloud => {\r\n return cloud.visible\r\n ? cloud.tightBoundingBox\r\n : null;\r\n });\r\n\r\n return mergeBoundingBoxes(boundingBoxes);\r\n }\r\n\r\n get genericPointClouds() {\r\n return this.clouds.filter(x => x instanceof GenericPointCloud) as GenericPointCloud[];\r\n }\r\n\r\n get streamingPointClouds() {\r\n return this.clouds.filter(x => x instanceof StreamablePointCloud) as StreamablePointCloud[];\r\n }\r\n\r\n get isEmpty() {\r\n return this.clouds.length === 0;\r\n }\r\n\r\n reconcile(pointClouds) {\r\n const currentPointClouds = new Set(this.clouds.map(cloud => cloud.identifier));\r\n const newPointClouds = new Set(pointClouds.map(cloud => cloud.id));\r\n\r\n const pointCloudsToLoad = pointClouds.filter(cloud => !currentPointClouds.has(cloud.id));\r\n const pointCloudsToDelete = this.clouds.filter(cloud => !newPointClouds.has(cloud.identifier));\r\n\r\n const numCloudsRemoved = pointCloudsToDelete.length;\r\n const numCloudsAdded = pointCloudsToLoad.length;\r\n\r\n // Delete clouds that need to be removed\r\n pointCloudsToDelete.forEach(pointCloud => {\r\n this.deletePointCloud(pointCloud.identifier);\r\n });\r\n\r\n // Add new pointclouds\r\n pointCloudsToLoad.forEach(pointCloud => {\r\n const cloudDetails = {\r\n name: pointCloud.name,\r\n identifier: pointCloud.id,\r\n path: slash(pointCloud.path),\r\n visible: pointCloud.visible,\r\n saved: pointCloud.saved\r\n };\r\n\r\n let newPointCloud;\r\n\r\n if (pointCloud.type === AssetType.LAS) {\r\n newPointCloud = new GenericPointCloud(this);\r\n } else if (pointCloud.type === AssetType.E57Points) {\r\n newPointCloud = new GenericPointCloud(this);\r\n } else if (pointCloud.type === AssetType.Encompass) {\r\n newPointCloud = new EncompassPointCloud(this);\r\n } else if (pointCloud.type === AssetType.Potree) {\r\n newPointCloud = new PotreePointCloud(this);\r\n }\r\n\r\n if (!newPointCloud) return;\r\n newPointCloud.load(cloudDetails);\r\n });\r\n\r\n // Toggle proper visibility for each cloud\r\n pointClouds.forEach(pointCloud => {\r\n this.toggleVisibility(pointCloud.id, pointCloud.visible);\r\n });\r\n\r\n const numClouds = this.clouds.length;\r\n\r\n return {numClouds, numCloudsAdded, numCloudsRemoved};\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n getByID(id) {\r\n return this.clouds.find(pointCloud => pointCloud.identifier === id);\r\n }\r\n\r\n doesCloudExist(identifier: string): boolean {\r\n return this.clouds.filter(cloud => cloud.identifier === identifier).length > 0;\r\n }\r\n\r\n addPointCloud(cloud: GenericPointCloud | StreamablePointCloud) {\r\n this.clouds.push(cloud);\r\n this.updateMeasureList();\r\n }\r\n\r\n deletePointCloud(identifier) {\r\n const clouds = new Set(this.clouds);\r\n const toRemove = this.clouds.filter(cloud => cloud.identifier === identifier);\r\n\r\n toRemove.forEach(cloud => {\r\n cloud.dispose();\r\n clouds.delete(cloud);\r\n });\r\n\r\n this.clouds = [...clouds];\r\n this.updateMinimapExtent();\r\n this.updateMeasureList();\r\n }\r\n\r\n updateMeasureList() {\r\n const measurements = this.controls.measurements;\r\n measurements.refreshMeasurementList();\r\n }\r\n\r\n toggleVisibility(identifier, state) {\r\n this.clouds\r\n .filter(cloud => cloud.identifier === identifier)\r\n .forEach(cloud => {\r\n cloud.setVisibility(state);\r\n });\r\n }\r\n\r\n updateClamping(key, data) {\r\n if (data.max <= data.min) {\r\n return;\r\n }\r\n\r\n let value = new Vector2(data.min, data.max);\r\n this.materialDefaults[key] = value;\r\n this.clouds.forEach(cloud => {\r\n cloud.materials.forEach(material => {\r\n material[key] = value;\r\n });\r\n });\r\n }\r\n\r\n setMaxDistance(distance: number) {\r\n const value = (distance > 999) ? 1e10 : distance;\r\n this.materialDefaults.distance = value;\r\n this.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.distance = value;\r\n });\r\n });\r\n }\r\n\r\n setVisibleClassifications(classifications) {\r\n // Update defaults for new clouds\r\n classifications.forEach(classification => {\r\n const {id, visible} = classification;\r\n this.materialDefaults.classifications[id] = visible;\r\n });\r\n\r\n // Update values in existing clouds\r\n this.clouds.forEach(cloud => {\r\n cloud.materials.forEach(material => {\r\n material.updateVisibleClassifications(\r\n this.materialDefaults);\r\n });\r\n\r\n cloud.picker.needsUpdate = true;\r\n });\r\n }\r\n\r\n setPointCloudScale(size) {\r\n this.materialDefaults.size = size;\r\n this.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.size = size;\r\n material.needsUpdate = true;\r\n });\r\n });\r\n }\r\n\r\n setPointCloudMinimum(size) {\r\n this.materialDefaults.minSize = size;\r\n this.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.minSize = size;\r\n material.needsUpdate = true;\r\n });\r\n });\r\n }\r\n\r\n updateMinimapExtent() {\r\n const map = this.minimap.map;\r\n if (this.layer) {\r\n map.removeLayer(this.layer);\r\n }\r\n\r\n if (!LocalScene.initialized) return;\r\n\r\n let boundingBox = this.combinedBoundingBox;\r\n if (!boundingBox) return;\r\n\r\n // Aerial view layer\r\n this.layer = boundsToMapLayer(boundingBox);\r\n map.addLayer(this.layer);\r\n }\r\n\r\n updateMaterialValues(cloud: PointCloud, material: PointCloudMaterial) {\r\n let controls = this.viewer.controls;\r\n let camera = this.viewer.camera;\r\n let target = controls.getCameraTarget();\r\n\r\n material.isOctreeCloud = !(cloud instanceof GenericPointCloud);\r\n material.isPotreeCloud = cloud instanceof PotreePointCloud;\r\n material.currentCameraTarget = target;\r\n material.screenHeight = this.viewer.height;\r\n material.screenwidth = this.viewer.width;\r\n material.fov = MathUtils.degToRad(camera.fov);\r\n\r\n if (cloud instanceof StreamablePointCloud) {\r\n material.octreeSpacing = cloud.spacing;\r\n material.octreeSize = parseFloat(cloud.root.size);\r\n material.octreeCorner = new Vector3()\r\n .add(cloud.root.center)\r\n .subScalar(cloud.root.size / 2.0);\r\n }\r\n\r\n let intensityRange = cloud.intensityRange;\r\n if (intensityRange) {\r\n let intensity = new Vector2(intensityRange.min,\r\n intensityRange.max);\r\n material.intensityRange = intensity;\r\n }\r\n\r\n let maxColor = cloud.maxColor;\r\n if (maxColor) {\r\n let maxValue = closestPowerOfTwo(maxColor);\r\n material.rgbMax = maxValue;\r\n }\r\n\r\n let tightBoundingBox = this.combinedBoundingBox;\r\n if (tightBoundingBox) {\r\n let height = new Vector2(tightBoundingBox.min.z,\r\n tightBoundingBox.max.z);\r\n material.heightRange = height;\r\n }\r\n }\r\n\r\n updateCloudSampling() {\r\n let percent = this.visiblePointsTarget / this.numLoadedPoints;\r\n percent = Math.min(1.0, percent);\r\n\r\n this.clouds.forEach(cloud => {\r\n if (!(cloud instanceof GenericPointCloud)) return;\r\n if (!cloud.visible || !cloud.root) return;\r\n\r\n cloud.root.children.forEach(child => {\r\n if (!child.geometry) return;\r\n let numPoints = child.numPoints;\r\n let sampledPoints = Math.floor(numPoints * percent);\r\n child.geometry.setDrawRange(0, sampledPoints);\r\n });\r\n });\r\n }\r\n\r\n updateCrossSection(start, end, width) {\r\n this.clouds.forEach(pointcloud => {\r\n let material = pointcloud.materialScene;\r\n material.crossSectionStart = start;\r\n material.crossSectionEnd = end;\r\n material.crossSectionWidth = width;\r\n material.needsUpdate = true;\r\n });\r\n }\r\n\r\n calculatePointsVisible() {\r\n let visibleNodes = this.scene.children\r\n .filter(x => x instanceof Points)\r\n .filter(x => x.visible) as Points[];\r\n\r\n this.numVisiblePoints = 0;\r\n this.numSceneNodesVisible = visibleNodes.length;\r\n\r\n visibleNodes.forEach(node => {\r\n let geometry = node.geometry as BufferGeometry;\r\n let numPoints = geometry.attributes.position.count;\r\n let numVisible = Math.min(numPoints, geometry.drawRange.count);\r\n this.numVisiblePoints += numVisible;\r\n });\r\n }\r\n\r\n updateVisibilityTexture(cloud: StreamablePointCloud, material) {\r\n // Static sizing, exit the function\r\n if (!material.adaptiveSize) return;\r\n\r\n let nodes = cloud.getVisibleNodes();\r\n let texture = material.visibleNodesTexture;\r\n let data = texture.image.data;\r\n\r\n let nodeMap = new Map();\r\n let visibleNodeTextureOffsets = new Map();\r\n let offsetsToChild = new Array(nodes.length).fill(Infinity);\r\n\r\n // Clear previous values\r\n for (let i = 0; i < data.length; i++) {\r\n data[i] = 0;\r\n }\r\n\r\n nodes.forEach((node, nodeIndex) => {\r\n nodeMap.set(node.name, node);\r\n visibleNodeTextureOffsets.set(node, nodeIndex);\r\n\r\n if (nodeIndex > 0) {\r\n let index = parseInt(node.name.slice(-1));\r\n let parentName = node.name.slice(0, -1);\r\n let parent = nodeMap.get(parentName);\r\n let parentOffset = visibleNodeTextureOffsets.get(parent);\r\n\r\n let parentOffsetToChild = (nodeIndex - parentOffset);\r\n\r\n offsetsToChild[parentOffset] = Math.min(offsetsToChild[parentOffset], parentOffsetToChild);\r\n\r\n data[parentOffset * 4 + 0] = data[parentOffset * 4 + 0] | (1 << index);\r\n data[parentOffset * 4 + 1] = (offsetsToChild[parentOffset] >> 8);\r\n data[parentOffset * 4 + 2] = (offsetsToChild[parentOffset] % 256);\r\n }\r\n\r\n let lodOffset = 0.0;\r\n let density = node.density;\r\n\r\n if (typeof density === \"number\" && !Number.isNaN(density)) {\r\n lodOffset = Math.log2(density) / 2 - 1.5;\r\n }\r\n\r\n let offsetUint8 = (lodOffset + 10) * 10;\r\n data[nodeIndex * 4 + 3] = offsetUint8;\r\n });\r\n\r\n texture.needsUpdate = true;\r\n }\r\n\r\n updateClipBoxTexture(material: PointCloudMaterial) {\r\n let pointMarkup = this.controls.pointMarkup;\r\n let texture = material.clipBoxTexture;\r\n\r\n let clippingBoxes = pointMarkup.clippingBoxes;\r\n let numClipBoxes = clippingBoxes.length;\r\n\r\n clippingBoxes.forEach((clippingBox, index) => {\r\n if (index >= texture.image.width) return;\r\n\r\n const position = clippingBox.position;\r\n const scale = clippingBox.scale;\r\n const hidePoints = clippingBox.hidePoints;\r\n const updateClassification = clippingBox.updateClassification;\r\n const newClassification = clippingBox.newClassification;\r\n const ignoredClassification = clippingBox.ignoredClassification;\r\n const inverse = getEulerInverse(clippingBox.rotation);\r\n\r\n // position\r\n assignPackedData(texture, index, 0, position.x);\r\n assignPackedData(texture, index, 1, position.y);\r\n assignPackedData(texture, index, 2, position.z);\r\n\r\n // scale\r\n assignPackedData(texture, index, 3, scale.x);\r\n assignPackedData(texture, index, 4, scale.y);\r\n assignPackedData(texture, index, 5, scale.z);\r\n\r\n // rotation\r\n assignPackedData(texture, index, 6, inverse.x);\r\n assignPackedData(texture, index, 7, inverse.y);\r\n assignPackedData(texture, index, 8, inverse.z);\r\n\r\n assignPackedData(texture, index, 9, hidePoints);\r\n assignPackedData(texture, index, 10, updateClassification);\r\n assignPackedData(texture, index, 11, newClassification);\r\n assignPackedData(texture, index, 12, ignoredClassification);\r\n });\r\n\r\n if (numClipBoxes > 0) {\r\n texture.needsUpdate = true;\r\n }\r\n\r\n material.updateNumClippingBoxes(numClipBoxes);\r\n }\r\n\r\n updateAreaTriangleTexture(material) {\r\n let texture = material.areaTriangleTexture;\r\n\r\n const controller = this.controls.measurements;\r\n let areaGeometry = controller.getAreaGeometry();\r\n\r\n let numAreaTriangles = 0;\r\n areaGeometry.forEach(data => {\r\n data.indices.forEach(triangleIndex => {\r\n let index = numAreaTriangles;\r\n if (index >= texture.image.width) {\r\n return;\r\n }\r\n\r\n // volume status\r\n assignPackedData(texture, index, 0, data.volumeStatus);\r\n\r\n // vertex #1\r\n let vertex1 = data.vertices[triangleIndex[0]];\r\n assignPackedData(texture, index, 1, vertex1.x);\r\n assignPackedData(texture, index, 2, vertex1.y);\r\n assignPackedData(texture, index, 3, vertex1.z);\r\n\r\n // vertex #2\r\n let vertex2 = data.vertices[triangleIndex[1]];\r\n assignPackedData(texture, index, 4, vertex2.x);\r\n assignPackedData(texture, index, 5, vertex2.y);\r\n assignPackedData(texture, index, 6, vertex2.z);\r\n\r\n // vertex #3\r\n let vertex3 = data.vertices[triangleIndex[2]];\r\n assignPackedData(texture, index, 7, vertex3.x);\r\n assignPackedData(texture, index, 8, vertex3.y);\r\n assignPackedData(texture, index, 9, vertex3.z);\r\n\r\n numAreaTriangles += 1;\r\n });\r\n });\r\n\r\n if (numAreaTriangles > 0) {\r\n texture.needsUpdate = true;\r\n }\r\n\r\n material.updateNumAreaTriangles(numAreaTriangles);\r\n }\r\n\r\n pointsInRadius(position, size) {\r\n var points = [];\r\n\r\n this.clouds.forEach(cloud => {\r\n // Grab valid nodes\r\n let nodes = cloud.getVisibleNodes(node => {\r\n let dx = Math.abs(node.center.x - position.x);\r\n let dy = Math.abs(node.center.y - position.y);\r\n\r\n return !((dx > node.size) || (dy > node.size));\r\n });\r\n\r\n // Grab valid points\r\n nodes.forEach(node => {\r\n let geometry = node.pointsScene.geometry as BufferGeometry;\r\n let positions = geometry.attributes.position;\r\n\r\n for (var i = 0; i < positions.count; i++) {\r\n let x = positions.getX(i) + node.pointsScene.position.x;\r\n let y = positions.getY(i) + node.pointsScene.position.y;\r\n let z = positions.getZ(i) + node.pointsScene.position.z;\r\n\r\n let dx = Math.abs(x - position.x);\r\n let dy = Math.abs(y - position.y);\r\n\r\n if ((dx > size) || (dy > size)) {\r\n continue;\r\n }\r\n\r\n let point = new Vector3(x, y, z);\r\n points.push(point);\r\n }\r\n });\r\n });\r\n\r\n return points;\r\n }\r\n\r\n pointsInPolygon(points, vertices) {\r\n let pointsInPolygon = [];\r\n\r\n points.forEach(point => {\r\n if (pointInPolygon(point, vertices)) {\r\n pointsInPolygon.push(point);\r\n }\r\n });\r\n\r\n return pointsInPolygon;\r\n }\r\n\r\n getSampledPoints(points, highest, keyfunc) {\r\n let samples = {};\r\n points.forEach(point => {\r\n let key = keyfunc(point);\r\n if (!(key in samples)) {\r\n samples[key] = [];\r\n }\r\n\r\n samples[key].push(point);\r\n });\r\n\r\n let dtmPoints = [];\r\n let keys = Object.keys(samples);\r\n keys.forEach(key => {\r\n let data = samples[key];\r\n data.sort((a, b) => (a.z > b.z) ? 1 : -1);\r\n\r\n let sampled = highest\r\n ? data[data.length - 1]\r\n : data[0];\r\n\r\n dtmPoints.push(sampled);\r\n });\r\n\r\n return dtmPoints;\r\n }\r\n\r\n getCameraFrustum() {\r\n // Calculate current view frustum\r\n const camera = this.viewer.camera;\r\n camera.updateProjectionMatrix();\r\n camera.updateMatrixWorld(true);\r\n camera.matrixWorldInverse.copy(camera.matrixWorld).invert();\r\n\r\n let cameraViewProjectionMatrix = new Matrix4();\r\n cameraViewProjectionMatrix.multiplyMatrices(\r\n camera.projectionMatrix,\r\n camera.matrixWorldInverse\r\n );\r\n\r\n let frustum = new Frustum();\r\n frustum.setFromProjectionMatrix(cameraViewProjectionMatrix);\r\n return frustum;\r\n }\r\n\r\n manageNodeCache() {\r\n let stack = [];\r\n let unusedNodes = [];\r\n let numVisible = 0;\r\n let numHidden = 0;\r\n\r\n this.streamingPointClouds.forEach(cloud => {\r\n if (!cloud.root) return;\r\n stack.push(cloud.root);\r\n });\r\n\r\n while (stack.length > 0) {\r\n let object = stack.shift();\r\n\r\n if (object.visible) {\r\n numVisible++;\r\n } else if (object.loaded) {\r\n numHidden++;\r\n unusedNodes.push(object);\r\n } else {\r\n continue;\r\n }\r\n\r\n object.children.forEach(child => {\r\n stack.push(child);\r\n });\r\n }\r\n\r\n const numberOfNodes = numVisible + numHidden;\r\n if (numberOfNodes < this.nodeCacheSize) return;\r\n\r\n // We delete from our list of unused nodes plus an extra percentage of the total\r\n let numberToDelete = numberOfNodes - 0.8 * this.nodeCacheSize;\r\n numberToDelete = Math.min(numberToDelete, numHidden);\r\n if (numberToDelete === 0) return;\r\n\r\n // Delete unused nodes, starting at the highest detail level we have\r\n unusedNodes.reverse();\r\n unusedNodes = unusedNodes.slice(0, numberToDelete);\r\n unusedNodes.forEach(node => {\r\n node.dispose();\r\n });\r\n }\r\n\r\n launchNewExecutables() {\r\n let numLoading = 0;\r\n let cloudsToExecute = [];\r\n\r\n this.genericPointClouds.forEach(cloud => {\r\n if ((!cloud.canReadData) || (!cloud.visible) || (cloud.loaded)) return;\r\n if (numLoading >= this.maxUnloadedClouds) return;\r\n\r\n numLoading += 1;\r\n\r\n if (!cloud.exeRunning) {\r\n let timeNow = performance.now();\r\n let timeSinceLaunch = timeNow - this.lastExeLaunched;\r\n if (timeSinceLaunch > this.exeLaunchTimeout) {\r\n this.lastExeLaunched = timeNow;\r\n cloudsToExecute.push(cloud);\r\n }\r\n }\r\n });\r\n\r\n // Launch exe for new\r\n if (cloudsToExecute.length > 0) {\r\n let cloud = cloudsToExecute.shift();\r\n cloud.launchExecutable();\r\n return;\r\n }\r\n }\r\n\r\n loadUnloadedGeometry() {\r\n const nodesToLoad = this.unloadedGeometry\r\n .slice(0, this.maxUnloadedNodes);\r\n\r\n nodesToLoad.forEach(node => {\r\n node.load();\r\n });\r\n }\r\n\r\n updateGenericPointClouds(frustum: Frustum) {\r\n if (isStaticSite || !this.shouldUpdate) return;\r\n\r\n this.genericPointClouds.forEach(cloud => {\r\n // Hide all nodes\r\n cloud.hideDescendants();\r\n });\r\n\r\n if (!this.cameraList.waitForCameras) {\r\n // Load visible nodes\r\n this.calculateGenericVisibility(frustum);\r\n }\r\n }\r\n\r\n updateStreamingPointClouds(frustum: Frustum) {\r\n if (!this.shouldUpdate) return;\r\n\r\n this.streamingPointClouds.forEach(cloud => {\r\n // Hide all nodes\r\n cloud.hideDescendants();\r\n });\r\n\r\n // Load visible nodes\r\n this.calculateStreamingVisibility(frustum);\r\n\r\n // Remove unused nodes\r\n this.manageNodeCache();\r\n }\r\n\r\n /** @private */\r\n calculateGenericVisibility(frustum: Frustum) {\r\n if (this.cameraList.waitForCameras) return;\r\n\r\n let nodes = [];\r\n\r\n this.genericPointClouds.forEach(cloud => {\r\n if (!cloud.visible || !cloud.root) return;\r\n\r\n const newNodes = [cloud.root, ...cloud.root.children];\r\n nodes = [...nodes, ...newNodes];\r\n });\r\n\r\n let numLoadedPoints = 0;\r\n\r\n nodes.forEach(node => {\r\n // Ignore nodes based on our view frustrum\r\n if (!frustum.intersectsBox(node.boundingBox)) {\r\n return;\r\n }\r\n\r\n // Add node to scene if data is loaded, or else add to unloaded list\r\n if (node.isGeometryNode && (!node.parent || node.parent.isTreeNode)) {\r\n if (node.loaded && this.loadedToGPUThisFrame < this.maxloadedToGPUPerFrame) {\r\n node.addToScene();\r\n this.loadedToGPUThisFrame++;\r\n } else {\r\n this.unloadedGeometry.push(node);\r\n }\r\n }\r\n\r\n // Update node visibility for loaded nodes\r\n if (node.isTreeNode) {\r\n node.setVisibility(true, this.boundsVisible);\r\n numLoadedPoints += node.numPoints;\r\n }\r\n });\r\n\r\n this.numLoadedPoints += numLoadedPoints;\r\n }\r\n\r\n /** @private */\r\n calculateStreamingVisibility(frustum: Frustum) {\r\n if (this.cameraList.waitForCameras) return;\r\n\r\n const priorityQueue = new BinaryHeap(x => 1 / x.weight);\r\n\r\n this.streamingPointClouds.forEach(cloud => {\r\n if (!cloud.visible || !cloud.root) return;\r\n\r\n priorityQueue.push({\r\n node: cloud.root,\r\n weight: Number.MAX_VALUE\r\n });\r\n });\r\n\r\n let numLoadedPoints = 0;\r\n\r\n const maxAllowedPoints = this.visiblePointsTarget;\r\n const maxNodeDistance = this.materialDefaults.distance;\r\n const controls = this.viewer.controls;\r\n const measurePoint = controls.getCameraTarget();\r\n const cameraPosition = this.viewer.camera.position;\r\n\r\n const screenHeight = this.viewer.height;\r\n const fov = MathUtils.degToRad(Math.max(this.viewer.camera.fov, 45));\r\n const minNodeSize = this.viewer.height * this.minPixelPercent;\r\n\r\n while (priorityQueue.size > 0) {\r\n const element = priorityQueue.pop();\r\n const node = element.node as StreamablePointCloudNode;\r\n const newPointsTarget = numLoadedPoints + node.numPoints;\r\n\r\n // Check to see if the point limit will be exceeded\r\n if (newPointsTarget >= maxAllowedPoints) {\r\n continue;\r\n }\r\n\r\n // Ignore nodes based on our view frustrum\r\n if (!frustum.intersectsBox(node.boundingBox)) {\r\n continue;\r\n }\r\n\r\n // Ignore nodes based on distance slider\r\n let bounds2d = new Vector2(node.center.x, node.center.y);\r\n let camera2d = new Vector2(measurePoint.x, measurePoint.y);\r\n let nodeDistance = bounds2d.distanceTo(camera2d);\r\n if (nodeDistance > (node.radius + maxNodeDistance)) {\r\n continue;\r\n }\r\n\r\n if (node.isGeometryNode && (!node.parent || node.parent.isTreeNode)) {\r\n if (node.loaded && this.loadedToGPUThisFrame < this.maxloadedToGPUPerFrame) {\r\n node.addToScene();\r\n this.loadedToGPUThisFrame++;\r\n } else {\r\n this.unloadedGeometry.push(node);\r\n }\r\n }\r\n\r\n if (node.isTreeNode) {\r\n node.setVisibility(true, this.boundsVisible);\r\n numLoadedPoints += node.numPoints;\r\n }\r\n\r\n node.children.forEach((child: StreamablePointCloudNode) => {\r\n const childDistance = child.center.distanceTo(cameraPosition);\r\n const insideSphere = childDistance < child.radius;\r\n\r\n // Pixel size based filtering\r\n const projFactor = getProjFactor(fov, childDistance, screenHeight);\r\n const nodeScreenSize = child.radius * projFactor;\r\n if (nodeScreenSize < minNodeSize) return;\r\n\r\n const weight = insideSphere\r\n ? Number.MAX_VALUE\r\n : nodeScreenSize;\r\n\r\n priorityQueue.push({\r\n node: child,\r\n weight: weight\r\n });\r\n });\r\n }\r\n\r\n this.numLoadedPoints += numLoadedPoints;\r\n }\r\n\r\n updateMaterials() {\r\n this.clouds.forEach(cloud => {\r\n cloud.materials.forEach(material => {\r\n if (!material || !cloud.root) return;\r\n\r\n this.updateMaterialValues(cloud, material);\r\n\r\n if (!material.gpuPicker) {\r\n this.updateAreaTriangleTexture(material);\r\n this.updateClipBoxTexture(material);\r\n }\r\n\r\n if (cloud instanceof StreamablePointCloud) {\r\n this.updateVisibilityTexture(cloud, material);\r\n }\r\n });\r\n });\r\n }\r\n\r\n update() {\r\n this.numLoadedPoints = 0;\r\n this.loadedToGPUThisFrame = 0;\r\n this.unloadedGeometry = [];\r\n\r\n const frustum = this.getCameraFrustum();\r\n\r\n // Update clouds based on current view\r\n this.updateGenericPointClouds(frustum);\r\n this.updateStreamingPointClouds(frustum);\r\n\r\n // Load unloaded geometry data\r\n this.loadUnloadedGeometry();\r\n\r\n // Create python exectutables for generic poinclouds\r\n this.launchNewExecutables();\r\n\r\n // Update material and texture data\r\n this.updateMaterials();\r\n\r\n // Sample raw pointclouds based on total points loaded\r\n this.updateCloudSampling();\r\n\r\n this.calculatePointsVisible();\r\n }\r\n}","import { PointCloudNode, PointCloud, PointCloudManager } from '.';\r\nimport LocalScene from '../projections';\r\nimport { PythonExecutable } from '../../../executable';\r\nimport { LineSegments, Points, Vector3 } from 'three';\r\nimport { toast } from '../../../app';\r\nimport { t } from '../../../localization';\r\nimport { readFileBuffer } from '../file-system-loader';\r\nimport { fse, tempDirectoryPath } from '../../../electron-modules';\r\nimport { AsyncWorkerPool } from '../worker-pool';\r\n\r\nconst workerPool = new AsyncWorkerPool(\"point-decoder-buffer.js\");\r\n\r\n/** Processed pointcloud node */\r\nclass GenericPointCloudNode extends PointCloudNode {\r\n public cloud: GenericPointCloud;\r\n public parent: GenericPointCloudRootNode;\r\n private path = null;\r\n private precision;\r\n private _shift;\r\n\r\n constructor(cloud, parent) {\r\n super();\r\n\r\n this.cloud = cloud;\r\n this.parent = parent;\r\n }\r\n\r\n get shift() {\r\n return this._shift;\r\n }\r\n\r\n set shift(value) {\r\n this._shift = value;\r\n }\r\n\r\n loadFromData(data) {\r\n this.numPoints = data.num_points;\r\n this.path = data.bytes_path;\r\n this.precision = data.precision;\r\n\r\n // Convert array to vector\r\n data.xyz_min = new Vector3(...data.xyz_min);\r\n data.xyz_max = new Vector3(...data.xyz_max);\r\n data.offset = new Vector3(...data.offset);\r\n\r\n // Calculate bounding box size\r\n let size = new Vector3()\r\n .add(data.xyz_max)\r\n .sub(data.xyz_min);\r\n\r\n // Calculate bounding box center\r\n let center = new Vector3()\r\n .add(data.xyz_min)\r\n .add(data.xyz_max)\r\n .divideScalar(2.0)\r\n .sub(data.offset);\r\n\r\n this.size = Math.max(size.x, size.y, size.z);\r\n this.nodeCenter = center;\r\n\r\n // Safe to add to parent's child list now\r\n this.parent.addChildNode(this);\r\n\r\n // Update root node info\r\n this.shift = LocalScene.offsetToScene(data.offset);\r\n\r\n this.cloud.updateColorLimits(data.rgb_max);\r\n this.cloud.updateIntensityRange(\r\n data.intensity_min, data.intensity_max);\r\n this.cloud.updateBoundingBox({\r\n min: data.xyz_min,\r\n max: data.xyz_max\r\n });\r\n this.cloud.updateRootNode();\r\n }\r\n\r\n getGeometry(data) {\r\n this.setGeometry(data);\r\n\r\n // Update unique values and min/max values\r\n this.cloud.updateClassifications(data.classification);\r\n\r\n this.loaded = true;\r\n this.loading = false;\r\n }\r\n\r\n addToScene() {\r\n // Create the pointcloud\r\n let pointsScene = new Points(this.geometry, this.cloud.materialScene);\r\n let pointsPicker = new Points(this.geometry, this.cloud.materialPicker);\r\n\r\n // Create bounding box object;\r\n let boundingBox = this.cloud.generateEdgeMesh(this.size);\r\n\r\n this.addCloudData(pointsPicker, pointsScene, boundingBox);\r\n }\r\n\r\n async getBinaryData() {\r\n const buffer = await readFileBuffer(this.path);\r\n fse.remove(this.path);\r\n\r\n const values = {\r\n buffer: buffer,\r\n precision: this.precision,\r\n numPoints: this.numPoints\r\n };\r\n\r\n\r\n const data = await workerPool.postMessage(values, [values.buffer]);\r\n\r\n // Convert raw buffer to float array\r\n data.positions = new Float32Array(data.positions);\r\n data.intensity = new Float32Array(data.intensity);\r\n data.classification = new Float32Array(data.classification);\r\n data.colors = new Float32Array(data.colors);\r\n\r\n return data;\r\n }\r\n\r\n async load() {\r\n if ((this.loaded) || (this.loading)) return;\r\n\r\n this.loading = true;\r\n\r\n const data = await this.getBinaryData();\r\n this.getGeometry(data);\r\n }\r\n}\r\n\r\n/** Simulated processed pointcloud root node */\r\nclass GenericPointCloudRootNode extends GenericPointCloudNode {\r\n constructor(cloud) {\r\n super(cloud, null);\r\n\r\n this.numPoints = 0;\r\n this.boundingBoxMesh = new LineSegments();\r\n this.nodeCenter = new Vector3();\r\n this.size = 0;\r\n }\r\n\r\n get center() {\r\n return this.nodeCenter;\r\n }\r\n\r\n /** Function override */\r\n dispose() {\r\n this.pointsScene = null;\r\n this.pointsPicker = null;\r\n this.boundingBoxMesh = null;\r\n }\r\n\r\n updateSizeInfo(data) {\r\n // Calculate bounding box size\r\n let size = new Vector3()\r\n .add(data.max)\r\n .sub(data.min);\r\n\r\n this.size = Math.max(size.x, size.y, size.z);\r\n\r\n // Calculate bounding box center\r\n let center = new Vector3()\r\n .add(data.min)\r\n .add(data.max)\r\n .divideScalar(2.0);\r\n\r\n this.nodeCenter = center;\r\n\r\n // Reset bounding geometry\r\n this._bounding_sphere = null;\r\n this._bounding_box = null;\r\n }\r\n\r\n async load() {\r\n if ((this.loaded) || (this.loading)) return;\r\n\r\n this.loaded = true;\r\n this.loading = false;\r\n }\r\n\r\n getGeometry() {\r\n return;\r\n }\r\n\r\n addToScene() {\r\n this.pointsScene = new Points();\r\n this.pointsPicker = new Points();\r\n }\r\n}\r\n\r\n/** Processed pointcloud */\r\nexport class GenericPointCloud extends PointCloud {\r\n private workerExe: PythonExecutable;\r\n private file = null;\r\n private header = null;\r\n public loaded = false;\r\n private loading: boolean;\r\n private cancelled = false;\r\n private loadStart;\r\n private timeEnd;\r\n private byteCutoffSize = 10 * 1024**3;\r\n private pointsDataParsed = 0;\r\n private numSampledPoints = 5000000;\r\n private minPointSize = 100000;\r\n public exeRunning = false;\r\n public canReadData = false;\r\n public percent;\r\n\r\n constructor(pointclouds: PointCloudManager) {\r\n super(pointclouds);\r\n this.workerExe = new PythonExecutable();\r\n }\r\n\r\n get shift() {\r\n return LocalScene.sceneOffset;\r\n }\r\n\r\n get size() {\r\n return Math.max.apply(null, this.header.size);\r\n }\r\n\r\n /** Get bounding box with global shift applied */\r\n get tightBoundingBox() {\r\n let bbox = this._tightBoundingBox;\r\n if (!bbox) return null;\r\n\r\n let boundingBox = {\r\n min: new Vector3().add(bbox.min).sub(this.shift),\r\n max: new Vector3().add(bbox.max).sub(this.shift)\r\n };\r\n\r\n return boundingBox;\r\n }\r\n\r\n /** Get estimated bounding box using header information */\r\n get estimatedBoundingBox() {\r\n return {\r\n max: new Vector3(...this.header.maxs).sub(this.shift),\r\n min: new Vector3(...this.header.mins).sub(this.shift)\r\n };\r\n }\r\n\r\n get headerFileInfo() {\r\n return this.header?.file_info;\r\n }\r\n\r\n get saved() {\r\n return this.file.saved;\r\n }\r\n\r\n get isLargeFile() {\r\n let isLargeFile = this.header\r\n ? this.header.number_of_bytes > this.byteCutoffSize\r\n : false;\r\n\r\n return isLargeFile;\r\n }\r\n\r\n dispose() {\r\n this.setState(false);\r\n this.disposeNodes();\r\n\r\n this.cancelled = true;\r\n this.workerExe.destroy();\r\n }\r\n\r\n fileLoadStart() {\r\n this.loading = true;\r\n this.loaded = false;\r\n this.updatePercent(0);\r\n }\r\n\r\n fileLoadFinish() {\r\n this.loading = false;\r\n this.loaded = true;\r\n this.timeEnd = performance.now();\r\n this.updatePercent(100);\r\n const elapsed = (this.timeEnd - this.loadStart) / 1000;\r\n console.log(`Point cloud loaded: ${this.file.name}. ${elapsed.toFixed(2)}s`);\r\n }\r\n\r\n fileLoadCancel() {\r\n this.loading = false;\r\n this.loaded = false;\r\n }\r\n\r\n fileLoadProgress() {\r\n let points_to_process = this.header.points_to_process;\r\n let percent = this.pointsDataParsed / points_to_process;\r\n this.updatePercent(100 * percent);\r\n }\r\n\r\n updatePercent(percent) {\r\n this.percent = percent;\r\n }\r\n\r\n updateRootNode() {\r\n this.root.updateSizeInfo(this.tightBoundingBox);\r\n }\r\n\r\n load(file) {\r\n this.file = file;\r\n\r\n this.pointsDataParsed = 0;\r\n this.canReadData = true;\r\n\r\n // Add pointcloud and set parameters\r\n this.pointclouds.addPointCloud(this);\r\n this.setIdentifier(file.identifier);\r\n this.setVisibility(file.visible);\r\n\r\n this.fileLoadStart();\r\n }\r\n\r\n fileLoadFinished(success) {\r\n if (success) {\r\n this.fileLoadFinish();\r\n } else {\r\n this.fileLoadCancel();\r\n }\r\n }\r\n\r\n launchExecutable() {\r\n this.exeRunning = true;\r\n this.loadStart = performance.now();\r\n\r\n const lasFilePath = this.file.path;\r\n\r\n let commands = [\r\n \"-p\", \"convert_engine_points\",\r\n \"--input_file\", lasFilePath,\r\n \"--output_folder\", tempDirectoryPath,\r\n \"--units\", LocalScene.dataProjectionUnits,\r\n \"--min_chunk_size\", this.minPointSize,\r\n \"--max_points\", this.numSampledPoints\r\n ];\r\n\r\n this.workerExe.run({\r\n command: commands,\r\n onLine: jsonData => {\r\n if (!jsonData) return;\r\n const {type, data} = jsonData;\r\n\r\n if (type === \"header\") {\r\n this.parseHeaderResponse(data);\r\n } else if (type === \"points\") {\r\n this.parsePointsResponse(data);\r\n }\r\n },\r\n onClose: () => {\r\n if (this.cancelled) return;\r\n\r\n const pointsToProcess = this.header?.points_to_process;\r\n const allPointsLoaded = pointsToProcess === this.pointsDataParsed;\r\n\r\n if (!allPointsLoaded) {\r\n this.error = true;\r\n toast.error(t(\"toast.points-load-error\", {\r\n name: this.file.name\r\n }));\r\n }\r\n\r\n this.fileLoadFinished(true);\r\n }\r\n });\r\n }\r\n\r\n parseHeaderResponse(data) {\r\n this.header = data;\r\n this.root = new GenericPointCloudRootNode(this);\r\n\r\n if (this.isLargeFile) {;\r\n toast.warning(t(\"toast.large-point-cloud\", {\r\n name: this.file.name\r\n }));\r\n }\r\n }\r\n\r\n parsePointsResponse(data) {\r\n // Update loaded percent\r\n this.pointsDataParsed += data['point_count'];\r\n this.fileLoadProgress();\r\n\r\n // Add new node to pointcloud\r\n let child = new GenericPointCloudNode(this, this.root);\r\n child.loadFromData(data);\r\n\r\n this.pointclouds.updateMinimapExtent();\r\n\r\n if (this.saved) return;\r\n this.viewer.zoomToSceneExtent(this.estimatedBoundingBox, false);\r\n }\r\n\r\n getVisibleNodes(condition?): PointCloudNode[] {\r\n let visibleNodes = [];\r\n\r\n // All data for raw pointclouds is contained in a single level\r\n this.root?.children.forEach(node => {\r\n if (!node.visible) return;\r\n if (condition && !condition(node)) return;\r\n\r\n visibleNodes.push(node);\r\n });\r\n\r\n return visibleNodes;\r\n }\r\n\r\n hideDescendants() {\r\n if (!this.root) return;\r\n\r\n [this.root, ...this.root.children].forEach(node => {\r\n node.setVisibility(false, false);\r\n });\r\n }\r\n}\r\n","import { Points, Vector3 } from \"three\";\r\nimport { PointCloud, PointCloudManager } from \".\";\r\nimport { toast } from \"../../../app\";\r\nimport { t } from \"../../../localization\";\r\nimport { readFileJSON } from \"../file-system-loader\";\r\nimport { PointCloudNode } from \"./point-cloud\";\r\n\r\n/** Base class for streamable cloud node */\r\nexport class StreamablePointCloudNode extends PointCloudNode {\r\n public cloud: StreamablePointCloud;\r\n public parent: StreamablePointCloudNode;\r\n protected level;\r\n\r\n constructor(name, level, center, size) {\r\n super();\r\n\r\n this.name = name;\r\n this.level = level;\r\n this.size = size;\r\n this.nodeCenter = center;\r\n }\r\n\r\n get shift() {\r\n return this.cloud.shift;\r\n }\r\n\r\n getChildOffset(index) {\r\n console.warn(\"Not implemented\");\r\n return {x: 0, y: 0, z: 0};\r\n }\r\n\r\n addChildNode(node) {\r\n this.children.push(node);\r\n\r\n // Make sure child nodes are sorted by index\r\n this.children.sort((a,b) => {\r\n let indexA = parseInt(a.name.slice(-1));\r\n let indexB = parseInt(b.name.slice(-1));\r\n return indexA - indexB;\r\n });\r\n }\r\n\r\n getChildNode(index) {\r\n const childName = `${this.name}${index}`;\r\n const childSize = this.size / 2.0;\r\n const childLevel = this.level + 1;\r\n\r\n const {x,y,z} = this.getChildOffset(index);\r\n\r\n const childCenter = new Vector3(\r\n this.nodeCenter.x + (x - 0.5) * childSize,\r\n this.nodeCenter.y + (y - 0.5) * childSize,\r\n this.nodeCenter.z + (z - 0.5) * childSize\r\n );\r\n\r\n const NodeConstructor = this.constructor as any;\r\n return new NodeConstructor(this.cloud, this, childName,\r\n childLevel, childCenter, childSize);\r\n }\r\n\r\n addToScene() {\r\n // Create pointcloud object\r\n let pointsScene = new Points(this.geometry, this.cloud.materialScene);\r\n let pointsPicker = new Points(this.geometry, this.cloud.materialPicker);\r\n\r\n pointsScene.visible = false;\r\n pointsPicker.visible = false;\r\n\r\n // Create bounding box object;\r\n let boundingBox = this.cloud.generateEdgeMesh(this.size);\r\n\r\n this.addCloudData(pointsPicker, pointsScene, boundingBox);\r\n }\r\n}\r\n\r\n/** Base class for streamable cloud */\r\nexport class StreamablePointCloud extends PointCloud {\r\n public spacing = null;\r\n protected structure = null;\r\n private _shift;\r\n\r\n constructor(pointclouds: PointCloudManager) {\r\n super(pointclouds);\r\n }\r\n\r\n get shift() {\r\n return this._shift;\r\n }\r\n\r\n set shift(value) {\r\n this._shift = value;\r\n }\r\n\r\n get size() {\r\n return this.root.size;\r\n }\r\n\r\n get dataDir() {\r\n return this.structure.path;\r\n }\r\n\r\n get saved() {\r\n return this.structure.saved;\r\n }\r\n\r\n get metadataPath() {\r\n console.warn(\"Not implemented\");\r\n return \"\";\r\n }\r\n\r\n async load(structure) {\r\n this.structure = structure;\r\n\r\n // Add pointcloud and set parameters\r\n this.pointclouds.addPointCloud(this);\r\n this.setName(structure.name);\r\n this.setVisibility(structure.visible);\r\n this.setIdentifier(structure.identifier);\r\n\r\n try {\r\n // Read index data\r\n const metadata = await readFileJSON(this.metadataPath);\r\n this.decodeMetadata(metadata);\r\n } catch(err) {\r\n this.error = true;\r\n console.error(err);\r\n toast.error(t(\"toast.points-load-error\", {\r\n name: structure.name\r\n }));\r\n }\r\n }\r\n\r\n decodeMetadata(data) {\r\n console.warn(\"Not implemented\");\r\n }\r\n\r\n getVisibleNodes(condition?): PointCloudNode[] {\r\n let visibleNodes = [];\r\n if (!this.root) return visibleNodes;\r\n\r\n let stack = [this.root];\r\n while (stack.length > 0) {\r\n let node = stack.shift();\r\n\r\n if (!node.visible) continue;\r\n if (condition && !condition(node)) continue;\r\n\r\n visibleNodes.push(node);\r\n node.children.forEach(child => {\r\n stack.push(child);\r\n });\r\n }\r\n\r\n return visibleNodes;\r\n }\r\n\r\n hideDescendants() {\r\n if (!this.root) return;\r\n\r\n let stack = [this.root];\r\n\r\n while (stack.length > 0) {\r\n let object = stack.shift();\r\n if (!object.visible) {\r\n continue;\r\n }\r\n\r\n object.setVisibility(false, false);\r\n object.children.forEach(child => {\r\n stack.push(child);\r\n });\r\n }\r\n }\r\n}\r\n","import { PointCloudManager, StreamablePointCloud, StreamablePointCloudNode } from '.';\r\nimport { readFileBuffer, readFileJSON} from \"../file-system-loader\";\r\nimport LocalScene from '../projections';\r\nimport { Vector3 } from 'three';\r\nimport { AsyncWorkerPool } from '../worker-pool';\r\n\r\ntype NodeArguments = ConstructorParameters\r\n\r\nconst workerPool = new AsyncWorkerPool(\"point-decoder-encompass.js\");\r\n\r\n/** Encompass style pointcloud node */\r\nclass EncompassPointCloudNode extends StreamablePointCloudNode {\r\n public cloud: EncompassPointCloud;\r\n public parent: EncompassPointCloudNode;\r\n\r\n constructor(cloud, parent, name, level, center, size,) {\r\n super(name, level, center, size);\r\n\r\n this.cloud = cloud;\r\n this.parent = parent;\r\n }\r\n\r\n get precision() {\r\n return this.cloud.precision;\r\n }\r\n\r\n get hierarchy() {\r\n return this.cloud.hierarchy;\r\n }\r\n\r\n getChildOffset(index) {\r\n return {\r\n x: index & 0b001,\r\n y: (index & 0b010) / 2,\r\n z: (index & 0b100) / 4\r\n };\r\n }\r\n\r\n async readNodeHierarchy() {\r\n console.warn(\"Not implemented\");\r\n }\r\n\r\n async getBinaryData() {\r\n let dataPath = this.cloud.getDataPath(this.name);\r\n let nodePath = `${dataPath}/${this.name}`;\r\n\r\n let minCorner = new Vector3()\r\n .add(this.nodeCenter)\r\n .subScalar(this.size/2);\r\n\r\n // Read node data\r\n const buffer = await readFileBuffer(nodePath);\r\n\r\n const values = {\r\n buffer: buffer,\r\n name: this.name,\r\n precision: this.precision,\r\n size: this.size,\r\n corner: minCorner\r\n };\r\n\r\n const data = await workerPool.postMessage(values, [values.buffer]);\r\n\r\n // Convert array to vector\r\n data.xyz_min = new Vector3(...data.xyz_min);\r\n data.xyz_max = new Vector3(...data.xyz_max);\r\n\r\n // Convert raw buffer to float array\r\n data.positions = new Float32Array(data.positions);\r\n data.intensity = new Float32Array(data.intensity);\r\n data.classification = new Float32Array(data.classification);\r\n data.colors = new Float32Array(data.colors);\r\n\r\n return data;\r\n }\r\n\r\n getGeometry(data) {\r\n this.setGeometry(data);\r\n\r\n this.numPoints = data.num_points;\r\n this.density = data.density;\r\n\r\n // Update unique values and min/max values\r\n this.cloud.updateClassifications(data.classification);\r\n this.cloud.updateColorLimits(data.rgb_max);\r\n this.cloud.updateIntensityRange(data.intensity_min, data.intensity_max);\r\n\r\n this.cloud.updateBoundingBox({\r\n min: data.xyz_min,\r\n max: data.xyz_max\r\n });\r\n\r\n this.loaded = true;\r\n this.loading = false;\r\n }\r\n\r\n async load() {\r\n if ((this.loaded) || (this.loading)) return;\r\n\r\n this.loading = true;\r\n\r\n await this.readNodeHierarchy();\r\n\r\n try {\r\n const data = await this.getBinaryData();\r\n this.getGeometry(data);\r\n } catch(err) {\r\n console.error(err);\r\n if (this.level !== 1) {\r\n this.parent.removeChildNode(this);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/** Encompass cloud node with no hierarchy */\r\nclass EncompassPointCloudNodeV0 extends EncompassPointCloudNode {\r\n constructor (...args: NodeArguments) {\r\n super(...args);\r\n }\r\n\r\n async readNodeHierarchy() {\r\n // No hierarchy is provided so we assume all 8 children exist\r\n // Missing nodes will be deleted later if the data doesnt exist\r\n for (let childIndex = 0; childIndex < 8; childIndex++) {\r\n let child = this.getChildNode(childIndex);\r\n this.addChildNode(child);\r\n }\r\n }\r\n}\r\n\r\n/** Encompass cloud node hierarchy inside r.idx */\r\nclass EncompassPointCloudNodeV1 extends EncompassPointCloudNode {\r\n constructor (...args: NodeArguments) {\r\n super(...args);\r\n }\r\n\r\n async readNodeHierarchy() {\r\n // Read legacy hierarchy\r\n for (let childIndex = 0; childIndex < 8; childIndex++) {\r\n let childName = `${this.name}${childIndex}`;\r\n let childExists = this.hierarchy[childName] !== undefined;\r\n if (!childExists) continue;\r\n let child = this.getChildNode(childIndex);\r\n this.addChildNode(child);\r\n }\r\n }\r\n}\r\n\r\n/** Encompass cloud node with folder based hierarchy */\r\nclass EncompassPointCloudNodeV2 extends EncompassPointCloudNode {\r\n constructor (...args: NodeArguments) {\r\n super(...args);\r\n }\r\n\r\n get isFolderRoot() {\r\n const nodeLength = (this.name.length - 1);\r\n return nodeLength % this.cloud.folderDepth === 0;\r\n }\r\n\r\n async loadHierarchy() {\r\n let dataPath = this.cloud.getDataPath(this.name);\r\n let hrcPath = `${dataPath}/${this.name}.hrc`;\r\n\r\n try {\r\n // Read hierarchy data\r\n const hierarchy = await readFileJSON(hrcPath);\r\n this.cloud.updateHierarchy(hierarchy);\r\n } catch {\r\n console.log(`Error reading hierarchy: ${this.name}`);\r\n }\r\n }\r\n\r\n async readNodeHierarchy() {\r\n if (this.isFolderRoot) {\r\n await this.loadHierarchy();\r\n }\r\n\r\n // Update children with known hierarchy\r\n const indices = this.hierarchy[this.name];\r\n indices?.forEach(childIndex => {\r\n let child = this.getChildNode(childIndex);\r\n this.addChildNode(child);\r\n });\r\n }\r\n}\r\n\r\n/** Encompass style pointcloud */\r\nexport class EncompassPointCloud extends StreamablePointCloud {\r\n public precision;\r\n public folderDepth;\r\n public hierarchy = {};\r\n\r\n constructor(pointclouds: PointCloudManager) {\r\n super(pointclouds);\r\n }\r\n\r\n get metadataPath() {\r\n return `${this.structure.path}/r.idx`;\r\n }\r\n\r\n getDataPath(node) {\r\n let dataDir = this.dataDir;\r\n let folderDepth = this.folderDepth;\r\n\r\n if (node === \"r\") {\r\n return dataDir;\r\n }\r\n\r\n let name = node.slice(1);\r\n if ((folderDepth) && (name.length >= folderDepth)) {\r\n let dirs = name.match(new RegExp('.{' + folderDepth + '}', 'g'));\r\n dataDir = `${dataDir}/${dirs.join(\"/\")}`;\r\n }\r\n\r\n return dataDir;\r\n }\r\n\r\n /** Decode cloud metadata. Cloud is already converted to meters */\r\n decodeMetadata(data) {\r\n this.precision = data.hasOwnProperty('precision')\r\n ? data.precision\r\n : 0.005;\r\n\r\n this.folderDepth = data.hasOwnProperty('hierarchy_step_size')\r\n ? data.hierarchy_step_size\r\n : null;\r\n\r\n this.spacing = data.hasOwnProperty('spacing')\r\n ? data.spacing\r\n : Math.sqrt(2) * data.size / 250.0;\r\n\r\n const offset = new Vector3(...data.point_offset);\r\n\r\n // Get our tight bounding box if available\r\n let tightBoundingBox = null;\r\n if (\"tight_bounding_box\" in data) {\r\n let box = data.tight_bounding_box;\r\n tightBoundingBox = {\r\n min: new Vector3(...box.min).sub(offset),\r\n max: new Vector3(...box.max).sub(offset)\r\n };\r\n }\r\n\r\n // Generate cloud root node\r\n let nodeSize = parseFloat(data.size);\r\n let nodeCenter = new Vector3(...data.center)\r\n .sub(offset);\r\n\r\n this.shift = LocalScene.offsetToScene(offset);\r\n\r\n const hasHierarchyV1 = this.checkLegacyHierarchy(data);\r\n const hasHierarchyV2 = data.hasOwnProperty('contains_hierarchy')\r\n ? data.contains_hierarchy\r\n : false;\r\n\r\n let RootNodeConstructor;\r\n if (hasHierarchyV1) {\r\n RootNodeConstructor = EncompassPointCloudNodeV1;\r\n } else if (hasHierarchyV2) {\r\n RootNodeConstructor = EncompassPointCloudNodeV2;\r\n } else {\r\n RootNodeConstructor = EncompassPointCloudNodeV0;\r\n }\r\n\r\n const rootNode = new RootNodeConstructor(\r\n this, null, \"r\", 1, nodeCenter, nodeSize);\r\n\r\n this.root = rootNode;\r\n this.updateBoundingBox(tightBoundingBox);\r\n this.pointclouds.updateMinimapExtent();\r\n\r\n if (this.saved) return;\r\n this.viewer.zoomToSceneExtent(this.tightBoundingBox, false);\r\n }\r\n\r\n updateHierarchy(hierarchy) {\r\n this.hierarchy = {\r\n ...this.hierarchy,\r\n ...hierarchy\r\n };\r\n }\r\n\r\n /** Check for legacy style hierarchy */\r\n checkLegacyHierarchy(data) {\r\n const availableNodes = data.hasOwnProperty('node_structure')\r\n ? data.node_structure\r\n : null;\r\n\r\n if (availableNodes && availableNodes.r) {\r\n console.log(\"Legacy hierarchy detected\");\r\n this.updateHierarchy(availableNodes);\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n","\r\n/**\r\n * Some types of possible point attribute data formats\r\n *\r\n * @class\r\n */\r\nconst PointAttributeTypes = {\r\n DATA_TYPE_DOUBLE: {ordinal: 0, name: \"double\", size: 8},\r\n DATA_TYPE_FLOAT: {ordinal: 1, name: \"float\", size: 4},\r\n DATA_TYPE_INT8: {ordinal: 2, name: \"int8\", size: 1},\r\n DATA_TYPE_UINT8: {ordinal: 3, name: \"uint8\", size: 1},\r\n DATA_TYPE_INT16: {ordinal: 4, name: \"int16\", size: 2},\r\n DATA_TYPE_UINT16: {ordinal: 5, name: \"uint16\", size: 2},\r\n DATA_TYPE_INT32: {ordinal: 6, name: \"int32\", size: 4},\r\n DATA_TYPE_UINT32: {ordinal: 7, name: \"uint32\", size: 4},\r\n DATA_TYPE_INT64: {ordinal: 8, name: \"int64\", size: 8},\r\n DATA_TYPE_UINT64: {ordinal: 9, name: \"uint64\", size: 8}\r\n};\r\n\r\nconst typenameTypeattributeMap = {\r\n \"double\": PointAttributeTypes.DATA_TYPE_DOUBLE,\r\n \"float\": PointAttributeTypes.DATA_TYPE_FLOAT,\r\n \"int8\": PointAttributeTypes.DATA_TYPE_INT8,\r\n \"uint8\": PointAttributeTypes.DATA_TYPE_UINT8,\r\n \"int16\": PointAttributeTypes.DATA_TYPE_INT16,\r\n \"uint16\": PointAttributeTypes.DATA_TYPE_UINT16,\r\n \"int32\": PointAttributeTypes.DATA_TYPE_INT32,\r\n \"uint32\": PointAttributeTypes.DATA_TYPE_UINT32,\r\n \"int64\": PointAttributeTypes.DATA_TYPE_INT64,\r\n \"uint64\": PointAttributeTypes.DATA_TYPE_UINT64,\r\n};\r\n\r\nlet i = 0;\r\nfor (let obj in PointAttributeTypes) {\r\n PointAttributeTypes[i] = PointAttributeTypes[obj];\r\n i++;\r\n}\r\n\r\nclass PointAttribute{\r\n name: any;\r\n type: any;\r\n numElements: any;\r\n byteSize: number;\r\n description: string;\r\n range: number[];\r\n static POSITION_CARTESIAN: PointAttribute;\r\n static RGBA_PACKED: PointAttribute;\r\n static COLOR_PACKED: any;\r\n static RGB_PACKED: PointAttribute;\r\n static NORMAL_FLOATS: PointAttribute;\r\n static INTENSITY: PointAttribute;\r\n static CLASSIFICATION: PointAttribute;\r\n static NORMAL_SPHEREMAPPED: PointAttribute;\r\n static NORMAL_OCT16: PointAttribute;\r\n static NORMAL: PointAttribute;\r\n static RETURN_NUMBER: PointAttribute;\r\n static NUMBER_OF_RETURNS: PointAttribute;\r\n static SOURCE_ID: PointAttribute;\r\n static INDICES: PointAttribute;\r\n static SPACING: PointAttribute;\r\n static GPS_TIME: PointAttribute;\r\n initialRange: any;\r\n\r\n constructor(name, type, numElements){\r\n this.name = name;\r\n this.type = type;\r\n this.numElements = numElements;\r\n this.byteSize = this.numElements * this.type.size;\r\n this.description = \"\";\r\n this.range = [Infinity, -Infinity];\r\n }\r\n\r\n};\r\n\r\nPointAttribute.POSITION_CARTESIAN = new PointAttribute(\r\n \"POSITION_CARTESIAN\", PointAttributeTypes.DATA_TYPE_FLOAT, 3);\r\n\r\nPointAttribute.RGBA_PACKED = new PointAttribute(\r\n \"COLOR_PACKED\", PointAttributeTypes.DATA_TYPE_INT8, 4);\r\n\r\nPointAttribute.COLOR_PACKED = PointAttribute.RGBA_PACKED;\r\n\r\nPointAttribute.RGB_PACKED = new PointAttribute(\r\n \"COLOR_PACKED\", PointAttributeTypes.DATA_TYPE_INT8, 3);\r\n\r\nPointAttribute.NORMAL_FLOATS = new PointAttribute(\r\n \"NORMAL_FLOATS\", PointAttributeTypes.DATA_TYPE_FLOAT, 3);\r\n\r\nPointAttribute.INTENSITY = new PointAttribute(\r\n \"INTENSITY\", PointAttributeTypes.DATA_TYPE_UINT16, 1);\r\n\r\nPointAttribute.CLASSIFICATION = new PointAttribute(\r\n \"CLASSIFICATION\", PointAttributeTypes.DATA_TYPE_UINT8, 1);\r\n\r\nPointAttribute.NORMAL_SPHEREMAPPED = new PointAttribute(\r\n \"NORMAL_SPHEREMAPPED\", PointAttributeTypes.DATA_TYPE_UINT8, 2);\r\n\r\nPointAttribute.NORMAL_OCT16 = new PointAttribute(\r\n \"NORMAL_OCT16\", PointAttributeTypes.DATA_TYPE_UINT8, 2);\r\n\r\nPointAttribute.NORMAL = new PointAttribute(\r\n \"NORMAL\", PointAttributeTypes.DATA_TYPE_FLOAT, 3);\r\n\r\nPointAttribute.RETURN_NUMBER = new PointAttribute(\r\n \"RETURN_NUMBER\", PointAttributeTypes.DATA_TYPE_UINT8, 1);\r\n\r\nPointAttribute.NUMBER_OF_RETURNS = new PointAttribute(\r\n \"NUMBER_OF_RETURNS\", PointAttributeTypes.DATA_TYPE_UINT8, 1);\r\n\r\nPointAttribute.SOURCE_ID = new PointAttribute(\r\n \"SOURCE_ID\", PointAttributeTypes.DATA_TYPE_UINT16, 1);\r\n\r\nPointAttribute.INDICES = new PointAttribute(\r\n \"INDICES\", PointAttributeTypes.DATA_TYPE_UINT32, 1);\r\n\r\nPointAttribute.SPACING = new PointAttribute(\r\n \"SPACING\", PointAttributeTypes.DATA_TYPE_FLOAT, 1);\r\n\r\nPointAttribute.GPS_TIME = new PointAttribute(\r\n \"GPS_TIME\", PointAttributeTypes.DATA_TYPE_DOUBLE, 1);\r\n\r\nexport class PointAttributes{\r\n attributes: any[];\r\n byteSize: number;\r\n size: number;\r\n vectors: any[];\r\n\r\n constructor(pointAttributes=null){\r\n this.attributes = [];\r\n this.byteSize = 0;\r\n this.size = 0;\r\n this.vectors = [];\r\n\r\n if (pointAttributes != null) {\r\n for (let i = 0; i < pointAttributes.length; i++) {\r\n let pointAttributeName = pointAttributes[i];\r\n let pointAttribute = PointAttribute[pointAttributeName];\r\n this.attributes.push(pointAttribute);\r\n this.byteSize += pointAttribute.byteSize;\r\n this.size++;\r\n }\r\n }\r\n }\r\n\r\n\r\n add(pointAttribute){\r\n this.attributes.push(pointAttribute);\r\n this.byteSize += pointAttribute.byteSize;\r\n this.size++;\r\n };\r\n\r\n addVector(vector){\r\n this.vectors.push(vector);\r\n }\r\n\r\n hasNormals(){\r\n for (let name in this.attributes) {\r\n let pointAttribute = this.attributes[name];\r\n if (\r\n pointAttribute === PointAttribute.NORMAL_SPHEREMAPPED ||\r\n\t\t\t\tpointAttribute === PointAttribute.NORMAL_FLOATS ||\r\n\t\t\t\tpointAttribute === PointAttribute.NORMAL ||\r\n\t\t\t\tpointAttribute === PointAttribute.NORMAL_OCT16) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n\r\n}\r\n\r\nexport const parseAttributes = jsonAttributes => {\r\n let attributes = new PointAttributes();\r\n\r\n let replacements = {\r\n \"rgb\": \"rgba\",\r\n };\r\n\r\n for (const jsonAttribute of jsonAttributes) {\r\n let {name, numElements, min, max} = jsonAttribute;\r\n let type = typenameTypeattributeMap[jsonAttribute.type];\r\n let potreeAttributeName = replacements[name] ? replacements[name] : name;\r\n let attribute = new PointAttribute(potreeAttributeName, type, numElements);\r\n\r\n if(numElements === 1){\r\n attribute.range = [min[0], max[0]];\r\n }else{\r\n attribute.range = [min, max];\r\n }\r\n\r\n if (name === \"gps-time\") {\r\n if (attribute.range[0] === attribute.range[1]) {\r\n attribute.range[1] += 1;\r\n }\r\n }\r\n\r\n attribute.initialRange = attribute.range;\r\n attributes.add(attribute);\r\n }\r\n\r\n // check if it has normals\r\n let hasNormals =\r\n attributes.attributes.find(a => a.name === \"NormalX\") !== undefined &&\r\n attributes.attributes.find(a => a.name === \"NormalY\") !== undefined &&\r\n attributes.attributes.find(a => a.name === \"NormalZ\") !== undefined;\r\n\r\n if(hasNormals){\r\n let vector = {\r\n name: \"NORMAL\",\r\n attributes: [\"NormalX\", \"NormalY\", \"NormalZ\"],\r\n };\r\n attributes.addVector(vector);\r\n }\r\n\r\n return attributes;\r\n};\r\n","import { Vector3 } from \"three\";\r\nimport { PointCloudManager, StreamablePointCloud, StreamablePointCloudNode } from \".\";\r\nimport { toast } from \"../../../app\";\r\nimport { t } from \"../../../localization\";\r\nimport { readFileBuffer } from \"../file-system-loader\";\r\nimport LocalScene from \"../projections\";\r\nimport { AsyncWorkerPool } from \"../worker-pool\";\r\nimport { parseAttributes, PointAttributes } from \"./point-attributes\";\r\n\r\nconst workerPool = new AsyncWorkerPool(\"point-decoder-potree.js\");\r\n\r\nclass DataView64 extends DataView {\r\n constructor(buffer) {\r\n super(buffer);\r\n }\r\n\r\n getUint64(position, littleEndian = false) {\r\n return Number(this.getBigUint64(position, littleEndian));\r\n }\r\n\r\n getInt64(position, littleEndian = false) {\r\n return Number(this.getBigInt64(position, littleEndian));\r\n }\r\n}\r\n\r\n/** Encompass style pointcloud node */\r\nclass PotreePointCloudNode extends StreamablePointCloudNode {\r\n public cloud: PotreePointCloud;\r\n public parent: PotreePointCloudNode;\r\n\r\n public nodeType = 0;\r\n public hierarchyByteOffset = 0;\r\n public hierarchyByteSize = 0;\r\n public byteOffset = 0;\r\n public byteSize = 0;\r\n\r\n private attemptNumber = 0;\r\n private maxAttempts = 3;\r\n\r\n constructor(cloud, parent, name, level, center, size) {\r\n super(name, level, center, size);\r\n\r\n this.cloud = cloud;\r\n this.parent = parent;\r\n }\r\n\r\n get toMeters() {\r\n return LocalScene.dataToMeters;\r\n }\r\n\r\n getChildOffset(index) {\r\n return {\r\n x: (index & 0b100) / 4,\r\n y: (index & 0b010) / 2,\r\n z: index & 0b001\r\n };\r\n }\r\n\r\n async loadHierarchy(){\r\n if (this.nodeType !== 2) return;\r\n\r\n const byteRange = {\r\n first: this.hierarchyByteOffset,\r\n last: this.hierarchyByteOffset + this.hierarchyByteSize\r\n };\r\n\r\n const buffer = await readFileBuffer(\r\n this.cloud.hierarchyPath, byteRange);\r\n\r\n this.parseHierarchy(buffer);\r\n }\r\n\r\n parseHierarchy(buffer) {\r\n const view = new DataView64(buffer);\r\n const bytesPerNode = 22;\r\n const numNodes = buffer.byteLength / bytesPerNode;\r\n\r\n let nodePos = 1;\r\n const nodes = new Array(numNodes);\r\n nodes[0] = this;\r\n\r\n for (let i = 0; i < numNodes; i++) {\r\n const current = nodes[i] as PotreePointCloudNode;\r\n\r\n const type = view.getUint8(i * bytesPerNode + 0);\r\n const childMask = view.getUint8(i * bytesPerNode + 1);\r\n const numPoints = view.getUint32(i * bytesPerNode + 2, true);\r\n const byteOffset = view.getInt64(i * bytesPerNode + 6, true);\r\n const byteSize = view.getInt64(i * bytesPerNode + 14, true);\r\n\r\n if (current.nodeType === 2) {\r\n current.byteOffset = byteOffset;\r\n current.byteSize = byteSize;\r\n current.numPoints = numPoints;\r\n } else if(type === 2) {\r\n current.hierarchyByteOffset = byteOffset;\r\n current.hierarchyByteSize = byteSize;\r\n current.numPoints = numPoints;\r\n } else {\r\n current.byteOffset = byteOffset;\r\n current.byteSize = byteSize;\r\n current.numPoints = numPoints;\r\n }\r\n\r\n if (current.byteSize === 0) {\r\n current.numPoints = 0;\r\n }\r\n\r\n current.nodeType = type;\r\n if (current.nodeType === 2){\r\n continue;\r\n }\r\n\r\n for (let childIndex = 0; childIndex < 8; childIndex++){\r\n let childExists = ((1 << childIndex) & childMask) !== 0;\r\n if (!childExists) continue;\r\n\r\n const child = current.getChildNode(childIndex);\r\n current.addChildNode(child);\r\n\r\n nodes[nodePos] = child;\r\n nodePos++;\r\n }\r\n }\r\n }\r\n\r\n async getBinaryData() {\r\n const byteRange = {\r\n first: this.byteOffset,\r\n last: this.byteOffset + this.byteSize\r\n };\r\n\r\n let minCorner = new Vector3()\r\n .add(this.nodeCenter)\r\n .subScalar(this.size/2);\r\n\r\n let buffer;\r\n\r\n if (this.byteSize === 0) {\r\n buffer = new ArrayBuffer(0);\r\n // console.warn(`Loaded node with 0 bytes: ${this.name}`);\r\n } else {\r\n buffer = await readFileBuffer(this.cloud.octreePath, byteRange);\r\n }\r\n\r\n const values = {\r\n buffer: buffer,\r\n name: this.name,\r\n pointAttributes: this.cloud.pointAttributes,\r\n scale: this.cloud.xyzScale,\r\n min: this.cloud.xyzCenter,\r\n offset: this.cloud.xyzOffset,\r\n size: this.size,\r\n numPoints: this.numPoints,\r\n corner: minCorner,\r\n toMeters: this.toMeters\r\n };\r\n\r\n const data = await workerPool.postMessage(values, [values.buffer]);\r\n\r\n // Convert raw buffer to float array\r\n data.positions = new Float32Array(data.attributeBuffers.positions.buffer);\r\n data.intensity = new Float32Array(data.attributeBuffers.intensity.buffer);\r\n data.classification = new Float32Array(data.attributeBuffers.classification.buffer);\r\n data.colors = new Float32Array(data.attributeBuffers.colors.buffer);\r\n\r\n return data;\r\n }\r\n\r\n getGeometry(data) {\r\n this.setGeometry(data);\r\n\r\n this.density = data.density;\r\n this.cloud.updateClassifications(data.classification);\r\n\r\n this.loaded = true;\r\n this.loading = false;\r\n }\r\n\r\n async load() {\r\n if ((this.loaded) || (this.loading)) return;\r\n\r\n this.loading = true;\r\n\r\n try {\r\n await this.loadHierarchy();\r\n const data = await this.getBinaryData();\r\n this.getGeometry(data);\r\n } catch(err) {\r\n this.attemptNumber += 1;\r\n\r\n if (this.attemptNumber <= this.maxAttempts) {\r\n console.log(`Reload node ${this.name} (attempt #${this.attemptNumber})`);\r\n this.loaded = false;\r\n this.loading = false;\r\n return;\r\n }\r\n\r\n this.cloud.error = true;\r\n console.error(err);\r\n }\r\n }\r\n}\r\n\r\n/** Potree style pointcloud */\r\nexport class PotreePointCloud extends StreamablePointCloud {\r\n public xyzScale;\r\n public xyzOffset;\r\n public xyzCenter;\r\n public pointAttributes: PointAttributes;\r\n private version = \"2.0\";\r\n private encoding = \"DEFAULT\"\r\n\r\n constructor(pointclouds: PointCloudManager) {\r\n super(pointclouds);\r\n }\r\n\r\n get metadataPath() {\r\n return `${this.structure.path}/metadata.json`;\r\n }\r\n\r\n get octreePath() {\r\n return `${this.structure.path}/octree.bin`;\r\n }\r\n\r\n get hierarchyPath() {\r\n return `${this.structure.path}/hierarchy.bin`;\r\n }\r\n\r\n get toMeters() {\r\n return LocalScene.dataToMeters;\r\n }\r\n\r\n /** Decode cloud metadata. Cloud is in dataProjection units */\r\n decodeMetadata(data) {\r\n if (data.version !== this.version) {\r\n this.error = true;\r\n toast.error(t(\"toast.point_version_error\", {\r\n version: data.version\r\n }));\r\n\r\n return;\r\n }\r\n\r\n if (data.encoding !== this.encoding) {\r\n this.error = true;\r\n toast.error(t(\"toast.point_encoding_error\", {\r\n encoding: data.encoding\r\n }));\r\n\r\n return;\r\n }\r\n\r\n this.pointAttributes = parseAttributes(data.attributes);\r\n\r\n // Update maximum rgb value\r\n const colors = data.attributes.find(x => x.name === \"rgb\");\r\n const rgbMax = colors ? Math.max(...colors.max) : 0;\r\n this.updateColorLimits(rgbMax);\r\n\r\n // Update intensity bounds\r\n const intensity = data.attributes.find(x => x.name === \"intensity\");\r\n this.updateIntensityRange(intensity.min, intensity.max);\r\n\r\n const bboxMin = new Vector3(...data.boundingBox.min)\r\n .multiplyScalar(this.toMeters);\r\n\r\n const bboxMax = new Vector3(...data.boundingBox.max)\r\n .multiplyScalar(this.toMeters);\r\n\r\n const offset = new Vector3()\r\n .add(bboxMin)\r\n .add(bboxMax)\r\n .divideScalar(2.0);\r\n\r\n this.xyzScale = data.scale;\r\n this.xyzOffset = data.offset;\r\n this.xyzCenter = offset;\r\n this.spacing = data.spacing * this.toMeters;\r\n\r\n const position = data.attributes\r\n .find(x => x.name === \"position\");\r\n\r\n const xyzMin = new Vector3(...position.min)\r\n .multiplyScalar(this.toMeters);\r\n\r\n const xyzMax = new Vector3(...position.max)\r\n .multiplyScalar(this.toMeters);\r\n\r\n const tightBoundingBox = {\r\n min: new Vector3().add(xyzMin).sub(offset),\r\n max: new Vector3().add(xyzMax).sub(offset)\r\n };\r\n\r\n const nodeSize = bboxMax.x - bboxMin.x;\r\n const nodeCenter = new Vector3();\r\n\r\n this.shift = LocalScene.offsetToScene(offset);\r\n\r\n const rootNode = new PotreePointCloudNode(\r\n this, null, \"r\", 1, nodeCenter, nodeSize);\r\n\r\n rootNode.nodeType = 2;\r\n rootNode.hierarchyByteSize = data.hierarchy.firstChunkSize;\r\n\r\n this.root = rootNode;\r\n this.updateBoundingBox(tightBoundingBox);\r\n this.pointclouds.updateMinimapExtent();\r\n\r\n if (this.saved) return;\r\n this.viewer.zoomToSceneExtent(this.tightBoundingBox, false);\r\n }\r\n}","/**\r\n * @author qiao / https://github.com/qiao\r\n * @author mrdoob / http://mrdoob.com\r\n * @author alteredq / http://alteredqualia.com/\r\n * @author WestLangley / http://github.com/WestLangley\r\n * @author erich666 / http://erichaines.com\r\n */\r\n\r\nimport {\r\n EventDispatcher,\r\n MathUtils,\r\n MOUSE,\r\n Quaternion,\r\n Spherical,\r\n Vector2,\r\n Vector3\r\n} from \"three\";\r\nimport { toast } from \"../../../app\";\r\nimport { t } from \"../../../localization\";\r\nimport { ControlModes, ControlType } from \"../../../types/controls\";\r\nimport { Viewer } from \"../main\";\r\n\r\nconst screenSpacePanning = 0;\r\nconst horizontalPanning = 1;\r\n\r\nconst CustomOrbitControls = function(viewer: Viewer, object, domElement ) {\r\n this.viewer = viewer as Viewer;\r\n this.object = object;\r\n this.domElement = ( domElement !== undefined ) ? domElement : document;\r\n\r\n this.keyPressed = {};\r\n this.walkMode = false;\r\n this.walkVelocity = new Vector3();\r\n this.walkRotation = new Spherical();\r\n this.maxWalkSpeed = 1.0;\r\n this.walkIncrement = 0.01;\r\n this.walkPercent = 1.0;\r\n this.walkPercentMin = 0.1;\r\n this.walkPercentMax = 5.0;\r\n this.oldRadiusState = 0.0;\r\n\r\n // Set to false to disable this control\r\n this.enabled = true;\r\n\r\n this.focused = false;\r\n\r\n // \"target\" sets the location of focus, where the object orbits around\r\n this.target = new Vector3();\r\n\r\n // How far you can dolly in and out ( PerspectiveCamera only )\r\n this.minDistance = 0.05;\r\n this.maxDistance = Infinity;\r\n\r\n // How far you can zoom in and out ( OrthographicCamera only )\r\n this.minZoom = 0;\r\n this.maxZoom = Infinity;\r\n\r\n // How far you can orbit vertically, upper and lower limits.\r\n // Range is 0 to Math.PI radians.\r\n this.minPolarAngle = 0; // radians\r\n this.maxPolarAngle = Math.PI; // radians\r\n\r\n // How far you can orbit horizontally, upper and lower limits.\r\n // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\r\n this.minAzimuthAngle = -Infinity; // radians\r\n this.maxAzimuthAngle = Infinity; // radians\r\n\r\n // Set to true to enable damping (inertia)\r\n // If damping is enabled, you must call controls.update() in your animation loop\r\n this.enableDamping = false;\r\n this.dampingFactor = 0.25;\r\n\r\n // This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\r\n // Set to false to disable zooming\r\n this.enableZoom = true;\r\n this.zoomSpeed = 1.0;\r\n\r\n // Set to false to disable rotating\r\n this.enableRotate = true;\r\n this.rotateSpeed = 1.0;\r\n\r\n // Set to false to disable panning\r\n this.enablePan = true;\r\n this.panSpeed = 1.0;\r\n this.panningMode = screenSpacePanning; // alternate horizontalPanning\r\n this.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\r\n\r\n // Set to true to automatically rotate around the target\r\n // If auto-rotate is enabled, you must call controls.update() in your animation loop\r\n this.autoRotate = false;\r\n this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\r\n\r\n // Set to false to disable use of the keys\r\n this.enableKeys = true;\r\n\r\n // The four arrow keys\r\n this.keys = {\r\n LEFT: 37,\r\n UP: 38,\r\n RIGHT: 39,\r\n BOTTOM: 40,\r\n SPACE: 32,\r\n PLUS: 187,\r\n MINUS: 189,\r\n NUMPAD_PLUS: 107,\r\n NUMPAD_MINUS: 109,\r\n WALK_FORWARD: 87,\r\n WALK_BACK: 83,\r\n WALK_RIGHT: 68,\r\n WALK_LEFT: 65,\r\n WALK_UP: 69,\r\n WALK_DOWN: 81\r\n };\r\n\r\n this.controlType = ControlType.Encompass;\r\n\r\n // Mouse buttons\r\n this.mouseButtons = { ORBIT: MOUSE.LEFT, ZOOM: MOUSE.MIDDLE, PAN: MOUSE.RIGHT };\r\n\r\n // for reset\r\n this.target0 = this.target.clone();\r\n this.position0 = this.object.position.clone();\r\n this.zoom0 = this.object.zoom;\r\n\r\n //\r\n // public methods\r\n //\r\n\r\n this.setControls = function (controlType) {\r\n this.controlType = controlType;\r\n this.mouseButtons = ControlModes[controlType];\r\n };\r\n\r\n this.getPolarAngle = function () {\r\n return spherical.phi;\r\n };\r\n\r\n this.getAzimuthalAngle = function () {\r\n return spherical.theta;\r\n };\r\n\r\n this.clearSphericalDelta = function () {\r\n sphericalDelta.set(0, 0, 0);\r\n };\r\n\r\n this.clearPanOffset = function() {\r\n panOffset.set(0, 0, 0);\r\n };\r\n\r\n this.saveState = function () {\r\n scope.target0.copy( scope.target );\r\n scope.position0.copy( scope.object.position );\r\n scope.zoom0 = scope.object.zoom;\r\n };\r\n\r\n this.resetWalkValues = function () {\r\n scope.walkVelocity = new Vector3();\r\n scope.keyPressed = {};\r\n };\r\n\r\n this.incrementWalkSpeed = function () {\r\n if (!scope.walkMode) return;\r\n scope.walkPercent = Math.min(scope.walkPercentMax, scope.walkPercent + 0.1);\r\n const percent = Math.round(scope.walkPercent*100.0);\r\n toast.static(t(\"toast.walk-speed\", {percent}));\r\n };\r\n\r\n this.decreaseWalkSpeed = function () {\r\n if (!scope.walkMode) return;\r\n scope.walkPercent = Math.max(scope.walkPercentMin, scope.walkPercent - 0.1);\r\n const percent = Math.round(scope.walkPercent*100.0);\r\n toast.static(t(\"toast.walk-speed\", {percent}));\r\n };\r\n\r\n this.setWalkMode = function (state) {\r\n if (state === scope.walkMode) {\r\n return;\r\n }\r\n\r\n if (state) {\r\n toast.static(t(\"toast.walk-mode-enabled\"));\r\n } else {\r\n toast.static(t(\"toast.walk-mode-disabled\"));\r\n }\r\n\r\n scope.clearSphericalDelta();\r\n scope.clearPanOffset();\r\n scope.resetWalkValues();\r\n scope.walkMode = state;\r\n\r\n if (state) {\r\n // Calculate initial rotation for walk mode\r\n const offset = new Vector3()\r\n .copy( scope.object.position )\r\n .sub( scope.target );\r\n\r\n const quat = new Quaternion().setFromUnitVectors(\r\n scope.object.up,\r\n new Vector3( 0, 1, 0 )\r\n );\r\n\r\n offset.applyQuaternion( quat );\r\n scope.walkRotation.setFromVector3( offset );\r\n scope.walkRotation.theta += MathUtils.degToRad(90);\r\n } else {\r\n // Restore previous orbit radius and reset\r\n scope.position0 = scope.activePosition();\r\n scope.target0 = scope.activeTarget();\r\n scope.reset();\r\n }\r\n };\r\n\r\n this.activePosition = function () {\r\n return scope.object.position;\r\n };\r\n\r\n this.activeTarget = function () {\r\n const radius = scope.oldRadiusState;\r\n return new Vector3(0, 0, -radius)\r\n .applyQuaternion(scope.object.quaternion)\r\n .add(scope.object.position);\r\n };\r\n\r\n this.applyWalkOffset = function (scaleFactor) {\r\n const offset = new Vector3();\r\n const quaternion = this.object.quaternion;\r\n\r\n // Forward/back logic\r\n if (this.keyPressed[scope.keys.WALK_FORWARD]) {\r\n scope.walkVelocity.x += scope.walkIncrement;\r\n scope.walkVelocity.x = Math.min(scope.maxWalkSpeed, scope.walkVelocity.x);\r\n } else if (this.keyPressed[scope.keys.WALK_BACK]) {\r\n scope.walkVelocity.x -= scope.walkIncrement;\r\n scope.walkVelocity.x = Math.max(-scope.maxWalkSpeed, scope.walkVelocity.x);\r\n } else {\r\n scope.walkVelocity.x *= (1 - scope.dampingFactor);\r\n if (Math.abs(scope.walkVelocity.x) < 1E-3) {\r\n scope.walkVelocity.x = 0.0;\r\n }\r\n }\r\n\r\n // Left/right logic\r\n if (this.keyPressed[scope.keys.WALK_RIGHT]) {\r\n scope.walkVelocity.y += scope.walkIncrement;\r\n scope.walkVelocity.y = Math.min(scope.maxWalkSpeed, scope.walkVelocity.y);\r\n } else if (this.keyPressed[scope.keys.WALK_LEFT]) {\r\n scope.walkVelocity.y -= scope.walkIncrement;\r\n scope.walkVelocity.y = Math.max(-scope.maxWalkSpeed, scope.walkVelocity.y);\r\n } else {\r\n scope.walkVelocity.y *= (1 - scope.dampingFactor);\r\n if (Math.abs(scope.walkVelocity.y) < 1E-3) {\r\n scope.walkVelocity.y = 0.0;\r\n }\r\n }\r\n\r\n // up/down logic\r\n if (this.keyPressed[scope.keys.WALK_UP]) {\r\n scope.walkVelocity.z += scope.walkIncrement;\r\n scope.walkVelocity.z = Math.min(scope.maxWalkSpeed, scope.walkVelocity.z);\r\n } else if (this.keyPressed[scope.keys.WALK_DOWN]) {\r\n scope.walkVelocity.z -= scope.walkIncrement;\r\n scope.walkVelocity.z = Math.max(-scope.maxWalkSpeed, scope.walkVelocity.z);\r\n } else {\r\n scope.walkVelocity.z *= (1 - scope.dampingFactor);\r\n if (Math.abs(scope.walkVelocity.z) < 1E-3) {\r\n scope.walkVelocity.z = 0.0;\r\n }\r\n }\r\n\r\n if (scope.walkVelocity.x !== 0) {\r\n const forward = new Vector3(0, 0, -1)\r\n .applyQuaternion(quaternion)\r\n .multiplyScalar(scope.walkVelocity.x);\r\n offset.add(forward);\r\n }\r\n\r\n if (scope.walkVelocity.y !== 0) {\r\n const right = new Vector3(1, 0, 0)\r\n .applyQuaternion(quaternion)\r\n .multiplyScalar(scope.walkVelocity.y);\r\n offset.add(right);\r\n }\r\n\r\n if (scope.walkVelocity.z !== 0) {\r\n const up = new Vector3(0, 1, 0)\r\n .applyQuaternion(quaternion)\r\n .multiplyScalar(scope.walkVelocity.z);\r\n offset.add(up);\r\n }\r\n\r\n // Apply scale so distance travelled is consistent\r\n // regardless of framerate / update interval speed\r\n offset.multiplyScalar(scaleFactor);\r\n\r\n offset.multiplyScalar(scope.walkPercent);\r\n\r\n scope.object.position.add(offset);\r\n };\r\n\r\n this.reset = function () {\r\n scope.target.copy( scope.target0 );\r\n\r\n scope.object.position.copy( scope.position0 );\r\n scope.object.zoom = scope.zoom0;\r\n scope.object.updateProjectionMatrix();\r\n\r\n scope.dispatchEvent( changeEvent );\r\n scope.update();\r\n\r\n state = STATE.NONE;\r\n };\r\n\r\n // this method is exposed, but perhaps it would be better if we can make it private...\r\n this.update = (function () {\r\n var offset = new Vector3();\r\n\r\n // so camera.up is the orbit axis\r\n var quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) );\r\n var quatInverse = quat.clone().invert();\r\n\r\n var lastPosition = new Vector3();\r\n var lastQuaternion = new Quaternion();\r\n var lastUpdated = performance.now();\r\n var changeDetected = false;\r\n\r\n return function update() {\r\n var position = scope.object.position;\r\n\r\n let timeElapsed = performance.now() - lastUpdated;\r\n let scaleFactor = timeElapsed / (1000/60);\r\n lastUpdated = performance.now();\r\n\r\n offset.copy( position ).sub( scope.target );\r\n\r\n // rotate offset to \"y-axis-is-up\" space\r\n offset.applyQuaternion( quat );\r\n\r\n // angle from z-axis around y-axis\r\n spherical.setFromVector3( offset );\r\n\r\n if ( scope.autoRotate && state === STATE.NONE ) {\r\n rotateLeft( getAutoRotationAngle() );\r\n }\r\n\r\n if (scope.walkMode) {\r\n scope.walkRotation.theta += sphericalDelta.theta;\r\n scope.walkRotation.phi += sphericalDelta.phi;\r\n scope.walkRotation.makeSafe();\r\n\r\n const {phi, theta} = scope.walkRotation;\r\n let x = Math.cos(theta) * Math.sin(phi);\r\n let y = Math.sin(theta) * Math.sin(phi);\r\n let z = -1*Math.cos(phi);\r\n\r\n let lookat = new Vector3(x,y,z)\r\n .add(scope.object.position);\r\n scope.object.lookAt( lookat );\r\n\r\n scope.applyWalkOffset(scaleFactor);\r\n } else {\r\n spherical.theta += sphericalDelta.theta;\r\n spherical.phi += sphericalDelta.phi;\r\n spherical.theta = Math.max( scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, spherical.theta) );\r\n spherical.phi = Math.max( scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));\r\n spherical.makeSafe();\r\n spherical.radius *= scale;\r\n spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));\r\n\r\n scope.oldRadiusState = spherical.radius;\r\n\r\n // move target to panned location\r\n scope.target.add( panOffset );\r\n\r\n offset.setFromSpherical( spherical );\r\n\r\n // rotate offset back to \"camera-up-vector-is-up\" space\r\n offset.applyQuaternion( quatInverse );\r\n\r\n position.copy( scope.target ).add( offset );\r\n\r\n scope.object.lookAt( scope.target );\r\n }\r\n\r\n if ( scope.enableDamping === true ) {\r\n sphericalDelta.theta *= ( 1 - scope.dampingFactor );\r\n sphericalDelta.phi *= ( 1 - scope.dampingFactor );\r\n if ((Math.abs(sphericalDelta.phi) < 1E-3) && (Math.abs(sphericalDelta.theta) < 1E-3)) {\r\n scope.clearSphericalDelta();\r\n }\r\n\r\n panOffset.multiplyScalar( 1 - scope.dampingFactor );\r\n if (panOffset.length() < 1E-3) {\r\n scope.clearPanOffset();\r\n }\r\n } else {\r\n scope.clearSphericalDelta();\r\n scope.clearPanOffset();\r\n }\r\n\r\n scale = 1;\r\n\r\n // update condition is:\r\n // min(camera displacement, camera rotation in radians)^2 > EPS\r\n // using small-angle approximation cos(x/2) = 1 - x^2 / 8\r\n\r\n if ( zoomChanged ||\r\n\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\r\n\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\r\n scope.dispatchEvent( changeEvent );\r\n\r\n lastPosition.copy( scope.object.position );\r\n lastQuaternion.copy( scope.object.quaternion );\r\n zoomChanged = false;\r\n changeDetected = true;\r\n\r\n return true;\r\n }\r\n\r\n if (changeDetected) {\r\n scope.dispatchEvent( moveStopEvent );\r\n }\r\n\r\n changeDetected = false;\r\n\r\n return false;\r\n };\r\n }());\r\n\r\n this.dispose = function () {\r\n scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\r\n scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\r\n scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\r\n scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\r\n scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\r\n scope.domElement.removeEventListener( 'mouseover', onMouseFocus, false );\r\n scope.domElement.removeEventListener( 'mouseout', onMouseFocus, false );\r\n document.removeEventListener( 'mousemove', onMouseMove, false );\r\n document.removeEventListener( 'mouseup', onMouseUp, false );\r\n window.removeEventListener( 'keydown', onKeyDown, false );\r\n window.removeEventListener( 'keyUp', onKeyUp, false );\r\n };\r\n\r\n //\r\n // internals\r\n //\r\n\r\n var scope = this;\r\n\r\n var moveStopEvent = { type: \"stop\" };\r\n var changeEvent = { type: 'change' };\r\n var startEvent = { type: 'start' };\r\n var endEvent = { type: 'end' };\r\n\r\n var STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };\r\n\r\n var state = STATE.NONE;\r\n\r\n var EPS = 0.000001;\r\n\r\n // current position in spherical coordinates\r\n var spherical = new Spherical();\r\n var sphericalDelta = new Spherical();\r\n\r\n var scale = 1;\r\n var panOffset = new Vector3();\r\n var zoomChanged = false;\r\n\r\n var rotateStart = new Vector2();\r\n var rotateEnd = new Vector2();\r\n var rotateDelta = new Vector2();\r\n\r\n var panStart = new Vector2();\r\n var panEnd = new Vector2();\r\n var panDelta = new Vector2();\r\n\r\n var dollyStart = new Vector2();\r\n var dollyEnd = new Vector2();\r\n var dollyDelta = new Vector2();\r\n\r\n function getAutoRotationAngle() {\r\n return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\r\n }\r\n\r\n function getZoomScale() {\r\n return Math.pow( 0.95, scope.zoomSpeed );\r\n }\r\n\r\n function rotateLeft( angle ) {\r\n sphericalDelta.theta -= angle;\r\n }\r\n\r\n function rotateUp( angle ) {\r\n sphericalDelta.phi -= angle;\r\n }\r\n\r\n var panLeft = (function () {\r\n var v = new Vector3();\r\n\r\n return function panLeft( distance, objectMatrix ) {\r\n v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\r\n v.multiplyScalar( -distance );\r\n\r\n panOffset.add( v );\r\n };\r\n }());\r\n\r\n var panUp = (function () {\r\n var v = new Vector3();\r\n\r\n return function panUp( distance, objectMatrix ) {\r\n switch ( scope.panningMode ) {\r\n case screenSpacePanning:\r\n\r\n v.setFromMatrixColumn( objectMatrix, 1 );\r\n break;\r\n\r\n case horizontalPanning:\r\n\r\n v.setFromMatrixColumn( objectMatrix, 0 );\r\n v.crossVectors( scope.object.up, v );\r\n break;\r\n }\r\n\r\n v.multiplyScalar( distance );\r\n\r\n panOffset.add( v );\r\n };\r\n }());\r\n\r\n // deltaX and deltaY are in pixels; right and down are positive\r\n var pan = (function () {\r\n var offset = new Vector3();\r\n\r\n return function pan( deltaX, deltaY ) {\r\n if (scope.walkMode) return;\r\n var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\r\n\r\n if ( scope.object.isPerspectiveCamera ) {\r\n // perspective\r\n var position = scope.object.position;\r\n offset.copy( position ).sub( scope.target );\r\n var targetDistance = offset.length();\r\n\r\n // half of the fov is center to top of screen\r\n targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\r\n\r\n // we actually don't use screenWidth, since perspective camera is fixed to screen height\r\n panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\r\n panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\r\n } else if ( scope.object.isOrthographicCamera ) {\r\n // orthographic\r\n panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\r\n panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\r\n } else {\r\n // camera neither orthographic nor perspective\r\n console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\r\n scope.enablePan = false;\r\n }\r\n };\r\n }());\r\n\r\n function dollyIn( dollyScale ) {\r\n if ( scope.object.isPerspectiveCamera ) {\r\n scale /= dollyScale;\r\n } else if ( scope.object.isOrthographicCamera ) {\r\n scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\r\n scope.object.updateProjectionMatrix();\r\n zoomChanged = true;\r\n } else {\r\n console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\r\n scope.enableZoom = false;\r\n }\r\n }\r\n\r\n function dollyOut( dollyScale ) {\r\n if ( scope.object.isPerspectiveCamera ) {\r\n scale *= dollyScale;\r\n } else if ( scope.object.isOrthographicCamera ) {\r\n scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\r\n scope.object.updateProjectionMatrix();\r\n zoomChanged = true;\r\n } else {\r\n console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\r\n scope.enableZoom = false;\r\n }\r\n }\r\n\r\n //\r\n // event callbacks - update the object state\r\n //\r\n\r\n function handleMouseDownRotate( event ) {\r\n // console.log( 'handleMouseDownRotate' );\r\n\r\n rotateStart.set( event.clientX, event.clientY );\r\n }\r\n\r\n function handleMouseDownDolly( event ) {\r\n // console.log( 'handleMouseDownDolly' );\r\n\r\n dollyStart.set( event.clientX, event.clientY );\r\n }\r\n\r\n function handleMouseDownPan( event ) {\r\n // console.log( 'handleMouseDownPan' );\r\n\r\n panStart.set( event.clientX, event.clientY );\r\n }\r\n\r\n function handleMouseMoveRotate( event ) {\r\n // console.log( 'handleMouseMoveRotate' );\r\n\r\n rotateEnd.set( event.clientX, event.clientY );\r\n\r\n rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\r\n\r\n var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\r\n\r\n // rotating across whole screen goes 360 degrees around\r\n rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth );\r\n\r\n // rotating up and down along whole screen attempts to go 360, but limited to 180\r\n rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\r\n\r\n rotateStart.copy( rotateEnd );\r\n\r\n scope.update();\r\n }\r\n\r\n function handleMouseMoveDolly( event ) {\r\n // console.log( 'handleMouseMoveDolly' );\r\n\r\n dollyEnd.set( event.clientX, event.clientY );\r\n\r\n dollyDelta.subVectors( dollyEnd, dollyStart );\r\n\r\n if ( dollyDelta.y > 0 ) {\r\n dollyIn( getZoomScale() );\r\n } else if ( dollyDelta.y < 0 ) {\r\n dollyOut( getZoomScale() );\r\n }\r\n\r\n dollyStart.copy( dollyEnd );\r\n\r\n scope.update();\r\n }\r\n\r\n function handleMouseMovePan( event ) {\r\n // console.log( 'handleMouseMovePan' );\r\n\r\n panEnd.set( event.clientX, event.clientY );\r\n\r\n panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\r\n\r\n pan( panDelta.x, panDelta.y );\r\n\r\n panStart.copy( panEnd );\r\n\r\n scope.update();\r\n }\r\n\r\n function handleMouseUp( event ) {\r\n\r\n // console.log( 'handleMouseUp' );\r\n\r\n }\r\n\r\n function handleMouseWheel( event ) {\r\n // console.log( 'handleMouseWheel' );\r\n\r\n if ( event.deltaY < 0 ) {\r\n dollyOut( getZoomScale() );\r\n } else if ( event.deltaY > 0 ) {\r\n dollyIn( getZoomScale() );\r\n }\r\n scope.update();\r\n }\r\n\r\n function handleKeyUp( event ) {\r\n // console.log( 'handleKeyUp' );\r\n\r\n if (scope.walkMode) {\r\n scope.keyPressed[event.keyCode] = false;\r\n return;\r\n }\r\n }\r\n\r\n function handleKeyDown( event ) {\r\n // console.log( 'handleKeyDown' );\r\n\r\n if (scope.walkMode) {\r\n scope.keyPressed[event.keyCode] = true;\r\n }\r\n\r\n switch ( event.keyCode ) {\r\n case scope.keys.UP:\r\n pan( 0, scope.keyPanSpeed );\r\n scope.update();\r\n break;\r\n\r\n case scope.keys.BOTTOM:\r\n pan( 0, -scope.keyPanSpeed );\r\n scope.update();\r\n break;\r\n\r\n case scope.keys.LEFT:\r\n pan( scope.keyPanSpeed, 0 );\r\n scope.update();\r\n break;\r\n\r\n case scope.keys.RIGHT:\r\n pan( -scope.keyPanSpeed, 0 );\r\n scope.update();\r\n break;\r\n\r\n case scope.keys.SPACE:\r\n scope.setWalkMode(!scope.walkMode);\r\n break;\r\n\r\n case scope.keys.PLUS:\r\n scope.incrementWalkSpeed();\r\n break;\r\n\r\n case scope.keys.NUMPAD_PLUS:\r\n scope.incrementWalkSpeed();\r\n break;\r\n\r\n case scope.keys.MINUS:\r\n scope.decreaseWalkSpeed();\r\n break;\r\n\r\n case scope.keys.NUMPAD_MINUS:\r\n scope.decreaseWalkSpeed();\r\n break;\r\n }\r\n }\r\n\r\n function handleTouchStartRotate( event ) {\r\n // console.log( 'handleTouchStartRotate' );\r\n\r\n rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\r\n }\r\n\r\n function handleTouchStartDolly( event ) {\r\n // console.log( 'handleTouchStartDolly' );\r\n\r\n var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\r\n var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\r\n\r\n var distance = Math.sqrt( dx * dx + dy * dy );\r\n\r\n dollyStart.set( 0, distance );\r\n }\r\n\r\n function handleTouchStartPan( event ) {\r\n // console.log( 'handleTouchStartPan' );\r\n\r\n panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\r\n }\r\n\r\n function handleTouchMoveRotate( event ) {\r\n // console.log( 'handleTouchMoveRotate' );\r\n\r\n rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\r\n\r\n rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );\r\n\r\n var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\r\n\r\n // rotating across whole screen goes 360 degrees around\r\n rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth );\r\n\r\n // rotating up and down along whole screen attempts to go 360, but limited to 180\r\n rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );\r\n\r\n rotateStart.copy( rotateEnd );\r\n\r\n scope.update();\r\n }\r\n\r\n function handleTouchMoveDolly( event ) {\r\n // console.log( 'handleTouchMoveDolly' );\r\n\r\n var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\r\n var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\r\n\r\n var distance = Math.sqrt( dx * dx + dy * dy );\r\n\r\n dollyEnd.set( 0, distance );\r\n\r\n dollyDelta.subVectors( dollyEnd, dollyStart );\r\n\r\n if ( dollyDelta.y > 0 ) {\r\n dollyOut( getZoomScale() );\r\n } else if ( dollyDelta.y < 0 ) {\r\n dollyIn( getZoomScale() );\r\n }\r\n\r\n dollyStart.copy( dollyEnd );\r\n\r\n scope.update();\r\n }\r\n\r\n function handleTouchMovePan( event ) {\r\n // console.log( 'handleTouchMovePan' );\r\n\r\n panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\r\n\r\n panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );\r\n\r\n pan( panDelta.x, panDelta.y );\r\n\r\n panStart.copy( panEnd );\r\n\r\n scope.update();\r\n }\r\n\r\n function handleTouchEnd( event ) {\r\n\r\n // console.log( 'handleTouchEnd' );\r\n\r\n }\r\n\r\n //\r\n // event handlers - FSM: listen for events and reset state\r\n //\r\n\r\n function onMouseDown( event ) {\r\n if ( scope.enabled === false ) return;\r\n\r\n event.preventDefault();\r\n\r\n var switchTo = event.button;\r\n if (scope.controlType === ControlType.Autocad) {\r\n if (event.shiftKey && event.button === MOUSE.MIDDLE) {\r\n switchTo = scope.mouseButtons.ORBIT;\r\n }\r\n }\r\n switch ( switchTo ) {\r\n case scope.mouseButtons.ORBIT:\r\n\r\n if ( scope.enableRotate === false ) return;\r\n\r\n handleMouseDownRotate( event );\r\n\r\n state = STATE.ROTATE;\r\n\r\n break;\r\n\r\n case scope.mouseButtons.ZOOM:\r\n\r\n if ( scope.enableZoom === false ) return;\r\n\r\n handleMouseDownDolly( event );\r\n\r\n state = STATE.DOLLY;\r\n\r\n break;\r\n\r\n case scope.mouseButtons.PAN:\r\n\r\n if ( scope.enablePan === false ) return;\r\n\r\n handleMouseDownPan( event );\r\n\r\n state = STATE.PAN;\r\n\r\n break;\r\n }\r\n\r\n if ( state !== STATE.NONE ) {\r\n document.addEventListener( 'mousemove', onMouseMove, false );\r\n document.addEventListener( 'mouseup', onMouseUp, false );\r\n\r\n scope.dispatchEvent( startEvent );\r\n }\r\n }\r\n\r\n function onMouseMove( event ) {\r\n if ( scope.enabled === false ) return;\r\n\r\n event.preventDefault();\r\n\r\n switch ( state ) {\r\n case STATE.ROTATE:\r\n if ( scope.enableRotate === false ) return;\r\n handleMouseMoveRotate( event );\r\n\r\n break;\r\n\r\n case STATE.DOLLY:\r\n if (scope.enableZoom === false) return;\r\n handleMouseMoveDolly( event );\r\n\r\n break;\r\n\r\n case STATE.PAN:\r\n if (scope.enablePan === false) return;\r\n handleMouseMovePan( event );\r\n\r\n break;\r\n }\r\n }\r\n\r\n function onMouseUp( event ) {\r\n if ( scope.enabled === false ) return;\r\n\r\n handleMouseUp( event );\r\n\r\n if (!scope.walkMode) {\r\n document.removeEventListener( 'mousemove', onMouseMove, false );\r\n }\r\n document.removeEventListener( 'mouseup', onMouseUp, false );\r\n\r\n scope.dispatchEvent( endEvent );\r\n\r\n state = STATE.NONE;\r\n }\r\n\r\n function onMouseWheel( event ) {\r\n if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n scope.dispatchEvent( startEvent );\r\n\r\n handleMouseWheel( event );\r\n\r\n scope.dispatchEvent( endEvent );\r\n }\r\n\r\n function onKeyDown( event ) {\r\n if (!scope.enabled || !scope.focused || !scope.enableKeys || !scope.enablePan) {\r\n return;\r\n }\r\n\r\n handleKeyDown( event );\r\n }\r\n\r\n function onKeyUp( event ) {\r\n if (!scope.enabled || !scope.enableKeys || !scope.enablePan) {\r\n return;\r\n }\r\n\r\n handleKeyUp( event );\r\n }\r\n\r\n function onTouchStart( event ) {\r\n if ( scope.enabled === false ) return;\r\n\r\n switch ( event.touches.length ) {\r\n case 1:\t// one-fingered touch: rotate\r\n\r\n if ( scope.enableRotate === false ) return;\r\n\r\n handleTouchStartRotate( event );\r\n\r\n state = STATE.TOUCH_ROTATE;\r\n\r\n break;\r\n\r\n case 2:\t// two-fingered touch: dolly\r\n\r\n if ( scope.enableZoom === false ) return;\r\n\r\n handleTouchStartDolly( event );\r\n\r\n state = STATE.TOUCH_DOLLY;\r\n\r\n break;\r\n\r\n case 3: // three-fingered touch: pan\r\n\r\n if ( scope.enablePan === false ) return;\r\n\r\n handleTouchStartPan( event );\r\n\r\n state = STATE.TOUCH_PAN;\r\n\r\n break;\r\n\r\n default:\r\n\r\n state = STATE.NONE;\r\n }\r\n\r\n if ( state !== STATE.NONE ) {\r\n scope.dispatchEvent( startEvent );\r\n }\r\n }\r\n\r\n function onTouchMove( event ) {\r\n if ( scope.enabled === false ) return;\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n switch ( event.touches.length ) {\r\n case 1: // one-fingered touch: rotate\r\n\r\n if ( scope.enableRotate === false ) return;\r\n if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\r\n\r\n handleTouchMoveRotate( event );\r\n\r\n break;\r\n\r\n case 2: // two-fingered touch: dolly\r\n\r\n if ( scope.enableZoom === false ) return;\r\n if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\r\n\r\n handleTouchMoveDolly( event );\r\n\r\n break;\r\n\r\n case 3: // three-fingered touch: pan\r\n\r\n if ( scope.enablePan === false ) return;\r\n if ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\r\n\r\n handleTouchMovePan( event );\r\n\r\n break;\r\n\r\n default:\r\n\r\n state = STATE.NONE;\r\n }\r\n }\r\n\r\n function onTouchEnd( event ) {\r\n if ( scope.enabled === false ) return;\r\n\r\n handleTouchEnd( event );\r\n\r\n scope.dispatchEvent( endEvent );\r\n\r\n state = STATE.NONE;\r\n }\r\n\r\n function onMouseFocus( event ) {\r\n if (event.type === 'mouseover') {\r\n scope.focused = true;\r\n } else if (event.type === 'mouseout') {\r\n scope.focused = false;\r\n }\r\n }\r\n\r\n // Bind all events to dom element\r\n scope.domElement.addEventListener( 'mousedown', onMouseDown, false );\r\n scope.domElement.addEventListener( 'wheel', onMouseWheel, false );\r\n scope.domElement.addEventListener( 'touchstart', onTouchStart, false );\r\n scope.domElement.addEventListener( 'touchend', onTouchEnd, false );\r\n scope.domElement.addEventListener( 'touchmove', onTouchMove, false );\r\n\r\n // Keep track of our canvas focus\r\n scope.domElement.addEventListener( 'mouseover', onMouseFocus, false );\r\n scope.domElement.addEventListener( 'mouseout', onMouseFocus, false );\r\n\r\n // Keydown doesnt work on canvas\r\n window.addEventListener( 'keydown', onKeyDown, false) ;\r\n window.addEventListener( 'keyup', onKeyUp, false) ;\r\n\r\n // Start our update loop\r\n this.update();\r\n};\r\n\r\nCustomOrbitControls.prototype = Object.create( EventDispatcher.prototype );\r\nCustomOrbitControls.prototype.constructor = CustomOrbitControls;\r\n\r\nexport {CustomOrbitControls};\r\n","import { createHash } from \"crypto\";\r\nimport { Color } from \"three\";\r\nimport { getClassificationColors, classifications } from \"../../../classifications\";\r\n\r\nlet classificationColors = [];\r\ngetClassificationColors().then(result => classificationColors = result);\r\n\r\nconst parseHex = (text, min, max) => {\r\n return parseInt(text.slice(min, max), 16);\r\n};\r\n\r\nconst hexToRGB = (hex) => {\r\n let r = parseInt(hex.slice(1, 3), 16);\r\n let g = parseInt(hex.slice(3, 5), 16);\r\n let b = parseInt(hex.slice(5, 7), 16);\r\n return [r,g,b];\r\n};\r\n\r\nexport const getClassFromAlias = (alias) => {\r\n let classNum = -1;\r\n classifications.forEach(classification => {\r\n if (classification.alias.includes(alias.toLowerCase())) {\r\n classNum = classification.id;\r\n }\r\n });\r\n\r\n return classNum;\r\n};\r\n\r\nexport const getNameFromClass = (classicationCheck) => {\r\n let alias = \"undefined\";\r\n\r\n classifications.forEach(classification => {\r\n if (classification.id === classicationCheck) {\r\n alias = classification.name;\r\n }\r\n });\r\n\r\n return alias;\r\n};\r\n\r\nconst getColorFromClassNum = (classNum) => {\r\n const rgbColor = hexToRGB(classificationColors[classNum]);\r\n return rgbColor;\r\n};\r\n\r\nexport const textToColor = (text, opacity=1.0) => {\r\n let classNum = getClassFromAlias(text);\r\n\r\n // If alias is similar to any of the defined classes (don't want to use 0,1 since white\r\n // and black are used for highlights and training areas)\r\n if (classNum > 1) {\r\n let rgbColor = getColorFromClassNum(classNum);\r\n return `rgba(${Math.ceil(rgbColor[0])}, ${Math.ceil(rgbColor[1])}, ${Math.ceil(rgbColor[2])}, ${opacity})`;\r\n }\r\n let [r,g,b,a] = textToColorArray(text, opacity);\r\n\r\n return `rgba(${Math.ceil(r)}, ${Math.ceil(g)}, ${Math.ceil(b)}, ${a})`;\r\n};\r\n\r\nexport const textToColorArray = (text, opacity=1.0) => {\r\n const colorHash = createHash('md5');\r\n const hash = colorHash.update(text).digest('hex');\r\n const h = (parseHex(hash, 0, 8) + parseHex(hash, 8, 16)) % 360;\r\n const s = 50 + (parseHex(hash, 16, 24) % 50);\r\n const l = 25 + (parseHex(hash, 24, 32) % 50);\r\n\r\n const color = new Color(`hsl(${h}, ${s}%, ${l}%)`);\r\n const {r,g,b} = color.multiplyScalar(255);\r\n\r\n return [Math.ceil(r), Math.ceil(g), Math.ceil(b), opacity];\r\n};\r\n\r\n\r\n\r\n","import 'ol/ol.css';\r\n\r\nimport Map from 'ol/Map';\r\nimport Tile from 'ol/layer/Tile';\r\nimport View from 'ol/View';\r\nimport {Attribution, defaults as defaultControls} from 'ol/control';\r\nimport {DragPan} from 'ol/interaction';\r\nimport {Viewer} from \"../main\";\r\nimport {OSM, XYZ} from \"ol/source\";\r\nimport {transform} from 'ol/proj';\r\nimport {PanoramicImage, PlanarImage} from '../cameras';\r\nimport {Cluster, Vector as VectorSource} from \"ol/source\";\r\nimport {Vector as VectorLayer} from \"ol/layer\";\r\nimport {\r\n Circle as CircleStyle,\r\n RegularShape as RegularShapeStyle,\r\n Fill, Stroke, Style, Text\r\n} from \"ol/style\";\r\nimport {Point, Polygon} from \"ol/geom\";\r\nimport {Feature} from \"ol\";\r\nimport {boundingExtent} from 'ol/extent';\r\nimport LocalScene, {\r\n DataProjectionCoordinate,\r\n LonLatCoordinate,\r\n SceneCoordinate\r\n} from '../projections';\r\nimport {Vector3} from 'three';\r\nimport { Projection } from '../../../redux/projections-slice';\r\nimport { OrthoMosaicList } from '.';\r\nimport { CameraImage } from '../cameras';\r\nimport { AerialViewState } from '../../../redux/camera-slice';\r\nimport onresize from \"resize-event\";\r\nimport { showContextMenu } from '../../../context-menu';\r\nimport { clearAerialTooltip, setAerialState } from '../../viewer';\r\nimport { ChangeDetector } from '../utilities';\r\nimport { showTagDetails } from '../../../folder';\r\n\r\nexport type Basemap = 'open-street-maps' | 'arcgis-world' | 'arcgis-street';\r\n\r\nenum MarkerShape {\r\n Square,\r\n Circle\r\n}\r\n\r\nconst BasemapLayer = (id: Basemap, text, source) => {\r\n return new Tile({\r\n source: source,\r\n properties: {\r\n id: id,\r\n text: text,\r\n type: 'basemap'\r\n }\r\n });\r\n};\r\n\r\nclass BaseCameraFeature extends Feature {\r\n public cameraID;\r\n public saved;\r\n public cameraCSV;\r\n\r\n constructor(opts) {\r\n super(opts);\r\n this.cameraID = opts.cameraID;\r\n this.cameraCSV = opts.cameraCSV;\r\n this.saved = opts.saved;\r\n }\r\n}\r\n\r\nclass PanoramicFeature extends BaseCameraFeature {\r\n constructor(opts) {\r\n super(opts);\r\n }\r\n}\r\n\r\nclass PlanarFeature extends BaseCameraFeature {\r\n constructor(opts) {\r\n super(opts);\r\n }\r\n}\r\n\r\nexport class TagFeature extends Feature {\r\n public tagID: string;\r\n public texture: string;\r\n public size: number;\r\n\r\n constructor(tagID, texture, size, opts) {\r\n super(opts);\r\n this.tagID = tagID;\r\n this.size = size;\r\n this.texture = texture;\r\n }\r\n}\r\n\r\nclass ViewTriangle {\r\n private aerial: AerialMap;\r\n private viewer: Viewer;\r\n private map: Map;\r\n private feature;\r\n private layer;\r\n\r\n constructor(parent, map, viewer) {\r\n this.aerial = parent;\r\n this.viewer = viewer;\r\n this.map = map;\r\n\r\n this.generateSource();\r\n }\r\n\r\n get camera() {\r\n return this.viewer.camera;\r\n }\r\n\r\n generateSource() {\r\n // Adding our view triangle source\r\n const source = new VectorSource({\r\n wrapX: false\r\n });\r\n\r\n const polygon = new Polygon([[[0,0], [0,0]]]);\r\n const feature = new Feature(polygon);\r\n source.addFeature(feature);\r\n\r\n const layer = new VectorLayer({\r\n zIndex: 1,\r\n visible: false,\r\n source: source,\r\n properties: {\r\n type: \"triangle\"\r\n },\r\n style: new Style({\r\n stroke: new Stroke({\r\n color: \"rgba(0,0,0,0.5)\",\r\n width: 1.0\r\n }),\r\n fill: new Fill({\r\n color: \"rgba(64,244,155,0.5)\"\r\n })\r\n })\r\n });\r\n\r\n this.map.addLayer(layer);\r\n this.feature = feature;\r\n this.layer = layer;\r\n }\r\n\r\n rotateViewMarker(lookat) {\r\n // Updating feature geometry\r\n let ring = this.generateMarkerCoordinates(lookat);\r\n let polygon = new Polygon([ring]);\r\n polygon.transform('EPSG:4326', 'EPSG:3857');\r\n this.feature.setGeometry(polygon);\r\n }\r\n\r\n generateMarkerCoordinates(lookat) {\r\n // Set up additional constants\r\n let height = this.map.getTargetElement().clientHeight;\r\n let coneAngle = 0.8 * 0.5 * (this.camera.fov * Math.PI / 180);\r\n let axis = new Vector3(0, 0, 1);\r\n\r\n // Cone length is measured in meters based on aerial height\r\n let meterPerPixel = this.map.getView().getResolution();\r\n let coneLength = height * 0.10 * meterPerPixel;\r\n let maxConeLength = 1000000;\r\n if (coneLength > maxConeLength) {\r\n coneLength = 0;\r\n }\r\n\r\n // Center position\r\n let v0 = this.camera.position;\r\n\r\n // Set triangle size\r\n let vector = new Vector3(lookat.x, lookat.y, 0);\r\n vector.setLength(coneLength);\r\n\r\n // First triangle corner\r\n let v1 = vector.clone()\r\n .applyAxisAngle(axis, coneAngle)\r\n .add(v0);\r\n\r\n // Second triangle corner\r\n let v2 = vector.clone()\r\n .applyAxisAngle(axis, -coneAngle)\r\n .add(v0);\r\n\r\n v0 = new SceneCoordinate(v0).toLonLat();\r\n v1 = new SceneCoordinate(v1).toLonLat();\r\n v2 = new SceneCoordinate(v2).toLonLat();\r\n\r\n let ring = [\r\n [v1.x, v1.y],\r\n [v2.x, v2.y],\r\n [v0.x, v0.y],\r\n [v1.x, v1.y]\r\n ];\r\n\r\n return ring;\r\n }\r\n\r\n clear() {\r\n this.layer.setVisible(false);\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n if (!LocalScene.initialized || !changeDetector.changed) return;\r\n\r\n // Update view marker geometry\r\n this.rotateViewMarker(this.viewer.lookatVector);\r\n this.layer.setVisible(true);\r\n }\r\n}\r\n\r\nexport class AerialMap {\r\n private viewer: Viewer;\r\n public containerElement;\r\n public map: Map;\r\n public orthoList: OrthoMosaicList;\r\n private triangle;\r\n private maxLayerZoom = 20;\r\n private maxMapZoomLevel = 28;\r\n private maxCameraZoomLevel = 23;\r\n private styleCache = {};\r\n private pointsSource: VectorSource;\r\n private clusterSource: Cluster;\r\n private clusterLayer: VectorLayer\r\n public activeCamera: CameraImage;\r\n private activeCameraLayer;\r\n private clusterDistance = 10;\r\n private clusterCircleSize = 5.0;\r\n private camerasToIterate = [];\r\n private maxIterationTime = 5;\r\n public calculating = false;\r\n private features = [];\r\n private cameras: CameraImage[] = [];\r\n private observer;\r\n\r\n public mapSystem = {\r\n string: \"EPSG:3857\",\r\n transform: null\r\n } as Projection;\r\n\r\n constructor(viewer: Viewer, container, props) {\r\n this.viewer = viewer;\r\n this.containerElement = container;\r\n\r\n this.initMap();\r\n this.initEvents();\r\n this.initResize();\r\n this.initDataLayers();\r\n\r\n this.orthoList = new OrthoMosaicList(this);\r\n }\r\n\r\n get defaultLayers() {\r\n const arcGISBase = \"https://services.arcgisonline.com/ArcGIS/rest/services\";\r\n\r\n const layers = [\r\n BasemapLayer(\"open-street-maps\", \"OpenStreetMaps\", new OSM({\r\n maxZoom: this.maxLayerZoom\r\n })),\r\n\r\n BasemapLayer(\"arcgis-world\", \"ArcGIS World\", new XYZ({\r\n url: `${arcGISBase}/World_Imagery/MapServer/tile/{z}/{y}/{x}.png`,\r\n maxZoom: this.maxLayerZoom\r\n })),\r\n\r\n BasemapLayer(\"arcgis-world\", \"ArcGIS World\", new XYZ({\r\n attributions: 'Powered by Esri',\r\n url: `${arcGISBase}/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}.png`,\r\n maxZoom: this.maxLayerZoom\r\n })),\r\n\r\n BasemapLayer(\"arcgis-street\", \"ArcGIS Street\", new XYZ({\r\n attributions: 'Powered by Esri',\r\n url: `${arcGISBase}/World_Street_Map/MapServer/tile/{z}/{y}/{x}.png`,\r\n maxZoom: this.maxLayerZoom\r\n })),\r\n ];\r\n\r\n return layers;\r\n }\r\n\r\n get cameraList() {\r\n return this.viewer.cameraList;\r\n }\r\n\r\n get width() {\r\n return this.containerElement.scrollWidth;\r\n }\r\n\r\n get height() {\r\n return this.containerElement.scrollHeight;\r\n }\r\n\r\n get basemapIDs() {\r\n const emptyBasemap = {\r\n id: null,\r\n text: \"No Base Map\"\r\n };\r\n\r\n let layers = [emptyBasemap];\r\n let uniqueIDs = new Set();\r\n\r\n this.basemapLayers.forEach(layer => {\r\n let id = layer.get(\"id\");\r\n let text = layer.get(\"text\");\r\n\r\n if (uniqueIDs.has(id)) return;\r\n uniqueIDs.add(id);\r\n\r\n layers.push({id, text});\r\n });\r\n\r\n return layers;\r\n }\r\n\r\n get basemapLayers() {\r\n return this.map\r\n .getLayers()\r\n .getArray()\r\n .filter(layer => layer.get(\"type\") === \"basemap\");\r\n }\r\n\r\n get activeBasemap() {\r\n let basemapID = null;\r\n this.basemapLayers.forEach(layer => {\r\n let isVisible = layer.getVisible();\r\n if (isVisible) {\r\n basemapID = layer.get(\"id\");\r\n }\r\n });\r\n\r\n return basemapID;\r\n }\r\n\r\n get aerialState() {\r\n const view = this.map.getView();\r\n\r\n const activeBasemap = this.basemapLayers\r\n .find(x => x.getVisible());\r\n\r\n const basemap = activeBasemap\r\n ? activeBasemap.get(\"id\")\r\n : null;\r\n\r\n return {\r\n center: view.getCenter(),\r\n zoom: view.getZoom(),\r\n rotation: view.getRotation(),\r\n basemap\r\n } as AerialViewState;\r\n }\r\n\r\n get anyToolEnabled() {\r\n return this.orthoLabels.enabled\r\n || this.measurements.enabled;\r\n }\r\n\r\n get orthoLabels() {\r\n return this.viewer.imageLabels.orthoLabels;\r\n }\r\n\r\n get localAligner() {\r\n return this.viewer.controls.localAligner;\r\n }\r\n\r\n get measurements() {\r\n return this.viewer.measurements;\r\n }\r\n\r\n get aerialTags() {\r\n return this.viewer.tags.aerialController;\r\n }\r\n\r\n get element() {\r\n return this.map.getTargetElement();\r\n }\r\n\r\n resetView(state = {} as AerialViewState) {\r\n const view = this.map.getView();\r\n\r\n const center = state.center\r\n ? state.center\r\n : [0, 0];\r\n\r\n const zoom = state.zoom\r\n ? state.zoom\r\n : 0;\r\n\r\n const rotation = state.rotation\r\n ? state.rotation\r\n : 0;\r\n\r\n const basemap = state.basemap;\r\n\r\n view.setCenter(center);\r\n view.setZoom(zoom);\r\n view.setRotation(rotation);\r\n this.setVisibleBasemap(basemap);\r\n }\r\n\r\n initMap() {\r\n const attribution = new Attribution({\r\n collapsible: true,\r\n });\r\n\r\n this.map = new Map({\r\n layers: this.defaultLayers,\r\n target: this.containerElement,\r\n controls: defaultControls({\r\n zoom: false,\r\n attribution: false,\r\n rotate: true\r\n }).extend([attribution]),\r\n view: new View({\r\n maxZoom: this.maxMapZoomLevel\r\n })\r\n });\r\n\r\n this.triangle = new ViewTriangle(this, this.map, this.viewer);\r\n\r\n this.resetView();\r\n this.setActiveCamera();\r\n }\r\n\r\n initResize() {\r\n this.observer = onresize(this.containerElement, () => {\r\n this.handleWindowResize();\r\n });\r\n\r\n this.handleWindowResize();\r\n }\r\n\r\n initEvents() {\r\n this.onMapClick = this.onMapClick.bind(this);\r\n this.onMouseUp = this.onMouseUp.bind(this);\r\n this.onDoubleClick = this.onDoubleClick.bind(this);\r\n this.onMouseMove = this.onMouseMove.bind(this);\r\n this.updateSavedState = this.updateSavedState.bind(this);\r\n\r\n this.map.on('click', this.onMapClick);\r\n this.map.on('dblclick', this.onDoubleClick);\r\n this.map.on('pointermove', this.onMouseMove);\r\n this.map.on('moveend', this.updateSavedState);\r\n this.element.addEventListener('mouseup', this.onMouseUp, false);\r\n }\r\n\r\n removeEvents() {\r\n this.map.un('click', this.onMapClick);\r\n this.map.un('dblclick', this.onDoubleClick);\r\n this.map.un('pointermove', this.onMouseMove);\r\n this.map.un('moveend', this.updateSavedState);\r\n this.element.removeEventListener('mouseup', this.onMouseUp, false);\r\n }\r\n\r\n initDataLayers() {\r\n // Create cluster layer for images\r\n this.pointsSource = new VectorSource({\r\n wrapX: false\r\n });\r\n\r\n this.clusterSource = new Cluster({\r\n distance: this.clusterDistance,\r\n source: this.pointsSource,\r\n });\r\n\r\n this.clusterLayer = new VectorLayer({\r\n zIndex: 1,\r\n source: this.clusterSource,\r\n style: feature => {\r\n return this.clusterStyle(feature);\r\n },\r\n });\r\n\r\n this.map.addLayer(this.clusterLayer);\r\n\r\n // Activate camera source\r\n this.activeCameraLayer = new VectorLayer({\r\n zIndex: 1,\r\n visible: false,\r\n source: new VectorSource({\r\n wrapX: false,\r\n features: [new Feature({\r\n geometry: new Point([0,0])\r\n })]\r\n }),\r\n style: this.styleGenerator(1, true, MarkerShape.Circle)\r\n });\r\n\r\n this.map.addLayer(this.activeCameraLayer);\r\n }\r\n\r\n onDoubleClick(event) {\r\n this.orthoLabels.onDoubleClick(event);\r\n }\r\n\r\n onMapClick(event) {\r\n const mapClicked = this.orthoLabels.onMapClick(event)\r\n || this.localAligner.onMapClick(event);\r\n\r\n if (mapClicked) {\r\n return;\r\n }\r\n\r\n let features = this.aerialTags.hovering\r\n ? this.aerialTags.getFeatureForEvent(event)\r\n : this.getFeatureForEvent(event);\r\n\r\n // No features were found\r\n if (features.length === 0) {\r\n return;\r\n }\r\n\r\n const currentView = this.map.getView();\r\n const currentZoom = Math.ceil(currentView.getZoom());\r\n const maxZoomReached = currentZoom >= this.maxCameraZoomLevel;\r\n const singleFeature = features.length === 1;\r\n\r\n if (singleFeature || maxZoomReached) {\r\n const feature = features[0];\r\n\r\n if (feature instanceof TagFeature) {\r\n const selectedTagID = feature.tagID;\r\n showTagDetails(selectedTagID, false);\r\n } else if (feature instanceof BaseCameraFeature) {\r\n const selectedCameraID = feature.cameraID;\r\n this.viewer.loadImage(selectedCameraID);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Zoom to cluster with 50% boundary\r\n let coordinates = [...features].map((x: Feature) => x.getGeometry().getCoordinates());\r\n let extent = boundingExtent(coordinates);\r\n let mapSize = this.map.getSize();\r\n\r\n this.map.getView().fit(extent, {\r\n size: [mapSize[0] * 0.5, mapSize[1] * 0.5],\r\n nearest: false,\r\n duration: 250,\r\n });\r\n\r\n clearAerialTooltip();\r\n }\r\n\r\n onMouseUp(event) {\r\n // Add custom attributes to event\r\n event.isLeftClick = event.button === 0;\r\n event.isRightClick = event.button === 2;\r\n\r\n const mouseClicked = this.orthoLabels.onMouseUp(event)\r\n || this.localAligner.onMouseUp(event);\r\n\r\n if (mouseClicked) {\r\n return;\r\n }\r\n\r\n if (event.isRightClick) {\r\n this.openContextMenu(event);\r\n }\r\n }\r\n\r\n onMouseMove(event) {\r\n if (this.orthoLabels.enabled) {\r\n this.orthoLabels.onMouseMove(event);\r\n } else if (this.measurements.enabled) {\r\n this.measurements.onMouseMoveAerial(event);\r\n } else if (this.localAligner.enabled) {\r\n this.localAligner.onMouseMoveAerial();\r\n } else {\r\n this.aerialTags.onMouseMove(event);\r\n }\r\n }\r\n\r\n updateSavedState() {\r\n setAerialState(this.aerialState);\r\n }\r\n\r\n openContextMenu(event) {\r\n if (this.anyToolEnabled) {\r\n return showContextMenu(event, {\r\n isAerial: true\r\n });\r\n }\r\n\r\n // Tag attributes\r\n const pixel = [event.offsetX, event.offsetY];\r\n const selectedTags = this.aerialTags\r\n .getFeatureForEvent({pixel})\r\n .map(tag => tag.tagID);\r\n\r\n // New tag coordinate\r\n const mapCoordinate = this.map.getCoordinateFromPixel(pixel);\r\n const lonlat = transform(mapCoordinate, 'EPSG:3857', 'EPSG:4326');\r\n const aerialCoord = new LonLatCoordinate(lonlat)\r\n .toDataProjection()\r\n .toArray()\r\n .slice(0,2);\r\n\r\n // Show default context menu\r\n showContextMenu(event, {\r\n isAerial: true,\r\n selectedTags,\r\n aerialCoord\r\n });\r\n }\r\n\r\n getFeatureForEvent(event): BaseCameraFeature[] {\r\n return this.map.getFeaturesAtPixel(event.pixel)\r\n .filter(feature => feature.get('features'))\r\n .reduce((previous, current) => [...previous, ...current.get('features')], [])\r\n .filter(feature => feature instanceof BaseCameraFeature);\r\n }\r\n\r\n handleWindowResize() {\r\n if (!this.map) return;\r\n this.map.updateSize();\r\n this.map.render();\r\n }\r\n\r\n setDragState(state) {\r\n this.map.getInteractions().forEach(interaction => {\r\n if (interaction instanceof DragPan) {\r\n interaction.setActive(state);\r\n }\r\n });\r\n }\r\n\r\n jumpToPosition(position) {\r\n const view = this.map.getView();\r\n view.setCenter(position);\r\n }\r\n\r\n centerOnImages() {\r\n if (this.cameraList.count === 0) {\r\n return;\r\n }\r\n\r\n const extent = this.pointsSource.getExtent();\r\n this.setMapExtent(extent);\r\n }\r\n\r\n addCameraMarkers(cameras: Array) {\r\n let newCameras = cameras.filter(x => !this.cameras.includes(x));\r\n this.cameras = [...this.cameras, ...newCameras];\r\n\r\n // Clear previous data\r\n this.features = [];\r\n this.pointsSource.clear();\r\n\r\n // Reset data to calculate\r\n this.camerasToIterate = this.cameras;\r\n this.calculating = this.cameras.length > 0;\r\n }\r\n\r\n calculateCameras() {\r\n if (this.viewer.calculatingSceneMarkers) return;\r\n if (this.camerasToIterate.length === 0) return;\r\n\r\n let cameraIndex = 0;\r\n let numToIterate = this.camerasToIterate.length;\r\n let camerasCalculated = [];\r\n\r\n let timeStart = performance.now();\r\n for (cameraIndex = 0; cameraIndex < numToIterate; cameraIndex++) {\r\n let camera = this.camerasToIterate[cameraIndex];\r\n let position = camera.position.aerial;\r\n let point = new Point([position[0], position[1]]);\r\n camerasCalculated.push({point, camera});\r\n\r\n let elapsed = performance.now() - timeStart;\r\n if (elapsed > this.maxIterationTime) break;\r\n }\r\n\r\n this.camerasToIterate = this.camerasToIterate.slice(cameraIndex+1);\r\n\r\n // Add new features\r\n camerasCalculated.forEach(({point, camera}) => {\r\n const opts = {\r\n geometry: point,\r\n cameraID: camera.id,\r\n cameraCSV: camera.csv,\r\n saved: camera.saved\r\n };\r\n\r\n let feature;\r\n if (camera instanceof PanoramicImage) {\r\n feature = new PanoramicFeature(opts);\r\n } else if (camera instanceof PlanarImage) {\r\n feature = new PlanarFeature(opts);\r\n }\r\n\r\n this.features.push(feature);\r\n });\r\n\r\n if (this.camerasToIterate.length !== 0) return;\r\n\r\n this.pointsSource.clear();\r\n this.pointsSource.addFeatures(this.features);\r\n this.calculating = false;\r\n\r\n const updateExtent = this.features\r\n .filter(x => x.saved).length === 0;\r\n\r\n if (!updateExtent) return;\r\n this.centerOnImages();\r\n }\r\n\r\n removeCameraMarkers(cameras: CameraImage[]) {\r\n const toRemove = new Set(cameras.map(x => x.id));\r\n\r\n const remainingCameras = this.cameras.filter(x => !toRemove.has(x.id));\r\n this.cameras = [...remainingCameras];\r\n\r\n const remainingFeatures = this.features.filter(x => !toRemove.has(x.cameraID));\r\n this.features = [...remainingFeatures];\r\n }\r\n\r\n recalculateAllMarkers() {\r\n const cameras = [...this.cameras];\r\n this.removeCameraMarkers(cameras);\r\n this.addCameraMarkers(cameras);\r\n }\r\n\r\n styleGenerator(numCameras, active, shape: MarkerShape) {\r\n const strokeColor = 'rgba(0, 0, 0, 1.0)';\r\n const textColor = 'rgba(0, 0, 0, 1.0)';\r\n const fillColor = active\r\n ? 'rgba(255, 195, 0, 0.8)'\r\n : 'rgba(255, 255, 255, 0.8)';\r\n\r\n const scale = (1 + 0.25 * Math.log(numCameras));\r\n const radius = this.clusterCircleSize * scale;\r\n\r\n const text = numCameras > 1\r\n ? numCameras.toString()\r\n : \"\";\r\n\r\n let image;\r\n\r\n if (shape === MarkerShape.Square) {\r\n image = new RegularShapeStyle({\r\n radius: radius * 1.3,\r\n stroke: new Stroke({\r\n color: strokeColor,\r\n width: Math.sqrt(2.0) * 0.95\r\n }),\r\n fill: new Fill({\r\n color: fillColor\r\n }),\r\n angle: Math.PI / 4,\r\n points: 4\r\n });\r\n } else if (shape === MarkerShape.Circle) {\r\n image = new CircleStyle({\r\n radius: radius,\r\n stroke: new Stroke({\r\n color: strokeColor\r\n }),\r\n fill: new Fill({\r\n color: fillColor\r\n }),\r\n });\r\n }\r\n\r\n return new Style({\r\n image,\r\n text: new Text({\r\n text: text,\r\n fill: new Fill({color: textColor}),\r\n }),\r\n });\r\n }\r\n\r\n clusterStyle(feature) {\r\n let features = feature.get('features');\r\n\r\n let numSquares = 0;\r\n let numCircles = 0;\r\n features.forEach(feature => {\r\n numSquares += (feature instanceof PlanarFeature) ? 1 : 0;\r\n numCircles += (feature instanceof PanoramicFeature) ? 1 : 0;\r\n });\r\n\r\n let shape;\r\n let key;\r\n\r\n if ((numSquares > 0) && (numCircles === 0)) {\r\n shape = MarkerShape.Square;\r\n key = `${features.length}-square`;\r\n } else {\r\n shape = MarkerShape.Circle;\r\n key = `${features.length}-circle`;\r\n }\r\n\r\n let style = this.styleCache[key];\r\n\r\n if (!style) {\r\n const numCameras = features.length;\r\n style = this.styleGenerator(\r\n numCameras, false, shape);\r\n\r\n this.styleCache[key] = style;\r\n }\r\n\r\n return style;\r\n }\r\n\r\n setVisibleBasemap(basemapID) {\r\n this.basemapLayers.forEach(layer => {\r\n let id = layer.get(\"id\");\r\n layer.setVisible(id === basemapID);\r\n });\r\n\r\n this.updateSavedState();\r\n }\r\n\r\n setActiveCamera(cameraID = null, centerOnImage = false) {\r\n let camera = this.cameras.find(x => x.id === cameraID);\r\n\r\n if (!camera) {\r\n this.activeCamera = null;\r\n this.activeCameraLayer?.setVisible(false);\r\n return;\r\n }\r\n\r\n const mapPosition = camera.position.aerial;\r\n const point = new Point([mapPosition[0], mapPosition[1]]);\r\n let feature = this.activeCameraLayer.getSource().getFeatures()[0];\r\n feature.setGeometry(point);\r\n this.activeCamera = camera;\r\n\r\n let shape;\r\n if (camera instanceof PanoramicImage) {\r\n shape = MarkerShape.Circle;\r\n } else if (camera instanceof PlanarImage) {\r\n shape = MarkerShape.Square;\r\n }\r\n\r\n // Set layer style\r\n const style = this.styleGenerator(1, true, shape);\r\n feature.setStyle(style);\r\n\r\n // Move aerial map to camera position\r\n if (centerOnImage) {\r\n this.jumpToPosition(mapPosition);\r\n }\r\n\r\n this.activeCameraLayer.setVisible(true);\r\n }\r\n\r\n setMapExtent(extent) {\r\n const view = this.map.getView();\r\n\r\n view.setRotation(0);\r\n view.fit(extent, {\r\n size: this.map.getSize()\r\n });\r\n view.setZoom(view.getZoom() - 1.0);\r\n }\r\n\r\n getByCSV(assetID) {\r\n return this.features.filter(feature => feature.cameraCSV === assetID);\r\n }\r\n\r\n destroy() {\r\n this.removeEvents();\r\n this.observer.disconnect();\r\n this.map.setTarget(null);\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n this.calculateCameras();\r\n\r\n if (this.viewer.orbitState) {\r\n this.triangle.clear();\r\n return;\r\n }\r\n\r\n if (this.viewer.hasPoints || this.viewer.cameraSelected) {\r\n this.triangle.update(changeDetector);\r\n }\r\n }\r\n}\r\n\r\nexport const extentFromPoints = (positions, reproject=true) => {\r\n let xPositions = [];\r\n let yPositions = [];\r\n\r\n if (reproject) {\r\n positions = positions.map(position => {\r\n let lonlat = new DataProjectionCoordinate(position).toLonLat();\r\n let mapPos = transform([lonlat.x, lonlat.y], 'EPSG:4326', 'EPSG:3857');\r\n return mapPos;\r\n });\r\n }\r\n\r\n positions.forEach(position => {\r\n xPositions.push(position[0]);\r\n yPositions.push(position[1]);\r\n });\r\n\r\n let extent = [\r\n Math.min(...xPositions),\r\n Math.min(...yPositions),\r\n Math.max(...xPositions),\r\n Math.max(...yPositions)\r\n ];\r\n\r\n return extent;\r\n};\r\n","export default __webpack_public_path__ + \"static/media/no-image-panoramic.85d85110.png\";","export default __webpack_public_path__ + \"static/media/no-image-planar.91c09176.png\";","import {\r\n DataProjectionCoordinate,\r\n getEulerInverse,\r\n SphericalPosition\r\n} from '../projections';\r\nimport { Viewer } from '../main';\r\nimport { AssetType, PlanarConfig } from '../../../redux/assets-slice';\r\nimport slash from 'slash';\r\nimport {\r\n AmbientLight,\r\n BoxGeometry,\r\n Euler,\r\n LinearFilter,\r\n MathUtils,\r\n Matrix4,\r\n Mesh,\r\n PerspectiveCamera,\r\n Scene,\r\n ShaderMaterial,\r\n Texture,\r\n TextureLoader,\r\n Vector2,\r\n Vector3\r\n} from 'three';\r\nimport { interpolate1D, planeFromVectors, roundDigit } from \"../utilities\";\r\nimport { PanoramicImageMaterial, PlanarImageMaterial } from \"../rendering\";\r\nimport { MouseControls } from \"../controls\";\r\n\r\nimport noImagePanoramicPath from \"../../textures/misc/no-image-panoramic.png\";\r\nimport noImagePlanarPath from \"../../textures/misc/no-image-planar.png\";\r\nimport { toast } from \"../../../app\";\r\nimport { SceneCameraState } from \"../../../redux/camera-slice\";\r\nimport { t } from \"../../../localization\";\r\nimport { ImageCache } from \"./cache\";\r\nimport { Bookmark } from '../../../redux/bookmarks-slice';\r\n\r\nconst imageCache = new ImageCache();\r\nconst loader = new TextureLoader();\r\nconst missingPanoramicTexture = loader.load(noImagePanoramicPath);\r\nconst missingPlanarTexture = loader.load(noImagePlanarPath);\r\n\r\nexport interface ImagePixel {\r\n u: number,\r\n v: number\r\n}\r\n\r\nexport interface CameraLoadOptions {\r\n fov?: number\r\n angles?: number[]\r\n lookat?: DataProjectionCoordinate\r\n centerOnImage?: boolean\r\n}\r\n\r\nclass ImagePosition {\r\n private _value;\r\n private image: CameraImage;\r\n\r\n constructor(image: CameraImage, position) {\r\n this.image = image;\r\n this._value = new Vector3(...position);\r\n }\r\n\r\n get offset() {\r\n let matrix = new Matrix4()\r\n .copy(this.image.matrix)\r\n .transpose();\r\n\r\n return new Vector3()\r\n .setFromMatrixPosition(matrix);\r\n }\r\n\r\n get height() {\r\n return this.image.height;\r\n }\r\n\r\n get uncorrectedEuler() {\r\n return this.image.rotation._euler;\r\n }\r\n\r\n get value() {\r\n let offset = new Vector3()\r\n .copy(this.offset)\r\n .applyEuler(this.image.rotation.eulerCSV);\r\n\r\n let position = new Vector3()\r\n .copy(this._value)\r\n .add(offset);\r\n\r\n return position;\r\n }\r\n\r\n get viewer() {\r\n return new DataProjectionCoordinate(this.value).toScene();\r\n }\r\n\r\n get marker() {\r\n const offset = new Vector3(0, 0, this.height);\r\n return this.viewer.sub(offset);\r\n }\r\n\r\n get aerial() {\r\n return new DataProjectionCoordinate(this.value).toAerial();\r\n }\r\n}\r\n\r\nclass ImageRotation {\r\n public array = [0,0,0];\r\n public _euler: THREE.Euler;\r\n private image: CameraImage;\r\n\r\n constructor(image: CameraImage, rotation) {\r\n this.image = image;\r\n this.setRotation(rotation);\r\n }\r\n\r\n get matrix() {\r\n return new Matrix4()\r\n .copy(this.image.matrix)\r\n .setPosition(0,0,0);\r\n }\r\n\r\n get adjustment() {\r\n const angles = this.image.adjustment;\r\n return new Euler(\r\n -1 * MathUtils.degToRad(angles[0]),\r\n -1 * MathUtils.degToRad(angles[1]),\r\n -1 * MathUtils.degToRad(angles[2])\r\n );\r\n }\r\n\r\n get euler() {\r\n let rotationWithTransform = multiplyRotations(this._euler, this.matrix);\r\n let rotationWithAdjustment = multiplyRotations(rotationWithTransform, this.adjustment);\r\n\r\n let euler = new Euler()\r\n .setFromRotationMatrix(rotationWithAdjustment);\r\n\r\n return euler;\r\n }\r\n\r\n get viewer() {\r\n return new Euler().copy(this.euler);\r\n }\r\n\r\n get eulerCSV() {\r\n return this._euler;\r\n }\r\n\r\n get eulerDegrees() {\r\n let degrees = new Euler();\r\n degrees.x = -1 * MathUtils.radToDeg(this.euler.x);\r\n degrees.y = -1 * MathUtils.radToDeg(this.euler.y);\r\n degrees.z = -1 * MathUtils.radToDeg(this.euler.z);\r\n return degrees;\r\n }\r\n\r\n get eulerCsvInvert() {\r\n return getEulerInverse(this.eulerCSV);\r\n }\r\n\r\n setRotation(rotation) {\r\n this.array = rotation;\r\n this._euler = new Euler(\r\n -1 * MathUtils.degToRad(rotation[0]),\r\n -1 * MathUtils.degToRad(rotation[1]),\r\n -1 * MathUtils.degToRad(rotation[2])\r\n );\r\n }\r\n\r\n clear() {\r\n this.setRotation([0,0,0]);\r\n }\r\n}\r\n\r\nexport class CameraImage {\r\n public id: string;\r\n public csv: string;\r\n public name: string;\r\n public path;\r\n public height;\r\n public config: PlanarConfig;\r\n public adjustment;\r\n public object;\r\n public enabled;\r\n public loaded = false;\r\n public loading = false;\r\n public missing = false;\r\n public ctx;\r\n public canvas;\r\n public materials;\r\n public geometry;\r\n public saved: boolean;\r\n public data;\r\n\r\n public image: HTMLImageElement;\r\n public imageWidth = 0;\r\n public imageHeight = 0;\r\n\r\n public scene: Scene;\r\n public camera: PerspectiveCamera;\r\n public matrix = new Matrix4();\r\n public controls: MouseControls;\r\n public position: ImagePosition;\r\n public rotation: ImageRotation;\r\n\r\n protected material: ShaderMaterial;\r\n protected missingImageTexture;\r\n\r\n constructor(data, controls, scene, camera) {\r\n this.id = data.id;\r\n this.csv = data.csv;\r\n this.name = data.name;\r\n this.path = data.path;\r\n this.height = data.height;\r\n this.adjustment = data.adjustment;\r\n this.config = data.config;\r\n this.saved = data.saved;\r\n\r\n this.data = data;\r\n this.scene = scene;\r\n this.camera = camera;\r\n this.controls = controls;\r\n\r\n this.position = new ImagePosition(this, data.position);\r\n this.rotation = new ImageRotation(this, data.rotation);\r\n\r\n this.reset();\r\n }\r\n\r\n get mimeType() {\r\n let extension = this.name.split(\".\").slice(-1)[0].toLowerCase();\r\n let imageTypes = {\r\n \"jpg\": \"image/jpeg\",\r\n \"jpeg\": \"image/jpeg\",\r\n \"png\": \"image/png\"\r\n };\r\n\r\n return imageTypes[extension] || null;\r\n }\r\n\r\n setCorrectionMatrix(matrix) {\r\n this.matrix = matrix;\r\n }\r\n\r\n pixelToDirection(pixel: ImagePixel) : Vector3 {\r\n console.warn(\"Not implemented\");\r\n return new Vector3();\r\n }\r\n\r\n directionToPixel(direction: Vector3) : ImagePixel {\r\n console.warn(\"Not implemented\");\r\n return null;\r\n }\r\n\r\n /** @private */\r\n setCameraPosition() {\r\n this.camera.position.copy(this.position.viewer);\r\n this.object.position.copy(this.position.viewer);\r\n this.object.rotation.copy(this.rotation.viewer);\r\n }\r\n\r\n /** @private */\r\n setCameraParameters(opts: CameraLoadOptions) {\r\n if (opts.fov) {\r\n this.controls.fov = opts.fov;\r\n }\r\n\r\n if (opts.lookat) {\r\n let position = new DataProjectionCoordinate(opts.lookat).toScene();\r\n this.controls.angles = positionToCameraAngle(\r\n this.object.position, position);\r\n } else if (opts.angles) {\r\n this.controls.angles = opts.angles;\r\n }\r\n }\r\n\r\n loadFromCache(bypassQueue=false) {\r\n return imageCache.get(this.path, this.mimeType, bypassQueue);\r\n }\r\n\r\n /** @private */\r\n async grabImageFromPath() {\r\n const {image, missing} = await this.loadFromCache(true);\r\n\r\n this.image = image;\r\n\r\n if (image) {\r\n this.imageWidth = image.width;\r\n this.imageHeight = image.height;\r\n }\r\n\r\n this.missing = missing;\r\n\r\n if (this.missing) {\r\n toast.error(t(\"toast.image-load-error\", {\r\n name: this.name\r\n }));\r\n }\r\n }\r\n\r\n setObjectVisible(state) {\r\n this.object.visible = state;\r\n }\r\n\r\n activateCamera(opts: CameraLoadOptions = {}) {\r\n this.setCameraPosition();\r\n this.setCameraParameters(opts);\r\n this.loadImageData();\r\n this.setObjectVisible(true);\r\n\r\n this.loaded = true;\r\n this.loading = false;\r\n }\r\n\r\n async loadCameraData() {\r\n this.enabled = true;\r\n this.loaded = false;\r\n this.loading = true;\r\n\r\n this.generateObject();\r\n this.setObjectVisible(false);\r\n await this.grabImageFromPath();\r\n }\r\n\r\n applyTempRotation(angles) {\r\n const angleEuler = new Euler(\r\n -1 * MathUtils.degToRad(angles[0]),\r\n -1 * MathUtils.degToRad(angles[1]),\r\n -1 * MathUtils.degToRad(angles[2])\r\n );\r\n\r\n const tempRotation = multiplyRotations(\r\n this.rotation.eulerCSV, angleEuler);\r\n const euler = new Euler()\r\n .setFromRotationMatrix(tempRotation);\r\n\r\n if (this.object) {\r\n this.object.rotation.copy(euler);\r\n }\r\n\r\n }\r\n\r\n /** @private */\r\n generateObject() {\r\n const geometry = new BoxGeometry(10, 10, 10);\r\n const mesh = new Mesh(geometry, this.material);\r\n this.object = mesh;\r\n this.scene.add(this.object);\r\n }\r\n\r\n /** @private */\r\n loadImageData() {\r\n let imageTexture;\r\n\r\n if (this.missing) {\r\n imageTexture = this.missingImageTexture;\r\n } else {\r\n imageTexture = new Texture();\r\n imageTexture.image = this.image;\r\n }\r\n\r\n imageTexture.minFilter = LinearFilter;\r\n imageTexture.needsUpdate = true;\r\n\r\n this.object.material.setTexture(imageTexture);\r\n }\r\n\r\n destroy() {\r\n if (!this.enabled) return false;\r\n\r\n if (this.object) {\r\n this.scene.remove(this.object);\r\n }\r\n\r\n this.materials.forEach(material => {\r\n if (material.map) {\r\n material.map.dispose();\r\n }\r\n material.dispose();\r\n });\r\n\r\n if (this.geometry) {\r\n this.geometry.dispose();\r\n }\r\n\r\n this.image = null;\r\n this.reset();\r\n }\r\n\r\n reset() {\r\n this.object = null;\r\n this.enabled = false;\r\n this.materials = [];\r\n this.geometry = null;\r\n }\r\n}\r\n\r\nexport class PanoramicImage extends CameraImage {\r\n protected missingImageTexture = missingPanoramicTexture\r\n\r\n constructor(data, mouseControls, scene, camera) {\r\n super(data, mouseControls, scene, camera);\r\n this.material = new PanoramicImageMaterial();\r\n }\r\n\r\n pixelToDirection(pixel: ImagePixel) : Vector3 {\r\n if (!pixel) return null;\r\n\r\n let width = this.imageWidth;\r\n let height = this.imageHeight;\r\n\r\n let theta = -1*MathUtils.degToRad(360 * (pixel.u / width) - 180);\r\n let phi = MathUtils.degToRad(180 * (pixel.v / height));\r\n\r\n let imageDirection = new Vector3(\r\n Math.cos(theta) * Math.sin(phi),\r\n Math.sin(theta) * Math.sin(phi),\r\n Math.cos(phi)\r\n );\r\n\r\n let direction = imageDirection.clone()\r\n .applyEuler(this.rotation.euler);\r\n\r\n return direction;\r\n }\r\n\r\n directionToPixel(direction: Vector3) : ImagePixel {\r\n if (!direction) return null;\r\n\r\n const inverse = getEulerInverse(this.rotation.euler);\r\n const imageDirection = direction.clone()\r\n .applyEuler(inverse);\r\n\r\n let sphere = new SphericalPosition()\r\n .fromVectors(new Vector3(0,0,0), imageDirection);\r\n\r\n let width = this.imageWidth;\r\n let height = this.imageHeight;\r\n\r\n let u = (width*(-sphere.theta + 180)/360);\r\n let v = (height*(sphere.phi)/180);\r\n\r\n u = (u + width) % width;\r\n v = (v + height) % height;\r\n\r\n return {u, v};\r\n }\r\n\r\n directionsToPlanar(directions, planarSize=100) {\r\n // Convert directons to a flat plane based on average normal\r\n const plane = planeFromVectors(directions);\r\n let planar = directions.map(x => {\r\n let target = new Vector3();\r\n plane.projectPoint(x, target);\r\n return target;\r\n });\r\n\r\n let allX = planar.map(x => x.x);\r\n let allY = planar.map(x => x.y);\r\n\r\n let xMin = Math.min(...allX);\r\n let xMax = Math.max(...allX);\r\n let yMin = Math.min(...allY);\r\n let yMax = Math.max(...allY);\r\n\r\n planar = planar.map(point => {\r\n point.x = planarSize * (point.x - xMin) / (xMax-xMin);\r\n point.y = planarSize * (point.y - yMin) / (yMax-yMin);\r\n point.z = 0.0;\r\n return point;\r\n });\r\n\r\n return planar;\r\n }\r\n\r\n interpolatePixels(points, width, height) {\r\n let interpolated = [];\r\n\r\n // Convert pixels to angles\r\n let theta = points.map(x => MathUtils.degToRad((360 * x[0] / width) - 180));\r\n let phi = points.map(x => MathUtils.degToRad(180 * x[1] / height));\r\n\r\n // Convert angles to xyz\r\n let xyz = [];\r\n for (var i=0;i {\r\n let nextIndex = (index+1) % xyz.length;\r\n let xyz2 = xyz[nextIndex];\r\n let distance = new Vector3(...xyz1)\r\n .distanceTo(new Vector3(...xyz2));\r\n\r\n if (distance === 0) {\r\n return;\r\n }\r\n\r\n let steps = Math.ceil(distance/stepSize) + 1;\r\n let _x = interpolate1D(xyz1[0], xyz2[0], steps);\r\n let _y = interpolate1D(xyz1[1], xyz2[1], steps);\r\n let _z = interpolate1D(xyz1[2], xyz2[2], steps);\r\n\r\n let interpTemp = [];\r\n for (var i=0;i {\r\n if (index === 0) {\r\n xyzNoDups.push(current);\r\n return;\r\n }\r\n\r\n let previous = xyz[index - 1];\r\n let distance = new Vector3(...current)\r\n .distanceTo(new Vector3(...previous));\r\n\r\n if (distance !== 0) {\r\n xyzNoDups.push(current);\r\n };\r\n });\r\n xyz = [...xyzNoDups];\r\n\r\n // Convert xyz back to pixels\r\n xyz.forEach(current => {\r\n let r = new Vector2(...current).length();\r\n let _theta = MathUtils.radToDeg(Math.atan2(current[1], current[0]));\r\n let _phi = MathUtils.radToDeg(Math.atan2(r, current[2]));\r\n\r\n interpolated.push([\r\n roundDigit(width * ((_theta + 180) / 360), 4),\r\n roundDigit(height * (_phi / 180), 4)\r\n ]);\r\n });\r\n\r\n return interpolated;\r\n };\r\n}\r\n\r\nexport class PlanarImage extends CameraImage {\r\n protected missingImageTexture = missingPlanarTexture\r\n\r\n constructor(data, mouseControls, scene, camera) {\r\n super(data, mouseControls, scene, camera);\r\n this.material = new PlanarImageMaterial(this.config);\r\n }\r\n\r\n pixelToDirection(pixel: ImagePixel) : Vector3 {\r\n if (!pixel) return null;\r\n\r\n let x = -1 * (pixel.u - this.config.cx) / this.config.fx;\r\n let y = (pixel.v - this.config.cy) / this.config.fy;\r\n\r\n let xyz = new Vector3(x, y, 1.0)\r\n .normalize()\r\n .multiplyScalar(-1.0);\r\n\r\n let direction = xyz.clone()\r\n .applyEuler(this.rotation.euler);\r\n\r\n return direction;\r\n }\r\n\r\n directionToPixel(direction: Vector3, margin=50) : ImagePixel {\r\n if (!direction) return null;\r\n\r\n const inverse = getEulerInverse(this.rotation.euler);\r\n\r\n const imageDirection = direction.clone()\r\n .applyEuler(inverse);\r\n\r\n let xyz = new Vector3()\r\n .copy(imageDirection)\r\n .divideScalar(imageDirection.z);\r\n\r\n let u = -xyz.x * this.config.fx + this.config.cx;\r\n let v = xyz.y * this.config.fy + this.config.cy;\r\n\r\n let outOfBounds = (u < -margin)\r\n || (v < -margin)\r\n || (u > (this.config.width + margin))\r\n || (v > (this.config.height + margin));\r\n\r\n if (outOfBounds) return null;\r\n\r\n return {u, v};\r\n }\r\n}\r\n\r\nexport class CameraList {\r\n public viewer: Viewer;\r\n public scene: Scene;\r\n public cameras: CameraImage[] = [];\r\n private mappingByID = {};\r\n private mappingByName = {};\r\n public matrix = new Matrix4();\r\n public aligned = false;\r\n public waitForCameras = false;\r\n public current: CameraImage | null = null;\r\n public newCameraLoading = false\r\n public cameraLoadedOnce = false;\r\n private cameraHeight;\r\n private cameraAdjustments;\r\n\r\n constructor(viewer) {\r\n this.viewer = viewer;\r\n\r\n this.initScene();\r\n this.initEvents();\r\n }\r\n\r\n get count() {\r\n return this.cameras.length;\r\n }\r\n\r\n get camera() {\r\n return this.viewer.camera;\r\n }\r\n\r\n get controls() {\r\n return this.viewer.controls;\r\n }\r\n\r\n get pointclouds() {\r\n return this.viewer.pointclouds;\r\n }\r\n\r\n get minimap() {\r\n return this.viewer.minimap;\r\n }\r\n\r\n get markers() {\r\n return this.viewer.markers;\r\n }\r\n\r\n get currentIndex() {\r\n return this.cameras.indexOf(this.current);\r\n }\r\n\r\n get cameraLoaded() {\r\n return this.current !== null;\r\n }\r\n\r\n get isEmpty() {\r\n return this.cameras.length === 0;\r\n }\r\n\r\n reconcile(camerasFiles) {\r\n const newCameras = new Set(camerasFiles.map(camera => camera.id));\r\n const currentCameras = new Set(this.cameras.map(camera => camera.id));\r\n const camerasToLoad = camerasFiles.filter(camera => !currentCameras.has(camera.id));\r\n const camerasToDelete = this.cameras.filter(camera => !newCameras.has(camera.id));\r\n\r\n const numCamerasRemoved = camerasToDelete.length;\r\n const numCamerasAdded = camerasToLoad.length;\r\n\r\n // Delete existing cameras\r\n this.deleteCameras(camerasToDelete);\r\n\r\n // Add all new cameras\r\n this.addCameras(camerasToLoad);\r\n\r\n const cameraList = this.cameras;\r\n const numCameras = cameraList.length;\r\n\r\n // Redraw cameras in scene and aerial view after changes\r\n if ((numCamerasRemoved > 0) || (numCamerasAdded > 0)) {\r\n this.minimap.addCameraMarkers(cameraList);\r\n this.markers.addCameraMarkers(cameraList);\r\n this.controls.measurements.refreshMeasurementList();\r\n }\r\n\r\n // Update arrow marker navigation\r\n const changed = ((numCamerasAdded > 0) && (numCamerasAdded < numCameras));\r\n if ((numCamerasRemoved > 0) || changed) {\r\n this.markers.updateArrowNavigation();\r\n }\r\n\r\n return {numCameras, numCamerasAdded, numCamerasRemoved};\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n initEvents() {\r\n return;\r\n }\r\n\r\n onKeyDown(event) {\r\n if (event.key === \"ArrowUp\") {\r\n this.incrementCamera(1);\r\n } else if (event.key === \"ArrowDown\") {\r\n this.incrementCamera(-1);\r\n }\r\n }\r\n\r\n setWaitForCameras(state) {\r\n this.waitForCameras = state;\r\n }\r\n\r\n /** @private */\r\n setNormalCamera() {\r\n let controls = this.controls;\r\n controls.setOrbitValues(false);\r\n }\r\n\r\n /** @private */\r\n setOrbitCamera() {\r\n let controls = this.controls;\r\n controls.setOrbitValues(true);\r\n }\r\n\r\n /** @private */\r\n setCurrentImage(cameraImage: CameraImage | null) {\r\n this.current = cameraImage;\r\n }\r\n\r\n addCameras(cameras) {\r\n if (cameras.length === 0) {\r\n return;\r\n }\r\n\r\n // Get a list of new cameras\r\n let addedIndex = 0;\r\n let newCameras = new Array(cameras.length);\r\n\r\n cameras.forEach(camera => {\r\n const rotation = [\r\n camera.roll,\r\n camera.pitch,\r\n camera.yaw\r\n ];\r\n\r\n const position = [\r\n camera.x,\r\n camera.y,\r\n camera.z\r\n ];\r\n\r\n const adjustment = camera.id in this.cameraAdjustments\r\n ? this.cameraAdjustments[camera.id]\r\n : [0, 0, 0];\r\n\r\n const cameraConfig = camera.config\r\n ? camera.config\r\n : {};\r\n\r\n const assetType = camera.assetType;\r\n\r\n const cameraInfo = {\r\n id: camera.id,\r\n csv: camera.csv,\r\n name: camera.name,\r\n path: slash(camera.path),\r\n rotation: rotation,\r\n position: position,\r\n height: this.cameraHeight,\r\n adjustment: adjustment,\r\n config: cameraConfig,\r\n saved: camera.saved\r\n };\r\n\r\n // Add new camera from info\r\n let newCamera = this.getNewCamera(cameraInfo, assetType);\r\n if (camera) {\r\n newCameras[addedIndex] = newCamera;\r\n addedIndex += 1;\r\n }\r\n });\r\n\r\n if (addedIndex === 0) {\r\n return;\r\n }\r\n\r\n this.cameras = [...this.cameras, ...newCameras.slice(0, addedIndex)];\r\n this.updateCameraMapping();\r\n }\r\n\r\n deleteCameras(cameras) {\r\n if (cameras.length === 0) {\r\n return;\r\n }\r\n\r\n cameras.forEach(camera => {\r\n camera.destroy();\r\n });\r\n\r\n // Update camera array\r\n const toRemove = new Set(cameras.map(x => x.id));\r\n const currentRemoved = this.current && toRemove.has(this.current.id);\r\n const remaining = this.cameras.filter(x => !toRemove.has(x.id));\r\n\r\n this.cameras = [...remaining];\r\n this.updateCameraMapping();\r\n\r\n // Update camera markers\r\n this.minimap.removeCameraMarkers(cameras);\r\n this.markers.removeCameraMarkers(cameras);\r\n\r\n if (this.cameras.length === 0 || currentRemoved) {\r\n this.setCurrentImage(null);\r\n this.cameraLoadedOnce = false;\r\n }\r\n }\r\n\r\n /** @private */\r\n getNewCamera(data, assetType) {\r\n let cameraID = data.id;\r\n if (this.getByID(cameraID)) {\r\n // Camera already exists\r\n return;\r\n }\r\n\r\n let CameraObjectClass;\r\n if (assetType === AssetType.Panoramic) {\r\n CameraObjectClass = PanoramicImage;\r\n } else if (assetType === AssetType.Planar) {\r\n CameraObjectClass = PlanarImage;\r\n } else {\r\n return; // Unknown camera type\r\n }\r\n\r\n let camera = new CameraObjectClass(\r\n data,\r\n this.controls.mouseControls,\r\n this.scene,\r\n this.controls.object,\r\n this.matrix\r\n );\r\n\r\n camera.setCorrectionMatrix(this.matrix);\r\n\r\n return camera;\r\n }\r\n\r\n getByID(cameraID) {\r\n return this.mappingByID[cameraID];\r\n }\r\n\r\n\r\n getByName(cameraName) {\r\n return this.mappingByName[cameraName];\r\n }\r\n\r\n getByCSV(assetID) {\r\n return this.cameras.filter(camera => camera.csv === assetID);\r\n }\r\n\r\n getRowsCSV(cameras: CameraImage[]) {\r\n let csvEncompassOut = [];\r\n csvEncompassOut.push(['Filename', 'X', 'Y', 'Z','Roll', 'Pitch', 'Yaw']);\r\n\r\n cameras.forEach(camera => {\r\n let position = camera.position.value;\r\n let rotation = camera.rotation.eulerDegrees;\r\n\r\n csvEncompassOut.push([\r\n camera.name,\r\n position.x, position.y, position.z,\r\n rotation.x, rotation.y, rotation.z\r\n ]);\r\n });\r\n\r\n return csvEncompassOut;\r\n }\r\n\r\n updateCameraMapping() {\r\n // Direct mapping is required because using this.cameras.find\r\n // inside getByID / getByName is too slow for large number of cameras\r\n this.mappingByID = {};\r\n this.mappingByName = {};\r\n\r\n this.cameras.forEach(camera => {\r\n this.mappingByID[camera.id] = camera;\r\n this.mappingByName[camera.name] = camera;\r\n });\r\n }\r\n\r\n async loadImage(cameraID, opts:CameraLoadOptions = {}) {\r\n if (this.newCameraLoading) {\r\n return;\r\n }\r\n\r\n let camera = this.getByID(cameraID);\r\n if (!camera) {\r\n return;\r\n }\r\n\r\n const {centerOnImage=true} = opts;\r\n\r\n if (camera.enabled) {\r\n // Reload existing camera\r\n console.log(`Reload camera: ${camera.name}`);\r\n this.setNormalCamera();\r\n camera.setCameraParameters(opts);\r\n this.minimap.setActiveCamera(camera.id, centerOnImage);\r\n return camera;\r\n }\r\n\r\n // Load new camera\r\n console.log(`Load camera: ${camera.name}`);\r\n\r\n this.newCameraLoading = true;\r\n\r\n if (!this.cameraLoaded) {\r\n this.setWaitForCameras(true);\r\n }\r\n\r\n // Load image data from path\r\n await camera.loadCameraData();\r\n this.setCurrentImage(camera);\r\n\r\n // Clear previous cameras and switch to normal camera\r\n this.clearImages(camera);\r\n this.setNormalCamera();\r\n this.minimap.setActiveCamera(camera.id, centerOnImage);\r\n\r\n // Set camera visible and apply texture\r\n camera.activateCamera(opts);\r\n\r\n this.setWaitForCameras(false);\r\n this.updateArrowNavigation();\r\n\r\n this.cameraLoadedOnce = true;\r\n this.newCameraLoading = false;\r\n\r\n this.preloadNearbyImages();\r\n\r\n return camera;\r\n }\r\n\r\n preloadNearbyImages() {\r\n const currentIndex = this.viewer.getCurrentCameraIndex();\r\n\r\n // Preload the next image\r\n const nextIndex = this.viewer.getNextCamera(currentIndex);\r\n const nextImage = this.cameras[nextIndex];\r\n nextImage.loadFromCache();\r\n\r\n // Preload the previous image\r\n const previousIndex = this.viewer.getPreviousCamera(currentIndex);\r\n const previousImage = this.cameras[previousIndex];\r\n previousImage.loadFromCache();\r\n }\r\n\r\n preloadBookmarks(bookmarks: Bookmark[]) {\r\n bookmarks.forEach(bookmark => {\r\n const cameraID = bookmark.sceneState.camera;\r\n const camera = this.getByID(cameraID);\r\n if (!camera) return;\r\n camera.loadFromCache();\r\n });\r\n }\r\n\r\n updateArrowNavigation() {\r\n this.viewer.markers.updateArrowNavigation();\r\n }\r\n\r\n clearImages(currentCamera: CameraImage) {\r\n /** Destroy all images except the current one */\r\n this.cameras.forEach(camera => {\r\n if (camera.id === currentCamera.id) {\r\n return;\r\n }\r\n camera.destroy();\r\n });\r\n }\r\n\r\n setMeshVisible(state) {\r\n this.cameras.forEach(camera => {\r\n if (state && !camera.enabled) {\r\n return;\r\n }\r\n\r\n if (camera.object) {\r\n camera.object.visible = state;\r\n }\r\n });\r\n }\r\n\r\n incrementCamera(increment) {\r\n if (!this.current) return;\r\n\r\n let cameraIndex = this.currentIndex;\r\n let nextIndex = cameraIndex + increment;\r\n nextIndex = (nextIndex + this.count) % this.count ;\r\n let nextCamera = this.cameras[nextIndex];\r\n this.viewer.loadImage(nextCamera.id);\r\n }\r\n\r\n setCameraHeights(height) {\r\n this.cameraHeight = height;\r\n this.cameras.forEach(camera => {\r\n camera.height = height;\r\n });\r\n this.markers.recalculateAllMarkers();\r\n }\r\n\r\n setCameraAdjustments(adjustments) {\r\n this.cameraAdjustments = adjustments;\r\n this.cameras.forEach(camera => {\r\n const adjustment = camera.id in adjustments\r\n ? adjustments[camera.id]\r\n : [0, 0, 0];\r\n camera.adjustment = adjustment;\r\n });\r\n }\r\n\r\n setCameraMatrix(elements) {\r\n const newMatrix = new Matrix4().fromArray(elements);\r\n if (!this.matrix.equals(newMatrix)) {\r\n this.matrix = newMatrix;\r\n this.applyMatrixToCameras();\r\n this.aligned = true;\r\n }\r\n }\r\n\r\n /** Reset to identity matrix */\r\n resetCameraMatrix() {\r\n this.matrix = new Matrix4();\r\n this.applyMatrixToCameras();\r\n this.aligned = false;\r\n }\r\n\r\n applyMatrixToCameras() {\r\n this.minimap.recalculateAllMarkers();\r\n this.markers.recalculateAllMarkers();\r\n\r\n this.cameras.forEach(camera => {\r\n camera.setCorrectionMatrix(this.matrix);\r\n });\r\n\r\n if (this.current) {\r\n this.setNormalCamera();\r\n this.current.setCameraPosition();\r\n }\r\n\r\n this.markers.updateArrowNavigation();\r\n }\r\n\r\n /** @private */\r\n loadSavedCameraState(savedCameraState: SceneCameraState) {\r\n let savedcameraID;\r\n const activeCamera = savedCameraState.camera;\r\n const savedLookat = savedCameraState.lookat;\r\n\r\n if (activeCamera) {\r\n // Load saved camera based on saved camera id\r\n const cameraExists = this.getByID(activeCamera);\r\n\r\n if (cameraExists) {\r\n savedcameraID = activeCamera;\r\n }\r\n } else if (savedLookat) {\r\n // Load closest camera based on saved position\r\n const lookat = new DataProjectionCoordinate(savedLookat);\r\n const closestCameraID = this.closestCameraToPosition(lookat);\r\n\r\n if (closestCameraID) {\r\n savedcameraID = closestCameraID;\r\n } else {\r\n toast.warning(t(\"toast.camera-error-xyz\"));\r\n }\r\n }\r\n\r\n if (!savedcameraID) return false;\r\n\r\n // Convert from SceneCameraState to CameraLoadOptions\r\n const lookatVector = savedCameraState.lookat\r\n ? new DataProjectionCoordinate(savedCameraState.lookat)\r\n : null;\r\n\r\n const cameraLoadOptions = {\r\n fov: savedCameraState.fov,\r\n angles: savedCameraState.angles,\r\n lookat: lookatVector,\r\n centerOnImage: false\r\n } as CameraLoadOptions;\r\n\r\n this.viewer.loadImage(savedcameraID, cameraLoadOptions);\r\n\r\n return true;\r\n }\r\n\r\n closestCameraToPosition(position: DataProjectionCoordinate): number | undefined {\r\n let minDistance = 10;\r\n let maxDistance = 500;\r\n\r\n let bestDistance = maxDistance;\r\n let cameraID;\r\n\r\n for (const camera of this.cameras) {\r\n const distance = position.distanceTo(camera.position.value);\r\n if (distance < bestDistance && distance <= maxDistance && distance >= minDistance) {\r\n bestDistance = distance;\r\n cameraID = camera.id;\r\n }\r\n }\r\n\r\n return cameraID;\r\n }\r\n\r\n update() {\r\n return;\r\n }\r\n}\r\n\r\nconst multiplyRotations = (rotationA, rotationB) => {\r\n let matrixA = rotationA instanceof Euler\r\n ? new Matrix4().makeRotationFromEuler(rotationA)\r\n : rotationA;\r\n\r\n let matrixB = rotationB instanceof Euler\r\n ? new Matrix4().makeRotationFromEuler(rotationB)\r\n : rotationB;\r\n\r\n return new Matrix4().multiplyMatrices(matrixA, matrixB);\r\n};\r\n\r\nexport const directionToCameraAngle = (direction: Vector3) : [number, number] => {\r\n return positionToCameraAngle(new Vector3(), direction);\r\n};\r\n\r\nexport const positionToCameraAngle = (cameraPos: Vector3, position: Vector3) : [number, number] => {\r\n const sphere = new SphericalPosition().fromVectors(cameraPos, position);\r\n const theta = MathUtils.degToRad(sphere.theta);\r\n const phi = MathUtils.degToRad(90 - sphere.phi);\r\n\r\n return [theta, phi] as [number, number];\r\n};","import { readFileBuffer } from \"../file-system-loader\";\r\n\r\ninterface ImageResponse {\r\n image: HTMLImageElement\r\n missing: boolean\r\n lastAccess: number\r\n imagePath: string\r\n}\r\n\r\nexport class ImageCache {\r\n private queue = [];\r\n private cache : { [path: string]: ImageResponse } = {};\r\n private processing = new Set();\r\n private maxNumProcessing = 2;\r\n private maxCacheSize = 20;\r\n\r\n async get(imagePath: string, mimeType: string, bypassQueue: boolean): Promise {\r\n if (imagePath in this.cache) {\r\n // Update last used timestamp and return cached values\r\n this.cache[imagePath].lastAccess = performance.now();\r\n return this.cache[imagePath];\r\n }\r\n\r\n if (this.processing.has(imagePath)) {\r\n // Image is already loading, just wait for the result\r\n return this.waitForImage(imagePath);\r\n }\r\n\r\n if (bypassQueue) {\r\n // Grab the image, ignoring the processing queue\r\n await this.loadToCache(imagePath, mimeType);\r\n return this.cache[imagePath];\r\n }\r\n\r\n // Add image path to processing queue and wait for the results\r\n this.queue.push({imagePath, mimeType});\r\n this.removeOldData();\r\n this.processQueue();\r\n\r\n return this.waitForImage(imagePath);\r\n }\r\n\r\n waitForImage(imagePath): Promise {\r\n return new Promise(resolve => {\r\n const interval = setInterval(async () => {\r\n if (imagePath in this.cache) {\r\n clearInterval(interval);\r\n resolve(this.cache[imagePath]);\r\n }\r\n }, 100);\r\n });\r\n }\r\n\r\n /** @private */\r\n async processQueue() {\r\n if (this.processing.size >= this.maxNumProcessing) return;\r\n if (this.queue.length === 0) return;\r\n\r\n const {imagePath, mimeType} = this.queue.shift();\r\n\r\n this.processing.add(imagePath);\r\n\r\n if (!this.cache.hasOwnProperty(imagePath)) {\r\n await this.loadToCache(imagePath, mimeType);\r\n }\r\n\r\n this.processing.delete(imagePath);\r\n this.processQueue();\r\n }\r\n\r\n /** @private */\r\n async loadToCache(imagePath: string, mimeType: string) {\r\n let image = null;\r\n let missing = false;\r\n\r\n try {\r\n const buffer = await readFileBuffer(imagePath);\r\n\r\n // Load image source from buffer\r\n let arrayBufferView = new Uint8Array(buffer);\r\n let blob = new Blob([arrayBufferView], {\r\n type: mimeType\r\n });\r\n\r\n // Image successfully loaded\r\n const blobPath = URL.createObjectURL(blob);\r\n image = await this.loadImageFromPath(blobPath);\r\n } catch {\r\n // Image must be missing\r\n missing = true;\r\n }\r\n\r\n const lastAccess = performance.now();\r\n\r\n // Image has been loaded\r\n this.cache[imagePath] = {\r\n missing,\r\n lastAccess,\r\n image,\r\n imagePath\r\n };\r\n }\r\n\r\n /** @private */\r\n removeOldData() {\r\n const keys = Object.keys(this.cache);\r\n if (keys.length <= this.maxCacheSize) return;\r\n\r\n const data = keys.map(key => this.cache[key]);\r\n\r\n data.sort((a,b) => {\r\n return a.lastAccess - b.lastAccess;\r\n });\r\n\r\n data.reverse();\r\n\r\n this.cache = {};\r\n\r\n data.forEach((image, index) => {\r\n if (index > this.maxCacheSize) return;\r\n this.cache[image.imagePath] = image;\r\n });\r\n }\r\n\r\n /** @private */\r\n loadImageFromPath(path): Promise {\r\n return new Promise(resolve => {\r\n const image = new Image();\r\n image.onload = () => {\r\n resolve(image);\r\n };\r\n image.src = path;\r\n });\r\n }\r\n}","import React, { ReactNode, useEffect, useState } from \"react\";\r\nimport { sendCustomEvent } from \"../events\";\r\nimport {\r\n showTagDetails,\r\n TagCreateDialog,\r\n TagDeleteDialog\r\n} from \"../folder\";\r\nimport { isStaticSite } from \"../electron-modules\";\r\nimport { DialogContent, Typography } from \"@material-ui/core\";\r\nimport {\r\n EnhancedTable,\r\n DraggableDialog,\r\n MenuDivider,\r\n DenseMenu,\r\n DenseIcon\r\n} from \"../components\";\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useAuth, useContextMenu, useDialog, useViewer } from \"../hooks\";\r\nimport DeleteIcon from '@material-ui/icons/Delete';\r\nimport InfoIcon from '@material-ui/icons/Info';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport RoomIcon from \"@material-ui/icons/Room\";\r\nimport ClearIcon from '@material-ui/icons/Clear';\r\nimport ZoomInIcon from '@material-ui/icons/ZoomIn';\r\nimport RotateLeftIcon from '@material-ui/icons/RotateLeft';\r\nimport ToggleOnIcon from '@material-ui/icons/ToggleOn';\r\nimport ToggleOffIcon from '@material-ui/icons/ToggleOff';\r\nimport TrendingUpIcon from '@material-ui/icons/TrendingUp';\r\nimport TrendingDownIcon from '@material-ui/icons/TrendingDown';\r\nimport SearchIcon from '@material-ui/icons/Search';\r\nimport SyncIcon from '@material-ui/icons/Sync';\r\nimport AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';\r\nimport LinkIcon from '@material-ui/icons/Link';\r\nimport { useDispatch, useSelector } from \"react-redux\";\r\nimport { CustomURL, selectAllCustomLinks } from \"../redux/custom-links-slice\";\r\nimport { openExternalLink } from \"../urls\";\r\nimport { toast } from \"../app\";\r\nimport { updateTag } from \"../redux/assets-slice\";\r\nimport { useTableState } from \"../hooks/use-table-state\";\r\nimport copyTextToClipboard from \"copy-to-clipboard\";\r\n\r\nexport interface LabelContextData {\r\n labelID: number\r\n pointID: number\r\n coordinate: number[] | object\r\n}\r\n\r\nexport interface ContextData {\r\n isAerial?: boolean\r\n sceneCoord?: number[]\r\n aerialCoord?: number[]\r\n labelData?: LabelContextData\r\n selectedTags?: string[]\r\n modelData?: object[]\r\n}\r\n\r\ninterface ContextMenuItem {\r\n text: string\r\n icon: ReactNode\r\n seperator?: boolean\r\n disabled?: boolean\r\n visible?: boolean\r\n callback: Function\r\n}\r\n\r\nexport const ContextMenu = (props) => {\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const dispatch = useDispatch();\r\n\r\n const contextMenu = useContextMenu();\r\n const newTagDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n const customLinks = useSelector(selectAllCustomLinks);\r\n const {permissions} = useAuth();\r\n\r\n const [modelProperties, setModelProperties] = useState(null);\r\n const [tagsToDelete, setTagsToDelete] = useState([]);\r\n const [tagCoordinate, setTagCoordinate] = useState([]);\r\n\r\n const {isAerial=false, labelData, selectedTags, modelData,\r\n sceneCoord, aerialCoord} = contextMenu.data as ContextData;\r\n\r\n const onClose = () => {\r\n contextMenu.handleClose();\r\n viewer?.clearCadHighlight();\r\n };\r\n\r\n const onEnter = () => {\r\n props.clearTooltipText();\r\n };\r\n\r\n const listItemSeperator = (visible) => {\r\n return {\r\n text: \"\",\r\n seperator: true,\r\n visible\r\n };\r\n };\r\n\r\n const constructCustomURL = (customURL: CustomURL, sceneCoord, aerialCoord) => {\r\n let urlString = customURL.url;\r\n\r\n let position = isAerial\r\n ? aerialCoord\r\n : sceneCoord;\r\n\r\n if (position.length === 2) {\r\n // Add placeholder height to aerial coordinates\r\n position.push(0);\r\n }\r\n\r\n urlString = urlString\r\n .replaceAll('{x}', position[0].toFixed(3))\r\n .replaceAll('{y}', position[1].toFixed(3))\r\n .replaceAll('{z}', position[2].toFixed(3));\r\n\r\n const target = customURL.target;\r\n openExternalLink(urlString, {target});\r\n };\r\n\r\n const getMenuItems = () => {\r\n if (!viewer || !contextMenu.open) {\r\n return [] as ContextMenuItem[];\r\n }\r\n\r\n let numLabelsSelected = viewer.numLabelsHighlighted();\r\n let profileActive = viewer.pointProfileActive();\r\n\r\n const labelSelected = labelData\r\n ? labelData.labelID !== null\r\n : false;\r\n\r\n const labelPointSelected = labelData\r\n ? labelData.pointID !== null\r\n : false;\r\n\r\n const hasLabelCoord = labelData\r\n ? labelData.coordinate !== null\r\n : false;\r\n\r\n const numTagsSelected = selectedTags\r\n ? selectedTags.length\r\n : 0;\r\n\r\n const hasModelData = modelData\r\n ? modelData.length > 0\r\n : false;\r\n\r\n const hasSceneCoord = !!sceneCoord;\r\n const hasAerialCoord = !!aerialCoord;\r\n\r\n const noTagSelected = numTagsSelected === 0;\r\n const oneTagSelected = numTagsSelected === 1;\r\n\r\n const pointProfileActions = [\r\n {\r\n text: t(\"context-menu.profile\"),\r\n icon: ,\r\n disabled: !hasSceneCoord,\r\n visible: !isAerial && !profileActive,\r\n callback: () => {\r\n viewer.pointProfileStart(sceneCoord);\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.profile-end\"),\r\n icon: ,\r\n disabled: !hasSceneCoord,\r\n visible: !isAerial && profileActive,\r\n callback: () => {\r\n viewer.pointProfileEnd();\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.profile-cancel\"),\r\n icon: ,\r\n visible: !isAerial && profileActive,\r\n callback: () => {\r\n viewer.pointProfileCancel();\r\n }\r\n },\r\n ] as ContextMenuItem[];;\r\n\r\n const tagActions = [\r\n {\r\n text: t(\"context-menu.new-tag\"),\r\n icon: ,\r\n visible: permissions.create\r\n && (hasSceneCoord || hasAerialCoord)\r\n && noTagSelected,\r\n callback: () => {\r\n setTagCoordinate(sceneCoord || aerialCoord);\r\n newTagDialog.handleOpen();\r\n }\r\n },\r\n {\r\n text: t('tags.move_to_tag'),\r\n icon: ,\r\n visible: isAerial && oneTagSelected,\r\n callback: () => {\r\n // Jump to nearest camera position\r\n viewer.jumpToTag(selectedTags[0]);\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.copy-tag\"),\r\n icon: ,\r\n visible: isStaticSite && oneTagSelected,\r\n callback: () => {\r\n // Copy url to clipboard\r\n const url = new URL(window.location as any);\r\n url.hash = `tag=${selectedTags[0]}`;\r\n copyTextToClipboard(url.href);\r\n toast.success(t(\"toast.copied-to-clipboard\"));\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.update-tag-view\"),\r\n icon: ,\r\n visible: permissions.edit && oneTagSelected,\r\n callback: () => {\r\n dispatch(updateTag({\r\n tagID: selectedTags[0],\r\n sceneState: viewer.sceneState\r\n }));\r\n\r\n toast.success(t(\"toast.updated-tag-view\"));\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.edit-tag\"),\r\n icon: ,\r\n visible: permissions.edit && oneTagSelected,\r\n callback: () => {\r\n showTagDetails(selectedTags[0], true);\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.delete-tags\", {\r\n count: numTagsSelected\r\n }),\r\n icon: ,\r\n visible: permissions.delete && !noTagSelected,\r\n callback: () => {\r\n setTagsToDelete(selectedTags);\r\n deleteDialog.handleOpen();\r\n }\r\n }\r\n ] as ContextMenuItem[];\r\n\r\n const orbitModeActions = [\r\n {\r\n text: viewer.orbitState\r\n ? t(\"context-menu.disable-3d-mode\")\r\n : t(\"context-menu.enable-3d-mode\"),\r\n icon: viewer.orbitState\r\n ? \r\n : ,\r\n disabled: !(viewer.hasPoints && viewer.cameraSelected),\r\n visible: !isAerial,\r\n callback: () => {\r\n viewer.toggleOrbitState();\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.reset-3d-mode\"),\r\n icon: ,\r\n disabled: !viewer.orbitState,\r\n visible: !isAerial,\r\n callback: () => {\r\n viewer.resetCamera();\r\n }\r\n },\r\n ] as ContextMenuItem[];\r\n\r\n const modelActions = [\r\n {\r\n text: t(\"context-menu.model-properties\"),\r\n icon: ,\r\n visible: hasModelData,\r\n callback: () => {\r\n setModelProperties(modelData);\r\n }\r\n }\r\n ] as ContextMenuItem[];\r\n\r\n const labelActions = [\r\n {\r\n text: t(\"context-menu.delete-label\", {\r\n count: numLabelsSelected\r\n }),\r\n icon: ,\r\n disabled: viewer.anyLabelSelected(),\r\n callback: () => {\r\n viewer.deleteHighlighted();\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.delete-point\"),\r\n icon: ,\r\n disabled: !labelPointSelected,\r\n callback: () => {\r\n viewer.deleteLabelPoint(labelData.pointID);\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.unselect-label\", {\r\n count: numLabelsSelected\r\n }),\r\n icon: ,\r\n disabled: viewer.anyLabelSelected(),\r\n callback: () => {\r\n viewer.unHighlightAll();\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.insert-point\"),\r\n icon: ,\r\n disabled: !hasLabelCoord || labelPointSelected,\r\n callback: () => {\r\n viewer.insertLabelPoint(\r\n labelData.labelID,\r\n labelData.coordinate\r\n );\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.edit-point\"),\r\n icon: ,\r\n disabled: !hasLabelCoord || labelPointSelected,\r\n callback: () => {\r\n viewer.editLabel(\r\n labelData.labelID,\r\n labelData.coordinate\r\n );\r\n }\r\n },\r\n {\r\n text: t(\"context-menu.find-in-list\"),\r\n icon: ,\r\n disabled: !labelSelected,\r\n callback: () => {\r\n viewer.moveToLabel(labelData.labelID);\r\n }\r\n }\r\n ] as ContextMenuItem[];\r\n\r\n const customUserActions = customLinks\r\n .filter(values => {\r\n return isAerial\r\n ? values.showInAerial\r\n : values.showInScene;\r\n })\r\n .map(values => {\r\n return {\r\n text: values.name,\r\n icon: ,\r\n disabled: !hasSceneCoord && !hasAerialCoord,\r\n callback: () => {\r\n constructCustomURL(values, sceneCoord, aerialCoord);\r\n }\r\n };\r\n }) as ContextMenuItem[];\r\n\r\n if (numLabelsSelected > 0) {\r\n // Labels are selected\r\n return [...labelActions];\r\n }\r\n\r\n const hasCustom = customUserActions.length > 0;\r\n\r\n return [\r\n ...tagActions,\r\n listItemSeperator(hasModelData),\r\n ...modelActions,\r\n listItemSeperator(!isAerial),\r\n ...orbitModeActions,\r\n listItemSeperator(!isAerial),\r\n ...pointProfileActions,\r\n listItemSeperator(hasCustom),\r\n ...customUserActions\r\n ] as ContextMenuItem[];\r\n };\r\n\r\n /** Context menu event listener */\r\n useEffect(() => {\r\n const callback = (menuEvent) => {\r\n const {event, data} = menuEvent.detail;\r\n contextMenu.handleOpen(event, data);\r\n };\r\n\r\n document.addEventListener(\"context-menu\", callback);\r\n\r\n return () => {\r\n document.removeEventListener(\"context-menu\", callback);\r\n };\r\n }, []);\r\n\r\n let options = getMenuItems();\r\n\r\n options = options.filter(item => {\r\n return item.hasOwnProperty(\"visible\")\r\n ? item.visible\r\n : true;\r\n });\r\n\r\n // Make sure a seperator isnt the first element\r\n if ((options.length > 0) && options[0].seperator) {\r\n options = options.slice(1);\r\n }\r\n\r\n return (\r\n \r\n 0}\r\n onClose={onClose}\r\n onEnter={onEnter}\r\n anchorPosition={contextMenu.anchorPosition}\r\n >\r\n {options.map((option) => {\r\n if (option.seperator) {\r\n return ;\r\n }\r\n\r\n return (\r\n {\r\n onClose();\r\n option.callback();\r\n }}\r\n >\r\n {option.icon\r\n ? option.icon\r\n : \r\n }\r\n\r\n \r\n {option.text}\r\n \r\n\r\n \r\n );\r\n })}\r\n \r\n\r\n {/* New Tag Dialog */}\r\n \r\n\r\n {/* Delete Tag Dialog */}\r\n \r\n\r\n \r\n\r\n \r\n );\r\n};\r\n\r\ninterface ModelPropertiesProps {\r\n data: any[]\r\n setData(data): void\r\n}\r\n\r\nconst ModelProperties = (props: ModelPropertiesProps) => {\r\n const {data, setData} = props;\r\n\r\n const {t} = useTranslation();\r\n const tableState = useTableState();\r\n\r\n const open = data ? data.length > 0 : false;\r\n\r\n const onClose = () => {\r\n setData(null);\r\n };\r\n\r\n const getRows = () => {\r\n if (!data) return [];\r\n\r\n return data.map((property, index) => {\r\n return {\r\n id: `PropertyTableRow_${index}`,\r\n ...property\r\n };\r\n });\r\n };\r\n\r\n const columns = [\r\n {\r\n id: 'property',\r\n label: t(\"model-properties.property\")\r\n },\r\n {\r\n id: 'value',\r\n label: t(\"model-properties.value\"),\r\n wordBreak: true\r\n }\r\n ];\r\n\r\n const rows = getRows();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const showContextMenu = (event, contextData = {} as ContextData) => {\r\n event.preventDefault();\r\n sendCustomEvent(\"context-menu\", {event, data: contextData});\r\n};","import React, { useEffect, useState } from \"react\";\r\nimport {\r\n Card,\r\n CardHeader,\r\n createStyles,\r\n Grid,\r\n IconButton,\r\n List,\r\n makeStyles,\r\n Theme,\r\n} from \"@material-ui/core\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useDispatch, useSelector } from \"react-redux\";\r\nimport slash from \"slash\";\r\nimport {\r\n ArrowTooltip,\r\n CheckboxWithLabel,\r\n DenseDivider,\r\n DraggableDialog,\r\n IconToolBar,\r\n InputWithLabel,\r\n PromptDialog,\r\n SimpleDialog,\r\n SlimScrollbar,\r\n ToolBarButton\r\n} from \"../components\";\r\nimport { dialog, fs } from \"../electron-modules\";\r\nimport { customURLFilter } from \"../file-extensions\";\r\nimport { useDialog, useUniqueProjectID } from \"../hooks\";\r\nimport {\r\n createCustomLink,\r\n updateCustomLink,\r\n CustomURL,\r\n selectAllCustomLinks,\r\n deleteCustomLink\r\n} from \"../redux/custom-links-slice\";\r\nimport DeleteIcon from '@material-ui/icons/Delete';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport GetAppIcon from '@material-ui/icons/GetApp';\r\nimport { toast } from \"../app\";\r\nimport CardContent from \"@material-ui/core/CardContent\";\r\nimport Typography from \"@material-ui/core/Typography\";\r\nimport { toLocaleString } from \"../utilities\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n card: {\r\n margin: theme.spacing(2),\r\n marginTop: theme.spacing(0),\r\n padding: theme.spacing(1),\r\n userSelect: \"none\"\r\n },\r\n cardHeader: {\r\n padding: theme.spacing(1)\r\n },\r\n cardButtons: {\r\n marginTop: 0,\r\n alignSelf: \"center\"\r\n },\r\n headerTitle: {\r\n fontWeight: \"bold\",\r\n cursor: \"pointer\"\r\n },\r\n cardContent: {\r\n margin: theme.spacing(1,2),\r\n padding: theme.spacing(0),\r\n paddingBottom: \"0px !important\",\r\n wordBreak: \"break-all\"\r\n }\r\n })\r\n);\r\n\r\nconst EditLinkDialog = (props) => {\r\n const {open, onClose, values} = props;\r\n\r\n const dispatch = useDispatch();\r\n const {t} = useTranslation();\r\n\r\n const [name, setName] = useState(\"\");\r\n const [url, setUrl] = useState(\"\");\r\n const [target, setTarget] = useState(\"\");\r\n const [showInScene, setShowInScene] = useState(false);\r\n const [showInAerial, setShowInAerial] = useState(false);\r\n\r\n const addNewLink = !values;\r\n\r\n const handleSubmit = () => {\r\n onClose();\r\n\r\n if (addNewLink) {\r\n dispatch(createCustomLink({\r\n name,\r\n url,\r\n target,\r\n showInScene,\r\n showInAerial\r\n }));\r\n } else {\r\n dispatch(updateCustomLink({\r\n linkID: values.id,\r\n name,\r\n url,\r\n target,\r\n showInScene,\r\n showInAerial\r\n }));\r\n\r\n toast.success(t('toast.updated_custom_url'));\r\n }\r\n };\r\n\r\n const resetDefaults = () => {\r\n setName(\"\");\r\n setUrl(\"\");\r\n setTarget(\"\");\r\n setShowInScene(false);\r\n setShowInAerial(false);\r\n };\r\n\r\n const loadCustomValues = () => {\r\n setName(values.name);\r\n setUrl(values.url);\r\n setTarget(values.target);\r\n setShowInScene(values.showInScene);\r\n setShowInAerial(values.showInAerial);\r\n };\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n if (addNewLink) {\r\n resetDefaults();\r\n } else {\r\n loadCustomValues();\r\n }\r\n }, [open]);\r\n\r\n const canSubmit = (name !== \"\")\r\n && (url !== \"\")\r\n && (target !== \"\");\r\n\r\n return (\r\n \r\n \r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n {t('custom-link.the_url_supports_the_following_special_values')}\r\n
    \r\n
  • {t('custom-link.the_current_x_coordinate')}
  • \r\n
  • {t('custom-link.the_current_y_coordinate')}
  • \r\n
  • {t('custom-link.the_current_z_coordinate')}
  • \r\n
\r\n }\r\n value={url}\r\n onChange={setUrl}\r\n />\r\n
\r\n\r\n \r\n \r\n \r\n\r\n {/** Display in scene view */}\r\n \r\n \r\n \r\n\r\n {/** Display in aerial view */}\r\n \r\n \r\n \r\n\r\n
\r\n \r\n );\r\n};\r\n\r\nconst CustomLink = (props) => {\r\n const classes = useStyles();\r\n const {i18n, t} = useTranslation();\r\n const dispatch = useDispatch();\r\n const editDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n\r\n const values = props.data as CustomURL;\r\n const dateString = toLocaleString(values.date, i18n.language);\r\n\r\n const handleEdit = () => {\r\n editDialog.handleOpen(values);\r\n };\r\n\r\n const handleDownload = async () => {\r\n const result = await dialog.showSaveDialog( {\r\n defaultPath: `${values.name}.json`,\r\n filters: customURLFilter,\r\n });\r\n\r\n if (result.canceled) return;\r\n\r\n const jsonData = {\r\n name: values.name,\r\n url: values.url,\r\n target: values.target,\r\n showInScene: values.showInScene,\r\n showInAerial: values.showInAerial\r\n };\r\n\r\n const text = JSON.stringify(jsonData, null, 2);\r\n const savePath = slash(result.filePath);\r\n fs.writeFileSync(savePath, text);\r\n };\r\n\r\n const handleDeleteSubmit = () => {\r\n dispatch(deleteCustomLink(values.id));\r\n };\r\n\r\n return (\r\n \r\n \r\n \r\n {/** Download definition */}\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/** Edit values */}\r\n \r\n \r\n \r\n \r\n \r\n\r\n {/** Delete */}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n }\r\n title={values.name}\r\n titleTypographyProps={{\r\n variant: \"body2\",\r\n className: classes.headerTitle\r\n }}\r\n subheader={dateString}\r\n subheaderTypographyProps={{\r\n variant: \"caption\"\r\n }}\r\n />\r\n \r\n
\r\n \r\n {t('custom-link.url')}: \r\n \r\n \r\n {values.url}\r\n \r\n
\r\n\r\n
\r\n \r\n {t('custom-link.target')}: \r\n \r\n \r\n {values.target}\r\n \r\n
\r\n
\r\n \r\n\r\n {/* Delete Dialog */}\r\n \r\n\r\n {/* Edit Dialog */}\r\n \r\n \r\n );\r\n};\r\n\r\nexport const CustomContextURL = (props) => {\r\n const {customURLDialog} = props;\r\n\r\n const dispatch = useDispatch();\r\n const {t} = useTranslation();\r\n const newURLDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const customLinks = useSelector(selectAllCustomLinks);\r\n\r\n const handleNewLink = () => {\r\n newURLDialog.handleOpen();\r\n };\r\n\r\n const handleImport = async () => {\r\n const result = await dialog.showOpenDialog({\r\n properties: ['openFile'],\r\n filters: customURLFilter\r\n });\r\n\r\n if (result.canceled) return;\r\n\r\n let filePath = slash(result.filePaths[0]);\r\n\r\n try {\r\n const text = fs.readFileSync(filePath, 'utf8');\r\n const data = JSON.parse(text);\r\n importURLData(data);\r\n } catch {\r\n toast.error(t('toast.error_reading_custom_url_definition'));\r\n }\r\n };\r\n\r\n const importURLData = (values) => {\r\n const valid = values.hasOwnProperty(\"name\")\r\n && values.hasOwnProperty(\"url\")\r\n && values.hasOwnProperty(\"target\")\r\n && values.hasOwnProperty(\"showInScene\")\r\n && values.hasOwnProperty(\"showInAerial\");\r\n\r\n if (valid) {\r\n dispatch(createCustomLink(values));\r\n return;\r\n }\r\n\r\n throw new Error(\"Invalid definition\");\r\n };\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n customURLDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/* Add new operation */}\r\n \r\n\r\n {/* Import definition file */}\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n {customLinks.map(data =>\r\n \r\n )}\r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n );\r\n};\r\n","import { nanoid } from \"@reduxjs/toolkit\";\r\nimport { AmbientLight, Scene, Vector3 } from \"three\";\r\nimport { t } from \"../../../localization\";\r\nimport { clearViewerTooltip, setViewerTooltip } from \"../../viewer\";\r\nimport { CustomMouseEvent, OrbitPosition, PanoControls } from \"../controls\";\r\nimport { textToColor } from \"../labelling\";\r\nimport { Viewer } from \"../main\";\r\nimport { RayCaster } from \"../ray-caster\";\r\nimport { getPointScale } from \"../utilities\";\r\nimport { ClippingBox, PositionHandle, RotateHandle, ScaleHandle } from \"./clipping-box\";\r\n\r\nexport enum OperationType {\r\n Delete,\r\n Classify,\r\n Split\r\n}\r\n\r\nclass ClippingGroup {\r\n public type;\r\n public name;\r\n public color;\r\n public id = nanoid();\r\n public active = false;\r\n public newClassification = 0;\r\n public ignoredClassification = 0;\r\n\r\n private markupList: PointMarkupList;\r\n public clippingBoxes: ClippingBox[] = [];\r\n\r\n constructor(markupList: PointMarkupList, type, name) {\r\n this.markupList = markupList;\r\n this.type = type;\r\n this.setName(name);\r\n }\r\n\r\n get isDelete() {\r\n return this.type === OperationType.Delete;\r\n }\r\n\r\n get isClassify() {\r\n return this.type === OperationType.Classify;\r\n }\r\n\r\n get isSplit() {\r\n return this.type === OperationType.Split;\r\n }\r\n\r\n get controls() {\r\n return this.markupList.controls;\r\n }\r\n\r\n get scene() {\r\n return this.markupList.scene;\r\n }\r\n\r\n getByID(id) {\r\n return this.clippingBoxes.find(x => x.id === id);\r\n }\r\n\r\n add(clippingBox: ClippingBox) {\r\n clippingBox.setColor(this.color);\r\n clippingBox.hidePoints = this.isDelete;\r\n clippingBox.updateClassification = this.isClassify;\r\n clippingBox.newClassification = this.newClassification;\r\n clippingBox.ignoredClassification = this.ignoredClassification;\r\n\r\n this.clippingBoxes.push(clippingBox);\r\n this.scene.add(clippingBox);\r\n this.setActive(false);\r\n }\r\n\r\n setName(name) {\r\n this.name = name;\r\n this.color = textToColor(name);\r\n\r\n this.clippingBoxes.forEach(clippingBox => {\r\n clippingBox.setColor(this.color);\r\n });\r\n }\r\n\r\n setNewClassification(value) {\r\n this.newClassification = value;\r\n\r\n this.clippingBoxes.forEach(clippingBox => {\r\n clippingBox.newClassification = value;\r\n });\r\n }\r\n\r\n setIgnoredClassification(value) {\r\n this.ignoredClassification = value;\r\n\r\n this.clippingBoxes.forEach(clippingBox => {\r\n clippingBox.ignoredClassification = value;\r\n });\r\n }\r\n\r\n setActive(state) {\r\n this.active = state;\r\n }\r\n\r\n setHover(id, hover) {\r\n const clippingBox = this.getByID(id);\r\n if (!clippingBox) return;\r\n\r\n clippingBox.setHover(hover);\r\n }\r\n\r\n zoom(id) {\r\n const clippingBox = this.getByID(id);\r\n if (!clippingBox) return;\r\n\r\n const pivot = clippingBox.position;\r\n\r\n const axisOffset = new Vector3(2, 0, 0.25)\r\n .applyQuaternion(clippingBox.quaternion)\r\n .multiply(clippingBox.scale)\r\n .multiplyScalar(2.0);\r\n\r\n const orbit = new Vector3()\r\n .copy(clippingBox.position)\r\n .add(axisOffset);\r\n\r\n const position = {orbit, pivot, smooth: true} as OrbitPosition;\r\n this.controls.setOrbitValues(true, position);\r\n }\r\n\r\n resetRotation(id) {\r\n const clippingBox = this.getByID(id);\r\n if (!clippingBox) return;\r\n\r\n let count = 0;\r\n let totalCount = 20;\r\n\r\n let dx = clippingBox.rotation.x / totalCount;\r\n let dy = clippingBox.rotation.y / totalCount;\r\n let dz = clippingBox.rotation.z / totalCount;\r\n\r\n const interval = setInterval(() => {\r\n const index = totalCount - count;\r\n\r\n clippingBox.rotation.set(\r\n dx*index,\r\n dy*index,\r\n dz*index\r\n );\r\n\r\n if (count === totalCount) {\r\n clearInterval(interval);\r\n }\r\n\r\n count = count + 1;\r\n }, 16);\r\n }\r\n\r\n removeByID(id) {\r\n const clippingBox = this.getByID(id);\r\n if (!clippingBox) return;\r\n\r\n this.scene.remove(clippingBox);\r\n this.clippingBoxes = this.clippingBoxes.filter(x => x.id !== id);\r\n }\r\n\r\n clear() {\r\n this.clippingBoxes.forEach(clippingBox => {\r\n this.scene.remove(clippingBox);\r\n });\r\n\r\n this.clippingBoxes = [];\r\n }\r\n\r\n update() {\r\n this.clippingBoxes.forEach(clippingBox => {\r\n clippingBox.update();\r\n });\r\n }\r\n}\r\n\r\nexport class PointMarkupList {\r\n public scene: Scene;\r\n public controls: PanoControls;\r\n private setMarkupGroups;\r\n\r\n public enabled = false;\r\n private mouseEvent = null;\r\n private shiftDown = false;\r\n private dragObject = null;\r\n\r\n public clippingGroups: ClippingGroup[] = [];\r\n\r\n constructor(controls: PanoControls, props) {\r\n const {setMarkupGroups} = props;\r\n\r\n this.controls = controls;\r\n this.setMarkupGroups = setMarkupGroups;\r\n\r\n this.initScene();\r\n }\r\n\r\n get viewer(): Viewer {\r\n return this.controls.viewer;\r\n }\r\n\r\n get scaleTooltip() {\r\n return [\r\n t('point-markup.click_and_hold_to_adjust_bounding_box'),\r\n t('point-markup.hold_shift_to_select_background_planes')\r\n ];\r\n }\r\n\r\n get rotateTooltip() {\r\n return [\r\n t('point-markup.click_and_hold_to_rotate_bounding_box')\r\n ];\r\n }\r\n\r\n get moveTooltip() {\r\n return [\r\n t('point-markup.click_and_hold_to_move_bounding_box')\r\n ];\r\n }\r\n\r\n get standardTooltip() {\r\n return [\r\n t('point-markup.click_to_add_new_bounding_box'),\r\n t('point-markup.right-click_to_cancel')\r\n ];\r\n }\r\n\r\n get active() {\r\n return !!this.activeGroup;\r\n }\r\n\r\n get activeGroup() {\r\n return this.clippingGroups.find(x => x.active);\r\n }\r\n\r\n get clippingBoxes() {\r\n return this.clippingGroups.map(x => x.clippingBoxes).flat();\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n getByID(id) {\r\n return this.clippingGroups.find(x => x.id === id);\r\n }\r\n\r\n setName(id, name) {\r\n const clippingGroup = this.getByID(id);\r\n if (!clippingGroup) return;\r\n\r\n clippingGroup.setName(name);\r\n this.refreshMarkupList();\r\n }\r\n\r\n setActive(id) {\r\n this.clippingGroups.forEach(group => {\r\n group.setActive(group.id === id);\r\n });\r\n this.refreshMarkupList();\r\n }\r\n\r\n addNewGroup(type, name) {\r\n let newGroup = new ClippingGroup(this, type, name);\r\n this.clippingGroups.push(newGroup);\r\n this.refreshMarkupList();\r\n }\r\n\r\n refreshMarkupList() {\r\n this.setMarkupGroups([...this.clippingGroups]);\r\n }\r\n\r\n setState(state) {\r\n if (state) {\r\n this.enable();\r\n } else {\r\n this.disable();\r\n }\r\n }\r\n\r\n zoom(id) {\r\n this.clippingGroups.forEach(group => {\r\n group.zoom(id);\r\n });\r\n }\r\n\r\n resetRotation(id) {\r\n this.clippingGroups.forEach(group => {\r\n group.resetRotation(id);\r\n });\r\n }\r\n\r\n removeClippingGroup(id) {\r\n const clippingGroup = this.getByID(id);\r\n if (!clippingGroup) return;\r\n\r\n clippingGroup.clippingBoxes.forEach(clippingBox => {\r\n this.scene.remove(clippingBox);\r\n });\r\n\r\n this.clippingGroups = this.clippingGroups.filter(x => x.id !== id);\r\n this.refreshMarkupList();\r\n }\r\n\r\n removeClippingBox(id) {\r\n this.clippingGroups.forEach(clippingGroup => {\r\n clippingGroup.removeByID(id);\r\n });\r\n\r\n this.refreshMarkupList();\r\n }\r\n\r\n setHover(id, state) {\r\n this.clippingGroups.forEach(clippingGroup => {\r\n clippingGroup.setHover(id, state);\r\n });\r\n }\r\n\r\n setNewClassification(id, value) {\r\n const clippingGroup = this.getByID(id);\r\n if (!clippingGroup) return;\r\n\r\n clippingGroup.setNewClassification(value);\r\n }\r\n\r\n setIgnoredClassification(id, value) {\r\n const clippingGroup = this.getByID(id);\r\n if (!clippingGroup) return;\r\n\r\n clippingGroup.setIgnoredClassification(value);\r\n }\r\n\r\n enable() {\r\n this.enabled = true;\r\n }\r\n\r\n disable() {\r\n this.enabled = false;\r\n\r\n this.clippingGroups.forEach(clippingGroup => {\r\n clippingGroup.clear();\r\n });\r\n\r\n this.clippingGroups = [];\r\n this.refreshMarkupList();\r\n\r\n clearViewerTooltip();\r\n }\r\n\r\n clear() {\r\n this.disable();\r\n this.enable();\r\n }\r\n\r\n addNewBlock(event) {\r\n if (this.dragObject) return;\r\n\r\n let {coordinate} = this.controls.getPickerResults(event);\r\n if (!coordinate) return;\r\n\r\n const camera = this.viewer.camera;\r\n\r\n const clippingBox = new ClippingBox(this.viewer);\r\n clippingBox.position.copy(coordinate);\r\n\r\n const vector = new Vector3()\r\n .add(coordinate)\r\n .sub(camera.position)\r\n .setLength(1.0);\r\n\r\n const cameraAngle = Math.atan2(vector.y, vector.x) - Math.PI / 2;\r\n const newBoxScale = getPointScale(camera, clippingBox);\r\n clippingBox.rotation.z = cameraAngle;\r\n clippingBox.scale.setScalar(newBoxScale);\r\n\r\n this.activeGroup.add(clippingBox);\r\n\r\n clearViewerTooltip();\r\n this.refreshMarkupList();\r\n }\r\n\r\n clearNewBlock() {\r\n this.clippingGroups.forEach(group => {\r\n group.setActive(false);\r\n });\r\n\r\n clearViewerTooltip();\r\n this.refreshMarkupList();\r\n }\r\n\r\n setDragObject(dragObject) {\r\n this.dragObject = dragObject;\r\n\r\n let draggable = dragObject ? true : false;\r\n let controls = this.viewer.controls;\r\n controls.setMovementState(!draggable);\r\n }\r\n\r\n getDragObject(event, camera) {\r\n const raycaster = new RayCaster(this.viewer, event);\r\n\r\n this.clippingBoxes.forEach(object => {\r\n object.setVisible(false);\r\n });\r\n\r\n // Ignore clipping box if we are inside its bounds\r\n const objects = this.clippingBoxes.filter(clippingBox => {\r\n const bbox = clippingBox.boundingBox;\r\n return !bbox.containsPoint(camera.position);\r\n });\r\n\r\n let intersects = raycaster.intersectObjects(objects, {\r\n recursive: false\r\n });\r\n\r\n if (intersects.length === 0) {\r\n this.setDragObject(null);\r\n return;\r\n }\r\n\r\n // Position and rotation have priority\r\n const handleOverride = intersects\r\n .find(intersect => {\r\n const isPosition = intersect.object instanceof PositionHandle;\r\n const isRotation = intersect.object instanceof RotateHandle;\r\n return isPosition || isRotation;\r\n });\r\n\r\n if (handleOverride) {\r\n this.setDragObject(handleOverride);\r\n } else {\r\n if (this.shiftDown && intersects.length > 1) {\r\n this.setDragObject(intersects[1]);\r\n } else {\r\n this.setDragObject(intersects[0]);\r\n }\r\n }\r\n\r\n const {object} = this.dragObject;\r\n object.highlighted = true;\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent) {\r\n if (!this.enabled || !this.active || event.mouseMoved) {\r\n return false;\r\n }\r\n\r\n if (event.isLeftClick) {\r\n this.addNewBlock(event);\r\n } else if (event.isRightClick) {\r\n this.clearNewBlock();\r\n }\r\n\r\n return true;\r\n }\r\n\r\n onMouseMove(event: CustomMouseEvent) {\r\n if (!this.enabled || !event) return;\r\n\r\n const camera = this.viewer.camera;\r\n this.mouseEvent = event;\r\n\r\n if (this.dragObject) {\r\n const {object} = this.dragObject;\r\n if (object instanceof RotateHandle) {\r\n setViewerTooltip(this.rotateTooltip);\r\n } else if (object instanceof PositionHandle) {\r\n setViewerTooltip(this.moveTooltip);\r\n } else if (object instanceof ScaleHandle) {\r\n setViewerTooltip(this.scaleTooltip);\r\n }\r\n } else {\r\n if (this.active) {\r\n setViewerTooltip(this.standardTooltip);\r\n } else {\r\n clearViewerTooltip();\r\n }\r\n }\r\n\r\n if (event.mouseDown && event.isLeftClick) {\r\n if (this.dragObject) {\r\n const {object, point} = this.dragObject;\r\n object.drag(event, point);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n this.getDragObject(event, camera);\r\n return false;\r\n }\r\n\r\n onKeyDown(event) {\r\n if (!this.enabled || this.shiftDown) return;\r\n if (event.key !== \"Shift\") return;\r\n\r\n this.shiftDown = true;\r\n this.onMouseMove(this.mouseEvent);\r\n }\r\n\r\n onKeyUp() {\r\n if (!this.enabled) return;\r\n\r\n this.shiftDown = false;\r\n this.setDragObject(null);\r\n this.onMouseMove(this.mouseEvent);\r\n }\r\n\r\n update() {\r\n this.clippingGroups.forEach(group => {\r\n group.update();\r\n });\r\n }\r\n}\r\n","import 'ol/ol.css';\r\nimport Map from 'ol/Map';\r\nimport Static from 'ol/source/ImageStatic';\r\nimport ImageLayer from 'ol/layer/Image';\r\nimport LayerGroup from 'ol/layer/Group';\r\nimport {transformExtent, transform} from 'ol/proj';\r\nimport LocalScene, {\r\n LonLatCoordinate,\r\n ProjectedCoordinate\r\n} from '../projections';\r\nimport { AerialMap } from '.';\r\nimport {polygon as turfPolygon} from '@turf/helpers';\r\nimport {default as turfIntersect} from '@turf/intersect';\r\n\r\nclass OrthoImageLayer extends ImageLayer {\r\n constructor(opts) {\r\n super(opts);\r\n }\r\n}\r\n\r\nexport class OrthoMosaic {\r\n public id;\r\n public layer: LayerGroup;\r\n private corners = [];\r\n public aerialBounds = [];\r\n private scaleX: number;\r\n private scaleY: number;\r\n private imageBase64: string;\r\n private name: string;\r\n private splitData;\r\n private cropBase64 = [];\r\n private cropCorners = [];\r\n private imageSize: [Number, Number];\r\n private imageSizeOriginal: [Number, Number];\r\n private imagePath: string;\r\n private saved: boolean;\r\n private extent = [];\r\n private orthosList: OrthoMosaicList;\r\n public loading = false;\r\n public loaded = false;\r\n\r\n constructor(orthosList: OrthoMosaicList, data) {\r\n this.orthosList = orthosList;\r\n this.id = data.id;\r\n this.name = data.name;\r\n this.corners = data.corners;\r\n this.imageBase64 = data.base64;\r\n this.imageSize = data.imageSize;\r\n this.splitData = data.splitData;\r\n this.imageSizeOriginal = data.imageSizeOriginal;\r\n this.saved = data.saved;\r\n this.imagePath = data.imagePath;\r\n this.scaleX = data.scaleX;\r\n this.scaleY = data.scaleY;\r\n\r\n this.calculateCroppedData();\r\n this.calculateExtent();\r\n this.calculateAerialPolygon();\r\n this.addMapLayer();\r\n }\r\n\r\n get opacity() {\r\n return this.orthosList.opacity;\r\n }\r\n\r\n get aerialMap() {\r\n return this.orthosList.aerialMap;\r\n }\r\n\r\n get map() {\r\n return this.orthosList.map;\r\n }\r\n\r\n get projection() {\r\n return LocalScene.dataProjectionName;\r\n }\r\n\r\n get proj4Projection() {\r\n return LocalScene.dataProjection;\r\n }\r\n\r\n get visible() {\r\n return this.layer.getVisible();\r\n }\r\n\r\n get path() {\r\n return this.imagePath;\r\n }\r\n\r\n get cornerCoordinates() {\r\n return this.corners;\r\n }\r\n\r\n get scale() {\r\n return [this.scaleX, this.scaleY];\r\n }\r\n\r\n get originalSize() {\r\n return this.imageSizeOriginal;\r\n }\r\n\r\n get orthoName() {\r\n return this.name;\r\n }\r\n\r\n get metadata() {\r\n return {\r\n x_scale: this.scaleX,\r\n y_scale: this.scaleY,\r\n x_offset: this.corners[0],\r\n y_offset: this.corners[3],\r\n x_skew: 0.0,\r\n y_skew: 0.0\r\n };\r\n }\r\n\r\n get cornerPixels() {\r\n return [\r\n [0, 0],\r\n [this.originalSize[0], 0],\r\n [this.originalSize[0], this.originalSize[1]],\r\n [0, this.originalSize[1]],\r\n ] as Array<[number, number]>;\r\n }\r\n\r\n zoomToExtent() {\r\n this.aerialMap.setMapExtent(this.extent);\r\n }\r\n\r\n calculateExtent() {\r\n const extent = transformExtent(this.corners,\r\n this.projection, 'EPSG:3857');\r\n this.extent = extent;\r\n }\r\n\r\n calculateAerialPolygon() {\r\n this.aerialBounds = imagePixelsToAerial(\r\n this.cornerPixels, this, this.proj4Projection);\r\n }\r\n\r\n calculateCroppedData() {\r\n if (this.splitData) {\r\n this.cropBase64 = [];\r\n this.cropCorners = [];\r\n\r\n this.splitData.forEach(data => {\r\n // Cropped base64 data\r\n let {index_start, index_end} = data;\r\n let base64 = this.imageBase64.slice(index_start, index_end);\r\n this.cropBase64.push(base64);\r\n\r\n // Cropped extent\r\n let {width_start, width_end, height_start, height_end} = data;\r\n let extentWidth = this.corners[2] - this.corners[0];\r\n let extentHeight = this.corners[3] - this.corners[1];\r\n\r\n let subtileCorners = [\r\n this.corners[0] + extentWidth * width_start,\r\n this.corners[3] - (extentHeight * height_end),\r\n this.corners[0] + extentWidth * width_end,\r\n this.corners[3] - (extentHeight * height_start),\r\n ];\r\n\r\n this.cropCorners.push(subtileCorners);\r\n });\r\n } else {\r\n // Single value. Convert to array\r\n this.cropBase64 = [this.imageBase64];\r\n this.cropCorners = [this.corners];\r\n }\r\n }\r\n\r\n intersectAerialPoints(aerialPoints) {\r\n return turfIntersect(\r\n turfPolygon([[...aerialPoints, aerialPoints[0]]]),\r\n turfPolygon([[...this.aerialBounds, this.aerialBounds[0]]])\r\n );\r\n }\r\n\r\n aerialToPixels(aerialPoints) {\r\n return aerialToImagePixels(\r\n aerialPoints, this, this.proj4Projection);\r\n }\r\n\r\n transform(coordinates) {\r\n let coordinatesTransformed = [];\r\n coordinates.forEach(coordinate =>{\r\n let coordTransformed = transform(coordinate, 'EPSG:3857', this.projection);\r\n coordinatesTransformed.push(coordTransformed);\r\n });\r\n return coordinatesTransformed;\r\n }\r\n\r\n reverseTransform(coordinates) {\r\n let coordinatesTransformed = [];\r\n coordinates.forEach(coordinate =>{\r\n let coordTransformed = transform(coordinate, this.projection, 'EPSG:3857');\r\n coordinatesTransformed.push(coordTransformed);\r\n });\r\n return coordinatesTransformed;\r\n }\r\n\r\n addMapLayer() {\r\n let allLayers = [];\r\n let numSubtiles = this.cropBase64.length;\r\n\r\n console.log(`Load ortho layer (${numSubtiles} subtiles)`);\r\n\r\n for (var i =0; i {\r\n let element = image.getImage();\r\n let data = {ortho: this, element, src};\r\n this.orthosList.addImageChunk(data);\r\n }\r\n });\r\n\r\n let layer = new OrthoImageLayer({source});\r\n\r\n // Add layer to group\r\n allLayers.push(layer);\r\n }\r\n\r\n // Craete layer group that contains all subtiles\r\n this.layer = new LayerGroup({layers: allLayers});\r\n this.setOpacity();\r\n\r\n this.map.addLayer(this.layer);\r\n\r\n if (this.saved) return;\r\n this.zoomToExtent();\r\n }\r\n\r\n setOpacity() {\r\n this.layer.setOpacity(this.opacity);\r\n }\r\n\r\n setVisibility(visible) {\r\n this.layer.setVisible(visible);\r\n }\r\n\r\n destroy() {\r\n if (!this.layer) {\r\n return;\r\n }\r\n\r\n this.map.removeLayer(this.layer);\r\n this.imageBase64 = null;\r\n this.layer = null;\r\n }\r\n}\r\n\r\nexport class OrthoMosaicList {\r\n public orthos: OrthoMosaic[] = [];\r\n public opacity = 0.8;\r\n public aerialMap: AerialMap;\r\n public maxAsyncLoad = 2;\r\n public chunksLoading = 0;\r\n public chunksToLoad = [];\r\n private enabled = true;\r\n\r\n constructor(aerialMap: AerialMap) {\r\n this.aerialMap = aerialMap;\r\n this.loadAvailableData();\r\n }\r\n\r\n get map(): Map {\r\n return this.aerialMap.map;\r\n }\r\n\r\n destroy() {\r\n this.enabled = false;\r\n }\r\n\r\n reconcile(orthoFiles) {\r\n const currentOrthos = new Set(this.orthos.map(ortho => ortho.id));\r\n const newOrthos = new Set(orthoFiles.map(ortho => ortho.id));\r\n\r\n const orthosToLoad = orthoFiles.filter(ortho => !currentOrthos.has(ortho.id));\r\n const orthosToDelete = this.orthos.filter(ortho => !newOrthos.has(ortho.id));\r\n\r\n // Delete orthos that need to be removed\r\n orthosToDelete.forEach(ortho => {\r\n this.deleteOrtho(ortho.id);\r\n });\r\n\r\n // Add new orthos\r\n orthosToLoad.forEach(ortho => {\r\n const {\r\n imageBounds, imageData, imageDataSplit, imageSize,\r\n imageSizeOriginal, imagePath, scaleX, scaleY\r\n } = ortho.data;\r\n\r\n const orthoInfo = {\r\n id: ortho.id,\r\n name: ortho.name,\r\n corners: imageBounds,\r\n base64: imageData,\r\n splitData: imageDataSplit,\r\n imageSize,\r\n imageSizeOriginal,\r\n saved: ortho.saved,\r\n imagePath,\r\n scaleX,\r\n scaleY\r\n };\r\n\r\n this.addNewOrtho(orthoInfo);\r\n });\r\n\r\n // Toggle proper visibility for each ortho\r\n orthoFiles.forEach(ortho => {\r\n this.toggleVisibility(ortho.id, ortho.visible);\r\n });\r\n }\r\n\r\n addNewOrtho(data) {\r\n let cameraID = data.id;\r\n if (this.getByID(cameraID)) {\r\n // Ortho already exists\r\n return false;\r\n }\r\n\r\n let ortho = new OrthoMosaic(this, data);\r\n this.orthos.push(ortho);\r\n }\r\n\r\n deleteOrtho(orthoID) {\r\n let ortho = this.getByID(orthoID);\r\n if (!ortho) {\r\n return;\r\n }\r\n\r\n ortho.destroy();\r\n const index = this.orthos.indexOf(ortho);\r\n this.orthos.splice(index, 1);\r\n }\r\n\r\n getByID(orthoID) {\r\n return this.orthos.find(ortho => ortho.id === orthoID);\r\n }\r\n\r\n addImageChunk(loadable) {\r\n this.chunksToLoad.push(loadable);\r\n }\r\n\r\n toggleVisibility = (orthoID, visible) => {\r\n let ortho = this.getByID(orthoID);\r\n if (!ortho) {\r\n return;\r\n }\r\n\r\n ortho.setVisibility(visible);\r\n }\r\n\r\n setOpacity = (value) => {\r\n if ((value < 0.0) || (value > 1.0)) {\r\n return;\r\n }\r\n\r\n this.opacity = value;\r\n this.orthos.forEach(ortho => ortho.setOpacity());\r\n }\r\n\r\n loadAvailableData() {\r\n if (!this.enabled) return false;\r\n\r\n if (this.chunksLoading < this.maxAsyncLoad) {\r\n let toLoad = this.chunksToLoad.pop();\r\n if (toLoad) {\r\n let {ortho, element, src} = toLoad;\r\n\r\n if (ortho.layer) {\r\n if (ortho.visible) {\r\n this.chunksLoading += 1;\r\n element.onload = () => {\r\n this.chunksLoading -= 1;\r\n };\r\n element.src = src;\r\n } else {\r\n this.chunksToLoad.push(toLoad);\r\n }\r\n }\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n this.loadAvailableData();\r\n }, 50);\r\n }\r\n}\r\n\r\nexport const imagePixelsToAerial = (points, image: OrthoMosaic, projection): Array<[number, number]> => {\r\n let newPoints = [];\r\n\r\n try {\r\n let metadata = image.metadata;\r\n newPoints = points.map(point => {\r\n let x = point[0]*metadata.x_scale + metadata.x_offset;\r\n let y = point[1]*metadata.y_scale + metadata.y_offset;\r\n let lonlat = new ProjectedCoordinate([x,y,0], projection).toLonLat();\r\n return transform([lonlat.x, lonlat.y], 'EPSG:4326', 'EPSG:3857');\r\n });\r\n } catch {\r\n // Do Nothing\r\n }\r\n\r\n return newPoints;\r\n};\r\n\r\nexport const aerialToImagePixels = (points, image: OrthoMosaic, projection): Array<[number, number]> => {\r\n let newPoints = [];\r\n\r\n\r\n let metadata = image.metadata;\r\n newPoints = points.map(point => {\r\n let lonlat = transform([point[0], point[1], 0], 'EPSG:3857', 'EPSG:4326');\r\n let projected = new LonLatCoordinate(lonlat)\r\n .toProjection(projection);\r\n\r\n let x = (projected.x - metadata.x_offset) / metadata.x_scale;\r\n let y = (projected.y - metadata.y_offset) / metadata.y_scale;\r\n return [x, y];\r\n });\r\n\r\n\r\n return newPoints;\r\n};\r\n\r\n","import { Viewer } from \"../main\";\r\nimport {\r\n SceneLabelTools,\r\n AerialLabelTools,\r\n textToColorArray\r\n} from \".\";\r\nimport { nanoid } from \"@reduxjs/toolkit\";\r\nimport LocalScene, { isValidProjection } from \"../projections\";\r\nimport {Line3, ShapeUtils, Vector2, Vector3} from \"three\";\r\nimport {\r\n polygon as turfPolygon,\r\n lineString as turfLineString,\r\n point as turfPoint\r\n} from '@turf/helpers';\r\nimport {default as turfSimplify} from '@turf/simplify';\r\nimport {default as turfUnion} from '@turf/union';\r\nimport { PanoramicImage, PlanarImage } from \"../cameras\";\r\nimport GeoJSONReader from 'jsts/org/locationtech/jts/io/GeoJSONReader';\r\nimport {BufferOp} from 'jsts/org/locationtech/jts/operation/buffer';\r\nimport { toast } from \"../../../app\";\r\nimport { imagePixelsToAerial } from \"../aerial\";\r\nimport { ChangeDetector, coordinatesToArray } from \"../utilities\";\r\nimport { clearAerialTooltip, clearViewerTooltip } from \"../../viewer\";\r\nimport { t } from \"../../../localization\";\r\nimport { asyncTimeout } from \"../../../utilities\";\r\n\r\nexport interface CocoCategory {\r\n supercategory: string,\r\n id: number,\r\n name: string,\r\n color: [number, number, number]\r\n}\r\n\r\nexport interface CocoImage {\r\n height: number,\r\n width: number,\r\n id: number,\r\n file_name: string,\r\n metadata?: {\r\n x_skew: number,\r\n y_skew: number,\r\n x_scale: number,\r\n y_scale: number,\r\n x_offset: number,\r\n y_offset: number\r\n }\r\n}\r\n\r\nexport interface CocoAnnotation {\r\n segmentation: Array<[]>,\r\n iscrowd: number,\r\n image_id: number,\r\n merge_id?: number\r\n bbox: [number, number, number, number],\r\n category_id: number,\r\n id: number,\r\n area: number,\r\n score: number,\r\n text: string,\r\n textScore: number,\r\n findText: number\r\n}\r\n\r\nexport class ImageLabel {\r\n public id;\r\n public category;\r\n public selected = false;\r\n public completed = false;\r\n public editing = false;\r\n public valid = true;\r\n public drawable = true;\r\n public highlighted = false;\r\n public score = 1.0;\r\n public text = '';\r\n public textScore = 1.0;\r\n public findText = false;\r\n private duplicatePixelDistance = 5;\r\n public coordinates = [];\r\n\r\n constructor() {\r\n this.id = nanoid();\r\n }\r\n\r\n get hasEnoughPoints() {\r\n console.warn(\"Not Implemented\");\r\n return false;\r\n }\r\n\r\n get numPoints() {\r\n console.warn(\"Not Implemented\");\r\n return 0;\r\n }\r\n\r\n select() {\r\n const stateChanged = !this.selected;\r\n this.selected = true;\r\n this.highlighted = false;\r\n this.completed = false;\r\n\r\n if (stateChanged) {\r\n this.draw();\r\n }\r\n }\r\n\r\n unSelect() {\r\n this.selected = false;\r\n this.complete();\r\n }\r\n\r\n complete() {\r\n const stateChanged = !this.completed;\r\n this.completed = true;\r\n\r\n if (stateChanged) {\r\n this.draw();\r\n }\r\n }\r\n\r\n setDrawable(state) {\r\n this.drawable = state;\r\n }\r\n\r\n setEditing(state) {\r\n this.editing = state;\r\n }\r\n\r\n setScore(score) {\r\n if (score){\r\n this.score = score;\r\n } else {\r\n this.score = 1.0;\r\n }\r\n }\r\n\r\n setText(text, score=1.0) {\r\n if (typeof text === 'string') {\r\n this.text = text;\r\n } else {\r\n this.text = '';\r\n }\r\n this.textScore = score;\r\n }\r\n\r\n setFindText(num) {\r\n this.findText = num;\r\n }\r\n\r\n zoom(): Promise {\r\n console.warn(\"Not Implemented\");\r\n return Promise.resolve(false);\r\n }\r\n\r\n setHighlighted(highlight) {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n destroy() {\r\n this.clear();\r\n }\r\n\r\n clear() {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n draw() {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n insertPoint(point, index) {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n createCoordData(coordinate) {\r\n console.warn(\"Not Implemented\");\r\n\r\n let coordArray = [];\r\n let point = new Vector3();\r\n\r\n return {coordArray, point};\r\n }\r\n\r\n pointToScreen(point) {\r\n console.warn(\"Not Implemented\");\r\n return [0, 0];\r\n }\r\n\r\n duplicatePoint(oldPoint, newPoint) {\r\n if (!oldPoint) {\r\n return false;\r\n }\r\n\r\n // Check screen distance from previous point\r\n let screenPosNew = this.pointToScreen(oldPoint);\r\n let screenPosOld = this.pointToScreen(newPoint);\r\n let dU = screenPosNew[0] - screenPosOld[0];\r\n let dV = screenPosNew[1] - screenPosOld[1];\r\n let distance = Math.sqrt(dU**2 + dV**2);\r\n\r\n return distance < this.duplicatePixelDistance;\r\n }\r\n}\r\n\r\nexport class LabelCategory {\r\n public id;\r\n public name;\r\n public listIdx = -1;\r\n public labels: ImageLabel[] = [];\r\n private invalidLabels: ImageLabel[] = [];\r\n private sorted = false;\r\n private originalOrder = [];\r\n\r\n constructor(name) {\r\n this.id = nanoid();\r\n this.name = name;\r\n }\r\n\r\n get numLabelsAll() {\r\n return this.labels.length + this.invalidLabels.length;\r\n }\r\n\r\n getLabelByID(labelID) {\r\n return this.labels.find(label => label.id === labelID);\r\n }\r\n\r\n setText(labelID, text, score=1.0) {\r\n let label = this.getLabelByID(labelID);\r\n if (label) {\r\n label.setText(text, score);\r\n }\r\n return;\r\n }\r\n\r\n setFindText(state) {\r\n this.labels.forEach(label => label.findText = state);\r\n }\r\n\r\n addNewLabel(drawLabel) {\r\n console.warn(\"Not implemented\");\r\n return null;\r\n }\r\n\r\n updateColor() {\r\n console.warn(\"Not implemented\");\r\n }\r\n\r\n insertPoint(labelID, coordinate) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return;\r\n }\r\n\r\n let {coordArray, point} = label.createCoordData(coordinate);\r\n let idxCoord = minDistanceIdx(coordArray, point);\r\n label.insertPoint(point, idxCoord);\r\n\r\n toast.success(t(\"toast.labels-add-point\"));\r\n }\r\n\r\n editLabel(labelID, coordinate) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return;\r\n }\r\n\r\n label.setEditing(true);\r\n\r\n let {coordArray, point} = label.createCoordData(coordinate);\r\n let idxCoord = minDistanceIdx(coordArray, point);\r\n let endIdx = (idxCoord === coordArray.length - 1) ? 0 : idxCoord + 1;\r\n let line = createSegment(coordArray[idxCoord], coordArray[endIdx]);\r\n\r\n let reverse = line.closestPointToPointParameter(point, true) > 0.5;\r\n label.coordinates = [\r\n ...label.coordinates.slice(idxCoord+1, label.coordinates.length),\r\n ...label.coordinates.slice(0, idxCoord+1)\r\n ];\r\n\r\n if (reverse) {\r\n label.coordinates.reverse();\r\n }\r\n }\r\n\r\n deleteLabel(labelID) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return;\r\n }\r\n\r\n label.destroy();\r\n const index = this.labels.indexOf(label);\r\n this.labels.splice(index, 1);\r\n }\r\n\r\n deleteLabels(labelIDs) {\r\n labelIDs.forEach(labelID => {\r\n this.deleteLabel(labelID);\r\n });\r\n }\r\n\r\n async zoomToLabel(labelID) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return;\r\n }\r\n\r\n let validLabel = await label.zoom();\r\n if (validLabel) {\r\n label.setHighlighted(true);\r\n }\r\n }\r\n\r\n unHighlight(labelID) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return;\r\n }\r\n\r\n label.setHighlighted(false);\r\n }\r\n\r\n updateName(name) {\r\n this.name = name;\r\n this.updateColor();\r\n }\r\n\r\n completeLabel(labelID) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return false;\r\n }\r\n\r\n if (!label.hasEnoughPoints) {\r\n return false;\r\n }\r\n\r\n label.setHighlighted(false);\r\n label.unSelect();\r\n label.complete();\r\n\r\n return true;\r\n }\r\n\r\n unSelectAll() {\r\n this.labels.forEach(label =>\r\n label.unSelect()\r\n );\r\n }\r\n\r\n selectLabel(labelID) {\r\n const label = this.getLabelByID(labelID);\r\n if (!label) {\r\n return;\r\n }\r\n\r\n label.select();\r\n label.score = 1.0;\r\n }\r\n\r\n sortLabels(scoreThreshold, type) {\r\n let allLabels = [...this.labels, ...this.invalidLabels];\r\n\r\n if (!this.sorted) {\r\n let order = [];\r\n this.labels.forEach(label => order.push(label.id));\r\n this.originalOrder = order;\r\n this.sorted = true;\r\n }\r\n\r\n if (type === \"ascending\"){\r\n allLabels.sort((a,b) => a.score - b.score);\r\n }\r\n else if (type === \"descending\") {\r\n allLabels.sort((a,b) => b.score - a.score);\r\n }\r\n\r\n this.labels = allLabels.filter(label => label.score > scoreThreshold);\r\n this.invalidLabels = allLabels.filter(label => label.score <= scoreThreshold);\r\n\r\n this.invalidLabels.forEach(label => label.clear());\r\n }\r\n\r\n undoSort() {\r\n let allLabels = [...this.labels, ...this.invalidLabels];\r\n\r\n let unsortedLabels = [];\r\n this.originalOrder.forEach(labelID => {\r\n let match = allLabels.find(label => label.id === labelID);\r\n unsortedLabels.push(match);\r\n });\r\n\r\n this.labels = unsortedLabels;\r\n this.invalidLabels = [];\r\n this.sorted = false;\r\n }\r\n\r\n moveToLabelInList(labelID) {\r\n this.labels.forEach((label, index) => {\r\n if (label.id === labelID) {\r\n this.listIdx = index;\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport class ImageLabelTools {\r\n viewer: Viewer;\r\n public orthoLabels: AerialLabelTools;\r\n public sceneLabels: SceneLabelTools;\r\n private activeLabeler: AerialLabelTools | SceneLabelTools;\r\n public categories: LabelCategory[] = [];\r\n private setCategoryList: Function;\r\n private setTrainingArea: Function;\r\n private currentCategory;\r\n private allowUpdate = true;\r\n\r\n constructor(viewer: Viewer, props) {\r\n const {setCategoryList, setTrainingArea} = props;\r\n\r\n this.viewer = viewer;\r\n this.orthoLabels = new AerialLabelTools(this, props);\r\n this.sceneLabels = new SceneLabelTools(this);\r\n this.setCategoryList = setCategoryList;\r\n this.setTrainingArea = setTrainingArea;\r\n\r\n this.setCategories();\r\n }\r\n\r\n get currentCategoryName() {\r\n return this.currentCategory.name;\r\n }\r\n\r\n get trainingArea() {\r\n if (this.activeLabeler instanceof AerialLabelTools) {\r\n return this.activeLabeler.trainingArea;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n get isAerialLabels() {\r\n return this.activeLabeler instanceof AerialLabelTools;\r\n }\r\n\r\n get isSceneLabels() {\r\n return this.activeLabeler instanceof SceneLabelTools;\r\n }\r\n\r\n get numHighlighted() {\r\n let count = 0;\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n if (label.highlighted) {\r\n count++;\r\n }\r\n });\r\n });\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n if (label.highlighted) {\r\n count++;\r\n }\r\n });\r\n\r\n return count;\r\n }\r\n\r\n get noneHighlighted() {\r\n return this.numHighlighted === 0;\r\n }\r\n\r\n get oneHighlighted() {\r\n return this.numHighlighted === 1;\r\n }\r\n\r\n getIdxInList(category) {\r\n let validCategory = this.categories.find(x => x.name === category.name);\r\n if (!validCategory) {\r\n return;\r\n }\r\n\r\n return validCategory.listIdx;\r\n }\r\n\r\n setUpdateState(state) {\r\n this.allowUpdate = state;\r\n }\r\n\r\n setFindText(categoryID) {\r\n this.categories.forEach(category => category.setFindText(false));\r\n\r\n const category = this.getCategoryByID(categoryID);\r\n if (!category) {\r\n return;\r\n }\r\n\r\n category.setFindText(true);\r\n }\r\n\r\n onKeyDown(event) {\r\n let label = this.activeLabeler.activeLabel;\r\n\r\n if (label) {\r\n // Check for completion hotkey -> Enter\r\n if (event.which === 13) {\r\n if (label.selected){\r\n this.completeLabel(label.id);\r\n }\r\n }\r\n\r\n // Check for deletion hotkey -> Delete\r\n if (event.which === 46) {\r\n this.activeLabeler.deletePoint();\r\n }\r\n\r\n }\r\n else {\r\n // Check add new label in current category hotkey -> space\r\n if (event.which === 32 && (this.currentCategory)) {\r\n this.addLabel(this.currentCategory.id);\r\n return;\r\n }\r\n }\r\n\r\n }\r\n\r\n setActiveLabelType(type) {\r\n this.deleteAllCategories();\r\n this.orthoLabels.setState(false);\r\n this.sceneLabels.setState(false);\r\n this.viewer.minimap.setDragState(true);\r\n\r\n if (type === \"ortho\") {\r\n this.activeLabeler = this.orthoLabels;\r\n } else if (type === \"scene\") {\r\n this.activeLabeler = this.sceneLabels;\r\n } else {\r\n this.activeLabeler = null;\r\n return;\r\n }\r\n\r\n this.activeLabeler.setState(true);\r\n }\r\n\r\n activeImagePaths() {\r\n if (!this.activeLabeler) {\r\n return [];\r\n }\r\n\r\n return this.activeLabeler.activeImagePaths;\r\n }\r\n\r\n activeImages() {\r\n if (!this.activeLabeler) {\r\n return [];\r\n }\r\n\r\n return this.activeLabeler.activeImages;\r\n }\r\n\r\n loadedImagePaths() {\r\n if (!this.activeLabeler) {\r\n return [];\r\n }\r\n\r\n return this.activeLabeler.loadedImagePaths;\r\n }\r\n\r\n checkIfSelected() {\r\n if (!this.activeLabeler) {\r\n return false;\r\n }\r\n\r\n return this.activeLabeler.activeLabel\r\n ? true\r\n : false;\r\n }\r\n\r\n checkUniqueName(name) {\r\n const categoriesWithName = this.categories.filter(category => {\r\n return category.name.toUpperCase() === name.toUpperCase();\r\n });\r\n\r\n return (categoriesWithName.length === 0);\r\n }\r\n\r\n getCategoryByID(id) {\r\n if (this.trainingArea?.id === id) {\r\n return this.trainingArea;\r\n }\r\n\r\n return this.categories.find(x => x.id === id);\r\n }\r\n\r\n getCategoryByName(name) {\r\n return this.categories.find(x => x.name === name);\r\n }\r\n\r\n setCategories() {\r\n if (!this.allowUpdate) {\r\n return;\r\n }\r\n\r\n // Sort categories based on name\r\n //this.categories.sort((a, b) => a.name.localeCompare(b.name));\r\n\r\n this.setCategoryList([...this.categories]);\r\n\r\n if (this.trainingArea) {\r\n this.setTrainingArea([this.trainingArea]);\r\n } else {\r\n this.setTrainingArea([]);\r\n }\r\n }\r\n\r\n sortCategory(category, score, sortType) {\r\n if (!this.activeLabeler) {\r\n return;\r\n }\r\n\r\n let categoryToSort = this.getCategoryByName(category.name);\r\n if (!categoryToSort) {\r\n return;\r\n }\r\n\r\n this.unHighlightAll();\r\n categoryToSort.unSelectAll();\r\n\r\n categoryToSort.sortLabels(score, sortType);\r\n this.setCategories();\r\n this.activeLabeler.drawAll();\r\n }\r\n\r\n undoSort(category) {\r\n if (!this.activeLabeler) {\r\n return;\r\n }\r\n\r\n let categoryToSort = this.getCategoryByName(category.name);\r\n if (!categoryToSort) {\r\n return;\r\n }\r\n\r\n this.unHighlightAll();\r\n categoryToSort.unSelectAll();\r\n\r\n categoryToSort.undoSort();\r\n this.setCategories();\r\n this.activeLabeler.drawAll();\r\n }\r\n\r\n addCategory(name) {\r\n if (!this.activeLabeler) {\r\n return;\r\n }\r\n\r\n let category = this.activeLabeler.getNewCategory(name);\r\n this.categories.push(category);\r\n\r\n if (this.categories.length === 1) {\r\n this.currentCategory = category;\r\n }\r\n\r\n this.setCategories();\r\n\r\n return category;\r\n }\r\n\r\n addTrainingArea() {\r\n if (this.activeLabeler instanceof SceneLabelTools) {\r\n return;\r\n }\r\n\r\n if (this.trainingArea) {\r\n return;\r\n }\r\n\r\n let trainingArea = this.activeLabeler.getNewTrainingArea();\r\n this.activeLabeler.setTrainingArea(trainingArea);\r\n this.setCategories();\r\n\r\n return trainingArea;\r\n }\r\n\r\n deleteCategory(categoryID) {\r\n const category = this.getCategoryByID(categoryID);\r\n if (!category) {\r\n return;\r\n }\r\n\r\n category.labels.forEach(label => {\r\n label.destroy();\r\n });\r\n\r\n const index = this.categories.indexOf(category);\r\n this.categories.splice(index, 1);\r\n\r\n if (this.currentCategory === category) {\r\n this.currentCategory = this.categories[0];\r\n } else if (this.categories.length === 0) {\r\n this.currentCategory = null;\r\n }\r\n\r\n this.setCategories();\r\n }\r\n\r\n editCategoryName(categoryID, name) {\r\n const category = this.getCategoryByID(categoryID);\r\n if (!category) {\r\n return;\r\n }\r\n\r\n category.updateName(name);\r\n this.setCategories();\r\n }\r\n\r\n deleteAllCategories() {\r\n let categories = [...this.categories];\r\n categories.forEach(category => {\r\n this.deleteCategory(category.id);\r\n });\r\n\r\n if (this.trainingArea) {\r\n this.deleteTrainingArea();\r\n }\r\n }\r\n\r\n deleteTrainingArea() {\r\n if (this.activeLabeler instanceof SceneLabelTools) {\r\n return;\r\n }\r\n\r\n this.activeLabeler.deleteTrainingArea();\r\n this.setCategories();\r\n }\r\n\r\n addTrainingAreaLabel(drawLabel=true) {\r\n if (this.activeLabeler instanceof SceneLabelTools) {\r\n return;\r\n }\r\n\r\n if (!this.trainingArea) {\r\n return;\r\n }\r\n\r\n const trainingArea = this.trainingArea;\r\n this.currentCategory = trainingArea;\r\n\r\n let label = trainingArea.addNewLabel(drawLabel);\r\n this.unSelectLabels();\r\n trainingArea.selectLabel(label.id);\r\n\r\n this.setCategories();\r\n\r\n return label;\r\n }\r\n\r\n addLabel(categoryID, drawLabel=true) {\r\n const category = this.getCategoryByID(categoryID);\r\n if (!category) {\r\n return;\r\n }\r\n this.currentCategory = category;\r\n\r\n let label = category.addNewLabel(drawLabel);\r\n this.unSelectLabels();\r\n category.selectLabel(label.id);\r\n\r\n this.setCategories();\r\n\r\n return label;\r\n }\r\n\r\n editLabel(labelID, coord) {\r\n this.unHighlight(labelID);\r\n this.selectLabel(labelID);\r\n this.categories.forEach(category => {\r\n category.editLabel(labelID, coord);\r\n });\r\n }\r\n\r\n deleteLabel(labelID) {\r\n this.categories.forEach(category => {\r\n category.deleteLabel(labelID);\r\n });\r\n\r\n this.trainingArea?.deleteLabel(labelID);\r\n\r\n this.setCategories();\r\n this.clearTooltips();\r\n }\r\n\r\n deletePoint(pointID) {\r\n this.activeLabeler.deleteSpecificPoint(pointID);\r\n }\r\n\r\n insertPoint(labelID, coord) {\r\n this.unHighlight(labelID);\r\n this.categories.forEach(category => {\r\n category.insertPoint(labelID, coord);\r\n });\r\n }\r\n\r\n setText(labelID, text, score=1.0) {\r\n this.categories.forEach(category => {\r\n category.setText(labelID, text, score);\r\n });\r\n }\r\n\r\n async zoomToLabel(labelID) {\r\n this.unHighlightAll();\r\n\r\n for (const category of this.categories) {\r\n await category.zoomToLabel(labelID);\r\n };\r\n\r\n await this.trainingArea?.zoomToLabel(labelID);\r\n this.setCategories();\r\n }\r\n\r\n unHighlight(labelID) {\r\n this.categories.forEach(category => {\r\n category.unHighlight(labelID);\r\n });\r\n\r\n this.trainingArea?.unHighlight(labelID);\r\n this.setCategories();\r\n }\r\n\r\n unHighlightAll() {\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n if (label.highlighted) {\r\n category.unHighlight(label.id);\r\n }\r\n });\r\n });\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n if (label.highlighted) {\r\n this.trainingArea.unHighlight(label.id);\r\n }\r\n });\r\n\r\n this.setCategories();\r\n }\r\n\r\n deleteHighlighted() {\r\n this.categories.forEach(category => {\r\n let labelIDs = [];\r\n category.labels.forEach(label => {\r\n if (label.highlighted) {\r\n labelIDs.push(label.id);\r\n }\r\n });\r\n category.deleteLabels(labelIDs);\r\n });\r\n\r\n let labelIDs = [];\r\n this.trainingArea?.labels.forEach(label => {\r\n if (label.highlighted) {\r\n labelIDs.push(label.id);\r\n }\r\n });\r\n this.trainingArea?.deleteLabels(labelIDs);\r\n\r\n this.setCategories();\r\n }\r\n\r\n completeLabel(labelID) {\r\n let success = false;\r\n let label = this.activeLabeler.activeLabel;\r\n\r\n this.categories.forEach(category => {\r\n success = success || category.completeLabel(labelID);\r\n });\r\n\r\n const isTrainingArea = this.trainingArea\r\n ? this.trainingArea.completeLabel(labelID)\r\n : false;\r\n\r\n success = success || isTrainingArea;\r\n\r\n this.setCategories();\r\n this.clearTooltips();\r\n\r\n if (!success || !label) {\r\n return;\r\n }\r\n\r\n if (isTrainingArea) {\r\n toast.success(t(\"toast.labels-add-training\"));\r\n } else {\r\n if (label.editing) {\r\n toast.success(t(\"toast.labels-update\"));\r\n } else {\r\n toast.success(t(\"toast.labels-add-standard\"));\r\n }\r\n }\r\n\r\n label.setEditing(false);\r\n }\r\n\r\n selectLabel(labelID) {\r\n this.unSelectLabels();\r\n this.categories.forEach(category => {\r\n category.unHighlight(labelID);\r\n category.selectLabel(labelID);\r\n });\r\n\r\n this.trainingArea?.unHighlight(labelID);\r\n this.trainingArea?.selectLabel(labelID);\r\n\r\n this.activeLabeler.resetTemporaryPoint();\r\n this.setCategories();\r\n }\r\n\r\n unSelectLabels() {\r\n this.categories.forEach(category => {\r\n category.unSelectAll();\r\n });\r\n\r\n this.trainingArea?.unSelectAll();\r\n }\r\n\r\n moveToLabelInList(labelID) {\r\n this.categories.forEach(category => {\r\n category.moveToLabelInList(labelID);\r\n });\r\n\r\n this.setCategories();\r\n }\r\n\r\n simplifyPolygon(points, tolerance=2, highQuality=false) {\r\n let simplePolygon;\r\n let newPoints = [...points, points[0]];\r\n let polygon = turfPolygon([newPoints]);\r\n let options = {tolerance, highQuality};\r\n\r\n try {\r\n let simplified = turfSimplify(polygon, options);\r\n simplePolygon = simplified.geometry.coordinates[0];\r\n simplePolygon.pop();\r\n } catch {\r\n simplePolygon = [];\r\n }\r\n\r\n // console.log(`Simplify geometry: ${newPoints.length} => ${simplePolygon.length}`);\r\n\r\n return simplePolygon;\r\n }\r\n\r\n mergeTrainingLabels(category, labelsToMerge) {\r\n let maxPointDistance = 0.5;\r\n let mergedLabels = new Set();\r\n\r\n labelsToMerge.forEach((firstLabel, index) => {\r\n if (mergedLabels.has(firstLabel.id)) {\r\n return;\r\n }\r\n\r\n const isPlanarImage = firstLabel.camera instanceof PlanarImage;\r\n const isPanoramicImage = firstLabel.camera instanceof PanoramicImage;\r\n\r\n // Not required for planar images\r\n if (isPlanarImage) {\r\n return;\r\n }\r\n\r\n let mergeableArray = labelsToMerge.slice(index + 1);\r\n mergeableArray.forEach(mergeLabel => {\r\n if (mergedLabels.has(mergeLabel.id)) {\r\n return;\r\n }\r\n\r\n if (firstLabel.camera !== mergeLabel.camera) {\r\n return;\r\n }\r\n\r\n let points1 = [...firstLabel.coords];\r\n let points2 = [...mergeLabel.coords];\r\n\r\n if (isPanoramicImage) {\r\n // Add image offset\r\n let width = firstLabel.imageWidth;\r\n points1 = points1.map(x => [(x[0]+(width/2)) % width, x[1]]);\r\n points2 = points2.map(x => [(x[0]+(width/2)) % width, x[1]]);\r\n }\r\n\r\n let matches = [];\r\n points1.forEach((point1, index1) => {\r\n let matchFound = false;\r\n points2.forEach((point2, index2) => {\r\n if (matchFound) {\r\n return;\r\n }\r\n\r\n let dist = new Vector2(...point1)\r\n .distanceTo(new Vector2(...point2));\r\n\r\n if (dist < maxPointDistance) {\r\n matchFound = true;\r\n matches.push({point1, point2, dist, index1, index2});\r\n }\r\n });\r\n });\r\n\r\n if (matches.length === 0) {\r\n return;\r\n }\r\n\r\n // Take the two best matches and update\r\n // the original point to match the second\r\n matches.sort((a,b) => a.dist - b.dist);\r\n matches = matches.slice(0,2);\r\n matches.forEach(data => {\r\n points1[data.index1] = data.point2;\r\n });\r\n\r\n let polygonPoints1 = [...points1, points1[0]];\r\n let polygonPoints2 = [...points2, points2[0]];\r\n\r\n let union = turfUnion(\r\n turfPolygon([polygonPoints1]),\r\n turfPolygon([polygonPoints2])\r\n );\r\n\r\n if (!union) {\r\n return;\r\n }\r\n\r\n // Union must have a single geometry\r\n if (union.geometry.type !== \"Polygon\") {\r\n return;\r\n }\r\n\r\n let coordinates = union.geometry.coordinates[0] as any;\r\n coordinates.pop(0);\r\n\r\n // Remove any duplicates from merged result\r\n coordinates = coordinates.filter(point1 => {\r\n let duplicate = false;\r\n matches.forEach(data => {\r\n let point2 = data.point2;\r\n let d = new Vector2(...point1)\r\n .distanceTo(new Vector2(...point2));\r\n\r\n if (d < maxPointDistance) {\r\n duplicate = true;\r\n }\r\n });\r\n\r\n return !duplicate;\r\n });\r\n\r\n if (isPanoramicImage) {\r\n // Subtract image offset and convert to pixel\r\n let width = firstLabel.imageWidth;\r\n coordinates = coordinates.map(coord => {\r\n return {\r\n u: (coord[0] - (width/2)) % width,\r\n v: coord[1]\r\n };\r\n });\r\n }\r\n\r\n // Delete second label\r\n category.deleteLabel(mergeLabel.id);\r\n\r\n // Add points to first label\r\n firstLabel.coordinates = [];\r\n coordinates.forEach(coord => {\r\n firstLabel.addPoint(coord, false);\r\n });\r\n category.completeLabel(firstLabel.id);\r\n mergedLabels.add(mergeLabel.id);\r\n });\r\n });\r\n\r\n const remainingLabels = labelsToMerge.filter(label => {\r\n return mergedLabels.has(label.id) === false;\r\n });\r\n\r\n const numLabelMerged = mergedLabels.size;\r\n\r\n if (numLabelMerged > 0) {\r\n this.mergeTrainingLabels(category, remainingLabels);\r\n }\r\n }\r\n\r\n simplifyPanoramicLabels(category) {\r\n // Simplify new labels (panoramic)\r\n category.labels.forEach(label => {\r\n const isPanoramicImage = label.camera instanceof PanoramicImage;\r\n if (!isPanoramicImage) {\r\n return;\r\n }\r\n\r\n let coordinates = [...label.coords];\r\n coordinates = this.simplifyPolygon(coordinates);\r\n\r\n // Subtract image offset and convert to pixel\r\n let width = label.imageWidth;\r\n coordinates = coordinates.map(coord => {\r\n return {\r\n u: (coord[0] + width) % width,\r\n v: coord[1]\r\n };\r\n });\r\n\r\n label.coordinates = [];\r\n coordinates.forEach(coord => {\r\n label.addPoint(coord, false);\r\n });\r\n label.complete();\r\n });\r\n }\r\n\r\n /** @private */\r\n geometryWithBuffer(geom, bufferSize: number, divisor: number) {\r\n const JSTSReader = new GeoJSONReader();\r\n const geomJSTS = JSTSReader.read(geom);\r\n const buffer = BufferOp.bufferOp(geomJSTS.geometry, bufferSize);\r\n const points = buffer.getCoordinates().map(coord => [coord.x, coord.y]);\r\n const simplified = this.simplifyPolygon(points, bufferSize/divisor);\r\n\r\n return simplified;\r\n }\r\n\r\n /** @private */\r\n checkForImageOverlap(label) {\r\n let hasOverlap = false;\r\n this.orthoLabels.visibleOrthos.forEach(ortho => {\r\n if (hasOverlap) {\r\n return;\r\n }\r\n\r\n let intersects = ortho.intersectAerialPoints(label.polygonPointsOnly);\r\n if (intersects) {\r\n hasOverlap = true;\r\n }\r\n });\r\n\r\n return hasOverlap;\r\n }\r\n\r\n /** @private */\r\n importLabel(label, category, images, projection, progressData, isTrainingArea) {\r\n let addedLabel;\r\n let cameras = this.viewer.cameraList;\r\n\r\n // Add new label\r\n let imageData = images[label.image_id];\r\n label.segmentation.forEach(points => {\r\n // Convert points to 2d array and simplify geometry\r\n points = coordinatesToArray(points);\r\n\r\n // Make sure enough points exist\r\n let minPoints = 3;\r\n if (label.is_linestring) {\r\n minPoints = 2;\r\n } else if (label.is_point) {\r\n minPoints = 1;\r\n }\r\n\r\n if (points.length < minPoints) {\r\n progressData.skippedLabels += 1;\r\n return;\r\n }\r\n\r\n if (this.activeLabeler instanceof AerialLabelTools) {\r\n\r\n if (label.is_linestring) {\r\n // Convert linestring to buffered polygon\r\n let lineGeom = turfLineString(points);\r\n points = this.geometryWithBuffer(lineGeom, label.buffer_size, 4);\r\n } else if (label.is_point) {\r\n let pointGeom = turfPoint(points[0]);\r\n points = this.geometryWithBuffer(pointGeom, label.buffer_size, 8);\r\n }\r\n\r\n // Create simplified version of polygon.\r\n if (!label.linework_data) {\r\n points = this.simplifyPolygon(points);\r\n }\r\n\r\n // Convert from image space to map coordinates\r\n points = imagePixelsToAerial(points, imageData, projection);\r\n } else if (this.activeLabeler instanceof SceneLabelTools) {\r\n // Planar images cant be immediately simplified\r\n let camera = cameras.getByName(imageData.file_name);\r\n if (camera && (camera instanceof PlanarImage)) {\r\n points = this.simplifyPolygon(points);\r\n }\r\n\r\n points = this.activeLabeler.pointsToPixels(points);\r\n }\r\n\r\n // Make sure enough points exist after simplification / pixel function\r\n if (points.length < 3) {\r\n progressData.skippedLabels += 1;\r\n return;\r\n }\r\n\r\n // Create label\r\n let newLabel = isTrainingArea\r\n ? this.addTrainingAreaLabel(false)\r\n : this.addLabel(category.id, false);\r\n\r\n newLabel.setScore(label.score);\r\n newLabel.setText(label.text, label.textScore);\r\n newLabel.setFindText(label.findText);\r\n\r\n if (this.activeLabeler instanceof SceneLabelTools) {\r\n // Camera is required for scene tools\r\n\r\n let camera = cameras.getByName(imageData.file_name);\r\n\r\n if (camera) {\r\n // Set camera label\r\n newLabel.setCamera(camera);\r\n newLabel.setKnownImageSize(\r\n imageData.width,\r\n imageData.height\r\n );\r\n } else {\r\n // Delete label and continue\r\n progressData.skippedLabels += 1;\r\n this.deleteLabel(newLabel.id);\r\n return;\r\n }\r\n }\r\n\r\n // Add points to new label\r\n points.forEach(point => {\r\n newLabel.addPoint(point, false);\r\n });\r\n\r\n newLabel.complete();\r\n addedLabel = newLabel;\r\n });\r\n\r\n return addedLabel;\r\n }\r\n\r\n async addCategoryLabels(labels, category, images, projection, progressData, isTrainingArea) {\r\n let labelsToMerge = {};\r\n\r\n for (let label of labels) {\r\n // Add new label from data\r\n let addedLabel = this.importLabel(label, category, images,\r\n projection, progressData, isTrainingArea);\r\n\r\n // Update loading progress\r\n const {labelTotal, labelIndex} = progressData;\r\n const percent = 100 * (labelIndex+1)/labelTotal;\r\n progressData.progress = Math.min(100, percent);\r\n progressData.labelIndex += 1;\r\n\r\n // Asynchronous timeout to stop ui from freezing\r\n if (labelIndex % 10 === 0) {\r\n progressData.callback(progressData.progress);\r\n await asyncTimeout(10.0);\r\n }\r\n\r\n const mergeID = label.merge_id;\r\n if (!addedLabel || !mergeID) continue;\r\n\r\n let previous = labelsToMerge[mergeID];\r\n labelsToMerge[mergeID] = previous\r\n ? [...previous, addedLabel]\r\n : [addedLabel];\r\n }\r\n\r\n return Object.keys(labelsToMerge)\r\n .map(x => labelsToMerge[x]);\r\n }\r\n\r\n /** @private */\r\n checkLabelOverlap(newCategory, checkOverlap, progressData) {\r\n if (!checkOverlap) {\r\n return;\r\n }\r\n\r\n [...newCategory.labels].forEach(label => {\r\n let hasOverlap = this.checkForImageOverlap(label);\r\n if (!hasOverlap) {\r\n progressData.skippedLabels += 1;\r\n newCategory.deleteLabel(label.id);\r\n }\r\n });\r\n }\r\n\r\n /** @private */\r\n checkLabelInvalid(newCategory, progressData) {\r\n [...newCategory.labels].forEach(label => {\r\n if (!label.hasEnoughPoints) {\r\n progressData.skippedLabels += 1;\r\n newCategory.deleteLabel(label.id);\r\n };\r\n });\r\n }\r\n\r\n private clearTooltips() {\r\n clearAerialTooltip();\r\n clearViewerTooltip();\r\n }\r\n\r\n async loadImageLabelData(data, progressCallback, overwrite, checkOverlap) {\r\n if (overwrite) {\r\n this.deleteAllCategories();\r\n }\r\n\r\n let projection = data.projection;\r\n let categories = data.categories;\r\n let labels = data.annotations;\r\n let hasTrainingArea = data.hasOwnProperty('trainingAreas');\r\n\r\n // Check for valid projection string\r\n let validProjection = isValidProjection(projection.string);\r\n if (!validProjection) {\r\n toast.error(t(\"toast.labels-invalid-projection\"));\r\n return;\r\n }\r\n\r\n let images = {};\r\n data.images.forEach(image => {\r\n images[image.id] = image;\r\n });\r\n\r\n // Calculate total combined labels\r\n let numLabelsTotal = 0;\r\n data.annotations.forEach(label => {\r\n numLabelsTotal += label.segmentation.length;\r\n });\r\n\r\n let progressData = {\r\n progress: 0,\r\n labelTotal: numLabelsTotal,\r\n labelIndex: 0,\r\n skippedLabels: 0,\r\n callback: progressCallback\r\n };\r\n\r\n // Stop category UI update\r\n this.setUpdateState(false);\r\n\r\n if (hasTrainingArea) {\r\n let trainingAreaCategory = this.addTrainingArea();\r\n\r\n let areasToMerge = await this.addCategoryLabels(\r\n data.trainingAreas, trainingAreaCategory, images,\r\n projection, progressData, true);\r\n\r\n // Merge training data was was previously connected\r\n areasToMerge.forEach(mergeList => {\r\n this.mergeTrainingLabels(trainingAreaCategory, mergeList);\r\n });\r\n\r\n // Complete all labels\r\n trainingAreaCategory.labels.forEach(label => {\r\n trainingAreaCategory.completeLabel(label.id);\r\n });\r\n }\r\n\r\n for (let category of categories) {\r\n let newLabels = labels.filter(x => x.category_id === category.id);\r\n\r\n let currentCategory = this.getCategoryByName(category.name);\r\n\r\n // Add new category (existing or current)\r\n let newCategory = currentCategory\r\n ? currentCategory\r\n : this.addCategory(category.name);\r\n\r\n let labelsToMerge = await this.addCategoryLabels(\r\n newLabels, newCategory, images, projection,\r\n progressData, false\r\n );\r\n\r\n // Merge training data was was previously connected\r\n labelsToMerge.forEach(mergeList => {\r\n this.mergeTrainingLabels(newCategory, mergeList);\r\n });\r\n\r\n // Check for overlap between label and image\r\n this.checkLabelOverlap(newCategory, checkOverlap, progressData);\r\n\r\n // Simplify panoramic labels\r\n this.simplifyPanoramicLabels(newCategory);\r\n\r\n // Remove any labels that are invalid now\r\n this.checkLabelInvalid(newCategory, progressData);\r\n\r\n // Complete all labels\r\n newCategory.labels.forEach(label => {\r\n newCategory.completeLabel(label.id);\r\n });\r\n\r\n // Remove category if nothing is left\r\n if (newCategory.labels.length === 0) {\r\n console.log(`Delete empty category: ${newCategory.name}`);\r\n this.deleteCategory(newCategory.id);\r\n } else {\r\n console.log(`Import labels for category: ${newCategory.name}`);\r\n }\r\n };\r\n\r\n // Set labels to drawable\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n label.setDrawable(true);\r\n });\r\n });\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n label.setDrawable(true);\r\n });\r\n\r\n // Draw all new labels\r\n this.activeLabeler.drawAll();\r\n\r\n // Categories can be updated in UI\r\n this.setUpdateState(true);\r\n\r\n if (progressData.skippedLabels > 0) {\r\n toast.error(t(\"toast.labels-skipped-import\", {\r\n count: progressData.skippedLabels\r\n }));\r\n }\r\n\r\n setTimeout(() => {\r\n this.setCategories();\r\n this.clearTooltips();\r\n progressCallback(0);\r\n }, 500);\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n this.sceneLabels.update(changeDetector);\r\n }\r\n\r\n labelObject() {\r\n let categories = this.categories.map((category, categoryID) => {\r\n let [r, g, b] = textToColorArray(category.name, 0);\r\n let color = [r, g, b];\r\n\r\n return {\r\n supercategory: category.name,\r\n id: categoryID,\r\n name: category.name,\r\n color: color\r\n } as CocoCategory;\r\n });\r\n\r\n let annotations = this.activeLabeler.getLabelAnnotations();\r\n let trainingAreas = this.activeLabeler.getTrainingAnnotations();\r\n\r\n let jsonObj = {\r\n type: this.activeLabeler.type,\r\n categories: categories,\r\n projection: LocalScene.dataProjection,\r\n images: this.activeLabeler.jsonImageObj(),\r\n annotations: annotations,\r\n ...(trainingAreas.length > 0) && {trainingAreas},\r\n };\r\n\r\n return jsonObj;\r\n }\r\n}\r\n\r\nexport const sectionsFromIntersection = (intersection, removeDuplicate=true) => {\r\n let sections = [];\r\n\r\n if (!intersection) {\r\n return sections;\r\n }\r\n\r\n let geometry = intersection.geometry;\r\n geometry.coordinates.forEach(result => {\r\n let intersectPoints = [...result];\r\n\r\n if (geometry.type === \"MultiPolygon\") {\r\n intersectPoints = intersectPoints[0];\r\n }\r\n\r\n if (removeDuplicate) {\r\n intersectPoints.pop();\r\n }\r\n\r\n sections.push(intersectPoints);\r\n });\r\n\r\n return sections;\r\n};\r\n\r\nexport const annotationFromPolygon = (polygon, labelIndex, categoryID, imageID, mergeID, score=1.0, text='', textScore=0.0, findText=false) => {\r\n let segment = [...polygon].flat();\r\n let allX = polygon.map(x => x[0]);\r\n let allY = polygon.map(x => x[1]);\r\n\r\n let boundBox = [\r\n Math.min(...allX),\r\n Math.min(...allY),\r\n Math.max(...allX) - Math.min(...allX),\r\n Math.max(...allY) - Math.min(...allY)\r\n ].map(x => Math.round(x));\r\n\r\n let area = areaFromPolygon(polygon);\r\n let findTextNum = findText ? 1 : 0;\r\n\r\n let annotation = {\r\n segmentation: [segment],\r\n iscrowd: 0,\r\n image_id: imageID,\r\n bbox: boundBox,\r\n category_id: categoryID,\r\n id: labelIndex,\r\n area: area,\r\n score:score,\r\n text: text,\r\n textScore:textScore,\r\n findText: findTextNum\r\n } as CocoAnnotation;\r\n\r\n if (mergeID !== null) {\r\n annotation.merge_id = mergeID;\r\n }\r\n\r\n return annotation;\r\n};\r\n\r\nexport const areaFromPolygon = (polygon) => {\r\n let contour = polygon.map(x => new Vector2(...x));\r\n return Math.abs(ShapeUtils.area(contour));\r\n};\r\n\r\nconst minDistanceIdx = (coordArray, point) => {\r\n let shortestDistance = Infinity;\r\n let closestPoint = new Vector3();\r\n let idxCoord;\r\n\r\n for (let idx = 0; idx < coordArray.length; idx++) {\r\n let endIdx = (idx === coordArray.length - 1) ? 0 : idx + 1;\r\n let lineSegment = createSegment(coordArray[idx], coordArray[endIdx]);\r\n lineSegment.closestPointToPoint(point, true, closestPoint);\r\n let distance = point.distanceTo(closestPoint);\r\n if (Math.abs(distance) < Math.abs(shortestDistance)) {\r\n shortestDistance = distance;\r\n idxCoord = idx;\r\n }\r\n }\r\n\r\n return idxCoord;\r\n};\r\n\r\nconst createSegment = (P1, P2) => {\r\n let startPoint = new Vector3(P1[0], P1[1]);\r\n let endPoint = new Vector3(P2[0], P2[1]);\r\n return new Line3(startPoint, endPoint);\r\n};","import 'ol/ol.css';\r\nimport {Vector as VectorSource} from \"ol/source\";\r\nimport {Vector as VectorLayer} from \"ol/layer\";\r\nimport VectorImageLayer from 'ol/layer/VectorImage';\r\nimport {Point, Polygon} from \"ol/geom\";\r\nimport {Feature} from \"ol\";\r\nimport {\r\n Circle as CircleStyle,\r\n Fill, Stroke, Style\r\n} from \"ol/style\";\r\nimport { checkValidPolygon } from \"../utilities\";\r\nimport {\r\n annotationFromPolygon,\r\n CocoImage,\r\n ImageLabel,\r\n ImageLabelTools,\r\n LabelCategory,\r\n sectionsFromIntersection,\r\n textToColor\r\n} from '.';\r\nimport {Color, Vector3} from 'three';\r\nimport {polygon as turfPolygon} from '@turf/helpers';\r\nimport {default as turfIntersect} from '@turf/intersect';\r\nimport {\r\n OrthoMosaic,\r\n AerialMap,\r\n extentFromPoints\r\n} from '../aerial';\r\nimport { LabelContextData, showContextMenu } from '../../../context-menu';\r\nimport { CustomMouseEvent } from '../controls';\r\nimport { clearAerialTooltip, setAerialTooltip } from '../../viewer';\r\nimport { t } from '../../../localization';\r\n\r\nconst pointRadius = 5.0;\r\nconst pointStrokeWidth = 1.0;\r\n\r\nclass LabelPoint extends Feature {\r\n public label: OrthoLabel;\r\n public index;\r\n\r\n constructor(opts, label, index) {\r\n super(opts);\r\n this.label = label;\r\n this.index = index;\r\n }\r\n}\r\n\r\nclass LabelPolygon extends Feature {\r\n public label: OrthoLabel;\r\n\r\n constructor(opts, label) {\r\n super(opts);\r\n this.label = label;\r\n }\r\n}\r\n\r\nclass Coordinate {\r\n public array = [];\r\n\r\n constructor(coordinates) {\r\n this.array = coordinates;\r\n }\r\n\r\n get x() {\r\n return this.array[0];\r\n }\r\n\r\n get y() {\r\n return this.array[1];\r\n }\r\n\r\n get point() {\r\n return this.array;\r\n }\r\n\r\n update(point) {\r\n if (point.length === 2) {\r\n this.array = point;\r\n }\r\n }\r\n}\r\n\r\nexport class OrthoLabel extends ImageLabel {\r\n public features = [];\r\n public category: OrthoCategory\r\n public coordinates: Coordinate[] = [];\r\n public aerialMap: AerialMap;\r\n private minCoordinates = 3;\r\n private styleCache = {};\r\n\r\n constructor(category: OrthoCategory, aerialMap: AerialMap) {\r\n super();\r\n this.category = category;\r\n this.aerialMap = aerialMap;\r\n }\r\n\r\n get hasEnoughPoints() {\r\n return this.numPoints >= this.minCoordinates;\r\n }\r\n\r\n get numPoints() {\r\n return this.coordinates.length;\r\n }\r\n\r\n get coords() {\r\n /** Used for polygon simplification */\r\n return this.coordinates.map(x => x.point);\r\n }\r\n\r\n get polygonPointsOnly() {\r\n return this.coordinates.map(x => x.point);\r\n }\r\n\r\n get isValid() {\r\n return checkValidPolygon(this.polygonPointsOnly);\r\n }\r\n\r\n get map() {\r\n return this.aerialMap.map;\r\n }\r\n\r\n get completedSource() {\r\n return this.category.featuresLayer.getSource();\r\n }\r\n\r\n get editingSource() {\r\n return this.category.editingLayer.getSource();\r\n }\r\n\r\n get featureStyle() {\r\n return this.getLayerFromCache(true);\r\n }\r\n\r\n get editingStyle() {\r\n return this.getLayerFromCache(false);\r\n }\r\n\r\n clearStyleCache() {\r\n this.styleCache = {};\r\n }\r\n\r\n setFeatureStyle() {\r\n this.features.forEach(feature => {\r\n if (this.completed) {\r\n feature.setStyle(this.featureStyle);\r\n } else {\r\n feature.setStyle(this.editingStyle);\r\n }\r\n });\r\n }\r\n\r\n getLayerFromCache(checkDefaultStyle) {\r\n if (checkDefaultStyle) {\r\n let defaults = this.category.defaultStyleParams;\r\n let isDefaultStyle = (this.valid === defaults[0])\r\n && (this.completed === defaults[1])\r\n && (this.highlighted === defaults[2]);\r\n\r\n if (isDefaultStyle) {\r\n return null;\r\n }\r\n }\r\n\r\n let styleKey = `${this.valid}-${this.completed}-${this.highlighted}`;\r\n\r\n if (!this.styleCache[styleKey]) {\r\n this.styleCache[styleKey] = this.category.getLayerStyle(\r\n this.valid, this.completed, this.highlighted);\r\n }\r\n\r\n return this.styleCache[styleKey];\r\n }\r\n\r\n updatePoint(point, index) {\r\n this.coordinates[index].update(point);\r\n }\r\n\r\n removePoint() {\r\n this.coordinates.pop();\r\n }\r\n\r\n removeSpecificPoint(index) {\r\n this.coordinates.splice(index, 1);\r\n this.draw();\r\n }\r\n\r\n pointToScreen(point) {\r\n return this.map.getPixelFromCoordinate(point.point);\r\n }\r\n\r\n createCoordData(coordinate) {\r\n const point = new Vector3(coordinate[0], coordinate[1]);\r\n const coordArray = this.coordinates.map(coord => {\r\n return coord.array;\r\n });\r\n\r\n return {coordArray, point};\r\n }\r\n\r\n addPoint(point, checkDuplicate=true) {\r\n const newPoint = new Coordinate(point);\r\n const oldPoint = this.coordinates[this.coordinates.length - 1];\r\n\r\n if (checkDuplicate && this.duplicatePoint(oldPoint, newPoint)) {\r\n return true;\r\n }\r\n\r\n this.coordinates.push(newPoint);\r\n return false;\r\n }\r\n\r\n insertPoint(newPoint, idxCoord) {\r\n let newCoord = new Coordinate(newPoint.toArray());\r\n this.coordinates.splice(idxCoord+1, 0, newCoord);\r\n this.draw();\r\n }\r\n\r\n drawPoints(temporaryPoint) {\r\n let positions = this.coordinates;\r\n if (temporaryPoint && !this.completed) {\r\n positions = [...positions, temporaryPoint];\r\n }\r\n\r\n positions.forEach((point, index) => {\r\n const feature = new LabelPoint({\r\n geometry: new Point([point.x, point.y])\r\n }, this, index);\r\n\r\n this.features.push(feature);\r\n\r\n let source = this.completed\r\n ? this.completedSource\r\n : this.editingSource;\r\n\r\n source.addFeature(feature);\r\n });\r\n }\r\n\r\n drawPolygon(temporaryPoint) {\r\n let positions = this.polygonPointsOnly;\r\n if (temporaryPoint && !this.completed) {\r\n positions = [...positions, temporaryPoint.point];\r\n }\r\n\r\n if (this.hasEnoughPoints){\r\n let validPolygon = checkValidPolygon(positions);\r\n if (this.valid !== validPolygon) {\r\n this.valid = validPolygon;\r\n this.category.setCategories();\r\n }\r\n }\r\n\r\n let feature = new LabelPolygon({\r\n geometry: new Polygon([positions])\r\n }, this);\r\n\r\n this.features.push(feature);\r\n\r\n let source = this.completed\r\n ? this.completedSource\r\n : this.editingSource;\r\n\r\n source.addFeature(feature);\r\n }\r\n\r\n draw(temporaryPoint=null) {\r\n if (!this.drawable) {\r\n return;\r\n }\r\n\r\n this.clear();\r\n this.drawPoints(temporaryPoint);\r\n this.drawPolygon(temporaryPoint);\r\n this.setFeatureStyle();\r\n }\r\n\r\n clear() {\r\n const sources = [\r\n this.completedSource,\r\n this.editingSource\r\n ];\r\n\r\n this.features.forEach(x => {\r\n sources.forEach(source => {\r\n if (source.hasFeature(x)) {\r\n source.removeFeature(x);\r\n }\r\n });\r\n });\r\n\r\n this.features = [];\r\n }\r\n\r\n zoom(): Promise {\r\n let positions = [...this.polygonPointsOnly];\r\n let extent = extentFromPoints(positions, false);\r\n this.aerialMap.setMapExtent(extent);\r\n return Promise.resolve(true);\r\n }\r\n\r\n setHighlighted(highlight) {\r\n if (highlight === this.highlighted) {\r\n return;\r\n }\r\n\r\n this.highlighted = highlight;\r\n this.draw();\r\n }\r\n}\r\n\r\nexport class OrthoCategory extends LabelCategory {\r\n private aerialTools: AerialLabelTools;\r\n public labels: OrthoLabel[] = [];\r\n public featuresLayer: VectorImageLayer;\r\n public editingLayer: VectorLayer;\r\n\r\n constructor(aerialTools: AerialLabelTools, name) {\r\n super(name);\r\n this.aerialTools = aerialTools;\r\n this.addMapLayers();\r\n }\r\n\r\n get aerialMap() {\r\n return this.aerialTools.aerialMap;\r\n }\r\n\r\n get map() {\r\n return this.aerialMap.map;\r\n }\r\n\r\n get defaultStyleParams() {\r\n // valid, completed, higlighted\r\n return [true, true, false];\r\n }\r\n\r\n darkenedColor(highlighted) {\r\n let pointColor = this.categoryColor(highlighted, 1.0);\r\n let dark = new Color(pointColor)\r\n .multiplyScalar(0.75);\r\n\r\n return `rgb(${dark.r*256}, ${dark.g*256}, ${dark.b*256})`;\r\n }\r\n\r\n categoryColor(highlighted=false, opacity=0.2) {\r\n if (highlighted) {\r\n return `rgba(${255}, ${255}, ${255}, ${opacity})`;\r\n }\r\n\r\n if (this instanceof TrainingAreaCategory){\r\n return `rgba(${0}, ${0}, ${0}, ${opacity})`;\r\n }\r\n\r\n return textToColor(this.name, opacity);\r\n }\r\n\r\n getLayerStyle(valid=true, completed=true, highlighted=false) {\r\n let opacity = valid ? 0.2 : 0.0;\r\n if (this instanceof TrainingAreaCategory) {\r\n opacity = 0.0;\r\n }\r\n\r\n return new Style({\r\n fill: new Fill({\r\n color: this.categoryColor(highlighted, opacity)\r\n }),\r\n stroke: new Stroke({\r\n lineDash: completed ? undefined : [10, 10],\r\n color: this.darkenedColor(highlighted),\r\n width: 2\r\n }),\r\n image: new CircleStyle({\r\n radius: pointRadius,\r\n stroke: new Stroke({\r\n width: pointStrokeWidth,\r\n color: 'rgba(0, 0, 0, 1.0)'\r\n }),\r\n fill: new Fill({\r\n color: this.categoryColor(highlighted, 0.8)\r\n }),\r\n })\r\n });\r\n }\r\n\r\n addMapLayers() {\r\n this.featuresLayer = new VectorImageLayer({\r\n zIndex: 1,\r\n source: new VectorSource({\r\n features: [],\r\n wrapX: false\r\n }),\r\n style: this.getLayerStyle()\r\n });\r\n\r\n this.map.addLayer(this.featuresLayer);\r\n\r\n this.editingLayer = new VectorLayer({\r\n zIndex: 1,\r\n source: new VectorSource({\r\n features: [],\r\n wrapX: false\r\n }),\r\n style: this.getLayerStyle(),\r\n updateWhileInteracting: false,\r\n updateWhileAnimating: false\r\n });\r\n\r\n this.map.addLayer(this.editingLayer);\r\n }\r\n\r\n setCategories() {\r\n this.aerialTools.imageLabelTools.setCategories();\r\n }\r\n\r\n updateColor() {\r\n this.featuresLayer.setStyle(this.getLayerStyle());\r\n this.editingLayer.setStyle(this.getLayerStyle());\r\n\r\n this.labels.forEach(label => {\r\n label.clearStyleCache();\r\n label.setFeatureStyle();\r\n });\r\n }\r\n\r\n addNewLabel(drawLabel) {\r\n let label = new OrthoLabel(this, this.aerialMap);\r\n label.setDrawable(drawLabel);\r\n this.labels.push(label);\r\n\r\n return label;\r\n }\r\n}\r\n\r\nexport class TrainingAreaLabel extends OrthoLabel {\r\n constructor(category: OrthoCategory, aerialMap: AerialMap) {\r\n super(category, aerialMap);\r\n }\r\n\r\n polygonsInsideImage(image: OrthoMosaic) {\r\n // Find the part of the training area label that intersects with this image\r\n let intersection = image.intersectAerialPoints(this.polygonPointsOnly);\r\n let intersectionData = sectionsFromIntersection(intersection, false);\r\n\r\n return intersectionData.map((arr) => {\r\n return image.aerialToPixels(arr);\r\n });\r\n }\r\n}\r\n\r\nclass TrainingAreaCategory extends OrthoCategory {\r\n public labels: TrainingAreaLabel[] = [];\r\n\r\n constructor(aerialTools: AerialLabelTools, name) {\r\n super(aerialTools, name);\r\n }\r\n\r\n addNewLabel(drawLabel) {\r\n let label = new TrainingAreaLabel(this, this.aerialMap);\r\n label.setDrawable(drawLabel);\r\n this.labels.push(label);\r\n\r\n return label;\r\n }\r\n}\r\n\r\nexport class AerialLabelTools {\r\n public type = \"ortho\";\r\n public enabled = false;\r\n public imageLabelTools: ImageLabelTools;\r\n public setPointDelete;\r\n public setPointAdd;\r\n public setCategoryList;\r\n private temporaryPoint: Coordinate;\r\n public trainingArea: TrainingAreaCategory;\r\n private polygonHover: LabelPolygon = null;\r\n private pointHover: LabelPoint = null;\r\n\r\n constructor(imageLabelTools: ImageLabelTools, props) {\r\n const {setCategoryList} = props;\r\n\r\n this.imageLabelTools = imageLabelTools;\r\n this.setCategoryList = setCategoryList;\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-start-drawing-polygon')\r\n ];\r\n }\r\n\r\n get dragTooltip() {\r\n return [\r\n t('measure.click-and-hold-to-move-vertex'),\r\n t('measure.right-click-to-select-point')\r\n ];\r\n }\r\n\r\n get highlightTooltip() {\r\n return [\r\n t('measure.right-click-to-select-label'),\r\n t('measure.ctrl-right-click-to-select-multiple-labels')\r\n ];\r\n }\r\n\r\n get categories() {\r\n return this.imageLabelTools.categories\r\n .filter(x => x instanceof OrthoCategory) as OrthoCategory[];\r\n }\r\n\r\n get viewer() {\r\n return this.imageLabelTools.viewer;\r\n }\r\n\r\n get aerialMap() {\r\n return this.viewer.minimap;\r\n }\r\n\r\n get map() {\r\n return this.aerialMap.map;\r\n }\r\n\r\n get drawing() {\r\n let label = this.activeLabel;\r\n if (!label || label.completed) {\r\n return false;\r\n }\r\n\r\n if (label.coordinates.length === 0) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n get activeLabel() {\r\n let selected = null;\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n if (label.selected) {\r\n selected = label;\r\n }\r\n });\r\n });\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n if (label.selected) {\r\n selected = label;\r\n }\r\n });\r\n\r\n return selected;\r\n }\r\n\r\n get numberLabels() {\r\n let count = 0;\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label => count++));\r\n return count;\r\n }\r\n\r\n get moreTooltip() {\r\n return [\r\n t(\"labels.click-to-add-more-points\", {\r\n count: this.numPoints\r\n }),\r\n t('labels.delete-key-to-remove-last-point'),\r\n ...(this.numPoints > 1) ? [t('labels.double-click-to-finish')] : [],\r\n ...(this.numPoints > 2) ? [t('labels.press-enter-to-exit')] : [],\r\n ...this.activeLabel.editing ? [] : [t('labels.right-click-to-cancel')]\r\n ];\r\n }\r\n\r\n get invalidTooltip() {\r\n return [\r\n t('labels.polygon-is-invalid-due-to-self-intersection'),\r\n ...this.moreTooltip\r\n ];\r\n }\r\n\r\n get numPoints() {\r\n let pointCount = 0;\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label => {\r\n if (label.selected) {\r\n pointCount = label.numPoints;\r\n }\r\n })\r\n );\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n if (label.selected) {\r\n pointCount = label.numPoints;\r\n }\r\n });\r\n\r\n return pointCount;\r\n }\r\n\r\n get selected() {\r\n let selected = false;\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label =>\r\n selected = (selected || label.selected)\r\n )\r\n );\r\n\r\n this.trainingArea?.labels.forEach(label =>\r\n selected = (selected || label.selected)\r\n );\r\n\r\n return selected;\r\n }\r\n\r\n get visibleOrthos() {\r\n let orthoList = this.viewer.orthoList;\r\n return orthoList.orthos.filter(x => x.visible);\r\n }\r\n\r\n get activeImagePaths() {\r\n return this.visibleOrthos.map(ortho => ortho.path);\r\n }\r\n\r\n get loadedImagePaths() {\r\n let orthoList = this.viewer.orthoList;\r\n return orthoList.orthos.map(ortho => ortho.path);\r\n }\r\n\r\n get polygonFeaturesForExtent() {\r\n let features = [];\r\n this.categories.forEach(category => {\r\n let source = category.featuresLayer.getSource();\r\n let extent = this.map.getView().calculateExtent(this.map.getSize());\r\n let sourceFeatures = source.getFeaturesInExtent(extent);\r\n let points = sourceFeatures.filter(x => x instanceof LabelPolygon);\r\n features = [...features, ...points];\r\n });\r\n\r\n return features;\r\n }\r\n\r\n get pointFeaturesForExtent() {\r\n let features = [];\r\n\r\n this.categories.forEach(category => {\r\n let source = category.featuresLayer.getSource();\r\n let extent = this.map.getView().calculateExtent(this.map.getSize());\r\n let sourceFeatures = source.getFeaturesInExtent(extent);\r\n let points = sourceFeatures.filter(x => x instanceof LabelPoint);\r\n features = [...features, ...points];\r\n });\r\n\r\n if (this.trainingArea) {\r\n let source = this.trainingArea.featuresLayer.getSource();\r\n let extent = this.map.getView().calculateExtent(this.map.getSize());\r\n let sourceFeatures = source.getFeaturesInExtent(extent);\r\n let points = sourceFeatures.filter(x => x instanceof LabelPoint);\r\n features = [...features, ...points];\r\n }\r\n\r\n return features;\r\n }\r\n\r\n get trainingLabels() {\r\n return this.trainingArea\r\n ? this.trainingArea.labels.filter(label => label.isValid)\r\n : [];\r\n }\r\n\r\n completeLabel(label: OrthoLabel) {\r\n this.resetTemporaryPoint();\r\n this.imageLabelTools.completeLabel(label.id);\r\n this.markLastPointDraggable(label);\r\n }\r\n\r\n updateDraggablePoint(event) {\r\n let {label, index} = this.pointHover;\r\n label.updatePoint(event.coordinate, index);\r\n label.draw();\r\n\r\n if (label.score < 1.0) {\r\n label.setScore(1.0);\r\n this.imageLabelTools.setCategories();\r\n }\r\n }\r\n\r\n markLastPointDraggable(label: OrthoLabel) {\r\n let pointFeatures = label.features.filter(x => x instanceof LabelPoint);\r\n let lastPoint = pointFeatures[pointFeatures.length - 1];\r\n this.setPointHover(lastPoint);\r\n }\r\n\r\n cancelLabel() {\r\n if (this.activeLabel && !this.activeLabel.editing) {\r\n this.imageLabelTools.deleteLabel(this.activeLabel.id);\r\n this.setToolTipText();\r\n this.drawAll();\r\n }\r\n }\r\n\r\n setState(state) {\r\n this.enabled = state;\r\n clearAerialTooltip();\r\n }\r\n\r\n setPointHover(feature) {\r\n this.pointHover = feature;\r\n\r\n if (feature) {\r\n this.setPointGrabTooltip();\r\n }\r\n\r\n const canDrag = feature ? false : true;\r\n this.aerialMap.setDragState(canDrag);\r\n }\r\n\r\n setPolygonHover(feature) {\r\n this.polygonHover = feature;\r\n }\r\n\r\n setTrainingArea(category: TrainingAreaCategory) {\r\n this.trainingArea = category;\r\n }\r\n\r\n deleteTrainingArea() {\r\n this.trainingArea.labels.forEach(label => {\r\n label.destroy();\r\n });\r\n\r\n this.trainingArea = null;\r\n }\r\n\r\n openContextMenu(event, feature) {\r\n let pointID = (feature instanceof LabelPoint) ? feature.index : null;\r\n let labelID = feature.label.id;\r\n let coordinate = this.map.getCoordinateFromPixel([\r\n event.offsetX, event.offsetY\r\n ]);\r\n\r\n const labelData = {\r\n coordinate,\r\n pointID,\r\n labelID\r\n } as LabelContextData;\r\n\r\n showContextMenu(event, {\r\n isAerial: true,\r\n labelData\r\n });\r\n }\r\n\r\n onMapClick(event) {\r\n if (!this.enabled) return false;\r\n\r\n let label = this.activeLabel;\r\n if (!label) {\r\n return false;\r\n }\r\n\r\n let duplicatePoint = label.addPoint(event.coordinate);\r\n if (duplicatePoint && label.hasEnoughPoints) {\r\n this.completeLabel(label);\r\n return true;\r\n }\r\n\r\n this.setToolTipText();\r\n this.resetTemporaryPoint();\r\n this.drawActiveLabel();\r\n return true;\r\n }\r\n\r\n onDoubleClick(event) {\r\n if (!this.enabled) return false;\r\n\r\n // Restrict double click zoom\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n onMouseMove(event) {\r\n if (!this.enabled) return false;\r\n\r\n this.resetTemporaryPoint();\r\n\r\n // Drawing new points\r\n if (this.selected) {\r\n this.temporaryPoint = new Coordinate(event.coordinate);\r\n this.setToolTipText();\r\n this.drawActiveLabel();\r\n return;\r\n }\r\n\r\n if (!event.dragging) {\r\n this.checkFeatureHover(event);\r\n }\r\n\r\n if (this.pointHover) {\r\n this.setPointGrabTooltip();\r\n if (event.dragging) {\r\n this.updateDraggablePoint(event);\r\n return;\r\n }\r\n } else if (this.polygonHover) {\r\n this.setPolygonHoverTooltip();\r\n } else {\r\n this.setToolTipText();\r\n }\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (!this.enabled) return false;\r\n\r\n if (event.isRightClick) {\r\n if (this.drawing) {\r\n this.cancelLabel();\r\n return true;\r\n }\r\n\r\n return this.onRightClick(event);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onRightClick(event) {\r\n const oneHighlighted = this.imageLabelTools.oneHighlighted;\r\n const noneHighlighted = this.imageLabelTools.noneHighlighted;\r\n\r\n if (noneHighlighted && !event.ctrlKey) {\r\n let feature = this.highlightLabel();\r\n if (feature) {\r\n this.openContextMenu(event, feature);\r\n return true;\r\n }\r\n }\r\n\r\n if (oneHighlighted && !event.ctrlKey) {\r\n this.imageLabelTools.unHighlightAll();\r\n let feature = this.highlightLabel();\r\n if (feature) {\r\n this.openContextMenu(event, feature);\r\n return true;\r\n }\r\n }\r\n\r\n if (event.ctrlKey) {\r\n this.highlightLabel();\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n checkFeatureHover(event) {\r\n if (event instanceof MouseEvent) {\r\n const pixel = [event.offsetX, event.offsetY];\r\n const coordinate = this.map.getCoordinateFromPixel(pixel);\r\n event = {pixel, coordinate};\r\n }\r\n\r\n let selectedPoint = this.getFeatureAtPixel(event,\r\n this.pointFeaturesForExtent);\r\n\r\n let selectedPolygon = this.getFeatureAtPixel(event,\r\n this.polygonFeaturesForExtent);\r\n\r\n this.setPointHover(selectedPoint);\r\n this.setPolygonHover(selectedPolygon);\r\n }\r\n\r\n getFeatureAtPixel(event, features) {\r\n const mousePixel = event.pixel;\r\n const mouseCoord = event.coordinate;\r\n const buffer = 10;\r\n\r\n const x = mousePixel[0];\r\n const y = mousePixel[1];\r\n\r\n const mouseBuffer = this.map.getCoordinateFromPixel([x, y])[0]\r\n - this.map.getCoordinateFromPixel([x - buffer, y])[0];\r\n\r\n for (let feature of features) {\r\n // NOTE: We know the geometry exists, so this is faster than\r\n // calling feature.getGeometry() or feature.get(\"geometry\")\r\n const geometry = feature.values_.geometry;\r\n\r\n const pointExtent = geometry.getExtent();\r\n const notVisible = (pointExtent[0] > (mouseCoord[0] + mouseBuffer))\r\n || (pointExtent[2] < (mouseCoord[0] - mouseBuffer))\r\n || (pointExtent[1] > (mouseCoord[1] + mouseBuffer))\r\n || (pointExtent[3] < (mouseCoord[1] - mouseBuffer));\r\n\r\n if (notVisible) {\r\n continue;\r\n }\r\n\r\n if (feature instanceof LabelPolygon) {\r\n const intersect = geometry.intersectsCoordinate(mouseCoord);\r\n if (intersect) {\r\n return feature;\r\n }\r\n }\r\n\r\n if (feature instanceof LabelPoint) {\r\n const coord = geometry.flatCoordinates;\r\n const pixel = this.map.getPixelFromCoordinate(coord);\r\n const dx = pixel[0] - mousePixel[0];\r\n const dy = pixel[1] - mousePixel[1];\r\n const dist = Math.sqrt(dx*dx + dy*dy);\r\n\r\n // Check using pointRadius + outline\r\n const maxDistance = pointRadius + pointStrokeWidth;\r\n const intersect = dist <= maxDistance;\r\n if (intersect) {\r\n return feature;\r\n }\r\n }\r\n };\r\n }\r\n\r\n highlightLabel() {\r\n let selected = null;\r\n\r\n if (this.pointHover) {\r\n selected = this.pointHover;\r\n } else if (this.polygonHover) {\r\n selected = this.polygonHover;\r\n } else {\r\n return;\r\n }\r\n\r\n let label = selected.label;\r\n label.setHighlighted(!label.highlighted);\r\n this.imageLabelTools.setCategories();\r\n\r\n return selected;\r\n }\r\n\r\n setToolTipText() {\r\n if (!this.activeLabel) {\r\n clearAerialTooltip();\r\n return;\r\n }\r\n\r\n const started = (this.numPoints === 0);\r\n\r\n let helpMsg = started\r\n ? this.startTooltip\r\n : this.moreTooltip;\r\n\r\n helpMsg = this.activeLabel.valid\r\n ? helpMsg\r\n : this.invalidTooltip;\r\n\r\n setAerialTooltip(helpMsg);\r\n }\r\n\r\n setPointGrabTooltip() {\r\n setAerialTooltip(this.dragTooltip);\r\n }\r\n\r\n setPolygonHoverTooltip() {\r\n setAerialTooltip(this.highlightTooltip);\r\n }\r\n\r\n drawAll() {\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n label.draw(this.temporaryPoint);\r\n });\r\n });\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n label.draw(this.temporaryPoint);\r\n });\r\n }\r\n\r\n drawActiveLabel() {\r\n if (!this.activeLabel) {\r\n return;\r\n }\r\n\r\n this.activeLabel.draw(this.temporaryPoint);\r\n\r\n }\r\n\r\n getNewCategory(name) {\r\n return new OrthoCategory(this, name);\r\n }\r\n\r\n getNewTrainingArea() {\r\n return new TrainingAreaCategory(this, \"training\");\r\n }\r\n\r\n deletePoint() {\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label => {\r\n if (label.selected) {\r\n label.removePoint();\r\n this.setToolTipText();\r\n this.drawActiveLabel();\r\n }\r\n })\r\n );\r\n\r\n this.imageLabelTools.setCategories();\r\n }\r\n\r\n deleteSpecificPoint(id) {\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label => {\r\n\r\n if (label.highlighted && (label.numPoints > 3)) {\r\n label.removeSpecificPoint(id);\r\n this.imageLabelTools.unHighlight(label.id);\r\n }\r\n })\r\n );\r\n\r\n this.trainingArea?.labels.forEach(label => {\r\n if (label.highlighted && (label.numPoints > 3)) {\r\n label.removeSpecificPoint(id);\r\n this.imageLabelTools.unHighlight(label.id);\r\n }\r\n });\r\n\r\n this.imageLabelTools.setCategories();\r\n }\r\n\r\n resetTemporaryPoint() {\r\n this.temporaryPoint = null;\r\n }\r\n\r\n calculatePolygonPixels = (polygonPoints, metadata) => {\r\n let pixelPolygon = [];\r\n\r\n polygonPoints.forEach(point => {\r\n let pixelPoint = [((point[0] - metadata.x_offset)/metadata.x_scale),\r\n ((point[1] - metadata.y_offset)/metadata.y_scale)];\r\n pixelPolygon.push(pixelPoint);\r\n });\r\n return pixelPolygon;\r\n }\r\n\r\n jsonImageObj() {\r\n let images = this.visibleOrthos.map((ortho, imageIndex) => {\r\n return {\r\n height: ortho.originalSize[1],\r\n width: ortho.originalSize[0],\r\n id: imageIndex,\r\n file_name: ortho.orthoName,\r\n metadata: ortho.metadata\r\n } as CocoImage;\r\n });\r\n\r\n return images;\r\n }\r\n\r\n getTrainingAnnotations = () => {\r\n let labelIndex = 0;\r\n let annotations = [];\r\n\r\n if (this.trainingLabels.length === 0) {\r\n return annotations;\r\n }\r\n\r\n this.visibleOrthos.forEach((image, imageID) => {\r\n this.trainingLabels.forEach((trainingLabel, trainingLabelIndex) => {\r\n trainingLabel.polygonsInsideImage(image).forEach(polygon => {\r\n let mergeID = trainingLabelIndex+1;\r\n let trainingLabel = annotationFromPolygon(polygon,\r\n labelIndex, 0, imageID, mergeID);\r\n\r\n annotations.push(trainingLabel);\r\n labelIndex += 1;\r\n });\r\n });\r\n });\r\n\r\n return annotations;\r\n }\r\n\r\n getLabelAnnotations() {\r\n let labelIndex = 0;\r\n let annotations = [];\r\n\r\n this.visibleOrthos.forEach((image, imageID) => {\r\n let boundsToCheck = [];\r\n\r\n if (this.trainingLabels.length === 0) {\r\n // Bounds are the entire image\r\n let boundsPolygon = [...image.cornerPixels, image.cornerPixels[0]];\r\n boundsToCheck.push({imageID, boundsPolygon});\r\n } else {\r\n // Bounds are training area polygons for this image\r\n this.trainingLabels.forEach(trainingLabel => {\r\n trainingLabel.polygonsInsideImage(image).forEach(boundsPolygon => {\r\n boundsToCheck.push({imageID, boundsPolygon});\r\n });\r\n });\r\n }\r\n\r\n this.categories.forEach((category, categoryID) => {\r\n category.labels.forEach((label, labelID) => {\r\n if (!label.valid) {\r\n return;\r\n }\r\n\r\n // Check for label inside each boundary polygon\r\n boundsToCheck.forEach(({imageID, boundsPolygon}) => {\r\n let labelPolygon = this.visibleOrthos[imageID]\r\n .aerialToPixels(label.polygonPointsOnly);\r\n labelPolygon = [...labelPolygon, labelPolygon[0]];\r\n\r\n let intersection = turfIntersect(\r\n turfPolygon([boundsPolygon]),\r\n turfPolygon([labelPolygon])\r\n );\r\n\r\n let intersectionData = sectionsFromIntersection(intersection);\r\n intersectionData.forEach((polygon) => {\r\n let mergeID = labelID + 1;\r\n let annotation = annotationFromPolygon(polygon, labelIndex,\r\n categoryID, imageID, mergeID, label.score, label.text, label.textScore,\r\n label.findText);\r\n\r\n annotations.push(annotation);\r\n labelIndex += 1;\r\n });\r\n });\r\n });\r\n });\r\n });\r\n\r\n return annotations;\r\n };\r\n\r\n get activeImages() {\r\n return [];\r\n }\r\n}\r\n","import { Raycaster, Vector3 } from \"three\";\r\nimport { eventToPixel } from \"./utilities\";\r\n\r\nexport class RayCaster {\r\n private initialized = false;\r\n private width;\r\n private height;\r\n private event;\r\n public camera;\r\n private raycaster;\r\n\r\n constructor(object, event) {\r\n const {width, height, camera} = object;\r\n\r\n this.width = width;\r\n this.height = height;\r\n this.camera = camera;\r\n this.event = event;\r\n\r\n this.init();\r\n }\r\n\r\n init() {\r\n let direction = this.vectorFromEvent(this.event);\r\n let raycaster = this.defaultRaycaster(direction);\r\n this.raycaster = raycaster;\r\n }\r\n\r\n setPrecision(precision) {\r\n if (!this.initialized) {\r\n return;\r\n }\r\n\r\n this.raycaster.params = {\r\n 'Points': {threshold: precision},\r\n 'Line': {threshold: precision}\r\n };\r\n }\r\n\r\n intersectPlane(target) {\r\n let intersect = new Vector3();\r\n this.raycaster.ray.intersectPlane(target, intersect);\r\n return intersect;\r\n }\r\n\r\n intersectObject(target) {\r\n return this.raycaster.intersectObject(target);\r\n }\r\n\r\n intersectTriangle(P1, P2, P3) {\r\n const result = new Vector3();\r\n this.raycaster.ray.intersectTriangle(P1, P2, P3, false, result);\r\n return result.length() > 0 ? result : null;\r\n }\r\n\r\n intersectObjects(targets, opts={}) {\r\n if (!this.initialized) {\r\n return [];\r\n }\r\n\r\n let defaults = {\r\n minDistance: null,\r\n sortByRay: false,\r\n recursive: true\r\n };\r\n\r\n let options = {...defaults, ...opts};\r\n\r\n let objects = this.raycaster.intersectObjects(\r\n targets, options.recursive);\r\n\r\n if (options.minDistance) {\r\n objects = objects.filter(item => {\r\n return item.distance > options.minDistance;\r\n });\r\n }\r\n\r\n if (options.sortByRay) {\r\n objects.sort(function(a, b) {\r\n return a.distanceToRay - b.distanceToRay;\r\n });\r\n }\r\n\r\n return objects;\r\n }\r\n\r\n vectorFromEvent(event) {\r\n let uv = eventToPixel(event);\r\n uv.x = 2 * (uv.x / this.width) - 1;\r\n uv.y = 1 - 2 * (uv.y / this.height);\r\n uv.z = 0.5;\r\n\r\n let direction = this.raycastDirection(uv);\r\n return direction;\r\n }\r\n\r\n raycastDirection(vec) {\r\n vec.unproject(this.camera);\r\n vec.sub(this.camera.position).normalize();\r\n return vec;\r\n }\r\n\r\n defaultRaycaster(direction) {\r\n if (!direction) {\r\n return false;\r\n }\r\n\r\n let raycaster = new Raycaster();\r\n let origin = this.camera.position;\r\n raycaster.set(origin, direction);\r\n this.initialized = true;\r\n return raycaster;\r\n }\r\n}\r\n","import { CustomMouseEvent } from \"../controls\";\r\nimport { ChangeDetector, getPointScale, toScreenPosition } from '../utilities';\r\nimport earcut from 'earcut';\r\nimport {\r\n BufferGeometry,\r\n Color,\r\n DoubleSide,\r\n Line,\r\n LineBasicMaterial,\r\n LineDashedMaterial,\r\n MathUtils,\r\n Mesh,\r\n MeshBasicMaterial,\r\n Scene,\r\n SphereGeometry,\r\n Triangle,\r\n Vector3\r\n} from \"three\";\r\nimport {\r\n pointInPolygon,\r\n checkValidPolygon\r\n} from \"../utilities\";\r\nimport {\r\n CameraImage,\r\n CameraLoadOptions,\r\n directionToCameraAngle,\r\n ImagePixel,\r\n PanoramicImage,\r\n PlanarImage\r\n} from \"../cameras\";\r\nimport {\r\n annotationFromPolygon,\r\n CocoImage,\r\n ImageLabel,\r\n ImageLabelTools,\r\n LabelCategory,\r\n sectionsFromIntersection,\r\n textToColor\r\n} from \".\";\r\nimport {\r\n polygon as turfPolygon,\r\n point as turfPoint\r\n} from '@turf/helpers';\r\nimport {default as turfIntersect} from '@turf/intersect';\r\nimport booleanContains from \"@turf/boolean-contains\";\r\nimport { Viewer } from \"../main\";\r\nimport { LabelContextData, showContextMenu } from \"../../../context-menu\";\r\nimport { clearViewerTooltip, setViewerTooltip } from \"../../viewer\";\r\nimport { RayCaster } from \"../ray-caster\";\r\nimport { t } from \"../../../localization\";\r\n\r\nclass LabelPoint extends Mesh {\r\n public coordinate: Coordinate;\r\n public label: SceneLabel;\r\n public index;\r\n\r\n constructor(geometry, material, coordinate, label, index) {\r\n super(geometry, material);\r\n this.coordinate = coordinate;\r\n this.label = label;\r\n this.index = index;\r\n }\r\n}\r\n\r\nclass LabelPolygon extends Mesh {\r\n public label: SceneLabel;\r\n\r\n constructor(geometry, material, label) {\r\n super(geometry, material);\r\n this.label = label;\r\n }\r\n}\r\n\r\nclass Coordinate {\r\n private camera: CameraImage;\r\n public pixel: ImagePixel;\r\n public _direction: Vector3;\r\n public _position: Vector3;\r\n\r\n constructor(pixel, camera) {\r\n this.camera = camera;\r\n this.updateValues(pixel);\r\n }\r\n\r\n updateValues(pixel) {\r\n this.pixel = pixel;\r\n\r\n // Reset direction/position values\r\n this._direction = null;\r\n this._position = null;\r\n }\r\n\r\n get direction() {\r\n if (this._direction === null) {\r\n this._direction = this.camera\r\n .pixelToDirection(this.pixel);\r\n }\r\n\r\n return this._direction;\r\n }\r\n\r\n get position() {\r\n if (this._position === null) {\r\n let cameraPos = this.camera.position.viewer;\r\n this._position = new Vector3()\r\n .copy(this.direction)\r\n .multiplyScalar(100)\r\n .add(cameraPos);\r\n }\r\n\r\n return this._position;\r\n }\r\n}\r\n\r\nclass SceneLabel extends ImageLabel {\r\n public camera: CameraImage;\r\n public category: SceneCategory\r\n public _imageWidth = null;\r\n public _imageHeight = null;\r\n public coordinates: Coordinate[] = [];\r\n public minCoordinates = 3;\r\n private standardMeshes = [];\r\n private opacityMeshes = [];\r\n private sphereGeometry = new SphereGeometry(0.05, 20, 20);\r\n private sphereMaterial: MeshBasicMaterial;\r\n private lineGeometry: BufferGeometry;\r\n private lineMaterial: LineBasicMaterial;\r\n private lineDashedMaterial: LineDashedMaterial;\r\n private polygonMaterial: MeshBasicMaterial;\r\n private minPoleAngle = 25;\r\n\r\n constructor(category: SceneCategory, camera: CameraImage) {\r\n super();\r\n this.category = category;\r\n\r\n this.lineGeometry = new BufferGeometry();\r\n this.updateMaterials();\r\n this.setCamera(camera);\r\n }\r\n\r\n get hasEnoughPoints() {\r\n return this.numPoints >= this.minCoordinates;\r\n }\r\n\r\n get numPoints() {\r\n return this.coordinates.length;\r\n }\r\n\r\n get coords() {\r\n /** Used for polygon simplification */\r\n return this.coordinates.map(x => [x.pixel.u, x.pixel.v]);\r\n }\r\n\r\n get positions() {\r\n return this.coordinates.map(x => x.position);\r\n }\r\n\r\n get directions() {\r\n return this.coordinates.map(x => x.direction);\r\n }\r\n\r\n get pixels() {\r\n return this.coordinates.map(x => x.pixel);\r\n }\r\n\r\n get viewer() : Viewer {\r\n return this.category.sceneLabels.viewer;\r\n }\r\n\r\n get standardScene() {\r\n return this.category.sceneLabels.standardScene;\r\n }\r\n\r\n get opacityScene() {\r\n return this.category.sceneLabels.opacityScene;\r\n }\r\n\r\n get standardColor() {\r\n return this.category.color(this.highlighted);\r\n }\r\n\r\n get darkenedColor() {\r\n let dark = new Color()\r\n .copy(this.category.color(this.highlighted))\r\n .multiplyScalar(0.75);\r\n\r\n return dark;\r\n }\r\n\r\n get imageWidth() {\r\n return this._imageWidth\r\n ? this._imageWidth\r\n : this.camera.imageWidth;\r\n }\r\n\r\n get imageHeight() {\r\n return this._imageHeight\r\n ? this._imageHeight\r\n : this.camera.imageHeight;\r\n }\r\n\r\n setCamera(camera) {\r\n this.camera = camera;\r\n }\r\n\r\n setKnownImageSize(width, height) {\r\n this._imageWidth = width;\r\n this._imageHeight = height;\r\n }\r\n\r\n updateMaterials() {\r\n this.dispose();\r\n\r\n this.sphereMaterial = new MeshBasicMaterial({\r\n color: this.standardColor\r\n });\r\n\r\n this.lineMaterial = new LineBasicMaterial({\r\n color: this.darkenedColor\r\n });\r\n\r\n this.lineDashedMaterial = new LineDashedMaterial({\r\n color: this.darkenedColor,\r\n dashSize: 1.5,\r\n gapSize: 2.5,\r\n });\r\n\r\n this.polygonMaterial = new MeshBasicMaterial({\r\n color: this.standardColor,\r\n side: DoubleSide\r\n });\r\n }\r\n\r\n removePoint() {\r\n this.coordinates.pop();\r\n }\r\n\r\n removeSpecificPoint(index) {\r\n this.coordinates.splice(index, 1);\r\n this.highlighted = false;\r\n this.updateMaterials();\r\n this.draw();\r\n }\r\n\r\n setPointScale(mesh) {\r\n const scale = getPointScale(this.viewer.camera, mesh);\r\n mesh.scale.set(scale, scale, scale);\r\n mesh.geometry.computeBoundingSphere();\r\n }\r\n\r\n /** @private */\r\n drawPoints(temporaryPoint) {\r\n let positions = this.positions;\r\n\r\n if (temporaryPoint && !this.completed) {\r\n positions = [...positions, temporaryPoint.position];\r\n }\r\n\r\n positions.forEach((position, index) => {\r\n const coordinate = this.coordinates[index];\r\n const mesh = new LabelPoint(this.sphereGeometry,\r\n this.sphereMaterial, coordinate, this, index);\r\n\r\n mesh.position.copy(position);\r\n\r\n this.standardScene.add(mesh);\r\n this.standardMeshes.push(mesh);\r\n this.setPointScale(mesh);\r\n });\r\n }\r\n\r\n /** @private */\r\n drawLines(temporaryPoint) {\r\n let positions = this.positions;\r\n if (positions.length === 0) {\r\n return;\r\n }\r\n\r\n if (temporaryPoint && !this.completed) {\r\n positions = [...positions, temporaryPoint.position];\r\n }\r\n\r\n let corners = [...positions, positions[0]];\r\n this.lineGeometry.setFromPoints(corners);\r\n this.lineGeometry.computeBoundingSphere();\r\n\r\n let material = this.completed\r\n ? this.lineMaterial\r\n : this.lineDashedMaterial;\r\n\r\n const line = new Line(this.lineGeometry, material);\r\n\r\n if (!this.completed) {\r\n line.computeLineDistances();\r\n }\r\n\r\n this.standardMeshes.push(line);\r\n this.standardScene.add(line);\r\n }\r\n\r\n /** @private */\r\n drawPolygons(temporaryPoint: Coordinate) {\r\n let positions = this.positions;\r\n let directions = this.directions;\r\n let pixels = this.pixels;\r\n\r\n if (temporaryPoint && !this.completed) {\r\n pixels = [...pixels, temporaryPoint.pixel];\r\n positions = [...positions, temporaryPoint.position];\r\n directions = [...directions, temporaryPoint.direction];\r\n }\r\n\r\n if (positions.length < this.minCoordinates) {\r\n return;\r\n }\r\n\r\n let coordinates3d = this.camera instanceof PanoramicImage\r\n ? this.camera.directionsToPlanar(directions)\r\n : pixels.map(x => new Vector3(x.u, x.v, 0.0));\r\n\r\n let oldState = this.valid;\r\n\r\n // Check for valid polygon\r\n let coordinates2d = coordinates3d.map(x => [x.x, x.y]);\r\n this.valid = checkValidPolygon(coordinates2d);\r\n\r\n // Panoramic images arent valid at the poles\r\n if (this.camera instanceof PanoramicImage) {\r\n this.valid = this.valid && !this.polygonAtPoles(directions);\r\n }\r\n\r\n if (this.valid !== oldState) {\r\n this.category.setCategories();\r\n }\r\n\r\n if (!this.valid) {\r\n return;\r\n }\r\n\r\n // Calculate triangle mesh indices\r\n let coordinatesFlat = coordinates2d.flat();\r\n let indices = earcut(coordinatesFlat, null, 2);\r\n\r\n // Deviation must be nearly zero to be valid\r\n let deviation = earcut.deviation(coordinatesFlat, null, 2, indices);\r\n if (deviation > 1E-6) {\r\n return;\r\n }\r\n\r\n let numTriangles = indices.length / 3;\r\n for (var i = 0; i < numTriangles; i++) {\r\n let triangle = new Triangle(\r\n coordinates3d[indices[3 * i]],\r\n coordinates3d[indices[3 * i + 1]],\r\n coordinates3d[indices[3 * i + 2]]\r\n );\r\n\r\n // Remove invalid triangles\r\n let center = new Vector3();\r\n triangle.getMidpoint(center);\r\n let valid = pointInPolygon(center, coordinates3d);\r\n if (!valid) {\r\n continue;\r\n }\r\n\r\n const points = [\r\n positions[indices[3 * i]],\r\n positions[indices[3 * i + 1]],\r\n positions[indices[3 * i + 2]]\r\n ];\r\n\r\n const geometry = new BufferGeometry().setFromPoints(points);\r\n geometry.setIndex([0,1,2]);\r\n\r\n let mesh = new LabelPolygon(geometry, this.polygonMaterial, this);\r\n this.opacityMeshes.push(mesh);\r\n this.opacityScene.add(mesh);\r\n }\r\n }\r\n\r\n draw(temporaryPoint=null) {\r\n this.clear();\r\n\r\n if (!this.drawable) {\r\n return;\r\n }\r\n\r\n if (this.category.currentCamera !== this.camera) {\r\n return;\r\n }\r\n\r\n if (!this.camera || this.camera.missing) {\r\n return;\r\n }\r\n\r\n this.drawPoints(temporaryPoint);\r\n this.drawLines(temporaryPoint);\r\n this.drawPolygons(temporaryPoint);\r\n }\r\n\r\n pointToScreen(point) {\r\n return toScreenPosition(this.viewer, point.position, true);\r\n }\r\n\r\n addPoint(pixel: ImagePixel | [], checkDuplicate=true) {\r\n const newPoint = new Coordinate(pixel, this.camera);\r\n const oldPoint = this.coordinates[this.coordinates.length - 1];\r\n\r\n if (checkDuplicate && this.duplicatePoint(oldPoint, newPoint)) {\r\n return true;\r\n }\r\n\r\n this.coordinates.push(newPoint);\r\n return false;\r\n }\r\n\r\n createCoordData(coordinate) {\r\n const point = new Vector3(coordinate.u, coordinate.v);\r\n const coordArray = this.coordinates.map(coord => {\r\n return [coord.pixel.u, coord.pixel.v];\r\n });\r\n\r\n return {coordArray, point};\r\n }\r\n\r\n insertPoint(newPoint, idxCoord) {\r\n const point = {u: newPoint.x, v: newPoint.y};\r\n const newCoord = new Coordinate(point, this.camera);\r\n this.coordinates.splice(idxCoord+1, 0, newCoord);\r\n this.draw();\r\n }\r\n\r\n polygonAtPoles(coordinates): boolean {\r\n // Check each point to make sure the phi angle is safe\r\n let pointsAtPole = false;\r\n coordinates.forEach(x => {\r\n let phi = MathUtils.radToDeg(Math.acos(x.z));\r\n let minAngle = phi < this.minPoleAngle;\r\n let maxAngle = phi > (180 - this.minPoleAngle);\r\n\r\n pointsAtPole = pointsAtPole || minAngle;\r\n pointsAtPole = pointsAtPole || maxAngle;\r\n });\r\n\r\n if (pointsAtPole) {\r\n return true;\r\n }\r\n\r\n // Check to see if the polygon surrounds the pole\r\n coordinates = coordinates.map(x => [x.x, x.y]);\r\n let polyPointRing = [...coordinates, coordinates[0]];\r\n\r\n return booleanContains(\r\n turfPolygon([polyPointRing]),\r\n turfPoint([0, 0])\r\n );\r\n }\r\n\r\n getCameraBestFit(): CameraLoadOptions {\r\n // Calculate average direction vector\r\n const averageDirection = new Vector3();\r\n this.directions.forEach(x => averageDirection.add(x));\r\n averageDirection.divideScalar(this.directions.length);\r\n\r\n const fovRequired = this.directions.map(direction => {\r\n let angle = direction.angleTo(averageDirection);\r\n return MathUtils.radToDeg(angle) * 2.0;\r\n });\r\n\r\n // Best fit field of view has as small buffer added\r\n const fov = Math.max(...fovRequired) * 1.10;\r\n\r\n // Convert average direction to camera angles\r\n const angles = directionToCameraAngle(averageDirection);\r\n\r\n return {fov, angles};\r\n }\r\n\r\n clear() {\r\n this.standardMeshes.forEach(mesh => {\r\n this.standardScene.remove(mesh);\r\n });\r\n\r\n this.opacityMeshes.forEach(mesh => {\r\n this.opacityScene.remove(mesh);\r\n });\r\n\r\n this.standardMeshes = [];\r\n this.opacityMeshes = [];\r\n }\r\n\r\n destroy() {\r\n this.clear();\r\n this.dispose();\r\n }\r\n\r\n dispose() {\r\n this.standardMeshes.forEach(mesh => {\r\n mesh.geometry.dispose();\r\n mesh.material.dispose();\r\n });\r\n\r\n this.opacityMeshes.forEach(mesh => {\r\n mesh.geometry.dispose();\r\n mesh.material.dispose();\r\n });\r\n }\r\n\r\n zoom(): Promise {\r\n // The camera must be loaded before we are able to calculate the\r\n // direction and zoom, so we load the camera before calculating\r\n\r\n return new Promise(async (resolve) => {\r\n const cameraID = this.camera.id;\r\n let currentCamera = this.viewer.getCurrentCamera();\r\n\r\n let camera = currentCamera.id !== cameraID\r\n ? await this.viewer.loadImage(cameraID)\r\n : currentCamera;\r\n\r\n if (camera.missing) {\r\n resolve(false);\r\n } else {\r\n let opts = this.getCameraBestFit();\r\n this.viewer.loadImage(cameraID, opts);\r\n resolve(true);\r\n }\r\n });\r\n }\r\n\r\n setHighlighted(highlight) {\r\n if (highlight === this.highlighted) {\r\n return;\r\n }\r\n\r\n this.highlighted = highlight;\r\n this.updateMaterials();\r\n this.draw();\r\n }\r\n}\r\n\r\nclass SceneCategory extends LabelCategory {\r\n public sceneLabels: SceneLabelTools;\r\n public labels: SceneLabel[] = [];\r\n\r\n constructor(sceneLabels, name) {\r\n super(name);\r\n this.sceneLabels = sceneLabels;\r\n }\r\n\r\n get currentCamera() {\r\n return this.sceneLabels.currentCamera;\r\n }\r\n\r\n color(highlight=false) : Color {\r\n let color = `rgba(${Math.ceil(255)}, ${Math.ceil(255)}, ${Math.ceil(255)})`;\r\n if (!highlight) {\r\n color = textToColor(this.name);\r\n }\r\n return new Color(color);\r\n }\r\n\r\n setCategories() {\r\n this.sceneLabels.imageLabelTools.setCategories();\r\n }\r\n\r\n updateColor() {\r\n this.labels.forEach(label => {\r\n label.updateMaterials();\r\n });\r\n\r\n this.sceneLabels.drawAll();\r\n }\r\n\r\n addNewLabel(drawLabel) {\r\n let label = new SceneLabel(this, this.currentCamera);\r\n label.setDrawable(drawLabel);\r\n this.labels.push(label);\r\n\r\n return label;\r\n }\r\n\r\n deleteUnfinishedLabel() {\r\n let numberOfLabels = this.labels.length;\r\n if (numberOfLabels === 0) {\r\n return;\r\n }\r\n\r\n if (!this.labels[numberOfLabels - 1].completed) {\r\n this.labels.pop();\r\n }\r\n }\r\n}\r\n\r\nexport class SceneLabelTools {\r\n public type = \"scene\";\r\n public imageLabelTools: ImageLabelTools;\r\n public standardScene: Scene;\r\n public opacityScene: Scene;\r\n public enabled = false;\r\n public opacity = 0.2;\r\n private temporaryPoint: Coordinate;\r\n public draggable = false;\r\n private polygonHover: LabelPolygon = null;\r\n private pointHover: LabelPoint = null;\r\n\r\n constructor(imageLabelTools: ImageLabelTools) {\r\n this.imageLabelTools = imageLabelTools;\r\n this.standardScene = new Scene();\r\n this.opacityScene = new Scene();\r\n\r\n window.addEventListener('keydown', event => {\r\n this.onKeyDown(event);\r\n }, false);\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-start-drawing-polygon')\r\n ];\r\n }\r\n\r\n get dragTooltip() {\r\n return [\r\n t('measure.click-and-hold-to-move-vertex'),\r\n t('measure.right-click-to-select-point')\r\n ];\r\n }\r\n\r\n get highlightTooltip() {\r\n return [\r\n t('measure.right-click-to-select-label'),\r\n t('measure.ctrl-right-click-to-select-multiple-labels')\r\n ];\r\n }\r\n\r\n get categories() {\r\n return this.imageLabelTools.categories\r\n .filter(x => x instanceof SceneCategory) as SceneCategory[];\r\n }\r\n\r\n get viewer() {\r\n return this.imageLabelTools.viewer;\r\n }\r\n\r\n get cameraList() {\r\n return this.viewer.cameraList;\r\n }\r\n\r\n get currentCamera() {\r\n let current = this.cameraList.current;\r\n if (this.viewer.orbitState || !current) {\r\n return null;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n get drawing() {\r\n let label = this.activeLabel;\r\n if (!label || label.completed) {\r\n return false;\r\n }\r\n\r\n if (label.coordinates.length === 0) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n get activeLabel() {\r\n let selected = null;\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n if (label.selected) {\r\n selected = label;\r\n }\r\n });\r\n });\r\n\r\n return selected;\r\n }\r\n\r\n get moreTooltip() {\r\n return [\r\n t(\"labels.click-to-add-more-points\", {\r\n count: this.numPoints\r\n }),\r\n t('labels.delete-key-to-remove-last-point'),\r\n ...(this.numPoints > 1) ? [t('labels.double-click-to-finish')] : [],\r\n ...(this.numPoints > 2) ? [t('labels.press-enter-to-exit')] : [],\r\n ...this.activeLabel.editing ? [] : [t('labels.right-click-to-cancel')]\r\n ];\r\n }\r\n\r\n get invalidTooltip() {\r\n const isPanoramic = this.activeLabel.camera instanceof PanoramicImage;\r\n\r\n const errorMessage = isPanoramic\r\n ? t('labels.polygon-is-invalid-due-to-self-intersection-or-closeness-to-poles')\r\n : t('labels.polygon-is-invalid-due-to-self-intersection');\r\n\r\n return [\r\n errorMessage,\r\n ...this.moreTooltip\r\n ];\r\n }\r\n\r\n get numPoints() {\r\n return this.activeLabel.numPoints;\r\n }\r\n\r\n get visibleCameras() {\r\n let visited = new Set();\r\n let cameras = [];\r\n\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n if (!label.valid) {\r\n return;\r\n }\r\n\r\n let camera = label.camera;\r\n let cameraID = camera.id;\r\n\r\n if (visited.has(cameraID)) {\r\n return;\r\n }\r\n\r\n visited.add(cameraID);\r\n cameras.push(camera);\r\n });\r\n });\r\n\r\n return cameras;\r\n }\r\n\r\n get activeImagePaths() {\r\n return this.visibleCameras.map(image => image.path);\r\n }\r\n\r\n get activeImages() {\r\n return this.visibleCameras;\r\n }\r\n\r\n get loadedImagePaths() {\r\n let imageList = this.viewer.cameraList;\r\n return imageList.cameras.map(image => image.path);\r\n }\r\n\r\n setState(state) {\r\n this.enabled = state;\r\n clearViewerTooltip();\r\n }\r\n\r\n getNewCategory(name) {\r\n return new SceneCategory(this, name);\r\n }\r\n\r\n getClickedDirection(event) {\r\n const raycaster = new RayCaster(this.viewer, event);\r\n const direction = raycaster.vectorFromEvent(event);\r\n return direction;\r\n }\r\n\r\n getImagePixel(event): ImagePixel {\r\n const direction = this.getClickedDirection(event);\r\n return this.currentCamera.directionToPixel(direction);\r\n }\r\n\r\n deletePoint() {\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label => {\r\n if (label.selected) {\r\n label.removePoint();\r\n this.setToolTipText();\r\n }\r\n })\r\n );\r\n\r\n this.imageLabelTools.setCategories();\r\n }\r\n\r\n deleteSpecificPoint(id) {\r\n this.categories.forEach(category =>\r\n category.labels.forEach(label => {\r\n\r\n if (label.highlighted && label.hasEnoughPoints) {\r\n label.removeSpecificPoint(id);\r\n this.imageLabelTools.unHighlight(label.id);\r\n }\r\n })\r\n );\r\n this.imageLabelTools.setCategories();\r\n }\r\n\r\n highlightLabel() {\r\n let selected = null;\r\n\r\n if (this.pointHover) {\r\n selected = this.pointHover;\r\n } else if (this.polygonHover) {\r\n selected = this.polygonHover;\r\n } else {\r\n return;\r\n }\r\n\r\n let label = selected.label;\r\n label.setHighlighted(!label.highlighted);\r\n this.imageLabelTools.setCategories();\r\n\r\n return selected;\r\n }\r\n\r\n mouseClick(event) {\r\n if (!this.currentCamera) return;\r\n\r\n let label = this.activeLabel;\r\n if (!label) return;\r\n\r\n let point = this.getImagePixel(event);\r\n if (!point) return;\r\n\r\n let duplicatePoint = label.addPoint(point);\r\n if (duplicatePoint && label.hasEnoughPoints) {\r\n this.completeLabel(label);\r\n return;\r\n }\r\n\r\n this.setToolTipText();\r\n this.resetTemporaryPoint();\r\n this.drawAll();\r\n }\r\n\r\n completeLabel(label) {\r\n this.resetTemporaryPoint();\r\n this.imageLabelTools.completeLabel(label.id);\r\n this.markLastPointDraggable(label);\r\n }\r\n\r\n markLastPointDraggable(label) {\r\n let labelPoints = label.standardMeshes\r\n .filter(x => x instanceof LabelPoint);\r\n\r\n let lastPoint = labelPoints[labelPoints.length - 1];\r\n this.setPointHover(lastPoint);\r\n }\r\n\r\n cancelLabel() {\r\n if (this.activeLabel && !this.activeLabel.editing) {\r\n this.imageLabelTools.deleteLabel(this.activeLabel.id);\r\n this.setToolTipText();\r\n this.drawAll();\r\n }\r\n }\r\n\r\n checkFeatureHover(event) {\r\n if (this.drawing) {\r\n this.setPolygonHover(false);\r\n return;\r\n }\r\n\r\n let targetPoly = this.opacityScene.children\r\n .filter(x => (x instanceof LabelPolygon));\r\n\r\n let targets = this.standardScene.children\r\n .filter(x => x instanceof LabelPoint);\r\n\r\n targets = targets.concat(targetPoly);\r\n\r\n let selectedPoint = null;\r\n let selectedPolygon = null;\r\n\r\n if (targets.length > 0) {\r\n let raycaster = new RayCaster(this.viewer, event);\r\n let objects = raycaster.intersectObjects(targets);\r\n objects = objects.map(x => x.object);\r\n\r\n let polygons = objects\r\n .filter(x => x instanceof LabelPolygon);\r\n\r\n let points = objects\r\n .filter(x => x instanceof LabelPoint);\r\n\r\n selectedPoint = (points.length > 0)\r\n ? points[0]\r\n : null;\r\n\r\n selectedPolygon = (polygons.length > 0)\r\n ? polygons[0]\r\n : null;\r\n }\r\n\r\n this.setPolygonHover(selectedPolygon);\r\n this.setPointHover(selectedPoint);\r\n }\r\n\r\n updateDraggablePoint(event) {\r\n let coordinate = this.pointHover.coordinate;\r\n let point = this.getImagePixel(event);\r\n if (!point) return;\r\n\r\n coordinate.updateValues(point);\r\n this.drawAll();\r\n\r\n const {label} = this.pointHover;\r\n if (label.score < 1.0) {\r\n label.setScore(1.0);\r\n this.imageLabelTools.setCategories();\r\n }\r\n }\r\n\r\n setPointHover(feature) {\r\n this.pointHover = feature;\r\n\r\n if (feature) {\r\n this.setPointGrabTooltip();\r\n }\r\n }\r\n\r\n setPolygonHover(feature) {\r\n this.polygonHover = feature;\r\n }\r\n\r\n setToolTipText() {\r\n if (!this.activeLabel) {\r\n clearViewerTooltip();\r\n return;\r\n }\r\n\r\n if (this.drawing) {\r\n let tooltipText = this.activeLabel.valid\r\n ? this.moreTooltip\r\n : this.invalidTooltip;\r\n\r\n setViewerTooltip(tooltipText);\r\n } else if (this.currentCamera) {\r\n setViewerTooltip(this.startTooltip);\r\n } else {\r\n clearViewerTooltip();\r\n }\r\n }\r\n\r\n setPointGrabTooltip() {\r\n setViewerTooltip(this.dragTooltip);\r\n }\r\n\r\n setPolygonHoverTooltip() {\r\n setViewerTooltip(this.highlightTooltip);\r\n }\r\n\r\n resetTemporaryPoint() {\r\n this.temporaryPoint = null;\r\n }\r\n\r\n openContextMenu(event, feature) {\r\n let point = this.getImagePixel(event);\r\n let pointID = (feature instanceof LabelPoint) ? feature.index : null;\r\n let labelID = feature.label.id;\r\n\r\n const labelData = {\r\n coordinate: point,\r\n pointID,\r\n labelID\r\n } as LabelContextData;\r\n\r\n showContextMenu(event, {\r\n labelData\r\n });\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (event.mouseMoved || !this.enabled) {\r\n return false;\r\n }\r\n\r\n if (event.isLeftClick) {\r\n this.mouseClick(event);\r\n return true;\r\n } else if (event.isRightClick) {\r\n if (this.drawing) {\r\n this.cancelLabel();\r\n return true;\r\n }\r\n\r\n return this.onRightClick(event);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onRightClick(event) {\r\n const oneHighlighted = this.imageLabelTools.oneHighlighted;\r\n const noneHighlighted = this.imageLabelTools.noneHighlighted;\r\n\r\n if (noneHighlighted && !event.ctrlKey) {\r\n let feature = this.highlightLabel();\r\n if (feature) {\r\n this.openContextMenu(event, feature);\r\n return true;\r\n }\r\n }\r\n\r\n if (oneHighlighted && !event.ctrlKey) {\r\n this.imageLabelTools.unHighlightAll();\r\n let feature = this.highlightLabel();\r\n if (feature) {\r\n this.openContextMenu(event, feature);\r\n return true;\r\n }\r\n }\r\n\r\n if (event.ctrlKey) {\r\n this.highlightLabel();\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onMouseMove(event: CustomMouseEvent) {\r\n this.resetTemporaryPoint();\r\n\r\n if (!this.enabled) return false;\r\n\r\n if (!event.mouseMoved && !event.mouseDown) {\r\n this.checkFeatureHover(event);\r\n }\r\n\r\n if (this.drawing) {\r\n let point = this.getImagePixel(event);\r\n if (!point) return false;\r\n\r\n this.temporaryPoint = new Coordinate(point,\r\n this.currentCamera);\r\n\r\n this.drawAll();\r\n }\r\n\r\n if (this.pointHover) {\r\n this.setPointGrabTooltip();\r\n\r\n if (event.mouseDown) {\r\n if (event.isLeftClick) {\r\n this.updateDraggablePoint(event);\r\n }\r\n return true;\r\n }\r\n } else if (this.polygonHover) {\r\n this.setPolygonHoverTooltip();\r\n } else {\r\n this.setToolTipText();\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onKeyDown(event) {\r\n if (event.which === 13) {\r\n let label = this.activeLabel;\r\n if (!label) {\r\n return;\r\n }\r\n\r\n if (label.selected){\r\n this.imageLabelTools.completeLabel(label.id);\r\n }\r\n }\r\n }\r\n\r\n drawAll() {\r\n this.standardScene.clear();\r\n this.opacityScene.clear();\r\n\r\n if (this.viewer.orbitState) {\r\n return;\r\n }\r\n\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n label.draw(this.temporaryPoint);\r\n });\r\n });\r\n }\r\n\r\n /** @private */\r\n calculatePlanarSections(polyPointRing, imageWidth, imageHeight) {\r\n let sections = [];\r\n\r\n let imageBorders = [\r\n [0, 0],\r\n [0, imageHeight-1],\r\n [imageWidth-1, imageHeight-1],\r\n [imageWidth-1, 0],\r\n [0, 0]\r\n ];\r\n\r\n let intersection = turfIntersect(\r\n turfPolygon([polyPointRing]),\r\n turfPolygon([imageBorders]),\r\n );\r\n\r\n let intersectionData = sectionsFromIntersection(intersection);\r\n intersectionData.forEach((arr) => {\r\n sections.push(arr);\r\n });\r\n\r\n return sections;\r\n }\r\n\r\n /** @private */\r\n calculatePanoramicSections(polyPointRing, image: PanoramicImage, imageWidth, imageHeight) {\r\n let sections = [];\r\n let horizontalShift = this.getHorizontalShift(polyPointRing, imageWidth);\r\n\r\n // Add horizontal shift\r\n polyPointRing = polyPointRing.map(x=> {\r\n return [(x[0] + horizontalShift) % imageWidth, x[1]];\r\n });\r\n\r\n // Interpolate pixels for smooth curve in pixel space\r\n polyPointRing = image.interpolatePixels(\r\n polyPointRing, imageWidth, imageHeight);\r\n\r\n const polygon = turfPolygon([polyPointRing]);\r\n\r\n if (horizontalShift === 0) {\r\n // No shift is required, which means the entire polygon is\r\n // inside the bounds of the image and no intersects are required\r\n const geometry = polygon.geometry;\r\n const coordinates = [...geometry.coordinates[0]];\r\n coordinates.pop();\r\n return [coordinates];\r\n }\r\n\r\n let imageBordersLeft = [\r\n [-9999, 0],\r\n [-9999, imageHeight],\r\n [horizontalShift-0.05, imageHeight],\r\n [horizontalShift-0.05, 0],\r\n [-9999, 0]\r\n ];\r\n\r\n let imageBordersRight = [\r\n [horizontalShift, 0],\r\n [horizontalShift, imageHeight],\r\n [9999, imageHeight],\r\n [9999, 0],\r\n [horizontalShift, 0]\r\n ];\r\n\r\n const polygonLeft = turfPolygon([imageBordersLeft]);\r\n const polygonRight = turfPolygon([imageBordersRight]);\r\n\r\n const intersectionLeft = turfIntersect(polygon, polygonLeft);\r\n const intersectionRight = turfIntersect(polygon, polygonRight);\r\n\r\n sectionsFromIntersection(intersectionLeft).forEach(arr => {\r\n sections.push(arr);\r\n });\r\n\r\n sectionsFromIntersection(intersectionRight).forEach(arr => {\r\n sections.push(arr);\r\n });\r\n\r\n // Subtract shift from sections\r\n sections = sections.map(points => {\r\n return points.map(point => {\r\n let y = point[1];\r\n let x = point[0] - horizontalShift;\r\n x = (x + imageWidth) % imageWidth;\r\n\r\n return [x, y];\r\n });\r\n });\r\n\r\n return sections;\r\n }\r\n\r\n /** @private */\r\n getHorizontalShift(polyPointRing, imageWidth) {\r\n let minSpread = Infinity;\r\n let widthCutoff = imageWidth / 4.0;\r\n let horizontalShift = 0;\r\n\r\n let increment = Math.ceil(imageWidth/20);\r\n let xValues = polyPointRing.map(point => point[0]);\r\n let minX = Math.min(...xValues);\r\n let maxX = Math.max(...xValues);\r\n let spread = Math.abs(minX - maxX);\r\n\r\n // Polygon must be good, return immediately\r\n if (spread < widthCutoff) {\r\n return 0;\r\n }\r\n\r\n for (var i=0; i [x.u, x.v]);\r\n let polyPointRing = [...coordinates, coordinates[0]];\r\n\r\n if (image instanceof PlanarImage) {\r\n sections = this.calculatePlanarSections(\r\n polyPointRing, imageWidth, imageHeight);\r\n } else if (image instanceof PanoramicImage) {\r\n sections = this.calculatePanoramicSections(\r\n polyPointRing, image, imageWidth, imageHeight);\r\n }\r\n\r\n return sections;\r\n }\r\n\r\n pointsToPixels(points): ImagePixel[] {\r\n return points.map(x => {\r\n return {u: x[0], v: x[1]} as ImagePixel;\r\n });\r\n }\r\n\r\n getCameraSize(image) {\r\n let width = 0;\r\n let height = 0;\r\n\r\n this.categories.forEach(category => {\r\n category.labels.forEach(label => {\r\n if (label.camera === image) {\r\n width = label.imageWidth;\r\n height = label.imageHeight;\r\n }\r\n });\r\n });\r\n\r\n return {width, height};\r\n }\r\n\r\n jsonImageObj() {\r\n let images = this.visibleCameras.map((image, imageIndex) => {\r\n const {width, height} = this.getCameraSize(image);\r\n return {\r\n height: height,\r\n width: width,\r\n id: imageIndex,\r\n file_name: image.name,\r\n } as CocoImage;\r\n });\r\n\r\n return images;\r\n }\r\n\r\n getTrainingAnnotations() {\r\n return [];\r\n }\r\n\r\n getLabelAnnotations() {\r\n let labelIndex = 1;\r\n let mergeIndex = 1;\r\n let annotations = [];\r\n\r\n const visibleCameras = this.visibleCameras;\r\n\r\n this.categories.forEach((category, categoryID) => {\r\n category.labels.forEach(label => {\r\n if (!label.valid) return;\r\n\r\n const imageID = visibleCameras.indexOf(label.camera);\r\n const polygonsInside = this.polygonInImage(label);\r\n const mergeable = polygonsInside.length > 1;\r\n\r\n polygonsInside.forEach((polygon, index) => {\r\n let annotation = annotationFromPolygon(\r\n polygon,\r\n labelIndex,\r\n categoryID,\r\n imageID,\r\n mergeable ? mergeIndex : null,\r\n label.score,\r\n label.text,\r\n label.textScore,\r\n label.findText\r\n );\r\n\r\n annotations.push(annotation);\r\n labelIndex++;\r\n });\r\n\r\n if (mergeable) {\r\n mergeIndex++;\r\n }\r\n });\r\n });\r\n\r\n return annotations;\r\n }\r\n\r\n setPointScale(mesh) {\r\n const scale = getPointScale(this.viewer.camera, mesh);\r\n mesh.scale.set(scale, scale, scale);\r\n mesh.geometry.computeBoundingSphere();\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n if (!changeDetector.changed) return;\r\n\r\n if (changeDetector.cameraChanged || changeDetector.orbitChanged) {\r\n this.categories.forEach(category => {\r\n // Remove incomplete observation if camera changed\r\n category.deleteUnfinishedLabel();\r\n this.resetTemporaryPoint();\r\n });\r\n\r\n this.drawAll();\r\n return;\r\n }\r\n\r\n this.standardScene.children.forEach(mesh => {\r\n if (mesh instanceof LabelPoint) {\r\n this.setPointScale(mesh);\r\n }\r\n });\r\n }\r\n}\r\n\r\n","import { Viewer } from \"../main\";\r\nimport { RayCaster } from \"../ray-caster\";\r\nimport { getPointScale } from \"../utilities\";\r\nimport {\r\n Box3,\r\n BoxGeometry,\r\n BufferGeometry,\r\n Color,\r\n DoubleSide,\r\n EdgesGeometry,\r\n Euler,\r\n Group,\r\n Line,\r\n Line3,\r\n LineBasicMaterial,\r\n LineSegments,\r\n Matrix4,\r\n Mesh,\r\n MeshBasicMaterial,\r\n Plane,\r\n PlaneGeometry,\r\n SphereGeometry,\r\n Vector3\r\n} from \"three\";\r\nimport LocalScene, { SceneCoordinate } from \"../projections\";\r\n\r\nexport class ScaleHandle extends Mesh {\r\n private clippingBox: ClippingBox;\r\n\r\n constructor(clippingBox: ClippingBox, opts) {\r\n const geometry = new PlaneGeometry(1, 1);\r\n const material = new MeshBasicMaterial({\r\n color: opts.color,\r\n side: DoubleSide,\r\n opacity: 0.6,\r\n transparent: true\r\n });\r\n\r\n super(geometry, material);\r\n\r\n this.clippingBox = clippingBox;\r\n this.position.copy(opts.position);\r\n this.lookAt(new Vector3(0,0,0));\r\n this.scale.set(2.0, 2.0, 2.0);\r\n this.visible = false;\r\n }\r\n\r\n get viewer() {\r\n return this.clippingBox.viewer;\r\n }\r\n\r\n set highlighted(state) {\r\n this.visible = state;\r\n }\r\n\r\n drag(event, point) {\r\n const raycaster = new RayCaster(this.viewer, event);\r\n const camera = raycaster.camera;\r\n\r\n // Opposite cube face\r\n const minusPoint = new Vector3()\r\n .add(this.position)\r\n .multiplyScalar(-1.0)\r\n .applyMatrix4(this.parent.matrix);\r\n\r\n const lineStart = new Vector3()\r\n .copy(this.parent.position);\r\n\r\n const lineEnd = new Vector3()\r\n .add(this.position)\r\n .applyMatrix4(this.parent.matrix);\r\n\r\n const line = new Line3(lineStart, lineEnd);\r\n\r\n const camOnLine = new Vector3();\r\n line.closestPointToPoint(camera.position, false, camOnLine);\r\n\r\n // Normal from camera to line\r\n const normal = new Vector3()\r\n .add(camera.position)\r\n .sub(camOnLine);\r\n\r\n // Position in direction of plane\r\n const plane = new Plane();\r\n plane.setFromNormalAndCoplanarPoint(normal, point);\r\n const intersect = raycaster.intersectPlane(plane);\r\n\r\n const intersectOnLine = new Vector3();\r\n line.closestPointToPoint(intersect, false, intersectOnLine);\r\n\r\n // New midpoint\r\n const midpoint = new Vector3()\r\n .add(intersectOnLine)\r\n .add(minusPoint)\r\n .divideScalar(2.0);\r\n\r\n // Stop movement when the cube would become negative width\r\n const axis = new Line3(minusPoint, lineEnd);\r\n const valid = axis.closestPointToPointParameter(midpoint, false) > 0;\r\n if (!valid) return;\r\n\r\n // Update scale\r\n const distance = intersectOnLine.distanceTo(minusPoint);\r\n this.setScale(distance/2.0);\r\n\r\n // Set new position\r\n this.parent.position.copy(midpoint);\r\n }\r\n\r\n setScale(newScale) {\r\n if (this.position.x !== 0) {\r\n this.parent.scale.x = newScale;\r\n }\r\n\r\n if (this.position.y !== 0) {\r\n this.parent.scale.y = newScale;\r\n }\r\n\r\n if (this.position.z !== 0) {\r\n this.parent.scale.z = newScale;\r\n }\r\n }\r\n}\r\n\r\nexport class RotateHandle extends Mesh {\r\n public highlighted\r\n private clippingBox: ClippingBox;\r\n private normal: Vector3;\r\n private ordering;\r\n\r\n constructor(clippingBox: ClippingBox,opts) {\r\n const geometry = new SphereGeometry(0.1, 32, 32);\r\n const material = new MeshBasicMaterial({\r\n color: opts.color\r\n });\r\n\r\n super(geometry, material);\r\n\r\n this.clippingBox = clippingBox;\r\n this.normal = opts.normal;\r\n this.ordering = opts.ordering;\r\n this.position.copy(opts.position);\r\n }\r\n\r\n get viewer() {\r\n return this.clippingBox.viewer;\r\n }\r\n\r\n drag(event, point) {\r\n const raycaster = new RayCaster(this.viewer, event);\r\n\r\n const zAxis = new Vector3()\r\n .copy(this.normal)\r\n .applyQuaternion(this.parent.quaternion);\r\n\r\n const plane = new Plane();\r\n plane.setFromNormalAndCoplanarPoint(zAxis, this.parent.position);\r\n\r\n const intersect = raycaster.intersectPlane(plane);\r\n const projected = new Vector3();\r\n plane.projectPoint(intersect, projected);\r\n\r\n const xAxis = new Vector3()\r\n .copy(projected)\r\n .sub(this.parent.position)\r\n .setLength(1.0);\r\n\r\n const yAxis = new Vector3()\r\n .copy(zAxis)\r\n .cross(xAxis);\r\n\r\n const newAxis = [xAxis, yAxis, zAxis];\r\n const matrix = new Matrix4().makeBasis(\r\n newAxis[this.ordering[0]],\r\n newAxis[this.ordering[1]],\r\n newAxis[this.ordering[2]]\r\n );\r\n\r\n const rotation = new Euler().setFromRotationMatrix(matrix);\r\n this.parent.rotation.copy(rotation);\r\n }\r\n}\r\n\r\nexport class PositionHandle extends Mesh {\r\n public highlighted;\r\n private clippingBox: ClippingBox;\r\n\r\n constructor(clippingBox: ClippingBox) {\r\n const geometry = new SphereGeometry(0.1, 32, 32);\r\n const material = new MeshBasicMaterial({\r\n color: 0xFFFF00\r\n });\r\n\r\n super(geometry, material);\r\n\r\n this.clippingBox = clippingBox;\r\n this.highlighted = false;\r\n }\r\n\r\n get viewer() {\r\n return this.clippingBox.viewer;\r\n }\r\n\r\n get controls() {\r\n return this.viewer.controls;\r\n }\r\n\r\n drag(event, point) {\r\n let {coordinate} = this.controls.getPickerResults(event);\r\n if (!coordinate) return;\r\n\r\n this.clippingBox.position.copy(coordinate);\r\n }\r\n}\r\n\r\nexport class ClippingBox extends Group {\r\n public viewer: Viewer;\r\n private wireframe: LineSegments\r\n private positionHandle: PositionHandle;\r\n private scaleHandles: ScaleHandle[] = [];\r\n private rotateHandles: RotateHandle[] = [];\r\n private wireframeMaterialStandard = new MeshBasicMaterial({color: 0xFFFF00});\r\n private wireframeMaterialHover = new MeshBasicMaterial({color: 0xFFFFFF});\r\n\r\n public operationID = null;\r\n public hidePoints = false;\r\n public updateClassification = false;\r\n public newClassification = 0;\r\n public ignoredClassification = 2;\r\n\r\n constructor(viewer: Viewer, operationID=null) {\r\n super();\r\n\r\n this.viewer = viewer;\r\n this.operationID = operationID;\r\n\r\n this.addWireframe();\r\n this.addScaleHandles();\r\n this.addRotateHandles();\r\n this.addPositionHandle();\r\n }\r\n\r\n get boundingBox() {\r\n const bbox = new Box3()\r\n .setFromObject(this.wireframe);\r\n\r\n return bbox;\r\n }\r\n\r\n get attributes() {\r\n const position = new SceneCoordinate(this.position)\r\n .toDataProjection()\r\n .toArray();\r\n\r\n const rotation = this.rotation\r\n .toArray()\r\n .slice(0,3);\r\n\r\n // Convert scalar to projection units\r\n const dataScale = new Vector3()\r\n .copy(this.scale)\r\n .divideScalar(LocalScene.dataToMeters)\r\n .toArray();\r\n\r\n return {\r\n position,\r\n rotation,\r\n scale: dataScale,\r\n hidePoints: this.hidePoints,\r\n updateClassification: this.updateClassification,\r\n newClassification: this.newClassification,\r\n ignoredClassification: this.ignoredClassification\r\n };\r\n }\r\n\r\n setHover(hover) {\r\n const wireframeMaterial = hover\r\n ? this.wireframeMaterialHover\r\n : this.wireframeMaterialStandard;\r\n\r\n this.wireframe.material = wireframeMaterial;\r\n this.wireframe.material.needsUpdate = true;\r\n }\r\n\r\n setColor(color) {\r\n this.wireframeMaterialStandard.color = new Color(color);\r\n }\r\n\r\n addWireframe() {\r\n // Wireframe\r\n const geometry = new EdgesGeometry(new BoxGeometry(2, 2, 2));\r\n const edgeMesh = new LineSegments(geometry, this.wireframeMaterialStandard);\r\n this.wireframe = edgeMesh;\r\n this.add(edgeMesh);\r\n\r\n // X-Axis\r\n const xAxisMaterial = new LineBasicMaterial({color: 0xFF0000});\r\n const xAxisGeometry = new BufferGeometry().setFromPoints([\r\n new Vector3(0,0,0), new Vector3(1,0,0)]);\r\n const xAxis = new Line(xAxisGeometry, xAxisMaterial);\r\n this.add(xAxis);\r\n\r\n // Y-Axis\r\n const yAxisMaterial = new LineBasicMaterial({color: 0x008000});\r\n const yAxisGeometry = new BufferGeometry().setFromPoints([\r\n new Vector3(0,0,0), new Vector3(0,1,0)]);\r\n const yAxis = new Line(yAxisGeometry, yAxisMaterial);\r\n this.add(yAxis);\r\n\r\n // Z-Axis\r\n const zAxisMaterial = new LineBasicMaterial({color: 0x0000FF});\r\n const zAxisGeometry = new BufferGeometry().setFromPoints([\r\n new Vector3(0,0,0), new Vector3(0,0,1)]);\r\n const zAxis = new Line(zAxisGeometry, zAxisMaterial);\r\n this.add(zAxis);\r\n }\r\n\r\n addScaleHandles() {\r\n const px = new ScaleHandle(this, {\r\n color: 0xFF0000,\r\n position: new Vector3(1,0,0),\r\n });\r\n\r\n const nx = new ScaleHandle(this, {\r\n color: 0xFF0000,\r\n position: new Vector3(-1,0,0),\r\n });\r\n\r\n const py = new ScaleHandle(this, {\r\n color: 0x008000,\r\n position: new Vector3(0,1,0),\r\n });\r\n\r\n const ny = new ScaleHandle(this, {\r\n color: 0x008000,\r\n position: new Vector3(0,-1,0),\r\n });\r\n\r\n const pz = new ScaleHandle(this, {\r\n color: 0x0000FF,\r\n position: new Vector3(0,0,1)\r\n });\r\n\r\n const nz = new ScaleHandle(this, {\r\n color: 0x0000FF,\r\n position: new Vector3(0,0,-1)\r\n });\r\n\r\n const newObjects = [px, nx, py, ny, pz, nz];\r\n newObjects.forEach(object => {\r\n this.scaleHandles.push(object);\r\n this.add(object);\r\n });\r\n }\r\n\r\n addRotateHandles() {\r\n const xRotate = new RotateHandle(this, {\r\n color: 0xFF0000,\r\n rotation: Math.PI/2,\r\n position: new Vector3(0,1,0),\r\n normal: new Vector3(1,0,0),\r\n ordering: [2,0,1]\r\n });\r\n\r\n const yRotate = new RotateHandle(this, {\r\n color: 0x008000,\r\n rotation: 0,\r\n position: new Vector3(0,0,1),\r\n normal: new Vector3(0,1,0),\r\n ordering: [1,2,0]\r\n });\r\n\r\n const zRotate = new RotateHandle(this, {\r\n color: 0x0000FF,\r\n rotation: Math.PI/2,\r\n position: new Vector3(1,0,0),\r\n normal: new Vector3(0,0,1),\r\n ordering: [0,1,2]\r\n });\r\n\r\n const newObjects = [xRotate, yRotate, zRotate];\r\n newObjects.forEach(object => {\r\n this.rotateHandles.push(object);\r\n this.add(object);\r\n });\r\n }\r\n\r\n addPositionHandle() {\r\n const handle = new PositionHandle(this);\r\n this.positionHandle = handle;\r\n this.add(handle);\r\n }\r\n\r\n setVisible(state) {\r\n this.positionHandle.highlighted = false;\r\n\r\n this.scaleHandles.forEach(handle => {\r\n handle.highlighted = state;\r\n });\r\n\r\n this.rotateHandles.forEach(handle => {\r\n handle.highlighted = state;\r\n });\r\n }\r\n\r\n raycast(raycaster, intersects) {\r\n this.positionHandle.raycast(raycaster, intersects);\r\n\r\n //return\r\n this.scaleHandles.forEach(handle => {\r\n handle.raycast(raycaster, intersects);\r\n });\r\n\r\n this.rotateHandles.forEach(handle => {\r\n handle.raycast(raycaster, intersects);\r\n });\r\n }\r\n\r\n update() {\r\n const camera = this.viewer.camera;\r\n const parentScale = this.scale;\r\n\r\n const objects = [this.positionHandle, ...this.rotateHandles];\r\n\r\n objects.forEach(object => {\r\n const objectScale = getPointScale(camera, this);\r\n const highlightScale = object.highlighted ? 1.2 : 1;\r\n\r\n const newScale = new Vector3(1,1,1)\r\n .divide(parentScale)\r\n .multiplyScalar(objectScale)\r\n .multiplyScalar(highlightScale);\r\n\r\n object.scale.copy(newScale);\r\n object.geometry.computeBoundingSphere();\r\n });\r\n }\r\n}\r\n","let isFirstTouch = false;\r\nlet numTouching = 0;\r\nlet pinchStart = null;\r\nlet pinchEnd = null;\r\n\r\nexport const touchToMouse = (event) => {\r\n let touches = event.changedTouches;\r\n\r\n // touchstart will increment numTouching\r\n if (event.type === \"touchstart\") {\r\n if (numTouching === 0) {\r\n isFirstTouch = true;\r\n numTouching = numTouching + 1;\r\n } else {\r\n isFirstTouch = false;\r\n }\r\n }\r\n\r\n // touchend will decrement numTouching\r\n if (event.type === \"touchend\") {\r\n numTouching = Math.max(0, numTouching - 1);\r\n }\r\n\r\n // Single touch, so create a fake mouse event instead\r\n if (touches.length === 1) {\r\n // We dont want to move after a pinch effect (it will be super glitchy)\r\n if (event.type === \"touchmove\") {\r\n if (!isFirstTouch) {\r\n return null;\r\n }\r\n }\r\n\r\n let first = touches[0];\r\n let eventType = \"\";\r\n\r\n switch (event.type) {\r\n case \"touchstart\":\r\n eventType = \"mousedown\";\r\n break;\r\n case \"touchmove\":\r\n eventType = \"mousemove\";\r\n break;\r\n case \"touchend\":\r\n eventType = \"mouseup\";\r\n break;\r\n default:\r\n return null;\r\n }\r\n\r\n event = new MouseEvent(eventType, {\r\n bubbles: true,\r\n cancelable: true,\r\n view: window,\r\n detail: 1,\r\n screenX: first.screenX,\r\n screenY: first.screenY,\r\n clientX: first.clientX,\r\n clientY: first.clientY,\r\n ctrlKey: false,\r\n altKey: false,\r\n shiftKey: false,\r\n metaKey: false,\r\n button: 0\r\n });\r\n\r\n return event;\r\n }\r\n\r\n // 2 finger touch (zoom in or out)\r\n if (touches.length === 2) {\r\n if (event.type === \"touchmove\") {\r\n let dist = Math.sqrt(\r\n (touches[0].clientX - touches[1].clientX) * (touches[0].clientX - touches[1].clientX) +\r\n (touches[0].clientY - touches[1].clientY) * (touches[0].clientY - touches[1].clientY)\r\n );\r\n\r\n if (pinchStart === null) {\r\n pinchStart = dist;\r\n } else {\r\n pinchEnd = dist;\r\n let pinchMove = pinchStart - pinchEnd;\r\n let sign = pinchMove / (Math.abs(pinchMove));\r\n\r\n event = new MouseEvent('wheel', {\r\n bubbles: true,\r\n cancelable: true,\r\n view: window,\r\n screenX: 0,\r\n screenY: 0,\r\n clientX: 0,\r\n clientY: 0,\r\n detail: sign,\r\n ctrlKey: false,\r\n altKey: false,\r\n shiftKey: false,\r\n metaKey: false,\r\n button: 0\r\n });\r\n event.deltaY = sign;\r\n pinchStart = null;\r\n\r\n return event;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n};\r\n\r\nexport const onLongPress = (event) => {\r\n return new MouseEvent('mouseup', {\r\n bubbles: true,\r\n cancelable: true,\r\n view: window,\r\n detail: 1,\r\n screenX: event.changedPointers[0].screenX,\r\n screenY: event.changedPointers[0].screenY,\r\n clientX: event.changedPointers[0].clientX,\r\n clientY: event.changedPointers[0].clientY,\r\n ctrlKey: false,\r\n altKey: false,\r\n shiftKey: false,\r\n metaKey: false,\r\n button: 2\r\n });\r\n};\r\n\r\nexport const onDoubleTap = (event) => {\r\n let pointer = event.changedPointers[0];\r\n\r\n return new MouseEvent('dblclick', {\r\n bubbles: true,\r\n cancelable: true,\r\n view: window,\r\n detail: 1,\r\n screenX: pointer.screenX,\r\n screenY: pointer.screenY,\r\n clientX: pointer.clientX,\r\n clientY: pointer.clientY,\r\n ctrlKey: false,\r\n altKey: false,\r\n shiftKey: false,\r\n metaKey: false,\r\n button: 0\r\n });\r\n};\r\n","import {\r\n DataProjectionCoordinate,\r\n SceneCoordinate\r\n} from \"../projections\";\r\nimport Chart from 'chart.js/auto';\r\nimport zoomPlugin from 'chartjs-plugin-zoom';\r\nimport {\r\n Line3,\r\n Mesh,\r\n MeshBasicMaterial,\r\n Scene,\r\n SphereGeometry,\r\n Vector2,\r\n Vector3\r\n} from \"three\";\r\nimport { PanoControls } from \"../controls\";\r\nimport { UnitConverter } from \"../utilities\";\r\nimport { t } from \"../../../localization\";\r\n\r\nChart.register(zoomPlugin);\r\n\r\nexport class PointProfile {\r\n public drawing = false;\r\n public scene = new Scene();\r\n public controls: PanoControls;\r\n public profileChart: ProfileChart;\r\n public line2D = new Line3();\r\n public line3D = new Line3();\r\n private sphere: Mesh;\r\n\r\n private lineWidth = 0.5;\r\n private hoverColor = 0x099c7b;\r\n private markerSize = 0.05;\r\n\r\n constructor(controls: PanoControls, props) {\r\n this.controls = controls;\r\n this.profileChart = new ProfileChart(this, props);\r\n\r\n this.initSphere();\r\n this.reset();\r\n }\r\n\r\n get viewer() {\r\n return this.controls.viewer;\r\n }\r\n\r\n get pointclouds() {\r\n return this.viewer.pointclouds;\r\n }\r\n\r\n reset() {\r\n this.line3D = new Line3();\r\n this.clearScene();\r\n this.updateUniforms();\r\n }\r\n\r\n destroy() {\r\n this.profileChart.destroy();\r\n }\r\n\r\n initSphere() {\r\n let geometry = new SphereGeometry(this.markerSize, 20, 20);\r\n let material = new MeshBasicMaterial({color: this.hoverColor});\r\n this.sphere = new Mesh(geometry, material);\r\n this.hideSphere();\r\n }\r\n\r\n clearScene() {\r\n if (!this.scene) return;\r\n this.scene.remove(this.sphere);\r\n }\r\n\r\n updateUniforms() {\r\n this.pointclouds.updateCrossSection(this.line3D.start,\r\n this.line3D.end, this.lineWidth);\r\n }\r\n\r\n onMouseMove(event) {\r\n let {coordinate} = this.controls.getPickerResults(event);\r\n if (coordinate === null) {\r\n return;\r\n }\r\n\r\n this.line3D.end = coordinate;\r\n this.updateUniforms();\r\n }\r\n\r\n selectStart(coordinate: number[]) {\r\n this.reset();\r\n this.profileChart.setData([]);\r\n this.drawing = true;\r\n\r\n const localPosition = new DataProjectionCoordinate(coordinate)\r\n .toScene();\r\n\r\n this.line3D.start.copy(localPosition);\r\n this.line3D.end.copy(localPosition);\r\n }\r\n\r\n selectEnd() {\r\n this.line2D = new Line3().copy(this.line3D);\r\n this.line2D.end.setZ(0);\r\n this.line2D.start.setZ(0);\r\n\r\n if (this.line3D.distance() === 0) {\r\n return;\r\n }\r\n\r\n this.drawing = false;\r\n this.updateUniforms();\r\n this.updatePoints();\r\n this.resetZoom();\r\n }\r\n\r\n selectCancel() {\r\n this.reset();\r\n this.drawing = false;\r\n }\r\n\r\n updatePoints() {\r\n let center = new Vector3();\r\n this.line3D.getCenter(center);\r\n let distance = this.line3D.distance() + this.lineWidth;\r\n\r\n // Grab points in a radius around our line\r\n let points = this.pointclouds.pointsInRadius(center, distance);\r\n\r\n // Filter for points that are along our line, with a valid width\r\n points = points.filter(vector => {\r\n let linePoint = new Vector3();\r\n this.line2D.closestPointToPoint(vector, false, linePoint);\r\n\r\n // Calculate distance from line\r\n let dx = vector.x - linePoint.x;\r\n let dy = vector.y - linePoint.y;\r\n let distanceAcrossLine = Math.sqrt(dx**2 + dy**2);\r\n let validWidth = distanceAcrossLine <= (this.lineWidth / 2.0);\r\n\r\n // Calculate distance along line\r\n let distanceAlongLine = this.line2D.closestPointToPointParameter(linePoint, false);\r\n let validDistance = (distanceAlongLine >= 0) && (distanceAlongLine <= 1);\r\n\r\n // Remember our distance travelled\r\n vector.distance = distanceAlongLine * this.line2D.distance();\r\n\r\n return validDistance && validWidth;\r\n });\r\n\r\n // Sort by distance along line\r\n points.sort((a, b) => a.distance - b.distance);\r\n\r\n this.profileChart.setData(points);\r\n this.profileChart.show();\r\n }\r\n\r\n drawSphere(position) {\r\n this.scene.remove(this.sphere);\r\n\r\n // Point to draw is snapped to the line, but with\r\n // the height of the original point\r\n let linePoint = new Vector3();\r\n let distanceClamped = position.distance / this.line2D.distance();\r\n this.line3D.at(distanceClamped, linePoint);\r\n linePoint.z = position.z;\r\n\r\n this.sphere.position.copy(linePoint);\r\n this.scene.add(this.sphere);\r\n }\r\n\r\n hideSphere() {\r\n if (!this.sphere) return;\r\n this.sphere.visible = false;\r\n }\r\n\r\n showSphere() {\r\n if (!this.sphere) return;\r\n this.sphere.visible = true;\r\n }\r\n\r\n resetZoom() {\r\n this.profileChart.resetZoom();\r\n }\r\n\r\n updateUnits(units) {\r\n this.profileChart.updateUnits(units);\r\n }\r\n\r\n updateSampling(type) {\r\n this.profileChart.updateSampling(type);\r\n }\r\n\r\n getProfileImage() {\r\n return this.profileChart.chartImageBase64.toBase64Image();\r\n }\r\n}\r\n\r\nclass ProfileChart {\r\n private data = [];\r\n private sampled = [];\r\n private displayUnits = \"m\";\r\n private samplingType = \"highest\";\r\n private samplingRate = 1000;\r\n private sampleMinimum = 0.02;\r\n private sampleMaximum = 1.00;\r\n\r\n private chart: Chart;\r\n private converter = new UnitConverter();\r\n private pointProfile: PointProfile;\r\n public setPointProfileOpen: Function;\r\n\r\n constructor(pointProfile: PointProfile, props) {\r\n const {setPointProfileOpen} = props;\r\n\r\n this.pointProfile = pointProfile;\r\n this.setPointProfileOpen = setPointProfileOpen;\r\n this.data = [];\r\n this.sampled = [];\r\n }\r\n\r\n get viewer() {\r\n return this.pointProfile.viewer;\r\n }\r\n\r\n get chartImageBase64() {\r\n return this.chart;\r\n }\r\n\r\n init(type, units) {\r\n const element = document.getElementById('profile-chart') as HTMLCanvasElement;\r\n const canvas = element.getContext('2d');\r\n\r\n const scales = {\r\n x: {\r\n type: 'linear',\r\n title: {\r\n display: true,\r\n text: t('profile.axis-distance')\r\n },\r\n ticks: {\r\n callback: value => {\r\n const output = this.convert(value);\r\n return `${output.toFixed(2)} ${this.displayUnits}.`;\r\n }\r\n }\r\n },\r\n y: {\r\n type: 'linear',\r\n title: {\r\n display: true,\r\n text: t('profile.axis-height')\r\n },\r\n ticks: {\r\n callback: value => {\r\n const output = this.convert(value);\r\n return `${output.toFixed(2)} ${this.displayUnits}.`;\r\n }\r\n }\r\n },\r\n };\r\n\r\n const tooltip = {\r\n caretPadding: 10,\r\n displayColors: false,\r\n filter: (_, index) => {\r\n // Return the first result only\r\n return index === 0;\r\n },\r\n callbacks: {\r\n label: context => {\r\n let vector = this.sampled[context.dataIndex];\r\n this.pointProfile.drawSphere(vector);\r\n\r\n const distance = this.convert(context.raw.x);\r\n const height = this.convert(context.raw.y);\r\n\r\n return [\r\n t(\"profile.height\", {\r\n height: height.toFixed(2),\r\n units: this.displayUnits\r\n }),\r\n t(\"profile.distance\", {\r\n distance: distance.toFixed(2),\r\n units: this.displayUnits\r\n }),\r\n ];\r\n }\r\n }\r\n };\r\n\r\n const plugins = {\r\n tooltip,\r\n legend: {\r\n display: false\r\n },\r\n title: {\r\n display: true,\r\n text: t('profile.elevation-profile'),\r\n fontSize: 14\r\n },\r\n zoom: {\r\n pan: {\r\n enabled: true,\r\n mode: 'xy',\r\n },\r\n zoom: {\r\n wheel: {\r\n enabled: true,\r\n },\r\n pinch: {\r\n enabled: true\r\n },\r\n mode: 'y',\r\n }\r\n }\r\n };\r\n\r\n const onHover = (_, items) => {\r\n if (items.length) {\r\n this.pointProfile.showSphere();\r\n } else {\r\n this.pointProfile.hideSphere();\r\n }\r\n };\r\n\r\n const otherOptions = {\r\n maintainAspectRatio: false,\r\n legend: {display: false},\r\n animation: {duration: 0},\r\n hover: {animationDuration: 0},\r\n responsive: true,\r\n responsiveAnimationDuration: 0\r\n };\r\n\r\n const dataset = {\r\n label: \"\",\r\n backgroundColor: 'rgb(255, 99, 132)',\r\n borderColor: 'rgb(255, 99, 132)',\r\n pointHoverBackgroundColor: 'rgb(0, 156, 123)',\r\n pointHoverBorderColor: 'rgb(0, 156, 123)',\r\n data: []\r\n };\r\n\r\n this.chart?.destroy();\r\n this.chart = new Chart(canvas, {\r\n type: 'scatter',\r\n data: {\r\n datasets: [dataset]\r\n },\r\n options: {\r\n onHover,\r\n plugins,\r\n scales,\r\n ...otherOptions\r\n } as any\r\n });\r\n\r\n this.updateUnits(units);\r\n this.updateSampling(type);\r\n }\r\n\r\n convert(value) {\r\n return this.converter.convert(\r\n value, \"m\", this.displayUnits, 2);\r\n }\r\n\r\n destroy() {\r\n this.chart?.destroy();\r\n }\r\n\r\n setData(data) {\r\n this.data = data;\r\n this.updateChart();\r\n }\r\n\r\n hide() {\r\n this.setPointProfileOpen(false);\r\n this.pointProfile.hideSphere();\r\n }\r\n\r\n show() {\r\n this.setPointProfileOpen(true);\r\n }\r\n\r\n resetZoom() {\r\n if (!this.chart) return;\r\n this.chart.resetZoom();\r\n }\r\n\r\n getSampledData() {\r\n let pointcloud = this.viewer.pointclouds;\r\n let highest = this.samplingType === \"highest\";\r\n let lineLength = this.pointProfile.line2D.distance();\r\n\r\n let distance = lineLength / this.samplingRate;\r\n distance = Math.max(this.sampleMinimum, distance);\r\n distance = Math.min(this.sampleMaximum, distance);\r\n\r\n const callback = point => {\r\n return Math.floor(point.distance / distance);\r\n };\r\n\r\n return pointcloud.getSampledPoints(this.data, highest, callback);\r\n }\r\n\r\n updateChart() {\r\n if (!this.chart) return;\r\n\r\n const needsSampling = this.samplingType !== \"all\";\r\n\r\n this.sampled = needsSampling\r\n ? this.getSampledData()\r\n : this.data;\r\n\r\n const numPoints = this.sampled.length;\r\n const chartTitle = needsSampling\r\n ? t('profile.elevation-profile-sampled-points', {numPoints})\r\n : t('profile.elevation-profile-points', {numPoints});\r\n\r\n // Convert to distance + projected height\r\n const points = this.sampled.map(vector => {\r\n const coordinate = new SceneCoordinate(vector)\r\n .toDataProjection();\r\n\r\n const height = coordinate.z;\r\n const distance = vector.distance;\r\n return new Vector2(distance, height);\r\n });\r\n\r\n // Update chart with new data\r\n this.chart.options.plugins.title.text = chartTitle;\r\n this.chart.data.datasets[0].data = points;\r\n this.chart.update();\r\n }\r\n\r\n /** Update units and refresh chart ui */\r\n updateUnits(units) {\r\n this.displayUnits = units;\r\n\r\n if (!this.chart) return;\r\n this.chart.update();\r\n }\r\n\r\n updateSampling(type) {\r\n this.samplingType = type;\r\n this.updateChart();\r\n }\r\n}\r\n","import {CustomOrbitControls} from \"./orbit-controls\";\r\nimport {Viewer} from '../main';\r\nimport { CameraAlignerAdv, CameraAlignerBasic, LocalAligner } from '../data-aligner';\r\nimport { ChangeDetector, isMobile, mergeBoundingBoxes } from '../utilities';\r\nimport { SceneCoordinate, SphericalPosition } from '../projections';\r\nimport {\r\n PerspectiveCamera,\r\n Scene,\r\n Vector3,\r\n} from 'three';\r\nimport { PointMarkupList } from \"../markup\";\r\nimport { MouseControls, touchToMouse } from \".\";\r\nimport Hammer from \"hammerjs\";\r\nimport { onDoubleTap, onLongPress } from \"./mobile-controls\";\r\nimport { showContextMenu } from \"../../../context-menu\";\r\nimport { PointProfile } from \"../point-profile\";\r\n\r\nexport interface OrbitPosition {\r\n orbit: Vector3,\r\n pivot: Vector3\r\n smooth: boolean;\r\n}\r\n\r\nexport class PanoControls {\r\n public viewer: Viewer;\r\n public object: PerspectiveCamera;\r\n public domElement: HTMLCanvasElement;\r\n public mouseControls: MouseControls;\r\n public cameraAlignerAdv: CameraAlignerAdv;\r\n public cameraAlignerBasic: CameraAlignerBasic;\r\n public localAligner: LocalAligner;\r\n public pointMarkup: PointMarkupList;\r\n public pointProfile: PointProfile;\r\n private hammer: Hammer;\r\n private enabled = true;\r\n public direction = new Vector3(0, 0, 0);\r\n private up = new Vector3(0, 0, 1);\r\n public orbit: OrbitController;\r\n public flyControls: FlyMoveControls;\r\n\r\n constructor(viewer: Viewer, object: PerspectiveCamera, domElement: HTMLCanvasElement, props) {\r\n this.viewer = viewer;\r\n this.object = object;\r\n this.domElement = domElement;\r\n\r\n this.hammer = new Hammer(this.domElement);\r\n this.orbit = new OrbitController(this.viewer, this, this.up);\r\n this.flyControls = new FlyMoveControls(this);\r\n\r\n this.mouseControls = new MouseControls(this.viewer, this.object, 10, 90);\r\n this.pointMarkup = new PointMarkupList(this, props);\r\n this.pointProfile = new PointProfile(this, props);\r\n this.cameraAlignerAdv = new CameraAlignerAdv(this, props);\r\n this.cameraAlignerBasic = new CameraAlignerBasic(this);\r\n this.localAligner = new LocalAligner(this, props);\r\n\r\n this.initEvents();\r\n }\r\n\r\n get anyToolEnabled() {\r\n return this.pointMarkup.enabled\r\n || this.sceneLabels.enabled\r\n || this.measurements.enabled\r\n || this.cameraAlignerAdv.enabled\r\n || this.cameraAlignerBasic.enabled\r\n || this.localAligner.enabled;\r\n }\r\n\r\n get toolScenes(): Scene[] {\r\n return [\r\n this.pointProfile.scene,\r\n this.cameraAlignerAdv.scene,\r\n this.pointMarkup.scene,\r\n this.localAligner.scene\r\n ];\r\n }\r\n\r\n get cameraList() {\r\n return this.viewer.cameraList;\r\n }\r\n\r\n get sceneLabels() {\r\n return this.viewer.imageLabels.sceneLabels;\r\n }\r\n\r\n get cadHandler() {\r\n return this.viewer.cadHandler;\r\n }\r\n\r\n get markers() {\r\n return this.viewer.markers;\r\n }\r\n\r\n get compass() {\r\n return this.viewer.compass;\r\n }\r\n\r\n get sceneTags() {\r\n return this.viewer.tags.sceneViewController;\r\n }\r\n\r\n get measurements() {\r\n return this.viewer.measurements;\r\n }\r\n\r\n get pointclouds() {\r\n return this.viewer.pointclouds;\r\n }\r\n\r\n get picker() {\r\n return this.viewer.gpuPickers.default;\r\n }\r\n\r\n get fov(): number {\r\n return this.object.fov;\r\n }\r\n\r\n get angles(): number[] {\r\n return this.mouseControls.angles;\r\n }\r\n\r\n set angles(values) {\r\n this.mouseControls.angles = values;\r\n }\r\n\r\n get lookat() {\r\n return this.mouseControls.lookat\r\n .add(this.viewer.camera.position);\r\n }\r\n\r\n destroy() {\r\n this.pointProfile.destroy();\r\n this.removeEvents();\r\n }\r\n\r\n initEvents() {\r\n this.onMouseDown = this.onMouseDown.bind(this);\r\n this.onMouseUp = this.onMouseUp.bind(this);\r\n this.onMouseWheel = this.onMouseWheel.bind(this);\r\n this.onMouseDoubleClick = this.onMouseDoubleClick.bind(this);\r\n this.onMouseMove = this.onMouseMove.bind(this);\r\n this.touchHandler = this.touchHandler.bind(this);\r\n\r\n this.domElement.addEventListener('mousedown', this.onMouseDown, false);\r\n this.domElement.addEventListener('mouseup', this.onMouseUp, false);\r\n this.domElement.addEventListener('wheel', this.onMouseWheel, false);\r\n this.domElement.addEventListener('dblclick', this.onMouseDoubleClick, false);\r\n this.domElement.addEventListener('mousemove', this.onMouseMove, false);\r\n this.domElement.addEventListener('touchstart', this.touchHandler, true);\r\n this.domElement.addEventListener('touchmove', this.touchHandler, true);\r\n this.domElement.addEventListener('touchend', this.touchHandler, true);\r\n this.domElement.addEventListener('touchcancel', this.touchHandler, true);\r\n\r\n if (!isMobile) return;\r\n\r\n // Doubletap and longpress are handled by hammer.js\r\n this.hammer.on('doubletap', touchEvent => {\r\n const mouseEvent = onDoubleTap(touchEvent);\r\n this.domElement.dispatchEvent(mouseEvent);\r\n });\r\n\r\n this.hammer.on('press', touchEvent => {\r\n const mouseEvent = onLongPress(touchEvent);\r\n this.mouseControls.down = true;\r\n this.domElement.dispatchEvent(mouseEvent);\r\n });\r\n }\r\n\r\n removeEvents() {\r\n this.domElement.removeEventListener('mousedown', this.onMouseDown, false);\r\n this.domElement.removeEventListener('mouseup', this.onMouseUp, false);\r\n this.domElement.removeEventListener('wheel', this.onMouseWheel, false);\r\n this.domElement.removeEventListener('dblclick', this.onMouseDoubleClick, false);\r\n this.domElement.removeEventListener('mousemove', this.onMouseMove, false);\r\n this.domElement.removeEventListener('touchstart', this.touchHandler, true);\r\n this.domElement.removeEventListener('touchmove', this.touchHandler, true);\r\n this.domElement.removeEventListener('touchend', this.touchHandler, true);\r\n this.domElement.removeEventListener('touchcancel', this.touchHandler, true);\r\n this.hammer.destroy();\r\n }\r\n\r\n resetSceneView() {\r\n this.mouseControls.angles = [0, 0];\r\n this.mouseControls.fov = 90;\r\n }\r\n\r\n setControlType(type) {\r\n this.orbit.setControls(type);\r\n }\r\n\r\n updateFarPlane(far) {\r\n this.object.far = far;\r\n this.orbit.camera.far = far;\r\n }\r\n\r\n getCameraTarget() {\r\n let cameraPosition = this.orbit.state\r\n ? this.orbit.activeTarget\r\n : this.object.position;\r\n\r\n return cameraPosition;\r\n }\r\n\r\n setOrbitValues(newOrbitState, position: OrbitPosition = null) {\r\n this.viewer.updatePickers();\r\n\r\n const stateChanged = this.orbit.state !== newOrbitState;\r\n if (!position && !stateChanged) return;\r\n\r\n let newOrbit;\r\n let newPivot;\r\n let smoothTransition = false;\r\n\r\n this.enabled = false;\r\n if (newOrbitState) {\r\n // Set our orbit controls position and target\r\n if (!position) {\r\n newOrbit = this.object.position;\r\n newPivot = new Vector3(0, 0, -1 * this.orbit.rotateLength)\r\n .applyQuaternion(this.object.quaternion)\r\n .add(newOrbit);\r\n } else {\r\n newOrbit = position.orbit;\r\n newPivot = position.pivot;\r\n smoothTransition = position.smooth;\r\n }\r\n\r\n this.orbit.setWalkMode(false);\r\n this.orbit.setPositionValues(newOrbit, newPivot,\r\n newOrbitState, smoothTransition);\r\n\r\n this.viewer.camera = this.orbit.camera;\r\n\r\n if (!smoothTransition) {\r\n this.flyControls.disable();\r\n }\r\n } else {\r\n this.orbit.controller.enabled = newOrbitState;\r\n this.viewer.camera = this.object;\r\n }\r\n\r\n this.enabled = true;\r\n\r\n // Set panoramic visibility\r\n if (this.cameraList) {\r\n this.cameraList.setMeshVisible(!newOrbitState);\r\n }\r\n\r\n this.viewer.handleWindowResize();\r\n this.viewer.updateCamera();\r\n }\r\n\r\n getPickerResults(event) {\r\n this.picker.update();\r\n const index = this.picker.value(event);\r\n return this.picker.getClosestCoordinate(index, event);\r\n }\r\n\r\n resetCamera(side) {\r\n const boundingBoxes = [\r\n this.pointclouds.combinedBoundingBox,\r\n this.sceneTags.combinedBoundingBox,\r\n this.cadHandler.combinedBoundingBox\r\n ];\r\n\r\n let combinedBounds = mergeBoundingBoxes(boundingBoxes);\r\n if (!combinedBounds) return;\r\n\r\n let newPosition = this.orbitFromBounds(combinedBounds, side, true);\r\n this.setOrbitValues(true, newPosition);\r\n }\r\n\r\n orbitFromBounds(bbox: {min: Vector3, max: Vector3}, side, smooth): OrbitPosition {\r\n let boxSize = new Vector3()\r\n .add(bbox.max)\r\n .sub(bbox.min);\r\n\r\n let boxMean = new Vector3()\r\n .add(boxSize)\r\n .divideScalar(2.0)\r\n .add(bbox.min);\r\n\r\n boxSize.multiplyScalar(1.5);\r\n\r\n let boundSize = Math.max(boxSize.x, boxSize.y, boxSize.z);\r\n let height = bbox.min.z + boxSize.z*0.25;\r\n let pivot = new Vector3(boxMean.x, boxMean.y, height);\r\n\r\n // Make sure our initial height doesnt exceed the far plane\r\n let maxHeight = this.viewer.camera.far * 0.75;\r\n let radius = Math.min(maxHeight, boundSize / 2.0);\r\n\r\n let orbit = this.orbitWithAngle(pivot, radius, side);\r\n\r\n return {orbit, pivot, smooth};\r\n }\r\n\r\n orbitWithAngle(pivot, radius, side) {\r\n let theta;\r\n let phi;\r\n\r\n side = side.toLowerCase();\r\n switch (side) {\r\n case \"top\":\r\n theta = 270;\r\n phi = 0.01;\r\n break;\r\n case \"bottom\":\r\n theta = 270;\r\n phi = 179.99;\r\n break;\r\n case \"right\":\r\n theta = 0.0;\r\n phi = 90;\r\n break;\r\n case \"left\":\r\n theta = 180;\r\n phi = 90;\r\n break;\r\n case \"front\":\r\n theta = 270;\r\n phi = 90;\r\n break;\r\n case \"back\":\r\n theta = 90;\r\n phi = 90;\r\n break;\r\n default:\r\n theta = 0.0;\r\n phi = 0.0;\r\n }\r\n\r\n let orbit = new SphericalPosition()\r\n .fromValues(radius, theta, phi)\r\n .toVector3()\r\n .add(pivot);\r\n\r\n return orbit;\r\n }\r\n\r\n toggleCamera() {\r\n let checked = this.orbit.state;\r\n this.setOrbitValues(!checked);\r\n }\r\n\r\n onMouseMove(initialEvent) {\r\n initialEvent.preventDefault();\r\n\r\n const event = this.mouseControls.onMouseMove(initialEvent);\r\n\r\n if (event.mouseDown || event.scrolling) {\r\n this.viewer.clearCoordinates();\r\n } else {\r\n this.viewer.updateCoordinates(event);\r\n }\r\n\r\n if (this.measurements.enabled) {\r\n const measureDragging = this.measurements.onMouseMoveScene(event);\r\n if (measureDragging) return;\r\n } else if (this.pointMarkup.enabled) {\r\n const markupDragging = this.pointMarkup.onMouseMove(event);\r\n if (markupDragging) return;\r\n } else if (this.sceneLabels.enabled) {\r\n const labelDragging = this.sceneLabels.onMouseMove(event);\r\n if (labelDragging) return;\r\n } else if (this.cameraAlignerAdv.enabled) {\r\n this.cameraAlignerAdv.onMouseMove();\r\n } else if (this.pointProfile.drawing) {\r\n this.pointProfile.onMouseMove(event);\r\n } else if (this.localAligner.enabled) {\r\n this.localAligner.onMouseMoveScene();\r\n } else {\r\n this.sceneTags.onMouseMove(event);\r\n }\r\n\r\n this.compass.onMouseMove(event);\r\n this.markers.onMouseMove(event);\r\n\r\n if (!this.enabled || this.orbit.state || !this.mouseControls.movement) {\r\n return;\r\n }\r\n\r\n this.mouseControls.updateRotation(\r\n this.object.fov,\r\n this.domElement.clientWidth,\r\n this.domElement.clientHeight\r\n );\r\n }\r\n\r\n onKeyDown(event) {\r\n this.pointMarkup.onKeyDown(event);\r\n this.cameraAlignerBasic.onKeyDown(event);\r\n }\r\n\r\n onKeyUp(event) {\r\n this.pointMarkup.onKeyUp();\r\n }\r\n\r\n onMouseDown(event) {\r\n event.preventDefault();\r\n this.mouseControls.onMouseDown(event);\r\n }\r\n\r\n onMouseUp(initialEvent) {\r\n if (!this.mouseControls.down || !this.enabled) return;\r\n const event = this.mouseControls.onMouseUp(initialEvent);\r\n\r\n this.measurements.measureGrabFinished();\r\n this.orbit.toggle(true);\r\n\r\n // Check onMouseUp of all scene elements. Marker and compass events\r\n // must come first, but the order of everything else does not matter.\r\n const mouseClicked = this.markers.onMouseUp(event)\r\n || this.compass.onMouseUp(event)\r\n || this.pointMarkup.onMouseUp(event)\r\n || this.measurements.onMouseUp(event)\r\n || this.cameraAlignerAdv.onMouseUp(event)\r\n || this.localAligner.onMouseUp(event)\r\n || this.sceneLabels.onMouseUp(event)\r\n || this.sceneTags.onMouseUp(event);\r\n\r\n if (event.mouseMoved && !this.orbit.state) {\r\n this.viewer.updatePickers();\r\n }\r\n\r\n if (event.mouseMoved || mouseClicked) return;\r\n\r\n if (event.isRightClick) {\r\n this.openContextMenu(event);\r\n }\r\n }\r\n\r\n onMouseWheel(event) {\r\n this.viewer.updatePickers();\r\n this.mouseControls.onMouseScroll();\r\n\r\n if (!this.enabled || this.orbit.state) return;\r\n\r\n event.preventDefault();\r\n this.mouseControls.onMouseWheel(event);\r\n }\r\n\r\n onMouseDoubleClick(event) {\r\n if ((!this.enabled) || (this.measurements.enabled)) return;\r\n if (!this.orbit.state) return;\r\n\r\n let {coordinate} = this.getPickerResults(event);\r\n if (!coordinate) return;\r\n\r\n const currentOrbit = this.orbit.activePosition;\r\n\r\n const vector = new Vector3()\r\n .add(coordinate)\r\n .sub(currentOrbit)\r\n .setLength(2.0);\r\n\r\n const orbit = new Vector3()\r\n .add(coordinate)\r\n .sub(vector);\r\n\r\n // Move to new pointcloud location\r\n this.flyControls.start(coordinate, orbit);\r\n }\r\n\r\n async openContextMenu(event) {\r\n if (this.anyToolEnabled) {\r\n return showContextMenu(event);\r\n }\r\n\r\n // Clicked scene coordinate\r\n const position = this.getPickerResults(event).coordinate;\r\n const sceneCoord = position\r\n ? new SceneCoordinate(position).toDataProjection().toArray()\r\n : null;\r\n\r\n // Tag attributes\r\n const selectedTags = this.sceneTags\r\n .getFeatureForEvent(event)\r\n .map(tag => tag.id);\r\n\r\n // Model attributes\r\n const modelData = await this.cadHandler.getProperties(event);\r\n\r\n // Show default context menu\r\n showContextMenu(event, {\r\n selectedTags,\r\n modelData,\r\n sceneCoord\r\n });\r\n }\r\n\r\n setMovementState(state) {\r\n let orbit = this.orbit.controller;\r\n orbit.enableRotate = state;\r\n orbit.enablePan = state;\r\n orbit.enableZoom = state;\r\n }\r\n\r\n getCameraDistance() {\r\n let minDistance = 1.0;\r\n let distance = minDistance;\r\n\r\n if (this.orbit.state) {\r\n let orbitObject = this.orbit.controller;\r\n let cameraPosition = orbitObject.object.position;\r\n let cameraPivot = orbitObject.target;\r\n let pivotLength = cameraPivot.distanceTo(cameraPosition);\r\n distance = Math.max(minDistance, pivotLength);\r\n }\r\n\r\n return distance;\r\n }\r\n\r\n getPrecision(precision) {\r\n let approxDistance = this.getCameraDistance();\r\n\r\n if (precision === null) {\r\n precision = Math.abs((1 - (100 - approxDistance) / 100.0) * (0.95) + 0.05);\r\n precision = Math.min(precision, 100.00);\r\n precision = Math.max(precision, 0.05);\r\n }\r\n\r\n let multiplier = this.viewer.far / this.viewer.defaultFarPlane;\r\n precision = precision * multiplier;\r\n\r\n return precision;\r\n }\r\n\r\n touchHandler(touchEvent) {\r\n // The only event allowed during 3d mode is touchend (mouseup). We dont\r\n // capture the initial mouseDown so we need to fake the down state\r\n if (this.orbit.state) {\r\n if (touchEvent.type !== \"touchend\") return;\r\n this.mouseControls.down = true;\r\n }\r\n\r\n const mouseEvent = touchToMouse(touchEvent);\r\n if (!mouseEvent) return;\r\n\r\n const target = touchEvent.changedTouches[0].target;\r\n touchEvent.preventDefault();\r\n target.dispatchEvent(mouseEvent);\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n this.cameraAlignerAdv.update(changeDetector);\r\n this.localAligner.update(changeDetector);\r\n this.pointMarkup.update();\r\n\r\n if (this.flyControls.enabled) {\r\n this.flyControls.move();\r\n }\r\n\r\n if (!this.enabled) return;\r\n\r\n this.mouseControls.update();\r\n this.orbit.update();\r\n }\r\n}\r\n\r\nclass FlyMoveControls {\r\n public enabled;\r\n private panoControls: PanoControls;\r\n private numberOfSteps = 20;\r\n private positions = [];\r\n\r\n constructor(parent) {\r\n this.panoControls = parent;\r\n this.disable();\r\n }\r\n\r\n get viewer() {\r\n return this.panoControls.viewer;\r\n }\r\n\r\n get orbit() {\r\n return this.panoControls.orbit;\r\n }\r\n\r\n enable(positions) {\r\n this.enabled = true;\r\n this.positions = positions;\r\n }\r\n\r\n disable() {\r\n this.enabled = false;\r\n this.positions = [];\r\n }\r\n\r\n getAngleDiff(sphereStart, sphereFinish) {\r\n let dRadius = sphereFinish.radius - sphereStart.radius;\r\n let dPhi = sphereFinish.phi - sphereStart.phi;\r\n let dTheta = sphereFinish.theta - sphereStart.theta;\r\n if (dTheta > 180) {\r\n dTheta = -1 * (360 - dTheta);\r\n } else if (dTheta < -180) {\r\n dTheta = dTheta + 360;\r\n }\r\n\r\n return {dRadius, dTheta, dPhi};\r\n }\r\n\r\n start(pivot, orbit) {\r\n let currentOrbit = this.orbit.activePosition;\r\n let currentPivot = this.orbit.activeTarget;\r\n\r\n let sphereStart = new SphericalPosition()\r\n .fromVectors(currentPivot, currentOrbit);\r\n\r\n let sphereFinish = new SphericalPosition()\r\n .fromVectors(pivot, orbit);\r\n\r\n let {dRadius, dTheta, dPhi} = this.getAngleDiff(\r\n sphereStart, sphereFinish);\r\n\r\n let dPivot = new Vector3()\r\n .add(pivot)\r\n .sub(currentPivot);\r\n\r\n let positions = [];\r\n for (let i = 0; i <= this.numberOfSteps; i++) {\r\n // Sine function provide smoother movement\r\n let value = (Math.PI/2) * (i / this.numberOfSteps);\r\n value = Math.sin(value);\r\n value = Math.pow(value, 0.5);\r\n\r\n const pivotOffset = dPivot.clone()\r\n .multiplyScalar(value);\r\n\r\n const newPivot = new Vector3()\r\n .add(currentPivot)\r\n .add(pivotOffset);\r\n\r\n let theta = sphereStart.theta + dTheta * value;\r\n let radius = sphereStart.radius + dRadius * value;\r\n let phi = sphereStart.phi + dPhi * value;\r\n\r\n let newOrbit = new SphericalPosition()\r\n .fromValues(radius, theta, phi)\r\n .toVector3()\r\n .add(newPivot);\r\n\r\n positions.push({\r\n orbit: newOrbit,\r\n pivot: newPivot\r\n });\r\n }\r\n\r\n this.enable(positions);\r\n }\r\n\r\n move() {\r\n if (this.positions.length === 0) {\r\n this.disable();\r\n return;\r\n }\r\n\r\n let {orbit, pivot} = this.positions.shift();\r\n this.orbit.setPositionValues(orbit, pivot);\r\n }\r\n}\r\n\r\nclass OrbitController {\r\n private viewer: Viewer;\r\n private controls: PanoControls;\r\n public controller;\r\n\r\n public rotateLength = 10.0;\r\n public movement = false;\r\n public camera;\r\n public callback;\r\n\r\n constructor(viewer: Viewer, controls: PanoControls, up) {\r\n this.viewer = viewer;\r\n this.controls = controls;\r\n\r\n this.camera = this.controls.object.clone();\r\n this.camera.isPerspectiveCamera = true;\r\n this.camera.up.copy(up);\r\n\r\n this.controller = new CustomOrbitControls(\r\n this.viewer, this.camera, this.controls.domElement);\r\n\r\n this.controller.addEventListener(\"stop\", () => {\r\n this.viewer.updatePickers();\r\n });\r\n\r\n this.controller.enableDamping = true;\r\n this.controller.dampingFactor = 0.15;\r\n this.controller.rotateSpeed = 0.50;\r\n this.controller.panSpeed = 0.50;\r\n this.controller.enabled = false;\r\n }\r\n\r\n get state() {\r\n return this.controller.enabled;\r\n }\r\n\r\n get walkMode() {\r\n return this.controller.walkMode;\r\n }\r\n\r\n get activePosition() {\r\n return this.controller.activePosition();\r\n }\r\n\r\n get activeTarget() {\r\n return this.controller.activeTarget();\r\n }\r\n\r\n setControls(value) {\r\n this.controller.setControls(value);\r\n }\r\n\r\n setWalkMode(state) {\r\n this.controller.setWalkMode(state);\r\n }\r\n\r\n getPositionValues() {\r\n let pivot = null;\r\n let orbit = null;\r\n\r\n try {\r\n orbit = new SceneCoordinate(this.activePosition)\r\n .toDataProjection()\r\n .toArray();\r\n\r\n pivot = new SceneCoordinate(this.activeTarget)\r\n .toDataProjection()\r\n .toArray();\r\n } catch {\r\n // Nothing\r\n }\r\n\r\n return {orbit, pivot};\r\n }\r\n\r\n setPositionValues(orbit, pivot, enabled=true, smooth=false) {\r\n if (smooth) {\r\n this.controls.flyControls.start(pivot, orbit);\r\n } else {\r\n this.controller.position0.set(orbit.x, orbit.y, orbit.z);\r\n this.controller.target0.set(pivot.x, pivot.y, pivot.z);\r\n this.controller.reset();\r\n }\r\n\r\n this.controller.enabled = enabled;\r\n }\r\n\r\n object() {\r\n return this.controls;\r\n }\r\n\r\n toggle(value) {\r\n if (this.state) {\r\n this.controller.enabled = value;\r\n }\r\n }\r\n\r\n update() {\r\n if (!this.state) {\r\n return;\r\n }\r\n\r\n this.controller.update();\r\n }\r\n}\r\n","import { Viewer } from \"../main\";\r\nimport {\r\n AmbientLight,\r\n BackSide,\r\n BoxBufferGeometry,\r\n DoubleSide,\r\n FrontSide,\r\n Group,\r\n Mesh,\r\n MeshPhongMaterial,\r\n PerspectiveCamera,\r\n PlaneBufferGeometry,\r\n Raycaster,\r\n Scene,\r\n SpotLight,\r\n Texture,\r\n Vector2,\r\n Vector3,\r\n WebGLRenderer\r\n} from \"three\";\r\nimport { eventToPixel } from \"../utilities\";\r\nimport { SceneCoordinate } from \"../projections\";\r\nimport { EffectComposer } from \"three/examples/jsm/postprocessing/EffectComposer\";\r\nimport { ShaderPass } from \"three/examples/jsm/postprocessing/ShaderPass\";\r\nimport { CopyShader } from \"three/examples/jsm/shaders/CopyShader\";\r\nimport { SSAARenderPass } from \"three/examples/jsm/postprocessing/SSAARenderPass\";\r\nimport { CustomMouseEvent } from \".\";\r\nimport { clearViewerTooltip } from \"../../viewer\";\r\nimport {t} from \"../../../localization\";\r\n\r\nclass TextMaterial extends MeshPhongMaterial {\r\n public textures;\r\n public text: string;\r\n public key: string;\r\n\r\n constructor(opts, textures, text, key) {\r\n super(opts);\r\n\r\n this.textures = textures;\r\n this.text = text;\r\n this.key = key;\r\n }\r\n}\r\n\r\nexport class CompassControls {\r\n private viewer: Viewer;\r\n private scene: Scene;\r\n private renderer: WebGLRenderer;\r\n private composer: EffectComposer\r\n private camera: PerspectiveCamera;\r\n private raycaster = new Raycaster();\r\n private pixelRatio = 2;\r\n private antialias = true;\r\n\r\n private sizeRatioLarge = 0.20;\r\n private sizeRatioSmall = 0.40;\r\n private alphaTest = 0.25;\r\n private lightPosition = new Vector3(3, 3, 3);\r\n private pivot: Group;\r\n\r\n private cube: Mesh;\r\n private cubeSize = 0.4;\r\n private cubeColorStandard = \"#dddddd\";\r\n private cubeColorHover = \"#aaaaaa\";\r\n private cubeEdgeColor = \"#444444\";\r\n private cubeTextColor = \"#000000\";\r\n private cubeMaterials: TextMaterial[] = [];\r\n\r\n private donutSize = 0.80;\r\n private donutColor = \"#444444\";\r\n private donutTextColor = \"#ffffff\";\r\n\r\n private north: Group;\r\n private west: Group;\r\n private east: Group;\r\n private south: Group;\r\n\r\n constructor(viewer: Viewer, props) {\r\n const {compassClassName} = props;\r\n\r\n this.viewer = viewer;\r\n\r\n this.initScene();\r\n this.initAntiAliasing();\r\n this.addObjects();\r\n this.addLights();\r\n\r\n // Apply compass class name from props\r\n this.domElement.className = compassClassName;\r\n }\r\n\r\n get width() {\r\n return this.domElement.width;\r\n }\r\n\r\n get height() {\r\n return this.domElement.height;\r\n }\r\n\r\n get domElement() {\r\n return this.renderer.domElement;\r\n }\r\n\r\n get cameraDistance() {\r\n return this.donutSize * 2.0;\r\n }\r\n\r\n get letters() {\r\n return [this.east, this.west, this.north, this.south];\r\n }\r\n\r\n initScene() {\r\n this.renderer = new WebGLRenderer({\r\n alpha: true,\r\n });\r\n\r\n this.renderer.setPixelRatio(this.pixelRatio);\r\n this.renderer.domElement.id = \"compass-canvas\";\r\n\r\n this.camera = new PerspectiveCamera(40, 1.0, 1, 10);\r\n this.camera.position.z = this.cameraDistance;\r\n this.camera.up = new Vector3(0, 1, 0);\r\n this.camera.lookAt(new Vector3(0, 0, 0));\r\n this.scene = new Scene();\r\n }\r\n\r\n initAntiAliasing() {\r\n this.composer = new EffectComposer(this.renderer);\r\n\r\n let ssaaRenderPass = new SSAARenderPass(this.scene,\r\n this.camera, \"white\", 0.0);\r\n\r\n ssaaRenderPass.unbiased = true;\r\n ssaaRenderPass.sampleLevel = 3;\r\n this.composer.addPass(ssaaRenderPass);\r\n\r\n let copyPass = new ShaderPass(CopyShader);\r\n this.composer.addPass(copyPass);\r\n }\r\n\r\n addObjects() {\r\n this.pivot = new Group();\r\n this.pivot.position.set(0, 0, 0);\r\n this.pivot.visible = false;\r\n\r\n this.addRotationCube();\r\n this.addCompassRing();\r\n this.addCompassLetters();\r\n\r\n // Add all items to scene\r\n this.scene.add(this.pivot);\r\n }\r\n\r\n addLights() {\r\n let ambientLight = new AmbientLight(0xffffff, 0.9);\r\n this.scene.add(ambientLight);\r\n\r\n let spotLight = new SpotLight(0xffffff, 0.5);\r\n spotLight.castShadow = true;\r\n spotLight.position.copy(this.lightPosition);\r\n this.scene.add(spotLight);\r\n }\r\n\r\n addRotationCube() {\r\n const cubeGeometry = new BoxBufferGeometry(this.cubeSize,\r\n this.cubeSize, this.cubeSize);\r\n\r\n this.cubeMaterials = [\r\n this.getTextMaterial(\"right\", t(\"directions.right\"), 270),\r\n this.getTextMaterial(\"left\", t(\"directions.left\"), 90),\r\n this.getTextMaterial(\"back\", t(\"directions.back\"), 180),\r\n this.getTextMaterial(\"front\", t(\"directions.front\"), 0),\r\n this.getTextMaterial(\"top\", t(\"directions.top\"), 0),\r\n this.getTextMaterial(\"bottom\", t(\"directions.bottom\"), 180),\r\n ];\r\n\r\n this.pivot.remove(this.cube);\r\n this.cube = new Mesh(cubeGeometry, this.cubeMaterials);\r\n this.pivot.add(this.cube);\r\n }\r\n\r\n addCompassRing() {\r\n let donutGeometry = new PlaneBufferGeometry(\r\n this.donutSize, this.donutSize\r\n );\r\n\r\n let donutMaterial = this.getCircleMaterial();\r\n donutMaterial.alphaTest = this.alphaTest;\r\n donutMaterial.side = DoubleSide;\r\n\r\n const mesh = new Mesh(donutGeometry, donutMaterial);\r\n mesh.position.z = -this.cubeSize / 2.0;\r\n this.pivot.add(mesh);\r\n }\r\n\r\n addCompassLetters() {\r\n this.letters.forEach(letter => this.pivot.remove(letter));\r\n this.east = this.getDirectionMesh(\"east\", t(\"directions.shorthand-east\"));\r\n this.west = this.getDirectionMesh(\"west\", t(\"directions.shorthand-west\"));\r\n this.north = this.getDirectionMesh(\"north\", t(\"directions.shorthand-north\"));\r\n this.south = this.getDirectionMesh(\"south\", t(\"directions.shorthand-south\"));\r\n this.letters.forEach(letter => this.pivot.add(letter));\r\n }\r\n\r\n getTextMaterial(direction, text, rotation): TextMaterial {\r\n let canvasSize = 1024;\r\n let fontSize = 200;\r\n let border = 32;\r\n let outlineSize = 5;\r\n\r\n // Scale is applied to fit text inside canvas\r\n let maxLength = canvasSize / fontSize;\r\n let fontScale = Math.min(1.0, maxLength / text.length);\r\n fontSize = fontSize * fontScale;\r\n\r\n let textures = [];\r\n\r\n [this.cubeColorStandard, this.cubeColorHover].forEach(cubeColor => {\r\n let canvas = document.createElement(\"canvas\");\r\n canvas.width = canvasSize;\r\n canvas.height = canvasSize;\r\n let context = canvas.getContext(\"2d\");\r\n\r\n // Rotate from center point\r\n context.translate( canvasSize / 2, canvasSize / 2 );\r\n context.rotate(rotation * Math.PI / 180);\r\n context.translate( -canvasSize / 2, -canvasSize / 2 );\r\n\r\n // Fill background (border + color)\r\n context.fillStyle = this.cubeEdgeColor;\r\n context.fillRect(0, 0, canvasSize, canvasSize);\r\n context.fillStyle = cubeColor;\r\n context.fillRect(border, border, canvasSize - 2 * border,\r\n canvasSize - 2 * border);\r\n\r\n // Write text\r\n let x = canvasSize / 2.0;\r\n let y = canvasSize / 2.0 + fontSize / 2.0;\r\n context.textAlign = \"center\";\r\n context.font = `bold ${fontSize}px Verdana`;\r\n context.fillStyle = this.cubeTextColor;\r\n context.fillText(text, x, y);\r\n\r\n // Black outline\r\n context.lineWidth = outlineSize;\r\n context.strokeStyle = \"#000000\";\r\n context.strokeText(text, x, y);\r\n\r\n let texture = new Texture(canvas);\r\n texture.needsUpdate = true;\r\n textures.push(texture);\r\n });\r\n\r\n let material = new TextMaterial({\r\n map: textures[0],\r\n }, textures, text, direction);\r\n\r\n return material;\r\n }\r\n\r\n getLetterMaterial(text): MeshPhongMaterial {\r\n let canvasSize = 256;\r\n let fontSize = 230;\r\n let outlineSize = 5;\r\n\r\n let canvas = document.createElement(\"canvas\");\r\n canvas.width = canvasSize;\r\n canvas.height = canvasSize;\r\n let context = canvas.getContext(\"2d\");\r\n\r\n let x = canvasSize / 2.0;\r\n let y = canvasSize / 2.0 + fontSize / 2.0 - fontSize * 0.1;\r\n context.textAlign = \"center\";\r\n context.font = `bold ${fontSize}px Verdana`;\r\n\r\n // Colored text\r\n context.fillStyle = this.donutTextColor;\r\n context.fillText(text, x, y);\r\n\r\n // Black outline\r\n context.lineWidth = outlineSize;\r\n context.strokeStyle = \"#000000\";\r\n context.strokeText(text, x, y);\r\n\r\n let texture = new Texture(canvas);\r\n texture.needsUpdate = true;\r\n\r\n return new MeshPhongMaterial({\r\n map: texture\r\n });\r\n }\r\n\r\n getCircleMaterial(): MeshPhongMaterial {\r\n let canvasSize = 256;\r\n\r\n let canvas = document.createElement(\"canvas\");\r\n canvas.width = canvasSize;\r\n canvas.height = canvasSize;\r\n let context = canvas.getContext(\"2d\");\r\n\r\n context.fillStyle = this.donutColor;\r\n\r\n let x = canvasSize / 2.0;\r\n let y = canvasSize / 2.0;\r\n\r\n context.beginPath();\r\n context.arc(x, y, canvasSize * 0.5 * 1.00, 0, Math.PI * 2, false);\r\n context.arc(x, y, canvasSize * 0.5 * 0.75, 0, Math.PI * 2, true);\r\n context.fill();\r\n\r\n let texture = new Texture(canvas);\r\n texture.needsUpdate = true;\r\n\r\n return new MeshPhongMaterial({\r\n map: texture\r\n });\r\n }\r\n\r\n getDirectionMesh(direction, text): Group {\r\n let pivot = new Group();\r\n\r\n // Set the height just barely above the circle texture\r\n let textHeight = this.cubeSize * 0.005;\r\n\r\n if (direction === \"east\") {\r\n pivot.position.x = this.cubeSize;\r\n } else if (direction === \"west\") {\r\n pivot.position.x = -1 * this.cubeSize;\r\n } else if (direction === \"north\") {\r\n pivot.position.y = this.cubeSize;\r\n } else if (direction === \"south\") {\r\n pivot.position.y = -1 * this.cubeSize;\r\n }\r\n\r\n pivot.position.z = -this.cubeSize / 2.0;\r\n\r\n let geometryUpper = new PlaneBufferGeometry(this.donutSize * 0.25,\r\n this.donutSize * 0.25);\r\n let materialUpper = this.getLetterMaterial(text);\r\n materialUpper.alphaTest = this.alphaTest;\r\n materialUpper.side = FrontSide;\r\n let meshUpper = new Mesh(geometryUpper, materialUpper);\r\n meshUpper.position.z = textHeight;\r\n pivot.add(meshUpper);\r\n\r\n let geometryLower = new PlaneBufferGeometry(this.donutSize * 0.25,\r\n this.donutSize * 0.25);\r\n let materialLower = this.getLetterMaterial(text);\r\n materialLower.alphaTest = this.alphaTest;\r\n materialLower.side = BackSide;\r\n let meshLower = new Mesh(geometryLower, materialLower);\r\n meshLower.scale.y = -1;\r\n meshLower.position.z = -1 * textHeight;\r\n pivot.add(meshLower);\r\n\r\n return pivot;\r\n }\r\n\r\n onMouseMove(event) {\r\n let {hovering} = this.checkMouseHover(event);\r\n\r\n return hovering;\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (event.mouseMoved) {\r\n return false;\r\n }\r\n\r\n let controls = this.viewer.controls;\r\n let {hovering, side} = this.checkMouseHover(event);\r\n\r\n if (side) {\r\n controls.resetCamera(side);\r\n }\r\n\r\n return hovering;\r\n }\r\n\r\n checkMouseHover(event) {\r\n let side = this.getSelectedSide(event);\r\n let hovering = side ? true : false;\r\n this.togglePointer(hovering);\r\n\r\n return {hovering, side};\r\n }\r\n\r\n getSelectedSide(event) {\r\n if (!this.cube.visible) {\r\n return;\r\n }\r\n\r\n let offset = new Vector3(\r\n this.domElement.offsetLeft,\r\n this.domElement.offsetTop,\r\n 0\r\n );\r\n\r\n let {x, y} = eventToPixel(event).sub(offset);\r\n\r\n let mouse = new Vector2();\r\n mouse.x = (x / this.width) * this.pixelRatio * 2 - 1;\r\n mouse.y = -1 * (y / this.height) * this.pixelRatio * 2 + 1;\r\n\r\n if ((mouse.x < -1) || (mouse.x > 1)) {\r\n return;\r\n }\r\n\r\n if ((mouse.y < -1) || (mouse.y > 1)) {\r\n return;\r\n }\r\n\r\n this.raycaster.setFromCamera(mouse, this.camera);\r\n\r\n let intersect = this.raycaster\r\n .intersectObject(this.cube);\r\n\r\n if (intersect.length === 0) {\r\n this.setCubeMaterials();\r\n return;\r\n }\r\n\r\n let materialIndex = Math.floor(intersect[0].faceIndex / 2);\r\n let material = this.cubeMaterials[materialIndex];\r\n this.setCubeMaterials(materialIndex);\r\n\r\n return material.key;\r\n }\r\n\r\n setCubeMaterials(hoverIndex = null) {\r\n let materials = this.cube.material as TextMaterial[];\r\n\r\n for (var i = 0; i < materials.length; i++) {\r\n if (hoverIndex === i) {\r\n this.cube.material[i].map = materials[i].textures[1];\r\n } else {\r\n this.cube.material[i].map = materials[i].textures[0];\r\n }\r\n\r\n this.cube.material[i].needsUpdate = true;\r\n }\r\n }\r\n\r\n rotateLetters(yaw) {\r\n this.east.rotation.z = yaw;\r\n this.west.rotation.z = yaw;\r\n this.north.rotation.z = yaw;\r\n this.south.rotation.z = yaw;\r\n }\r\n\r\n zenith(pointA, pointB) {\r\n let height = pointA.z - pointB.z;\r\n let distance = pointA.distanceTo(pointB);\r\n let zenith = Math.acos(height / distance);\r\n return -1 * zenith;\r\n }\r\n\r\n bearing(pointA, pointB) {\r\n let startLat = pointA.y * Math.PI / 180;\r\n let destLat = pointB.y * Math.PI / 180;\r\n\r\n let startLng = pointA.x * Math.PI / 180;\r\n let destLng = pointB.x * Math.PI / 180;\r\n\r\n let y = Math.sin(destLng - startLng) * Math.cos(destLat);\r\n let x = Math.cos(startLat) * Math.sin(destLat) -\r\n Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);\r\n let brng = Math.atan2(y, x);\r\n brng = brng * 180 / Math.PI;\r\n brng = (brng + 360.0) % 360;\r\n return brng * Math.PI / 180;\r\n }\r\n\r\n updateOffset(offset) {\r\n let shift = this.viewer.expanded\r\n ? offset\r\n : 0;\r\n\r\n this.domElement.style.right = `${shift}px`;\r\n }\r\n\r\n setSize(width, height) {\r\n const ratio = this.viewer.expanded\r\n ? this.sizeRatioLarge\r\n : this.sizeRatioSmall;\r\n\r\n const size = Math.min(width, height) * ratio;\r\n this.renderer.setSize(size, size);\r\n this.composer.setSize(size, size);\r\n }\r\n\r\n togglePointer(state) {\r\n if (state) {\r\n clearViewerTooltip();\r\n }\r\n\r\n const cursor = state ? \"pointer\" : \"\";\r\n this.viewer.setContainerCursor(cursor);\r\n }\r\n\r\n calculateRotations(loaded, camera, orbitMode) {\r\n if (!loaded) {\r\n return;\r\n }\r\n\r\n let quaternion = camera.quaternion;\r\n this.cube.visible = orbitMode;\r\n\r\n let lookatLocal = new Vector3(0, 0, -1)\r\n .applyQuaternion(quaternion)\r\n .add(camera.position);\r\n\r\n let lookatLonLat = new SceneCoordinate(lookatLocal)\r\n .toLonLat();\r\n\r\n let yPosLocal = new Vector3(0, 1, 0)\r\n .add(camera.position);\r\n\r\n let yPosLonLat = new SceneCoordinate(yPosLocal)\r\n .toLonLat();\r\n\r\n // Center point\r\n let cameraLocal = camera.position.clone();\r\n let cameraLatLon = new SceneCoordinate(cameraLocal)\r\n .toLonLat();\r\n\r\n let groupYaw = this.bearing(cameraLatLon, lookatLonLat);\r\n let groupPitch = orbitMode ? this.zenith(cameraLocal, lookatLocal) : 0;\r\n\r\n // Rotate our direction textures\r\n this.rotateLetters(-1 * groupYaw);\r\n\r\n // Pivot our geometry group\r\n this.pivot.rotation.z = groupYaw;\r\n this.pivot.rotation.x = groupPitch;\r\n\r\n // North wont equal our y-axis, so the cube is rotated independantly\r\n let cubeYaw = this.bearing(cameraLatLon, yPosLonLat);\r\n this.cube.rotation.z = -1 * cubeYaw;\r\n }\r\n\r\n render(loaded, camera, orbitMode) {\r\n this.calculateRotations(loaded, camera, orbitMode);\r\n this.pivot.visible = loaded;\r\n\r\n if (this.antialias) {\r\n this.composer.render();\r\n } else {\r\n this.renderer.render(this.scene, this.camera);\r\n }\r\n }\r\n}\r\n","import { MathUtils, PerspectiveCamera, Vector2, Vector3 } from \"three\";\r\nimport { Viewer } from \"../main\";\r\n\r\nexport interface CustomMouseEvent extends MouseEvent {\r\n isLeftClick: boolean\r\n isRightClick: boolean\r\n mouseDown: boolean\r\n mouseMoved: boolean\r\n scrolling: boolean\r\n}\r\n\r\nexport class MouseControls {\r\n private viewer: Viewer;\r\n private camera: PerspectiveCamera;\r\n\r\n public down = false;\r\n public button = 0;\r\n\r\n private phiDelta = 0;\r\n public thetaDelta = 0;\r\n public wheelDelta = 0;\r\n\r\n private wheelTimeout = null;\r\n private wheelDelay = 150;\r\n\r\n private endTimeout = 50;\r\n private endDelay = 500;\r\n\r\n public rotating = false;\r\n public zooming = false;\r\n public scrolling = false;\r\n public movement = false;\r\n private moveInterval = null;\r\n\r\n private moveStart = new Vector2();\r\n private moveEnd = new Vector2();\r\n private moveDelta = new Vector2();\r\n private moveDistance = 0;\r\n private lastMovement = performance.now();\r\n private maxPixelDistance = 4;\r\n\r\n public minFOV;\r\n public maxFOV;\r\n\r\n constructor(viewer: Viewer, camera: PerspectiveCamera, minimumFOV, maximumFOV) {\r\n this.viewer = viewer;\r\n this.camera = camera;\r\n this.minFOV = minimumFOV;\r\n this.maxFOV = maximumFOV;\r\n }\r\n\r\n get angles(): number[] {\r\n return [this.thetaDelta, this.phiDelta];\r\n }\r\n\r\n set angles(values) {\r\n const [theta, phi] = values;\r\n\r\n if (theta != null) {\r\n this.thetaDelta = theta;\r\n }\r\n\r\n if (phi != null) {\r\n this.phiDelta = phi;\r\n }\r\n }\r\n\r\n get lookat() {\r\n let phiDelta = this.phiDelta + MathUtils.degToRad(90);\r\n let x = Math.cos(this.thetaDelta) * Math.sin(phiDelta);\r\n let y = Math.sin(this.thetaDelta) * Math.sin(phiDelta);\r\n let z = -1 * Math.cos(phiDelta);\r\n\r\n return new Vector3(x,y,z);\r\n }\r\n\r\n get recentActivity() {\r\n /** Returns true if movement occured within endDelay milliseconds */\r\n let now = performance.now();\r\n let end = this.lastMovement + this.endDelay;\r\n return now < end;\r\n }\r\n\r\n set fov(value) {\r\n let fov = Math.max(this.minFOV,\r\n Math.min(this.maxFOV, value));\r\n\r\n this.camera.fov = fov;\r\n }\r\n\r\n getCustomEvent(event): CustomMouseEvent {\r\n event.isLeftClick = event.button === 0;\r\n event.isRightClick = event.button === 2;\r\n event.mouseDown = this.down;\r\n event.mouseMoved = this.movement;\r\n event.scrolling = this.scrolling;\r\n\r\n return event;\r\n }\r\n\r\n clearInterval() {\r\n if (this.moveInterval !== null) {\r\n clearTimeout(this.moveInterval);\r\n }\r\n }\r\n\r\n setInterval(callback) {\r\n this.moveInterval = setTimeout(() => {\r\n callback();\r\n }, this.endTimeout);\r\n }\r\n\r\n onMouseScroll() {\r\n this.scrolling = true;\r\n clearTimeout(this.wheelTimeout);\r\n\r\n this.wheelTimeout = setTimeout(() => {\r\n this.scrolling = false;\r\n }, this.wheelDelay);\r\n }\r\n\r\n onMouseMove(event): CustomMouseEvent {\r\n if (this.down === false) {\r\n return this.getCustomEvent(event);\r\n }\r\n\r\n this.moveEnd.set(event.clientX, event.clientY);\r\n\r\n const distance = this.moveStart.distanceTo(this.moveEnd);\r\n this.moveDistance += distance;\r\n\r\n this.moveDelta.subVectors(this.moveEnd, this.moveStart);\r\n this.moveStart.copy(this.moveEnd);\r\n this.movement = this.moveDistance > this.maxPixelDistance;\r\n\r\n return this.getCustomEvent(event);\r\n }\r\n\r\n updateRotation(fov, width, height, invertX=false, invertY=false) {\r\n if (this.button !== 0) return;\r\n\r\n let delta = new Vector2().copy(this.moveDelta);\r\n delta.multiplyScalar(fov / 90);\r\n\r\n if (invertX) {\r\n delta.x *= -1;\r\n }\r\n\r\n if (invertY) {\r\n delta.y *= -1;\r\n }\r\n\r\n this.rotate(\r\n 2 * Math.PI * delta.x / width,\r\n Math.PI * delta.y / height\r\n );\r\n\r\n this.lastMovement = performance.now();\r\n }\r\n\r\n updateCameraMatrix() {\r\n const lookat = new Vector3()\r\n .copy(this.lookat)\r\n .add(this.camera.position);\r\n\r\n this.camera.lookAt(lookat);\r\n this.camera.updateProjectionMatrix();\r\n }\r\n\r\n onMouseWheel(event) {\r\n this.wheelDelta = 0;\r\n if (event.deltaY > 0) {\r\n this.wheelDelta = -5;\r\n } else if (event.deltaY < 0) {\r\n this.wheelDelta = 5;\r\n }\r\n\r\n if (this.wheelDelta !== 0) {\r\n this.zoom();\r\n }\r\n }\r\n\r\n zoom() {\r\n const fov = this.camera.fov - this.wheelDelta;\r\n this.camera.fov = Math.max(this.minFOV, Math.min(fov, this.maxFOV));\r\n this.wheelDelta = 0.0;\r\n this.lastMovement = performance.now();\r\n }\r\n\r\n rotate(theta, phi) {\r\n this.thetaDelta += theta;\r\n this.phiDelta += phi;\r\n this.phiDelta = Math.min(this.phiDelta, MathUtils.degToRad(89));\r\n this.phiDelta = Math.max(this.phiDelta, MathUtils.degToRad(-89));\r\n\r\n const maxAngle = 360 * Math.PI / 180;\r\n this.thetaDelta = this.thetaDelta % maxAngle;\r\n this.phiDelta = this.phiDelta % maxAngle;\r\n }\r\n\r\n onMouseDown(event): CustomMouseEvent {\r\n this.down = true;\r\n this.button = event.button;\r\n this.moveStart.set(event.clientX, event.clientY);\r\n this.moveDistance = 0;\r\n this.movement = false;\r\n\r\n return this.getCustomEvent(event);\r\n }\r\n\r\n onMouseUp(event): CustomMouseEvent {\r\n const newEvent = this.getCustomEvent(event);\r\n this.down = false;\r\n this.movement = false;\r\n\r\n return newEvent;\r\n }\r\n\r\n update() {\r\n this.updateCameraMatrix();\r\n }\r\n\r\n}\r\n","import { Viewer } from \"../main\";\r\nimport { ImageMaterial } from \"../rendering\";\r\nimport {\r\n BasicRenderTarget,\r\n RenderUtils\r\n} from \"../rendering\";\r\nimport {\r\n Line3,\r\n Mesh,\r\n MeshBasicMaterial,\r\n PerspectiveCamera,\r\n Scene,\r\n SphereGeometry,\r\n Vector3,\r\n WebGLRenderer\r\n} from \"three\";\r\nimport { MouseControls } from \".\";\r\nimport onresize from \"resize-event\";\r\nimport { CameraImage } from \"../cameras\";\r\nimport { getPointScale } from \"../utilities\";\r\nimport { RayCaster } from \"../ray-caster\";\r\n\r\nexport interface IntersectResponse {\r\n canComplete: boolean\r\n canAddMore: boolean\r\n disableAddMore: boolean\r\n disableComplete: boolean\r\n disablePreviousImage: boolean\r\n disableNextImage: boolean,\r\n}\r\n\r\ninterface Coordinate {\r\n position: Vector3\r\n direction: Vector3\r\n}\r\n\r\nexport interface MultiImageOptions {\r\n canComplete: boolean\r\n canAddMore: boolean\r\n disableAddMore: boolean\r\n disableComplete: boolean\r\n disablePreviousImage: boolean\r\n disableNextImage: boolean\r\n coordinates: [Coordinate | null, Coordinate | null]\r\n intersect: null | IntersectResponse\r\n}\r\n\r\ninterface WindowLoadOptions {\r\n closePrompt?: Function\r\n onComplete?: Function\r\n onAddMore?: Function\r\n canComplete: boolean\r\n canAddMore: boolean\r\n}\r\n\r\nexport class MultiImageWindow {\r\n private viewer: Viewer;\r\n private cameraScene: Scene;\r\n public objectScene: Scene;\r\n private mouseControls: MouseControls;\r\n public camera: PerspectiveCamera\r\n private renderer: WebGLRenderer;\r\n private renderUtils: RenderUtils;\r\n private containerElement;\r\n private imageRenderMaterial: ImageMaterial\r\n private imageRenderTarget: BasicRenderTarget\r\n private setMultiImageOpen: Function;\r\n private setMultiImageState: Function;\r\n private activeCamera: CameraImage\r\n private tools: MultipleCameraMeasurement;\r\n public onComplete: Function;\r\n public onAddMore: Function;\r\n public closePrompt: Function;\r\n private intersectResponse = null;\r\n private pixelRatio = 1.0;\r\n private enabled = false;\r\n public canComplete = false;\r\n private canAddMore = false;\r\n private disablePreviousImage = false;\r\n private disableNextImage = false;\r\n public disableAddMore = false;\r\n public disableComplete = false;\r\n private cameraIndex;\r\n private observer;\r\n\r\n constructor(viewer: Viewer, props) {\r\n const {setMultiImageOpen, setMultiImageState} = props;\r\n\r\n this.viewer = viewer;\r\n this.setMultiImageOpen = setMultiImageOpen;\r\n this.setMultiImageState = setMultiImageState;\r\n\r\n this.initRenderer();\r\n this.initMaterials();\r\n this.initMouseEvents();\r\n\r\n this.mouseControls = new MouseControls(this.viewer, this.camera, 10, 90);\r\n this.tools = new MultipleCameraMeasurement(viewer, this);\r\n }\r\n\r\n get width(): number {\r\n return this.parentElement\r\n ? this.parentElement.offsetWidth\r\n : 0;\r\n }\r\n\r\n get height(): number {\r\n return this.parentElement\r\n ? this.parentElement.offsetHeight\r\n : 0;\r\n }\r\n\r\n get aspect() {\r\n return this.width / this.height;\r\n }\r\n\r\n get lookat() {\r\n return this.mouseControls.lookat\r\n .add(this.camera.position);\r\n }\r\n\r\n get parentElement() {\r\n return this.containerElement?.parentElement;\r\n }\r\n\r\n init(container) {\r\n this.containerElement = container;\r\n this.containerElement.appendChild(this.renderer.domElement);\r\n\r\n this.initResize();\r\n }\r\n\r\n destroy() {\r\n if (this.observer) {\r\n this.observer.disconnect();\r\n }\r\n }\r\n\r\n update() {\r\n const state = {\r\n canComplete: this.canComplete,\r\n canAddMore: this.canAddMore,\r\n disableAddMore: this.disableAddMore,\r\n disableComplete: this.disableComplete,\r\n disablePreviousImage: this.disablePreviousImage,\r\n disableNextImage: this.disableNextImage,\r\n coordinates: this.tools.coordinates,\r\n intersect: this.intersectResponse\r\n } as MultiImageOptions;\r\n\r\n this.setMultiImageState(state);\r\n }\r\n\r\n updateIntersect() {\r\n this.intersectResponse = this.tools.calculate();\r\n this.update();\r\n }\r\n\r\n show(opts: WindowLoadOptions = {canComplete: true, canAddMore: true}) {\r\n const currentIndex = this.viewer.getCurrentCameraIndex();\r\n if (currentIndex === -1) {\r\n return;\r\n }\r\n\r\n this.canComplete = opts.canComplete;\r\n this.canAddMore = opts.canAddMore;\r\n this.onComplete = opts.onComplete ? opts.onComplete : () => {};\r\n this.onAddMore = opts.onAddMore ? opts.onAddMore : () => {};\r\n this.closePrompt = opts.closePrompt ? opts.closePrompt : () => {};\r\n\r\n if (this.enabled) {\r\n this.update();\r\n return;\r\n }\r\n\r\n this.setMultiImageOpen(true);\r\n\r\n // Load next camera index\r\n const newIndex = this.viewer.getNextCamera(currentIndex);\r\n this.loadCamera(newIndex);\r\n }\r\n\r\n loadNextImage() {\r\n const newIndex = this.viewer.getNextCamera(this.cameraIndex);\r\n this.loadCamera(newIndex);\r\n }\r\n\r\n loadPreviousImage() {\r\n const newIndex = this.viewer.getPreviousCamera(this.cameraIndex);\r\n this.loadCamera(newIndex);\r\n }\r\n\r\n async loadCamera(index) {\r\n this.cameraIndex = index;\r\n\r\n const nextCamera = this.viewer.cameraList.cameras[index];\r\n const CameraConstructor = nextCamera.constructor as any;\r\n\r\n this.resetSecondObservation();\r\n\r\n this.disablePreviousImage = true;\r\n this.disableNextImage = true;\r\n this.update();\r\n\r\n const newCamera = new CameraConstructor(\r\n nextCamera.data,\r\n this.mouseControls,\r\n this.cameraScene,\r\n this.camera\r\n );\r\n\r\n newCamera.setCorrectionMatrix(nextCamera.matrix);\r\n\r\n // Load image data from path\r\n await newCamera.loadCameraData();\r\n\r\n // Destroy previously loaded camera\r\n this.activeCamera?.destroy();\r\n\r\n // Set camera visible and apply texture\r\n newCamera.activateCamera();\r\n this.activeCamera = newCamera;\r\n\r\n this.updateIntersect();\r\n\r\n this.disablePreviousImage = false;\r\n this.disableNextImage = false;\r\n this.update();\r\n }\r\n\r\n setState(state) {\r\n this.enabled = state;\r\n\r\n if (!state) {\r\n this.resetObservations();\r\n }\r\n }\r\n\r\n close() {\r\n this.setMultiImageOpen(false);\r\n }\r\n\r\n initResize() {\r\n if (this.observer) {\r\n this.observer.disconnect();\r\n }\r\n\r\n this.observer = onresize(this.parentElement, () => {\r\n this.handleWindowResize();\r\n });\r\n\r\n this.handleWindowResize();\r\n }\r\n\r\n initMouseEvents() {\r\n const element = this.renderer.domElement;\r\n element.addEventListener('mousedown', this.onMouseDown.bind(this), false);\r\n element.addEventListener('mouseup', this.onMouseUp.bind(this), false);\r\n element.addEventListener('mousemove', this.onMouseMove.bind(this), false);\r\n element.addEventListener('wheel', this.onMouseWheel.bind(this), false);\r\n }\r\n\r\n initRenderer() {\r\n this.renderer = new WebGLRenderer({\r\n alpha: true,\r\n });\r\n\r\n this.renderer.autoClear = false;\r\n this.renderer.setPixelRatio(this.pixelRatio);\r\n this.renderer.domElement.id = \"multi-image-canvas\";\r\n\r\n this.camera = new PerspectiveCamera(90);\r\n this.camera.near = 0.1;\r\n this.camera.far = 10;\r\n this.camera.up = new Vector3(0, 0, 1);\r\n\r\n this.cameraScene = new Scene();\r\n this.objectScene = new Scene();\r\n\r\n this.renderUtils = new RenderUtils(\r\n this.renderer,\r\n this.camera,\r\n this.pixelRatio\r\n );\r\n }\r\n\r\n initMaterials() {\r\n // Used for rendering panoramic as background\r\n this.imageRenderMaterial = new ImageMaterial();\r\n this.imageRenderTarget = new BasicRenderTarget(\r\n this.width, this.height, true);\r\n\r\n this.renderUtils.addTarget(this.imageRenderTarget);\r\n }\r\n\r\n onMouseDown(event) {\r\n event.preventDefault();\r\n this.mouseControls.onMouseDown(event);\r\n }\r\n\r\n onMouseUp(initialEvent) {\r\n if (!this.mouseControls.down || !this.enabled) return;\r\n\r\n const event = this.mouseControls.onMouseUp(initialEvent);\r\n if (event.mouseMoved || event.isRightClick) return;\r\n\r\n const raycaster = new RayCaster(this, event);\r\n const direction = raycaster.vectorFromEvent(event);\r\n const position = this.camera.position;\r\n this.addSecondObservation(position, direction);\r\n }\r\n\r\n onMouseMove(initialEvent) {\r\n if (!this.enabled) return;\r\n\r\n const event = this.mouseControls.onMouseMove(initialEvent);\r\n if (!event.mouseMoved || !event.mouseDown) return;\r\n\r\n this.mouseControls.updateRotation(\r\n this.camera.fov,\r\n this.width,\r\n this.height\r\n );\r\n }\r\n\r\n onMouseWheel(event) {\r\n if (!this.enabled) return false;\r\n\r\n this.mouseControls.onMouseScroll();\r\n this.mouseControls.onMouseWheel(event);\r\n }\r\n\r\n getClickedPoint(callback) {\r\n this.tools.getClickedPoint(callback);\r\n }\r\n\r\n resetObservations() {\r\n this.resetFirstObservation();\r\n this.resetSecondObservation();\r\n }\r\n\r\n resetFirstObservation() {\r\n this.tools.resetFirstObservation();\r\n this.updateIntersect();\r\n }\r\n\r\n resetSecondObservation() {\r\n this.tools.resetSecondObservation();\r\n this.updateIntersect();\r\n }\r\n\r\n addFirstObservation(position, direction) {\r\n this.tools.addFirstObservation(position, direction);\r\n this.updateIntersect();\r\n }\r\n\r\n addSecondObservation(position, direction) {\r\n this.tools.addSecondObservation(position, direction);\r\n this.updateIntersect();\r\n }\r\n\r\n handleWindowResize() {\r\n this.camera.aspect = this.aspect;\r\n this.camera.updateProjectionMatrix();\r\n\r\n this.renderer.domElement.style.display = \"none\";\r\n this.renderer.setSize(this.width, this.height);\r\n this.renderer.domElement.style.display = \"block\";\r\n\r\n // Re-render is required or else the div will flash white\r\n this.render();\r\n }\r\n\r\n updateMaterial(material, values) {\r\n let keys = Object.keys(values);\r\n keys.forEach(key => {\r\n material[key] = values[key];\r\n });\r\n }\r\n\r\n renderPanoramic() {\r\n // Render panoramic image\r\n this.renderUtils.setRenderTarget(this.imageRenderTarget, true);\r\n this.renderer.render(this.cameraScene, this.camera);\r\n\r\n // Update material texture with results\r\n this.updateMaterial(this.imageRenderMaterial, {\r\n colorMap: this.imageRenderTarget.texture\r\n });\r\n\r\n // Render to screen and clear depth\r\n this.renderUtils.renderToScreen(this.imageRenderMaterial);\r\n this.renderer.clearDepth();\r\n }\r\n\r\n renderSceneObjects() {\r\n this.renderUtils.renderScenes([this.objectScene], 1.0);\r\n }\r\n\r\n render() {\r\n if (!this.enabled) return false;\r\n\r\n this.mouseControls.update();\r\n this.tools.update();\r\n this.renderUtils.update();\r\n this.renderPanoramic();\r\n this.renderSceneObjects();\r\n }\r\n};\r\n\r\nclass MultipleCameraMeasurement {\r\n private viewer: Viewer;\r\n private window: MultiImageWindow;\r\n public coordinates = [null, null];\r\n private firstPoint = null;\r\n private secondPoint = null;\r\n private sphereGeometry = new SphereGeometry(0.05, 20, 20);\r\n private sphereMaterial = new MeshBasicMaterial({color: 0xe6e600});\r\n\r\n constructor(viewer, window) {\r\n this.viewer = viewer;\r\n this.window = window;\r\n }\r\n\r\n get viewerScene() {\r\n return this.viewer.measurements.scene;\r\n }\r\n\r\n get viewerCamera() {\r\n return this.viewer.camera;\r\n }\r\n\r\n get windowScene() {\r\n return this.window.objectScene;\r\n }\r\n\r\n get windowCamera() {\r\n return this.window.camera;\r\n }\r\n\r\n get sameCamera() {\r\n const origin1 = this.window.camera?.position;\r\n const origin2 = this.viewer.camera?.position;\r\n\r\n if (origin1 && origin2) {\r\n if (origin1.distanceTo(origin2) < 0.005) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n getEndpoint(origin, direction) {\r\n return direction\r\n .clone()\r\n .setLength(1.0)\r\n .add(origin);\r\n }\r\n\r\n getSphereMesh(position) {\r\n let sphere = new Mesh(this.sphereGeometry, this.sphereMaterial);\r\n sphere.position.copy(position);\r\n\r\n return sphere;\r\n }\r\n\r\n getClickedPoint(callback) {\r\n let rayA = this.coordinates[0];\r\n let rayB = this.coordinates[1];\r\n if ((rayA === null) || (rayB === null)) {\r\n return;\r\n }\r\n\r\n if (this.sameCamera) {\r\n return;\r\n }\r\n\r\n let {point, valid} = this.getIntersection(rayA, rayB);\r\n if (valid) {\r\n callback(point);\r\n }\r\n }\r\n\r\n setButtonDisabled(state) {\r\n this.window.disableComplete = state;\r\n this.window.disableAddMore = state;\r\n }\r\n\r\n calculate() {\r\n const defaultResponse = {\r\n error: null,\r\n distances: [0, 0],\r\n calculated: false,\r\n valid: true,\r\n message: null\r\n };\r\n\r\n if (this.sameCamera) {\r\n this.setButtonDisabled(true);\r\n return {\r\n ...defaultResponse,\r\n valid: false,\r\n message: \"Measuring from same camera\"\r\n };\r\n } else {\r\n this.setButtonDisabled(false);\r\n }\r\n\r\n let rayA = this.coordinates[0];\r\n let rayB = this.coordinates[1];\r\n if ((rayA === null) || (rayB === null)) {\r\n return defaultResponse;\r\n }\r\n\r\n let {error, distances, valid, message}\r\n = this.getIntersection(rayA, rayB);\r\n\r\n this.setButtonDisabled(!valid);\r\n\r\n if (!valid) {\r\n return {...defaultResponse, message, valid: false};\r\n }\r\n\r\n return {\r\n ...defaultResponse,\r\n error,\r\n distances,\r\n calculated: true\r\n };\r\n }\r\n\r\n resetFirstObservation() {\r\n if (this.firstPoint) {\r\n this.viewerScene.remove(this.firstPoint);\r\n }\r\n this.coordinates[0] = null;\r\n this.firstPoint = null;\r\n }\r\n\r\n resetSecondObservation() {\r\n if (this.secondPoint) {\r\n this.windowScene.remove(this.secondPoint);\r\n }\r\n this.coordinates[1] = null;\r\n this.secondPoint = null;\r\n }\r\n\r\n addFirstObservation(position, direction) {\r\n this.viewerScene.remove(this.firstPoint);\r\n\r\n let origin = position.clone();\r\n let endPoint = this.getEndpoint(origin, direction);\r\n this.coordinates[0] = {origin, direction};\r\n\r\n this.firstPoint = this.getSphereMesh(endPoint);\r\n this.viewerScene.add(this.firstPoint);\r\n this.updatePointScale();\r\n }\r\n\r\n addSecondObservation(position, direction) {\r\n this.windowScene.remove(this.secondPoint);\r\n\r\n let origin = position.clone();\r\n let endPoint = this.getEndpoint(origin, direction);\r\n this.coordinates[1] = {origin, direction};\r\n\r\n this.secondPoint = this.getSphereMesh(endPoint);\r\n this.windowScene.add(this.secondPoint);\r\n this.updatePointScale();\r\n }\r\n\r\n setPointScale(mesh: Mesh, camera: PerspectiveCamera) {\r\n if (!mesh) return;\r\n const scale = getPointScale(camera, mesh);\r\n mesh.scale.set(scale, scale, scale);\r\n mesh.geometry.computeBoundingSphere();\r\n }\r\n\r\n updatePointScale() {\r\n this.setPointScale(this.firstPoint, this.viewerCamera);\r\n this.setPointScale(this.secondPoint, this.windowCamera);\r\n }\r\n\r\n /** Get closest possible midpoint for two line segments */\r\n getIntersection(rayA, rayB) {\r\n let message = \"\";\r\n let valid = true;\r\n\r\n let Nv = rayA.direction.clone().cross(rayB.direction);\r\n let Na = rayA.direction.clone().cross(Nv).normalize();\r\n let Nb = rayB.direction.clone().cross(Nv).normalize();\r\n let Da = rayA.direction.clone().normalize();\r\n let Db = rayB.direction.clone().normalize();\r\n let da = rayB.origin.clone().sub(rayA.origin).dot(Nb) / Da.dot(Nb);\r\n let db = rayA.origin.clone().sub(rayB.origin).dot(Na) / Db.dot(Na);\r\n let ptA = rayA.origin.clone().add(Da.multiplyScalar(da));\r\n let ptB = rayB.origin.clone().add(Db.multiplyScalar(db));\r\n\r\n // Get our midpoint and segment length\r\n let lineSegment = new Line3(ptA, ptB);\r\n let segmentLength = lineSegment.distance();\r\n let midPoint = new Vector3();\r\n lineSegment.getCenter(midPoint);\r\n\r\n // Make sure our result is in front of us\r\n const d1n = ptA.clone().sub(rayA.origin).setLength(1.0);\r\n const d2n = ptB.clone().sub(rayB.origin).setLength(1.0);\r\n const a1 = Math.abs(rayA.direction.angleTo(d1n));\r\n const a2 = Math.abs(rayB.direction.angleTo(d2n));\r\n const behindCamera = (a1 > 0.005) || (a2 > 0.005);\r\n if (behindCamera) {\r\n valid = false;\r\n message = \"Intersection point behind camera\";\r\n }\r\n\r\n let distances = [\r\n ptA.distanceTo(rayA.origin),\r\n ptB.distanceTo(rayB.origin)\r\n ];\r\n\r\n return {\r\n point: midPoint,\r\n error: segmentLength,\r\n distances,\r\n valid,\r\n message\r\n };\r\n }\r\n\r\n update() {\r\n this.updatePointScale();\r\n }\r\n}","export default __webpack_public_path__ + \"static/media/arrow-standard.81f0ce35.png\";","export default __webpack_public_path__ + \"static/media/arrow-shadow.7243bcb0.png\";","import {\r\n BufferGeometry,\r\n BufferAttribute,\r\n Vector3,\r\n Mesh,\r\n Scene,\r\n Object3D,\r\n Texture,\r\n TextureLoader,\r\n PlaneGeometry,\r\n MeshBasicMaterial,\r\n DoubleSide,\r\n MathUtils\r\n} from \"three\";\r\nimport {Viewer} from '../main';\r\nimport {MarkerMaterial} from \"../rendering\";\r\nimport { CameraImage, PlanarImage } from \"../cameras\";\r\nimport arrowPathStandard from '../../textures/misc/arrow-standard.png';\r\nimport arrowPathShadow from '../../textures/misc/arrow-shadow.png';\r\nimport { CustomMouseEvent } from \"../controls\";\r\nimport { MarkerNavType } from \"../../../redux/settings-slice\";\r\nimport { RayCaster } from \"../ray-caster\";\r\n\r\nexport class CameraMarkers {\r\n private viewer: Viewer;\r\n private arrowNavigation: ArrowNavigation;\r\n public markerNavigation: MarkerNavigation;\r\n private navigationType: MarkerNavType;\r\n public cameras: CameraImage[] = [];\r\n public modifier = false;\r\n public scene: Scene = null;\r\n\r\n constructor(viewer) {\r\n this.viewer = viewer;\r\n this.initScene();\r\n this.initKeyDown();\r\n\r\n this.markerNavigation = new MarkerNavigation(viewer, this);\r\n this.arrowNavigation = new ArrowNavigation(viewer, this);\r\n }\r\n\r\n get controls() {\r\n return this.viewer.controls;\r\n }\r\n\r\n get cameraList() {\r\n return this.viewer.cameraList;\r\n }\r\n\r\n get renderInFront() {\r\n return this.viewer.orbitState || this.arrowNavigation.visible;\r\n }\r\n\r\n get calculating() {\r\n return this.markerNavigation.calculating;\r\n }\r\n\r\n get isHidden() {\r\n return this.navigationType === MarkerNavType.None;\r\n }\r\n\r\n get isArrows() {\r\n return this.navigationType === MarkerNavType.Arrows;\r\n }\r\n\r\n get isMarkers() {\r\n return this.navigationType === MarkerNavType.Markers;\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n }\r\n\r\n initKeyDown() {\r\n this.onKeyUp = this.onKeyUp.bind(this);\r\n this.onKeyDown = this.onKeyDown.bind(this);\r\n\r\n window.addEventListener( 'keydown', this.onKeyDown, false);\r\n window.addEventListener( 'keyup', this.onKeyUp, false);\r\n }\r\n\r\n addCameraMarkers(cameras: Array) {\r\n // Add new cameras to array\r\n let newCameras = cameras.filter(x => !this.cameras.includes(x));\r\n this.cameras = [...this.cameras, ...newCameras];\r\n\r\n // Draw markers for marker navigation\r\n this.markerNavigation.drawCameraMarkers(this.cameras);\r\n }\r\n\r\n setNavigationType(state) {\r\n this.navigationType = state;\r\n\r\n if (this.isArrows) {\r\n this.arrowNavigation.loadSectionsToCache();\r\n }\r\n\r\n this.markerNavigation.updatePicker();\r\n }\r\n\r\n removeCameraMarkers(cameras: CameraImage[]) {\r\n // Remove cameras from array\r\n const toRemove = new Set(cameras.map(x => x.id));\r\n const remaining = this.cameras.filter(x => !toRemove.has(x.id));\r\n this.cameras = [...remaining];\r\n }\r\n\r\n recalculateAllMarkers() {\r\n const cameras = [...this.cameras];\r\n this.removeCameraMarkers(cameras);\r\n this.addCameraMarkers(cameras);\r\n }\r\n\r\n updateArrowNavigation() {\r\n this.arrowNavigation.updateNavigation();\r\n }\r\n\r\n clearArrowNavigation() {\r\n this.arrowNavigation.clearNavigation();\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (event.mouseMoved) {\r\n return false;\r\n }\r\n\r\n let camera: CameraImage;\r\n\r\n if (event.isLeftClick) {\r\n camera = this.markerNavigation.mouseClick(event);\r\n if (camera) {\r\n this.viewer.loadImage(camera.id);\r\n return true;\r\n }\r\n\r\n camera = this.arrowNavigation.mouseClick(event);\r\n if (camera) {\r\n this.viewer.loadImage(camera.id);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onMouseMove(event: CustomMouseEvent) {\r\n if (event.mouseMoved) {\r\n return;\r\n }\r\n\r\n // Mouse move for arrow navigation\r\n this.arrowNavigation.onMouseMove(event);\r\n\r\n // Mouse move for standard navigation\r\n this.markerNavigation.onMouseMove(event);\r\n }\r\n\r\n\r\n onKeyUp(event) {\r\n if (event.which !== 17) return;\r\n this.modifier = false;\r\n }\r\n\r\n onKeyDown(event) {\r\n if (event.which !== 17) return;\r\n this.modifier = true;\r\n }\r\n\r\n update() {\r\n let isOrbitMode = this.viewer.orbitState;\r\n\r\n if (this.isHidden) {\r\n this.markerNavigation.setVisible(false);\r\n this.arrowNavigation.setVisible(false);\r\n } else {\r\n if (this.isMarkers) {\r\n this.markerNavigation.setVisible(true);\r\n this.arrowNavigation.setVisible(false);\r\n } else if (this.isArrows) {\r\n if (isOrbitMode) {\r\n this.markerNavigation.setVisible(true);\r\n this.arrowNavigation.setVisible(false);\r\n } else {\r\n this.markerNavigation.setVisible(this.modifier);\r\n this.arrowNavigation.setVisible(!this.modifier);\r\n }\r\n }\r\n }\r\n\r\n this.markerNavigation.setEnabled(this.isArrows || this.isMarkers);\r\n this.arrowNavigation.setEnabled(this.isArrows);\r\n\r\n this.markerNavigation.update();\r\n this.arrowNavigation.update();\r\n }\r\n}\r\n\r\nclass MarkerNavigation {\r\n private viewer: Viewer;\r\n private markers: CameraMarkers;\r\n private markerMesh = null;\r\n private pickingMesh = null;\r\n private standardMaterial: MarkerMaterial = null;\r\n private pickingMaterial: MarkerMaterial = null;\r\n public enabled = false;\r\n public visible = false;\r\n private geometry;\r\n private verticesPerCamera = 6;\r\n private uvs: number[] = [0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1];\r\n private corners: number[] = [0, 2, 1, 2, 3, 1];\r\n private camerasToIterate = [];\r\n private camerasCalculated = [];\r\n private selectedID = null;\r\n private maxIterationTime = 5;\r\n public markerPositions = [];\r\n public calculating = false;\r\n private vertices: Vector3[] = [\r\n new Vector3(-0.5, 0.5, 0),\r\n new Vector3(0.5, 0.5, 0),\r\n new Vector3(-0.5, -0.5, 0),\r\n new Vector3(0.5, -0.5, 0)\r\n ]\r\n\r\n constructor(viewer: Viewer, markers: CameraMarkers) {\r\n this.markers = markers;\r\n this.viewer = viewer;\r\n\r\n this.initGeometry();\r\n }\r\n\r\n get scene() {\r\n return this.markers.scene;\r\n }\r\n\r\n get meshes() {\r\n return [this.markerMesh, this.pickingMesh];\r\n }\r\n\r\n get materials() {\r\n return [this.standardMaterial, this.pickingMaterial];\r\n }\r\n\r\n get picker() {\r\n return this.viewer.gpuPickers.markers;\r\n }\r\n\r\n initGeometry() {\r\n if (this.markerMesh) {\r\n this.scene.remove(this.markerMesh);\r\n }\r\n\r\n if (this.pickingMesh) {\r\n this.picker.remove(this.pickingMesh);\r\n }\r\n\r\n let geometry = new BufferGeometry();\r\n geometry.setAttribute('selected', new BufferAttribute(new Float32Array(0), 1));\r\n geometry.setAttribute('visible', new BufferAttribute(new Float32Array(0), 1));\r\n geometry.setAttribute('gpu_index', new BufferAttribute(new Int32Array(0), 1));\r\n geometry.setAttribute('camera_index', new BufferAttribute(new Int32Array(0), 1));\r\n geometry.setAttribute('position', new BufferAttribute(new Float32Array(0), 3));\r\n geometry.setAttribute('uv', new BufferAttribute(new Float32Array(0), 2));\r\n\r\n this.standardMaterial = new MarkerMaterial(false);\r\n this.markerMesh = new Mesh(geometry, this.standardMaterial);\r\n this.scene.add(this.markerMesh);\r\n\r\n this.pickingMaterial = new MarkerMaterial(true);\r\n this.pickingMesh = new Mesh(geometry, this.pickingMaterial);\r\n this.picker.add(this.pickingMesh);\r\n }\r\n\r\n setEnabled(state) {\r\n this.enabled = state;\r\n }\r\n\r\n setVisible(state) {\r\n if (!this.visible && state) {\r\n this.updatePicker();\r\n }\r\n\r\n this.visible = state;\r\n }\r\n\r\n updatePicker() {\r\n this.picker.needsUpdate = true;\r\n }\r\n\r\n drawCameraMarkers(cameras) {\r\n let numCameras = cameras.length;\r\n let selected = new Float32Array(numCameras * this.verticesPerCamera);\r\n let visible = new Float32Array(numCameras * this.verticesPerCamera);\r\n let markerShape = new Float32Array(numCameras * this.verticesPerCamera);\r\n let positions = new Float32Array(numCameras * this.verticesPerCamera * 3);\r\n let uvs = new Float32Array(numCameras * this.verticesPerCamera * 2);\r\n let indices = new Int32Array(numCameras * this.verticesPerCamera);\r\n let cameraIndices = new Int32Array(numCameras * this.verticesPerCamera);\r\n\r\n cameras.forEach((camera, cameraIndex) => {\r\n // Set the marker shape. Default is circular\r\n let cameraShape = camera instanceof PlanarImage ? 1.0 : 0.0;\r\n\r\n // Assign our uv values\r\n const numUvs = this.uvs.length;\r\n this.uvs.forEach((uv, uvIndex) => {\r\n let index = (numUvs * cameraIndex) + uvIndex;\r\n uvs[index] = uv;\r\n });\r\n\r\n // Create attribute arrays for each vertex in each cam.\r\n const numVertices = this.verticesPerCamera;\r\n for (var i = 0; i < this.verticesPerCamera; i++) {\r\n let index = (numVertices * cameraIndex) + i;\r\n selected[index] = 0.0;\r\n visible[index] = 1.0;\r\n indices[index] = 0.0;\r\n markerShape[index] = cameraShape;\r\n cameraIndices[index] = cameraIndex;\r\n }\r\n });\r\n\r\n let geometry = new BufferGeometry();\r\n geometry.setAttribute('selected', new BufferAttribute(selected, 1));\r\n geometry.setAttribute('visible', new BufferAttribute(visible, 1));\r\n geometry.setAttribute('marker_shape', new BufferAttribute(markerShape, 1));\r\n geometry.setAttribute('gpu_index', new BufferAttribute(indices, 1));\r\n geometry.setAttribute('camera_index', new BufferAttribute(cameraIndices, 1));\r\n geometry.setAttribute('position', new BufferAttribute(positions, 3));\r\n geometry.setAttribute('uv', new BufferAttribute(uvs, 2));\r\n this.geometry = geometry;\r\n\r\n // Reset chunked arrays\r\n this.camerasToIterate = cameras;\r\n this.camerasCalculated = [];\r\n this.calculating = cameras.length > 0;\r\n\r\n if (numCameras === 0) {\r\n this.updateGeometry();\r\n }\r\n }\r\n\r\n markCameraSelected(markerID) {\r\n this.meshes.forEach(mesh => {\r\n let attributes = mesh.geometry.attributes;\r\n attributes.selected.array.fill(0.0);\r\n\r\n let index = attributes.camera_index.array.indexOf(markerID);\r\n if (index !== -1) {\r\n for (var i = 0; i < this.verticesPerCamera; i++) {\r\n attributes.selected.array[index + i] = 1.00;\r\n }\r\n }\r\n\r\n attributes.selected.needsUpdate = true;\r\n });\r\n\r\n if (this.selectedID !== markerID) {\r\n // Update picker if selected marker changed\r\n this.updatePicker();\r\n }\r\n\r\n this.selectedID = markerID;\r\n }\r\n\r\n calculateCameras() {\r\n if (this.camerasToIterate.length === 0) return;\r\n\r\n let cameraIndex = 0;\r\n let numToIterate = this.camerasToIterate.length;\r\n let camerasCalculated = [];\r\n\r\n let timeStart = performance.now();\r\n for (cameraIndex = 0; cameraIndex < numToIterate; cameraIndex++) {\r\n let camera = this.camerasToIterate[cameraIndex];\r\n camerasCalculated.push(camera.position.marker);\r\n\r\n let elapsed = performance.now() - timeStart;\r\n if (elapsed > this.maxIterationTime) break;\r\n }\r\n\r\n this.camerasToIterate = this.camerasToIterate.slice(cameraIndex+1);\r\n\r\n this.camerasCalculated = [\r\n ...this.camerasCalculated,\r\n ...camerasCalculated\r\n ];\r\n\r\n // If we have more data to parse exit early\r\n // and wait until next iteration\r\n if (this.camerasToIterate.length !== 0) return;\r\n\r\n let numCameras = this.camerasCalculated.length;\r\n let positions = new Float32Array(numCameras * this.verticesPerCamera * 3);\r\n\r\n this.markerPositions = new Array(numCameras);\r\n this.camerasCalculated.forEach((position, cameraIndex) => {\r\n // Setting our positions array\r\n const numCorners = this.corners.length;\r\n this.markerPositions[cameraIndex] = position;\r\n this.corners.forEach((corner, cornerIndex) => {\r\n let index = (numCorners * cameraIndex) + cornerIndex;\r\n var points = this.vertices[corner];\r\n positions[(index * 3)] = points.x + position.x;\r\n positions[(index * 3) + 1] = points.y + position.y;\r\n positions[(index * 3) + 2] = points.z + position.z;\r\n });\r\n });\r\n\r\n this.geometry.setAttribute('position', new BufferAttribute(positions, 3));\r\n this.geometry.attributes.position.needsUpdate = true;\r\n\r\n this.calculating = false;\r\n this.updateGeometry();\r\n }\r\n\r\n updateGeometry() {\r\n this.meshes.forEach(mesh => {\r\n mesh.geometry.dispose();\r\n mesh.geometry.copy(this.geometry);\r\n mesh.geometry.needsUpdate = true;\r\n });\r\n\r\n this.viewer.updatePickers();\r\n }\r\n\r\n cameraPickerID(event) {\r\n try {\r\n // Update gpu picker if required\r\n this.picker.update();\r\n\r\n // Grab our index and marker id\r\n const index = this.picker.value(event);\r\n\r\n if (index === null) {\r\n return null;\r\n }\r\n\r\n const attributes = this.pickingMesh.geometry.attributes;\r\n const arrIndex = attributes.gpu_index.array.indexOf(index);\r\n const markerID = attributes.camera_index.array[arrIndex];\r\n\r\n return markerID as number;\r\n }\r\n catch (e) {\r\n console.log(\"Prevented framebuffer exception: \");\r\n console.log(e);\r\n\r\n return null;\r\n }\r\n }\r\n\r\n onMouseMove(event) {\r\n let markerID = this.cameraPickerID(event);\r\n this.markCameraSelected(markerID);\r\n }\r\n\r\n mouseClick(event) : CameraImage {\r\n let markerID = this.cameraPickerID(event);\r\n\r\n return (markerID !== null)\r\n ? this.markers.cameras[markerID]\r\n : null;\r\n }\r\n\r\n update() {\r\n const camera = this.viewer.camera;\r\n const position = camera.position;\r\n const rotation = camera.rotation.toVector3();\r\n const cameraIndex = this.viewer.getCurrentCameraIndex();\r\n const initialCameraLoading = this.viewer.initialCameraLoading;\r\n\r\n // Set meshes visibility\r\n this.meshes.forEach(mesh => {\r\n mesh.visible = this.visible;\r\n });\r\n\r\n // Update shader parameters\r\n this.materials.forEach((material: MarkerMaterial) => {\r\n material.currentCameraRotation = rotation;\r\n material.currentCameraPosition = position;\r\n material.windowHeight = window.innerHeight;\r\n material.initialCameraLoading = initialCameraLoading;\r\n material.currentIndex = cameraIndex;\r\n material.orbitMode = this.viewer.orbitState;\r\n material.fov = MathUtils.degToRad(camera.fov);\r\n material.needsUpdate = true;\r\n });\r\n\r\n this.calculateCameras();\r\n }\r\n}\r\n\r\nclass ArrowMarker {\r\n public camera: CameraImage;\r\n private radius = 1.5\r\n private height = -1.0;\r\n private size = 0.5;\r\n public object: Object3D;\r\n\r\n constructor(textures, section, angle) {\r\n this.object = new Object3D();\r\n this.object.rotation.z = 1 * MathUtils.degToRad(angle);\r\n this.addMesh(section, textures[0], this.height);\r\n this.addMesh(section, textures[1], this.height * 1.03);\r\n }\r\n\r\n get visible() {\r\n return this.object.visible;\r\n }\r\n\r\n get enabled() {\r\n return this.camera !== null;\r\n }\r\n\r\n clear() {\r\n this.camera = null;\r\n this.setVisible(false);\r\n }\r\n\r\n setVisible(state) {\r\n this.object.visible = state;\r\n }\r\n\r\n setCamera(camera: CameraImage) {\r\n this.camera = camera;\r\n }\r\n\r\n setScale(scale) {\r\n this.object.children.forEach(x => {\r\n x.scale.copy(scale);\r\n });\r\n }\r\n\r\n addMesh(section, texture, height) {\r\n // Add standard marker mesh\r\n const geometryStandard = new PlaneGeometry(this.size * 0.75, this.size);\r\n const materialStandard = new MeshBasicMaterial({\r\n map: texture,\r\n side: DoubleSide,\r\n transparent: true,\r\n alphaTest: 0.5\r\n });\r\n\r\n const mesh = new Mesh(geometryStandard, materialStandard);\r\n mesh.userData = {section};\r\n mesh.position.x = this.radius;\r\n mesh.position.z = height;\r\n mesh.rotation.z = -1 * MathUtils.degToRad(90);\r\n this.object.add(mesh);\r\n }\r\n}\r\n\r\nclass ArrowNavigation {\r\n private viewer: Viewer;\r\n private markers: CameraMarkers;\r\n private object: Object3D;\r\n private textures: Texture[] = [];\r\n public enabled = false;\r\n public visible = false;\r\n private minDistance = 5.0;\r\n private maxDistance = 40.0;\r\n private numSections = 8;\r\n private needsUpdate;\r\n private sections: ArrowMarker[] = [];\r\n private defaultScale = new Vector3(1.0, 1.0, 1.0);\r\n private zoomedScale = new Vector3(1.2, 1.2, 1.2);\r\n\r\n constructor(viewer: Viewer, markers: CameraMarkers) {\r\n this.markers = markers;\r\n this.viewer = viewer;\r\n\r\n this.loadTextures();\r\n this.initMeshObject();\r\n this.clearNavigation();\r\n }\r\n\r\n get scene() {\r\n return this.markers.scene;\r\n }\r\n\r\n initMeshObject() {\r\n this.object = new Object3D();\r\n\r\n for (let section=0;section {\r\n arrow.clear();\r\n });\r\n }\r\n\r\n calculateCameras() {\r\n if (this.markers.calculating || !this.visible || !this.needsUpdate) {\r\n return;\r\n }\r\n\r\n this.needsUpdate = false;\r\n\r\n // Positions are precalculated when adding scene view markers\r\n let positions = this.markers.markerNavigation.markerPositions;\r\n\r\n this.clearNavigation();\r\n\r\n const cameraPos = this.viewer.camera.position;\r\n\r\n const validCameras = [];\r\n positions.forEach((markerPos, cameraIndex) => {\r\n let x = markerPos.x - cameraPos.x;\r\n let y = markerPos.y - cameraPos.y;\r\n\r\n const distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));\r\n\r\n // Calculate min and max distance from camera;\r\n let tooClose = distance < this.minDistance;\r\n let tooFar = distance > this.maxDistance;\r\n if (tooClose || tooFar) {\r\n return;\r\n }\r\n\r\n // Calculate section\r\n let angle = Math.atan2(y, x) * 180 / Math.PI;\r\n let section = this.angleToSection(angle);\r\n\r\n let camera = this.markers.cameras[cameraIndex];\r\n validCameras.push({camera, distance, section});\r\n });\r\n\r\n // Sort by distance\r\n validCameras.sort((a, b) => {\r\n return a.distance - b.distance;\r\n });\r\n\r\n validCameras.forEach(({camera, section}) => {\r\n if (this.sections[section].enabled) {\r\n return;\r\n }\r\n\r\n this.sections[section].setCamera(camera);\r\n this.sections[section].setVisible(true);\r\n });\r\n\r\n this.loadSectionsToCache();\r\n\r\n // Update mesh position\r\n this.object.position.copy(cameraPos);\r\n }\r\n\r\n loadSectionsToCache() {\r\n this.sections.forEach(section => {\r\n if (!section.camera) return;\r\n section.camera.loadFromCache();\r\n });\r\n }\r\n\r\n onMouseMove(event) {\r\n this.sections.forEach(arrow => {\r\n arrow.setScale(this.defaultScale);\r\n });\r\n\r\n let object = this.getIntersect(event);\r\n if (!object) {\r\n return;\r\n }\r\n\r\n object.setScale(this.zoomedScale);\r\n }\r\n\r\n mouseClick(event) {\r\n let object = this.getIntersect(event);\r\n if (!object || !object.camera) {\r\n return null;\r\n }\r\n\r\n this.sections.forEach(arrow => {\r\n arrow.setVisible(false);\r\n });\r\n\r\n return object.camera;\r\n }\r\n\r\n /** @private */\r\n getIntersect(event) : ArrowMarker {\r\n if (!this.visible) {\r\n return;\r\n }\r\n\r\n let targets = this.sections.map(arrow => {\r\n return arrow.object.children[0];\r\n });\r\n\r\n let raycaster = new RayCaster(this.viewer, event);\r\n let intersects = raycaster.intersectObjects(targets);\r\n if (intersects.length === 0) {\r\n return;\r\n }\r\n\r\n const intersect = intersects[0].object;\r\n const sectionID = intersect.userData.section;\r\n const object = this.sections[sectionID];\r\n\r\n return object;\r\n }\r\n\r\n update() {\r\n if (!this.object) {\r\n return;\r\n }\r\n\r\n this.calculateCameras();\r\n this.object.visible = this.visible;\r\n }\r\n}\r\n","import {\r\n calculatePointsPCA,\r\n DataProjectionCoordinate,\r\n GeocentricCoordinate,\r\n geometryToArray,\r\n SceneCoordinate\r\n} from '../projections';\r\nimport {MeasurementController} from '.';\r\nimport {getArea, getLength} from 'ol/sphere';\r\nimport {LineString, Polygon} from 'ol/geom';\r\nimport Delaunator from 'delaunator';\r\nimport earcut from 'earcut';\r\nimport {nanoid} from '@reduxjs/toolkit';\r\nimport {isMobile, pointInPolygon, randomHexColor} from '../utilities';\r\nimport {t} from '../../../localization';\r\nimport {\r\n BufferGeometry,\r\n DoubleSide,\r\n MathUtils,\r\n Mesh,\r\n MeshBasicMaterial,\r\n Triangle,\r\n Vector3,\r\n Vector2\r\n} from 'three';\r\nimport {spiralIntersect} from \"./land-xml-calculation\";\r\nimport {toast} from \"../../../app\";\r\nimport { PointCloudManager } from '../pointcloud';\r\nimport { MeasureType, SamplingRate, VolumeType } from '../../../types/measurements';\r\n\r\nexport type MeasurementType = MeasurementArea\r\n | MeasurementLine\r\n | MeasurementPoint\r\n | MeasurementVolume\r\n | SnapDownMeasurement\r\n | SnapUpMeasurement\r\n | HeightMeasurement\r\n | StationMeasurement\r\n\r\nexport class Measurement {\r\n public controller: MeasurementController;\r\n public id = nanoid();\r\n public type: MeasureType;\r\n private _header = 'measure.measurement';\r\n private _title = 'measure.measurement';\r\n public timeCreated = new Date();\r\n\r\n get title() {\r\n return t(this._title);\r\n }\r\n\r\n get header() {\r\n return t(this._header);\r\n }\r\n\r\n get timestamp() {\r\n return Math.floor(this.timeCreated.getTime() / 1000);\r\n }\r\n\r\n get cancelMessage() {\r\n return isMobile\r\n ? t('measure.long-press-to-cancel')\r\n : t('measure.right-click-to-cancel');\r\n }\r\n\r\n get startTooltip() {\r\n console.warn(\"Not Implemented\");\r\n return [] as string[];\r\n }\r\n\r\n get startTooltipMulti() {\r\n return [\r\n t('measure.click-to-add-observation-1')\r\n ];\r\n }\r\n\r\n get endTooltip() {\r\n console.warn(\"Not Implemented\");\r\n return [] as string[];\r\n }\r\n\r\n get endTooltipMulti() {\r\n console.warn(\"Not Implemented\");\r\n return [] as string[];\r\n }\r\n\r\n get moreTooltip() {\r\n console.warn(\"Not Implemented\");\r\n return [] as string[];\r\n }\r\n\r\n get moreTooltipMulti() {\r\n console.warn(\"Not Implemented\");\r\n return [] as string[];\r\n }\r\n\r\n get viewer() {\r\n return this.controller.viewer;\r\n }\r\n\r\n get pointclouds() {\r\n return this.controller.pointclouds;\r\n }\r\n\r\n get valid() {\r\n return true;\r\n }\r\n\r\n setController(controller) {\r\n this.controller = controller;\r\n }\r\n\r\n setTitle(title) {\r\n this._title = title;\r\n }\r\n\r\n setHeader(header) {\r\n this._header = header;\r\n }\r\n\r\n setTimestamp(isoTime) {\r\n this.timeCreated = new Date(isoTime);\r\n }\r\n\r\n clear() {}\r\n}\r\n\r\nexport class Measurement3D extends Measurement {\r\n public vertices:Array = [];\r\n public maxVertexLength = 2;\r\n public minVertexRequired = 2;\r\n public type = MeasureType.Length;\r\n\r\n constructor() {\r\n super();\r\n\r\n this.setTitle(\"measure.3d-measurement\");\r\n this.setHeader(\"measure.3d-measurement\");\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-start-line')\r\n ];\r\n }\r\n\r\n get canFinish() {\r\n return (this.vertices.length + 1) >= this.minVertexRequired;\r\n }\r\n\r\n get hasPoints() {\r\n return this.vertices.length > 0;\r\n }\r\n\r\n get numVertices() {\r\n return this.vertices.length;\r\n }\r\n\r\n /** Return 3d distance in meters, based on scene view coordinates */\r\n get distance3D() {\r\n return this.getLineDistance(false);\r\n }\r\n\r\n /** Return 2d distance in meters, based on scene view coordinates */\r\n get distance2D() {\r\n return this.getLineDistance(true);\r\n }\r\n\r\n /** Get measurement height difference in meters, based on scene view coordinates */\r\n get rise() {\r\n // Currently uses the first + last point\r\n let lastIndex = this.vertices.length - 1;\r\n let firstPoint = this.vertices[0].toScene();\r\n let lastPoint = this.vertices[lastIndex].toScene();\r\n let height = Math.abs(lastPoint.z - firstPoint.z);\r\n\r\n return height;\r\n }\r\n\r\n get angle() {\r\n let numberOfPoints = this.vertices.length;\r\n if (numberOfPoints !== 2) {\r\n return NaN;\r\n }\r\n\r\n let angle = Math.atan(this.rise / this.distance2D);\r\n return MathUtils.radToDeg(angle);\r\n }\r\n\r\n get grade() {\r\n let numberOfPoints = this.vertices.length;\r\n if (numberOfPoints !== 2) {\r\n return NaN;\r\n }\r\n\r\n return 100 * (this.rise / this.distance2D);\r\n }\r\n\r\n get coordinates() {\r\n return this.vertices.map(vertex => {\r\n return vertex.toArray();\r\n });\r\n }\r\n\r\n get sceneVertices() {\r\n return this.vertices.map(vertex => {\r\n return vertex.toScene().toArray();\r\n });\r\n }\r\n\r\n add(vertex) {\r\n let finished = false;\r\n let addedPoint = false;\r\n\r\n let coordinate = new SceneCoordinate(vertex).toGeocentric();\r\n\r\n if (this.vertices.length === 0) {\r\n this.vertices.push(coordinate);\r\n addedPoint = true;\r\n } else {\r\n // We only add a new point if the distance travelled is large enough\r\n let oldVertex = this.vertices[this.vertices.length - 1];\r\n if (oldVertex.distanceTo(coordinate) > 0.10) {\r\n // New point is far enough away from previous point\r\n this.vertices.push(coordinate);\r\n addedPoint = true;\r\n } else {\r\n // Clicked the same point twice, so we finish the measurement\r\n // if we have gathered enough points\r\n if (this.vertices.length >= this.minVertexRequired) {\r\n finished = true;\r\n }\r\n }\r\n }\r\n\r\n // For types with a fixed number of points, set finished to\r\n // true if we have reached the max number of points\r\n if (!finished) {\r\n finished = this.vertices.length === this.maxVertexLength;\r\n }\r\n\r\n return {\r\n finished: finished,\r\n added: addedPoint,\r\n valid: true\r\n };\r\n }\r\n\r\n getProjectedVertices(projection) {\r\n let vertices = this.vertices.map(vertex => {\r\n return vertex.toProjection(projection).toArray();\r\n });\r\n\r\n if (this instanceof MeasurementArea) {\r\n vertices.push(vertices[0]);\r\n }\r\n\r\n return vertices;\r\n }\r\n\r\n /** Private */\r\n getLineDistance(ignoreHeight) {\r\n let vertexA;\r\n let vertexB;\r\n\r\n let distance = 0;\r\n let vertices = this.vertices;\r\n\r\n for (var i = 1; i < vertices.length; i++) {\r\n let prevIndex = i - 1;\r\n vertexA = vertices[prevIndex].toScene();\r\n vertexB = vertices[i].toScene();\r\n\r\n if (ignoreHeight) {\r\n vertexA.z = 0;\r\n vertexB.z = 0;\r\n }\r\n\r\n distance += vertexA.distanceTo(vertexB);\r\n }\r\n\r\n return distance;\r\n }\r\n}\r\n\r\nexport class StationMeasurement extends Measurement3D {\r\n public type = MeasureType.Station;\r\n public distAlong = 0.0;\r\n public distAcross = 0.0;\r\n public stationStart = 0.0;\r\n public sideOfLine = 'R';\r\n private clickedPoint;\r\n private enu = false;\r\n public units = 'm';\r\n\r\n constructor() {\r\n super();\r\n\r\n this.setTitle(\"measure.station-measure\");\r\n this.setHeader(\"measure.station-info\");\r\n }\r\n\r\n get activeAlignment() {\r\n return this.controller.activeAlignment;\r\n }\r\n\r\n get alignmentInfo() {\r\n return this.controller.getAlignmentByID(this.activeAlignment);\r\n }\r\n\r\n get startTooltip() {\r\n if (this.activeAlignment) {\r\n return [\r\n t('measure.click-to-station')\r\n ];\r\n } else {\r\n return [\r\n t('measure.choose-alignment')\r\n ];\r\n }\r\n }\r\n\r\n get distanceAcross() {\r\n return this.distAcross;\r\n }\r\n\r\n get distanceAlong() {\r\n return this.distAlong;\r\n }\r\n\r\n get staStart() {\r\n return this.stationStart;\r\n }\r\n\r\n get sideOfSegment() {\r\n return this.sideOfLine;\r\n }\r\n\r\n isBetween(segment) {\r\n if (segment.shapeType === 'Curve') {\r\n const curveCheck = this.curveIntersect(segment, true);\r\n if (!curveCheck) {\r\n return false;\r\n }\r\n }\r\n\r\n const x1 = segment.Start[0];\r\n const x2 = segment.End[0];\r\n const x3 = this.clickedPoint[0];\r\n\r\n const y1 = segment.Start[1];\r\n const y2 = segment.End[1];\r\n const y3 = this.clickedPoint[1];\r\n\r\n const distEndsSquared = Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2);\r\n\r\n const u = ((x3-x1)*(x2-x1)+(y3-y1)*(y2-y1)) / distEndsSquared;\r\n const deltaX = x1 + u * (x2-x1);\r\n const deltaY = y1 + u * (y2-y1);\r\n\r\n const epsilon = 0.001;\r\n const crossProduct = (deltaY - y1) * (x2 - x1) - (deltaX - x1) * (y2 - y1);\r\n if (Math.abs(crossProduct) > epsilon) {\r\n return false;\r\n }\r\n\r\n const dotProduct = (deltaX - x1)*(x2 - x1) + (deltaY - y1)*(y2 - y1);\r\n return !(dotProduct < 0 || dotProduct > distEndsSquared);\r\n }\r\n\r\n getClosestSegment(segments) {\r\n let minDist;\r\n let chosenSegment;\r\n segments.forEach(segmentTest => {\r\n this.lineIntersect(segmentTest, true);\r\n if (!minDist) {\r\n minDist = this.distAcross;\r\n }\r\n if(this.distAcross<=minDist) {\r\n chosenSegment = segmentTest;\r\n minDist = this.distAcross;\r\n }\r\n });\r\n\r\n return chosenSegment;\r\n }\r\n\r\n lineIntersect(segment, checkOnly=false) {\r\n const x1 = segment.Start[0];\r\n const x2 = segment.End[0];\r\n const x3 = this.clickedPoint[0];\r\n\r\n const y1 = segment.Start[1];\r\n const y2 = segment.End[1];\r\n const y3 = this.clickedPoint[1];\r\n\r\n const distEndsSquared = Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2);\r\n\r\n const u = ((x3-x1)*(x2-x1)+(y3-y1)*(y2-y1)) / distEndsSquared;\r\n const deltaX = x1 + u * (x2-x1);\r\n const deltaY = y1 + u * (y2-y1);\r\n\r\n let intersectCoordinate;\r\n let clickedCoordinate;\r\n let startCoordinate;\r\n\r\n if (this.enu){\r\n clickedCoordinate = new DataProjectionCoordinate(\r\n [this.clickedPoint[0], this.clickedPoint[1],\r\n this.clickedPoint[2]]);\r\n startCoordinate = new DataProjectionCoordinate([x1, y1,\r\n this.clickedPoint[2]]);\r\n intersectCoordinate = new DataProjectionCoordinate(\r\n [deltaX, deltaY, this.clickedPoint[2]]);\r\n } else {\r\n clickedCoordinate = new DataProjectionCoordinate(\r\n [this.clickedPoint[1], this.clickedPoint[0],\r\n this.clickedPoint[2]]);\r\n startCoordinate = new DataProjectionCoordinate([y1, x1,\r\n this.clickedPoint[2]]);\r\n intersectCoordinate = new DataProjectionCoordinate(\r\n [deltaY, deltaX, this.clickedPoint[2]]);\r\n }\r\n\r\n if (!checkOnly) {\r\n this.vertices.unshift(intersectCoordinate.toGeocentric());\r\n }\r\n\r\n const distAlong = new Vector2(...startCoordinate)\r\n .distanceTo(new Vector2(...intersectCoordinate));\r\n\r\n const distAcross = new Vector2(...clickedCoordinate)\r\n .distanceTo(new Vector2(...intersectCoordinate));\r\n\r\n const sideValue = (x1-x2)*(y3-y2) - (y1-y2)*(x3-x2);\r\n const side = sideValue > 0 ? 'L':'R';\r\n\r\n this.distAlong = distAlong;\r\n this.distAcross = distAcross;\r\n this.sideOfLine = side;\r\n // console.log(`across: ${this.distAcross} | along: ${this.distAlong} | side: ${this.sideOfLine}`);\r\n\r\n return true;\r\n }\r\n\r\n curveIntersect(segment, checkOnly=false) {\r\n const rotation = segment.rot;\r\n const radius = segment.radius;\r\n const center = segment.Center.slice(0, 2);\r\n const point = this.clickedPoint;\r\n\r\n const distance = Math.sqrt(Math.pow(center[0] - point[0], 2)\r\n + Math.pow(center[1] - point[1], 2));\r\n\r\n const distAcross = radius - distance;\r\n\r\n const pointVector = [(point[0] - center[0]) / distance,\r\n (point[1] - center[1]) / distance];\r\n\r\n const startVector = [(segment.Start[0] - center[0]) / radius,\r\n (segment.Start[1] - center[1]) / radius];\r\n\r\n const endVector = [(segment.End[0] - center[0]) / radius,\r\n (segment.End[1] - center[1]) / radius];\r\n\r\n let pointArc = [center[0] + (radius*pointVector[0]),\r\n center[1]+(radius*pointVector[1])];\r\n\r\n const distStartToArc = Math.sqrt(Math.pow(pointArc[0] - segment.Start[0], 2)\r\n + Math.pow(segment.Start[1] - pointArc[1], 2));\r\n\r\n const calcAngle = Math.acos(1 - (distStartToArc * distStartToArc) /\r\n (2 * radius * radius));\r\n\r\n let angle = Math.atan2(pointVector[1], pointVector[0]);\r\n angle = (angle < 0) ? angle + Math.PI*2 : angle;\r\n let angleStart = Math.atan2(startVector[1], startVector[0]);\r\n angleStart = (angleStart < 0) ? angleStart + Math.PI*2 : angleStart;\r\n let angleEnd = Math.atan2(endVector[1], endVector[0]);\r\n angleEnd = (angleEnd < 0) ? angleEnd + Math.PI*2 : angleEnd;\r\n let angleLarge = (angleStart > angleEnd) ? angleStart : angleEnd;\r\n let angleSmall = (angleStart < angleEnd) ? angleStart : angleEnd;\r\n let angleSmallQuadrant = angleSmall;\r\n let angleLargeQuadrant = angleLarge;\r\n let angleQuadrant = angle;\r\n\r\n // console.log(`original rotations: ${angle} | ${angleStart} | ${angleEnd}`)\r\n // console.log(`original size rotations: ${angle} | ${angleSmall} | ${angleLarge}`)\r\n\r\n if ((angleSmall > 0) && (angleSmall < Math.PI/2)) {\r\n // console.log('small angle check')\r\n if ((angleLarge < Math.PI*2) && (angleLarge > Math.PI * 1.5)) {\r\n // console.log('big angle check')\r\n angleLargeQuadrant = angleSmall + (Math.PI/2);\r\n angleLargeQuadrant = (angleLargeQuadrant > Math.PI*2) ? angleLargeQuadrant - Math.PI*2 : angleLargeQuadrant;\r\n angleSmallQuadrant = angleLarge + (Math.PI/2);\r\n angleSmallQuadrant = (angleSmallQuadrant > Math.PI*2) ? angleSmallQuadrant - Math.PI*2 : angleSmallQuadrant;\r\n angleQuadrant += (Math.PI/2);\r\n angleQuadrant = (angleQuadrant > Math.PI*2) ? angleQuadrant - Math.PI*2 : angleQuadrant;\r\n }\r\n }\r\n // console.log(`altered size rotations: ${angleQuadrant} | ${angleSmallQuadrant} | ${angleLargeQuadrant}`)\r\n let angleReverse = angleQuadrant - Math.PI;\r\n angleReverse = (angleReverse < 0) ? angleReverse + Math.PI*2 : angleReverse;\r\n\r\n if ((angleQuadrant <= angleSmallQuadrant) || (angleQuadrant >= angleLargeQuadrant)) {\r\n if ((angleReverse <= angleSmallQuadrant) || (angleReverse >= angleLargeQuadrant)) {\r\n // console.log(`failed rotations: ${angleReverse} | ${angleSmallQuadrant} | ${angleLargeQuadrant}`)\r\n return false;\r\n }\r\n // console.log(`succeeded rotations: ${angleReverse} | ${angleSmallQuadrant} | ${angleLargeQuadrant}`)\r\n }\r\n\r\n const distAlong = radius * calcAngle;\r\n\r\n if (rotation === \"ccw\"){\r\n if (distAcross > 0){\r\n this.sideOfLine = \"L\";\r\n } else {\r\n this.sideOfLine = \"R\";\r\n }\r\n } else if (rotation === \"cw\") {\r\n if (distAcross > 0) {\r\n this.sideOfLine = \"R\";\r\n } else {\r\n this.sideOfLine = \"L\";\r\n }\r\n } else {\r\n console.error(`Rotation Type ${rotation} is invalid for this geometry`);\r\n return false;\r\n }\r\n\r\n if (!checkOnly){\r\n this.distAcross = Math.abs(distAcross);\r\n this.distAlong = distAlong;\r\n let coordinate;\r\n if (this.enu){\r\n coordinate = new DataProjectionCoordinate(\r\n [pointArc[0], pointArc[1], this.clickedPoint[2]]).toGeocentric();\r\n } else {\r\n coordinate = new DataProjectionCoordinate(\r\n [pointArc[1], pointArc[0], this.clickedPoint[2]]).toGeocentric();\r\n }\r\n this.vertices.unshift(coordinate);\r\n // console.log(`across: ${this.distAcross} | along: ${this.distAlong} | side: ${this.sideOfLine}`);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n spiralIntersection(spiral) {\r\n const results = spiralIntersect(spiral, this.clickedPoint);\r\n if (!results) return false;\r\n\r\n let coordinate;\r\n if (this.enu){\r\n coordinate = new DataProjectionCoordinate(\r\n [results.coordinates[0], results.coordinates[1],\r\n this.clickedPoint[2]]).toGeocentric();\r\n } else {\r\n coordinate = new DataProjectionCoordinate(\r\n [results.coordinates[1], results.coordinates[0],\r\n this.clickedPoint[2]]).toGeocentric();\r\n }\r\n this.distAlong = results.distAlong;\r\n this.distAcross = results.distAcross;\r\n this.sideOfLine = results.sideOfLine;\r\n this.vertices.unshift(coordinate);\r\n }\r\n\r\n getIntersect(segment) {\r\n this.stationStart = segment.staStart;\r\n if (segment.shapeType === \"Line\") {\r\n return this.lineIntersect(segment);\r\n } else if (segment.shapeType === \"Curve\") {\r\n return this.curveIntersect(segment);\r\n } else if (segment.shapeType === \"Spiral\") {\r\n return this.spiralIntersection(segment);\r\n } else {\r\n console.error('Unknown Shape type in XML file');\r\n return false;\r\n }\r\n }\r\n\r\n add(vertex) {\r\n let finished = false;\r\n let addedPoint = false;\r\n let valid = false;\r\n\r\n const coordinate = new SceneCoordinate(vertex).toGeocentric();\r\n const clickPointInData = new SceneCoordinate(vertex).toDataProjection();\r\n\r\n const alignmentInfo = this.alignmentInfo;\r\n const enu = alignmentInfo.enu;\r\n const xmlAlignment = alignmentInfo.alignment;\r\n\r\n let units;\r\n if (alignmentInfo.units === \"meter\") {\r\n units = \"m\";\r\n } else if (alignmentInfo.units === \"USSurveyFoot\") {\r\n units = \"sft\";\r\n } else {\r\n units = \"ft\";\r\n }\r\n this.units = units;\r\n\r\n if (!xmlAlignment) {\r\n toast.warning(t(\"toast.station-no-alignment\"));\r\n return {\r\n finished: finished,\r\n added: addedPoint,\r\n valid: valid\r\n };\r\n }\r\n\r\n this.enu = enu;\r\n\r\n if (this.enu) {\r\n this.clickedPoint = [clickPointInData.x, clickPointInData.y, clickPointInData.z];\r\n } else {\r\n this.clickedPoint = [clickPointInData.y, clickPointInData.x, clickPointInData.z];\r\n }\r\n\r\n const segments = xmlAlignment.geometry.filter(segment => this.isBetween(segment));\r\n const segment = this.getClosestSegment(segments);\r\n\r\n if (segment) {\r\n finished = this.getIntersect(segment);\r\n if (finished) {\r\n this.vertices.push(coordinate);\r\n addedPoint = true;\r\n const allCoords = this.vertices;\r\n valid = (allCoords.length === 2);\r\n }\r\n } else {\r\n toast.warning(t(\"toast.station-no-segment\"));\r\n }\r\n\r\n return {\r\n finished: finished,\r\n added: addedPoint,\r\n valid: valid\r\n };\r\n }\r\n\r\n loadExistingStation(measurement) {\r\n this.distAlong = measurement.along;\r\n this.distAcross = Math.abs(measurement.across);\r\n this.stationStart = measurement.station;\r\n this.sideOfLine = (measurement.across > 0) ? 'R' : 'L';\r\n this.units = measurement.units;\r\n }\r\n}\r\n\r\nexport class MeasurementLine extends Measurement3D {\r\n public maxVertexLength = 16;\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n get moreTooltip() {\r\n return [\r\n t('measure.click-to-add-more-points', {\r\n count: this.numVertices\r\n }),\r\n t('measure.double-click-to-finish'),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get moreTooltipMulti() {\r\n return [\r\n t('measure.click-to-add-observation-1-multiple', {\r\n count: this.numVertices\r\n }),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get endTooltip() {\r\n return this.moreTooltip;\r\n }\r\n\r\n get endTooltipMulti() {\r\n return [\r\n t('measure.click-to-add-observation-1'),\r\n t('measure.number-of-points', {\r\n count: this.numVertices\r\n }),\r\n this.cancelMessage\r\n ];\r\n }\r\n}\r\n\r\nexport class MeasurementPoint extends Measurement3D {\r\n public type = MeasureType.Point;\r\n public maxVertexLength = 1;\r\n public minVertexRequired = 1;\r\n\r\n constructor() {\r\n super();\r\n\r\n this.setTitle(\"measure.3d-point\");\r\n this.setHeader(\"measure.3d-point\");\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-for-single-point')\r\n ];\r\n }\r\n}\r\n\r\nexport class MeasurementArea extends Measurement3D {\r\n public surfaceGenerator;\r\n public type = MeasureType.Area;\r\n public maxVertexLength = 16;\r\n public minVertexRequired = 3;\r\n\r\n constructor() {\r\n super();\r\n\r\n this.setTitle(\"measure.3d-area\");\r\n this.setHeader(\"measure.3d-area\");\r\n }\r\n\r\n get areaInvalidMessage() {\r\n return t('measure.invalid-area');\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-start-area')\r\n ];\r\n }\r\n\r\n get moreTooltip() {\r\n return [\r\n t('measure.click-to-add-more-points', {\r\n count: this.numVertices\r\n }),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get moreTooltipMulti() {\r\n return [\r\n t('measure.click-to-add-observation-1-multiple', {\r\n count: this.numVertices\r\n }),\r\n t('measure.number-of-points', {\r\n count: this.numVertices\r\n }),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get endTooltip() {\r\n return [\r\n t('measure.click-to-add-more-points', {\r\n count: this.numVertices\r\n }),\r\n t('measure.double-click-to-finish'),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get endTooltipMulti() {\r\n return [\r\n t('measure.click-to-add-observation-1'),\r\n t('measure.number-of-points', {\r\n count: this.numVertices\r\n }),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get surfaceVertices() {\r\n return this.surfaceGenerator.vertices;\r\n }\r\n\r\n get surfaceIndices() {\r\n return this.surfaceGenerator.indices;\r\n }\r\n\r\n get area3D() {\r\n return this.surfaceGenerator.area;\r\n }\r\n\r\n get valid() {\r\n return this.surfaceGenerator.valid;\r\n }\r\n\r\n setController(controller) {\r\n this.controller = controller;\r\n this.surfaceGenerator = new SurfaceGenerator(this);\r\n }\r\n\r\n generateSurface(temporaryPoint: SceneCoordinate = null) {\r\n this.surfaceGenerator.clear();\r\n this.surfaceGenerator.generate(temporaryPoint);\r\n }\r\n\r\n clear() {\r\n this.surfaceGenerator.clear();\r\n }\r\n}\r\n\r\nexport class MeasurementVolume extends MeasurementArea {\r\n public volumeHelper: VolumeHelper;\r\n public type = MeasureType.Volume;\r\n\r\n constructor() {\r\n super();\r\n\r\n this.setHeader(\"measure.3d-volume\");\r\n this.setTitle(\"measure.3d-volume\");\r\n }\r\n\r\n get invalidVolumeMessage() {\r\n return t('measure.invalid-volume');\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-start-volume')\r\n ];\r\n }\r\n\r\n get calculated() {\r\n return this.volumeHelper.calculated;\r\n }\r\n\r\n get calculating() {\r\n return this.volumeHelper.calculatingVolume;\r\n }\r\n\r\n get volumeType() {\r\n return this.controller.volumeType;\r\n }\r\n\r\n get sampleRate() {\r\n return this.controller.sampleRate;\r\n }\r\n\r\n get volume() {\r\n return this.volumeHelper.value;\r\n }\r\n\r\n async calculateVolume() {\r\n this.volumeHelper.clear();\r\n this.volumeHelper.setSampleRate(this.sampleRate);\r\n this.volumeHelper.setVolumeType(this.volumeType);\r\n\r\n await this.volumeHelper.calculate();\r\n\r\n this.controller.renderMeasurement(this);\r\n this.controller.refreshMeasurementList();\r\n }\r\n\r\n /** Cancel webworker and pass empty array as results */\r\n stopVolumeCalculation() {\r\n this.volumeHelper.stopCalculation();\r\n }\r\n\r\n setController(controller) {\r\n this.controller = controller;\r\n this.volumeHelper = new VolumeHelper(this, this.pointclouds);\r\n this.surfaceGenerator = new SurfaceGenerator(this);\r\n }\r\n\r\n loadExistingVolume(value) {\r\n if (!value) return;\r\n this.volumeHelper.setVolume(value);\r\n }\r\n\r\n clear() {\r\n this.volumeHelper.destroyWorker();\r\n this.volumeHelper.clear();\r\n this.surfaceGenerator.clear();\r\n }\r\n}\r\n\r\nexport class HeightMeasurement extends Measurement3D {\r\n public type = MeasureType.Height\r\n\r\n constructor() {\r\n super();\r\n\r\n this.setTitle(\"measure.height-measurement\");\r\n this.setHeader(\"measure.height-measurement\");\r\n }\r\n\r\n get moreTooltip() {\r\n return [\r\n t('measure.select_another_point_to_finish'),\r\n this.cancelMessage\r\n ];\r\n }\r\n\r\n get height() {\r\n let vertex0 = this.vertices[0].toScene();\r\n let vertex1 = this.vertices[1].toScene();\r\n return Math.abs(vertex0.z - vertex1.z);\r\n }\r\n}\r\n\r\nexport class SnapMeasurement extends Measurement3D {\r\n constructor() {\r\n super();\r\n }\r\n\r\n add(vertex) {\r\n let valid = false;\r\n let added = false;\r\n let snapResult = this.snap(vertex);\r\n\r\n let coordinate = new SceneCoordinate(vertex).toGeocentric();\r\n this.vertices.push(coordinate);\r\n\r\n if (snapResult) {\r\n valid = true;\r\n added = true;\r\n\r\n let snapCoordinate = new SceneCoordinate(snapResult).toGeocentric();\r\n this.vertices.push(snapCoordinate);\r\n }\r\n\r\n return {\r\n finished: true,\r\n added: added,\r\n valid: valid\r\n };\r\n }\r\n\r\n snap(vertex) {\r\n let verticalTolerance = 0.30;\r\n let finalHeight;\r\n let validHeights;\r\n\r\n let pos = new Vector3().copy(vertex);\r\n let points = this.pointclouds.pointsInRadius(pos, 0.15);\r\n let heights = points.map(point => point.z);\r\n\r\n if (this instanceof SnapDownMeasurement) {\r\n validHeights = heights.filter(height => vertex.z - height > verticalTolerance);\r\n } else {\r\n validHeights = heights.filter(height => height - vertex.z > verticalTolerance);\r\n }\r\n\r\n if (validHeights.length === 0) {\r\n return undefined;\r\n }\r\n\r\n if (this instanceof SnapDownMeasurement) {\r\n finalHeight = validHeights.reduce((acc, curr) => Math.max(acc, curr));\r\n } else {\r\n finalHeight = validHeights.reduce((acc, curr) => Math.min(acc, curr));\r\n }\r\n\r\n return new Vector3(vertex.x, vertex.y, finalHeight);\r\n }\r\n}\r\n\r\nexport class SnapUpMeasurement extends SnapMeasurement {\r\n constructor() {\r\n super();\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-snap-up')\r\n ];\r\n }\r\n}\r\n\r\nexport class SnapDownMeasurement extends SnapMeasurement {\r\n constructor() {\r\n super();\r\n }\r\n\r\n get startTooltip() {\r\n return [\r\n t('measure.click-to-snap-down')\r\n ];\r\n }\r\n}\r\n\r\nexport class AerialMeasurement extends Measurement {\r\n public geometry;\r\n\r\n constructor(geometry = null) {\r\n super();\r\n\r\n this.setTitle(null);\r\n this.setHeader(\"measure.2d-measurement\");\r\n this.geometry = geometry;\r\n }\r\n\r\n get coordinates() {\r\n return this.geometry.getCoordinates();\r\n }\r\n\r\n get numVertices() {\r\n return this.coordinates[0].length;\r\n }\r\n\r\n getGeometry() {\r\n return this.geometry;\r\n }\r\n\r\n getProjectedVertices(projection) {\r\n return geometryToArray(this.geometry, projection);\r\n }\r\n\r\n loadFromCoordinates(coordinates) {}\r\n}\r\n\r\nexport class AerialLengthMeasurement extends AerialMeasurement {\r\n public type = MeasureType.Length;\r\n\r\n constructor(geometry = null) {\r\n super(geometry);\r\n\r\n this.setTitle(\"measure.2d-length\");\r\n this.setHeader(\"measure.length\");\r\n }\r\n\r\n get distance2D() {\r\n return getLength(this.geometry);\r\n }\r\n\r\n loadFromCoordinates(coordinates) {\r\n this.geometry = new LineString(coordinates);\r\n }\r\n}\r\n\r\nexport class AerialAreaMeasurement extends AerialMeasurement {\r\n public type = MeasureType.Area\r\n\r\n constructor(geometry = null) {\r\n super(geometry);\r\n\r\n this.setTitle(\"measure.2d-area\");\r\n this.setHeader(\"measure.area\");\r\n }\r\n\r\n get numVertices() {\r\n return this.coordinates[0].length - 1;\r\n }\r\n\r\n get area2d() {\r\n return getArea(this.geometry);\r\n }\r\n\r\n loadFromCoordinates(coordinates) {\r\n this.geometry = new Polygon(coordinates);\r\n }\r\n}\r\n\r\nclass VolumeHelper {\r\n private measurement: MeasurementVolume;\r\n private pointclouds: PointCloudManager;\r\n public calculatingVolume = false;\r\n public calculated = false;\r\n public value = 0.0;\r\n private sigma = 2.0;\r\n private numNeighbours = 10;\r\n private sampleRate = SamplingRate.Medium;\r\n private volumeType = VolumeType.MultiPlane;\r\n private worker = null;\r\n private vertices;\r\n private bounds;\r\n private meshes = [];\r\n\r\n constructor(measurement, pointclouds) {\r\n this.measurement = measurement;\r\n this.pointclouds = pointclouds;\r\n this.initWebworker();\r\n this.clear();\r\n }\r\n\r\n get scene() {\r\n return this.measurement.controller.scene;\r\n }\r\n\r\n setVolumeType(type: VolumeType) {\r\n this.volumeType = type;\r\n }\r\n\r\n setSampleRate(rate: SamplingRate) {\r\n this.sampleRate = rate;\r\n }\r\n\r\n async calculate() {\r\n if (this.calculatingVolume) return;\r\n\r\n this.vertices = this.measurement.vertices.map(vertex => {\r\n return vertex.toScene();\r\n });\r\n\r\n if (this.volumeType === VolumeType.LowestPlane) {\r\n const minHeight = Math.min(...this.vertices.map(x => x.z));\r\n this.vertices.forEach(vertex => {\r\n vertex.z = minHeight;\r\n });\r\n }\r\n\r\n this.bounds = this.getCalculatedBounds();\r\n\r\n await this.calculateVolume();\r\n }\r\n\r\n initWebworker() {\r\n const workerURL = \"workers/sparse-outliers.js\";\r\n this.worker = new Worker(`${process.env.PUBLIC_URL}/${workerURL}`);\r\n }\r\n\r\n getCalculatedBounds() {\r\n let arr = this.vertices;\r\n\r\n let x = arr.map(vertex => vertex.x);\r\n let xMin = Math.min(...x);\r\n let xMax = Math.max(...x);\r\n\r\n let y = arr.map(vertex => vertex.y);\r\n let yMin = Math.min(...y);\r\n let yMax = Math.max(...y);\r\n\r\n let z = arr.map(vertex => vertex.z);\r\n let zMin = Math.min(...z);\r\n let zMax = Math.max(...z);\r\n\r\n let center = new Vector3(\r\n xMin + (xMax - xMin) / 2.0,\r\n yMin + (yMax - yMin) / 2.0,\r\n zMin + (zMax - zMin) / 2.0\r\n );\r\n\r\n let size = Math.max(xMax - xMin, yMax - yMin);\r\n\r\n return {\r\n center: center,\r\n size: size\r\n };\r\n }\r\n\r\n async removeOutliers(points): Promise {\r\n return new Promise(resolve => {\r\n this.worker.onmessage = event => {\r\n resolve(event.data);\r\n };\r\n\r\n this.worker.postMessage({\r\n points: points,\r\n sigma: this.sigma,\r\n numNeighbours: this.numNeighbours\r\n });\r\n });\r\n }\r\n\r\n destroyWorker() {\r\n if (!this.worker) return;\r\n\r\n this.worker.terminate();\r\n this.initWebworker();\r\n }\r\n\r\n drawMesh(points, triangles) {\r\n const material = new MeshBasicMaterial({\r\n color: 0xFFFFFF, side: DoubleSide});\r\n\r\n const indices = triangles.flat();\r\n const geometry = new BufferGeometry().setFromPoints(points);\r\n geometry.setIndex(indices);\r\n\r\n const mesh = new Mesh(geometry, material);\r\n\r\n this.meshes.push(mesh);\r\n this.scene.add(mesh);\r\n }\r\n\r\n setVolume(value) {\r\n this.calculated = true;\r\n this.value = value;\r\n }\r\n\r\n getVolume(points, triangles) {\r\n let volume = 0;\r\n triangles.forEach(tri => {\r\n let p1 = points[tri[0]].clone();\r\n let p2 = points[tri[1]].clone();\r\n let p3 = points[tri[2]].clone();\r\n let signedTetrahedronVolume = p1.dot(p2.cross(p3)) / 6.0;\r\n volume += signedTetrahedronVolume;\r\n });\r\n\r\n return volume;\r\n }\r\n\r\n generateTriangleArray(buffer, reverse = false) {\r\n let arr = Array.from(buffer);\r\n let v1 = arr.filter((v, index) => index % 3 === 0);\r\n let v2 = arr.filter((v, index) => index % 3 === 1);\r\n let v3 = arr.filter((v, index) => index % 3 === 2);\r\n let final = [];\r\n for (var i = 0; i < arr.length / 3; i++) {\r\n let vertices = [v1[i], v2[i], v3[i]];\r\n if (reverse) {\r\n vertices = [v1[i], v3[i], v2[i]];\r\n }\r\n final.push(vertices);\r\n }\r\n\r\n return final;\r\n }\r\n\r\n removeInvalidTriangles(points, triangles) {\r\n let validTriangles = [];\r\n triangles.forEach(triangle => {\r\n let p1 = points[triangle[0]];\r\n let p2 = points[triangle[1]];\r\n let p3 = points[triangle[2]];\r\n\r\n let tri = new Triangle(p1, p2, p3);\r\n let center = new Vector3();\r\n tri.getMidpoint(center);\r\n let valid = pointInPolygon(center, this.vertices);\r\n\r\n if (valid) {\r\n validTriangles.push(triangle);\r\n }\r\n });\r\n\r\n return validTriangles;\r\n }\r\n\r\n getDelaunayTriangles(points, reverseWinding) {\r\n let xFunc = point => {\r\n return point.x;\r\n };\r\n\r\n let yFunc = point => {\r\n return point.y;\r\n };\r\n\r\n let delaunay = Delaunator.from(points, xFunc, yFunc);\r\n\r\n let triangles = this.generateTriangleArray(delaunay.triangles, reverseWinding);\r\n triangles = this.removeInvalidTriangles(points, triangles);\r\n\r\n return triangles;\r\n }\r\n\r\n async calculateVolume() {\r\n this.calculatingVolume = true;\r\n this.measurement.controller.refreshMeasurementList();\r\n\r\n // Create a more dense version of our boundary polygon\r\n let denseBounds = getDensePolygon(this.vertices, this.sampleRate);\r\n\r\n // Query points for this bounding box\r\n let points = this.pointclouds.pointsInRadius(this.bounds.center,\r\n this.bounds.size / 2.0);\r\n\r\n // Get the points inside a polygon only\r\n points = this.pointclouds.pointsInPolygon(points, this.vertices);\r\n\r\n const callback = point => {\r\n let x = Math.floor(point.x / this.sampleRate);\r\n let y = Math.floor(point.y / this.sampleRate);\r\n return `${x}-${y}`;\r\n };\r\n\r\n // Calculate DTM for points, in a 2d grid\r\n points = this.pointclouds.getSampledPoints(points, true, callback);\r\n\r\n // Remove sparse outliers\r\n points = await this.removeOutliers(points);\r\n\r\n this.calculationFinished(points, denseBounds);\r\n }\r\n\r\n calculationFinished(points, denseBounds=[]) {\r\n this.destroyWorker();\r\n\r\n if (points.length !== 0) {\r\n this.webWorkerFinished(points, denseBounds);\r\n }\r\n\r\n this.calculatingVolume = false;\r\n this.measurement.controller.refreshMeasurementList();\r\n }\r\n\r\n /** @private */\r\n webWorkerFinished(pointsArray, denseBounds) {\r\n const points = pointsArray.map(point => {\r\n return new Vector3().copy(point);\r\n });\r\n\r\n // Calculate upper mesh with reverse winding order\r\n const upperPoints = [...denseBounds, ...points];\r\n const trianglesUpper = this.getDelaunayTriangles(\r\n upperPoints, true);\r\n\r\n // Calculate lower mesh\r\n const lowerPoints = [...denseBounds];\r\n const trianglesLower = this.getDelaunayTriangles(\r\n lowerPoints, false);\r\n\r\n const trianglesCombined = [\r\n ...trianglesLower,\r\n ...trianglesUpper\r\n ];\r\n\r\n this.value = this.getVolume(upperPoints, trianglesCombined);\r\n this.drawMesh(upperPoints, trianglesCombined);\r\n this.calculated = true;\r\n }\r\n\r\n /** @private */\r\n stopCalculation() {\r\n if (!this.calculatingVolume) return;\r\n this.calculationFinished([]);\r\n }\r\n\r\n clear() {\r\n this.meshes.forEach(mesh => {\r\n this.scene.remove(mesh);\r\n });\r\n\r\n this.meshes = [];\r\n this.value = null;\r\n this.calculatingVolume = false;\r\n this.calculated = false;\r\n }\r\n}\r\n\r\nclass SurfaceGenerator {\r\n private measurement: MeasurementArea;\r\n private changeRequired = 0.01;\r\n private renderInScene = false;\r\n private indices = [];\r\n private meshes = [];\r\n public vertices = [];\r\n public area = 0;\r\n\r\n constructor(measurement) {\r\n this.measurement = measurement;\r\n this.clear();\r\n }\r\n\r\n get scene() {\r\n let measurement = this.measurement;\r\n return measurement.controller.scene;\r\n }\r\n\r\n get valid() {\r\n return this.indices.length > 0;\r\n }\r\n\r\n clear() {\r\n this.removeMeshesFromScene();\r\n this.indices = [];\r\n this.meshes = [];\r\n }\r\n\r\n addMeshesToScene() {\r\n if (!this.meshes || !this.renderInScene) {\r\n return;\r\n }\r\n\r\n this.meshes.forEach(mesh => {\r\n this.scene.add(mesh);\r\n });\r\n }\r\n\r\n removeMeshesFromScene() {\r\n if (!this.meshes || !this.renderInScene) {\r\n return;\r\n }\r\n\r\n this.meshes.forEach(mesh => {\r\n this.scene.remove(mesh);\r\n });\r\n }\r\n\r\n generateMesh(triangle) {\r\n let hexColor = randomHexColor(); // TODO: remove random coloring later\r\n\r\n const vertices = [triangle.a, triangle.b, triangle.c];\r\n const geometry = new BufferGeometry()\r\n .setFromPoints(vertices);\r\n\r\n const material = new MeshBasicMaterial({\r\n color: hexColor,\r\n side: DoubleSide\r\n });\r\n\r\n const mesh = new Mesh(geometry, material);\r\n\r\n return mesh;\r\n }\r\n\r\n calculateArea() {\r\n let area = 0;\r\n\r\n this.indices.forEach(indices => {\r\n let triangle = new Triangle(\r\n this.vertices[indices[0]],\r\n this.vertices[indices[1]],\r\n this.vertices[indices[2]]\r\n );\r\n area += triangle.getArea();\r\n });\r\n\r\n this.area = area;\r\n }\r\n\r\n optimize(vertices, triangleIndices) {\r\n let verticesModified = false;\r\n let numIndices = triangleIndices.length;\r\n\r\n for (var triIndexA = 0; triIndexA < numIndices; triIndexA++) {\r\n for (var triIndexB = 0; triIndexB < numIndices; triIndexB++) {\r\n if (verticesModified) {\r\n continue;\r\n }\r\n\r\n let triA = triangleIndices[triIndexA];\r\n let triB = triangleIndices[triIndexB];\r\n\r\n let vertSet = new Set([...triA, ...triB]);\r\n let allVerts = Array.from(vertSet);\r\n if (allVerts.length !== 4) {\r\n continue;\r\n }\r\n\r\n let sharedVerts = triA.filter(x => triB.includes(x));\r\n let uniqueVerts = allVerts.filter(x => !sharedVerts.includes(x));\r\n\r\n let modTriA = [...uniqueVerts, sharedVerts[0]];\r\n let modTriB = [...uniqueVerts, sharedVerts[1]];\r\n\r\n let t1 = new Triangle(vertices[triA[0]],\r\n vertices[triA[1]], vertices[triA[2]]);\r\n let t2 = new Triangle(vertices[triB[0]],\r\n vertices[triB[1]], vertices[triB[2]]);\r\n let oldArea = t1.getArea() + t2.getArea();\r\n\r\n let t3 = new Triangle(vertices[modTriA[0]],\r\n vertices[modTriA[1]], vertices[modTriA[2]]);\r\n let t4 = new Triangle(vertices[modTriB[0]],\r\n vertices[modTriB[1]], vertices[modTriB[2]]);\r\n let newArea = t3.getArea() + t4.getArea();\r\n\r\n // New area must be smaller\r\n if (newArea > oldArea) {\r\n continue;\r\n }\r\n\r\n // Difference between areas must be non-trivial\r\n let diff = (oldArea - newArea) / oldArea;\r\n if (diff < this.changeRequired) {\r\n continue;\r\n }\r\n\r\n triangleIndices[triIndexA] = modTriA;\r\n triangleIndices[triIndexB] = modTriB;\r\n verticesModified = true;\r\n }\r\n }\r\n\r\n if (verticesModified) {\r\n return this.optimize(vertices, triangleIndices);\r\n }\r\n\r\n return triangleIndices;\r\n }\r\n\r\n generate(temporaryPoint: SceneCoordinate) {\r\n this.vertices = this.measurement.vertices.map(vertex => {\r\n return vertex.toScene();\r\n });\r\n\r\n if (temporaryPoint) {\r\n this.vertices.push(temporaryPoint);\r\n }\r\n\r\n let numVertices = this.vertices.length;\r\n let triangles = [];\r\n\r\n if (numVertices === 3) {\r\n triangles.push([0, 1, 2]);\r\n } else if (numVertices > 3) {\r\n let points = calculatePointsPCA(this.vertices, true);\r\n let indices = earcut(points, null, 3);\r\n let deviation = earcut.deviation(points, null, 3, indices);\r\n\r\n // Deviation must be nearly zero to be valid\r\n if (deviation > 1E-6) {\r\n return;\r\n }\r\n\r\n let triangleIndices = [];\r\n let numTriangles = indices.length / 3;\r\n for (var i = 0; i < numTriangles; i++) {\r\n triangleIndices.push([\r\n indices[3 * i],\r\n indices[3 * i + 1],\r\n indices[3 * i + 2]\r\n ]);\r\n }\r\n\r\n // Optimized surface meshes\r\n triangleIndices = this.optimize(this.vertices, triangleIndices);\r\n\r\n triangleIndices.forEach(triVertices => {\r\n triangles.push(triVertices);\r\n });\r\n }\r\n\r\n let meshes = [];\r\n triangles.forEach(indices => {\r\n let triangle = new Triangle(\r\n this.vertices[indices[0]],\r\n this.vertices[indices[1]],\r\n this.vertices[indices[2]]\r\n );\r\n let mesh = this.generateMesh(triangle);\r\n meshes.push(mesh);\r\n });\r\n\r\n this.indices = triangles;\r\n this.meshes = meshes;\r\n\r\n this.addMeshesToScene();\r\n this.calculateArea();\r\n }\r\n}\r\n\r\nconst getDensePolygon = (vertices, spacing) => {\r\n let densePolygonTemp = [];\r\n\r\n vertices.forEach((start, index) => {\r\n let nextIndex = (index + 1) % vertices.length;\r\n\r\n let end = vertices[nextIndex];\r\n let direction = new Vector3().add(end).sub(start);\r\n let vectorLength = direction.length();\r\n let steps = Math.floor(vectorLength / spacing);\r\n let increment = vectorLength / steps;\r\n direction.setLength(1.0);\r\n\r\n if (steps === 0) {\r\n densePolygonTemp.push(start);\r\n return;\r\n }\r\n\r\n for (var i = 0; i <= steps; i++) {\r\n let directionIncrement = new Vector3().add(direction)\r\n .multiplyScalar(increment * i);\r\n let final = new Vector3().add(start).add(directionIncrement);\r\n densePolygonTemp.push(final);\r\n }\r\n });\r\n\r\n let densePolygon = [];\r\n densePolygonTemp.forEach((point, index) => {\r\n if (index === 0) {\r\n densePolygon.push(point);\r\n } else {\r\n let old = densePolygonTemp[index - 1];\r\n let distance = point.distanceTo(old);\r\n if (distance > 0) {\r\n densePolygon.push(point);\r\n }\r\n }\r\n });\r\n\r\n return densePolygonTemp;\r\n};\r\n","import { MeasurementController } from \".\";\r\nimport {Circle as CircleStyle, Fill, Stroke, Style} from \"ol/style\";\r\nimport {Vector as VectorSource} from \"ol/source\";\r\nimport {Vector as VectorLayer} from \"ol/layer\";\r\nimport {transform} from 'ol/proj';\r\nimport {Draw} from \"ol/interaction\";\r\nimport {getArea, getLength, getDistance} from 'ol/sphere';\r\nimport Overlay from 'ol/Overlay';\r\nimport {unByKey} from 'ol/Observable';\r\nimport Feature from 'ol/Feature';\r\nimport Polygon from 'ol/geom/Polygon';\r\nimport LineString from 'ol/geom/LineString';\r\nimport './aerial-tooltip.css';\r\nimport { setAerialTooltip } from \"../../viewer\";\r\nimport { t } from \"../../../localization\";\r\nimport { MeasureType } from \"../../../types/measurements\";\r\n\r\nexport class MinimapMeasure {\r\n private controller: MeasurementController;\r\n private mapSource: VectorSource;\r\n private mapLayer: VectorLayer;\r\n private styleHover: Style;\r\n private styleDefault: Style;\r\n private drawStyle: Style;\r\n\r\n public enabled = false;\r\n public measurementType: MeasureType;\r\n public sketch = null;\r\n private draw = null;\r\n private initialized = false;\r\n private tempTooltips = [];\r\n private measurements = [];\r\n\r\n constructor(controller) {\r\n this.controller = controller;\r\n\r\n this.styleHover = new Style({\r\n fill: new Fill({\r\n color: 'rgba(255, 255, 255, 0.2)'\r\n }),\r\n image: new CircleStyle({\r\n radius: 7,\r\n fill: new Fill({\r\n color: '#008B8B'\r\n })\r\n }),\r\n stroke: new Stroke({\r\n color: \"#ffcc33\",\r\n width: 2\r\n })\r\n });\r\n\r\n this.styleDefault = new Style({\r\n fill: new Fill({\r\n color: 'rgba(255, 255, 255, 0.2)'\r\n }),\r\n image: new CircleStyle({\r\n radius: 7,\r\n fill: new Fill({\r\n color: '#008B8B'\r\n })\r\n }),\r\n stroke: new Stroke({\r\n color: \"#008B8B\",\r\n width: 2\r\n })\r\n });\r\n\r\n this.drawStyle = new Style({\r\n fill: new Fill({\r\n color: 'rgba(255, 255, 255, 0.2)'\r\n }),\r\n stroke: new Stroke({\r\n color: 'rgba(0, 0, 0, 0.5)',\r\n lineDash: [10, 10],\r\n width: 2\r\n }),\r\n image: new CircleStyle({\r\n radius: 5,\r\n stroke: new Stroke({\r\n color: 'rgba(0, 0, 0, 0.7)'\r\n }),\r\n fill: new Fill({\r\n color: 'rgba(255, 255, 255, 0.2)'\r\n })\r\n })\r\n });\r\n }\r\n\r\n get map() {\r\n return this.controller.viewer.minimap.map;\r\n }\r\n\r\n get mapElement() {\r\n return this.controller.viewer.minimap.containerElement;\r\n }\r\n\r\n get drawingType() {\r\n return (this.measurementType === MeasureType.Area)\r\n ? \"Polygon\"\r\n : \"LineString\";\r\n }\r\n\r\n get moreTooltip() {\r\n let coordinates = this.sketch.getGeometry().flatCoordinates;\r\n let numPoints = (coordinates.length / 2.0) - 1;\r\n\r\n let canFinish = (this.measurementType === MeasureType.Area)\r\n ? numPoints > 2\r\n : true;\r\n\r\n if (canFinish) {\r\n return [\r\n t(\"measure.click-to-add-more-points\", {\r\n count: numPoints\r\n }),\r\n t('measure.double-click-to-finish'),\r\n t('measure.right-click-to-cancel')\r\n ];\r\n }\r\n\r\n return [\r\n t(\"measure.click-to-add-more-points\", {\r\n count: numPoints\r\n }),\r\n t('measure.right-click-to-cancel')\r\n ];\r\n }\r\n\r\n get startTooltip() {\r\n if (this.measurementType === MeasureType.Length) {\r\n return [t('measure.click-to-start-drawing-line')];\r\n }\r\n\r\n if (this.measurementType === MeasureType.Area) {\r\n return [t('measure.click-to-start-drawing-polygon')];\r\n }\r\n\r\n return [t('measure.invalid-measure-type')];\r\n }\r\n\r\n get formatter() {\r\n return this.controller.formatter;\r\n }\r\n\r\n init() {\r\n if (this.initialized) return;\r\n\r\n this.mapSource = new VectorSource({\r\n wrapX: false\r\n });\r\n\r\n this.mapLayer = new VectorLayer({\r\n zIndex: 1,\r\n source: this.mapSource,\r\n style: feature => {\r\n return feature.get(\"hover\")\r\n ? this.styleHover\r\n : this.styleDefault;\r\n },\r\n properties: {\r\n type: \"measure\"\r\n }\r\n });\r\n\r\n this.map.addLayer(this.mapLayer);\r\n\r\n this.addInteraction();\r\n this.initEvents();\r\n this.initialized = true;\r\n }\r\n\r\n initEvents() {\r\n this.mapElement.addEventListener('mouseenter', () => {\r\n if (this.controller.enabled) {\r\n this.reloadInteraction();\r\n }\r\n });\r\n\r\n this.mapElement.addEventListener('mouseleave', () => {\r\n if (this.controller.enabled) {\r\n this.removeInteraction();\r\n }\r\n });\r\n }\r\n\r\n render(measurement) {\r\n this.removeByID(measurement.id);\r\n\r\n const geometry = measurement.geometry;\r\n const feature = new Feature(geometry);\r\n feature.set(\"hover\", false);\r\n\r\n const tooltips = this.getTooltipsForGeometry(geometry);\r\n this.mapSource.addFeature(feature);\r\n\r\n this.measurements.push({\r\n id: measurement.id,\r\n feature,\r\n tooltips\r\n });\r\n }\r\n\r\n getByID(id) {\r\n return this.measurements.find(measurement => measurement.id === id);\r\n }\r\n\r\n removeByID(id) {\r\n const measurement = this.getByID(id);\r\n if (!measurement) return;\r\n\r\n const {feature, tooltips} = measurement;\r\n\r\n this.mapSource.removeFeature(feature);\r\n tooltips.forEach(tooltip => {\r\n this.map.removeOverlay(tooltip);\r\n });\r\n\r\n this.measurements = this.measurements\r\n .filter(measurement => measurement.id !== id);\r\n }\r\n\r\n removeAll() {\r\n [...this.measurements].forEach(measurement => {\r\n this.removeByID(measurement.id);\r\n });\r\n\r\n this.measurements = [];\r\n }\r\n\r\n setHover(id, hover) {\r\n const measurement = this.getByID(id);\r\n if (!measurement) return;\r\n\r\n measurement.feature.set(\"hover\", hover);\r\n measurement.tooltips.forEach(tooltip => {\r\n const element = tooltip.element;\r\n const child = element.children[0];\r\n\r\n if (hover) {\r\n child.classList.add(\"tooltip-hover\");\r\n } else {\r\n child.classList.remove(\"tooltip-hover\");\r\n }\r\n });\r\n }\r\n\r\n setMeasurementType(measurementType: MeasureType) {\r\n const validMeasureType = (measurementType === MeasureType.Length)\r\n || (measurementType === MeasureType.Area);\r\n\r\n this.measurementType = validMeasureType\r\n ? measurementType\r\n : null;\r\n\r\n this.reloadInteraction();\r\n\r\n if (this.measurementType === null) {\r\n this.removeInteraction();\r\n }\r\n }\r\n\r\n onMouseMove(event) {\r\n if (event.dragging || !this.controller.enabled) {\r\n return;\r\n }\r\n\r\n let helpMsg = this.sketch\r\n ? this.moreTooltip\r\n : this.startTooltip;\r\n\r\n setAerialTooltip(helpMsg);\r\n }\r\n\r\n getTooltipsForGeometry(geometry) {\r\n const tooltips = [];\r\n\r\n // Per segment tooltips\r\n const segments = this.getSegmentInfo(geometry);\r\n segments.forEach(segment => {\r\n const {position, message} = segment;\r\n const {element, tooltip} = this.addNewTooltip(false);\r\n tooltip.setPosition(position);\r\n element.innerHTML = message;\r\n tooltips.push(tooltip);\r\n });\r\n\r\n // Additional tooltip for total length / area\r\n let objectMessage;\r\n let objectPosition;\r\n\r\n // Total line length\r\n if (geometry instanceof LineString) {\r\n const length = getLength(geometry);\r\n objectMessage = this.formatter.formatLength(length);\r\n objectPosition = geometry.getLastCoordinate();\r\n }\r\n\r\n // Total area\r\n const hasEnoughSegments = segments.length >= 3;\r\n if ((geometry instanceof Polygon) && hasEnoughSegments) {\r\n const area = getArea(geometry);\r\n objectMessage = this.formatter\r\n .formatArea(area);\r\n objectPosition = geometry\r\n .getInteriorPoint()\r\n .getCoordinates();\r\n }\r\n\r\n if (objectPosition) {\r\n const {element, tooltip} = this.addNewTooltip(true);\r\n tooltip.setPosition(objectPosition);\r\n element.innerHTML = objectMessage;\r\n tooltips.push(tooltip);\r\n }\r\n\r\n return tooltips;\r\n }\r\n\r\n clearTempTooltips() {\r\n this.tempTooltips.forEach(tooltip => {\r\n this.map.removeOverlay(tooltip);\r\n });\r\n\r\n this.tempTooltips = [];\r\n }\r\n\r\n reloadInteraction() {\r\n if (!this.map) return;\r\n\r\n if (this.draw) {\r\n this.map.removeInteraction(this.draw);\r\n }\r\n\r\n this.sketch = null;\r\n this.addInteraction();\r\n }\r\n\r\n removeInteraction() {\r\n if (!this.draw) return;\r\n\r\n this.clearTempTooltips();\r\n this.map.removeInteraction(this.draw);\r\n }\r\n\r\n addInteraction() {\r\n if (this.measurementType === null || this.map === null) return;\r\n if (!this.controller.editable) return;\r\n\r\n this.removeInteraction();\r\n\r\n this.draw = new Draw({\r\n type: this.drawingType,\r\n condition: event => {\r\n if (event.originalEvent.button === 0) {\r\n return true;\r\n }\r\n\r\n if (event.originalEvent.button === 2) {\r\n if (this.controller.enabled) {\r\n this.reloadInteraction();\r\n setAerialTooltip(this.startTooltip);\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n style: this.drawStyle\r\n });\r\n\r\n this.map.addInteraction(this.draw);\r\n\r\n let listener;\r\n\r\n this.draw.on('drawstart', event => {\r\n this.sketch = event.feature;\r\n this.clearTempTooltips();\r\n\r\n const geometry = this.sketch.getGeometry();\r\n listener = geometry.on('change', () => {\r\n this.clearTempTooltips();\r\n this.tempTooltips = this.getTooltipsForGeometry(geometry);\r\n });\r\n }, this);\r\n\r\n this.draw.on('drawend', (event) => {\r\n this.clearTempTooltips();\r\n\r\n this.sketch = null;\r\n unByKey(listener);\r\n\r\n const geometry = event.feature.getGeometry();\r\n this.controller.addAerialMeasurement(\r\n geometry, this.measurementType);\r\n\r\n setAerialTooltip(this.startTooltip);\r\n }, this);\r\n }\r\n\r\n addNewTooltip(alternateColor) {\r\n const element = document.createElement('div');\r\n element.className = \"tooltip tooltip-minimap\";\r\n\r\n element.className = alternateColor\r\n ? \"tooltip tooltip-minimap tooltip-alternate\"\r\n : \"tooltip tooltip-minimap\";\r\n\r\n const tooltip = new Overlay({\r\n element,\r\n positioning: \"center-center\",\r\n className: \"ol-overlay-container tooltip-container\"\r\n });\r\n\r\n this.map.addOverlay(tooltip);\r\n return {tooltip, element};\r\n }\r\n\r\n getSegmentInfo(geometry) {\r\n const transformed = geometry.clone().transform('EPSG:3857', 'EPSG:4326');\r\n const flatCoordinates = transformed.flatCoordinates;\r\n const numPoints = flatCoordinates.length / 2;\r\n\r\n const segments = [];\r\n for (let i=0; i 0;\r\n }\r\n\r\n get assets() {\r\n return this.measureAssets;\r\n }\r\n\r\n setBuilder(builderType) {\r\n this.measureType = builderType;\r\n this.measurement = this.getEmptyMeasurement();\r\n this.measurement.setController(this.controller);\r\n }\r\n\r\n getEmptyMeasurement() {\r\n const type = this.measureType;\r\n\r\n if (type === MeasureType.SnapUp) {\r\n return new SnapUpMeasurement();\r\n } else if (type === MeasureType.SnapDown) {\r\n return new SnapDownMeasurement();\r\n } else if (type === MeasureType.Height) {\r\n return new HeightMeasurement();\r\n } else if (type === MeasureType.Point) {\r\n return new MeasurementPoint();\r\n } else if (type === MeasureType.Area) {\r\n return new MeasurementArea();\r\n } else if (type === MeasureType.Volume) {\r\n return new MeasurementVolume();\r\n } else if (type === MeasureType.Station) {\r\n return new StationMeasurement();\r\n }\r\n\r\n return new MeasurementLine();\r\n }\r\n\r\n getMeasurement() {\r\n if (this.isFinished) {\r\n const measurement = this.measurement;\r\n this.measurement = this.getEmptyMeasurement();\r\n this.measurement.setController(this.controller);\r\n this.isFinished = false;\r\n\r\n return measurement;\r\n }\r\n\r\n return this.measurement;\r\n }\r\n\r\n reset() {\r\n this.isFinished = false;\r\n if (!this.measurement) return;\r\n\r\n this.measurement.vertices = [];\r\n this.measurement.clear();\r\n }\r\n\r\n add(vertex) {\r\n if (!this.isFinished) {\r\n let result = this.measurement.add(vertex);\r\n this.isFinished = result.finished;\r\n return result;\r\n }\r\n\r\n return {\r\n added: false,\r\n valid: false\r\n };\r\n }\r\n}\r\n","import { AmbientLight, Scene, Vector3 } from 'three';\r\nimport { CustomMouseEvent } from '../controls';\r\nimport { Viewer } from '../main';\r\nimport LocalScene from '../projections';\r\nimport {\r\n AerialAreaMeasurement,\r\n AerialLengthMeasurement,\r\n Measurement3D,\r\n MeasurementArea,\r\n MeasurementPoint,\r\n MinimapMeasure,\r\n MeasurementConstructor,\r\n MeasurementFormatter,\r\n MeasurementGroup,\r\n MeasurementGroupExporter,\r\n MeasurementSceneView,\r\n MeasureEndpoint,\r\n MeasurementVolume,\r\n HeightMeasurement\r\n} from '.';\r\nimport { clearAerialTooltip, clearViewerTooltip } from '../../viewer';\r\nimport { RayCaster } from '../ray-caster';\r\nimport { toast } from '../../../app';\r\nimport { t } from '../../../localization';\r\nimport { ChangeDetector } from '../utilities';\r\nimport { Asset, XMLData } from '../../../redux/assets-slice';\r\nimport { MeasureType, VolumeType, SamplingRate } from '../../../types/measurements';\r\n\r\nexport class MeasurementController {\r\n public viewer: Viewer;\r\n public enabled = false;\r\n public timeout = false;\r\n private measureAssets = [] as Asset[];\r\n public activeAlignment = '';\r\n\r\n private measureType = MeasureType.Length;\r\n public volumeType = VolumeType.MultiPlane;\r\n public sampleRate = SamplingRate.Medium;\r\n\r\n public formatter: MeasurementFormatter;\r\n public measurementSceneView: MeasurementSceneView;\r\n public measurementAerialView: MinimapMeasure;\r\n public measurementBuilder: MeasurementConstructor;\r\n public measurementGroupExporter: MeasurementGroupExporter;\r\n public measurementGroup: MeasurementGroup;\r\n public setMeasurements;\r\n public scene: Scene;\r\n\r\n\r\n constructor(viewer: Viewer, props) {\r\n const {setMeasurements} = props;\r\n\r\n this.viewer = viewer;\r\n this.setMeasurements = setMeasurements;\r\n\r\n this.initScene();\r\n\r\n this.formatter = new MeasurementFormatter(\"m\");\r\n this.measurementSceneView = new MeasurementSceneView(this, this.scene);\r\n this.measurementAerialView = new MinimapMeasure(this);\r\n this.measurementBuilder = new MeasurementConstructor(this);\r\n this.measurementGroupExporter = new MeasurementGroupExporter(this);\r\n this.measurementGroup = new MeasurementGroup(this);\r\n }\r\n\r\n get pointclouds() {\r\n return this.viewer.pointclouds;\r\n }\r\n\r\n get controls() {\r\n return this.viewer.controls;\r\n }\r\n\r\n get isImageOnly() {\r\n return this.viewer.isImageOnly;\r\n }\r\n\r\n get measuring() {\r\n return this.measurementBuilder.active;\r\n }\r\n\r\n get activeMeasurement() {\r\n return this.measurementBuilder.measurement;\r\n }\r\n\r\n get notEmpty() {\r\n return this.measurementGroup.measurements.length > 0;\r\n }\r\n\r\n get dragObject() {\r\n return this.measurementSceneView.dragObject;\r\n }\r\n\r\n get editable() {\r\n // Always true since view-only mode doesnt exist\r\n return true;\r\n }\r\n\r\n get hoveredPoint() {\r\n return this.measurementSceneView.hoveredPoint;\r\n }\r\n\r\n get measurementAssets() {\r\n return this.measureAssets;\r\n }\r\n\r\n reconcileXMLs(xmlFiles) {\r\n const currentAssets = new Set(\r\n this.measurementAssets.map(asset => asset.id));\r\n const newAssets = new Set(xmlFiles.map(asset => asset.id));\r\n const assetsToLoad = xmlFiles.filter(xml => !currentAssets.has(xml.id));\r\n const assetToDelete = this.measurementAssets.filter(\r\n xml => !newAssets.has(xml.id));\r\n\r\n this.updateMeasureAssets(assetToDelete, xmlFiles);\r\n\r\n assetsToLoad.forEach(xmlFile => {\r\n this.loadMeasureAsset(xmlFile);\r\n });\r\n }\r\n\r\n setState(state) {\r\n if (state) {\r\n this.enable();\r\n } else {\r\n this.disable(true);\r\n }\r\n }\r\n\r\n enable() {\r\n this.enabled = true;\r\n this.createNewMeasurementGroup();\r\n this.measurementAerialView.enabled = true;\r\n this.measurementAerialView.init();\r\n }\r\n\r\n disable(clear=false) {\r\n if (clear) {\r\n this.measurementSceneView.removeAll();\r\n this.measurementAerialView.removeAll();\r\n }\r\n\r\n this.enabled = false;\r\n this.stopDrawingItems();\r\n this.measurementGroup.reset();\r\n this.measurementAerialView.enabled = false;\r\n this.measurementAerialView.removeInteraction();\r\n this.viewer.multiImageWindow.close();\r\n\r\n clearAerialTooltip();\r\n clearViewerTooltip();\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n enableTimeout() {\r\n this.timeout = true;\r\n setTimeout(() => {\r\n this.timeout = false;\r\n }, 500);\r\n }\r\n\r\n loadMeasureAsset(asset) {\r\n this.measureAssets.push(asset);\r\n }\r\n\r\n updateMeasureAssets(toDelete=[], xmlFiles) {\r\n const removeIDs = new Set(toDelete.map(deletable => deletable.id));\r\n const currentAssets = [...this.measureAssets];\r\n this.measureAssets = [];\r\n currentAssets.forEach(asset => {\r\n if (!(removeIDs.has(asset.id))) {\r\n xmlFiles.forEach(xmlFile => {\r\n if (asset.id === xmlFile.id) {\r\n this.measureAssets.push(xmlFile);\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n setActiveAlignment(id) {\r\n this.activeAlignment = id;\r\n }\r\n\r\n getAlignmentByID(id) {\r\n for (let asset of this.measureAssets) {\r\n const {alignments, enu, units} = asset.data as XMLData;\r\n const alignment = alignments.find(x => x.id === id);\r\n const alignUnits = (units as any).linearUnit as string;\r\n\r\n if (!alignment) continue;\r\n\r\n return {\r\n alignment,\r\n enu,\r\n units: alignUnits\r\n };\r\n };\r\n }\r\n\r\n loadMeasurementData(data) {\r\n try {\r\n const projection = data.projection;\r\n const sameProjection = LocalScene.isDataProjection(projection.name);\r\n\r\n if (!sameProjection) {\r\n toast.error(t(\"toast.measure-projection-mismatch\", {\r\n projection: projection.name\r\n }));\r\n\r\n return false;\r\n };\r\n\r\n // Clear data and create new group\r\n this.createNewMeasurementGroup();\r\n\r\n // Load measurements into new group\r\n let measurements = data.measurements;\r\n this.measurementGroup.loadMeasurements(measurements);\r\n this.refreshMeasurementList();\r\n\r\n toast.success(t(\"toast.measure-load-success\", {\r\n count: data.count\r\n }));\r\n } catch {\r\n this.createNewMeasurementGroup();\r\n toast.error(t(\"toast.measure-load-error\"));\r\n }\r\n }\r\n\r\n cancelMeasurement() {\r\n this.stopDrawingItems();\r\n this.viewer.multiImageWindow.close();\r\n }\r\n\r\n returnCoordinate(obj) {\r\n return false;\r\n /*\r\n return isLineworkObject(obj)\r\n || isFeatureServerObject(obj)\r\n || obj instanceof TexturedSprite;\r\n */\r\n }\r\n\r\n getCoordinate(event) : Vector3 {\r\n return this.controls.getPickerResults(event).coordinate;\r\n }\r\n\r\n getAreaGeometry() {\r\n const temporaryMeasurement = this.activeMeasurement;\r\n return this.measurementGroup\r\n .getAreaGeometry(temporaryMeasurement);\r\n }\r\n\r\n /** @private */\r\n clickMultiImage(event) {\r\n if (!this.editable) {\r\n return;\r\n }\r\n\r\n const measurement = this.measurementBuilder.measurement;\r\n const multiImage = this.viewer.multiImageWindow;\r\n const isSinglePoint = measurement instanceof MeasurementPoint;\r\n\r\n // Calculate clicked position\r\n const raycaster = new RayCaster(this.viewer, event);\r\n const direction = raycaster.vectorFromEvent(event);\r\n const position = this.viewer.camera.position;\r\n\r\n multiImage.show({\r\n closePrompt: () => {\r\n if (measurement.hasPoints) {\r\n return {\r\n title: t('asset.discard-measurements'),\r\n text: t('asset.active-measurements-found'),\r\n callback: () => {\r\n this.cancelMeasurement();\r\n clearViewerTooltip();\r\n }\r\n };\r\n }\r\n },\r\n onComplete: () => {\r\n multiImage.getClickedPoint(coordinate => {\r\n const isFinished = this.onClickFinish(coordinate);\r\n\r\n // Certain measurement types require a simulated double-click\r\n if (!isFinished) {\r\n this.onClickFinish(coordinate);\r\n }\r\n\r\n clearViewerTooltip();\r\n multiImage.close();\r\n });\r\n },\r\n onAddMore: () => {\r\n multiImage.getClickedPoint(coordinate => {\r\n this.onClickFinish(coordinate);\r\n multiImage.canComplete = measurement.canFinish;\r\n multiImage.resetObservations();\r\n });\r\n },\r\n canComplete: measurement.canFinish,\r\n canAddMore: !isSinglePoint,\r\n });\r\n\r\n multiImage.addFirstObservation(position, direction);\r\n }\r\n\r\n /** @private */\r\n clickStandard(event) {\r\n let coordinate = this.hoveredPoint\r\n ? this.hoveredPoint.position\r\n : this.getCoordinate(event);\r\n\r\n if (!coordinate) return;\r\n this.onClickFinish(coordinate);\r\n }\r\n\r\n /** @private */\r\n onClickFinish(coordinate) {\r\n let isFinished = false;\r\n let result = this.measurementBuilder.add(coordinate);\r\n\r\n if (!result.valid) {\r\n this.cancelMeasurement();\r\n return isFinished;\r\n }\r\n\r\n if (result.added) {\r\n this.measurementSceneView.addTemporaryPoint(coordinate);\r\n this.updateMeasureText();\r\n }\r\n\r\n if (this.measurementBuilder.isFinished) {\r\n isFinished = true;\r\n this.addSceneMeasurement();\r\n };\r\n\r\n return isFinished;\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (event.mouseMoved || !this.enabled) {\r\n return false;\r\n }\r\n\r\n if (event.isLeftClick) {\r\n this.mouseClick(event);\r\n return true;\r\n }\r\n\r\n if (event.isRightClick) {\r\n if (this.measuring) {\r\n // Cancel measurement\r\n this.cancelMeasurement();\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n mouseClick(event) {\r\n if (!this.editable || this.timeout) return;\r\n\r\n if (this.isImageOnly) {\r\n // Image only multi-image measurements\r\n this.clickMultiImage(event);\r\n } else {\r\n this.clickStandard(event);\r\n }\r\n }\r\n\r\n onMouseMoveAerial(event) {\r\n return this.measurementAerialView.onMouseMove(event);\r\n }\r\n\r\n onMouseMoveScene(event: CustomMouseEvent) {\r\n return this.measurementSceneView.onMouseMove(event);\r\n }\r\n\r\n resetDragObject() {\r\n this.measurementSceneView.setDragObject(null);\r\n }\r\n\r\n addSceneMeasurement() {\r\n this.updateMeasureText();\r\n\r\n let measurement = this.measurementBuilder.getMeasurement();\r\n\r\n if (measurement instanceof MeasurementArea) {\r\n measurement.generateSurface();\r\n }\r\n\r\n if (measurement instanceof HeightMeasurement) {\r\n this.enableTimeout();\r\n }\r\n\r\n this.measurementSceneView.removeTemporaryObjects();\r\n this.measurementGroup.add(measurement);\r\n this.renderMeasurement(measurement);\r\n this.markLastPointDraggable(measurement);\r\n\r\n if (measurement instanceof MeasurementVolume) {\r\n measurement.calculateVolume();\r\n }\r\n }\r\n\r\n addAerialMeasurement(geometry, type: MeasureType) {\r\n let measurement;\r\n\r\n if (type === MeasureType.Area) {\r\n measurement = new AerialAreaMeasurement(geometry);\r\n } else {\r\n measurement = new AerialLengthMeasurement(geometry);\r\n }\r\n\r\n measurement.setController(this);\r\n this.measurementGroup.add(measurement);\r\n this.renderMeasurement(measurement);\r\n }\r\n\r\n markLastPointDraggable(measurement) {\r\n let sceneEndpoints = this.scene.children\r\n .filter(x => x instanceof MeasureEndpoint) as MeasureEndpoint[];\r\n\r\n let measureEndpoints = sceneEndpoints\r\n .filter(x => x.measurementID === measurement.id);\r\n\r\n let lastPoint = measureEndpoints[measureEndpoints.length - 1];\r\n this.measurementSceneView.setDragObject(lastPoint);\r\n }\r\n\r\n stopDrawingItems() {\r\n this.measurementBuilder.reset();\r\n this.measurementSceneView.removeTemporaryObjects();\r\n this.measurementAerialView.reloadInteraction();\r\n this.updateMeasureText(false);\r\n }\r\n\r\n setPointGrabTooltip() {\r\n this.measurementSceneView.setPointGrabTooltip();\r\n }\r\n\r\n measureGrabFinished() {\r\n this.measurementSceneView.measureGrabFinished();\r\n }\r\n\r\n refreshMeasurementList() {\r\n this.setMeasurements([...this.measurementGroup.measurements]);\r\n }\r\n\r\n updateMeasureText(checkMorePoints = true) {\r\n if (!this.enabled) return false;\r\n\r\n let morepoints = false;\r\n let measurement = this.measurementBuilder.measurement;\r\n\r\n if (checkMorePoints) {\r\n morepoints = !this.measurementBuilder.isFinished;\r\n if (measurement.vertices.length === 0) {\r\n morepoints = false;\r\n }\r\n }\r\n\r\n this.measurementSceneView.setTooltipText(measurement, morepoints);\r\n }\r\n\r\n createNewMeasurementGroup() {\r\n this.measurementAerialView.removeAll();\r\n this.measurementSceneView.removeAll();\r\n this.measurementGroup = new MeasurementGroup(this);\r\n this.setMeasurementType(this.measureType);\r\n }\r\n\r\n setMeasurementType(measurementType: MeasureType) {\r\n if (!this.enabled) return;\r\n\r\n this.measureType = measurementType;\r\n this.measurementBuilder.setBuilder(measurementType);\r\n this.measurementSceneView.removeTemporaryObjects();\r\n this.viewer.multiImageWindow.close();\r\n\r\n let measurement = this.measurementBuilder.measurement;\r\n this.measurementSceneView.setTooltipText(measurement);\r\n\r\n this.stopDrawingItems();\r\n this.measurementAerialView.setMeasurementType(measurementType);\r\n }\r\n\r\n removeByID(id) {\r\n this.measurementSceneView.removeByID(id);\r\n this.measurementGroup.removeByID(id);\r\n this.measurementAerialView.removeByID(id);\r\n\r\n clearViewerTooltip();\r\n }\r\n\r\n setTitle(id, title) {\r\n const measurement = this.measurementGroup.getByID(id);\r\n\r\n if (measurement) {\r\n measurement.setTitle(title);\r\n this.refreshMeasurementList();\r\n }\r\n\r\n clearViewerTooltip();\r\n }\r\n\r\n removeAll() {\r\n this.measurementGroup.removeAll();\r\n this.clearViews();\r\n }\r\n\r\n clearViews() {\r\n this.measurementSceneView.removeAll();\r\n this.measurementAerialView.removeAll();\r\n }\r\n\r\n export(type, ordering) {\r\n if (type === \"csv\") {\r\n this.exportCSV(ordering);\r\n } else if (type === \"dat\") {\r\n this.exportDAT();\r\n } else if (type === \"dxf\" || type === \"shp\") {\r\n this.exportLinework(type);\r\n }\r\n }\r\n\r\n exportDAT() {\r\n this.measurementGroupExporter\r\n .exportDAT(this.measurementGroup);\r\n }\r\n\r\n exportCSV(ordering) {\r\n this.measurementGroupExporter.exportCSV(\r\n this.measurementGroup, ordering);\r\n }\r\n\r\n exportLinework(type) {\r\n this.measurementGroupExporter\r\n .exportLinework(this.measurementGroup, type);\r\n }\r\n\r\n setUnits(units) {\r\n this.formatter.setUnits(units);\r\n\r\n if (this.measurementGroup) {\r\n this.reload();\r\n }\r\n }\r\n\r\n setVolumeType(type: VolumeType) {\r\n this.volumeType = type;\r\n this.refreshVolume();\r\n }\r\n\r\n setSampleRate(rate: SamplingRate) {\r\n this.sampleRate = rate;\r\n this.refreshVolume();\r\n }\r\n\r\n reload() {\r\n this.clearViews();\r\n this.measurementGroup.measurements.forEach(measurement => {\r\n this.renderMeasurement(measurement);\r\n });\r\n this.refreshMeasurementList();\r\n }\r\n\r\n refreshVolume() {\r\n // All volumes will need to be recalculated\r\n this.measurementGroup.measurements.forEach(measurement => {\r\n if (measurement instanceof MeasurementVolume) {\r\n measurement.stopVolumeCalculation();\r\n measurement.calculateVolume();\r\n }\r\n });\r\n }\r\n\r\n setHover(measurement, hover = false) {\r\n if (measurement instanceof Measurement3D) {\r\n this.measurementSceneView.setHover(measurement.id, hover);\r\n } else {\r\n this.measurementAerialView.setHover(measurement.id, hover);\r\n }\r\n }\r\n\r\n renderMeasurement(measurement) {\r\n if (measurement instanceof Measurement3D) {\r\n this.measurementSceneView.render(measurement);\r\n } else {\r\n this.measurementAerialView.render(measurement);\r\n }\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n this.measurementSceneView.update(changeDetector);\r\n }\r\n}\r\n","import { t } from \"../../../localization\";\r\nimport { MeasureType } from \"../../../types/measurements\";\r\nimport { isLonLatProjection } from \"../projections\";\r\nimport { MeasurementVolume } from \"./measurement\";\r\n\r\nexport class MeasurementFormatter {\r\n public units;\r\n public emptyValue = \"\";\r\n private metersCutoff = 500;\r\n private squareMetersCutoff = 250000;\r\n private formatterPrecision = 2; // 0.01m\r\n private vectorPrecisionLonLat = 6; // ~0.01m\r\n private vectorPrecisionStandard = 2; // 0.01m\r\n\r\n constructor(units) {\r\n if (units !== 'ft' && units !== 'm' && units !== \"sft\") {\r\n throw TypeError('units must be \"ft\", \"sft\" or \"m\"');\r\n }\r\n\r\n this.setUnits(units);\r\n }\r\n\r\n get nullValue() {\r\n return t(\"general.not-applicable\");\r\n }\r\n\r\n get isMetric() {\r\n return this.units === \"m\";\r\n }\r\n\r\n get isSurveyFeet() {\r\n return this.units === \"sft\";\r\n }\r\n\r\n get areaUnits() {\r\n return `${this.isMetric ? \"m\" : \"ft\"}^2`;\r\n }\r\n\r\n get volumeUnits() {\r\n return `${this.isMetric ? \"m\" : \"yd\"}^3`;\r\n }\r\n\r\n setUnits(units) {\r\n this.units = units;\r\n }\r\n\r\n formatLength(value) {\r\n let units;\r\n let finalValue = value;\r\n\r\n if ((this.units === 'ft') || (this.units === \"sft\")) {\r\n if (value > this.metersCutoff) {\r\n units = \"mi\";\r\n finalValue = MeasurementFormatter.metresToMiles(finalValue, this.isSurveyFeet);\r\n } else {\r\n // Round the meters units first for feet + inches\r\n if (this.formatterPrecision) {\r\n finalValue = finalValue.toFixed(this.formatterPrecision);\r\n }\r\n\r\n finalValue = parseFloat(finalValue);\r\n finalValue = MeasurementFormatter.metresToFeet(finalValue, this.isSurveyFeet);\r\n let feet = Math.floor(finalValue);\r\n let inches = Math.round((finalValue - feet) * 12.0);\r\n return `${feet} ft ${inches} in `;\r\n }\r\n } else {\r\n if (value > this.metersCutoff) {\r\n units = \"km\";\r\n finalValue = MeasurementFormatter.metresToKiloMetres(finalValue);\r\n } else {\r\n units = \"m\";\r\n }\r\n }\r\n\r\n if (this.formatterPrecision) {\r\n finalValue = finalValue.toFixed(this.formatterPrecision);\r\n }\r\n\r\n return `${finalValue} ${units}`;\r\n }\r\n\r\n formatVolume(measurement: MeasurementVolume) {\r\n let units;\r\n let finalValue = measurement.volume as any;\r\n\r\n if ((this.units === 'ft') || (this.units === \"sft\")) {\r\n units = \"yd3\";\r\n finalValue = MeasurementFormatter.cubicMetresToCubicYards(finalValue);\r\n } else {\r\n units = \"m3\";\r\n }\r\n\r\n if (this.formatterPrecision) {\r\n finalValue = finalValue.toFixed(this.formatterPrecision);\r\n }\r\n\r\n return `${finalValue} ${units}`;\r\n }\r\n\r\n formatArea(value) {\r\n let units;\r\n let finalValue = value;\r\n\r\n if ((this.units === 'ft') || (this.units === \"sft\")) {\r\n if (value > this.squareMetersCutoff) {\r\n units = \"mi2\";\r\n finalValue = MeasurementFormatter.squareMetresToSquareMiles(\r\n finalValue, this.isSurveyFeet);\r\n } else {\r\n units = \"ft2\";\r\n finalValue = MeasurementFormatter.squareMetresToSquareFeet(\r\n finalValue, this.isSurveyFeet);\r\n }\r\n } else {\r\n if (value > this.squareMetersCutoff) {\r\n units = \"km2\";\r\n finalValue = MeasurementFormatter.squareMetresToSquareKilometres(\r\n finalValue);\r\n } else {\r\n units = \"m2\";\r\n }\r\n }\r\n\r\n if (this.formatterPrecision) {\r\n finalValue = finalValue.toFixed(this.formatterPrecision);\r\n }\r\n\r\n return `${finalValue} ${units}`;\r\n }\r\n\r\n formatAngle(value, format = true) {\r\n if (!isNaN(value)) {\r\n if (format) {\r\n return `${value.toFixed(this.formatterPrecision)}°`;\r\n }\r\n return value.toFixed(this.formatterPrecision);\r\n }\r\n return this.nullValue;\r\n }\r\n\r\n formatGrade(value, format = true) {\r\n let maxGrade = 1000000;\r\n if (isFinite(value) && (value < maxGrade)) {\r\n if (format) {\r\n return `${value.toFixed(this.formatterPrecision)}%`;\r\n }\r\n return value.toFixed(this.formatterPrecision);\r\n }\r\n return this.nullValue;\r\n }\r\n\r\n formatStation(measurement, format=true) {\r\n const along = measurement.distanceAlong;\r\n const start = measurement.staStart;\r\n const lengthUnits = measurement.units;\r\n\r\n let alongFinal = along;\r\n let stationFinal = start;\r\n const imperial = ((this.units === 'ft') || (this.units === \"sft\"));\r\n\r\n if (imperial) {\r\n if (lengthUnits === \"m\") {\r\n alongFinal = MeasurementFormatter.metresToFeet(alongFinal, this.isSurveyFeet);\r\n stationFinal = MeasurementFormatter.metresToFeet(stationFinal, this.isSurveyFeet);\r\n }\r\n\r\n } else {\r\n if (lengthUnits === \"sft\") {\r\n stationFinal = MeasurementFormatter.feetToMetres(stationFinal, true);\r\n alongFinal = MeasurementFormatter.feetToMetres(alongFinal, true);\r\n } else if (lengthUnits === \"ft\"){\r\n stationFinal = MeasurementFormatter.feetToMetres(stationFinal, false);\r\n alongFinal = MeasurementFormatter.feetToMetres(alongFinal, false);\r\n }\r\n }\r\n\r\n const stationTotal = stationFinal + alongFinal;\r\n let stationNumber;\r\n let stationAlong;\r\n if (imperial) {\r\n stationNumber = parseInt(String(stationTotal).slice(0,4));\r\n stationAlong = parseFloat(String(stationTotal).slice(4));\r\n } else {\r\n stationNumber = parseInt(String(stationTotal).slice(0,3));\r\n stationAlong = parseFloat(String(stationTotal).slice(3));\r\n }\r\n\r\n if (this.formatterPrecision) {\r\n stationAlong = stationAlong.toFixed(this.formatterPrecision);\r\n }\r\n if (format){\r\n return `${stationNumber} + ${stationAlong} ${this.units}`;\r\n }\r\n return `${stationNumber} + ${stationAlong}`;\r\n }\r\n\r\n formatOffset(measurement, format=true) {\r\n const across = measurement.distanceAcross;\r\n const side = measurement.sideOfSegment;\r\n let finalValue = (side === \"R\") ? across : -across;\r\n const imperial = ((this.units === 'ft') || (this.units === \"sft\"));\r\n const lengthUnits = measurement.units;\r\n\r\n if (imperial) {\r\n if (lengthUnits === \"m\") {\r\n finalValue = MeasurementFormatter.metresToFeet(finalValue, this.isSurveyFeet);\r\n }\r\n } else {\r\n if (lengthUnits === \"sft\") {\r\n finalValue = MeasurementFormatter.feetToMetres(finalValue, true);\r\n } else if (lengthUnits === \"ft\"){\r\n finalValue = MeasurementFormatter.feetToMetres(finalValue, false);\r\n }\r\n }\r\n\r\n if (this.formatterPrecision) {\r\n finalValue = finalValue.toFixed(this.formatterPrecision);\r\n }\r\n\r\n if (format){\r\n return `${finalValue} ${this.units}`;\r\n }\r\n return `${finalValue}`;\r\n }\r\n\r\n convertUnits(value, type: MeasureType) {\r\n if ((this.units === 'ft') || (this.units === \"sft\")) {\r\n if (type === MeasureType.Area) {\r\n value = MeasurementFormatter.squareMetresToSquareFeet(\r\n value, this.isSurveyFeet);\r\n } else if (type === MeasureType.Volume) {\r\n value = MeasurementFormatter.cubicMetresToCubicYards(value);\r\n } else {\r\n value = MeasurementFormatter.metresToFeet(value, this.isSurveyFeet);\r\n }\r\n }\r\n\r\n if (this.formatterPrecision) {\r\n value = value.toFixed(this.formatterPrecision);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n getVectorPrecision(projection = null) {\r\n let precisionX = this.vectorPrecisionStandard;\r\n let precisionY = this.vectorPrecisionStandard;\r\n let precisionZ = this.vectorPrecisionStandard;\r\n\r\n if (projection && isLonLatProjection(projection)) {\r\n precisionX = this.vectorPrecisionLonLat;\r\n precisionY = this.vectorPrecisionLonLat;\r\n }\r\n\r\n return {\r\n x: precisionX,\r\n y: precisionY,\r\n z: precisionZ\r\n };\r\n }\r\n\r\n static metresToYards(value) {\r\n /** International units and US units are the same for yards */\r\n return value * (1 / 0.9144);\r\n }\r\n\r\n static metresToFeet(value, isSurveryFeet=false) {\r\n if (isSurveryFeet) {\r\n return value * (3937.0 / 1200.0);\r\n }\r\n\r\n return value * (1 / 0.3048);\r\n }\r\n\r\n static feetToMetres(value, isSurveryFeet=false) {\r\n if (isSurveryFeet) {\r\n return value * (1200.0 / 3937.0);\r\n }\r\n\r\n return value * (0.3048);\r\n }\r\n\r\n static metresToMiles(value, isSurveryFeet=false) {\r\n return value * this.metresToFeet(1.0, isSurveryFeet) / 5280;\r\n }\r\n\r\n static metresToKiloMetres(metres) {\r\n return metres * 0.001;\r\n }\r\n\r\n static squareMetresToSquareKilometres(squareMetres) {\r\n return squareMetres * 0.000001;\r\n }\r\n\r\n static squareMetresToSquareFeet(squareMetres, isSurveryFeet=false) {\r\n let val = Math.pow(this.metresToFeet(1.0, isSurveryFeet), 2);\r\n return squareMetres * val;\r\n }\r\n\r\n static squareMetresToSquareMiles(squareMetres, isSurveryFeet=false) {\r\n let val = Math.pow(this.metresToMiles(1.0, isSurveryFeet), 2);\r\n return squareMetres * val;\r\n }\r\n\r\n static cubicMetresToCubicYards(cubicMetres) {\r\n let val = Math.pow(this.metresToYards(1.0), 3);\r\n return cubicMetres * val;\r\n }\r\n}\r\n\r\n\r\n","import LocalScene, {\r\n GeocentricCoordinate,\r\n ProjectedCoordinate,\r\n} from '../projections';\r\nimport {\r\n AerialAreaMeasurement,\r\n AerialMeasurement,\r\n Measurement3D,\r\n MeasurementArea,\r\n MeasurementPoint,\r\n MeasurementVolume,\r\n MeasurementController, StationMeasurement, MeasurementGroup\r\n} from '.';\r\nimport { Vector3 } from 'three';\r\nimport { windowSafeDateISO } from '../utilities';\r\nimport {\r\n DXFModelFilter,\r\n measureCSVFilter,\r\n measureDataFilter,\r\n measureDataFormat,\r\n ZIPFileFilter\r\n} from '../../../file-extensions';\r\nimport { t } from '../../../localization';\r\nimport { writeToString } from \"fast-csv\";\r\nimport { downloadFile } from '../../../utilities';\r\nimport {dialog, fs, getTemporaryFile} from \"../../../electron-modules\";\r\nimport {toast} from \"../../../app\";\r\nimport {PythonExecutable} from \"../../../executable\";\r\nimport path from \"path\";\r\nimport slash from \"slash\";\r\n\r\nexport class MeasurementGroupExporter {\r\n private controller: MeasurementController;\r\n\r\n constructor(controller) {\r\n this.controller = controller;\r\n }\r\n\r\n get viewer() {\r\n return this.controller.viewer;\r\n }\r\n\r\n get formatter() {\r\n return this.controller.formatter;\r\n }\r\n\r\n\r\n async exportCSV(measurementGroup, ordering) {\r\n await this.handleExport3D(measurementGroup, ordering);\r\n await this.handleExport2D(measurementGroup, ordering);\r\n }\r\n\r\n async exportDAT(measurementGroup) {\r\n const name = `${this.viewer.projectName}.${measureDataFormat}`;\r\n const data = this.getDataExport(measurementGroup);\r\n const content = JSON.stringify(data, null, 2);\r\n downloadFile(name, content, \"plain\", measureDataFilter);\r\n }\r\n\r\n async handleExport2D(measurementGroup: MeasurementGroup, ordering) {\r\n const name = t('measure.name-measurements-2d', {\r\n name: this.viewer.projectName,\r\n date: windowSafeDateISO()\r\n });\r\n\r\n const rows = this.getExportRows2D(measurementGroup, ordering);\r\n if (rows.length === 0) return;\r\n\r\n const content = await writeToString(rows);\r\n downloadFile(name, content, \"csv\", measureCSVFilter);\r\n }\r\n\r\n async handleExport3D(measurementGroup: MeasurementGroup, ordering) {\r\n const name = t('measure.name-measurements-3d', {\r\n name: this.viewer.projectName,\r\n date: windowSafeDateISO()\r\n });\r\n\r\n const rows = this.getExportRows3D(measurementGroup, ordering);\r\n if (rows.length === 0) return;\r\n\r\n const content = await writeToString(rows);\r\n downloadFile(name, content, \"csv\", measureCSVFilter);\r\n }\r\n\r\n /** @private */\r\n getDataExport(measurementGroup: MeasurementGroup, viewProjection=false) {\r\n let data = {\r\n count: 0,\r\n name: measurementGroup.name,\r\n projection: LocalScene.dataProjection,\r\n measurements: {\r\n measurements2D: [],\r\n measurements3D: []\r\n }\r\n };\r\n\r\n let measurements = measurementGroup.measurements;\r\n measurements.forEach(measurement => {\r\n let measurement_coordinates;\r\n if (viewProjection) {\r\n measurement_coordinates = measurement.vertices.map(vertex => {\r\n let vertextView = vertex.toViewProjection();\r\n let coordinates = [vertextView.x, vertextView.y];\r\n if (typeof vertextView.z !== 'undefined') {\r\n coordinates.push(vertextView.z);\r\n }\r\n return coordinates;\r\n });\r\n } else {\r\n measurement_coordinates = measurement.coordinates;\r\n }\r\n\r\n const created = measurement.timeCreated\r\n .toISOString()\r\n .split('.')[0];\r\n\r\n const info = {\r\n id: null,\r\n coordinates: measurement_coordinates,\r\n time_created: created,\r\n title: measurement.title,\r\n type: measurement.type,\r\n volume: null,\r\n station: null,\r\n along: null,\r\n across: null,\r\n units: null\r\n };\r\n\r\n if (measurement instanceof AerialMeasurement) {\r\n data.measurements.measurements2D.push(info);\r\n } else {\r\n if (measurement instanceof MeasurementVolume) {\r\n info.volume = measurement.volumeHelper.value;\r\n }\r\n if (measurement instanceof StationMeasurement) {\r\n info.station = measurement.stationStart;\r\n info.across = measurement.distanceAcross;\r\n info.along = measurement.distanceAlong;\r\n info.units = measurement.units;\r\n }\r\n\r\n data.measurements.measurements3D.push(info);\r\n }\r\n\r\n data.count += 1;\r\n });\r\n\r\n return data;\r\n }\r\n\r\n /** @private */\r\n getExportRows2D(measurementGroup, ordering) {\r\n let measureCsvOut = [];\r\n\r\n const precision = this.formatter\r\n .getVectorPrecision(LocalScene.viewProjection);\r\n\r\n let measurements = measurementGroup.measurements.filter(measurement =>\r\n measurement instanceof AerialMeasurement\r\n );\r\n\r\n if (measurements.length === 0) {\r\n return measureCsvOut;\r\n }\r\n\r\n let mapProjection = this.viewer.minimap.mapSystem;\r\n\r\n let header = this.getHeaderValues2D(measurements, ordering);\r\n let nullValue = this.formatter.nullValue;\r\n measureCsvOut.push(header);\r\n\r\n // Load measurements in reverse order\r\n measurements.reverse();\r\n measurements.forEach(measurement => {\r\n let row;\r\n let value;\r\n\r\n if (measurement instanceof AerialAreaMeasurement) {\r\n value = this.formatter.convertUnits(\r\n measurement.area2d, measurement.type);\r\n row = [measurement.title, t('measure.area'), nullValue, value];\r\n } else {\r\n value = this.formatter.convertUnits(\r\n measurement.distance2D, measurement.type);\r\n row = [measurement.title, t('measure.length'), value, nullValue];\r\n }\r\n\r\n let coordinates = measurement.geometry.flatCoordinates;\r\n if (measurement instanceof AerialAreaMeasurement) {\r\n coordinates = coordinates.slice(0, coordinates.length - 2);\r\n }\r\n\r\n let vertices = [];\r\n let numPoints = coordinates.length / 2.0;\r\n\r\n for (var i = 0; i < numPoints; i++) {\r\n let x = coordinates[2 * i];\r\n let y = coordinates[(2 * i) + 1];\r\n\r\n let coord = new Vector3(x, y, 0.0);\r\n let ecef = new ProjectedCoordinate(coord, mapProjection).toGeocentric();\r\n let proj = new GeocentricCoordinate(ecef).toViewProjection();\r\n vertices.push(proj);\r\n }\r\n\r\n vertices.forEach(vertex => {\r\n // Export with x and y values swapped\r\n if (ordering === \"yxz\") {\r\n vertex = new Vector3(vertex.y, vertex.x, vertex.z);\r\n }\r\n\r\n row = row.concat([\r\n vertex.x.toFixed(precision.x),\r\n vertex.y.toFixed(precision.y),\r\n ]);\r\n });\r\n\r\n measureCsvOut.push(row);\r\n });\r\n\r\n return measureCsvOut;\r\n }\r\n\r\n /** @private */\r\n getExportRows3D(measurementGroup, ordering) {\r\n let measureCsvOut = [];\r\n\r\n const precision = this.formatter\r\n .getVectorPrecision(LocalScene.viewProjection);\r\n\r\n let measurements = measurementGroup.measurements.filter(measurement =>\r\n measurement instanceof Measurement3D\r\n );\r\n\r\n if (measurements.length === 0) {\r\n return measureCsvOut;\r\n }\r\n\r\n let header = this.getHeaderValues3D(measurements, ordering);\r\n let nullValue = this.formatter.nullValue;\r\n measureCsvOut.push(header);\r\n\r\n // Load measurements in reverse order\r\n measurements.reverse();\r\n measurements.forEach(measurement => {\r\n let row;\r\n\r\n if (measurement instanceof MeasurementPoint) {\r\n // Most data will be blank for a single point\r\n row = [\r\n measurement.title,\r\n nullValue,\r\n nullValue,\r\n nullValue,\r\n nullValue,\r\n nullValue,\r\n nullValue,\r\n nullValue,\r\n nullValue\r\n ];\r\n } else if (measurement instanceof StationMeasurement){\r\n row = [\r\n measurement.title,\r\n this.formatter.convertUnits(\r\n measurement.distance2D, measurement.type),\r\n this.formatter.convertUnits(\r\n measurement.distance3D, measurement.type),\r\n nullValue,\r\n nullValue,\r\n this.formatter.formatGrade(measurement.grade, false),\r\n this.formatter.formatAngle(measurement.angle, false),\r\n this.formatter.formatStation(measurement, false),\r\n this.formatter.formatOffset(measurement, false)\r\n ];\r\n } else if (measurement instanceof MeasurementArea) {\r\n let areaValue;\r\n let volumeValue = nullValue;\r\n\r\n if (measurement.valid) {\r\n areaValue = this.formatter.convertUnits(\r\n measurement.area3D, measurement.type);\r\n } else {\r\n areaValue = measurement.areaInvalidMessage;\r\n }\r\n\r\n if (measurement instanceof MeasurementVolume) {\r\n volumeValue = measurement.invalidVolumeMessage;\r\n if (measurement.valid && measurement.calculated) {\r\n volumeValue = this.formatter.convertUnits(\r\n measurement.volume, measurement.type);\r\n }\r\n }\r\n\r\n row = [\r\n measurement.title,\r\n nullValue,\r\n nullValue,\r\n areaValue,\r\n volumeValue,\r\n nullValue,\r\n nullValue,\r\n nullValue,\r\n nullValue\r\n ];\r\n } else {\r\n row = [\r\n measurement.title,\r\n this.formatter.convertUnits(\r\n measurement.distance2D, measurement.type),\r\n this.formatter.convertUnits(\r\n measurement.distance3D, measurement.type),\r\n nullValue,\r\n nullValue,\r\n this.formatter.formatGrade(measurement.grade, false),\r\n this.formatter.formatAngle(measurement.angle, false),\r\n nullValue,\r\n nullValue\r\n ];\r\n }\r\n\r\n let verticesReprojected = measurement.vertices.map(vertex => {\r\n return vertex.toViewProjection();\r\n });\r\n\r\n verticesReprojected.forEach(vertex => {\r\n // Export with x and y values swapped\r\n if (ordering === \"yxz\") {\r\n vertex = new Vector3(vertex.y, vertex.x, vertex.z);\r\n }\r\n\r\n row = row.concat([\r\n vertex.x.toFixed(precision.x),\r\n vertex.y.toFixed(precision.y),\r\n vertex.z.toFixed(precision.z)\r\n ]);\r\n });\r\n\r\n measureCsvOut.push(row);\r\n });\r\n\r\n return measureCsvOut;\r\n }\r\n\r\n getHeaderValues2D(measurements, ordering) {\r\n let header = [\r\n t('measure.notes'),\r\n t('measure.measure-type'),\r\n t('measure.length-formatter-units', {\r\n units: this.formatter.units\r\n }),\r\n t('measure.area-formatter-units-2', {\r\n units: this.formatter.units\r\n })\r\n ];\r\n\r\n let numVertices = 0;\r\n measurements.forEach(measurement => {\r\n let coordinates = measurement.geometry.flatCoordinates;\r\n if (measurement instanceof AerialAreaMeasurement) {\r\n coordinates = coordinates.slice(0, coordinates.length - 2);\r\n }\r\n\r\n let numPoints = coordinates.length / 2.0;\r\n numVertices = Math.max(numVertices, numPoints);\r\n });\r\n\r\n for (var i = 0; i < numVertices; i++) {\r\n if (ordering === \"yxz\") {\r\n header = header.concat([`Y_${i + 1}`, `X_${i + 1}`]);\r\n } else {\r\n header = header.concat([`X_${i + 1}`, `Y_${i + 1}`]);\r\n }\r\n }\r\n\r\n return header;\r\n }\r\n\r\n getHeaderValues3D(measurements, ordering) {\r\n let header = [\r\n t('measure.notes'),\r\n t('measure.distance-2d-formatter-units', {\r\n units: this.formatter.units\r\n }),\r\n t('measure.distance-3d-formatter-units', {\r\n units: this.formatter.units\r\n }),\r\n t('measure.area-3d-formatter-areaunits', {\r\n units: this.formatter.areaUnits\r\n }),\r\n t('measure.volume-3d-formatter-volumeunits', {\r\n units: this.formatter.volumeUnits\r\n }),\r\n t('measure.grade'),\r\n t('measure.angle-deg'),\r\n t('measure.station-info'),\r\n t('measure.station-offset')\r\n ];\r\n\r\n // Determine the max number of vertices\r\n let numVertices = 0;\r\n measurements.forEach(measurement => {\r\n let measurementVertices = measurement.vertices.length;\r\n numVertices = Math.max(numVertices, measurementVertices);\r\n });\r\n\r\n for (var i = 0; i < numVertices; i++) {\r\n if (ordering === \"yxz\") {\r\n header = header.concat([`Y_${i + 1}`, `X_${i + 1}`, `Z_${i + 1}`]);\r\n } else {\r\n header = header.concat([`X_${i + 1}`, `Y_${i + 1}`, `Z_${i + 1}`]);\r\n }\r\n }\r\n\r\n return header;\r\n }\r\n\r\n exportLinework = (measurementGroup, type) => {\r\n const isDXF = type === \"dxf\";\r\n dialog.showSaveDialog({\r\n defaultPath: this.viewer.projectName,\r\n filters: [\r\n ...(isDXF ? DXFModelFilter : []),\r\n ...(!isDXF ? ZIPFileFilter : [])\r\n ],\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n if (result.filePath) {\r\n const filePath = slash(result.filePath);\r\n const extension = path.extname(filePath);\r\n\r\n const data = this.getDataExport(measurementGroup, true);\r\n const content = JSON.stringify(data, null, 2);\r\n\r\n let temp3DMPath = getTemporaryFile(\"3dm\");\r\n try {\r\n fs.writeFileSync(temp3DMPath, content);\r\n } catch (err) {\r\n console.log(err);\r\n toast.error(t(\"toast.measurement-export-failed\"));\r\n return;\r\n }\r\n\r\n let pythonName = 'linework_from_3dm';\r\n\r\n if (!pythonName) {\r\n return;\r\n }\r\n\r\n let exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--3dm_path\", temp3DMPath,\r\n `--output_path`, filePath\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onClose: () => {\r\n toast.success(t(\"toast.measurement-export-success\", {\r\n type: extension,\r\n path: path.basename(filePath)\r\n }));\r\n }\r\n });\r\n\r\n }\r\n });\r\n }\r\n}\r\n","import {GeocentricCoordinate} from '../projections';\r\nimport {\r\n AerialAreaMeasurement,\r\n AerialLengthMeasurement,\r\n AerialMeasurement,\r\n HeightMeasurement,\r\n Measurement,\r\n Measurement3D,\r\n MeasurementArea,\r\n MeasurementController,\r\n MeasurementLine,\r\n MeasurementPoint,\r\n MeasurementVolume,\r\n StationMeasurement\r\n} from '.';\r\nimport {Vector3} from \"three\";\r\nimport { MeasureType } from '../../../types/measurements';\r\n\r\nexport class MeasurementGroup {\r\n public name;\r\n public controller: MeasurementController;\r\n public measurements = [];\r\n\r\n get viewer() {\r\n return this.controller.viewer;\r\n }\r\n\r\n constructor(controller) {\r\n this.controller = controller;\r\n }\r\n\r\n add(measurement) {\r\n this.measurements.push(measurement);\r\n this.updateMeasurements();\r\n }\r\n\r\n getByID(id) {\r\n return this.measurements.find(measurement => measurement.id === id);\r\n }\r\n\r\n removeByID(id) {\r\n this.removeFromArray(id);\r\n this.updateMeasurements();\r\n }\r\n\r\n removeFromArray(id) {\r\n this.measurements = this.measurements.filter(measurement => measurement.id !== id);\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n }\r\n\r\n removeAll() {\r\n this.measurements.forEach(measurement => {\r\n measurement.clear();\r\n });\r\n this.measurements = [];\r\n this.updateMeasurements();\r\n }\r\n\r\n updateMeasurements() {\r\n this.controller.refreshMeasurementList();\r\n }\r\n\r\n loadMeasurements(result) {\r\n // Add 3d measurements\r\n let measure3D = result.measurements3D.map(measurement => {\r\n let newMeasurement = this.getEmptyMeasurement(measurement.type);\r\n newMeasurement.setController(this.controller);\r\n newMeasurement.setTitle(measurement.title);\r\n newMeasurement.setTimestamp(measurement.time_created);\r\n\r\n measurement.coordinates.forEach(vertex => {\r\n vertex = new Vector3().fromArray(vertex);\r\n if (vertex.length() === 0) return;\r\n\r\n newMeasurement.vertices.push(new GeocentricCoordinate(vertex));\r\n });\r\n\r\n if (newMeasurement instanceof MeasurementArea) {\r\n newMeasurement.generateSurface();\r\n }\r\n\r\n if (newMeasurement instanceof MeasurementVolume) {\r\n newMeasurement.loadExistingVolume(measurement.volume);\r\n }\r\n\r\n if (newMeasurement instanceof StationMeasurement) {\r\n newMeasurement.loadExistingStation(measurement);\r\n }\r\n\r\n return newMeasurement;\r\n });\r\n\r\n // Add 2d measurements\r\n let measure2D = result.measurements2D.map(measurement => {\r\n let newMeasurement = (measurement.type === MeasureType.Length)\r\n ? new AerialLengthMeasurement()\r\n : new AerialAreaMeasurement();\r\n\r\n newMeasurement.loadFromCoordinates(measurement.coordinates);\r\n newMeasurement.setController(this.controller);\r\n newMeasurement.setTitle(measurement.title);\r\n newMeasurement.setTimestamp(measurement.time_created);\r\n\r\n return newMeasurement;\r\n });\r\n\r\n this.measurements = [...measure3D, ...measure2D];\r\n\r\n // Sort by reverse timestamp ordering\r\n this.measurements = this.measurements.sort((a, b) =>\r\n a.timestamp < b.timestamp ? 1 : b.timestamp < a.timestamp ? -1 : 0\r\n );\r\n this.measurements.reverse();\r\n\r\n // Display the measurements\r\n this.measurements.forEach(measurement => {\r\n this.controller.renderMeasurement(measurement);\r\n });\r\n\r\n // Make sure drag object is false\r\n this.controller.resetDragObject();\r\n }\r\n\r\n getEmptyMeasurement(type: MeasureType) {\r\n if (type === MeasureType.Point) {\r\n return new MeasurementPoint();\r\n } else if (type === MeasureType.Area) {\r\n return new MeasurementArea();\r\n } else if (type === MeasureType.Volume) {\r\n return new MeasurementVolume();\r\n } else if (type === MeasureType.Height) {\r\n return new HeightMeasurement();\r\n } else if (type === MeasureType.Station) {\r\n return new StationMeasurement();\r\n }\r\n\r\n return new MeasurementLine();\r\n }\r\n\r\n getLineCoordinates(projection) {\r\n let lines = [];\r\n let names = [];\r\n let measurements = this.measurements;\r\n\r\n measurements.forEach(measurement => {\r\n if (measurement instanceof MeasurementPoint) {\r\n return;\r\n }\r\n\r\n let isAerial = measurement instanceof AerialMeasurement;\r\n let isLine = measurement instanceof Measurement3D;\r\n if (isAerial || isLine) {\r\n let line = measurement.getProjectedVertices(projection);\r\n lines.push(line);\r\n names.push(measurement.title);\r\n }\r\n });\r\n\r\n return {\r\n data: lines,\r\n names: names\r\n };\r\n }\r\n\r\n getPointCoordinates(projection) {\r\n let points = [];\r\n let names = [];\r\n let measurements = this.measurements;\r\n\r\n measurements.forEach(measurement => {\r\n if (measurement instanceof MeasurementPoint) {\r\n let point = measurement.getProjectedVertices(projection);\r\n points.push(point[0]);\r\n names.push(measurement.title);\r\n }\r\n });\r\n\r\n return {\r\n data: points,\r\n names: names\r\n };\r\n }\r\n\r\n getAreaGeometry(temporaryMeasurement: Measurement = null) {\r\n let measurements = [...this.measurements];\r\n\r\n if (temporaryMeasurement) {\r\n measurements.push(temporaryMeasurement);\r\n }\r\n\r\n let areaMeasurements = measurements.filter(measurement => {\r\n return measurement instanceof MeasurementArea;\r\n });\r\n\r\n let measureGeometry = [];\r\n areaMeasurements.forEach(measurement => {\r\n if (!measurement.valid) return;\r\n\r\n let volumeStatus = 0;\r\n if (measurement instanceof MeasurementVolume) {\r\n volumeStatus = measurement.calculated ? 2 : 1;\r\n }\r\n\r\n measureGeometry.push({\r\n vertices: measurement.surfaceVertices,\r\n indices: measurement.surfaceIndices,\r\n volumeStatus: volumeStatus\r\n });\r\n });\r\n\r\n measureGeometry.sort((a, b) => {\r\n return a.volumeStatus - b.volumeStatus;\r\n });\r\n measureGeometry.reverse();\r\n\r\n return measureGeometry;\r\n }\r\n}\r\n","import { CustomMouseEvent } from '../controls';\r\nimport { SceneCoordinate } from '../projections';\r\nimport { ChangeDetector, getPointScale } from '../utilities';\r\nimport {\r\n MeasurementArea,\r\n MeasurementVolume,\r\n MeasurementController,\r\n Measurement,\r\n HeightMeasurement,\r\n MeasurementLine,\r\n MeasurementType,\r\n StationMeasurement\r\n} from '.';\r\nimport {\r\n Mesh,\r\n Scene,\r\n SphereGeometry,\r\n MeshBasicMaterial,\r\n LineBasicMaterial,\r\n Line,\r\n BufferGeometry,\r\n Vector3,\r\n Sphere\r\n} from 'three';\r\nimport { setViewerTooltip } from '../../viewer';\r\nimport { RayCaster } from '../ray-caster';\r\nimport { t } from '../../../localization';\r\n\r\ninterface MeasureObject {\r\n id: number\r\n lines: Line[]\r\n points: MeasureEndpoint[]\r\n annotations: any[]\r\n}\r\n\r\nconst alternateAnnotationColor = \"lightgreen\";\r\n\r\nexport class MeasureEndpoint extends Mesh {\r\n public measurementVertex;\r\n public measurementID;\r\n\r\n constructor(geometry, material, index, id) {\r\n super(geometry, material);\r\n this.measurementVertex = index;\r\n this.measurementID = id;\r\n }\r\n\r\n /** Custom hit detection based on bounding sphere */\r\n raycast(raycaster, intersects) {\r\n const sphere = new Sphere();\r\n sphere.copy(this.geometry.boundingSphere);\r\n sphere.applyMatrix4(this.matrixWorld);\r\n\r\n const ray = raycaster.ray;\r\n if (!ray.intersectsSphere(sphere)) return;\r\n\r\n const origin = raycaster.ray.origin;\r\n const distance = origin.distanceTo(this.position);\r\n\r\n intersects.push({\r\n distance: distance,\r\n point: null,\r\n object: this\r\n });\r\n }\r\n}\r\n\r\nexport class TemporaryEndpoint extends Mesh {\r\n constructor(geometry, material) {\r\n super(geometry, material);\r\n }\r\n}\r\n\r\nexport class MeasurementSceneView {\r\n private controller: MeasurementController;\r\n private scene: Scene;\r\n\r\n private sphereBuffer = 1.2;\r\n private sphereGeometry = new SphereGeometry(0.05, 20, 20);\r\n private sphereMaterialStandard = new MeshBasicMaterial({color: 0xffffff});\r\n private sphereMaterialHover = new MeshBasicMaterial({color: 0xffcc33});\r\n private lineMaterialStandard = new LineBasicMaterial({color: 0x008B8B});\r\n private lineMaterialHeight = new LineBasicMaterial({color: 0xFF7474});\r\n private lineMaterialHover = new LineBasicMaterial({color: 0xffcc33});\r\n\r\n private measurements: MeasureObject[] = [];\r\n private temporaryEndpoints: TemporaryEndpoint[] = [];\r\n private temporaryLines = [];\r\n private temporaryAnnotations = [];\r\n public hoveredPoint: TemporaryEndpoint = null;\r\n public dragObject: MeasureEndpoint = null;\r\n private dragValid = false;\r\n\r\n constructor(controller, scene) {\r\n this.controller = controller;\r\n this.scene = scene;\r\n }\r\n\r\n get viewer() {\r\n return this.controller.viewer;\r\n }\r\n\r\n get camera() {\r\n return this.viewer.camera;\r\n }\r\n\r\n get dragTooltip() {\r\n return [\r\n t('measure.click-and-hold-to-move-vertex')\r\n ];\r\n }\r\n\r\n get restrictedTooltip() {\r\n return [\r\n t('measure.unable-to-move-this-measurement-type')\r\n ];\r\n }\r\n\r\n get formatter() {\r\n return this.controller.formatter;\r\n }\r\n\r\n get measurementGroup() {\r\n return this.controller.measurementGroup;\r\n }\r\n\r\n onMouseMove(event: CustomMouseEvent) {\r\n if (!this.controller.enabled) return false;\r\n\r\n if (!event.mouseMoved && !event.mouseDown) {\r\n this.checkEndpointSelected(event);\r\n }\r\n\r\n if (this.controller.measuring) {\r\n let measurement = this.controller.activeMeasurement;\r\n let coordinate = this.controller.getCoordinate(event);\r\n this.addActiveEndpoint(measurement, coordinate);\r\n }\r\n\r\n if (this.dragObject) {\r\n //this.setPointGrabTooltip();\r\n\r\n if (event.mouseDown) {\r\n if (event.isLeftClick) {\r\n let coordinate = this.controller.getCoordinate(event);\r\n this.updateMeasureEndpoint(coordinate);\r\n return true;\r\n }\r\n }\r\n } else {\r\n this.controller.updateMeasureText();\r\n }\r\n\r\n return false;\r\n }\r\n\r\n updateMeasureEndpoint(coordinate) {\r\n if (!this.dragObject) return;\r\n if (!coordinate) return;\r\n\r\n let id = this.dragObject.measurementID;\r\n let vertexIndex = this.dragObject.measurementVertex;\r\n let measurement = this.measurementGroup.getByID(id);\r\n\r\n if (!measurement) return;\r\n\r\n if (measurement instanceof StationMeasurement) {\r\n this.setRestrictedPointTooltip();\r\n this.dragValid = false;\r\n return;\r\n }\r\n if (measurement instanceof MeasurementVolume) {\r\n measurement.stopVolumeCalculation();\r\n }\r\n\r\n this.dragValid = true;\r\n\r\n // Update our measurement vertex value\r\n let vertex = new SceneCoordinate(coordinate).toGeocentric();\r\n measurement.vertices[vertexIndex] = vertex;\r\n\r\n // Clear existing measurement and redraw\r\n this.removeByID(measurement.id);\r\n this.render(measurement);\r\n }\r\n\r\n measureGrabFinished() {\r\n if ((!this.dragObject) || (!this.dragValid)) return;\r\n\r\n this.controller.refreshMeasurementList();\r\n\r\n this.measurementGroup.measurements.forEach(measurement => {\r\n if (measurement instanceof MeasurementVolume) {\r\n if (measurement.calculated) return;\r\n measurement.calculateVolume();\r\n }\r\n });\r\n }\r\n\r\n checkEndpointSelected(event) {\r\n let controller = this.controller;\r\n if (!controller.editable) return;\r\n if (controller.measuring) return;\r\n\r\n let targets = this.scene.children\r\n .filter(x => x instanceof MeasureEndpoint);\r\n\r\n let raycaster = new RayCaster(this.viewer, event);\r\n let objects = raycaster.intersectObjects(targets, {\r\n minDistance: 0.10,\r\n sortByRay: true\r\n });\r\n\r\n let draggable = objects.length > 0;\r\n let dragObject = draggable ? objects[0].object : null;\r\n this.setDragObject(dragObject);\r\n }\r\n\r\n setDragObject(dragObject) {\r\n // Image-only measurements can't be dragged\r\n if (this.controller.isImageOnly) {\r\n dragObject = null;\r\n }\r\n\r\n this.dragObject = dragObject;\r\n\r\n let draggable = dragObject ? true : false;\r\n let controls = this.controller.controls;\r\n controls.setMovementState(!draggable);\r\n\r\n if (dragObject) {\r\n this.setPointGrabTooltip();\r\n }\r\n }\r\n\r\n setPointGrabTooltip() {\r\n setViewerTooltip(this.dragTooltip);\r\n }\r\n\r\n setRestrictedPointTooltip() {\r\n setViewerTooltip(this.restrictedTooltip);\r\n }\r\n\r\n setTooltipText(measurement: MeasurementType, morepoints = false) {\r\n let tooltipText = [] as string[];\r\n\r\n if (morepoints) {\r\n let endTooltipCount = measurement.minVertexRequired - 1;\r\n endTooltipCount = Math.max(2, endTooltipCount);\r\n\r\n if (measurement.vertices.length < endTooltipCount) {\r\n tooltipText = this.controller.isImageOnly\r\n ? measurement.moreTooltipMulti\r\n : measurement.moreTooltip;\r\n } else {\r\n tooltipText = this.controller.isImageOnly\r\n ? measurement.endTooltipMulti\r\n : measurement.endTooltip;\r\n }\r\n } else {\r\n tooltipText = this.controller.isImageOnly\r\n ? measurement.startTooltipMulti\r\n : measurement.startTooltip;\r\n }\r\n\r\n setViewerTooltip(tooltipText);\r\n }\r\n\r\n setPointScale(mesh) {\r\n const scale = getPointScale(this.camera, mesh);\r\n mesh.scale.set(scale, scale, scale);\r\n mesh.geometry.computeBoundingSphere();\r\n mesh.geometry.boundingSphere.radius *= this.sphereBuffer;\r\n }\r\n\r\n addTemporaryPoint(coordinate) {\r\n let sphere = this.createTempEndpoint(coordinate);\r\n this.scene.add(sphere);\r\n this.temporaryEndpoints.push(sphere);\r\n }\r\n\r\n addActiveEndpoint(measurement, coordinate) {\r\n if (coordinate === null) return;\r\n\r\n if (this.hoveredPoint) {\r\n this.scene.remove(this.hoveredPoint);\r\n }\r\n\r\n let sphere = this.createTempEndpoint(coordinate);\r\n this.scene.add(sphere);\r\n this.hoveredPoint = sphere;\r\n\r\n this.removeObjects(this.temporaryLines);\r\n this.removeAnnotations(this.temporaryAnnotations);\r\n\r\n this.temporaryLines = [];\r\n this.temporaryAnnotations = [];\r\n\r\n // Draw new lines and area\r\n let vertices = [...this.temporaryEndpoints, this.hoveredPoint]\r\n .map(point => point.position);\r\n\r\n const temporaryPoint = new SceneCoordinate(\r\n this.hoveredPoint.position);\r\n\r\n this.temporaryLines = this.drawLines(\r\n measurement, vertices, temporaryPoint);\r\n\r\n this.temporaryAnnotations = this.drawAnnotations(\r\n measurement, this.temporaryLines);\r\n }\r\n\r\n createEndpoint(coordinates, index, id) {\r\n let sphere = new MeasureEndpoint(this.sphereGeometry,\r\n this.sphereMaterialStandard, index, id);\r\n\r\n sphere.position.copy(coordinates);\r\n this.setPointScale(sphere);\r\n\r\n return sphere;\r\n }\r\n\r\n createTempEndpoint(coordinate) {\r\n let sphere = new TemporaryEndpoint(this.sphereGeometry,\r\n this.sphereMaterialStandard);\r\n\r\n sphere.position.copy(coordinate);\r\n this.setPointScale(sphere);\r\n\r\n return sphere;\r\n }\r\n\r\n createLine(start: Vector3, end: Vector3, useAlternate) {\r\n const vertices = [start.clone(), end.clone()];\r\n const geometry = new BufferGeometry().setFromPoints(vertices);\r\n const material = useAlternate\r\n ? this.lineMaterialHeight\r\n : this.lineMaterialStandard;\r\n\r\n let line = new Line(geometry, material);\r\n line.userData.defaultMaterial = material;\r\n\r\n return line;\r\n }\r\n\r\n setHover(id, hover) {\r\n let measurement = this.getByID(id);\r\n if (!measurement) return;\r\n\r\n for (let object of measurement.lines) {\r\n const lineMaterial = hover\r\n ? this.lineMaterialHover\r\n : object.userData.defaultMaterial;\r\n\r\n object.material = lineMaterial as LineBasicMaterial;\r\n object.material.needsUpdate = true;\r\n }\r\n\r\n for (let object of measurement.points) {\r\n const pointMaterial = hover\r\n ? this.sphereMaterialHover\r\n : this.sphereMaterialStandard;\r\n\r\n object.material = pointMaterial;\r\n object.material.needsUpdate = true;\r\n }\r\n }\r\n\r\n drawPoints(measurement: Measurement, vertices: Vector3[]): MeasureEndpoint[] {\r\n let points = [];\r\n\r\n for (let i=0; i= 3;\r\n if ((measurement instanceof MeasurementArea) && hasEnoughPoints) {\r\n vertices.push(vertices[0]);\r\n measurement.generateSurface(temporaryPoint);\r\n }\r\n\r\n // Draw standard lines\r\n for (let i=0; i vertices[1].z;\r\n let vertex0 = firstPointHigher ? vertices[0] : vertices[1];\r\n let vertex1 = firstPointHigher ? vertices[1] : vertices[0];\r\n let vertex2 = new SceneCoordinate([vertex0.x, vertex0.y, vertex1.z]);\r\n\r\n let line0 = this.createLine(vertex1, vertex2, true);\r\n this.scene.add(line0);\r\n lines.push(line0);\r\n\r\n let line1 = this.createLine(vertex2, vertex0, true);\r\n this.scene.add(line1);\r\n lines.push(line1);\r\n }\r\n\r\n return lines;\r\n }\r\n\r\n drawAnnotations(measurement: Measurement, lines: Line[]) {\r\n let totalLength = 0;\r\n let annotations = [];\r\n\r\n // Draw standard length annotations\r\n lines.forEach((line, index) => {\r\n const positions = line.geometry.attributes.position;\r\n const vertexA = new Vector3().fromBufferAttribute(positions, 0);\r\n const vertexB = new Vector3().fromBufferAttribute(positions, 1);\r\n\r\n const length = vertexA.distanceTo(vertexB);\r\n const message = this.formatter.formatLength(length);\r\n\r\n totalLength += length;\r\n\r\n const midpoint = new Vector3()\r\n .addVectors(vertexA, vertexB)\r\n .divideScalar(2.0);\r\n\r\n const position = new SceneCoordinate(midpoint)\r\n .toDataProjection()\r\n .toArray();\r\n\r\n const isHeight = measurement instanceof HeightMeasurement;\r\n const lastLines = index >= lines.length-2;\r\n\r\n const annotationStyle = (isHeight && lastLines)\r\n ? {color: alternateAnnotationColor}\r\n : null;\r\n\r\n const annotation = this.viewer.addAnnotation(\r\n message,\r\n position,\r\n null,\r\n annotationStyle\r\n );\r\n\r\n annotations.push(annotation);\r\n });\r\n\r\n let objectMessage;\r\n let objectPosition;\r\n\r\n // Total line length\r\n if (measurement instanceof MeasurementLine) {\r\n const line = lines[lines.length - 1];\r\n const positions = line.geometry.attributes.position;\r\n const endPoint = new Vector3().fromBufferAttribute(positions, 1);\r\n\r\n objectMessage = this.formatter.formatLength(totalLength);\r\n objectPosition = new SceneCoordinate(endPoint)\r\n .toDataProjection()\r\n .toArray();\r\n }\r\n\r\n // Total area / volume\r\n const hasEnoughLines = lines.length >= 3;\r\n if ((measurement instanceof MeasurementArea) && hasEnoughLines) {\r\n const midpoint = new Vector3();\r\n lines.forEach(line => {\r\n const positions = line.geometry.attributes.position;\r\n const vertex = new Vector3().fromBufferAttribute(positions, 1);\r\n midpoint.add(vertex);\r\n });\r\n midpoint.divideScalar(lines.length);\r\n\r\n if (measurement instanceof MeasurementVolume) {\r\n if (measurement.calculated) {\r\n objectMessage = this.formatter.formatVolume(measurement);\r\n }\r\n } else {\r\n objectMessage = this.formatter.formatArea(measurement.area3D);\r\n }\r\n\r\n objectPosition = new SceneCoordinate(midpoint)\r\n .toDataProjection()\r\n .toArray();\r\n }\r\n\r\n if (objectPosition && objectMessage) {\r\n const annotationStyle = {\r\n color: alternateAnnotationColor\r\n };\r\n\r\n const annotation = this.viewer.addAnnotation(\r\n objectMessage,\r\n objectPosition,\r\n null,\r\n annotationStyle\r\n );\r\n\r\n annotations.push(annotation);\r\n }\r\n\r\n this.viewer.updateAnnotations();\r\n\r\n return annotations;\r\n }\r\n\r\n render(measurement) {\r\n let oldMeasurement = this.getByID(measurement.id);\r\n this.removeMeasurement(oldMeasurement);\r\n\r\n const vertices = measurement.vertices\r\n .map(vertex => vertex.toScene());\r\n\r\n const points = this.drawPoints(measurement, vertices);\r\n const lines = this.drawLines(measurement, vertices);\r\n const annotations = this.drawAnnotations(measurement, lines);\r\n\r\n this.measurements.push({\r\n id: measurement.id,\r\n annotations,\r\n lines,\r\n points\r\n });\r\n }\r\n\r\n removeObjects(objects) {\r\n objects.forEach(object => {\r\n this.scene.remove(object);\r\n });\r\n }\r\n\r\n removeAnnotations(annotations) {\r\n annotations.forEach(annotation => {\r\n this.viewer.removeAnnotation(annotation);\r\n });\r\n\r\n this.viewer.updateAnnotations();\r\n }\r\n\r\n removeTemporaryObjects() {\r\n this.removeObjects(this.temporaryEndpoints);\r\n this.removeObjects(this.temporaryLines);\r\n this.removeAnnotations(this.temporaryAnnotations);\r\n\r\n if (this.hoveredPoint) {\r\n this.scene.remove(this.hoveredPoint);\r\n }\r\n\r\n this.temporaryLines = [];\r\n this.temporaryAnnotations = [];\r\n this.temporaryEndpoints = [];\r\n this.hoveredPoint = null;\r\n }\r\n\r\n getByID(id) {\r\n return this.measurements.find(measurement => measurement.id === id);\r\n }\r\n\r\n removeByID(id) {\r\n // Clear scene objects and remove from array\r\n let measurement = this.getByID(id);\r\n this.removeMeasurement(measurement);\r\n\r\n // Reset measurement volume/area values\r\n let measurementObject = this.measurementGroup.getByID(id);\r\n measurementObject.clear();\r\n }\r\n\r\n removeMeasurement(measurement) {\r\n if (!measurement) return;\r\n\r\n this.removeObjects(measurement.lines);\r\n this.removeObjects(measurement.points);\r\n this.removeAnnotations(measurement.annotations);\r\n\r\n this.measurements = this.measurements\r\n .filter(x => x.id !== measurement.id);\r\n }\r\n\r\n removeAll() {\r\n for (let measurement of this.measurements) {\r\n this.removeObjects(measurement.lines);\r\n this.removeObjects(measurement.points);\r\n this.removeAnnotations(measurement.annotations);\r\n }\r\n\r\n this.measurements = [];\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n if (!changeDetector.changed) return;\r\n\r\n this.temporaryEndpoints.forEach(mesh => {\r\n this.setPointScale(mesh);\r\n });\r\n\r\n this.measurements.forEach(measurement => {\r\n measurement.points.forEach(mesh => {\r\n this.setPointScale(mesh);\r\n });\r\n });\r\n }\r\n}\r\n","import {\r\n BufferAttribute,\r\n BufferGeometry,\r\n Color,\r\n Mesh,\r\n Points,\r\n Vector3,\r\n Camera,\r\n LineSegments,\r\n Object3D,\r\n Line,\r\n LineBasicMaterial,\r\n} from \"three\";\r\nimport { LinearEncoding, NearestFilter, RGBAFormat } from \"three/src/constants\";\r\nimport { WebGLRenderer } from \"three/src/renderers/WebGLRenderer\";\r\nimport { WebGLRenderTarget } from \"three/src/renderers/WebGLRenderTarget\";\r\nimport { Scene } from \"three/src/scenes/Scene\";\r\nimport { RayCaster } from \"./ray-caster\";\r\nimport { Viewer } from \"./main\";\r\nimport { BasicPickerMaterial, CustomSpriteMaterial } from \"./rendering\";\r\nimport { allIndexOf, eventToPixel } from \"./utilities\";\r\n\r\n/** Clone geometry and add gpu_index */\r\nexport const geometryWithIndex = (mesh) => {\r\n const pickerGeometry = mesh.geometry.clone();\r\n const indices = new Int32Array(pickerGeometry.attributes.position.count);\r\n pickerGeometry.setAttribute('gpu_index', new BufferAttribute(indices, 1));\r\n\r\n return pickerGeometry;\r\n};\r\n\r\nexport const copyGeometryValues = (pickerMesh, mesh) => {\r\n pickerMesh['originalObject'] = mesh;\r\n pickerMesh.position.copy(mesh.position);\r\n pickerMesh.rotation.copy(mesh.rotation);\r\n pickerMesh.scale.copy(mesh.scale);\r\n};\r\n\r\n/** Create basic gpu picker mesh from existing objects */\r\nexport const getBasicPicker = (object, constructor) => {\r\n // Clone geometry and add gpu_index\r\n const pickerGeometry = geometryWithIndex(object);\r\n\r\n // Create new picker material from existing material(s)\r\n let pickerMaterial;\r\n if (Array.isArray(object.material)) {\r\n pickerMaterial = object.material.map(material => {\r\n return new BasicPickerMaterial(material.side);\r\n });\r\n } else {\r\n pickerMaterial = new BasicPickerMaterial(object.material.side);\r\n }\r\n\r\n const pickerMesh = new constructor(pickerGeometry, pickerMaterial);\r\n copyGeometryValues(pickerMesh, object);\r\n\r\n return pickerMesh;\r\n};\r\n\r\n/** Create basic gpu picker mesh from sprite types */\r\nexport const getCustomSpritePicker = (mesh) => {\r\n const material = mesh.material;\r\n const constructor = mesh.constructor;\r\n\r\n // Clone geometry and add gpu_index\r\n const pickerGeometry = geometryWithIndex(mesh);\r\n\r\n // Clone material with gpuPicker=true\r\n const pickerMaterial = new CustomSpriteMaterial({\r\n map: material.map,\r\n gpuPicker: true,\r\n size: material.size\r\n });\r\n\r\n const pickerMesh = new constructor(pickerGeometry, pickerMaterial);\r\n copyGeometryValues(pickerMesh, mesh);\r\n\r\n return pickerMesh;\r\n};\r\n\r\nexport default class GPUPicker {\r\n private name\r\n public debug = false;\r\n public scene : Scene\r\n private viewer: Viewer\r\n private camera: Camera\r\n private numSections = 3;\r\n private sections;\r\n public target : WebGLRenderTarget\r\n private _needsUpdate = false;\r\n private oldClearColor = new Color();\r\n private newClearColor = new Color(0xffffff)\r\n public result;\r\n\r\n constructor(viewer: Viewer, name) {\r\n this.name = name;\r\n this.viewer = viewer;\r\n this.scene = new Scene();\r\n\r\n this.target = new WebGLRenderTarget(0, 0, {\r\n minFilter: NearestFilter,\r\n magFilter: NearestFilter,\r\n format: RGBAFormat,\r\n encoding: LinearEncoding,\r\n generateMipmaps: false\r\n });\r\n\r\n this.clearSections();\r\n }\r\n\r\n get height() {\r\n return this.target.height;\r\n }\r\n\r\n get width() {\r\n return this.target.width;\r\n }\r\n\r\n get renderer(): WebGLRenderer {\r\n return this.viewer.renderer;\r\n }\r\n\r\n get needsUpdate() {\r\n return this._needsUpdate;\r\n }\r\n\r\n set needsUpdate(value) {\r\n if (this.debug) {\r\n console.log(`Update ${this.name} picker state`, value);\r\n }\r\n\r\n this._needsUpdate = value;\r\n }\r\n\r\n remove(mesh) {\r\n this.scene.remove(mesh);\r\n this.needsUpdate = true;\r\n }\r\n\r\n add(mesh) {\r\n this.scene.add(mesh);\r\n mesh.material.transparent = false;\r\n this.needsUpdate = true;\r\n }\r\n\r\n clear() {\r\n this.scene.clear();\r\n }\r\n\r\n value(event) {\r\n let uv = eventToPixel(event);\r\n let tX = uv.x;\r\n let tY = this.height - uv.y;\r\n\r\n let sectionWidth = Math.floor(this.width/this.numSections);\r\n let sectionHeight = Math.floor(this.height/this.numSections);\r\n let sectionX = Math.floor(tX/sectionWidth);\r\n let sectionY = Math.floor(tY/sectionHeight);\r\n let sectionIndex = sectionX + (sectionY * this.numSections);\r\n\r\n tX = tX % sectionWidth;\r\n tY = tY % sectionHeight;\r\n let pixelIndex = 4 * (tX + tY * sectionWidth);\r\n\r\n if (this.sections[sectionIndex] === null) {\r\n const timeStart = performance.now();\r\n\r\n let startX = sectionX*sectionWidth;\r\n let startY = sectionY*sectionHeight;\r\n\r\n let pixelBuffer = new Uint8Array(4 * sectionWidth * sectionHeight);\r\n this.renderer.readRenderTargetPixels(this.target, startX, startY,\r\n sectionWidth, sectionHeight, pixelBuffer);\r\n\r\n // Update section results\r\n this.sections[sectionIndex] = pixelBuffer;\r\n\r\n const timeEnd = performance.now();\r\n let time = (timeEnd - timeStart).toFixed(1);\r\n\r\n if (this.debug) {\r\n console.log(`Render ${this.name} picker: ${time}ms`);\r\n }\r\n }\r\n\r\n let result = this.sections[sectionIndex];\r\n if (!result) {\r\n return null;\r\n }\r\n\r\n let mouseResult = new Uint8Array([\r\n result[pixelIndex + 0],\r\n result[pixelIndex + 1],\r\n result[pixelIndex + 2],\r\n result[pixelIndex + 3]\r\n ]);\r\n\r\n let pickerID = (mouseResult[0] << 24)\r\n + (mouseResult[1] << 16)\r\n + (mouseResult[2] << 8)\r\n + mouseResult[3];\r\n\r\n return (pickerID >= 0) ? pickerID : null;\r\n }\r\n\r\n update() {\r\n if (!this.needsUpdate) {\r\n return;\r\n }\r\n\r\n this.clearSections();\r\n this.updateBaseIDs();\r\n\r\n this.needsUpdate = false;\r\n\r\n let oldRenderTarget = this.renderer.getRenderTarget();\r\n this.renderer.getClearColor(this.oldClearColor);\r\n let oldClearAlpha = this.renderer.getClearAlpha();\r\n\r\n this.renderer.setRenderTarget(this.target);\r\n this.renderer.setClearColor(this.newClearColor);\r\n this.renderer.clear();\r\n this.renderer.render(this.scene, this.camera);\r\n this.renderer.setRenderTarget(oldRenderTarget);\r\n this.renderer.setClearColor(this.oldClearColor);\r\n this.renderer.setClearAlpha(oldClearAlpha);\r\n }\r\n\r\n clearSections() {\r\n this.sections = new Array(this.numSections**2).fill(null);\r\n }\r\n\r\n updateBaseIDs() {\r\n let currentBaseID = 0;\r\n this.scene.children.forEach((child: Mesh) => {\r\n let geometry = child.geometry as BufferGeometry;\r\n let indices = geometry.attributes.gpu_index.array as any;\r\n\r\n for (var i=0;i {\r\n if (object !== null) return;\r\n\r\n let geometry = (child as any).geometry as BufferGeometry;\r\n let indices = geometry.attributes.gpu_index.array as Array;\r\n\r\n // Determine if the index exists inside this object\r\n let minIndex = indices[0];\r\n let maxIndex = indices[indices.length - 1];\r\n if ((gpuIndex < minIndex) || (gpuIndex > maxIndex)) {\r\n return;\r\n }\r\n\r\n let arrayIndex = indices.indexOf(gpuIndex);\r\n if (arrayIndex === -1) return;\r\n\r\n object = child;\r\n });\r\n\r\n return object;\r\n }\r\n\r\n getObjectPosition(object, gpuIndex, event): Vector3 {\r\n let coordinate = null;\r\n if (!object) return coordinate;\r\n\r\n const geometry = object.geometry as BufferGeometry;\r\n const indices = geometry.attributes.gpu_index.array as Array;\r\n const positions = geometry.attributes.position;\r\n const index = indices.indexOf(gpuIndex);\r\n\r\n const parameters = {geometry, indices, positions, index};\r\n\r\n if (object instanceof Points) {\r\n coordinate = this.getCoordinate(object, positions, index);\r\n } else if (object instanceof Mesh) {\r\n coordinate = this.coordinateFromMesh(object, parameters, event);\r\n } else if (object instanceof LineSegments) {\r\n coordinate = this.coordinateFromLine(object, parameters, event);\r\n }\r\n\r\n return coordinate;\r\n }\r\n\r\n /** @private */\r\n coordinateFromMesh(object, parameters, event) {\r\n const {geometry, positions, index} = parameters;\r\n\r\n let coordinate = null;\r\n let trianglesToCheck = [];\r\n\r\n if (geometry.index !== null) {\r\n const faces = geometry.index.array as Array;\r\n const faceIndices = allIndexOf(faces, index);\r\n\r\n // Multiple base index might exist for this position. All\r\n // of them need to be added and checked for validity\r\n faceIndices.forEach(faceIndex => {\r\n faceIndex = Math.floor(faceIndex/3) * 3;\r\n trianglesToCheck.push([\r\n faces[faceIndex],\r\n faces[faceIndex + 1],\r\n faces[faceIndex + 2]\r\n ]);\r\n });\r\n } else {\r\n // Only one mesh face will exist\r\n const faceIndex = Math.floor(index/3) * 3;\r\n trianglesToCheck.push([faceIndex, faceIndex + 1, faceIndex + 2]);\r\n }\r\n\r\n const raycaster = new RayCaster(this.viewer, event);\r\n\r\n trianglesToCheck.forEach(face => {\r\n const P1 = this.getCoordinate(object, positions, face[0]);\r\n const P2 = this.getCoordinate(object, positions, face[1]);\r\n const P3 = this.getCoordinate(object, positions, face[2]);\r\n const result = raycaster.intersectTriangle(P1, P2, P3);\r\n if (!result) return;\r\n\r\n coordinate = result;\r\n });\r\n\r\n return coordinate;\r\n }\r\n\r\n /** @private */\r\n coordinateFromLine(object, parameters, event) {\r\n const {geometry, positions, index} = parameters;\r\n\r\n let isFirstPoint;\r\n if (geometry.index !== null) {\r\n // Index positions (check position in index array);\r\n const pointIndices = geometry.index.array as Array;\r\n const pointIndex = pointIndices.indexOf(index);\r\n isFirstPoint = (pointIndex % 2) === 0;\r\n } else {\r\n // Non-index positions\r\n isFirstPoint = (index % 2) === 0;\r\n }\r\n\r\n const P1 = this.getCoordinate(object, positions, index);\r\n const P2 = isFirstPoint\r\n ? this.getCoordinate(object, positions, index + 1)\r\n : this.getCoordinate(object, positions, index - 1);\r\n\r\n const lineMaterial = new LineBasicMaterial({});\r\n const lineGeometry = new BufferGeometry().setFromPoints([P1, P2]);\r\n const line = new Line( lineGeometry, lineMaterial );\r\n const raycaster = new RayCaster(this.viewer, event);\r\n const results = raycaster.intersectObject(line);\r\n\r\n return (results.length > 0)\r\n ? results[0].point\r\n : null;\r\n }\r\n\r\n /** @private */\r\n getCoordinate(object, positions, index) {\r\n return new Vector3()\r\n .fromBufferAttribute(positions, index)\r\n .applyMatrix4(object.matrixWorld);\r\n }\r\n}\r\n","var Stats = function () {\r\n\r\n var mode = 0;\r\n\r\n var container = document.createElement( 'div' );\r\n container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000';\r\n container.addEventListener( 'click', function ( event ) {\r\n\r\n event.preventDefault();\r\n showPanel( ++ mode % container.children.length );\r\n\r\n }, false );\r\n\r\n //\r\n\r\n function addPanel( panel ) {\r\n\r\n container.appendChild( panel.dom );\r\n return panel;\r\n\r\n }\r\n\r\n function showPanel( id ) {\r\n\r\n for ( var i = 0; i < container.children.length; i ++ ) {\r\n\r\n container.children[ i ].style.display = i === id ? 'block' : 'none';\r\n\r\n }\r\n\r\n mode = id;\r\n\r\n }\r\n\r\n //\r\n\r\n var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0;\r\n\r\n var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) );\r\n var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) );\r\n\r\n if ( window.self.performance && window.self.performance.memory ) {\r\n\r\n var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) );\r\n\r\n }\r\n\r\n showPanel( 0 );\r\n\r\n return {\r\n\r\n REVISION: 16,\r\n\r\n dom: container,\r\n\r\n addPanel: addPanel,\r\n showPanel: showPanel,\r\n\r\n begin: function () {\r\n\r\n beginTime = ( performance || Date ).now();\r\n\r\n },\r\n\r\n end: function () {\r\n\r\n frames ++;\r\n\r\n var time = ( performance || Date ).now();\r\n\r\n msPanel.update( time - beginTime, 200 );\r\n\r\n if ( time >= prevTime + 1000 ) {\r\n\r\n fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 );\r\n\r\n prevTime = time;\r\n frames = 0;\r\n\r\n if ( memPanel ) {\r\n\r\n var memory = performance.memory;\r\n memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 );\r\n\r\n }\r\n\r\n }\r\n\r\n return time;\r\n\r\n },\r\n\r\n update: function () {\r\n\r\n beginTime = this.end();\r\n\r\n },\r\n\r\n // Backwards Compatibility\r\n\r\n domElement: container,\r\n setMode: showPanel\r\n\r\n };\r\n\r\n};\r\n\r\nStats.Panel = function ( name, fg, bg ) {\r\n\r\n var min = Infinity, max = 0, round = Math.round;\r\n var PR = round( window.devicePixelRatio || 1 );\r\n\r\n var WIDTH = 80 * PR, HEIGHT = 48 * PR,\r\n TEXT_X = 3 * PR, TEXT_Y = 2 * PR,\r\n GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,\r\n GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;\r\n\r\n var canvas = document.createElement( 'canvas' );\r\n canvas.width = WIDTH;\r\n canvas.height = HEIGHT;\r\n canvas.style.cssText = 'width:80px;height:48px';\r\n\r\n var context = canvas.getContext( '2d' );\r\n context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif';\r\n context.textBaseline = 'top';\r\n\r\n context.fillStyle = bg;\r\n context.fillRect( 0, 0, WIDTH, HEIGHT );\r\n\r\n context.fillStyle = fg;\r\n context.fillText( name, TEXT_X, TEXT_Y );\r\n context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );\r\n\r\n context.fillStyle = bg;\r\n context.globalAlpha = 0.9;\r\n context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );\r\n\r\n return {\r\n\r\n dom: canvas,\r\n\r\n update: function ( value, maxValue ) {\r\n\r\n min = Math.min( min, value );\r\n max = Math.max( max, value );\r\n\r\n context.fillStyle = bg;\r\n context.globalAlpha = 1;\r\n context.fillRect( 0, 0, WIDTH, GRAPH_Y );\r\n context.fillStyle = fg;\r\n context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y );\r\n\r\n context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT );\r\n\r\n context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT );\r\n\r\n context.fillStyle = bg;\r\n context.globalAlpha = 0.9;\r\n context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) );\r\n\r\n }\r\n\r\n };\r\n\r\n};\r\n\r\nexport default Stats;\r\n","import { Viewer } from \"../main\";\r\nimport {\r\n DXFFile,\r\n DXFHandler,\r\n IFCFile,\r\n IFCHandler,\r\n SHPFile,\r\n SHPHandler\r\n} from \".\";\r\nimport {\r\n AmbientLight,\r\n LineSegments,\r\n Mesh,\r\n Scene,\r\n Points,\r\n Box3,\r\n MathUtils,\r\n TextureLoader,\r\n Color,\r\n Vector3,\r\n BufferGeometry,\r\n BufferAttribute,\r\n LineBasicMaterial,\r\n MeshBasicMaterial,\r\n Texture,\r\n Sprite,\r\n SpriteMaterial,\r\n LOD,\r\n Object3D,\r\n DoubleSide,\r\n LinearFilter\r\n} from \"three\";\r\nimport { Asset, AssetType, LineworkLayerData } from \"../../../redux/assets-slice\";\r\nimport { mergeBoundingBoxes } from \"../utilities\";\r\nimport { CustomSpriteMaterial } from \"../rendering\";\r\nimport spritePath from \"../../textures/sprites/point.png\";\r\nimport { getBasicPicker, getCustomSpritePicker } from \"../gpu-picker\";\r\nimport LocalScene, { reprojectPoints, webMercator } from \"../projections\";\r\nimport {Feature} from \"ol\";\r\nimport {MultiLineString, MultiPolygon, Point} from \"ol/geom\";\r\nimport {Vector as VectorSource} from \"ol/source\";\r\nimport * as olColor from 'ol/color';\r\nimport VectorLayer from \"ol/layer/Vector\";\r\nimport { Layer } from \"ol/layer\";\r\nimport WebGLVectorLayerRenderer from 'ol/renderer/webgl/VectorLayer.js';\r\n\r\nconst cadPointSize = 10;\r\n\r\nexport enum GeomType {\r\n Points = \"POINTS\",\r\n Lines = \"LINES\",\r\n Polygons = \"POLYGONS\",\r\n Text = \"TEXT\"\r\n}\r\n\r\ninterface SegmentInfo {\r\n numPoints: number\r\n properties: any\r\n}\r\n\r\nconst validGeomTypes = Object.values(GeomType) as string[];\r\n\r\nconst pointTexture = new TextureLoader().load(spritePath);\r\n\r\nclass WebGLLayer extends Layer {\r\n generateStyle() {\r\n return {\r\n symbol: {\r\n symbolType: 'circle',\r\n size: cadPointSize,\r\n color: ['get', 'symbolColor'],\r\n offset: [0, 0],\r\n opacity: 0.95,\r\n },\r\n 'stroke-color': ['get', 'strokeColor'],\r\n 'stroke-width': ['get', 'strokeWidth'],\r\n 'fill-color': ['get', 'fillColor']\r\n };\r\n }\r\n\r\n createRenderer() {\r\n const style = this.generateStyle();\r\n return new WebGLVectorLayerRenderer(this, {style});\r\n }\r\n}\r\n\r\nexport class LineworkPoints extends Points {\r\n constructor(geometry, material) {\r\n super(geometry, material);\r\n }\r\n\r\n updateMaterial(fov, height) {\r\n const material = this.material as CustomSpriteMaterial;\r\n material.screenHeight = height;\r\n material.fov = MathUtils.degToRad(fov);\r\n material.needsUpdate = true;\r\n }\r\n}\r\n\r\nexport class LineworkLine extends LineSegments {\r\n constructor(geometry, material) {\r\n super(geometry, material);\r\n }\r\n}\r\n\r\nexport class LineworkText extends LOD {\r\n public text;\r\n private mesh: Sprite;\r\n public material: SpriteMaterial;\r\n public geometry: BufferGeometry;\r\n public calculated = false;\r\n private maxDistance = 25;\r\n\r\n private fontSize = 48;\r\n private lineThickness = 4;\r\n private borderThickness = 4\r\n private borderRadius = 4;\r\n private margin = 5;\r\n\r\n constructor(text, color) {\r\n super();\r\n\r\n this.material = new SpriteMaterial({\r\n map: null,\r\n transparent: false,\r\n alphaTest: 0.6,\r\n color,\r\n opacity: 0.0\r\n });\r\n\r\n this.mesh = new Sprite(this.material);\r\n this.geometry = this.mesh.geometry;\r\n\r\n this.addLevel(this.mesh, 0);\r\n this.addLevel(new Object3D(), this.maxDistance);\r\n\r\n this.text = text;\r\n }\r\n\r\n drawBackground(ctx, x, y, w, h, r){\r\n ctx.beginPath();\r\n ctx.moveTo(x + r, y);\r\n ctx.lineTo(x + w - r, y);\r\n ctx.quadraticCurveTo(x + w, y, x + w, y + r);\r\n ctx.lineTo(x + w, y + h - r);\r\n ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\r\n ctx.lineTo(x + r, y + h);\r\n ctx.quadraticCurveTo(x, y + h, x, y + h - r);\r\n ctx.lineTo(x, y + r);\r\n ctx.quadraticCurveTo(x, y, x + r, y);\r\n ctx.closePath();\r\n ctx.fill();\r\n ctx.stroke();\r\n }\r\n\r\n generateTexture(text) {\r\n const numLines = text.length;\r\n const canvas = document.createElement('canvas');\r\n const font = `${this.fontSize}px Arial`;\r\n\r\n const context = canvas.getContext('2d');\r\n context.font = font;\r\n\r\n // Calculate accurate text width\r\n let textWidth = 0;\r\n text.forEach(line => {\r\n const width = Math.ceil(context.measureText(line).width);\r\n textWidth = Math.max(textWidth, width);\r\n });\r\n\r\n // Update canvas width and height with final values\r\n canvas.height = this.fontSize * (numLines + 0.5) + (2 * this.borderThickness);\r\n canvas.width = textWidth + (2 * this.margin) + (2 * this.borderThickness);\r\n context.font = font;\r\n\r\n if (false) {\r\n // Draw background\r\n context.lineWidth = this.borderThickness;\r\n context.fillStyle = \"#000000\";\r\n context.strokeStyle = \"#000000\";\r\n this.drawBackground(context,\r\n this.borderThickness / 2,\r\n this.borderThickness / 2,\r\n textWidth + this.borderThickness + 2 * this.margin,\r\n canvas.height - this.borderThickness,\r\n this.borderRadius\r\n );\r\n }\r\n\r\n // Draw text\r\n context.lineWidth = this.lineThickness;\r\n context.fillStyle = \"#ffffff\";\r\n context.strokeStyle = \"#000000\";\r\n\r\n text.forEach((line, i) => {\r\n const x = this.borderThickness + this.margin;\r\n const y = (i + 1) * this.fontSize + this.margin;\r\n\r\n context.strokeText(line, x, y);\r\n context.fillText(line, x, y);\r\n });\r\n\r\n const xScale = canvas.width / canvas.height;\r\n const textScale = new Vector3(xScale, 1.0, 1.0)\r\n .multiplyScalar(numLines)\r\n .divideScalar(3);\r\n\r\n let texture = new Texture(canvas);\r\n texture.flipY = true;\r\n texture.needsUpdate = true;\r\n texture.minFilter = LinearFilter;\r\n texture.magFilter = LinearFilter;\r\n\r\n return {texture, textScale};\r\n }\r\n\r\n updateTexture() {\r\n const {texture, textScale} = this.generateTexture(this.text);\r\n this.mesh.scale.copy(textScale);\r\n\r\n const material = this.mesh.material;\r\n material.opacity = 1.0;\r\n material.map = texture;\r\n material.needsUpdate = true;\r\n\r\n this.calculated = true;\r\n }\r\n}\r\n\r\nexport class LineworkPolygon extends Mesh {\r\n constructor(geometry, material) {\r\n super(geometry, material);\r\n }\r\n}\r\n\r\nexport class LineworkLayer {\r\n public id: string;\r\n public visible: boolean;\r\n public name: string;\r\n public file: LineworkFile\r\n protected color: string;\r\n protected enabled = true;\r\n\r\n public mapLayers = [];\r\n public standardMeshes = [];\r\n public pickingMeshes = [];\r\n public features = [];\r\n\r\n constructor(file: LineworkFile, layer: LineworkLayerData) {\r\n this.file = file;\r\n this.id = layer.id;\r\n this.visible = layer.visible;\r\n this.name = layer.name;\r\n this.color = layer.color;\r\n }\r\n\r\n get scene() {\r\n return this.file.scene;\r\n }\r\n\r\n get map() {\r\n return this.file.map;\r\n }\r\n\r\n get picker() {\r\n return this.file.picker;\r\n }\r\n\r\n get viewer() {\r\n return this.file.viewer;\r\n }\r\n\r\n get meshes() {\r\n return [...this.standardMeshes, ...this.pickingMeshes];\r\n }\r\n\r\n get mapSource() {\r\n return this.file.mapSource;\r\n }\r\n\r\n get mapLayer() {\r\n return this.file.mapLayer;\r\n }\r\n\r\n get meshColor() {\r\n return new Color(parseInt(this.color.slice(1), 16));\r\n }\r\n\r\n get styleColor() {\r\n return this.color;\r\n }\r\n\r\n /** @private */\r\n getCoordinateArray = (segments) => {\r\n let coordinates = [];\r\n let segmentInfo: SegmentInfo[] = [];\r\n\r\n // Generate combined coordinates array + segment lengths\r\n segments.forEach(segment => {\r\n segmentInfo.push({\r\n numPoints: segment.coordinates.length,\r\n properties: segment.properties\r\n } as SegmentInfo);\r\n\r\n segment.coordinates.forEach(coordinate => {\r\n coordinates.push(coordinate);\r\n });\r\n });\r\n\r\n return {coordinates, segmentInfo};\r\n }\r\n\r\n async addNewGeometry(data) {\r\n for (let type of Object.keys(data)) {\r\n if (!validGeomTypes.includes(type)) continue;\r\n\r\n const geomType = type as GeomType;\r\n const features = data[geomType];\r\n\r\n if (geomType === GeomType.Text) {\r\n // TODO: how to make this async? OffscreenCanvas isnt\r\n // supported in all browsers so a webworker wont help\r\n this.addTextData(features);\r\n } else {\r\n const {coordinates, segmentInfo} = this.getCoordinateArray(features);\r\n await this.addSceneData(coordinates, segmentInfo, geomType);\r\n await this.addAerialData(coordinates, segmentInfo, geomType);\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n addTextData(features) {\r\n features.forEach(feature => {\r\n const {coordinates, properties} = feature;\r\n const offset = new Vector3(...coordinates[0]);\r\n const text = properties.text;\r\n\r\n const shpMesh = new LineworkText(text, this.meshColor);\r\n\r\n // Convert offset to meters\r\n offset.multiplyScalar(LocalScene.dataToMeters);\r\n\r\n // Move model to scene coordinates\r\n const shift = LocalScene.offsetToScene(offset);\r\n shpMesh.position.copy(shift);\r\n\r\n if (!this.enabled) return;\r\n\r\n // Scene view mesh\r\n this.standardMeshes.push(shpMesh);\r\n this.scene.add(shpMesh);\r\n\r\n // Update visibility\r\n shpMesh.visible = this.visible;\r\n });\r\n }\r\n\r\n /** @private */\r\n async addAerialData(coordinates, segmentInfo: SegmentInfo[], geomType: GeomType) {\r\n if (coordinates.length === 0) return;\r\n if (!validGeomTypes.includes(geomType)) return;\r\n\r\n // Reproject points to web mercator\r\n const reprojected = await reprojectPoints(\r\n coordinates, LocalScene.dataProjection, webMercator);\r\n\r\n let mapCoordinates;\r\n let geometries = [];\r\n\r\n if (geomType === GeomType.Points) {\r\n // WebGL layer doesnt like MultiPoint, so we use Point instead\r\n reprojected.forEach(coordinate => {\r\n let geometry = new Point(coordinate);\r\n geometries.push(geometry);\r\n });\r\n } else if (geomType === GeomType.Polygons) {\r\n let polygonRings = [];\r\n const numFaces = reprojected.length / 3;\r\n for (let i=0; i {\r\n const {numPoints} = segmentInfo;\r\n const endIndex = startIndex + numPoints;\r\n const slice = reprojected.slice(startIndex, endIndex);\r\n mapCoordinates.push(slice);\r\n startIndex = endIndex;\r\n });\r\n\r\n geometries.push(new MultiLineString(mapCoordinates, \"XY\"));\r\n }\r\n\r\n const features = geometries.map(geometry => {\r\n const feature = new Feature({geometry});\r\n feature.set(\"geomType\", geomType);\r\n this.setFeatureColor(feature);\r\n return feature;\r\n });\r\n\r\n this.features = [...this.features, ...features];\r\n if (!this.visible) return;\r\n\r\n this.mapSource.addFeatures(features);\r\n }\r\n\r\n /** @private */\r\n async addSceneData(coordinates, segmentInfo: SegmentInfo[], geomType: GeomType) {\r\n if (coordinates.length === 0) return;\r\n\r\n // Not required for 2D data\r\n if (coordinates[0].length < 3) return;\r\n\r\n // Subtract offset to handle float32 issues\r\n const flatCoordinates = [];\r\n const offset = new Vector3(...coordinates[0]);\r\n coordinates.forEach(coordinate => {\r\n // Make sure height exists to avoid errors\r\n if (coordinate.length === 2) {\r\n coordinate.push(0);\r\n }\r\n\r\n flatCoordinates.push(\r\n coordinate[0] - offset.x,\r\n coordinate[1] - offset.y,\r\n coordinate[2] - offset.z\r\n );\r\n });\r\n\r\n const bufferGeometry = new BufferGeometry();\r\n const positions = new Float32Array(flatCoordinates);\r\n const gpuIndex = new Int32Array(flatCoordinates.length / 3);\r\n\r\n bufferGeometry.setAttribute('position', new BufferAttribute(positions, 3));\r\n bufferGeometry.setAttribute('gpu_index', new BufferAttribute(gpuIndex, 1));\r\n bufferGeometry.computeBoundingSphere();\r\n\r\n let material;\r\n let shpMesh;\r\n let pickerMesh;\r\n\r\n if (geomType === GeomType.Points) {\r\n // Create material and mesh objects\r\n material = new CustomSpriteMaterial({\r\n map: pointTexture,\r\n size: 0.10,\r\n gpuPicker: false,\r\n color: this.meshColor\r\n });\r\n\r\n shpMesh = new LineworkPoints(bufferGeometry, material);\r\n pickerMesh = getCustomSpritePicker(shpMesh);\r\n } else if (geomType === GeomType.Lines) {\r\n // Set geometry indices for line segments\r\n const bufferIndices = this.getLineIndices(segmentInfo);\r\n bufferGeometry.setIndex(bufferIndices);\r\n\r\n // Create material and mesh objects\r\n material = new LineBasicMaterial({\r\n color: this.meshColor\r\n });\r\n\r\n shpMesh = new LineworkLine(bufferGeometry, material);\r\n pickerMesh = getBasicPicker(shpMesh, LineSegments);\r\n } else if (geomType === GeomType.Polygons) {\r\n // Create material and mesh objects\r\n material = new MeshBasicMaterial({\r\n color: this.meshColor,\r\n side: DoubleSide\r\n });\r\n\r\n shpMesh = new Mesh(bufferGeometry, material);\r\n pickerMesh = getBasicPicker(shpMesh, Mesh);\r\n } else {\r\n return;\r\n }\r\n\r\n // Convert mesh to meters\r\n shpMesh.scale.setScalar(LocalScene.dataToMeters);\r\n pickerMesh.scale.setScalar(LocalScene.dataToMeters);\r\n offset.multiplyScalar(LocalScene.dataToMeters);\r\n\r\n // Move model to scene coordinates\r\n const shift = LocalScene.offsetToScene(offset);\r\n shpMesh.position.copy(shift);\r\n pickerMesh.position.copy(shift);\r\n\r\n if (!this.enabled) return;\r\n\r\n // Scene view mesh\r\n this.standardMeshes.push(shpMesh);\r\n this.scene.add(shpMesh);\r\n\r\n // Picking scene mesh\r\n this.pickingMeshes.push(pickerMesh);\r\n this.picker.add(pickerMesh);\r\n\r\n // Update visibility\r\n shpMesh.visible = this.visible;\r\n pickerMesh.visible = this.visible;\r\n }\r\n\r\n /** Generate bufferGeometry index values for line segments */\r\n getLineIndices(segmentInfo: SegmentInfo[]) {\r\n let geomIndex = 0;\r\n let bufferIndices = [];\r\n\r\n segmentInfo.forEach(segmentInfo => {\r\n const {numPoints} = segmentInfo;\r\n\r\n for (let i=0; i < numPoints-1; i++) {\r\n bufferIndices.push(geomIndex, geomIndex + 1);\r\n geomIndex = geomIndex + 1;\r\n }\r\n\r\n geomIndex = geomIndex + 1;\r\n });\r\n\r\n return bufferIndices;\r\n }\r\n\r\n removeFromScene(item) {\r\n if (!item) return;\r\n this.picker.remove(item);\r\n this.scene.remove(item);\r\n }\r\n\r\n disposeGeometry(item) {\r\n if (!item) return;\r\n item.geometry.dispose();\r\n item.material.dispose();\r\n }\r\n\r\n setVisibility(state) {\r\n if (state === this.visible) return;\r\n\r\n this.visible = state;\r\n\r\n this.features.forEach(feature => {\r\n try {\r\n if (this.visible) {\r\n this.mapSource.addFeature(feature);\r\n } else {\r\n this.mapSource.removeFeature(feature);\r\n }\r\n } catch(err) {\r\n // Feature has already been added/removed\r\n return;\r\n }\r\n });\r\n\r\n this.standardMeshes.forEach(standardMesh => {\r\n standardMesh.visible = state;\r\n });\r\n\r\n this.pickingMeshes.forEach(pickingMesh => {\r\n pickingMesh.visible = state;\r\n });\r\n }\r\n\r\n setFeatureColor(feature) {\r\n const geomType = feature.get(\"geomType\");\r\n feature.set(\"symbolColor\", this.styleColor);\r\n\r\n if (geomType === GeomType.Polygons) {\r\n // Fill color has 50% opacity\r\n feature.set(\"fillColor\", withOpacity(this.styleColor, 0.5));\r\n feature.set(\"strokeColor\", \"#000000\");\r\n feature.set(\"strokeWidth\", 1.0);\r\n } else {\r\n feature.set(\"fillColor\", this.styleColor);\r\n feature.set(\"strokeColor\", this.styleColor);\r\n feature.set(\"strokeWidth\", 2.0);\r\n }\r\n }\r\n\r\n setColor(color) {\r\n this.color = color;\r\n\r\n this.standardMeshes.forEach(mesh => {\r\n const material = mesh.material;\r\n material.color = this.meshColor;\r\n material.needsUpdate = true;\r\n });\r\n\r\n this.features.forEach(feature => {\r\n this.setFeatureColor(feature);\r\n });\r\n }\r\n\r\n destroy() {\r\n this.enabled = false;\r\n\r\n this.standardMeshes.forEach(standardMesh => {\r\n this.removeFromScene(standardMesh);\r\n this.disposeGeometry(standardMesh);\r\n });\r\n this.standardMeshes = [];\r\n\r\n this.pickingMeshes.forEach(pickingMesh => {\r\n this.removeFromScene(pickingMesh);\r\n this.disposeGeometry(pickingMesh);\r\n });\r\n this.pickingMeshes = [];\r\n\r\n this.features.forEach(feature => {\r\n try {\r\n this.mapSource.removeFeature(feature);\r\n } catch(err) {\r\n // Feature has already been removed\r\n return;\r\n }\r\n });\r\n this.features = [];\r\n }\r\n}\r\n\r\nexport class LineworkFile {\r\n public id: string;\r\n protected path: string;\r\n protected name: string;\r\n protected saved: boolean\r\n public boundingBox: Box3;\r\n public mapLayer: VectorLayer | WebGLLayer;\r\n public mapSource: VectorSource;\r\n\r\n public loaded = false;\r\n public enabled = true;\r\n public loading = false;\r\n public visible = false;\r\n public percent = 0.0;\r\n public error = false;\r\n\r\n protected handler: IFCHandler | SHPHandler | DXFHandler;\r\n\r\n constructor(handler, asset: Asset) {\r\n this.id = asset.id;\r\n this.path = asset.path;\r\n this.name = asset.name;\r\n this.saved = asset.saved;\r\n this.handler = handler;\r\n\r\n const source = new VectorSource({\r\n wrapX: false,\r\n features: [],\r\n });\r\n\r\n const layer = new WebGLLayer({\r\n zIndex: 1,\r\n source: source,\r\n });\r\n\r\n this.mapLayer = layer;\r\n this.mapSource = source;\r\n this.map.addLayer(layer);\r\n }\r\n\r\n get viewer() {\r\n return this.handler.viewer;\r\n }\r\n\r\n get scene() {\r\n return this.handler.scene;\r\n }\r\n\r\n get map() {\r\n return this.handler.map;\r\n }\r\n\r\n get picker() {\r\n return this.handler.picker;\r\n }\r\n\r\n load() {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n destroy() {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n removeMapLayer() {\r\n if (!this.mapLayer) return;\r\n this.map.removeLayer(this.mapLayer);\r\n }\r\n\r\n updateProperties(asset: Asset) {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n updatePercent(percent) {\r\n this.percent = percent;\r\n }\r\n\r\n updatePicker() {\r\n this.picker.needsUpdate = true;\r\n }\r\n\r\n validBounds(bounds: {min: number[], max: number[]}) {\r\n return [...bounds.min, ...bounds.max]\r\n .filter(x => isFinite(x)).length === 6;\r\n };\r\n}\r\n\r\nexport class LineworkHandler {\r\n protected files: LineworkFile[] = [];\r\n protected cadHandler: CADHandler;\r\n\r\n constructor(cadHandler: CADHandler) {\r\n this.cadHandler = cadHandler;\r\n }\r\n\r\n get viewer() {\r\n return this.cadHandler.viewer;\r\n }\r\n\r\n get camera() {\r\n return this.viewer.camera;\r\n }\r\n\r\n get map() {\r\n return this.viewer.minimap.map;\r\n }\r\n\r\n get scene() {\r\n return this.cadHandler.scene;\r\n }\r\n\r\n get picker() {\r\n return this.cadHandler.picker;\r\n }\r\n\r\n get numberOfFiles() {\r\n return this.files.length;\r\n }\r\n\r\n get combinedBoundingBox() {\r\n const boundingBoxes = this.files.map(file => file.boundingBox);\r\n return mergeBoundingBoxes(boundingBoxes);\r\n }\r\n\r\n get objects() {\r\n console.warn(\"Not implemented\");\r\n return [];\r\n }\r\n\r\n getByID(assetID) {\r\n return this.files.find(file => file.id === assetID);\r\n }\r\n\r\n addNewFile(asset, FileConstructor) {\r\n let assetID = asset.id;\r\n if (this.getByID(assetID)) return false;\r\n\r\n const file = new FileConstructor(this, asset);\r\n this.files.push(file);\r\n }\r\n\r\n deleteFile(asset) {\r\n let file = this.getByID(asset.id);\r\n if (!file) return;\r\n\r\n file.destroy();\r\n const index = this.files.indexOf(file);\r\n this.files.splice(index, 1);\r\n }\r\n\r\n async getProperties(event) {\r\n console.warn(\"Not Implemented\");\r\n return [];\r\n }\r\n\r\n clearHighlight() {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n updateProperties(asset) {\r\n let file = this.getByID(asset.id);\r\n if (!file) return;\r\n\r\n file.updateProperties(asset);\r\n }\r\n\r\n reconcile(modelFiles, FileConstructor) {\r\n const currentFiles = new Set(this.files.map(ifc => ifc.id));\r\n const newFiles = new Set(modelFiles.map(ifc => ifc.id));\r\n const filesToLoad = modelFiles.filter(ifc => !currentFiles.has(ifc.id));\r\n const filesToDelete = this.files.filter(ifc => !newFiles.has(ifc.id));\r\n\r\n // Delete file that need to be removed\r\n filesToDelete.forEach(file => {\r\n this.deleteFile(file);\r\n });\r\n\r\n // Add new files\r\n filesToLoad.forEach(file => {\r\n this.addNewFile(file, FileConstructor);\r\n });\r\n\r\n // Toggle visibility and colors for each file\r\n modelFiles.forEach(file => {\r\n this.updateProperties(file);\r\n });\r\n\r\n return filesToLoad.length;\r\n }\r\n\r\n updateMeshes() {\r\n let meshes = [];\r\n this.files.forEach(file => {\r\n if ((file instanceof SHPFile) || (file instanceof DXFFile)) {\r\n file.layers.forEach(layer => {\r\n meshes = [...meshes, ...layer.meshes];\r\n });\r\n }\r\n });\r\n\r\n // Update point sizing\r\n const points = meshes.filter(mesh => mesh instanceof LineworkPoints);\r\n\r\n points.forEach((mesh: LineworkPoints) => {\r\n mesh.updateMaterial(\r\n this.camera.fov,\r\n this.viewer.height\r\n );\r\n });\r\n\r\n // Update textures for text objects\r\n let text = meshes\r\n .filter(mesh => mesh instanceof LineworkText)\r\n .filter(mesh => !mesh.calculated)\r\n .filter(mesh => mesh.getCurrentLevel() === 0)\r\n .slice(0, 10);\r\n\r\n text.forEach((mesh: LineworkText) => {\r\n mesh.updateTexture();\r\n });\r\n }\r\n\r\n /** Load any file waiting for conversion */\r\n loadNextfile() {\r\n for (let file of this.files) {\r\n if (file.loaded || !file.enabled || !file.visible) continue;\r\n if (file.loading) break;\r\n\r\n // Load new file\r\n file.load();\r\n break;\r\n };\r\n }\r\n\r\n update() {\r\n this.loadNextfile();\r\n this.updateMeshes();\r\n }\r\n}\r\n\r\nexport class CADHandler {\r\n public scene: Scene;\r\n public viewer: Viewer;\r\n private ifcHandler: IFCHandler\r\n private shpHandler: SHPHandler\r\n private dxfHandler: DXFHandler\r\n\r\n constructor(viewer: Viewer) {\r\n this.viewer = viewer;\r\n\r\n this.initScene();\r\n this.ifcHandler = new IFCHandler(this);\r\n this.shpHandler = new SHPHandler(this);\r\n this.dxfHandler = new DXFHandler(this);\r\n }\r\n\r\n get picker() {\r\n return this.viewer.gpuPickers.default;\r\n }\r\n\r\n get handlers() {\r\n return [\r\n this.ifcHandler,\r\n this.shpHandler,\r\n this.dxfHandler\r\n ];\r\n }\r\n\r\n get numberOfFiles() {\r\n return this.handlers\r\n .map(x=> x.numberOfFiles)\r\n .reduce((previous, current) => previous + current, 0);\r\n }\r\n\r\n get combinedBoundingBox() {\r\n const boundingBoxes = this.handlers.map(handler =>\r\n handler.combinedBoundingBox);\r\n\r\n return mergeBoundingBoxes(boundingBoxes);\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n getByID(id) {\r\n let file;\r\n this.handlers.forEach(handler => {\r\n if (file) return;\r\n file = handler.getByID(id);\r\n });\r\n\r\n return file;\r\n }\r\n\r\n async getProperties(event) {\r\n let properties = [];\r\n\r\n for (let handler of this.handlers) {\r\n const attributes = await handler.getProperties(event);\r\n properties = [\r\n ...properties,\r\n ...attributes\r\n ];\r\n }\r\n\r\n return properties;\r\n }\r\n\r\n clearHighlight() {\r\n for (let handler of this.handlers) {\r\n handler.clearHighlight();\r\n }\r\n }\r\n\r\n reconcile(modelFiles) {\r\n let numAdded = 0;\r\n\r\n // Add/remove ifc files\r\n const ifcFiles = modelFiles.filter(x => x.type === AssetType.IFC);\r\n numAdded += this.ifcHandler.reconcile(ifcFiles, IFCFile);\r\n\r\n // Add/remove shp files\r\n const shpFiles = modelFiles.filter(x => x.type === AssetType.SHP);\r\n numAdded += this.shpHandler.reconcile(shpFiles, SHPFile);\r\n\r\n // Add/remove dxf files\r\n const dxfFiles = modelFiles.filter(x => x.type === AssetType.DXF);\r\n numAdded += this.dxfHandler.reconcile(dxfFiles, DXFFile);\r\n\r\n return numAdded;\r\n }\r\n\r\n update() {\r\n this.handlers.forEach(handler => {\r\n handler.update();\r\n });\r\n }\r\n}\r\n\r\nconst withOpacity = (color, opacity) => {\r\n let colorWithOpacity = olColor.asArray(color).slice();\r\n colorWithOpacity[3] = opacity;\r\n return colorWithOpacity;\r\n};","import {Map as OLMap} from 'ol/index';\r\nimport {\r\n Fill,\r\n Style,\r\n Text,\r\n Icon,\r\n Stroke\r\n} from 'ol/style';\r\nimport {Cluster, Vector as VectorSource} from 'ol/source';\r\nimport {Vector as VectorLayer} from 'ol/layer';\r\nimport {Point} from 'ol/geom';\r\nimport {\r\n AmbientLight,\r\n BufferAttribute,\r\n BufferGeometry,\r\n MathUtils,\r\n Mesh,\r\n Scene,\r\n Vector3\r\n} from \"three\";\r\nimport {DataProjectionCoordinate} from \"./projections\";\r\nimport {TagMaterial} from \"./rendering\";\r\nimport {Viewer} from \"./main\";\r\nimport GPUPicker from \"./gpu-picker\";\r\nimport { TagFeature } from './aerial';\r\nimport { isEqual } from 'lodash';\r\nimport { getTagTexturePath } from '../textures/tag-icons';\r\nimport { Asset, TagData, TagItemData } from '../../redux/assets-slice';\r\nimport { clearAerialTooltip, clearViewerTooltip, setAerialTooltip, setViewerTooltip } from '../viewer';\r\nimport { mergeBoundingBoxes } from './utilities';\r\nimport { t } from '../../localization';\r\nimport { TagSize } from '../../types/tags';\r\nimport { showTagDetails } from '../../folder';\r\nimport { SceneCameraState } from '../../redux/camera-slice';\r\n\r\nconst tagIconSize = 24;\r\n\r\nexport class TagMesh extends Mesh {\r\n public tags;\r\n\r\n constructor(geometry, material, tags) {\r\n super(geometry, material);\r\n this.tags = tags;\r\n };\r\n};\r\n\r\nclass TagPosition {\r\n private _value;\r\n private tag: TagItem;\r\n\r\n constructor(tag: TagItem, position) {\r\n this.tag = tag;\r\n this._value = new Vector3(...position);\r\n }\r\n\r\n get array() {\r\n return this.tag.isAerial\r\n ? [this._value.x, this._value.y]\r\n : [this._value.x, this._value.y, this._value.z];\r\n }\r\n\r\n get viewer() {\r\n return new DataProjectionCoordinate(this._value).toScene();\r\n }\r\n\r\n get aerial() {\r\n return new DataProjectionCoordinate(this._value).toAerial();\r\n }\r\n}\r\n\r\nexport class TagItem {\r\n public id: string;\r\n public csv: string;\r\n public name: string;\r\n public file: TagFile;\r\n public position: TagPosition;\r\n public comment: string;\r\n public sceneState: SceneCameraState;\r\n public isAerial = false;\r\n public texture: string;\r\n public visible: boolean;\r\n public size: number;\r\n\r\n constructor(asset: TagFile, tag: TagItemData) {\r\n this.id = tag.id;\r\n this.file = asset;\r\n this.name = tag.name;\r\n this.comment = tag.comment;\r\n this.sceneState = tag.sceneState;\r\n this.isAerial = !(\"z\" in tag);\r\n\r\n this.csv = asset.id;\r\n this.texture = asset.texture;\r\n this.visible = asset.visible;\r\n this.size = asset.size;\r\n\r\n const position = [tag.x, tag.y, tag.z];\r\n this.position = new TagPosition(this, position);\r\n }\r\n}\r\n\r\nclass TagFile {\r\n public id: string;\r\n public saved: boolean;\r\n public size: TagSize;\r\n public texture: string;\r\n public visible: boolean;\r\n public name: string;\r\n public tags: TagItem[] = [];\r\n\r\n constructor(asset: Asset) {\r\n this.id = asset.id;\r\n this.saved = asset.saved;\r\n this.name = asset.name;\r\n }\r\n\r\n update(asset: Asset) {\r\n const {size, texture, items} = asset.data as TagData;\r\n\r\n const visibleChanged = this.visible !== asset.visible;\r\n this.visible = asset.visible;\r\n\r\n const textureChanged = this.texture !== texture;\r\n this.texture = texture;\r\n\r\n const sizeChanged = this.size !== size;\r\n this.size = size;\r\n\r\n const newTagIDs = items.map(x => x.id);\r\n const currentTagIDs = this.tags.map(x => x.id);\r\n const tagsChanged = !isEqual(newTagIDs, currentTagIDs);\r\n\r\n // Update all tags (comments may have changed)\r\n this.tags = items.map(tag => {\r\n return new TagItem(this, tag);\r\n });\r\n\r\n return visibleChanged\r\n || textureChanged\r\n || tagsChanged\r\n || sizeChanged;\r\n }\r\n}\r\n\r\nexport default class TagController {\r\n public viewer: Viewer;\r\n public sceneViewController: SceneViewTags;\r\n public aerialController: AerialTags;\r\n public tagState = {};\r\n private files: TagFile[] = [];\r\n\r\n constructor(viewer: Viewer) {\r\n this.viewer = viewer;\r\n this.sceneViewController = new SceneViewTags(this);\r\n this.aerialController = new AerialTags(this);\r\n }\r\n\r\n get hovering() {\r\n return this.aerialController.hovering;\r\n }\r\n\r\n get scene(): Scene {\r\n return this.sceneViewController.scene;\r\n }\r\n\r\n get allTags(): TagItem[] {\r\n return this.files.reduce((previous, current) =>\r\n [...previous, ...current.tags], []);\r\n }\r\n\r\n get combinedBoundingBox() {\r\n return this.boundingBoxForTags(this.allTags);\r\n }\r\n\r\n public get numberOfFiles() {\r\n return this.files.length;\r\n }\r\n\r\n addNewFile(asset) {\r\n let assetID = asset.id;\r\n if (this.getByID(assetID)) {\r\n return;\r\n }\r\n\r\n const file = new TagFile(asset);\r\n this.files.push(file);\r\n }\r\n\r\n deleteFile(assetID) {\r\n let file = this.getByID(assetID);\r\n if (!file) {\r\n return;\r\n }\r\n\r\n const index = this.files.indexOf(file);\r\n this.files.splice(index, 1);\r\n }\r\n\r\n updateTagData = (assetID, asset) => {\r\n let file = this.getByID(assetID);\r\n if (!file) return false;\r\n\r\n return file.update(asset);\r\n }\r\n\r\n getTooltipText(tagID): string[] {\r\n const selected = this.allTags.find(x => x.id === tagID);\r\n if (!selected) return;\r\n\r\n const fileName = selected.file.name;\r\n const tagName = selected.name;\r\n\r\n return [`[${fileName}]`, tagName];\r\n }\r\n\r\n getByID(assetID) {\r\n return this.files.find(file => file.id === assetID);\r\n }\r\n\r\n getTagByID(tagID) {\r\n return this.files\r\n .map(file => file.tags)\r\n .flat()\r\n .find(tag => tag.id === tagID);\r\n }\r\n\r\n getRowsCSV(tags: TagItem[]) {\r\n let tagCsvOut = [];\r\n\r\n const hasHeight = tags.filter(tag => !tag.isAerial).length > 0;\r\n\r\n const header = [\r\n ...['Name', 'Easting', 'Northing'],\r\n ...hasHeight ? ['Elevation'] : [],\r\n 'Comments'\r\n ];\r\n\r\n tagCsvOut.push(header);\r\n\r\n tags.forEach(tag => {\r\n const row = [\r\n tag.name,\r\n ...tag.position.array,\r\n ...tag.isAerial ? [''] : [],\r\n tag.comment\r\n ];\r\n tagCsvOut.push(row);\r\n });\r\n\r\n return tagCsvOut;\r\n }\r\n\r\n setMaxDistance(distance: number) {\r\n let value = (distance > 999) ? 1e10 : distance;\r\n this.sceneViewController.setMaxDistance(value);\r\n }\r\n\r\n reconcile(tagFiles) {\r\n const currentFiles = new Set(this.files.map(x => x.id));\r\n const newFiles = new Set(tagFiles.map(x => x.id));\r\n const filesToLoad = tagFiles.filter(x => !currentFiles.has(x.id));\r\n const filesToDelete = this.files.filter(x => !newFiles.has(x.id));\r\n\r\n // Delete files that need to be removed\r\n filesToDelete.forEach(file => {\r\n this.deleteFile(file.id);\r\n });\r\n\r\n // Add new tag files\r\n filesToLoad.forEach(file => {\r\n this.addNewFile(file);\r\n });\r\n\r\n let needsUpdate = filesToDelete.length > 0;\r\n tagFiles.forEach(file => {\r\n const updated = this.updateTagData(file.id, file);\r\n needsUpdate = needsUpdate || updated;\r\n });\r\n\r\n if (needsUpdate) {\r\n this.sceneViewController.update(this.files);\r\n this.aerialController.update(this.files);\r\n }\r\n\r\n this.viewer.zoomToSceneExtent(this.combinedBoundingBox, false);\r\n\r\n return filesToLoad.length;\r\n }\r\n\r\n boundingBoxForTags(tags: TagItem[]) {\r\n const buffer = 2.0;\r\n\r\n const boundingBoxes = tags.map(tag => {\r\n if (tag.isAerial) return null;\r\n\r\n const position = tag.position.viewer;\r\n const min = new Vector3().copy(position).subScalar(buffer);\r\n const max = new Vector3().copy(position).addScalar(buffer);\r\n return {min, max};\r\n });\r\n\r\n return mergeBoundingBoxes(boundingBoxes);\r\n }\r\n\r\n update() {\r\n this.sceneViewController.updateUniforms();\r\n }\r\n}\r\n\r\nclass SceneViewTags {\r\n public scene: Scene;\r\n private tagController: TagController;\r\n\r\n private readonly corners: (0 | 1 | 2 | 3)[] = [0, 2, 1, 2, 3, 1];\r\n private readonly uvs: (0 | 1)[] = [0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1];\r\n private readonly vertices: Vector3[] = [\r\n new Vector3(-0.5, 0.5, 0),\r\n new Vector3(0.5, 0.5, 0),\r\n new Vector3(-0.5, -0.5, 0),\r\n new Vector3(0.5, -0.5, 0)\r\n ]\r\n private readonly numberOfVertices = 6;\r\n private pickingMeshes = [];\r\n private standardMeshes = [];\r\n private selectedID = null;\r\n private maxDistance = 0;\r\n\r\n constructor(tagController: TagController) {\r\n this.tagController = tagController;\r\n\r\n this.initScene();\r\n }\r\n\r\n get viewer() {\r\n return this.tagController.viewer;\r\n }\r\n\r\n get meshes() {\r\n return [...this.pickingMeshes, ...this.standardMeshes];\r\n }\r\n\r\n get materials() {\r\n return this.meshes.map(mesh => mesh.material);\r\n }\r\n\r\n get numberOfTags() {\r\n let count = 0;\r\n\r\n this.standardMeshes.forEach(mesh => {\r\n let geometry = mesh.geometry;\r\n let positions = geometry.attributes.position;\r\n count += (positions.count / this.numberOfVertices);\r\n });\r\n\r\n return count;\r\n }\r\n\r\n get combinedBoundingBox() {\r\n return this.tagController.combinedBoundingBox;\r\n }\r\n\r\n private get picker(): GPUPicker {\r\n return this.viewer.gpuPickers.tags;\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n public update(files: TagFile[]) {\r\n this.scene.clear();\r\n this.picker.clear();\r\n\r\n this.standardMeshes = [];\r\n this.pickingMeshes = [];\r\n\r\n files.forEach(file => {\r\n const sceneViewTags = file.tags.filter(tag => !tag.isAerial);\r\n if (sceneViewTags.length === 0) return;\r\n\r\n const size = sceneViewTags.length * this.numberOfVertices;\r\n const positions = new Float32Array(size * 3);\r\n const visibilities = new Float32Array(size);\r\n const selected = new Float32Array(size);\r\n const gpuIndices = new Int32Array(size);\r\n const uvs = new Float32Array(size * 2);\r\n\r\n sceneViewTags.forEach((tag, i) => {\r\n const coordinate = tag.position.viewer;\r\n\r\n this.corners.forEach((corner, cornerNumber) => {\r\n const tagIndex = ((this.corners.length * i) + cornerNumber) * 3;\r\n const points = this.vertices[corner];\r\n\r\n positions[tagIndex] = points.x + coordinate.x;\r\n positions[tagIndex + 1] = points.y + coordinate.y;\r\n positions[tagIndex + 2] = points.z + coordinate.z;\r\n });\r\n\r\n this.uvs.forEach((uv, j) => {\r\n uvs[(this.uvs.length * i) + j] = uv;\r\n });\r\n\r\n const start = i * this.numberOfVertices;\r\n\r\n for (let j = start; j < start + this.numberOfVertices; j++) {\r\n visibilities[j] = +tag.visible;\r\n selected[j] = 0;\r\n gpuIndices[j] = 0;\r\n }\r\n });\r\n\r\n const geometry = new BufferGeometry();\r\n\r\n geometry.setAttribute('position', new BufferAttribute(positions, 3));\r\n geometry.setAttribute('visible', new BufferAttribute(visibilities, 1));\r\n geometry.setAttribute('selected', new BufferAttribute(selected, 1));\r\n geometry.setAttribute('gpu_index', new BufferAttribute(gpuIndices, 1));\r\n geometry.setAttribute('uv', new BufferAttribute(uvs, 2));\r\n\r\n const tagMaterial = new TagMaterial(file.texture, file.size, false);\r\n const standardMesh = new TagMesh(geometry, tagMaterial, sceneViewTags);\r\n this.scene.add(standardMesh);\r\n\r\n const pickingMaterial = new TagMaterial(file.texture, file.size, true);\r\n const pickingMesh = new TagMesh(geometry, pickingMaterial, sceneViewTags);\r\n this.picker.add(pickingMesh);\r\n\r\n this.standardMeshes.push(standardMesh);\r\n this.pickingMeshes.push(pickingMesh);\r\n });\r\n\r\n this.updatePicker();\r\n }\r\n\r\n updatePicker() {\r\n this.picker.needsUpdate = true;\r\n }\r\n\r\n setMaxDistance(value: number) {\r\n this.maxDistance = value;\r\n this.updateUniforms();\r\n };\r\n\r\n public updateUniforms() {\r\n if (this.numberOfTags === 0) return;\r\n\r\n const camera = this.viewer.camera;\r\n if (!camera) return;\r\n\r\n const position = camera.position;\r\n const rotation = camera.rotation.toVector3();\r\n const initialCameraLoading = this.viewer.initialCameraLoading;\r\n\r\n const controls = this.viewer.controls;\r\n const target = controls.getCameraTarget();\r\n\r\n this.materials.forEach((material: TagMaterial) => {\r\n material.currentCameraRotation = rotation;\r\n material.currentCameraPosition = position;\r\n material.currentCameraTarget = target;\r\n material.windowHeight = window.innerHeight;\r\n material.initialCameraLoading = initialCameraLoading;\r\n material.fov = MathUtils.degToRad(camera.fov);\r\n material.distance = this.maxDistance;\r\n material.needsUpdate = true;\r\n });\r\n }\r\n\r\n tagFromPickerIndex(mesh, index) {\r\n if (!mesh) {\r\n return null;\r\n }\r\n\r\n const attributes = mesh.geometry.attributes;\r\n const arrayIndex = attributes.gpu_index.array.indexOf(index);\r\n const tagIndex = Math.floor(arrayIndex/this.numberOfVertices);\r\n\r\n return mesh.tags[tagIndex];\r\n }\r\n\r\n getFeatureForEvent(event): TagItem[] {\r\n this.picker.update();\r\n const index = this.picker.value(event);\r\n const mesh = this.picker.getSelectedObject(index);\r\n const selected = this.tagFromPickerIndex(mesh, index);\r\n this.markTagSelected(selected, index);\r\n return selected ? [selected] : [];\r\n }\r\n\r\n markTagSelected(selected, index) {\r\n this.meshes.forEach(mesh => {\r\n const attributes = mesh.geometry.attributes;\r\n attributes.selected.array.fill(0.0);\r\n\r\n const arrayIndex = attributes.gpu_index.array.indexOf(index);\r\n const selectedIndex = Math.floor(arrayIndex/this.numberOfVertices);\r\n const baseIndex = selectedIndex*this.numberOfVertices;\r\n\r\n if (arrayIndex !== -1) {\r\n for (let i = 0; i < this.numberOfVertices; i++) {\r\n attributes.selected.array[baseIndex + i] = 1.0;\r\n }\r\n }\r\n attributes.selected.needsUpdate = true;\r\n });\r\n\r\n const newSelectedID = selected?.id;\r\n if (newSelectedID !== this.selectedID) {\r\n this.updatePicker();\r\n }\r\n\r\n this.selectedID = newSelectedID;\r\n }\r\n\r\n public onMouseUp(event) {\r\n if (event.mouseMoved) return false;\r\n\r\n if (event.isLeftClick) {\r\n const selected = this.getFeatureForEvent(event);\r\n\r\n if (selected.length > 0) {\r\n const selectedTagID = selected[0].id;\r\n showTagDetails(selectedTagID, false);\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n public onMouseMove(event) {\r\n if (this.numberOfTags === 0) return;\r\n\r\n const selected = this.getFeatureForEvent(event);\r\n\r\n if (selected.length > 0) {\r\n const selectedTagID = selected[0].id;\r\n let tooltipText = this.tagController\r\n .getTooltipText(selectedTagID);\r\n\r\n setViewerTooltip(tooltipText);\r\n } else {\r\n clearViewerTooltip();\r\n }\r\n }\r\n}\r\n\r\nclass AerialTags {\r\n private tagController: TagController;\r\n private readonly source: VectorSource;\r\n private readonly layer: VectorLayer;\r\n private styleCache = {};\r\n public hovering = false;\r\n\r\n constructor(tagController: TagController) {\r\n this.tagController = tagController;\r\n this.source = new VectorSource();\r\n\r\n this.layer = new VectorLayer({\r\n zIndex: 1,\r\n source: new Cluster({\r\n source: this.source,\r\n }),\r\n style: feature => {\r\n return this.getClusterStyle(feature);\r\n },\r\n });\r\n\r\n this.map.addLayer(this.layer);\r\n }\r\n\r\n get map(): OLMap {\r\n const viewer = this.tagController.viewer;\r\n return viewer.minimap.map;\r\n }\r\n\r\n get numberOfTags() {\r\n return this.source.getFeatures().length;\r\n }\r\n\r\n public onMouseMove(event) {\r\n if (this.numberOfTags === 0) return;\r\n\r\n const features = this.getFeatureForEvent(event);\r\n this.hovering = features.length > 0;\r\n\r\n if (features.length === 0) {\r\n clearAerialTooltip();\r\n } else if (features.length === 1) {\r\n const selected = features[0];\r\n let tooltipText = this.tagController\r\n .getTooltipText(selected.tagID);\r\n\r\n setAerialTooltip(tooltipText);\r\n } else {\r\n setAerialTooltip([\r\n t(\"tags.multiple-tags\", {\r\n count: features.length\r\n })\r\n ]);\r\n }\r\n }\r\n\r\n getFeatureForEvent(event): TagFeature[] {\r\n return this.map.getFeaturesAtPixel(event.pixel)\r\n .filter(feature => feature.get('features'))\r\n .reduce((previous, current) => [...previous, ...current.get('features')], [])\r\n .filter(feature => feature instanceof TagFeature);\r\n }\r\n\r\n getClusterStyle(feature) {\r\n const features = feature.get('features');\r\n const size = features.length;\r\n\r\n let tagScale = 0;\r\n const texturePaths = {};\r\n features.forEach((feature: TagFeature) => {\r\n const texture = feature.texture;\r\n const texturePath = getTagTexturePath(texture);\r\n tagScale = Math.max(tagScale, feature.size);\r\n\r\n if (!(texturePath in texturePaths)) {\r\n texturePaths[texturePath] = 0;\r\n }\r\n texturePaths[texturePath] += 1;\r\n });\r\n\r\n const mostFrequent = Object.keys(texturePaths)\r\n .sort((a,b) => texturePaths[a] - texturePaths[b])\r\n .reverse()\r\n .slice(0, 3);\r\n\r\n // Unique attributes that determines if we need a new style\r\n const attributes = [size, ...mostFrequent, tagScale];\r\n const key = attributes.join(\"-\");\r\n\r\n let style = this.styleCache[key];\r\n\r\n if (!style) {\r\n const strokeColor = '#000000';\r\n const textColor = '#FFFFFF';\r\n const combinedStyles = [];\r\n const iconSize = tagIconSize *tagScale;\r\n\r\n // First texture in feature cluster\r\n combinedStyles.push(new Style({\r\n image: new Icon({\r\n src: mostFrequent[0],\r\n width: iconSize,\r\n height: iconSize,\r\n anchor: [0.5, 1],\r\n anchorXUnits: 'fraction',\r\n anchorYUnits: 'fraction'\r\n })\r\n }));\r\n\r\n // Second texture in feature cluster\r\n if (mostFrequent[1]) {\r\n combinedStyles.push(new Style({\r\n image: new Icon({\r\n src: mostFrequent[1],\r\n width: iconSize,\r\n height: iconSize,\r\n anchor: [0.5 + 0.2, 1],\r\n anchorXUnits: 'fraction',\r\n anchorYUnits: 'fraction'\r\n })\r\n }));\r\n }\r\n\r\n // Third texture in feature cluster\r\n if (mostFrequent[2]) {\r\n combinedStyles.push(new Style({\r\n image: new Icon({\r\n src: mostFrequent[2],\r\n width: iconSize,\r\n height: iconSize,\r\n anchor: [0.5 + 0.4, 1],\r\n anchorXUnits: 'fraction',\r\n anchorYUnits: 'fraction'\r\n })\r\n }));\r\n }\r\n\r\n combinedStyles.reverse();\r\n\r\n combinedStyles.push(new Style({\r\n text: new Text({\r\n text: size > 1 ? size.toString() : \"\",\r\n offsetY: -15,\r\n offsetX: 7.5,\r\n scale: 1.25,\r\n stroke: new Stroke({\r\n color: strokeColor,\r\n width: 3\r\n }),\r\n fill: new Fill({\r\n color: textColor\r\n }),\r\n }),\r\n }));\r\n\r\n style = [...combinedStyles];\r\n this.styleCache[key] = style;\r\n }\r\n\r\n return style;\r\n }\r\n\r\n update(files: TagFile[]) {\r\n const features = [];\r\n\r\n files.forEach(file => {\r\n file.tags.forEach(tag => {\r\n if (!tag.visible) return;\r\n\r\n const point = new Point(tag.position.aerial);\r\n const feature = new TagFeature(\r\n tag.id, tag.texture,\r\n tag.size, point\r\n );\r\n\r\n features.push(feature);\r\n });\r\n });\r\n\r\n this.source.clear();\r\n this.source.addFeatures(features);\r\n }\r\n}","export default __webpack_public_path__ + \"static/media/point.cc8fa849.png\";","import { nanoid } from '@reduxjs/toolkit';\r\nimport {transform} from 'ol/proj';\r\nimport { AmbientLight, MeshBasicMaterial, Scene, SphereGeometry, Vector3 } from 'three';\r\nimport { toast } from '../../../app';\r\nimport { t } from '../../../localization';\r\nimport { Projection } from '../../../redux/projections-slice';\r\nimport {\r\n clearAerialTooltip,\r\n clearViewerTooltip,\r\n setAerialTooltip,\r\n setViewerTooltip\r\n} from \"../../viewer\";\r\nimport { CustomMouseEvent, PanoControls } from \"../controls\";\r\nimport { Viewer } from '../main';\r\nimport {\r\n closestUtmZone,\r\n DataProjectionCoordinate,\r\n estimateTransform,\r\n latitudeLongitude,\r\n reprojectPoints,\r\n SceneCoordinate\r\n} from '../projections';\r\nimport { ChangeDetector, getPointScale } from \"../utilities\";\r\nimport { aerialObsColor, pointObsColor, PointObservation } from './observations';\r\nimport {Vector as VectorSource} from \"ol/source\";\r\nimport {Vector as VectorLayer} from \"ol/layer\";\r\nimport {Circle as CircleStyle, Fill, Stroke, Style} from \"ol/style\";\r\nimport {Point} from \"ol/geom\";\r\nimport {Feature} from \"ol\";\r\nimport * as olColor from 'ol/color';\r\n\r\nexport enum LocalObservationTypes {\r\n None,\r\n Scene,\r\n Aerial\r\n}\r\n\r\nexport interface LocalObservation {\r\n id: string\r\n scene: DataProjectionCoordinate\r\n aerial: number[]\r\n error: number\r\n active: LocalObservationTypes\r\n}\r\n\r\nexport class LocalAligner {\r\n public scene: Scene;\r\n private layer: VectorLayer;\r\n private source: VectorSource;\r\n private controls: PanoControls;\r\n private setObservations: Function;\r\n\r\n public enabled = false;\r\n private activeObservation: LocalObservation = null;\r\n private observations = [] as LocalObservation[];\r\n private sphereGeometry = new SphereGeometry(0.05, 20, 20);\r\n\r\n constructor(controls: PanoControls, props) {\r\n const {setLocalObservations} = props;\r\n this.controls = controls;\r\n this.setObservations = setLocalObservations;\r\n\r\n this.initScene();\r\n this.addMapLayers();\r\n }\r\n\r\n get viewer(): Viewer {\r\n return this.controls.viewer;\r\n }\r\n\r\n get map() {\r\n return this.viewer.minimap.map;\r\n }\r\n\r\n get aerialTooltip() {\r\n return [\r\n t('local-projection.click_to_add_aerial_observation'),\r\n t('local-projection.right-click_to_cancel')\r\n ];\r\n }\r\n\r\n get sceneTooltip() {\r\n return [\r\n t('local-projection.click_to_add_point_observation'),\r\n t('local-projection.right-click_to_cancel')\r\n ];\r\n }\r\n\r\n get isSceneObs() {\r\n return this.activeObservation\r\n ? this.activeObservation.active === LocalObservationTypes.Scene\r\n : false;\r\n }\r\n\r\n get isAerialObs() {\r\n return this.activeObservation\r\n ? this.activeObservation.active === LocalObservationTypes.Aerial\r\n : false;\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n addMapLayers() {\r\n const styleColor = `#${aerialObsColor.toString(16)}`;\r\n const color = olColor\r\n .asArray(styleColor)\r\n .slice();\r\n color[3] = 0.8;\r\n\r\n this.source = new VectorSource({\r\n features: [],\r\n wrapX: false\r\n });\r\n\r\n this.layer = new VectorLayer({\r\n zIndex: 1,\r\n source: this.source,\r\n style: new Style({\r\n image: new CircleStyle({\r\n radius: 5,\r\n stroke: new Stroke({\r\n color: 'rgba(0, 0, 0, 0.7)'\r\n }),\r\n fill: new Fill({\r\n color: color\r\n })\r\n })\r\n })\r\n });\r\n }\r\n\r\n async getLocalProjection(estimator: string, units: string) {\r\n const filled = this.observations.filter(observation => {\r\n return observation.scene && observation.aerial;\r\n });\r\n\r\n const valid = (this.observations.length >= 3)\r\n && (filled.length === this.observations.length);\r\n\r\n if (!valid) {\r\n toast.error(t('local-projection.all_observations_must_be_used_to_calculate_projection'));\r\n return;\r\n }\r\n\r\n const input = this.observations.map(observation => {\r\n return observation.scene.toArray().slice(0,2);\r\n });\r\n\r\n const latlon = this.observations.map(observation => {\r\n return transform(observation.aerial, 'EPSG:3857', 'EPSG:4326');\r\n });\r\n\r\n // Calculate average map coordinate\r\n const average = [\r\n latlon.map(p => p[0]).reduce((a,b) => a+b, 0) / latlon.length,\r\n latlon.map(p => p[1]).reduce((a,b) => a+b, 0) / latlon.length\r\n ];\r\n\r\n // Determine closest UTM zone and reproject points\r\n const {projection, utmZone} = closestUtmZone(new Vector3(...average), units);\r\n const output = await reprojectPoints(latlon, latitudeLongitude, projection);\r\n\r\n // Estimate local transform\r\n const local = estimateTransform(estimator, input, output);\r\n if (!local.transform) return;\r\n\r\n const newProjection = {\r\n ...projection,\r\n transform: local.transform\r\n } as Projection;\r\n\r\n // Update observation errors\r\n this.observations.forEach((observation, index) => {\r\n observation.error = local.errors[index];\r\n });\r\n\r\n this.refreshObservationList();\r\n\r\n return {projection: newProjection, utmZone};\r\n };\r\n\r\n resetErrorValues() {\r\n this.observations.forEach(observation => {\r\n observation.error = null;\r\n });\r\n }\r\n\r\n setActiveObservation(id: string, type: LocalObservationTypes) {\r\n this.observations = this.observations.map(observation => {\r\n return {\r\n ...observation,\r\n active: observation.id === id ? type : LocalObservationTypes.None,\r\n };\r\n });\r\n\r\n this.activeObservation = this.observations.find(x => x.id === id);\r\n this.refreshObservationList();\r\n this.drawObservations();\r\n }\r\n\r\n addPointObservationMesh(position) {\r\n let sphereMaterial = new MeshBasicMaterial({color: pointObsColor});\r\n let mesh = new PointObservation(this.sphereGeometry, sphereMaterial);\r\n\r\n this.scene.add(mesh);\r\n\r\n mesh.position.copy(position);\r\n this.setPointScale(mesh);\r\n\r\n return mesh;\r\n }\r\n\r\n drawObservations() {\r\n if (!this.enabled) return;\r\n this.drawPointObservations();\r\n this.drawAerialObservations();\r\n }\r\n\r\n /** @private */\r\n drawPointObservations() {\r\n // Delete old point meshes\r\n this.scene.children\r\n .filter(mesh => mesh instanceof PointObservation)\r\n .forEach(mesh => this.scene.remove(mesh));\r\n\r\n // Draw new point meshes\r\n this.observations.forEach(observation => {\r\n if (!observation.scene) return;\r\n\r\n // Active observation will be ignored, to allow for replacing of points\r\n if (this.activeObservation) {\r\n const isActiveObservation = observation.id === this.activeObservation.id;\r\n if (isActiveObservation && this.isSceneObs) return;\r\n }\r\n\r\n // Add point\r\n const position = new DataProjectionCoordinate(observation.scene).toScene();\r\n const mesh = this.addPointObservationMesh(position);\r\n this.scene.add(mesh);\r\n });\r\n }\r\n\r\n /** @private */\r\n drawAerialObservations() {\r\n // Delete old points\r\n this.source.clear();\r\n\r\n let features = [];\r\n this.observations.forEach(observation => {\r\n if (!observation.aerial) return;\r\n\r\n // Active observation will be ignored, to allow for replacing of points\r\n if (this.activeObservation) {\r\n const isActiveObservation = observation.id === this.activeObservation.id;\r\n if (isActiveObservation && this.isAerialObs) return;\r\n }\r\n\r\n const polygon = new Point(observation.aerial);\r\n const feature = new Feature(polygon);\r\n features.push(feature);\r\n });\r\n\r\n this.source.addFeatures(features);\r\n }\r\n\r\n addNewObservations(numObservations) {\r\n for (let i=0; i x.id === id);\r\n }\r\n\r\n removeByID(id) {\r\n const observation = this.getByID(id);\r\n if (!observation) return;\r\n\r\n this.observations = this.observations.filter(x => x.id !== id);\r\n this.resetErrorValues();\r\n this.clearActiveObservation();\r\n this.drawObservations();\r\n }\r\n\r\n resetObservations() {\r\n this.observations = [];\r\n this.clearActiveObservation();\r\n this.drawObservations();\r\n }\r\n\r\n clearActiveObservation() {\r\n clearAerialTooltip();\r\n clearViewerTooltip();\r\n this.setActiveObservation(null, LocalObservationTypes.None);\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (!this.enabled || !this.activeObservation || event.mouseMoved) {\r\n return false;\r\n }\r\n\r\n if (event.isLeftClick && this.isSceneObs) {\r\n this.onSceneClick(event);\r\n return true;\r\n } else if (event.isRightClick) {\r\n this.clearActiveObservation();\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onSceneClick(event) {\r\n let coordinate = this.getCoordinate(event);\r\n if (!coordinate) return;\r\n\r\n toast.success(t('local-projection.new_point_observation_added'));\r\n let position = new SceneCoordinate(coordinate).toDataProjection();\r\n this.activeObservation.scene = position;\r\n this.clearActiveObservation();\r\n this.drawObservations();\r\n }\r\n\r\n onMapClick(event) {\r\n if (!this.enabled || !this.isAerialObs) {\r\n return false;\r\n }\r\n\r\n toast.success(t('local-projection.new_aerial_observation_added'));\r\n this.activeObservation.aerial = event.coordinate;\r\n this.clearActiveObservation();\r\n }\r\n\r\n onMouseMoveScene() {\r\n if (!this.enabled || !this.isSceneObs) {\r\n return false;\r\n }\r\n\r\n if (this.activeObservation) {\r\n setViewerTooltip(this.sceneTooltip);\r\n } else {\r\n clearViewerTooltip();\r\n }\r\n }\r\n\r\n onMouseMoveAerial() {\r\n if (!this.enabled || !this.isAerialObs) {\r\n return false;\r\n }\r\n\r\n if (this.activeObservation) {\r\n setAerialTooltip(this.aerialTooltip);\r\n } else {\r\n clearAerialTooltip();\r\n }\r\n }\r\n\r\n updateAllMeshes() {\r\n this.scene.children.forEach(child => {\r\n if (child instanceof PointObservation) {\r\n this.setPointScale(child);\r\n }\r\n });\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n if (!this.enabled || !changeDetector.changed) return;\r\n\r\n this.updateAllMeshes();\r\n }\r\n}","import {\r\n Box3,\r\n Mesh,\r\n MeshPhongMaterial,\r\n Vector3\r\n} from \"three\";\r\nimport { IFCLoader } from \"web-ifc-three\";\r\nimport { boundsToMapLayer, roundDigit } from \"../utilities\";\r\nimport { LineworkFile, CADHandler, LineworkHandler } from \".\";\r\nimport { readFileBuffer } from \"../file-system-loader\";\r\nimport { isDevMode } from \"../../../electron-modules\";\r\nimport { toast } from \"../../../app\";\r\nimport { Asset } from \"../../../redux/assets-slice\";\r\nimport LocalScene from \"../projections\";\r\nimport { getBasicPicker } from \"../gpu-picker\";\r\nimport { RayCaster } from \"../ray-caster\";\r\nimport { t } from \"../../../localization\";\r\n\r\nexport class IFCFile extends LineworkFile {\r\n public standardMesh: Mesh;\r\n public pickingMesh: Mesh;\r\n private loader: IFCLoader;\r\n private useWebWorkers = true;\r\n\r\n private highlightMaterial = new MeshPhongMaterial({\r\n color: 0xff00ff,\r\n depthTest: false,\r\n transparent: true,\r\n opacity: 0.3\r\n });\r\n\r\n constructor(ifcHandler: IFCHandler, asset: Asset) {\r\n super(ifcHandler, asset);\r\n this.loader = new IFCLoader();\r\n }\r\n\r\n get manager() {\r\n return this.loader.ifcManager;\r\n }\r\n\r\n get ifcAPI() {\r\n return this.manager.ifcAPI;\r\n }\r\n\r\n async load() {\r\n this.loading = true;\r\n this.loaded = false;\r\n this.updatePercent(0);\r\n\r\n // Initialize IFC manager\r\n await this.initManager();\r\n\r\n try {\r\n const buffer = await readFileBuffer(this.path);\r\n if (!this.enabled) return;\r\n\r\n await this.parseFromBuffer(buffer);\r\n } catch {\r\n this.error = true;\r\n toast.error(t(\"toast.model-load-error\", {\r\n name: this.name\r\n }));\r\n }\r\n\r\n this.loaded = true;\r\n this.loading = false;\r\n this.updatePercent(100.0);\r\n\r\n if (this.saved || this.error) return;\r\n this.viewer.zoomToSceneExtent(this.boundingBox, false);\r\n }\r\n\r\n async parseFromBuffer(buffer) {\r\n return new Promise(async (resolve, reject) => {\r\n /** Note: requires modified code in ifc-worker.js */\r\n if (this.useWebWorkers) {\r\n const handler = (this.manager as any).worker;\r\n handler.ifcWorker.onmessage = (event) => {\r\n const {action, error} = event.data;\r\n if (action === \"error\") {\r\n reject(error);\r\n return;\r\n };\r\n\r\n handler.handleResponse(event);\r\n };\r\n }\r\n\r\n const mesh = await this.loader.parse(buffer);\r\n await this.addSceneData(mesh);\r\n await this.addAerialData();\r\n\r\n resolve(true);\r\n });\r\n }\r\n\r\n async addAerialData() {\r\n // Aerial view layer\r\n this.mapLayer = boundsToMapLayer(this.boundingBox);\r\n this.map.addLayer(this.mapLayer);\r\n\r\n // Apply current visibility\r\n this.mapLayer.setVisible(this.visible);\r\n }\r\n\r\n async addSceneData(mesh) {\r\n // Apply mesh scene rotation\r\n mesh.rotation.set(Math.PI/2, 0, 0);\r\n\r\n // Apply mesh coordinate shift\r\n const modelID = mesh.modelID;\r\n const coordinationMatrix = await this.ifcAPI.GetCoordinationMatrix(modelID);\r\n\r\n const offset = new Vector3()\r\n .fromArray(coordinationMatrix.slice(12, 15))\r\n .applyEuler(mesh.rotation)\r\n .multiplyScalar(-1);\r\n\r\n // Convert mesh to meters\r\n mesh.scale.setScalar(LocalScene.dataToMeters);\r\n offset.multiplyScalar(LocalScene.dataToMeters);\r\n\r\n // Move model to scene coordinates\r\n const shift = LocalScene.offsetToScene(offset);\r\n mesh.position.copy(shift);\r\n\r\n // Scene view mesh\r\n this.standardMesh = mesh;\r\n this.scene.add(this.standardMesh);\r\n\r\n // Picking scene mesh\r\n this.pickingMesh = getBasicPicker(mesh, Mesh);\r\n this.picker.add(this.pickingMesh);\r\n\r\n // Apply current visibility\r\n this.standardMesh.visible = this.visible;\r\n this.pickingMesh.visible = this.visible;\r\n\r\n // Update bounding box\r\n this.boundingBox = new Box3()\r\n .setFromObject(this.standardMesh);\r\n }\r\n\r\n async initManager() {\r\n if (this.useWebWorkers) {\r\n const workerURL = \"workers/ifc-worker.js\";\r\n const workerPath = `${process.env.PUBLIC_URL}/${workerURL}`;\r\n await this.manager.useWebWorkers(true, workerPath);\r\n } else {\r\n await this.manager.useWebWorkers(false, null);\r\n }\r\n\r\n const wasmPath = isDevMode\r\n ? \"../../workers/\"\r\n : \"\";\r\n\r\n await this.manager.setWasmPath(wasmPath);\r\n\r\n this.manager.applyWebIfcConfig({\r\n COORDINATE_TO_ORIGIN: true,\r\n USE_FAST_BOOLS: true\r\n });\r\n\r\n this.manager.setOnProgress(event => {\r\n let percent = event.loaded / event.total;\r\n this.updatePercent(100 * percent);\r\n });\r\n }\r\n\r\n /** Update visibility */\r\n updateProperties(asset: Asset) {\r\n const state = asset.visible;\r\n this.visible = state;\r\n\r\n if (this.mapLayer) {\r\n this.mapLayer.setVisible(state);\r\n }\r\n\r\n if (this.standardMesh) {\r\n this.standardMesh.visible = state;\r\n }\r\n\r\n if (this.pickingMesh) {\r\n this.pickingMesh.visible = state;\r\n }\r\n\r\n this.updatePicker();\r\n }\r\n\r\n removeFromScene(item) {\r\n if (!item) return;\r\n this.picker.remove(item);\r\n this.scene.remove(item);\r\n }\r\n\r\n removeSubset() {\r\n const ifcMesh = this.standardMesh;\r\n if (!ifcMesh) return;\r\n\r\n const modelID = ifcMesh['modelID'];\r\n this.manager.removeSubset(modelID, this.highlightMaterial);\r\n }\r\n\r\n /** @private */\r\n attributesToProperties(attributes) {\r\n const properties = [];\r\n\r\n for (let [key, data] of Object.entries(attributes)) {\r\n let value = (data as any)?.value;\r\n if (!value) {\r\n continue;\r\n }\r\n\r\n if (typeof value === \"number\") {\r\n value = roundDigit(value, 10);\r\n }\r\n\r\n properties.push({property: key, value});\r\n };\r\n\r\n return properties;\r\n }\r\n\r\n async getProperties(faceIndex) {\r\n const ifcMesh = this.standardMesh;\r\n const modelID = ifcMesh['modelID'];\r\n const geometry = ifcMesh.geometry;\r\n\r\n const expressID = this.manager.getExpressId(geometry, faceIndex);\r\n const attributes = await this.manager.getItemProperties(\r\n modelID, expressID, true);\r\n\r\n const properties = this.attributesToProperties(attributes);\r\n\r\n const subsetMesh = this.manager.createSubset({\r\n modelID,\r\n ids: [ expressID ],\r\n scene: this.scene,\r\n removePrevious: true,\r\n material: this.highlightMaterial\r\n });\r\n\r\n subsetMesh.rotation.copy(ifcMesh.rotation);\r\n subsetMesh.position.copy(ifcMesh.position);\r\n subsetMesh.scale.copy(ifcMesh.scale);\r\n\r\n return properties;\r\n }\r\n\r\n disposeGeometry(item) {\r\n if (!item) return;\r\n item.geometry.dispose();\r\n item.material.forEach(material => {\r\n material.dispose();\r\n });\r\n }\r\n\r\n destroy() {\r\n this.enabled = false;\r\n\r\n this.removeSubset();\r\n\r\n this.removeFromScene(this.standardMesh);\r\n this.disposeGeometry(this.standardMesh);\r\n this.standardMesh = null;\r\n\r\n this.removeFromScene(this.pickingMesh);\r\n this.disposeGeometry(this.pickingMesh);\r\n this.pickingMesh = null;\r\n\r\n this.removeMapLayer();\r\n this.mapLayer = null;\r\n\r\n this.manager.dispose()\r\n .catch(err => {\r\n console.log(err);\r\n });\r\n }\r\n}\r\n\r\nexport class IFCHandler extends LineworkHandler {\r\n protected files: IFCFile[] = [];\r\n\r\n constructor(cadHandler: CADHandler) {\r\n super(cadHandler);\r\n }\r\n\r\n get objects() {\r\n return this.files\r\n .map(file => file.standardMesh)\r\n .filter(mesh => mesh !== null);\r\n }\r\n\r\n async getProperties(event) {\r\n const raycaster = new RayCaster(this.viewer, event);\r\n const objects = this.objects.filter(mesh => mesh && mesh.visible);\r\n const intersects = raycaster.intersectObjects(objects);\r\n if (intersects.length === 0) return [];\r\n\r\n const intersect = intersects[0];\r\n const selectedFile = this.files.find((file: IFCFile) => {\r\n return file.standardMesh === intersect.object;\r\n });\r\n\r\n if (!selectedFile) return [];\r\n\r\n const attributes = await selectedFile\r\n .getProperties(intersect.faceIndex);\r\n\r\n return attributes;\r\n }\r\n\r\n clearHighlight() {\r\n this.files.forEach(file => {\r\n file.removeSubset();\r\n });\r\n }\r\n}\r\n","import { toast } from \"../../../app\";\r\nimport { readFileBuffer } from \"../file-system-loader\";\r\nimport {\r\n CADHandler,\r\n LineworkLayer,\r\n LineworkFile,\r\n LineworkHandler\r\n} from \".\";\r\nimport { Asset, LineworkLayerData } from \"../../../redux/assets-slice\";\r\nimport { pathWithExtension } from \"../../../utilities\";\r\nimport { t } from \"../../../localization\";\r\nimport { Box3 } from \"three\";\r\nimport { DataProjectionCoordinate } from \"../projections\";\r\n\r\n\r\nclass SHPLayer extends LineworkLayer {\r\n constructor(file: SHPFile, layer: LineworkLayerData) {\r\n super(file, layer);\r\n }\r\n}\r\n\r\nexport class SHPFile extends LineworkFile {\r\n public layers: LineworkLayer[] = [];\r\n\r\n constructor(shpHandler: SHPHandler, asset: Asset) {\r\n super(shpHandler, asset);\r\n this.addLayers(asset.data);\r\n }\r\n\r\n get shpPath() {\r\n return pathWithExtension(this.path, \"shp\");\r\n }\r\n\r\n get dbfPath() {\r\n return pathWithExtension(this.path, \"dbf\");\r\n }\r\n\r\n getByName(layer) {\r\n return this.layers.find(x => x.name === layer);\r\n };\r\n\r\n async load() {\r\n this.loading = true;\r\n this.loaded = false;\r\n this.updatePercent(0);\r\n\r\n try {\r\n const shp = await readFileBuffer(this.shpPath);\r\n const dbf = await readFileBuffer(this.dbfPath);\r\n const {bounds, features} = await this.parseFromBuffer(shp, dbf);\r\n const layerNames = Object.keys(features);\r\n\r\n if (this.validBounds(bounds)) {\r\n this.boundingBox = new Box3(\r\n new DataProjectionCoordinate(bounds.min).toScene(),\r\n new DataProjectionCoordinate(bounds.max).toScene()\r\n );\r\n\r\n if (!this.saved) {\r\n this.viewer.zoomToSceneExtent(this.boundingBox, false);\r\n }\r\n }\r\n\r\n for (let i=0; i {\r\n return new Promise((resolve, reject) => {\r\n const workerURL = \"workers/shp-reader.js\";\r\n let worker = new Worker(`${process.env.PUBLIC_URL}/${workerURL}`);\r\n\r\n worker.onmessage = event => {\r\n const {success, response} = event.data;\r\n\r\n if (success) {\r\n resolve(response);\r\n } else {\r\n console.error(response);\r\n reject(response);\r\n }\r\n };\r\n\r\n const data = {shp, dbf, type: \"features\"};\r\n worker.postMessage(data, [data.shp, data.dbf]);\r\n });\r\n };\r\n\r\n addLayers(layers) {\r\n layers.forEach(data => {\r\n let newLayer = new SHPLayer(this, data);\r\n this.layers.push(newLayer);\r\n });\r\n }\r\n\r\n /** Update visibility and colors */\r\n updateProperties(asset: Asset) {\r\n this.visible = asset.visible;\r\n\r\n const layers = asset.data as LineworkLayerData[];\r\n layers.forEach(data => {\r\n const layer = this.getByName(data.name);\r\n layer.setColor(data.color);\r\n\r\n if (!this.visible) {\r\n layer.setVisibility(false);\r\n } else {\r\n layer.setVisibility(data.visible);\r\n }\r\n });\r\n\r\n this.updatePicker();\r\n }\r\n\r\n destroy() {\r\n this.enabled = false;\r\n\r\n // Remove map layer\r\n this.removeMapLayer();\r\n\r\n // Destroy all layers\r\n this.layers.forEach(x => x.destroy());\r\n this.layers = [];\r\n }\r\n}\r\n\r\nexport class SHPHandler extends LineworkHandler {\r\n protected files: SHPFile[] = [];\r\n\r\n constructor(cadHandler: CADHandler) {\r\n super(cadHandler);\r\n }\r\n\r\n async getProperties(event) {\r\n return [];\r\n }\r\n\r\n clearHighlight() {\r\n return;\r\n }\r\n}","import {\r\n CADHandler,\r\n LineworkLayer,\r\n LineworkFile,\r\n LineworkHandler\r\n} from \".\";\r\nimport { Asset, LineworkLayerData } from \"../../../redux/assets-slice\";\r\nimport { readFileText } from \"../file-system-loader\";\r\nimport { toast } from \"../../../app\";\r\nimport { t } from \"../../../localization\";\r\nimport { DataProjectionCoordinate } from \"../projections\";\r\nimport { Box3 } from \"three\";\r\n\r\nclass DXFLayer extends LineworkLayer {\r\n constructor(file: DXFFile, layer: LineworkLayerData) {\r\n super(file, layer);\r\n }\r\n}\r\n\r\nexport class DXFFile extends LineworkFile {\r\n public layers: DXFLayer[] = [];\r\n\r\n constructor(dxfHandler: DXFHandler, asset: Asset) {\r\n super(dxfHandler, asset);\r\n this.addLayers(asset.data);\r\n }\r\n\r\n getByName(layer) {\r\n return this.layers.find(x => x.name === layer);\r\n };\r\n\r\n async load() {\r\n this.loading = true;\r\n this.loaded = false;\r\n this.updatePercent(0);\r\n\r\n try {\r\n const text = await readFileText(this.path);\r\n const {bounds, features} = await this.parseFromText(text);\r\n const layerNames = Object.keys(features);\r\n\r\n if (this.validBounds(bounds)) {\r\n this.boundingBox = new Box3(\r\n new DataProjectionCoordinate(bounds.min).toScene(),\r\n new DataProjectionCoordinate(bounds.max).toScene()\r\n );\r\n\r\n if (!this.saved) {\r\n this.viewer.zoomToSceneExtent(this.boundingBox, false);\r\n }\r\n }\r\n\r\n for (let i=0; i {\r\n return new Promise((resolve, reject) => {\r\n const workerURL = \"workers/dxf-reader.js\";\r\n let worker = new Worker(`${process.env.PUBLIC_URL}/${workerURL}`);\r\n\r\n worker.onmessage = event => {\r\n const {success, response} = event.data;\r\n\r\n if (success) {\r\n resolve(response);\r\n } else {\r\n console.error(response);\r\n reject(response);\r\n }\r\n };\r\n\r\n const data = {text, type: \"features\"};\r\n worker.postMessage(data);\r\n });\r\n }\r\n\r\n addLayers(layers) {\r\n layers.forEach(data => {\r\n let newLayer = new DXFLayer(this, data);\r\n this.layers.push(newLayer);\r\n });\r\n }\r\n\r\n /** Update visibility and colors */\r\n updateProperties(asset: Asset) {\r\n this.visible = asset.visible;\r\n\r\n const layers = asset.data as LineworkLayerData[];\r\n layers.forEach(data => {\r\n const layer = this.getByName(data.name);\r\n layer.setColor(data.color);\r\n\r\n if (!this.visible) {\r\n layer.setVisibility(false);\r\n } else {\r\n layer.setVisibility(data.visible);\r\n }\r\n });\r\n\r\n this.updatePicker();\r\n }\r\n\r\n destroy() {\r\n this.enabled = false;\r\n\r\n // Remove map layer\r\n this.removeMapLayer();\r\n\r\n // Destroy all layers\r\n this.layers.forEach(x => x.destroy());\r\n this.layers = [];\r\n }\r\n}\r\n\r\nexport class DXFHandler extends LineworkHandler {\r\n protected files: DXFFile[] = [];\r\n\r\n constructor(cadHandler: CADHandler) {\r\n super(cadHandler);\r\n }\r\n\r\n async getProperties(event) {\r\n return [];\r\n }\r\n\r\n clearHighlight() {\r\n return;\r\n }\r\n}\r\n","import { WebSourceAsset } from \"../../../redux/assets-slice\";\r\nimport { ServerType } from \"../../../types/web-sources\";\r\nimport { Viewer } from \"../main\";\r\nimport {\r\n WebSource,\r\n ArcGISMapServer,\r\n ArcGISImageServer,\r\n ArcGISFeatureServer,\r\n OGCWMS,\r\n OGCWFS,\r\n OGCWMTS,\r\n TileServer\r\n} from \".\";\r\n\r\nexport class WebSourceList {\r\n public viewer: Viewer;\r\n private sources: WebSource[] = [];\r\n\r\n constructor(viewer: Viewer) {\r\n this.viewer = viewer;\r\n }\r\n\r\n reconcile(webSources: WebSourceAsset[]) {\r\n const currentSources = new Set(this.sources.map(x => x.id));\r\n const newSources = new Set(webSources.map(x => x.id));\r\n const sourcesToLoad = webSources.filter(x => !currentSources.has(x.id));\r\n const sourcesToDelete = this.sources.filter(x => !newSources.has(x.id));\r\n\r\n // Delete sources that need to be removed\r\n sourcesToDelete.forEach(webSource => {\r\n this.deleteSource(webSource);\r\n });\r\n\r\n // Add new sources\r\n sourcesToLoad.forEach(asset => {\r\n this.addNewSource(asset);\r\n });\r\n\r\n // Toggle visibility for each source\r\n webSources.forEach(asset => {\r\n this.toggleVisibility(asset);\r\n });\r\n }\r\n\r\n getByID(assetID) {\r\n return this.sources.find(file => file.id === assetID);\r\n }\r\n\r\n toggleVisibility(asset: WebSourceAsset) {\r\n let source = this.getByID(asset.id);\r\n if (!source) return;\r\n\r\n source.toggleVisibility(asset);\r\n }\r\n\r\n getNewSource(asset: WebSourceAsset) {\r\n const {type} = asset.data;\r\n\r\n switch (type) {\r\n case ServerType.ArcGISMapServer:\r\n return new ArcGISMapServer(this, asset);\r\n case ServerType.ArcGISImageServer:\r\n return new ArcGISImageServer(this, asset);\r\n case ServerType.ArcGISFeatureServer:\r\n return new ArcGISFeatureServer(this, asset);\r\n case ServerType.OGCWMS:\r\n return new OGCWMS(this, asset);\r\n case ServerType.OGCWFS:\r\n return new OGCWFS(this, asset);\r\n case ServerType.OGCWMTS:\r\n return new OGCWMTS(this, asset);\r\n case ServerType.TileServer:\r\n return new TileServer(this, asset);\r\n default:\r\n return;\r\n }\r\n }\r\n\r\n addNewSource(asset: WebSourceAsset) {\r\n let newSource = this.getNewSource(asset);\r\n if (!newSource) return;\r\n\r\n this.sources.push(newSource);\r\n }\r\n\r\n deleteSource(webSource: WebSource) {\r\n let source = this.getByID(webSource.id);\r\n if (!source) return;\r\n\r\n source.destroy();\r\n const index = this.sources.indexOf(source);\r\n this.sources.splice(index, 1);\r\n }\r\n}","import { Layer, Tile } from \"ol/layer\";\r\nimport { TileArcGISRest, TileWMS, XYZ } from \"ol/source\";\r\nimport { WebSourceAsset } from \"../../../redux/assets-slice\";\r\nimport { ServerType } from \"../../../types/web-sources\";\r\nimport { isEqual } from 'lodash';\r\nimport VectorSource from \"ol/source/Vector\";\r\nimport GeoJSON from 'ol/format/GeoJSON.js';\r\nimport { WebSourceList } from \".\";\r\nimport {createXYZ} from 'ol/tilegrid.js';\r\nimport VectorLayer from \"ol/layer/Vector\";\r\nimport WMTSCapabilities from \"ol/format/WMTSCapabilities\";\r\nimport WMTS, { optionsFromCapabilities } from \"ol/source/WMTS\";\r\nimport TileLayer from \"ol/layer/Tile\";\r\nimport EsriJSON from 'ol/format/EsriJSON.js';\r\nimport {\r\n fromUserExtent,\r\n fromUserResolution,\r\n Projection,\r\n ProjectionLike,\r\n toUserExtent,\r\n transformExtent\r\n} from \"ol/proj\";\r\nimport { createStyleFunction } from 'ol-esri-style';\r\nimport { Feature } from \"ol\";\r\nimport TileGrid from \"ol/tilegrid/TileGrid\";\r\nimport { Extent } from \"ol/extent\";\r\n\r\n/** Return the numeric part of openlayers style projection */\r\nconst projectionToEsriSRID = (projection: Projection) => {\r\n return projection\r\n .getCode()\r\n .split(/:(?=\\d+$)/)\r\n .pop();\r\n};\r\n\r\nexport class WebSource {\r\n public id: string;\r\n protected name: string;\r\n protected url: string;\r\n protected enabled = true;\r\n protected visible = false;\r\n protected clearable = false;\r\n protected removeOnClear = true;\r\n protected layers: Layer[] = [];\r\n private visibleIdentifier = [];\r\n protected type: ServerType;\r\n private handler: WebSourceList\r\n\r\n constructor(webmapHandler: WebSourceList, asset: WebSourceAsset) {\r\n this.id = asset.id;\r\n this.name = asset.name;\r\n this.url = asset.data.url;\r\n this.handler = webmapHandler;\r\n }\r\n\r\n get viewer() {\r\n return this.handler.viewer;\r\n }\r\n\r\n get map() {\r\n return this.viewer.minimap.map;\r\n }\r\n\r\n getByID(identifier) {\r\n return this.layers.find(layer => {\r\n return layer.get(\"identifier\") === identifier;\r\n });\r\n }\r\n\r\n setLayerVisible(identifier) {\r\n const layer = this.getByID(identifier);\r\n if (!layer) return false;\r\n\r\n layer.setVisible(true);\r\n layer.changed();\r\n return true;\r\n }\r\n\r\n toggleVisibility(asset: WebSourceAsset) {\r\n this.visible = asset.visible;\r\n\r\n const newIdentifiers = asset.data.layers\r\n .filter(layer => layer.visible && this.visible)\r\n .map(layer => layer.identifier);\r\n\r\n const needsUpdate = !isEqual(newIdentifiers, this.visibleIdentifier);\r\n this.visibleIdentifier = newIdentifiers;\r\n if (!needsUpdate) return;\r\n\r\n // Clear old layers\r\n this.clearLayers(this.removeOnClear);\r\n\r\n if (newIdentifiers.length === 0) return;\r\n this.generateLayers(newIdentifiers);\r\n }\r\n\r\n generateLayers(identifiers: string[]) {\r\n console.warn(\"Not Implemented\");\r\n }\r\n\r\n clearLayers(removeLayers) {\r\n if (removeLayers) {\r\n // Remove all layers from map\r\n this.layers.forEach(layer => {\r\n this.map.removeLayer(layer);\r\n });\r\n this.layers = [];\r\n } else {\r\n // Set all layer visibility to false\r\n this.layers.forEach(layer => {\r\n layer.setVisible(false);\r\n });\r\n }\r\n }\r\n\r\n destroy() {\r\n this.enabled = false;\r\n this.clearLayers(true);\r\n }\r\n}\r\n\r\nclass FeatureVectorSource extends VectorSource {\r\n private prevResolution;\r\n\r\n constructor(source: FeatureWebSource, options) {\r\n const tileGrid = createXYZ({\r\n tileSize: source.tileSize\r\n });\r\n\r\n super({\r\n ...options,\r\n strategy: (extent, resolution, projection) => {\r\n return this.getExtents(\r\n source, tileGrid, extent, resolution, projection\r\n );\r\n }\r\n });\r\n }\r\n\r\n /** strategy was modified from https://github.com/openlayers/openlayers/blob/v7.5.1/src/ol/loadingstrategy.js */\r\n getExtents(source: FeatureWebSource, tileGrid: TileGrid, extent: Extent,\r\n resolution: number, projection: ProjectionLike) {\r\n if (resolution !== this.prevResolution) {\r\n source.onResolutionChange();\r\n }\r\n\r\n this.prevResolution = resolution;\r\n\r\n const z = tileGrid.getZForResolution(\r\n fromUserResolution(resolution, projection)\r\n );\r\n\r\n const tileRange = tileGrid.getTileRangeForExtentAndZ(\r\n fromUserExtent(extent, projection), z\r\n );\r\n\r\n const extents = [];\r\n for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {\r\n for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {\r\n const tileCoord = [z, x, y];\r\n const extent = tileGrid.getTileCoordExtent(tileCoord);\r\n extents.push(toUserExtent(extent, projection));\r\n }\r\n }\r\n\r\n return extents;\r\n }\r\n\r\n updateFeatures(features: Feature[]) {\r\n let newFeatures = [];\r\n\r\n // Update existing feature geometry\r\n features.forEach(feature => {\r\n const featureID = feature.getId();\r\n const oldFeature = this.getFeatureById(featureID);\r\n\r\n if (oldFeature) {\r\n const geometry = feature.getGeometry();\r\n oldFeature.setGeometry(geometry);\r\n } else {\r\n newFeatures.push(feature);\r\n }\r\n });\r\n\r\n // Add new feature to source\r\n this.addFeatures(newFeatures);\r\n }\r\n}\r\n\r\nclass FeatureWebSource extends WebSource {\r\n public tileSize = 512;\r\n protected removeOnClear = false;\r\n protected controllers: AbortController[] = [];\r\n\r\n onResolutionChange() {\r\n this.cancelRequests();\r\n this.clearLoadedExtents();\r\n }\r\n\r\n cancelRequests() {\r\n // Cancel any existing requests\r\n this.controllers.forEach(controller => {\r\n controller.abort();\r\n });\r\n };\r\n\r\n clearLoadedExtents() {\r\n // Clear all loaded extents\r\n this.layers.forEach(layer => {\r\n const source = layer.getSource() as VectorSource;\r\n\r\n // @ts-expect-error\r\n source.loadedExtentsRtree_.clear();\r\n });\r\n }\r\n}\r\n\r\nexport class ArcGISMapServer extends WebSource {\r\n protected type = ServerType.ArcGISMapServer;\r\n\r\n /** Generate a single layer for all visible identifiers */\r\n generateLayers(identifiers: string[]) {\r\n const layer = new Tile({\r\n source: new TileArcGISRest({\r\n crossOrigin: \"anonymous\",\r\n url: this.url,\r\n params: {\r\n LAYERS: `show: ${identifiers.join(\",\")}`\r\n },\r\n wrapX: false\r\n })\r\n });\r\n\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n }\r\n}\r\n\r\nexport class ArcGISImageServer extends WebSource {\r\n protected type = ServerType.ArcGISImageServer;\r\n\r\n constructor(webmapHandler: WebSourceList, asset: WebSourceAsset) {\r\n super(webmapHandler, asset);\r\n\r\n let layer = new Tile({\r\n source: new TileArcGISRest({\r\n crossOrigin: \"anonymous\",\r\n url: this.url,\r\n wrapX: false\r\n }),\r\n visible: false\r\n });\r\n\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n }\r\n\r\n toggleVisibility(asset: WebSourceAsset) {\r\n this.visible = asset.visible;\r\n this.layers[0].setVisible(this.visible);\r\n }\r\n}\r\n\r\ninterface ArcGISFeatureCapabilities {\r\n metadata: any;\r\n hasHeight: boolean;\r\n extent: number[];\r\n supportsPagination: boolean;\r\n supportsQuantization: boolean;\r\n supportsQueryWithResultType: boolean;\r\n}\r\n\r\nexport class ArcGISFeatureServer extends FeatureWebSource {\r\n protected type = ServerType.ArcGISFeatureServer;\r\n private capabilities: { [layer: string]: ArcGISFeatureCapabilities } = {};\r\n private featureCount: { [layer: string]: number } = {};\r\n\r\n async getCapabilities(identifier: string): Promise {\r\n if (identifier in this.capabilities) {\r\n return this.capabilities[identifier];\r\n }\r\n\r\n const url = new URL(this.url);\r\n url.pathname += `/${identifier}`;\r\n url.searchParams.set('f', 'json');\r\n\r\n const response = await fetch(url.toString());\r\n const metadata = await response.json();\r\n\r\n const hasHeight = metadata.hasZ;\r\n const capabilities = metadata.advancedQueryCapabilities || {};\r\n const {supportsPagination=false, supportsQueryWithResultType=false} = capabilities;\r\n const supportsQuantization = !!metadata.supportsCoordinatesQuantization;\r\n\r\n let extent;\r\n\r\n try {\r\n const projection = `EPSG:${metadata.extent.spatialReference.wkid}`;\r\n\r\n extent = transformExtent([\r\n metadata.extent.xmin, metadata.extent.ymin,\r\n metadata.extent.xmax, metadata.extent.ymax\r\n ], projection, 'EPSG:3857');\r\n } catch (err) {\r\n console.warn(\"Error grabbing feature extent\");\r\n }\r\n\r\n this.capabilities[identifier] = {\r\n metadata,\r\n hasHeight,\r\n extent,\r\n supportsPagination,\r\n supportsQuantization,\r\n supportsQueryWithResultType\r\n };\r\n\r\n return this.capabilities[identifier];\r\n }\r\n\r\n async getNumberOfFeatures(identifier) {\r\n if (identifier in this.featureCount) {\r\n return this.featureCount[identifier];\r\n }\r\n\r\n const url = new URL(this.url);\r\n url.pathname += `/${identifier}`;\r\n url.pathname += '/query';\r\n\r\n url.searchParams.set('f', 'json');\r\n url.searchParams.set(\"where\", \"1=1\");\r\n url.searchParams.set('returnCountOnly', 'true');\r\n\r\n const response = await fetch(url.toString());\r\n const esriResponse = await response.json();\r\n\r\n this.featureCount[identifier] = esriResponse.count;\r\n return this.featureCount[identifier];\r\n }\r\n\r\n /** Generate one layer for each identifier */\r\n generateLayers(identifiers: string[]) {\r\n identifiers.forEach(async identifier => {\r\n // Try to update existing layer visibility\r\n if (this.setLayerVisible(identifier)) return;\r\n\r\n const capabilities = await this.getCapabilities(identifier);\r\n const featureCount = await this.getNumberOfFeatures(identifier);\r\n\r\n const vectorSource = new FeatureVectorSource(this, {\r\n loader: (extent, resolution, projection) => {\r\n this.getFeatures(vectorSource, identifier,\r\n extent, projection, capabilities, featureCount);\r\n },\r\n wrapX: false\r\n });\r\n\r\n const layer = new VectorLayer({\r\n source: vectorSource,\r\n extent: capabilities.extent,\r\n properties: {identifier}\r\n });\r\n\r\n // Apply feature style based on metadata\r\n const mapProjection = this.map.getView().getProjection();\r\n const styleFunction = await createStyleFunction(\r\n capabilities.metadata, mapProjection);\r\n layer.setStyle(styleFunction);\r\n\r\n if (!this.enabled) return;\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n });\r\n }\r\n\r\n reconstructQuantizedGeometry(esriResponse) {\r\n if (!esriResponse.features) return [];\r\n\r\n const {geometryType} = esriResponse;\r\n\r\n return esriResponse.features.map(feature => {\r\n const [scaleX, scaleY] = esriResponse.transform.scale;\r\n const [offsetX, offsetY] = esriResponse.transform.translate;\r\n\r\n const geometry = feature.geometry;\r\n\r\n if (geometryType === \"esriGeometryPoint\") {\r\n /** Reconstruct single point */\r\n geometry.x = offsetX + geometry.x * scaleX;\r\n geometry.y = offsetY + geometry.y * scaleY;\r\n } else if (geometryType === \"esriGeometryPolygon\") {\r\n /** Reconstruct polygon(s) */\r\n geometry.rings = geometry.rings.map(ring => {\r\n let coordinate = [offsetX, offsetY];\r\n\r\n return ring.map(point => {\r\n coordinate[0] += (point[0]*scaleX);\r\n coordinate[1] -= (point[1]*scaleY);\r\n return [...coordinate];\r\n });\r\n });\r\n } else if (geometryType === \"esriGeometryPolyline\") {\r\n /** Reconstruct polyline(s) */\r\n if (geometry.hasOwnProperty(\"paths\")) {\r\n geometry.paths = geometry.paths.map(path => {\r\n let coordinate = [offsetX, offsetY];\r\n\r\n return path.map(point => {\r\n coordinate[0] += (point[0]*scaleX);\r\n coordinate[1] -= (point[1]*scaleY);\r\n return [...coordinate];\r\n });\r\n });\r\n }\r\n } else {\r\n console.log(`Unknown geometry type: ${geometryType}`);\r\n }\r\n\r\n return feature;\r\n });\r\n }\r\n\r\n async getFeatures(source: FeatureVectorSource, identifier: string, extent,\r\n projection, capabilities, featureCount, resultOffset=0) {\r\n const srid = projectionToEsriSRID(projection);\r\n\r\n const {supportsPagination, supportsQuantization,\r\n supportsQueryWithResultType, hasHeight} = capabilities;\r\n\r\n // Complex layers can use geometry simplification and quantization\r\n const isComplexLayer = featureCount >= 1000;\r\n\r\n const extendBounds = {\r\n xmin: extent[0],\r\n ymin: extent[1],\r\n xmax: extent[2],\r\n ymax: extent[3],\r\n spatialReference: {\r\n wkid: srid\r\n }\r\n };\r\n\r\n // Limit geometry complexity to one vertex point per tile pixel\r\n const extentWidth = extendBounds.xmax - extendBounds.xmin;\r\n const tolerance = extentWidth / this.tileSize;\r\n\r\n const quantizationParameters = {\r\n extent: {\r\n type: \"extent\",\r\n ...extendBounds\r\n },\r\n mode: \"view\",\r\n originPosition: \"upperLeft\",\r\n tolerance\r\n };\r\n\r\n const url = new URL(this.url);\r\n url.pathname += `/${identifier}`;\r\n url.pathname += '/query';\r\n\r\n url.searchParams.set('f', 'json');\r\n url.searchParams.set('returnGeometry', 'true');\r\n url.searchParams.set('spatialRel', 'esriSpatialRelIntersects');\r\n url.searchParams.set('geometry', JSON.stringify(extendBounds));\r\n url.searchParams.set('geometryType', 'esriGeometryEnvelope');\r\n url.searchParams.set('inSR', srid);\r\n url.searchParams.set('outFields', '*');\r\n url.searchParams.set('outSR', srid);\r\n url.searchParams.set('where', '1=1');\r\n url.searchParams.set('returnZ', 'true');\r\n\r\n if (isComplexLayer) {\r\n if (supportsQuantization) {\r\n url.searchParams.set('quantizationParameters', JSON.stringify(quantizationParameters));\r\n } else {\r\n url.searchParams.set('maxAllowableOffset', tolerance.toString());\r\n }\r\n }\r\n\r\n if (supportsPagination) {\r\n url.searchParams.set('orderByFields', 'OBJECTID');\r\n }\r\n\r\n if (resultOffset > 0) {\r\n url.searchParams.set(\"resultOffset\", resultOffset.toString());\r\n }\r\n\r\n if (supportsQueryWithResultType) {\r\n // Tile type supports more features per query\r\n url.searchParams.set('resultType', 'tile');\r\n }\r\n\r\n // Add controller to array\r\n const controller = new AbortController();\r\n this.controllers.push(controller);\r\n\r\n let esriResponse;\r\n let fetchError = false;\r\n\r\n try {\r\n const response = await fetch(url.toString(), {\r\n signal: controller.signal\r\n });\r\n esriResponse = await response.json();\r\n } catch (err) {\r\n fetchError = true;\r\n }\r\n\r\n // Remove controller from array\r\n const index = this.controllers.indexOf(controller);\r\n this.controllers.splice(index, 1);\r\n\r\n // Something went wrong, exit early\r\n if (fetchError || esriResponse.error) return;\r\n\r\n if (isComplexLayer) {\r\n if (supportsQuantization) {\r\n esriResponse.features = this.reconstructQuantizedGeometry(esriResponse);\r\n }\r\n }\r\n\r\n const parser = new EsriJSON();\r\n const features = parser.readFeatures(esriResponse, {\r\n featureProjection: projection\r\n });\r\n\r\n if (features.length === 0) return;\r\n if (!this.enabled) return;\r\n\r\n // Add new features and update existing ones\r\n source.updateFeatures(features);\r\n\r\n // TODO: Add feature to scene view\r\n if (hasHeight) {\r\n //addSceneFeatures(esriResponse);\r\n }\r\n\r\n if (esriResponse.exceededTransferLimit && supportsPagination) {\r\n const newResultOffset = resultOffset + features.length;\r\n this.getFeatures(source, identifier, extent, projection,\r\n capabilities, featureCount, newResultOffset);\r\n }\r\n }\r\n}\r\n\r\nexport class OGCWMS extends WebSource {\r\n protected type = ServerType.OGCWMS;\r\n\r\n /** Generate a single layer for all visible identifiers */\r\n generateLayers(identifiers: string[]) {\r\n const layer = new Tile({\r\n source: new TileWMS({\r\n crossOrigin: \"anonymous\",\r\n url: this.url,\r\n params: {\r\n 'LAYERS': identifiers.join(\",\"),\r\n 'TILED': true\r\n },\r\n serverType: 'geoserver',\r\n wrapX: false\r\n })\r\n });\r\n\r\n if (!this.enabled) return;\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n }\r\n}\r\n\r\nexport class OGCWFS extends FeatureWebSource {\r\n protected type = ServerType.OGCWFS;\r\n\r\n /** Generate one layer for each identifier */\r\n generateLayers(identifiers: string[]) {\r\n identifiers.forEach(identifier => {\r\n // Try to update existing layer visibility\r\n if (this.setLayerVisible(identifier)) return;\r\n\r\n const vectorSource = new FeatureVectorSource(this, {\r\n loader: (extent, resolution, projection) => {\r\n this.getFeatures(vectorSource, identifier,\r\n extent, projection);\r\n },\r\n wrapX: false\r\n });\r\n\r\n const layer = new VectorLayer({\r\n source: vectorSource,\r\n properties: {identifier}\r\n });\r\n\r\n if (!this.enabled) return;\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n });\r\n }\r\n\r\n async getFeatures(source: FeatureVectorSource, identifier: string, extent, projection) {\r\n const url = new URL(this.url);\r\n url.searchParams.set('service', 'WFS');\r\n url.searchParams.set('request', 'GetFeature');\r\n url.searchParams.set('typename', identifier);\r\n url.searchParams.set('outputFormat', 'application/json');\r\n url.searchParams.set('srsname', 'EPSG:3857');\r\n\r\n const geomExtent = `${extent.join(',')},EPSG:3857`;\r\n url.searchParams.set('bbox', geomExtent);\r\n\r\n // Add controller to array\r\n const controller = new AbortController();\r\n this.controllers.push(controller);\r\n\r\n let serverResponse;\r\n let fetchError = false;\r\n\r\n try {\r\n const response = await fetch(url.toString(), {\r\n signal: controller.signal\r\n });\r\n serverResponse = await response.json();\r\n } catch (err) {\r\n fetchError = true;\r\n }\r\n\r\n // Remove controller from array\r\n const index = this.controllers.indexOf(controller);\r\n this.controllers.splice(index, 1);\r\n\r\n // Something went wrong, exit early\r\n if (fetchError) return;\r\n\r\n const parser = new GeoJSON();\r\n const features = parser.readFeatures(serverResponse, {\r\n featureProjection: projection\r\n });\r\n\r\n if (features.length === 0) return;\r\n if (!this.enabled) return;\r\n\r\n // Add new features and update existing ones\r\n source.updateFeatures(features);\r\n }\r\n}\r\n\r\nexport class OGCWMTS extends WebSource {\r\n protected type = ServerType.OGCWMTS;\r\n protected removeOnClear = false;\r\n private capabilities;\r\n\r\n constructor(webmapHandler: WebSourceList, asset: WebSourceAsset) {\r\n super(webmapHandler, asset);\r\n }\r\n\r\n async getCapabilities(): Promise {\r\n if (this.capabilities) {\r\n return this.capabilities;\r\n }\r\n\r\n const url = new URL(this.url);\r\n url.pathname = `${url.pathname}/1.0.0/WMTSCapabilities.xml`;\r\n\r\n const response = await fetch(url.href);\r\n const text = await response.text();\r\n\r\n const parser = new WMTSCapabilities();\r\n this.capabilities = parser.read(text);\r\n return this.capabilities;\r\n }\r\n\r\n /** Generate one layer for each identifier */\r\n async generateLayers(identifiers: string[]) {\r\n let capabilities = await this.getCapabilities();\r\n\r\n identifiers.forEach(identifier => {\r\n // Try to update existing layer visibility\r\n if (this.setLayerVisible(identifier)) return;\r\n\r\n const options = optionsFromCapabilities(capabilities, {\r\n layer: identifier,\r\n matrixSet: 'EPSG:3857',\r\n wrapX: false\r\n });\r\n\r\n const layer = new TileLayer({\r\n source: new WMTS(options),\r\n properties: {identifier}\r\n });\r\n\r\n if (!this.enabled) return;\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n });\r\n }\r\n}\r\n\r\nexport class TileServer extends WebSource {\r\n protected type = ServerType.TileServer;\r\n\r\n constructor(webmapHandler: WebSourceList, asset: WebSourceAsset) {\r\n super(webmapHandler, asset);\r\n\r\n let url = this.url\r\n .replace(\"{level}\", \"{z}\")\r\n .replace(\"{zoom}\", \"{z}\")\r\n .replace(\"{col}\", \"{x}\")\r\n .replace(\"{row}\", \"{y}\");\r\n\r\n let layer = new Tile({\r\n source: new XYZ({\r\n crossOrigin: \"anonymous\",\r\n url: url,\r\n wrapX: false\r\n }),\r\n visible: false\r\n });\r\n\r\n this.layers.push(layer);\r\n this.map.addLayer(layer);\r\n }\r\n\r\n toggleVisibility(asset: WebSourceAsset) {\r\n this.visible = asset.visible;\r\n this.layers[0].setVisible(this.visible);\r\n }\r\n}\r\n","import {ImageMaterial} from './rendering';\r\nimport {\r\n PointCloudManager,\r\n GenericPointCloud\r\n} from './pointcloud';\r\nimport {CompassControls, PanoControls} from './controls';\r\nimport { mergeBoundingBoxes, toScreenPosition } from './utilities';\r\nimport {CameraImage, CameraList, CameraLoadOptions} from './cameras';\r\nimport {CameraMarkers} from './markers';\r\nimport {\r\n AerialMap,\r\n extentFromPoints\r\n} from './aerial';\r\nimport {Clamp, ColorMapKey, ColorType, MarkerNavType} from '../../redux/settings-slice';\r\nimport LocalScene, {\r\n DataProjectionCoordinate,\r\n ProjectedCoordinate,\r\n SceneCoordinate,\r\n webMercator\r\n} from './projections';\r\nimport { getColorMap } from \"../textures/colormaps\";\r\nimport {\r\n MeasurementController,\r\n Measurement\r\n} from './measurements';\r\nimport { ChangeDetector } from './utilities';\r\nimport { isDevMode } from '../../electron-modules';\r\nimport GPUPicker from './gpu-picker';\r\nimport { throttle } from 'throttle-debounce';\r\nimport { SceneCameraState } from '../../redux/camera-slice';\r\nimport { ImageLabelTools, OrthoCategory } from './labelling';\r\nimport {\r\n Vector3,\r\n PerspectiveCamera,\r\n WebGLRenderer,\r\n TextureLoader,\r\n Line3\r\n} from \"three\";\r\nimport Stats from '../../stats.module.js';\r\nimport { RenderUtils, BasicRenderTarget } from './rendering';\r\nimport { MultiImageWindow } from './controls';\r\nimport onresize from \"resize-event\";\r\nimport Tags, { TagItem } from './tags';\r\nimport {toast} from '../../app';\r\nimport { updateMouseCoords } from '../../app-bar';\r\nimport { CADHandler } from './linework';\r\nimport { t } from '../../localization';\r\nimport { setCameraState } from '../viewer';\r\nimport path from 'path';\r\nimport { Bookmark } from '../../redux/bookmarks-slice';\r\nimport { VolumeType, SamplingRate, MeasureType } from '../../types/measurements';\r\nimport { WebSourceList } from './web-sources';\r\n\r\nconst annotationStyle = {\r\n transform: \"translate(-50%, -50%)\",\r\n background: \"rgba(0,0,0,0.6)\",\r\n cursor: \"pointer\",\r\n borderRadius: \"4px\",\r\n color: \"white\",\r\n fontSize: \"0.7em\",\r\n padding: \"4px 8px\",\r\n position: \"absolute\",\r\n whiteSpace: \"nowrap\",\r\n userSelect: \"none\"\r\n};\r\n\r\nexport class Viewer {\r\n public readonly containerElement: HTMLElement;\r\n public defaultFarPlane: number = 10000;\r\n private defaultNearPlane: number = 0.1;\r\n public pixelRatio = 1.0;\r\n public camera: PerspectiveCamera;\r\n public renderer: WebGLRenderer;\r\n private imageRenderMaterial: ImageMaterial;\r\n private imageRenderTarget: BasicRenderTarget;\r\n public gpuPickers: {\r\n default: GPUPicker,\r\n markers: GPUPicker,\r\n tags: GPUPicker\r\n };\r\n public imageLabels: ImageLabelTools;\r\n private renderUtils: RenderUtils;\r\n private changeDetector: ChangeDetector;\r\n public compass: CompassControls;\r\n public controls: PanoControls;\r\n public pointclouds: PointCloudManager;\r\n public cameraList: CameraList;\r\n public minimap: AerialMap;\r\n public markers: CameraMarkers;\r\n public measurements: MeasurementController;\r\n public cadHandler: CADHandler;\r\n public webmapHandler: WebSourceList;\r\n public tags: Tags;\r\n public multiImageWindow: MultiImageWindow;\r\n private stats: StatsPanel;\r\n public mouseCoords: Vector3;\r\n private updateMouseCoords: Function;\r\n private annotations = [];\r\n private enabled = true;\r\n public isEmpty = true;\r\n private focused = false;\r\n private drawPickerScene = false;\r\n public expanded = false;\r\n\r\n public projectName;\r\n private observer;\r\n\r\n // TODO: add intial aerial state, and make these... nicer?\r\n private initialZoomApplied = false;\r\n private initialStateApplied = false;\r\n\r\n public timingDebug = {\r\n \"markers\": false,\r\n \"scene\": false\r\n };\r\n\r\n constructor(viewContainer, mapContainer, props) {\r\n this.containerElement = viewContainer;\r\n\r\n this.initRenderer();\r\n this.initGpuPickers();\r\n this.initMaterials();\r\n this.initEvents();\r\n this.updateCamera();\r\n\r\n this.updateMouseCoords = throttle(100, (event) => {\r\n let coords = event\r\n ? this.controls.getPickerResults(event).coordinate\r\n : null;\r\n\r\n updateMouseCoords(coords);\r\n });\r\n\r\n this.compass = new CompassControls(this, props);\r\n this.pointclouds = new PointCloudManager(this);\r\n this.controls = new PanoControls(this, this.camera,\r\n this.renderer.domElement, props);\r\n this.measurements = new MeasurementController(this, props);\r\n this.cameraList = new CameraList(this);\r\n this.minimap = new AerialMap(this, mapContainer, props);\r\n this.tags = new Tags(this);\r\n this.cadHandler = new CADHandler(this);\r\n this.webmapHandler = new WebSourceList(this);\r\n this.imageLabels = new ImageLabelTools(this, props);\r\n this.markers = new CameraMarkers(this);\r\n this.changeDetector = new ChangeDetector(this);\r\n this.multiImageWindow = new MultiImageWindow(this, props);\r\n this.stats = new StatsPanel(this);\r\n\r\n this.addContainerElements();\r\n this.initResize();\r\n this.animate();\r\n }\r\n\r\n get width(): number {\r\n return this.containerElement.offsetWidth;\r\n }\r\n\r\n get height(): number {\r\n return this.containerElement.offsetHeight;\r\n }\r\n\r\n get near() {\r\n return this.camera.near;\r\n }\r\n\r\n get far() {\r\n return this.camera.far;\r\n }\r\n\r\n get fov() {\r\n return this.camera.fov;\r\n }\r\n\r\n get orthoList() {\r\n return this.minimap.orthoList;\r\n }\r\n\r\n get lookatVector() {\r\n return new Vector3(0, 0, -1)\r\n .applyQuaternion(this.camera.quaternion);\r\n }\r\n\r\n get upVector() {\r\n return new Vector3(0, 1, 0)\r\n .applyQuaternion(this.camera.quaternion);\r\n }\r\n\r\n get rightVector() {\r\n return new Vector3(1, 0, 0)\r\n .applyQuaternion(this.camera.quaternion);\r\n }\r\n\r\n get orbitState(): boolean {\r\n return this.controls.orbit.state;\r\n }\r\n\r\n get cameraSelected() {\r\n return this.cameraList.cameraLoaded;\r\n }\r\n\r\n get hasPoints() {\r\n return !this.pointclouds.isEmpty;\r\n }\r\n\r\n get hasCameras() {\r\n return !this.cameraList.isEmpty;\r\n }\r\n\r\n get hasModels() {\r\n return this.cadHandler.numberOfFiles > 0;\r\n }\r\n\r\n get hasTags() {\r\n return this.tags.numberOfFiles > 0;\r\n }\r\n\r\n get isImageOnly() {\r\n return this.hasCameras && !this.hasPoints;\r\n }\r\n\r\n get isPointsOnly() {\r\n return !this.hasCameras && this.hasPoints;\r\n }\r\n\r\n get calculatingSceneMarkers() {\r\n return this.markers.calculating;\r\n }\r\n\r\n get calculatingAerialMarkers() {\r\n return this.minimap.calculating;\r\n }\r\n\r\n get showCompassElement() {\r\n if (!LocalScene.initialized) return false;\r\n let show = this.orbitState;\r\n\r\n if (this.hasCameras) {\r\n // Current camera is done loading (or there is no camera selected)\r\n let currentCamera = this.cameraList.current;\r\n show = currentCamera\r\n ? currentCamera.loaded || currentCamera.loading\r\n : true;\r\n }\r\n\r\n return show;\r\n }\r\n\r\n get initialCameraLoading() {\r\n return this.cameraList.newCameraLoading\r\n && !this.cameraList.cameraLoadedOnce;\r\n }\r\n\r\n get aerialState() {\r\n return this.minimap.aerialState;\r\n }\r\n\r\n get sceneState() {\r\n let state = {\r\n camera: null,\r\n fov: null,\r\n lookat: null,\r\n angles: null,\r\n orbit: null,\r\n pivot: null\r\n } as SceneCameraState;\r\n\r\n if (this.orbitState) {\r\n // Update for orbit camera\r\n let {orbit, pivot} = this.controls.orbit.getPositionValues();\r\n\r\n state = {\r\n ...state,\r\n orbit: orbit,\r\n pivot: pivot\r\n };\r\n } else if (this.cameraList.current) {\r\n // Update for standard camera\r\n state = {\r\n ...state,\r\n camera: this.cameraList.current.id,\r\n fov: this.controls.fov,\r\n angles: this.controls.angles\r\n };\r\n }\r\n\r\n return state;\r\n }\r\n\r\n /** Exposed Global Methods */\r\n setExpanded(state) {\r\n this.expanded = state;\r\n }\r\n\r\n setContainerCursor(cursor) {\r\n this.containerElement.style.cursor = cursor;\r\n }\r\n\r\n addContainerElements() {\r\n this.containerElement.appendChild(this.renderer.domElement);\r\n this.containerElement.appendChild(this.compass.domElement);\r\n }\r\n\r\n removeContainerElements() {\r\n this.containerElement.removeChild(this.renderer.domElement);\r\n this.containerElement.removeChild(this.compass.domElement);\r\n }\r\n\r\n addAnnotation(text: string, position: number[], onClick = null, customStyle = null) {\r\n const div = document.createElement(\"div\");\r\n\r\n Object.keys(annotationStyle).forEach(key => {\r\n div.style[key] = annotationStyle[key];\r\n });\r\n\r\n if (customStyle) {\r\n Object.keys(customStyle).forEach(key => {\r\n div.style[key] = customStyle[key];\r\n });\r\n }\r\n\r\n div.innerHTML = text;\r\n\r\n if (onClick) {\r\n div.onclick = onClick;\r\n } else {\r\n div.style.pointerEvents = \"none\";\r\n }\r\n\r\n const annotation = {\r\n position: position,\r\n element: div\r\n };\r\n\r\n this.annotations.push(annotation);\r\n this.containerElement.appendChild(annotation.element);\r\n\r\n return annotation;\r\n }\r\n\r\n removeAnnotation(annotation) {\r\n const index = this.annotations.indexOf(annotation);\r\n if (index === -1) return;\r\n\r\n this.annotations.splice(index, 1);\r\n this.containerElement.removeChild(annotation.element);\r\n }\r\n\r\n setProjectName(name: string) {\r\n this.projectName = name;\r\n }\r\n\r\n togglePickerDebug(value) {\r\n this.drawPickerScene = value;\r\n }\r\n\r\n getAvailableClassifications(): number[] {\r\n return this.pointclouds.uniqueClassifications;\r\n }\r\n\r\n setVisibleClassifications(classifications) {\r\n this.pointclouds.setVisibleClassifications(classifications);\r\n }\r\n\r\n setPointsShouldUpdate(state) {\r\n this.pointclouds.shouldUpdate = state;\r\n }\r\n\r\n setPointBoundsVisible(state) {\r\n this.pointclouds.boundsVisible = state;\r\n }\r\n\r\n setPointCloudOpacity(opacity: number) {\r\n this.pointclouds.transparency = opacity;\r\n }\r\n\r\n setPointCloudMinimum(size: number) {\r\n this.pointclouds.setPointCloudMinimum(size);\r\n }\r\n\r\n setPointCloudScale(size: number) {\r\n this.pointclouds.setPointCloudScale(size);\r\n }\r\n\r\n setPointCloudMaxPoints(points: number) {\r\n this.pointclouds.visiblePointsTarget = points * 1000000;\r\n }\r\n\r\n setPointCloudDistance(distance: number) {\r\n this.pointclouds.setMaxDistance(distance);\r\n }\r\n\r\n setPointCloudHeightClip(clamp: Clamp) {\r\n this.pointclouds.updateClamping('heightClamp', clamp);\r\n }\r\n\r\n setPointCloudIntensityClip(clamp: Clamp) {\r\n this.pointclouds.updateClamping('intensityClamp', clamp);\r\n }\r\n\r\n setPointCloudColorMap(colorMapKey: ColorMapKey) {\r\n const textureData = getColorMap(colorMapKey).image;\r\n\r\n const loader = new TextureLoader();\r\n loader.load(textureData, texture => {\r\n this.pointclouds.materialDefaults.colorMap = colorMapKey;\r\n this.pointclouds.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.colorMap = texture;\r\n material.colorMap.needsUpdate = true;\r\n });\r\n });\r\n });\r\n }\r\n\r\n setPointCloudColorType(colorType: ColorType) {\r\n this.pointclouds.materialDefaults.colorType = colorType;\r\n this.pointclouds.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.colorType = colorType;\r\n });\r\n });\r\n }\r\n\r\n setPointCloudDynamicSize(state: boolean) {\r\n this.pointclouds.materialDefaults.dynamicSize = state;\r\n this.pointclouds.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.adaptiveSize = state;\r\n });\r\n });\r\n }\r\n\r\n setPointCloudCircularPoints(state: boolean) {\r\n this.pointclouds.materialDefaults.circularPoints = state;\r\n this.pointclouds.clouds.forEach(pointCloud => {\r\n pointCloud.materials.forEach(material => {\r\n material.circularPoints = state;\r\n });\r\n });\r\n }\r\n\r\n setTagDistance(distance: number) {\r\n this.tags.setMaxDistance(distance);\r\n }\r\n\r\n setNavigationType(state: MarkerNavType) {\r\n this.markers.setNavigationType(state);\r\n }\r\n\r\n setControlType(type: number) {\r\n this.controls.setControlType(type);\r\n }\r\n\r\n toggleOrbitState() {\r\n this.controls.toggleCamera();\r\n }\r\n\r\n resetCamera() {\r\n this.controls.resetCamera(\"top\");\r\n }\r\n\r\n /** NOTE: Temporary(?) solution for the viewer being created over and over again */\r\n destroy() {\r\n this.observer.disconnect();\r\n\r\n // Destroy viewer + events\r\n this.enabled = false;\r\n this.camera = null;\r\n this.removeContainerElements();\r\n this.removeEvents();\r\n\r\n this.minimap.destroy();\r\n this.controls.destroy();\r\n this.orthoList.destroy();\r\n this.multiImageWindow.destroy();\r\n }\r\n\r\n setDataProjection(newProjection) {\r\n LocalScene.setDataProjection(newProjection);\r\n }\r\n\r\n setViewProjection(newProjection) {\r\n LocalScene.setViewProjection(newProjection);\r\n }\r\n\r\n setMeasurementUnits(units) {\r\n this.controls.measurements.setUnits(units);\r\n }\r\n\r\n setActiveAlignment(id) {\r\n this.measurements.setActiveAlignment(id);\r\n }\r\n\r\n async loadImage(cameraID, opts: CameraLoadOptions = {}) {\r\n this.setInitialZoomFlag(true);\r\n let newCamera = await this.cameraList.loadImage(cameraID, opts);\r\n return newCamera;\r\n }\r\n\r\n /** @private */\r\n setCameraState(state: SceneCameraState) {\r\n if (this.initialStateApplied) return false;\r\n\r\n if (state.camera || state.lookat) {\r\n if (this.cameraList.loadSavedCameraState(state)) {\r\n this.setInitialStateFlag(true);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /** @private */\r\n setOrbitState(state: SceneCameraState) {\r\n if (this.initialStateApplied) return false;\r\n\r\n const has3dAssets = this.hasModels || this.hasTags || this.hasPoints;\r\n if (!has3dAssets) return false;\r\n\r\n if (state.orbit && state.pivot) {\r\n if (!this.orbitState) {\r\n // Move to orbit mode with default lookat\r\n this.controls.setOrbitValues(true);\r\n }\r\n\r\n const newPosition = {\r\n orbit: new DataProjectionCoordinate(state.orbit).toScene(),\r\n pivot: new DataProjectionCoordinate(state.pivot).toScene(),\r\n smooth: false\r\n };\r\n\r\n // Apply new positions to orbit camera\r\n this.controls.setOrbitValues(true, newPosition);\r\n this.setInitialZoomFlag(true);\r\n this.setInitialStateFlag(true);\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /** @private */\r\n setTagState(tagID: string) {\r\n if (this.initialStateApplied) return false;\r\n\r\n this.jumpToTag(tagID);\r\n this.setInitialStateFlag(true);\r\n return true;\r\n }\r\n\r\n clearCadHighlight() {\r\n this.cadHandler.clearHighlight();\r\n }\r\n\r\n getAerialZoomLevel() {\r\n return this.minimap?.map.getView().getZoom();\r\n }\r\n\r\n getCameraPosition() {\r\n return new SceneCoordinate(this.camera.position)\r\n .toDataProjection();\r\n }\r\n\r\n\r\n isBehindCamera(position: Vector3) {\r\n const start = new Vector3()\r\n .add(this.camera.position);\r\n\r\n const end = new Vector3()\r\n .add(this.camera.position)\r\n .add(this.lookatVector);\r\n\r\n const line = new Line3(start, end);\r\n return line.closestPointToPointParameter(position) < 0;\r\n }\r\n\r\n /** Local Aligner */\r\n toggleLocalAligner(state) {\r\n this.controls.localAligner.setState(state);\r\n }\r\n\r\n estimateLocalTransform = (estimator: string, units: string) => {\r\n return this.controls.localAligner.getLocalProjection(estimator, units);\r\n };\r\n\r\n clearLocalTransformErrors = () => {\r\n this.controls.localAligner.resetErrorValues();\r\n };\r\n\r\n refreshLocalTransform() {\r\n this.controls.localAligner.drawObservations();\r\n }\r\n\r\n generateLocalAlignerRows(numRows) {\r\n this.controls.localAligner.addNewObservations(numRows);\r\n }\r\n\r\n setLocalAlignerActive(id, type) {\r\n this.controls.localAligner.setActiveObservation(id, type);\r\n };\r\n\r\n deleteLocalAlignment(id) {\r\n this.controls.localAligner.removeByID(id);\r\n }\r\n\r\n /** Point Markup */\r\n pointMarkupActive() {\r\n return this.controls.pointMarkup.active;\r\n }\r\n\r\n addPointMarkupOperation(type, name) {\r\n this.controls.pointMarkup.addNewGroup(type, name);\r\n }\r\n\r\n updatePointMarkupName(id, name) {\r\n this.controls.pointMarkup.setName(id, name);\r\n }\r\n\r\n setPointMarkupActive(id) {\r\n this.controls.pointMarkup.setActive(id);\r\n }\r\n\r\n pointMarkupToggle(state) {\r\n this.controls.pointMarkup.setState(state);\r\n }\r\n\r\n clearPointMarkup() {\r\n this.controls.pointMarkup.clear();\r\n }\r\n\r\n pointMarkupZoom(id) {\r\n this.controls.pointMarkup.zoom(id);\r\n }\r\n\r\n pointMarkupDeleteGroup(id) {\r\n this.controls.pointMarkup.removeClippingGroup(id);\r\n }\r\n\r\n pointMarkupDeleteBox(id) {\r\n this.controls.pointMarkup.removeClippingBox(id);\r\n }\r\n\r\n pointMarkupNameExists(name) {\r\n return this.controls.pointMarkup.clippingGroups\r\n .filter(x => x.name === name).length > 0;\r\n }\r\n\r\n setPointMarkupNewClassification(id, value) {\r\n this.controls.pointMarkup.setNewClassification(id, value);\r\n }\r\n\r\n setPointMarkupIgnoredClassification(id, value) {\r\n this.controls.pointMarkup.setIgnoredClassification(id, value);\r\n }\r\n\r\n resetPointMarkupRotation(id) {\r\n this.controls.pointMarkup.resetRotation(id);\r\n }\r\n\r\n setPointMarkupHover(id, hover) {\r\n this.controls.pointMarkup.setHover(id, hover);\r\n }\r\n\r\n /** Multi Image Window */\r\n initMultiImageContainer(container) {\r\n this.multiImageWindow.init(container);\r\n }\r\n\r\n toggleMultiImageWindow(state) {\r\n this.multiImageWindow.setState(state);\r\n }\r\n\r\n multiImageNextImage() {\r\n this.multiImageWindow.loadNextImage();\r\n }\r\n\r\n multiImagePreviousImage() {\r\n this.multiImageWindow.loadPreviousImage();\r\n }\r\n\r\n multiImageOnComplete() {\r\n this.multiImageWindow.onComplete();\r\n }\r\n\r\n multiImageOnAddMore() {\r\n this.multiImageWindow.onAddMore();\r\n }\r\n\r\n multiImageClosePrompt() {\r\n return this.multiImageWindow.closePrompt();\r\n }\r\n\r\n /** Point Profile */\r\n initProfileContainer(type, units) {\r\n this.controls.pointProfile.profileChart.init(type, units);\r\n }\r\n\r\n resetPointProfile() {\r\n this.controls.pointProfile.reset();\r\n }\r\n\r\n refreshPointProfile() {\r\n this.controls.pointProfile.updatePoints();\r\n }\r\n\r\n resetPointProfileView() {\r\n this.controls.pointProfile.resetZoom();\r\n }\r\n\r\n pointProfileActive() {\r\n return this.controls.pointProfile.drawing;\r\n }\r\n\r\n pointProfileStart(coordinate) {\r\n this.controls.pointProfile.selectStart(coordinate);\r\n }\r\n\r\n pointProfileEnd() {\r\n this.controls.pointProfile.selectEnd();\r\n }\r\n\r\n pointProfileCancel() {\r\n this.controls.pointProfile.selectCancel();\r\n }\r\n\r\n setPointProfileUnits(units) {\r\n this.controls.pointProfile.updateUnits(units);\r\n }\r\n\r\n setPointProfileSampling(type) {\r\n this.controls.pointProfile.updateSampling(type);\r\n }\r\n\r\n getPointProfileImage() {\r\n return this.controls.pointProfile.getProfileImage();\r\n }\r\n\r\n /** Measurements */\r\n toggleMeasurements(state) {\r\n this.controls.measurements.setState(state);\r\n }\r\n\r\n updateVolumeType(type: VolumeType) {\r\n this.controls.measurements.setVolumeType(type);\r\n }\r\n\r\n updateVolumeSampleRate(rate: SamplingRate) {\r\n this.controls.measurements.setSampleRate(rate);\r\n }\r\n\r\n updateMeasurementType(type: MeasureType) {\r\n this.controls.measurements.setMeasurementType(type);\r\n }\r\n\r\n updateMeasureHover(measurement: Measurement, state) {\r\n this.controls.measurements.setHover(measurement, state);\r\n }\r\n\r\n deleteMeasurement(measurement: Measurement) {\r\n this.controls.measurements.removeByID(measurement.id);\r\n }\r\n\r\n renameMeasurement(measurement: Measurement, title) {\r\n this.controls.measurements.setTitle(measurement.id, title);\r\n }\r\n\r\n exportMeasurements(type, ordering) {\r\n this.controls.measurements.export(type, ordering);\r\n }\r\n\r\n getMeasurementFormatter() {\r\n return this.controls.measurements.formatter;\r\n }\r\n\r\n loadMeasurementData(data) {\r\n return this.controls.measurements.loadMeasurementData(data);\r\n }\r\n\r\n /** Ortho Viewer */\r\n setOrthoOpacity(value) {\r\n this.orthoList.setOpacity(value);\r\n }\r\n\r\n /** Labelling/Annotation */\r\n activeImageLabelPaths() {\r\n return this.imageLabels.activeImagePaths();\r\n }\r\n\r\n activeImages() {\r\n return this.imageLabels.activeImages();\r\n }\r\n\r\n loadedImageLabelPaths() {\r\n return this.imageLabels.loadedImagePaths();\r\n }\r\n\r\n async loadImageLabelData(data, progressCallback, overwrite, checkOverlap) {\r\n await this.imageLabels.loadImageLabelData(\r\n data, progressCallback, overwrite, checkOverlap);\r\n }\r\n\r\n setActiveLabelType(state) {\r\n this.imageLabels.setActiveLabelType(state);\r\n }\r\n\r\n labelSelected() {\r\n return this.imageLabels.checkIfSelected();\r\n }\r\n\r\n labelHotkey(event) {\r\n this.imageLabels.onKeyDown(event);\r\n }\r\n\r\n setLabelText(id, text) {\r\n this.imageLabels.setText(id, text);\r\n }\r\n\r\n setLabelFindText(id) {\r\n this.imageLabels.setFindText(id);\r\n }\r\n\r\n addCategory(category) {\r\n this.imageLabels.addCategory(category);\r\n }\r\n\r\n deleteCategory(id) {\r\n this.imageLabels.deleteCategory(id);\r\n }\r\n\r\n addTrainingArea() {\r\n this.imageLabels.addTrainingArea();\r\n }\r\n\r\n deleteHighlighted() {\r\n this.imageLabels.deleteHighlighted();\r\n }\r\n\r\n editCategoryName(id, name) {\r\n this.imageLabels.editCategoryName(id, name);\r\n }\r\n\r\n deleteAllCategories() {\r\n this.imageLabels.deleteAllCategories();\r\n }\r\n\r\n deleteTrainingArea() {\r\n this.imageLabels.deleteTrainingArea();\r\n }\r\n\r\n deleteLabel(id) {\r\n this.imageLabels.deleteLabel(id);\r\n }\r\n\r\n zoomToLabel(id) {\r\n this.imageLabels.zoomToLabel(id);\r\n }\r\n\r\n addLabel(id) {\r\n this.imageLabels.addLabel(id);\r\n }\r\n\r\n addTrainingAreaLabel() {\r\n this.imageLabels.addTrainingAreaLabel();\r\n }\r\n\r\n currentCategory() {\r\n return this.imageLabels.currentCategoryName;\r\n }\r\n\r\n getIdxInList(category) {\r\n return this.imageLabels.getIdxInList(category);\r\n }\r\n\r\n selectLabel(id) {\r\n this.imageLabels.selectLabel(id);\r\n }\r\n\r\n deleteLabelPoint(pointID) {\r\n this.imageLabels.deletePoint(pointID);\r\n }\r\n\r\n insertLabelPoint(id, coord) {\r\n this.imageLabels.insertPoint(id, coord);\r\n }\r\n\r\n editLabel(id, coord) {\r\n this.imageLabels.editLabel(id, coord);\r\n }\r\n\r\n moveToLabel(id) {\r\n this.imageLabels.moveToLabelInList(id);\r\n }\r\n\r\n completeLabel(label) {\r\n this.imageLabels.completeLabel(label);\r\n }\r\n\r\n unHighlight(id) {\r\n this.imageLabels.unHighlight(id);\r\n }\r\n\r\n unHighlightAll() {\r\n this.imageLabels.unHighlightAll();\r\n }\r\n\r\n sortCategory = (category, score, sortType) => {\r\n this.imageLabels.sortCategory(category, score, sortType);\r\n };\r\n\r\n undoSort = (category) => {\r\n this.imageLabels.undoSort(category);\r\n };\r\n\r\n numLabelsHighlighted() {\r\n return this.imageLabels.numHighlighted;\r\n }\r\n\r\n checkCategoryUniqueness(categoryName) {\r\n return this.imageLabels.checkUniqueName(categoryName);\r\n }\r\n\r\n labelObject = () => {\r\n return this.imageLabels.labelObject();\r\n };\r\n\r\n getOrthoLabelPolygons = () => {\r\n if (!this.imageLabels.isAerialLabels) return;\r\n\r\n const data = {};\r\n\r\n this.imageLabels.categories.forEach((category: OrthoCategory) => {\r\n const segments = category.labels\r\n .filter(label => label.valid)\r\n .map(label => {\r\n return label.polygonPointsOnly.map(coord => {\r\n return new ProjectedCoordinate(coord, webMercator)\r\n .toDataProjection()\r\n .toArray()\r\n .slice(0, 2);\r\n });\r\n });\r\n\r\n data[category.name] = segments;\r\n });\r\n\r\n return data;\r\n };\r\n\r\n anyLabelSelected = () => {\r\n return this.imageLabels.checkIfSelected();\r\n };\r\n\r\n getLasFileInfo(id) {\r\n const pointCloud = this.pointclouds.getByID(id);\r\n if (!pointCloud) return;\r\n if (!(pointCloud instanceof GenericPointCloud)) return;\r\n\r\n return pointCloud.headerFileInfo;\r\n }\r\n\r\n /** Asset Click */\r\n\r\n snapToFolder(assetIDs) {\r\n let boundingBoxes = [];\r\n\r\n assetIDs.forEach(assetID => {\r\n const file = this.cadHandler.getByID(assetID);\r\n if (file) {\r\n boundingBoxes.push(file.boundingBox);\r\n }\r\n\r\n const pointCloud = this.pointclouds.getByID(assetID);\r\n if (pointCloud) {\r\n boundingBoxes.push(pointCloud.tightBoundingBox);\r\n }\r\n\r\n const tagFile = this.tags.getByID(assetID);\r\n if (tagFile) {\r\n const tagBBOX = this.tags.boundingBoxForTags(tagFile.tags);\r\n boundingBoxes.push(tagBBOX);\r\n }\r\n });\r\n\r\n const combinedBounds = mergeBoundingBoxes(boundingBoxes);\r\n\r\n this.setInitialZoomFlag(false);\r\n this.zoomToSceneExtent(combinedBounds, true);\r\n }\r\n\r\n snapToOrtho(id) {\r\n const ortho = this.minimap.orthoList.getByID(id);\r\n if (!ortho) return;\r\n\r\n ortho.zoomToExtent();\r\n }\r\n\r\n snapToModel(id) {\r\n const file = this.cadHandler.getByID(id);\r\n if (!file) return;\r\n\r\n this.setInitialZoomFlag(false);\r\n this.zoomToSceneExtent(file.boundingBox, true);\r\n }\r\n\r\n snapToPointCloud(id) {\r\n const pointCloud = this.pointclouds.getByID(id);\r\n if (!pointCloud) return;\r\n\r\n this.setInitialZoomFlag(false);\r\n this.zoomToSceneExtent(pointCloud.tightBoundingBox, true);\r\n }\r\n\r\n snapToImages(assetID) {\r\n const features = this.getCameraFeaturesForCSV(assetID);\r\n if (features.length === 0) return;\r\n\r\n let positions = features.map(x => x.getGeometry().getCoordinates());\r\n let extent = extentFromPoints(positions, false);\r\n this.minimap.setMapExtent(extent);\r\n }\r\n\r\n zoomToSceneExtent(boundingBox, smooth: boolean) {\r\n if (!boundingBox || this.initialZoomApplied) return;\r\n\r\n try {\r\n this.setInitialZoomFlag(true);\r\n\r\n let newPosition = this.controls.orbitFromBounds(\r\n boundingBox, \"top\", smooth);\r\n\r\n // Apply new positions to orbit camera\r\n this.controls.setOrbitValues(true, newPosition);\r\n\r\n // Zoom to map extent\r\n let positions = [boundingBox.min, boundingBox.max].map(position => {\r\n return new SceneCoordinate(position).toDataProjection();\r\n });\r\n\r\n let extent = extentFromPoints(positions);\r\n this.minimap.setMapExtent(extent);\r\n } catch (err) {\r\n console.error(\"Error zooming to extent\", boundingBox);\r\n }\r\n }\r\n\r\n /** Camera Aligner */\r\n toggleCameraAligner(state) {\r\n this.controls.cameraAlignerAdv.setState(state);\r\n }\r\n\r\n resetCameraAligner() {\r\n this.controls.cameraAlignerAdv.reset();\r\n }\r\n\r\n generateAdvancedAlignerRows(numRows) {\r\n this.controls.cameraAlignerAdv.addNewObservations(numRows);\r\n }\r\n\r\n setErrorsCameraAligner(errors) {\r\n this.controls.cameraAlignerAdv.setErrors(errors);\r\n }\r\n\r\n clearErrorsCameraAligner() {\r\n this.controls.cameraAlignerAdv.clearErrors();\r\n }\r\n\r\n deleteRowCameraAligner(i) {\r\n this.controls.cameraAlignerAdv.removeByID(i);\r\n }\r\n\r\n setBasicAlignerState(state) {\r\n this.controls.cameraAlignerBasic.setState(state);\r\n }\r\n\r\n resetBasicAlignerCamera(values = [0, 0, 0]) {\r\n this.controls.cameraAlignerBasic.reset(values);\r\n }\r\n\r\n getBasicAlignerValue() {\r\n return this.controls.cameraAlignerBasic.cameraAngles;\r\n }\r\n\r\n flashObservations(id) {\r\n this.controls.cameraAlignerAdv.flashObservations(id);\r\n }\r\n\r\n setCurrentObservation(id, type) {\r\n this.controls.cameraAlignerAdv.setCurrentObservation(id, type);\r\n }\r\n\r\n /** Panoramic/Planar image functions */\r\n\r\n getCurrentCamera() {\r\n return this.cameraList.current;\r\n }\r\n\r\n getCurrentCameraName() {\r\n return this.cameraList.current?.name;\r\n }\r\n\r\n getCurrentCameraIndex() {\r\n return this.cameraList.cameras\r\n .indexOf(this.cameraList.current);\r\n }\r\n\r\n getNextCamera(index) {\r\n let numCameras = this.cameraList.cameras.length;\r\n return (index + 1) % numCameras;\r\n }\r\n\r\n getPreviousCamera(index) {\r\n let numCameras = this.cameraList.cameras.length;\r\n return (index + (numCameras - 1)) % numCameras;\r\n }\r\n\r\n updateCompass() {\r\n this.compass.addRotationCube();\r\n this.compass.addCompassLetters();\r\n }\r\n\r\n updateCompassOffset(offset) {\r\n this.compass.updateOffset(offset);\r\n }\r\n\r\n getCameraFeaturesForCSV = (assetID) => {\r\n return this.minimap.getByCSV(assetID);\r\n };\r\n\r\n getCamerasForCSV = (assetID) => {\r\n return this.cameraList.getByCSV(assetID);\r\n };\r\n\r\n getCameraRowsCSV = (cameras: CameraImage[]) => {\r\n return this.cameraList.getRowsCSV(cameras);\r\n };\r\n\r\n getAllCameras() {\r\n return this.cameraList.cameras;\r\n }\r\n\r\n getCameraFolders(cameras) {\r\n let folderPaths = [];\r\n let previousCSV = null;\r\n\r\n cameras.forEach(camera => {\r\n if (camera.csv === previousCSV) return;\r\n\r\n previousCSV = camera.csv;\r\n const imagePath = camera.path;\r\n folderPaths.push(path.dirname(imagePath));\r\n });\r\n\r\n return folderPaths;\r\n };\r\n\r\n getTagsForCSV = (assetID) => {\r\n return this.tags.getByID(assetID).tags;\r\n };\r\n\r\n getTagRowsCSV = (tags: TagItem[]) => {\r\n return this.tags.getRowsCSV(tags);\r\n };\r\n\r\n getModelStatus(assetID) {\r\n let file = this.cadHandler.getByID(assetID);\r\n\r\n return {\r\n assetPercent: file ? file.percent : 0.0,\r\n assetError: file ? file.error : false,\r\n assetIsLarge: false\r\n };\r\n }\r\n\r\n getCloudStatus(assetID) {\r\n let cloud = this.pointclouds.getByID(assetID);\r\n\r\n return {\r\n assetIsLarge: cloud instanceof GenericPointCloud ? cloud.isLargeFile : false,\r\n assetPercent: cloud instanceof GenericPointCloud ? cloud.percent : 0.0,\r\n assetError: cloud ? cloud.error : false\r\n };\r\n }\r\n\r\n setEmptyProject(state) {\r\n this.isEmpty = state;\r\n\r\n if (!this.isEmpty) return;\r\n this.setInitialZoomFlag(false);\r\n LocalScene.resetSceneShift();\r\n }\r\n\r\n reconcileAssets(assets, savedCameraState: SceneCameraState, savedTagID: string) {\r\n const {\r\n camerasFiles, pointClouds, orthoFiles,\r\n tagFiles, modelFiles, xmlFiles, webSources\r\n } = assets;\r\n\r\n // Tag CSV files\r\n this.tags.reconcile(tagFiles);\r\n\r\n // Model/Linework files\r\n this.cadHandler.reconcile(modelFiles);\r\n\r\n // Web sources\r\n this.webmapHandler.reconcile(webSources);\r\n\r\n // LandXML files\r\n this.measurements.reconcileXMLs(xmlFiles);\r\n\r\n // Orthomosaics\r\n this.orthoList.reconcile(orthoFiles);\r\n\r\n // Point Clouds\r\n const {numClouds, numCloudsRemoved} =\r\n this.pointclouds.reconcile(pointClouds);\r\n\r\n // Image CSV files\r\n const {numCameras, numCamerasAdded, numCamerasRemoved} =\r\n this.cameraList.reconcile(camerasFiles);\r\n\r\n // Try to apply forced tag perspective\r\n if (this.applySavedTagState(savedTagID, false)) return;\r\n\r\n // Try to apply forced scene state\r\n if (this.applySavedSceneState(savedCameraState, false)) return;\r\n\r\n const allCameras = this.cameraList.cameras;\r\n const numCamerasChanged = numCamerasAdded + numCamerasRemoved;\r\n\r\n // All pointclouds have been removed\r\n if ((numClouds === 0) && (numCloudsRemoved > 0) && (numCameras > 0)) {\r\n if (this.cameraList.cameraLoaded) {\r\n // Exit 3d mode if camera is loaded\r\n this.controls.setOrbitValues(false);\r\n } else {\r\n // Load first camera\r\n this.loadImage(allCameras[0].id, {\r\n centerOnImage: false\r\n });\r\n }\r\n }\r\n\r\n // All cameras have been removed, go back to orbit mode\r\n if ((numCameras === 0) && (numCamerasRemoved > 0)) {\r\n this.cameraList.setOrbitCamera();\r\n this.controls.resetSceneView();\r\n this.minimap.setActiveCamera();\r\n this.markers.clearArrowNavigation();\r\n }\r\n\r\n // Load first camera if nothing is loaded\r\n const loadCamera = (numCamerasChanged > 0)\r\n && !this.cameraList.cameraLoaded\r\n && !this.cameraList.newCameraLoading\r\n && (allCameras.length > 0);\r\n\r\n if (loadCamera) {\r\n this.loadImage(allCameras[0].id, {\r\n centerOnImage: false\r\n });\r\n }\r\n }\r\n\r\n preloadBookmarks(bookmarks: Bookmark[]) {\r\n this.cameraList.preloadBookmarks(bookmarks);\r\n }\r\n\r\n async jumpToTag(tagID: string) {\r\n const tag = this.tags.getTagByID(tagID);\r\n if (!tag) return;\r\n\r\n const mapPosition = tag.position.aerial;\r\n this.minimap.jumpToPosition(mapPosition);\r\n\r\n const position = tag.position.array;\r\n if (position.length === 2) {\r\n toast.success(t(\"toast.tag-jump-success\"));\r\n return;\r\n }\r\n\r\n if (tag.sceneState) {\r\n // Apply tag scene state\r\n if (this.applySavedSceneState(tag.sceneState, true)) {\r\n toast.success(t(\"toast.tag-jump-success\"));\r\n return;\r\n }\r\n }\r\n\r\n if (this.hasCameras) {\r\n // Tag has not scene state, so we use the closest camera instead\r\n const lookat = new DataProjectionCoordinate(position);\r\n const closestCameraID = this.cameraList\r\n .closestCameraToPosition(lookat);\r\n\r\n if (closestCameraID) {\r\n await this.loadImage(closestCameraID, {lookat});\r\n toast.success(t(\"toast.tag-jump-success\"));\r\n } else {\r\n toast.warning(t(\"toast.camera-error-position\"));\r\n }\r\n }\r\n }\r\n\r\n setCameraHeights(height) {\r\n this.cameraList.setCameraHeights(height);\r\n }\r\n\r\n setCameraAdjustments(adjustments) {\r\n this.cameraList.setCameraAdjustments(adjustments);\r\n }\r\n\r\n setCameraMatrix(matrix) {\r\n this.cameraList.setCameraMatrix(matrix);\r\n if (this.controls.cameraAlignerAdv.enabled) {\r\n this.controls.cameraAlignerAdv.redrawImageObsMarkers();\r\n }\r\n }\r\n\r\n resetCameraMatrix() {\r\n this.cameraList.resetCameraMatrix();\r\n if (this.controls.cameraAlignerAdv.enabled) {\r\n this.controls.cameraAlignerAdv.redrawImageObsMarkers();\r\n }\r\n }\r\n\r\n setInitialZoomFlag(state) {\r\n this.initialZoomApplied = state;\r\n }\r\n\r\n setInitialStateFlag(state) {\r\n this.initialStateApplied = state;\r\n }\r\n\r\n applySavedSceneState(state, resetInitialFlag: boolean) {\r\n if (resetInitialFlag) {\r\n this.setInitialStateFlag(false);\r\n }\r\n\r\n return state.orbit\r\n ? this.setOrbitState(state)\r\n : this.setCameraState(state);\r\n };\r\n\r\n applySavedTagState(tagID: string, resetInitialFlag: boolean) {\r\n const tag = this.tags.getTagByID(tagID);\r\n if (!tag) return false;\r\n\r\n if (resetInitialFlag) {\r\n this.setInitialStateFlag(false);\r\n }\r\n\r\n return this.setTagState(tagID);\r\n }\r\n\r\n applySavedAerialState(state) {\r\n this.minimap.map.updateSize();\r\n this.minimap.resetView(state);\r\n }\r\n\r\n resetDefaultAerialCamera() {\r\n this.minimap.setActiveCamera();\r\n }\r\n\r\n resetDefaultControlState() {\r\n this.setInitialStateFlag(false);\r\n this.controls.resetSceneView();\r\n }\r\n\r\n removeInteractions() {\r\n const measurements = this.controls.measurements;\r\n if (measurements.enabled) {\r\n measurements.measurementAerialView.removeInteraction();\r\n }\r\n }\r\n\r\n /** Private Methods */\r\n onKeyDown(event) {\r\n if (!this.focused) return;\r\n\r\n event.preventDefault();\r\n this.cameraList.onKeyDown(event);\r\n this.controls.onKeyDown(event);\r\n }\r\n\r\n onKeyUp(event) {\r\n this.controls.onKeyUp(event);\r\n }\r\n\r\n onMouseFocus(event) {\r\n if (event.type === 'mouseover') {\r\n this.focused = true;\r\n } else if (event.type === 'mouseout') {\r\n this.focused = false;\r\n this.clearCoordinates();\r\n }\r\n }\r\n\r\n initEvents() {\r\n this.onMouseFocus = this.onMouseFocus.bind(this);\r\n this.onKeyDown = this.onKeyDown.bind(this);\r\n this.onKeyUp = this.onKeyUp.bind(this);\r\n\r\n // Keep track of our canvas focus\r\n this.containerElement.addEventListener('mouseover', this.onMouseFocus, false);\r\n this.containerElement.addEventListener('mouseout', this.onMouseFocus, false);\r\n\r\n // Keydown doesnt work on canvas\r\n window.addEventListener('keydown', this.onKeyDown, false);\r\n window.addEventListener('keyup', this.onKeyUp, false);\r\n }\r\n\r\n removeEvents() {\r\n this.containerElement.removeEventListener('mouseover', this.onMouseFocus, false);\r\n this.containerElement.removeEventListener('mouseout', this.onMouseFocus, false);\r\n window.removeEventListener('keydown', this.onKeyDown, false);\r\n window.removeEventListener('keyup', this.onKeyUp, false);\r\n }\r\n\r\n updateCoordinates(event) {\r\n if (!this.focused) return;\r\n\r\n this.updateMouseCoords(event);\r\n }\r\n\r\n clearCoordinates() {\r\n this.updateMouseCoords(null);\r\n }\r\n\r\n updateCamera() {\r\n // Update renderutils\r\n this.renderUtils.setCamera(this.camera);\r\n\r\n // Update GPU picker camera\r\n Object.values(this.gpuPickers).forEach(picker => {\r\n picker.setCamera(this.camera);\r\n });\r\n }\r\n\r\n updatePickers() {\r\n Object.keys(this.gpuPickers).forEach(name => {\r\n this.updatePicker(name);\r\n });\r\n }\r\n\r\n updatePicker(name) {\r\n this.gpuPickers[name].needsUpdate = true;\r\n }\r\n\r\n initRenderer() {\r\n this.camera = new PerspectiveCamera(90);\r\n this.camera.near = this.defaultNearPlane;\r\n this.camera.far = this.defaultFarPlane;\r\n this.camera.up = new Vector3(0, 0, 1);\r\n\r\n this.renderer = new WebGLRenderer({\r\n antialias: true,\r\n alpha: true,\r\n logarithmicDepthBuffer: false,\r\n powerPreference: \"high-performance\"\r\n });\r\n\r\n this.renderer.autoClear = false;\r\n this.renderer.setPixelRatio(this.pixelRatio);\r\n this.renderer.clear();\r\n\r\n this.renderUtils = new RenderUtils(\r\n this.renderer,\r\n this.camera,\r\n this.pixelRatio\r\n );\r\n }\r\n\r\n initGpuPickers() {\r\n this.gpuPickers = {\r\n markers: new GPUPicker(this, \"markers\"),\r\n default: new GPUPicker(this, \"default\"),\r\n tags: new GPUPicker(this, \"tags\")\r\n };\r\n\r\n Object.values(this.gpuPickers).forEach(picker => {\r\n this.renderUtils.addTarget(picker.target);\r\n });\r\n }\r\n\r\n initMaterials() {\r\n // Used for rendering panoramic as background\r\n this.imageRenderMaterial = new ImageMaterial();\r\n this.imageRenderTarget = new BasicRenderTarget(\r\n this.width, this.height, true);\r\n\r\n this.renderUtils.addTarget(this.imageRenderTarget);\r\n }\r\n\r\n initResize() {\r\n this.observer = onresize(this.containerElement, () => {\r\n this.handleWindowResize();\r\n });\r\n\r\n this.handleWindowResize();\r\n }\r\n\r\n updateSavedState() {\r\n setCameraState(this.sceneState);\r\n }\r\n\r\n handleWindowResize() {\r\n let aspect = this.width / this.height;\r\n\r\n this.camera.aspect = aspect;\r\n this.camera.updateProjectionMatrix();\r\n\r\n this.renderer.domElement.style.display = \"none\";\r\n this.renderer.setSize(this.width, this.height);\r\n this.compass?.setSize(this.width, this.height);\r\n this.renderer.domElement.style.display = \"block\";\r\n\r\n this.updatePickers();\r\n\r\n // Re-render is required or else the div will flash white\r\n this.render();\r\n }\r\n\r\n updateMaterial(material, values) {\r\n let keys = Object.keys(values);\r\n keys.forEach(key => {\r\n material[key] = values[key];\r\n });\r\n }\r\n\r\n renderPanoramic() {\r\n // Render panoramic image\r\n this.renderUtils.setRenderTarget(this.imageRenderTarget, true);\r\n this.renderer.render(this.cameraList.scene, this.camera);\r\n\r\n // Update material texture with results\r\n this.updateMaterial(this.imageRenderMaterial, {\r\n colorMap: this.imageRenderTarget.texture\r\n });\r\n\r\n // Render to screen and clear depth\r\n this.renderUtils.renderToScreen(this.imageRenderMaterial);\r\n this.renderer.clearDepth();\r\n }\r\n\r\n renderSceneObjects() {\r\n // Render objects at full opacity\r\n this.renderUtils.renderScenes([\r\n this.markers.renderInFront ? null : this.markers.scene,\r\n this.cadHandler.scene\r\n ], 1.0);\r\n\r\n // Render pointcloud with transparency\r\n this.renderUtils.renderScenes([this.pointclouds.scene],\r\n this.pointclouds.transparency, false);\r\n\r\n // Render scene labels (mixed opacity)\r\n let sceneLabels = this.imageLabels.sceneLabels;\r\n this.renderUtils.renderScenes([sceneLabels.opacityScene],\r\n sceneLabels.opacity);\r\n this.renderUtils.renderScenes([sceneLabels.standardScene], 1.0);\r\n\r\n // Items here are rendered on top of everything, so they can always be seen\r\n this.renderUtils.renderScenes([\r\n this.markers.renderInFront ? this.markers.scene : null,\r\n ...this.controls.toolScenes,\r\n this.measurements.scene,\r\n this.tags.scene\r\n ], 1.0);\r\n }\r\n\r\n renderPickerScene() {\r\n this.renderUtils.setRenderTarget(null, true);\r\n\r\n Object.values(this.gpuPickers).forEach(picker => {\r\n // Force gpu picker data\r\n picker.needsUpdate = true;\r\n picker.update();\r\n\r\n // Render picker scene\r\n this.renderer.render(picker.scene, this.camera);\r\n });\r\n }\r\n\r\n updateSceneElements() {\r\n withTiming(\"point clouds\", () => this.pointclouds.update());\r\n withTiming(\"measurements\", () => this.measurements.update(this.changeDetector));\r\n withTiming(\"controls\", () => this.controls.update(this.changeDetector));\r\n withTiming(\"camera list\", () => this.cameraList.update());\r\n withTiming(\"minimap\", () => this.minimap.update(this.changeDetector));\r\n withTiming(\"markers\", () => this.markers.update());\r\n withTiming(\"image labels\", () => this.imageLabels.update(this.changeDetector));\r\n withTiming(\"tags\", () => this.tags.update());\r\n withTiming(\"cad handler\", () => this.cadHandler.update());\r\n }\r\n\r\n updateAnnotations() {\r\n if (!this.enabled) return;\r\n if (this.annotations.length === 0) return;\r\n\r\n const pixelBuffer = 100;\r\n const minCameraDistance = 1.0;\r\n\r\n this.annotations.map(annotation => {\r\n const scenePos = new DataProjectionCoordinate(\r\n annotation.position).toScene();\r\n const distance = scenePos.distanceTo(\r\n this.camera.position);\r\n\r\n return {...annotation, position: scenePos, distance};\r\n }).sort((a, b) => {\r\n return b.distance - a.distance;\r\n }).forEach((annotation, zIndex) => {\r\n const {element, position, distance} = annotation;\r\n\r\n const uv = toScreenPosition(this, position, true);\r\n\r\n const hidden = (distance <= minCameraDistance)\r\n || (uv[0] < -pixelBuffer)\r\n || (uv[0] > this.width + pixelBuffer)\r\n || (uv[1] < -pixelBuffer)\r\n || (uv[1] > this.height + pixelBuffer)\r\n || this.isBehindCamera(position);\r\n\r\n if (hidden) {\r\n element.style.display = \"none\";\r\n return;\r\n }\r\n\r\n element.style.left = `${uv[0]}px`;\r\n element.style.top = `${uv[1]}px`;\r\n element.style['z-index'] = zIndex;\r\n element.style.display = \"\";\r\n });\r\n }\r\n\r\n render() {\r\n this.renderUtils.update();\r\n this.changeDetector.update();\r\n this.updateSceneElements();\r\n\r\n if (this.drawPickerScene) {\r\n this.renderPickerScene();\r\n } else {\r\n this.renderPanoramic();\r\n this.renderSceneObjects();\r\n }\r\n\r\n if (this.changeDetector.changed) {\r\n this.updateAnnotations();\r\n this.updateSavedState();\r\n }\r\n\r\n // Render compass element\r\n this.compass.render(this.showCompassElement,\r\n this.camera, this.orbitState);\r\n\r\n this.multiImageWindow.render();\r\n }\r\n\r\n animate() {\r\n if (!this.enabled) return;\r\n\r\n this.stats.begin();\r\n this.render();\r\n this.stats.end();\r\n\r\n requestAnimationFrame(() => {\r\n this.animate();\r\n });\r\n }\r\n}\r\n\r\nclass StatsPanel {\r\n private stats: Stats;\r\n private viewer: Viewer;\r\n private nodesVisible;\r\n private pointsVisible;\r\n private enabled = isDevMode;\r\n private expanded = false;\r\n\r\n constructor(viewer: Viewer) {\r\n this.viewer = viewer;\r\n this.clear();\r\n this.init();\r\n }\r\n\r\n get indexToShow() {\r\n let childCount = this.stats.dom.children.length;\r\n return [0, childCount-1, childCount-2];\r\n }\r\n\r\n get parentElement() {\r\n return document.getElementById(\"debug-placeholder\");\r\n }\r\n\r\n clear() {\r\n // Remove old stats panels\r\n [...document.getElementsByClassName(\"stats\")].forEach(element => {\r\n element.remove();\r\n });\r\n }\r\n\r\n init() {\r\n if (!this.enabled) return false;\r\n\r\n this.stats = new Stats();\r\n this.stats.dom.classList.add(\"stats\");\r\n this.setStyle();\r\n\r\n this.pointsVisible = this.stats.addPanel(\r\n new Stats.Panel('', '#ff8', '#221'));\r\n\r\n this.nodesVisible = this.stats.addPanel(\r\n new Stats.Panel('NODE', '#f8f', '#212'));\r\n\r\n [...this.stats.dom.children].forEach(element => {\r\n element.style.display = 'none';\r\n element.style.margin = '2px';\r\n });\r\n\r\n this.parentElement.appendChild(this.stats.dom);\r\n\r\n this.drawExpandedState();\r\n this.initEvents();\r\n }\r\n\r\n drawExpandedState() {\r\n // Hide all elements\r\n [...this.stats.dom.children].forEach(element => {\r\n element.style.display = 'none';\r\n });\r\n\r\n this.indexToShow.forEach(index => {\r\n this.stats.dom.children[index].style.display = 'inline-block';\r\n });\r\n\r\n if (this.expanded) {\r\n [...this.stats.dom.children].forEach(element => {\r\n element.style.display = 'inline-block';\r\n });\r\n }\r\n }\r\n\r\n initEvents() {\r\n this.stats.dom.onclick = (event) => {\r\n event.preventDefault();\r\n this.expanded = !this.expanded;\r\n this.drawExpandedState();\r\n };\r\n }\r\n\r\n setStyle() {\r\n this.stats.dom.style.position = \"\";\r\n this.stats.dom.style.top = \"\";\r\n this.stats.dom.style['z-index'] = \"\";\r\n }\r\n\r\n begin() {\r\n if (!this.enabled) return false;\r\n\r\n this.stats.begin();\r\n }\r\n\r\n end() {\r\n if (!this.enabled) return false;\r\n\r\n const {numSceneNodesVisible, numVisiblePoints,\r\n visiblePointsTarget} = this.viewer.pointclouds;\r\n\r\n this.pointsVisible.update(\r\n numVisiblePoints / 1000,\r\n visiblePointsTarget / 1000\r\n );\r\n\r\n this.nodesVisible.update(numSceneNodesVisible, 500);\r\n\r\n this.stats.end();\r\n }\r\n}\r\n\r\n/** @private */\r\nconst withTiming = (name, callback, timeout=10) => {\r\n const timeStart = performance.now();\r\n\r\n callback();\r\n\r\n const timeElapsed = performance.now() - timeStart;\r\n if (timeElapsed < timeout) return;\r\n\r\n console.warn(`Slow update detected: ${name} took ${timeElapsed.toFixed(2)}ms`);\r\n};","import openStreetMaps from './open-street-maps.png';\r\nimport arcgisWorld from './arcgis-world.png';\r\nimport arcgisStreet from './arcgis-street.png';\r\n\r\nconst textures = {\r\n 'open-street-maps': openStreetMaps,\r\n 'arcgis-world': arcgisWorld,\r\n 'arcgis-street': arcgisStreet\r\n};\r\n\r\nexport default textures;\r\n","export default __webpack_public_path__ + \"static/media/open-street-maps.45e253e7.png\";","export default __webpack_public_path__ + \"static/media/arcgis-world.f700fb3f.png\";","export default __webpack_public_path__ + \"static/media/arcgis-street.d6a677f8.png\";","import React, {useMemo, useState} from \"react\";\r\nimport {createStyles, makeStyles, Theme} from \"@material-ui/core/styles\";\r\nimport Popover from '@material-ui/core/Popover';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport FormatListBulletedIcon from '@material-ui/icons/FormatListBulleted';\r\nimport {Avatar} from \"@material-ui/core\";\r\nimport previews from './textures/map-preview';\r\nimport { useViewer, useGlobalSettings } from \"../hooks\";\r\nimport { OpenLayersIcon } from \"../components\";\r\nimport { getGradient } from \"../theme\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n preview: {\r\n width: theme.spacing(4),\r\n height: theme.spacing(4),\r\n marginRight: theme.spacing(2),\r\n borderRadius: theme.spacing(1),\r\n boxShadow: \"2px 2px 3px rgba(0,0,0,0.5)\"\r\n }\r\n }),\r\n);\r\n\r\n/** No base map (custom gradient) */\r\nconst EmptyBasemapIcon = () => {\r\n const classes = useStyles();\r\n const {aerialBackground} = useGlobalSettings();\r\n\r\n const aerialGradient = useMemo(() => {\r\n return getGradient(aerialBackground);\r\n }, [aerialBackground]);\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\n/** Standard layer icon */\r\nconst LayerPreviewIcon = (props) => {\r\n const {layerID} = props;\r\n\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport const LayerSwitcher = (props) => {\r\n const {clearTooltipText} = props;\r\n\r\n const {viewer} = useViewer();\r\n const [anchorEl, setAnchorEl] = useState(null);\r\n\r\n const handleClick = (event: React.MouseEvent) => {\r\n setAnchorEl(event.currentTarget);\r\n clearTooltipText();\r\n };\r\n\r\n const handleClose = () => {\r\n setAnchorEl(null);\r\n };\r\n\r\n const handleSelect = (layerID) => {\r\n const minimap = viewer.minimap;\r\n minimap.setVisibleBasemap(layerID);\r\n };\r\n\r\n const getMenuItems = () => {\r\n const minimap = viewer.minimap;\r\n const layers = minimap.basemapIDs;\r\n const selected = minimap.activeBasemap;\r\n\r\n return layers.map(layer => {\r\n const icon = layer.id === null\r\n ? \r\n : ;\r\n\r\n return {\r\n id: layer.id,\r\n text: layer.text,\r\n icon: icon,\r\n selected: layer.id === selected\r\n };\r\n });\r\n };\r\n\r\n const open = Boolean(anchorEl);\r\n const options = viewer ? getMenuItems() : [];\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n\r\n \r\n {options.map(option => {\r\n return (\r\n {\r\n handleSelect(option.id);\r\n handleClose();\r\n }}\r\n >\r\n {option.icon}\r\n {option.text}\r\n \r\n );\r\n })}\r\n \r\n\r\n \r\n );\r\n};","import React, {useCallback, useEffect, useMemo, useRef, useState} from \"react\";\r\nimport {Viewer} from './js/main';\r\nimport {ContextMenu} from \"../context-menu\";\r\nimport {LayerSwitcher} from \"./layer-switcher\";\r\nimport {createStyles, makeStyles, Theme, useTheme} from \"@material-ui/core/styles\";\r\nimport {\r\n changeMeasureUnits,\r\n selectDataProjection,\r\n selectViewProjection\r\n} from '../redux/projections-slice';\r\nimport {useSelector, useDispatch} from 'react-redux';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport {\r\n getPointCloudAssets,\r\n getOrthoAssets,\r\n selectAllAssets,\r\n getTagAssets,\r\n getModelAssets,\r\n getCameraListFromAssets,\r\n getLandXMLAssets,\r\n getWebMapAssets\r\n} from \"../redux/assets-slice\";\r\nimport {headerHeight, toast} from \"../app\";\r\nimport LocalScene from \"./js/projections\";\r\nimport { throttle, debounce } from 'throttle-debounce';\r\nimport { selectProjectName } from \"../redux/project-slice\";\r\nimport {assetDrawerWidth, assetDrawerHeight} from \"../asset-drawer\";\r\nimport RotateLeftIcon from '@material-ui/icons/RotateLeft';\r\nimport {\r\n changeSwitched,\r\n selectViewerSwitched\r\n} from \"../redux/settings-slice\";\r\nimport {\r\n CursorTooltip,\r\n OpenLayersIcon\r\n} from \"../components\";\r\nimport {isDevMode, isElectronApp} from '../electron-modules';\r\nimport {\r\n changeCameraState,\r\n changeSavedAerialState,\r\n initialAerialState,\r\n initialSceneState,\r\n selectBasicAdjustments,\r\n selectCameraHeight,\r\n selectCameraState,\r\n selectCameraTransform,\r\n selectForcedTagID,\r\n selectSavedAerialState\r\n} from \"../redux/camera-slice\";\r\nimport { isEqual } from 'lodash';\r\nimport {\r\n readTransformFile,\r\n clearWindowHash,\r\n setWindowHash,\r\n getLocalizedProjectName\r\n} from \"../utilities\";\r\nimport proj4 from 'proj4';\r\nimport { transform } from 'ol/proj';\r\nimport {register} from 'ol/proj/proj4';\r\nimport {\r\n getModifiedAerialState,\r\n getModifiedSceneState,\r\n parseURLParams,\r\n roundDigit,\r\n toBoolean\r\n} from \"./js/utilities\";\r\nimport { MathUtils } from \"three\";\r\nimport { sendCustomEvent } from \"../events\";\r\nimport { useUniqueProjectID, useViewer, useGlobalSettings, useBookmarks } from \"../hooks\";\r\nimport { getGradient } from \"../theme\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n parent: {\r\n width: \"100vw\",\r\n height: `calc(100vh - ${headerHeight}px)`,\r\n },\r\n containerLarge: {\r\n width: '100%',\r\n height: `calc(100vh - ${headerHeight}px)`,\r\n position: 'fixed',\r\n \"@media (max-width: 600px) and (min-height: 450px)\": {\r\n /* Mobile devices (portrait) */\r\n marginTop: \"25vh\",\r\n height: `calc(100vh - 25vh - ${headerHeight}px)`,\r\n },\r\n \"@media (max-height: 450px)\": {\r\n /* Mobile devices (landscape) */\r\n marginLeft: \"30vw\",\r\n width: \"calc(100% - 30vw)\"\r\n },\r\n },\r\n offsetLarge: {\r\n marginTop: theme.spacing(0),\r\n marginLeft: assetDrawerWidth,\r\n width: `calc(100% - ${assetDrawerWidth}px)`,\r\n height: `calc(100vh - ${headerHeight}px)`,\r\n },\r\n containerSmall: {\r\n overflow: \"hidden\",\r\n width: `${assetDrawerWidth}px`,\r\n height: `${assetDrawerWidth*0.75}px`,\r\n position: 'fixed',\r\n background: 'white',\r\n margin: '0.5em',\r\n boxShadow: \"0px 0px 1px 1px rgba(0,0,0,0.5)\",\r\n zIndex: 1,\r\n \"@media (max-width: 600px) and (min-height: 450px)\": {\r\n /* Mobile devices (portrait) */\r\n height: `25vh`,\r\n width: \"100%\",\r\n margin: theme.spacing(0),\r\n },\r\n \"@media (max-height: 450px)\": {\r\n /* Mobile devices (landscape) */\r\n width: \"30%\",\r\n height: `calc(100% - ${headerHeight}px)`,\r\n margin: theme.spacing(0)\r\n },\r\n },\r\n offsetSmall: {\r\n width: `${assetDrawerWidth}px`,\r\n height: `${100-assetDrawerHeight}%`,\r\n bottom: theme.spacing(0),\r\n margin: theme.spacing(0),\r\n border: theme.spacing(0),\r\n borderTop: \"1px solid black\",\r\n boxShadow: \"none\",\r\n zIndex: theme.zIndex.modal,\r\n },\r\n compassElement: {\r\n pointerEvents: \"none\",\r\n position: \"absolute\",\r\n top: theme.spacing(0),\r\n right: theme.spacing(0)\r\n }\r\n }),\r\n);\r\n\r\ninterface ViewSwitcherProps {\r\n onClick(): void\r\n}\r\n\r\nconst ViewSwitcher = (props: ViewSwitcherProps) => {\r\n const {onClick} = props;\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\ninterface SceneViewerProps {\r\n assetDrawerState: boolean;\r\n setMeasurements: React.Dispatch;\r\n setCategoryList: React.Dispatch;\r\n setTrainingArea: React.Dispatch;\r\n setMarkupGroups: React.Dispatch;\r\n setMultiImageOpen: React.Dispatch;\r\n setMultiImageState: React.Dispatch;\r\n setPointProfileOpen: React.Dispatch;\r\n setLocalObservations: React.Dispatch;\r\n setAlignerObservations: React.Dispatch;\r\n}\r\n\r\nexport const SceneViewer = (props: SceneViewerProps) => {\r\n const {assetDrawerState, setMeasurements, setCategoryList,\r\n setTrainingArea, setMarkupGroups, setMultiImageOpen,\r\n setMultiImageState, setPointProfileOpen, setLocalObservations,\r\n setAlignerObservations} = props;\r\n\r\n const theme = useTheme();\r\n const {t} = useTranslation();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const uniqueProjectID = useUniqueProjectID();\r\n\r\n const {viewerBackground, aerialBackground, controlType,\r\n orthoOpacity, volumeType, volumeSampleRate} = useGlobalSettings();\r\n\r\n const viewerRef = useRef(null);\r\n const aerialRef = useRef(null);\r\n\r\n const {viewer, setViewer} = useViewer();\r\n const {bookmarks, loadBookmark} = useBookmarks();\r\n const assets = useSelector(selectAllAssets);\r\n\r\n const dataProjection = useSelector(selectDataProjection);\r\n const viewProjection = useSelector(selectViewProjection);\r\n const cameraTransformPath = useSelector(selectCameraTransform);\r\n const projectName = useSelector(selectProjectName);\r\n const viewerSwitched = useSelector(selectViewerSwitched);\r\n const cameraHeight = useSelector(selectCameraHeight);\r\n const basicAdjustments = useSelector(selectBasicAdjustments);\r\n const savedAerialState = useSelector(selectSavedAerialState);\r\n const savedCameraState = useSelector(selectCameraState);\r\n const savedTagID = useSelector(selectForcedTagID);\r\n\r\n const [viewerTooltipLines, setViewerTooltipLines] = useState([]);\r\n const [aerialTooltipLines, setAerialTooltipLines] = useState([]);\r\n const [aerialState, setAerialState] = useState({...initialAerialState});\r\n const [cameraState, setCameraState] = useState({...initialSceneState});\r\n\r\n const viewerGradient = useMemo(() => {\r\n return getGradient(viewerBackground);\r\n }, [viewerBackground]);\r\n\r\n const aerialGradient = useMemo(() => {\r\n return getGradient(aerialBackground);\r\n }, [aerialBackground]);\r\n\r\n const clearTooltipText = useCallback(() => {\r\n clearViewerTooltip();\r\n clearAerialTooltip();\r\n }, []);\r\n\r\n const getClasses = (switched) => {\r\n let mapClasses = [];\r\n let viewerClasses = [];\r\n\r\n const classLarge = [\r\n classes.containerLarge,\r\n assetDrawerState ? classes.offsetLarge : \"\"\r\n ];\r\n const classSmall = [\r\n classes.containerSmall,\r\n assetDrawerState ? classes.offsetSmall : \"\"\r\n ];\r\n\r\n if (switched) {\r\n mapClasses = [...mapClasses, ...classLarge];\r\n viewerClasses = [...viewerClasses, ...classSmall];\r\n } else {\r\n mapClasses = [...mapClasses, ...classSmall];\r\n viewerClasses = [...viewerClasses, ...classLarge];\r\n }\r\n\r\n return {\r\n viewerClasses: viewerClasses.join(\" \"),\r\n mapClasses: mapClasses.join(\" \")\r\n };\r\n };\r\n\r\n const handleSwitched = useCallback(() => {\r\n dispatch(changeSwitched(!viewerSwitched));\r\n }, [viewerSwitched]);\r\n\r\n const clearAllAssets = () => {\r\n // Adding an empty array will clear everything\r\n addAllAssets([]);\r\n };\r\n\r\n const addAllAssets = (assetList) => {\r\n if (!viewer) return;\r\n\r\n const viewerAssets = {\r\n camerasFiles: getCameraListFromAssets(assetList, true),\r\n pointClouds: getPointCloudAssets(assetList),\r\n orthoFiles: getOrthoAssets(assetList),\r\n tagFiles: getTagAssets(assetList),\r\n modelFiles: getModelAssets(assetList),\r\n xmlFiles: getLandXMLAssets(assetList),\r\n webSources: getWebMapAssets(assetList)\r\n };\r\n\r\n viewer.reconcileAssets(viewerAssets, savedCameraState, savedTagID);\r\n viewer.preloadBookmarks(bookmarks);\r\n viewer.setEmptyProject(assetList.length === 0);\r\n };\r\n\r\n const handleHashUpdate = () => {\r\n if (isElectronApp) return;\r\n\r\n const state = {} as any;\r\n\r\n /** Scene state values */\r\n if (cameraState.camera) {\r\n const [theta, phi] = cameraState.angles;\r\n state.cam = cameraState.camera;\r\n state.fov = cameraState.fov;\r\n state.theta = roundDigit(MathUtils.radToDeg(theta), 3);\r\n state.phi = roundDigit(MathUtils.radToDeg(phi), 3);\r\n }\r\n\r\n if (cameraState.orbit) {\r\n const [ox, oy, oz] = cameraState.orbit;\r\n state.ox = roundDigit(ox, 3);\r\n state.oy = roundDigit(oy, 3);\r\n state.oz = roundDigit(oz, 3);\r\n\r\n const [px, py, pz] = cameraState.pivot;\r\n state.px = roundDigit(px, 3);\r\n state.py = roundDigit(py, 3);\r\n state.pz = roundDigit(pz, 3);\r\n }\r\n\r\n /** Aerial state values */\r\n if (aerialState.center) {\r\n const [lon, lat] = transform(aerialState.center, 'EPSG:3857', 'EPSG:4326');\r\n state.lat = roundDigit(lat, 8);\r\n state.lon = roundDigit(lon, 8);\r\n state.zoom = roundDigit(aerialState.zoom, 3);\r\n state.rotation = roundDigit(aerialState.rotation, 3);\r\n state.expanded = viewerSwitched ? 1 : 0;\r\n }\r\n\r\n const hash = Object.entries(state)\r\n .map(([key, value]) => `${key}=${value}`)\r\n .join(\"&\");\r\n\r\n if (cameraState.orbit || cameraState.camera) {\r\n setWindowHash(hash);\r\n } else {\r\n clearWindowHash();\r\n }\r\n };\r\n\r\n const handleHashChange = (url) => {\r\n if (isElectronApp) return;\r\n\r\n const parameters = parseURLParams(url);\r\n if (!parameters) return;\r\n\r\n const modifiedSceneState = getModifiedSceneState(\r\n viewer.sceneState, parameters);\r\n\r\n const modifiedAerialState = getModifiedAerialState(\r\n viewer.aerialState, parameters);\r\n\r\n if (\"expanded\" in parameters) {\r\n const switched = toBoolean(parameters.expanded);\r\n dispatch(changeSwitched(switched));\r\n }\r\n\r\n if (\"bookmark\" in parameters) {\r\n const bookmarkID = parameters.bookmark;\r\n if (loadBookmark(bookmarkID)) return;\r\n }\r\n\r\n if (\"tag\" in parameters) {\r\n const tagID = parameters.tag;\r\n if (viewer.applySavedTagState(tagID, true)) return;\r\n }\r\n\r\n viewer.applySavedAerialState(modifiedAerialState);\r\n viewer.applySavedSceneState(modifiedSceneState, true);\r\n };\r\n\r\n const onMatrixChange = async (filePath: string) => {\r\n const {success, content} = await readTransformFile(filePath);\r\n\r\n if (success) {\r\n viewer?.setCameraMatrix(content);\r\n } else {\r\n toast.error(t(\"toast.correction-matrix-error\"));\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n /** Ran after new project is created or project is loaded */\r\n viewer.applySavedAerialState(savedAerialState);\r\n viewer.resetDefaultAerialCamera();\r\n viewer.resetDefaultControlState();\r\n viewer.setEmptyProject(true);\r\n }, [viewer, uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n handleHashUpdate();\r\n dispatch(changeCameraState(cameraState));\r\n }, [viewer, cameraState]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n handleHashUpdate();\r\n dispatch(changeSavedAerialState(aerialState));\r\n }, [viewer, aerialState]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n const localizedProjectName = getLocalizedProjectName(projectName);\r\n viewer.setProjectName(localizedProjectName);\r\n }, [viewer, projectName]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n clearTooltipText();\r\n if (viewerSwitched) {\r\n viewer.removeInteractions();\r\n }\r\n\r\n handleHashUpdate();\r\n viewer.setExpanded(!viewerSwitched);\r\n }, [viewer, viewerSwitched]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n window.onhashchange = event => {\r\n handleHashChange(event.newURL);\r\n };\r\n }, [viewer, loadBookmark]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.setControlType(controlType);\r\n }, [viewer, controlType]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.setOrthoOpacity(orthoOpacity);\r\n }, [viewer, orthoOpacity]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.updateVolumeType(volumeType);\r\n }, [viewer, volumeType]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.updateVolumeSampleRate(volumeSampleRate);\r\n }, [viewer, volumeSampleRate]);\r\n\r\n const compassClassName = classes.compassElement;\r\n\r\n useEffect(() => {\r\n const viewerProps = {\r\n setMeasurements,\r\n setCategoryList,\r\n setTrainingArea,\r\n setMarkupGroups,\r\n setMultiImageOpen,\r\n setMultiImageState,\r\n compassClassName,\r\n setPointProfileOpen,\r\n setLocalObservations,\r\n setAlignerObservations\r\n };\r\n\r\n let viewerObj = new Viewer(\r\n viewerRef.current,\r\n aerialRef.current,\r\n viewerProps\r\n );\r\n\r\n setViewer(viewerObj);\r\n\r\n if (isDevMode) {\r\n // Temporary global for easy access\r\n window['viewer'] = viewerObj;\r\n window['local'] = LocalScene;\r\n window['toast'] = toast;\r\n }\r\n\r\n return () => {\r\n console.log(\"Destroy viewer\");\r\n viewerObj.destroy();\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n viewer?.setCameraHeights(cameraHeight);\r\n }, [viewer, cameraHeight]);\r\n\r\n useEffect(() => {\r\n viewer?.setCameraAdjustments(basicAdjustments);\r\n }, [viewer, basicAdjustments]);\r\n\r\n useEffect(() => {\r\n // Register current projection for openlayers to use\r\n proj4.defs(dataProjection.name, dataProjection.string);\r\n register(proj4);\r\n\r\n // Clear previous asset data\r\n clearAllAssets();\r\n\r\n if (!viewer) return;\r\n\r\n // Update data projection\r\n viewer.setDataProjection(dataProjection);\r\n\r\n // Allow saved state to be reused\r\n viewer.setInitialStateFlag(false);\r\n\r\n // Refresh values that rely on previously\r\n // calculated scene position\r\n viewer.refreshLocalTransform();\r\n\r\n // All all assets back to the project\r\n addAllAssets(assets);\r\n }, [viewer, dataProjection]);\r\n\r\n useEffect(() => {\r\n viewer?.setViewProjection(viewProjection);\r\n\r\n const units = LocalScene.viewProjectionUnits;\r\n dispatch(changeMeasureUnits(units));\r\n }, [viewer, viewProjection]);\r\n\r\n useEffect(() => {\r\n if (!cameraTransformPath) {\r\n viewer?.resetCameraMatrix();\r\n return;\r\n }\r\n\r\n onMatrixChange(cameraTransformPath);\r\n }, [viewer, cameraTransformPath]);\r\n\r\n useEffect(() => {\r\n addAllAssets(assets);\r\n }, [viewer, assets]);\r\n\r\n /** Viewer tooltip event listener */\r\n useEffect(() => {\r\n const callback = throttle(50, (event) => {\r\n const {lines} = event.detail;\r\n\r\n /** NOTE: React will never return equal for arrays, so lodash is used */\r\n if (isEqual(lines, viewerTooltipLines)) return;\r\n setViewerTooltipLines(lines);\r\n });\r\n\r\n document.addEventListener(\"viewer-tooltip\", callback);\r\n\r\n return () => {\r\n callback.cancel();\r\n document.removeEventListener(\"viewer-tooltip\", callback);\r\n };\r\n }, [viewerTooltipLines]);\r\n\r\n /** Aerial tooltip event listener */\r\n useEffect(() => {\r\n const callback = throttle(50, (event) => {\r\n const {lines} = event.detail;\r\n\r\n /** NOTE: React will never return equal for arrays, so lodash is used */\r\n if (isEqual(lines, aerialTooltipLines)) return;\r\n setAerialTooltipLines(lines);\r\n });\r\n\r\n document.addEventListener(\"aerial-tooltip\", callback);\r\n\r\n return () => {\r\n callback.cancel();\r\n document.removeEventListener(\"aerial-tooltip\", callback);\r\n };\r\n }, [aerialTooltipLines]);\r\n\r\n /** Viewer state event listener */\r\n useEffect(() => {\r\n const callback = debounce(100, (event) => {\r\n const {state} = event.detail;\r\n\r\n /** NOTE: Equality will always fail, so lodash is used */\r\n if (isEqual(state, cameraState)) return;\r\n setCameraState(state);\r\n });\r\n\r\n document.addEventListener(\"viewer-state\", callback);\r\n\r\n return () => {\r\n callback.cancel();\r\n document.removeEventListener(\"viewer-state\", callback);\r\n };\r\n }, [cameraState]);\r\n\r\n /** Aerial state event listener */\r\n useEffect(() => {\r\n const callback = debounce(100, (event) => {\r\n const {state} = event.detail;\r\n\r\n /** NOTE: Equality will always fail, so lodash is used */\r\n if (isEqual(state, aerialState)) return;\r\n setAerialState(state);\r\n });\r\n\r\n document.addEventListener(\"aerial-state\", callback);\r\n\r\n return () => {\r\n callback.cancel();\r\n document.removeEventListener(\"aerial-state\", callback);\r\n };\r\n }, [aerialState]);\r\n\r\n let {viewerClasses, mapClasses} = getClasses(viewerSwitched);\r\n\r\n return (\r\n \r\n
\r\n\r\n {/* Viewer div */}\r\n \r\n \r\n {viewerSwitched && }\r\n\r\n \r\n
\r\n \r\n\r\n {/* Map div */}\r\n \r\n \r\n {!viewerSwitched && }\r\n\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\n\r\nexport const clearAerialTooltip = () => setAerialTooltip([]);\r\nexport const clearViewerTooltip = () => setViewerTooltip([]);\r\n\r\nexport const setAerialTooltip = (lines: string[]) => {\r\n sendCustomEvent(\"aerial-tooltip\", {lines});\r\n};\r\n\r\nexport const setViewerTooltip = (lines: string[]) => {\r\n sendCustomEvent(\"viewer-tooltip\", {lines});\r\n};\r\n\r\nexport const setAerialState = (state) => {\r\n sendCustomEvent(\"aerial-state\", {state});\r\n};\r\n\r\nexport const setCameraState = (state) => {\r\n sendCustomEvent(\"viewer-state\", {state});\r\n};","import { CustomMouseEvent, PanoControls } from '../controls';\r\nimport { DataProjectionCoordinate, SceneCoordinate } from '../projections';\r\nimport { ChangeDetector, getPointScale } from '../utilities';\r\nimport {\r\n Scene,\r\n SphereGeometry,\r\n MeshBasicMaterial,\r\n Vector3,\r\n AmbientLight\r\n} from 'three';\r\nimport { Viewer } from '../main';\r\nimport { clearViewerTooltip, setViewerTooltip } from '../../viewer';\r\nimport { RayCaster } from '../ray-caster';\r\nimport { t } from '../../../localization';\r\nimport { flashColor, imageObsColor, ImageObservation, pointObsColor, PointObservation } from '.';\r\nimport { nanoid } from '@reduxjs/toolkit';\r\nimport { toast } from '../../../app';\r\n\r\nexport interface AlignerObservation {\r\n id: string,\r\n imageObs: Vector3,\r\n imageMesh: ImageObservation,\r\n imageSelected: boolean,\r\n pointObs: DataProjectionCoordinate,\r\n pointMesh: PointObservation,\r\n pointSelected: boolean,\r\n imageIdentifier: string,\r\n name: string,\r\n pose: any[],\r\n error: number\r\n}\r\n\r\nexport class CameraAlignerAdv {\r\n private controls: PanoControls;\r\n private setObservations: Function;\r\n public enabled = false;\r\n public scene: Scene;\r\n private observations = [] as AlignerObservation[];\r\n private imageObsInterval = null;\r\n private pointObsInterval = null;\r\n private sphereGeometry = new SphereGeometry(0.05, 20, 20);\r\n\r\n constructor(controls: PanoControls, props) {\r\n const {setAlignerObservations} = props;\r\n\r\n this.controls = controls;\r\n this.setObservations = setAlignerObservations;\r\n\r\n this.initScene();\r\n }\r\n\r\n get viewer(): Viewer {\r\n return this.controls.viewer;\r\n }\r\n\r\n get cameraList() {\r\n return this.viewer.cameraList;\r\n }\r\n\r\n get selecting() {\r\n return !!this.selected;\r\n }\r\n\r\n get selected() {\r\n return this.observations.find(x => x.imageSelected || x.pointSelected);\r\n }\r\n\r\n get currentRow() {\r\n return this.observations.indexOf(this.selected);\r\n }\r\n\r\n get observationType() {\r\n const selected = this.selected;\r\n if (!selected) return null;\r\n return selected.imageSelected ? \"image\" : \"point\";\r\n }\r\n\r\n get moreTooltip() {\r\n return [\r\n t(`data-aligner-adv.click-to-add-${this.observationType}`),\r\n t(\"data-aligner-adv.right-click-to-cancel\")\r\n ];\r\n }\r\n\r\n initScene() {\r\n this.scene = new Scene();\r\n this.scene.add(new AmbientLight(0xFFFFFF));\r\n }\r\n\r\n setState(state) {\r\n this.resetObservations();\r\n this.enabled = state;\r\n }\r\n\r\n refreshObservationList() {\r\n this.setObservations([...this.observations]);\r\n }\r\n\r\n resetObservations() {\r\n for (let observation of this.observations) {\r\n this.scene.remove(observation.imageMesh);\r\n this.scene.remove(observation.pointMesh);\r\n }\r\n\r\n this.observations = [];\r\n this.refreshObservationList();\r\n }\r\n\r\n reset() {\r\n }\r\n\r\n addNewObservations(numObservations) {\r\n for (let i=0; i x.id === id);\r\n }\r\n\r\n removeByID(id) {\r\n const observation = this.getByID(id);\r\n if (!observation) return;\r\n\r\n this.observations = this.observations.filter(x => x.id !== id);\r\n this.scene.remove(observation.imageMesh);\r\n this.scene.remove(observation.pointMesh);\r\n this.cancelAlignment();\r\n }\r\n\r\n clickImage(event) {\r\n let currentCamera = this.cameraList.current;\r\n\r\n // Get direction vector\r\n if (currentCamera != null && !this.viewer.orbitState) {\r\n let raycaster = new RayCaster(this.viewer, event);\r\n let direction = raycaster.vectorFromEvent(event);\r\n let position = currentCamera.position.value;\r\n let rotation = currentCamera.rotation.array;\r\n\r\n // Allows for observations to overwrite each other\r\n this.scene.remove(this.observations[this.currentRow].imageMesh);\r\n\r\n toast.success(t('data-aligner-adv.new_point_observation_added'));\r\n this.observations[this.currentRow].name = currentCamera.name;\r\n this.observations[this.currentRow].imageIdentifier = currentCamera.id;\r\n this.observations[this.currentRow].imageObs = direction;\r\n this.observations[this.currentRow].pose = [\r\n currentCamera.path,\r\n position.x, position.y, position.z,\r\n rotation[0], rotation[1], rotation[2]\r\n ];\r\n\r\n let imageDir = direction.clone().add(this.viewer.camera.position);\r\n\r\n this.addImageObservationMesh(imageDir);\r\n clearViewerTooltip();\r\n }\r\n }\r\n\r\n clickScene(event) {\r\n let {coordinate} = this.controls.getPickerResults(event);\r\n if (!coordinate) {\r\n console.warn(\"Cloud position: no result\");\r\n return;\r\n }\r\n\r\n toast.success(t('data-aligner-adv.new_point_observation_added'));\r\n let position = new SceneCoordinate(coordinate).toDataProjection();\r\n this.scene.remove(this.observations[this.currentRow].pointMesh);\r\n this.observations[this.currentRow].pointObs = position;\r\n\r\n this.addPointObservationMesh(coordinate);\r\n clearViewerTooltip();\r\n }\r\n\r\n onMouseUp(event: CustomMouseEvent): boolean {\r\n if (event.mouseMoved || !this.enabled) {\r\n return false;\r\n }\r\n\r\n if (event.isLeftClick) {\r\n // Get direction vector\r\n this.mouseClick(event);\r\n return;\r\n }\r\n\r\n if (event.isRightClick) {\r\n if (this.selecting) {\r\n // Cancel observation selection\r\n this.cancelAlignment();\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n onMouseMove() {\r\n const type = this.observationType;\r\n\r\n if ((type === \"point\") || (type === \"image\")) {\r\n setViewerTooltip(this.moreTooltip);\r\n } else {\r\n clearViewerTooltip();\r\n }\r\n }\r\n\r\n mouseClick(event) {\r\n let observationToAdd = this.observationType;\r\n\r\n if (observationToAdd === \"point\") {\r\n this.clickScene(event);\r\n } else if (observationToAdd === \"image\") {\r\n this.clickImage(event);\r\n } else {\r\n return;\r\n }\r\n\r\n this.refreshObservationList();\r\n }\r\n\r\n cancelAlignment() {\r\n clearViewerTooltip();\r\n\r\n this.resetSelectedState();\r\n this.updateAllMeshes();\r\n this.refreshObservationList();\r\n }\r\n\r\n addPointObservationMesh(position) {\r\n let sphereMaterial = new MeshBasicMaterial({color: pointObsColor});\r\n let mesh = new PointObservation(this.sphereGeometry, sphereMaterial);\r\n\r\n this.scene.add(mesh);\r\n this.observations[this.currentRow].pointMesh = mesh;\r\n this.observations[this.currentRow].pointSelected = false;\r\n\r\n mesh.position.copy(position);\r\n this.setPointScale(mesh);\r\n }\r\n\r\n addImageObservationMesh(position) {\r\n let sphereMaterial = new MeshBasicMaterial({color: imageObsColor});\r\n let mesh = new ImageObservation(this.sphereGeometry, sphereMaterial);\r\n\r\n this.scene.add(mesh);\r\n this.observations[this.currentRow].imageMesh = mesh;\r\n this.observations[this.currentRow].imageSelected = false;\r\n\r\n // update position (new or existing mesh)\r\n mesh.position.copy(position);\r\n this.setPointScale(mesh);\r\n }\r\n\r\n /** @private */\r\n flashObservation(mesh, defaultColor) {\r\n let numberOfFlashes = 0;\r\n const maxNumberOfFlashes = 6;\r\n const timerDelay = 500;\r\n\r\n const interval = setInterval(() => {\r\n if (numberOfFlashes % 2 === 0) {\r\n mesh.material.color.setHex(flashColor);\r\n } else {\r\n mesh.material.color.setHex(defaultColor);\r\n }\r\n\r\n numberOfFlashes++;\r\n\r\n if (numberOfFlashes === maxNumberOfFlashes) {\r\n mesh.material.color.setHex(defaultColor);\r\n clearInterval(interval);\r\n }\r\n }, timerDelay);\r\n\r\n return interval;\r\n };\r\n\r\n clearFlashIntervals() {\r\n if (this.imageObsInterval) {\r\n clearInterval(this.imageObsInterval);\r\n this.imageObsInterval = null;\r\n }\r\n\r\n if (this.pointObsInterval) {\r\n clearInterval(this.pointObsInterval);\r\n this.pointObsInterval = null;\r\n }\r\n\r\n // Reset the color for all observations\r\n this.observations.forEach(observation => {\r\n if (observation.imageMesh) {\r\n let material = observation.imageMesh.material as any;\r\n material.color.setHex(imageObsColor);\r\n }\r\n\r\n if (observation.pointMesh) {\r\n let material = observation.pointMesh.material as any;\r\n material.color.setHex(pointObsColor);\r\n }\r\n });\r\n }\r\n\r\n flashObservations(id) {\r\n this.clearFlashIntervals();\r\n\r\n const observation = this.getByID(id);\r\n if (!observation) return;\r\n\r\n if (observation.imageMesh) {\r\n this.imageObsInterval = this.flashObservation(\r\n observation.imageMesh, imageObsColor);\r\n }\r\n\r\n if (observation.pointMesh) {\r\n this.pointObsInterval = this.flashObservation(\r\n observation.pointMesh, pointObsColor);\r\n }\r\n };\r\n\r\n setCurrentObservation(id, type) {\r\n const observation = this.getByID(id);\r\n if (!observation) return;\r\n\r\n this.resetSelectedState();\r\n\r\n if (type === \"image\") {\r\n observation.imageSelected = true;\r\n } else if (type === \"point\") {\r\n observation.pointSelected = true;\r\n }\r\n\r\n this.updateAllMeshes();\r\n this.refreshObservationList();\r\n }\r\n\r\n resetSelectedState() {\r\n this.observations.forEach(obs => {\r\n obs.imageSelected = false;\r\n obs.pointSelected= false;\r\n });\r\n }\r\n\r\n redrawImageObsMarkers() {\r\n if (this.observations === null || this.observations.length === 0) {\r\n return;\r\n }\r\n\r\n for (let i=0; i {\r\n // Resize point observations and set visibility\r\n if (obs.pointMesh) {\r\n this.setPointScale(obs.pointMesh);\r\n obs.pointMesh.visible = !obs.pointSelected;\r\n }\r\n\r\n // Resize image ibservations and set visibility\r\n if (obs.imageMesh && this.cameraList.current){\r\n const currentID = this.cameraList.current.id;\r\n const matchingCamera = obs.imageIdentifier === currentID;\r\n\r\n if (matchingCamera && !this.viewer.orbitState) {\r\n this.setPointScale(obs.imageMesh);\r\n obs.imageMesh.visible = !obs.imageSelected;\r\n } else {\r\n obs.imageMesh.visible = false;\r\n }\r\n }\r\n });\r\n }\r\n\r\n update(changeDetector: ChangeDetector) {\r\n if (!this.enabled || !changeDetector.changed) return;\r\n\r\n this.updateAllMeshes();\r\n }\r\n}","import { CameraImage } from \"../cameras\";\r\nimport { PanoControls } from \"../controls\";\r\n\r\nexport class CameraAlignerBasic {\r\n public enabled = false;\r\n private increment = 0.1;\r\n public cameraAngles = [0, 0, 0];\r\n private controls: PanoControls\r\n\r\n constructor(controls: PanoControls) {\r\n this.controls = controls;\r\n this.reset();\r\n }\r\n\r\n get currentCamera() : CameraImage {\r\n return this.controls.cameraList?.current;\r\n }\r\n\r\n setState(state) {\r\n this.enabled = state;\r\n }\r\n\r\n reset(values = [0,0,0]) {\r\n this.cameraAngles = [...values];\r\n this.updateAlignment();\r\n }\r\n\r\n onKeyDown(event) {\r\n if (!this.enabled) return false;\r\n\r\n let increment = event.altKey\r\n ? this.increment*10\r\n : this.increment;\r\n\r\n if (event.code === \"Numpad7\") {\r\n this.cameraAngles[0] -= increment;\r\n } else if (event.code === \"Numpad9\") {\r\n this.cameraAngles[0] += increment;\r\n } else if (event.code === \"Numpad4\") {\r\n this.cameraAngles[1] -= increment;\r\n } else if (event.code === \"Numpad6\") {\r\n this.cameraAngles[1] += increment;\r\n } else if (event.code === \"Numpad1\") {\r\n this.cameraAngles[2] -= increment;\r\n } else if (event.code === \"Numpad3\") {\r\n this.cameraAngles[2] += increment;\r\n } else {\r\n return;\r\n }\r\n\r\n this.updateAlignment();\r\n }\r\n\r\n updateAlignment() {\r\n this.currentCamera?.applyTempRotation(this.cameraAngles);\r\n }\r\n}","import { Mesh } from \"three\";\r\n\r\nexport const pointObsColor = 0xE6E600;\r\nexport const aerialObsColor = 0x62B7B0;\r\nexport const imageObsColor = 0x9900CC;\r\nexport const flashColor = 0xFFFFFF;\r\n\r\nexport class ImageObservation extends Mesh {\r\n constructor(geometry, material) {\r\n super(geometry, material);\r\n }\r\n}\r\n\r\nexport class PointObservation extends Mesh {\r\n constructor(geometry, material) {\r\n super(geometry, material);\r\n }\r\n}\r\n","import React, {useRef, useCallback, useEffect, useState, memo} from 'react';\r\nimport { useSelector, useDispatch } from 'react-redux';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport InfoIcon from '@material-ui/icons/Info';\r\nimport WarningIcon from '@material-ui/icons/Warning';\r\nimport PriorityHighIcon from '@material-ui/icons/PriorityHigh';\r\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\r\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\r\nimport HistoryIcon from '@material-ui/icons/History';\r\nimport AddToPhotosIcon from '@material-ui/icons/AddToPhotos';\r\nimport DeleteIcon from '@material-ui/icons/Delete';\r\nimport ZoomInIcon from '@material-ui/icons/ZoomIn';\r\nimport SortIcon from '@material-ui/icons/Sort';\r\nimport SortByAlphaIcon from '@material-ui/icons/SortByAlpha';\r\nimport ImportExportIcon from '@material-ui/icons/ImportExport';\r\nimport TextFieldsIcon from '@material-ui/icons/TextFields';\r\nimport {\r\n Box,\r\n Card,\r\n CardHeader,\r\n Checkbox,\r\n CircularProgress,\r\n Dialog,\r\n DialogContent,\r\n FormHelperText,\r\n Grid,\r\n InputLabel,\r\n List,\r\n ListItem,\r\n MenuItem,\r\n TextField,\r\n Typography\r\n} from '@material-ui/core';\r\nimport {\r\n LinearProgressWithLabel,\r\n EnhancedIconButton,\r\n ProgressDialog,\r\n TextDialog,\r\n DraggableDialog,\r\n PromptDialog,\r\n DenseDivider,\r\n IconToolBar,\r\n SlimScrollbar,\r\n ToolBarButton,\r\n ArrowTooltip,\r\n EnhancedTable,\r\n DropdownWithLabel,\r\n NumberFieldWithLabel,\r\n CheckboxWithLabel,\r\n FileWithLabel,\r\n FolderWithLabel,\r\n NumberField,\r\n DraggableList,\r\n TextWithLabel\r\n} from '../components';\r\nimport { createStyles, makeStyles, Theme, useTheme } from \"@material-ui/core/styles\";\r\nimport {\r\n dialog,\r\n ipcRenderer,\r\n fs,\r\n getTemporaryFile,\r\n shell,\r\n tempDirectoryPath,\r\n registerEvent,\r\n fse\r\n} from '../electron-modules';\r\nimport { changeSwitched } from \"../redux/settings-slice\";\r\nimport slash from 'slash';\r\nimport { PythonExecutable } from '../executable';\r\nimport LocalScene from '../viewer/js/projections';\r\nimport { FixedSizeList } from \"react-window\";\r\nimport path from 'path';\r\nimport {\r\n addAsset,\r\n AssetType,\r\n deleteAsset,\r\n getCameraFileAssets,\r\n getPointCloudAssets,\r\n selectAllAssets\r\n} from '../redux/assets-slice';\r\nimport { asyncTimeout, useAssetTools } from '../utilities';\r\nimport DialogTitle from '@material-ui/core/DialogTitle/DialogTitle';\r\nimport Button from '@material-ui/core/Button/Button';\r\nimport DialogActions from '@material-ui/core/DialogActions/DialogActions';\r\nimport Select from '@material-ui/core/Select/Select';\r\nimport { nanoid } from '@reduxjs/toolkit';\r\nimport { throttle } from 'throttle-debounce';\r\nimport { selectProjectName } from '../redux/project-slice';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport { DropResult } from 'react-beautiful-dnd';\r\nimport { toast } from '../app';\r\nimport clsx from 'clsx';\r\nimport {\r\n ImageLabel,\r\n LabelCategory,\r\n textToColor,\r\n getClassFromAlias,\r\n getNameFromClass,\r\n TrainingAreaLabel\r\n} from '../viewer/js/labelling';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {\r\n drawingFilter,\r\n DXFModelFilter,\r\n getCombinedExtension,\r\n labelFilter,\r\n modelFilter,\r\n SHPModelFilter\r\n} from '../file-extensions';\r\nimport {\r\n useDialog,\r\n useUniqueProjectID,\r\n useViewer,\r\n useActiveTool\r\n} from '../hooks';\r\nimport {selectDefaultFolder} from \"../redux/folders-slice\";\r\nimport { useTableState } from '../hooks/use-table-state';\r\nimport { writeToString } from 'fast-csv';\r\n\r\nenum LabelImportType {\r\n Ignore=\"__ignore\",\r\n Default=\"__default\"\r\n}\r\n\r\nconst labelHeight = 53;\r\nconst geometryLimit = 1000;\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n titleClose: {\r\n position: 'absolute',\r\n right: theme.spacing(0),\r\n color: theme.palette.grey[500],\r\n },\r\n titleInfo: {\r\n position: 'absolute',\r\n right: theme.spacing(4),\r\n marginTop: theme.spacing(0),\r\n color: theme.palette.grey[500],\r\n },\r\n titleMin: {\r\n position: 'absolute',\r\n right: theme.spacing(4),\r\n marginTop: theme.spacing(-1),\r\n color: theme.palette.grey[500],\r\n },\r\n userWarning: {\r\n padding: theme.spacing(3)\r\n },\r\n marginTop: {\r\n marginTop: theme.spacing(2)\r\n },\r\n box: {\r\n padding: theme.spacing(4)\r\n },\r\n formControl: {\r\n width: '100%'\r\n },\r\n listContent: {\r\n margin: theme.spacing(0),\r\n padding: theme.spacing(0)\r\n },\r\n categoryName: {\r\n flex: 1\r\n },\r\n success: {\r\n color: theme.palette.success.main\r\n },\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n error: {\r\n color: theme.palette.error.main\r\n },\r\n info: {\r\n color: theme.palette.info.main\r\n },\r\n folderList: {\r\n padding: \"0px\",\r\n overflow: \"auto\",\r\n flex: 1,\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n headerTitle: {\r\n fontWeight: \"bold\",\r\n cursor: \"pointer\"\r\n },\r\n cardHeader: {\r\n padding: theme.spacing(1)\r\n },\r\n cardButtons: {\r\n marginTop: 0,\r\n alignSelf: \"center\"\r\n },\r\n labelFixedHeight: {\r\n height: `${labelHeight}px`\r\n },\r\n labelParent: {\r\n flex: 1,\r\n userSelect: \"none\",\r\n display: \"flex\",\r\n flexDirection: \"column\"\r\n },\r\n labelTitleWarning: {\r\n color: theme.palette.warning.main\r\n },\r\n labelTitleError: {\r\n color: theme.palette.error.main\r\n },\r\n classificationText: {\r\n fontSize: \"0.6rem\"\r\n },\r\n card: {\r\n margin: theme.spacing(2),\r\n marginTop: theme.spacing(0),\r\n padding: theme.spacing(1),\r\n userSelect: \"none\"\r\n },\r\n progressToolbar: {\r\n display: \"flex\",\r\n marginLeft: \"12px\",\r\n marginRight: \"12px\"\r\n },\r\n toolbarLinear: {\r\n margin: \"auto 12px\"\r\n },\r\n toolbarProgressCenter: {\r\n top: \"50%\",\r\n height: \"6px\",\r\n marginTop: \"-3px\"\r\n },\r\n downloadMargin: {\r\n marginTop: theme.spacing(1)\r\n },\r\n downloadResourceDialog: {\r\n paddingTop: theme.spacing(2.5),\r\n paddingBottom: theme.spacing(2.5),\r\n paddingLeft: theme.spacing(4),\r\n paddingRight: theme.spacing(4)\r\n },\r\n mixedDataWarning: {\r\n padding: theme.spacing(2.0),\r\n color: theme.palette.warning.main\r\n },\r\n tableDropdown: {\r\n fontSize: \"0.875rem\",\r\n width: \"100%\"\r\n },\r\n checkBoxWithLabel: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n },\r\n toggleOptionFlex: {\r\n flex: 1,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n toggleOptionCheckbox: {\r\n paddingTop: theme.spacing(0.5),\r\n paddingBottom: theme.spacing(0.5)\r\n },\r\n mappingMargin: {\r\n marginBottom: \"3px\"\r\n },\r\n checkBoxParent: {\r\n paddingLeft: theme.spacing(3),\r\n paddingRight: theme.spacing(3)\r\n },\r\n paddingBottom: {\r\n paddingBottom: theme.spacing(3),\r\n display: \"block\"\r\n },\r\n captionPadding: {\r\n paddingBottom: theme.spacing(1),\r\n paddingTop: theme.spacing(0.5),\r\n display: \"block\"\r\n },\r\n paddingBottomAndTop: {\r\n paddingBottom: theme.spacing(3),\r\n paddingTop: theme.spacing(3),\r\n display: \"block\"\r\n },\r\n paddingBottomAndTopMinimal: {\r\n paddingBottom: theme.spacing(1),\r\n paddingTop: theme.spacing(1),\r\n display: \"block\"\r\n },\r\n fileButtonDiv: {\r\n paddingTop: theme.spacing(1),\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n outputFolder: {\r\n paddingBottom: theme.spacing(4)\r\n },\r\n selectDivider: {\r\n margin: theme.spacing(0.5),\r\n opacity: 0.2\r\n },\r\n infoLabel: {\r\n fontWeight: \"bold\",\r\n paddingRight: theme.spacing(0.5)\r\n },\r\n flexPaper: {\r\n flex: 1,\r\n margin: 16,\r\n minWidth: 350\r\n },\r\n }),\r\n);\r\n\r\nconst Label = (props) => {\r\n const label = props.label as ImageLabel;\r\n const {index, isScrolling, style, labelName, isSceneLabel} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [getInfo, setGetInfo] = useState(false);\r\n\r\n const selected = label.selected;\r\n const completed = label.completed;\r\n const isTrainingLabel = label instanceof TrainingAreaLabel;\r\n\r\n const scoreClass = () => {\r\n let scoreValidity = classes.success;\r\n if (label.score < 0.9) {\r\n scoreValidity = classes.warning;\r\n }\r\n if (label.score < 0.7) {\r\n scoreValidity = classes.error;\r\n }\r\n return scoreValidity;\r\n };\r\n\r\n const getInfoLabel = () => {\r\n setGetInfo(true);\r\n };\r\n\r\n const deleteLabel = (id) => {\r\n viewer?.deleteLabel(id);\r\n };\r\n\r\n const zoomToLabel = (id) => {\r\n viewer?.zoomToLabel(id);\r\n };\r\n\r\n const unHighlight = (id) => {\r\n viewer?.unHighlight(id);\r\n };\r\n\r\n return (\r\n \r\n
\r\n {/** Label number */}\r\n \r\n {`${labelName} #${index + 1} (${label.numPoints})`}\r\n \r\n\r\n {/** Classification score */}\r\n {!isTrainingLabel && (
\r\n \r\n {t('labels.classification-score')}: \r\n \r\n\r\n \r\n {label.score.toFixed(2)}\r\n \r\n
)}\r\n
\r\n\r\n {isScrolling && (\r\n \r\n Loading...\r\n \r\n )}\r\n\r\n {!isScrolling && (\r\n\r\n {/*Classification Score*/}\r\n \r\n\r\n \r\n\r\n {/* Warning on Label */}\r\n \r\n \r\n \r\n\r\n {/* Highlighted Label */}\r\n {\r\n unHighlight(label.id);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Info on Label */}\r\n getInfoLabel()}\r\n >\r\n \r\n \r\n\r\n {/* Zoom to extent */}\r\n {\r\n zoomToLabel(label.id);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Delete Label */}\r\n {\r\n deleteLabel(label.id);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Label Info */}\r\n \r\n )}\r\n
\r\n );\r\n};\r\n\r\nconst CategoryContent = (props) => {\r\n const category = props.category as LabelCategory;\r\n const {labelName, idx, isSceneLabel} = props;\r\n\r\n const classes = useStyles();\r\n const listRef = useRef(null);\r\n\r\n const scrollingDivLength = category.labels.length;\r\n const useScrollingDiv = scrollingDivLength > 5;\r\n const scrollingDivHeight = Math.min(scrollingDivLength*labelHeight, 250);\r\n\r\n useEffect(() => {\r\n if (listRef) {\r\n if (listRef.current){\r\n listRef.current.scrollToItem(idx);\r\n }\r\n }\r\n }, [idx, listRef]);\r\n\r\n return (\r\n {/* Use normal list for small labels list */}\r\n {!useScrollingDiv && (\r\n \r\n {category.labels.map((label, index) =>\r\n \r\n )}\r\n \r\n )}\r\n\r\n {/* Use scrolling list for large amounts of labels */}\r\n {useScrollingDiv && (\r\n \r\n {({index, isScrolling, style}) => (\r\n \r\n )}\r\n \r\n )}\r\n );\r\n};\r\n\r\nconst CategoryExpand = (props) => {\r\n const {setExpanded, expanded} = props;\r\n\r\n const {t} = useTranslation();\r\n\r\n return ( {\r\n event.stopPropagation();\r\n setExpanded(!expanded);\r\n }}\r\n >\r\n {expanded && }\r\n {!expanded && }\r\n );\r\n};\r\n\r\nconst TrainingArea = (props) => {\r\n const {trainingArea} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [expanded, setExpanded] = useState(false);\r\n const [deletePrompt, setDeletePrompt] = useState(false);\r\n\r\n const clearTrainingArea = () => {\r\n // Delete all areas\r\n [...trainingArea.labels].forEach(label => {\r\n viewer?.deleteLabel(label.id);\r\n });\r\n\r\n setDeletePrompt(false);\r\n };\r\n\r\n const addThenExpand = () => {\r\n addLabel();\r\n setExpanded(true);\r\n };\r\n\r\n const addLabel = () => {\r\n viewer?.addTrainingAreaLabel();\r\n };\r\n\r\n const addNewLabelDisabled = viewer?.labelSelected();\r\n const addNewlabelTooltip = t('labels.add-new-training-area');\r\n\r\n return (\r\n \r\n \r\n {/* Header */}\r\n \r\n {/* Expand/collapse areas */}\r\n \r\n\r\n {/* Add new area label */}\r\n {\r\n addThenExpand();\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Delete Training Area */}\r\n {\r\n setDeletePrompt(true);\r\n }}\r\n >\r\n \r\n \r\n\r\n \r\n }\r\n disableTypography={true}\r\n title={\r\n \r\n {t('labels.training-areas')}\r\n \r\n }\r\n subheader={\r\n \r\n {t('labels.total-areas', {\r\n count: trainingArea.labels.length\r\n })}\r\n \r\n }\r\n />\r\n\r\n {/* Expandable content */}\r\n {expanded && ()}\r\n \r\n\r\n setDeletePrompt(false)}\r\n onSubmit={clearTrainingArea}\r\n title={t('labels.clear-training-areas')}\r\n prompt={t('labels.do-you-want-to-remove-all-training-areas')}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n \r\n );\r\n};\r\n\r\nconst Category = (props) => {\r\n const category = props.category as LabelCategory;\r\n const {isValidCategory, labelDisabled,\r\n runTextDetection, isSceneLabel} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [expanded, setExpanded] = useState(false);\r\n const [editPrompt, setEditPrompt] = useState(false);\r\n const [deletePrompt, setDeletePrompt] = useState(false);\r\n const [sortPrompt, setSortPrompt] = useState(false);\r\n const [textDetectPrompt, setTextDetectPrompt] = useState(false);\r\n const [sorted, setSorted] = useState(false);\r\n\r\n const idx = viewer?.getIdxInList(category);\r\n\r\n const formatName = (name) => {\r\n const maxLength = 22;\r\n\r\n return (name.length > maxLength)\r\n ? name.substr(0, maxLength - 1) + \"...\"\r\n : name;\r\n };\r\n\r\n const addThenExpand = (categoryID) => {\r\n addLabel(categoryID);\r\n setExpanded(true);\r\n };\r\n\r\n const addLabel = (id) => {\r\n viewer?.addLabel(id);\r\n };\r\n\r\n const handleDeleteCategory = () => {\r\n viewer?.deleteCategory(category.id);\r\n setDeletePrompt(false);\r\n };\r\n\r\n const handleEditCategory = (name) => {\r\n if (!isValidCategory(name)) {\r\n return;\r\n }\r\n\r\n viewer?.editCategoryName(category.id, name);\r\n setEditPrompt(false);\r\n };\r\n\r\n const runSort = (scoreValue, sortType) => {\r\n viewer?.sortCategory(category, scoreValue, sortType);\r\n setSorted(true);\r\n };\r\n\r\n const undoSort = () => {\r\n viewer?.undoSort(category);\r\n setSorted(false);\r\n };\r\n\r\n useEffect(() => {\r\n if (idx >= 0) {\r\n setExpanded(true);\r\n }\r\n }, [idx]);\r\n\r\n\r\n const addNewLabelDisabled = viewer?.labelSelected();\r\n const addNewlabelTooltip = t('labels.add-new-label', {\r\n type: viewer.currentCategory()\r\n });\r\n\r\n const numLabelsTooltip = t('labels.click-to-undo-sort', {\r\n count: category.numLabelsAll\r\n });\r\n\r\n const color = textToColor(category.name);\r\n\r\n return (\r\n \r\n \r\n {/* Header */}\r\n \r\n {/* Expand/collapse labels */}\r\n \r\n\r\n {/* Detect Text in Class */}\r\n {\r\n setTextDetectPrompt(true);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Sort by Scores */}\r\n {\r\n setSortPrompt(true);\r\n }}\r\n >\r\n \r\n \r\n\r\n\r\n {/* Edit category name */}\r\n {\r\n setEditPrompt(true);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Add new label */}\r\n {\r\n addThenExpand(category.id);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Delete category */}\r\n {\r\n setDeletePrompt(true);\r\n }}\r\n >\r\n \r\n \r\n\r\n \r\n }\r\n disableTypography={true}\r\n title={\r\n \r\n {formatName(category.name)}\r\n \r\n }\r\n subheader={\r\n \r\n \r\n {t('labels.total-labels', {\r\n count: category.labels.length\r\n })}\r\n \r\n {(sorted) && undoSort()}\r\n error\r\n />}\r\n \r\n }\r\n />\r\n\r\n {/* Expandable content */}\r\n {expanded && ()}\r\n\r\n \r\n\r\n setEditPrompt(false)}\r\n onSubmit={handleEditCategory}\r\n title={t('labels.edit-class')}\r\n prompt={t('labels.enter-new-class-name')}\r\n placeholder={category.name}\r\n label={t('labels.class-name')}\r\n />\r\n\r\n setDeletePrompt(false)}\r\n onSubmit={handleDeleteCategory}\r\n title={t('labels.delete-class')}\r\n prompt={t('labels.do-you-want-to-delete-this-class', {\r\n name: category.name\r\n })}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n \r\n\r\n \r\n\r\n \r\n );\r\n};\r\n\r\n\r\nconst LabelIntersectDialog = (props) => {\r\n const {open, setOpen, forceInitialProgress, setTrainClassifyExe,\r\n setTrainClassifyProgress, resetExecutableValues,\r\n checkTrainingData, pointClouds, categories, setProcessType} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const dispatch = useDispatch();\r\n const defaultFolder = useSelector(selectDefaultFolder);\r\n\r\n const {addCSVFiles, addPointCloudFiles} = useAssetTools();\r\n\r\n const projectName = useSelector(selectProjectName);\r\n const [method, setMethod] = useState(\"label_intersect_v2\");\r\n const [outputPath, setOutputPath] = useState(null);\r\n\r\n const LASfiles = pointClouds.filter(x => x.type === AssetType.LAS);\r\n\r\n const minLasVersion = Math.min(...LASfiles.map(pointCloud => {\r\n const header = viewer.getLasFileInfo(pointCloud.id);\r\n return header ? parseFloat(header.attributes.version) : 0;\r\n }));\r\n\r\n const visibleClouds = LASfiles.filter(x => x.visible);\r\n const cloudsAvailable = (visibleClouds.length > 0);\r\n // const mixedData = (LASfiles.length !== pointClouds.length);\r\n const maxNumClasses = (minLasVersion >= 1.4) ? 255 : 31;\r\n const availableLasClasses = viewer?.getAvailableClassifications();\r\n availableLasClasses?.sort(function(a, b) {\r\n return a - b;\r\n });\r\n\r\n const defaults = {\r\n image_sampling_dist: {value: 1, error: false},\r\n intersection_angle: {value: 10, error: false},\r\n min_num_matches: {value: 2, error: false},\r\n position_confidence: {value: \"high\", error: false},\r\n max_distance_from_camera: {value: 60, error: false},\r\n close_label_dist: {value: 1, error: false},\r\n min_camera_distance: {value: 1, error: false},\r\n max_camera_distance: {value: 60, error: false},\r\n max_intersect_distance: {value: 1, error: false},\r\n cluster_distance: {value: 1, error: false},\r\n num_matches_required: {value: 3, error: false},\r\n object_size: {value: 0.5, error: false},\r\n };\r\n\r\n // Shared parameters\r\n const [imageSamplingDistance, setImageSamplingDistance] = useState(defaults.image_sampling_dist);\r\n\r\n // Point synthesis parameters\r\n const [intersectionAngle, setIntersectionAngle] = useState(defaults.intersection_angle);\r\n const [minNumMatches, setMinNumMatches] = useState(defaults.min_num_matches);\r\n const [positionConfidence, setPositionConfidence] = useState(defaults.position_confidence);\r\n const [maxDistanceFromCamera, setMaxDistanceFromCamera] = useState(defaults.max_distance_from_camera);\r\n const [closeLabelDist, setCloseLabelDist] = useState(defaults.close_label_dist);\r\n\r\n // Ray intersection parameters\r\n const [minCameraDistance, setMinCameraDistance] = useState(defaults.min_camera_distance);\r\n const [maxCameraDistance, setMaxCameraDistance] = useState(defaults.max_camera_distance);\r\n const [maxIntersectDistance, setMaxIntersectDistance] = useState(defaults.max_intersect_distance);\r\n const [clusterDistance, setClusterDistance] = useState(defaults.cluster_distance);\r\n const [numMatchesRequired, setNumMatchesRequired] = useState(defaults.num_matches_required);\r\n\r\n\r\n // Extract Point Cloud parameters\r\n const [extractPoints, setExtractPoints] = useState(false);\r\n const [objSize, setObjSize] = useState(defaults.object_size);\r\n const [overwrite, setOverwrite] = useState(false);\r\n const [collapse1, setCollapse1] = useState(true);\r\n const [collapse2, setCollapse2] = useState(true);\r\n const [categoryClasses, setCategoryClasses] = useState(null);\r\n const [ignoreClasses, setIgnoreClasses] = useState(null);\r\n\r\n const getCategoryClasses = (categories) => {\r\n let categoriesTemp = categories.map((category, index) => {\r\n let name = category.name;\r\n let lasClass = getClassFromAlias(name);\r\n if (lasClass < 0) {\r\n lasClass = 0;\r\n }\r\n\r\n return {\r\n id: nanoid(),\r\n index: index,\r\n primary: name,\r\n secondary: lasClass.toString(),\r\n error: false,\r\n min: 0,\r\n max: maxNumClasses,\r\n step:1,\r\n };\r\n });\r\n setCategoryClasses([...categoriesTemp]);\r\n };\r\n\r\n const getIgnoreClasses = () => {\r\n let ignoreTemp = availableLasClasses?.map((classification, index) => {\r\n const name = getNameFromClass(classification);\r\n return {\r\n id: nanoid(),\r\n classification: classification,\r\n index: index,\r\n name: name,\r\n value: false\r\n };\r\n });\r\n if (ignoreTemp) {\r\n setIgnoreClasses([...ignoreTemp]);\r\n }\r\n };\r\n\r\n const updateCategoryNumbers = (data) => {\r\n let categoriesTemp = [...categoryClasses];\r\n categoriesTemp[data.index].secondary = data.value;\r\n categoriesTemp[data.index].error = data.error;\r\n setCategoryClasses([...categoriesTemp]);\r\n };\r\n\r\n const updateIgnoreClasses = (index, checked) => {\r\n let ignoreTemp = [...ignoreClasses];\r\n ignoreTemp[index].value = checked;\r\n setIgnoreClasses([...ignoreTemp]);\r\n };\r\n\r\n const onDragEnd = ({ destination, source }: DropResult) => {\r\n if (!destination) return;\r\n\r\n let rowsTemp = [...categoryClasses];\r\n const [removed] = rowsTemp.splice(source.index, 1);\r\n rowsTemp.splice(destination.index, 0, removed);\r\n rowsTemp.forEach((row, index) => row.index=index);\r\n\r\n setCategoryClasses([...rowsTemp]);\r\n return;\r\n };\r\n\r\n const handleClose = () => {\r\n setOpen(false);\r\n };\r\n\r\n const handleSubmit = () => {\r\n runIntersection();\r\n setOpen(false);\r\n };\r\n\r\n const runIntersection = async () => {\r\n const jsonData = viewer?.labelObject();\r\n if (!checkTrainingData(jsonData)) {\r\n return false;\r\n }\r\n\r\n const tempCocoPath = getTemporaryFile(\"3dl\");\r\n const csvEncompassPath = getTemporaryFile('csv');\r\n\r\n\r\n try {\r\n // Write COCO file to temp path\r\n let text = JSON.stringify(jsonData, null, 2);\r\n await fse.writeFile(tempCocoPath, text);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n return;\r\n }\r\n\r\n try {\r\n // Export cameras to csv\r\n const cameras = viewer.activeImages();\r\n const rows = viewer.getCameraRowsCSV(cameras);\r\n const content = await writeToString(rows);\r\n await fse.writeFile(csvEncompassPath, content);\r\n } catch {\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n return;\r\n }\r\n\r\n let exe = new PythonExecutable();\r\n\r\n // Shared parameters\r\n let commands = [\r\n \"-p\", method,\r\n \"--csv_image_file\", csvEncompassPath,\r\n \"--coco_data_file\", tempCocoPath,\r\n \"--output_folder\", outputPath,\r\n \"--project_name\", projectName,\r\n \"--image_sampling_dist\", imageSamplingDistance.value\r\n ];\r\n\r\n // Point synthesis parameters\r\n if (useFunctionV1) {\r\n commands = [\r\n ...commands,\r\n \"--intersection_angle\", intersectionAngle.value,\r\n \"--min_num_matches\", minNumMatches.value,\r\n \"--position_confidence\", positionConfidence.value,\r\n \"--max_distance_from_camera\", maxDistanceFromCamera.value,\r\n \"--close_label_dist\", closeLabelDist.value\r\n ];\r\n }\r\n\r\n // Ray intersection parameters\r\n if (useFunctionV2) {\r\n commands = [\r\n ...commands,\r\n \"--min_camera_distance\", minCameraDistance.value,\r\n \"--max_camera_distance\", maxCameraDistance.value,\r\n \"--max_intersect_distance\", maxIntersectDistance.value,\r\n \"--cluster_distance\", clusterDistance.value,\r\n \"--num_matches_required\", numMatchesRequired.value,\r\n ];\r\n }\r\n\r\n if (extractPoints) {\r\n const classesToIgnore = ignoreClasses.filter(ic => ic.value).map(ic => {\r\n return ic.classification;\r\n });\r\n\r\n const categoryClassesNames = categoryClasses.map(category => {\r\n return category.primary;\r\n });\r\n\r\n const categoryClassesNums = categoryClasses.map(category => {\r\n return category.secondary;\r\n });\r\n\r\n commands = [\r\n ...commands,\r\n \"--find_in_lidar\", visibleClouds.map(cloud=>cloud.path),\r\n \"--max_obj_size\", objSize.value,\r\n \"--ignore_classes\", classesToIgnore,\r\n \"--overwrite_las\", (overwrite) ? \"True\" : \"False\",\r\n \"--label_class_names\", categoryClassesNames,\r\n \"--label_class_nums\", categoryClassesNums,\r\n \"--units\", LocalScene.dataProjectionUnits\r\n ];\r\n }\r\n\r\n forceInitialProgress();\r\n setTrainClassifyExe(exe);\r\n\r\n toast.success(t(\"toast.labels-position-submit\"));\r\n\r\n let successEstimate = false;\r\n let successLabelInPC = false;\r\n let successCombine = false;\r\n let successConvert = false;\r\n let convertAttempted = false;\r\n let successLasWritten = false;\r\n let lasOutputPath;\r\n let csvOutputPaths=[];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: async jsonData => {\r\n if (!jsonData) {\r\n return;\r\n }\r\n\r\n if (jsonData.position_estimate_progress) {\r\n setTrainClassifyProgress(jsonData.position_estimate_progress);\r\n setProcessType(t(\"labels.label-process-export\"));\r\n } else if (jsonData.positions_found) {\r\n successEstimate = true;\r\n toast.success(t(\"toast.labels-position-found\", {\r\n count: jsonData.positions_found\r\n }));\r\n } else if (jsonData.csvs_written) {\r\n csvOutputPaths = jsonData.csvs_written;\r\n await addCSVFiles(csvOutputPaths, defaultFolder.id);\r\n\r\n } else if (jsonData[\"Locate Points in Labels\"]) {\r\n setTrainClassifyProgress(jsonData[\"Locate Points in Labels\"]);\r\n setProcessType(t(\"labels.label-process-extract-points\"));\r\n } else if (jsonData.labels_found_pointcloud) {\r\n successLabelInPC = true;\r\n toast.success(t(\"toast.labels-points-found\", {\r\n count: jsonData.labels_found_pointcloud\r\n }));\r\n } else if (jsonData.combine_las) {\r\n setTrainClassifyProgress(jsonData.combine_las);\r\n setProcessType(t(\"labels.label-process-combine_pointcloud\"));\r\n } else if (jsonData.combine_las_complete) {\r\n successCombine = true;\r\n toast.success(t(\"toast.labels-points-found\", {\r\n count: jsonData.combine_las_complete\r\n }));\r\n } else if (jsonData.las_to_3dp) {\r\n convertAttempted = true;\r\n setTrainClassifyProgress(jsonData.las_to_3dp);\r\n setProcessType(t(\"labels.label-process-convert-pointcloud\"));\r\n } else if (jsonData.las_to_3dp_success) {\r\n successConvert = true;\r\n toast.success(t(\"toast.labels-pointcloud-converted\"));\r\n } else if (jsonData.writing_las) {\r\n setTrainClassifyProgress(jsonData.writing_las);\r\n setProcessType(t(\"labels.label-process-writing-las\"));\r\n } else if (jsonData.las_written) {\r\n successLasWritten = true;\r\n lasOutputPath = jsonData.las_written;\r\n }\r\n },\r\n onClose: async () => {\r\n if (successEstimate) {\r\n toast.success(t(\"toast.labels-position-save\", {\r\n path: outputPath\r\n }));\r\n } else {\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n }\r\n if (extractPoints) {\r\n if (!successCombine && (visibleClouds.length > 1)) {\r\n toast.error(t(\"toast.labels-combine-failed\"));\r\n }\r\n else if (!successConvert && convertAttempted) {\r\n toast.error(t(\"toast.labels-convert-failed\"));\r\n }\r\n else if (!successLabelInPC) {\r\n toast.error(t(\"toast.labels-find-points-failed\"));\r\n }\r\n else if (!successLasWritten) {\r\n toast.error(t(\"toast.labels-write-failed\"));\r\n }\r\n else {\r\n toast.success(t(\"toast.labels-las-written-save\", {\r\n path: lasOutputPath\r\n }));\r\n await addPointCloudFiles([lasOutputPath], defaultFolder.id);\r\n if (overwrite && (visibleClouds.length === 1)){\r\n dispatch(deleteAsset(visibleClouds[0].id));\r\n }\r\n }\r\n }\r\n\r\n resetExecutableValues();\r\n }\r\n });\r\n };\r\n\r\n const resetDefaultValues = () => {\r\n // Shared parameters\r\n setImageSamplingDistance(defaults.image_sampling_dist);\r\n setExtractPoints(false);\r\n\r\n // Point synthesis parameters\r\n setIntersectionAngle(defaults.intersection_angle);\r\n setMinNumMatches(defaults.min_num_matches);\r\n setPositionConfidence(defaults.position_confidence);\r\n setMaxDistanceFromCamera(defaults.max_distance_from_camera);\r\n setCloseLabelDist(defaults.close_label_dist);\r\n\r\n // Ray intersection parameters\r\n setMinCameraDistance(defaults.min_camera_distance);\r\n setMaxCameraDistance(defaults.max_camera_distance);\r\n setMaxIntersectDistance(defaults.max_intersect_distance);\r\n setClusterDistance(defaults.cluster_distance);\r\n setNumMatchesRequired(defaults.num_matches_required);\r\n\r\n // Point Extraction Parameters\r\n setOverwrite(false);\r\n setObjSize(defaults.object_size);\r\n\r\n };\r\n\r\n useEffect(() => {\r\n getCategoryClasses(categories);\r\n getIgnoreClasses();\r\n if (open) {\r\n return;\r\n }\r\n resetDefaultValues();\r\n setOutputPath(null);\r\n }, [open]);\r\n\r\n useEffect(() => {\r\n resetDefaultValues();\r\n }, [method]);\r\n\r\n const useFunctionV1 = method === \"label_intersect\";\r\n const useFunctionV2 = method === \"label_intersect_v2\";\r\n const folderSelected = outputPath !== null;\r\n\r\n let canSubmit = folderSelected\r\n && !imageSamplingDistance.error\r\n && !intersectionAngle.error\r\n && !minNumMatches.error\r\n && !positionConfidence.error\r\n && !maxDistanceFromCamera.error\r\n && !closeLabelDist.error\r\n && !minCameraDistance.error\r\n && !maxCameraDistance.error\r\n && !maxIntersectDistance.error\r\n && !clusterDistance.error\r\n && !numMatchesRequired.error;\r\n\r\n return (\r\n \r\n {/* Label Analysis Dialog */}\r\n \r\n {t('labels.label-analysis')}\r\n \r\n \r\n\r\n {/* Export method */}\r\n \r\n \r\n \r\n\r\n {/* Output folder */}\r\n \r\n \r\n \r\n {(useFunctionV2 && cloudsAvailable) && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n {t('labels.position-parameters')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* Function parameters for V1 of function */}\r\n {(useFunctionV1 && collapse1) && (\r\n\r\n {/* Minimum intersect angle */}\r\n \r\n \r\n \r\n\r\n {/* Number of matches */}\r\n \r\n \r\n \r\n\r\n {/* Position confidence */}\r\n \r\n {\r\n setPositionConfidence({\r\n value: value,\r\n error: false\r\n });\r\n }}\r\n options={[\r\n [\"low\", t('general.low')],\r\n [\"medium\", t('general.medium')],\r\n [\"high\", t('general.high')]\r\n ]}\r\n />\r\n \r\n\r\n {/* Max camera distance */}\r\n \r\n \r\n \r\n\r\n {/* Image sampling distance */}\r\n \r\n \r\n \r\n\r\n {/* Clustering distance */}\r\n \r\n \r\n \r\n )}\r\n\r\n {/* Function parameters for V2 of function */}\r\n {(useFunctionV2 && collapse1) && (\r\n\r\n {/* Intersect Distance */}\r\n \r\n \r\n \r\n\r\n {/* Number of matches required */}\r\n \r\n \r\n \r\n\r\n {/* Min camera distance */}\r\n \r\n \r\n \r\n\r\n {/* Max camera distance */}\r\n \r\n \r\n \r\n\r\n {/* Image sampling distance */}\r\n \r\n \r\n \r\n\r\n {/* Clustering distance */}\r\n \r\n \r\n \r\n \r\n )}\r\n\r\n {(extractPoints) && (\r\n \r\n \r\n {t('labels.point-extraction-parameters')}\r\n \r\n \r\n \r\n \r\n \r\n \r\n {(collapse2) && (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {/* Object Size */}\r\n \r\n \r\n \r\n {/* Overwrite Las */}\r\n \r\n {t(\"labels.extract-points-overwrite\")}\r\n \r\n {t(\"labels.extract-points-overwrite-info\")}\r\n \r\n {\r\n setOverwrite(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n \r\n \r\n \r\n \r\n {ignoreClasses.map((ignoreClass, index) => (\r\n \r\n \r\n {ignoreClass.name}\r\n \r\n {\r\n updateIgnoreClasses(index, event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n \r\n {`${ignoreClass.classification}`}\r\n \r\n \r\n ))}\r\n \r\n\r\n\r\n )}\r\n )}\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst ImportDialog = (props) => {\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n const {viewer} = useViewer();\r\n const theme = useTheme();\r\n\r\n const tableState = useTableState();\r\n\r\n const [disabled, setDisabled] = useState(false);\r\n const [importCategory, setImportCategory] = useState({});\r\n const [overwrite, setOverwrite] = useState(true);\r\n const [importLarge, setImportLarge] = useState(false);\r\n const [importPoints, setImportPoints] = useState(true);\r\n const [importLines, setImportLines] = useState(true);\r\n const [checkOverlap, setCheckOverlap] = useState(false);\r\n\r\n const [lineBuffer, setLineBuffer] = useState(\"0.5\"); // TODO: pull from global setting later?\r\n const [pointBuffer, setPointBuffer] = useState(\"0.5\"); // TODO: pull from global setting later?\r\n\r\n const {importData, setImportData, isOrthoLabel,\r\n categoryList, setLabelLoadProgress} = props;\r\n\r\n const open = !!importData;\r\n\r\n const categories = importData\r\n ? importData.categories as any[]\r\n : [];\r\n\r\n let annotations = importData\r\n ? importData.annotations as any[]\r\n : [];\r\n\r\n const hasLines = annotations.filter(x => x.is_linestring).length > 0;\r\n const hasPoints = annotations.filter(x => x.is_point).length > 0;\r\n\r\n let hasLargeClasses = false;\r\n categories.forEach(category => {\r\n let numGeometry = annotations\r\n .filter(x => x.category_id === category.id)\r\n .length;\r\n if (numGeometry > geometryLimit) {\r\n hasLargeClasses = true;\r\n }\r\n });\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t('labels.class-name')\r\n },\r\n {\r\n id: 'count',\r\n label: t('labels.geometry-count'),\r\n numeric: true\r\n },\r\n {\r\n id: 'category',\r\n label: t('labels.imported-class-name')\r\n },\r\n ];\r\n\r\n const categoryNames = Array.from(new Set([\r\n ...categoryList.map(x => x.name),\r\n ...categories.map(x => x.name)\r\n ])).sort((a, b) => a.localeCompare(b));\r\n\r\n const filterAnnotationTypes = (data) => {\r\n return [...data].filter(x => {\r\n if (!importPoints && x.is_point) {\r\n return false;\r\n } else if (!importLines && x.is_linestring) {\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n };\r\n\r\n const validBufferSize = (buffer) => {\r\n let bufferSize = parseFloat(buffer);\r\n let minIterations = 0.01;\r\n let maxIterations = 10;\r\n\r\n let validNumber = (bufferSize >= minIterations)\r\n && (bufferSize <= maxIterations);\r\n\r\n if (!validNumber) {\r\n toast.error(t(\"toast.labels-buffer-size\", {\r\n minIterations,\r\n maxIterations\r\n }));\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const handleClose = () => {\r\n setImportData(null);\r\n };\r\n\r\n const handleImport = async () => {\r\n if ((hasPoints && importPoints) && !validBufferSize(pointBuffer)) {\r\n return;\r\n }\r\n\r\n if ((hasLines && importLines) && !validBufferSize(lineBuffer)) {\r\n return;\r\n }\r\n\r\n const labelData = {\r\n ...importData,\r\n annotations: filterAnnotationTypes(importData.annotations)\r\n };\r\n\r\n const importCategories = [];\r\n\r\n labelData.categories.forEach((category, index) => {\r\n let newCategoryName = getMappedCategory(category.name);\r\n\r\n let numGeometry = labelData.annotations\r\n .filter(x => x.category_id === category.id)\r\n .length;\r\n\r\n if (numGeometry === 0) {\r\n return;\r\n }\r\n\r\n let ignoreLayer = (newCategoryName === LabelImportType.Ignore)\r\n || (importLarge ? false : numGeometry > geometryLimit);\r\n\r\n if (ignoreLayer) {\r\n // Filter our data for this category\r\n labelData.annotations = labelData.annotations\r\n .filter(x => x.category_id !== category.id);\r\n\r\n return;\r\n }\r\n\r\n importCategories.push({\r\n ...category,\r\n name: newCategoryName\r\n });\r\n });\r\n\r\n // Apply linestring / point buffer\r\n labelData.annotations.forEach((anno, index) => {\r\n if (anno.is_linestring) {\r\n labelData.annotations[index].buffer_size = lineBuffer;\r\n } else if (anno.is_point) {\r\n labelData.annotations[index].buffer_size = pointBuffer;\r\n }\r\n });\r\n\r\n // Replace categories with remapped version\r\n labelData.categories = importCategories;\r\n\r\n handleClose();\r\n\r\n // Nothing left, exit early\r\n if (labelData.categories.length === 0) {\r\n toast.warning(t(\"toast.labels-not-available\"));\r\n } else {\r\n await viewer?.loadImageLabelData(\r\n labelData,\r\n setLabelLoadProgress,\r\n overwrite,\r\n checkOverlap\r\n );\r\n\r\n toast.success(t(\"toast.labels-load-success\"));\r\n }\r\n };\r\n\r\n const getMappedCategory = (key) => {\r\n return importCategory[key]\r\n ? importCategory[key]\r\n : key;\r\n };\r\n\r\n const createSelect = (key, disabled) => {\r\n return (\r\n {\r\n const updated = {...importCategory};\r\n updated[key] = event.target.value;\r\n setImportCategory(updated);\r\n }}\r\n >\r\n {getLayerMenuItems()}\r\n \r\n );\r\n };\r\n\r\n const getLayerMenuItems = () => {\r\n const menuIgnore = (\r\n \r\n {t('labels.ignore-layer')}\r\n \r\n );\r\n\r\n const menuDivider = (\r\n
\r\n );\r\n\r\n return [\r\n menuIgnore,\r\n menuDivider,\r\n ...categoryNames.map(name => (\r\n \r\n {name}\r\n \r\n ))\r\n ];\r\n };\r\n\r\n const onMenuClick = (event) => {\r\n const value = event.target.value;\r\n const updated = {...importCategory};\r\n categories.forEach(data => {\r\n if (value === LabelImportType.Default) {\r\n delete updated[data.name];\r\n } else {\r\n updated[data.name] = value;\r\n }\r\n });\r\n\r\n setImportCategory(updated);\r\n };\r\n\r\n const getRows = () => {\r\n const filtered = categories.filter(category => {\r\n let numGeometry = annotations\r\n .filter(x => x.category_id === category.id)\r\n .length;\r\n return numGeometry > 0;\r\n });\r\n\r\n return filtered.map((category, index) => {\r\n let numGeometry = annotations\r\n .filter(x => x.category_id === category.id)\r\n .length;\r\n\r\n let disabled = !importLarge && (numGeometry > geometryLimit);\r\n\r\n return {\r\n id: `ImportLayerTableRow_${index}`,\r\n name: category.name as string,\r\n count: numGeometry,\r\n category: createSelect(category.name, disabled),\r\n disabled\r\n };\r\n });\r\n };\r\n\r\n const handlePointBufferChange = (event) => {\r\n setPointBuffer(event.target.value);\r\n };\r\n\r\n const handleLineBufferChange = (event) => {\r\n setLineBuffer(event.target.value);\r\n };\r\n\r\n useEffect(() => {\r\n if (!importData) {\r\n setImportCategory({});\r\n setOverwrite(true);\r\n setCheckOverlap(false);\r\n setImportLarge(false);\r\n setImportPoints(true);\r\n setImportLines(true);\r\n }\r\n }, [importData]);\r\n\r\n useEffect(() => {\r\n let valid = true;\r\n\r\n if (importLines && lineBuffer === \"\") {\r\n valid = false;\r\n }\r\n\r\n if (importPoints && pointBuffer === \"\") {\r\n valid = false;\r\n }\r\n\r\n setDisabled(!valid);\r\n }, [importLines, importPoints, pointBuffer, lineBuffer]);\r\n\r\n annotations = filterAnnotationTypes(annotations);\r\n\r\n const rows = getRows();\r\n\r\n return (\r\n \r\n {t('labels.import-labels')}\r\n\r\n \r\n\r\n {/* Setting layer default */}\r\n \r\n
\r\n {t('labels.apply-class-mapping')}\r\n\r\n \r\n {t('labels.select-option')}\r\n {t('labels.default-mapping')}\r\n {getLayerMenuItems()}\r\n \r\n
\r\n
\r\n\r\n {/* Overwrite existing labels */}\r\n \r\n
\r\n {t('labels.overwrite-existing-labels')}\r\n\r\n {\r\n setOverwrite(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n
\r\n
\r\n\r\n {/* Ignore outside image bounds */}\r\n {isOrthoLabel && (\r\n
\r\n {t('labels.discard-non-overlapping-labels')}\r\n\r\n \r\n {\r\n setCheckOverlap(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n \r\n
\r\n
)}\r\n\r\n {/* Import large classes */}\r\n {hasLargeClasses && (\r\n
\r\n \r\n {t('labels.import-large-classes')}\r\n \r\n\r\n \r\n {\r\n setImportLarge(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n \r\n
\r\n
)}\r\n\r\n {/* Import polylines */}\r\n \r\n {hasLines && (
\r\n {t('labels.import-linestrings')}\r\n\r\n {\r\n setImportLines(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n
)}\r\n {(hasLines && importLines) && (\r\n {t('labels.a-buffer-will-be-applied-to-convert-to-a-polygon')}\r\n )}\r\n
\r\n\r\n \r\n {(hasLines && importLines) && (
\r\n \r\n
)}\r\n
\r\n\r\n {/* Import points */}\r\n \r\n {hasPoints && (
\r\n {t('labels.import-points')}\r\n\r\n {\r\n setImportPoints(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n
)}\r\n {(hasPoints && importPoints) && (\r\n {t('labels.a-buffer-will-be-applied-to-convert-to-a-polygon')}\r\n )}\r\n
\r\n\r\n \r\n {(hasPoints && importPoints) && (
\r\n \r\n
)}\r\n
\r\n\r\n
\r\n\r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst ClassifyFromAerial = (props) => {\r\n const {categories, open, setOpen, setProgress,\r\n pointClouds} = props;\r\n\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [rows, setRows] = useState([]);\r\n const [sorted, setSorted] = useState(false);\r\n const [sortedAlpha, setSortedAlpha] = useState(false);\r\n const [sortByNum, setSortByNum] = useState(false);\r\n const [overwriteFile, setOverwriteFile] = useState(false);\r\n const [preserveGround, setPreserveGround] = useState(false);\r\n const [newLasPath, setNewLasPath] = useState(null);\r\n\r\n const LASfiles = pointClouds.filter(x => x.type === AssetType.LAS);\r\n\r\n const minLasVersion = Math.min(...LASfiles.map(pointCloud => {\r\n const header = viewer.getLasFileInfo(pointCloud.id);\r\n return header ? parseFloat(header.attributes.version) : 0;\r\n }));\r\n\r\n const visibleClouds = LASfiles.filter(x => x.visible);\r\n const mixedData = (LASfiles.length !== pointClouds.length);\r\n const maxNumClasses = (minLasVersion >= 1.4) ? 255 : 31;\r\n\r\n const canSubmit = (visibleClouds.length > 0)\r\n && (minLasVersion > 0)\r\n && ((newLasPath !== null) || (overwriteFile))\r\n && rows.filter(x => x.error).length === 0;\r\n\r\n const checkNamesForClass = (name) => {\r\n let classNum = getClassFromAlias(name);\r\n if (classNum < 0) {\r\n classNum = 0;\r\n }\r\n return classNum;\r\n };\r\n\r\n const getRows = (categories) => {\r\n let rowsTemp = categories.map((category, index) => {\r\n let name = category.name;\r\n let lasClass = checkNamesForClass(name);\r\n\r\n return {\r\n id: `AerialClassifyTableRow_${index}`,\r\n index: index,\r\n primary: name,\r\n secondary: lasClass,\r\n error: false,\r\n min: 0,\r\n max: maxNumClasses,\r\n step:1,\r\n };\r\n });\r\n\r\n setRows([...rowsTemp]);\r\n };\r\n\r\n const updateClassNumbers = (data) => {\r\n let rowsTemp = [...rows];\r\n rowsTemp[data.index].secondary = data.value;\r\n rowsTemp[data.index].error = data.error;\r\n setRows([...rowsTemp]);\r\n };\r\n\r\n const handleClose = () => {\r\n setOpen(false);\r\n setProgress(0);\r\n setOverwriteFile(false);\r\n setPreserveGround(false);\r\n };\r\n\r\n const handleSubmit = () => {\r\n setOpen(false);\r\n classifyPointclouds();\r\n };\r\n\r\n const classifyPointclouds = () => {\r\n const applicationOrder = rows.map(row => row.primary);\r\n const lasClasses = rows.map(row => parseInt(row.secondary));\r\n const inputPaths = visibleClouds.map(x => x.path);\r\n const overwriteGround = !preserveGround;\r\n const outputPath = newLasPath;\r\n\r\n const polygonData = viewer.getOrthoLabelPolygons();\r\n const jsonData = applicationOrder.map((name, index) => {\r\n return {\r\n name,\r\n class: lasClasses[index],\r\n segments: polygonData[name]\r\n };\r\n });\r\n\r\n const text = JSON.stringify(jsonData, null, 4);\r\n const tempTextPath = getTemporaryFile(\"txt\");\r\n\r\n try {\r\n fs.writeFileSync(tempTextPath, text);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-aerial-error\"));\r\n return;\r\n }\r\n\r\n toast.success(t('toast.aerial_classification_submitted'));\r\n\r\n let newCloudPaths = null;\r\n let processTimeout = 500;\r\n\r\n let exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", \"classify_from_aerial\",\r\n \"--input_paths\", inputPaths,\r\n \"--input_json\", tempTextPath,\r\n \"--overwrite_ground\", overwriteGround,\r\n \"--overwrite_file\", overwriteFile\r\n ];\r\n\r\n if (!overwriteFile) {\r\n commands.push(\"--output_folder\");\r\n commands.push(outputPath);\r\n }\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n if (jsonData.label_bounds_error) {\r\n toast.error(t(\"toast.labels-aerial-error-bounds\"));\r\n } else if (jsonData.progress) {\r\n setProgress(jsonData.progress);\r\n } else if (jsonData.overwrite_failure) {\r\n toast.error(t(\"toast.labels-aerial-error-overwrite\"));\r\n } else if (jsonData.output_paths) {\r\n newCloudPaths = jsonData.output_paths;\r\n }\r\n },\r\n onClose: async () => {\r\n if (!newCloudPaths) {\r\n toast.warning(t(\"toast.labels-classify-incomplete\"));\r\n handleClose();\r\n return;\r\n }\r\n\r\n await asyncTimeout(processTimeout);\r\n toast.success(t(\"toast.labels-import-modified\"));\r\n\r\n visibleClouds.forEach((asset, index) => {\r\n const assetPath = newCloudPaths[index];\r\n\r\n // Add new pointcloud\r\n dispatch(addAsset({\r\n folderID: asset.folderID,\r\n name: path.basename(assetPath),\r\n path: assetPath,\r\n type: asset.type\r\n }));\r\n\r\n // Remove old pointcloud\r\n dispatch(deleteAsset(asset.id));\r\n });\r\n\r\n handleClose();\r\n }\r\n });\r\n };\r\n\r\n const sortRowsByClassNum = (reverseSort) => {\r\n let rowsTemp = [...rows];\r\n if (rows.length === 0) {\r\n return;\r\n }\r\n\r\n if (!reverseSort){\r\n rowsTemp.sort((a,b) => a.secondary - b.secondary);\r\n }\r\n else {\r\n rowsTemp.sort((a,b) => b.secondary - a.secondary);\r\n }\r\n\r\n rowsTemp.forEach((row, index) => row.index=index);\r\n setRows([...rowsTemp]);\r\n setSortByNum(!reverseSort);\r\n setSorted(true);\r\n };\r\n\r\n const sortRowsAlphabetically = () => {\r\n let rowsTemp = [...rows];\r\n if (rows.length === 0) {\r\n return;\r\n }\r\n\r\n rowsTemp.sort((a, b) => a.primary.localeCompare(b.primary));\r\n rowsTemp.forEach((row, index) => row.index=index);\r\n setSortedAlpha(true);\r\n setRows([...rowsTemp]);\r\n };\r\n\r\n const sortReset = () => {\r\n let rowsTemp = [...rows];\r\n if (rows.length === 0) {\r\n return;\r\n }\r\n\r\n rowsTemp.sort((a,b) => parseInt(a.id) - parseInt(b.id));\r\n rowsTemp.forEach((row, index) => row.index=index);\r\n setSorted(false);\r\n setSortedAlpha(false);\r\n setRows([...rowsTemp]);\r\n };\r\n\r\n const onDragEnd = ({ destination, source }: DropResult) => {\r\n if (!destination) return;\r\n\r\n let rowsTemp = [...rows];\r\n const [removed] = rowsTemp.splice(source.index, 1);\r\n rowsTemp.splice(destination.index, 0, removed);\r\n rowsTemp.forEach((row, index) => row.index=index);\r\n\r\n setRows([...rowsTemp]);\r\n return;\r\n };\r\n\r\n useEffect(() => {\r\n getRows(categories);\r\n }, [open]);\r\n\r\n const sortButtonTitle = sorted\r\n ? t('labels.reverse-sort-order')\r\n : t('labels.sort-by-las-classification');\r\n\r\n return (\r\n \r\n {t('labels.classify-point-cloud-from-aerial-image')}\r\n \r\n \r\n {t('labels.classes-lower-in-the-list-will-be-applied')}\r\n \r\n\r\n
\r\n {\r\n sortRowsByClassNum(sortByNum);\r\n }}\r\n >\r\n \r\n \r\n\r\n {\r\n sortRowsAlphabetically();\r\n }}\r\n >\r\n \r\n \r\n\r\n\r\n {(sorted || sortedAlpha) && {\r\n sortReset();\r\n }}\r\n >\r\n \r\n }\r\n
\r\n\r\n \r\n \r\n \r\n\r\n \r\n\r\n {/* Preserve ground classification */}\r\n \r\n \r\n \r\n\r\n {/* Overwrite point clouds */}\r\n \r\n \r\n \r\n\r\n {/* Output folder */}\r\n {!overwriteFile && \r\n \r\n }\r\n\r\n \r\n\r\n {mixedData && (\r\n \r\n {t('labels.classification-from-aerial-will-only-apply-to-las-files')}\r\n \r\n )}\r\n\r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n );\r\n};\r\n\r\nconst ClassificationParameters = (props) => {\r\n const {open, setOpen, runClassification, defaultScore} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [modelPath, setModelPath] = useState(null);\r\n const [runOnCPU, setRunOnCPU] = useState(false);\r\n const [score, setScore] = useState({\r\n value: defaultScore,\r\n error: false\r\n });\r\n\r\n const handleCancel = () => {\r\n setOpen(false);\r\n };\r\n\r\n const handleSubmit = () => {\r\n toast.success(t(\"toast.labels-classify-submit\"));\r\n runClassification(parseFloat(score.value), modelPath, runOnCPU);\r\n setOpen(false);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setModelPath(null);\r\n setRunOnCPU(false);\r\n setScore({value: defaultScore, error: false});\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const canSubmit = (modelPath !== null) && (!score.error);\r\n\r\n return (\r\n \r\n {t('labels.model-classification-parameters')}\r\n\r\n \r\n\r\n {/* Classification Score */}\r\n {t('labels.classification-score')}\r\n \r\n\r\n {/* Model path */}\r\n
\r\n \r\n
\r\n\r\n {/* Run on CPU */}\r\n
\r\n {t('labels.run-on-cpu')}\r\n {\r\n setRunOnCPU(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n
\r\n\r\n \r\n {t('labels.running-on-cpu-is-slower')}\r\n \r\n\r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst TrainingParameters = (props) => {\r\n const {open, setOpen, runTraining, defaultIterations} = props;\r\n const {t} = useTranslation();\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [pretrainedPath, setPretrainedPath] = useState(null);\r\n const [runOnCPU, setRunOnCPU] = useState(false);\r\n const [iterations, setIterations] = useState({\r\n value: defaultIterations,\r\n error: false,\r\n });\r\n\r\n const handleCancel = () => {\r\n setOpen(false);\r\n };\r\n\r\n const handleSubmit = () => {\r\n runTraining(parseInt(iterations.value), outputPath, pretrainedPath, runOnCPU);\r\n setOpen(false);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setPretrainedPath(null);\r\n setRunOnCPU(false);\r\n setOutputPath(null);\r\n setIterations({value: defaultIterations, error: false});\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const canSubmit = (outputPath !== null) && (!iterations.error);\r\n\r\n return (\r\n \r\n {t('labels.model-training-parameters')}\r\n\r\n \r\n \r\n\r\n {/* Training iterations */}\r\n \r\n \r\n \r\n\r\n {/* Output folder */}\r\n \r\n \r\n \r\n\r\n {/* Run on CPU */}\r\n \r\n \r\n \r\n\r\n \r\n {/* Pretrained model */}\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst GetInfoWindow = (props) => {\r\n const {open, setOpen, label, index, isSceneLabel} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const orignalText = label.text.split('\\n');\r\n const [text, setText] = useState(orignalText);\r\n\r\n const scoreClass = (score) => {\r\n let scoreValidity = classes.success;\r\n if (score < 0.9) {\r\n scoreValidity = classes.warning;\r\n }\r\n if (score < 0.7) {\r\n scoreValidity = classes.error;\r\n }\r\n return scoreValidity;\r\n };\r\n\r\n const handleCancel = () => {\r\n setText([...orignalText]);\r\n setOpen(false);\r\n };\r\n\r\n const updateLabelText = (txtList) => {\r\n const newText = txtList.join(\"\\n\");\r\n viewer?.setLabelText(label.id, newText);\r\n };\r\n\r\n const handleSubmit = () => {\r\n let trimmedText = text.map(x => x.trim());\r\n setText([...trimmedText]);\r\n updateLabelText(trimmedText);\r\n setOpen(false);\r\n };\r\n\r\n const handleKeyDown = (event) => {\r\n if (event.key === 'Enter') {\r\n handleSubmit();\r\n }\r\n };\r\n\r\n const handleTextChange = (event, index) => {\r\n let newText = [...text];\r\n newText[index] = event.target.value;\r\n setText([...newText]);\r\n };\r\n\r\n const classValid = label.valid\r\n ? classes.success\r\n : classes.error;\r\n\r\n const classHighlight = label.highlighted\r\n ? classes.success\r\n : classes.error;\r\n\r\n return (\r\n \r\n {t('labels.label-info')}\r\n\r\n \r\n {t('labels.information')}\r\n \r\n\r\n {/** Label Number */}\r\n \r\n \r\n {t('labels.label-number', {index})}\r\n \r\n \r\n\r\n {/** Valid Geometry */}\r\n \r\n \r\n {`${t('labels.polygon-valid')}:`}\r\n \r\n \r\n {String(label.valid).toUpperCase()}\r\n \r\n \r\n\r\n {/** Highlighted */}\r\n \r\n \r\n {`${t('labels.highlighted')}:`}\r\n \r\n \r\n {String(label.highlighted).toUpperCase()}\r\n \r\n \r\n\r\n {/** Classification Score */}\r\n \r\n \r\n {`${t('labels.classification-score')}:`}\r\n \r\n \r\n {label.score.toFixed(2)}\r\n \r\n \r\n\r\n {(isSceneLabel) && \r\n {/** Text Confidence */}\r\n \r\n \r\n {`${t('labels.text-detection-score')}:`}\r\n \r\n \r\n {`${label.textScore.toFixed(2)}`}\r\n \r\n \r\n\r\n {/** Detected Text */}\r\n \r\n \r\n {text.map((txt, index)=>\r\n handleTextChange(event, index)}\r\n onKeyDown={(event) => handleKeyDown(event)}\r\n autoFocus\r\n margin=\"dense\"\r\n size=\"small\"\r\n label={t('labels.detected-text-line-line', {\r\n line: index+1\r\n })}\r\n type=\"text\"\r\n fullWidth\r\n value={txt}\r\n />\r\n )}\r\n \r\n \r\n\r\n }\r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n {(isSceneLabel) && }\r\n \r\n \r\n );\r\n};\r\n\r\nconst TextDetectionParameters = (props) => {\r\n const {open, setOpen, runTextDetection, defaultScore, category} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [spellcheck, setSpellcheck] = useState(false);\r\n const [score, setScore] = useState({\r\n value: defaultScore,\r\n error: false\r\n });\r\n\r\n const handleCancel = () => {\r\n setOpen(false);\r\n };\r\n\r\n const handleSubmit = () => {\r\n viewer?.setLabelFindText(category.id);\r\n runTextDetection(parseFloat(score.value), spellcheck);\r\n setOpen(false);\r\n };\r\n\r\n const resetDefaults = () => {\r\n setSpellcheck(false);\r\n setScore({value: defaultScore, error: false});\r\n };\r\n\r\n useEffect(() => {\r\n if (open) return;\r\n resetDefaults();\r\n }, [open]);\r\n\r\n const canSubmit = (!score.error);\r\n\r\n return (\r\n \r\n {t('labels.detect-text-in-name-labels', {\r\n name: category.name\r\n })}\r\n\r\n \r\n\r\n {/* Classification Score */}\r\n {t('labels.detection-score-threshold')}\r\n \r\n {t('labels.detected-text-with-detection-scores-below')}\r\n \r\n \r\n\r\n {/* Spell check toggle */}\r\n
\r\n {t('labels.spell-check-detected-text')}\r\n {\r\n setSpellcheck(event.target.checked);\r\n }}\r\n size=\"small\"\r\n color=\"secondary\"\r\n />\r\n
\r\n\r\n \r\n {t('labels.utilize-spell-checking')}\r\n \r\n\r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst ScoreSortingParameters = (props) => {\r\n const {open, setOpen, runSort, defaultScore, category} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const [sortType, setSortType] = useState('descending');\r\n const [score, setScore] = useState({\r\n value: defaultScore,\r\n error: false\r\n });\r\n\r\n const handleCancel = () => {\r\n setOpen(false);\r\n };\r\n\r\n const handleSubmit = () => {\r\n toast.success(t(\"toast.labels-sort-submit\"));\r\n runSort(parseFloat(score.value), sortType);\r\n setOpen(false);\r\n };\r\n\r\n /*\r\n useEffect(() => {\r\n if (open) {\r\n return;\r\n }\r\n\r\n // Reset default values\r\n setSortType('descending');\r\n setScore({value: defaultScore, error: false});\r\n }, [open]);\r\n */\r\n\r\n const canSubmit = (!score.error);\r\n\r\n return (\r\n \r\n {t('labels.sort-name-labels', {\r\n name: category.name\r\n })}\r\n\r\n \r\n\r\n {/* Classification Score */}\r\n {t('labels.classification-score-threshold')}\r\n \r\n {t('labels.classification-scores-below', {\r\n name: category.name\r\n })}\r\n \r\n \r\n\r\n {/* Sort Type */}\r\n
\r\n {t('labels.sorting-method')}\r\n \r\n {t('labels.choose-method-if-any-by-which-to-sort-the-category')}\r\n \r\n\r\n
\r\n {\r\n let value = event.target.value as any;\r\n setSortType(value);\r\n }}\r\n >\r\n {t('labels.ascending-low-to-high')}\r\n {t('labels.descending-high-to-low')}\r\n {t('labels.dont-sort')}\r\n \r\n {\" \"}\r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n \r\n\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const ImageLabelling = memo((props: any) => {\r\n const {categoryList, trainingArea} = props;\r\n\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const imageLabelDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const {activeToolOpen, setActiveToolOpen} = useActiveTool();\r\n\r\n const [labelType, setLabelType] = useState(null);\r\n const [addCategory, setAddCategory] = useState(false);\r\n const [classifyLasPrompt, setClassifyLasPrompt] = useState(false);\r\n const [closePrompt, setClosePrompt] = useState(false);\r\n const [importData, setImportData] = useState(null);\r\n const [labelLoadProgress, setLabelLoadProgress] = useState(0);\r\n const [classifyAerialProgress, setClassifyAerialProgress] = useState(0);\r\n const [trainClassifyProgress, updateTrainClassifyProgress] = useState(0);\r\n const [trainClassifyExe, setTrainClassifyExe] = useState(null);\r\n const [processType, setProcessType] = useState(\"\");\r\n const [classifyImage, setClassifyImage] = useState(false);\r\n const [readingLabelFile, setReadingLabelFile] = useState(false);\r\n const [training, setTraining] = useState(false);\r\n const [trainingURL, setTrainingURL] = useState(null);\r\n const [downloadingResources, setDownloadingResources] = useState(\"\");\r\n const [downloadResourcesDialog, setDownloadResourcesDialog] = useState(\"\");\r\n const [trainingPrompt, setTrainingPrompt] = useState(false);\r\n const [classificationPrompt, setClassificationPrompt] = useState(false);\r\n const [labelExportOpen, setLabelExportOpen] = useState(false);\r\n const [textDetection, setTextDetection] = useState(false);\r\n const assets = useSelector(selectAllAssets);\r\n const cameraFiles = getCameraFileAssets(assets);\r\n const pointCloudFiles = getPointCloudAssets(assets);\r\n\r\n const isOrthoLabel = labelType === \"ortho\";\r\n const isSceneLabel = labelType === \"scene\";\r\n const numPanoramics = cameraFiles.filter(x => x.type === AssetType.Panoramic).length;\r\n const numPlanars = cameraFiles.filter(x => x.type === AssetType.Planar).length;\r\n const canExportCSV = isSceneLabel && (numPlanars === 0);\r\n\r\n // UI progress needs to be throttled, so it doesnt update too quickly and freeze the app\r\n const progressThrottleMilliseconds = 50;\r\n\r\n const setTrainClassifyProgress = useCallback(throttle(\r\n progressThrottleMilliseconds, (value) => {\r\n updateTrainClassifyProgress(value);\r\n }), []);\r\n\r\n const resetExecutableValues = () => {\r\n setTrainClassifyProgress(0);\r\n setTrainingURL(null);\r\n setDownloadingResources(\"\");\r\n setTraining(false);\r\n setTextDetection(false);\r\n setClassifyImage(false);\r\n };\r\n\r\n const handleClose = () => {\r\n imageLabelDialog.handleClose();\r\n handleCancelProgress();\r\n };\r\n\r\n const checkClose = () => {\r\n if (isModified) {\r\n setClosePrompt(true);\r\n } else {\r\n handleClose();\r\n }\r\n };\r\n\r\n const isValidCategory = (name) => {\r\n // Uniqueness check\r\n const isUnique = viewer?.checkCategoryUniqueness(name);\r\n if (!isUnique) {\r\n toast.error(t(\"toast.labels-class-exists\"));\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n const handleCategoryChange = (state) => {\r\n setAddCategory(state);\r\n };\r\n\r\n const handleCancel = () => {\r\n handleCategoryChange(false);\r\n };\r\n\r\n const handleAddCategory = (name) => {\r\n if (!isValidCategory(name)) {\r\n return;\r\n }\r\n\r\n viewer?.addCategory(name);\r\n handleCategoryChange(false);\r\n };\r\n\r\n const handleCancelProgress = () => {\r\n trainClassifyExe?.destroy();\r\n resetExecutableValues();\r\n };\r\n\r\n const showTrainingWindow = (url) => {\r\n ipcRenderer?.send(\"show-training-window\", url);\r\n };\r\n\r\n const stopTrainingWindow = () => {\r\n ipcRenderer?.send(\"stop-training-window\");\r\n };\r\n\r\n const checkTrainingData = (jsonData) => {\r\n const canTrain = jsonData\r\n && (jsonData.annotations.length > 0)\r\n && (jsonData.images.length > 0);\r\n\r\n if (!canTrain) {\r\n toast.warning(t(\"toast.labels-not-active\"));\r\n }\r\n\r\n return canTrain;\r\n };\r\n\r\n const exportImageLabels = () => {\r\n // No labels to export\r\n if (categoryList.length === 0) {\r\n toast.warning(t(\"toast.labels-not-created\"));\r\n return;\r\n }\r\n\r\n dialog.showSaveDialog({\r\n defaultPath: viewer.projectName,\r\n filters: [\r\n ...labelFilter,\r\n ...(isOrthoLabel ? DXFModelFilter : []),\r\n ...(isOrthoLabel ? SHPModelFilter : [])\r\n ],\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n\r\n if (result.filePath) {\r\n const filePath = slash(result.filePath);\r\n const extension = path.extname(filePath);\r\n\r\n if (extension === \".dxf\") {\r\n exportToLinework(filePath, extension, \"dxf_path\");\r\n }\r\n\r\n if (extension === \".shp\") {\r\n exportToLinework(filePath, extension, \"shp_path\");\r\n }\r\n\r\n if (extension === \".3dl\") {\r\n exportLabels3DL(filePath);\r\n }\r\n }\r\n }).catch(error => {\r\n console.log(error);\r\n });\r\n };\r\n\r\n /** @private */\r\n const exportLabels3DL = (filePath) => {\r\n const jsonData = viewer?.labelObject();\r\n\r\n let text = JSON.stringify(jsonData, null, 2);\r\n fs.writeFile(filePath, text, 'utf8', (err) => {\r\n if (err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n }\r\n else {\r\n toast.success(t(\"toast.labels-export-to\", {\r\n path: path.basename(filePath)\r\n }));\r\n\r\n console.log(`File written successfully to ${filePath}`);\r\n }\r\n });\r\n };\r\n\r\n /** @private */\r\n const exportToLinework = (filePath, extension, outputKey) => {\r\n const jsonData = viewer?.labelObject();\r\n if (!checkTrainingData(jsonData)) {\r\n return false;\r\n }\r\n\r\n // Write COCO file to temp path\r\n let text = JSON.stringify(jsonData, null, 2);\r\n let tempCocoPath = getTemporaryFile(\"3dl\");\r\n\r\n try {\r\n fs.writeFileSync(tempCocoPath, text);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n return;\r\n }\r\n\r\n let pythonName;\r\n if (extension === \".dxf\") {\r\n pythonName = \"coco_to_dxf\";\r\n } else if (extension === \".shp\") {\r\n pythonName = \"coco_to_shp\";\r\n }\r\n\r\n if (!pythonName) {\r\n return;\r\n }\r\n\r\n let exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--coco_path\", tempCocoPath,\r\n `--${outputKey}`, filePath\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onClose: () => {\r\n toast.success(t(\"toast.labels-saved-linework\", {\r\n type: extension,\r\n path: path.basename(filePath)\r\n }));\r\n }\r\n });\r\n };\r\n\r\n const importImageLabels = () => {\r\n const combinedExtension = getCombinedExtension(\r\n \"dialog.supported-files\", [\r\n labelFilter,\r\n modelFilter,\r\n isOrthoLabel ? drawingFilter : null\r\n ]);\r\n\r\n dialog.showOpenDialog({\r\n properties: ['openFile'],\r\n filters: [\r\n ...combinedExtension,\r\n ...labelFilter,\r\n ...modelFilter,\r\n ...(isOrthoLabel ? drawingFilter : [])\r\n ]\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n\r\n const filePath = slash(result.filePaths[0]);\r\n const extension = path.extname(filePath);\r\n\r\n if (extension === \".pth\") {\r\n importLabelsPTH(filePath);\r\n }\r\n\r\n if (extension === \".3dl\") {\r\n importLabels3DL(filePath);\r\n }\r\n\r\n const importLinework =\r\n (extension === \".shp\")\r\n || (extension === \".dxf\")\r\n || (extension === \".zip\");\r\n\r\n if (importLinework) {\r\n importLabelsLinework(filePath);\r\n }\r\n }).catch(error => {\r\n setReadingLabelFile(false);\r\n console.log(error);\r\n });\r\n };\r\n\r\n /** @private */\r\n const importLabelsPTH = (filePath) => {\r\n setReadingLabelFile(true);\r\n\r\n const exe = new PythonExecutable();\r\n\r\n let response;\r\n let commands = [\r\n \"-p\", \"extract_coco_from_model\",\r\n \"--model_path\", filePath,\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n if (jsonData.downloading_resources) {\r\n setDownloadResourcesDialog(\"download\");\r\n } else if (jsonData.extracting_resources) {\r\n setDownloadResourcesDialog(\"extract\");\r\n } else if (jsonData.coco_data) {\r\n response = jsonData.coco_data;\r\n }\r\n },\r\n onClose: () => {\r\n setDownloadResourcesDialog(\"\");\r\n\r\n if (response) {\r\n importLabelData(response);\r\n } else {\r\n toast.error(t(\"toast.labels-read-error\"));\r\n }\r\n }\r\n });\r\n };\r\n\r\n /** @private */\r\n const importLabelsLinework = (filePath) => {\r\n setReadingLabelFile(true);\r\n\r\n const exe = new PythonExecutable();\r\n\r\n let response;\r\n let commands = [\r\n \"-p\", \"convert_linework\",\r\n \"--input_paths\", [filePath],\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n onLine: jsonData => {\r\n if (jsonData.label_data) {\r\n response = {\r\n ...jsonData.label_data,\r\n projection: LocalScene.dataProjection\r\n };\r\n }\r\n },\r\n onClose: () => {\r\n importLabelData(response);\r\n }\r\n });\r\n };\r\n\r\n /** @private */\r\n const importLabels3DL = (filePath) => {\r\n try {\r\n const text = fs.readFileSync(filePath, 'utf8');\r\n const data = JSON.parse(text);\r\n importLabelData(data);\r\n } catch {\r\n toast.error(t(\"toast.labels-read-error\"));\r\n }\r\n };\r\n\r\n /** @private */\r\n const importLabelData = (data) => {\r\n setReadingLabelFile(false);\r\n\r\n if (!data) {\r\n toast.error(t(\"toast.labels-read-error\"));\r\n return;\r\n }\r\n\r\n if (data.type !== labelType) {\r\n toast.error(t(\"toast.labels-type-mismatch\", {\r\n type: data.type\r\n }));\r\n return;\r\n }\r\n\r\n setImportData(data);\r\n };\r\n\r\n const forceInitialProgress = () => {\r\n setTrainClassifyProgress(0.001);\r\n };\r\n\r\n const cudaErrorDialog = (cudaError) => {\r\n const downloadURL = 'https://developer.nvidia.com/cuda-11.1.0-download-archive?target_os=Windows&target_arch=x86_64&target_version=10';\r\n\r\n dialog.showMessageBox({\r\n title: t(\"dialog.cuda-error-title\"),\r\n message: t(\"dialog.cuda-error-message\", {version: cudaError}),\r\n buttons: [\r\n t(\"buttons.dismiss\"),\r\n t(\"buttons.get-cuda\")\r\n ],\r\n type: 'error',\r\n noLink: true\r\n })\r\n .then(selection => {\r\n if (selection.response !== 1) return;\r\n shell.openExternal(downloadURL);\r\n });\r\n };\r\n\r\n const updateDownloadingResources = (jsonData) => {\r\n if (jsonData.downloading_resources) {\r\n setDownloadingResources(\"download\");\r\n } else if (jsonData.extracting_resources) {\r\n setDownloadingResources(\"extract\");\r\n } else {\r\n setDownloadingResources(\"\");\r\n }\r\n };\r\n\r\n const canRunClassification = () => {\r\n const imagePaths = viewer?.loadedImageLabelPaths();\r\n const canClassify = imagePaths && (imagePaths.length > 0);\r\n\r\n if (!canClassify) {\r\n toast.warning(t(\"toast.labels-no-images\"));\r\n }\r\n\r\n return canClassify;\r\n };\r\n\r\n const runClassification = (score, modelPath, runOnCPU) => {\r\n resetExecutableValues();\r\n setClassifyImage(true);\r\n\r\n let tempImagePath = getTemporaryFile(\"txt\");\r\n let imageData = viewer.loadedImageLabelPaths();\r\n let imageJSON = JSON.stringify(imageData, null, 4);\r\n\r\n try {\r\n fs.writeFileSync(tempImagePath, imageJSON);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-classify-error\"));\r\n\r\n setTraining(false);\r\n return;\r\n }\r\n\r\n try {\r\n let pythonName = isOrthoLabel\r\n ? \"image_classification_orthomosaic\"\r\n : \"image_classification_panoramic\";\r\n\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--image_paths_txt\", tempImagePath,\r\n \"--output_folder\", tempDirectoryPath,\r\n \"--prediction_model\", modelPath,\r\n \"--proj_string\", LocalScene.dataProjection,\r\n \"--prediction_score_threshold\", score,\r\n \"--run_on_cpu\", runOnCPU\r\n ];\r\n\r\n forceInitialProgress();\r\n\r\n let importData;\r\n let exe = new PythonExecutable();\r\n setTrainClassifyExe(exe);\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n updateDownloadingResources(jsonData);\r\n\r\n if (jsonData.cudaError){\r\n cudaErrorDialog(jsonData.cudaError);\r\n }\r\n\r\n if (jsonData.progress) {\r\n setTrainClassifyProgress(jsonData.progress);\r\n } else if (jsonData.coco_data) {\r\n importData = jsonData.coco_data;\r\n }\r\n },\r\n onClose: async () => {\r\n if (importData) {\r\n toast.success(t(\"toast.labels-classify-loading\"));\r\n\r\n await viewer.loadImageLabelData(\r\n importData,\r\n setLabelLoadProgress,\r\n true,\r\n false\r\n );\r\n\r\n toast.success(t(\"toast.labels-classify-loaded\"));\r\n } else {\r\n toast.error(t(\"toast.labels-classify-error\"));\r\n }\r\n\r\n resetExecutableValues();\r\n }\r\n });\r\n } catch {\r\n setClassifyImage(false);\r\n toast.error(t(\"toast.labels-classify-error\"));\r\n }\r\n };\r\n\r\n const runTraining = (numIterations, outputPath, pretrainedModelPath, runOnCPU) => {\r\n resetExecutableValues();\r\n setTraining(true);\r\n\r\n let modelPath;\r\n let tempCocoPath = path.join(outputPath, \"labels_for_training.3dl\");\r\n let tempImagePath = getTemporaryFile(\"txt\");\r\n\r\n try {\r\n const jsonData = viewer.labelObject();\r\n if (!checkTrainingData(jsonData)) {\r\n setTraining(false);\r\n return;\r\n }\r\n\r\n toast.success(t(\"toast.labels-train-submit\"));\r\n\r\n let imageData = viewer.activeImageLabelPaths();\r\n let labelJSON = JSON.stringify(jsonData, null, 4);\r\n let imageJSON = JSON.stringify(imageData, null, 4);\r\n\r\n try {\r\n fs.writeFileSync(tempImagePath, imageJSON);\r\n fs.writeFileSync(tempCocoPath, labelJSON);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n\r\n setTraining(false);\r\n return;\r\n }\r\n\r\n forceInitialProgress();\r\n\r\n let pythonName = isOrthoLabel\r\n ? \"image_training_orthomosaic\"\r\n : \"image_training_panoramic\";\r\n\r\n let exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--image_paths_txt\", tempImagePath,\r\n \"--output_folder\", outputPath,\r\n \"--coco_data_file\", tempCocoPath,\r\n \"--solver_max_iterations\", numIterations,\r\n \"--batch_size_per_image\", 256,\r\n \"--run_on_cpu\", runOnCPU\r\n ];\r\n\r\n setTrainClassifyExe(exe);\r\n\r\n if (pretrainedModelPath) {\r\n commands = [\r\n ...commands,\r\n \"--pretrained_model_pth\",\r\n pretrainedModelPath\r\n ];\r\n }\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n updateDownloadingResources(jsonData);\r\n if (jsonData.cudaError){\r\n cudaErrorDialog(jsonData.cudaError);\r\n } else if (jsonData.gpu_memory_error) {\r\n toast.error(t(\"toast.labels-train-error-memory\"));\r\n } else if (jsonData.model_diverge_error){\r\n toast.error(t(\"toast.labels-train-error-diverge\"));\r\n } else if (jsonData.label_bounds_error){\r\n toast.error(t(\"toast.labels-train-error-bounds\"));\r\n } else if (jsonData.progress) {\r\n setTrainClassifyProgress(jsonData.progress);\r\n } else if (jsonData.model_file_path) {\r\n modelPath = jsonData.model_file_path;\r\n } else if (jsonData.url) {\r\n setTrainingURL(jsonData.url);\r\n showTrainingWindow(jsonData.url);\r\n } else if (jsonData.class_number_mismatch) {\r\n toast.error(t(\"toast.labels-train-error-class\", {\r\n oldClasses: jsonData.old_classes.join(\", \"),\r\n newClasses: jsonData.new_classes.join(\", \")\r\n }));\r\n }\r\n },\r\n onClose: () => {\r\n if (modelPath) {\r\n toast.success(t(\"toast.labels-train-complete\", {\r\n path: modelPath\r\n }));\r\n } else {\r\n toast.warning(t(\"toast.labels-train-incomplete\"));\r\n }\r\n\r\n stopTrainingWindow();\r\n resetExecutableValues();\r\n }\r\n });\r\n }\r\n catch (err ){\r\n console.log(err);\r\n setTraining(false);\r\n toast.error(t(\"toast.labels-train-error\"));\r\n }\r\n };\r\n\r\n const runTextDetection = (score, spellcheck) => {\r\n resetExecutableValues();\r\n setTextDetection(true);\r\n\r\n let spellcheckCommand = spellcheck\r\n ? t('general.true')\r\n : t('general.false');\r\n\r\n let tempCocoPath = getTemporaryFile(\"3dl\");\r\n let tempImagePath = getTemporaryFile(\"txt\");\r\n\r\n try {\r\n const jsonData = viewer?.labelObject();\r\n if (!checkTrainingData(jsonData)) {\r\n setTextDetection(false);\r\n return;\r\n }\r\n\r\n let imageData = viewer.activeImageLabelPaths();\r\n let labelJSON = JSON.stringify(jsonData, null, 4);\r\n let imageJSON = JSON.stringify(imageData, null, 4);\r\n\r\n try {\r\n fs.writeFileSync(tempImagePath, imageJSON);\r\n fs.writeFileSync(tempCocoPath, labelJSON);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.labels-export-failed\"));\r\n\r\n setTextDetection(false);\r\n return;\r\n }\r\n\r\n let pythonName = \"text_from_image\";\r\n let commands = [\r\n \"-p\", pythonName,\r\n \"--image_paths_txt\", tempImagePath,\r\n \"--coco_data_file\", tempCocoPath,\r\n \"--score_threshold\", score,\r\n \"--spell_check\", spellcheckCommand\r\n ];\r\n\r\n forceInitialProgress();\r\n\r\n let importData;\r\n let exe = new PythonExecutable();\r\n setTrainClassifyExe(exe);\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n updateDownloadingResources(jsonData);\r\n\r\n if (jsonData.cudaError){\r\n cudaErrorDialog(jsonData.cudaError);\r\n }\r\n\r\n if (jsonData.progress) {\r\n setTrainClassifyProgress(jsonData.progress);\r\n } else if (jsonData.coco_data) {\r\n importData = jsonData.coco_data;\r\n }\r\n },\r\n onClose: async () => {\r\n if (importData) {\r\n toast.success(t(\"toast.labels-text-loading\"));\r\n\r\n await viewer.loadImageLabelData(\r\n importData,\r\n setLabelLoadProgress,\r\n true,\r\n false\r\n );\r\n\r\n toast.success(t(\"toast.labels-text-loaded\"));\r\n } else {\r\n toast.error(t(\"toast.labels-text-error\"));\r\n }\r\n\r\n resetExecutableValues();\r\n }\r\n });\r\n } catch {\r\n setTextDetection(false);\r\n toast.error(t(\"toast.labels-classify-error\"));\r\n }\r\n };\r\n\r\n const canRunAerialToLas = () => {\r\n const LASfiles = pointCloudFiles.filter(x => x.type === AssetType.LAS);\r\n const visibleClouds = LASfiles.filter(x => x.visible);\r\n\r\n if (visibleClouds.length === 0) {\r\n toast.warning(t(\"toast.labels-no-clouds\"));\r\n }\r\n\r\n if (!isModified) {\r\n toast.warning(t(\"toast.labels-no-categories\"));\r\n }\r\n\r\n return isModified && (visibleClouds.length > 0);\r\n };\r\n\r\n useEffect(() => {\r\n /** Keep track if a tool is currently being used */\r\n setActiveToolOpen(imageLabelDialog.open);\r\n }, [imageLabelDialog.open]);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n imageLabelDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-label-ortho\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n imageLabelDialog.handleOpen(\"ortho\");\r\n });\r\n\r\n registerEvent(\"open-label-scene\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n imageLabelDialog.handleOpen(\"scene\");\r\n });\r\n }, [activeToolOpen]);\r\n\r\n useEffect(() => {\r\n if (!imageLabelDialog.open) return;\r\n\r\n const onKeyDown = event => {\r\n if (event.target instanceof HTMLInputElement) {\r\n return;\r\n }\r\n\r\n viewer?.labelHotkey(event);\r\n };\r\n\r\n window.addEventListener('keydown', onKeyDown, false);\r\n\r\n return () => {\r\n window.removeEventListener('keydown', onKeyDown, false);\r\n };\r\n }, [imageLabelDialog.open]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.setActiveLabelType(labelType);\r\n\r\n if (isOrthoLabel) {\r\n dispatch(changeSwitched(true));\r\n } else if (isSceneLabel) {\r\n dispatch(changeSwitched(false));\r\n }\r\n }, [viewer, labelType]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n setLabelType(imageLabelDialog.data);\r\n }, [viewer, imageLabelDialog.data]);\r\n\r\n useEffect(() => {\r\n if (classifyImage) {\r\n setProcessType(\"labels.image-classification\");\r\n } else if (training) {\r\n setProcessType(\"labels.training\");\r\n } else if (textDetection) {\r\n setProcessType(\"labels.text-detection\");\r\n }\r\n\r\n if (trainClassifyProgress === 100) {\r\n setTrainClassifyProgress(0);\r\n setProcessType(\"\");\r\n }\r\n }, [\r\n trainClassifyProgress,\r\n classifyImage,\r\n training,\r\n textDetection\r\n ]);\r\n\r\n const isModified = categoryList.length !== 0;\r\n const exportDisabled = viewer?.anyLabelSelected();\r\n const trainingLinkDisabled = trainingURL === null;\r\n const sceneTrainingDisabled = isSceneLabel\r\n && (numPanoramics > 0)\r\n && (numPlanars > 0);\r\n const categoryListDisabled = sceneTrainingDisabled;\r\n const hasTrainingArea = trainingArea.length > 0;\r\n\r\n const labelDisabled = (labelLoadProgress > 0)\r\n || training\r\n || classifyImage\r\n || textDetection;\r\n\r\n const localizedProcessType = t(processType);\r\n\r\n const modalName = isOrthoLabel\r\n ? t('labels.orthomosaic-training-classification')\r\n : t('labels.panoramic-training-classification');\r\n\r\n const downloadTooltip = downloadingResources\r\n ? \"\"\r\n : t('labels.running-process-on-dataset', {\r\n process: localizedProcessType\r\n });\r\n\r\n return (\r\n \r\n \r\n {/* Label toolbar icons */}\r\n \r\n\r\n {/* Add category */}\r\n handleCategoryChange(true)}\r\n success\r\n disabled={categoryListDisabled}\r\n />\r\n\r\n {/* Enable training areas */}\r\n {\r\n viewer?.addTrainingArea();\r\n }}\r\n />\r\n\r\n {/* Disable training areas */}\r\n {\r\n viewer?.deleteTrainingArea();\r\n }}\r\n />\r\n\r\n {/* Run Training */}\r\n {\r\n setTrainingPrompt(true);\r\n }}\r\n disabled={categoryListDisabled || labelDisabled}\r\n />\r\n\r\n {/* Run Classification */}\r\n {\r\n if (!canRunClassification()) {\r\n return;\r\n }\r\n\r\n setClassificationPrompt(true);\r\n }}\r\n disabled={categoryListDisabled || labelDisabled}\r\n />\r\n\r\n {/* Classify Las from Classes */}\r\n {\r\n if (!canRunAerialToLas()) {\r\n return;\r\n }\r\n\r\n setClassifyLasPrompt(true);\r\n }}\r\n visible={isOrthoLabel}\r\n disabled={categoryListDisabled || labelDisabled}\r\n />\r\n\r\n {/* Import label file */}\r\n \r\n\r\n {/* Export Label file */}\r\n \r\n\r\n {/* Export label intersects */}\r\n {\r\n if (!canRunClassification()) {\r\n return;\r\n }\r\n\r\n setLabelExportOpen(true);\r\n }}\r\n disabled={!canExportCSV || exportDisabled || labelDisabled}\r\n />\r\n\r\n \r\n\r\n \r\n\r\n {(trainClassifyProgress > 0) && (\r\n\r\n
\r\n\r\n \r\n\r\n {/** Training/Classification progress */}\r\n
\r\n \r\n
\r\n\r\n
\r\n\r\n {/** Tensorbard training link */}\r\n {training && (\r\n {\r\n showTrainingWindow(trainingURL);\r\n }}\r\n />\r\n )}\r\n\r\n {/** Training/Classification cancel button */}\r\n \r\n
\r\n\r\n\r\n
)}\r\n\r\n {/** Downloading resources */}\r\n {(downloadingResources === \"download\") && (\r\n \r\n {t('labels.downloading-resources')} \r\n \r\n )}\r\n\r\n {/** Extracting resources */}\r\n {(downloadingResources === \"extract\") && (\r\n \r\n {t('labels.extracting-resources')} \r\n \r\n )}\r\n\r\n {sceneTrainingDisabled && (\r\n \r\n {t('labels.image-classification-is-not-supported-for-mixed-camera')}\r\n \r\n )}\r\n\r\n {(numPlanars > 0) && (\r\n \r\n {t('labels.label-analysis-is-disabled-for-planar-images')}\r\n \r\n )}\r\n\r\n {!categoryListDisabled && (\r\n \r\n {/** Training areas */}\r\n {hasTrainingArea && (\r\n \r\n {trainingArea.map(areas =>\r\n )}\r\n \r\n\r\n \r\n )}\r\n\r\n {/** Standard categories */}\r\n \r\n {categoryList.map(category =>\r\n )}\r\n \r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n {/* Close modal */}\r\n setClosePrompt(false)}\r\n onSubmit={() => {\r\n handleClose();\r\n setClosePrompt(false);\r\n }}\r\n title={t('labels.close-classification-window')}\r\n prompt={t('labels.do-you-want-to-close-the-window', {\r\n name: modalName\r\n })}\r\n button={t('buttons.close')}\r\n />\r\n\r\n {/* Set training parameters */}\r\n \r\n\r\n {/* Set classification parameters */}\r\n \r\n\r\n {/* Set classify from las parameters */}\r\n \r\n\r\n {/* Image label import percent dialog */}\r\n 0}\r\n text={t('labels.applying_point_cloud_classification')}\r\n percent={classifyAerialProgress}\r\n />\r\n\r\n {/* Image label import percent dialog */}\r\n 0}\r\n text={t('labels.importing-image-labels')}\r\n percent={labelLoadProgress}\r\n />\r\n\r\n \r\n \r\n \r\n {t('labels.reading-label-file')} \r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n {/** Downloading resources (modal) */}\r\n {(downloadResourcesDialog === \"download\") && (\r\n \r\n {t('labels.downloading-resources')} \r\n \r\n )}\r\n\r\n {/** Extracting resources (modal) */}\r\n {(downloadResourcesDialog === \"extract\") && (\r\n \r\n {t('labels.extracting-resources')} \r\n \r\n )}\r\n\r\n \r\n \r\n\r\n {/* Modal for importing linework data */}\r\n \r\n\r\n {/* Modal for exporting label intersections */}\r\n \r\n\r\n
\r\n );\r\n});\r\n","import React from 'react';\r\nimport ControlPointIcon from '@material-ui/icons/ControlPoint';\r\nimport {createStyles, makeStyles, Theme} from \"@material-ui/core/styles\";\r\nimport { Box } from '@material-ui/core';\r\nimport { aerialObsColor, imageObsColor, pointObsColor } from '../viewer/js/data-aligner';\r\nimport clsx from 'clsx';\r\nimport { EnhancedIconButton } from '../components';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n aerialObservationSuccess: {\r\n color: `#${aerialObsColor.toString(16)}`\r\n },\r\n imageObservationSuccess: {\r\n color: `#${imageObsColor.toString(16)}`\r\n },\r\n pointObservationSuccess: {\r\n color: `#${pointObsColor.toString(16)}`\r\n },\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n error: {\r\n color: theme.palette.error.main\r\n },\r\n info: {\r\n color: theme.palette.info.main\r\n },\r\n errorLow: {\r\n color: theme.palette.success.main\r\n },\r\n errorMedium: {\r\n color: theme.palette.warning.main\r\n },\r\n errorHigh: {\r\n color: theme.palette.error.main\r\n },\r\n }),\r\n);\r\n\r\nexport const PointObservationIcon = (props) => {\r\n const classes = useStyles();\r\n return ObservationIcon({...props, color: classes.pointObservationSuccess});\r\n};\r\n\r\nexport const AerialObservationIcon = (props) => {\r\n const classes = useStyles();\r\n return ObservationIcon({...props, color: classes.aerialObservationSuccess});\r\n};\r\n\r\nexport const ImageObservationIcon = (props) => {\r\n const classes = useStyles();\r\n return ObservationIcon({...props, color: classes.imageObservationSuccess});\r\n};\r\n\r\nconst ObservationIcon = (props) => {\r\n const {color, selected, clicked, ...other} = props;\r\n const classes = useStyles();\r\n\r\n let buttonColor;\r\n\r\n if (clicked) {\r\n buttonColor = classes.info;\r\n } else if (selected) {\r\n buttonColor = color;\r\n } else {\r\n buttonColor = classes.error;\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const ObservationError = (props) => {\r\n const {value, lowCutoff, highCutoff} = props;\r\n const classes = useStyles();\r\n const isNumber = !isNaN(parseFloat(value));\r\n\r\n if (!isNumber) {\r\n return {\"N/A\"};\r\n }\r\n\r\n return (\r\n = lowCutoff),\r\n [classes.errorHigh]: (value >= highCutoff)\r\n })}>\r\n {value.toFixed(2)}\r\n \r\n );\r\n};","import React, {useEffect, useState, memo, useMemo} from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport {createStyles, makeStyles, Theme, useTheme} from \"@material-ui/core/styles\";\r\nimport {Checkbox} from \"@material-ui/core\";\r\nimport DialogActions from '@material-ui/core/DialogActions';\r\nimport DialogContent from '@material-ui/core/DialogContent';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport { useSelector, useDispatch } from 'react-redux';\r\nimport {\r\n EnhancedTable,\r\n DraggableDialog,\r\n PromptDialog\r\n} from '../components';\r\nimport { PythonExecutable, trackToolUsage } from '../executable';\r\nimport { fse, getTemporaryFile, registerEvent} from '../electron-modules';\r\nimport {\r\n getMatrixValues,\r\n saveMatrixFile,\r\n saveProject\r\n} from \"../utilities\";\r\nimport path from 'path';\r\nimport {\r\n changeBasicAdjustments,\r\n changeCameraTransform,\r\n selectBasicAdjustments,\r\n selectCameraTransform,\r\n selectActiveCamera\r\n} from '../redux/camera-slice';\r\nimport { selectAllAssets, getCameraFileAssets } from '../redux/assets-slice';\r\nimport LocalScene, { SceneCoordinate } from '../viewer/js/projections';\r\nimport { toast } from '../app';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { ImageObservationIcon, ObservationError, PointObservationIcon } from './observations';\r\nimport { AlignerObservation } from '../viewer/js/data-aligner';\r\nimport { UnitConverter } from '../viewer/js/utilities';\r\nimport {\r\n useDialog,\r\n useUniqueProjectID,\r\n useViewer,\r\n useActiveTool\r\n} from '../hooks';\r\nimport { useTableState } from '../hooks/use-table-state';\r\nimport { writeToString } from 'fast-csv';\r\n\r\nconst converter = new UnitConverter();\r\n\r\nconst highCutoff = 1.0;\r\nconst lowCutoff = 0.5;\r\nconst requiredRows = 5;\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n minHeightContent: {\r\n minHeight: \"100px\"\r\n },\r\n toggleOptionParent: {\r\n margin: theme.spacing(0),\r\n padding: theme.spacing(0),\r\n boxShadow: \"0px 10px 10px 2px\",\r\n justifyContent: \"center\"\r\n },\r\n toggleOptionCheckbox: {\r\n paddingTop: theme.spacing(0.5),\r\n paddingBottom: theme.spacing(0.5)\r\n },\r\n toggleOptionFlex: {\r\n flex: 1,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n userWarning: {\r\n padding: theme.spacing(3)\r\n },\r\n box: {\r\n padding: theme.spacing(4)\r\n },\r\n marginBottom: {\r\n marginBottom: theme.spacing(2)\r\n },\r\n adornedEnd: {\r\n paddingRight: theme.spacing(0)\r\n },\r\n utmButton: {\r\n marginLeft: theme.spacing(1)\r\n },\r\n selectMargin: {\r\n margin: theme.spacing(1),\r\n },\r\n button: {\r\n marginTop: theme.spacing(2),\r\n marginLeft: theme.spacing(1)\r\n },\r\n dropdown: {\r\n minWidth: 200,\r\n },\r\n formControl: {\r\n width: '100%'\r\n },\r\n buttonDiv: {\r\n textAlign: \"right\"\r\n },\r\n success: {\r\n color: theme.palette.success.main\r\n },\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n error: {\r\n color: theme.palette.error.main\r\n },\r\n info: {\r\n color: theme.palette.info.main\r\n },\r\n assetCheckbox: {\r\n position: \"relative\",\r\n transform: \"translateY(0%)\"\r\n },\r\n checkboxPadding: {\r\n padding: \"0px\"\r\n },\r\n matrixValuesParent: {\r\n display: \"flex\",\r\n paddingTop: theme.spacing(2),\r\n justifyContent: \"space-evenly\"\r\n },\r\n matrixValues: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n textAlign: \"center\"\r\n }\r\n }),\r\n);\r\n\r\nconst ResidualError = (props) => {\r\n return ;\r\n};\r\n\r\nexport const ImageAlignerAdvanced = memo((props: any) => {\r\n const observations = props.observations as AlignerObservation[];\r\n\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const theme = useTheme();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const tableState = useTableState();\r\n const alignerAdvDialog = useDialog();\r\n const removeDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const {activeToolOpen, setActiveToolOpen} = useActiveTool();\r\n\r\n const [calculating, setCalculating] = useState(false);\r\n const [alignerMatrixPath, setAlignerMatrixPath] = useState(null);\r\n const [closePrompt, setClosePrompt] = useState(false);\r\n const [alignPosition, setAlignPosition] = useState(true);\r\n const [alignRotation, setAlignRotation] = useState(true);\r\n const [newRotation, setNewRotation] = useState([0,0,0]);\r\n const [newOffset, setNewOffset] = useState([0,0,0]);\r\n const units = LocalScene.dataProjectionUnits;\r\n\r\n const cameraTransformPath = useSelector(selectCameraTransform);\r\n const currentCamera = useSelector(selectActiveCamera);\r\n const basicAdjustments = useSelector(selectBasicAdjustments);\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const camerasFiles = getCameraFileAssets(assets);\r\n\r\n const exportCSV = async () => {\r\n let observationsCSV = [];\r\n let tmpObservationPath = getTemporaryFile('csv');\r\n\r\n let encompassCSV = [];\r\n let tmpEncompassPath = getTemporaryFile('csv');\r\n\r\n encompassCSV.push([\r\n 'filename', 'X', 'Y', 'Z', 'Roll', 'Pitch', 'Yaw'\r\n ]);\r\n\r\n observationsCSV.push([\r\n 'filename', 'x_img', 'y_img', 'z_img',\r\n 'x_ground', 'y_ground', 'z_ground'\r\n ]);\r\n\r\n observations.forEach(observation => {\r\n const {imageObs, pointObs, name, pose} = observation;\r\n\r\n observationsCSV.push([\r\n name,\r\n imageObs.x, imageObs.y, imageObs.z,\r\n pointObs.x, pointObs.y, pointObs.z\r\n ]);\r\n\r\n encompassCSV.push(pose);\r\n });\r\n\r\n const observationsCSVContent = await writeToString(observationsCSV);\r\n await fse.writeFile(tmpObservationPath, observationsCSVContent);\r\n\r\n const encompassCSVContent = await writeToString(encompassCSV);\r\n await fse.writeFile(tmpEncompassPath, encompassCSVContent);\r\n\r\n return {tmpObservationPath, tmpEncompassPath};\r\n };\r\n\r\n const runCalculation = async () => {\r\n const {tmpObservationPath, tmpEncompassPath} = await exportCSV();\r\n\r\n let exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", \"camera_aligner_advanced\",\r\n \"--csv_obs\", tmpObservationPath,\r\n \"--csv_encompass\", tmpEncompassPath,\r\n \"--sulphur\", true,\r\n \"--align_position\", alignPosition,\r\n \"--align_rotation\", alignRotation,\r\n \"--units\", LocalScene.dataProjectionUnits\r\n ];\r\n\r\n let isConverted = false;\r\n let largeResiduals = false;\r\n\r\n let camPoseEntry = observations[0].pose;\r\n let initialPath = path.dirname(camPoseEntry[0]);\r\n let nameCorrection = path.basename(initialPath);\r\n let correctionName = nameCorrection + \"_correction_matrix.4x4\";\r\n let correctionPath = path.join(initialPath, correctionName);\r\n\r\n setCalculating(true);\r\n trackToolUsage(\"aligner-advanced\");\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n let residualsTemp = parseResiduals(jsonData);\r\n if (residualsTemp.length === 0) return;\r\n\r\n isConverted = true;\r\n viewer.setErrorsCameraAligner(residualsTemp);\r\n largeResiduals = residualsTemp\r\n .filter(x => x > highCutoff).length > 0;\r\n },\r\n onClose: () => {\r\n setCalculating(false);\r\n\r\n if (!isConverted) {\r\n return toast.error(t(\"toast.aligner-failed\"));\r\n }\r\n\r\n toast.success(t(\"toast.alignment-completed\"));\r\n setAlignerMatrixPath(correctionPath);\r\n\r\n if (largeResiduals) {\r\n toast.warning(t(\"toast.data-aligner-adv-large-error\"));\r\n }\r\n }\r\n });\r\n\r\n };\r\n\r\n const parseResiduals = (jsonData) => {\r\n let resArray = [];\r\n\r\n if (jsonData) {\r\n jsonData.forEach(res => {\r\n let rounded = Math.round(parseFloat(res) * 100) / 100;\r\n resArray.push(rounded);\r\n });\r\n }\r\n\r\n return resArray;\r\n };\r\n\r\n const addNewRow = () => {\r\n viewer.generateAdvancedAlignerRows(1);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const onDelete = (row) => {\r\n viewer.deleteRowCameraAligner(row.id);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const onClick = (row, index) => {\r\n if (index !== 0) return;\r\n\r\n const observation = observations.find(x => x.id === row.id);\r\n if (!observation) return;\r\n\r\n const camID = observation.imageIdentifier;\r\n const position = observation.imageMesh?.position;\r\n\r\n if (!position) return;\r\n\r\n const lookat = new SceneCoordinate(position).toDataProjection();\r\n viewer.loadImage(camID, {lookat});\r\n viewer.flashObservations(observation.id);\r\n };\r\n\r\n const onCancel = () => {\r\n setAlignerMatrixPath(null);\r\n viewer.clearErrorsCameraAligner();\r\n dispatch(changeCameraTransform(null));\r\n };\r\n\r\n const onClearAlignments = () => {\r\n dispatch(changeBasicAdjustments({}));\r\n viewer?.resetBasicAlignerCamera();\r\n saveProject(false);\r\n onCancel();\r\n };\r\n\r\n const confirmAlignment = () => {\r\n dispatch(changeCameraTransform(alignerMatrixPath));\r\n };\r\n\r\n const saveAlignmentFile = () => {\r\n saveMatrixFile(cameraTransformPath);\r\n };\r\n\r\n const handleAlignPositionCheck = () => {\r\n setAlignPosition(!alignPosition);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const handleAlignRotationCheck = () => {\r\n setAlignRotation(!alignRotation);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const checkClose = () => {\r\n if (!hasAlignment && !isTableEmpty()) {\r\n setClosePrompt(true);\r\n } else {\r\n alignerAdvDialog.handleClose();\r\n }\r\n };\r\n\r\n const onImageClick = (id) => {\r\n viewer.setCurrentObservation(id, 'image');\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const onSceneClick = (id) => {\r\n viewer.setCurrentObservation(id, 'point');\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const isTableEmpty = () => {\r\n const filledRows = observations.filter(observation => {\r\n return observation.pointObs || observation.imageObs;\r\n });\r\n\r\n return filledRows.length === 0;\r\n };\r\n\r\n const isTableFilled = () => {\r\n const filledRows = observations.filter(observation => {\r\n return observation.pointObs && observation.imageObs;\r\n });\r\n\r\n return filledRows.length === observations.length;\r\n };\r\n\r\n const getTransformValues = async (filePath) => {\r\n const cameraTransform = await getMatrixValues(filePath);\r\n\r\n let offset;\r\n if (cameraTransform.success) {\r\n offset = [\r\n converter.convert(cameraTransform.offset.x, \"m\", units, 2),\r\n converter.convert(cameraTransform.offset.y, \"m\", units, 2),\r\n converter.convert(cameraTransform.offset.z, \"m\", units, 2)\r\n ];\r\n } else {\r\n offset = [0,0,0];\r\n }\r\n\r\n let rotation;\r\n if (cameraTransform.success) {\r\n rotation = [\r\n cameraTransform.rotation.x.toFixed(2),\r\n cameraTransform.rotation.y.toFixed(2),\r\n cameraTransform.rotation.z.toFixed(2)\r\n ];\r\n } else {\r\n rotation = [0,0,0];\r\n }\r\n\r\n setNewRotation(rotation);\r\n setNewOffset(offset);\r\n };\r\n\r\n useEffect(() => {\r\n /** Keep track if a tool is currently being used */\r\n setActiveToolOpen(alignerAdvDialog.open);\r\n }, [alignerAdvDialog.open]);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n alignerAdvDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-image-aligner-adv\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n alignerAdvDialog.handleOpen();\r\n });\r\n }, [activeToolOpen]);\r\n\r\n useEffect(() => {\r\n const aligned = cameraTransformPath !== null;\r\n const removed = currentCamera === null;\r\n const noCameras = camerasFiles.length === 0;\r\n\r\n if (aligned && removed && noCameras) {\r\n removeDialog.handleOpen();\r\n }\r\n }, [currentCamera]);\r\n\r\n useEffect(() => {\r\n getTransformValues(alignerMatrixPath);\r\n }, [alignerMatrixPath]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n viewer.toggleCameraAligner(alignerAdvDialog.open);\r\n if (!alignerAdvDialog.open) return;\r\n\r\n viewer.generateAdvancedAlignerRows(requiredRows);\r\n }, [viewer, alignerAdvDialog.open]);\r\n\r\n const getRows = (observations, calculating) => {\r\n return observations.map(observation => {\r\n const disabled = calculating;\r\n\r\n const imageSelected = !!observation.imageObs;\r\n const imageClicked = observation.imageSelected;\r\n\r\n const pointSelected = !!observation.pointObs;\r\n const pointClicked = observation.pointSelected;\r\n\r\n const imageObs = (\r\n {\r\n if (disabled) return;\r\n onImageClick(observation.id);\r\n }}\r\n />\r\n );\r\n\r\n const pointObs = (\r\n {\r\n if (disabled) return;\r\n onSceneClick(observation.id);\r\n }}\r\n />\r\n );\r\n\r\n const error = (\r\n \r\n );\r\n\r\n return {\r\n id: observation.id,\r\n name: t(observation.name),\r\n img_obs: imageObs,\r\n pc_obs: pointObs,\r\n error,\r\n disabled\r\n };\r\n });\r\n };\r\n\r\n const calculated = !!alignerMatrixPath;\r\n const hasBasicAlignment = Object.keys(basicAdjustments).length !== 0;\r\n const hasAdvancedAlignment = !!cameraTransformPath;\r\n const hasAlignment = hasBasicAlignment || hasAdvancedAlignment;\r\n\r\n const canSubmit = isTableFilled()\r\n && observations.length >= requiredRows\r\n && (alignPosition || alignRotation)\r\n && !calculating;\r\n\r\n const columns = [\r\n {\r\n id: 'name',\r\n label: t(\"data-aligner-adv.filename\"),\r\n pointer: true,\r\n wordBreak: true\r\n },\r\n {\r\n id: 'img_obs',\r\n label: t(\"data-aligner-adv.image-control\"),\r\n center: true,\r\n sortable: false\r\n },\r\n {\r\n id: 'pc_obs',\r\n label: t(\"data-aligner-adv.point-control\"),\r\n center: true,\r\n sortable: false\r\n },\r\n {\r\n id: 'error',\r\n label: t(\"data-aligner-adv.error\") + '(\\u00B0)',\r\n numeric: true,\r\n center: true\r\n }\r\n ];\r\n\r\n const rows = useMemo(() => {\r\n return getRows(observations, calculating);\r\n }, [observations, calculating]);\r\n\r\n const actions = [\r\n {\r\n title: t(\"buttons.delete\"),\r\n icon: ,\r\n onClick: (row) => {\r\n deleteDialog.handleOpen(row);\r\n }\r\n }\r\n ];\r\n\r\n return (\r\n \r\n\r\n \r\n {/** Clear previous alignment */}\r\n {hasAlignment && (\r\n \r\n \r\n {t(\"data-aligner-adv.have-set-alignment\")}\r\n \r\n \r\n\r\n \r\n\r\n {/** Download saved alignment matrix */}\r\n {hasAdvancedAlignment && (\r\n \r\n )}\r\n\r\n {/** Clear all previous alignments */}\r\n \r\n\r\n \r\n )}\r\n\r\n {/** Standard conditions */}\r\n {!hasAlignment && (\r\n \r\n \r\n {t(\"data-aligner-adv.select-at-least\", {requiredRows})}\r\n \r\n\r\n \r\n\r\n \r\n\r\n {calculated && (
\r\n \r\n {t('data-aligner-adv.matrix_offset_units', {units})}: [{newOffset[0]}, {newOffset[1]}, {newOffset[2]}]\r\n \r\n\r\n \r\n {t('data-aligner-adv.matrix_rotation')}: [{newRotation[0]}, {newRotation[1]}, {newRotation[2]}]\r\n \r\n
)}\r\n\r\n \r\n {/** Add new observation row */}\r\n \r\n\r\n {/** Cancel calculated alignment */}\r\n {calculated && (\r\n \r\n )}\r\n\r\n {/** Run python calculations */}\r\n {!calculated && (\r\n \r\n )}\r\n\r\n {/** Confirm alignment */}\r\n {calculated && (\r\n \r\n )}\r\n \r\n\r\n \r\n {/* Calculate lever arm */}\r\n
\r\n \r\n {t('data-aligner-adv.allow_offset')}\r\n \r\n \r\n
\r\n\r\n {/* Calculate rotation */}\r\n
\r\n \r\n {t('data-aligner-adv.allow_rotation')}\r\n \r\n \r\n
\r\n
\r\n\r\n
)}\r\n\r\n \r\n\r\n {/* Delete Dialog */}\r\n {\r\n onDelete(deleteDialog.data);\r\n deleteDialog.handleClose();\r\n }}\r\n title={t(\"enhanced-table.prompt-delete-title\")}\r\n prompt={t('data-aligner-adv.do_you_want_to_delete_this_observation')}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n setClosePrompt(false)}\r\n onSubmit={() => {\r\n alignerAdvDialog.handleClose();\r\n setClosePrompt(false);\r\n }}\r\n title={t(\"data-aligner-adv.prompt-close-aligner-title\")}\r\n prompt={t(\"data-aligner-adv.prompt-close-aligner-text\")}\r\n button={t('buttons.close')}\r\n />\r\n\r\n {\r\n dispatch(changeCameraTransform(null));\r\n removeDialog.handleClose();\r\n }}\r\n title={t(\"data-aligner-adv.prompt-remove-matrix-title\")}\r\n prompt={t(\"data-aligner-adv.prompt-remove-matrix-text\")}\r\n button={t('buttons.remove-matrix')}\r\n />\r\n
\r\n );\r\n});\r\n","import React, {useEffect, useState, memo} from 'react';\r\nimport { createStyles, makeStyles, Theme } from \"@material-ui/core/styles\";\r\nimport {\r\n Box,\r\n Button,\r\n DialogActions,\r\n DialogContent,\r\n Grid,\r\n Typography\r\n} from '@material-ui/core';\r\nimport { DraggableDialog, PromptDialog } from '../components';\r\nimport clsx from 'clsx';\r\nimport {\r\n changeBasicAdjustments,\r\n changeCameraTransform,\r\n selectBasicAdjustments,\r\n selectCameraTransform,\r\n selectActiveCamera\r\n} from '../redux/camera-slice';\r\nimport { useSelector, useDispatch } from 'react-redux';\r\nimport { saveProject } from \"../utilities\";\r\nimport { trackToolUsage } from \"../executable\";\r\nimport { toast } from '../app';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport {isEqual} from 'lodash';\r\nimport {\r\n useDialog,\r\n useUniqueProjectID,\r\n useViewer,\r\n useActiveTool\r\n} from '../hooks';\r\nimport { registerEvent } from '../electron-modules';\r\nimport { Vector3 } from 'three';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n minHeightContent: {\r\n minHeight: \"100px\"\r\n },\r\n titleTop: {\r\n marginTop: theme.spacing(2.0)\r\n },\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n success: {\r\n color: theme.palette.success.main\r\n }\r\n }),\r\n);\r\n\r\nconst AlignerShortcuts = () => {\r\n const {t} = useTranslation();\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n {t(\"data-aligner-basic.adjust-roll\")} (-):\r\n {t(\"data-aligner-basic.keypad\")} 7\r\n \r\n \r\n\r\n \r\n \r\n \r\n {t(\"data-aligner-basic.adjust-roll\")} (+):\r\n {t(\"data-aligner-basic.keypad\")} 9\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"data-aligner-basic.adjust-pitch\")} (-):\r\n {t(\"data-aligner-basic.keypad\")} 4\r\n \r\n \r\n\r\n \r\n \r\n \r\n {t(\"data-aligner-basic.adjust-pitch\")} (+):\r\n {t(\"data-aligner-basic.keypad\")} 6\r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n {t(\"data-aligner-basic.adjust-yaw\")} (-):\r\n {t(\"data-aligner-basic.keypad\")} 1\r\n \r\n \r\n\r\n \r\n \r\n \r\n {t(\"data-aligner-basic.adjust-yaw\")} (+):\r\n {t(\"data-aligner-basic.keypad\")} 3\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const ImageAlignerBasic = memo(() => {\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const alignerBasicDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const {activeToolOpen, setActiveToolOpen} = useActiveTool();\r\n\r\n const [singleAlignment, setSingleAlignment] = useState([0, 0, 0]);\r\n const [closePrompt, setClosePrompt] = useState(false);\r\n const [hasTransform, setHasTransform] = useState(false);\r\n const currentCamera = useSelector(selectActiveCamera);\r\n const basicAdjustments = useSelector(selectBasicAdjustments);\r\n const cameraTransformPath = useSelector(selectCameraTransform);\r\n\r\n const handleClose = () => {\r\n alignerBasicDialog.handleClose();\r\n setClosePrompt(false);\r\n };\r\n\r\n const checkClose = () => {\r\n if (isModified) {\r\n setClosePrompt(true);\r\n } else {\r\n handleClose();\r\n }\r\n };\r\n\r\n const resetAligner = () => {\r\n viewer?.resetBasicAlignerCamera(savedAngle);\r\n toast.success(t(\"toast.alignment-reset\"));\r\n };\r\n\r\n const saveAdjustment = () => {\r\n const updated = {...basicAdjustments};\r\n\r\n const vector = new Vector3(...alignment);\r\n const valid = vector.length() !== 0;\r\n\r\n if (valid) {\r\n updated[currentCamera] = alignment;\r\n } else {\r\n delete updated[currentCamera];\r\n }\r\n\r\n dispatch(changeBasicAdjustments(updated));\r\n viewer?.resetBasicAlignerCamera(alignment);\r\n saveProject(false);\r\n\r\n trackToolUsage(\"aligner-basic\");\r\n toast.success(t(\"toast.alignment-saved\"));\r\n };\r\n\r\n const cancelAdvancedAlignment = () => {\r\n dispatch(changeCameraTransform(null));\r\n saveProject(false);\r\n };\r\n\r\n const checkDataModified = () => {\r\n if (!hasActiveCamera) return false;\r\n\r\n const epsilon = 1e-10;\r\n const dx = Math.abs(savedAngle[0] - singleAlignment[0]) < epsilon;\r\n const dy = Math.abs(savedAngle[1] - singleAlignment[1]) < epsilon;\r\n const dz = Math.abs(savedAngle[2] - singleAlignment[2]) < epsilon;\r\n\r\n return !(dx && dy && dz);\r\n };\r\n\r\n useEffect(() => {\r\n /** Keep track if a tool is currently being used */\r\n setActiveToolOpen(alignerBasicDialog.open);\r\n }, [alignerBasicDialog.open]);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n alignerBasicDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-image-aligner-basic\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n alignerBasicDialog.handleOpen();\r\n });\r\n }, [activeToolOpen]);\r\n\r\n useEffect(() => {\r\n setHasTransform(cameraTransformPath !== null);\r\n }, [viewer, cameraTransformPath]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n\r\n const enabled = hasActiveCamera && alignerBasicDialog.open;\r\n viewer.setBasicAlignerState(enabled);\r\n }, [viewer, alignerBasicDialog.open, currentCamera]);\r\n\r\n useEffect(() => {\r\n // Not applicable if transform matrix is applied\r\n if (hasTransform) return;\r\n\r\n viewer?.resetBasicAlignerCamera(savedAngle);\r\n }, [viewer, currentCamera]);\r\n\r\n useEffect(() => {\r\n if (!viewer || !alignerBasicDialog.open) return;\r\n\r\n let interval = setInterval(() => {\r\n const angles = viewer.getBasicAlignerValue();\r\n\r\n /** NOTE: react will never return equal for arrays, so lodash is used */\r\n if (isEqual(singleAlignment, angles)) return;\r\n setSingleAlignment([...angles]);\r\n }, 50);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }, [viewer, alignerBasicDialog.open, singleAlignment]);\r\n\r\n const hasActiveCamera = currentCamera !== null;\r\n const activeCameraName = hasActiveCamera ?\r\n viewer?.getCurrentCameraName() : null;\r\n\r\n const alignment = hasActiveCamera\r\n ? singleAlignment.map(x => parseFloat(x.toFixed(2)))\r\n : [0,0,0];\r\n\r\n const savedAngle = currentCamera in basicAdjustments\r\n ? basicAdjustments[currentCamera]\r\n : [0, 0, 0];\r\n\r\n const isModified = checkDataModified();\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {(hasTransform) && (\r\n {t(\"data-aligner-basic.global-transformation\")}\r\n )}\r\n\r\n {(hasTransform === false) && (\r\n {/* Current camera section */}\r\n \r\n \r\n {t(\"data-aligner-basic.current-camera\")}:\r\n \r\n\r\n \r\n {hasActiveCamera ? activeCameraName : t(\"data-aligner-basic.no-camera-selected\")}\r\n \r\n \r\n\r\n {/* Current adjustment section */}\r\n \r\n \r\n {t(\"data-aligner-basic.current-adjustment\")}:\r\n \r\n\r\n \r\n {hasActiveCamera ? `[${alignment[0]}, ${alignment[1]}, ${alignment[2]}]` :\r\n t(\"general.not-applicable\")}\r\n \r\n \r\n\r\n {/* Current adjustment section */}\r\n \r\n \r\n {t(\"data-aligner-basic.alignment-status\")}:\r\n \r\n\r\n \r\n {isModified ? t(\"data-aligner-basic.modified\") : t(\"data-aligner-basic.saved\")}\r\n \r\n \r\n\r\n {/* Alignment shortcut keys */}\r\n \r\n \r\n {t(\"data-aligner-basic.alignment-shortcuts\")}:\r\n \r\n\r\n \r\n \r\n )}\r\n\r\n \r\n\r\n \r\n {(hasTransform) && ()}\r\n\r\n {(hasTransform === false) && (\r\n \r\n {t(\"buttons.reset-values\")}\r\n \r\n\r\n \r\n {t(\"buttons.save-adjustment\")}\r\n \r\n )}\r\n \r\n \r\n\r\n setClosePrompt(false)}\r\n onSubmit={() => {\r\n viewer?.resetBasicAlignerCamera(savedAngle);\r\n handleClose();\r\n }}\r\n title={t(\"data-aligner-basic.prompt-close-aligner-title\")}\r\n prompt={t(\"data-aligner-basic.prompt-close-aligner-text\")}\r\n button={t('buttons.close')}\r\n />\r\n \r\n );\r\n});","import React, {useEffect, useState, memo, useMemo} from 'react';\r\nimport { createStyles, makeStyles, Theme, useTheme } from \"@material-ui/core/styles\";\r\nimport { useTranslation } from 'react-i18next';\r\nimport { toast } from '../app';\r\nimport DeleteIcon from \"@material-ui/icons/Delete\";\r\nimport { DraggableDialog, EnhancedTable, PromptDialog, TextDialog } from '../components';\r\nimport { Button, Checkbox, DialogActions, DialogContent, Typography } from '@material-ui/core';\r\nimport { LocalObservation, LocalObservationTypes } from '../viewer/js/data-aligner';\r\nimport { AerialObservationIcon, ObservationError, PointObservationIcon } from './observations';\r\nimport { updateDataProjection, updateViewProjection, selectDataProjection, Transform } from '../redux/projections-slice';\r\nimport { useDispatch, useSelector } from 'react-redux';\r\nimport { projectionToUnits } from '../viewer/js/projections';\r\nimport { UnitConverter } from '../viewer/js/utilities';\r\nimport { userProjections } from '../projections';\r\nimport { trackToolUsage } from '../executable';\r\nimport { nanoid } from '@reduxjs/toolkit';\r\nimport {\r\n useDialog,\r\n useUniqueProjectID,\r\n useViewer,\r\n useActiveTool\r\n} from '../hooks';\r\nimport { registerEvent } from '../electron-modules';\r\nimport { useTableState } from '../hooks/use-table-state';\r\n\r\nconst highCutoff = 0.5;\r\nconst lowCutoff = 0.25;\r\nconst requiredRows = 3;\r\n\r\nconst converter = new UnitConverter();\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n transformInfo: {\r\n display: \"flex\",\r\n justifyContent: \"space-evenly\",\r\n paddingTop: theme.spacing(1)\r\n },\r\n toggleOptionFlex: {\r\n flex: 1,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n toggleOptionParent: {\r\n margin: theme.spacing(0),\r\n padding: theme.spacing(0),\r\n boxShadow: \"0px 10px 10px 2px\",\r\n justifyContent: \"center\"\r\n },\r\n toggleOptionCheckbox: {\r\n paddingTop: theme.spacing(0.5),\r\n paddingBottom: theme.spacing(0.5)\r\n },\r\n transformValues: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n textAlign: \"center\"\r\n }\r\n }),\r\n);\r\n\r\nconst AlignmentError = (props) => {\r\n const lowCutoffWithUnits = converter.convert(lowCutoff, \"m\", props.units);\r\n const highCutoffWithUnits = converter.convert(highCutoff, \"m\", props.units);\r\n\r\n return ;\r\n};\r\n\r\nexport const LocalAligner = memo((props: any) => {\r\n const observations = props.observations as LocalObservation[];\r\n\r\n const classes = useStyles();\r\n const dispatch = useDispatch();\r\n const theme = useTheme();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const tableState = useTableState();\r\n const localAlignerDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const {activeToolOpen, setActiveToolOpen} = useActiveTool();\r\n\r\n const dataProjection = useSelector(selectDataProjection);\r\n const units = projectionToUnits(dataProjection);\r\n\r\n const [calculating, setCalculating] = useState(false);\r\n const [rotate, setRotate] = useState(true);\r\n const [scale, setScale] = useState(true);\r\n const [closePrompt, setClosePrompt] = useState(false);\r\n const [utmZone, setUtmZone] = useState(0);\r\n const [savePrompt, setSavePrompt] = useState(false);\r\n const [oldProjection, setOldProjection] = useState(null);\r\n const [newProjection, setNewProjection] = useState(null);\r\n\r\n const handleScale = () => {\r\n setScale(!scale);\r\n };\r\n\r\n const handleRotate = () => {\r\n setRotate(!rotate);\r\n };\r\n\r\n const addNewRow = () => {\r\n viewer.generateLocalAlignerRows(1);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const onDelete = (row) => {\r\n viewer.deleteLocalAlignment(row.id);\r\n setNewProjection(null);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const checkClose = () => {\r\n if (!isTableEmpty()) {\r\n setClosePrompt(true);\r\n } else {\r\n localAlignerDialog.handleClose();\r\n }\r\n };\r\n\r\n const isTableEmpty = () => {\r\n const filledRows = observations.filter(observation => {\r\n return observation.scene || observation.aerial;\r\n });\r\n\r\n return filledRows.length === 0;\r\n };\r\n\r\n const isTableFilled = () => {\r\n const filledRows = observations.filter(observation => {\r\n return observation.scene && observation.aerial;\r\n });\r\n\r\n return filledRows.length === observations.length;\r\n };\r\n\r\n const getEstimator = () => {\r\n let estimator = \"T\";\r\n if (scale) estimator += \"S\";\r\n if (rotate) estimator += \"R\";\r\n return estimator;\r\n };\r\n\r\n const runCalculation = async () => {\r\n setCalculating(true);\r\n trackToolUsage(\"aligner-local\");\r\n\r\n const estimator = getEstimator();\r\n const {projection, utmZone}\r\n = await viewer.estimateLocalTransform(estimator, units);\r\n\r\n const tempProjection = {\r\n ...projection,\r\n name: `Temp Projection ${nanoid(6)}`\r\n };\r\n\r\n userProjections.save(tempProjection);\r\n dispatch(updateDataProjection(tempProjection));\r\n dispatch(updateViewProjection(tempProjection));\r\n\r\n setNewProjection(tempProjection);\r\n setUtmZone(utmZone);\r\n\r\n setCalculating(false);\r\n toast.success(t('local-projection.calculation_completed'));\r\n };\r\n\r\n const onCancel = () => {\r\n // Revert back to original projection\r\n updateViewerProjection(oldProjection);\r\n\r\n // Delete new projection\r\n deleteViewerProjection(newProjection);\r\n\r\n // Clear calculated values\r\n viewer.clearLocalTransformErrors();\r\n setNewProjection(null);\r\n };\r\n\r\n const saveNewProjection = () => {\r\n setSavePrompt(true);\r\n };\r\n\r\n const deleteViewerProjection = (projection) => {\r\n if (!projection) return;\r\n userProjections.delete(projection.name);\r\n };\r\n\r\n const updateViewerProjection = (projection) => {\r\n if (dataProjection === projection) return;\r\n dispatch(updateDataProjection(projection));\r\n dispatch(updateViewProjection(projection));\r\n };\r\n\r\n const onAddProjection = (name) => {\r\n if (userProjections.exists(name)) {\r\n toast.error(t(\"toast.projection-duplicate\"));\r\n return;\r\n }\r\n\r\n const projection = {...newProjection, name};\r\n userProjections.save(projection);\r\n updateViewerProjection(projection);\r\n setSavePrompt(false);\r\n localAlignerDialog.handleClose();\r\n };\r\n\r\n const resetDefaults = () => {\r\n setRotate(true);\r\n setScale(true);\r\n setNewProjection(null);\r\n };\r\n\r\n const onAerialClick = (id) => {\r\n viewer.setLocalAlignerActive(id, LocalObservationTypes.Aerial);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const onSceneClick = (id) => {\r\n viewer.setLocalAlignerActive(id, LocalObservationTypes.Scene);\r\n if (!calculated) return;\r\n onCancel();\r\n };\r\n\r\n const getTransformValues = () => {\r\n let translateX;\r\n let translateY;\r\n let rotation;\r\n let scaling;\r\n\r\n if (calculated) {\r\n const transform = newProjection.transform as Transform;\r\n translateX = transform.origin[0].toFixed(2);\r\n translateY = transform.origin[1].toFixed(2);\r\n rotation = (-1*transform.rotation).toFixed(2);\r\n scaling = (1.0/transform.scale).toFixed(2);\r\n }\r\n\r\n return {translateX, translateY, rotation, scaling};\r\n };\r\n\r\n const getRows = (observations, calculating) => {\r\n return observations.map(observation => {\r\n const disabled = calculating;\r\n\r\n const aerialSelected = !!observation.aerial;\r\n const aerialClicked = observation.active === LocalObservationTypes.Aerial;\r\n\r\n const pointSelected = !!observation.scene;\r\n const pointClicked = observation.active === LocalObservationTypes.Scene;\r\n\r\n const aerialObs = (\r\n {\r\n if (disabled) return;\r\n onAerialClick(observation.id);\r\n }}\r\n />\r\n );\r\n\r\n const pointObs = (\r\n {\r\n if (disabled) return;\r\n onSceneClick(observation.id);\r\n }}\r\n />\r\n );\r\n\r\n const error = (\r\n \r\n );\r\n\r\n return {\r\n id: observation.id,\r\n disabled,\r\n map_obs: aerialObs,\r\n pc_obs: pointObs,\r\n error: error,\r\n };\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n /** Keep track if a tool is currently being used */\r\n setActiveToolOpen(localAlignerDialog.open);\r\n }, [localAlignerDialog.open]);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n localAlignerDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-local-projection\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n localAlignerDialog.handleOpen();\r\n });\r\n }, [activeToolOpen]);\r\n\r\n useEffect(() => {\r\n viewer?.toggleLocalAligner(localAlignerDialog.open);\r\n\r\n if (localAlignerDialog.open) {\r\n viewer?.generateLocalAlignerRows(requiredRows);\r\n setOldProjection(dataProjection);\r\n } else {\r\n resetDefaults();\r\n }\r\n userProjections.load();\r\n }, [viewer, localAlignerDialog.open]);\r\n\r\n const calculated = !!newProjection;\r\n const {translateX, translateY, rotation, scaling}\r\n = getTransformValues();\r\n\r\n const canSubmit = isTableFilled()\r\n && observations.length >= requiredRows\r\n && !calculating;\r\n\r\n const columns = [\r\n {\r\n id: \"map_obs\",\r\n label: t('local-projection.aerial_control'),\r\n center: true,\r\n sortable: false\r\n },\r\n {\r\n id: \"pc_obs\",\r\n label: t('local-projection.point_control'),\r\n center: true,\r\n sortable: false\r\n },\r\n {\r\n id: \"error\",\r\n label: t('local-projection.error_units', {units}),\r\n numeric: true,\r\n center: true,\r\n forceOpacity: true\r\n }\r\n ];\r\n\r\n const rows = useMemo(() => {\r\n return getRows(observations, calculating);\r\n }, [observations, calculating]);\r\n\r\n const actions = [\r\n {\r\n title: t(\"buttons.delete\"),\r\n icon: ,\r\n onClick: (row) => {\r\n deleteDialog.handleOpen(row);\r\n }\r\n }\r\n ];\r\n\r\n return (\r\n \r\n\r\n \r\n \r\n \r\n {t(\"local-projection.select-at-least\", {requiredRows})}\r\n \r\n\r\n \r\n \r\n\r\n {calculated && (\r\n
\r\n \r\n {t('local-projection.estimated_rotation')} {rotation}\r\n \r\n\r\n \r\n {t('local-projection.estimated_scale')} {scaling}\r\n \r\n
\r\n\r\n
\r\n \r\n {t('local-projection.estimated_offset')} [{translateX}, {translateY}]\r\n \r\n\r\n \r\n {t('local-projection.closest_utm_zone')} {utmZone}\r\n \r\n
\r\n
)}\r\n\r\n \r\n {/** Add new observation row */}\r\n \r\n\r\n {/** Cancel projection */}\r\n {calculated && (\r\n \r\n )}\r\n\r\n {/** Run python calculations */}\r\n {!calculated && (\r\n \r\n )}\r\n\r\n {/** Confirm projection */}\r\n {calculated && (\r\n \r\n )}\r\n \r\n\r\n \r\n {/* Allow scaling while estimating transform */}\r\n
\r\n \r\n {t('local-projection.allow_scaling')}\r\n \r\n \r\n
\r\n\r\n {/* Allow rotation while estimating transform */}\r\n
\r\n \r\n {t('local-projection.allow_rotation')}\r\n \r\n \r\n
\r\n
\r\n\r\n \r\n\r\n {/* Delete Dialog */}\r\n {\r\n onDelete(deleteDialog.data);\r\n deleteDialog.handleClose();\r\n }}\r\n title={t(\"enhanced-table.prompt-delete-title\")}\r\n prompt={t('local-projection..do_you_want_to_delete_this_observation')}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n setSavePrompt(false)}\r\n onSubmit={onAddProjection}\r\n title={t('local-projection.create_new_projection')}\r\n prompt={t('local-projection.enter_local_projection_name')}\r\n label={t('local-projection.projection_name')}\r\n clear={true}\r\n />\r\n\r\n setClosePrompt(false)}\r\n onSubmit={() => {\r\n onCancel();\r\n localAlignerDialog.handleClose();\r\n setClosePrompt(false);\r\n }}\r\n title={t('local-projection.close_local_alignment')}\r\n prompt={t('local-projection.do_you_want_to_close_the_local_projection_aligner')}\r\n button={t('buttons.close')}\r\n />\r\n\r\n
\r\n );\r\n});\r\n","export enum StatusCode {\r\n Preparing = 0,\r\n Uploading = 1,\r\n Queued = 2,\r\n Uploaded = 3,\r\n Errored = 4\r\n}","import React, { memo } from 'react';\r\nimport {createStyles, makeStyles, Theme, useTheme} from \"@material-ui/core/styles\";\r\nimport {useDispatch, useSelector} from 'react-redux';\r\nimport {List, ListItem, Typography} from '@material-ui/core';\r\nimport { DynamicScrollbar } from '../components';\r\nimport {settingsDrawerWidth} from \"../settings\";\r\nimport {\r\n selectAllFolders\r\n} from '../redux/folders-slice';\r\nimport {\r\n getCameraListFromAssets,\r\n selectAllAssets,\r\n setVisibleFolder\r\n} from '../redux/assets-slice';\r\nimport { headerHeight } from '../app';\r\nimport clsx from 'clsx';\r\nimport { useTranslation } from 'react-i18next';\r\nimport LocalScene, { SceneCoordinate } from '../viewer/js/projections';\r\nimport {\r\n changeCameraState,\r\n initialSceneState,\r\n SceneCameraState\r\n} from '../redux/camera-slice';\r\nimport { getLocalizedFolderName } from '../utilities';\r\nimport { useGlobalSettings, useViewer } from '../hooks';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n parent: {\r\n position: \"absolute\",\r\n right: theme.spacing(1),\r\n pointerEvents: \"none\",\r\n marginTop: `${headerHeight/2}px`,\r\n display: \"flex\",\r\n height: \"100%\",\r\n alignItems: \"center\"\r\n },\r\n offset: {\r\n right: `calc(${settingsDrawerWidth}px + ${theme.spacing(1)}px)`\r\n },\r\n list: {\r\n zoom: 0.85,\r\n background: \"white\",\r\n borderRadius: theme.spacing(0.5),\r\n borderRight: `${theme.spacing(1)}px solid ${theme.palette.primary.main}`,\r\n pointerEvents: \"auto\",\r\n boxShadow: \"0px 0px 5px 2px rgb(0 0 0 / 25%)\"\r\n },\r\n listItem: {\r\n padding: theme.spacing(1, 1.5)\r\n },\r\n title: {\r\n textAlign: \"center\",\r\n padding: theme.spacing(1, 1.5),\r\n fontWeight: \"bold\",\r\n zoom: 0.95\r\n }\r\n })\r\n);\r\n\r\ninterface QuickNavProps {\r\n settingsDrawerState: boolean;\r\n}\r\n\r\nexport const QuickNav = memo((props: QuickNavProps) => {\r\n const {settingsDrawerState} = props;\r\n\r\n const dispatch = useDispatch();\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const globalSettings = useGlobalSettings();\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const folders = useSelector(selectAllFolders);\r\n\r\n const getFolderAssets = (folderID) => {\r\n const folderAssets = assets.filter(asset => (asset.folderID === folderID));\r\n return folderAssets.map(folderAsset => folderAsset.id);\r\n };\r\n\r\n const camerasForFolder = (folderID) => {\r\n const cameraData = getCameraListFromAssets(assets, false);\r\n return cameraData.filter(camera => camera.folder === folderID);\r\n };\r\n\r\n const getBestSceneState = (cameras) : SceneCameraState => {\r\n const position = viewer.camera.position;\r\n let lookat = new SceneCoordinate(position)\r\n .toDataProjection();\r\n\r\n let data = cameras.map(data => {\r\n const dx = data.x - lookat.x;\r\n const dy = data.y - lookat.y;\r\n const distance = Math.sqrt(dx*dx + dy*dy);\r\n return {...data, distance};\r\n }).sort((a,b) => a.distance - b.distance);\r\n\r\n return {\r\n ...initialSceneState,\r\n camera: data[0].id,\r\n lookat: [lookat.x, lookat.y, data[0].z]\r\n } as SceneCameraState;\r\n };\r\n\r\n const onClick = (folderID) => {\r\n if (!viewer) return;\r\n\r\n const cameras = camerasForFolder(folderID);\r\n const hasCameras = cameras.length > 0;\r\n\r\n if (hasCameras) {\r\n if (LocalScene.initialized) {\r\n const sceneState = getBestSceneState(cameras);\r\n viewer.setInitialStateFlag(false);\r\n dispatch(changeCameraState(sceneState));\r\n }\r\n } else {\r\n const folderAssetIds = getFolderAssets(folderID);\r\n viewer.snapToFolder(folderAssetIds);\r\n }\r\n\r\n dispatch(setVisibleFolder(folderID));\r\n };\r\n\r\n const isSelected = (folderID) => {\r\n const folderAssets = assets.filter(x => x.folderID === folderID);\r\n const numFolderAssets = folderAssets.length;\r\n const numVisible = folderAssets.filter(x => x.visible).length;\r\n const numAssetsVisible = assets.filter(x => x.visible).length;\r\n\r\n return (numFolderAssets === numVisible)\r\n && (numVisible === numAssetsVisible);\r\n };\r\n\r\n // Only folders with assets inside are visible\r\n const folderOptions = folders.filter(folder => {\r\n const items = assets.filter(x => x.folderID === folder.id);\r\n return items.length > 0;\r\n });\r\n\r\n const openNav = globalSettings.openQuickNav\r\n && (folderOptions.length > 1);\r\n\r\n return (\r\n \r\n {openNav && (\r\n
\r\n
\r\n \r\n \r\n {t(\"quick-nav.title\")}\r\n \r\n\r\n \r\n {folderOptions.map((folder, index) => {\r\n const localizedFolderName = getLocalizedFolderName(folder.name);\r\n\r\n return (\r\n onClick(folder.id)}\r\n selected={isSelected(folder.id)}\r\n >\r\n {localizedFolderName}\r\n \r\n );\r\n })}\r\n \r\n \r\n
\r\n
\r\n )}\r\n
\r\n );\r\n});","import {app, fs, fse, isDevMode} from '../../electron-modules';\r\nimport path from \"path\";\r\nimport {pathWithExtension} from \"../../utilities\";\r\nimport LocalScene from \"../../viewer/js/projections\";\r\nimport slash from \"slash\";\r\nimport {Asset, AssetType, CameraData} from \"../../redux/assets-slice\";\r\nimport {t} from \"../../localization\";\r\nimport { PythonExecutable } from '../../executable';\r\n\r\nexport const deleteFolder = async (folderPath: string) => {\r\n try {\r\n await fse.remove(folderPath);\r\n } catch {}\r\n};\r\n\r\nexport const createNewFolder = async (folderPath: string) => {\r\n await deleteFolder(folderPath);\r\n await fse.mkdirs(folderPath);\r\n};\r\n\r\nexport const moveCameraData = async (asset: Asset, dataPath: string) => {\r\n const imagesPath = path.join(dataPath, asset.id);\r\n\r\n await createNewFolder(imagesPath);\r\n\r\n const imagesData = asset.data as CameraData[];\r\n for (let i= 0; i < imagesData.length; i++) {\r\n const imageData = imagesData[i];\r\n const imageName = path.basename(imageData.path);\r\n const newImagePath = path.join(imagesPath, imageName);\r\n\r\n if (fs.existsSync(imageData.path)) {\r\n await fse.copy(imageData.path, newImagePath);\r\n }\r\n }\r\n};\r\n\r\n/** Execute python function to copy folders instead. Nodejs is\r\n * very slow and has issues with large files */\r\nexport const moveStreamablePointsData = async (asset: Asset,\r\n dataPath: string, exe: PythonExecutable) => {\r\n const inputPath = asset.path;\r\n const outputPath = path.join(dataPath, asset.id);\r\n\r\n return new Promise((resolve) => {\r\n let commands = [\r\n \"-p\", \"copy_folder\",\r\n \"--input_folder\", inputPath,\r\n \"--output_folder\", outputPath\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n onClose: async () => {\r\n resolve(true);\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport const moveGenericPointCloud = async (asset: Asset, dataPath: string,\r\n exe: PythonExecutable, onLogs, singleFileOutput: boolean) => {\r\n const inputPath = asset.path;\r\n const pointPath = path.join(dataPath, asset.id);\r\n\r\n return new Promise((resolve) => {\r\n let commands = [\r\n \"-p\", \"process_las\",\r\n \"--input_path\", inputPath,\r\n \"--output_folder\", pointPath,\r\n \"--single_file\", singleFileOutput,\r\n \"--units\", LocalScene.dataProjectionUnits\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLogs: onLogs,\r\n onClose: async () => {\r\n resolve(true);\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport const getBuildPath = () => {\r\n const appPath = slash(app.getAppPath());\r\n\r\n return isDevMode\r\n ? path.join(appPath, \"build\")\r\n : path.join(path.dirname(appPath), \"app.asar.unpacked\", \"build\");\r\n};\r\n\r\nexport const getMiniViewerPath = () => {\r\n const appPath = slash(app.getAppPath());\r\n return isDevMode\r\n ? path.join(appPath, \"miniviewer.exe\")\r\n : path.join(path.dirname(appPath), \"app.asar.unpacked\", \"miniviewer.exe\");\r\n};\r\n\r\nexport const moveModelData = async (asset: Asset, dataPath: string, onExportError) => {\r\n const outputFolder = path.join(dataPath, asset.id);\r\n const modelName = path.basename(asset.path);\r\n const copyToFile = async (asset, inputPath, outputPath) => {\r\n try {\r\n await fse.copy(inputPath, outputPath);\r\n } catch {\r\n onExportError(\r\n t(\"dialog.general-error-title\"),\r\n t(\"dialog.export-error-generic\", {name: asset.name})\r\n );\r\n return;\r\n }\r\n };\r\n\r\n await createNewFolder(outputFolder);\r\n\r\n if (asset.type === AssetType.SHP) {\r\n const shpInput = pathWithExtension(asset.path, \"shp\");\r\n const shpOutput = path.join(outputFolder, pathWithExtension(modelName, \"shp\"));\r\n await copyToFile(asset, shpInput, shpOutput);\r\n\r\n const dbfInput = pathWithExtension(asset.path, \"dbf\");\r\n const dbfOutput = path.join(outputFolder, pathWithExtension(modelName, \"dbf\"));\r\n await copyToFile(asset, dbfInput, dbfOutput);\r\n } else {\r\n const inputPath = asset.path;\r\n const outputPath = path.join(outputFolder, modelName);\r\n await copyToFile(asset, inputPath, outputPath);\r\n }\r\n};","import path from \"path\";\r\nimport {Asset, AssetType} from \"../../redux/assets-slice\";\r\nimport {fse} from \"../../electron-modules\";\r\nimport {isModelFile, isRawPointsFile, isStreamablePointsFile} from \"../utils/misc\";\r\nimport {\r\n moveCameraData,\r\n moveModelData,\r\n moveGenericPointCloud,\r\n moveStreamablePointsData\r\n} from \"./utils\";\r\nimport { PythonExecutable } from \"../../executable\";\r\nimport { asyncTimeout } from \"../../utilities\";\r\n\r\nconst assetsFolder = \"assets\";\r\nconst processTimeout = 1000;\r\n\r\nconst getAssetIndex = (state, asset) => {\r\n const assetIds = state.assets.map(x => x.id);\r\n return assetIds.indexOf(asset.id);\r\n};\r\n\r\nexport const updateCameraDataState = (asset, state) => {\r\n const assetIndex = getAssetIndex(state, asset);\r\n const imagesData = asset.data;\r\n imagesData.forEach((imageData, imageIndex) => {\r\n const imageName = path.basename(imageData.path);\r\n const finalPath = path.join(assetsFolder, asset.id, imageName);\r\n state.assets[assetIndex].data[imageIndex].path = `./${finalPath}`;\r\n });\r\n};\r\n\r\nexport const updateModelDataState = (asset, state) => {\r\n const assetIndex = getAssetIndex(state, asset);\r\n const modelName = path.basename(asset.path);\r\n const finalPath = path.join(assetsFolder, asset.id, modelName);\r\n state.assets[assetIndex].path = `./${finalPath}`;\r\n};\r\n\r\nexport const updateStreamablePointsState = (asset, state) => {\r\n const assetIndex = getAssetIndex(state, asset);\r\n const finalPath = path.join(assetsFolder, asset.id);\r\n state.assets[assetIndex].path = `./${finalPath}`;\r\n};\r\n\r\nexport const updateRawPointsState = (asset, state, singleFileOutput) => {\r\n const assetIndex = getAssetIndex(state, asset);\r\n\r\n const finalPath = singleFileOutput\r\n ? path.join(assetsFolder, asset.id)\r\n : path.join(assetsFolder, asset.id, \"points\");\r\n\r\n state.assets[assetIndex].path = `./${finalPath}`;\r\n state.assets[assetIndex].type = singleFileOutput\r\n ? AssetType.Potree\r\n : AssetType.Encompass;\r\n};\r\n\r\nexport const updateCameraTransformPath = (state, outputPath) => {\r\n const dataPath = path.join(outputPath, assetsFolder);\r\n\r\n const outputName = \"camera.4x4\";\r\n const matrixPath = state.camera.transform;\r\n const newImagePath = path.join(dataPath, outputName);\r\n\r\n if (matrixPath) {\r\n fse.copy(matrixPath, newImagePath);\r\n const finalPath = path.join(assetsFolder, outputName);\r\n state.camera.transform = `./${finalPath}`;\r\n }\r\n};\r\n\r\nexport const moveAssetData = async (asset: Asset, outputPath: string,\r\n exe: PythonExecutable, onLogs, singleFileOutput, handleExportError) => {\r\n const dataPath = path.join(outputPath, assetsFolder);\r\n\r\n if (isStreamablePointsFile(asset)) {\r\n await moveStreamablePointsData(asset, dataPath, exe);\r\n } else if (isRawPointsFile(asset)) {\r\n await moveGenericPointCloud(asset, dataPath, exe, onLogs, singleFileOutput);\r\n } else if (asset.type === AssetType.Panoramic) {\r\n await moveCameraData(asset, dataPath);\r\n } else if (asset.type === AssetType.Planar) {\r\n await moveCameraData(asset, dataPath);\r\n } else if (isModelFile(asset)) {\r\n await moveModelData(asset, dataPath, handleExportError);\r\n }\r\n\r\n await asyncTimeout(processTimeout);\r\n};","import {createNewFolder, deleteFolder, getBuildPath, getMiniViewerPath} from \"./utils\";\r\nimport path from \"path\";\r\nimport {t} from \"../../localization\";\r\nimport {fs, fse, storage} from \"../../electron-modules\";\r\nimport {Asset, AssetType} from \"../../redux/assets-slice\";\r\nimport {\r\n moveAssetData,\r\n updateCameraDataState, updateCameraTransformPath,\r\n updateModelDataState,\r\n updateRawPointsState,\r\n updateStreamablePointsState\r\n} from \"./state\";\r\nimport {isModelFile, isRawPointsFile, isStreamablePointsFile} from \"../utils/misc\";\r\nimport { cloneDeep } from \"lodash\";\r\nimport { PythonExecutable } from \"../../executable\";\r\nimport { ProjectType } from \"../../types/project\";\r\n\r\n\r\ninterface ExporterOpts {\r\n name: string;\r\n outputPath: string;\r\n assets: Asset[];\r\n singleFileOutput: boolean;\r\n state;\r\n onError?(title: string, message: string): void;\r\n onUpdate?(message: string): void;\r\n onLogs?(message: string): void;\r\n onProgress?(percent: number): void;\r\n onFinish?(): void;\r\n onCancel?(): void;\r\n}\r\n\r\nconst exporterOptsDefaults = {\r\n onError: () => {},\r\n onUpdate: () => {},\r\n onLogs: () => {},\r\n onProgress: () => {},\r\n onFinish: () => {},\r\n onCancel: () => {}\r\n};\r\nconst assetsFolder = \"assets\";\r\n\r\nexport const getStaticExporter = (): [(opts: ExporterOpts) => Promise, () => Promise] => {\r\n const exe = new PythonExecutable();\r\n const buildPath = getBuildPath();\r\n let cancelFlag = false;\r\n\r\n const cancel = async (webOutputPath) => {\r\n await deleteFolder(webOutputPath);\r\n cancelFlag = false;\r\n };\r\n\r\n const startExport = async (opts: ExporterOpts) => {\r\n opts = {...exporterOptsDefaults, ...opts};\r\n\r\n const rootOutputPath = path.join(opts.outputPath, opts.name);\r\n const webOutputPath = path.join(rootOutputPath, \"web\");\r\n const dataPath = path.join(webOutputPath, assetsFolder);\r\n\r\n opts.onUpdate(t('export.creating-output-folder'));\r\n await createNewFolder(rootOutputPath);\r\n await createNewFolder(webOutputPath);\r\n\r\n opts.onUpdate(t('export.copy-html-files-output-folder'));\r\n try {\r\n await fse.copy(buildPath, webOutputPath);\r\n } catch(err) {\r\n opts.onError(t(\"dialog.general-error-title\"), t(\"dialog.export-error-static\"));\r\n return;\r\n }\r\n\r\n opts.onUpdate(t('export.preparing-data-to-export'));\r\n await createNewFolder(dataPath);\r\n\r\n for (const [index, asset] of opts.assets.entries()) {\r\n opts.onUpdate(t(\"export.processing-data\", {name: asset.name}));\r\n\r\n await moveAssetData(asset, webOutputPath, exe, opts.onLogs,\r\n opts.singleFileOutput, opts.onError);\r\n\r\n const percent = 100.0 * (index + 1) / opts.assets.length;\r\n opts.onProgress(percent);\r\n\r\n if (cancelFlag) {\r\n await cancel(webOutputPath);\r\n opts.onCancel();\r\n return;\r\n }\r\n }\r\n\r\n opts.onUpdate(t('export.export-project-state'));\r\n\r\n const state = cloneDeep(opts.state);\r\n\r\n // Update project type\r\n state.project.type = ProjectType.Static;\r\n\r\n opts.assets.forEach(asset => {\r\n if (isStreamablePointsFile(asset)) {\r\n updateStreamablePointsState(asset, state);\r\n } else if (isRawPointsFile(asset)) {\r\n updateRawPointsState(asset, state, opts.singleFileOutput);\r\n } else if (asset.type === AssetType.Panoramic || asset.type === AssetType.Planar) {\r\n updateCameraDataState(asset, state);\r\n } else if (isModelFile(asset)) {\r\n updateModelDataState(asset, state);\r\n }\r\n });\r\n\r\n // Update camera transform path\r\n updateCameraTransformPath(state, webOutputPath);\r\n\r\n const miniViewerPath = getMiniViewerPath();\r\n const exeOutputPath = path.join(rootOutputPath, path.basename(miniViewerPath));\r\n fs.copyFileSync(miniViewerPath, exeOutputPath);\r\n\r\n // Copy global settings\r\n const globalSettingsPath = path.join(\r\n storage.getDataPath(), \"global-settings.json\");\r\n\r\n const globalSettingsOutput = path.join(\r\n webOutputPath, \"global-settings.json\");\r\n\r\n if (fs.existsSync(globalSettingsPath)) {\r\n fs.copyFileSync(globalSettingsPath, globalSettingsOutput);\r\n }\r\n\r\n // Write final config file\r\n try {\r\n const projectJson = JSON.stringify(state, null, 2);\r\n const projectPath = path.join(webOutputPath, \"static.json\");\r\n await fse.writeFile(projectPath, projectJson);\r\n } catch (err) {\r\n opts.onError(t(\"dialog.general-error-title\"), t(\"dialog.export-error-static\"));\r\n return;\r\n }\r\n\r\n if (!cancelFlag) {\r\n opts.onFinish();\r\n } else {\r\n await cancel(webOutputPath);\r\n opts.onCancel();\r\n }\r\n };\r\n\r\n const cancelExport = async () => {\r\n cancelFlag = true;\r\n exe.destroy();\r\n };\r\n\r\n return [startExport, cancelExport];\r\n};","import React from 'react';\r\nimport { useTheme, ListItem } from \"@material-ui/core\";\r\nimport WarningIcon from '@material-ui/icons/Warning';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport {\r\n AssetType,\r\n CameraData,\r\n getCameraFileAssets,\r\n getLandXMLAssets,\r\n getModelAssets,\r\n getOrthoAssets,\r\n getPointCloudAssets,\r\n getTagAssets,\r\n getWebMapAssets,\r\n selectAllAssets,\r\n TagData\r\n} from \"../redux/assets-slice\";\r\nimport { ArrowTooltip } from '../components';\r\nimport { useSelector } from 'react-redux';\r\n\r\nconst BulletListItem = (props) => {\r\n const theme = useTheme();\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n );\r\n};\r\n\r\nexport const NewProjectInfo = () => {\r\n const assets = useSelector(selectAllAssets);\r\n const orthoFiles = getOrthoAssets(assets);\r\n const pointClouds = getPointCloudAssets(assets);\r\n const cameraFiles = getCameraFileAssets(assets);\r\n const modelFiles = getModelAssets(assets);\r\n const landXMLFiles = getLandXMLAssets(assets);\r\n const webmapSources = getWebMapAssets(assets);\r\n const tagFiles = getTagAssets(assets);\r\n\r\n const theme = useTheme();\r\n const {t} = useTranslation();\r\n\r\n const numGenericPointCloud = pointClouds.filter(asset => {\r\n return (asset.type === AssetType.LAS)\r\n || (asset.type === AssetType.E57Points);\r\n }).length;\r\n\r\n let numberOfImages = 0;\r\n cameraFiles.forEach(cameraAsset => {\r\n const images = (cameraAsset.data as CameraData[]);\r\n numberOfImages += images.length;\r\n });\r\n\r\n let numberOfTags = 0;\r\n tagFiles.forEach(tagAsset => {\r\n const tags = (tagAsset.data as TagData).items;\r\n numberOfTags += tags.length;\r\n });\r\n\r\n return (\r\n \r\n {(pointClouds.length > 0) && (\r\n \r\n {t(\"export.asset-points\", {\r\n count: pointClouds.length\r\n })}\r\n\r\n {(numGenericPointCloud > 0) && (\r\n \r\n \r\n \r\n )}\r\n \r\n )}\r\n\r\n {(numberOfImages > 0) && (\r\n \r\n {t(\"export.asset-camera\", {\r\n count: numberOfImages\r\n })}\r\n \r\n )}\r\n\r\n {(numberOfTags > 0) && (\r\n \r\n {t(\"export.asset-tags\", {\r\n count: numberOfTags\r\n })}\r\n \r\n )}\r\n\r\n {(orthoFiles.length > 0) && (\r\n \r\n {t(\"export.asset-orthos\", {\r\n count: orthoFiles.length\r\n })}\r\n \r\n )}\r\n\r\n {(modelFiles.length > 0) && (\r\n \r\n {t(\"export.asset-models\", {\r\n count: modelFiles.length\r\n })}\r\n \r\n )}\r\n\r\n {(webmapSources.length > 0) && (\r\n \r\n {t(\"export.asset-webmap\", {\r\n count: webmapSources.length\r\n })}\r\n \r\n )}\r\n\r\n {(landXMLFiles.length > 0) && (\r\n \r\n {t(\"export.asset-landxml\", {\r\n count: landXMLFiles.length\r\n })}\r\n \r\n )}\r\n\r\n \r\n );\r\n};\r\n","import React, {useCallback, useEffect, useMemo, useState} from 'react';\r\nimport {dialog, registerEvent} from '../../electron-modules';\r\nimport {store} from '../../redux/store';\r\nimport {\r\n AssetType,\r\n getCameraFileAssets,\r\n getModelAssets,\r\n getPointCloudAssets,\r\n selectAllAssets\r\n} from '../../redux/assets-slice';\r\nimport {trackToolUsage} from '../../executable';\r\nimport {useSelector} from 'react-redux';\r\nimport {\r\n Button,\r\n CircularProgress,\r\n createStyles,\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n DialogContentText,\r\n DialogTitle,\r\n Grid,\r\n makeStyles,\r\n Theme,\r\n Typography,\r\n useTheme\r\n} from '@material-ui/core';\r\nimport {\r\n AlertDialog,\r\n CheckboxWithLabel,\r\n FolderWithLabel,\r\n LinearProgressWithLabel,\r\n SimpleDialog,\r\n} from '../../components';\r\nimport sanitize from \"sanitize-filename\";\r\nimport {selectProjectName} from '../../redux/project-slice';\r\nimport {toast} from '../../app';\r\nimport {useTranslation} from 'react-i18next';\r\nimport {getStaticExporter} from \"./exporter\";\r\nimport {useDialog} from \"../../hooks\";\r\nimport {getLocalizedProjectName} from '../../utilities';\r\nimport {throttle} from 'throttle-debounce';\r\nimport { NewProjectInfo } from '../common';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n warning: {\r\n color: theme.palette.warning.main\r\n },\r\n exportText: {\r\n padding: theme.spacing(1)\r\n },\r\n contentCenter: {\r\n textAlign: \"center\"\r\n },\r\n cancelProgress: {\r\n marginRight: theme.spacing(1)\r\n },\r\n cancelContent: {\r\n paddingBottom: theme.spacing(3)\r\n },\r\n paddingTop: {\r\n paddingTop: theme.spacing(3)\r\n },\r\n listItem: {\r\n width: '100%',\r\n marginTop: theme.spacing(2)\r\n },\r\n switchLabel: {\r\n display: \"inline-block\",\r\n maxWidth: \"calc(100% - 50px)\"\r\n },\r\n switchElement: {\r\n float: \"right\"\r\n },\r\n outputFolder: {\r\n marginTop: theme.spacing(2)\r\n },\r\n dropdown: {\r\n width: \"40%\"\r\n },\r\n header: {\r\n marginTop: theme.spacing(1)\r\n }\r\n }),\r\n);\r\n\r\nexport const StaticExporter = () => {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const {t} = useTranslation();\r\n const exporterDialog = useDialog();\r\n const messageDialog = useDialog();\r\n const successDialog = useDialog();\r\n const cancelDialog = useDialog();\r\n\r\n const projectName = useSelector(selectProjectName);\r\n const assets = useSelector(selectAllAssets);\r\n const pointClouds = getPointCloudAssets(assets);\r\n const camerasFiles = getCameraFileAssets(assets);\r\n const modelFiles = getModelAssets(assets);\r\n\r\n const [outputPath, setOutputPath] = useState(null);\r\n const [singleFileOutput, setSingleFileOutput] = useState(true);\r\n const [exportTopMessage, setExportTopMessage] = useState(\"\");\r\n const [exportBottomMessage, setExportBottomMessage] = useState(\"\");\r\n const [exportPercent, updateExportPercent] = useState(0);\r\n const [isExportRunning, setIsExportRunning] = useState(false);\r\n\r\n const [startExport, cancelExport] = useMemo(getStaticExporter, []);\r\n\r\n const progressThrottleMilliseconds = 100;\r\n\r\n const setExportPercent = useCallback(throttle(\r\n progressThrottleMilliseconds, (value) => {\r\n updateExportPercent(value);\r\n }), []);\r\n\r\n const canExport = assets.length > 0;\r\n\r\n const numGenericPointCloud = pointClouds.filter(asset => {\r\n return (asset.type === AssetType.LAS)\r\n || (asset.type === AssetType.E57Points);\r\n }).length;\r\n\r\n const onExportFinished = () => {\r\n setIsExportRunning(false);\r\n messageDialog.handleClose();\r\n };\r\n\r\n const handleExportCancel = () => {\r\n onExportFinished();\r\n cancelDialog.handleOpen();\r\n cancelExport();\r\n };\r\n\r\n const handleExport = () => {\r\n exporterDialog.handleClose();\r\n exportToStatic();\r\n };\r\n\r\n const setExportMessage = (top = \"\", bottom = \"\") => {\r\n setExportTopMessage(top);\r\n setExportBottomMessage(bottom);\r\n };\r\n\r\n const exportToStatic = async () => {\r\n trackToolUsage(\"exporter\");\r\n\r\n setExportPercent(0);\r\n setExportMessage();\r\n messageDialog.handleOpen();\r\n\r\n const assets = [\r\n ...pointClouds,\r\n ...camerasFiles,\r\n ...modelFiles\r\n ];\r\n\r\n await startExport({\r\n name: exportName,\r\n outputPath: outputPath,\r\n assets: assets,\r\n singleFileOutput: singleFileOutput,\r\n state: store.getState(),\r\n onUpdate: setExportMessage,\r\n onLogs: setExportBottomMessage,\r\n onProgress: setExportPercent,\r\n onError: (title, message) => {\r\n onExportFinished();\r\n dialog.showErrorBox(title, message);\r\n },\r\n onFinish: () => {\r\n onExportFinished();\r\n successDialog.handleOpen();\r\n },\r\n onCancel: () => {\r\n setIsExportRunning(false);\r\n cancelDialog.handleClose();\r\n }\r\n });\r\n };\r\n\r\n const resetDefaults = () => {\r\n setOutputPath(null);\r\n setSingleFileOutput(true);\r\n };\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-static-export\", () => {\r\n if (!canExport) return toast.error(t(\"toast.no-data-loaded\"));\r\n exporterDialog.handleOpen();\r\n });\r\n }, [canExport]);\r\n\r\n useEffect(() => {\r\n if (!exporterDialog.open) return;\r\n resetDefaults();\r\n }, [exporterDialog.open]);\r\n\r\n const localizedProjectName = getLocalizedProjectName(projectName);\r\n const sanitizedName = sanitize(localizedProjectName);\r\n const exportName = t('export.export-name', {name: sanitizedName});\r\n\r\n return (\r\n \r\n {/* Exporting dialog */}\r\n \r\n {t('export.export-status')}\r\n\r\n \r\n \r\n {exportTopMessage}\r\n \r\n\r\n \r\n {exportBottomMessage}\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n {t('export.cancel-export')}\r\n \r\n \r\n \r\n\r\n {/* Main dialog */}\r\n \r\n \r\n\r\n {/* Export file type(s) info */}\r\n \r\n \r\n\r\n \r\n \r\n\r\n {/* Point cloud export version */}\r\n {(numGenericPointCloud > 0) && (\r\n \r\n \r\n \r\n )}\r\n\r\n {/* Output Folder */}\r\n \r\n \r\n \r\n\r\n \r\n \r\n\r\n {/* Cancelling dialog */}\r\n \r\n {t('export.data-export')}\r\n \r\n \r\n \r\n {t('export.cancelling-export')}\r\n \r\n \r\n \r\n\r\n {/* Success dialog */}\r\n \r\n \r\n {t('export.successfully-exported-data')}\r\n \r\n \r\n \r\n );\r\n};","import {Asset, AssetType, TagData, WebSourceAsset, XMLData} from \"../../redux/assets-slice\";\r\nimport { Bookmark } from \"../../redux/bookmarks-slice\";\r\nimport {t} from \"../../localization\";\r\nimport LocalScene from \"../../viewer/js/projections\";\r\nimport { fse, getTemporaryFile } from \"../../electron-modules\";\r\nimport { PythonExecutable } from \"../../executable\";\r\nimport { getLocalizedProjectName, getMatrixValues, pathWithExtension } from \"../../utilities\";\r\nimport { engineCloudURL } from \"../../urls\";\r\nimport { CustomURL } from \"../../redux/custom-links-slice\";\r\nimport {\r\n getBaseAsset,\r\n getTagsData,\r\n getImageData,\r\n getModelLayers,\r\n getWebmapLayers,\r\n withOriginalID\r\n} from \"../utils/misc\";\r\nimport { StatusCode } from \"../../types/cloud-export\";\r\n\r\nconst SHP_FILE_TYPES = [\"shp\", \"dbf\"];\r\nconst POTREE_FILES = ['hierarchy.bin', 'octree.bin', 'metadata.json'];\r\n\r\ninterface ExporterOpts {\r\n name: string;\r\n assets: Asset[];\r\n state: any;\r\n update: boolean;\r\n appCode: string;\r\n onError?(title: string, message: string): void;\r\n onStart?(statuses: {}): void;\r\n onUpdate?(statuses: {}, error: boolean): void;\r\n onProgress?(percent: number): void;\r\n onFinish?(projectID: string): void;\r\n}\r\n\r\nconst exporterOptsDefaults = {\r\n onError: () => {},\r\n onStart: () => {},\r\n onUpdate: () => {},\r\n onProgress: () => {},\r\n onFinish: () => {}\r\n};\r\n\r\nconst createProject = async (state, update: boolean): Promise => {\r\n const folders = state.folders.map(folder => {\r\n const assets = state.assets\r\n .filter(asset => asset.folderID === folder.id) as Asset[];\r\n\r\n const tags = assets\r\n .filter(asset => asset.type === AssetType.Tag)\r\n .map(tagAsset => ({\r\n ...getBaseAsset(tagAsset),\r\n texture: (tagAsset.data as TagData).texture,\r\n size: (tagAsset.data as TagData).size,\r\n tags: getTagsData(tagAsset)\r\n }));\r\n\r\n const panoramics = assets\r\n .filter(asset => asset.type === AssetType.Panoramic)\r\n .map(panoAsset => ({\r\n ...getBaseAsset(panoAsset),\r\n images: getImageData(panoAsset)\r\n }));\r\n\r\n const planars = assets\r\n .filter(asset => asset.type === AssetType.Planar)\r\n .map(panoAsset => ({\r\n ...getBaseAsset(panoAsset),\r\n images: getImageData(panoAsset)\r\n }));\r\n\r\n const pointClouds = assets\r\n .filter(asset => {\r\n return (asset.type === AssetType.LAS)\r\n || (asset.type === AssetType.E57Points)\r\n || (asset.type === AssetType.Potree);\r\n })\r\n .map(pointCloudAsset => ({\r\n ...getBaseAsset(pointCloudAsset),\r\n type: AssetType.Potree\r\n }));\r\n\r\n const orthomosaics = assets\r\n .filter(asset => asset.type === AssetType.OrthoMosaic)\r\n .map(orthoAsset => ({\r\n ...getBaseAsset(orthoAsset),\r\n imageData: orthoAsset.data\r\n }));\r\n\r\n const landxmls = assets\r\n .filter(asset => asset.type === AssetType.LandXML)\r\n .map(landXMLAsset => ({\r\n ...getBaseAsset(landXMLAsset),\r\n ...(landXMLAsset.data as XMLData)\r\n }));\r\n\r\n const ifcFiles = assets\r\n .filter(asset => asset.type === AssetType.IFC)\r\n .map(ifcAsset => ({\r\n ...getBaseAsset(ifcAsset)\r\n }));\r\n\r\n const shpFiles = assets\r\n .filter(asset => asset.type === AssetType.SHP)\r\n .map(shpAsset => ({\r\n ...getBaseAsset(shpAsset),\r\n layers: getModelLayers(shpAsset)\r\n }));\r\n\r\n const dxfFiles = assets\r\n .filter(asset => asset.type === AssetType.DXF)\r\n .map(dxfAsset => ({\r\n ...getBaseAsset(dxfAsset),\r\n layers: getModelLayers(dxfAsset)\r\n }));\r\n\r\n const webmapSources = assets\r\n .filter(asset => asset.type === AssetType.Webmap)\r\n .map((webmapAsset: WebSourceAsset) => ({\r\n ...getBaseAsset(webmapAsset),\r\n url: webmapAsset.data.url,\r\n map_type: webmapAsset.data.type,\r\n public: webmapAsset.data.public,\r\n layers: getWebmapLayers(webmapAsset)\r\n }));\r\n\r\n return {\r\n name: folder.name,\r\n originalId: folder.id,\r\n default: folder.default,\r\n assets: {\r\n tags,\r\n panoramics,\r\n planars,\r\n pointClouds,\r\n orthomosaics,\r\n landxmls,\r\n ifcFiles,\r\n shpFiles,\r\n dxfFiles,\r\n webmapSources\r\n }\r\n };\r\n });\r\n\r\n const projections = {\r\n data: {\r\n type: state.projections.data.type,\r\n name: state.projections.data.name,\r\n default: state.projections.data.default,\r\n string: state.projections.data.string,\r\n transform: state.projections.data.transform\r\n },\r\n view: {\r\n type: state.projections.view.type,\r\n name: state.projections.view.name,\r\n default: state.projections.view.default,\r\n string: state.projections.view.string,\r\n transform: state.projections.view.transform\r\n }\r\n };\r\n\r\n const bookmarks = state.bookmarks.map((bookmark: Bookmark) => {\r\n return withOriginalID(bookmark);\r\n });\r\n\r\n const customLinks = state.custom_links.map((link: CustomURL) => {\r\n return withOriginalID(link);\r\n });\r\n\r\n const {success, rotation, offset}\r\n = await getMatrixValues(state.camera.transform);\r\n\r\n const transform = success ? {\r\n rotation: rotation.toArray(),\r\n translation: offset.toArray()\r\n } : null;\r\n\r\n const adjustments = Object.keys(state.camera.adjustments).map(camera => {\r\n const rotation = state.camera.adjustments[camera];\r\n return {camera, rotation};\r\n });\r\n\r\n const cameraState = {\r\n transform: transform,\r\n adjustments: adjustments,\r\n height: state.camera.height,\r\n aerialState: state.camera.aerialState,\r\n sceneState: state.camera.sceneState\r\n };\r\n\r\n const method = update ? \"PUT\" : \"POST\";\r\n const localizedProjectName = getLocalizedProjectName(state.project.name);\r\n\r\n const request = await fetch(`${engineCloudURL}/api/projects`, {\r\n method,\r\n headers: {\r\n 'Content-Type': 'application/json'\r\n },\r\n body: JSON.stringify({\r\n name: localizedProjectName,\r\n originalId: state.project.id,\r\n settings: state.settings,\r\n configVersion: state.project.configVersion,\r\n measurementUnits: state.projections.measureUnits,\r\n folders,\r\n bookmarks,\r\n customLinks,\r\n projections,\r\n cameraState\r\n })\r\n });\r\n\r\n const response = await request.json();\r\n if (!response.id) {\r\n throw new Error(\"Error creating new project\");\r\n }\r\n\r\n return response;\r\n};\r\n\r\ninterface UploadItem {\r\n id: string;\r\n url: string;\r\n paths: string[];\r\n name: string;\r\n processPoints?: boolean;\r\n units?: string;\r\n}\r\n\r\nconst getAssetsToUpload = (project, opts) => {\r\n const projectID = project.id;\r\n const uploadList: UploadItem[] = [];\r\n\r\n project.uploads.forEach(({uploadId, originalId}) => {\r\n const asset = opts.state.assets.find(asset => asset.id === originalId);\r\n\r\n if ((asset.type === AssetType.Panoramic) || (asset.type === AssetType.Planar)) {\r\n asset.data.forEach(image => {\r\n uploadList.push({\r\n id: image.id,\r\n url: getUploadURL(projectID, uploadId),\r\n paths: [image.path],\r\n name: image.name\r\n });\r\n });\r\n }\r\n\r\n if ((asset.type === AssetType.LAS) || (asset.type === AssetType.E57Points)) {\r\n uploadList.push({\r\n id: asset.id,\r\n url: getUploadURL(projectID, uploadId),\r\n paths: [asset.path],\r\n name: asset.name,\r\n processPoints: true,\r\n units: LocalScene.dataProjectionUnits\r\n });\r\n }\r\n\r\n if (asset.type === AssetType.Potree) {\r\n uploadList.push({\r\n id: asset.id,\r\n url: getUploadURL(projectID, uploadId),\r\n paths: POTREE_FILES.map(filePath => `${asset.path}/${filePath}`),\r\n name: asset.name,\r\n });\r\n }\r\n\r\n if ((asset.type === AssetType.IFC) || (asset.type === AssetType.DXF)) {\r\n uploadList.push({\r\n id: asset.id,\r\n url: getUploadURL(projectID, uploadId),\r\n paths: [asset.path],\r\n name: asset.name\r\n });\r\n }\r\n\r\n if (asset.type === AssetType.SHP) {\r\n uploadList.push({\r\n id: asset.id,\r\n url: getUploadURL(projectID, uploadId),\r\n paths: SHP_FILE_TYPES.map(fileType => pathWithExtension(asset.path, fileType)),\r\n name: asset.name,\r\n });\r\n }\r\n });\r\n\r\n return uploadList;\r\n};\r\n\r\nconst getUploadURL = (projectID, assetID) => {\r\n return `${engineCloudURL}/api/projects/${projectID}/assets/${assetID}/files`;\r\n};\r\n\r\nexport const getCloudExporter = () => {\r\n let projectID;\r\n let statuses = {};\r\n\r\n const exe = new PythonExecutable();\r\n\r\n const startExport = async (opts: ExporterOpts) => {\r\n opts = {...exporterOptsDefaults, ...opts};\r\n\r\n let project;\r\n\r\n try {\r\n project = await createProject(opts.state, opts.update);\r\n } catch {\r\n // Error creating project (missing required values / server error)\r\n opts.onError(t(\"dialog.general-error-title\"), t(\"dialog.export-error-cloud\"));\r\n return;\r\n }\r\n\r\n projectID = project.id;\r\n\r\n const assets = getAssetsToUpload(project, opts);\r\n if (assets.length === 0) {\r\n opts.onFinish(project.id);\r\n return;\r\n }\r\n\r\n // Save assets to temporary json file\r\n const tempOutputPath = getTemporaryFile(\"json\");\r\n const text = JSON.stringify(assets, null, 2);\r\n await fse.writeFile(tempOutputPath, text);\r\n\r\n let commands = [\r\n \"-p\", \"upload_engine_assets\",\r\n \"--engine_cloud_url\", engineCloudURL,\r\n \"--input_path\", tempOutputPath,\r\n \"--app_code\", opts.appCode\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n if (jsonData.progress) {\r\n opts.onProgress(jsonData.progress);\r\n }\r\n\r\n if (jsonData.start) {\r\n statuses = jsonData.start;\r\n opts.onStart(statuses);\r\n }\r\n\r\n if (jsonData.update) {\r\n const status = jsonData.update;\r\n\r\n try {\r\n statuses[status.id].status_code = status.status_code;\r\n const hasError = status.status_code === StatusCode.Errored;\r\n opts.onUpdate(statuses, hasError);\r\n } catch {\r\n console.warn(\"Error updating status row\");\r\n }\r\n }\r\n },\r\n onClose: (error) => {\r\n if (error) return;\r\n opts.onFinish(project.id);\r\n }\r\n });\r\n };\r\n\r\n const cancelExport = (update: boolean) => {\r\n exe.destroy();\r\n\r\n if (update || !projectID) {\r\n return;\r\n }\r\n\r\n fetch(`${engineCloudURL}/api/projects/${projectID}`, {\r\n method: 'DELETE',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n }).then(() => {\r\n projectID = null;\r\n });\r\n };\r\n\r\n return {\r\n startExport,\r\n cancelExport\r\n };\r\n};","import React, {useCallback, useEffect, useMemo, useState} from 'react';\r\nimport {dialog, registerEvent} from '../../electron-modules';\r\nimport {store} from '../../redux/store';\r\nimport {\r\n getCameraFileAssets,\r\n getModelAssets,\r\n getPointCloudAssets,\r\n selectAllAssets\r\n} from '../../redux/assets-slice';\r\nimport {trackToolUsage} from '../../executable';\r\nimport {useSelector} from 'react-redux';\r\nimport {\r\n Button,\r\n CircularProgress,\r\n createStyles,\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n DialogContentText,\r\n DialogTitle,\r\n Grid,\r\n makeStyles,\r\n Theme,\r\n Typography,\r\n useTheme\r\n} from '@material-ui/core';\r\nimport {\r\n DenseDivider,\r\n EnhancedTable,\r\n LinearProgressWithLabel,\r\n SimpleDialog,\r\n TypographyLink\r\n} from '../../components';\r\nimport sanitize from \"sanitize-filename\";\r\nimport {selectProjectID, selectProjectName} from '../../redux/project-slice';\r\nimport {toast} from '../../app';\r\nimport {useTranslation} from 'react-i18next';\r\nimport {useAuth, useDialog} from \"../../hooks\";\r\nimport {getCloudExporter} from \"./exporter\";\r\nimport {getLocalizedProjectName} from '../../utilities';\r\nimport {throttle} from 'throttle-debounce';\r\nimport {getLocalizedURL} from '../../localization';\r\nimport { engineCloudURL } from '../../urls';\r\nimport { useTableState } from '../../hooks/use-table-state';\r\nimport { NewProjectInfo } from '../common';\r\nimport { StatusCode } from '../../types/cloud-export';\r\n\r\ninterface AssetStatus {\r\n filename: string;\r\n status_code: number;\r\n}\r\n\r\ninterface AssetStatuses {\r\n [key: string]: AssetStatus;\r\n}\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n contentCenter: {\r\n textAlign: \"center\"\r\n },\r\n cancelProgress: {\r\n marginRight: theme.spacing(1)\r\n },\r\n cancelContent: {\r\n paddingBottom: theme.spacing(3)\r\n }\r\n }),\r\n);\r\n\r\ninterface LinkedProjectProps {\r\n name: string\r\n}\r\n\r\nconst LinkedProjectInfo = (props: LinkedProjectProps) => {\r\n const {name} = props;\r\n\r\n const {t} = useTranslation();\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst AssetStatusText = (props: {status: AssetStatus}) => {\r\n const {status} = props;\r\n\r\n const theme = useTheme();\r\n const {t} = useTranslation();\r\n\r\n const getColor = (status_code: StatusCode) => {\r\n switch (status_code) {\r\n case StatusCode.Uploaded:\r\n return theme.palette.success.main;\r\n case StatusCode.Uploading:\r\n case StatusCode.Preparing:\r\n return theme.palette.info.main;\r\n case StatusCode.Errored:\r\n return theme.palette.error.main;\r\n case StatusCode.Queued:\r\n default:\r\n return theme.palette.primary.main;\r\n }\r\n };\r\n\r\n const getText = (status_code: StatusCode) => {\r\n switch (status_code) {\r\n case StatusCode.Uploaded:\r\n return t(`export.uploaded`);\r\n case StatusCode.Uploading:\r\n return t(`export.uploading`);\r\n case StatusCode.Preparing:\r\n return t(`export.preparing`);\r\n case StatusCode.Errored:\r\n return t(`export.errored`);\r\n case StatusCode.Queued:\r\n default:\r\n return t(`export.queued`);\r\n }\r\n };\r\n\r\n return (\r\n \r\n {getText(status.status_code)}\r\n \r\n );\r\n};\r\n\r\nexport const CloudExporter = () => {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const {i18n, t} = useTranslation();\r\n\r\n const tableState = useTableState({\r\n defaultSort: \"status_text\",\r\n rowPropertyMap: {\r\n status_text: \"status_code\"\r\n }\r\n });\r\n\r\n const exporterDialog = useDialog();\r\n const messageDialog = useDialog();\r\n const cancelDialog = useDialog();\r\n\r\n const projectID = useSelector(selectProjectID);\r\n const projectName = useSelector(selectProjectName);\r\n const assets = useSelector(selectAllAssets);\r\n const pointClouds = getPointCloudAssets(assets);\r\n const camerasFiles = getCameraFileAssets(assets);\r\n const modelFiles = getModelAssets(assets);\r\n\r\n const [assetStatuses, updateAssetStatuses] = useState({});\r\n const [exportPercent, updateExportPercent] = useState(0);\r\n const [isExportRunning, setIsExportRunning] = useState(false);\r\n const [isExportFinished, setIsExportFinished] = useState(false);\r\n const [projectExists, setProjectExists] = useState(false);\r\n const [hasErrors, setHasErrors] = useState(false);\r\n const [projectURL, setProjectURL] = useState(\"\");\r\n\r\n const {linkAccount, loggedIn, getAppCode} = useAuth();\r\n const {startExport, cancelExport} = useMemo(getCloudExporter, []);\r\n\r\n const percentThrottleMilliseconds = 100;\r\n const setExportPercent = useCallback(throttle(\r\n percentThrottleMilliseconds, (value) => {\r\n updateExportPercent(value);\r\n }), []);\r\n\r\n const updateThrottleMilliseconds = 250;\r\n const setAssetStatuses = useCallback(throttle(\r\n updateThrottleMilliseconds, (value) => {\r\n updateAssetStatuses(value);\r\n }), []);\r\n\r\n const canExport = assets.length > 0;\r\n\r\n const getRows = (assetStatuses: AssetStatuses) => {\r\n return Object.keys(assetStatuses).map(key => {\r\n const assetStatus = assetStatuses[key];\r\n\r\n return {\r\n id: key,\r\n filename: assetStatus.filename,\r\n status_code: assetStatus.status_code,\r\n status_text: \r\n };\r\n });\r\n };\r\n\r\n const reset = () => {\r\n setExportPercent(0);\r\n setAssetStatuses({});\r\n setIsExportFinished(false);\r\n setProjectURL(\"\");\r\n setHasErrors(false);\r\n };\r\n\r\n const onExportFinished = () => {\r\n setIsExportRunning(false);\r\n setIsExportFinished(true);\r\n setExportPercent(100);\r\n };\r\n\r\n const handleExportCancel = () => {\r\n reset();\r\n messageDialog.handleClose();\r\n cancelExport(projectExists);\r\n };\r\n\r\n const handleExport = () => {\r\n exporterDialog.handleClose();\r\n exportToCloud();\r\n };\r\n\r\n const checkProject = async (originalID): Promise => {\r\n try {\r\n const url = `${engineCloudURL}/api/projects/${originalID}/exists`;\r\n const response = await fetch(url);\r\n return response.status === 200;\r\n } catch {\r\n return false;\r\n }\r\n };\r\n\r\n const exportToCloud = async() => {\r\n trackToolUsage(\"exporter\");\r\n\r\n reset();\r\n messageDialog.handleOpen();\r\n\r\n const assets = [\r\n ...pointClouds,\r\n ...camerasFiles,\r\n ...modelFiles\r\n ];\r\n\r\n await startExport({\r\n name: exportName,\r\n assets: assets,\r\n update: projectExists,\r\n state: store.getState(),\r\n appCode: await getAppCode(true),\r\n onStart: setAssetStatuses,\r\n onUpdate: (statuses, error) => {\r\n setAssetStatuses({...statuses});\r\n if (error) setHasErrors(true);\r\n },\r\n onProgress: setExportPercent,\r\n onError: (title, message) => {\r\n onExportFinished();\r\n dialog.showErrorBox(title, message);\r\n },\r\n onFinish: (projectID) => {\r\n setProjectURL(getLocalizedURL(\r\n `${engineCloudURL}/viewer/${projectID}`, i18n.language));\r\n onExportFinished();\r\n }\r\n });\r\n };\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-cloud-export\", async () => {\r\n if (!canExport) return toast.error(t(\"toast.no-data-loaded\"));\r\n\r\n if (!loggedIn) {\r\n const success = await linkAccount();\r\n if (!success) return;\r\n }\r\n\r\n const exists = await checkProject(projectID);\r\n setProjectExists(exists);\r\n exporterDialog.handleOpen();\r\n });\r\n }, [loggedIn, projectID, canExport]);\r\n\r\n const localizedProjectName = getLocalizedProjectName(projectName);\r\n const sanitizedName = sanitize(localizedProjectName);\r\n const exportName = t('export.export-name', {name: sanitizedName});\r\n\r\n let uploadMessage;\r\n\r\n if (projectExists) {\r\n uploadMessage = hasErrors\r\n ? t(\"export.project_updated_with_errors\")\r\n : t(\"export.project-updated-successfully\");\r\n } else {\r\n uploadMessage = hasErrors\r\n ? t(\"export.project_uploaded_with_errors\")\r\n : t(\"export.project-uploaded-successfully\");\r\n }\r\n\r\n const columns = [\r\n {\r\n id: 'filename',\r\n label: t(\"export.filename\")\r\n },\r\n {\r\n id: 'status_text',\r\n label: t(\"export.status\")\r\n }\r\n ];\r\n\r\n const rows = useMemo(() => {\r\n return getRows(assetStatuses);\r\n }, [assetStatuses]);\r\n\r\n return (\r\n \r\n {/* Exporting dialog */}\r\n \r\n {t('export.export-status')}\r\n\r\n \r\n {isExportFinished && (\r\n <>\r\n \r\n {uploadMessage}\r\n \r\n\r\n \r\n\r\n \r\n \r\n )}\r\n\r\n \r\n\r\n {(rows.length > 0) && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n\r\n \r\n {!isExportFinished && (\r\n \r\n {t('export.cancel-export')}\r\n \r\n )}\r\n\r\n {isExportFinished && (\r\n \r\n {t(\"export.close\")}\r\n \r\n )}\r\n \r\n \r\n\r\n {/* Main dialog */}\r\n \r\n \r\n\r\n {/* Export file type(s) info */}\r\n \r\n\r\n {/** Existing cloud project */}\r\n {projectExists && }\r\n\r\n {/** New cloud project */}\r\n {!projectExists && \r\n \r\n\r\n \r\n }\r\n \r\n \r\n \r\n\r\n {/* Cancelling dialog */}\r\n \r\n {t('export.data-export')}\r\n \r\n \r\n \r\n {t('export.cancelling-export')}\r\n \r\n \r\n \r\n
\r\n );\r\n};","import React, {useEffect, useState, memo} from 'react';\r\nimport {\r\n Box,\r\n Button,\r\n Card,\r\n CardContent,\r\n CardHeader,\r\n createStyles,\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n DialogTitle,\r\n Grid,\r\n List,\r\n ListItem,\r\n makeStyles,\r\n MenuItem,\r\n Select,\r\n Theme,\r\n Typography\r\n} from '@material-ui/core';\r\nimport {\r\n DraggableDialog,\r\n ProgressDialog,\r\n PromptDialog,\r\n DenseDivider,\r\n IconToolBar,\r\n SlimScrollbar,\r\n ToolBarButton,\r\n EnhancedIconButton,\r\n DropDownDialog,\r\n TextDialog,\r\n CheckboxWithLabel\r\n} from '../components';\r\nimport { fs, getTemporaryFile, registerEvent } from '../electron-modules';\r\nimport { FolderWithLabel } from '../components';\r\nimport DeleteIcon from '@material-ui/icons/Delete';\r\nimport ZoomInIcon from '@material-ui/icons/ZoomIn';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\r\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\r\nimport AddToPhotosIcon from '@material-ui/icons/AddToPhotos';\r\nimport RefreshIcon from '@material-ui/icons/Refresh';\r\nimport { useSelector } from 'react-redux';\r\nimport {\r\n addAsset,\r\n AssetType,\r\n deleteAsset,\r\n getPointCloudAssets,\r\n selectAllAssets\r\n} from '../redux/assets-slice';\r\nimport { PythonExecutable } from '../executable';\r\nimport path from 'path';\r\nimport { asyncTimeout, useAssetTools } from '../utilities';\r\nimport { toast } from '../app';\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { classifications } from '../classifications';\r\nimport { textToColor } from '../viewer/js/labelling';\r\nimport { createFolder } from '../redux/folders-slice';\r\nimport { OperationType } from '../viewer/js/markup';\r\nimport {\r\n useDialog,\r\n useUniqueProjectID,\r\n useViewer,\r\n useActiveTool\r\n} from '../hooks';\r\nimport { useAppDispatch } from '../redux/store';\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n card: {\r\n margin: theme.spacing(2),\r\n marginTop: theme.spacing(0),\r\n padding: theme.spacing(1),\r\n userSelect: \"none\"\r\n },\r\n cardHeader: {\r\n padding: theme.spacing(1)\r\n },\r\n cardContent: {\r\n padding: `${theme.spacing(2)}px !important`\r\n },\r\n cardButtons: {\r\n marginTop: 0,\r\n alignSelf: \"center\"\r\n },\r\n headerTitle: {\r\n fontWeight: \"bold\"\r\n },\r\n clippingBoxParent: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\"\r\n },\r\n clippingBoxButtons: {\r\n color: \"green\"\r\n },\r\n folderList: {\r\n padding: \"0px\",\r\n overflow: \"auto\",\r\n flex: 1,\r\n alignItems: \"center\",\r\n justifyContent: \"center\"\r\n },\r\n operationList: {\r\n flex: 1,\r\n overflow: \"hidden\",\r\n overflowY: \"auto\"\r\n },\r\n mixedDataWarning: {\r\n padding: theme.spacing(1.0),\r\n color: theme.palette.warning.main,\r\n textAlign: \"center\"\r\n },\r\n boxOrientation: {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n paddingBottom: theme.spacing(1.5),\r\n fontSize: \"0.85em\",\r\n \"&:last-child\": {\r\n paddingBottom: theme.spacing(0)\r\n }\r\n },\r\n dropdownRoot: {\r\n minWidth: \"40%\"\r\n },\r\n dropdownSelect: {\r\n paddingTop: theme.spacing(0),\r\n paddingBottom: theme.spacing(0),\r\n fontSize: \"0.85em\"\r\n }\r\n })\r\n);\r\n\r\nconst CategoryExpand = (props) => {\r\n const {setExpanded, expanded} = props;\r\n\r\n const {t} = useTranslation();\r\n\r\n return ( {\r\n event.stopPropagation();\r\n setExpanded(!expanded);\r\n }}\r\n >\r\n {expanded && }\r\n {!expanded && }\r\n );\r\n};\r\n\r\nconst PointMarkupBox = (props) => {\r\n const {clippingBox, index} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [deletePrompt, setDeletePrompt] = useState(false);\r\n\r\n const handleDelete = () => {\r\n setDeletePrompt(false);\r\n viewer.pointMarkupDeleteBox(clippingBox.id);\r\n };\r\n\r\n const onMouseOver = () => {\r\n viewer.setPointMarkupHover(clippingBox.id, true);\r\n };\r\n\r\n const onMouseLeave = () => {\r\n viewer.setPointMarkupHover(clippingBox.id, false);\r\n };\r\n\r\n return (\r\n \r\n \r\n {t('point-markup.bounding_box_index', {\r\n index: index+1\r\n })}\r\n \r\n\r\n
\r\n {/* Zoom to extent */}\r\n {\r\n viewer.pointMarkupZoom(clippingBox.id);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Reset rotation */}\r\n {\r\n viewer.resetPointMarkupRotation(clippingBox.id);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Delete bounding box */}\r\n {\r\n setDeletePrompt(true);\r\n }}\r\n >\r\n \r\n \r\n
\r\n\r\n {/* Delete Dialog */}\r\n {\r\n setDeletePrompt(false);\r\n }}\r\n title={t('point-markup.delete_bounding_box')}\r\n prompt={t('point-markup.do_you_want_to_delete_this_bounding_box')}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n \r\n );\r\n};\r\n\r\nconst PointMarkupGroup = (props) => {\r\n const {operation} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [expanded, setExpanded] = useState(false);\r\n const [editPrompt, setEditPrompt] = useState(false);\r\n const [deletePrompt, setDeletePrompt] = useState(false);\r\n const [newClassification, setNewClassification] = useState(0);\r\n\r\n const isDelete = operation.type === OperationType.Delete;\r\n const isClassify = operation.type === OperationType.Classify;\r\n const isSplit = operation.type === OperationType.Split;\r\n\r\n const color = textToColor(operation.name);\r\n const newBoxDisabled = viewer?.pointMarkupActive();\r\n const operationBoxes = operation.clippingBoxes;\r\n\r\n const defaultIgnoreValue = isSplit ? -1 : 2;\r\n const [ignoredClassification, setIgnoredClassification]\r\n = useState(defaultIgnoreValue);\r\n\r\n const handleDelete = () => {\r\n setDeletePrompt(false);\r\n viewer.pointMarkupDeleteGroup(operation.id);\r\n };\r\n\r\n const handleRename = (name) => {\r\n if (viewer.pointMarkupNameExists(name)) {\r\n toast.error(t('toast.filename_already_exists'));\r\n return;\r\n }\r\n\r\n setEditPrompt(false);\r\n viewer.updatePointMarkupName(operation.id, name);\r\n };\r\n\r\n const addThenExpand = () => {\r\n viewer.setPointMarkupActive(operation.id);\r\n setExpanded(true);\r\n };\r\n\r\n useEffect(() => {\r\n viewer.setPointMarkupNewClassification(operation.id, newClassification);\r\n }, [viewer, newClassification]);\r\n\r\n useEffect(() => {\r\n viewer.setPointMarkupIgnoredClassification(operation.id, ignoredClassification);\r\n }, [viewer, ignoredClassification]);\r\n\r\n let classOptions = [];\r\n for (let i=0; i<32; i++) {\r\n const {id, name} = classifications[i];\r\n const displayName = `${name} (${id})`;\r\n classOptions.push({displayName});\r\n };\r\n\r\n return (\r\n \r\n \r\n {/* Header */}\r\n \r\n {/* Expand/collapse areas */}\r\n \r\n\r\n {/* Edit output name */}\r\n {\r\n setEditPrompt(true);\r\n }}\r\n >\r\n \r\n \r\n\r\n {/* Add new bounding box */}\r\n \r\n \r\n \r\n\r\n {/* Delete operation box */}\r\n {\r\n setDeletePrompt(true);\r\n }}\r\n >\r\n \r\n \r\n \r\n }\r\n disableTypography={true}\r\n title={\r\n \r\n {operation.name}\r\n \r\n }\r\n subheader={\r\n \r\n {t('point-markup.bounding_boxes', {\r\n count: operationBoxes.length\r\n })}\r\n \r\n }\r\n />\r\n\r\n {expanded && (\r\n {/** Ignore Classification */}\r\n {(isClassify || isDelete) && (\r\n
\r\n {t('point-markup.ignore_classification')}\r\n {\r\n setIgnoredClassification(event.target.value);\r\n }}\r\n >\r\n {t('point-markup.use_all_classes')}\r\n {classOptions}\r\n \r\n
\r\n
)}\r\n\r\n {/** New classification */}\r\n {isClassify && (\r\n
\r\n {t('point-markup.new_classification')}\r\n {\r\n setNewClassification(event.target.value);\r\n }}\r\n >\r\n {classOptions}\r\n \r\n
\r\n
)}\r\n\r\n {(operationBoxes.length > 0) && (\r\n \r\n\r\n {/** Bounding boxes */}\r\n \r\n {operationBoxes.map((clippingBox, index) =>\r\n \r\n )}\r\n \r\n )}\r\n\r\n
)}\r\n \r\n\r\n {/* Delete Dialog */}\r\n {\r\n setDeletePrompt(false);\r\n }}\r\n title={t('point-markup.delete_bounding_boxes')}\r\n prompt={t('point-markup.do_you_want_to_delete_this_operation_including_all_bounding_boxes')}\r\n button={t('buttons.delete')}\r\n />\r\n\r\n {/* Output Name Dialog */}\r\n setEditPrompt(false)}\r\n onSubmit={handleRename}\r\n title={t('point-markup.edit_output_file')}\r\n prompt={t('point-markup.enter_new_filename')}\r\n placeholder={operation.name}\r\n label={t('point-markup.output_file')}\r\n />\r\n \r\n );\r\n};\r\n\r\nconst DataExportSplit = (props) => {\r\n const {open, setOpen, setProgress, markupGroups, visibleClouds} = props;\r\n\r\n const classes = useStyles();\r\n const dispatch = useAppDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const {addAssetPaths} = useAssetTools();\r\n\r\n const [exportPoints, setExportPoints] = useState(true);\r\n const [exportImages, setExportImages] = useState(true);\r\n const [outputPath, setOutputPath] = useState(null);\r\n\r\n const handleClose = () => {\r\n setOpen(false);\r\n setExportPoints(true);\r\n setExportImages(true);\r\n setOutputPath(null);\r\n setProgress(0.0);\r\n };\r\n\r\n const handleSubmit = () => {\r\n if (visibleClouds.length === 0) {\r\n toast.warning(t(\"toast.no-point-clouds\"));\r\n return;\r\n }\r\n\r\n const operationData = markupGroups.map(operation => {\r\n const operationBoxes = operation.clippingBoxes;\r\n const attributes = operationBoxes.map(x => x.attributes);\r\n\r\n return {\r\n name: operation.name,\r\n data: attributes\r\n };\r\n });\r\n\r\n const cameras = viewer.getAllCameras();\r\n const cameraData = cameras.map(camera => {\r\n const position = camera.position.value\r\n .toArray();\r\n\r\n const rotation = camera.rotation.eulerDegrees\r\n .toArray()\r\n .slice(0,3);\r\n\r\n return {\r\n name: camera.name,\r\n path: camera.path,\r\n position,\r\n rotation\r\n };\r\n });\r\n\r\n const jsonData = {\r\n operationData,\r\n outputPath,\r\n inputPaths: exportPoints ? inputPaths : [],\r\n imageData: exportImages ? cameraData : [],\r\n };\r\n\r\n // Write file to temp path\r\n const text = JSON.stringify(jsonData, null, 4);\r\n const tempTextPath = getTemporaryFile(\"txt\");\r\n\r\n try {\r\n fs.writeFileSync(tempTextPath, text);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.markup-failed\"));\r\n\r\n return;\r\n }\r\n\r\n toast.success(t(\"toast.markup-submit\"));\r\n\r\n let outputPaths = null;\r\n let processTimeout = 500;\r\n\r\n const exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", \"apply_data_splitting\",\r\n \"--input_json\", tempTextPath\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n if (jsonData.progress) {\r\n setProgress(jsonData.progress);\r\n } else if (jsonData.output_paths) {\r\n outputPaths = jsonData.output_paths;\r\n }\r\n },\r\n onClose: async () => {\r\n if (!outputPaths) {\r\n toast.error(t(\"toast.markup-failed\"));\r\n handleClose();\r\n return;\r\n }\r\n\r\n await asyncTimeout(processTimeout);\r\n viewer.clearPointMarkup();\r\n toast.success(t(\"toast.markup-import\"));\r\n\r\n for (let outputPath of outputPaths) {\r\n const folder = await dispatch(createFolder(outputPath.name));\r\n await addAssetPaths(outputPath.paths, folder.id);\r\n }\r\n\r\n handleClose();\r\n }\r\n });\r\n };\r\n\r\n let canSubmit = false;\r\n let pathOverlap = false;\r\n\r\n const inputPaths = visibleClouds.map(x => x.path);\r\n const inputFoldersPoints = inputPaths.map(x => path.dirname(x));\r\n\r\n if (viewer) {\r\n const cameras = viewer.getAllCameras();\r\n const inputFolderCameras = viewer.getCameraFolders(cameras);\r\n\r\n const inputFolders = new Set([\r\n ...inputFoldersPoints,\r\n ...inputFolderCameras\r\n ]);\r\n\r\n pathOverlap = inputFolders.has(outputPath);\r\n\r\n canSubmit = !pathOverlap\r\n && (outputPath !== null)\r\n && (exportImages || exportPoints);\r\n }\r\n\r\n return (\r\n \r\n {t('point-markup.point-markup-export')}\r\n\r\n \r\n \r\n\r\n {pathOverlap && (\r\n \r\n {t('point-markup.output-folder-must-be-different')}\r\n \r\n )}\r\n\r\n {/* Include images in export */}\r\n \r\n \r\n \r\n\r\n {/* Include points in export */}\r\n \r\n \r\n \r\n\r\n {/* Output folder */}\r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n );\r\n};\r\n\r\nconst DataExportMarkup = (props) => {\r\n const {open, setOpen, setProgress, markupGroups, visibleClouds} = props;\r\n\r\n const classes = useStyles();\r\n const dispatch = useAppDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [overwriteFile, setOverwriteFile] = useState(false);\r\n const [outputPath, setOutputPath] = useState(null);\r\n\r\n const handleClose = () => {\r\n setOpen(false);\r\n setOverwriteFile(false);\r\n setOutputPath(null);\r\n setProgress(0.0);\r\n };\r\n\r\n const handleSubmit = () => {\r\n if (visibleClouds.length === 0) {\r\n toast.warning(t(\"toast.no-point-clouds\"));\r\n return;\r\n }\r\n\r\n let boundingBoxes = markupGroups.map(operation => {\r\n const operationBoxes = operation.clippingBoxes;\r\n const attributes = operationBoxes.map(x => x.attributes);\r\n return attributes;\r\n }).flat();\r\n\r\n const jsonData = {\r\n inputPaths,\r\n outputPath,\r\n boundingBoxes,\r\n overwriteFile\r\n };\r\n\r\n // Write file to temp path\r\n const text = JSON.stringify(jsonData, null, 4);\r\n const tempTextPath = getTemporaryFile(\"txt\");\r\n\r\n try {\r\n fs.writeFileSync(tempTextPath, text);\r\n } catch(err) {\r\n console.log(err);\r\n toast.error(t(\"toast.markup-failed\"));\r\n\r\n return;\r\n }\r\n\r\n toast.success(t(\"toast.markup-submit\"));\r\n\r\n let newCloudPaths = null;\r\n let processTimeout = 500;\r\n\r\n const exe = new PythonExecutable();\r\n let commands = [\r\n \"-p\", \"apply_point_markup\",\r\n \"--input_json\", tempTextPath\r\n ];\r\n\r\n exe.run({\r\n command: commands,\r\n saveLogs: true,\r\n onLine: jsonData => {\r\n if (jsonData.progress) {\r\n setProgress(jsonData.progress);\r\n } else if (jsonData.output_paths) {\r\n newCloudPaths = jsonData.output_paths;\r\n }\r\n },\r\n onClose: async () => {\r\n if (!newCloudPaths) {\r\n toast.error(t(\"toast.markup-failed\"));\r\n handleClose();\r\n return;\r\n }\r\n\r\n await asyncTimeout(processTimeout);\r\n viewer.clearPointMarkup();\r\n toast.success(t(\"toast.markup-import\"));\r\n\r\n visibleClouds.forEach((asset, index) => {\r\n\r\n const assetPath = newCloudPaths[index];\r\n\r\n // Add new pointcloud\r\n dispatch(addAsset({\r\n folderID: asset.folderID,\r\n name: path.basename(assetPath),\r\n path: assetPath,\r\n type: asset.type\r\n }));\r\n\r\n // Remove old pointcloud\r\n dispatch(deleteAsset(asset.id));\r\n });\r\n\r\n handleClose();\r\n }\r\n });\r\n };\r\n\r\n const inputPaths = visibleClouds.map(x => x.path);\r\n const inputFolders = inputPaths.map(x => path.dirname(x));\r\n\r\n let canSubmit = true;\r\n\r\n let pathOverlap = inputFolders.includes(outputPath);\r\n if (pathOverlap) {\r\n canSubmit = false;\r\n }\r\n\r\n if (!overwriteFile && (outputPath === null)) {\r\n canSubmit = false;\r\n }\r\n\r\n return (\r\n \r\n {t('point-markup.point-markup-export')}\r\n\r\n \r\n \r\n\r\n {pathOverlap && (\r\n \r\n {t('point-markup.output-folder-must-be-different')}\r\n \r\n )}\r\n\r\n {/* Setting layer default */}\r\n \r\n {\r\n setOverwriteFile(value);\r\n setOutputPath(null);\r\n }}\r\n />\r\n \r\n\r\n {/* Output folder */}\r\n {!overwriteFile && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n \r\n\r\n \r\n );\r\n};\r\n\r\nexport const PointMarkup = memo((props: any) => {\r\n const {markupGroups} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const pointMarkupDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const {activeToolOpen, setActiveToolOpen} = useActiveTool();\r\n\r\n const [toolType, setToolType] = useState(null);\r\n const [closePrompt, setClosePrompt] = useState(false);\r\n const [exportPromptMarkup, setExportPromptMarkup] = useState(false);\r\n const [exportPromptSplit, setExportPromptSplit] = useState(false);\r\n const [newOperationPrompt, setNewOperationPrompt] = useState(false);\r\n const [newOutputPrompt, setNewOutputPrompt] = useState(false);\r\n const [conversionProgress, setConversionProgress] = useState(0);\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const pointClouds = getPointCloudAssets(assets);\r\n const LASfiles = pointClouds.filter(x => x.type === AssetType.LAS);\r\n const visibleClouds = LASfiles.filter(x => x.visible);\r\n\r\n const checkClose = () => {\r\n if (isModified) {\r\n setClosePrompt(true);\r\n } else {\r\n pointMarkupDialog.handleClose();\r\n }\r\n };\r\n\r\n const addNewOperation = (operationType) => {\r\n setNewOperationPrompt(false);\r\n\r\n if (operationType === OperationType.Delete) {\r\n viewer.addPointMarkupOperation(operationType, t('point-markup.delete_point_data'));\r\n } else if (operationType === OperationType.Classify) {\r\n viewer.addPointMarkupOperation(operationType, t('point-markup.classify_point_data'));\r\n }\r\n };\r\n\r\n const addNewOutputFolder = (name) => {\r\n if (viewer.pointMarkupNameExists(name)) {\r\n toast.error(t('toast.filename_already_exists'));\r\n return;\r\n }\r\n\r\n setNewOutputPrompt(false);\r\n\r\n const operationType = OperationType.Split;\r\n viewer.addPointMarkupOperation(operationType, name);\r\n };\r\n\r\n useEffect(() => {\r\n /** Keep track if a tool is currently being used */\r\n setActiveToolOpen(pointMarkupDialog.open);\r\n }, [pointMarkupDialog.open]);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n pointMarkupDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-point-markup\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n pointMarkupDialog.handleOpen(\"markup\");\r\n });\r\n\r\n registerEvent(\"open-data-splitting\", () => {\r\n if (activeToolOpen) return toast.warning(t('toast.one_tool_only'));\r\n pointMarkupDialog.handleOpen(\"split\");\r\n });\r\n }, [activeToolOpen]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.pointMarkupToggle(pointMarkupDialog.open);\r\n }, [viewer, pointMarkupDialog.open]);\r\n\r\n useEffect(() => {\r\n setToolType(pointMarkupDialog.data);\r\n }, [pointMarkupDialog.data]);\r\n\r\n const isPointMarkup = toolType === \"markup\";\r\n const isFolderSplit = toolType === \"split\";\r\n const isModified = markupGroups.length > 0;\r\n const mixedData = pointClouds.length !== LASfiles.length;\r\n\r\n const dialogTitle = isPointMarkup\r\n ? t('point-markup.point-cloud-markup')\r\n : t('point-markup.data-splitting');\r\n\r\n return (\r\n \r\n \r\n\r\n {/* Label toolbar icons */}\r\n \r\n {/* Add new operation */}\r\n {\r\n setNewOperationPrompt(true);\r\n }}\r\n success\r\n />\r\n\r\n {/* Add new output file */}\r\n {\r\n setNewOutputPrompt(true);\r\n }}\r\n success\r\n />\r\n\r\n {/* Apply changes to las file */}\r\n {\r\n if (isPointMarkup) {\r\n setExportPromptMarkup(true);\r\n } else {\r\n setExportPromptSplit(true);\r\n }\r\n }}\r\n />\r\n \r\n\r\n \r\n\r\n {mixedData && (\r\n \r\n {t('point-markup.will-only-to-las-files')}\r\n \r\n )}\r\n\r\n \r\n \r\n \r\n {markupGroups.map(operation =>\r\n \r\n )}\r\n \r\n \r\n \r\n\r\n \r\n\r\n {/* Close modal */}\r\n setClosePrompt(false)}\r\n onSubmit={() => {\r\n pointMarkupDialog.handleClose();\r\n setClosePrompt(false);\r\n }}\r\n title={t('point-markup.close-window')}\r\n prompt={t('point-markup.want-to-close')}\r\n button={t('point-markup.close')}\r\n />\r\n\r\n {/* Add new operation */}\r\n {\r\n setNewOperationPrompt(false);\r\n }}\r\n onSubmit={addNewOperation}\r\n title={t('point-markup.add_new_operation')}\r\n prompt={t('point-markup.select_operation_type')}\r\n defaultValue={OperationType.Delete}\r\n options={[\r\n [OperationType.Delete, t('point-markup.delete_point_data')],\r\n [OperationType.Classify, t('point-markup.classify_point_data')]\r\n ]}\r\n />\r\n\r\n {/* Add output folder */}\r\n {\r\n setNewOutputPrompt(false);\r\n }}\r\n onSubmit={addNewOutputFolder}\r\n title={t('point-markup.create_new_output')}\r\n prompt={t('point-markup.enter_new_file_name')}\r\n label={t('point-markup.output_file_name')}\r\n />\r\n\r\n {/* Conversion percent dialog */}\r\n 0}\r\n text={t('point-markup.applying-point-cloud-markup')}\r\n percent={conversionProgress}\r\n />\r\n\r\n {/* Point markup export */}\r\n {exportPromptMarkup && ()}\r\n\r\n {/* Data splitting export */}\r\n {exportPromptSplit && ()}\r\n\r\n \r\n );\r\n});\r\n","import React, {useEffect, useState, memo} from 'react';\r\nimport {\r\n Button,\r\n Card,\r\n CardContent,\r\n CardHeader,\r\n createStyles,\r\n Dialog,\r\n DialogActions,\r\n DialogContent,\r\n DialogTitle,\r\n FormControlLabel,\r\n IconButton,\r\n InputLabel,\r\n List,\r\n ListSubheader,\r\n makeStyles,\r\n MenuItem,\r\n Radio,\r\n RadioGroup,\r\n Select,\r\n Table,\r\n TableBody,\r\n TableCell,\r\n TableContainer,\r\n TableHead,\r\n TableRow,\r\n Theme,\r\n Typography,\r\n useTheme\r\n} from '@material-ui/core';\r\nimport clsx from 'clsx';\r\nimport RotateRightIcon from '@material-ui/icons/RotateRight';\r\nimport {\r\n AerialAreaMeasurement, AerialLengthMeasurement,\r\n HeightMeasurement,\r\n Measurement3D, MeasurementArea, MeasurementPoint,\r\n MeasurementVolume, StationMeasurement\r\n} from '../viewer/js/measurements';\r\nimport DeleteIcon from '@material-ui/icons/Delete';\r\nimport EditIcon from '@material-ui/icons/Edit';\r\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\r\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\r\nimport 'font-awesome/css/font-awesome.css';\r\nimport { dialog, fs, isStaticSite } from \"../electron-modules\";\r\nimport slash from 'slash';\r\nimport fileDialog from 'file-dialog';\r\nimport { useSelector, useDispatch } from 'react-redux';\r\nimport { selectMeasureUnits, changeMeasureUnits, selectDataProjection } from '../redux/projections-slice';\r\nimport LocalScene from '../viewer/js/projections';\r\nimport {\r\n ArrowTooltip,\r\n PromptDialog,\r\n TextDialog,\r\n DenseDivider,\r\n IconToolBar,\r\n SlimScrollbar,\r\n ToolBarButton,\r\n ToolBarDivider,\r\n DraggableDialog,\r\n DenseMenu\r\n} from '../components';\r\nimport { toast } from '../app';\r\nimport { measureDataFilter, measureDataFormat } from '../file-extensions';\r\nimport { useTranslation } from 'react-i18next';\r\nimport {selectAllAssets, getLandXMLAssets, XMLData} from \"../redux/assets-slice\";\r\nimport {\r\n useDialog,\r\n useUniqueProjectID,\r\n useViewer,\r\n useActiveTool,\r\n useContextMenu\r\n} from '../hooks';\r\nimport { nanoid } from '@reduxjs/toolkit';\r\nimport { VolumeType, SamplingRate, MeasureType } from '../types/measurements';\r\nimport copyTextToClipboard from \"copy-to-clipboard\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n copyClipboard: {\r\n cursor: \"pointer\"\r\n },\r\n textField: {\r\n marginBottom: theme.spacing(3)\r\n },\r\n userWarning: {\r\n display: \"block\",\r\n padding: theme.spacing(1, 0),\r\n color: theme.palette.warning.main,\r\n textAlign: \"center\"\r\n },\r\n cardButtons: {\r\n marginTop: 0,\r\n alignSelf: \"center\"\r\n },\r\n card: {\r\n margin: theme.spacing(2),\r\n marginTop: theme.spacing(0),\r\n padding: theme.spacing(1),\r\n userSelect: \"none\"\r\n },\r\n cardHeader: {\r\n padding: theme.spacing(1)\r\n },\r\n cardContent: {\r\n padding: `${theme.spacing(2)}px !important`\r\n },\r\n footerDiv: {\r\n width: \"100%\",\r\n boxShadow: \"0px 10px 10px 2px\",\r\n zIndex: 1,\r\n textAlign: \"center\"\r\n },\r\n measurementUnitsParent: {\r\n justifyContent: \"space-between\",\r\n padding: theme.spacing(0, 2),\r\n flexWrap: \"nowrap\"\r\n },\r\n measurementUnits: {\r\n margin: theme.spacing(0)\r\n },\r\n measurementUnitsRadio: {\r\n padding: theme.spacing(0.5),\r\n margin: theme.spacing(0)\r\n },\r\n imageOnlyInfoButton: {\r\n marginLeft: theme.spacing(1)\r\n },\r\n marginside: {\r\n margin: 0,\r\n padding: \"10px\"\r\n },\r\n actions: {\r\n padding: \"5px\"\r\n },\r\n expandText: {\r\n width: \"100%\",\r\n display: \"block\",\r\n textAlign: \"center\",\r\n cursor: \"pointer\",\r\n userSelect: \"none\",\r\n paddingBottom: \"5px\",\r\n paddingTop: \"5px\"\r\n },\r\n bold: {\r\n fontWeight: \"bold\"\r\n },\r\n row: {\r\n display: \"flex\",\r\n width: \"100%\",\r\n alignItems: \"baseline\"\r\n },\r\n alignmentSelect: {\r\n alignSelf: \"center\",\r\n width: \"90%\"\r\n },\r\n cell: {\r\n padding: theme.spacing(0.5),\r\n fontSize: \"0.85em !important\"\r\n },\r\n tableCell: {\r\n fontSize: \"0.8rem !important\",\r\n textAlign: \"center\"\r\n },\r\n cellParent: {\r\n flex: 1,\r\n display: \"flex\",\r\n alignItems: \"baseline\",\r\n justifyContent: \"space-between\",\r\n padding: theme.spacing(0, 0.5)\r\n },\r\n measureTable: {\r\n width: \"fit-content\",\r\n margin: \"0px auto\",\r\n marginTop: theme.spacing(1.5)\r\n },\r\n headerTitle: {\r\n fontWeight: \"bold\",\r\n cursor: \"pointer\"\r\n },\r\n calculateButton: {\r\n padding: theme.spacing(0),\r\n fontSize: \"0.7rem\"\r\n },\r\n recalculate: {\r\n display: \"flex\",\r\n flexDirection: \"row-reverse\",\r\n alignItems: \"center\"\r\n },\r\n recalculateButton: {\r\n padding: theme.spacing(0),\r\n marginRight: theme.spacing(1)\r\n },\r\n })\r\n);\r\n\r\nconst ExportDialog = (props) => {\r\n const {open, classes, onClose} = props;\r\n\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n\r\n const [exportType, setExportType] = useState(\"csv\");\r\n const [ordering, setOrdering] = useState(\"xyz\");\r\n\r\n const onSubmit = () => {\r\n viewer?.exportMeasurements(exportType, ordering);\r\n onClose();\r\n };\r\n\r\n return (\r\n \r\n \r\n {t('measure.measurements-export')}\r\n \r\n\r\n \r\n {/* Export type */}\r\n {t('measure.export-type')}\r\n {\r\n setExportType(event.target.value as string);\r\n }}\r\n >\r\n {t('measure.csv-file')}\r\n {t('measure.measure-data')}\r\n {t('measure.measure-data-dxf')}\r\n {t('measure.measure-data-shp')}\r\n \r\n\r\n {exportType === \"csv\" && (\r\n \r\n {/* Ordering */}\r\n {t('measure.ordering')}\r\n {\r\n setOrdering(event.target.value as string);\r\n }}\r\n >\r\n {t('measure.easting-northing-elevation')}\r\n {t('measure.northing-easting-elevation')}\r\n \r\n \r\n )}\r\n\r\n {exportType !== \"csv\" && (\r\n \r\n {t('measure.the-file-generated-using-measure-data')}\r\n \r\n )}\r\n \r\n\r\n \r\n \r\n\r\n \r\n {t('buttons.export')}\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst MeasureTypeIcon = (props) => {\r\n const {type, title, icon, measureType, setMeasureType} = props;\r\n\r\n const onClick = () => {\r\n setMeasureType(type);\r\n };\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nconst ImportExportIcon = (props) => {\r\n const {icon, onClick} = props;\r\n const {t} = useTranslation();\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nconst ClipboardCopy = (props) => {\r\n const {text, ...other} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n return (\r\n {\r\n event.stopPropagation();\r\n copyTextToClipboard(text);\r\n toast.success(t(\"toast.copied-to-clipboard\"));\r\n }}\r\n {...other}\r\n >\r\n \r\n {props.children}\r\n \r\n \r\n );\r\n};\r\n\r\nconst MeasurementCard = (props) => {\r\n const {measurement, first} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const renameDialog = useDialog();\r\n const deleteDialog = useDialog();\r\n\r\n const [expanded, setExpanded] = useState(false);\r\n const formatter = viewer.getMeasurementFormatter();\r\n\r\n const onMouseOver = () => {\r\n viewer?.updateMeasureHover(measurement, true);\r\n };\r\n\r\n const onMouseLeave = () => {\r\n viewer?.updateMeasureHover(measurement, false);\r\n };\r\n\r\n const generateVertexPositions = () => {\r\n if (!(measurement instanceof Measurement3D)) {\r\n return ();\r\n }\r\n\r\n const precision = formatter.getVectorPrecision(LocalScene.viewProjection);\r\n const verticesReprojected = measurement.vertices.map(vertex => {\r\n return vertex.toViewProjection();\r\n });\r\n\r\n const singlePoint = verticesReprojected.length === 1;\r\n\r\n if (singlePoint) {\r\n const x = verticesReprojected[0].x.toFixed(precision.x);\r\n const y = verticesReprojected[0].y.toFixed(precision.y);\r\n const z = verticesReprojected[0].z.toFixed(precision.z);\r\n const text = `(${x}, ${y}, ${z})`;\r\n\r\n return (\r\n
\r\n {/** Single point */}\r\n
\r\n
\r\n {t('measure.position')}\r\n
\r\n\r\n \r\n
{text}
\r\n
\r\n
\r\n
\r\n );\r\n }\r\n\r\n return (\r\n \r\n \r\n\r\n \r\n \r\n \r\n {t('measure.measurement_positions_xyz')}\r\n \r\n \r\n \r\n\r\n \r\n {verticesReprojected.map((vertex, index) => {\r\n const x = vertex.x.toFixed(precision.x);\r\n const y = vertex.y.toFixed(precision.y);\r\n const z = vertex.z.toFixed(precision.z);\r\n const text = `(${x}, ${y}, ${z})`;\r\n\r\n return (\r\n \r\n \r\n \r\n
{text}
\r\n
\r\n
\r\n
\r\n );\r\n\r\n })}\r\n
\r\n\r\n
\r\n
\r\n );\r\n };\r\n\r\n const getVolumeComponent = (measurement: MeasurementVolume) => {\r\n if (!measurement.valid) {\r\n return measurement.invalidVolumeMessage;\r\n }\r\n\r\n if (measurement.calculated) {\r\n const value = formatter.formatVolume(measurement);\r\n\r\n return (\r\n
\r\n
\r\n \r\n {\r\n event.stopPropagation();\r\n measurement.calculateVolume();\r\n }}\r\n >\r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n\r\n return (\r\n \r\n {t('measure.calculating')}\r\n \r\n );\r\n };\r\n\r\n const handleRenameSubmit = name => {\r\n renameDialog.handleClose();\r\n viewer?.renameMeasurement(measurement, name);\r\n };\r\n\r\n const handleDeleteSubmit = () => {\r\n deleteDialog.handleClose();\r\n viewer?.deleteMeasurement(measurement);\r\n };\r\n\r\n const getVolumeMethod = () => {\r\n return (measurement.volumeType === VolumeType.LowestPlane)\r\n ? t('measure.volume_lowest_plane')\r\n : t('measure.volume_multi_plane');\r\n };\r\n\r\n const getVolumeRate = () => {\r\n if (measurement.sampleRate === SamplingRate.High) return t('general.high');\r\n if (measurement.sampleRate === SamplingRate.Medium) return t('general.medium');\r\n if (measurement.sampleRate === SamplingRate.Low) return t('general.low');\r\n return t('general.unknown');\r\n };\r\n\r\n useEffect(() => {\r\n setExpanded(first);\r\n }, [first]);\r\n\r\n const positions = generateVertexPositions();\r\n\r\n const is3DPoint = measurement instanceof MeasurementPoint;\r\n const is3DArea = measurement instanceof MeasurementArea;\r\n const isVolume = measurement instanceof MeasurementVolume;\r\n const is2DArea = measurement instanceof AerialAreaMeasurement;\r\n const is3DLength = measurement instanceof Measurement3D && !is3DPoint && !is3DArea;\r\n const is2DLength = measurement instanceof AerialLengthMeasurement;\r\n const hasHeight = measurement instanceof HeightMeasurement;\r\n const isStationMeasurement = measurement instanceof StationMeasurement;\r\n\r\n return (\r\n \r\n \r\n {/* Header */}\r\n \r\n {/* Expand/collapse measurement */}\r\n \r\n {\r\n event.stopPropagation();\r\n setExpanded(!expanded);\r\n }}\r\n >\r\n {expanded && }\r\n {!expanded && }\r\n \r\n \r\n\r\n {/* Rename measurement */}\r\n \r\n {\r\n event.stopPropagation();\r\n renameDialog.handleOpen();\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n {/* Delete measurement */}\r\n \r\n {\r\n event.stopPropagation();\r\n deleteDialog.handleOpen();\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n \r\n }\r\n title={measurement.title}\r\n titleTypographyProps={{\r\n variant: \"body2\",\r\n className: classes.headerTitle\r\n }}\r\n subheader={t('measure.total-vertices-measurement', {\r\n count: measurement.numVertices\r\n })}\r\n subheaderTypographyProps={{\r\n variant: \"caption\"\r\n }}\r\n />\r\n\r\n {/* Expandable content */}\r\n {expanded && (\r\n \r\n\r\n {is3DLength && (\r\n
\r\n {/** 2D Distance */}\r\n
\r\n
\r\n {t('measure.row-distance-2d')}\r\n
\r\n\r\n
\r\n {formatter.formatLength(measurement.distance2D)}\r\n
\r\n
\r\n\r\n {/** Grade */}\r\n
\r\n
\r\n {t('measure.row-grade')}\r\n
\r\n\r\n
\r\n {formatter.formatGrade(measurement.grade)}\r\n
\r\n
\r\n
\r\n\r\n
\r\n {/** 3D Distance */}\r\n
\r\n
\r\n {t('measure.row-distance-3d')}\r\n
\r\n\r\n
\r\n {formatter.formatLength(measurement.distance3D)}\r\n
\r\n
\r\n\r\n {/** Angle */}\r\n
\r\n
\r\n {t('measure.row-angle')}\r\n
\r\n\r\n
\r\n {formatter.formatGrade(measurement.angle)}\r\n
\r\n
\r\n
\r\n
)}\r\n\r\n {hasHeight && (\r\n
\r\n {/** Height */}\r\n
\r\n
\r\n {t('measure.row-height')}\r\n
\r\n\r\n
\r\n {formatter.formatLength(measurement.height)}\r\n
\r\n
\r\n\r\n {/** Blank div */}\r\n
\r\n
\r\n )}\r\n\r\n {is3DArea && (\r\n
\r\n {/** Area */}\r\n
\r\n
\r\n {t('measure.row-area')}\r\n
\r\n\r\n
\r\n
\r\n\r\n {/** Volume */}\r\n {isVolume && (
\r\n
\r\n {t('measure.row-volume')}\r\n
\r\n\r\n
\r\n {getVolumeComponent(measurement)}\r\n
\r\n
)}\r\n\r\n {/** Blank div */}\r\n {!isVolume && (
)}\r\n
\r\n )}\r\n\r\n {is2DArea && (\r\n
\r\n {/** Area */}\r\n
\r\n
\r\n {measurement.header}\r\n
\r\n
\r\n
\r\n\r\n {/** Blank div */}\r\n
\r\n
\r\n )}\r\n\r\n {is2DLength && (\r\n
\r\n {/** 2D Distance */}\r\n
\r\n
\r\n {measurement.header}\r\n
\r\n
\r\n {formatter.formatLength(measurement.distance2D)}\r\n
\r\n
\r\n\r\n {/** Blank div */}\r\n
\r\n
\r\n )}\r\n\r\n {isVolume && (\r\n
\r\n\r\n {/** Volume Type */}\r\n
\r\n
\r\n {t('measure.method')}\r\n
\r\n\r\n
\r\n {getVolumeMethod()}\r\n
\r\n
\r\n\r\n {/** Sampling Rate */}\r\n
\r\n
\r\n {t('measure.sampling_rate')}\r\n
\r\n\r\n
\r\n {getVolumeRate()}\r\n
\r\n
\r\n\r\n
\r\n
)}\r\n\r\n {isStationMeasurement && (\r\n
\r\n {/** Station*/}\r\n
\r\n
\r\n {t('measure.station-distAlong')}\r\n
\r\n\r\n
\r\n {formatter.formatStation(measurement)}\r\n
\r\n
\r\n\r\n {/** Offset */}\r\n
\r\n
\r\n {t('measure.station-distAcross')}\r\n
\r\n\r\n
\r\n {formatter.formatOffset(measurement)}\r\n
\r\n
\r\n
\r\n
)}\r\n\r\n {positions}\r\n\r\n \r\n )}\r\n \r\n\r\n {/* Delete Dialog */}\r\n \r\n\r\n {/* Rename Dialog */}\r\n \r\n \r\n );\r\n};\r\n\r\nexport const Measurements = memo((props: any) => {\r\n const {measurementsDialog, measurements} = props;\r\n\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n const dispatch = useDispatch();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const contextMenu = useContextMenu();\r\n const exportDialog = useDialog();\r\n const uniqueProjectID = useUniqueProjectID();\r\n const {setActiveToolOpen} = useActiveTool();\r\n\r\n const assets = useSelector(selectAllAssets);\r\n const xmlAssets = getLandXMLAssets(assets);\r\n\r\n const dataProjection = useSelector(selectDataProjection);\r\n const measurementUnits = useSelector(selectMeasureUnits);\r\n const [activeMeasurePrompt, setActiveMeasurePrompt] = useState(false);\r\n const [measureType, setMeasureType] = useState(MeasureType.Length);\r\n const [alignmentChoice, setAlignmentChoice] = useState(\"\");\r\n const [measureUnits, setMeasureUnits] = useState('m');\r\n\r\n const loadImportData = (text) => {\r\n let encoded = decodeURIComponent(text);\r\n let data = JSON.parse(encoded);\r\n viewer.loadMeasurementData(data);\r\n };\r\n\r\n const openImportElectron = () => {\r\n dialog.showOpenDialog({\r\n filters: measureDataFilter,\r\n properties: ['openFile']\r\n }).then(result => {\r\n if (result.canceled) {\r\n return;\r\n }\r\n\r\n if (result.filePaths) {\r\n const filePath = slash(result.filePaths[0]);\r\n fs.readFile(filePath, 'utf-8', (err, text) => {\r\n if (err) {\r\n dialog.showErrorBox(t('dialog.measure-load-title'),\r\n t('dialog.measure-load-message'));\r\n }\r\n\r\n loadImportData(text);\r\n });\r\n }\r\n }).catch(() => {\r\n dialog.showErrorBox(t(\"dialog.general-error-title\"),\r\n t(\"dialog.file-load-error\"));\r\n });\r\n };\r\n\r\n const openImportBrowser = () => {\r\n fileDialog({accept: `.${measureDataFormat}`})\r\n .then(files => {\r\n if (files.length === 0) {\r\n return;\r\n }\r\n\r\n let reader = new FileReader();\r\n reader.onload = event => {\r\n let text = event.target.result;\r\n loadImportData(text);\r\n };\r\n reader.readAsText(files[0]);\r\n });\r\n };\r\n\r\n const onExport = () => {\r\n contextMenu.handleClose();\r\n exportDialog.handleOpen();\r\n };\r\n\r\n const onImport = () => {\r\n contextMenu.handleClose();\r\n\r\n if (isStaticSite) {\r\n openImportBrowser();\r\n } else {\r\n openImportElectron();\r\n }\r\n };\r\n\r\n const handleUnitsChange = (event) => {\r\n const value = event.target.value;\r\n dispatch(changeMeasureUnits(value));\r\n };\r\n\r\n const onModalClose = () => {\r\n setActiveMeasurePrompt(false);\r\n };\r\n\r\n const checkClose = () => {\r\n if (measurements.length > 0) {\r\n setActiveMeasurePrompt(true);\r\n return;\r\n }\r\n\r\n measurementsDialog.handleClose();\r\n };\r\n\r\n /** Update the default dropdown value if no alignment is selected */\r\n const updateDefaultDropdown = () => {\r\n const xmlAlignments = xmlAssets.map(asset => {\r\n const alignments = (asset.data as XMLData).alignments;\r\n return alignments.map(alignment => alignment.id);\r\n }).flat();\r\n\r\n if (xmlAlignments.includes(alignmentChoice)) return;\r\n setAlignmentChoice(xmlAlignments[0]);\r\n };\r\n\r\n useEffect(() => {\r\n /** Keep track if a tool is currently being used */\r\n setActiveToolOpen(measurementsDialog.open);\r\n }, [measurementsDialog.open]);\r\n\r\n useEffect(() => {\r\n /** Close dialog when new project is loaded */\r\n measurementsDialog.handleClose();\r\n }, [uniqueProjectID]);\r\n\r\n useEffect(() => {\r\n viewer?.toggleMeasurements(measurementsDialog.open);\r\n viewer?.updateMeasurementType(measureType);\r\n }, [viewer, measurementsDialog.open]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.updateMeasurementType(measureType);\r\n }, [viewer, measureType]);\r\n\r\n useEffect(() => {\r\n if (!measurementUnits) return;\r\n\r\n setMeasureUnits(measurementUnits);\r\n viewer?.setMeasurementUnits(measurementUnits);\r\n }, [viewer, measurementUnits]);\r\n\r\n useEffect(() => {\r\n measurementsDialog.handleClose();\r\n }, [dataProjection]);\r\n\r\n useEffect(() => {\r\n if (!viewer) return;\r\n viewer.setActiveAlignment(alignmentChoice);\r\n }, [viewer, alignmentChoice]);\r\n\r\n useEffect(() => {\r\n if (xmlAssets.length === 0) {\r\n setAlignmentChoice(\"\");\r\n if (!isStationMeasurement) return;\r\n setMeasureType(MeasureType.Length);\r\n } else {\r\n updateDefaultDropdown();\r\n }\r\n }, [xmlAssets]);\r\n\r\n const reversed = [...measurements].reverse();\r\n const iconProps = {classes, measureType, setMeasureType};\r\n\r\n const exportDisabled = measurements.length === 0;\r\n const importDisabled = viewer?.hasCameras || viewer?.hasPoints;\r\n const isImageOnly = viewer?.isImageOnly;\r\n\r\n const isStationMeasurement = (measureType === MeasureType.Station);\r\n const allowStationMeasurements = xmlAssets.length > 0;\r\n\r\n return (\r\n \r\n \r\n {/* Measurement icons */}\r\n \r\n\r\n \r\n\r\n \r\n\r\n {(isImageOnly === false) && ()}\r\n\r\n {(isImageOnly === false) && ()}\r\n\r\n {(isImageOnly === false) && ()}\r\n\r\n \r\n\r\n {(isImageOnly === false) && ()}\r\n\r\n {(allowStationMeasurements) && ()}\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n {/* Alignment dropdown */}\r\n {isStationMeasurement && allowStationMeasurements && \r\n \r\n {t(\"measure.alignment\")}\r\n \r\n\r\n {\r\n let value = event.target.value as any;\r\n setAlignmentChoice(value);\r\n }}\r\n >\r\n {xmlAssets.map(asset => {\r\n const alignments = (asset.data as XMLData).alignments;\r\n\r\n return [\r\n \r\n {asset.name}\r\n ,\r\n\r\n ...alignments.map(alignment =>\r\n \r\n {alignment.name}\r\n \r\n )\r\n ];\r\n }).flat()}\r\n \r\n }\r\n\r\n \r\n\r\n {/* Measurement list */}\r\n \r\n {measurements.length === 0 && (\r\n {t('measure.no-measurements-have-been-added')}\r\n )}\r\n\r\n \r\n {reversed.map((measurement, index) =>\r\n \r\n )}\r\n \r\n \r\n\r\n {/* Measurement footer */}\r\n
\r\n\r\n {/* Measurement units */}\r\n
\r\n \r\n }\r\n label={{t('units.meters')}}\r\n />\r\n\r\n }\r\n label={{t('units.feet')}}\r\n />\r\n\r\n }\r\n label={{t('units.survey-feet')}}\r\n />\r\n \r\n
\r\n\r\n
\r\n \r\n\r\n {/* Import/Export menu */}\r\n \r\n \r\n {t('measure.export-measurements')}\r\n \r\n\r\n \r\n {t('measure.import-measurements')}\r\n \r\n \r\n\r\n {/* Export Measurements */}\r\n \r\n\r\n {/* Discard measurements dialog */}\r\n {\r\n onModalClose();\r\n measurementsDialog.handleClose();\r\n }}\r\n title={t('asset.discard-measurements')}\r\n prompt={t('asset.active-measurements-found')}\r\n button={t('buttons.discard')}\r\n />\r\n\r\n
\r\n );\r\n});\r\n","import React, {useEffect, useState, memo, useMemo} from \"react\";\r\nimport {\r\n Button,\r\n createStyles,\r\n makeStyles,\r\n Theme\r\n} from \"@material-ui/core\";\r\nimport {\r\n CursorTooltip,\r\n DraggableDialog,\r\n PromptDialog\r\n} from \"../components\";\r\nimport { MultiImageOptions } from \"../viewer/js/controls\";\r\nimport LocalScene from \"../viewer/js/projections\";\r\nimport { roundDigit, UnitConverter } from \"../viewer/js/utilities\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useViewer, useGlobalSettings } from \"../hooks\";\r\nimport { getGradient } from \"../theme\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n buttonParentLeft: {\r\n position: \"absolute\",\r\n bottom: \"0px\",\r\n },\r\n buttonParentRight: {\r\n position: \"absolute\",\r\n bottom: \"0px\",\r\n right: \"0px\"\r\n },\r\n smallButton: {\r\n padding: theme.spacing(0.5, 1),\r\n margin: theme.spacing(0.75),\r\n fontSize: \"0.6rem\"\r\n },\r\n buttonRight: {\r\n float: \"right\"\r\n },\r\n multiImageHeader: {\r\n position: \"absolute\",\r\n display: \"inline-block\",\r\n background: \"rgba(255,255,255,0.75)\",\r\n boxShadow: \"5px 5px 5px rgb(0 0 0 / 25%)\",\r\n margin: \"10px\",\r\n padding: \"10px\",\r\n top: \"0px\",\r\n borderRadius: \"3px\",\r\n fontSize: \"0.8em\",\r\n userSelect: \"none\",\r\n fontFamily: theme.typography.fontFamily,\r\n \"& div:not(:last-child)\": {\r\n paddingBottom: theme.spacing(0.75)\r\n }\r\n }\r\n }),\r\n);\r\n\r\nconst WindowButton = (props) => {\r\n const {text, hidden, disabled, onClick, color} = props;\r\n\r\n const classes = useStyles();\r\n\r\n return (\r\n \r\n {!hidden && ({text})}\r\n \r\n );\r\n};\r\n\r\nconst MultiImageInfo = (props) => {\r\n const {state} = props;\r\n\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const clampedColor = (value, minValue, midValue) => {\r\n if (value < minValue) {\r\n return \"green\";\r\n }\r\n\r\n if (value < midValue) {\r\n return \"#f89406\";\r\n }\r\n\r\n return \"red\";\r\n };\r\n\r\n const {coordinates, intersect} = state;\r\n const {error, distances, calculated, valid, message} = intersect;\r\n const units = LocalScene.dataProjectionUnits;\r\n const converter = new UnitConverter();\r\n\r\n const observationStyle1 = {color: coordinates[0] ? \"green\" : \"red\"};\r\n const observationStyle2 = {color: coordinates[1] ? \"green\" : \"red\"};\r\n\r\n const observationText1 = coordinates[0]\r\n ? t('measure.selected')\r\n : t('measure.not-selected');\r\n\r\n const observationText2 = coordinates[1]\r\n ? t('measure.selected')\r\n : t('measure.not-selected');\r\n\r\n const errorStyle = {color: clampedColor(error, 0.1, 0.25)};\r\n const errorValue = roundDigit(converter.convert(error, 'm', units), 4);\r\n const errorElement = {errorValue}{units};\r\n\r\n const distanceStyle1 = {color: clampedColor(distances[0], 0.1, 0.25)};\r\n const distanceValue1 = roundDigit(converter.convert(distances[0], 'm', units), 2);\r\n const distanceElement1 = {distanceValue1}{units};\r\n\r\n const distanceStyle2 = {color: clampedColor(distances[1], 0.1, 0.25)};\r\n const distanceValue2 = roundDigit(converter.convert(distances[1], 'm', units), 2);\r\n const distanceElement2 = {distanceValue2}{units};\r\n\r\n return (\r\n
\r\n\r\n {/* Calculated information */}\r\n {calculated && (\r\n
\r\n {`${t('measure.estimated-error')}: `}\r\n {errorElement}\r\n
\r\n\r\n
\r\n {`${t('measure.camera-distance-1')}: `}\r\n {distanceElement1}\r\n
\r\n\r\n
\r\n {`${t('measure.camera-distance-2')}: `}\r\n {distanceElement2}\r\n
\r\n
)}\r\n\r\n {/* Observation status */}\r\n {!calculated && (\r\n\r\n
\r\n {`${t('measure.observation-1')}: `}\r\n {observationText1}\r\n
\r\n\r\n
\r\n {`${t('measure.observation-2')}: `}\r\n {observationText2}\r\n
\r\n
)}\r\n\r\n {/* Status message */}\r\n {!valid && (
\r\n {`${t('measure.status')}: `}\r\n {message}\r\n
)}\r\n\r\n\r\n
\r\n );\r\n};\r\n\r\nexport const MultiImageWindow = memo((props: any) => {\r\n const state = props.multiImageState as MultiImageOptions;\r\n const {multiImageOpen, setMultiImageOpen} = props;\r\n\r\n const classes = useStyles();\r\n const {viewer} = useViewer();\r\n const {t} = useTranslation();\r\n const {viewerBackground} = useGlobalSettings();\r\n\r\n const [customPromptOpen, setCustomPromptOpen] = useState(false);\r\n const [customPromptState, setCustomPromptState] = useState({\r\n title: null,\r\n text: null,\r\n callback: () => {}\r\n });\r\n\r\n const viewerGradient = useMemo(() => {\r\n return getGradient(viewerBackground);\r\n }, [viewerBackground]);\r\n\r\n const onClose = () => {\r\n const result = viewer.multiImageClosePrompt();\r\n\r\n if (result) {\r\n setCustomPromptState({...result});\r\n setCustomPromptOpen(true);\r\n } else {\r\n setMultiImageOpen(false);\r\n }\r\n };\r\n\r\n const onRefModified = (container) => {\r\n if (!container) return;\r\n viewer.initMultiImageContainer(container);\r\n };\r\n\r\n const onNextImage = () => {\r\n viewer.multiImageNextImage();\r\n };\r\n\r\n const onPreviousImage = () => {\r\n viewer.multiImagePreviousImage();\r\n };\r\n\r\n const onComplete = () => {\r\n viewer.multiImageOnComplete();\r\n };\r\n\r\n const onAddPoint = () => {\r\n viewer.multiImageOnAddMore();\r\n };\r\n\r\n useEffect(() => {\r\n viewer?.toggleMultiImageWindow(multiImageOpen);\r\n }, [multiImageOpen]);\r\n\r\n const {canAddMore, canComplete, disableAddMore, disableComplete,\r\n disablePreviousImage, disableNextImage} = state;\r\n\r\n const textLines = [\r\n t('measure.click-to-add-observation-2')\r\n ];\r\n\r\n return (\r\n \r\n \r\n {/* Canvas element */}\r\n \r\n \r\n \r\n\r\n {state.intersect && ()}\r\n\r\n
\r\n\r\n {/* Previous Image */}\r\n \r\n\r\n {/* Next Image */}\r\n \r\n\r\n
\r\n\r\n
\r\n\r\n {/* Add Point */}\r\n
\r\n\r\n \r\n\r\n {/* Custom close prompt */}\r\n {\r\n setCustomPromptOpen(false);\r\n }}\r\n onSubmit={() => {\r\n setMultiImageOpen(false);\r\n setCustomPromptOpen(false);\r\n customPromptState.callback();\r\n }}\r\n title={customPromptState.title}\r\n prompt={customPromptState.text}\r\n button={t('buttons.discard')}\r\n />\r\n
\r\n );\r\n});","export default __webpack_public_path__ + \"static/media/about-icon.f4dfa411.png\";","import React, {useEffect} from \"react\";\r\nimport {registerEvent} from \"./electron-modules\";\r\nimport {Dialog, DialogContent, DialogTitle, Link, Paper, Typography} from \"@material-ui/core\";\r\nimport makeStyles from \"@material-ui/core/styles/makeStyles\";\r\nimport logoPath from \"./viewer/textures/misc/about-icon.png\";\r\nimport manifest from \"../package.json\";\r\nimport clsx from 'clsx';\r\nimport CloseIcon from \"@material-ui/icons/Close\";\r\nimport IconButton from \"@material-ui/core/IconButton\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useDialog } from \"./hooks\";\r\n\r\nconst useStyles = makeStyles((theme) => ({\r\n dependencies: {\r\n fontSize: \"18px\",\r\n fontWeight: 500\r\n },\r\n dialog: {\r\n overflowY: \"auto\",\r\n },\r\n dialogDiv: {\r\n position: \"fixed\",\r\n overflowY: \"auto\",\r\n display: \"block\"\r\n },\r\n dialogContent: {\r\n textAlign: \"center\",\r\n lineHeight: 1,\r\n fontFamily: \"sans-serif\",\r\n overflowY: \"initial\"\r\n },\r\n dialogPaper: {\r\n overflowY: \"initial\",\r\n maxHeight: \"fit-content\",\r\n top: \"65px\"\r\n },\r\n divContent: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n },\r\n iconButton: {\r\n position: 'absolute',\r\n right: 8,\r\n top: 8\r\n },\r\n indent: {\r\n paddingLeft: \"2px\"\r\n },\r\n links: {\r\n color: \"#5c76c0\",\r\n display: \"block\",\r\n padding: theme.spacing(0.5)\r\n },\r\n listItems: {\r\n fontSize: \"14px\",\r\n },\r\n logoImage: {\r\n width: \"400px\",\r\n maxWidth: \"50%\"\r\n },\r\n paper: {\r\n overflowY: \"initial\"\r\n },\r\n support: {\r\n fontSize: \"14px\",\r\n fontWeight: 700\r\n },\r\n titleParent: {\r\n display: \"flex\",\r\n alignItems: \"center\"\r\n },\r\n title: {\r\n userSelect: \"none\",\r\n flex: \"1 !important\"\r\n },\r\n close: {\r\n color: theme.palette.grey[500],\r\n marginRight: theme.spacing(1)\r\n }\r\n})\r\n);\r\n\r\nexport const AboutDialog = () => {\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n const helpDialog = useDialog();\r\n\r\n const javascriptDependencies = {\r\n jquery: manifest.dependencies.jquery,\r\n ol: manifest.dependencies.ol,\r\n react: manifest.dependencies.react,\r\n three: manifest.dependencies.three,\r\n typescript: manifest.dependencies.typescript,\r\n electron: manifest.devDependencies.electron\r\n };\r\n\r\n // Python packages\r\n const pythonDependencies = {\r\n numpy:'1.17.1',\r\n scipy: '1.1.0',\r\n 'scikit-learn': '0.20.3',\r\n matplotlib: '2.2.4',\r\n pykml: '0.1.3',\r\n lxml: '4.4.1'\r\n };\r\n\r\n const miscDependancies = [\r\n {\r\n \"name\": \"detectron2\",\r\n \"version\": \"2.0\",\r\n \"href\": 'https://github.com/facebookresearch/detectron2'\r\n }, {\r\n \"name\": \"PotreeConvertor.exe\",\r\n \"version\": \"1.6\",\r\n \"href\": 'https://github.com/potree/PotreeConverter'\r\n }, {\r\n \"name\": \"laszip-cli.exe\",\r\n \"version\": \"3.2.9\",\r\n \"href\": 'https://github.com/LASzip/LASzip'\r\n }, {\r\n \"name\": \"pytorch\",\r\n \"version\": \"1.7.0\",\r\n \"href\": 'https://pytorch.org/'\r\n }, {\r\n \"name\": \"tensorboard\",\r\n \"version\": \"2.3.0\",\r\n \"href\": 'https://www.tensorflow.org/tensorboard'\r\n }\r\n ];\r\n\r\n const getDependencies = () => {\r\n let jsDependencies = Object.keys(javascriptDependencies).map(key => {\r\n let data = javascriptDependencies[key];\r\n let version = data.replace('^', '');\r\n\r\n return {\r\n \"name\": key,\r\n \"version\": version,\r\n \"href\": `https://www.npmjs.com/package/${key}`\r\n };\r\n });\r\n\r\n let pyDependencies = Object.keys(pythonDependencies).map(key => {\r\n let version = pythonDependencies[key].replace('^', '');\r\n\r\n return {\r\n \"name\": key,\r\n \"version\": version,\r\n \"href\": `https://pypi.python.org/pypi/${key}`\r\n };\r\n });\r\n\r\n let final = [\r\n ...jsDependencies,\r\n ...pyDependencies,\r\n ...miscDependancies\r\n ];\r\n\r\n // Sort data by key\r\n final.sort((a, b) => {\r\n return a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1;\r\n });\r\n\r\n return final;\r\n };\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-about\", () => {\r\n helpDialog.handleOpen();\r\n });\r\n }, [helpDialog]);\r\n\r\n const version = manifest.version;\r\n const dependencies = getDependencies();\r\n\r\n return (\r\n
\r\n \r\n
\r\n \r\n {t(\"about.title\")}\r\n \r\n\r\n {/* Close button */}\r\n \r\n \r\n \r\n
\r\n\r\n \r\n \r\n {\"Solv3D\r\n \r\n\r\n

SOLV3D engine viewer v{version}

\r\n SOLV3D Inc. Support
\r\n\r\n \r\n help@solv3d.com\r\n \r\n\r\n \r\n solv3d.com\r\n \r\n\r\n

\r\n {t(\"about.heading\")}\r\n

\r\n\r\n {dependencies.map((item, index) => (\r\n
\r\n \r\n {item.name}\r\n \r\n ({item.version})\r\n
\r\n ))}\r\n\r\n
\r\n \r\n
\r\n );\r\n};","import React, {\r\n useState,\r\n useEffect,\r\n useRef,\r\n} from \"react\";\r\nimport CloseIcon from '@material-ui/icons/Close';\r\nimport {\r\n makeStyles,\r\n Theme,\r\n createStyles,\r\n Dialog,\r\n DialogTitle,\r\n IconButton,\r\n List,\r\n ListItem,\r\n ListItemText\r\n} from \"@material-ui/core\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { useTaskQueue } from \"./hooks\";\r\nimport { TaskStatus } from \"./providers\";\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n consoleDialogHeader: {\r\n display: \"flex\",\r\n alignItems: \"center\"\r\n },\r\n consoleDialogTitle: {\r\n userSelect: \"none\",\r\n flex: 1,\r\n paddingBottom: \"2px\",\r\n paddingTop: \"2px\"\r\n },\r\n consoleDialogClose: {\r\n color: theme.palette.grey[500],\r\n paddingBottom: \"2px\",\r\n paddingTop: \"2px\"\r\n },\r\n consoleHeight: {\r\n background: \"black\",\r\n height: \"min(50vh, 300px)\",\r\n color: \"white\",\r\n overflowY: \"scroll\"\r\n },\r\n consoleLine: {\r\n padding: theme.spacing(0, 1),\r\n wordBreak: \"break-all\"\r\n }\r\n })\r\n);\r\n\r\nexport const TaskQueue = () => {\r\n /**\r\n * NOTE: this will be selectable from a seperate ui later, but now it\r\n * gets automatically set to the current running task. Move this to some other file\r\n * when the final ui is made.\r\n **/\r\n\r\n const {taskQueue} = useTaskQueue();\r\n const runningTask = taskQueue.find(x => x.status === TaskStatus.Running);\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nconst ConsoleWindow = (props) => {\r\n const {selectedTaskID} = props;\r\n\r\n const classes = useStyles();\r\n const listRef = useRef(null);\r\n const {t} = useTranslation();\r\n\r\n const [lineData, setLineData] = useState([]);\r\n const {taskQueue, stopRunningTask} = useTaskQueue();\r\n\r\n const textUpdateMilliseconds = 100;\r\n const activeTask = taskQueue.find(x => x.id === selectedTaskID);\r\n\r\n // NOTE: when this is selecteable from an ui, the close button wont actually\r\n // kill the process, it will only set the selectedTaskID to null\r\n const onCancel = () => {\r\n stopRunningTask(selectedTaskID);\r\n };\r\n\r\n useEffect(() => {\r\n if (!activeTask) return;\r\n\r\n // Initial exe logs\r\n setLineData(activeTask.exe.logText);\r\n\r\n const interval = setInterval(() => {\r\n // Check for new data if the exe is still running\r\n if (!activeTask || !activeTask.exe.running) return;\r\n setLineData([...activeTask.exe.logText]);\r\n }, textUpdateMilliseconds);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }, [activeTask]);\r\n\r\n useEffect(() => {\r\n if (!listRef.current) return;\r\n\r\n // Auto-scroll to bottom when new data is read\r\n const height = listRef.current.scrollHeight;\r\n listRef.current.scrollTop = height;\r\n }, [listRef, lineData]);\r\n\r\n return (\r\n \r\n
\r\n \r\n {t('console.output_logs')}\r\n \r\n\r\n {/* Close button */}\r\n \r\n \r\n \r\n
\r\n\r\n
\r\n
\r\n \r\n {lineData.map((line, index) =>\r\n \r\n \r\n {line}\r\n \r\n )\r\n }\r\n \r\n
\r\n
\r\n\r\n \r\n );\r\n};\r\n","import { useCallback, useState } from \"react\";\r\nimport { t } from \"../localization\";\r\nimport { ItemSearchState, SortBy, SortDir, SortOption } from \"../types/search\";\r\n\r\nexport const getSortOptions = () => {\r\n const sortOptions: SortOption[] = [\r\n {\r\n label: t('item-search.name_ascending'),\r\n value: {\r\n sortDir: 'asc',\r\n sortBy: 'name'\r\n }\r\n },\r\n {\r\n label: t('item-search.name_descending'),\r\n value: {\r\n sortDir: 'desc',\r\n sortBy: 'name'\r\n }\r\n },\r\n {\r\n label: t('item-search.date_ascending'),\r\n value: {\r\n sortDir: 'asc',\r\n sortBy: 'date'\r\n }\r\n },\r\n {\r\n label: t('item-search.date_descending'),\r\n value: {\r\n sortDir: 'desc',\r\n sortBy: 'date'\r\n }\r\n }\r\n ];\r\n\r\n return sortOptions;\r\n};\r\n\r\nexport const useItemsSearch = () => {\r\n const [state, setState] = useState({\r\n sortDir: \"asc\",\r\n sortBy: \"name\",\r\n query: \"\"\r\n });\r\n\r\n const handleSearchChange = useCallback((query: string): void => {\r\n setState((prevState) => ({...prevState, query}));\r\n }, []);\r\n\r\n const handleSortChange = useCallback((sortDir: SortDir, sortBy: SortBy): void => {\r\n setState((prevState) => ({...prevState, sortDir, sortBy}));\r\n }, []);\r\n\r\n const sortByDate = (items: any[], sortDir: SortDir) => {\r\n return [...items].sort((a, b) => {\r\n const dateA = new Date(a.timeCreated);\r\n const dateB = new Date(b.timeCreated);\r\n\r\n return (sortDir === \"asc\")\r\n ? (dateA > dateB ? 1 : -1)\r\n : (dateB > dateA ? 1 : -1);\r\n });\r\n };\r\n\r\n const sortByName = (items: any[], sortDir: SortDir) => {\r\n return [...items].sort((a, b) => {\r\n const nameA = a.name as string;\r\n const nameB = b.name as string;\r\n\r\n return (sortDir === \"asc\")\r\n ? nameA.localeCompare(nameB)\r\n : nameB.localeCompare(nameA);\r\n });\r\n };\r\n\r\n const handleSearch = (items: any[]) => {\r\n const query = state.query;\r\n if (!query) return items;\r\n\r\n const queryParts = query\r\n .split(\" \")\r\n .map(x => x.toLowerCase());\r\n\r\n return items.filter(project => {\r\n const nameParts = project.name\r\n .split(\" \")\r\n .map(x => x.toLowerCase());\r\n\r\n return queryParts.filter(text => {\r\n return nameParts.filter(x => x.includes(text)).length > 0;\r\n }).length === queryParts.length;\r\n });\r\n };\r\n\r\n const handleSort = (items: any[]) => {\r\n const {sortDir, sortBy} = state;\r\n if (!sortDir) return items;\r\n\r\n // Initial sorting by date is always applied\r\n let initialSort = sortByDate(items, \"asc\");\r\n\r\n if (sortBy === \"date\") {\r\n return sortByDate(initialSort, sortDir);\r\n }\r\n\r\n return sortByName(initialSort, sortDir);\r\n };\r\n\r\n return {\r\n handleSearch,\r\n handleSearchChange,\r\n handleSort,\r\n handleSortChange,\r\n state\r\n };\r\n};","import React, { useEffect, useState } from \"react\";\r\nimport {\r\n Box,\r\n List,\r\n ListItem,\r\n ListItemText,\r\n MenuItem,\r\n TextField,\r\n Typography\r\n} from \"@material-ui/core\";\r\nimport { useTheme } from \"@material-ui/core/styles\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { SimpleDialog } from \"./components\";\r\nimport { registerEvent } from \"./electron-modules\";\r\nimport { useAuth, useDialog, useWebSockets } from \"./hooks\";\r\nimport { SortOption } from \"./types/search\";\r\nimport stc from \"string-to-color\";\r\nimport { getSortOptions, useItemsSearch } from \"./hooks/use-item-search\";\r\nimport { asyncTimeout, clearWindowHash, loadProjectJSON, toLocaleString } from \"./utilities\";\r\nimport { toast } from \"./app\";\r\nimport { engineCloudURL } from \"./urls\";\r\n\r\ninterface CloudProject {\r\n id: string;\r\n name: string;\r\n timeCreated: string\r\n}\r\n\r\nconst ProjectListRow = (props) => {\r\n const {project, onClose} = props;\r\n\r\n const {i18n, t} = useTranslation();\r\n const theme = useTheme();\r\n const websockets = useWebSockets();\r\n\r\n const onClick = async () => {\r\n onClose();\r\n toast.success(t(\"toast.load-cloud-file\"));\r\n await asyncTimeout(250);\r\n\r\n const url = `${engineCloudURL}/viewer/${project.id}/static.json`;\r\n const response = await fetch(url);\r\n const projectJSON = await response.json();\r\n\r\n clearWindowHash();\r\n loadProjectJSON(projectJSON);\r\n\r\n const cloudProject = projectJSON.project;\r\n websockets.joinRoom(cloudProject.id);\r\n };\r\n\r\n const dateString = toLocaleString(project.timeCreated, i18n.language);\r\n const accentColor = stc(project.name);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const CloudProjectList = () => {\r\n const {t} = useTranslation();\r\n const {linkAccount, loggedIn} = useAuth();\r\n const projectDialog = useDialog();\r\n const theme = useTheme();\r\n\r\n const [userProjects, setUserProjects] = useState([]);\r\n const itemsSearch = useItemsSearch();\r\n const sortOptions = getSortOptions();\r\n\r\n const getUserProjects = async () => {\r\n try {\r\n const url = `${engineCloudURL}/api/projects`;\r\n const response = await fetch(url);\r\n const data = await response.json();\r\n\r\n const projects = data\r\n .filter(project => project.isAdmin)\r\n .map(project => {\r\n return {\r\n id: project.id,\r\n name: project.name as string,\r\n timeCreated: project.timeCreated as string\r\n } as CloudProject;\r\n });\r\n\r\n setUserProjects(projects);\r\n } catch {\r\n setUserProjects([]);\r\n }\r\n };\r\n\r\n const onSearchChange = event => {\r\n const query = event.target.value;\r\n itemsSearch.handleSearchChange(query);\r\n };\r\n\r\n const onSortChange = event => {\r\n const {sortDir, sortBy} = JSON.parse(event.target.value);\r\n itemsSearch.handleSortChange(sortDir, sortBy);\r\n };\r\n\r\n useEffect(() => {\r\n registerEvent(\"open-cloud-projects\", async () => {\r\n if (!loggedIn) {\r\n const success = await linkAccount();\r\n if (!success) return;\r\n }\r\n\r\n projectDialog.handleOpen();\r\n });\r\n }, [loggedIn]);\r\n\r\n useEffect(() => {\r\n if (!projectDialog.open) return;\r\n getUserProjects();\r\n }, [projectDialog.open]);\r\n\r\n let projects = [...userProjects];\r\n projects = itemsSearch.handleSearch(projects);\r\n projects = itemsSearch.handleSort(projects);\r\n\r\n const hasProjects = projects.length > 0;\r\n\r\n const sortValue = JSON.stringify({\r\n sortDir: itemsSearch.state.sortDir,\r\n sortBy: itemsSearch.state.sortBy\r\n });\r\n\r\n return (\r\n \r\n \r\n \r\n\r\n {/** Search text */}\r\n \r\n\r\n {/** Sort by dropdown */}\r\n \r\n {sortOptions.map((option: SortOption, index) => (\r\n \r\n {option.label}\r\n \r\n ))}\r\n \r\n\r\n \r\n\r\n {!hasProjects && \r\n \r\n \r\n {t('project-list.no_projects_found')}\r\n \r\n \r\n }\r\n\r\n {hasProjects && (\r\n \r\n {projects.map(project =>\r\n \r\n )}\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n );\r\n};\r\n","import {MainAppBar, MainAppFooter} from \"./app-bar\";\r\nimport React, {useEffect, useState} from \"react\";\r\nimport {GlobalSettings, SettingsDrawer, settingsDrawerWidth} from \"./settings\";\r\nimport {AssetDrawer, assetDrawerWidth} from \"./asset-drawer\";\r\nimport {ProjectionsManager} from \"./projections\";\r\nimport {ImageAlignerAdvanced, ImageAlignerBasic, LocalAligner} from \"./alignment\";\r\nimport {ImageLabelling} from \"./labelling\";\r\nimport {QuickNav} from \"./navigation\";\r\nimport {SceneViewer} from \"./viewer/viewer\";\r\nimport {\r\n Backdrop,\r\n Box,\r\n CircularProgress,\r\n createStyles,\r\n DialogContentText,\r\n makeStyles,\r\n Theme,\r\n useTheme\r\n} from \"@material-ui/core\";\r\nimport {useDispatch, useSelector} from 'react-redux';\r\nimport {changeDrawerOpen, selectDrawerOpen} from \"./redux/settings-slice\";\r\nimport {app, dialog, isCloudSite, isDevMode, isElectronApp, isStaticSite, remote} from \"./electron-modules\";\r\nimport slash from \"slash\";\r\nimport {isConfigFile, loadProjectJSON, useAssetTools} from \"./utilities\";\r\nimport {CloudExporter, StaticExporter} from \"./export\";\r\nimport {PythonExecutable, WorkflowExecutable} from \"./executable\";\r\nimport {PointMarkup} from \"./markup\";\r\nimport {Measurements, MultiImageWindow} from \"./measurements\";\r\nimport {AboutDialog} from \"./about\";\r\nimport {sendCustomEvent} from \"./events\";\r\nimport {PointProfile} from \"./point-profile\";\r\nimport clsx from 'clsx';\r\nimport {useTranslation} from \"react-i18next\";\r\nimport {assetFolderClass, TagDetailsDialog} from \"./folder\";\r\nimport {selectDefaultFolder} from \"./redux/folders-slice\";\r\nimport {TaskQueue} from \"./task-queue\";\r\nimport {useAuth, useDialog, useViewer, useWebSockets} from \"./hooks\";\r\nimport {CustomContextURL} from \"./context-menu\";\r\nimport {toast as hotToast} from 'react-hot-toast';\r\nimport {AlertDialog, Toaster} from \"./components\";\r\nimport {CloudProjectList} from \"./cloud-projects\";\r\nimport {parseURLParams} from \"./viewer/js/utilities\";\r\nimport {openExternalLink, redirectToLogin, setEngineCloudURL} from \"./urls\";\r\nimport {getLocalizedURL} from \"./localization\";\r\n\r\ninterface JSONData {\r\n license_check: {\r\n valid: boolean;\r\n expired: boolean;\r\n locked: boolean;\r\n offline: boolean;\r\n message: string;\r\n engineCloudURL?: string;\r\n }\r\n}\r\n\r\nexport const headerHeight = 48;\r\nexport const footerHeight = 24;\r\n\r\nconst useStyles = makeStyles((theme: Theme) =>\r\n createStyles({\r\n backdrop: {\r\n color: '#fff',\r\n zIndex: theme.zIndex.snackbar + 1,\r\n flexDirection: \"column\",\r\n },\r\n backdropText: {\r\n padding: theme.spacing(1)\r\n },\r\n debugStandard: {\r\n position: \"absolute\",\r\n bottom: theme.spacing(0),\r\n left: \"0.5em\",\r\n textAlign: \"center\",\r\n zIndex: 1300,\r\n width: \"fit-content\",\r\n marginLeft: \"0px !important\"\r\n },\r\n debugShifted: {\r\n left: `calc(${assetDrawerWidth}px + 0.5em)`\r\n }\r\n }),\r\n);\r\n\r\nconst DragDropLoader = (props) => {\r\n const dispatch = useDispatch();\r\n const {addFilePaths} = useAssetTools();\r\n const defaultFolder = useSelector(selectDefaultFolder);\r\n\r\n const handleDrawerOpen = () => {\r\n dispatch(changeDrawerOpen(true));\r\n };\r\n\r\n const handleDrop = event => {\r\n if (isStaticSite) return;\r\n\r\n // Drag and drop on specific folder is handled in folder.tsx\r\n const isFolder = !!event.target.closest(`.${assetFolderClass}`);\r\n if (isFolder) return;\r\n\r\n const filePaths = [...event.dataTransfer.files]\r\n .map(file => slash(file.path));\r\n\r\n const configs = filePaths.filter(isConfigFile);\r\n if (configs.length === 0) {\r\n handleDrawerOpen();\r\n }\r\n\r\n addFilePaths(filePaths, defaultFolder.id);\r\n };\r\n\r\n const handleDragOver = event => {\r\n if (isStaticSite) return;\r\n\r\n event.stopPropagation();\r\n event.preventDefault();\r\n };\r\n\r\n return (\r\n \r\n {props.children}\r\n
\r\n );\r\n};\r\n\r\nconst ProjectLoader = () => {\r\n const defaultFolder = useSelector(selectDefaultFolder);\r\n const {addFilePaths} = useAssetTools();\r\n const websockets = useWebSockets();\r\n\r\n const getAllFileArgs = () => {\r\n try {\r\n\r\n let rawArgs = remote.process.argv;\r\n let fileArgs = rawArgs.slice(1, rawArgs.length);\r\n return fileArgs.map((arg) => slash(arg.toString()));\r\n } catch {\r\n return null;\r\n }\r\n };\r\n\r\n /** Load files from launch arguments */\r\n const loadFromCompiledExe = () => {\r\n const filePaths = getAllFileArgs();\r\n addFilePaths(filePaths, defaultFolder.id);\r\n };\r\n\r\n /** Load project json from relative location */\r\n const loadFromStaticSite = async () => {\r\n // Block browser context menu\r\n window.oncontextmenu = event => {\r\n event.preventDefault();\r\n };\r\n\r\n const cache = Date.now();\r\n const parameters = parseURLParams(window.location.href);\r\n const configRoot = isCloudSite ? window.location.pathname : \".\";\r\n const configURL = `${configRoot}/static.json?cache=${cache}`;\r\n\r\n try {\r\n const response = await fetch(configURL);\r\n const projectJSON = await response.json();\r\n loadProjectJSON(projectJSON, parameters);\r\n\r\n if (isCloudSite) {\r\n const cloudProject = projectJSON.project;\r\n websockets.joinRoom(cloudProject.id);\r\n }\r\n } catch {\r\n console.error(\"Error reading static config\");\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (isStaticSite) {\r\n loadFromStaticSite();\r\n } else {\r\n loadFromCompiledExe();\r\n }\r\n }, []);\r\n\r\n return ;\r\n};\r\n\r\nconst BackdropToggle = () => {\r\n const theme = useTheme();\r\n const classes = useStyles(theme);\r\n\r\n const [backdropOpen, setBackdropOpen] = useState(false);\r\n\r\n /** Backdrop state event listener */\r\n useEffect(() => {\r\n const callback = (event) => {\r\n const {visible} = event.detail;\r\n setBackdropOpen(visible);\r\n };\r\n\r\n document.addEventListener(\"backdrop-state\", callback);\r\n\r\n return () => {\r\n document.removeEventListener(\"backdrop-state\", callback);\r\n };\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport const AppWithAuth = () => {\r\n const [appAccess, setAppAccess] = useState(false);\r\n\r\n const {i18n, t} = useTranslation();\r\n const accessDialog = useDialog();\r\n const { initialized, loggedIn, permissions } = useAuth();\r\n\r\n useEffect(() => {\r\n if (!initialized) return;\r\n\r\n if (permissions.access) {\r\n setAppAccess(true);\r\n } else {\r\n accessDialog.handleOpen();\r\n }\r\n }, [initialized]);\r\n\r\n const onClose = () => {\r\n accessDialog.handleClose();\r\n\r\n if (loggedIn) {\r\n window.location.href = getLocalizedURL(\"/projects\", i18n.language);\r\n } else {\r\n redirectToLogin();\r\n }\r\n };\r\n\r\n return (\r\n <>\r\n {appAccess && }\r\n\r\n \r\n \r\n {loggedIn && t('project_access.you_have_invalid_permissions')}\r\n {!loggedIn && t('project_access.you_have_invalid_viewonly')}\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nconst App = () => {\r\n const {signOut} = useAuth();\r\n const classes = useStyles();\r\n const {t} = useTranslation();\r\n\r\n const projectDrawerState = useSelector(selectDrawerOpen);\r\n\r\n const {viewer} = useViewer();\r\n const measurementsDialog = useDialog();\r\n const customURLDialog = useDialog();\r\n\r\n const [assetDrawerState, setDrawerState] = useState(false);\r\n const [settingsDrawerState, setSettingsDrawerState] = useState(false);\r\n const [measurements, setMeasurements] = useState([]);\r\n const [localObservations, setLocalObservations] = useState([]);\r\n const [alignerObservations, setAlignerObservations] = useState([]);\r\n const [categoryList, setCategoryList] = useState([]);\r\n const [markupGroups, setMarkupGroups] = useState([]);\r\n const [trainingArea, setTrainingArea] = useState([]);\r\n const [multiImageOpen, setMultiImageOpen] = useState(false);\r\n const [pointProfileOpen, setPointProfileOpen] = useState(false);\r\n const [multiImageState, setMultiImageState] = useState({});\r\n\r\n /** Add a target to links that do not already have one */\r\n const handleLinkWithoutTargets = (event) => {\r\n const element = event.target;\r\n if (!element.href || element.target) return;\r\n event.preventDefault();\r\n openExternalLink(element.href);\r\n };\r\n\r\n useEffect(() => {\r\n document.addEventListener(\"click\", handleLinkWithoutTargets);\r\n\r\n return () => {\r\n document.removeEventListener(\"click\", handleLinkWithoutTargets);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (isDevMode || isStaticSite) return;\r\n\r\n new PythonExecutable().run({\r\n command: ['--check-tool', 'viewer'],\r\n onLine: (jsonData: JSONData) => {\r\n if (!jsonData.license_check) {\r\n return;\r\n }\r\n\r\n if (jsonData.license_check.engineCloudURL) {\r\n const modified = setEngineCloudURL(jsonData.license_check.engineCloudURL);\r\n\r\n if (modified) {\r\n signOut();\r\n }\r\n }\r\n\r\n const {valid, message} = jsonData.license_check;\r\n if (valid) return;\r\n\r\n const mainWindow = remote.getCurrentWindow();\r\n\r\n dialog.showMessageBox(mainWindow, {\r\n title: t(\"dialog.invalid-license-title\"),\r\n message: t(\"dialog.invalid-license-message\", {message}),\r\n buttons: [\r\n t(\"buttons.exit\"),\r\n t(\"buttons.open-engine\")\r\n ],\r\n type: 'error',\r\n noLink: true\r\n })\r\n .then(selection => {\r\n if (selection.response === 1) {\r\n new WorkflowExecutable().run({command: []});\r\n }\r\n\r\n app.quit();\r\n });\r\n },\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n setDrawerState(projectDrawerState);\r\n }, [projectDrawerState]);\r\n\r\n useEffect(() => {\r\n let width = settingsDrawerState ? settingsDrawerWidth : 0;\r\n viewer?.updateCompassOffset(width);\r\n }, [viewer, settingsDrawerState]);\r\n\r\n return (\r\n \r\n \r\n\r\n \r\n {isElectronApp && <>\r\n \r\n \r\n \r\n }\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n {\r\n setSettingsDrawerState(false);\r\n }}\r\n />\r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n \r\n\r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n \r\n\r\n {/* Debug stats panel */}\r\n
\r\n\r\n \r\n\r\n \r\n
\r\n
\r\n );\r\n};\r\n\r\n/** Global method for toast messages */\r\nexport const toast = {\r\n success: (message) => {\r\n hotToast.success(message);\r\n },\r\n error: (message) => {\r\n hotToast.error(message);\r\n },\r\n warning: (message) => {\r\n hotToast(message, {\r\n icon: \"⚠️\"\r\n });\r\n },\r\n static: (message) => {\r\n hotToast(message, {\r\n icon: \"🔔\",\r\n id: \"static\"\r\n });\r\n }\r\n};\r\n\r\n/** Global method for showing backdrop */\r\nexport const showBackdrop = () => {\r\n sendCustomEvent(\"backdrop-state\", {visible: true});\r\n};\r\n\r\n/** Global method for hiding backdrop */\r\nexport const hideBackdrop = () => {\r\n sendCustomEvent(\"backdrop-state\", {visible: false});\r\n};\r\n","import {createSlice, nanoid} from '@reduxjs/toolkit';\r\nimport { ProjectType } from '../types/project';\r\n\r\ninterface ProjectState {\r\n id: string;\r\n name: string;\r\n path: string;\r\n type: ProjectType;\r\n uniqueSession: string;\r\n configVersion: string;\r\n}\r\n\r\nexport const defaultProjectTitle = 'project-settings.untitled-project';\r\n\r\n// Current config version\r\nexport const currentConfigVersion = \"3.22.0\";\r\n\r\n// Not possible to upgrade below this version\r\nexport const minimumConfigVersion = \"3.4.0\";\r\n\r\nexport const projectSlice = createSlice({\r\n name: 'project',\r\n initialState: {\r\n id: nanoid(),\r\n name: defaultProjectTitle,\r\n path: '',\r\n type: ProjectType.Standard,\r\n uniqueSession: nanoid(),\r\n configVersion: currentConfigVersion\r\n } as ProjectState,\r\n reducers: {\r\n updateProjectID: (state, action) => {\r\n state.id = action.payload;\r\n },\r\n updateSessionID: (state, action) => {\r\n state.uniqueSession = action.payload;\r\n },\r\n updateProjectName: (state, action) => {\r\n state.name = action.payload;\r\n },\r\n changePath: (state, action) => {\r\n state.path = action.payload;\r\n }\r\n }\r\n});\r\n\r\nexport const {\r\n updateProjectID,\r\n updateSessionID,\r\n updateProjectName,\r\n changePath\r\n} = projectSlice.actions;\r\n\r\nexport default projectSlice.reducer;\r\n\r\nexport const selectProjectID = (state): string => state.project.id;\r\nexport const selectProjectName = (state): string => state.project.name;\r\nexport const selectProjectType = (state): ProjectType => state.project.type;\r\nexport const selectSessionID = (state): string => state.project.uniqueSession;"],"sourceRoot":""}