diff --git a/.gitbook/assets/Routing-directions.png b/.gitbook/assets/Routing-directions.png
new file mode 100644
index 0000000..a84a48c
Binary files /dev/null and b/.gitbook/assets/Routing-directions.png differ
diff --git a/.gitbook/assets/Screenshot 2023-10-20 at 12.43.03 PM.png b/.gitbook/assets/Screenshot 2023-10-20 at 12.43.03 PM.png
new file mode 100644
index 0000000..d60cbda
Binary files /dev/null and b/.gitbook/assets/Screenshot 2023-10-20 at 12.43.03 PM.png differ
diff --git a/.gitbook/assets/Screenshot 2023-10-20 at 12.43.15 PM.png b/.gitbook/assets/Screenshot 2023-10-20 at 12.43.15 PM.png
new file mode 100644
index 0000000..5959ebe
Binary files /dev/null and b/.gitbook/assets/Screenshot 2023-10-20 at 12.43.15 PM.png differ
diff --git a/.gitbook/assets/Screenshot 2023-10-20 at 12.43.38 PM.png b/.gitbook/assets/Screenshot 2023-10-20 at 12.43.38 PM.png
new file mode 100644
index 0000000..a1f4dd6
Binary files /dev/null and b/.gitbook/assets/Screenshot 2023-10-20 at 12.43.38 PM.png differ
diff --git a/.gitbook/assets/desk_to_room_optimizer.gif b/.gitbook/assets/desk_to_room_optimizer.gif
new file mode 100644
index 0000000..53e5892
Binary files /dev/null and b/.gitbook/assets/desk_to_room_optimizer.gif differ
diff --git a/.gitbook/assets/externalIdDisplayRule (1).gif b/.gitbook/assets/externalIdDisplayRule (1).gif
new file mode 100644
index 0000000..09cfc6a
Binary files /dev/null and b/.gitbook/assets/externalIdDisplayRule (1).gif differ
diff --git a/.gitbook/assets/externalIdDisplayRule.gif b/.gitbook/assets/externalIdDisplayRule.gif
new file mode 100644
index 0000000..09cfc6a
Binary files /dev/null and b/.gitbook/assets/externalIdDisplayRule.gif differ
diff --git a/.gitbook/assets/externalIdsDisplayRules.gif b/.gitbook/assets/externalIdsDisplayRules.gif
new file mode 100644
index 0000000..cd1710a
Binary files /dev/null and b/.gitbook/assets/externalIdsDisplayRules.gif differ
diff --git a/.gitbook/assets/image (1).png b/.gitbook/assets/image (1).png
new file mode 100644
index 0000000..cbdaabc
Binary files /dev/null and b/.gitbook/assets/image (1).png differ
diff --git a/.gitbook/assets/image (2).png b/.gitbook/assets/image (2).png
new file mode 100644
index 0000000..e72bfe0
Binary files /dev/null and b/.gitbook/assets/image (2).png differ
diff --git a/.gitbook/assets/image (3).png b/.gitbook/assets/image (3).png
new file mode 100644
index 0000000..30b4c5c
Binary files /dev/null and b/.gitbook/assets/image (3).png differ
diff --git a/.gitbook/assets/image (4).png b/.gitbook/assets/image (4).png
new file mode 100644
index 0000000..99bcf4c
Binary files /dev/null and b/.gitbook/assets/image (4).png differ
diff --git a/.gitbook/assets/image (5).png b/.gitbook/assets/image (5).png
new file mode 100644
index 0000000..6826c15
Binary files /dev/null and b/.gitbook/assets/image (5).png differ
diff --git a/SUMMARY.md b/SUMMARY.md
index 8d35ad3..8daab63 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -7,6 +7,7 @@
* [Web](sdks-and-frameworks/web/README.md)
* [Getting Started](sdks-and-frameworks/web/getting-started/README.md)
* [Map Engine Setup](sdks-and-frameworks/web/getting-started/prerequisites.md)
+ * [Create a Search Experience](sdks-and-frameworks/web/getting-started/create-a-search-experience.md)
* [Tutorial](sdks-and-frameworks/web/getting-started/tutorial.md)
* [Map Visualization](sdks-and-frameworks/web/map-visualization/README.md)
* [Display Rules in Practice](sdks-and-frameworks/web/map-visualization/display-rules-in-practice.md)
@@ -14,7 +15,7 @@
* [Switching Solutions](sdks-and-frameworks/web/map-visualization/switching-solutions.md)
* [Remove Labels from Buildings and Venues](sdks-and-frameworks/web/remove-labels-from-buildings-and-venues.md)
* [Change Building Outline](sdks-and-frameworks/web/change-building-outline-color.md)
- * [Turn Off Collisions Based on Zoom Level](sdks-and-frameworks/web/displaying-objects/turn-off-collisions-based-on-zoom-level.md)
+ * [Managing Collisions Based on Zoom Level](sdks-and-frameworks/web/map-visualization/managing-collisions-based-on-zoom-level.md)
* [3D Maps](key-features/3d-maps/README.md)
* [Managing your 3D Maps](sdks-and-frameworks/web/map-visualization/3d-maps/managing-your-3d-maps.md)
* [Wayfinding](sdks-and-frameworks/web/directions-and-routing/README.md)
@@ -23,8 +24,10 @@
* [Directions Renderer](sdks-and-frameworks/web/wayfinding/directions-renderer.md)
* [User's Location as Point of Origin](sdks-and-frameworks/web/directions-and-routing/directions-renderer/users-location-as-point-of-origin.md)
* [Search](sdks-and-frameworks/web/search/README.md)
- * [Basic Searching](sdks-and-frameworks/web/basic-searching.md)
- * [External IDs](sdks-and-frameworks/web/other-guides/external-ids.md)
+ * [Search Operations](sdks-and-frameworks/web/search/search-operations.md)
+ * [Searching](sdks-and-frameworks/web/search/searching.md)
+ * [Using External ID, Geospatial Joins](sdks-and-frameworks/web/other-guides/external-ids.md)
+ * [Utilizing MapsIndoors Web Components and Other Searches](sdks-and-frameworks/web/search/utilizing-mapsindoors-web-components-and-other-searches.md)
* [Map Management](sdks-and-frameworks/web/map-management/README.md)
* [Data Visualization](sdks-and-frameworks/web/data-visualization/README.md)
* [Booking](sdks-and-frameworks/web/booking/README.md)
diff --git a/sdks-and-frameworks/integration-api/README.md b/sdks-and-frameworks/integration-api/README.md
index 33dcdc4..258d1a5 100644
--- a/sdks-and-frameworks/integration-api/README.md
+++ b/sdks-and-frameworks/integration-api/README.md
@@ -1,17 +1,5 @@
# Integration API
-**Documentation reflects the latest version:**
-
-You can find documentation on legacy versions here:
-
-{% content-ref url="../../other-docs/legacy-docs/" %}
-[legacy-docs](../../other-docs/legacy-docs/)
-{% endcontent-ref %}
-
-***
-
-### Introduction and Getting Started[](https://docs.mapsindoors.com/api#introduction-and-getting-started)
-
The MapsIndoors Integration API offers an alternative to changing your Mapsindoors data via the [CMS](https://cms.mapsindoors.com/). From this API you can get, add, change and delete either directly via third party tools like [Postman](https://www.postman.com/) or via the provided Swagger frontend.
You can access data through the Integration API using a range of endpoints. The endpoints are described in the Swagger interface definition: [https://integration.mapsindoors.com/doc](https://integration.mapsindoors.com/doc/index.html)
diff --git a/sdks-and-frameworks/web/basic-searching.md b/sdks-and-frameworks/web/basic-searching.md
deleted file mode 100644
index 93944a1..0000000
--- a/sdks-and-frameworks/web/basic-searching.md
+++ /dev/null
@@ -1,158 +0,0 @@
----
-layout:
- title:
- visible: true
- description:
- visible: true
- tableOfContents:
- visible: true
- outline:
- visible: true
- pagination:
- visible: false
----
-
-# Basic Searching
-
-Searching through your MapsIndoors data is an key part of a great user experience with your maps. Users can look for places to go, or filter what is shown on the map.
-
-Searches work on all MapsIndoors geodata. It is up to you to create a search experience that fits your use case. To help you in this, there is a range of filters you can apply to the search queries to get the best results. E.g. you can filter by Categories, search only a specific part of the map or search near a Location.
-
-All three return a list of Locations from your solution matching the parameters they are given. The results are ranked upon the three following factors:
-
-* If a "near" parameter is set, how close is the origin point to the result?
-* How well does the search input text match the text of the result (using the "Levenshtein distance" algorithm)?
-* Which kind of geodata is the result (e.g. Buildings are ranked over POIs)?
-
-This means that the first item in the search result list will be the one best matching the three factors.
-
-See the full list of parameters:
-
-| Parameter | Description |
-| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
-| take | Max number of Locations to get |
-| Skip | Skip the first number of entries |
-| categories | A list of Categories to limit the search to |
-| Parents | A list of Building or Venue IDs to limit the search to |
-| Types | A list of Types to limit the search to |
-| Bounds | Limits the result of Locations to a bounding area |
-| Floor | Limits the result of Locations to be on a specific Floor |
-| Near | Sorts the list of Locations on which Location is nearest the point given |
-| Depth | The Depth property makes it possible to get "x" amount of descendants to the given parent. The default for this is 1 (eg. Building > Floor) |
-
-#### Example of Creating a Search Query[](https://docs.mapsindoors.com/searching#example-of-creating-a-search-query)
-
-See the full list of parameters in the [reference guide](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations):
-
-```javascript
-const searchParameters = {
- q: 'Office',
- near: { lat: 38.897579747054046, lng: -77.03658652944773 }, // // Blue Room, The White House
- take: 1
-}
-
-mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
- console.log(locations);
-});
-```
-
-## Display Search Results on the Map[](https://docs.mapsindoors.com/searching#display-search-results-on-the-map)
-
-When displaying the search results, it is helpful to filter the map to only show matching Locations. Matching Buildings and Venues will still be shown on the map, as they give context to the user, even if they aren't selectable on the map.
-
-#### Example of Filtering the Map to Display Searched Locations on the Map
-
-```javascript
-const searchParameters = {
- q: 'Office',
- near: { lat: 38.897579747054046, lng: -77.03658652944773 }, // // Blue Room, The White House
- take: 1
-}
-
-mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
- mapsIndoorsInstance.filter(locations.map(location => location.id), false);
-});
-```
-
-### Clearing the Map of Your Filter[](https://docs.mapsindoors.com/searching#clearing-the-map-of-your-filter)
-
-After displaying the search results on your map you can then clear the filter so that all Locations show up on the map again.
-
-#### Example of Clearing Your Map Filter to Show All Locations Again
-
-```javascript
-mapsIndoorsInstance.filter(null);
-```
-
-#### Display Locations as List[](https://docs.mapsindoors.com/searching#display-locations-as-list)
-
-You can also search for Locations, and have them presented to you as a list, instead of just displaying them on the map.
-
-The full code example is shown in the JSFiddle below which will be examined below.
-
-#### Search[](https://docs.mapsindoors.com/searching#search)
-
-The `mapsindoors.services.LocationsService` class exposes the `getLocations` function that enables you to search for Locations.
-
-It will return a promise that gets resolved when the query has executed.
-
-See [mapsindoors.services.LocationsService](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html) for more information.
-
-```javascript
-searchElement.addEventListener('input', debounce((e) => {
- const value = e.target.value;
- if (value > '') {
- mapsindoors.services.LocationsService.getLocations({ q: value, includeOutsidePOI: true })
- .then(displayResults)
- .then(filterMap);
- } else {
- clearResults();
- clearFilter();
- }
-}, 500));
-```
-
-The `debounce` method is there to ensure that the service is not being called in rapid succession. This method delays the execution of the function by 500ms, unless `debounce` is called again within 500ms, in which case the timer is reset.
-
-See this article ["What is debouncing" by Jamis Charles](https://medium.com/@jamischarles/what-is-debouncing-2505c0648ff1) for a more detailed description of the `debounce` concept.
-
-When the function executes, we check whether the input is empty or not. A request object is created if the input is not empty.
-
-The `getLocations` function expects either no input, in which case it returns all Locations, or an Object (please refer to the official documentation for an exhaustive list of properties). In this case, the constant `value` is passed to the `q` property and the `includeOutsidePOI` property is set to `true`. When the Promise resolves, the response is passed to the `displayResults` helper function.
-
-If the input is empty, we clear the result list and reset the map filter by calling the helper functions `clearResults` and `clearFilter`.
-
-#### Checking for Results[](https://docs.mapsindoors.com/searching#checking-for-results)
-
-We need to clear the previous results, and check if any Locations were returned. If so, we loop through them and add them to the result list.
-
-```javascript
-function displayResults(locations) {
- clearResults();
-
- if (locations.length > 0) {
- for (const location of locations) {
- searchResults.innerHTML += `
${location.properties.name} `;
- }
- } else {
- searchResults.innerHTML = 'No results matched the query. ';
- }
-
- return locations;
-}
-```
-
-If no Locations are returned, a message is shown to the user stating "No results matched the query.". Otherwise, we pass the Locations on to the next helper function called `filterMap`.
-
-```javascript
-function filterMap(locations) {
- mapsIndoors.filter(locations.map(location => location.id), false);
- return locations;
-}
-```
-
-The purpose of the `filterMap` function is to create a list of `location id`s used to filter the Locations on the map.
-
-The second parameter tells MapsIndoors not to change the viewport of the map.
-
-For more information, see `MapsIndoors.filter` in the [reference documentation](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/MapsIndoors.html#filter).
diff --git a/sdks-and-frameworks/web/data-visualization/README.md b/sdks-and-frameworks/web/data-visualization/README.md
index d07c20b..842d0b6 100644
--- a/sdks-and-frameworks/web/data-visualization/README.md
+++ b/sdks-and-frameworks/web/data-visualization/README.md
@@ -1,2 +1,15 @@
# Data Visualization
+Data visualization in the form of displaying external dynamic data within your indoor map is crucial for enhancing the map's utility, relevance, real-time applicability and not least for customizing it to fit your specific use cases. \
+
+
+MapsIndoor’s data visualization functionality is built to ensure a unified, up-to-date, and contextually relevant mapping experience for users. \
+
+
+By altering your map data visualization dynamically, you will create a use-case-specific digital twin that only shows information that is relevant for solving your users’ needs.\
+
+
+Integrate everything from live data sensors, calendar booking systems, ERP systems, and more to MapsIndoors.\
+
+
+Follow our guides to customise your maps with the data integrations you need.
diff --git a/sdks-and-frameworks/web/directions-and-routing/README.md b/sdks-and-frameworks/web/directions-and-routing/README.md
index b981fa3..9b3b9b9 100644
--- a/sdks-and-frameworks/web/directions-and-routing/README.md
+++ b/sdks-and-frameworks/web/directions-and-routing/README.md
@@ -14,4 +14,31 @@ layout:
# Wayfinding
-##
+Wayfinding is a critical component of your indoor map solution enabling efficient route calculations and optimal navigation within indoor spaces.\
+
+
+MapsIndoors’ wayfinding functionality is a comprehensive solution that seamlessly integrates local and global maps, considers various travel modes, utilizes entry points for smooth transitions, and breaks down routes into logical legs and steps, ultimately enhancing navigation and user satisfaction.\
+
+
+Key elements to dig into when enabling wayfinding in your MapsIndoors solution are:
+
+**Outdoor to indoor navigation**\
+Turn-by-turn directions visualized on the map with estimated travel time and detailed descriptions.
+
+**Venue to Venue wayfinding**
+
+When you're getting routes between two of your own MapsIndoors venues and may require using public routes from Google Maps or Mapbox to get there.
+
+**Dynamic routes**\
+Automated route updates based on obstacles like furniture and changing floor plan layout.
+
+**Personalized routes**\
+User profiles allow for personalized guidance, based on what the user is allowed to see and where they are allowed to navigate. Getting the right people to the right destinations.
+
+**Accessible wayfinding**\
+Allow users with disabilities to effortlessly navigate your building by avoiding stairs and using elevators and ramps for navigation.
+
+\
+
+
+All the guidance is here for you. Happy wayfinding!
diff --git a/sdks-and-frameworks/web/directions-and-routing/directions-service.md b/sdks-and-frameworks/web/directions-and-routing/directions-service.md
index 91004c8..1099bb7 100644
--- a/sdks-and-frameworks/web/directions-and-routing/directions-service.md
+++ b/sdks-and-frameworks/web/directions-and-routing/directions-service.md
@@ -26,38 +26,36 @@ This guide will show you how to implement directions, render routes, and interac
* Would you like to show directions on the map?
* How will the end user let the map know it's time to update with the next part of their journey?
-
-
-
-
+Creating and combining the interfaces and the map view.
+Determining the scope and simplicity of your end user experience should be a big focus when implementing the MapsIndoors SDK
From an implementation standpoint, there are two functional things that need to be taken care of.
1. Setting up and requesting directions
-Getting directions via the SDK
+
-2. [Handling and rendering directions responses](../wayfinding/directions-renderer.md)
+1. [Handling and rendering directions responses](../wayfinding/directions-renderer.md)
-What you can do once you have the response.
+
The first step in getting directions is initializaing the directions service instance. By passing the externalDirectionsProvider, the MapsIndoors SDK will handle merging responses from the base map, e.g. outdoor directions that will charge billable requests if you request from somewhere else other than MapsIndoors data (e.g. an end users house, to somewhere indoors.)
-**Implementation**
+## **Implementation**
The class `DirectionsService` is used to request routes from one point to another. The minimal required input is an `origin` and a `destination`.
-Mapbox (required parameter of the DirectionsService instance)
+**Mapbox** (required parameter of the DirectionsService instance)
```javascript
const externalDirectionsProvider = new mapsindoors.directions.MapboxProvider();
const miDirectionsServiceInstance = new mapsindoors.services.DirectionsService(externalDirectionsProvider);
```
-Google (not required for legacy reasons, but recommended to pass an externalDirectionsProvider as a parameter)
+**Google** (not required for legacy reasons, but recommended to pass an externalDirectionsProvider as a parameter)
```javascript
const externalDirectionsProvider = new mapsindoors.directions.GoogleMapsProvider();
diff --git a/sdks-and-frameworks/web/directions-and-routing/directions.md b/sdks-and-frameworks/web/directions-and-routing/directions.md
index 19849d9..dfa91ab 100644
--- a/sdks-and-frameworks/web/directions-and-routing/directions.md
+++ b/sdks-and-frameworks/web/directions-and-routing/directions.md
@@ -4,7 +4,7 @@
As a key element in the MapsIndoors platform, we offer APIs for efficiently calculating and displaying the most optimal routes from anywhere in the world to any Location in MapsIndoors. In the case of travelling inside a Venue, this calculation can be done on a local map provided by MapsIndoors. In the case of travelling between Venues or from outdoors to indoors, MapsIndoors provides a seamless journey outline from a specified Origin through automatically selected Entry Points at the edge of your Venues to the specified destination. See illustration below:
-MJE: GRAFIC NEEDS AND UPDATE - AND PARKING SHOULD BE REMOVED. DOTS MUST STILL ILLUSTRATE LEG DIVISION AS DESCRIBED IN THE ARTICLE.
+
In order to provide a route between Venues, MapsIndoors integrates with external and global map engines (Mapbox and Google Maps).
diff --git a/sdks-and-frameworks/web/getting-started/create-a-search-experience.md b/sdks-and-frameworks/web/getting-started/create-a-search-experience.md
new file mode 100644
index 0000000..78a63b3
--- /dev/null
+++ b/sdks-and-frameworks/web/getting-started/create-a-search-experience.md
@@ -0,0 +1,828 @@
+# Create a Search Experience
+
+In this step, you'll create a simple search and display the search results in a list. You'll also learn how to filter the data displayed on the map.
+
+{% tabs %}
+{% tab title="Google Maps - Manually" %}
+## Create a Simple Query Search
+
+MapsIndoors Locations can be retrieved in the MapsIndoors namespace using the [`LocationsService.getLocations()` method](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations) but first you need to add a ` ` and `` element to the DOM.
+
+* Create an ` ` and `` element in ``.
+* Attach an `onclick` event to the `` element and call a `onSearch` method, which you will create next.
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+ Search
+
+
+```
+
+* Create the `onSearch` method.
+* Get a reference to the search ` ` element.
+* Define a new object with the search parameter `q` and the value of `searchInputElement`.
+* Call the `getLocations` method and log out the results to the console.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.GoogleMapsView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const googleMapsInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+googleMapsInstance.controls[google.maps.ControlPosition.RIGHT_TOP].push(floorSelectorElement);
+
+ function onSearch() {
+ const searchInputElement = document.querySelector('input');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ console.log(locations);
+ });
+ }
+```
+
+See all available search parameters in the [reference documentation](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations).
+
+### Display a List of Search Results
+
+To display a list of search results you can append each search result to a list element.
+
+* Add the `` list element below the search field in `` with the `id` attribute set to "search-results".
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+ Search
+
+
+
+```
+
+* Get a reference to the list element.
+* Reset the list on every complete search.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.GoogleMapsView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const googleMapsInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+googleMapsInstance.controls[google.maps.ControlPosition.RIGHT_TOP].push(floorSelectorElement);
+
+function onSearch() {
+ const searchInputElement = document.querySelector('input');
+ // Get list element reference
+ const searchResultsElement = document.getElementById('search-results');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ // Reset search results list
+ searchResultsElement.innerHTML = null;
+ });
+}
+```
+
+* Add a _for_ loop and append every result to the search results list element.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.GoogleMapsView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const googleMapsInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+googleMapsInstance.controls[google.maps.ControlPosition.RIGHT_TOP].push(floorSelectorElement);
+
+function onSearch() {
+ const searchInputElement = document.querySelector('input');
+ // Get list element reference
+ const searchResultsElement = document.getElementById('search-results');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ // Reset search results list
+ searchResultsElement.innerHTML = null;
+
+ // Append new search results
+ locations.forEach(location => {
+ const listElement = document.createElement('li');
+ listElement.innerHTML = location.properties.name;
+ searchResultsElement.appendChild(listElement);
+ });
+ });
+}
+```
+
+### Filter Locations on Map Based on Search Results[](https://docs.mapsindoors.com/getting-started/web/search#filter-locations-on-map-based-on-search-results)
+
+To filter the map to only display the search results you can use the `filter` method.
+
+* Call `mapsIndoorsInstance.filter` with an array of Location IDs.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.GoogleMapsView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const googleMapsInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+googleMapsInstance.controls[google.maps.ControlPosition.RIGHT_TOP].push(floorSelectorElement);
+
+function onSearch() {
+ const searchInputElement = document.querySelector('input');
+ // Get list element reference
+ const searchResultsElement = document.getElementById('search-results');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ // Reset search results list
+ searchResultsElement.innerHTML = null;
+
+ // Append new search results
+ locations.forEach(location => {
+ const listElement = document.createElement('li');
+ listElement.innerHTML = location.properties.name;
+ searchResultsElement.appendChild(listElement);
+ });
+
+ // Filter map to only display search results
+ mapsIndoorsInstance.filter(locations.map(location => location.id), false);
+}
+```
+
+To remove the location filter again, call `mapsIndoorsInstance.filter(null)`.
+
+Here's a JSFiddle demonstrating the result you should have by now:
+
+{% embed url="https://jsfiddle.net/mapspeople/cwg9eumd/2/" %}
+
+
+{% endtab %}
+
+{% tab title="Google Maps - MI Components" %}
+## Create a Simple Query Search
+
+Using the `` component you get a ` `element tied tightly together with the [Location Service](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/LocationsService.html).
+
+* Insert the `` custom element into ``.
+* Add the `mapsindoors` and `placeholder` attributes.
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+
+
+
+```
+
+* Get a reference to the `` element.
+* Attach an `results` event listener and log out the results to the console.
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector('mi-map-googlemaps');
+const miSearchElement = document.querySelector('mi-search');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ console.log(event.detail);
+});
+```
+
+For more information on available events and how to configure the `` component, see [components.mapsindoors.com/search](https://components.mapsindoors.com/search/).
+
+### Display a List of Search Results[](https://docs.mapsindoors.com/getting-started/web/search#show-a-list-of-search-results)
+
+To display a list of search results you can append each search result to a list element.
+
+
+
+* Insert the `` custom element below the search field in ``.
+* Add the `scroll-buttons-enabled` and `scroll-length` attributes.
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+For more information on how to configure the `` component, see [components.mapsindoors.com/list](https://components.mapsindoors.com/list/).
+
+* Get a reference to the list element.
+* Reset the list on every complete search.
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector('mi-map-googlemaps');
+const miSearchElement = document.querySelector('mi-search');
+const miListElement = document.querySelector('mi-list');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ // Reset search results list
+ miListElement.innerHTML = null;
+});
+```
+
+* Add a _for_ loop and append every result to the search results list element.
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector('mi-map-googlemaps');
+const miSearchElement = document.querySelector('mi-search');
+const miListElement = document.querySelector('mi-list');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ // Reset search results list
+ miListElement.innerHTML = null;
+
+// Append new search results
+event.detail.forEach(location => {
+ const miListItemElement = document.createElement('mi-list-item-location');
+ miListItemElement.location = location;
+ miListElement.appendChild(miListItemElement);
+});
+});
+```
+
+### Filter Locations on Map Based on Search Results[](https://docs.mapsindoors.com/getting-started/web/search#filter-locations-on-map-based-on-search-results)
+
+To filter the map to only display the search results you can use the `filter` method.
+
+
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector('mi-map-googlemaps');
+const miSearchElement = document.querySelector('mi-search');
+const miListElement = document.querySelector('mi-list');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ // Reset search results list
+ miListElement.innerHTML = null;
+
+ // Append new search results
+ event.detail.forEach(location => {
+ const miListItemElement = document.createElement('mi-list-item-location');
+ miListItemElement.location = location;
+ miListElement.appendChild(miListItemElement);
+ });
+
+// Get the MapsIndoors instance
+miMapElement.getMapsIndoorsInstance().then((mapsIndoorsInstance) => {
+ // Filter map to only display search results
+ mapsIndoorsInstance.filter(event.detail.map(location => location.id), false);
+}
+```
+
+To remove the location filter again, call `mapsIndoorsInstance.filter(null)`.
+
+Here's a JSFiddle demonstrating the result you should have by now:
+
+{% embed url="https://jsfiddle.net/mapspeople/jtnw0u1y/1/" fullWidth="false" %}
+
+
+{% endtab %}
+
+{% tab title="Mapbox - Manually" %}
+## Create a Simple Query Search
+
+MapsIndoors Locations can be retrieved in the MapsIndoors namespace using the [`LocationsService.getLocations()` method](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations) but first you need to add an ` ` and `` element to the DOM.
+
+* Create an ` ` and `` element in ``.
+* Attach an `onclick` event to the `` element and call a `onSearch` method, which you will create next.
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+
+ Search
+
+
+```
+
+* Create the `onSearch` method.
+* Get a reference to the search ` ` element.
+* Define a new object with the search parameter `q` and the value of `searchInputElement`.
+* Call the `getLocations` method and log out the results to the console.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.MapboxView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+mapboxInstance.addControl({ onAdd: function () { return floorSelectorElement }, onRemove: function () { } });
+
+ function onSearch() {
+ const searchInputElement = document.querySelector('input');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ console.log(locations);
+ });
+ }
+```
+
+See all available search parameters in the [reference documentation](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations).
+
+### Display a List of Search Results[](https://docs.mapsindoors.com/getting-started/web/search#show-a-list-of-search-results)
+
+To display a list of search results you can append each search result to a list element.
+
+* Add the `` list element below the search field in `` with the `id` attribute set to "search-results".
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+
+ Search
+
+
+
+```
+
+* Get a reference to the list element.
+* Reset the list on every complete search.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.MapboxView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const mapboxInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+mapboxInstance.addControl({ onAdd: function () { return floorSelectorElement }, onRemove: function () { } });
+
+function onSearch() {
+ const searchInputElement = document.querySelector('input');
+ // Get list element reference
+ const searchResultsElement = document.getElementById('search-results');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ // Reset search results list
+ searchResultsElement.innerHTML = null;
+ });
+}
+```
+
+* Add a _for_ loop and append every result to the search results list element.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.MapboxView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const mapboxInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+mapboxInstance.addControl({ onAdd: function () { return floorSelectorElement }, onRemove: function () { } });
+
+function onSearch() {
+ const searchInputElement = document.querySelector('input');
+ // Get list element reference
+ const searchResultsElement = document.getElementById('search-results');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ // Reset search results list
+ searchResultsElement.innerHTML = null;
+
+ // Append new search results
+ locations.forEach(location => {
+ const listElement = document.createElement('li');
+ listElement.innerHTML = location.properties.name;
+ searchResultsElement.appendChild(listElement);
+ });
+ });
+}
+```
+
+### Filter Locations on Map Based on Search Results[](https://docs.mapsindoors.com/getting-started/web/search#filter-locations-on-map-based-on-search-results)
+
+To filter the map to only display the search results you can use the `filter` method.
+
+
+
+* Call `mapsIndoorsInstance.filter` with an array of Location IDs.
+
+```javascript
+// main.js
+
+const mapViewOptions = {
+ accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+ maxZoom: 22,
+};
+const mapViewInstance = new mapsindoors.mapView.MapboxView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({ mapView: mapViewInstance });
+const mapboxInstance = mapViewInstance.getMap();
+
+// Floor Selector
+const floorSelectorElement = document.createElement('div');
+new mapsindoors.FloorSelector(floorSelectorElement, mapsIndoorsInstance);
+mapboxInstance.addControl({ onAdd: function () { return floorSelectorElement }, onRemove: function () { } });
+
+function onSearch() {
+ const searchInputElement = document.querySelector('input');
+ // Get list element reference
+ const searchResultsElement = document.getElementById('search-results');
+
+ const searchParameters = { q: searchInputElement.value };
+ mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ // Reset search results list
+ searchResultsElement.innerHTML = null;
+
+ // Append new search results
+ locations.forEach(location => {
+ const listElement = document.createElement('li');
+ listElement.innerHTML = location.properties.name;
+ searchResultsElement.appendChild(listElement);
+ });
+
+ // Filter map to only display search results
+ mapsIndoorsInstance.filter(locations.map(location => location.id), false);
+}
+```
+
+To remove the location filter again, call `mapsIndoorsInstance.filter(null)`.
+
+Here's a JSFiddle demonstrating the result you should have by now:
+
+{% embed url="https://jsfiddle.net/mapspeople/r86903om/" %}
+{% endtab %}
+
+{% tab title="Mapbox - MI Components" %}
+## Create a Simple Query Search
+
+Using the `` component you get an ` `element tied tightly together with the [Location Service](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/LocationsService.html).
+
+* Insert the `` custom element into ``.
+* Add the `mapsindoors` and `placeholder` attributes.
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+
+
+
+```
+
+* Get a reference to the `` element.
+* Attach a `results` event listener and log the results in the console.
+
+```javascript
+// main.js
+const miMapElement = document.querySelector('mi-map-mapbox');
++ const miSearchElement = document.querySelector('mi-search');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter([-77.0362723, 38.8974905]); // The White House
+ });
+});
+
+miSearchElement.addEventListener('results', (event) => {
+ console.log(event.detail);
+});
+```
+
+For more information on available events and how to configure the `` component, see [components.mapsindoors.com/search](https://components.mapsindoors.com/search/).
+
+### Display a List of Search Results[](https://docs.mapsindoors.com/getting-started/web/search#show-a-list-of-search-results)
+
+To display a list of search results you can append each search result to a list element.
+
+
+
+* Insert the `` custom element below the search field in ``.
+* Add the `scroll-buttons-enabled` and `scroll-length` attributes.
+
+```html
+
+
+
+
+
+
+
+
+ MapsIndoors
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+For more information on how to configure the `` component, see [components.mapsindoors.com/list](https://components.mapsindoors.com/list/).
+
+* Get a reference to the list element.
+* Reset the list on every complete search.
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector("mi-map-mapbox");
+const miSearchElement = document.querySelector('mi-search');
+const miListElement = document.querySelector('mi-list');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ // Reset search results list
+ miListElement.innerHTML = null;
+});
+```
+
+* Add a _for_ loop and append every result to the search results list element.
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector('mi-map-mapbox');
+const miSearchElement = document.querySelector('mi-search');
+const miListElement = document.querySelector('mi-list');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ // Reset search results list
+ miListElement.innerHTML = null;
+
+// Append new search results
+ event.detail.forEach(location => {
+ const miListItemElement = document.createElement('mi-list-item-location');
+ miListItemElement.location = location;
+ miListElement.appendChild(miListItemElement);
+ });
+});
+```
+
+### Filter Locations on Map Based on Search Results[](https://docs.mapsindoors.com/getting-started/web/search#filter-locations-on-map-based-on-search-results)
+
+To filter the map to only display the search results you can use the `filter` method.
+
+
+
+```javascript
+// main.js
+
+const miMapElement = document.querySelector("mi-map-mapbox");
+const miSearchElement = document.querySelector('mi-search');
+const miListElement = document.querySelector('mi-list');
+
+miMapElement.addEventListener('mapsIndoorsReady', () => {
+ miMapElement.getMapInstance().then((mapInstance) => {
+ mapInstance.setCenter({ lat: 38.8974905, lng: -77.0362723 }); // The White House
+ });
+})
+
+miSearchElement.addEventListener('results', (event) => {
+ // Reset search results list
+ miListElement.innerHTML = null;
+
+ // Append new search results
+ event.detail.forEach(location => {
+ const miListItemElement = document.createElement('mi-list-item-location');
+ miListItemElement.location = location;
+ miListElement.appendChild(miListItemElement);
+ });
+
+// Get the MapsIndoors instance
+miMapElement.getMapsIndoorsInstance().then((mapsIndoorsInstance) => {
+ // Filter map to only display search results
+ mapsIndoorsInstance.filter(event.detail.map(location => location.id), false);
+});
+```
+
+To remove the location filter again, call `mapsIndoorsInstance.filter(null)`.
+
+Here's a JSFiddle demonstrating the result you should have by now:
+
+{% embed url="https://jsfiddle.net/mapspeople/bd4n1qtr/" %}
+{% endtab %}
+{% endtabs %}
diff --git a/sdks-and-frameworks/web/map-management/README.md b/sdks-and-frameworks/web/map-management/README.md
index 526fbd2..a9a1a22 100644
--- a/sdks-and-frameworks/web/map-management/README.md
+++ b/sdks-and-frameworks/web/map-management/README.md
@@ -1,2 +1,18 @@
# Map Management
+Being able to manage your own maps however and whenever you want makes you agile, independent of support and able to immediately act on your customer requests.
+
+
+
+Customization and updating of your map is fast and easily done through the MapsIndoors CMS.\
+
+
+Key features of the MapsIndoors CMS include:
+
+* Add POIs and areas, like objects, work zones, or any relevant points of interest.
+* Make floorplan changes
+* Control visibility and user roles
+* Update locations data\
+
+
+Check out the details and explore many more CMS features in the [MapsIndoors CMS section](../../../products/cms/).
diff --git a/sdks-and-frameworks/web/map-visualization/README.md b/sdks-and-frameworks/web/map-visualization/README.md
index d325fda..a98580c 100644
--- a/sdks-and-frameworks/web/map-visualization/README.md
+++ b/sdks-and-frameworks/web/map-visualization/README.md
@@ -1,2 +1,28 @@
# Map Visualization
+Getting your map visualization right means going beyond simple floorplan representation and elevating the map to a rich and user-friendly indoor mapping experience. \
+
+
+The design and customization of your map visualization are crucial for creating a user-friendly, visually engaging, and functionally relevant mapping experience. The map visualization is your foundation for effective navigation, information accessibility, and overall user satisfaction. \
+
+
+In MapsIndoors, key aspects of map visualization cover:
+
+**Real-World Geospatial Visualization**
+
+MapsIndoors enables the visualization of venue details, building structures, floor plans, rooms, and related data on georeferenced Google or Mapbox maps. This real-world geospatial context enhances the accuracy and relevance of the indoor map.
+
+**Map Design**
+
+Users can customize the appearance of their maps to align with branding and specific use cases. Whether in 2D or 3D, the ability to design the map's look and feel provides flexibility and coherence with organizational aesthetics.
+
+**Dynamic Maps**
+
+MapsIndoors supports dynamic maps that can display relevant content based on users, use cases, or zoom levels. This adaptability ensures that users receive the most pertinent information based on their context and needs.
+
+**Map Interaction**
+
+The platform includes built-in features for map interaction, such as a floor selector, zoom, pan, tilt, and search functionalities. These features make it easy for users to navigate and interact with maps in ways that are relevant to their specific requirements.\
+
+
+Whether you’re building your map solution on Mapbox or Google Maps, we’ve got your back. Follow the guides and you’ll soon be up and running.
diff --git a/sdks-and-frameworks/web/map-visualization/display-a-map.md b/sdks-and-frameworks/web/map-visualization/display-a-map.md
index 5bb5e77..b066e0d 100644
--- a/sdks-and-frameworks/web/map-visualization/display-a-map.md
+++ b/sdks-and-frameworks/web/map-visualization/display-a-map.md
@@ -1,10 +1,34 @@
# Display a Map
-### Overview[](https://docs.mapsindoors.com/simple-map-web#overview)
+_MJE: I propose existing content below is deleted as that's already covered in the getting-started. This page should have all the details instead_
+
+**Google**:
+
+how to use JSON styling.
+
+how to use Cloud Styling.
+
+how to enable vector map and tilt / rotation with a warning (2D models etc.).
+
+how to control font (if possible) and labels.
+
+**Mapbox**:
+
+how to set the map style.
-In this guide you will learn to load a Google map with a MapsIndoors map on top. The full code example is shown in the JSFiddle below (hvor?) , but will be run through bit by bit in this guide.
+how to control label font and style.
-Skal denne artikel have en komplet rewrite med to sektioner; Google Maps og Mapbox?
+
+
+
+
+***
+
+
+
+### Overview[](https://docs.mapsindoors.com/simple-map-web#overview)
+
+In this guide you will learn to load a base map - Google Maps or Mapbox - with a MapsIndoors map on top. The full code example is shown in the JSFiddle below (Fiddle is missing) , but will be run through bit by bit in this guide.
@@ -18,22 +42,53 @@ The MapsIndoors SDK is loaded by using a script tag like the one below:
The `apikey` parameter contains your application's MapsIndoors API key.
-For IE11 it's critical to load the MapsIndoors SDK before the Google Maps API due to conflicting polyfills. (IE11 - kræver det en forklaring?)
+#### Loading the base map[](https://docs.mapsindoors.com/simple-map-web#loading-the-google-maps-javascript-api)
-#### Loading the Google Maps JavaScript API[](https://docs.mapsindoors.com/simple-map-web#loading-the-google-maps-javascript-api)
+A base map is loaded by using a script tag like the one below:
-The Google Maps API is loaded by using a script tag like the one below:
+{% tabs %}
+{% tab title="Mapbox" %}
+```html
+
+```
+{% endtab %}
-```javascript
+{% tab title="Google Maps" %}
+```html
```
-The `libraries` parameter is for loading additional libraries for the Google Maps API. The MapsIndoors SDK is dependent on the Geometry Library from Google.
+The `libraries` parameter is for loading additional libraries for the Google Maps API. The MapsIndoors SDK is dependent on the Geometry library from Google.
The `key` parameter contains your Google Maps API key. Look [here](https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/get-api-key) for more information about how to obtain a key.
+{% endtab %}
+{% endtabs %}
#### Setting Up the MapView[](https://docs.mapsindoors.com/simple-map-web#setting-up-the-mapview)
+{% tabs %}
+{% tab title="Mapbox" %}
+```javascript
+const mapViewOptions = {
+ accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
+ element: document.getElementById('map'),
+ center: { lat: 38.8974905, lng: -77.0362723 }, // The White House
+ zoom: 17,
+};
+const mapViewInstance = new mapsindoors.mapView.MapboxView(mapViewOptions);
+const mapsIndoorsInstance = new mapsindoors.MapsIndoors({
+ mapView: mapViewInstance,
+});
+```
+
+* `element` is the DOM element on the page that will contain the map. `document.getElementById('map')`
+* `center` is the geographical point on which the map is centered.
+* `zoom` is the initial zoom level the map will be displayed at.
+
+For a full list of parameters, see the [mapView.MapboxView](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.mapView.MapboxView.html) reference.
+{% endtab %}
+
+{% tab title="Google Maps" %}
```javascript
const mapView = new mapsindoors.mapView.GoogleMapsView({
element: document.getElementById("map"),
@@ -51,6 +106,10 @@ const mapView = new mapsindoors.mapView.GoogleMapsView({
* `zoom` is the initial zoom level the map will be displayed at.
* The `maxZoom` parameter is set to disable the map from zooming further in than level 21 which is the current maximum.
+For a full list of parameters, see the [mapView.GoogleMapsView](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.mapView.GoogleMapsView.html) reference.
+{% endtab %}
+{% endtabs %}
+
#### Initializing MapsIndoors[](https://docs.mapsindoors.com/simple-map-web#initializing-mapsindoors)
```javascript
@@ -59,7 +118,7 @@ const mapsIndoors = new mapsindoors.MapsIndoors({
});
```
-A new instance of the MapsIndoors class is created and assigns the GoogleMapsView to the `mapView` parameter.
+A new instance of the MapsIndoors class is created and assigns the MapboxView or GoogleMapsView to the `mapView` parameter.
#### Adding a Floor Selector[](https://docs.mapsindoors.com/simple-map-web#adding-a-floor-selector)
diff --git a/sdks-and-frameworks/web/displaying-objects/turn-off-collisions-based-on-zoom-level.md b/sdks-and-frameworks/web/map-visualization/managing-collisions-based-on-zoom-level.md
similarity index 80%
rename from sdks-and-frameworks/web/displaying-objects/turn-off-collisions-based-on-zoom-level.md
rename to sdks-and-frameworks/web/map-visualization/managing-collisions-based-on-zoom-level.md
index 982d943..b6af877 100644
--- a/sdks-and-frameworks/web/displaying-objects/turn-off-collisions-based-on-zoom-level.md
+++ b/sdks-and-frameworks/web/map-visualization/managing-collisions-based-on-zoom-level.md
@@ -1,4 +1,4 @@
-# Turn Off Collisions Based on Zoom Level
+# Managing Collisions Based on Zoom Level
**Handling Label Collisions in MapsIndoors SDK with Mapbox**
@@ -44,9 +44,7 @@ mapsIndoorsInstance.addListener('zoom_changed', (zoomLevel) => {
**Explanation**
-* **`zoom_changed` Listener**: Detects changes in zoom level, triggering the condition check.
-* **Conditional Check**: Compares the current zoom level against the
+* `zoom_changed` listener: Detects changes in zoom level, triggering the condition check against the current zoom level.
+* `setLayoutProperty`: Adjusts the `text-allow-overlap` property of the 'MI\_POINT\_LAYER' to either allow or prevent label overlap, depending on the zoom condition.
-maximum permissible zoom level (retrieved via [mapsIndoorsInstance.getMaxZoom()](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.MapsIndoors.html#getMaxZoom) ) to determine label rendering behavior.
-
-* **`setLayoutProperty`**: Adjusts the `text-allow-overlap` property of the 'MI\_POINT\_LAYER' to either allow or prevent label overlap, depending on the zoom condition.
+Optional Conditional Check: Compares the current zoom level against the maximum permissible zoom level (retrieved via [mapsIndoorsInstance.getMaxZoom()](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.MapsIndoors.html#getMaxZoom) ) to determine label rendering behavior.
diff --git a/sdks-and-frameworks/web/map-visualization/switching-solutions.md b/sdks-and-frameworks/web/map-visualization/switching-solutions.md
index 0f555e6..6040db2 100644
--- a/sdks-and-frameworks/web/map-visualization/switching-solutions.md
+++ b/sdks-and-frameworks/web/map-visualization/switching-solutions.md
@@ -4,163 +4,24 @@ Some larger organizations may have not just multiple Venues, but also multiple S
At its core, this is done simply by switching out the API key and reloading the system. However, there are a few more steps that can be done to ensure a smooth transition between Solutions.
-## Starting a Solution[](https://docs.mapsindoors.com/switch-solutions#starting-a-solution)
-To initialize MapsIndoors, do the following:
-
-### Google Maps
-
-{% tabs %}
-{% tab title="Java" %}
-```java
-protected void onCreate(Bundle savedInstanceState) {
- ...
- mMapView = mapFragment.getView();
- MapsIndoors.load(getApplicationContext(), "YOUR_MAPSINDOORS_API_KEY", null);
- mapFragment.getMapAsync(this);
- ...
-}
-@Override
-public void onMapReady(GoogleMap googleMap) {
- mMap = googleMap;
-
- if (mMapView != null) {
- initMapControl(mMapView);
- }
-}
-void initMapControl(View view) {
- MPMapConfig mapConfig = new MPMapConfig.Builder(this, mMap, getString(R.string.google_maps_key), view, true).build();
- MapControl.create(mapConfig, (mapControl, miError) -> {
- mMapControl = mapControl;
- if (miError == null) {
- //Orient your map to where you need data to be shown. This could be done by getting the default venue through MapsIndoors and panning the camera there
- }
- });
-}
-```
-{% endtab %}
-
-{% tab title="Kotlin" %}
-```kotlin
-override fun onCreate(savedInstanceState: Bundle?) {
- ...
- MapsIndoors.load(applicationContext, "YOUR_MAPSINDOORS_API_KEY", null)
-
- mapFragment.view?.let {
- mapView = it
- }
- ...
-}
-override fun onMapReady(googleMap: GoogleMap) {
- mMap = googleMap
-
- mapView?.let { view ->
- initMapControl(view)
- }
-}
-fun initMapControl(view: View) {
- MPMapConfig mapConfig = new MPMapConfig.Builder(this, mMap, getString(R.string.google_maps_key), view, true).build();
- //Creates a new instance of MapControl
- MapControl.create(config) { mapControl, miError ->
- if (miError == null) {
- mMapControl = mapControl!!
- //Orient your map to where you need data to be shown. This could be done by getting the default venue through MapsIndoors and panning the camera there
- }
- }
-}
-```
-{% endtab %}
-{% endtabs %}
-
-### Mapbox
-
-{% tabs %}
-{% tab title="Java" %}
-```java
-protected void onCreate(Bundle savedInstanceState) {
- ...
- MapsIndoors.load(getApplicationContext(), "YOUR_MAPSINDOORS_API_KEY", null);
- ...
-}
-void initMapControl(View view) {
- MPMapConfig mapConfig = new MPMapConfig.Builder(this, mMapboxMap, mMapView, getString(R.string.mapbox_access_token),true).build();
- //Creates a new instance of MapControl
- MapControl.create(mapConfig, (mapControl, miError) -> {
- mMapControl = mapControl;
- if (miError == null) {
- //Orient your map to where you need data to be shown. This could be done by getting the default venue through MapsIndoors and panning the camera there
- }
- });
-}
-```
-{% endtab %}
-
-{% tab title="Kotlin" %}
-```kotlin
-override fun onCreate(savedInstanceState: Bundle?) {
- ...
- MapsIndoors.load(applicationContext, "YOUR_MAPSINDOORS_API_KEY", null)
- ...
-}
-fun initMapControl(view: View) {
- val config = MPMapConfig.Builder(this, mMap, mapView, getString(R.string.mapbox_access_token),true).build()
- //Creates a new instance of MapControl
- MapControl.create(config) { mapControl, miError ->
- if (miError == null) {
- //Orient your map to where you need data to be shown. This could be done by getting the default venue through MapsIndoors and panning the camera there
- }
- }
-}
-```
-{% endtab %}
-{% endtabs %}
## Switching Solutions[](https://docs.mapsindoors.com/switch-solutions#switching-solutions)
-You switch Solutions by changing the active API key using `setAPIKey()`.
-
-We recommend creating your own function to call in the future for this purpose, like the example here with `switchSolution()`:
-
-### Google maps
-
-{% tabs %}
-{% tab title="Java" %}
-```java
-protected void switchSolution() {
- mMapControl.onDestroy();
- MapsIndoors.load(getApplication(), "YOUR_SECONDARY_API_KEY", null);
- mMapView.getMapAsync(this);
-}
-```
-{% endtab %}
-
-{% tab title="Kotlin" %}
-```kotlin
-private fun switchSolution() {
- mMapControl.onDestroy()
- MapsIndoors.load(applicationContext, "YOUR_SECONDARY_API_KEY", null)
- mMapView.getMapAsync(this)
-}
-```
-{% endtab %}
-{% endtabs %}
+You switch Solutions by ....
-### Mapbox
+### Headline
{% tabs %}
-{% tab title="Java" %}
+{% tab title="Mapbox" %}
```java
-mMapControl.onDestroy();
-MapsIndoors.load(getApplicationContext(), "YOUR_SECONDARY_API_KEY", null);
-initMapControl(mMapBoxMap, mMapView);
+//code
```
{% endtab %}
-{% tab title="Kotlin" %}
+{% tab title="Google Maps" %}
```kotlin
-mMapControl.onDestroy()
-MapsIndoors.load(applicationContext, "YOUR_SECONDARY_API_KEY", null)
-initMapControl(mMapBoxMap, mMapView)
+//code
```
{% endtab %}
{% endtabs %}
diff --git a/sdks-and-frameworks/web/other-guides/external-ids.md b/sdks-and-frameworks/web/other-guides/external-ids.md
index 093cc8a..e8d0261 100644
--- a/sdks-and-frameworks/web/other-guides/external-ids.md
+++ b/sdks-and-frameworks/web/other-guides/external-ids.md
@@ -1,31 +1,355 @@
----
-description: Web v4
----
+# Using External ID, Geospatial Joins
-# External IDs
+## Background on External ID
-The ExternalID is a reference from your real-life data to a piece of MapsIndoors geodata.
+The External ID is a reference from your real-life data to a piece of MapsIndoors geodata.
-In a large venue like a conference hall, headquarter, or university, every room will have a unique ID like `1.234AB` or `HALL_A` in a naming scheme that makes sense to that organisation.
+In a large venue like a conference hall, headquarter, or university, every room will have a unique ID like `1.234AB` or `HALL_A` in a naming scheme that makes sense to that organization.
-In MapsIndoors, we create all Rooms, Buildings, and Venues with an internal id that is a unique identifier, and it will not change. However, you might need to change the ID for a particular room in your physical building. It might be a large meeting room that is now split in two smaller rooms and one of them keeps that original ID. The ExternalID should then reflect your naming scheme, and not concern itself with the internal random identifier our database handed out to any of your rooms, as they will now be two new ones.
+In MapsIndoors, we create all Rooms, Buildings, and Venues with an internal id that is a unique identifier, and it will not change.
-Previously, regardless of the type of geodata, we called it `RoomID`. This is less than optimal when a `RoomID` refers to a Building, or even a whole Venue, hence the change.
+You will likely want to use the `externalId` as an identifier for an your system's ID or another external system of your choosing. If you have a queue monitoring system and want to display some regularly updated statuses on a piece of geodata in MapsIndoors, you can use the External ID as the common denominator between the systems.
-### Advanced Uses of ExternalID[](https://docs.mapsindoors.com/external-id#advanced-uses-of-externalid)
-You can also use the ExternalID as an identifier for an external system of your choosing. If you have a queue monitoring system and want to display some regularly updated statuses on a piece of geodata in MapsIndoors, you can use the ExternalID as the common denominator between the systems.
-There are many ways you can utilise the power of ExternalID as a reference point for one of your systems, and we recommend looking at the [Integration API documentation](https://docs.mapsindoors.com/api/) and [getting in touch](https://resources.mapspeople.com/contact-us) to hear more about your options with this feature.
+There are many ways you can utilize the power of external ID as a reference point for one of your systems, and we recommend looking at the [Integration API documentation](https://docs.mapsindoors.com/api/) and [getting in touch](https://resources.mapspeople.com/contact-us) to hear more about your options with this feature.
+
+Alternatively, you might need to change the ID for a particular room in your physical building. It might be a large meeting room that is now split in two smaller rooms and one of them keeps that original ID. The external ID should then reflect your naming scheme, and not concern itself with the internal random identifier our database handed out to any of your rooms, as they will now be two new ones.
+
+Historically, we referred to this as room ID, so if you see a property on an object when working with the SDK and see a `roomId`, it should be consistent with the external ID property.
## Getting Locations by External ID
-A method on MapsIndoors is available to retrieve locations by their externalId. This is only for exact matches and is not a part of the general search implementations, so must be specifically implemented.
+A method on MapsIndoors is available to retrieve locations by their external ID. This is only for exact matches and is not a part of the general search implementations, so must be specifically implemented.
The function on all 3 platforms functions similarly, returning an Array or List of Locations that match the supplied External ID strings.
-Running the below snippet will return an Array of `MPLocations`.
+The below example shows how to retrieve some MapsIndoors locations based on your own IDs from your system, e.g. 'extId1', 'extId2' and updates the corresponding MapsIndoors locations with display rules.
+
+Update the map with display rules based on your own data
+
+### Implementation example
```javascript
-locationsService.getLocationsByExternalId(externalIds)
+
+// Define arrays of external IDs for available and unavailable resources
+const availableExternalIds = ['extId1', 'extId2']; // Replace with your actual IDs
+const unavailableExternalIds = ['extId3', 'extId4']; // Replace with your actual IDs
+
+// Fetch locations based on external IDs
+async function fetchLocationsByExternalIds(externalIds) {
+ const promises = externalIds.map(id => mapsindoors.services.LocationsService.getLocationsByExternalId(id));
+ return await Promise.all(promises);
+}
+
+// Fetch locations for available and unavailable resources
+const availableLocations = await fetchLocationsByExternalIds(availableExternalIds);
+const unavailableLocations = await fetchLocationsByExternalIds(unavailableExternalIds);
+
+// Segment locations into Meeting Rooms and Workstations
+const availableMeetingRooms = availableLocations.filter(location => location.properties.type === 'MeetingRoom');
+const availableWorkstations = availableLocations.filter(location => location.properties.type === 'Workstation');
+
+const unavailableMeetingRooms = unavailableLocations.filter(location => location.properties.type === 'MeetingRoom');
+const unavailableWorkstations = unavailableLocations.filter(location => location.properties.type === 'Workstation');
+
+// Extract MapsIndoors location Ids
+const availableMeetingRoomIds = availableMeetingRooms.map(location => location.id);
+const unavailableMeetingRoomIds = unavailableMeetingRooms.map(location => location.id);
+
+const availableWorkstationIds = availableWorkstations.map(location => location.id);
+const unavailableWorkstationIds = unavailableWorkstations.map(location => location.id);
+
+// Set display rules for Meeting Rooms
+mapsIndoorsInstance.setDisplayRule(availableMeetingRoomIds, {
+ polygonVisible: true,
+ polygonFillColor: "#90ee90",
+ polygonFillOpacity: 1,
+ polygonZoomFrom: 16,
+ polygonZoomTo: 22,
+ visible: true,
+});
+
+mapsIndoorsInstance.setDisplayRule(unavailableMeetingRoomIds, {
+ polygonVisible: true,
+ polygonFillColor: "#ff4d4d",
+ polygonFillOpacity: 1,
+ polygonZoomFrom: 16,
+ polygonZoomTo: 22,
+ visible: true,
+});
+
+// Set display rules for Workstations
+mapsIndoorsInstance.setDisplayRule(availableWorkstationIds, {
+ model3DVisible: true,
+ model3DModel: 'your_3D_model_URL_for_available_workstations',
+ model3DZoomFrom: 16,
+ model3DZoomTo: 22,
+ visible: true,
+});
+
+mapsIndoorsInstance.setDisplayRule(unavailableWorkstationIds, {
+ model3DVisible: true,
+ model3DModel: 'your_3D_model_URL_for_unavailable_workstations',
+ model3DZoomFrom: 16,
+ model3DZoomTo: 22,
+ visible: true,
+});
+
+```
+
+## Adding Geospatial Criteria to Your Own Search
+
+You may wish to have some kind of recommendation system, so returning a list of your objects from your system might get a benefit to adding geospatial information.
+
+* Find all the nearby rooms that require cleaning
+* Find the closest nearby available meeting room
+* Get me all of the service orders tickets on this floor
+
+Let's dig into how to implement this
+
+### First and foremost, the Map is not required
+
+1. Load the MapsIndoors SDK
+
+Use the relevant script tag for the MapsIndoors SDK. There is no API directly accessible as a developer, so the script tag must be run and therefore you need to have a javascript environment.
+
+As of the date of writing this Oct, 2023 the most recent version is
+
+```html
+
+```
+
+However, you can find the latest version of our SDK [here](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/).
+
+2. Use the getLocationsByExternalId method with whatever list of IDs are returned from your own search handled outside of MapsIndoors.
+
+```
+// Define arrays of external IDs for available and unavailable resources
+const availableExternalIds = ['extId1', 'extId2']; // Replace with your actual IDs
+
+// Fetch locations based on external IDs
+async function fetchLocationsByExternalIds(externalIds) {
+ const promises = externalIds.map(id => mapsindoors.services.LocationsService.getLocationsByExternalId(id));
+ return await Promise.all(promises);
+}
+
+// Fetch locations for available and unavailable resources
+const availableLocations = await fetchLocationsByExternalIds(availableExternalIds);
+```
+
+For a more full implementation to demonstrate this
+
+{% embed url="https://storage.googleapis.com/meeting-room-recommender-demo/index.html" %}
+
+Narrow recommendations based on walking distance proximity
+
+{% hint style="info" %}
+Make sure to use the latest version of the SDK when implementing.
+
+Depending on your ambition, you could do things like automatically book the closest nearby for the user if they wish.
+
+This particular feature shows value with MapsIndoors even for employees who are quite familiar with their surroundings.
+{% endhint %}
+
+```
+
+
+
+
+ Meeting Room Finder
+
+
+
+
+
+ Make better recommendations by incorporating MapsIndoors data
+ All meeting rooms on the same floor as the employee. Most of this would be in a resource calendar system.
+
+
+
+ All Rooms
+ Available Meeting Rooms
+ Top 10 Nearby Meeting Rooms
+ Top 3 Meeting Rooms
+
+
+
+
+
+
+
+
```
diff --git a/sdks-and-frameworks/web/search/README.md b/sdks-and-frameworks/web/search/README.md
index 8300a94..4d5f5bf 100644
--- a/sdks-and-frameworks/web/search/README.md
+++ b/sdks-and-frameworks/web/search/README.md
@@ -1,2 +1,23 @@
# Search
+Searching the map and making sure you are able to find what you need is crucial for users navigating complex indoor spaces. Search functionality on an indoor map is a critical component for improving navigation, efficiency, and overall user satisfaction.\
+
+
+Depending on your solution and use case, search can come into play in different ways. It could be specific locations, points of interest, or services within the indoor space, like enabling users to search for a meeting room, a desk, a booth, a coffee, an elevator, anything.
+
+In MapsIndoors, searching is a crucial element of user interaction, allowing users to discover locations and filter map displays for a tailored experience. The search functionality covers all MapsIndoors geodata, and customization options are available to create a search experience that aligns with your specific use case.\
+
+
+Key features of the searching functionality include:
+
+* Filters for Precision
+* Search Result Ranking
+* Displaying Search Results
+* Clearing Filters
+* List Presentation
+
+
+
+Overall, the search mechanism in MapsIndoors prioritizes proximity, text matching, and geodata type to provide users with relevant and ranked results. The flexibility to customize the search experience and the ability to present results in both map and list formats are built to contribute to a user-friendly and adaptable indoor mapping solution.
+
+We’ve lined up all the guidance you need for getting the best out of MapsIndoors’ search functionality. Enjoy.
diff --git a/sdks-and-frameworks/web/search/search-operations.md b/sdks-and-frameworks/web/search/search-operations.md
new file mode 100644
index 0000000..3af6671
--- /dev/null
+++ b/sdks-and-frameworks/web/search/search-operations.md
@@ -0,0 +1,24 @@
+# Search Operations
+
+### Search Operations with MapsIndoors
+
+Enhance your application's search capabilities with MapsIndoors data. The following topics offer a brief introduction to various functionalities you can implement. For in-depth guidance, click on the specific topics.
+
+#### [Basic Searching](searching.md)
+
+* **Retrieve Specific Location**: Use [`getLocation(id)`](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocation) to obtain individual location objects.
+* **Querying Locations**: Perform broader searches with [`getLocations(args)`](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations).
+ * **Filter Customization**: Fine-tune your searches with specialized query parameters.
+
+#### [Extending Your Search](../other-guides/external-ids.md)
+
+* **Using External IDs**: Translate your unique IDs to MapsIndoors IDs using [`getLocationsByExternalId`](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocationsByExternalId).
+* **Advanced Search Integration**: Integrate MapsIndoors data into your existing search functionalities.
+* **Distance Matrix**: Create a distance matrix when dealing with multiple locations. [Ref docs here](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/DistanceMatrixService.html)
+
+#### [Utilizing MapsIndoors Web Components and Other Searches](utilizing-mapsindoors-web-components-and-other-searches.md)
+
+* **Utilizing MapsIndoors web components**
+ * **Components:** MapsIndoors search component, list component, etc.
+ * **Click Event Handling**: Interactive retrieval of location details.
+* **Venue and Building Info**: Access information about venues and buildings stored in MapsIndoors.
diff --git a/sdks-and-frameworks/web/search/searching.md b/sdks-and-frameworks/web/search/searching.md
new file mode 100644
index 0000000..7e75a40
--- /dev/null
+++ b/sdks-and-frameworks/web/search/searching.md
@@ -0,0 +1,397 @@
+---
+layout:
+ title:
+ visible: true
+ description:
+ visible: true
+ tableOfContents:
+ visible: true
+ outline:
+ visible: true
+ pagination:
+ visible: false
+---
+
+# Searching
+
+Searching through your MapsIndoors data is an key part of a great user experience with your maps. Users can look for places to go, or filter what is shown on the map.
+
+Searches work on all MapsIndoors geodata. It is up to you to create a search experience that fits your use case.
+
+## Retrieve Specific Location: `getLocation(id)`
+
+### **Use-Case 1: Center the Map to the Location**
+
+#### Example 1: Using MapsIndoors Location ID on the Card
+
+This example assumes that you've stored the MapsIndoors Location ID directly on the card, accessible via a custom attribute or some other mechanism. When the card is clicked, `getLocation(id)` retrieves the corresponding location, centers the map on it, and sets the zoom level.
+
+```javascript
+card.addEventListener('click', () => {
+ const locationId = card.getAttribute('data-location-id'); // Assume the MapsIndoors ID is stored in a data attribute
+ mapsindoors.services.LocationsService.getLocation(locationId).then(location => {
+ mapsIndoorsInstance.setFloor(location.properties.floor);
+ mapInstance.setCenter({
+ lat: location.properties.anchor.coordinates[1],
+ lng: location.properties.anchor.coordinates[0]
+ });
+ mapInstance.setZoom(18);
+ });
+});
+```
+
+#### Example 2: Using an External Custom ID on the Card
+
+In this example, an external (custom) ID is stored on the card. The `getLocationsByExternalId` method is used to fetch locations, taking into account that multiple locations could be returned.
+
+```javascript
+card.addEventListener('click', () => {
+ const externalId = card.getAttribute('data-external-id'); // Assume the external ID is stored in a data attribute
+
+ // Use getLocationsByExternalId to fetch locations by their external IDs
+ mapsindoors.services.LocationsService.getLocationsByExternalId(externalId).then(locations => {
+ if (locations.length > 0) {
+ const location = locations[0]; // Take the first location if multiple are returned
+
+ // Set the floor and center the map
+ mapsIndoorsInstance.setFloor(location.properties.floor);
+ mapInstance.setCenter({
+ lat: location.properties.anchor.coordinates[1],
+ lng: location.properties.anchor.coordinates[0]
+ });
+
+ mapInstance.setZoom(18);
+ } else {
+ // Handle the case where no locations are returned for the given external ID
+ console.warn(`No locations found for external ID ${externalId}`);
+ }
+ });
+});
+```
+
+Both examples work off a click event attached to a card element. The key difference lies in the method used to query MapsIndoors for the location information. Example 1 uses the native MapsIndoors ID, while Example 2 uses an external ID. Both methods then focus the map on the retrieved location.
+
+### **Use-Case 2: Utilizing MapsIndoors SDK Highlighting and Filtering**
+
+Take advantage of using MapsIndoors native filtering and highlighting functionality via the SDK without needing to implement your own custom display logic.
+
+
+
+DESCRIPTION OF BOTH FILTERING AND HIGHLIGHTING WILL GO HERE
+
+IMAGE\_PLACEHOLDER\_HERE
+
+HOLDING OFF ON THIS UNTIL I GET MORE DETAILS ON HOW THESE METHODS WORK
+
+### **Use-Case 3: Modify Display Rule**
+
+#### Example 1: Customizing Display Rule on Click Event with MapsIndoors Location ID
+
+```javascript
+// Define the rule outside the listener for better readability and reusability
+const rule = {
+ visible: true,
+ polygonVisible: true,
+ polygonFillColor: "#FF0000",
+ polygonFillOpacity: 1,
+ iconSize: { width: 30, height: 30 },
+ labelVisible: true,
+};
+
+let previousLocationId = null; // Keep track of previously filtered location
+
+card.addEventListener('click', () => {
+ const locationId = card.getAttribute('data-location-id');
+ mapsindoors.services.LocationsService.getLocation(locationId).then(location => {
+ // Optionally set the floor and center the map
+ mapsIndoorsInstance.setFloor(location.properties.floor);
+ mapInstance.setCenter({
+ lat: location.properties.anchor.coordinates[1],
+ lng: location.properties.anchor.coordinates[0]
+ });
+
+ // Reset display rule for previously filtered location, if any
+ if (previousLocationId) {
+ mapsIndoorsInstance.setDisplayRule(previousLocationId, null);
+ }
+
+ // Apply the new display rule to the clicked location
+ mapsIndoorsInstance.setDisplayRule(location.id, rule);
+
+ // Update the previous location ID
+ previousLocationId = location.id;
+ });
+});
+```
+
+#### Example 2: Using an External Custom ID
+
+```javascript
+// Define the display rule
+const rule = {
+ visible: true,
+ polygonVisible: true,
+ polygonFillColor: "#FF0000",
+ polygonFillOpacity: 1,
+ iconSize: { width: 30, height: 30 },
+ labelVisible: true,
+};
+
+let previousLocationId = null; // Keep track of the previously filtered location
+
+card.addEventListener('click', () => {
+ const externalId = card.getAttribute('data-external-id');
+
+ // Use getLocationsByExternalId() to fetch locations by their external IDs
+ mapsindoors.services.LocationsService.getLocationsByExternalId(externalId).then(locations => {
+ if (locations.length > 0) {
+ const location = locations[0]; // Assume the first location is the one to display
+
+ // Optionally set the floor and center the map
+ mapsIndoorsInstance.setFloor(location.properties.floor);
+ mapInstance.setCenter({
+ lat: location.properties.anchor.coordinates[1],
+ lng: location.properties.anchor.coordinates[0]
+ });
+
+ // Reset display rule for the previously filtered location, if any
+ if (previousLocationId) {
+ mapsIndoorsInstance.setDisplayRule(previousLocationId, null);
+ }
+
+ // Apply the new display rule to the location
+ mapsIndoorsInstance.setDisplayRule(location.id, rule);
+
+ // Update the ID of the previously filtered location
+ previousLocationId = location.id;
+
+ } else {
+ console.warn(`No locations found for external ID ${externalId}`);
+ }
+ });
+});
+```
+
+This code assumes that if multiple locations are returned from `getLocationByExternalId()`, the first one is the relevant location for display. The remainder of the code remains largely similar to the previous example, but we're fetching the locations based on an external ID instead of a MapsIndoors Location ID.
+
+### Use-Case 4: Add a Popup / Info Window
+
+For this use-case, we're focusing on how to display an information popup or info window when a MapsIndoors location is clicked. Both Mapbox and Google Maps implementations are provided. These popups will show a custom image and a link, allowing developers the flexibility to populate it with any content. Let's assume you're getting back your location object from one of the approaches in [Use-Case 1](searching.md#use-case-1-center-the-map-to-the-location).
+
+**Mapbox Implementation**
+
+In the Mapbox example, we add an event listener to the MapsIndoors instance that listens for 'click' events. When a location is clicked, we display a Mapbox popup at the location's coordinates. Any previously displayed popup will be removed to avoid clutter.
+
+```javascript
+let currentPopup = null;
+
+export const handleLocationClickForMapbox = (location, mapsIndoorsInstance, mapInstance) => {
+ if (currentPopup) {
+ currentPopup.remove();
+ }
+
+ const coords = location.properties.anchor.coordinates;
+ const popupContent = `
+
+
+ `;
+
+ currentPopup = new mapboxgl.Popup({ closeOnClick: true, closeButton: true })
+ .setLngLat(coords)
+ .setHTML(popupContent)
+ .addTo(mapInstance);
+};
+
+mapsIndoorsInstance.addListener('click', location => {
+ handleLocationClickForMapbox(location, mapsIndoorsInstance, mapInstance);
+});
+```
+
+**Google Maps Implementation**
+
+In the Google Maps example, we add an event listener to the MapsIndoors instance to listen for location clicks. When a location is clicked, an info window appears at the coordinates of that location. Similar to the Mapbox example, any previously displayed info window will be closed.
+
+```javascript
+let previousInfoWindow = null;
+
+mapsIndoorsInstance.addListener('click', location => {
+ if (previousInfoWindow) {
+ previousInfoWindow.close();
+ }
+
+ const coords = location.properties.anchor.coordinates;
+ const infoWindowContent = `
+
+
+ `;
+
+ const infoWindowOptions = {
+ content: infoWindowContent,
+ position: {
+ lat: coords[1],
+ lng: coords[0]
+ }
+ };
+
+ const infoWindow = new google.maps.InfoWindow(infoWindowOptions);
+ infoWindow.open(googleMapsInstance);
+ previousInfoWindow = infoWindow;
+});
+```
+
+Both implementations ensure that only one popup or info window is open at a given time, closing any previous ones when a new location is clicked. This keeps the map clean and focuses the user's attention on the most recently clicked location.
+
+
+
+## Retrieve Queried Locations: `getLocations(`args opt`)`
+
+To help you in this, there is a range of filters you can apply to the search queries to get the best results. E.g. you can filter by Categories, search only a specific part of the map or search near a Location.
+
+All three return a list of Locations from your solution matching the parameters they are given. The results are ranked upon the three following factors:
+
+* If a "near" parameter is set, how close is the origin point to the result?
+* How well does the search input text match the text of the result?
+ * (Our base algorithm for searching is using the "[Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein\_distance)" algorithm)
+* Which kind of geodata is the result (e.g. Buildings are ranked over POIs)?
+
+This means that the first item in the search result list will be the one best matching the three factors. **You always have the ability to reorder your array of locations based on your preference before rendering them in your user interface, if you choose to handle that via some client-side code.**
+
+Feel free to refer to this table for a comprehensive understanding of each parameter's type, optional/required status, and functionality.
+
+| Parameter | Type | Optional/Required | Description | Default / Example | Code Example |
+| ------------ | ----------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
+| `q` | string | Optional | Use a text query to search for one or more locations. | | |
+| `fields` | string | Optional | Fields to search in when using the search string parameter 'q'. Options: "name,description,aliases,categories" | | |
+| `types` | Array. | Optional | Filter by types in a comma-separated list. A location only has one type. | | `mapsindoors.services.LocationsService.getLocations({ lr: 'en', types: ['meetingroom'] }).then(locations => { ... });` |
+| `categories` | Array. | Optional | Filter by categories in a comma-separated list. A location can be in multiple categories. | | `mapsindoors.services.LocationsService.getLocations({ categories: categoryKey, lr: 'en' }).then(locations => { ... });` |
+| `bbox` | Object | Optional | Limits the result to inside the bounding box. Must include `bbox.east`, `bbox.north`, `bbox.south`, `bbox.west` | | |
+| `bbox.east` | number | Required if `bbox` | Max longitude of the bounds in degrees. | | |
+| `bbox.north` | number | Required if `bbox` | Max latitude of the bounds in degrees. | | |
+| `bbox.south` | number | Required if `bbox` | Min latitude of the bounds in degrees. | | |
+| `bbox.west` | number | Required if `bbox` | Min longitude of the bounds in degrees. | | |
+| `take` | number | Optional | Max number of locations to get. | | `await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', take: 5, ... });` |
+| `skip` | number | Optional | Skip the first number of entries. | | |
+| `near` | LatLngLiteral \| string | Optional | Can either be a coordinate `{lat: number, lng: number}` or a string in the format "type:id". | | `await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', radius: 50, ... });` |
+| `radius` | number | Optional | A radius in meters. Must be supplied when using `near` with a point. | | `await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', radius: 50, ... });` |
+| `floor` | integer | Optional | Filter locations to a specific floor. | | `await mapsindoors.services.LocationsService.getLocations({ near: 'location:9897fd93fcb14bd39ec8110d', floor: 50, ... });` |
+| `orderBy` | string | Optional | Which property the result should be sorted by. | | |
+| `sortOrder` | string | Optional | Specifies in which order the results are sorted, either "ASC" or "DESC" | "ASC" | |
+| `building` | string | Optional | Limit the search for locations to a building. | | |
+| `venue` | string | Optional | Limit the search for locations to a venue (id or name). | | |
+
+### Example of Creating a Search Query[](https://docs.mapsindoors.com/searching#example-of-creating-a-search-query)
+
+See the full list of parameters in the [reference guide](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html#.getLocations):
+
+```javascript
+const searchParameters = {
+ q: 'Office',
+ near: { lat: 38.897579747054046, lng: -77.03658652944773 }, // // Blue Room, The White House
+ take: 1
+}
+
+mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ console.log(locations);
+});
+```
+
+## Display Search Results on the Map[](https://docs.mapsindoors.com/searching#display-search-results-on-the-map)
+
+When displaying the search results, it is helpful to filter the map to only show matching Locations. Matching Buildings and Venues will still be shown on the map, as they give context to the user, even if they aren't selectable on the map.
+
+#### Example of Filtering the Map to Display Searched Locations on the Map
+
+```javascript
+const searchParameters = {
+ q: 'Office',
+ near: { lat: 38.897579747054046, lng: -77.03658652944773 }, // // Blue Room, The White House
+ take: 1
+}
+
+mapsindoors.services.LocationsService.getLocations(searchParameters).then(locations => {
+ mapsIndoorsInstance.filter(locations.map(location => location.id), false);
+});
+```
+
+### Clearing the Map of Your Filter[](https://docs.mapsindoors.com/searching#clearing-the-map-of-your-filter)
+
+After displaying the search results on your map you can then clear the filter so that all Locations show up on the map again.
+
+#### Example of Clearing Your Map Filter to Show All Locations Again
+
+```javascript
+mapsIndoorsInstance.filter(null);
+```
+
+### Display Locations as List[](https://docs.mapsindoors.com/searching#display-locations-as-list)
+
+You can also search for Locations, and have them presented to you as a list, instead of just displaying them on the map.
+
+The full code example is shown in the JSFiddle below which will be examined below.
+
+#### Search example[](https://docs.mapsindoors.com/searching#search)
+
+The `mapsindoors.services.LocationsService` class exposes the `getLocations` function that enables you to search for Locations.
+
+It will return a promise that gets resolved when the query has executed.
+
+See [mapsindoors.services.LocationsService](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/mapsindoors.services.LocationsService.html) for more information.
+
+```javascript
+searchElement.addEventListener('input', debounce((e) => {
+ const value = e.target.value;
+ if (value > '') {
+ mapsindoors.services.LocationsService.getLocations({ q: value, includeOutsidePOI: true })
+ .then(displayResults)
+ .then(filterMap);
+ } else {
+ clearResults();
+ clearFilter();
+ }
+}, 500));
+```
+
+The `debounce` method is there to ensure that the service is not being called in rapid succession. This method delays the execution of the function by 500ms, unless `debounce` is called again within 500ms, in which case the timer is reset.
+
+See this article ["What is debouncing" by Jamis Charles](https://medium.com/@jamischarles/what-is-debouncing-2505c0648ff1) for a more detailed description of the `debounce` concept.
+
+When the function executes, we check whether the input is empty or not. A request object is created if the input is not empty.
+
+The `getLocations` function expects either no input, in which case it returns all Locations, or an Object (please refer to the official documentation for an exhaustive list of properties). In this case, the constant `value` is passed to the `q` property and the `includeOutsidePOI` property is set to `true`. When the Promise resolves, the response is passed to the `displayResults` helper function.
+
+If the input is empty, we clear the result list and reset the map filter by calling the helper functions `clearResults` and `clearFilter`.
+
+#### Checking for Results[](https://docs.mapsindoors.com/searching#checking-for-results)
+
+We need to clear the previous results, and check if any Locations were returned. If so, we loop through them and add them to the result list.
+
+```javascript
+function displayResults(locations) {
+ clearResults();
+
+ if (locations.length > 0) {
+ for (const location of locations) {
+ searchResults.innerHTML += `${location.properties.name} `;
+ }
+ } else {
+ searchResults.innerHTML = 'No results matched the query. ';
+ }
+
+ return locations;
+}
+```
+
+If no Locations are returned, a message is shown to the user stating "No results matched the query.". Otherwise, we pass the Locations on to the next helper function called `filterMap`.
+
+```javascript
+function filterMap(locations) {
+ mapsIndoors.filter(locations.map(location => location.id), false);
+ return locations;
+}
+```
+
+The purpose of the `filterMap` function is to create a list of `location id`s used to filter the Locations on the map.
+
+The second parameter tells MapsIndoors not to change the viewport of the map.
+
+For more information, see `MapsIndoors.filter` in the [reference documentation](https://app.mapsindoors.com/mapsindoors/js/sdk/latest/docs/MapsIndoors.html#filter).
diff --git a/sdks-and-frameworks/web/search/utilizing-mapsindoors-web-components-and-other-searches.md b/sdks-and-frameworks/web/search/utilizing-mapsindoors-web-components-and-other-searches.md
new file mode 100644
index 0000000..0341d9b
--- /dev/null
+++ b/sdks-and-frameworks/web/search/utilizing-mapsindoors-web-components-and-other-searches.md
@@ -0,0 +1,19 @@
+# Utilizing MapsIndoors Web Components and Other Searches
+
+MapsIndoors web components are intended to take advantage of pre-designed and already integated HTML elements which will greatly reduce the complexity of your user-interface design and help minimize the amount of MapsIndoors specific SDK implementation code you'll need to write.
+
+{% embed url="https://www.npmjs.com/package/@mapsindoors/components" %}
+
+https://components.mapsindoors.com/
+
+
+
+While the MapsIndoors components will not cover every full user experience, it will allow you to implement MapsIndoors more efficiently.
diff --git a/sdks-and-frameworks/web/wayfinding/directions-renderer.md b/sdks-and-frameworks/web/wayfinding/directions-renderer.md
index 0fb3fed..367aa52 100644
--- a/sdks-and-frameworks/web/wayfinding/directions-renderer.md
+++ b/sdks-and-frameworks/web/wayfinding/directions-renderer.md
@@ -6,8 +6,6 @@ Once the `miDirectionsServiceInstance` and `miDirectionsRendererInstance` are in
This example shows how to set up a query for a route and display the result on a Google Map using the DirectionsRenderer:
-MJE: Needs Mapbox equivalent tap, ticket created DOC-84
-
for Google Maps
```javascript