GithubHelp home page GithubHelp logo

mapillary / mapillary-js Goto Github PK

View Code? Open in Web Editor NEW
423.0 38.0 80.0 59.4 MB

Interactive, extendable street imagery map experiences in the browser, powered by WebGL

Home Page: https://mapillary.github.io/mapillary-js

License: MIT License

JavaScript 0.21% CSS 1.32% TypeScript 98.45% Dockerfile 0.02%
imagery webgl typescript mapillary spatial-visualization computational-geometry street-imagery 3d viewer renderer

mapillary-js's Introduction

GitHub workflow GitHub license npm version

MapillaryJS

MapillaryJS is a client-side JavaScript library for interactive, extendable street imagery map experiences on the web. It takes spatial, semantic, and texture data and renders it using WebGL. MapillaryJS can be customized with camera controls, user interactivity, and data providers and it can be augmented with geospatial rendering, animation, and content placement.

Mapillary

Installation and Usage

To start using MapillaryJS with data from the Mapillary platform, you need an account. When signed in, you need to register an application to get a client access token. When providing your own data, no access token is needed.

ES6 bundler

Install the package via Yarn (or npm).

yarn add mapillary-js

Use a CSS loader or include the CSS file in the <head> of your HTML file.

<link
  href="https://unpkg.com/[email protected]/dist/mapillary.css"
  rel="stylesheet"
/>

Include the following code in your JavaScript file.

import { Viewer } from "mapillary-js";

const viewer = new Viewer({
  accessToken: "<your access token>",
  container: "<your HTML element ID>",
  imageId: "<your image ID for initializing the viewer>",
});
TypeScript

Install the package via Yarn (or npm).

yarn add mapillary-js

Use a CSS loader or include the CSS file in the <head> of your HTML file.

<link
  href="https://unpkg.com/[email protected]/dist/mapillary.css"
  rel="stylesheet"
/>

Include the following code in your TypeScript file.

import { Viewer, ViewerOptions } from "mapillary-js";

const options: ViewerOptions = {
  accessToken: "<your access token>",
  container: "<your HTML element ID>",
  imageId: "<your image ID for initializing the viewer>",
};
const viewer = new Viewer(options);
CDN

Include the JavaScript and CSS files in the <head> of your HTML file.

<script src="https://unpkg.com/[email protected]/dist/mapillary.js"></script>
<link
  href="https://unpkg.com/[email protected]/dist/mapillary.css"
  rel="stylesheet"
/>

Add a container to the <body> of your HTML file.

<div id="mly" style="width: 400px; height: 300px;"></div>

The global UMD name for MapillaryJS is mapillary. Include the following script in the <body> of your HTML file.

<script>
var { Viewer } = mapillary;

var viewer = new Viewer({
  accessToken: "<your access token>",
  container: "mly",
  imageId: "<your image ID for initializing the viewer>",
});
</script>

Documentation

Code of Conduct

Facebook has adopted the Contributor Covenant as its Code of Conduct, and we expect project participants to adhere to it. Please read the full text so that you can understand what actions will and will not be tolerated.

License

MapillaryJS is MIT licensed.

mapillary-js's People

Contributors

abbe98 avatar aniket-kale avatar caboosey avatar dependabot[bot] avatar gyllen avatar mdiener21 avatar mlopezantequera avatar nickplesha avatar npmcdn-to-unpkg-bot avatar oscarlorentzon avatar paulinus avatar raykendo avatar tmcw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapillary-js's Issues

Image size handling

Make it possible to either set the image size in the viewer constructor or handle it internally based on the execution environment.

Make 640 the default size.

Add GlRenderer and DOMRenderer

After running with the UI concept for a while its pretty clear that we need a better place for rendering both for gl and DOM content. I suggest we create two renderers a GlRenderer and a DOMRender and instead of seeing the UIs as endpoints they will have access to a service where they can push data to render.

                            +----------------+
                            |                |
                            | State Context  |
                            |                |
                            +-------.--------+
                                    .
                                    .
                                    .
                                    .
                            +-------.--------+
                            |                |
                            |      UI        |
                            |                |
                            +----------------+
                                 -/   \--
                              --/        \--
                           --/              \--
                         -/                    \--
                +-------o-------+        +--------\-------+
                |               |        |                |
                |  DOMRenderer  |        |    GlRenderer  |
                |               |        |                |
                +---------------+        +----------------+

The renderer will have a rx pipeline as input for the Renderers, using the AnimationFrame as scheduler for the GlRenderer is probably a good idea.

URL util class

Create a class for the URLs used in the library to avoid duplication.

Create a DirectionUI

A UI that will both work with panoramas and normal photos. It will consist of direction arrows (panoramas and perspective photos) and turn left/right arrows (perspective photos). This will be a default UI. For the time being the experience will be similar to what is at mapillary.com.

Update PlayerUI to match state

I created a naive PlayerUI. However Im not sure how to handle the state API. The solution might be to remove passed nodes in the trajectory per default.

Fire movestart and moveend events

Subscribe to state and fire movestart and moveend events appropriately.

The events should be based on the trajectory length, the current trajectory index and the alpha value.

Create JourneyUI as demo

Input is sequences and images. Start image in a sequence and end image in a sequence. Also add images that could be annotated with text. Journey should make a shorter stop on these images.

FrameAnimation Rate

Not sure this is a bug, but Im running a screen thats on 30hz, this causes my animations to be half the speed of what you probably see them in.

Create a Cover UI

The main purpose of this UI would be to prevent from loading unnecessary data, until activated.

Proposition: a container covering the whole area of the viewer, which is clickable and where clicked it initializes the viewer. Doing it that way requires finding some metaphor for activating the viewer. It's easy for platforms like YouTube or Vimeo where the play button makes sense.

What action/metaphor should we use, so we don't throw unnecessary decisions at the user? Let's discuss it here.

UIService compiler error

Locally the Typescript compiler gives the following error when running gulp ts:

TypeScript error: src/viewer/UIService.ts(59,35): Error TS2511: Cannot create an instance of the abstract class 'UI'.

This is not logged when running in CircleCI.

It is still possible to run the library in the browser.

Keyboard navigation

Keyboard navigation should handle all directions as well as panorama edges.

Naming / naming conventions for components related to UI

Continuing the discussion started by @knikel in #19. Think it is important enough to merit its own issue.

The name UI is not really capturing the whole concept of the components that live in the UI folder.

We currently have components/classes doing essentially one of the following five things in the UI folder:

  • GL rendering - Registers to the GLRenderer to render scenes (GLUI)
  • DOM rendering - Registers to the DOMRenderer to render HTML elements (SimpleNavUI)
  • Displaying UI - Creates and shows a complete UI (CoverUI)
  • Handling events - Handles DOM events and reacts on them (KeyboardUI)
  • Intelligent actions - Subscribes to streams and performs intelligent actions based on their combination (SimplePlayUI)

As said most of these components are not really UIs by them self. What these components do when combined together though is creating a User Experience. A GLImagePlane component, a DOMNavigation, a MouseHandler and a KeyboardHandler as well as a CacheBot and a PlayBot together creates a UX.

With this view of things the UI folder should be renamed to UX, base classes or interfaces should be named UXComponentBase or IUXComponent respectively.

For GL and DOM components the convention could be to prefix or suffix with GL or DOM. Handlers can be suffixed by Handler and bots by Bot. There could be five folders initially under the UX folder:

GL
DOM
Handler
Bot
General

Create textures without the TextureLoader in GLUI.

Avoid using the TextureLoader because it relies on the images being cached in the browser. Use the cached image element on the node class to create the texture directly using the Texture constructor.

Zoom functionality

It should be possible to zoom in and out when looking at a panorama. Zoom should be a property on the state and the state should expose a method for changing the zoom. There should be max and min zoom levels.

The mouse handler should handle wheel events and zoom accordingly.

A decision needs to be taken regarding if it should be possible to move when in zoomed state.

Zoom should be reset when arriving at a perspective image.

Create a single set of UIs

To to launch if none are specified at initialization of Lib. Make use of this in examples so we get gl effect.

Create ObjectUI

We want to display objects located in images. There will be many sources of objects that we want to display. They do share some common attributes though.

  1. They have a location in longitude/latitude
  2. They contain meta information in a key/value
  3. They may or may not be editable

I suggest the current construction of a new UI

                                            +----------------+
                                            |                |
                                            | State Context  |
                                            |                |
              +----------------+            +-------.--------+
              |                |                    .
Service X ->  | Service X Glue ..                   .
              |                | ..                 . CurrentNode
              +----------------+   ..               .
                                    ....    +-------.--------+
                                       .... |                |
                     Generic Object API   ...   ObjectUI     |
                                       ...  |                |
              +----------------+    ...     +-------.--------+
              |                | ...                .
Service Y ->  | Service Y Glue ..                   . Render in Three.js canvas
              |                |                    . (How is to be decided)
              +----------------+                    .                           

By using a generic Object API we are able to integrate new components by just creating a new glue component.

Uncaught error when calling Navigator.moveDir if no edge exist in specified direction

When calling and subscribing to Navigator.moveDir for a direction that is not represented among the edges for the current node the application crashes with the following error message:

Uncaught TypeError: Cannot read property 'subscribe' of null

The subscriber gets null back instead of an observable where the first item is null.

This happens everywhere where a direction is not represented, e.g. when moving in the STEP_LEFT direction for the K0vg7We6gvg4xbN0ubve1g node.

This is currently handled in the keyboard handler by checking if the direction actually exists before calling Navigator.moveDir.

Clear functionality in DOMRenderer

It should be possible for a DOMUI to clear its hash and therefore its content in the virtual DOM with an method on the DOMRenderer similar to the functionality in the GLRenderer:

public clear(name: string): void {
return this._clear$.onNext(name);
}

this._clear$
.map<IGLRenderHashesOperation>((name: string) => {
return (hashes: IGLRenderHashes): IGLRenderHashes => {
delete hashes[name];
return hashes;
};
})
.subscribe(this._renderOperation$);

DOMUIs should clear their hash (and release potential memory) on deactivation.

Adjust to different aspect ratios within GL handlers and renderer

Right now the GLUI is hardcoded to a 4:3 aspect ratio. Enforcing the container to a 4:3 ratio can by done in CSS. This is not what we want though.

The GLRenderer and the WebGL handlers should be able to handle all aspect ratios, either through letterboxing or through filling the screen in the optimal way depending on image type, image orientation and current aspect ratio.

Preferably the letterbox/fill behaviour should be configurable.

Perspective navigation UI

Create a navigation UI with step arrows pointing in the correct world direction with respect to the current camera.

Reset graph when lat lon of current node changes a lot

When the latitude or longitude of the node that is to be set on state changes a lot the graph should be reset and the reference lat lon updated according to the new node.

The trajectory of the state needs to be handled, probably reset.

Panorama support

  • Render panorama images on spheres in GLUI.
  • Look around functionality in State.
  • Mouse drag handler using state API for looking around.

What should be a default set of enabled UI?

It would be great if we could start deciding what set of UIs should be enabled by default in mapillary-js. Below is my take on what's essential for the initial version. Bear in mind that some of these could be disabled, with an option flag when initializing the viewer.

Current list of UI/features we should take into consideration:

  • AttributionUI - Displays attribution for the user, links to mapillary.com
  • CoverUI - Downloads a 320px photo, sets it as a background cover above all the other UI elements in the viewer container. Displays a button which will activate other UIs and will start fetching data in the future (doesn't work yet).
  • DetectionsUI - Makes an API call to /or endpoint for the given photo, displays rectangles with detected traffic signs on top of the viewer.
  • EventUI - Emits various events, to which mapillary-js user can hook into
  • GlUI - The heart of mapillary-js πŸ˜‰
  • KeyboardUI - Allows navigation using the keyboard
  • LoadingUI - Display loading progress as a 2px bar in the top of the viewer.
  • SimpleCacheUI - Caches the fetched data in case the user returns to the photo previously visited
  • SimpleNavUI - Displays direction arrows in various corners/at various edges of the viewer.
  • SimplePlayUI - Allows to play/stop playing of sequences
  • SimpleUI - Canvas based viewer

Proposition: I think, we should have a set of sane defaults for most uses. Let's start with the most important UIs: GlUI and SimpleUI. I would say that we should also have GlUI enabled by default, and SimpleUI should be its' fallback in case the system where mapillary-js is displayed doesn't support WebGL. Next, DirectionsUI should always be displayed, but we should provide means to toggle it. For the SimpleUI, when no WebgGL has been detected, we fall back to SimpleNavUI, since this viewer won't display panoramas. CoverUI should be also enabled by default, since it prevents loading unnecessary data and handles the scenario when multiple viewers are within the one view. AttributionUI is essential too as we want to give credit to the community (username links to the profile) and there is also a link to the photo on mapillary.com. We should display loading progress by default through LoadingUI. SimpleCacheUI should be enabled by default too, so we don't make unnecessary requests. EventUI is a no brainer, we want everyone to be able to hook into the events without doing any extra work on their side.

Proposed essential UIs/features: GlUI, CoverUI, LoadingUI, Directions, SimpleCacheUI - SimpleUI would be used only after internal feature check.

Regarding optional UIs… KeyboardUI is a tricky one, since the library consumer might have event handlers attached to keys already. I would say this should be enabled when specified. Last, SimplePlayUI, this is a really cool feature, but I'm totally unsure whether it should be enabled by default? mly.Viewer.play() is an appealing option, though.

WDYT?

Motionless transition logic

Create functionality in state regarding motionless transitions and handle when showing image planes in GLUI.

Create PlayUI

Add button that will be either stop symbol or plat symbol.

Cleanup Documentation

Clean up documentation for 1.0 release my suggestion is.

1. Remove all classes except Viewer
2. Add the IViewerOptions Struct

Orbit state implementation

Create an orbit state implementation with methods for changing the camera position through different camera deltas.

Handle unworthy nodes

Unworthy nodes should be created at the edges of tiles. When navigating to the unworthy nodes the surrounding tiles should be fetched and the edges for the unworthy nodes should be recalculated.

Waiting state implementation

Create a passive state implementation with a method for changing alpha. This state will be used for functionality like dragging through sequences.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.