################################################ Architecture ################################################ CITYlayers is a browser-based urban data visualization tool for policymakers and private/public decision makers. It enables the visualization of urban data and provides city-scale services utilizing the CITYhub's simulation capabilities. CITYlayers is developed by a team of researchers and professionals at the Next-Generation Cities Institute (NGCI) at Concordia University, Montréal, Canada. In this document, we provide an overview of CITYlayers features, requirements, and architecture. This document is based on the `arc42 template `__ by Gernot Starke and Peter Hruschka. ******************************** 1. Introduction & Goals ******************************** 1.1 Requirements Overview -------------------------- CITYlayers is a browser-based visualization tool of urban data and provides city-scale services utilizing the CITYhub's simulation capabilities. The following are CITYlayers requirements: - Enable the visualization of geospatial-based datasets (e.g., points and/or polygons on a map, 2D/3D models of buildings). - Serve as a friendly user interface to the various back-ends, databases, models, and simulations we have in the NGCI in the domain of cities. - Provide interactive map-based visualizations, charts, tables, and reports that support decision-making based on metrics provided by our simulations. 1.2 Quality Goals ------------------ These are our main software quality goals: +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Goal** | **Description** | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Functionality** | CITYlayers must provide functionalities based on science-backed, real-world use cases and support stakeholder decision-making. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Maintainability** | CITYlayers code must be easy to understand, modify, and debug, following consistent style guidelines and documentation. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Extensibility** | CITYlayers architecture must support adding new features with minimal impact on existing code. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Usability** | CITYlayers UI/UX components must be easy to operate and support multiple languages. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Security** | CITYlayers must prevent unauthorized access to private data from our partners, while also providing open data. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Portability** | CITYlayers must run across different browsers, devices, and environments. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ | **Performance** | CITYlayers must meet acceptable response times and computational resource utilization in all target devices. | +---------------------+---------------------------------------------------------------------------------------------------------------------------------+ In section 4 (Solution Strategy), we explain the strategies we use to attain these goals. For additional and future quality goals, please read Section 10 (Quality Requirements). 1.3 Stakeholders ----------------- The following people and organizations have an influence in CITYlayers architectural decisions: +------------------------------------------+------------------------------------------------------------------------------------------------------+ | **Stakeholder** | **Description** | +------------------------------------------+------------------------------------------------------------------------------------------------------+ | **Next-Generation Cities Institute** | The research institute responsible for designing and developing CITYlayers. | +------------------------------------------+------------------------------------------------------------------------------------------------------+ | **Industrial and Governmental Partners** | Organizations that commission tailor-made CITYlayers features through paid, collaborative projects. | +------------------------------------------+------------------------------------------------------------------------------------------------------+ | **Research Partners** | Researchers who collaborate with the NGCI to validate, enhance, and promote CITYlayers. | +------------------------------------------+------------------------------------------------------------------------------------------------------+ ******************************** 2. Architectural Constraints ******************************** The following are aspects that limit our freedom of design and implementation decisions for CITYlayers: +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Constraint** | **Description** | +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Browsers** | CITYlayers is a browser-based application, which implies limitations on performance, usage of resources, and particular security or feature constraints of each browser. | +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Libraries** | CITYlayers uses React 19 as its component framework and a collection of libraries such as mapbox-gl to deal with map drawing and other visual features. This means CITYlayers depends on them to work properly. | +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ For more details on libraries, please read Section 3.2 (Technical Context). ******************************** 3. Context & Scope ******************************** 3.1 End-user Context --------------------- In CITYlayers, users can view layers and use services. - **Layers** are non-interactive: users can toggle them on/off and see datapoints being drawn on the map, and even hover to see details about a specific datapoint. However, the appearance, order, disposition and data associated to each datapoint cannot be changed. - **Services** allow users to interactively select polygons, datapoints, and input parameters, which will be passed on to simulations in the back-end and will influence the metrics and results seen on-screen. 3.2 Technical Context ---------------------- To implement layers and services, we use a set of tailor-made components which build upon the functionality of existing third-party open-source libraries. Here is a list of the key libraries we use and their purpose in the project: +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **Library** | **Purpose** | **GitHub Repository** | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **react** | Base component framework | https://github.com/facebook/react | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **mapbox-gl** | Draw base maps and 2D/3D layered visualizations | https://github.com/mapbox/mapbox-gl-js | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **ant-design** | Draw UI components such as buttons, menus and modals | https://github.com/ant-design/ant-design | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **axios** | Send HTTP requests (e.g. to an API) | https://github.com/axios/axios | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **zustand** | Manage the global state (data stores shared among components) | https://github.com/pmndrs/zustand | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **turf** | Perform geospatial operations (e.g., find the area or centroid of a polygon) | https://github.com/Turfjs/turf | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **chart.js** | Draw scatterplot, radar and bar charts | https://github.com/chartjs/Chart.js | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **victory** | Draw boxplot and line charts | https://github.com/FormidableLabs/victory | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **html2pdf** | Generate PDF reports based on HTML components | https://github.com/eKoopmans/html2pdf.js | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ | **i18next** | Provide multi-language support and on-the-fly language switching | https://github.com/i18next/i18next | +----------------+------------------------------------------------------------------------------+-----------------------------------------------+ All libraries will be downloaded and installed via `Yarn `__ when you set up CITYlayers in a development environment. ******************************** 4. Solution Strategy ******************************** We implement the following strategies to meet our quality goals: +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Goal** | **Solution Strategy** | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Functionality** | CITYlayers provides services and layers that are informative, explainable, and that support stakeholders' decision-making, such as the Multi-Building Retrofit. | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Maintainability** | CITYlayers is made of React components, which are reusable and can be changed with minimal impact to other components. We follow coding style guidelines to ensure consistent code. | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Extensibility** | Components can be combined with other existing or completely new components to provide new functionalities. For example, the same menus and modals are used across services. | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Usability** | The UI/UX of CITYlayers components is designed to be visually consistent, clear, interactive, and support multiple languages (currently English and French only). | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Security** | CITYlayers supports token-based authentication, which can be used to limit access to private datasets. | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Portability** | As any TypeScript React application, CITYlayers runs in any modern browser, and could be served statically by any modern web server (e.g. NGINX, Apache, etc.). | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Performance** | While CITYlayers is a project in construction and many of its features require performance improvements, our continued goal is ensuring CITYlayers runs without lag both in high-end and low-end laptops. | +---------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ******************************** 5. Building Block View ******************************** Figure 1 describes CITYlayers component relationships, where black arrowheads represent dependencies, and white arrowheads represent inheritance. As illustrated, services such as MultiBuildingRetrofit do not draw to the map directly. Instead, they delegate this task to the DrawToolbox, which acts as a facade for draw operations and the sole entity to instantiate and change the state of mapbox-gl-related objects. This helps avoid excessive coupling and other well-known problems in component frameworks, such as `prop drilling `__. .. figure:: ../../images/citylayers-components.png :width: 700 :alt: CITYlayers component diagram :align: center Figure 1 - CITYlayers component diagram ******************************** 6. Runtime View ******************************** Figure 2 describes concrete behavior and interactions of CITYlayers building blocks in the form of scenarios. Each use-case scenario is represented by an ellipsis in the diagram. Optional scenarios are represented by dashed lines. .. figure:: ../../images/citylayers-use-case.png :width: 950 :alt: CITYlayers use case diagram :align: center Figure 2 - CITYlayers use case diagram ******************************** 7. Deployment View ******************************** Figure 3 describes the technical infrastructure used to run CITYlayers. Black arrowheads represent connection and exchange of messages between parts. .. figure:: ../../images/citylayers-deployment.png :width: 600 :alt: CITYlayers deployment diagram :align: center Figure 3 - CITYlayers deployment diagram Figure 4 illustrates CITYlayers' architecture within the TOOLS4CITIES ecosystem, showing its connections to CITYhub and other tools, along with supporting back-end services and databases. Note: `Hasura `__ is being replaced by CITYlayers API, as shown in Figure 3. .. figure:: ../../images/citylayers-architecture.jpg :width: 700 :alt: CITYlayers component diagram :align: center Figure 4 - CITYlayers within TOOLS4CITIES architectural diagram ******************************** 8. Crosscutting Concepts ******************************** Figure 5 describes concepts approached by CITYlayers layers and services, such as buildings and other city objects. .. figure:: ../../images/citylayers-crosscutting.png :width: 100% :alt: CITYlayers crosscutting concepts :align: center Figure 5 - Crosscutting concepts of CITYlayers ******************************** 9. Architectural Decisions ******************************** This section summarizes some of the most important architectural decisions we made as a team throughout the project. This is not an exhaustive list, and it may be updated in the future. * **Why React?** We chose React because it is a widely-used component framework, well-maintained and well-documented. While other frameworks exist and may be as good as React or better, we chose to continue using it, given that, at this point, we have a large and diverse tailor-made component collection which was built upon React, and we want to keep using it. * **Why TypeScript instead of JavaScript?** We decided to add types to our components and variables because it makes our code easier to understand and document. Moreover, it decreases bugs caused by human error, given that we can rely on linter warnings and recommendations to spot bugs early. * **Why mapbox-gl instead of deck.gl (or another map library)?** We migrated from `deck.gl `__ to mapbox-gl after upgrading to React 19 broke `nebula.js `__, our former polygon-drawing library. Mapbox-gl offered a better path forward: full React 19 and TypeScript compatibility, plus enhanced visual features such as skyboxes, more customizable lighting and weather effects, as well as multi-language support. * **Why Zustand instead of React Context API?** Zustand minimizes the need for component re-renders on state changes and requires less component boilerplate and nesting than the React Context API. ******************************** 10. Quality Requirements ******************************** As explained in Section 1.2, CITYlayers current quality requirements are: Functionality, Maintainability, Extensibility, Usability, Security, Portability, and Performance. In future work, we intend to concentrate our efforts in the following quality requirements: +-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Objective** | **Description** | +-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Reliability** | CITYlayers should operate consistently without failures and with graceful error handling. | +-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Scalability** | CITYlayers should handle growth in users, data volume, or transaction load. It should support horizontal and/or vertical scaling without major architectural changes or performance degradation. | +-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Availability** | CITYlayers should implement redundancy mechanisms to ensure low downtime (e.g. multiple instances with load balancing). | +-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Deployability** | CITYlayers should be quick and easy to deploy on any platform using a CI/CD pipeline. | +-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ******************************** 11. Risks & Technical Debt ******************************** Risks are inherent to any project, and technical debt increases as the years pass and the project grows. Here is a list of them, along with mitigation strategies we are implementing to address them: +-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ | **Risk** | **Mitigation strategy** | +-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ | **Performance degradation** | Optimize components for lower RAM usage; refactor to decrease bundle size. | +-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ | **Increased state management complexity** | Refactor stores to make them smaller; use local component states instead of global stores whenever possible. | +-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ | **Lack of mobile support** | We are aware of this risk, and we decided not to address it. For now, CITYlayers is a browser application for desktops and laptops only. | +-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ | **Decreased maintainability of legacy components** | Gradual refactor and periodic dependency updates; keep tests updated so refactoring becomes easier. | +-----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ This is not an exhaustive list, and it may be updated in the future. ******************************** 12. Glossary ******************************** +----------+-----------------------------------+ | **Term** | **Definition** | +----------+-----------------------------------+ | **API** | Application Programming Interface | +----------+-----------------------------------+ | **CD** | Continuous Deployment | +----------+-----------------------------------+ | **CI** | Continuous Integration | +----------+-----------------------------------+ | **FC** | Functional Component | +----------+-----------------------------------+ | **GL** | Graphics Library | +----------+-----------------------------------+ | **HTTP** | Hyper Text Transfer Protocol | +----------+-----------------------------------+ | **RAM** | Random Access Memory | +----------+-----------------------------------+ | **UI** | User Interface | +----------+-----------------------------------+ | **UX** | User Experience | +----------+-----------------------------------+