Getting Directions

Goal: This guide will show you how to add directions functionality to your application. Users will be able to select an origin and destination, get a route between them, and step through the directions on the map. This step builds on the search and details UI from Step 3, introducing a new directions panel and integrating the MapsIndoors DirectionsService and DirectionsRenderer.

SDK Concepts Introduced:

  • Using the DirectionsService to calculate routes between locations.

  • Using the DirectionsRenderer to display and step through routes on the map.

  • Using directionsRenderer.setRoute() to display a calculated route on the map.

  • Using directionsRenderer.setStepIndex() to navigate to a specific step in the route.

  • Using directionsRenderer.nextStep() and directionsRenderer.previousStep() for step navigation.

  • Using directionsRenderer.getLegIndex() and directionsRenderer.getStepIndex() to track current position.

Prerequisites

  • Completion of Step 3: Show the Details. Your app should already support searching for locations and viewing details.

  • Your MapsIndoors API Key and Google Maps API Key should be correctly set up. We will continue using the demo API key 02c329e6777d431a88480a09 and venue ID dfea941bb36964e728df92d3d for this example.

Update index.html

Open your index.html file. Add a new directions panel inside the existing .panel container:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MapsIndoors</title>
    <link rel="stylesheet" href="style.css">
    <!-- Google Maps JavaScript API -->
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY"></script>
    <script src="https://app.mapsindoors.com/mapsindoors/js/sdk/4.41.0/mapsindoors-4.41.0.js.gz"
            xintegrity="sha384-3lk3cwVPj5MpUyo5T605mB0PMHLLisIhNrSREQsQHjD9EXkHBjz9ETgopmTbfMDc"
            crossorigin="anonymous"></script>
</head>

<body>
    <div id="map"></div>
    <div class="panel">
        <div id="search-ui" class="flex-column">
            <input type="text" id="search-input" placeholder="Search for a location...">
            <ul id="search-results"></ul>
        </div>
        <div id="details-ui" class="hidden">
            <h3 id="details-name"></h3>
            <p id="details-description"></p>
            <button id="details-directions" class="details-button details-action-button">Get Directions</button>
            <button id="details-close" class="details-button">Close</button>
        </div>
        <div id="directions-ui" class="hidden flex-column">
            <h3>Directions</h3>
            <div class="directions-inputs">
                <input type="text" id="origin-input" placeholder="Choose origin...">
                <ul id="origin-results" class="directions-results-list"></ul>
                <input type="text" id="destination-input" placeholder="Choose destination..." disabled>
            </div>
            <button id="get-directions" class="details-button details-action-button">Show Route</button>
            <div class="directions-step-nav">
                <span id="step-indicator"></span>
                <button id="prev-step" class="details-button">Previous</button>
                <button id="next-step" class="details-button">Next</button>
            </div>
            <button id="directions-close" class="details-button">Close Directions</button>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

Explanation of index.html updates

  • The #details-ui panel now includes a "Get Directions" button, allowing users to open the directions panel for the selected location.

  • The #directions-ui panel is added to the .panel container. This new panel contains:

    • Input fields for origin and destination.

    • A button to get directions.

    • Step navigation controls (step indicator, previous/next buttons).

    • A close button for the directions panel.

  • All panels (#search-ui, #details-ui, #directions-ui) use consistent class and ID naming, and only one is visible at a time, managed by the show/hide functions in the JavaScript.

Update style.css

Add styles for the new directions UI elements:

Explanation of style.css updates

  • Styles for the new #directions-ui panel and its child elements are added:

    • .directions-inputs styles the input fields and results list for selecting origin and destination.

    • .directions-results-list styles the list of search results for the origin input.

    • .directions-step-nav and #step-indicator style the step navigation controls.

Update script.js

Add the following logic for directions and UI state management.

Explanation of script.js updates:

  • UI State Management:

    • New constants like directionsUIElement are added to reference the new directions panel in the DOM.

    • The existing UI state management functions (showSearchUI(), showDetailsUI()) are updated to explicitly hide the directionsUIElement.

    • New functions showDirectionsUI() and hideDirectionsUI() are introduced to manage the visibility of the directions panel, ensuring it's mutually exclusive with the search and details panels.

    • The "Get Directions" button (detailsDirectionsButton) in the details panel now has an event listener that calls showDirectionsPanel(), passing the currentDetailsLocation to pre-fill the destination.

    • The directionsCloseButton listener is added to hide the directions UI, show the details UI, and make the directionsRenderer invisible when directions are closed, providing a clear exit path.

  • Location Click Handling:

    • The script maintains the unified click handler pattern established in previous steps. The handleLocationClick function continues to serve as the central entry point for user interactions with locations, responding to both map POI clicks and search result clicks.

    • This consistent pattern ensures that when a user clicks on a location (either on the map or in search results), the following actions always occur:

      • The map pans to the selected location using mapsIndoorsInstance.goTo(location)

      • The floor is set to the location's floor with mapsIndoorsInstance.setFloor(location.properties.floor)

      • The location is visually selected on the map using mapsIndoorsInstance.selectLocation(location)

      • The location details panel is shown via showDetails(location)

    • This unified approach ensures a consistent user experience regardless of how locations are selected.

  • Directions Panel and Origin/Destination Selection:

    • New DOM element references are established for directions-related UI elements: originInputElement, originResultsElement, destinationInputElement, getDirectionsButton, prevStepButton, nextStepButton, stepIndicator, and directionsCloseButton.

    • State variables selectedOrigin, selectedDestination, currentRoute, and directionsRenderer are declared to manage the directions workflow state.

    • The showDirectionsPanel(destinationLocation) function resets the directions state, pre-fills the destination input with the selected location's name, and shows the directions UI.

    • An origin search is implemented with an input event listener on originInputElement, which calls the onOriginSearch() function. This function uses mapsindoors.services.LocationsService.getLocations() to search for origin locations, similar to the main search functionality.

  • Route Calculation:

    • When the user clicks the "Show Route" button (getDirectionsButton), the script checks if both selectedOrigin and selectedDestination are set.

    • It extracts coordinates and floor information from the location objects' properties.anchor and properties.floor.

    • A new instance of mapsindoors.services.DirectionsService() is created.

    • The getRoute() method is called with origin and destination parameters to calculate the route.

    • The route is stored in the currentRoute variable for later reference.

  • Route Display and Step Navigation:

    • Any existing directionsRenderer is hidden before creating a new one.

    • A new mapsindoors.directions.DirectionsRenderer is instantiated with the mapsIndoorsInstance, fitBounds: true for automatic map adjustment, and styling options.

    • The renderer is configured with the calculated route via directionsRenderer.setRoute(route).

    • The renderer is set to display the first step of the first leg with directionsRenderer.setStepIndex(0, 0).

    • The showCurrentStep() function updates the step indicator text and enables/disables the navigation buttons based on the current position in the route.

    • Event listeners for the navigation buttons call directionsRenderer.previousStep() and directionsRenderer.nextStep() respectively, followed by showCurrentStep() to update the UI.

  • Workflow Integration:

    • The script carefully integrates the directions functionality with the existing search and details features.

    • The details panel now includes a "Get Directions" button that transitions to the directions workflow.

    • The directions panel allows users to return to the details view via the close button.

    • All three UI states (search, details, directions) are mutually exclusive, providing a clear and focused user interface.

These updates allow users to search for a location, view its details, and get step-by-step directions between two locations within your venue, all within a clear and interactive UI.

Expected Outcome

  • Users can search for a location, view its details, and click "Get Directions" to open the directions panel.

  • When the directions panel opens from the details view, the destination input is pre-filled with the selected location's name and is disabled.

  • The user can type in the origin input to search for and select an origin location.

  • After both origin and destination are selected, clicking "Show Route" calculates and displays the route on the map.

  • The map updates to show the full route, and the step navigation controls become active.

  • Users can use the "Previous" and "Next" buttons to step through the route, with the map highlighting the current step and the step-indicator updating accordingly.

  • Only one panel (search, details, or directions) is visible at a time.

  • Clicking the "Close Directions" button returns to the details panel and hides the route from the map.

Troubleshooting

  • If the route is not shown after clicking "Show Route", ensure both origin and destination are selected and that the locations have valid anchor coordinates.

  • If the map does not update, check for errors in the browser console and verify your API keys and venue ID.

  • If the UI panels do not switch as expected, ensure the show/hide functions are called correctly and that the correct classes are applied.

Last updated

Was this helpful?