{
    "componentChunkName": "component---src-design-system-templates-article-index-tsx",
    "path": "/blog/developers/use-cases/augmenting-directions/",
    "result": {"data":{"contentfulComposePage":{"title":"Augmenting Directions with Wait Time Information","seo":{"title":"Augmenting Directions with Wait Time Information","description":"Learn how to use the Mappedin SDK to overlay detailed information such as walking times and real-time wait time estimates at airport checkpoints."},"content":{"author":"Jere Suikkila","publishDate":"Mar 23, 2022","updatedAt":"Jul 26, 2022","content":{"raw":"{\"nodeType\":\"document\",\"data\":{},\"content\":[{\"nodeType\":\"embedded-asset-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"jkD16NKgOwV1LuqHgzihV\",\"type\":\"Link\",\"linkType\":\"Asset\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Navigating an airport is one of the most stressful parts of traveling. To avoid the hassle, airports can provide \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://www.mappedin.com/blog/use-cases/transportation/indoor-mapping-in-airports-enhancing-the-passenger-experience\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"detailed digital maps\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\" including a \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://www.mappedin.com/blog/use-cases/transportation/blue-dot-navigation/airports\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"Blue Dot wayfinding\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\" feature using the Mappedin SDKs. With the flexibility and the power of the Mappedin SDK, it's possible to overlay more detailed information such as walking times and real-time wait time estimates at checkpoints.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"The interactive demo below shows a simple implementation of this concept. You can also open the Sandbox in its own window or drag from the left sidebar to see and modify the sample code. To use the demo below:\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"ordered-list\",\"data\":{},\"content\":[{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Click on a location near the entrance (not a gate)\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Click on a plane to navigate to that gate\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"To reset the map, click outside of interactive location polygons\",\"marks\":[],\"data\":{}}]}]}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"<iframe src=\\\"https://codesandbox.io/embed/mappedin-airport-checkpoint-zoobe?fontsize=14&hidenavigation=1&theme=dark&view=preview\\\"\\n     style=\\\"width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;\\\"\\n     title=\\\"mappedin-airport-checkpoint\\\"\\n     allow=\\\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\\\"\\n     sandbox=\\\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\\\"\\n   ></iframe>\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"After you have selected start and destination locations on the map, the path is calculated with \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"directionsTo(destination)\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" that returns the path, distance and instructions:\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"pSmr7NVVnNE720Bpt8yJx\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"The \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"directions\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" object can be used for more than just drawing the path on the map. The overall distance returned will help us calculate walking time to the destination. The \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"path\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" will be used to go over the nodes in the navigation graph.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"2n2K0lLxObFNttkrmMahm7\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"We iterate over the directions to display wait times on the map at every checkpoint node. Every checkpoint gets a marker, which is formatted based on the delay caused and the wait time.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"In this example the wait times are randomized in the \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"Checkpoints\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" class and retrieved with \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"checkpoints.getCheckpointWaitTime(pathNode)\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\". However, this data could be easily fetched from an API.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"rank: COLLISION_RANKING_TIERS.ALWAYS_VISIBLE\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" ensures that the marker is visible\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"5PMhO26q4h5SjSpCuz1ilp\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Once we have drawn the markers on the map, we draw the route and set a custom path color within the \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://developer.mappedin.com/docs/web/latest/modules.html#TPathOptions\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"pathOptions\",\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\".\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"5NZrSbm5DBGOvhabGcjXOZ\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"This shows just one way in which the directions from the Mappedin SDK can be augmented. An airport map could also include a marker to display gate information or some paths could be temporarily restricted based on real-world conditions such as swing gates.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Combining your dynamic data with \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://www.mappedin.com/blog/product/map-editor/product-101-map-editor/\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"Mappedin's easily managed indoor maps\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\" creates exciting opportunities.\",\"marks\":[],\"data\":{}}]}]}","references":[{"contentful_id":"jkD16NKgOwV1LuqHgzihV","__typename":"ContentfulAsset","description":"","file":{"url":"//images.ctfassets.net/wdjnw2prxlw8/jkD16NKgOwV1LuqHgzihV/c37923c6f46dd001000f9acb60dd20a2/image.png","contentType":"image/png"}},{"contentful_id":"pSmr7NVVnNE720Bpt8yJx","__typename":"ContentfulCodeBlock","code":{"code":"const directions: MappedinDirections = startLocation.directionsTo(\n  endLocation as MappedinLocation\n);"},"language":"TypeScript","settings":null},{"contentful_id":"2n2K0lLxObFNttkrmMahm7","__typename":"ContentfulCodeBlock","code":{"code":"{\n  distance: number;\n  path: MappedinNode[];\n  instructions: TMappedinDirective[];\n}"},"language":"TypeScript","settings":null},{"contentful_id":"5PMhO26q4h5SjSpCuz1ilp","__typename":"ContentfulCodeBlock","code":{"code":"directions.path.forEach((pathNode) => {\n  if (checkpoints.checkpointNodes.includes(pathNode)) {\n    const waitTime = checkpoints.getCheckpointWaitTime(pathNode);\n    totalWaitTime += waitTime;\n    mapView!.createMarker(\n      pathNode,\n      `<div class=\"waittime waittime-${getWaitSeverity(\n        waitTime\n      )}\">${waitTime} min wait at checkpoint</div>`,\n      {\n        rank: COLLISION_RANKING_TIERS.ALWAYS_VISIBLE\n      }\n    );\n  }\n});"},"language":"TypeScript","settings":null},{"contentful_id":"5NZrSbm5DBGOvhabGcjXOZ","__typename":"ContentfulCodeBlock","code":{"code":"mapView!.Journey.draw(directions, {\n  pathOptions: {\n    color: 0x44ab42\n  }\n});"},"language":"TypeScript","settings":null}]},"image":{"file":{"url":"//images.ctfassets.net/wdjnw2prxlw8/jkD16NKgOwV1LuqHgzihV/c37923c6f46dd001000f9acb60dd20a2/image.png"}},"pdf":null,"relatedPosts":[{"title":"Integrating Indoor Positioning System with Mappedin SDKs","slug":"ips-integration","content":{"__typename":"ContentfulBlogPost","author":"Jere Suikkila","publishDate":"Feb 15, 2022","updatedAt":"Jul 6, 2022","tags":{"category":{"name":"Developers","slug":"developers"},"topic":{"name":"Use Cases","slug":"use-cases"}},"content":{"raw":"{\"data\":{},\"content\":[{\"data\":{\"target\":{\"sys\":{\"id\":\"yV1ZZQhfqbkAoBwXzD0Xn\",\"type\":\"Link\",\"linkType\":\"Asset\"}}},\"content\":[],\"nodeType\":\"embedded-asset-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"You are here\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\" is one of the first things we expect to find on a map today. There is no need to manually triangulate our position based on stars because the device we hold in our hands can already tell us our location. That is if we are outdoors. The story gets more complicated if we move indoors.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"With Indoor Positioning Systems (IPS) users can see their precise location represented by a blue dot within the context of an indoor map. Similar to outdoor GPS, users are not required to enter a \\\"start\\\" location and as they begin to follow along a route, the blue dot moves with them, providing an enhanced navigational experience.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Indoor Positioning Systems are valuable components of rich indoor mapping experiences. They ensure that the user does not need to know their location in a venue. This saves both time and confusion, making for a much more pleasant wayfinding experience.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"GPS has about 3 meter accuracy when we are outside and have no obstructions such as skyscrapers around us. However, inside a building, GPS is nearly useless. That's why several technologies have been developed to provide indoor positioning in various scenarios such as \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://resources.mappedin.com/blog/what-is-blue-dot-wayfinding\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"wayfinding\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\", \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://resources.mappedin.com/blog/indoor-mapping-use-case-asset-tracking\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"asset tracking\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\", contact monitoring and smart building applications.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Positioning smarts for indoors\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-2\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"4aHfBcHMLcb5o2fmxayffP\",\"type\":\"Link\",\"linkType\":\"Asset\"}}},\"content\":[],\"nodeType\":\"embedded-asset-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"The different indoor positioning systems have different tradeoffs. For example, using beacons requires installing Bluetooth Low Energy (BLE) devices in known positions around the venue. WiFi-based systems use existing infrastructure and requires a radio frequency mapping of the venue. Some systems blend multiple technologies in sensor fusion to further process the positioning data into a more accurate representation of the actual position.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"To integrate with the Mappedin SDKs, it does not really matter what underlying technology is used to obtain the indoor position as long as it can provide information about the current floor and the \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"geocoordinates\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" (latitude and longitude). Based on that the Mappedin SDK is able to \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/guides/webv4/bluedot\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"place the Blue Dot on the map\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" indicating the current position of the device.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"7tbzSHUglPtWzsIa9kPuUD\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"One of the easiest ways to \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://resources.mappedin.com/blog/product-101-imdf-export\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"setup Indoor Positioning System is Apple's infrastructure-free positioning\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" combined with Mappedin map rendering and data management.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Integrating positioning data with Mappedin React Native SDKs\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-2\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Below is the \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/guides/react-native/quickstart/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"minimal implementation of drawing a map\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" with Mappedin React Native SDK. In 5 minutes, we will build on this code to display the Blue Dot and override the positions from a premade path of geocoordinates. After ensuring everything works as expected, you can easily connect the IPS to provide the position to Mappedin SDK instead\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"aRyiK6XjGEWNpHL0a2E4F\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"We have pregenerated a route in \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/code/sdks/react-native/positions.json\"},\"content\":[{\"data\":{},\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"value\":\"positions.json\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" that can be used for debugging Blue Dot features in \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"value\":\"mappedin-demo-mall\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\". Below is the first element of the list, which we will set as our starting coordinate for camera focus. It follows the \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPosition\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"specification of Geolocation Position of Web APIs\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\".\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"WWftOy5W8uhstWiXOHYNk\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"First, we create a \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"value\":\"MappedinCoordinate\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\" for our starting location and zoom in the camera to get a closer view of the Blue Dot.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"4nDiMFiWYwIzJj2E7aOJsU\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"We set the \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/docs/react-native/latest/enums/state\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"map state\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" to \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"value\":\"follow\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\", which keeps the Blue Dot in the middle of the view. Then we enable the Blue Dot and set the starting location.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"3gV9owEJDn12XKswCpc1ko\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"To walk through the list of positions, we can create a simple interval outside of our \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"value\":\"render\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\" method for overriding the position every few seconds. The position will jump to the start after the route is completed. This code is not optimized and should be replaced with the positioning updates coming from your IPS.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"7D6MiKAE2X6B36mYYzcoK2\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"29dn1eaOYbx5f8K4w1D0Pf\",\"type\":\"Link\",\"linkType\":\"Asset\"}}},\"content\":[],\"nodeType\":\"embedded-asset-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Completed sample\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-2\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Below code sample can be pasted into a fresh \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/guides/react-native/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"React Native starter project\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" with the addition of \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/code/sdks/react-native/positions.json\"},\"content\":[{\"data\":{},\"marks\":[{\"type\":\"code\"},{\"type\":\"bold\"}],\"value\":\"positions.json\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\".\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"7hyVSBE6ShMkx2Qu837G2w\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[],\"nodeType\":\"embedded-entry-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Summary\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-2\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Mappedin SDKs are ready to work with any IPS provider that can be integrated with your app to provide geolocation and floor to Mappedin within minutes. The Blue Dot can be enabled and then connected to the position updates in just a few lines of code, delivering accurate indoor positioning and enhanced wayfinding experiences.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"If you want to discuss indoor positioning as it relates to your venue, \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://www.mappedin.com/contact-us/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"contact us now\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\".\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"blockquote\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"document\"}"},"articleType":"Dev Content","image":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAMAAABI111xAAABoVBMVEXR3N/x8fHS0tKQkJCSkpLq6urT0tIOXXXM1djT1NTm5ubCwsK1tbXv7+9Yjp67yc2sr7TQ0dTo6OjE1Nnj4+OqqqrIyMgkbIG5ys/a2tvw8PDr6+uko6Nei5mlu8K8vsLu7u62y9Ht7e07eo2pwcnq6uvm5+jT3N+4y9GcucFGgZNAfI5SiZo6eYwian8MXHSrxMzh5ueJrLYhaoAja4EdZ30ZanoWe4wGXnY/UWVGV2sDV3BmS1wsVGqevMXM1tkdZ3xMWm4MVW4HYXgSbIAXZXsydYlBf5FTippjlaNzn6x/pK+StL5JgZFZY3W0f4kKWHCjvcW+zuTM1+nW1tacnJzl5eXR0NDs7OyFrLjt7u7b4OESXnU5Wm8UVW2MrrioqKje3t63t7d9fX3Ozc1qnKtwn61om6pll6YLWnJXh5bU1NS6urrf39/Pz8+Tk5Pp6enAv79omqkuWW1kTF2Wtr9ZWVnBwMCdvcaQtb/g6u1pm6ocY3gEV3B1nqrFxMTNzMzn5+dlZWXAvr9tnq0laX5HSVxklqTh4eHV1dVVVVWFZ6dkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5gkTDjAgrcPzDgAAALpJREFUCNdjZGDEAL8Zhd8JMzK+52VlZPzJARZ6JMnGqPhG9IXEv4dKyEpZ+B98UbxvIAQXABr3j4WPgeGHHZDzkwGo+5I+WIIJKPicDwjExAXu8NvtvszHt52XhZchEqJvVfhbPkYGhqOeDAxMPKm8vLz3eHh4GICQJ5/hPy/DKRYmBgYuRkvGGaIcXxg+i/5geM7G8I9FEKK5iJGxk3lJbTdIAxMTz7vXbziBYAoHF98fjnZh+bfhZgDvBy0LpeAB/AAAAABJRU5ErkJggg==","aspectRatio":1.7768817204301075,"src":"//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=480&q=50","srcSet":"//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=120&h=68&q=50 120w,\n//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=240&h=135&q=50 240w,\n//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=480&h=270&q=50 480w,\n//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=720&h=405&q=50 720w,\n//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=960&h=540&q=50 960w,\n//images.ctfassets.net/wdjnw2prxlw8/yV1ZZQhfqbkAoBwXzD0Xn/e605b6b14ed11811c0cb5f995cdd75a0/bluedot-accurate.png?w=1322&h=744&q=50 1322w","sizes":"(max-width: 480px) 100vw, 480px"}}}},{"title":"Create a leasing map for a mall with Mappedin Web SDK","slug":"create-leasing-app","content":{"__typename":"ContentfulBlogPost","author":"Jere Suikkila","publishDate":"Nov 29, 2021","updatedAt":"Jul 26, 2022","tags":{"category":{"name":"Developers","slug":"developers"},"topic":{"name":"Use Cases","slug":"use-cases"}},"content":{"raw":"{\"nodeType\":\"document\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Mappedin SDKs are flexible toolkits for working with your venue map to create custom applications beyond consumer-facing indoor navigation. A leasing map is another useful map view for many malls, where potential store owners can view available locations for leasing with more detailed information such as square footage and availability dates.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Augmenting the  map data with an external data source is easy. Locations and polygons have \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"externalId\",\"marks\":[{\"type\":\"code\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" attributes set in the \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://www.mappedin.com/mapping/map-editor/\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"Mappedin CMS\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\" so that it is seamless to integrate data from other sources on top of the map data rendered by the Mappedin SDK.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"In this blog post we implement some basic functionality for a leasing-focused mall application. We will walk through the following features, which are shown in the embedded demo below. The CodeSandbox demo allows for forking the existing demo for editing. We won't go through every line of code in this post but explain how the key functionalities beyond the basic Mappedin guides are created and could be improved further.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"unordered-list\",\"data\":{},\"content\":[{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Displaying the map (\",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://developer.mappedin.com/guides/webv4/loading-map\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"See guide\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\")\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Adding availability data\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Coloring multiple polygons\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Displaying markers (\",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://developer.mappedin.com/guides/webv4/markers\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"See guide\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\")\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Focus on a polygon (\",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://developer.mappedin.com/guides/webv4/camera-controls\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"See guide\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\")\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Listing locations (\",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://developer.mappedin.com/guides/webv4/listing-locations\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"See guide\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\")\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"list-item\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Filtering locations\",\"marks\":[],\"data\":{}}]}]}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"In the example below, click on a location on the list or on the map to open an informative marker about the unit.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"<iframe src=\\\"https://codesandbox.io/embed/mappedin-leasing-demo-1-p3ri4?fontsize=14&hidenavigation=1&theme=light&view=preview\\\"\\n     style=\\\"width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;\\\"\\n     title=\\\"mappedin-leasing-demo-1\\\"\\n     allow=\\\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\\\"\\n     sandbox=\\\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\\\"\\n   ></iframe>\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"The example uses Typescript and it should be trivial to modify it to Javascript. The \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://resources.mappedin.com/blog/product-launch-sdk-v-4.0\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"Mappedin Web SDK v4\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\" released in November 2021 provides types so it's natural to take full advantage of them while building applications on top of it.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"heading-2\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Adding availability data\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Availability data is the key to a customer-friendly leasing application. Being able to to display available units and additional information about them requires a data source. Connecting that to the map requires connecting to the source API and making sure the data is in a format that works for your frontend use-case.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"After setting up for the basic setup in the \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"init\",\"marks\":[{\"type\":\"code\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" function (see \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://developer.mappedin.com/guides/webv4/add-interactivity\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"Adding interactivity -guide\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\"), we move to setting up the availability. In a real service, fetching the availability data could be done before or simultaneously with fetching the venue data. In this example, the available units are created based on the venue data, so we need that first.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"In a real system, the available unit data is requested from a system that manages the leasing data. Additionally, the application could come with authentication to ensure that the leasing data is available only to a limited audience instead of being public. It could also provide richer data about the unit, which is not covered in this example.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"34kUkyVZyQA4tmMPJflvrZ\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Coloring all the polygons is just a loop over the given polygons and setting the color for each of them.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"4YolIoiCt359j2Zc8kpOyu\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"heading-2\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Displaying markers\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"We created a function for displaying the informational leasing marker.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\" \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"removeAllMarkers() \",\"marks\":[{\"type\":\"code\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"call on the second line of the function makes sure there is only one marker visible at a time by removing all other markers. The marker can be an \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"svg\",\"marks\":[{\"type\":\"code\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" of a pin or any other valid HTML. Therefore, we are able to use a string template and fill it with the (in this case made up) leasing information.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"1tLdMRDNws5Lx8g4vJiNnZ\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"The styling of the marker is easy to customize with CSS:\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"1SUmJhszfuhSEE5fEDD63D\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"heading-2\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Listing and filtering locations\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"The demo implements a single checkbox for filtering how the location list is displayed. Our \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"populateLocationList(onlyShowAvailable = false)\",\"marks\":[{\"type\":\"code\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" function takes a boolean input for either displaying all of the locations or only the ones that are marked available. We also set \",\"marks\":[],\"data\":{}},{\"nodeType\":\"text\",\"value\":\"onChange\",\"marks\":[{\"type\":\"code\"}],\"data\":{}},{\"nodeType\":\"text\",\"value\":\" event handler for the checkbox to first clear and then repopulate the location list based on the new filter value. In our loop to create the location list elements, we check the filter and availability data, to make sure only the desired locations are shown.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"embedded-entry-block\",\"data\":{\"target\":{\"sys\":{\"id\":\"AKbNomDcMFE00wEo1C9mN\",\"type\":\"Link\",\"linkType\":\"Entry\"}}},\"content\":[]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"This code is very specific to this one filter. However,\\n with richer data coming from a leasing system this could be customized \\nfurther. For example, it could be possible to filter to show only the \\nanchor stores or to display units larger than a threshold area.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"heading-2\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"What's next?\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"To take this example to the next level, it could use more filters that interactively highlight polygons on the map, a search option and richer markers based on availability data coming from a real-world system.\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"blockquote\",\"data\":{},\"content\":[{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"Did this post help you implement a leasing application? Which example would you like us to build next? Let us know on \",\"marks\":[],\"data\":{}},{\"nodeType\":\"hyperlink\",\"data\":{\"uri\":\"https://twitter.com/mappedin\"},\"content\":[{\"nodeType\":\"text\",\"value\":\"Twitter\",\"marks\":[],\"data\":{}}]},{\"nodeType\":\"text\",\"value\":\"\",\"marks\":[],\"data\":{}}]}]},{\"nodeType\":\"paragraph\",\"data\":{},\"content\":[{\"nodeType\":\"text\",\"value\":\"\",\"marks\":[],\"data\":{}}]}]}"},"articleType":"Dev Content","image":{"fluid":{"base64":"data:image/png;base64,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","aspectRatio":1.589307411907655,"src":"//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=480&q=50","srcSet":"//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=120&h=76&q=50 120w,\n//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=240&h=151&q=50 240w,\n//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=480&h=302&q=50 480w,\n//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=720&h=453&q=50 720w,\n//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=960&h=604&q=50 960w,\n//images.ctfassets.net/wdjnw2prxlw8/3KUijAcYOygyu9sDfmRbJw/c34a546da3590d0c5775f15561d80477/image.png?w=1308&h=823&q=50 1308w","sizes":"(max-width: 480px) 100vw, 480px"}}}},{"title":"Open Source Contact Monitoring","slug":"contact-monitoring","content":{"__typename":"ContentfulBlogPost","author":"Ed Wei","publishDate":"Jul 28, 2020","updatedAt":"Jul 6, 2022","tags":{"category":{"name":"Developers","slug":"developers"},"topic":{"name":"Use Cases","slug":"use-cases"}},"content":{"raw":"{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"We are happy to share that we have open sourced our Contact Monitoring solution! To see how it all works under the hood and get your own system running, read on.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Why\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-2\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"\",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://www.apple.com/covid19/contacttracing\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Apple and Google has teamed up together\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" to offer a set of public contact tracing APIs that allows iOS and Android devices to be used to detect when an individual has been in contact with some who has been tested positive for COVID-19. While governments and health authorities around the world are benefiting from this technology, very little is available for the enterprise world, where employees are coming back to work, places are re-opening. With our contact monitoring solution, we can utilize indoor positioning technologies, such as \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.apple.com/videos/play/wwdc2019/245/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Apple's Indoor Maps Program\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\", and use that information to accurately determine contact events. We've been \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://info.mappedin.com/apple-maps\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"working with Apple\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" for many years, building on top this positioning technology. It would naturally be a fit here. A solution like this would benefit places like hospitals, corporate offices, manufacturing facilities, etc.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"Privacy\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\" is an area where we feel full transparency is the ultimate solution. There's nothing better than showing all of the code that's involved in processing the data. This is why we have decided to \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"open source\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\" our solution. We've done our best to ensure there's no personal information being collected. We used generated IDs everywhere, only send data when you are on site at your venue, and you have the full power on deciding how long to retain the data in the database. You can read our documentation on \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://github.com/mappedin/contact-monitoring-ingest-api\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"github\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" for more information.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Overview\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-2\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Below is a diagram that shows how the contact monitoring solution works.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"CDwcDKa0753SBqmxlmjpn\",\"type\":\"Link\",\"linkType\":\"Asset\"}}},\"content\":[],\"nodeType\":\"embedded-asset-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"We have created a \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"mobile sdk\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\" that anyone can integrate with their existing employee app. It continuously collects positioning data, but only when the device is located on site. The data is then sent to the server for processing. The server processes the events in near realtime and determines contact. And finally, we made a dashboard that can visualize the contact events.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"There are mainly 3 components that we are open sourcing, \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"Mobile SDK\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\", \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"Ingestion API\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\", and \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"Dashboard\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Native Mobile SDK\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-3\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"This SDK is responsible for tapping into indoor positioning systems to get device's location data, and it does so in the background in a way that minimizes battery usage. It only collects position data \",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[{\"type\":\"bold\"}],\"value\":\"while you are on site\",\"nodeType\":\"text\"},{\"data\":{},\"marks\":[],\"value\":\". Testing in our lab indicates that we consistently get accuracy of 2 meters (or 6 feet) when using Apple's Indoor Positioning System. \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://www.mappedin.com/contact-us/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Contact us\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" to get your venue indoor positioning ready.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"To learn more about how our Contact Monitoring Mobile SDK works, \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/blog/2020-07-27-contact-monitoring-mobile/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"go here\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\".\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Ingestion API\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-3\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"The Ingestion API is where the heart of the system is. It is responsible for collecting device location data, process it at high volume to determine contact, and store it optimally for querying by our dashboard. We went through several iterations of the design of the algorithm. You can \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://developer.mappedin.com/blog/2020-07-28-contact-monitoring-api/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"read about it here\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\".\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Dashboard\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-3\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"The dashboard is where all the contact monitoring information is surfaced. It queries the processed data and provides visualizations that uses Mappedin's indoor maps. \",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://www.mappedin.com/contact-us/\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Contact us\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\" to get a map created for you.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{\"target\":{\"sys\":{\"id\":\"VAtrLwrNUbT1vB4g0ADSU\",\"type\":\"Link\",\"linkType\":\"Asset\"}}},\"content\":[],\"nodeType\":\"embedded-asset-block\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Some functionalities of the dashboard include:\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"List detail view & map detail view\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"list-item\"},{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Contact events are aggregated as you zoom out of the map and disperse as you zoom in\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"list-item\"},{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"When an event is selected, a summary of that event displays\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"list-item\"},{\"data\":{},\"content\":[{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"An event is placed at the location where the interaction started\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"list-item\"}],\"nodeType\":\"unordered-list\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Get started on running your own Contact Monitoring system\",\"nodeType\":\"text\"}],\"nodeType\":\"heading-3\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Head on over to our github pages.\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"},{\"data\":{},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"\",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://github.com/mappedin/contact-monitoring-ios-sdk\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"iOS Contact Monitoring SDK\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\"\\n\",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://github.com/mappedin/contact-monitoring-ingest-api\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Contact Monitoring Ingest API\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\"\\n\",\"nodeType\":\"text\"},{\"data\":{\"uri\":\"https://github.com/mappedin/contact-monitoring-dashboard\"},\"content\":[{\"data\":{},\"marks\":[],\"value\":\"Contact Monitoring Dashboard\",\"nodeType\":\"text\"}],\"nodeType\":\"hyperlink\"},{\"data\":{},\"marks\":[],\"value\":\"\",\"nodeType\":\"text\"}],\"nodeType\":\"paragraph\"}],\"nodeType\":\"document\"}"},"articleType":"Dev Content","image":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAABPGlDQ1BpY2MAAHjarY6/SwJhGICfLy0tkRout+DAQQKNuhyKhjAHCRpEBH9MneelwWUf50EFtUV/QrS0NrU1SJv0FwRFRXO0RYPgknINV2lLU8/yPjy88L4wMqVLafmBnYZj5zJrarFUVgOvjDFDkCViutGUqWx2A+B7/qb7gAC4S+hSWuel25Pc1crb9GRo9V0mqvzNRNVsGkAPMAxpOyA2geieIx0Qx4BiF0tlEGeAUvP8ElAqnrcBxc7n0iDugSmjrldBvADxylCvDfnXXYBxLZnRCguZJP+MY+47AOldeWBv1+qOmpLSMtX1hjEXV7V5TYNiqax6250nBCAiwUE7jMLyEfjMQcu14DoC4eagxXoQtuAmL3Vb/3lAdP3NrUXN81ALRk9dt1OAwCz0H133o+W6/QvwPUO7+wmwI11jwHnLJwAAAAlwSFlzAAAXEQAAFxEByibzPwAAAAd0SU1FB+YJHRMcI/najgoAAALDSURBVBgZLcHNbhtVFADge8+5d+bOjMeOHedPlZJCSOQqZNFs+gRFLNjwCDwIW7Y8AjsWIBBrWCNVQk0jUkVNnJLUqR07jV2Pxx7P3L9DhPg+/tvPPzHG4jQlxr797vsFNrPJhMcpk+jyjJVzZpec3DdfPz980un1ej/+8mtVaeOd9x6CKAqUkoGK4vSo8wnFzVAgEaEKHYGXMQtSFjVP374n76y1CICIAvABEBcoAhAhSrWz27HjG4wbMQrtAh4lJEISISM6vezJuBYltSSJlQoFIgDgTf/24OAQhPz9z1d348V00NXJBhVZqGKspcwZQOaN8Z5troSb62sPVtttISVjhKsh5OP7nbuTH/74azgadXa37nRQzKZa67jRBO78g6pk3i/z6dHnHQ7w+s15t9s1VQmPW0kxvH47HO3Vqmd77S++/GrxoWedcU7bRWGlImNkoKJAdnvDj1l2enb28vjVbL4YZ7mYLG0SULY0SRztP+gcNLAarT7i40ExGQA54GSNseQ4Bi9enlx0L7Qx3nvGGNTraUMFl/dFAk4KNI4O93dRSCAbpC259yRuNUSiUIVciOOzi1k+5+x/wAEc0Woky7LM8/nJ+U1z61NY3HOV6OmtuTrXBMwTLwsyVV4sgRHnnP1HIACHAAUPOBv134+TEYbpip/PMPZ67mZ5OdLMWylQoADgSVrnWBjnnDHCGUORcuC9NdVsukKOQGyvNa+6Z6FSGkNHIYHQlWaMEDwRhUpFKAX3oh7JOIRWq72cz0pmTdZn1n+2/XizFtx9nFjrOOdRFAkhrLXaaADw1mljrLUi54qC5PjvS2JMG/vo+t3+1lrIHM6X//QntVZ7e3tnY329d311O+g3Go3B7VBKUZYVcM6Pnj6VUs6LpVKKMaa1cc467x15ZwxwDhyEwHZzJa3X1zc2sywbDAaV1t77fwFCDootIOUo1AAAABJ0RVh0ZXhpZjpFeGlmT2Zmc2V0ADI2UxuiZQAAABl0RVh0ZXhpZjpQaXhlbFhEaW1lbnNpb24ANTU3NXEcx3AAAAAZdEVYdGV4aWY6UGl4ZWxZRGltZW5zaW9uADM5MjNwgutQAAAAKHRFWHRpY2M6Y29weXJpZ2h0AENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDIy5LS/nAAAABh0RVh0aWNjOmRlc2NyaXB0aW9uADI0RzJXMUc0qa0vjAAAAABJRU5ErkJggg==","aspectRatio":1.4211062962018863,"src":"//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=480&q=50","srcSet":"//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=120&h=84&q=50 120w,\n//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=240&h=169&q=50 240w,\n//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=480&h=338&q=50 480w,\n//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=720&h=507&q=50 720w,\n//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=960&h=676&q=50 960w,\n//images.ctfassets.net/wdjnw2prxlw8/46WIUSrjNwDxcBLgYdaXWL/6119e327ffa037fccc07d089b031ff8a/image.png?w=1440&h=1013&q=50 1440w","sizes":"(max-width: 480px) 100vw, 480px"}}}}],"tags":{"category":{"slug":"developers","name":"Developers"},"topic":{"slug":"use-cases","name":"Use Cases"}}}}},"pageContext":{"slug":"augmenting-directions"}},
    "staticQueryHashes": ["1252674921","3226752585","3508205345","764694655"]}