<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Data Analysis on Digi Hunch</title><link>https://static.digihunch.com/tag/data-analysis/</link><description>Recent content in Data Analysis on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Wed, 02 Apr 2025 09:27:15 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/data-analysis/index.xml" rel="self" type="application/rss+xml"/><item><title>A taste of IoT device tracking</title><link>https://static.digihunch.com/2023/03/a-taste-of-iot-device-tracking/</link><pubDate>Fri, 03 Mar 2023 10:53:00 -0400</pubDate><guid>https://static.digihunch.com/2023/03/a-taste-of-iot-device-tracking/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-iot-device-tracking.webp" alt="Featured image of post A taste of IoT device tracking" /&gt;&lt;p class="wp-block-paragraph"&gt;Last fall I worked on a demo project for IoT device tracking on AWS so I had some reading. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Overview&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;From a strategic level, as servers move away to the cloud, AWS envisions that the footprint left on premise will mainly be IoT devices. The role of the cloud therefore becomes a central point of management for IoT devices. As a result, most of the AWS services for IoT are managed services. The best resources are two white papers: &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/iot-lens/welcome.html?did=wp_card&amp;amp;trk=wp_card"&gt;IoT Lens &amp;#8211; AWS Well-Architected Framework&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/securing-iot-with-aws/securing-iot-with-aws.html?did=wp_card&amp;amp;trk=wp_card"&gt;Securing Internet of Things (IoT) with AWS&lt;/a&gt;. The most important services are:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;IoT Analytics&lt;/strong&gt;: Makes it easy to run sophisticated analytics on volumes on IoT data. It connects to the underlying IoT data store and allow you to build your own analytical queries and Jupiter notebooks.&lt;/li&gt;&#10;&lt;li&gt;IoT Events&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/startups/an-introduction-to-aws-iot-core/"&gt;IoT Core&lt;/a&gt;: Core features for IoT. &lt;/li&gt;&#10;&lt;li&gt;IoT SiteWise&lt;/li&gt;&#10;&lt;li&gt;IoT Device Management&lt;/li&gt;&#10;&lt;li&gt;IoT Greengrass&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;FreeRTOS&lt;/strong&gt;: IoT devices usually need to be small and power efficient. The software and OS running on the device is important. FreeRTOS is a real-time operating system for micro-controllers supported by AWS. FreeRTOS provides kernel, OS and libraries to securely connect your edge device to the cloud in no time.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In this post I will explore IoT architecture at high level. In real life, you program your device with AWS IoT Device SDK and AWS IoT API in different languages. In this post, I use a script to simulate GPS data, and push it to AWS IoT using SDK. Then I render the location using sample AWS code for Amazon Location.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-iot-architecture"&gt;IoT Architecture&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When creating IoT services we consider registration and telemetry capturing flow. The Well architected white paper proposes registration flow as such:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="668" src="https://static.digihunch.com/wp-content/uploads/2023/03/registration-flow.webp" alt="" class="wp-image-12900" style="width:569px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2023/03/registration-flow.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/03/registration-flow-300x196.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/03/registration-flow-768x501.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;figcaption class="wp-element-caption"&gt;Registration Flow&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Device Registry to keep track of devices (aka Things). You can find where your devices are, and filter by a common feature (e.g. ModelX device only). Registration flow usually involves a testing of communication between device and server. The authentication must be 2-way where server needs to validate device identity, and device needs to validate server identity. You can use a unique X.509 certificate per device to adhere to security best practices on AWS. This way, if one device gets hacked, the entire fleet of devices is not affected by one certificate being compromised. An alternative authentication method is Cognito. With Cognito you can sign your users into a mobile application, so you use IAM policies to authenticate them into viewing different dashboards or viewing the data that pertains to them specifically. IoT Core policies can help manage authorization.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The white paper also proposes a few options for capturing telemetry:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="593" src="https://static.digihunch.com/wp-content/uploads/2023/03/opt-cap-telemetry.webp" alt="" class="wp-image-12902" srcset="https://static.digihunch.com/wp-content/uploads/2023/03/opt-cap-telemetry.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/03/opt-cap-telemetry-300x174.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/03/opt-cap-telemetry-768x445.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;figcaption class="wp-element-caption"&gt;Options for capturing telemetry&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;These options presents a common pub-sub pattern, where the device streams message by topic to the Message Broker in IoT core. The IoT core also involves policy and rules. A rule may involve a subscriber to consume the messages. A more comprehensive architecture from AWS &lt;a href="https://aws-quickstart.github.io/quickstart-iot-device-connectivity/"&gt;IoT device connectivity workshop&lt;/a&gt; looks like this:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="548" src="https://static.digihunch.com/wp-content/uploads/2023/03/iot-device-connectivity.webp" alt="" class="wp-image-12903" srcset="https://static.digihunch.com/wp-content/uploads/2023/03/iot-device-connectivity.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/03/iot-device-connectivity-300x161.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/03/iot-device-connectivity-768x411.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The message path from device to IoT core remains the same. When building an IoT solution, we first address the messaging path.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;IoT Protocols&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In IoT core, Device Gateway is the entry point for IoT devices connecting to AWS.It supports MQTT, WebSockets and HTTP 1.1 protocols, on top of TLS. Registration flow uses HTTP/REST protocol for provisioning, and with MQTT protocol for a message test. For pushing telemetry, we can use both but prefer &lt;a href="https://mqtt.org/"&gt;MQTT&lt;/a&gt; (topic based) because of its advantages in IoT messaging. &lt;a href="https://www.hivemq.com/blog/mqtt-vs-http-protocols-in-iot-iiot/"&gt;Here&lt;/a&gt; is a good article on the differences. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AWS has a white paper on &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/designing-mqtt-topics-aws-iot-core/designing-mqtt-topics-aws-iot-core.html"&gt;designing MQTT topics&lt;/a&gt;, with a few communication patterns and best practices. The SDK documentation also explained the &lt;a href="https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html"&gt;communication protocols&lt;/a&gt;, including:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;HTTPS: publish only&lt;/li&gt;&#10;&lt;li&gt;MQTT: publish and subscribe&lt;/li&gt;&#10;&lt;li&gt;MQTT over WebSocket: publish and subscribe. Device Gateway will maintain long lived, bi-directional connections, enabling devices to send and receive messages at any time with low latency.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Pay attention to the authentication mechanism. As to what protocol is used in a communication, they can be dynamically negotiated using the ALPN protocol. ALPN (Application-Layer Protocol Negotiation) is a TLS protocol extension that allows the application layer to negotiate which&amp;nbsp;&lt;a href="https://en.wikipedia.org/wiki/Communications_protocol"&gt;protocol&lt;/a&gt;&amp;nbsp;should be performed over a secure connection in a manner that avoids additional round trips and which is independent of the application-layer protocols.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;GPS data simulator&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;I don&amp;#8217;t have a GPS chip. To get sample GPS data, I used geojson.io website, use a pen to paint the points and collect the result in JSON format. The data looks like this:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;FeatureCollection&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;features&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Feature&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;: {},&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;geometry&amp;#34;&lt;/span&gt;: {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;coordinates&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;4966304331144&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;88901098598916&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;4966304331144&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;889903059931726&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;49658503509582&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;89066350338888&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;49658503509582&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;891365440561145&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;4966304331144&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;89219897769374&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;4966304331144&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;88735841200943&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;49660773410511&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;8880603972496&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;119.&lt;span style="color:#a6e22e"&gt;4966304331144&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 49.&lt;span style="color:#a6e22e"&gt;88885011844141&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;LineString&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Save this file as map.geojson to later feed it to device simulation script. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Rendering location data&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In AWS &lt;a href="https://github.com/aws-samples/amazon-location-samples"&gt;location samples&lt;/a&gt; project, the sample project &lt;strong&gt;&lt;a href="https://github.com/aws-samples/amazon-location-samples/tree/main/maplibre-js-react-iot-asset-tracking"&gt;maplibre-js-react-iot-asset-tracking&lt;/a&gt;&lt;/strong&gt; is a good demo of IT. The &lt;a href="https://github.com/aws-samples/amazon-location-samples/blob/main/maplibre-js-react-iot-asset-tracking/README.md"&gt;readme&lt;/a&gt; document contains a walk through, using AWS amplify services. The steps includes creating certificates, configuring lambda function to add location data to tracker. The project directory also includes the device simulation script, as &lt;a href="https://github.com/aws-samples/amazon-location-samples/blob/main/maplibre-js-react-iot-asset-tracking/generate_thing_events/index.js"&gt;index.js&lt;/a&gt;. I slightly modified the content to this:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;awsIot&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;aws-iot-device-sdk&amp;#34;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Replace with your AWS IoT endpoint&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;THING_ENDPOINT&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;safdsa-ats.iot.us-east-1.amazonaws.com&amp;#34;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// get from console&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CLIENT_ID&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;trackThing01&amp;#34;&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IOT_TOPIC&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;iot/trackedAssets&amp;#34;&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DEVICE_ID&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;thing123&amp;#34;&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;GEOJSON_FILEPATH&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;geojson/map.geojson&amp;#34;&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;file_raw&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readFileSync&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;GEOJSON_FILEPATH&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;positions_raw&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;file_raw&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;features&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;geometry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;coordinates&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;POINTS_ON_MAP&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;positions_raw&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;;&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;POINTS_ON_MAP&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;lat&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;positions_raw&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;][&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;],&lt;span style="color:#66d9ef"&gt;long&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;positions_raw&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;][&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]})&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;device&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;awsIot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;device&lt;/span&gt;({&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;THING_ENDPOINT&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;keyPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__dirname&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/certs/private.pem.key`&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;certPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__dirname&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/certs/certificate.pem.crt`&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;caPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__dirname&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/certs/root-CA.pem`&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;clientId&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CLIENT_ID&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;keepalive&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;60000&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Connecting to %s with client ID %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;THING_ENDPOINT&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;CLIENT_ID&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;device&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;connect&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Connected to device %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;CLIENT_ID&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;point&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;of&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;POINTS_ON_MAP&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;deviceId&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DEVICE_ID&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;timestamp&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date().&lt;span style="color:#a6e22e"&gt;getTime&lt;/span&gt;(),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;point&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Publishing message to topic %s: %s&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;IOT_TOPIC&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;device&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;publish&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;IOT_TOPIC&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;), { &lt;span style="color:#a6e22e"&gt;qos&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; });&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Set timeout to sleep&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Promise((&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;setTimeout&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10000&lt;/span&gt;));&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;device&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;end&lt;/span&gt;();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;We can obtain certificate ID from AWS console or by CLI command: &lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aws iot list-certificates --output text --query &lt;span style="color:#e6db74"&gt;&amp;#39;reverse(sort_by(certificates,&amp;amp;creationDate))[:1].[certificateId]&amp;#39;&lt;/span&gt; | cat&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;When running the script, it pushes data to IoT core service. The AWS Amplify project creates Lambda function that is subscribed to the topic and trigger actions. The data are used to render points on a map, which is available on the front end.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This is an overly simplified use case but it covers the basics. IoT solution will use a lot managed service and familiar technologies (e.g. TLS, &lt;a href="https://static.digihunch.com/2021/08/creating-tls-certificate-kubernetes/"&gt;certificate&lt;/a&gt;). Creating an IoT solution is mostly about address the onboarding services and make use of the MQTT based workflow. AWS managed services makes these easier.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="320" src="https://static.digihunch.com/wp-content/uploads/2023/02/tracking-1024x320.png" alt="" class="wp-image-8342" srcset="https://static.digihunch.com/wp-content/uploads/2023/02/tracking-1024x320.png 1024w, https://static.digihunch.com/wp-content/uploads/2023/02/tracking-300x94.png 300w, https://static.digihunch.com/wp-content/uploads/2023/02/tracking-768x240.png 768w, https://static.digihunch.com/wp-content/uploads/2023/02/tracking-1536x481.png 1536w, https://static.digihunch.com/wp-content/uploads/2023/02/tracking-2048x641.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;More IoT &lt;a href="https://workshops.aws/categories/AWS%20IoT"&gt;workshops&lt;/a&gt; are available on &lt;a href="https://workshops.aws/"&gt;AWS workshops&lt;/a&gt;. &lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2023/02/dicom-testing-with-tls/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;DICOM testing over TLS&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2023/03/landing-zone-in-azure/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Landing Zone in Azure – Introduction&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Intro to Data Analytics Platform on Azure</title><link>https://static.digihunch.com/2021/03/intro-to-data-analytics-platform/</link><pubDate>Sun, 21 Mar 2021 21:57:00 -0400</pubDate><guid>https://static.digihunch.com/2021/03/intro-to-data-analytics-platform/</guid><description>&lt;p class="wp-block-paragraph"&gt;Having been in transactional data world for almost the entire career, recently I have to pick up quite a few things to catch up on the analytical workload. The main purpose of data analytics project is to build analysis services models and manage deployed databases. Later in this post I&amp;#8217;ll discuss some useful Azure resources for data analytics.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-data-model"&gt;Data Model&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Data are typically organized in relational model for better transactional performance, following the normalization forms. The relational model, however, might not be the most appropriate schema for analytics. In this case, it is better to use a separate non-relational repositories that can store information in a format that better aligns with its semantics, and hence more friendly to analytical applications.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A model consists of: data sources, tables, relationships, measures, KPIs, roles, etc. The model can be deployed to analysis database (e.g. SSAS). When deploying, queries (from source) and calculations are done. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Data modelling is the process of determining how your tables are related to each other. This process is done by defining and creating relationships between the tables. From that point, you can enhance the model by defining metrics and adding custom calculations to enrich your data. Creating an effective and proper data model is a critical step in helping organizations understand and gain valuable insights into the data.&amp;nbsp;The model is another critical component that has a direct effect on the performance of your report and overall data analysis. The process of preparing data and modelling data is an iterative process.&amp;nbsp;&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-data-warehouse"&gt;Data Warehouse&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Moreover, organizations have multiple data stores, with varying formats and different structures such as live stream, sensor, etc. They all need to be combined to generate insights. The process of combining all of the local data source is known as data warehousing. The process of analyzing streaming data and data from the Internet is known as Big Data Analytics.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A data warehouse gathers data from many sources within an organizations. This data is then used as the source for analysis, reporting and OLAP. The focus of a data warehouse is to provide answers to complex queries. A modern data warehouse might contain a mixture of relational and non-relational data, including files, social media streams, IoT sensor data.&lt;/p&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://docs.microsoft.com/en-us/azure/synapse-analytics/sql-data-warehouse/media/sql-data-warehouse-overview-what-is/data-warehouse-solution.png" alt="Data warehouse solution"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The diagram above is platform neutral. If you take Azure for example, a typical data warehouse platform involves the following components:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Azure Data Factory: ingestion of data (integration service)&lt;/li&gt;&lt;li&gt;Azure Data Lake Storage: store large quantity of data before analyzing&lt;/li&gt;&lt;li&gt;Azure Databricks: other forms of data preparation (transformation, cleaning) by Spark&lt;/li&gt;&lt;li&gt;Azure Synapse Analytics: store cleansed data, for Azure Analysis Service to consume&lt;/li&gt;&lt;li&gt;Azure Analysis Service: query Synapse Analytics for detailed analysis and generate insights&lt;/li&gt;&lt;li&gt;Power BI: Generate graphs, charts and reports by using information from Azure Analysis service&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This is the diagram of those components as seen on Azure &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/solution-ideas/articles/modern-data-warehouse" class="rank-math-link"&gt;documentation&lt;/a&gt;:&lt;/p&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://docs.microsoft.com/en-us/azure/architecture/solution-ideas/media/modern-data-warehouse.png" alt="Architecture diagram"/&gt;&lt;figcaption&gt;Modern Data Warehouse&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Let&amp;#8217;s discuss each components.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-azure-data-factory-adf"&gt;Azure Data Factory (ADF)&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Big data requires a service that can orchestrate and operationalize process to refine the enormous stores of raw data into actionable business insights. ADF is managed cloud service built for complex hybrid ETL, ELT and data integration projects.&amp;nbsp; ADF retrieves data from one or more data sources, and convert it into a format you can process. The data sources might present data in different ways, and contain noises that need to be discarded. For example, the source data may contain dates with bad format. ADF can unify the data structure. In ADF, you define the work performed as a pipeline of operations. A pipeline can run continuously, or triggered by schedule.&lt;br&gt;A linked service provides the information needed for ADF to connect to a source or destination. A pipeline is a logical grouping of activities that together perform a task.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The ADF UX (user interface experience) lets you visually author and deploy resources for your data factory without having to write any code. You can drag activities to a pipeline canvas, perform test runs, debug iteratively, and deploy&amp;nbsp; and monitor your pipeline runs.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-azure-data-lake-storage-adls"&gt;Azure Data Lake Storage (ADLS)&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A data lake is a repository for large quantities of raw data. Because the data is raw and unprocessed, it&amp;#8217;s very fast to load and update, but the data hasn&amp;#8217;t been put into a structure for efficient analysis. You can think of a data lake as a staging point for your ingested data, before it&amp;#8217;s massaged and converted into a format suitable for performing analytics. Note that a data warehouse also stores large quantities of data, but the data in a warehouse has been converted into a format for efficient analysis. Data lake holds raw data, whereas data warehouse holds structured information.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Azure Data Lake Storage is essentially an extension of Azure Blob storage, organized as a near-infinite file system. It supports POSIX file and directory structure for storage and RBAC. ADLS is also compatible with HDFS, a popular open-source solution to store large quantities of data.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-azure-databricks"&gt;Azure Databricks&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Apache &lt;a href="https://docs.microsoft.com/en-us/azure/synapse-analytics/spark/apache-spark-overview#what-is-apache-spark"&gt;Spark&lt;/a&gt; is in-memory cluster computing technology, much faster than disk-based applications, and works with multiple programming languages to let you manipulate distributed data sets (DDS). There is no need to structure everything as map and reduce operations. Databricks develops a web-based platform for working with Spark cluster. It provides automated cluster management and IPython-style notebooks.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Azure Databricks is a managed Apache Spark environment running on Azure to provide big data processing, streaming, and machine learning. Apache Spark is a highly efficient data processing engine, with rich selections of libraries, that can consume and process large amounts of data very quickly. Azure Databricks also supports structured stream processing.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Delta Lake is an open-source storage layer in Azure Databricks that brings reliability to data lakes. Delta Lake provides ACID transactions, scalable metadata handling and unifies streaming and batch data processing. Delta Lake runs on top of your existing data lake and is fully compatible with Apache Spark APIs.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-azure-synapse-analytics"&gt;Azure Synapse Analytics &lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Azure Synapse is an end-to-end solution. It unifies data analysis, integration and orchestration, Data Lake, Data Warehouse, ELT/ELT, ML capabilities and visualization. With Synapse, you can process large amounts of data very quickly. You can ingest data from external sources (e.g. flat file, ADLS, other DBMS) and then transform and aggregate the data into a format suitable for analytics processing. You can also use this data as input to further analytical processing using Azure Analysis Services. Azure Synapse is a comprehensive service with the following components:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Synapse Analytics &amp;#8211;&amp;nbsp; a successor of SQL DW technology. Synapse analytics has inherited its MPP capability.&lt;/li&gt;&lt;li&gt;Data Exploration &amp;#8211; Synapse Studio makes data exploration in Data lakes, SQL engine and Spark very easy.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Data Integration &amp;#8211; inherited ADF’s data movement and transformation components, which allows building complex ETL pipelines without code&lt;/li&gt;&lt;li&gt;Development &amp;#8211;&amp;nbsp; supports Spark, Python, Scala, Spark notebooks, SQL&lt;/li&gt;&lt;li&gt;Data visualization &amp;#8211; Synapse Studio allows user to connect to Power BI workspace and get the same report development experience&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The most critical component, Synapse Analytics is analytics engine, designed to process large amounts of data very quickly. Synapse Analytics leverages a MPP (massively parallel processing) architecture, including a control node and a pool of compute nodes. When you submit a processing request, the control node transforms it into smaller requests and send them to compute nodes. Each compute node runs the queries over the portion of data that they each hold. When each node has finished its processing, the results are sent back to the control node where they&amp;#8217;re combined into an overall result.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Synapse Analytics supports two computational models: SQL pools and Spark pools. In a SQL pool, each compute node uses an Azure SQL Database and Azure Storage to handle a portion of the data. You can submit queries in the form of T-SQL statement. Synapse Analytics uses a technology named PolyBase to retrieve data from a wide variety of sources (e.g. Blob, ADSL, CSV). You can save the data read in as SQL tables in Synapse Analytics service. In a Spark pool, the nodes are replaced with Spark cluster. You run Spark jobs comprising code written in Notebooks (in Python, Scala, or Spark SQL). The Spark cluster splits the work out into a series of parallel tasks that can be performed concurrently. You can save data generated by your notebooks in Azure Storage or ADLS. To scale Spark pool, you can specify the cluster size, or turn on autoscaling.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-azure-analysis-service-aas"&gt;Azure Analysis Service (AAS)&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AAS is a fully managed PaaS that enables you to build tabular models to support OLAP queries. You can combine data from multiple sources (e.g. Azure SQL Database, ADLS, Cosmos DB, etc). You use those data sources to build models that incorporate your business knowledge. A model is essentially a set of queries and expressions that retrieve data from various data sources and generate results. The results can be cached in-memory for later use, or they can be calculated dynamically, directly from underlying data sources. AAS has significant functional overlap with Synapse Analytics, but it&amp;#8217;s more suited for processing on a smaller scale. The comparison below outlines the difference:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-stripes"&gt;&lt;table class="has-background" style="background-color:#e9fbe5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Synapse Analytics&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Azure Analysis Service (AAS)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;#8211; very high volumes of data (multi-terabyte to petabyte sized datasets)&lt;br&gt;&amp;#8211; very complex queries and aggregations&lt;br&gt;&amp;#8211; data minding, and data exploration&lt;br&gt;&amp;#8211; complex ETL operations&lt;br&gt;&amp;#8211; low to mid concurrency (127 users or fewer)&lt;/td&gt;&lt;td&gt;&amp;#8211; smaller volumes of data (a few terabytes)&lt;br&gt;&amp;#8211; multiple resources that can be correlated&lt;br&gt;&amp;#8211; high read concurrency&lt;br&gt;&amp;#8211; detailed analysis, and drilling into data, using functions in Power BI&lt;br&gt;&amp;#8211; rapid dashboard development from tabular data&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Many scenarios can benefit from using Synapse Analytics and Analysis Services together. If you have large amounts of ingested data that requires preprocessing, you can use Synapse Analytics to read this data and manipulate it into a model that contains business information rather than a large amount of raw data. The scalability of Synapse Analytics gives it the ability to process and reduce many terabytes of data down into a smaller, succinct dataset that summarizes and aggregates much of this data. You can then use AAS to perform detailed interrogation of this information, and visualize the results of these inquiries with Power BI.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-azure-hdinsight"&gt;Azure HDInsight&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Azure HDInsight is a managed analytics service based on Apache Hadoop, a collection of open-source tools and utilities that enable you to run processing tasks over large amounts of data. HDInsight uses a clustered model, similar to that of Synapse Analytics. HDInsight stores data using ADLS. You can use HDInsight to analyze data using frameworks such as Hadoop Map/Reduce, Apache Spark, Apache Hive, Apache Kafka, Apache Storm and more.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-power-bi"&gt;Power BI&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Microsoft PowerBI is a collection of software services, apps and connectors. It consists of a Microsoft Windows Desktop application Power BI Desktop, an online SaaS service Power BI service, and mobile Power BI apps available on any device. These three elements are designed to let people create, share and consume business insights. A common workflow with Power BI can be outlined as:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&lt;li&gt;Bring data into Power BI Desktop, and create a report&lt;/li&gt;&lt;li&gt;Publish to the Power BI service, where you can create new visualizations or build dashboards&lt;/li&gt;&lt;li&gt;Share dashboard with others, especially people who are on the go&lt;/li&gt;&lt;li&gt;View and interact with shared dashboards and reports in Power BI mobile apps.&lt;/li&gt;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Basic building blocks in Power BI include:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;visualizations: chart, colour-coded map, etc&lt;/li&gt;&lt;li&gt;datasets;&lt;/li&gt;&lt;li&gt;reports: a collection of visualizations that appear together on one or more pages;&lt;/li&gt;&lt;li&gt;dashboards: when you&amp;#8217;re ready to share a report, or a collection of visualizations, you create a dashboard, much like the dashboard in a car, a Power BI dashboard is a collection of visuals from a single page that you can share with others. Often, it&amp;#8217;s a selected group of visuals that provide uick insight into the data or story you&amp;#8217;re trying to present.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2021/03/git-branching-strategy/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Git Branching Strategy&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2021/04/public-key-infrastructure-pki/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Public Key Infrastructure (PKI) – Introduction&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Census Data from Statistics Canada</title><link>https://static.digihunch.com/2021/02/interpret-census-data-from-statistics-canada/</link><pubDate>Thu, 25 Feb 2021 21:18:09 -0400</pubDate><guid>https://static.digihunch.com/2021/02/interpret-census-data-from-statistics-canada/</guid><description>&lt;p class="wp-block-paragraph"&gt;&lt;a class="rank-math-link" href="http://www.statcan.gc.ca"&gt;Statistics Canada&lt;/a&gt; carries census every 5 years, with 2016 being the last run. The census data by Statistics Canada provides a wealth of insights but are published in raw format. Post-processing work is needed to extrapolate information, such as median income of a neighbourhood, age distribution of a city, etc. For someone like myself without any background in geographical informatics, it took a bit of learning to see how these work together. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The following information are typically included in the Census data:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Population&lt;/li&gt;&#10;&lt;li&gt;Population density&lt;/li&gt;&#10;&lt;li&gt;Age&lt;/li&gt;&#10;&lt;li&gt;Structural type of dewellings&lt;/li&gt;&#10;&lt;li&gt;Family size&lt;/li&gt;&#10;&lt;li&gt;Marital status&lt;/li&gt;&#10;&lt;li&gt;Language&lt;/li&gt;&#10;&lt;li&gt;Income&lt;/li&gt;&#10;&lt;li&gt;Place of birth&lt;/li&gt;&#10;&lt;li&gt;Level of education&lt;/li&gt;&#10;&lt;li&gt;Occupation&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We will start with level of Geographics. The level of geographics may change slightly between census programs in different years. The most recent 2016 census uses the following &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/dict/figures/f1_1-eng.cfm" class="rank-math-link"&gt;diagram &lt;/a&gt;to depict levels of geographics:&lt;/p&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://www12.statcan.gc.ca/census-recensement/2016/ref/dict/figures/f1_1-eng.jpg" alt="Figure 1.1 Hierarchy of standard geographic areas for dissemination, 2016 Census"/&gt;&lt;figcaption class="wp-element-caption"&gt;Geographic Levels&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This diagram reflects a number of different hierarchies of geographic units. The best resource to understand each block, is the &lt;a href="https://www150.statcan.gc.ca/n1/pub/92-195-x/92-195-x2016001-eng.htm" class="rank-math-link"&gt;illustrated glossary&lt;/a&gt; and the chapter &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/98-304/chap12-eng.cfm" class="rank-math-link"&gt;Census Geography&lt;/a&gt; in comprehensive &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/98-304/index-eng.cfm" class="rank-math-link"&gt;Guide to the Census Population&lt;/a&gt;. For example, the chain on the far left of the diagram runs across these levels:&lt;/p&gt;&#10;&lt;p class="has-white-background-color has-background wp-block-paragraph"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="121px" viewBox="-0.5 -0.5 121 321" style="max-width:100%;max-height:321px;"&gt;&lt;defs&gt;&lt;/defs&gt;&lt;g&gt;&lt;path d="M 60 40 L 60 60 L 60 50 L 60 63.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 68.88 L 56.5 61.88 L 60 63.63 L 63.5 61.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="0" width="120" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 20px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Canada&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="24" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Canada&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 60 110 L 60 130 L 60 120 L 60 133.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 138.88 L 56.5 131.88 L 60 133.63 L 63.5 131.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="70" width="120" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 90px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Geographical Region of Canada&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="94" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Geographical Region&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 60 180 L 60 200 L 60 190 L 60 203.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 208.88 L 56.5 201.88 L 60 203.63 L 63.5 201.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="140" width="120" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 160px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Province or Territory&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="164" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Province or Territory&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 60 250 L 60 270 L 60 260 L 60 273.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 278.88 L 56.5 271.88 L 60 273.63 L 63.5 271.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="210" width="120" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 230px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Forward Sortation Area&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="234" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Forward Sortation Ar&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="280" width="120" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 300px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Postal Code&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="304" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Postal Code&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;/g&gt;&lt;switch&gt;&lt;g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;/g&gt;&lt;a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank" rel="noopener"&gt;&lt;text text-anchor="middle" font-size="10px" x="50%" y="100%"&gt;Viewer does not support full SVG 1.1&lt;/text&gt;&lt;/a&gt;&lt;/switch&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In this hierarchy, the level of &lt;a href="https://www150.statcan.gc.ca/n1/pub/92-195-x/2011001/geo/region/region-eng.htm" class="rank-math-link"&gt;Geographical Region&lt;/a&gt; of Canada is standardized in &lt;a href="https://www150.statcan.gc.ca/n1/pub/92-195-x/2011001/other-autre/sgc-cgt/sgc-cgt-eng.htm" class="rank-math-link"&gt;Standard Geographic Classification&lt;/a&gt; (SGC), in which the provinces and territories are also &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/dict/geo038-eng.cfm" class="rank-math-link"&gt;encoded&lt;/a&gt;. Note that each Census include a &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/dict/az1-eng.cfm" class="rank-math-link"&gt;dictionary &lt;/a&gt;where all sorts of codes are kept. The dictionary also includes definition of the rest two levels: FSA (forward sortation area as the first three digits of postal code) and &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/dict/geo035-eng.cfm" class="rank-math-link"&gt;postal code&lt;/a&gt; (all six digits). Note that postal code is a mark of Canada Post Corporation, and you may translate postal code into other levels in standard geographic areas, such as CD. This is not straightforward though. You will need a product called &lt;a href="https://www150.statcan.gc.ca/n1/en/catalogue/92-154-X" class="rank-math-link"&gt;Postal Code Conversion File&lt;/a&gt; (PCCF) for the conversion. Statistics Canada does not directly distribute this product. It works with its &lt;a href="https://www.statcan.gc.ca/eng/dli/dli" class="rank-math-link"&gt;Data Liberation Initiative&lt;/a&gt; (DLI) partners to deliver this product.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;On the diagram there are also other path to run down the hierarchy. For example, from Canada down to federal electoral district (aka ridings). However, the census is not carried out by either election ridings or postal code. Instead, it is carried out by its own collection of levels dedicated for census purpose. When using census data, we need to be familiar with these units.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Census metropolitan area (CMA) and census agglomeration (CA)&lt;/strong&gt;: formed by one or more adjacent municipalities centred on a population centre (known as the core), such as Chatham-Kent CA, Kitchener-Cambridge-Waterloo CMA. Note that CMA and CA can expand across provincial borders, such as Ottawa &amp;#8211; Gatineau CMA. So CMA or CA is not a unit under province or territory.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Census Division (CD, essentially a region or county)&lt;/strong&gt;: general term for provincially legislated areas (such as county, municipalité régionale de comté and regional district) or their equivalents.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Census Subdivision (CSD, essentially a city)&lt;/strong&gt;: the general term for municipalities or areas treated as municipal equivalents for statistical purposes.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;&lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/ref/dict/geo013-eng.cfm" class="rank-math-link"&gt;Census Tract&lt;/a&gt; (CT)&lt;/strong&gt;: small, relatively stable geographic areas that usually have a population of less than 10,000 persons, based on data from the previous Census of Population Program.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Dissemination Area (DA)&lt;/strong&gt;: &amp;nbsp;is a small, relatively stable geographic unit composed of one or more adjacent dissemination blocks with an average population of&amp;nbsp;400 to 700&amp;nbsp;persons based on data from the previous Census of Population Program. It is the smallest standard geographic area for which &lt;span style="text-decoration: underline;"&gt;all census data&lt;/span&gt; are disseminated.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Dissemination Block (DB)&lt;/strong&gt;: an area bounded on all sides by roads and/or boundaries of standard geographic areas. The dissemination block is the smallest geographic area for which &lt;span style="text-decoration: underline;"&gt;population &lt;/span&gt;and dwelling counts are disseminated.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With these in mind, we can build two hierarchies closely related to census data:&lt;/p&gt;&#10;&lt;p class="has-white-background-color has-background wp-block-paragraph"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="291px" viewBox="-0.5 -0.5 291 331" style="max-width:100%;max-height:331px;"&gt;&lt;defs&gt;&lt;/defs&gt;&lt;g&gt;&lt;path d="M 60 30 L 60 50 L 60 40 L 60 53.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 58.88 L 56.5 51.88 L 60 53.63 L 63.5 51.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="0" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 15px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Canada&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="19" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Canada&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 60 90 L 60 110 L 60 100 L 60 113.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 118.88 L 56.5 111.88 L 60 113.63 L 63.5 111.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="60" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 75px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;CMA/CA&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="79" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;CMA/CA&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 60 150 L 60 170 L 60 160 L 60 173.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 178.88 L 56.5 171.88 L 60 173.63 L 63.5 171.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="120" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 135px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Census Tract&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="139" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Census Tract&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 60 210 L 60 230 L 60 220 L 60 233.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 60 238.88 L 56.5 231.88 L 60 233.63 L 63.5 231.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="0" y="180" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 195px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Dissemination Area&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="199" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Dissemination Area&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="240" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 255px; margin-left: 1px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Dissemination Block&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="60" y="259" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Dissemination Block&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 230 30 L 230 50 L 230 40 L 230 53.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 230 58.88 L 226.5 51.88 L 230 53.63 L 233.5 51.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="170" y="0" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 15px; margin-left: 171px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Canada&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="230" y="19" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Canada&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 230 90 L 230 110 L 230 100 L 230 113.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 230 118.88 L 226.5 111.88 L 230 113.63 L 233.5 111.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="170" y="60" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 75px; margin-left: 171px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Geo. Region&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="230" y="79" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Geo. Region&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 230 150 L 230 170 L 230 160 L 230 173.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 230 178.88 L 226.5 171.88 L 230 173.63 L 233.5 171.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="170" y="120" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 135px; margin-left: 171px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Census Division&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="230" y="139" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Census Division&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 230 210 L 230 230 L 230 220 L 230 233.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 230 238.88 L 226.5 231.88 L 230 233.63 L 233.5 231.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="170" y="180" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 195px; margin-left: 171px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Census Subdivision&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="230" y="199" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Census Subdivision&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 230 270 L 230 290 L 230 280 L 230 293.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 230 298.88 L 226.5 291.88 L 230 293.63 L 233.5 291.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;rect x="170" y="240" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 255px; margin-left: 171px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Dissemination Area&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="230" y="259" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Dissemination Area&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="170" y="300" width="120" height="30" rx="4.5" ry="4.5" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 315px; margin-left: 171px;"&gt;&lt;div style="box-sizing: border-box; font-size: 0; text-align: center; "&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "&gt;Dissemination Block&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="230" y="319" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Dissemination Block&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;/g&gt;&lt;switch&gt;&lt;g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;/g&gt;&lt;a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank" rel="noopener"&gt;&lt;text text-anchor="middle" font-size="10px" x="50%" y="100%"&gt;Viewer does not support full SVG 1.1&lt;/text&gt;&lt;/a&gt;&lt;/switch&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Now we download &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/dp-pd/prof/details/download-telecharger/comp/page_dl-tc.cfm?Lang=E" class="rank-math-link"&gt;census profile&lt;/a&gt; &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/dp-pd/prof/index.cfm?Lang=E" class="rank-math-link"&gt;data &lt;/a&gt;from &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/dp-pd/index-eng.cfm" class="rank-math-link"&gt;Statistics Canada&lt;/a&gt;. In the dropdown you can pick from the many of the aforementioned geographic levels.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="1158" height="245" src="https://static.digihunch.com/wp-content/uploads/2021/02/image.png" alt="" class="wp-image-2176"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;If you pick Census tracts (CT), there is one data file. The CSV file is about 160M. Also note that under geographic level column, it indicates two levels: CA/CMA and CT, which is important to keep in mind as we go through the data. In the content of the CSV, under the GEO_LEVEL column, value 1 stands for CA/CMA and value 2 stands for CT. Therefore, when GEO_LEVEL=1, the GEO_CODE value is a &lt;a href="https://www23.statcan.gc.ca/imdb/p3VD.pl?Function=getVD&amp;amp;TVD=314312&amp;amp;CVD=314313&amp;amp;CPV=B&amp;amp;CST=01012016&amp;amp;CLV=1&amp;amp;MLV=3" class="rank-math-link"&gt;CA&lt;/a&gt;/&lt;a href="https://www23.statcan.gc.ca/imdb/p3VD.pl?Function=getVD&amp;amp;TVD=314312&amp;amp;CVD=314313&amp;amp;CPV=A&amp;amp;CST=01012016&amp;amp;CLV=1&amp;amp;MLV=3" class="rank-math-link"&gt;CMA&lt;/a&gt; &lt;a href="https://www23.statcan.gc.ca/imdb/p3VD.pl?Function=getVD&amp;amp;TVD=314312" class="rank-math-link"&gt;code &lt;/a&gt;based on &lt;a href="https://www.statcan.gc.ca/eng/subjects/standard/sgc/2016/introduction" class="rank-math-link"&gt;Statistical Area Classification&lt;/a&gt;; when GEO_LEVEL=2, the GEO_CODE value is a CT numerical name (preceded by CMA/CA code). What CT numerical name represents what geographic area, is all defined in &lt;a href="https://www12.statcan.gc.ca/census-recensement/2011/geo/map-carte/ref/cma_ca_ct-rmr_ar_sr/index-eng.cfm" class="rank-math-link"&gt;Census Tract Reference Map&lt;/a&gt;. There is no textual name for each census tract.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To take another example, select Dissemination areas (DAs) from the dropdown. Now the size of the CSV becomes 1.6G, but smaller data files are provided by province and territories. Select the data file for Ontario only.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="916" height="965" src="https://static.digihunch.com/wp-content/uploads/2021/02/image-1.png" alt="" class="wp-image-2177"/&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that there are five geographic levels as indicated: Canada, provinces/territories, CDs, CSDs and DAs. This suggests we will see 5 different values under the GEO_LEVEL column in the data file:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;0 &amp;#8211; Canada&lt;/li&gt;&#10;&lt;li&gt;1 &amp;#8211; Provinces and Territories&lt;/li&gt;&#10;&lt;li&gt;2 &amp;#8211; CDs&lt;/li&gt;&#10;&lt;li&gt;3 &amp;#8211; CSDs&lt;/li&gt;&#10;&lt;li&gt;4 &amp;#8211; DAs&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Read the &lt;a href="https://www.statcan.gc.ca/eng/subjects/standard/sgc/2016/introduction" class="rank-math-link"&gt;SGC documentation&lt;/a&gt; to understand the code from level Canada to level CSD. DA is similar to CT because the code is defined in &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/geo/ADA/ADA-eng.cfm" class="rank-math-link"&gt;reference map&lt;/a&gt; here. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Apart from DA and CT, there are other levels (such as ridings) with reference maps, as outlined in the &lt;a href="https://www12.statcan.gc.ca/census-recensement/2016/geo/index-eng.cfm" class="rank-math-link"&gt;Census geography&lt;/a&gt; page.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With all the above information, we can parse the data programmatically. Of course, the schema and coding information applies to Canada. Outside of Canada, pretty much all states have a counterpart government agency that manages census and statistics, just with different formats to understand from ground up. A lot of census geography concepts applies to other countries as well. For example:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;a href="https://www.census.gov/" class="rank-math-link"&gt;Census Bureau&lt;/a&gt; of United States&lt;/li&gt;&#10;&lt;li&gt;Australian &lt;a href="https://www.abs.gov.au/" class="rank-math-link"&gt;Bureau of Statistics&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.ons.gov.uk/census" class="rank-math-link"&gt;Office for National Statistics&lt;/a&gt; (UK)&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://ec.europa.eu/eurostat/web/main" class="rank-math-link"&gt;Eurostat &lt;/a&gt;(European Union)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Welcome to the world of data.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2021/02/basic-resource-object-in-kubernetes-2-of-2/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Basic Resource Object in Kubernetes 2 of 2&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2021/03/git-branching-strategy/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Git Branching Strategy&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>