# Integration Example

Discover the online example of the API integration by clicking on [this link](https://maps.jakarto.com/src/api/demo/index.html)

<figure><img src="https://github.com/jakarto3d/docs-gitbook/blob/main/space-jakartowns/en/.gitbook/assets/image%20(1).png" alt=""><figcaption><p>Screenshot of the output achieved with the code below.</p></figcaption></figure>

````html
<!DOCTYPE html>
<html lang="en">

<head>
   

```html
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Jakartowns JavaScript API Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            padding-bottom: 1cm; /* Add space for the footer */
        }

        h1 {
            text-align: center;
        }

        .container {
            display: flex;
            justify-content: center;
            align-items: flex-start;
        }

        #JakartownsContainer {
            align-items: center;
            position: relative;
            width: 40%;
            left: 5%;
            aspect-ratio: 16 / 9;
        }

        #formContainer {
            flex: 1;
            margin-left: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        form {
            text-align: center;
            margin-top: 20px;
        }

        form label {
            display: block;
            font-weight: bold;
            margin-bottom: 5px;
        }

        form input[type="text"] {
            padding: 5px;
            margin-bottom: 10px;
            width: 200px;
        }

        form input[type="button"] {
            padding: 5px 10px;
            margin: 10px 5px;
            background-color: #4caf50;
            color: white;
            border: none;
            cursor: pointer;
        }

        #logs {
            text-align: center;
            margin-top: 20px;
        }

        #goToJakartownsBtn {
            padding: 8px 16px;
            background-color: #4285f4;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 20px;
        }
    </style>
</head>

<body>
    <h1>Jakartowns JavaScript API Demo</h1>
    <div id="logs"></div>
    <div class="container">
        <div id='JakartownsContainer'>
            <div id="app"></div>
        </div>
        <div id="formContainer">
            <form>
                <label for="longitude">Longitude:</label>
                <input type="text" id="longitude" name="longitude" placeholder="Enter longitude" required><br>
                <label for="latitude">Latitude:</label>
                <input type="text" id="latitude" name="latitude" placeholder="Enter latitude" required><br>
                <label for="tilt">Tilt:</label>
                <input type="text" id="tilt" name="tilt" placeholder="Enter tilt"><br>
                <label for="pan">Pan:</label>
                <input type="text" id="pan" name="pan" placeholder="Enter pan"><br>
                <label for="fov">Field of View:</label>
                <input type="text" id="fov" name="fov" placeholder="Enter FOV"><br>
                <input type="button" id="setPositionBtn" value="Set Position">
                <input type="button" id="setTiltBtn" value="Set Tilt">
                <input type="button" id="setPanBtn" value="Set Pan">
                <input type="button" id="setFovBtn" value="Set FOV">
            </form>
            <button id="goToJakartownsBtn">Go to Jakartowns Web App</button>

        </div>
    </div>
    <script>
        const logs = document.querySelector('#logs');

        async function print(txt) {
            await logs.insertAdjacentHTML('beforebegin', txt);
        }
    </script>
    <script>
        async function isAuthenticated() {
            // Request to confirm the authentication on Jakarto platform
            const confirmation_request = await fetch('https://account.jakarto.com/auth', {
                credentials: 'include',
                method: 'GET',
            });
            await confirmation_request.text();
            return confirmation_request.status === 200;
        }

        async function main() {
            print('Checking authentication...<br/>');
            let isConnected = await isAuthenticated();
            print(`Connected: ${isConnected}<br/>`);

            if (!isConnected) {
                print('User not authenticated. Sending request to connect to Jakarto webservices...<br/>');

                const form = new FormData();
                // TODO: Replace values by user credentials
                form.append('email', 'TO_REPLACE');
                form.append('password', 'TO_REPLACE');

                // Request to set the connection cookie
                // ⚠ Authentication will work even if the above credentials are incorrect if you already have a valid cookie (by connecting to the Jakarto web platform using the regular web page)
                // If you want to enforce a new cookie, please first disconnect your account from https://account.jakarto.com
                await fetch('https://account.jakarto.com/users/login', {
                    headers: {
                        'content-type': 'application/x-www-form-urlencoded',
                    },
                    body: new URLSearchParams(form),
                    method: 'POST',
                    mode: 'cors',
                    credentials: 'include',
                    redirect: 'manual', // avoid redirection... it will cause a CORS error on jakartowns.jakarto.com/ route
                });
            } else {
                print('Already connected<br/>');
            }

            print('Confirming authentication...<br/>');
            isConnected = await isAuthenticated();
            print(`Connected: ${isConnected}<br/>`);

            if (!isConnected) {
                print('User cannot connect. Please check credentials.<br/>');
                return;
            }

            print('<br/>Example with <b>frontend API</b>:<br/>');

            function loadScript(javascriptUrl) {
                return new Promise((resolve, reject) => {
                    const script = document.createElement('script');
                    script.src = javascriptUrl;
                    script.async = true;
                    script.onload = resolve;
                    script.onerror = reject;
                    document.head.appendChild(script);
                });
            }

            print(`Frontend API status: script not yet loaded. Expected status ==> false. Status: ${window.hasOwnProperty('jakartowns')}<br/>`);
            await loadScript('https://maps.jakarto.com/api/v1.js');
            print(`Frontend API status: script should be loaded. Expected status ==> true. Status: ${window.hasOwnProperty('jakartowns')}<br/>`);

            async function setPosition(viewer, wantedPosition) {
                const jakartownsData = await viewer.setPosition(wantedPosition);
                console.log(`Current image UID: ${JSON.stringify(jakartownsData.uid)}`);
                console.log(`Distance between targeted lngLat and panorama lngLat: ${JSON.stringify(jakartownsData.distance)} km`);
            }

            async function setTilt(viewer, wantedTilt) {
                const tilt = await viewer.setTilt(wantedTilt);
                console.log(`Tilt set to: ${tilt}`);
            }

            async function setPan(viewer, wantedPan) {
                const pan = await viewer.setPan(wantedPan);
                console.log(`Pan set to: ${pan}`);
            }

            async function setFov(viewer, wantedFov) {
                const fov = await viewer.setFov(wantedFov);
                console.log(`FOV set to: ${fov}`);
            }

            const jakartownsOptions = {
                headerEnabled: true,
                minimapEnabled: false,
            };

            if (window.jakartowns === undefined) {
                const currentURL = window.location.origin;
                alert('You need to be connected to the Jakarto platform first. The page will redirect to the authentication page.');
                window.open(`https://account.jakarto.com/users/login?redirectTo=${currentURL}`, '_self');
            }

            window.jakartowns.app.create_jakartowns(
                '#app',
                jakartownsOptions,
                (viewer) => {
                    window.jakartowns_instance = viewer; // do anything with the viewer instance outside of this callback
                    console.log('Jakartowns instance is loaded');

                    // Listeners on client update (Jakartowns side)
                    window.addEventListener('position', (e) => {
                        // When the user changes their position
                        console.log('position event', e.detail);
                        document.getElementById('longitude').value = e.detail.longitude;
                        document.getElementById('latitude').value = e.detail.latitude;
                    });

                    window.addEventListener('rotation', (e) => {
                        // When the user changes the horizontal rotation of the view
                        console.log('rotation event', e.detail);
                        document.getElementById('pan').value = e.detail;
                    });

                    window.addEventListener('tilt', (e) => {
                        // When the user changes the vertical rotation of the view
                        console.log('tilt event', e.detail);
                        document.getElementById('tilt').value = e.detail;
                    });

                    window.addEventListener('fov', (e) => {
                        // When the user changes the field of view of the view
                        console.log('fov event', e.detail);
                        document.getElementById('fov').value = e.detail;
                    });

                    // API usage example
                    document.querySelector('#setPositionBtn').addEventListener('click', (

event) => {
                        const newLngLat = { latitude: document.getElementById('latitude').value, longitude: document.getElementById('longitude').value };
                        setPosition(viewer, newLngLat);
                    });

                    document.querySelector('#setTiltBtn').addEventListener('click', (event) => {
                        setTilt(viewer, document.getElementById('tilt').value);
                    });

                    document.querySelector('#setPanBtn').addEventListener('click', (event) => {
                        setPan(viewer, document.getElementById('pan').value);
                    });

                    document.querySelector('#setFovBtn').addEventListener('click', (event) => {
                        setFov(viewer, document.getElementById('fov').value);
                    });
                },
            );
        }

        main();

        function goToJakartownsWebApp() {
            const latitude = document.getElementById('latitude').value;
            const longitude = document.getElementById('longitude').value;
            const tilt = document.getElementById('tilt').value || '0';
            const pan = document.getElementById('pan').value || '0';
            const fov = document.getElementById('fov').value || '90';

            const url = `https://maps.jakarto.com/?lat=${latitude}&lng=${longitude}&pan=${pan}&tilt=${tilt}&fov=${fov}`;
            window.open(url, '_blank');
        }

        const goToJakartownsBtn = document.getElementById('goToJakartownsBtn');
        goToJakartownsBtn.addEventListener('click', goToJakartownsWebApp);

    </script>
</body>

</html>
````


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.jakarto.com/guide-jakartowns/en/developers/api-javascript/exemple-dintegration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
