Longdo Panorama API
Longdo Panorama API is designed to make it easier for web developers to include a panorama scene into a web site. The API comes with all necessary features and controls. With just a few line of code, developers will have ready-to-use panorama views on their web sites. The appearance and behaviors of API can be customized as needed. The API relies on WebGL technology (Adobe Flash replacement) which is supported by all modern web browsers in order to bring the best performance to users.
Basic usage
Include this <script> tag in your html file.
<script src="//api.longdo.com/pano/pano-api.min.js"></script>
Create a plceholder for panorama
<div id="pano"></div>
Initialize panorama
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
});
Here is the full source code.
<html>
<head>
<script src="//api.longdo.com/pano/pano-api.min.js"></script>
</head>
<body>
<div id="pano" style="width:100%; height:100%"></div>
<script>
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
});
</script>
</body>
</html>
You will get something looks like this.
You can also specify your own image server. For image server configuration document, please check coming soon
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
server: '//pano.longdo.com'
});
Options
There are a number of options you can specify when initializing panorama view, for example you can choose whether to show default controls.
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
server: '//pano.longdo.com',
panoControlUi: false,
panoWidgetUi: false,
});
For a full list of options, please check full option list
Showing panorama view alongside a map
Most users tends to accustom with viewing panorama alongside a map. By having a map that works together with panorama view, users can keep track of where they are and move to specific location in a much easier way. Longdo is kind enough to provide a nice map API called Longdo Map API with an awesome API document here.
To initialize a panorama view and a map that automatically works together, all developers have to do are:
- Create a map object (or see example below)
- Pass a map object to panorama view initialization option.
var map = new longdo.Map({
placeholder: document.getElementById('map'),
});
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
map: map,
});
Here is the full source code.
<html>
<head>
<script src="https://api.longdo.com/map/?key=3d89e6a907541b7e4855efc22f40c24c"></script>
<script src="//api.longdo.com/pano/pano-api.min.js"></script>
</head>
<body>
<div id="pano" style="position:absolute; width:50%; height:100%; left:50%"></div>
<div id="map" style="position:absolute; width:50%; height:100%;"></div>
<script>
var map = new longdo.Map({
placeholder: document.getElementById('map'),
});
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
map: map,
showPath: true // show blue lines representing road paths
});
</script>
</body>
</html>
Try dragging an orange human icon on to a map to move to specific location.
The orange icon on the map represents location and direction of panorama view. The blue points and lines on the map are locations that have panorama images. There are many more features enabled just by adding Longdo Map to Panorama API. We encourage developers to have a try and explore these cool features.
Controlling API via code
Once you have an instance of Panorama view (see how to create it here), you can control API's behaviors using various methods API has provided, for example:
Let's suppose you have created an instance like this.
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
});
- You can control zoom level using:
pano.zoomIn();
pano.zoomOut();
pano.zoom(20); // min zoom level
pano.zoom(90); // max zoom level
- You can jump to any location using:
pano.location({
lat: 13.722386,
lon: 100.529292
})
- You can move forward and backward from current position using:
pano.seek(10) // move forward 10 meters
pano.seek(-5) // move backward 5 meters
- You can tell API to look at a specific location using:
pano.lookAt({lat: 13.722298, lon: 100.529407}) // That is, Longdo office!
There are so many methods to control API. We just cannot mention them all here. If you are interested, please check the full list of methods here.
Callback
One of the most important thing besides having awesome features and controls is having accesses to various events happened in API. These accesses are usually referred as callbacks or event listeners
These callbacks are simply just regular functions. What special about them is they will be called automatically by API when something (event) happens, for example: the function onPositionChange() will be called with related information immediately after location of panorama view is changed. Callback functions can be created and passed to API like this:
var myCallback = {
onPositionChange: function (lat, lon, head, frameTime, frameName) {
console.log(`Panorama view just moved to new location at ${lat}, ${lon}`);
},
}
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
callback : myCallback
});
Other examples of frequently used callback functions are onViewChange(), onPathChange() and onZoomChange(). To check all available callback, please visit a full list of callback
Adding geometry objects
The even more interesting feature comes with Panorama API is adding geometry objects (Point, Line or Shape) to panorama scene. When you want specify a particular location on a map, you will need latitude and longitude coordinate. It goes the same for panorama scene, except you will need to have one more value, object's relative height(sometimes called z or altitude).
To add a point on panorama scene:
// create a pin at specific location
var pin = new longdo.PanoramaViewer.Pin({lat:14.503098 , lon:100.971659 , alt:22}, {
url: '//api.longdo.com/pano/server/images/measure-pin.png',
});
pano.pushPin(pin); // add a created pin to panorama scene
To add a line on panorama scene:
// create a line at specific locations
var line = new longdo.PanoramaViewer.Line([
{lat:14.503098 , lon:100.971659 , alt:22},
{lat:14.504098 , lon:100.972659 , alt:21}
]);
line.color(1,0,0,1); // color in RGBA order value range from 0.0 - 1.0, thus red.
pano.pushLine(line); // add a created line to panorama scene
After adding some points with different icons and lines with different color, you will get something like this.
You can also add animation to point objects:
// create a line at specific locations
pin.animation(longdo.PanoramaViewer.Animation.ANIMATE_BOUNCE);
See a full list of methods here
Measurement
If survey data is embedded with necessary positioning information (x, y, z, yaw pitch and row of a camera), Longdo Panorama API will support measuring objects in the scene. Supported measurement are
- Objects' real-world location (latitude, longitude, altitude).
- Distance between any points.
- Area among arbitrary points.
To see if a current scene support measurement, users can notice 'ruler' icon at top-right of the scene. If this icon is present, the API will be able to perform measurement on the current scene.
The easiest way to start measurement mode is clicking this icon. Then users will be prompt to click at a specific point on the scene. Right after users click on the scene, it will move to nearby location and show the red line across the scene. Users again will be prompt to click at the same point in the previous scene but from different view which will automatically lie on the red line. This is called 'Epipolar measurement', that is, to identify objects location, it need to be identified on two different perspective (in order to determine the depth/distance from us).
Another measurement technique is to use laser point cloud data. In order to use point cloud measurement, laser data must have been prepared on the server side. The advantage of using laser measurement is that users are required to click on the scene only once. It will be much more simpler than rely on epipolar measurement, but of course at the expense of back-end computation and data storage. If 'point cloud' icon is present at the top-right of the scene, current scene can be measured using laser technique. To start measuring, simply click at the ruler icon and click at object on the scene.
However, a huge disadvantage of using laser technique is only the areas that have laser point cloud can be measured. That is mean we cannot measure any objects where no laser point cloud on them. To see where laser point cloud are on the current scene, simply click 'point cloud' icon. A photo of current will be changed with the laser on it.
To enter measurement mode and get back the result. There three mode developer can choose.
- longdo.PanoramaViewer.MODE_MEASURE_POINT - same function with clicking at ruler icon.
- longdo.PanoramaViewer.MODE_GET_LOCATION - to get single point coordinate, clicking at multiple points will not form lines. Every time users click at a new point, the previous one will be removed.
- longdo.PanoramaViewer.MODE_GET_LINE_LOCATION - to get line coordinates, lines will be not associated with length label as the first mode does. To stop measurement simply double click on anywhere on the scene. The last clicking will not be recorded as a part of the final line. Line will be disappear after a double click.
- longdo.PanoramaViewer.MODE_VERTICAL_CLEARANCE - to measure vertical clearance. This mode is supposed to be used when laser is available and a camera is at the clearance. API will automatically determine height of nearby location and print out minimum height on a scene.
var pano = new longdo.PanoramaViewer({
placeholder: document.getElementById('pano'),
callback : {
onMessage : function (message, data){
console.log(message); // indicate category of measurement output.
console.log(data); // actual measurement data.
}
}
});
pano.mode(longdo.PanoramaViewer.MODE_GET_LINE_LOCATION);
// have users perform measurement, and wait for result from callback
All information about measurement will be sent back via 'onMessage' callback.
API Development
Sections below describe API internal works. These are mainly for API developers. If you are a user or a web developer who use API of out the box, this section is an optional reading.
Source code
Source code of the project is hosted at Longdo Gitlab. You will need an account to access the source code. The project may be distributed as an open source project in a near future, but as of now it is a close source project. If you need additional features or you want to customize a project in a certain way, please contact Longdo office. The contact is listed at the bottom of this document.
Build and run
git clone https://git.longdo.com/punyapat/longdo-map-pano
cd longdo-map-pano
npm install
npm run test
npm start
Open browser at http://localhost:8080, you should see something like this:
Production
npm run build
This will generate pano-api.min.js
which is a single Javascript file required to use an API. It will also generate content in /doc
which are documents you are reading now. Copy an entire project directory to a production site.
* You must delete source code in /js
if you are not using an apache
server for file hosting. The /js
is protected only by .htaccess
file.
API Internal
API is being developed using Javascript. Some of them are written using ES6 syntax, so Babel is required for converting them back to plain Javascript. It uses Webpack to pack all required files into single javascript file (pano-api.js
), see package.json
for more information. It uses AVA for unit test and Nightwatch for night watch test. pano-api.js
is minified using uglifyjs into pano-api.min.js
. This documents are generated from comments in Javascript files and README.md using jsdoc.
Workflow
All source code is stored in /js
. The main start point is in StreetView.js
. It defines longdo.PanoramaViewer class. This class holds other necessary classes e.g. SphereHD
, CubePin
and Measurement
. API is an WebGL application so the most important method is draw()
. Everything displayed on screen start their workflow from this method. Take a look inside draw()
you will see
cube.draw()
- render panorama images.drawShape()
- render polygon (if any).drawLine()
- render line (if any).drawPin()
- render pin (if any).
You can start tracking what is happening from draw()
. Detail of each class is described in comments.
Contact information
Metamedia Technology Co., Ltd. Rm. 407, 4F, Sathorn Square Office Tower, 98 North Sathorn Rd., Silom, Bangrak, Bangkok 10500 Thailand Tel: +66 2108 1790-1 | Fax: +66 2163 2878 | email: [email protected]