├── .editorconfig ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── yarn.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── config ├── init.js ├── postcss.config.cjs ├── rollup.js ├── rollup.serve.config.js ├── tsconfig.test.json └── tslint.json ├── declarations └── mapillary.js.flow ├── doc ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .stylelintrc.js ├── README.md ├── babel.config.js ├── docs │ ├── extension │ │ ├── animation.md │ │ ├── extend.md │ │ ├── fly-controls.md │ │ ├── geometry-provider.md │ │ ├── graphics-developer.md │ │ ├── procedural-data-provider.md │ │ ├── three-custom-renderer.md │ │ └── webgl-custom-renderer.md │ ├── intro │ │ ├── glossary.md │ │ ├── start.md │ │ └── try.mdx │ ├── main │ │ ├── component.md │ │ ├── control.md │ │ ├── event.md │ │ ├── guide.md │ │ └── init.md │ ├── migration │ │ ├── v2.md │ │ ├── v3.md │ │ └── v4.md │ └── theory │ │ ├── coordinates.md │ │ ├── navigation-graph.md │ │ ├── polygon-triangulation.md │ │ └── theory.md ├── docusaurus.config.js ├── docusaurus.docs.config.js ├── examples │ └── examples.md ├── mapillary-js.sh ├── package.json ├── plugins │ └── plugin-overwrite-slug │ │ └── index.js ├── sidebars │ ├── api.sidebars.js │ ├── docs.sidebars.js │ └── examples.sidebars.js ├── src │ ├── css │ │ ├── custom.css │ │ ├── editor.css │ │ ├── log.css │ │ ├── mapbox.css │ │ └── options.css │ ├── js │ │ ├── components │ │ │ ├── Code.js │ │ │ ├── ViewerComponent.js │ │ │ ├── code.module.css │ │ │ └── viewer.module.css │ │ ├── examples │ │ │ ├── component-keyboard.js │ │ │ ├── component-marker-map.js │ │ │ ├── component-marker-million.js │ │ │ ├── component-marker.js │ │ │ ├── component-pointer.js │ │ │ ├── component-popup-tag.js │ │ │ ├── component-popup.js │ │ │ ├── component-spatial.js │ │ │ ├── component-tag-create.js │ │ │ ├── component-tag-interact.js │ │ │ ├── component-tag.js │ │ │ ├── extend-animation.js │ │ │ ├── extend-editor.js │ │ │ ├── extend-fly-controls.js │ │ │ ├── extend-graphics-developer.js │ │ │ ├── extend-map-sync.js │ │ │ ├── extend-procedural-data-provider.js │ │ │ ├── extend-three-renderer.js │ │ │ ├── extend-webgl-renderer.js │ │ │ ├── support.js │ │ │ ├── viewer-coordinates.js │ │ │ ├── viewer-events.js │ │ │ ├── viewer-filters.js │ │ │ ├── viewer-from-map.js │ │ │ ├── viewer-initialization.js │ │ │ ├── viewer-methods.js │ │ │ ├── viewer-options.js │ │ │ └── viewer-to-map.js │ │ ├── options │ │ │ ├── BooleanController.js │ │ │ ├── Controller.js │ │ │ ├── Folder.js │ │ │ ├── FunctionController.js │ │ │ ├── Log.js │ │ │ ├── NumberController.js │ │ │ └── OptionController.js │ │ └── utils │ │ │ ├── ChunkDataProvider.js │ │ │ ├── DeletableProceduralDataProvider.js │ │ │ ├── DynamicProceduralDataProvider.js │ │ │ ├── ProceduralDataProvider.js │ │ │ ├── error.js │ │ │ ├── image.js │ │ │ └── provider.js │ ├── pages │ │ ├── examples │ │ │ ├── component-keyboard.js │ │ │ ├── component-marker-map.js │ │ │ ├── component-marker-million.js │ │ │ ├── component-marker.js │ │ │ ├── component-pointer.js │ │ │ ├── component-popup-tag.js │ │ │ ├── component-popup.js │ │ │ ├── component-spatial.js │ │ │ ├── component-tag-create.js │ │ │ ├── component-tag-interact.js │ │ │ ├── component-tag.js │ │ │ ├── extend-animation.js │ │ │ ├── extend-editor.js │ │ │ ├── extend-fly-controls.js │ │ │ ├── extend-graphics-developer.js │ │ │ ├── extend-map-sync.js │ │ │ ├── extend-procedural-data-provider.js │ │ │ ├── extend-three-renderer.js │ │ │ ├── extend-webgl-renderer.js │ │ │ ├── support.js │ │ │ ├── viewer-coordinates.js │ │ │ ├── viewer-events.js │ │ │ ├── viewer-filters.js │ │ │ ├── viewer-from-map.js │ │ │ ├── viewer-initialization.js │ │ │ ├── viewer-methods.js │ │ │ ├── viewer-options.js │ │ │ └── viewer-to-map.js │ │ ├── index.js │ │ └── styles.module.css │ └── theme │ │ └── ReactLiveScope │ │ └── index.js ├── static │ ├── .nojekyll │ └── img │ │ ├── examples │ │ ├── code.svg │ │ ├── rotate.svg │ │ ├── scale.svg │ │ └── translate.svg │ │ ├── extension │ │ ├── custom-render-design.png │ │ └── data-provider-design.png │ │ ├── favicon.png │ │ ├── hero │ │ ├── dropoff.png │ │ ├── mjs.png │ │ └── semantic.png │ │ ├── logo_black.svg │ │ ├── logo_green.svg │ │ ├── oss_logo.png │ │ └── theory │ │ ├── graph-diagram.png │ │ ├── graph-multiple-tiles-edges.png │ │ ├── graph-multiple-tiles-nodes.png │ │ ├── graph-multiple-tiles.png │ │ ├── graph-single-tile.png │ │ ├── polygon-behind-camera.png │ │ ├── polygon-clipped-on-sphere.png │ │ ├── polygon-clipped-projected.png │ │ ├── polygon-clipped.png │ │ ├── polygon-combined-sphere.png │ │ ├── polygon-equirectangular-panorama.jpg │ │ ├── polygon-in-front-of-image.png │ │ ├── polygon-on-grid.png │ │ ├── polygon-on-real-image.png │ │ ├── polygon-on-undistorted-image.png │ │ ├── polygon-rendered.jpg │ │ ├── polygon-triangulated.png │ │ └── polygon-undistorted.jpg ├── typedoc.json └── yarn.lock ├── examples ├── debug │ ├── chunk.html │ ├── delete.html │ ├── fisheye.html │ ├── index.html │ ├── leaflet.html │ ├── marker.html │ ├── popup.html │ ├── reset.html │ ├── shader.html │ ├── spatial.html │ ├── tag.html │ └── umd.html └── doc │ ├── component-keyboard.html │ ├── component-marker-map.html │ ├── component-marker-million.html │ ├── component-marker.html │ ├── component-pointer.html │ ├── component-popup-tag.html │ ├── component-popup.html │ ├── component-spatial.html │ ├── component-tag-create.html │ ├── component-tag-interact.html │ ├── component-tag.html │ ├── extend-animation.html │ ├── extend-editor.html │ ├── extend-fly-controls.html │ ├── extend-graphics-developer.html │ ├── extend-map-sync.html │ ├── extend-procedural-data-provider.html │ ├── extend-three-renderer.html │ ├── extend-webgl-renderer.html │ ├── support.html │ ├── viewer-coordinates.html │ ├── viewer-events.html │ ├── viewer-filters.html │ ├── viewer-from-map.html │ ├── viewer-initialization.html │ ├── viewer-methods.html │ ├── viewer-options.html │ └── viewer-to-map.html ├── jest.config.js ├── package.json ├── rollup.config.js ├── server.js ├── src ├── api │ ├── APIWrapper.ts │ ├── CellMath.ts │ ├── Common.ts │ ├── DataProviderBase.ts │ ├── GeometryProviderBase.ts │ ├── S2GeometryProvider.ts │ ├── contracts │ │ ├── ClusterContract.ts │ │ ├── CoreImagesContract.ts │ │ ├── EntContract.ts │ │ ├── ImageTilesContract.ts │ │ ├── ImageTilesRequestContract.ts │ │ ├── ImagesContract.ts │ │ ├── MeshContract.ts │ │ ├── SequenceContract.ts │ │ └── SpatialImagesContract.ts │ ├── ents │ │ ├── CameraEnt.ts │ │ ├── CoreImageEnt.ts │ │ ├── CreatorEnt.ts │ │ ├── IDEnt.ts │ │ ├── ImageEnt.ts │ │ ├── ImageTileEnt.ts │ │ ├── SequenceEnt.ts │ │ ├── SpatialImageEnt.ts │ │ └── URLEnt.ts │ ├── events │ │ ├── ProviderCellEvent.ts │ │ ├── ProviderClusterEvent.ts │ │ ├── ProviderEvent.ts │ │ └── ProviderEventType.ts │ ├── interfaces │ │ ├── IDataProvider.ts │ │ ├── IGeometryProvider.ts │ │ ├── LngLat.ts │ │ └── LngLatAlt.ts │ └── provider │ │ ├── GraphContracts.ts │ │ ├── GraphConverter.ts │ │ ├── GraphDataProvider.ts │ │ ├── GraphDataProviderOptions.ts │ │ ├── GraphEnts.ts │ │ └── GraphQueryCreator.ts ├── component │ ├── Component.ts │ ├── ComponentName.ts │ ├── ComponentService.ts │ ├── attribution │ │ └── AttributionComponent.ts │ ├── bearing │ │ └── BearingComponent.ts │ ├── cache │ │ └── CacheComponent.ts │ ├── cover │ │ ├── CoverComponent.ts │ │ └── CoverState.ts │ ├── direction │ │ ├── DirectionComponent.ts │ │ ├── DirectionDOMCalculator.ts │ │ └── DirectionDOMRenderer.ts │ ├── events │ │ ├── ComponentEvent.ts │ │ ├── ComponentEventType.ts │ │ ├── ComponentGeometryEvent.ts │ │ ├── ComponentHoverEvent.ts │ │ ├── ComponentMarkerEvent.ts │ │ ├── ComponentPlayEvent.ts │ │ ├── ComponentStateEvent.ts │ │ └── ComponentTagModeEvent.ts │ ├── fallback │ │ ├── FallbackComponentName.ts │ │ ├── image │ │ │ └── ImageFallbackComponent.ts │ │ └── navigation │ │ │ └── NavigationFallbackComponent.ts │ ├── image │ │ ├── ImageComponent.ts │ │ ├── ImageGLRenderer.ts │ │ └── interfaces │ │ │ └── ProjectorShaderMaterial.ts │ ├── interfaces │ │ ├── BearingConfiguration.ts │ │ ├── CacheConfiguration.ts │ │ ├── ComponentConfiguration.ts │ │ ├── CoverConfiguration.ts │ │ ├── DirectionConfiguration.ts │ │ ├── IComponent.ts │ │ ├── KeyboardConfiguration.ts │ │ ├── MarkerConfiguration.ts │ │ ├── NavigationFallbackConfiguration.ts │ │ ├── PointerConfiguration.ts │ │ ├── SequenceConfiguration.ts │ │ ├── Shader.ts │ │ ├── SliderConfiguration.ts │ │ ├── SpatialConfiguration.ts │ │ ├── TagConfiguration.ts │ │ └── ZoomConfiguration.ts │ ├── keyboard │ │ ├── KeyPlayHandler.ts │ │ ├── KeySequenceNavigationHandler.ts │ │ ├── KeySpatialNavigationHandler.ts │ │ ├── KeyZoomHandler.ts │ │ └── KeyboardComponent.ts │ ├── marker │ │ ├── MarkerComponent.ts │ │ ├── MarkerScene.ts │ │ ├── MarkerSet.ts │ │ ├── interfaces │ │ │ ├── CircleMarkerOptions.ts │ │ │ └── SimpleMarkerOptions.ts │ │ └── marker │ │ │ ├── CircleMarker.ts │ │ │ ├── Marker.ts │ │ │ └── SimpleMarker.ts │ ├── pointer │ │ ├── BounceHandler.ts │ │ ├── DragPanHandler.ts │ │ ├── EarthControlHandler.ts │ │ ├── HandlerTypes.ts │ │ ├── ImageBoundary.ts │ │ ├── PointerComponent.ts │ │ ├── ScrollZoomHandler.ts │ │ └── TouchZoomHandler.ts │ ├── popup │ │ ├── PopupComponent.ts │ │ ├── interfaces │ │ │ ├── PopupOffset.ts │ │ │ └── PopupOptions.ts │ │ └── popup │ │ │ ├── Popup.ts │ │ │ └── PopupAlignment.ts │ ├── sequence │ │ ├── SequenceComponent.ts │ │ ├── SequenceDOMRenderer.ts │ │ └── SequenceMode.ts │ ├── slider │ │ ├── SliderComponent.ts │ │ ├── SliderDOMRenderer.ts │ │ ├── SliderGLRenderer.ts │ │ ├── SliderInterfaces.ts │ │ ├── SliderMeshFactory.ts │ │ ├── SliderMeshScene.ts │ │ ├── SliderShaders.ts │ │ ├── SliderTransform.ts │ │ ├── interfaces │ │ │ └── SliderBBoxProjectorShaderMaterial.ts │ │ └── shaders │ │ │ ├── fisheye.fragment.glsl.ts │ │ │ ├── fisheye.vertex.glsl.ts │ │ │ ├── fisheye_curtain.fragment.glsl.ts │ │ │ ├── fisheye_curtain.vertex.glsl.ts │ │ │ ├── perspective.fragment.glsl.ts │ │ │ ├── perspective.vertex.glsl.ts │ │ │ ├── perspective_curtain.fragment.glsl.ts │ │ │ ├── perspective_curtain.vertex.glsl.ts │ │ │ ├── perspective_distorted.fragment.glsl.ts │ │ │ ├── perspective_distorted.vertex.glsl.ts │ │ │ ├── perspective_distorted_curtain.fragment.glsl.ts │ │ │ ├── perspective_distorted_curtain.vertex.glsl.ts │ │ │ ├── spherical.fragment.glsl.ts │ │ │ ├── spherical.vertex.glsl.ts │ │ │ ├── spherical_curtain.fragment.glsl.ts │ │ │ └── spherical_curtain.vertex.glsl.ts │ ├── spatial │ │ ├── Modes.ts │ │ ├── SpatialCache.ts │ │ ├── SpatialCommon.ts │ │ ├── SpatialComponent.ts │ │ ├── SpatialScene.ts │ │ ├── enums │ │ │ ├── CameraVisualizationMode.ts │ │ │ ├── OriginalPositionMode.ts │ │ │ └── PointVisualizationMode.ts │ │ └── scene │ │ │ ├── CameraFrameBase.ts │ │ │ ├── CellLine.ts │ │ │ ├── ClusterPoints.ts │ │ │ ├── PerspectiveCameraFrame.ts │ │ │ ├── PositionLine.ts │ │ │ ├── SpatialAssets.ts │ │ │ ├── SpatialCell.ts │ │ │ ├── SpatialIntersection.ts │ │ │ ├── SpatialOctree.ts │ │ │ ├── SpatialOctreeMath.ts │ │ │ ├── SpatialOctreeNode.ts │ │ │ └── SphericalCameraFrame.ts │ ├── tag │ │ ├── TagComponent.ts │ │ ├── TagCreator.ts │ │ ├── TagDOMRenderer.ts │ │ ├── TagMode.ts │ │ ├── TagOperation.ts │ │ ├── TagScene.ts │ │ ├── TagSet.ts │ │ ├── error │ │ │ └── GeometryTagError.ts │ │ ├── geometry │ │ │ ├── Geometry.ts │ │ │ ├── PointGeometry.ts │ │ │ ├── PointsGeometry.ts │ │ │ ├── PolygonGeometry.ts │ │ │ ├── RectGeometry.ts │ │ │ └── VertexGeometry.ts │ │ ├── handlers │ │ │ ├── CreateHandlerBase.ts │ │ │ ├── CreatePointHandler.ts │ │ │ ├── CreatePointsHandler.ts │ │ │ ├── CreatePolygonHandler.ts │ │ │ ├── CreateRectDragHandler.ts │ │ │ ├── CreateRectHandler.ts │ │ │ ├── CreateVertexHandler.ts │ │ │ ├── EditVertexHandler.ts │ │ │ └── TagHandlerBase.ts │ │ ├── interfaces │ │ │ ├── ExtremePointCreateTagOptions.ts │ │ │ ├── ExtremePointTagOptions.ts │ │ │ ├── OutlineCreateTagOptions.ts │ │ │ ├── OutlineTagOptions.ts │ │ │ ├── SpotTagOptions.ts │ │ │ └── TagInteraction.ts │ │ └── tag │ │ │ ├── CreateTag.ts │ │ │ ├── ExtremePointCreateTag.ts │ │ │ ├── ExtremePointRenderTag.ts │ │ │ ├── ExtremePointTag.ts │ │ │ ├── OutlineCreateTag.ts │ │ │ ├── OutlineRenderTag.ts │ │ │ ├── OutlineRenderTagBase.ts │ │ │ ├── OutlineTag.ts │ │ │ ├── RenderTag.ts │ │ │ ├── SpotRenderTag.ts │ │ │ ├── SpotTag.ts │ │ │ ├── Tag.ts │ │ │ ├── TagDomain.ts │ │ │ └── events │ │ │ ├── TagEventType.ts │ │ │ └── TagStateEvent.ts │ ├── util │ │ ├── ComponentSize.ts │ │ ├── HandlerBase.ts │ │ ├── MeshFactory.ts │ │ ├── MeshScene.ts │ │ └── MouseOperator.ts │ └── zoom │ │ └── ZoomComponent.ts ├── error │ ├── ArgumentMapillaryError.ts │ ├── CancelMapillaryError.ts │ ├── GraphMapillaryError.ts │ └── MapillaryError.ts ├── external │ ├── api.ts │ ├── component.ts │ └── viewer.ts ├── geo │ ├── Camera.ts │ ├── Geo.ts │ ├── GeoCoords.ts │ ├── GeoRBush.ts │ ├── Lines.ts │ ├── Spatial.ts │ ├── Transform.ts │ ├── ViewportCoords.ts │ └── interfaces │ │ └── CameraType.ts ├── geometry │ ├── Camera.ts │ ├── Common.ts │ ├── Constants.ts │ ├── camera │ │ ├── FisheyeCamera.ts │ │ ├── PerspectiveCamera.ts │ │ └── SphericalCamera.ts │ └── interfaces │ │ ├── ICamera.ts │ │ └── ICameraFactory.ts ├── graph │ ├── FilterCreator.ts │ ├── FilterExpression.ts │ ├── Graph.ts │ ├── GraphCalculator.ts │ ├── GraphMode.ts │ ├── GraphService.ts │ ├── Image.ts │ ├── ImageCache.ts │ ├── Sequence.ts │ ├── edge │ │ ├── EdgeCalculator.ts │ │ ├── EdgeCalculatorCoefficients.ts │ │ ├── EdgeCalculatorDirections.ts │ │ ├── EdgeCalculatorSettings.ts │ │ ├── NavigationDirection.ts │ │ └── interfaces │ │ │ ├── NavigationEdge.ts │ │ │ ├── NavigationEdgeData.ts │ │ │ ├── PotentialEdge.ts │ │ │ ├── SphericalDirection.ts │ │ │ ├── StepDirection.ts │ │ │ └── TurnDirection.ts │ └── interfaces │ │ ├── GraphConfiguration.ts │ │ └── NavigationEdgeStatus.ts ├── mapillary.ts ├── render │ ├── DOMRenderer.ts │ ├── GLRenderer.ts │ ├── RenderCamera.ts │ ├── RenderMode.ts │ ├── RenderPass.ts │ ├── RenderService.ts │ └── interfaces │ │ ├── GLFrameRenderer.ts │ │ ├── GLRenderFunction.ts │ │ ├── IGLRenderHash.ts │ │ ├── ViewportSize.ts │ │ └── VirtualNodeHash.ts ├── shader │ ├── Resolver.ts │ ├── Shader.ts │ ├── ShaderChunk.ts │ ├── chunk │ │ ├── bearing_fragment.glsl.ts │ │ ├── common.glsl.ts │ │ ├── coordinates.glsl.ts │ │ ├── extrinsic_vertex.glsl.ts │ │ ├── gl_frag_color_fragment.glsl.ts │ │ ├── gl_position_vertex.glsl.ts │ │ ├── map_color_fragment.glsl.ts │ │ ├── precision_fragment.glsl.ts │ │ ├── uniforms_fragment.glsl.ts │ │ ├── uniforms_vertex.glsl.ts │ │ ├── varyings_fragment.glsl.ts │ │ └── varyings_vertex.glsl.ts │ └── shaders │ │ └── texture.glsl.ts ├── state │ ├── FrameGenerator.ts │ ├── State.ts │ ├── StateContext.ts │ ├── StateService.ts │ ├── StateTransitionMatrix.ts │ ├── TransitionMode.ts │ ├── interfaces │ │ ├── AnimationFrame.ts │ │ ├── EulerRotation.ts │ │ ├── IAnimationState.ts │ │ ├── IStateBase.ts │ │ └── IStateContext.ts │ └── state │ │ ├── CustomState.ts │ │ ├── EarthState.ts │ │ ├── EulerRotationDelta.ts │ │ ├── GravityTraversingState.ts │ │ ├── InteractiveStateBase.ts │ │ ├── InteractiveWaitingState.ts │ │ ├── StateBase.ts │ │ ├── TraversingState.ts │ │ └── WaitingState.ts ├── tile │ ├── RegionOfInterestCalculator.ts │ ├── TextureProvider.ts │ ├── TileLoader.ts │ ├── TileMath.ts │ ├── TileStore.ts │ └── interfaces │ │ ├── TileBoundingBox.ts │ │ ├── TileRegionOfInterest.ts │ │ └── TileTypes.ts ├── util │ ├── Common.ts │ ├── DOM.ts │ ├── EventEmitter.ts │ ├── Func.ts │ ├── SubscriptionHolder.ts │ ├── Support.ts │ └── interfaces │ │ └── IEventEmitter.ts └── viewer │ ├── CacheService.ts │ ├── ComponentController.ts │ ├── ConfigurationService.ts │ ├── Container.ts │ ├── CustomCameraControls.ts │ ├── CustomRenderer.ts │ ├── KeyboardService.ts │ ├── LoadingService.ts │ ├── Modes.ts │ ├── MouseService.ts │ ├── Navigator.ts │ ├── Observer.ts │ ├── PanService.ts │ ├── PlayService.ts │ ├── Projection.ts │ ├── ProjectionService.ts │ ├── SpriteService.ts │ ├── TouchService.ts │ ├── Viewer.ts │ ├── enums │ ├── Alignment.ts │ ├── CameraControls.ts │ └── RenderPass.ts │ ├── events │ ├── ViewerBearingEvent.ts │ ├── ViewerDataLoadingEvent.ts │ ├── ViewerDragEndEvent.ts │ ├── ViewerEvent.ts │ ├── ViewerEventType.ts │ ├── ViewerImageEvent.ts │ ├── ViewerLoadEvent.ts │ ├── ViewerMouseEvent.ts │ ├── ViewerNavigableEvent.ts │ ├── ViewerNavigationEdgeEvent.ts │ ├── ViewerReferenceEvent.ts │ ├── ViewerResetEvent.ts │ └── ViewerStateEvent.ts │ ├── interfaces │ ├── ICustomCameraControls.ts │ ├── ICustomRenderer.ts │ ├── ISpriteAtlas.ts │ ├── IViewer.ts │ ├── MouseClaim.ts │ ├── MousePixelDeferral.ts │ ├── PointOfView.ts │ ├── TouchPinch.ts │ └── Unprojection.ts │ └── options │ ├── ComponentOptions.ts │ ├── FallbackOptions.ts │ ├── UrlOptions.ts │ └── ViewerOptions.ts ├── styles ├── attribution.css ├── bearing.css ├── cover.css ├── direction.css ├── mapillary.css ├── navigation.css ├── popup.css ├── sequence.css ├── slider.css ├── svg │ ├── pointer-wheat.svg │ ├── pointer-white.svg │ ├── stepper-left.svg │ ├── stepper-play.svg │ ├── stepper-right.svg │ ├── stepper-stop.svg │ ├── turn-around.svg │ └── turn.svg ├── tag.css └── zoom.css ├── test ├── Bootstrap.ts ├── api │ ├── APIWrapper.test.ts │ ├── CellMath.test.ts │ ├── Common.test.ts │ ├── DataProviderBase.test.ts │ ├── GeometryProviderBase.test.ts │ ├── S2GeometryProvider.test.ts │ └── provider │ │ ├── GraphConverter.test.ts │ │ └── GraphDataProvider.test.ts ├── component │ ├── Component.test.ts │ ├── direction │ │ ├── DirectionComponent.test.ts │ │ └── DirectionDOMRenderer.test.ts │ ├── keyboard │ │ ├── KeyPlayHandler.test.ts │ │ └── KeyZoomHandler.test.ts │ ├── marker │ │ ├── Marker.test.ts │ │ ├── MarkerComponent.test.ts │ │ ├── MarkerScene.test.ts │ │ └── MarkerSet.test.ts │ ├── mouse │ │ └── DragPanHandler.test.ts │ ├── popup │ │ ├── Popup.test.ts │ │ └── PopupComponent.test.ts │ ├── sequence │ │ └── SequenceComponent.test.ts │ ├── spatial │ │ ├── SpatialCache.test.ts │ │ ├── SpatialComponent.test.ts │ │ └── scene │ │ │ ├── SpatialOctree.test.ts │ │ │ ├── SpatialOctreeMath.test.ts │ │ │ └── SpatialOctreeNode.test.ts │ ├── tag │ │ ├── CreateHandlerBase.test.ts │ │ ├── CreatePointHandler.test.ts │ │ ├── ExtremePointRenderTag.test.ts │ │ ├── OutlineRenderTag.test.ts │ │ ├── PointGeometry.test.ts │ │ ├── PointsGeometry.test.ts │ │ ├── PolygonGeometry.test.ts │ │ ├── RectGeometry.test.ts │ │ ├── TagComponent.test.ts │ │ ├── TagScene.test.ts │ │ └── TagSet.test.ts │ └── util │ │ └── HandlerBase.test.ts ├── geo │ ├── Camera.test.ts │ ├── GeoCoords.test.ts │ ├── Lines.test.ts │ ├── Spatial.test.ts │ ├── Transform.test.ts │ └── ViewportCoords.test.ts ├── geometry │ ├── FisheyeCamera.test.ts │ ├── PerspectiveCamera.test.ts │ └── SphericalCamera.test.ts ├── graph │ ├── FilterCreator.test.ts │ ├── Graph.test.ts │ ├── GraphCalculator.test.ts │ ├── GraphService.test.ts │ ├── Image.test.ts │ ├── ImageCache.test.ts │ ├── Sequence.test.ts │ └── edge │ │ ├── EdgeCalculator.Pano.test.ts │ │ ├── EdgeCalculator.Sequence.test.ts │ │ ├── EdgeCalculator.Similar.test.ts │ │ ├── EdgeCalculator.Step.test.ts │ │ ├── EdgeCalculator.Turn.test.ts │ │ └── EdgeCalculator.test.ts ├── helper │ ├── ConfigurationServiceMockCreator.ts │ ├── ContainerMockCreator.ts │ ├── DOMRendererMockCreator.ts │ ├── EdgeCalculatorHelper.ts │ ├── EventHelper.ts │ ├── FrameHelper.ts │ ├── GLRendererMockCreator.ts │ ├── GeoHelper.ts │ ├── GraphServiceMockCreator.ts │ ├── ImageHelper.ts │ ├── ImageMockCreator.ts │ ├── KeyboardServiceMockCreator.ts │ ├── LoadingServiceMockCreator.ts │ ├── MockCreator.ts │ ├── MockCreatorBase.ts │ ├── MouseServiceMockCreator.ts │ ├── NavigatorMockCreator.ts │ ├── PanServiceMockCreator.ts │ ├── PlayServiceMockCreator.ts │ ├── ProviderHelper.ts │ ├── RenderServiceMockCreator.ts │ ├── RequestHelper.ts │ ├── SpriteServiceMockCreator.ts │ ├── StateHelper.ts │ ├── StateServiceMockCreator.ts │ ├── TestComponent.ts │ ├── TestImage.ts │ ├── TestMath.ts │ ├── TouchServiceMockCreator.ts │ ├── TransformHelper.ts │ └── WebGLRenderer.ts ├── render │ ├── DOMRenderer.test.ts │ ├── GLRenderer.test.ts │ ├── RenderCamera.test.ts │ └── RenderService.test.ts ├── state │ ├── StateService.test.ts │ ├── StateTransitionMatrix.test.ts │ └── state │ │ ├── CustomState.test.ts │ │ ├── StateBase.test.ts │ │ ├── TraversingState.test.ts │ │ └── WaitingState.test.ts ├── tile │ ├── TextureProvider.test.ts │ ├── TileLoader.test.ts │ ├── TileMath.test.ts │ └── TileTypes.test.ts ├── util │ ├── EventEmitter.test.ts │ ├── SubscriptionHolder.test.ts │ └── Support.test.ts └── viewer │ ├── CacheService.test.ts │ ├── ComponentController.test.ts │ ├── ConfigurationService.test.ts │ ├── CustomCameraControls.test.ts │ ├── CustomRenderer.test.ts │ ├── KeyboardService.test.ts │ ├── LoadingService.test.ts │ ├── Modes.test.ts │ ├── MouseService.test.ts │ ├── Navigator.test.ts │ ├── Observer.test.ts │ ├── PanService.test.ts │ ├── PlayService.test.ts │ ├── ProjectionService.test.ts │ ├── SpriteService.test.ts │ ├── TouchService.test.ts │ └── Viewer.test.ts ├── tsconfig.json ├── types └── s2-geometry │ └── index.d.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.{ts,html,css}] 13 | indent_size = 4 14 | 15 | [*.{js,json,yml}] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | ### Basic information 18 | 19 | **MapillaryJS version**: `...` 20 | **System/Browser**: `...` 21 | 22 | ### Steps to Reproduce Behavior 23 | 24 | 1. 25 | 2. 26 | 3. 27 | 28 | ### Expected behavior 29 | 30 | ... 31 | 32 | ### Actual behavior 33 | 34 | ... 35 | 36 | ### Additional information 37 | 38 | ... 39 | 40 | 41 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ## Motivation 13 | 14 | (Write your motivation here.) 15 | 16 | ### Have you read the [Contributing Guidelines](https://github.com/mapillary/mapillary-js/blob//main/.github/CONTRIBUTING.md)? 17 | 18 | (Write your answer here.) 19 | 20 | ## Contribution 21 | 22 | (If this PR adds or changes functionality, describe it here.) 23 | 24 | ## Test Plan 25 | 26 | (Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.) 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | .idea 3 | .vagrant 4 | .vscode 5 | vagrant.* 6 | Vagrantfile 7 | 8 | # Dependencies 9 | /node_modules 10 | 11 | # Misc 12 | *.DS_STORE 13 | *.tgz 14 | *.watchman* 15 | 16 | yarn-error.log* 17 | yarn-debug.log* 18 | 19 | # Artifacts 20 | /build 21 | /dist 22 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/.npmignore -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.10 2 | 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | 5 | RUN apt-get update && \ 6 | apt-get install -y \ 7 | git \ 8 | curl && \ 9 | apt-get clean && \ 10 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 11 | 12 | RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - && \ 13 | apt-get install -y nodejs 14 | 15 | RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg \ 16 | | apt-key add && \ 17 | echo "deb https://dl.yarnpkg.com/debian/ stable main" \ 18 | | tee /etc/apt/sources.list.d/yarn.list && \ 19 | apt update && \ 20 | apt install yarn 21 | 22 | COPY . /source/original-source/mapillary-js 23 | 24 | WORKDIR /source/mapillary-js 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/init.js: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { join } from "path"; 3 | 4 | export const pathname = (dirname) => { 5 | const url = join(import.meta.url, `../${dirname}`); 6 | return new URL(url).pathname; 7 | }; 8 | 9 | const mapillaryAccessToken = process.env.MAPILLARY_ACCESS_TOKEN; 10 | const mapboxAccessToken = process.env.MAPBOX_ACCESS_TOKEN; 11 | 12 | const esmContent = ` 13 | export const accessToken = '${mapillaryAccessToken}'; 14 | export const mapboxAccessToken = '${mapboxAccessToken}'; 15 | `; 16 | const umdContent = ` 17 | var accessToken = '${mapillaryAccessToken}'; 18 | var mapboxAccessToken = '${mapboxAccessToken}'; 19 | `; 20 | 21 | const files = [ 22 | { 23 | name: "token.js", 24 | content: esmContent, 25 | }, 26 | { 27 | name: "token.umd.js", 28 | content: umdContent, 29 | }, 30 | ]; 31 | 32 | const dirname = pathname("../doc/.access-token"); 33 | if (!fs.existsSync(dirname)) { 34 | fs.mkdirSync(dirname); 35 | } 36 | 37 | for (const { name, content } of files) { 38 | fs.writeFileSync(join(dirname, name), content); 39 | } 40 | -------------------------------------------------------------------------------- /config/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('autoprefixer'), 4 | require('postcss-inline-svg')({ 5 | paths: ['./styles'], 6 | encode: svg => Buffer.from(svg).toString('base64'), 7 | transform: encoded => `"data:image/svg+xml;base64,${encoded}"` 8 | }), 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /config/rollup.js: -------------------------------------------------------------------------------- 1 | import commonjs from "@rollup/plugin-commonjs"; 2 | import resolve from "@rollup/plugin-node-resolve"; 3 | import sourcemaps from "rollup-plugin-sourcemaps"; 4 | 5 | const resolveOptions = { preferBuiltins: false }; 6 | 7 | export const plugins = [sourcemaps(), resolve(resolveOptions), commonjs()]; 8 | 9 | export const umdOutput = { 10 | format: "umd", 11 | name: "mapillary", 12 | sourcemap: true, 13 | }; 14 | 15 | export const srcInput = "build/esm/src/mapillary.js"; 16 | 17 | export const esm = { 18 | input: srcInput, 19 | output: [ 20 | { 21 | file: "dist/mapillary.module.js", 22 | format: "es", 23 | sourcemap: true, 24 | }, 25 | ], 26 | plugins, 27 | }; 28 | -------------------------------------------------------------------------------- /config/rollup.serve.config.js: -------------------------------------------------------------------------------- 1 | import { esm } from './rollup.js'; 2 | 3 | export default esm; 4 | -------------------------------------------------------------------------------- /config/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": false, 5 | "downlevelIteration": true, 6 | "module": "commonjs", 7 | "outDir": "../build/cjs/", 8 | "sourceMap": false, 9 | "target": "ES5" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /doc/.eslintignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | 4 | # Generated files 5 | .access-token 6 | .docusaurus 7 | api 8 | build 9 | src/mapillary-js 10 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .access-token 9 | .cache-loader 10 | .docusaurus 11 | /api 12 | /src/mapillary-js 13 | 14 | # Misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # ESLint 26 | .eslintcache 27 | -------------------------------------------------------------------------------- /doc/.prettierignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | 4 | # Generated files 5 | .access-token 6 | .docusaurus 7 | api 8 | build 9 | src/mapillary-js 10 | -------------------------------------------------------------------------------- /doc/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": false, 4 | "jsxBracketSameLine": true, 5 | "printWidth": 80, 6 | "proseWrap": "never", 7 | "singleQuote": true, 8 | "tabWidth": 2, 9 | "trailingComma": "all", 10 | "useTabs": false 11 | } 12 | -------------------------------------------------------------------------------- /doc/.stylelintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | module.exports = { 11 | plugins: ['stylelint-copyright'], 12 | rules: { 13 | 'docusaurus/copyright-header': true, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /doc/babel.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | module.exports = { 11 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 12 | }; 13 | -------------------------------------------------------------------------------- /doc/docs/main/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: guide 3 | title: Guide 4 | --- 5 | 6 | Our guide to main concepts is the best place to start to learn how to develop applications using MapillaryJS step by step. Every next chapter in it builds on the knowledge introduced in the previous chapters. By the end of this section, you will be able to use the viewer and component APIs to control the MapillaryJS behavior according to your application's use case. 7 | 8 | :::info You will learn 9 | 10 | - [How to initialize the viewer with different behaviors and appearances](/docs/main/init) 11 | - [How to control the viewer's behavior and appearance after initialization](/docs/main/control) 12 | - [How to listen to and handle viewer events](/docs/main/event) 13 | - [How to work with component APIs and component events](/docs/main/component) 14 | 15 | ::: 16 | -------------------------------------------------------------------------------- /doc/docs/theory/theory.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: theory 3 | title: Theory 4 | --- 5 | 6 | This section is a deep dive in some of the theoretical concepts used in MapillaryJS. Reading and understanding this section is not needed when using MapillaryJS in your applications. 7 | 8 | :::info You will learn 9 | 10 | - [What coordinate systems are used and how can you convert between them](/docs/theory/coordinates) 11 | - [How the navigation graph is built](/docs/theory/navigation-graph) 12 | - [How to triangulate polygons on the sphere](/docs/theory/polygon-triangulation) 13 | 14 | ::: 15 | -------------------------------------------------------------------------------- /doc/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | const path = require('path'); 11 | const docsConfig = require('./docusaurus.docs.config.js'); 12 | 13 | const config = {...docsConfig}; 14 | config.plugins = config.plugins.slice(); 15 | config.plugins.push( 16 | [ 17 | 'docusaurus-plugin-typedoc', 18 | { 19 | sidebar: {sidebarFile: null}, 20 | }, 21 | ], 22 | [ 23 | path.resolve(__dirname, 'plugins/plugin-overwrite-slug'), 24 | { 25 | basePath: 'api', 26 | files: [ 27 | { 28 | path: 'index.md', 29 | slug: '/', 30 | }, 31 | ], 32 | }, 33 | ], 34 | [ 35 | '@docusaurus/plugin-content-docs', 36 | { 37 | id: 'api', 38 | path: 'api', 39 | routeBasePath: 'api', 40 | sidebarPath: require.resolve('./sidebars/api.sidebars.js'), 41 | editUrl: 'https://github.com/mapillary/mapillary-js/edit/main/doc', 42 | }, 43 | ], 44 | ); 45 | 46 | /** @type {import('@docusaurus/types').DocusaurusConfig} */ 47 | module.exports = config; 48 | -------------------------------------------------------------------------------- /doc/mapillary-js.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOC="$(dirname "${BASH_SOURCE[0]}")" 4 | 5 | # MapillaryJS 6 | # 7 | # Can not be in doc/node_modules because of 8 | # class inheritance problems related to CJS 9 | # module conversion in server build. 10 | MJS_NAME="mapillary-js" 11 | MJS_MODULE="$DOC/src/$MJS_NAME" 12 | MJS="$DOC/.." 13 | 14 | mkdir -p "$MJS_MODULE" 15 | cp -R "$MJS/dist" "$MJS_MODULE" 16 | -------------------------------------------------------------------------------- /doc/plugins/plugin-overwrite-slug/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | const fs = require('fs'); 11 | const path = require('path'); 12 | 13 | const DEFAULT_OPTIONS = {}; 14 | 15 | module.exports = (context, options) => { 16 | const opts = {...DEFAULT_OPTIONS, ...options}; 17 | 18 | const {basePath, files} = opts; 19 | 20 | files.forEach((file) => { 21 | const name = path.join(process.cwd(), basePath, file.path); 22 | const content = fs.readFileSync(name, 'utf-8'); 23 | const lines = content.split('\n'); 24 | const overwritten = lines.reduce((acc, line) => { 25 | if (!line.startsWith('slug: ')) { 26 | return acc; 27 | } 28 | return acc.replace(line, `slug: '${file.slug}'`); 29 | }, content); 30 | fs.writeFileSync(name, overwritten); 31 | }); 32 | 33 | return { 34 | name: 'plugin-overwrite-slug', 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /doc/sidebars/api.sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | module.exports = { 11 | api: [ 12 | { 13 | type: 'autogenerated', 14 | dirName: '.', 15 | }, 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /doc/sidebars/examples.sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | module.exports = { 11 | examples: ['examples'], 12 | }; 13 | -------------------------------------------------------------------------------- /doc/src/css/log.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | .example-log-container { 11 | user-select: none; 12 | color: #eee; 13 | position: absolute; 14 | top: 0px; 15 | right: 12px; 16 | width: 200px; 17 | font: 10px 'Lucida Grande', sans-serif; 18 | } 19 | 20 | .example-log-container.option-child { 21 | top: initial; 22 | right: initial; 23 | margin-left: 4px; 24 | width: 196px; 25 | font: 10px 'Lucida Grande', sans-serif; 26 | } 27 | 28 | .example-log-container .header { 29 | border-bottom: 1px solid #2c2c2c; 30 | background-color: #000; 31 | height: 20px; 32 | line-height: 20px; 33 | text-align: center; 34 | } 35 | 36 | .example-log-container .log-item { 37 | text-overflow: ellipsis; 38 | white-space: nowrap; 39 | overflow: hidden; 40 | background-color: #1a1a1a; 41 | padding: 0 4px 0 5px; 42 | height: 18px; 43 | line-height: 18px; 44 | border-bottom: 1px solid #2c2c2c; 45 | border-left: 3px solid #1ed36f; 46 | } 47 | -------------------------------------------------------------------------------- /doc/src/css/mapbox.css: -------------------------------------------------------------------------------- 1 | @import '~mapbox-gl/dist/mapbox-gl.css'; 2 | -------------------------------------------------------------------------------- /doc/src/js/components/Code.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import useBaseUrl from '@docusaurus/useBaseUrl'; 12 | 13 | import styles from './code.module.css'; 14 | 15 | export function Code(props) { 16 | const {title, style} = props; 17 | const name = title.replace(/\s/g, '-'); 18 | return ( 19 | 26 | View source code on GitHub 31 | 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /doc/src/js/components/ViewerComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import {accessToken, mapboxAccessToken} from '../../../.access-token/token'; 12 | 13 | import styles from './viewer.module.css'; 14 | 15 | export class ViewerComponent extends React.Component { 16 | constructor(props) { 17 | super(props); 18 | this.containerRef = React.createRef(); 19 | } 20 | 21 | componentDidMount() { 22 | const {init} = this.props; 23 | init({ 24 | accessToken, 25 | mapboxAccessToken, 26 | container: this.containerRef.current, 27 | }); 28 | } 29 | 30 | componentWillUnmount() { 31 | const {dispose} = this.props; 32 | dispose(); 33 | } 34 | 35 | render() { 36 | const {style} = this.props; 37 | return ( 38 |
43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /doc/src/js/components/code.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | .codeButton { 11 | position: fixed; 12 | top: 76px; 13 | left: 16px; 14 | padding: 13px 12px 9px 12px; 15 | border-radius: 50%; 16 | margin-bottom: 0px; 17 | background-color: #fff; 18 | opacity: 0.9; 19 | box-shadow: 0px 0px 3px rgb(0 0 0 / 40%); 20 | } 21 | 22 | .codeArrows { 23 | width: 24px; 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/js/components/viewer.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | @import '../../mapillary-js/dist/mapillary.css'; 11 | 12 | .mapillaryViewer { 13 | height: calc(100vh - 60px); 14 | width: 100%; 15 | } 16 | -------------------------------------------------------------------------------- /doc/src/js/options/Controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | export class Controller { 11 | constructor(object, property) { 12 | this.object = object; 13 | this.property = property; 14 | 15 | this.name = document.createElement('span'); 16 | this.name.textContent = property; 17 | 18 | this.container = document.createElement('div'); 19 | this.container.classList.add('controller'); 20 | this.container.appendChild(this.name); 21 | 22 | this._onChange = null; 23 | } 24 | 25 | getValue() { 26 | return this.object[this.property]; 27 | } 28 | 29 | onChange(handler) { 30 | this._onChange = handler; 31 | return this; 32 | } 33 | 34 | setName(name) { 35 | this.name.textContent = name; 36 | return this; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /doc/src/js/options/FunctionController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import {Controller} from './Controller'; 11 | 12 | export class FunctionController extends Controller { 13 | constructor(object, property) { 14 | super(object, property); 15 | 16 | this.container.classList.add('function'); 17 | 18 | this._onChange = this.object[this.property]; 19 | 20 | this.container.addEventListener('click', (event) => { 21 | event.preventDefault(); 22 | this.fire(); 23 | }); 24 | } 25 | 26 | fire() { 27 | if (this._onChange) { 28 | this._onChange(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /doc/src/js/options/OptionController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import {Controller} from './Controller'; 11 | 12 | export class OptionController extends Controller { 13 | constructor(object, property, opts) { 14 | super(object, property); 15 | 16 | const options = opts.slice(); 17 | this.select = document.createElement('select'); 18 | for (const opt of options) { 19 | const option = document.createElement('option'); 20 | option.innerHTML = opt; 21 | option.setAttribute('value', opt); 22 | this.select.appendChild(option); 23 | } 24 | 25 | this.container.appendChild(this.select); 26 | this.container.classList.add('option'); 27 | 28 | this.select.addEventListener('change', (event) => { 29 | if (!this._onChange) { 30 | return; 31 | } 32 | const index = event.target.selectedIndex; 33 | const value = options[index]; 34 | this.object[this.property] = value; 35 | this._onChange(value); 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /doc/src/js/utils/error.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import {CancelMapillaryError} from '../../mapillary-js/dist/mapillary.module'; 11 | 12 | export function mapillaryErrorHandler(error) { 13 | if (error instanceof CancelMapillaryError) { 14 | console.warn(`Navigation request cancelled: ${error.message}`); 15 | } else { 16 | console.error(error); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /doc/src/js/utils/image.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | export function generateImageBuffer(options) { 11 | const {tilesY, tilesX, tileSize} = options; 12 | const w = tileSize; 13 | const h = tileSize; 14 | const canvas = document.createElement('canvas'); 15 | canvas.width = w * tilesX; 16 | canvas.height = h * tilesY; 17 | const ctx = canvas.getContext('2d'); 18 | 19 | for (let y = tilesY - 1; y >= 0; y--) { 20 | for (let x = 0; x < tilesX; x++) { 21 | const r = Math.floor((255 * x) / (tilesX - 1)); 22 | const g = Math.floor((255 * (tilesY - 1 - y)) / (tilesY - 1)); 23 | const b = 0; 24 | ctx.fillStyle = `rgb(${r} ${g} ${b})`; 25 | ctx.fillRect(w * x, h * y, w, h); 26 | } 27 | } 28 | 29 | return new Promise((resolve) => { 30 | canvas.toBlob( 31 | async (blob) => { 32 | const buffer = await blob.arrayBuffer(); 33 | resolve(buffer); 34 | }, 35 | 'image/jpeg', 36 | 1, 37 | ); 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-keyboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-keyboard'; 15 | 16 | export default function Example() { 17 | const title = 'Component Keyboard'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-marker-map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-marker-map'; 15 | 16 | export default function Example() { 17 | const title = 'Component Marker Map'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-marker-million.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-marker-million'; 15 | 16 | export default function Example() { 17 | const title = 'Component Marker Million'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-marker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-marker'; 15 | 16 | export default function Example() { 17 | const title = 'Component Marker'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-pointer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-pointer'; 15 | 16 | export default function Example() { 17 | const title = 'Component Pointer'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-popup-tag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-popup-tag'; 15 | 16 | export default function Example() { 17 | const title = 'Component Popup-Tag'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-popup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-popup'; 15 | 16 | export default function Example() { 17 | const title = 'Component Popup'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-spatial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-spatial'; 15 | 16 | export default function Example() { 17 | const title = 'Component Spatial'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-tag-create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-tag-create'; 15 | 16 | export default function Example() { 17 | const title = 'Component Tag Create'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-tag-interact.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-tag-interact'; 15 | 16 | export default function Example() { 17 | const title = 'Component Tag Interact'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/component-tag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/component-tag'; 15 | 16 | export default function Example() { 17 | const title = 'Component Tag'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-animation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-animation'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Animation'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-editor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-editor'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Editor'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-fly-controls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-fly-controls'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Fly Controls'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-graphics-developer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-graphics-developer'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Graphics Developer'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-map-sync.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-map-sync'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Map Sync'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-procedural-data-provider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-procedural-data-provider'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Procedural Data Provider'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-three-renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-three-renderer'; 15 | 16 | export default function Example() { 17 | const title = 'Extend Three Renderer'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/extend-webgl-renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/extend-webgl-renderer'; 15 | 16 | export default function Example() { 17 | const title = 'Extend WebGL Renderer'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/support.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/support'; 15 | 16 | export default function Example() { 17 | const title = 'Support'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-coordinates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-coordinates'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer Coordinates'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-events'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer Events'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-filters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-filters'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer Filters'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-from-map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-from-map'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer From Map'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-initialization.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-initialization'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer Initialization'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-methods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-methods'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer Methods'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-options.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-options'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer Options'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/examples/viewer-to-map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import Layout from '@theme/Layout'; 12 | import {Code} from '../../js/components/Code'; 13 | import {ViewerComponent} from '../../js/components/ViewerComponent'; 14 | import {dispose, init} from '../../js/examples/viewer-to-map'; 15 | 16 | export default function Example() { 17 | const title = 'Viewer To Map'; 18 | return ( 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /doc/src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @format 8 | */ 9 | 10 | /** 11 | * CSS files with the .module.css suffix will be treated as CSS modules 12 | * and scoped locally. 13 | */ 14 | 15 | .heroBanner { 16 | padding: 4rem 0; 17 | text-align: center; 18 | position: relative; 19 | overflow: hidden; 20 | } 21 | 22 | .heroBannerLogo { 23 | max-width: 150px; 24 | max-height: 150px; 25 | } 26 | 27 | @media screen and (max-width: 966px) { 28 | .heroBanner { 29 | padding: 2rem; 30 | } 31 | } 32 | 33 | .buttons { 34 | display: flex; 35 | align-items: center; 36 | justify-content: center; 37 | } 38 | 39 | .features { 40 | display: flex; 41 | align-items: center; 42 | padding: 2rem 0; 43 | width: 100%; 44 | } 45 | 46 | .featureImage { 47 | height: 200px; 48 | max-width: 300px; 49 | } 50 | -------------------------------------------------------------------------------- /doc/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/.nojekyll -------------------------------------------------------------------------------- /doc/static/img/examples/code.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/static/img/examples/rotate.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /doc/static/img/examples/scale.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/static/img/examples/translate.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/static/img/extension/custom-render-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/extension/custom-render-design.png -------------------------------------------------------------------------------- /doc/static/img/extension/data-provider-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/extension/data-provider-design.png -------------------------------------------------------------------------------- /doc/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/favicon.png -------------------------------------------------------------------------------- /doc/static/img/hero/dropoff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/hero/dropoff.png -------------------------------------------------------------------------------- /doc/static/img/hero/mjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/hero/mjs.png -------------------------------------------------------------------------------- /doc/static/img/hero/semantic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/hero/semantic.png -------------------------------------------------------------------------------- /doc/static/img/logo_black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /doc/static/img/logo_green.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /doc/static/img/oss_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/oss_logo.png -------------------------------------------------------------------------------- /doc/static/img/theory/graph-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/graph-diagram.png -------------------------------------------------------------------------------- /doc/static/img/theory/graph-multiple-tiles-edges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/graph-multiple-tiles-edges.png -------------------------------------------------------------------------------- /doc/static/img/theory/graph-multiple-tiles-nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/graph-multiple-tiles-nodes.png -------------------------------------------------------------------------------- /doc/static/img/theory/graph-multiple-tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/graph-multiple-tiles.png -------------------------------------------------------------------------------- /doc/static/img/theory/graph-single-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/graph-single-tile.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-behind-camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-behind-camera.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-clipped-on-sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-clipped-on-sphere.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-clipped-projected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-clipped-projected.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-clipped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-clipped.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-combined-sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-combined-sphere.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-equirectangular-panorama.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-equirectangular-panorama.jpg -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-in-front-of-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-in-front-of-image.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-on-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-on-grid.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-on-real-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-on-real-image.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-on-undistorted-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-on-undistorted-image.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-rendered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-rendered.jpg -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-triangulated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-triangulated.png -------------------------------------------------------------------------------- /doc/static/img/theory/polygon-undistorted.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapillary/mapillary-js/a0d7bc72c8c90030426219f1fe6eb20e700cd5f0/doc/static/img/theory/polygon-undistorted.jpg -------------------------------------------------------------------------------- /doc/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": [ 3 | "../src/external/api.ts", 4 | "../src/external/component.ts", 5 | "../src/external/viewer.ts" 6 | ], 7 | "excludeExternals": true, 8 | "excludePrivate": true, 9 | "excludeProtected": true, 10 | "hideGenerator": true, 11 | "includeVersion": true, 12 | "name": "MapillaryJS", 13 | "out": "../api", 14 | "readme": "none", 15 | "tsconfig": "../tsconfig.json" 16 | } 17 | -------------------------------------------------------------------------------- /examples/doc/extend-animation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extend Animation 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/extend-fly-controls.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extend Fly Controls 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/extend-graphics-developer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extend Graphics Developer 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/extend-procedural-data-provider.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extend Procedural Data Provider 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/doc/extend-three-renderer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extend Three.js Renderer 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/extend-webgl-renderer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Extend WebGL Renderer 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/support.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Support 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/viewer-events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Viewer Events 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 28 | 29 | 30 | 31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/doc/viewer-initialization.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Viewer Initialization 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/doc/viewer-options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Viewer Options 5 | 6 | 7 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | 30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | collectCoverage: true, 3 | collectCoverageFrom: ["/src/**/*"], 4 | coveragePathIgnorePatterns: [ 5 | "/src/api/contracts/", 6 | "/src/api/ents/", 7 | "/src/export/", 8 | "/src/component/shaders/", 9 | "/src/mapillary.js", 10 | "/src/viewer/events/", 11 | "/src/viewer/options/", 12 | "interfaces", 13 | ], 14 | coverageProvider: "babel", 15 | moduleDirectories: ["node_modules"], 16 | moduleFileExtensions: ["js"], 17 | rootDir: "build/cjs", 18 | slowTestThreshold: 1, 19 | testEnvironment: "jsdom", 20 | testRunner: "jest-jasmine2", 21 | watchman: false, 22 | }; 23 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import dts from 'rollup-plugin-dts'; 2 | import { terser } from 'rollup-plugin-terser'; 3 | import { 4 | esm, 5 | srcInput as input, 6 | plugins, 7 | umdOutput, 8 | } from './config/rollup.js'; 9 | 10 | const unminifiedOutput = Object.assign( 11 | { file: 'dist/mapillary.unminified.js' }, 12 | umdOutput); 13 | 14 | const minifiedOutput = Object.assign( 15 | { file: 'dist/mapillary.js' }, 16 | umdOutput); 17 | 18 | const bundles = [ 19 | esm, 20 | { 21 | input, 22 | output: [ 23 | unminifiedOutput 24 | ], 25 | plugins, 26 | }, 27 | { 28 | input, 29 | output: [ 30 | minifiedOutput, 31 | ], 32 | plugins: [ 33 | ...plugins, 34 | terser(), 35 | ], 36 | }, 37 | { 38 | input: 'build/esm/src/mapillary.d.ts', 39 | output: [ 40 | { 41 | file: 'dist/mapillary.d.ts', 42 | format: 'es', 43 | } 44 | ], 45 | plugins: [ 46 | dts(), 47 | ], 48 | }, 49 | ]; 50 | 51 | export default bundles; 52 | -------------------------------------------------------------------------------- /src/api/CellMath.ts: -------------------------------------------------------------------------------- 1 | import { IGeometryProvider } from "./interfaces/IGeometryProvider"; 2 | 3 | export function connectedComponent( 4 | cellId: string, 5 | depth: number, 6 | geometry: IGeometryProvider) 7 | : string[] { 8 | 9 | const cells = new Set(); 10 | cells.add(cellId); 11 | connectedComponentRecursive(cells, [cellId], 0, depth, geometry); 12 | return Array.from(cells); 13 | } 14 | 15 | function connectedComponentRecursive( 16 | cells: Set, 17 | current: string[], 18 | currentDepth: number, 19 | maxDepth: number, 20 | geometry: IGeometryProvider) 21 | : void { 22 | 23 | if (currentDepth >= maxDepth) { return; } 24 | 25 | const adjacent: string[] = []; 26 | for (const cellId of current) { 27 | const aCells = geometry.getAdjacent(cellId); 28 | adjacent.push(...aCells); 29 | } 30 | 31 | const newCells: string[] = []; 32 | for (const a of adjacent) { 33 | if (cells.has(a)) { continue; } 34 | cells.add(a); 35 | newCells.push(a); 36 | } 37 | 38 | connectedComponentRecursive( 39 | cells, 40 | newCells, 41 | currentDepth + 1, 42 | maxDepth, 43 | geometry); 44 | } 45 | -------------------------------------------------------------------------------- /src/api/contracts/CoreImagesContract.ts: -------------------------------------------------------------------------------- 1 | import { CoreImageEnt } from "../ents/CoreImageEnt"; 2 | 3 | /** 4 | * Contract describing core image results. 5 | */ 6 | export interface CoreImagesContract { 7 | /** 8 | * Geometry cell ID. 9 | */ 10 | cell_id: string; 11 | 12 | /** 13 | * Array of core image ents. 14 | */ 15 | images: CoreImageEnt[]; 16 | } 17 | -------------------------------------------------------------------------------- /src/api/contracts/EntContract.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Contract describing ent results. 3 | */ 4 | export interface EntContract { 5 | /** 6 | * Ent node. 7 | */ 8 | node: T; 9 | 10 | /** 11 | * Ent node id. 12 | */ 13 | node_id: string; 14 | } 15 | -------------------------------------------------------------------------------- /src/api/contracts/ImageTilesContract.ts: -------------------------------------------------------------------------------- 1 | import { ImageTileEnt } from "../ents/ImageTileEnt"; 2 | import { EntContract } from "./EntContract"; 3 | 4 | /** 5 | * Contract describing image tile results. 6 | */ 7 | export type ImageTilesContract = EntContract; 8 | -------------------------------------------------------------------------------- /src/api/contracts/ImageTilesRequestContract.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Contract describing image tile requests. 3 | */ 4 | export interface ImageTilesRequestContract { 5 | /** 6 | * ID of the tile's image. 7 | */ 8 | imageId: string; 9 | 10 | /** 11 | * Tile level. 12 | */ 13 | z: number; 14 | } 15 | -------------------------------------------------------------------------------- /src/api/contracts/ImagesContract.ts: -------------------------------------------------------------------------------- 1 | import { ImageEnt } from "../ents/ImageEnt"; 2 | import { EntContract } from "./EntContract"; 3 | 4 | /** 5 | * Contract describing image results. 6 | */ 7 | export type ImagesContract = EntContract[]; 8 | -------------------------------------------------------------------------------- /src/api/contracts/MeshContract.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Contract describing triangulated meshes. 3 | */ 4 | export interface MeshContract { 5 | /** 6 | * Flattened array of faces for the mesh. Each face consist 7 | * three vertex indices. 8 | */ 9 | faces: number[]; 10 | 11 | /** 12 | * Flattened array of vertices for the mesh. Each vertex 13 | * consists of X, Y and Z coordinates in the camera 14 | * reference frame. 15 | */ 16 | vertices: number[]; 17 | } 18 | -------------------------------------------------------------------------------- /src/api/contracts/SequenceContract.ts: -------------------------------------------------------------------------------- 1 | import { SequenceEnt } from "../ents/SequenceEnt"; 2 | 3 | /** 4 | * Contract describing sequence results. 5 | */ 6 | export type SequenceContract = SequenceEnt; 7 | -------------------------------------------------------------------------------- /src/api/contracts/SpatialImagesContract.ts: -------------------------------------------------------------------------------- 1 | import { SpatialImageEnt } from "../ents/SpatialImageEnt"; 2 | import { EntContract } from "./EntContract"; 3 | 4 | /** 5 | * Contract describing spatial image results. 6 | */ 7 | export type SpatialImagesContract = EntContract[]; 8 | -------------------------------------------------------------------------------- /src/api/ents/CameraEnt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Ent representing camera properties. 3 | */ 4 | export interface CameraEnt { 5 | /** 6 | * Camera type dependent camera parameters. 7 | * 8 | * For perspective and fisheye camera types, 9 | * the camera parameters array should be 10 | * constructed according to 11 | * 12 | * `[focal, k1, k2]` 13 | * 14 | * where focal is the camera focal length, 15 | * and k1, k2 are radial distortion parameters. 16 | * 17 | * For spherical camera type the camera 18 | * parameters should be an emtpy array. 19 | */ 20 | camera_parameters: number[]; 21 | 22 | /** 23 | * Projection type of the camera. 24 | * 25 | * @description Supported camera types are: 26 | * 27 | * ```js 28 | * 'spherical' 29 | * 'fisheye' 30 | * 'perspective' 31 | * ``` 32 | * 33 | * Other camera types will be treated as 34 | * perspective images. 35 | */ 36 | camera_type: string; 37 | } 38 | -------------------------------------------------------------------------------- /src/api/ents/CoreImageEnt.ts: -------------------------------------------------------------------------------- 1 | import { IDEnt } from "./IDEnt"; 2 | import { LngLat } from "../interfaces/LngLat"; 3 | 4 | /** 5 | * Ent representing core image properties. 6 | */ 7 | export interface CoreImageEnt extends IDEnt { 8 | /** 9 | * SfM computed longitude, latitude in WGS84 datum, measured in degrees. 10 | * 11 | * @description Optional - no 3D interaction available 12 | * if unset. 13 | */ 14 | computed_geometry?: LngLat; 15 | 16 | /** 17 | * Original EXIF longitude, latitude in WGS84 datum, measured in degrees. 18 | */ 19 | geometry: LngLat; 20 | 21 | /** 22 | * Sequence that the image is part of. 23 | */ 24 | sequence: IDEnt; 25 | } 26 | -------------------------------------------------------------------------------- /src/api/ents/CreatorEnt.ts: -------------------------------------------------------------------------------- 1 | import { IDEnt } from "./IDEnt"; 2 | 3 | /** 4 | * Ent representing image creator properties. 5 | */ 6 | export interface CreatorEnt extends IDEnt { 7 | /** 8 | * The username of the creator. 9 | */ 10 | username: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/api/ents/IDEnt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Ent representing an entity with a unique ID. 3 | * 4 | * @interface IDEnt 5 | */ 6 | export interface IDEnt { 7 | /** 8 | * Unique ID. 9 | */ 10 | id: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/api/ents/ImageEnt.ts: -------------------------------------------------------------------------------- 1 | import { SpatialImageEnt } from "./SpatialImageEnt"; 2 | import { CoreImageEnt } from "./CoreImageEnt"; 3 | 4 | /** 5 | * Ent representing image properties. 6 | */ 7 | export interface ImageEnt extends CoreImageEnt, SpatialImageEnt { } 8 | -------------------------------------------------------------------------------- /src/api/ents/ImageTileEnt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Ent representing image tile properties. 3 | */ 4 | export interface ImageTileEnt { 5 | /** 6 | * URL for fetching image tile pixel data. 7 | */ 8 | url: string, 9 | 10 | /** 11 | * X tile coordinate. 12 | */ 13 | x: number, 14 | 15 | /** 16 | * Y tile coordinate. 17 | */ 18 | y: number, 19 | 20 | /** 21 | * Tile level. 22 | */ 23 | z: number, 24 | } 25 | -------------------------------------------------------------------------------- /src/api/ents/SequenceEnt.ts: -------------------------------------------------------------------------------- 1 | import { IDEnt } from "./IDEnt"; 2 | 3 | /** 4 | * Ent representing sequence properties. 5 | * 6 | * @interface SequenceEnt 7 | */ 8 | export interface SequenceEnt extends IDEnt { 9 | /** 10 | * The image IDs of the sequence sorted in 11 | * acsending order based on capture time. 12 | */ 13 | image_ids: string[]; 14 | } 15 | -------------------------------------------------------------------------------- /src/api/ents/URLEnt.ts: -------------------------------------------------------------------------------- 1 | import { IDEnt } from "./IDEnt"; 2 | 3 | /** 4 | * Ent representing URL properties. 5 | */ 6 | export interface URLEnt extends IDEnt { 7 | /** 8 | * URL for fetching ent data. 9 | */ 10 | url: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/api/events/ProviderCellEvent.ts: -------------------------------------------------------------------------------- 1 | import { ProviderEvent } from "./ProviderEvent"; 2 | 3 | /** 4 | * 5 | * Interface for data provider cell events. 6 | */ 7 | export interface ProviderCellEvent extends ProviderEvent { 8 | /** 9 | * Cell ids for cells where data have been created. 10 | */ 11 | cellIds: string[]; 12 | 13 | /** 14 | * Provider event type. 15 | */ 16 | type: "datacreate"; 17 | } 18 | -------------------------------------------------------------------------------- /src/api/events/ProviderClusterEvent.ts: -------------------------------------------------------------------------------- 1 | import { ProviderEvent } from "./ProviderEvent"; 2 | 3 | /** 4 | * 5 | * Interface for data provider cluster events. 6 | */ 7 | export interface ProviderClusterEvent extends ProviderEvent { 8 | /** 9 | * Cluster ids for clusters that have been deleted. 10 | */ 11 | clusterIds: string[]; 12 | 13 | /** 14 | * Provider event type. 15 | */ 16 | type: "datadelete"; 17 | } 18 | -------------------------------------------------------------------------------- /src/api/events/ProviderEvent.ts: -------------------------------------------------------------------------------- 1 | import { IDataProvider } from "../interfaces/IDataProvider"; 2 | import { ProviderEventType } from "./ProviderEventType"; 3 | 4 | /** 5 | * Interface for general provider events. 6 | */ 7 | export interface ProviderEvent { 8 | /** 9 | * Data provider target that emitted the event. 10 | */ 11 | target: IDataProvider; 12 | 13 | /** 14 | * Provider event type. 15 | */ 16 | type: ProviderEventType; 17 | } 18 | -------------------------------------------------------------------------------- /src/api/events/ProviderEventType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @event 3 | */ 4 | export type ProviderEventType = 5 | | "datacreate" 6 | | "datadelete"; 7 | -------------------------------------------------------------------------------- /src/api/interfaces/LngLat.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface that represents a longitude, latitude coordinate, 3 | * measured in degrees. Coordinates are defined in the WGS84 datum. 4 | */ 5 | export interface LngLat { 6 | /** 7 | * Latitude, measured in degrees. 8 | */ 9 | lat: number; 10 | 11 | /** 12 | * Longitude, measured in degrees. 13 | */ 14 | lng: number; 15 | } 16 | -------------------------------------------------------------------------------- /src/api/interfaces/LngLatAlt.ts: -------------------------------------------------------------------------------- 1 | import { LngLat } from "./LngLat"; 2 | 3 | /** 4 | * Interface that represents longitude-latitude-altitude 5 | * coordinates. Longitude and latitude are measured in degrees 6 | * and altitude in meters. Coordinates are defined in the WGS84 datum. 7 | * 8 | * @interface 9 | */ 10 | export interface LngLatAlt extends LngLat { 11 | /** 12 | * Altitude, measured in meters. 13 | */ 14 | alt: number; 15 | } 16 | -------------------------------------------------------------------------------- /src/api/provider/GraphContracts.ts: -------------------------------------------------------------------------------- 1 | // Cluster reconstruction 2 | export interface GraphCameraContract { 3 | focal: number; 4 | k1: number; 5 | k2: number; 6 | projection_type: string; 7 | } 8 | 9 | export interface GraphCameraShotContract { 10 | camera: string; 11 | rotation: number[]; 12 | translation: number[]; 13 | } 14 | 15 | export interface GraphReferenceContract { 16 | altitude: number; 17 | latitude: number; 18 | longitude: number; 19 | } 20 | 21 | export interface GraphPointContract { 22 | color: number[]; 23 | coordinates: number[]; 24 | } 25 | 26 | export interface GraphClusterContract { 27 | cameras: { [cameraId: string]: GraphCameraContract; }; 28 | points: { [pointId: string]: GraphPointContract; }; 29 | reference_lla: GraphReferenceContract, 30 | shots: { [imageKey: string]: GraphCameraShotContract; }; 31 | } 32 | 33 | // General 34 | export interface GraphError { 35 | error: { 36 | code: number; 37 | fbtrace_id: string; 38 | message: string; 39 | type: string; 40 | }; 41 | } 42 | export interface GraphContract { 43 | data: T; 44 | } 45 | -------------------------------------------------------------------------------- /src/api/provider/GraphDataProviderOptions.ts: -------------------------------------------------------------------------------- 1 | export interface GraphDataProviderOptions { 2 | endpoint?: string; 3 | accessToken?: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/api/provider/GraphEnts.ts: -------------------------------------------------------------------------------- 1 | import { IDEnt } from "../ents/IDEnt"; 2 | import { SpatialImageEnt } from "../ents/SpatialImageEnt"; 3 | import { URLEnt } from "../ents/URLEnt"; 4 | 5 | export interface GraphGeometry { coordinates: [number, number]; } 6 | 7 | export interface GraphCoreImageEnt extends IDEnt { 8 | computed_geometry: GraphGeometry; 9 | geometry: GraphGeometry; 10 | sequence: string; 11 | } 12 | 13 | export interface GraphSpatialImageEnt extends SpatialImageEnt { 14 | merge_cc: number; 15 | organization: IDEnt; 16 | sfm_cluster: URLEnt; 17 | thumb_1024_url: string; 18 | thumb_2048_url: string; 19 | } 20 | 21 | export interface GraphImageEnt extends 22 | GraphCoreImageEnt, 23 | GraphSpatialImageEnt { } 24 | -------------------------------------------------------------------------------- /src/component/ComponentName.ts: -------------------------------------------------------------------------------- 1 | export type ComponentName = 2 | | "attribution" 3 | | "bearing" 4 | | "cache" 5 | | "cover" 6 | | "direction" 7 | | "image" 8 | | "keyboard" 9 | | "marker" 10 | | "pointer" 11 | | "popup" 12 | | "sequence" 13 | | "slider" 14 | | "spatial" 15 | | "tag" 16 | | "zoom"; 17 | -------------------------------------------------------------------------------- /src/component/cover/CoverState.ts: -------------------------------------------------------------------------------- 1 | export enum CoverState { 2 | Hidden, 3 | Loading, 4 | Visible, 5 | } 6 | -------------------------------------------------------------------------------- /src/component/events/ComponentEvent.ts: -------------------------------------------------------------------------------- 1 | import { IComponent } from "../interfaces/IComponent"; 2 | import { ComponentEventType } from "./ComponentEventType"; 3 | 4 | /** 5 | * Interface for general component events. 6 | */ 7 | export interface ComponentEvent { 8 | /** 9 | * The component object that fired the event. 10 | */ 11 | target: IComponent; 12 | 13 | /** 14 | * The event type. 15 | */ 16 | type: ComponentEventType; 17 | } 18 | -------------------------------------------------------------------------------- /src/component/events/ComponentEventType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @event 3 | */ 4 | export type ComponentEventType = 5 | | "geometrycreate" 6 | | "hover" 7 | | "markerdragend" 8 | | "markerdragstart" 9 | | "markerposition" 10 | | "playing" 11 | | "tagcreateend" 12 | | "tagcreatestart" 13 | | "tagmode" 14 | | "tags"; 15 | -------------------------------------------------------------------------------- /src/component/events/ComponentGeometryEvent.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from "../tag/geometry/Geometry"; 2 | import { ComponentEvent } from "./ComponentEvent"; 3 | 4 | /** 5 | * Interface for component geometry events. 6 | */ 7 | export interface ComponentGeometryEvent extends ComponentEvent { 8 | /** 9 | * Geometry related to the event. 10 | */ 11 | geometry: Geometry; 12 | 13 | type: "geometrycreate"; 14 | } 15 | -------------------------------------------------------------------------------- /src/component/events/ComponentHoverEvent.ts: -------------------------------------------------------------------------------- 1 | import { ComponentEvent } from "./ComponentEvent"; 2 | 3 | /** 4 | * Interface for component hover events. 5 | */ 6 | export interface ComponentHoverEvent extends ComponentEvent { 7 | /** 8 | * The image id corresponding to the element or object that 9 | * is being hovered. When the mouse leaves the element or 10 | * object the id will be null. 11 | */ 12 | id: string; 13 | 14 | type: "hover"; 15 | } 16 | -------------------------------------------------------------------------------- /src/component/events/ComponentMarkerEvent.ts: -------------------------------------------------------------------------------- 1 | import { Marker } from "../marker/marker/Marker"; 2 | import { ComponentEvent } from "./ComponentEvent"; 3 | 4 | /** 5 | * Interface for component marker events. 6 | */ 7 | export interface ComponentMarkerEvent extends ComponentEvent { 8 | /** 9 | * The marker that was affected by the event. 10 | */ 11 | marker: Marker; 12 | 13 | type: 14 | | "markerdragend" 15 | | "markerdragstart" 16 | | "markerposition"; 17 | } 18 | -------------------------------------------------------------------------------- /src/component/events/ComponentPlayEvent.ts: -------------------------------------------------------------------------------- 1 | import { ComponentEvent } from "./ComponentEvent"; 2 | 3 | /** 4 | * Interface for component play events. 5 | */ 6 | export interface ComponentPlayEvent extends ComponentEvent { 7 | /** 8 | * Value indiciating if the component is playing or not. 9 | */ 10 | playing: boolean; 11 | 12 | type: "playing"; 13 | } 14 | -------------------------------------------------------------------------------- /src/component/events/ComponentStateEvent.ts: -------------------------------------------------------------------------------- 1 | import { IComponent } from "../interfaces/IComponent"; 2 | import { Marker } from "../marker/marker/Marker"; 3 | import { Geometry } from "../tag/geometry/Geometry"; 4 | import { TagMode } from "../tag/TagMode"; 5 | import { ComponentEvent } from "./ComponentEvent"; 6 | import { ComponentEventType } from "./ComponentEventType"; 7 | 8 | /** 9 | * Interface for component state events. 10 | * 11 | * @example 12 | * ```js 13 | * // The `hover` event is an example of a `ComponentStateEvent`. 14 | * // Set up an event listener on the direction component. 15 | * var directionComponent = viewer.getComponent('direction'); 16 | * directionComponent.on('hover', function(e) { 17 | * console.log('A hover event has occured'); 18 | * }); 19 | * ``` 20 | */ 21 | export interface ComponentStateEvent extends ComponentEvent { 22 | type: 23 | | "tagcreateend" 24 | | "tagcreatestart" 25 | | "tags"; 26 | } 27 | -------------------------------------------------------------------------------- /src/component/events/ComponentTagModeEvent.ts: -------------------------------------------------------------------------------- 1 | import { TagMode } from "../tag/TagMode"; 2 | import { ComponentEvent } from "./ComponentEvent"; 3 | 4 | /** 5 | * Interface for component tag mode events. 6 | */ 7 | export interface ComponentTagModeEvent extends ComponentEvent { 8 | /** 9 | * Value indicating the current tag mode of the component. 10 | */ 11 | mode: TagMode; 12 | 13 | type: "tagmode"; 14 | } 15 | -------------------------------------------------------------------------------- /src/component/fallback/FallbackComponentName.ts: -------------------------------------------------------------------------------- 1 | export type FallbackComponentName = 2 | | "imagefallback" 3 | | "navigationfallback" 4 | -------------------------------------------------------------------------------- /src/component/image/interfaces/ProjectorShaderMaterial.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from "three"; 2 | 3 | export interface ProjectorShaderMaterial extends THREE.ShaderMaterial { 4 | uniforms: { 5 | [uniform: string]: THREE.IUniform; 6 | opacity: THREE.IUniform; 7 | map: THREE.IUniform; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /src/component/interfaces/BearingConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | import { ComponentSize } from "../util/ComponentSize"; 3 | 4 | export interface BearingConfiguration extends ComponentConfiguration { 5 | /** 6 | * The size of the ui elements. 7 | * 8 | * @default ComponentSize.Automatic 9 | */ 10 | size?: ComponentSize; 11 | } 12 | -------------------------------------------------------------------------------- /src/component/interfaces/ComponentConfiguration.ts: -------------------------------------------------------------------------------- 1 | export interface ComponentConfiguration { 2 | [key: string]: any; 3 | } 4 | -------------------------------------------------------------------------------- /src/component/interfaces/CoverConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { CoverState } from "../cover/CoverState"; 2 | import { ComponentConfiguration } from "./ComponentConfiguration"; 3 | 4 | export interface CoverConfiguration extends ComponentConfiguration { 5 | id?: string; 6 | src?: string; 7 | state?: CoverState; 8 | } 9 | -------------------------------------------------------------------------------- /src/component/interfaces/IComponent.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | 3 | export interface IComponent { 4 | /** 5 | * Value indicating if the component is currently active. 6 | */ 7 | readonly activated: boolean; 8 | 9 | /** 10 | * Default configuration for the component. 11 | */ 12 | readonly defaultConfiguration: ComponentConfiguration; 13 | 14 | /** 15 | * The name of the component. Used when interacting with the 16 | * component through the Viewer's API. 17 | */ 18 | readonly name: string; 19 | 20 | /** 21 | * Configure the component. 22 | */ 23 | configure(configuration: ComponentConfiguration): void; 24 | } 25 | -------------------------------------------------------------------------------- /src/component/interfaces/KeyboardConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | 3 | /** 4 | * Interface for configuration of keyboard component. 5 | * 6 | * @interface 7 | * @example 8 | * ```js 9 | * var viewer = new Viewer({ 10 | * ... 11 | * component: { 12 | * keyboard: { 13 | * keyZoom: false, 14 | * keySequenceNavigation: false, 15 | * keySpatialNavigation: false, 16 | * }, 17 | * }, 18 | * ... 19 | * }); 20 | * ``` 21 | */ 22 | export interface KeyboardConfiguration extends ComponentConfiguration { 23 | /** 24 | * Enable or disable the `KeyPlayHandler`. 25 | * 26 | * @default true 27 | */ 28 | keyPlay?: boolean; 29 | 30 | /** 31 | * Enable or disable the `KeySequenceNavigationHandler`. 32 | * 33 | * @default true 34 | */ 35 | keySequenceNavigation?: boolean; 36 | 37 | /** 38 | * Enable or disable the `KeySpatialNavigationHandler`. 39 | * 40 | * @default true 41 | */ 42 | keySpatialNavigation?: boolean; 43 | 44 | /** 45 | * Enable or disable the `KeyZoomHandler`. 46 | * 47 | * @default true 48 | */ 49 | keyZoom?: boolean; 50 | } 51 | -------------------------------------------------------------------------------- /src/component/interfaces/MarkerConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | 3 | /** 4 | * Interface for configuration of marker component. 5 | * 6 | * @interface 7 | * @example 8 | * ```js 9 | * var viewer = new Viewer({ 10 | * ... 11 | * component: { 12 | * marker: { 13 | * visibleBBoxSize: 80, 14 | * }, 15 | * }, 16 | * ... 17 | * }); 18 | * ``` 19 | */ 20 | export interface MarkerConfiguration extends ComponentConfiguration { 21 | /** 22 | * The size of the bounding box for which markers will be visible. 23 | * 24 | * @description Provided values will be clamped to the [1, 200] 25 | * interval. 26 | * 27 | * @default 100 28 | */ 29 | visibleBBoxSize?: number; 30 | } 31 | -------------------------------------------------------------------------------- /src/component/interfaces/NavigationFallbackConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | 3 | /** 4 | * Interface for configuration of navigation component. 5 | * 6 | * @interface 7 | * @example 8 | * ```js 9 | * var viewer = new Viewer({ 10 | * ... 11 | * component: { 12 | * fallback: { 13 | * navigation: { 14 | * spatial: false, 15 | * }, 16 | * }, 17 | * }, 18 | * ... 19 | * }); 20 | * ``` 21 | */ 22 | export interface NavigationFallbackConfiguration 23 | extends ComponentConfiguration { 24 | /** 25 | * Enable or disable the sequence arrows. 26 | * 27 | * @default true 28 | */ 29 | sequence?: boolean; 30 | 31 | /** 32 | * Enable or disable the spatial arrows. 33 | * 34 | * @default true 35 | */ 36 | spatial?: boolean; 37 | } 38 | -------------------------------------------------------------------------------- /src/component/interfaces/PointerConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | 3 | /** 4 | * Interface for configuration of mouse component. 5 | * 6 | * @interface 7 | * @example 8 | * ```js 9 | * var viewer = new Viewer({ 10 | * ... 11 | * component: { 12 | * pointer: { 13 | * dragPan: false, 14 | * scrollZoom: false, 15 | * touchZoom: false, 16 | * }, 17 | * }, 18 | * ... 19 | * }); 20 | * ``` 21 | */ 22 | export interface PointerConfiguration extends ComponentConfiguration { 23 | /** 24 | * Activate or deactivate the `DragPanHandler`. 25 | * 26 | * @default true 27 | */ 28 | dragPan?: boolean; 29 | 30 | /** 31 | * Activate or deactivate the `EarthControlHandler`. 32 | * 33 | * @default true 34 | */ 35 | earthControl?: boolean; 36 | 37 | /** 38 | * Activate or deactivate the `ScrollZoomHandler`. 39 | * 40 | * @default true 41 | */ 42 | scrollZoom?: boolean; 43 | 44 | /** 45 | * Activate or deactivate the `TouchZoomHandler`. 46 | * 47 | * @default true 48 | */ 49 | touchZoom?: boolean; 50 | } 51 | -------------------------------------------------------------------------------- /src/component/interfaces/Shader.ts: -------------------------------------------------------------------------------- 1 | export interface Shader { 2 | fragment: string; 3 | vertex: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/component/interfaces/TagConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | import { TagMode } from "../tag/TagMode"; 3 | 4 | /** 5 | * Interface for configuration of tag component. 6 | * 7 | * @interface 8 | * @example 9 | * ```js 10 | * var viewer = new Viewer({ 11 | * ... 12 | * component: { 13 | * tag: { 14 | * createColor: 0xFF0000, 15 | * mode: TagMode.CreateRect, 16 | * }, 17 | * }, 18 | * ... 19 | * }); 20 | * ``` 21 | */ 22 | export interface TagConfiguration extends ComponentConfiguration { 23 | /** 24 | * The color of vertices and edges for tags that 25 | * are being created. 26 | * 27 | * @default 0xFFFFFF 28 | */ 29 | createColor?: number; 30 | 31 | /** 32 | * Show an indicator at the centroid of the points geometry 33 | * that creates the geometry when clicked. 34 | * @default true 35 | */ 36 | indicatePointsCompleter?: boolean; 37 | 38 | /** 39 | * The interaction mode of the tag component. 40 | * 41 | * @default TagMode.Default 42 | */ 43 | mode?: TagMode; 44 | } 45 | -------------------------------------------------------------------------------- /src/component/interfaces/ZoomConfiguration.ts: -------------------------------------------------------------------------------- 1 | import { ComponentConfiguration } from "./ComponentConfiguration"; 2 | import { ComponentSize } from "../util/ComponentSize"; 3 | 4 | export interface ZoomConfiguration extends ComponentConfiguration { 5 | /** 6 | * The size of the ui elements. 7 | * 8 | * @default ComponentSize.Automatic 9 | */ 10 | size?: ComponentSize; 11 | } 12 | -------------------------------------------------------------------------------- /src/component/marker/interfaces/CircleMarkerOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface CircleMarkerOptions 3 | * 4 | * Interface that represents the options for configuring a `CircleMarker`. 5 | */ 6 | export interface CircleMarkerOptions { 7 | /** 8 | * The color of the marker. 9 | * 10 | * @default "#fff" 11 | */ 12 | color?: number | string; 13 | 14 | /** 15 | * The opacity of the marker. 16 | * 17 | * @default 0.4 18 | */ 19 | opacity?: number; 20 | 21 | /** 22 | * The radius of the circle in meters. 23 | * 24 | * @default 1 25 | */ 26 | radius?: number; 27 | } 28 | -------------------------------------------------------------------------------- /src/component/pointer/HandlerTypes.ts: -------------------------------------------------------------------------------- 1 | /** @ignore */ 2 | export type MouseTouchPair = [MouseEvent, MouseEvent] | [Touch, Touch]; 3 | 4 | /** @ignore */ 5 | export type ClientTouch = { 6 | clientX: number; 7 | clientY: number; 8 | shiftKey: boolean; 9 | }; 10 | -------------------------------------------------------------------------------- /src/component/popup/interfaces/PopupOffset.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for the popup offset with respect to its anchor point. 3 | * 4 | * @description An object of number arrays specifying an offset for 5 | * each float direction. Negative offsets indicate left and up. 6 | * 7 | * @interface 8 | * 9 | * @example 10 | * ```js 11 | * var offset = = { 12 | * bottom: [0, 10], 13 | * bottomLeft: [-10, 10], 14 | * bottomRight: [10, 10], 15 | * center: [0, 0], 16 | * left: [-10, 0], 17 | * right: [10, 0], 18 | * top: [0, -10], 19 | * topLeft: [-10, -10], 20 | * topRight: [10, -10], 21 | * } 22 | * 23 | * var popup = new Popup({ offset: offset }); 24 | * ``` 25 | */ 26 | export interface PopupOffset { 27 | bottom: number[]; 28 | bottomLeft: number[]; 29 | bottomRight: number[]; 30 | center: number[]; 31 | left: number[]; 32 | right: number[]; 33 | top: number[]; 34 | topLeft: number[]; 35 | topRight: number[]; 36 | } 37 | -------------------------------------------------------------------------------- /src/component/popup/popup/PopupAlignment.ts: -------------------------------------------------------------------------------- 1 | export type PopupAlignment = "center" | "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right"; 2 | -------------------------------------------------------------------------------- /src/component/sequence/SequenceMode.ts: -------------------------------------------------------------------------------- 1 | export enum SequenceMode { 2 | Default, 3 | Playback, 4 | Timeline, 5 | } 6 | -------------------------------------------------------------------------------- /src/component/slider/SliderInterfaces.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from "three"; 2 | import { Image } from "../../graph/Image"; 3 | import { IAnimationState } from "../../state/interfaces/IAnimationState"; 4 | import { SliderGLRenderer } from "./SliderGLRenderer"; 5 | export interface SliderImages { 6 | background: Image; 7 | foreground: Image; 8 | } 9 | export interface SliderCombination { 10 | images: SliderImages; 11 | state: IAnimationState; 12 | } 13 | export interface GLRendererOperation { 14 | (glRenderer: SliderGLRenderer): SliderGLRenderer; 15 | } 16 | export type PositionLookat = [ 17 | THREE.Vector3, 18 | THREE.Vector3, 19 | number, 20 | number, 21 | number, 22 | ]; 23 | -------------------------------------------------------------------------------- /src/component/slider/interfaces/SliderBBoxProjectorShaderMaterial.ts: -------------------------------------------------------------------------------- 1 | export interface SliderBBoxProjectorShaderMaterial extends THREE.ShaderMaterial { 2 | uniforms: { 3 | [uniform: string]: THREE.IUniform; 4 | opacity: THREE.IUniform; 5 | projectorTex: THREE.IUniform; 6 | bbox: THREE.IUniform; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /src/component/slider/shaders/fisheye.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const fisheyeFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | 8 | uniform sampler2D projectorTex; 9 | uniform float opacity; 10 | uniform float focal; 11 | uniform float k1; 12 | uniform float k2; 13 | uniform float scale_x; 14 | uniform float scale_y; 15 | uniform float radial_peak; 16 | 17 | varying vec4 vRstq; 18 | 19 | void main() 20 | { 21 | float x = vRstq.x; 22 | float y = vRstq.y; 23 | float z = vRstq.z; 24 | 25 | float r = sqrt(x * x + y * y); 26 | float theta = atan(r, z); 27 | 28 | if (radial_peak > 0. && theta > radial_peak) { 29 | theta = radial_peak; 30 | } 31 | 32 | float theta2 = theta * theta; 33 | float theta_d = theta * (1.0 + theta2 * (k1 + theta2 * k2)); 34 | float s = focal * theta_d / r; 35 | 36 | float u = scale_x * s * x + 0.5; 37 | float v = -scale_y * s * y + 0.5; 38 | 39 | vec4 baseColor; 40 | if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) { 41 | baseColor = texture2D(projectorTex, vec2(u, v)); 42 | baseColor.a = opacity; 43 | } else { 44 | baseColor = vec4(0.0, 0.0, 0.0, 0.0); 45 | } 46 | 47 | gl_FragColor = baseColor; 48 | } 49 | ` 50 | -------------------------------------------------------------------------------- /src/component/slider/shaders/fisheye.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const fisheyeVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | 6 | uniform mat4 projectorMat; 7 | 8 | varying vec4 vRstq; 9 | 10 | void main() 11 | { 12 | vRstq = projectorMat * vec4(position, 1.0); 13 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 14 | } 15 | ` 16 | -------------------------------------------------------------------------------- /src/component/slider/shaders/fisheye_curtain.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const fisheyeCurtainVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | uniform mat4 projectorMat; 6 | varying vec4 vRstq; 7 | void main() 8 | { 9 | vRstq = projectorMat * vec4(position, 1.0); 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 11 | } 12 | ` 13 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | 8 | uniform sampler2D projectorTex; 9 | uniform float opacity; 10 | uniform float focal; 11 | uniform float k1; 12 | uniform float k2; 13 | uniform float scale_x; 14 | uniform float scale_y; 15 | uniform float radial_peak; 16 | 17 | varying vec4 vRstq; 18 | 19 | void main() 20 | { 21 | float x = vRstq.x / vRstq.z; 22 | float y = vRstq.y / vRstq.z; 23 | float r2 = x * x + y * y; 24 | 25 | if (radial_peak > 0. && r2 > radial_peak * sqrt(r2)) { 26 | r2 = radial_peak * radial_peak; 27 | } 28 | 29 | float d = 1.0 + k1 * r2 + k2 * r2 * r2; 30 | float u = scale_x * focal * d * x + 0.5; 31 | float v = - scale_y * focal * d * y + 0.5; 32 | 33 | vec4 baseColor; 34 | if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) { 35 | baseColor = texture2D(projectorTex, vec2(u, v)); 36 | baseColor.a = opacity; 37 | } else { 38 | baseColor = vec4(0.0, 0.0, 0.0, 0.0); 39 | } 40 | 41 | gl_FragColor = baseColor; 42 | } 43 | ` 44 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | 6 | uniform mat4 projectorMat; 7 | 8 | varying vec4 vRstq; 9 | 10 | void main() 11 | { 12 | vRstq = projectorMat * vec4(position, 1.0); 13 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 14 | } 15 | ` 16 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective_curtain.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveCurtainFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | uniform sampler2D projectorTex; 8 | uniform float opacity; 9 | uniform float focal; 10 | uniform float k1; 11 | uniform float k2; 12 | uniform float scale_x; 13 | uniform float scale_y; 14 | uniform float radial_peak; 15 | uniform float curtain; 16 | varying vec4 vRstq; 17 | void main() 18 | { 19 | float x = vRstq.x / vRstq.z; 20 | float y = vRstq.y / vRstq.z; 21 | float r2 = x * x + y * y; 22 | if (radial_peak > 0. && r2 > radial_peak * sqrt(r2)) { 23 | r2 = radial_peak * radial_peak; 24 | } 25 | float d = 1.0 + k1 * r2 + k2 * r2 * r2; 26 | float u = scale_x * focal * d * x + 0.5; 27 | float v = - scale_y * focal * d * y + 0.5; 28 | vec4 baseColor; 29 | if ((u < curtain || curtain >= 1.0) && u >= 0. && u <= 1. && v >= 0. && v <= 1.) { 30 | baseColor = texture2D(projectorTex, vec2(u, v)); 31 | baseColor.a = opacity; 32 | } else { 33 | baseColor = vec4(0.0, 0.0, 0.0, 0.0); 34 | } 35 | gl_FragColor = baseColor; 36 | } 37 | ` 38 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective_curtain.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveCurtainVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | uniform mat4 projectorMat; 6 | varying vec4 vRstq; 7 | void main() 8 | { 9 | vRstq = projectorMat * vec4(position, 1.0); 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 11 | } 12 | ` 13 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective_distorted.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveDistortedFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | uniform sampler2D projectorTex; 8 | uniform float opacity; 9 | varying vec4 vRstq; 10 | void main() 11 | { 12 | float u = vRstq.x / vRstq.w; 13 | float v = vRstq.y / vRstq.w; 14 | vec4 baseColor; 15 | if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) { 16 | baseColor = texture2D(projectorTex, vec2(u, v)); 17 | baseColor.a = opacity; 18 | } else { 19 | baseColor = vec4(0.0, 0.0, 0.0, 0.0); 20 | } 21 | gl_FragColor = baseColor; 22 | } 23 | ` 24 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective_distorted.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveDistortedVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | uniform mat4 projectorMat; 6 | varying vec4 vRstq; 7 | void main() 8 | { 9 | vRstq = projectorMat * vec4(position, 1.0); 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 11 | } 12 | ` 13 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective_distorted_curtain.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveDistortedCurtainFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | uniform sampler2D projectorTex; 8 | uniform float opacity; 9 | uniform float curtain; 10 | varying vec4 vRstq; 11 | void main() 12 | { 13 | float u = vRstq.x / vRstq.w; 14 | float v = vRstq.y / vRstq.w; 15 | vec4 baseColor; 16 | if ((u < curtain || curtain >= 1.0) && u >= 0. && u <= 1. && v >= 0. && v <= 1.) { 17 | baseColor = texture2D(projectorTex, vec2(u, v)); 18 | baseColor.a = opacity; 19 | } else { 20 | baseColor = vec4(0.0, 0.0, 0.0, 0.0); 21 | } 22 | gl_FragColor = baseColor; 23 | } 24 | ` 25 | -------------------------------------------------------------------------------- /src/component/slider/shaders/perspective_distorted_curtain.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const perspectiveDistortedCurtainVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | uniform mat4 projectorMat; 6 | varying vec4 vRstq; 7 | void main() 8 | { 9 | vRstq = projectorMat * vec4(position, 1.0); 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 11 | } 12 | ` 13 | -------------------------------------------------------------------------------- /src/component/slider/shaders/spherical.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const sphericalFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | 8 | #define tau 6.28318530718 9 | 10 | uniform sampler2D projectorTex; 11 | uniform float opacity; 12 | 13 | varying vec4 vRstq; 14 | 15 | void main() 16 | { 17 | vec3 b = normalize(vRstq.xyz); 18 | float lat = -asin(b.y); 19 | float lng = atan(b.x, b.z); 20 | float x = lng / tau + 0.5; 21 | float y = lat / tau * 2.0 + 0.5; 22 | vec4 baseColor = texture2D(projectorTex, vec2(x, y)); 23 | baseColor.a = opacity; 24 | gl_FragColor = baseColor; 25 | } 26 | ` 27 | -------------------------------------------------------------------------------- /src/component/slider/shaders/spherical.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const sphericalVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | 6 | uniform mat4 projectorMat; 7 | 8 | varying vec4 vRstq; 9 | 10 | void main() 11 | { 12 | vRstq = projectorMat * vec4(position, 1.0); 13 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 14 | } 15 | ` 16 | -------------------------------------------------------------------------------- /src/component/slider/shaders/spherical_curtain.fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export const sphericalCurtainFrag = ` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #define tau 6.28318530718 8 | uniform sampler2D projectorTex; 9 | uniform float curtain; 10 | uniform float opacity; 11 | varying vec4 vRstq; 12 | void main() 13 | { 14 | vec3 b = normalize(vRstq.xyz); 15 | float lat = -asin(b.y); 16 | float lng = atan(b.x, b.z); 17 | float x = lng / tau + 0.5; 18 | float y = lat / tau * 2.0 + 0.5; 19 | bool inverted = curtain < 0.5; 20 | float curtainMin = inverted ? curtain + 0.5 : curtain - 0.5; 21 | float curtainMax = curtain; 22 | bool insideCurtain = inverted ? 23 | x > curtainMin || x < curtainMax : 24 | x > curtainMin && x < curtainMax; 25 | vec4 baseColor; 26 | if (insideCurtain) { 27 | baseColor = texture2D(projectorTex, vec2(x, y)); 28 | baseColor.a = opacity; 29 | } else { 30 | baseColor = vec4(0.0, 0.0, 0.0, 0.0); 31 | } 32 | gl_FragColor = baseColor; 33 | } 34 | ` 35 | -------------------------------------------------------------------------------- /src/component/slider/shaders/spherical_curtain.vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export const sphericalCurtainVert = ` 2 | #ifdef GL_ES 3 | precision highp float; 4 | #endif 5 | uniform mat4 projectorMat; 6 | varying vec4 vRstq; 7 | void main() 8 | { 9 | vRstq = projectorMat * vec4(position, 1.0); 10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 11 | } 12 | ` 13 | -------------------------------------------------------------------------------- /src/component/spatial/Modes.ts: -------------------------------------------------------------------------------- 1 | import { State } from "../../state/State"; 2 | import { CameraVisualizationMode } from "./enums/CameraVisualizationMode"; 3 | 4 | export function isModeVisible(mode: CameraVisualizationMode): boolean { 5 | return mode !== CameraVisualizationMode.Hidden; 6 | } 7 | 8 | export function isOverviewState(state: State): boolean { 9 | return state === State.Custom || state === State.Earth; 10 | } 11 | -------------------------------------------------------------------------------- /src/component/spatial/SpatialCommon.ts: -------------------------------------------------------------------------------- 1 | import { LngLatAlt } from "../../api/interfaces/LngLatAlt"; 2 | import { enuToGeodetic, geodeticToEnu } from "../../geo/GeoCoords"; 3 | 4 | export const SPATIAL_DEFAULT_COLOR = 0xFFFFFF; 5 | 6 | export function resetEnu(reference: LngLatAlt, prevEnu: number[], prevReference: LngLatAlt): number[] { 7 | const [prevX, prevY, prevZ] = prevEnu; 8 | const [lng, lat, alt] = enuToGeodetic( 9 | prevX, 10 | prevY, 11 | prevZ, 12 | prevReference.lng, 13 | prevReference.lat, 14 | prevReference.alt); 15 | 16 | return geodeticToEnu( 17 | lng, 18 | lat, 19 | alt, 20 | reference.lng, 21 | reference.lat, 22 | reference.alt); 23 | } 24 | -------------------------------------------------------------------------------- /src/component/spatial/enums/CameraVisualizationMode.ts: -------------------------------------------------------------------------------- 1 | export enum CameraVisualizationMode { 2 | /** 3 | * Cameras are hidden. 4 | */ 5 | Hidden, 6 | 7 | /** 8 | * Cameras are shown, all with the same color. 9 | */ 10 | Homogeneous, 11 | 12 | /** 13 | * Cameras are shown with colors based on the 14 | * their clusters. 15 | */ 16 | Cluster, 17 | 18 | /** 19 | * Cameras are shown with colors based on the 20 | * their connected components. 21 | */ 22 | ConnectedComponent, 23 | 24 | /** 25 | * Cameras are shown, with colors based on the 26 | * their sequence. 27 | */ 28 | Sequence, 29 | } 30 | -------------------------------------------------------------------------------- /src/component/spatial/enums/OriginalPositionMode.ts: -------------------------------------------------------------------------------- 1 | export enum OriginalPositionMode { 2 | /** 3 | * Original positions are hidden. 4 | */ 5 | Hidden, 6 | 7 | /** 8 | * Visualize original positions with altitude change. 9 | */ 10 | Altitude, 11 | 12 | /** 13 | * Visualize original positions without altitude change, 14 | * i.e. as flat lines from the camera origin. 15 | */ 16 | Flat, 17 | } 18 | -------------------------------------------------------------------------------- /src/component/spatial/enums/PointVisualizationMode.ts: -------------------------------------------------------------------------------- 1 | export enum PointVisualizationMode { 2 | /** 3 | * Points are hidden. 4 | */ 5 | Hidden, 6 | 7 | /** 8 | * Visualize points with original colors. 9 | */ 10 | Original, 11 | 12 | /** 13 | * Paint all points belonging to a specific 14 | * cluster with the same random color. 15 | */ 16 | Cluster, 17 | } 18 | -------------------------------------------------------------------------------- /src/component/spatial/scene/SpatialAssets.ts: -------------------------------------------------------------------------------- 1 | import { CameraVisualizationMode } from "../enums/CameraVisualizationMode"; 2 | 3 | export class SpatialAssets { 4 | private readonly _colors: Map; 5 | 6 | constructor() { 7 | this._colors = new Map(); 8 | const cvm = CameraVisualizationMode; 9 | this._colors.set(cvm[cvm.Homogeneous], "#FFFFFF"); 10 | } 11 | 12 | public getColor(id: string): number | string { 13 | const colors = this._colors; 14 | if (!colors.has(id)) { 15 | colors.set(id, this._randomColor()); 16 | } 17 | return colors.get(id); 18 | } 19 | 20 | private _randomColor(): number | string { 21 | return `hsl(${Math.floor(360 * Math.random())}, 100%, 60%)`; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/component/spatial/scene/SpatialOctreeMath.ts: -------------------------------------------------------------------------------- 1 | // Level 0: 1 x 1 x 1 meter cubes 2 | export const OCTREE_ROOT_LEVEL = 14; // 16384 meters 3 | export const OCTREE_LEAF_LEVEL = 6; // 64 meters 4 | 5 | export function isLeafLevel(level: number, leafLevel: number): boolean { 6 | return level === leafLevel; 7 | } 8 | 9 | export function levelToSize(level: number): number { 10 | return 2 ** level; 11 | } 12 | 13 | export interface OctreeBoundingBox { 14 | min: number[]; 15 | max: number[]; 16 | } 17 | 18 | export function levelToRootBoundingBox(level: number): OctreeBoundingBox { 19 | const size = levelToSize(level); 20 | const half = size / 2; 21 | const min = [-half, -half, -half]; 22 | const max = [half, half, half]; 23 | return { min, max }; 24 | } 25 | -------------------------------------------------------------------------------- /src/component/tag/TagDOMRenderer.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from "three"; 2 | import * as vd from "virtual-dom"; 3 | 4 | import { Geometry } from "./geometry/Geometry"; 5 | import { CreateTag } from "./tag/CreateTag"; 6 | import { RenderTag } from "./tag/RenderTag"; 7 | import { Tag } from "./tag/Tag"; 8 | 9 | import { ViewportSize } from "../../render/interfaces/ViewportSize"; 10 | import { ISpriteAtlas } from "../../viewer/interfaces/ISpriteAtlas"; 11 | 12 | export class TagDOMRenderer { 13 | public render( 14 | tags: RenderTag[], 15 | createTag: CreateTag, 16 | atlas: ISpriteAtlas, 17 | camera: THREE.PerspectiveCamera, 18 | size: ViewportSize): vd.VNode { 19 | 20 | let vNodes: vd.VNode[] = []; 21 | 22 | for (const tag of tags) { 23 | vNodes = vNodes.concat(tag.getDOMObjects(atlas, camera, size)); 24 | } 25 | 26 | if (createTag != null) { 27 | vNodes = vNodes.concat(createTag.getDOMObjects(camera, size)); 28 | } 29 | 30 | return vd.h("div.mapillary-tag-container", {}, vNodes); 31 | } 32 | 33 | public clear(): vd.VNode { 34 | return vd.h("div", {}, []); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/component/tag/TagMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for tag modes 3 | * @enum {number} 4 | * @readonly 5 | * @description Modes for the interaction in the tag component. 6 | */ 7 | export enum TagMode { 8 | /** 9 | * Disables creating tags. 10 | */ 11 | Default, 12 | 13 | /** 14 | * Create a point geometry through a click. 15 | */ 16 | CreatePoint, 17 | 18 | /** 19 | * Create a points geometry through clicks. 20 | */ 21 | CreatePoints, 22 | 23 | /** 24 | * Create a polygon geometry through clicks. 25 | */ 26 | CreatePolygon, 27 | 28 | /** 29 | * Create a rect geometry through clicks. 30 | */ 31 | CreateRect, 32 | 33 | /** 34 | * Create a rect geometry through drag. 35 | * 36 | * @description Claims the mouse which results in mouse handlers like 37 | * drag pan and scroll zoom becoming inactive. 38 | */ 39 | CreateRectDrag, 40 | } 41 | -------------------------------------------------------------------------------- /src/component/tag/TagOperation.ts: -------------------------------------------------------------------------------- 1 | export enum TagOperation { 2 | None, 3 | Centroid, 4 | Vertex, 5 | } 6 | -------------------------------------------------------------------------------- /src/component/tag/error/GeometryTagError.ts: -------------------------------------------------------------------------------- 1 | import { MapillaryError } from "../../../error/MapillaryError"; 2 | 3 | export class GeometryTagError extends MapillaryError { 4 | constructor(message?: string) { 5 | super(message != null ? message : "The provided geometry value is incorrect"); 6 | 7 | Object.setPrototypeOf(this, GeometryTagError.prototype); 8 | 9 | this.name = "GeometryTagError"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/component/tag/handlers/CreatePointHandler.ts: -------------------------------------------------------------------------------- 1 | import { 2 | map, 3 | filter, 4 | } from "rxjs/operators"; 5 | import { Subscription } from "rxjs"; 6 | import { PointGeometry } from "../geometry/PointGeometry"; 7 | import { CreateHandlerBase } from "./CreateHandlerBase"; 8 | 9 | export class CreatePointHandler extends CreateHandlerBase { 10 | private _geometryCreatedSubscription: Subscription; 11 | 12 | protected _enableCreate(): void { 13 | this._container.mouseService.deferPixels(this._name, 4); 14 | 15 | this._geometryCreatedSubscription = this._mouseEventToBasic$(this._container.mouseService.proximateClick$).pipe( 16 | filter(this._validateBasic), 17 | map( 18 | (basic: number[]): PointGeometry => { 19 | return new PointGeometry(basic); 20 | })) 21 | .subscribe(this._geometryCreated$); 22 | } 23 | 24 | protected _disableCreate(): void { 25 | this._container.mouseService.undeferPixels(this._name); 26 | 27 | this._geometryCreatedSubscription.unsubscribe(); 28 | } 29 | 30 | protected _getNameExtension(): string { 31 | return "create-point"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/component/tag/handlers/CreatePointsHandler.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { Transform } from "../../../geo/Transform"; 3 | import { ExtremePointCreateTag } from "../tag/ExtremePointCreateTag"; 4 | import { CreateVertexHandler } from "./CreateVertexHandler"; 5 | 6 | export class CreatePointsHandler extends CreateVertexHandler { 7 | protected get _create$(): Subject { 8 | return this._tagCreator.createPoints$; 9 | } 10 | 11 | protected _addPoint(tag: ExtremePointCreateTag, basicPoint: number[]): void { 12 | tag.geometry.addPoint2d(basicPoint); 13 | } 14 | 15 | protected _getNameExtension(): string { 16 | return "create-points"; 17 | } 18 | 19 | protected _setVertex2d(tag: ExtremePointCreateTag, basicPoint: number[], transform: Transform): void { 20 | tag.geometry.setPoint2d((tag.geometry).points.length - 1, basicPoint, transform); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/component/tag/handlers/CreatePolygonHandler.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { Transform } from "../../../geo/Transform"; 3 | import { PolygonGeometry } from "../geometry/PolygonGeometry"; 4 | import { OutlineCreateTag } from "../tag/OutlineCreateTag"; 5 | import { CreateVertexHandler } from "./CreateVertexHandler"; 6 | 7 | export class CreatePolygonHandler extends CreateVertexHandler { 8 | protected get _create$(): Subject { 9 | return this._tagCreator.createPolygon$; 10 | } 11 | 12 | protected _addPoint(tag: OutlineCreateTag, basicPoint: number[]): void { 13 | tag.addPoint(basicPoint); 14 | } 15 | 16 | protected _getNameExtension(): string { 17 | return "create-polygon"; 18 | } 19 | 20 | protected _setVertex2d(tag: OutlineCreateTag, basicPoint: number[], transform: Transform): void { 21 | tag.geometry.setVertex2d((tag.geometry).polygon.length - 2, basicPoint, transform); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/component/tag/interfaces/ExtremePointCreateTagOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for the options that define the behavior and 3 | * appearance of the extreme point create tag. 4 | * 5 | * @interface 6 | */ 7 | export interface ExtremePointCreateTagOptions { 8 | /** 9 | * Text color as hexadecimal number. 10 | * @default 0xFFFFFF 11 | */ 12 | color?: number; 13 | 14 | /** 15 | * Show an indicator at the centroid of the extreme 16 | * point tag rectrangle that creates the geometry when 17 | * clicked. 18 | * @default true 19 | */ 20 | indicateCompleter?: boolean; 21 | } 22 | -------------------------------------------------------------------------------- /src/component/tag/interfaces/OutlineCreateTagOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for the options that define the behavior and 3 | * appearance of the outline create tag. 4 | * 5 | * @interface 6 | */ 7 | export interface OutlineCreateTagOptions { 8 | /** 9 | * Text color as hexadecimal number. 10 | * @default 0xFFFFFF 11 | */ 12 | color?: number; 13 | } 14 | -------------------------------------------------------------------------------- /src/component/tag/interfaces/SpotTagOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for the options that define the behavior and 3 | * appearance of the spot tag. 4 | * 5 | * @interface 6 | */ 7 | export interface SpotTagOptions { 8 | /** 9 | * Color for the spot specified as a hexadecimal number. 10 | * @default 0xFFFFFF 11 | */ 12 | color?: number; 13 | 14 | /** 15 | * Indicate whether the tag geometry should be editable. 16 | * @default false 17 | */ 18 | editable?: boolean; 19 | 20 | /** 21 | * A string referencing the sprite data property to pull from. 22 | */ 23 | icon?: string; 24 | 25 | /** 26 | * Text shown as label if no icon is provided. 27 | */ 28 | text?: string; 29 | 30 | /** 31 | * Text color as hexadecimal number. 32 | * @default 0xFFFFFF 33 | */ 34 | textColor?: number; 35 | } 36 | -------------------------------------------------------------------------------- /src/component/tag/interfaces/TagInteraction.ts: -------------------------------------------------------------------------------- 1 | import { Tag } from "../tag/Tag"; 2 | import { TagOperation } from "../TagOperation"; 3 | 4 | export type InteractionCursor = "crosshair" | "move" | "nesw-resize" | "nwse-resize"; 5 | 6 | export interface TagInteraction { 7 | cursor?: InteractionCursor; 8 | offsetX: number; 9 | offsetY: number; 10 | operation: TagOperation; 11 | tag: Tag; 12 | vertexIndex?: number; 13 | } 14 | -------------------------------------------------------------------------------- /src/component/tag/tag/TagDomain.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for tag domains. 3 | * @enum {number} 4 | * @readonly 5 | * @description Defines where lines between two vertices are treated 6 | * as straight. 7 | * 8 | * Only applicable for polygons. For rectangles lines between 9 | * vertices are always treated as straight in the distorted 2D 10 | * projection and bended in the undistorted 3D space. 11 | */ 12 | export enum TagDomain { 13 | /** 14 | * Treats lines between two vertices as straight in the 15 | * distorted 2D projection, i.e. on the image. If the image 16 | * is distorted this will result in bended lines when rendered 17 | * in the undistorted 3D space. 18 | */ 19 | TwoDimensional, 20 | 21 | /** 22 | * Treats lines as straight in the undistorted 3D space. If the 23 | * image is distorted this will result in bended lines when rendered 24 | * on the distorted 2D projection of the image. 25 | */ 26 | ThreeDimensional, 27 | } 28 | -------------------------------------------------------------------------------- /src/component/tag/tag/events/TagEventType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @event 3 | */ 4 | export type TagEventType = 5 | | "click" 6 | | "geometry" 7 | | "tag"; 8 | -------------------------------------------------------------------------------- /src/component/tag/tag/events/TagStateEvent.ts: -------------------------------------------------------------------------------- 1 | import { Tag } from "../Tag"; 2 | import { TagEventType } from "./TagEventType"; 3 | 4 | /** 5 | * Interface for tag state events. 6 | * 7 | * @example 8 | * ```js 9 | * var tag = new OutlineTag({ // tag options }); 10 | * // Set an event listener 11 | * tag.on('tag', function() { 12 | * console.log("A tag event has occurred."); 13 | * }); 14 | * ``` 15 | */ 16 | export interface TagStateEvent { 17 | /** 18 | * The component object that fired the event. 19 | */ 20 | target: Tag; 21 | 22 | /** 23 | * The event type. 24 | */ 25 | type: TagEventType; 26 | } 27 | -------------------------------------------------------------------------------- /src/component/util/ComponentSize.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for component size. 3 | * @enum {number} 4 | * @readonly 5 | * @description May be used by a component to allow for resizing 6 | * of the UI elements rendered by the component. 7 | */ 8 | export enum ComponentSize { 9 | /** 10 | * Automatic size. The size of the elements will automatically 11 | * change at a predefined threshold. 12 | */ 13 | Automatic, 14 | 15 | /** 16 | * Large size. The size of the elements will be fixed until another 17 | * component size is configured. 18 | */ 19 | Large, 20 | 21 | /** 22 | * Small size. The size of the elements will be fixed until another 23 | * component size is configured. 24 | */ 25 | Small, 26 | } 27 | -------------------------------------------------------------------------------- /src/error/ArgumentMapillaryError.ts: -------------------------------------------------------------------------------- 1 | import { MapillaryError } from "./MapillaryError"; 2 | 3 | export class ArgumentMapillaryError extends MapillaryError { 4 | constructor(message?: string) { 5 | super(message != null ? message : "The argument is not valid."); 6 | 7 | Object.setPrototypeOf(this, ArgumentMapillaryError.prototype); 8 | 9 | this.name = "ArgumentMapillaryError"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/error/CancelMapillaryError.ts: -------------------------------------------------------------------------------- 1 | import { MapillaryError } from "./MapillaryError"; 2 | 3 | /** 4 | * @class CancelMapillaryError 5 | * 6 | * @classdesc Error thrown when a move to request has been 7 | * cancelled before completing because of a subsequent request. 8 | */ 9 | export class CancelMapillaryError extends MapillaryError { 10 | constructor(message?: string) { 11 | super(message != null ? message : "The request was cancelled."); 12 | 13 | Object.setPrototypeOf(this, CancelMapillaryError.prototype); 14 | 15 | this.name = "CancelMapillaryError"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/error/GraphMapillaryError.ts: -------------------------------------------------------------------------------- 1 | import { MapillaryError } from "./MapillaryError"; 2 | 3 | export class GraphMapillaryError extends MapillaryError { 4 | constructor(message: string) { 5 | super(message); 6 | 7 | Object.setPrototypeOf(this, GraphMapillaryError.prototype); 8 | 9 | this.name = "GraphMapillaryError"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/error/MapillaryError.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @class MapillaryError 3 | * 4 | * @classdesc Generic Mapillary error. 5 | */ 6 | export class MapillaryError extends Error { 7 | constructor(message?: string) { 8 | super(message); 9 | 10 | Object.setPrototypeOf(this, MapillaryError.prototype); 11 | 12 | this.name = "MapillaryError"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/geo/GeoRBush.ts: -------------------------------------------------------------------------------- 1 | import { BBox } from "rbush"; 2 | import RBush from "rbush"; 3 | 4 | import { LngLat } from "../api/interfaces/LngLat"; 5 | 6 | export class GeoRBush extends RBush { 7 | public compareMinX(a: T, b: T): number { 8 | return a.lng - b.lng; 9 | } 10 | 11 | public compareMinY(a: T, b: T): number { 12 | return a.lat - b.lat; 13 | } 14 | 15 | public toBBox(item: T): BBox { 16 | return { 17 | minX: item.lng, 18 | minY: item.lat, 19 | maxX: item.lng, 20 | maxY: item.lat, 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/geo/interfaces/CameraType.ts: -------------------------------------------------------------------------------- 1 | export type CameraType = 2 | "spherical" | 3 | "fisheye" | 4 | "perspective"; 5 | -------------------------------------------------------------------------------- /src/geometry/Camera.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CameraParameters, 3 | CameraUniforms, 4 | ICamera, 5 | } from "./interfaces/ICamera"; 6 | 7 | export abstract class Camera implements ICamera { 8 | public readonly parameters: CameraParameters = {}; 9 | public readonly uniforms: CameraUniforms = {}; 10 | 11 | constructor( 12 | public readonly type: string, 13 | public readonly projectToSfmFunction: string) { } 14 | 15 | public abstract bearingFromSfm(_point: number[]): number[]; 16 | public abstract projectToSfm(_point: number[]): number[]; 17 | } 18 | -------------------------------------------------------------------------------- /src/geometry/Constants.ts: -------------------------------------------------------------------------------- 1 | export const EPSILON = 1e-8; 2 | -------------------------------------------------------------------------------- /src/geometry/interfaces/ICamera.ts: -------------------------------------------------------------------------------- 1 | export type CameraParameters = { [key: string]: number; }; 2 | 3 | export type CameraUniforms = { [key: string]: boolean | number | number[]; }; 4 | 5 | /** 6 | * @interface 7 | * 8 | * @description Interface for cameras. This is a 9 | * specification for implementers to model: it is not 10 | * an exported method or class. 11 | * 12 | * Implmenting a custom camera allows the implementer to 13 | * render textures and camera frustums with proper undistortion. 14 | * 15 | * Custom cameras must have a unique type. 16 | */ 17 | export interface ICamera { 18 | readonly type: string; 19 | 20 | readonly parameters: CameraParameters; 21 | readonly uniforms: CameraUniforms; 22 | 23 | readonly projectToSfmFunction: string; 24 | 25 | bearingFromSfm(point: number[]): number[]; 26 | projectToSfm(bearing: number[]): number[]; 27 | } 28 | 29 | export interface CameraConstructor { 30 | new(parameters: number[]): ICamera; 31 | }; 32 | -------------------------------------------------------------------------------- /src/geometry/interfaces/ICameraFactory.ts: -------------------------------------------------------------------------------- 1 | import { ICamera } from "./ICamera"; 2 | 3 | export interface ICameraFactory { 4 | makeCamera(type: string, parameters: number[]): ICamera; 5 | } 6 | -------------------------------------------------------------------------------- /src/graph/GraphMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for graph modes. 3 | * @enum {number} 4 | * @readonly 5 | * @description Modes for the retrieval and caching performed 6 | * by the graph service on the graph. 7 | */ 8 | export enum GraphMode { 9 | /** 10 | * Caching is performed on sequences only and sequence edges are 11 | * calculated. Spatial tiles 12 | * are not retrieved and spatial edges are not calculated when 13 | * caching nodes. Complete sequences are being cached for requested 14 | * nodes within the graph. 15 | */ 16 | Sequence, 17 | 18 | /** 19 | * Caching is performed with emphasis on spatial data. Sequence edges 20 | * as well as spatial edges are cached. Sequence data 21 | * is still requested but complete sequences are not being cached 22 | * for requested nodes. 23 | * 24 | * This is the initial mode of the graph service. 25 | */ 26 | Spatial, 27 | } 28 | -------------------------------------------------------------------------------- /src/graph/edge/interfaces/NavigationEdge.ts: -------------------------------------------------------------------------------- 1 | import { NavigationEdgeData } from "./NavigationEdgeData"; 2 | 3 | /** 4 | * Interface that describes the properties for a 5 | * navigation edge from a source image to a 6 | * target image. 7 | * 8 | * @interface NavigationEdge 9 | */ 10 | export interface NavigationEdge { 11 | /** 12 | * The id of the source image. 13 | */ 14 | source: string; 15 | 16 | /** 17 | * The id of the target image. 18 | */ 19 | target: string; 20 | 21 | /** 22 | * Additional data describing properties of the edge. 23 | */ 24 | data: NavigationEdgeData; 25 | } 26 | -------------------------------------------------------------------------------- /src/graph/edge/interfaces/NavigationEdgeData.ts: -------------------------------------------------------------------------------- 1 | import { NavigationDirection } from "../NavigationDirection"; 2 | 3 | /** 4 | * Interface that describes additional properties of an edge. 5 | * 6 | * @interface NavigationEdgeData 7 | */ 8 | export interface NavigationEdgeData { 9 | /** 10 | * The edge direction. 11 | */ 12 | direction: NavigationDirection; 13 | 14 | /** 15 | * The counter clockwise horizontal rotation angle from 16 | * the X-axis in a spherical coordiante system of the 17 | * motion from the source image to the destination node. 18 | */ 19 | worldMotionAzimuth: number; 20 | } 21 | -------------------------------------------------------------------------------- /src/graph/edge/interfaces/SphericalDirection.ts: -------------------------------------------------------------------------------- 1 | import { NavigationDirection } from "../NavigationDirection"; 2 | 3 | export interface SphericalDirection { 4 | direction: NavigationDirection; 5 | prev: NavigationDirection; 6 | next: NavigationDirection; 7 | directionChange: number; 8 | } 9 | -------------------------------------------------------------------------------- /src/graph/edge/interfaces/StepDirection.ts: -------------------------------------------------------------------------------- 1 | import { NavigationDirection } from "../NavigationDirection"; 2 | 3 | export interface StepDirection { 4 | direction: NavigationDirection; 5 | motionChange: number; 6 | useFallback: boolean; 7 | } 8 | -------------------------------------------------------------------------------- /src/graph/edge/interfaces/TurnDirection.ts: -------------------------------------------------------------------------------- 1 | import { NavigationDirection } from "../NavigationDirection"; 2 | 3 | export interface TurnDirection { 4 | direction: NavigationDirection; 5 | directionChange: number; 6 | motionChange?: number; 7 | } 8 | -------------------------------------------------------------------------------- /src/graph/interfaces/GraphConfiguration.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for graph configuration. 3 | * 4 | * @interface GraphConfiguration 5 | */ 6 | export interface GraphConfiguration { 7 | /** 8 | * The maximum number of cached sequences left 9 | * after uncache. 10 | */ 11 | maxSequences: number; 12 | 13 | /** 14 | * The maximum number of unused cached images left 15 | * after uncache. 16 | */ 17 | maxUnusedImages: number; 18 | 19 | /** 20 | * The maximum number of unused pre-stored cached images left 21 | * after uncache. 22 | */ 23 | maxUnusedPreStoredImages: number; 24 | 25 | /** 26 | * The maximum number of unused cached tiles left 27 | * after uncache. 28 | */ 29 | maxUnusedTiles: number; 30 | } 31 | -------------------------------------------------------------------------------- /src/graph/interfaces/NavigationEdgeStatus.ts: -------------------------------------------------------------------------------- 1 | import { NavigationEdge } from "../edge/interfaces/NavigationEdge"; 2 | 3 | /** 4 | * Interface that indicates edge status. 5 | * 6 | * @interface NavigationEdgeStatus 7 | */ 8 | export interface NavigationEdgeStatus { 9 | /** 10 | * Value indicating whether the edges have been cached. 11 | */ 12 | cached: boolean; 13 | 14 | /** 15 | * The edges. 16 | * 17 | * @description If the cached property is false the edges 18 | * property will always be an empty array. If the cached 19 | * property is true, there will exist edges in the the 20 | * array if the image has edges. 21 | */ 22 | edges: NavigationEdge[]; 23 | } 24 | -------------------------------------------------------------------------------- /src/render/RenderMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for render mode 3 | * @enum {number} 4 | * @readonly 5 | * @description Modes for specifying how rendering is done 6 | * in the viewer. All modes preserves the original aspect 7 | * ratio of the images. 8 | */ 9 | export enum RenderMode { 10 | 11 | /** 12 | * Displays all content within the viewer. 13 | * 14 | * @description Black bars shown on both 15 | * sides of the content. Bars are shown 16 | * either below and above or to the left 17 | * and right of the content depending on 18 | * the aspect ratio relation between the 19 | * image and the viewer. 20 | */ 21 | Letterbox, 22 | 23 | /** 24 | * Fills the viewer by cropping content. 25 | * 26 | * @description Cropping is done either 27 | * in horizontal or vertical direction 28 | * depending on the aspect ratio relation 29 | * between the image and the viewer. 30 | */ 31 | Fill, 32 | } 33 | -------------------------------------------------------------------------------- /src/render/RenderPass.ts: -------------------------------------------------------------------------------- 1 | export enum RenderPass { 2 | Background, 3 | Opaque, 4 | } 5 | -------------------------------------------------------------------------------- /src/render/interfaces/GLFrameRenderer.ts: -------------------------------------------------------------------------------- 1 | import { GLRenderFunction } from "./GLRenderFunction"; 2 | import { RenderPass } from "../RenderPass"; 3 | 4 | export interface GLFrameRenderer { 5 | frameId: number; 6 | needsRender: boolean; 7 | render: GLRenderFunction; 8 | pass: RenderPass; 9 | } 10 | -------------------------------------------------------------------------------- /src/render/interfaces/GLRenderFunction.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from "three"; 2 | 3 | export interface GLRenderFunction extends Function { 4 | ( 5 | perspectiveCamera: THREE.PerspectiveCamera, 6 | renderer: THREE.WebGLRenderer, 7 | ): void; 8 | } 9 | -------------------------------------------------------------------------------- /src/render/interfaces/IGLRenderHash.ts: -------------------------------------------------------------------------------- 1 | import { GLFrameRenderer } from "./GLFrameRenderer"; 2 | 3 | export interface GLRenderHash { 4 | name: string; 5 | renderer: GLFrameRenderer; 6 | } 7 | -------------------------------------------------------------------------------- /src/render/interfaces/ViewportSize.ts: -------------------------------------------------------------------------------- 1 | export interface ViewportSize { 2 | height: number; 3 | width: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/render/interfaces/VirtualNodeHash.ts: -------------------------------------------------------------------------------- 1 | import * as vd from "virtual-dom"; 2 | 3 | export interface VirtualNodeHash { 4 | name: string; 5 | vNode: vd.VNode; 6 | } 7 | -------------------------------------------------------------------------------- /src/shader/Shader.ts: -------------------------------------------------------------------------------- 1 | import { 2 | fragment as textureFragment, 3 | vertex as textureVertex, 4 | } from "./shaders/texture.glsl"; 5 | 6 | export interface GLShader { 7 | fragment: string; 8 | vertex: string; 9 | } 10 | 11 | // tslint:disable-next-line:variable-name 12 | export const Shader: { [name: string]: GLShader; } = { 13 | texture: { 14 | fragment: textureFragment, 15 | vertex: textureVertex, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /src/shader/chunk/bearing_fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | vec3 bearing = normalize(positionExtrinsic.xyz); 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/chunk/common.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | #define PI 3.141592653589793 3 | #define PI2 6.283185307179586 4 | #define POSITIVE_INFINITY 3.402823466e+38 5 | `; 6 | -------------------------------------------------------------------------------- /src/shader/chunk/coordinates.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | vec2 sfmToUv(const in vec2 sfm, const in vec2 scale) { 3 | float u = scale.x * sfm.x + 0.5; 4 | float v = - scale.y * sfm.y + 0.5; 5 | return vec2(u, v); 6 | } 7 | `; 8 | -------------------------------------------------------------------------------- /src/shader/chunk/extrinsic_vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | positionExtrinsic = extrinsicMatrix * vec4(position, 1.0); 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/chunk/gl_frag_color_fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | gl_FragColor = mapColor; 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/chunk/gl_position_vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/chunk/map_color_fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | vec2 uv = sfmToUv(sfm, scale); 3 | float u = uv.x; 4 | float v = uv.y; 5 | 6 | vec4 mapColor; 7 | if (u >= 0. && u <= 1. && v >= 0. && v <= 1.) { 8 | mapColor = texture2D(map, vec2(u, v)); 9 | mapColor.a = opacity; 10 | } else { 11 | mapColor = vec4(0.0, 0.0, 0.0, 0.0); 12 | } 13 | `; 14 | -------------------------------------------------------------------------------- /src/shader/chunk/precision_fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | `; 8 | -------------------------------------------------------------------------------- /src/shader/chunk/uniforms_fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | uniform sampler2D map; 3 | uniform float opacity; 4 | uniform vec2 scale; 5 | `; 6 | -------------------------------------------------------------------------------- /src/shader/chunk/uniforms_vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | uniform mat4 extrinsicMatrix; 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/chunk/varyings_fragment.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | varying vec4 positionExtrinsic; 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/chunk/varyings_vertex.glsl.ts: -------------------------------------------------------------------------------- 1 | export default /* glsl */` 2 | varying vec4 positionExtrinsic; 3 | `; 4 | -------------------------------------------------------------------------------- /src/shader/shaders/texture.glsl.ts: -------------------------------------------------------------------------------- 1 | export const vertex = /* glsl */` 2 | #include 3 | #include 4 | 5 | void main() 6 | { 7 | #include 8 | #include 9 | } 10 | `; 11 | 12 | export const fragment = /* glsl */` 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #expand 19 | #expand 20 | #expand 21 | 22 | void main() 23 | { 24 | #include 25 | #expand 26 | #include 27 | #include 28 | } 29 | `; 30 | -------------------------------------------------------------------------------- /src/state/State.ts: -------------------------------------------------------------------------------- 1 | export enum State { 2 | Custom, 3 | Earth, 4 | GravityTraversing, 5 | Traversing, 6 | Waiting, 7 | WaitingInteractively, 8 | } 9 | -------------------------------------------------------------------------------- /src/state/TransitionMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for transition mode 3 | * @enum {number} 4 | * @readonly 5 | * @description Modes for specifying how transitions 6 | * between images are performed. 7 | */ 8 | export enum TransitionMode { 9 | /** 10 | * Default transitions. 11 | * 12 | * @description The viewer dynamically determines 13 | * whether transitions should be performed with or 14 | * without motion and blending for each transition 15 | * based on the underlying data. 16 | */ 17 | Default, 18 | 19 | /** 20 | * Instantaneous transitions. 21 | * 22 | * @description All transitions are performed 23 | * without motion or blending. 24 | */ 25 | Instantaneous, 26 | } 27 | -------------------------------------------------------------------------------- /src/state/interfaces/AnimationFrame.ts: -------------------------------------------------------------------------------- 1 | import { IAnimationState } from "./IAnimationState"; 2 | 3 | export interface AnimationFrame { 4 | id: number; 5 | fps: number; 6 | state: IAnimationState; 7 | } 8 | -------------------------------------------------------------------------------- /src/state/interfaces/EulerRotation.ts: -------------------------------------------------------------------------------- 1 | export interface EulerRotation { 2 | phi: number; 3 | theta: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/state/interfaces/IAnimationState.ts: -------------------------------------------------------------------------------- 1 | import { State } from "../State"; 2 | import { Camera } from "../../geo/Camera"; 3 | import { Transform } from "../../geo/Transform"; 4 | import { LngLatAlt } from "../../api/interfaces/LngLatAlt"; 5 | import { Image } from "../../graph/Image"; 6 | 7 | export interface IAnimationState { 8 | alpha: number; 9 | camera: Camera; 10 | currentCamera: Camera; 11 | currentImage: Image; 12 | currentIndex: number; 13 | currentTransform: Transform; 14 | imagesAhead: number; 15 | lastImage: Image; 16 | motionless: boolean; 17 | previousCamera: Camera; 18 | previousImage: Image; 19 | previousTransform: Transform; 20 | reference: LngLatAlt; 21 | state: State; 22 | stateTransitionAlpha: number; 23 | trajectory: Image[]; 24 | zoom: number; 25 | } 26 | -------------------------------------------------------------------------------- /src/state/interfaces/IStateBase.ts: -------------------------------------------------------------------------------- 1 | import { Camera } from "../../geo/Camera"; 2 | import { LngLatAlt } from "../../api/interfaces/LngLatAlt"; 3 | import { TransitionMode } from "../TransitionMode"; 4 | import { Image } from "../../graph/Image"; 5 | import { IGeometryProvider } from "../../mapillary"; 6 | 7 | export interface IStateBase { 8 | alpha: number; 9 | camera: Camera; 10 | currentIndex: number; 11 | geometry: IGeometryProvider, 12 | reference: LngLatAlt; 13 | trajectory: Image[]; 14 | transitionMode: TransitionMode; 15 | zoom: number; 16 | } 17 | -------------------------------------------------------------------------------- /src/state/state/CustomState.ts: -------------------------------------------------------------------------------- 1 | import { Matrix4, Vector3 } from "three"; 2 | import { StateBase } from "./StateBase"; 3 | import { IStateBase } from "../interfaces/IStateBase"; 4 | 5 | export class CustomState extends StateBase { 6 | constructor(state: IStateBase) { 7 | super(state); 8 | } 9 | 10 | public setViewMatrix(viewMatrix: number[]): void { 11 | const viewMatrixInverse = new Matrix4() 12 | .fromArray(viewMatrix) 13 | .invert(); 14 | 15 | const me = viewMatrixInverse.elements; 16 | const eye = new Vector3(me[12], me[13], me[14]); 17 | const forward = new Vector3(-me[8], -me[9], -me[10]); 18 | const up = new Vector3(me[4], me[5], me[6]); 19 | 20 | const camera = this._camera; 21 | camera.position.copy(eye); 22 | camera.lookat.copy(eye 23 | .clone() 24 | .add(forward)); 25 | camera.up.copy(up); 26 | 27 | const focal = 0.5 / Math.tan(Math.PI / 3); 28 | camera.focal = focal; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/tile/interfaces/TileBoundingBox.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface that describes a bounding box. 3 | * 4 | * @interface TileBoundingBox 5 | */ 6 | export interface TileBoundingBox { 7 | /** 8 | * The minimum x value. 9 | */ 10 | minX: number; 11 | 12 | /** 13 | * The minimum y value. 14 | */ 15 | minY: number; 16 | 17 | /** 18 | * The maximum x value. 19 | */ 20 | maxX: number; 21 | 22 | /** 23 | * The maximum y value. 24 | */ 25 | maxY: number; 26 | } 27 | -------------------------------------------------------------------------------- /src/tile/interfaces/TileRegionOfInterest.ts: -------------------------------------------------------------------------------- 1 | import { TileBoundingBox } from "./TileBoundingBox"; 2 | 3 | /** 4 | * Interface that describes a region of interest. 5 | * 6 | * @interface TileRegionOfInterest 7 | */ 8 | export interface TileRegionOfInterest { 9 | /** 10 | * The bounding box for the region of interest in basic coordinates. 11 | */ 12 | bbox: TileBoundingBox; 13 | 14 | /** 15 | * Width of the footprint of a canvas pixel in basic coordinates. 16 | */ 17 | pixelWidth: number; 18 | 19 | /** 20 | * Height of the footprint of a canvas pixel in basic coordinates. 21 | */ 22 | pixelHeight: number; 23 | } 24 | -------------------------------------------------------------------------------- /src/tile/interfaces/TileTypes.ts: -------------------------------------------------------------------------------- 1 | export const TILE_MIN_REQUEST_LEVEL = 11; 2 | export const TILE_SIZE = 1024; 3 | 4 | export interface TileImageSize { 5 | h: number; 6 | w: number; 7 | } 8 | 9 | export interface TileCoords2D { 10 | x: number; 11 | y: number; 12 | } 13 | 14 | export interface TileCoords3D extends TileCoords2D { 15 | z: number; 16 | } 17 | 18 | export interface TilePixelCoords2D extends 19 | TileImageSize, 20 | TileCoords2D { } 21 | 22 | export interface TileLevelColumnRows { 23 | columns: number; 24 | rows: number; 25 | } 26 | 27 | export interface TileLevel { 28 | z: number; 29 | max: number; 30 | } 31 | -------------------------------------------------------------------------------- /src/util/DOM.ts: -------------------------------------------------------------------------------- 1 | export class DOM { 2 | private _document: HTMLDocument; 3 | 4 | constructor(doc?: Node) { 5 | this._document = !!doc ? doc : document; 6 | } 7 | 8 | public get document(): HTMLDocument { 9 | return this._document; 10 | } 11 | 12 | public createElement( 13 | tagName: K, className?: string, container?: HTMLElement): HTMLElementTagNameMap[K] { 14 | const element: HTMLElementTagNameMap[K] = this._document.createElement(tagName); 15 | 16 | if (!!className) { 17 | element.className = className; 18 | } 19 | 20 | if (!!container) { 21 | container.appendChild(element); 22 | } 23 | 24 | return element; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/util/Func.ts: -------------------------------------------------------------------------------- 1 | export type Func = (item: T) => TResult; 2 | -------------------------------------------------------------------------------- /src/util/SubscriptionHolder.ts: -------------------------------------------------------------------------------- 1 | import { Subscription } from "rxjs"; 2 | 3 | export class SubscriptionHolder { 4 | private _subscriptions: Subscription[] = []; 5 | 6 | public push(subscription: Subscription): void { 7 | this._subscriptions.push(subscription); 8 | } 9 | 10 | public unsubscribe(): void { 11 | for (const sub of this._subscriptions) { 12 | sub.unsubscribe(); 13 | } 14 | 15 | this._subscriptions = []; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/util/interfaces/IEventEmitter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface describing event emitter members. 3 | */ 4 | export interface IEventEmitter { 5 | /** 6 | * @ignore 7 | */ 8 | fire( 9 | type: string, 10 | event: T): void; 11 | 12 | /** 13 | * Unsubscribe from an event by its name. 14 | * @param {string} type - The name of the event 15 | * to unsubscribe from. 16 | * @param {(event: T) => void} handler - The 17 | * handler to remove. 18 | */ 19 | off( 20 | type: string, 21 | handler: (event: T) => void): void; 22 | 23 | /** 24 | * Subscribe to an event by its name. 25 | * @param {string} type - The name of the event 26 | * to subscribe to. 27 | * @param {(event: T) => void} handler - The 28 | * handler called when the event occurs. 29 | */ 30 | on( 31 | type: string, 32 | handler: (event: T) => void): void; 33 | } 34 | -------------------------------------------------------------------------------- /src/viewer/ConfigurationService.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Observable, 3 | of as observableOf, 4 | } from "rxjs"; 5 | 6 | import { ViewerOptions } from "../external/viewer"; 7 | 8 | export class ConfigurationService { 9 | private _imageTiling$: Observable; 10 | private _exploreUrl$: Observable; 11 | 12 | constructor(options: ViewerOptions) { 13 | const host = options?.url?.exploreHost ?? "www.mapillary.com"; 14 | const scheme = options?.url?.scheme ?? "https"; 15 | const exploreUrl = `${scheme}://${host}`; 16 | this._exploreUrl$ = observableOf(exploreUrl); 17 | 18 | const imageTiling = options?.imageTiling === false ? false : true; 19 | this._imageTiling$ = observableOf(imageTiling); 20 | } 21 | 22 | public get exploreUrl$(): Observable { 23 | return this._exploreUrl$; 24 | } 25 | 26 | public get imageTiling$(): Observable { 27 | return this._imageTiling$; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/viewer/KeyboardService.ts: -------------------------------------------------------------------------------- 1 | import { 2 | fromEvent as observableFromEvent, 3 | Observable, 4 | } from "rxjs"; 5 | 6 | export class KeyboardService { 7 | private _keyDown$: Observable; 8 | private _keyUp$: Observable; 9 | 10 | constructor(canvasContainer: HTMLElement) { 11 | this._keyDown$ = observableFromEvent(canvasContainer, "keydown"); 12 | this._keyUp$ = observableFromEvent(canvasContainer, "keyup"); 13 | } 14 | 15 | public get keyDown$(): Observable { 16 | return this._keyDown$; 17 | } 18 | 19 | public get keyUp$(): Observable { 20 | return this._keyUp$; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/viewer/Modes.ts: -------------------------------------------------------------------------------- 1 | import { State } from "../state/State"; 2 | import { CameraControls } from "./enums/CameraControls"; 3 | 4 | export function cameraControlsToState(cameraControls: CameraControls): State { 5 | switch (cameraControls) { 6 | case CameraControls.Custom: 7 | return State.Custom; 8 | case CameraControls.Earth: 9 | return State.Earth; 10 | case CameraControls.Gravity: 11 | return State.GravityTraversing; 12 | case CameraControls.Street: 13 | return State.Traversing; 14 | default: 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/viewer/enums/Alignment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for alignments 3 | * @enum {number} 4 | * @readonly 5 | */ 6 | export enum Alignment { 7 | /** 8 | * Align to bottom 9 | */ 10 | Bottom, 11 | 12 | /** 13 | * Align to bottom left 14 | */ 15 | BottomLeft, 16 | 17 | /** 18 | * Align to bottom right 19 | */ 20 | BottomRight, 21 | 22 | /** 23 | * Align to center 24 | */ 25 | Center, 26 | 27 | /** 28 | * Align to left 29 | */ 30 | Left, 31 | 32 | /** 33 | * Align to right 34 | */ 35 | Right, 36 | 37 | /** 38 | * Align to top 39 | */ 40 | Top, 41 | 42 | /** 43 | * Align to top left 44 | */ 45 | TopLeft, 46 | 47 | /** 48 | * Align to top right 49 | */ 50 | TopRight, 51 | } 52 | -------------------------------------------------------------------------------- /src/viewer/enums/CameraControls.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for camera controls. 3 | * 4 | * @description Specifies different modes for how the 5 | * camera is controlled through pointer, keyboard or 6 | * other modes of input. 7 | * 8 | * @enum {number} 9 | * @readonly 10 | */ 11 | export enum CameraControls { 12 | /** 13 | * Control the camera with custom logic by 14 | * attaching a custom camera controls 15 | * instance to the {@link Viewer}. 16 | */ 17 | Custom, 18 | 19 | /** 20 | * Control the camera from a birds perspective 21 | * to get an overview. 22 | */ 23 | Earth, 24 | 25 | /** 26 | * Control the camera in a first person view 27 | * from the street level perspective. 28 | * 29 | * @description The virtual viewer camera will 30 | * be rotated according to the orientation of 31 | * the images. 32 | */ 33 | Street, 34 | 35 | /** 36 | * Control the camera in a first person view 37 | * from the street level perspective. 38 | * 39 | * @description The virtual viewer camera will 40 | * maintain gravity alignment for its up vector 41 | * at all times. 42 | */ 43 | Gravity, 44 | } 45 | -------------------------------------------------------------------------------- /src/viewer/enums/RenderPass.ts: -------------------------------------------------------------------------------- 1 | export enum RenderPass { 2 | /** 3 | * Occurs after the background render pass. 4 | */ 5 | Opaque, 6 | 7 | /** 8 | * Occurs last in the render sequence, after the opaque render pass. 9 | */ 10 | Transparent, 11 | } 12 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerBearingEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | 3 | /** 4 | * Interface for bearing viewer events. 5 | */ 6 | export interface ViewerBearingEvent extends ViewerEvent { 7 | /** 8 | * Bearing is measured in degrees 9 | * clockwise with respect to north. 10 | * 11 | * @description Bearing is related to the computed 12 | * compass angle ({@link Image.computedCompassAngle}) 13 | * from SfM, not the original EXIF compass angle. 14 | */ 15 | bearing: number; 16 | 17 | type: "bearing"; 18 | } 19 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerDataLoadingEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | 3 | /** 4 | * Interface for viewer data loading events. 5 | * 6 | * @description Fired when any viewer data (image, mesh, metadata, etc) 7 | * begins loading or changing asyncronously as a result of viewer 8 | * navigation. 9 | * 10 | * Also fired when the data has finished loading and the viewer 11 | * is able to perform the navigation. 12 | */ 13 | export interface ViewerDataLoadingEvent extends ViewerEvent { 14 | /** 15 | * Indicates if the viewer navigation is awaiting data load. 16 | */ 17 | loading: boolean; 18 | 19 | type: "dataloading"; 20 | } 21 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerDragEndEvent.ts: -------------------------------------------------------------------------------- 1 | import { LngLat } from "../../api/interfaces/LngLat"; 2 | import { ViewerEvent } from "./ViewerEvent"; 3 | 4 | /** 5 | * Interface for drag end viewer events. 6 | * 7 | * @example 8 | * ```js 9 | * // Set up an event listener on the viewer. 10 | * viewer.on('dragened', function(e) { 11 | * console.log(e.originalEvent); 12 | * }); 13 | * ``` 14 | */ 15 | export interface ViewerDragEndEvent extends ViewerEvent { 16 | /** 17 | * The original event that triggered the viewer event. 18 | */ 19 | originalEvent: MouseEvent | FocusEvent; 20 | 21 | /** 22 | * The event type. 23 | */ 24 | type: "dragend"; 25 | } 26 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerEvent.ts: -------------------------------------------------------------------------------- 1 | import { IViewer } from "../interfaces/IViewer"; 2 | import { ViewerEventType } from "./ViewerEventType"; 3 | 4 | /** 5 | * Interface for general viewer events. 6 | */ 7 | export interface ViewerEvent { 8 | /** 9 | * The viewer object that fired the event. 10 | */ 11 | target: IViewer; 12 | 13 | /** 14 | * The event type. 15 | */ 16 | type: ViewerEventType; 17 | } 18 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerEventType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @event 3 | */ 4 | export type ViewerEventType = 5 | | "bearing" 6 | | "click" 7 | | "contextmenu" 8 | | "dataprovider" 9 | | "dblclick" 10 | | "drag" 11 | | "dragend" 12 | | "dragstart" 13 | | "fov" 14 | | "dataloading" 15 | | "load" 16 | | "mousedown" 17 | | "mousemove" 18 | | "mouseout" 19 | | "mouseover" 20 | | "mouseup" 21 | | "moveend" 22 | | "movestart" 23 | | "navigable" 24 | | "image" 25 | | "position" 26 | | "pov" 27 | | "reference" 28 | | "remove" 29 | | "reset" 30 | | "sequenceedges" 31 | | "spatialedges"; 32 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerImageEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | import { Image } from "../../graph/Image"; 3 | 4 | /** 5 | * Interface for viewer image events. 6 | */ 7 | export interface ViewerImageEvent extends ViewerEvent { 8 | /** 9 | * The viewer's current image. 10 | * 11 | * @description If the viewer is reset, the emitted 12 | * image will be null. 13 | */ 14 | image: Image | null; 15 | 16 | type: "image"; 17 | } 18 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerLoadEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | 3 | /** 4 | * Interface for viewer load events. 5 | * 6 | * @description Fired immediately after all necessary resources 7 | * have been downloaded and the first visually complete 8 | * rendering of the viewer has occurred. 9 | * 10 | * The visually complete rendering does not include custom 11 | * renderers. 12 | * 13 | * This event is only fired for viewer configurations where 14 | * the WebGL context is created, i.e. not when using the 15 | * fallback functionality only. 16 | * 17 | * @example 18 | * ```js 19 | * // Set up an event listener on the viewer. 20 | * viewer.on('load', function(e) { 21 | * console.log('A load event has occured'); 22 | * }); 23 | * ``` 24 | */ 25 | export interface ViewerLoadEvent extends ViewerEvent { 26 | type: "load"; 27 | } 28 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerNavigableEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | 3 | /** 4 | * Interface for navigable viewer events. 5 | */ 6 | export interface ViewerNavigableEvent extends ViewerEvent { 7 | /** 8 | * The navigable state indicates if the viewer supports 9 | * moving, i.e. calling the `moveTo` and `moveDir` 10 | * methods. The viewer will not be in a navigable state if the cover 11 | * is activated and the viewer has been supplied a id. When the cover 12 | * is deactivated or activated without being supplied a id it will 13 | * be navigable. 14 | */ 15 | navigable: boolean; 16 | 17 | type: "navigable"; 18 | } 19 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerNavigationEdgeEvent.ts: -------------------------------------------------------------------------------- 1 | import { NavigationEdgeStatus } 2 | from "../../graph/interfaces/NavigationEdgeStatus"; 3 | import { ViewerEvent } from "./ViewerEvent"; 4 | 5 | /** 6 | * Interface for navigation edge viewer events. 7 | */ 8 | export interface ViewerNavigationEdgeEvent extends ViewerEvent { 9 | /** 10 | * The viewer's current navigation edge status. 11 | */ 12 | status: NavigationEdgeStatus; 13 | 14 | type: 15 | | "sequenceedges" 16 | | "spatialedges"; 17 | } 18 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerReferenceEvent.ts: -------------------------------------------------------------------------------- 1 | import { LngLatAlt } from "../../external/api"; 2 | import { ViewerEvent } from "./ViewerEvent"; 3 | 4 | /** 5 | * Interface for viewer reference events. 6 | */ 7 | export interface ViewerReferenceEvent extends ViewerEvent { 8 | /** 9 | * The viewer's current reference. 10 | */ 11 | reference: LngLatAlt; 12 | 13 | type: "reference"; 14 | } 15 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerResetEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | 3 | /** 4 | * Interface for viewer reset events. 5 | * 6 | * @description Fired immediately after all resources 7 | * have been cleared. 8 | * 9 | * @example 10 | * ```js 11 | * // Set up an event listener on the viewer. 12 | * viewer.on('reset', function(e) { 13 | * console.log('A reset event has occured'); 14 | * }); 15 | * ``` 16 | */ 17 | export interface ViewerResetEvent extends ViewerEvent { 18 | type: "reset"; 19 | } 20 | -------------------------------------------------------------------------------- /src/viewer/events/ViewerStateEvent.ts: -------------------------------------------------------------------------------- 1 | import { ViewerEvent } from "./ViewerEvent"; 2 | 3 | /** 4 | * Interface for viewer state events. 5 | * 6 | * @example 7 | * ```js 8 | * // The `fov` event is an example of a `ViewerStateEvent`. 9 | * // Set up an event listener on the viewer. 10 | * viewer.on('fov', function(e) { 11 | * console.log('A fov event has occured'); 12 | * }); 13 | * ``` 14 | */ 15 | export interface ViewerStateEvent extends ViewerEvent { 16 | /** 17 | * The event type. 18 | */ 19 | type: 20 | | "dataprovider" 21 | | "fov" 22 | | "moveend" 23 | | "movestart" 24 | | "position" 25 | | "pov" 26 | | "remove"; 27 | } 28 | -------------------------------------------------------------------------------- /src/viewer/interfaces/ISpriteAtlas.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from "three"; 2 | import * as vd from "virtual-dom"; 3 | 4 | import { Alignment } from "../enums/Alignment"; 5 | 6 | export interface ISpriteAtlas { 7 | loaded: boolean; 8 | getGLSprite(name: string): THREE.Object3D; 9 | getDOMSprite(name: string, float?: Alignment): vd.VNode; 10 | } 11 | -------------------------------------------------------------------------------- /src/viewer/interfaces/MouseClaim.ts: -------------------------------------------------------------------------------- 1 | export interface MouseClaim { 2 | name: string; 3 | zindex: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/viewer/interfaces/MousePixelDeferral.ts: -------------------------------------------------------------------------------- 1 | export interface MousePixelDeferral { 2 | name: string; 3 | deferPixels: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/viewer/interfaces/PointOfView.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @interface PointOfView 3 | * 4 | * Interface that represents the point of view of the viewer. 5 | */ 6 | export interface PointOfView { 7 | /** 8 | * Value indicating the current bearing of the viewer 9 | * measured in degrees clockwise with respect to north. 10 | * Ranges from 0° to 360°. 11 | */ 12 | bearing: number; 13 | 14 | /** 15 | * The camera tilt in degrees, relative to a horizontal plane. 16 | * Ranges from 90° (directly upwards) to -90° (directly downwards). 17 | */ 18 | tilt: number; 19 | } 20 | -------------------------------------------------------------------------------- /src/viewer/interfaces/Unprojection.ts: -------------------------------------------------------------------------------- 1 | import { LngLat } from "../../api/interfaces/LngLat"; 2 | 3 | export interface Unprojection { 4 | basicPoint: number[]; 5 | lngLat: LngLat; 6 | pixelPoint: number[]; 7 | } 8 | -------------------------------------------------------------------------------- /src/viewer/options/FallbackOptions.ts: -------------------------------------------------------------------------------- 1 | import { NavigationFallbackConfiguration } 2 | from "../../component/interfaces/NavigationFallbackConfiguration"; 3 | 4 | /** 5 | * Interface for the fallback component options that can be 6 | * provided to the viewer when the browser does not have 7 | * WebGL support. 8 | * 9 | * @interface 10 | */ 11 | export interface FallbackOptions { 12 | 13 | /** 14 | * Show static images without pan, zoom, or transitions. 15 | * 16 | * @description Fallback for `image` when WebGL is not supported. 17 | * 18 | * @default false 19 | */ 20 | image?: boolean; 21 | 22 | /** 23 | * Show static navigation arrows in the corners. 24 | * 25 | * @description Fallback for `direction` and `sequence` when WebGL is not supported. 26 | * 27 | * @default false 28 | */ 29 | navigation?: boolean | NavigationFallbackConfiguration; 30 | } 31 | -------------------------------------------------------------------------------- /src/viewer/options/UrlOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for the URL options that can be provided to the viewer. 3 | * 4 | * @interface 5 | */ 6 | export interface UrlOptions { 7 | /** 8 | * Explore host. 9 | * 10 | * @description Host used for links to the full 11 | * mapillary website. 12 | * 13 | * @default {"www.mapillary.com"} 14 | */ 15 | exploreHost?: string; 16 | 17 | /** 18 | * Scheme. 19 | * 20 | * @description Used for all hosts. 21 | * 22 | * @default {"https"} 23 | */ 24 | scheme?: string; 25 | } 26 | -------------------------------------------------------------------------------- /styles/mapillary.css: -------------------------------------------------------------------------------- 1 | .mapillary-viewer { 2 | background-color: #0F0F0F; 3 | position: relative; 4 | overflow: hidden; 5 | -webkit-tap-highlight-color: rgba(0,0,0,0); 6 | } 7 | 8 | .mapillary-interactive { 9 | cursor: grab; 10 | } 11 | 12 | .mapillary-interactive:active { 13 | cursor: grabbing; 14 | } 15 | 16 | .mapillary-viewer .mapillary-dom { 17 | bottom: 0; 18 | left: 0; 19 | overflow: hidden; 20 | pointer-events: none; 21 | position: absolute; 22 | right: 0; 23 | top: 0; 24 | user-select: none; 25 | } 26 | 27 | .mapillary-dom .mapillary-dom-renderer { 28 | pointer-events: auto; 29 | } 30 | 31 | .mapillary-viewer div { 32 | box-sizing: content-box; 33 | } 34 | 35 | .mapillary-viewer input:focus { 36 | background: none; 37 | } 38 | -------------------------------------------------------------------------------- /styles/svg/pointer-wheat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /styles/svg/pointer-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /styles/svg/stepper-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | chevronleft 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /styles/svg/stepper-play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | play 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /styles/svg/stepper-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | chevronright 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /styles/svg/stepper-stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | stop 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /styles/svg/turn-around.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /styles/svg/turn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /test/component/spatial/SpatialComponent.test.ts: -------------------------------------------------------------------------------- 1 | 2 | import { SpatialComponent } from "../../../src/component/spatial/SpatialComponent"; 3 | import { ContainerMockCreator } from "../../helper/ContainerMockCreator"; 4 | import { NavigatorMockCreator } from "../../helper/NavigatorMockCreator"; 5 | 6 | describe("SpatialComponent.ctor", () => { 7 | it("should be defined", () => { 8 | const component: SpatialComponent = 9 | new SpatialComponent( 10 | SpatialComponent.componentName, 11 | new ContainerMockCreator().create(), 12 | new NavigatorMockCreator().create()); 13 | 14 | expect(component).toBeDefined(); 15 | }); 16 | }); 17 | 18 | describe("SpatialComponent.deactivate", () => { 19 | it("should deactivate properly", () => { 20 | const component: SpatialComponent = 21 | new SpatialComponent( 22 | SpatialComponent.componentName, 23 | new ContainerMockCreator().create(), 24 | new NavigatorMockCreator().create()); 25 | 26 | component.activate(); 27 | component.deactivate(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/graph/Sequence.test.ts: -------------------------------------------------------------------------------- 1 | import { SequenceEnt } from "../../src/api/ents/SequenceEnt"; 2 | import { Sequence } from "../../src/graph/Sequence"; 3 | 4 | describe("Sequence", () => { 5 | let sequence: Sequence; 6 | 7 | beforeEach(() => { 8 | let response: SequenceEnt = { 9 | id: "A", 10 | image_ids: ["B", "C", "D", "E"], 11 | }; 12 | 13 | sequence = new Sequence(response); 14 | }); 15 | 16 | it("should create a sequence", () => { 17 | expect(sequence).toBeDefined(); 18 | }); 19 | 20 | it("should find next key when it exists", () => { 21 | expect(sequence.findNext("C")).toEqual("D"); 22 | }); 23 | 24 | it("should find prev key when it exists", () => { 25 | expect(sequence.findPrev("C")).toEqual("B"); 26 | }); 27 | 28 | it("should return null if no next key", () => { 29 | expect(sequence.findNext("E")).toBe(null); 30 | }); 31 | 32 | it("should return null if no prev key", () => { 33 | expect(sequence.findPrev("B")).toBe(null); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/helper/ConfigurationServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | 3 | import { MockCreator } from "./MockCreator"; 4 | import { MockCreatorBase } from "./MockCreatorBase"; 5 | 6 | import { ConfigurationService } from "../../src/viewer/ConfigurationService"; 7 | 8 | export class ConfigurationServiceMockCreator extends 9 | MockCreatorBase { 10 | public create(): ConfigurationService { 11 | const mock: ConfigurationService = 12 | new MockCreator() 13 | .create(ConfigurationService, "ConfigurationService"); 14 | 15 | this._mockProperty( 16 | mock, 17 | "exploreUrl$", 18 | new Subject()); 19 | this._mockProperty( 20 | mock, 21 | "imageTiling$", 22 | new Subject()); 23 | 24 | return mock; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/helper/DOMRendererMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { DOMRenderer } from "../../src/render/DOMRenderer"; 3 | import { VirtualNodeHash } from "../../src/render/interfaces/VirtualNodeHash"; 4 | 5 | import { MockCreator } from "./MockCreator"; 6 | import { MockCreatorBase } from "./MockCreatorBase"; 7 | 8 | export class DOMRendererMockCreator extends MockCreatorBase { 9 | public create(): DOMRenderer { 10 | const mock: DOMRenderer = new MockCreator().create(DOMRenderer, "DOMRenderer"); 11 | 12 | this._mockProperty(mock, "element$", new Subject()); 13 | this._mockProperty(mock, "render$", new Subject()); 14 | 15 | return mock; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/helper/GLRendererMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { GLRenderer } from "../../src/render/GLRenderer"; 3 | import { GLRenderHash } from "../../src/render/interfaces/IGLRenderHash"; 4 | 5 | import { MockCreator } from "./MockCreator"; 6 | import { MockCreatorBase } from "./MockCreatorBase"; 7 | 8 | export class GLRendererMockCreator extends MockCreatorBase { 9 | public create(): GLRenderer { 10 | const mock = new MockCreator().create(GLRenderer, "GLRenderer"); 11 | 12 | this._mockProperty(mock, "webGLRenderer$", new Subject()); 13 | this._mockProperty(mock, "render$", new Subject()); 14 | this._mockProperty(mock, "opaqueRender$", new Subject()); 15 | this._mockProperty(mock, "transparentRender$", new Subject()); 16 | 17 | return mock; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/helper/GeoHelper.ts: -------------------------------------------------------------------------------- 1 | import * as THREE from "three"; 2 | import { Spatial } from "../../src/geo/Spatial"; 3 | 4 | export class GeoHelper { 5 | private spatial: Spatial = new Spatial(); 6 | 7 | public getTranslation(r: number[], C: number[]): number[] { 8 | let R: THREE.Matrix4 = this.spatial.rotationMatrix(r); 9 | let t: number[] = new THREE.Vector3().fromArray(C).applyMatrix4(R).multiplyScalar(-1).toArray(); 10 | 11 | return t; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/helper/GraphServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | 3 | import { MockCreator } from "./MockCreator"; 4 | import { MockCreatorBase } from "./MockCreatorBase"; 5 | 6 | import { FilterFunction } from "../../src/graph/FilterCreator"; 7 | import { GraphMode } from "../../src/graph/GraphMode"; 8 | import { GraphService } from "../../src/graph/GraphService"; 9 | 10 | export class GraphServiceMockCreator extends MockCreatorBase { 11 | public create(): GraphService { 12 | const mock: GraphService = new MockCreator().create(GraphService, "GraphService"); 13 | 14 | this._mockProperty(mock, "dataAdded$", new Subject()); 15 | this._mockProperty(mock, "dataDeleted$", new Subject()); 16 | this._mockProperty(mock, "dataReset$", new Subject()); 17 | this._mockProperty(mock, "graphMode$", new Subject()); 18 | this._mockProperty(mock, "filter$", new Subject()); 19 | 20 | return mock; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/helper/ImageMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Image as MImage } from "../../src/graph/Image"; 2 | 3 | import { MockCreator } from "./MockCreator"; 4 | import { MockCreatorBase } from "./MockCreatorBase"; 5 | 6 | export class ImageMockCreator extends MockCreatorBase { 7 | public create(configuration?: { [key: string]: any }): MImage { 8 | const mock: MImage = new MockCreator().create(MImage, "Image"); 9 | 10 | this._mockProperty( 11 | mock, "image", 12 | configuration.image ?? new Image()); 13 | this._mockProperty( 14 | mock, "key", 15 | configuration.key ?? "key"); 16 | 17 | return mock; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/helper/KeyboardServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { KeyboardService } from "../../src/viewer/KeyboardService"; 3 | 4 | import { MockCreator } from "./MockCreator"; 5 | import { MockCreatorBase } from "./MockCreatorBase"; 6 | 7 | export class KeyboardServiceMockCreator extends MockCreatorBase { 8 | public create(): KeyboardService { 9 | const mock: KeyboardService = new MockCreator().create(KeyboardService, "KeyboardService"); 10 | 11 | this._mockProperty(mock, "keyDown$", new Subject()); 12 | this._mockProperty(mock, "keyUp$", new Subject()); 13 | 14 | return mock; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/helper/LoadingServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { LoadingService } from "../../src/viewer/LoadingService"; 3 | 4 | import { MockCreator } from "./MockCreator"; 5 | import { MockCreatorBase } from "./MockCreatorBase"; 6 | 7 | export class LoadingServiceMockCreator extends MockCreatorBase { 8 | public create(): LoadingService { 9 | const mock: LoadingService = new MockCreator().create(LoadingService, "LoadingService"); 10 | 11 | this._mockProperty(mock, "loading$", new Subject()); 12 | 13 | return mock; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/helper/MockCreator.ts: -------------------------------------------------------------------------------- 1 | export class MockCreator { 2 | public create(ctor: new (...args: any[]) => T, name: string): T { 3 | const spy: { [key: string]: any } = {}; 4 | 5 | for (const key in ctor.prototype) { 6 | if (!!Object.getOwnPropertyDescriptor(ctor.prototype, key) && 7 | !Object.getOwnPropertyDescriptor(ctor.prototype, key).get) { 8 | spy[key] = jasmine.createSpy(name + "." + key, ctor.prototype[key]); 9 | } 10 | } 11 | 12 | return spy; 13 | } 14 | 15 | public mockProperty(instance: T, propertyName: string, propertyValue: U): T { 16 | Object.defineProperty( 17 | instance, 18 | propertyName, 19 | { 20 | get: (): U => { return propertyValue; }, 21 | set: (value: U): void => { propertyValue = value; }, 22 | }); 23 | 24 | return instance; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/helper/MockCreatorBase.ts: -------------------------------------------------------------------------------- 1 | import { MockCreator } from "./MockCreator"; 2 | 3 | export abstract class MockCreatorBase { 4 | private _mockCreator: MockCreator = new MockCreator(); 5 | 6 | public abstract create(): T; 7 | 8 | protected _mockProperty(instance: T, propertyName: string, propertyValue: U): void { 9 | this._mockCreator.mockProperty(instance, propertyName, propertyValue); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/helper/PanServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | 3 | import { MockCreator } from "./MockCreator"; 4 | import { MockCreatorBase } from "./MockCreatorBase"; 5 | 6 | import { Transform } from "../../src/geo/Transform"; 7 | import { Image } from "../../src/graph/Image"; 8 | import { PanService } from "../../src/viewer/PanService"; 9 | 10 | export class PanServiceMockCreator extends MockCreatorBase { 11 | public create(): PanService { 12 | const mock: PanService = 13 | new MockCreator().create(PanService, "PanService"); 14 | 15 | this._mockProperty( 16 | mock, 17 | "panImages$", 18 | new Subject<[Image, Transform]>()); 19 | 20 | return mock; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/helper/PlayServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { NavigationDirection } from "../../src/graph/edge/NavigationDirection"; 3 | import { PlayService } from "../../src/viewer/PlayService"; 4 | 5 | import { MockCreator } from "./MockCreator"; 6 | import { MockCreatorBase } from "./MockCreatorBase"; 7 | 8 | export class PlayServiceMockCreator extends MockCreatorBase { 9 | public create(): PlayService { 10 | const mock: PlayService = new MockCreator().create(PlayService, "PlayService"); 11 | 12 | this._mockProperty(mock, "direction$", new Subject()); 13 | this._mockProperty(mock, "playing$", new Subject()); 14 | this._mockProperty(mock, "speed$", new Subject()); 15 | 16 | return mock; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/helper/ProviderHelper.ts: -------------------------------------------------------------------------------- 1 | import { DataProviderBase } from "../../src/api/DataProviderBase"; 2 | import { GeometryProviderBase } from "../../src/api/GeometryProviderBase"; 3 | 4 | export class GeometryProvider extends GeometryProviderBase { } 5 | 6 | export class DataProvider extends DataProviderBase { 7 | constructor(geometry?: GeometryProviderBase) { 8 | super(geometry ?? new GeometryProvider()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/helper/RenderServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { RenderCamera } from "../../src/render/RenderCamera"; 3 | import { RenderService } from "../../src/render/RenderService"; 4 | 5 | import { MockCreator } from "./MockCreator"; 6 | import { MockCreatorBase } from "./MockCreatorBase"; 7 | 8 | export class RenderServiceMockCreator extends MockCreatorBase { 9 | public create(): RenderService { 10 | const mock: RenderService = new MockCreator().create(RenderService, "RenderService"); 11 | 12 | this._mockProperty(mock, "bearing$", new Subject()); 13 | this._mockProperty(mock, "projectionMatrix$", new Subject()); 14 | this._mockProperty(mock, "renderCamera$", new Subject()); 15 | this._mockProperty(mock, "renderCameraFrame$", new Subject()); 16 | this._mockProperty(mock, "size$", new Subject()); 17 | 18 | return mock; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/helper/RequestHelper.ts: -------------------------------------------------------------------------------- 1 | export class XMLHTTPRequestMock { 2 | public response: {}; 3 | public responseType: string; 4 | public status: number; 5 | public timeout: number; 6 | 7 | public onload: (e: Event) => any; 8 | public onerror: (e: Event) => any; 9 | public ontimeout: (e: Event) => any; 10 | public onabort: (e: Event) => any; 11 | 12 | public abort(): void { this.onabort(new Event("abort")); } 13 | public open(...args: any[]): void { return; } 14 | public send(...args: any[]): void { return; } 15 | }; 16 | -------------------------------------------------------------------------------- /test/helper/SpriteServiceMockCreator.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from "rxjs"; 2 | import { ISpriteAtlas } from "../../src/viewer/interfaces/ISpriteAtlas"; 3 | import { SpriteService } from "../../src/viewer/SpriteService"; 4 | 5 | import { MockCreator } from "./MockCreator"; 6 | import { MockCreatorBase } from "./MockCreatorBase"; 7 | 8 | export class SpriteServiceMockCreator extends MockCreatorBase { 9 | public create(): SpriteService { 10 | const mock: SpriteService = new MockCreator().create(SpriteService, "SpriteService"); 11 | 12 | this._mockProperty(mock, "spriteAtlas$", new Subject()); 13 | 14 | return mock; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/helper/TestComponent.ts: -------------------------------------------------------------------------------- 1 | import { Component } from "../../src/component/Component"; 2 | import { ComponentConfiguration } from "../../src/component/interfaces/ComponentConfiguration"; 3 | import { Container } from "../../src/viewer/Container"; 4 | import { Navigator } from "../../src/viewer/Navigator"; 5 | 6 | export interface TestConfiguration extends ComponentConfiguration { 7 | test: boolean; 8 | } 9 | 10 | export class TestComponent extends Component { 11 | constructor(name: string, container: Container, navigator: Navigator) { 12 | super(name, container, navigator); 13 | } 14 | protected _activate(): void { /* noop */ } 15 | protected _deactivate(): void { /* noop */ } 16 | protected _getDefaultConfiguration(): TestConfiguration { return { test: false }; } 17 | } 18 | -------------------------------------------------------------------------------- /test/helper/TestImage.ts: -------------------------------------------------------------------------------- 1 | import { Image } from "../../src/graph/Image"; 2 | import { MeshContract } from "../../src/api/contracts/MeshContract"; 3 | import { CoreImageEnt } from "../../src/api/ents/CoreImageEnt"; 4 | 5 | 6 | export class TestImage extends Image { 7 | private _mesh: MeshContract; 8 | 9 | constructor(core: CoreImageEnt) { 10 | super(core); 11 | } 12 | 13 | public get assetsCached(): boolean { 14 | return true; 15 | } 16 | 17 | public get image(): HTMLImageElement { 18 | return null; 19 | } 20 | 21 | public get mesh(): MeshContract { 22 | return this._mesh; 23 | } 24 | 25 | public set mesh(value: MeshContract) { 26 | this._mesh = value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/helper/TestMath.ts: -------------------------------------------------------------------------------- 1 | export function isClockwise(polygon: number[][]): boolean { 2 | if (polygon.length < 3) { return false; }; 3 | let edgeSum = 0; 4 | for (let i = 0; i < polygon.length; ++i) { 5 | const [x1, y1] = polygon[i]; 6 | const [x2, y2] = polygon[(i + 1) % polygon.length]; 7 | edgeSum += (x2 - x1) * (y2 + y1); 8 | } 9 | return edgeSum > 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/helper/TransformHelper.ts: -------------------------------------------------------------------------------- 1 | import { ImageHelper } from "./ImageHelper"; 2 | import { Transform } from "../../src/geo/Transform"; 3 | import { CameraType } from "../../src/geo/interfaces/CameraType"; 4 | import { ProjectionService } from "../../src/viewer/ProjectionService"; 5 | 6 | export class TransformHelper { 7 | private _imageHelper: ImageHelper = new ImageHelper(); 8 | 9 | public createTransform( 10 | cameraType: CameraType = "perspective"): Transform { 11 | 12 | const image = this._imageHelper 13 | .createImage(cameraType); 14 | const camera = new ProjectionService() 15 | .makeCamera(cameraType, image.cameraParameters); 16 | 17 | return new Transform( 18 | image.exifOrientation, 19 | image.width, 20 | image.height, 21 | image.scale, 22 | image.rotation, 23 | [0, 0, 0], 24 | null, 25 | camera); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/helper/WebGLRenderer.ts: -------------------------------------------------------------------------------- 1 | export class RendererMock implements THREE.Renderer { 2 | public domElement: HTMLCanvasElement = document.createElement("canvas"); 3 | 4 | public clear(): void { /* noop */; } 5 | public clearDepth(): void { /* noop */ } 6 | public getContext(): void { /* noop */ } 7 | public getRenderTarget(): THREE.WebGLRenderTarget { return; } 8 | public render( 9 | s: THREE.Scene, 10 | c: THREE.Camera, 11 | t?: THREE.WebGLRenderTarget) 12 | : void { /* noop */ } 13 | public resetState(): void { /* noop */ } 14 | public setClearColor( 15 | color: THREE.Color | string | number, 16 | alpha?: number): void { /* noop */ } 17 | public setPixelRatio(ratio: number): void { /* noop */ } 18 | public setRenderTarget(): void { /* noop */ } 19 | public setSize( 20 | w: number, 21 | h: number, 22 | updateStyle?: boolean): void { /* noop */ } 23 | } 24 | -------------------------------------------------------------------------------- /test/state/StateService.test.ts: -------------------------------------------------------------------------------- 1 | import { bootstrap } from "../Bootstrap"; 2 | bootstrap(); 3 | 4 | import { StateService } from "../../src/state/StateService"; 5 | import { State } from "../../src/state/State"; 6 | import { S2GeometryProvider } from "../../src/api/S2GeometryProvider"; 7 | 8 | describe("StateService.ctor", () => { 9 | it("should be contructed", () => { 10 | let stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider()); 11 | 12 | expect(stateService).toBeDefined(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/tile/TileTypes.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | TILE_MIN_REQUEST_LEVEL, 3 | TILE_SIZE, 4 | } from "../../src/tile/interfaces/TileTypes"; 5 | 6 | describe("MIN_REQUEST_LEVEL", () => { 7 | it("should return 11", () => { 8 | expect(TILE_MIN_REQUEST_LEVEL).toBe(11); 9 | }); 10 | }); 11 | 12 | describe("TILE_SIZE", () => { 13 | it("should return 1024", () => { 14 | expect(TILE_SIZE).toBe(1024); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/viewer/LoadingService.test.ts: -------------------------------------------------------------------------------- 1 | import { LoadingService } from "../../src/viewer/LoadingService"; 2 | 3 | describe("LoadingService", () => { 4 | let loadingService: LoadingService; 5 | 6 | beforeEach(() => { 7 | loadingService = new LoadingService(); 8 | }); 9 | 10 | it("should be initialized to not loading", (done: Function) => { 11 | loadingService.loading$ 12 | .subscribe((loading: boolean) => { 13 | expect(loading).toBe(false); 14 | done(); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/viewer/Modes.test.ts: -------------------------------------------------------------------------------- 1 | import { State } from "../../src/state/State"; 2 | import { cameraControlsToState } from "../../src/viewer/Modes"; 3 | import { CameraControls } from "../../src/viewer/enums/CameraControls"; 4 | 5 | describe("cameraControlsToState", () => { 6 | it("converts to valid states", () => { 7 | expect(cameraControlsToState(CameraControls.Custom)) 8 | .toBe(State.Custom); 9 | expect(cameraControlsToState(CameraControls.Earth)) 10 | .toBe(State.Earth); 11 | expect(cameraControlsToState(CameraControls.Street)) 12 | .toBe(State.Traversing); 13 | expect(cameraControlsToState(-1)) 14 | .toBe(null); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "lib": ["es6", "dom"], 6 | "module": "es6", 7 | "moduleResolution": "node", 8 | "noImplicitAny": true, 9 | "outDir": "build/esm/", 10 | "sourceMap": true, 11 | "target": "es6", 12 | "typeRoots": ["node_modules/@types", "types"], 13 | "types": [ 14 | "earcut", 15 | "jest", 16 | "node", 17 | "pbf", 18 | "polylabel", 19 | "rbush", 20 | "s2-geometry", 21 | "three", 22 | "virtual-dom" 23 | ] 24 | }, 25 | "include": ["src/**/*", "test/**/*"] 26 | } 27 | -------------------------------------------------------------------------------- /types/s2-geometry/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "s2-geometry" { 2 | export module S2 { 3 | interface ILatLng { 4 | lat: number; 5 | lng: number; 6 | } 7 | 8 | function latLngToNeighborKeys(lat: number, lng: number, level: number): string[]; 9 | 10 | function latLngToKey(lat: number, lng: number, level: number): string; 11 | function keyToId(key: string): string; 12 | 13 | function idToLatLng(id: string): ILatLng; 14 | function idToKey(id: string): string; 15 | function keyToLatLng(key: string): ILatLng; 16 | 17 | class S2Cell { 18 | static FromHilbertQuadKey(key: string): S2Cell; 19 | getCornerLatLngs(): ILatLng[]; 20 | } 21 | } 22 | } 23 | --------------------------------------------------------------------------------