Giter VIP home page Giter VIP logo

utk's Introduction

PyPI Slack

UTK logo

The Urban Toolkit (UTK)

The Urban Toolkit is a flexible and extensible visualization framework that enables the easy authoring of web-based visualizations through a new high-level grammar specifically built with common urban use cases in mind.

For a quick getting starter document and tutorials, visit: urbantk.org

UTK was first presented in the paper:
The Urban Toolkit: A Grammar-based Framework for Urban Visual Analytics
Gustavo Moreira, Maryam Hosseini, Md Nafiul Alam Nipu, Marcos Lage, Nivan Ferreira, Fabio Miranda
IEEE Transactions on Visualization and Computer Graphics (Accepted, to appear)


UTK cases

Table of contents

  1. Features
  2. Installation and quick start
    1. UTK backend
    2. UTK frontend
  3. Tutorials
  4. Development
    1. Slack channel
  5. Other resources
  6. Team

Features

  • Easy integration of physical and thematic layers.
  • Rapid iteration over the visualization design space.
  • Data transformation to support visualization tasks.
  • Support for 2D and 3D maps.
  • Support for juxtaposed and embedded plots.
  • Integration with OpenStreetMap.

UTK has been tested on Linux (Ubuntu 23.04), Windows 10 & 11, and MacOS 13.

Installation and quick start

UTK leverages several spatial packages, such as Geopandas, OSMnx, Osmium, Shapely. To facilite the installation of UTK, we have made it available through pip, only requiring the following commands in a terminal / command prompt:

pip install utk

UTK requires Python 3.9 or a newer version. If you are having problems installing UTK in Mac OSX because of Osmium, make sure you have CMake installed as well (e.g., through conda or Homebrew).

A detailed description of UTK's capabilities can be found in our paper, but generally speaking UTK is divided into two components: a backend component, accessible through UTK's Python library, and a frontend component, accessible through a web interface.

UTK backend

UTK's backend is available through our Python library. For example, using a Jupyter Notebook, it can be imported with:

import utk

To download data for Manhattan, NY, you only need to then:

uc = utk.OSM.load('Manhattan, NY', layers=['surface', 'parks', 'water', 'roads'])
uc.save('./manhattan')

This will create a new folder (manhattan) with the downloaded and parsed OSM data. On top of that, UTK also offers functionalities to load data from shapefiles (utk.physical_from_shapefile), csv files (utk.thematic_from_csv), dataframes (utk.thematic_from_df), and also accumulate sunlight access values (utk.data.shadow). A detailed description of UTK's Python API can be found here.

UTK frontend

UTK's frontend is available through the utk command. After the pip installation is complete, you can check a toy example with the following commands:

utk example

UTK's toy example will then be accessible through localhost:5001. After accessing it using a browser, you should see a grammar-defined visualization showing sunlight access per building:

UTK example

Beyong the simple example, you can also use the utk command to start and stop UTK's server:

utk start
utk stop

The utk command takes the following arguments:

usage: utk [-h] [-d [DATA]] [-b [BUNDLE]] [-g [GRAMMAR]] [-a [ADDRESS]]
           [-p PORT]
           {start,list,stop,example}

The Urban Toolkit

positional arguments:
  {start,list,stop,example}
                        Start, list or stop utk servers, or start server with
                        a simple example.

optional arguments:
  -h, --help            show this help message and exit
  -d [DATA], --data [DATA]
                        Path to data folder.
  -b [BUNDLE], --bundle [BUNDLE]
                        Path to app bundle (defaults to installed utk bundle).
  -g [GRAMMAR], --grammar [GRAMMAR]
                        Path to grammar JSON file, if different from
                        [DATA]/grammar.json (default: [DATA]/grammar.json).
  -a [ADDRESS], --address [ADDRESS]
                        Server address (default: localhost).
  -p PORT, --port PORT  Server port (default: 5001).
  -w, --watch           Watch folders, and re-build if there are changes.

Even though we offer support for a variety of arguments, most users will simply need to run the following to use data stored in a folder called ./data/:

utk start --data ./data

After starting UTK's server and opening localhost:5001 on a browser, you will see UTK's main interface, composed of a grammar editor (left) and map viewer (right). Adding new elements to the grammar specification on the right (e.g., new plots, new data) will automatically update the map viewer:

UTK example

Simulations

Currently supported simulations:

  • Shadow casting. To run this simulation, your system will need to support Plotoptix (see here). To use the other functionalities from UTK, your system doesn't need to support Plotoptix.

Tutorials

UTK tutorials

Step-by-step tutorials are available on our website. These tutorials highlight how UTK can be used to create sophisticated urban visualizations.

A detailed description of UTK's grammar can be found here.

Development

If you would like to modify UTK's core code, you won't be able to use the utk command (since it points to the utk pip installation). Alternatively, you will have to:

  1. Clone the repository with git clone [email protected]:urban-toolkit/utk.git.
  2. Install Node.js, either using conda, package managers, or pre-built installers.
  3. Build the utk-ts bundle. Inside src/utk-ts, you should run the following in the terminal: npm install && npm run build. After that, a bundle will be created.
  4. Build the utk-frontend bundle. Inside src/utk-frontend, you should run the following in the terminal: npm install && npm run build:web. After that, another bundle will be created.
  5. Run the UTK server. Inside the src, run the following in the terminal: python utk_server.py start --bundle utk-frontend/build/utk-app/, and with the other appropriate arguments (e.g., --data with the path to your data folder).

To automatically build the bundles (steps 2 and 3) when you make changes to the source code, you can run utk_server.py with the --watch argument.

Slack channel

For question, including development ones, join UTK's Slack. Feel free to post questions on the #installation, #quick-start, and#development channels.

Other resources

Team

utk's People

Contributors

fabio-miranda avatar gmmuller avatar mlage avatar nafiul-nipu avatar sajal1123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

utk's Issues

Support multiple map views

In some parts of the code, I'm assuming that there is only one mapview instantiated (components[0]).

Also, the link between grammar and the map camera only works for one mapview.

Change camera parameters in the grammar to have meaningful values

This is how the camera is currently specified in the grammar:

"camera": {
                    "position": [
                        -9753739,
                        5117375.5,
                        2216.08675
                    ],
                    "direction": {
                        "right": [
                            14146.2158203125,
                            100883.421875,
                            2216086.75
                        ],
                        "lookAt": [
                            14146.2158203125,
                            100883.421875,
                            2213086.75
                        ],
                        "up": [
                            0,
                            1,
                            0
                        ]
                    }
                }

Even though that is the parameters used internally they should be exposed in a more friendly way to the user. One way to do that, for example, is using lat/long (EPSG:4326) instead of EPSG:3395 for the camera position. Internally the system still manipulates 3395

Unify COORDINATES and COORDINATES3D

We have three geometry levels COORDINATES, COORDINATES3D, and OBJECTS. In theory, we could merge COORDINATES and COORDINATES3D because the first one is just a special case of the second where z=0. The problem is that we can easily do spatial joins in 2D but 3D is more complicated. So we have to support all the spatial join in 3D before doing the merge or be able to tell that the layer is in 2D without having to rely on the geometry levels label.

Resize grid when screen size changes

Currently, all views and widgets are initialized and positioned according to the initial size of the screen. Every time the screen changes the size and position should be adjusted.

Reactivate loading messages

In the grammar view component, there is a disabled functionality of log messages. It is important to keep the user updated about what is happening behind the scenes.

This issue might involve restructuring the way the dashboard is being loaded because everything is loaded at the same time. Is there is a widget, like the map, that is taking more time to load it is going to affect the loading of all the other components and widgets, which should not happen.

Nested knots

The user can use knots inside other knots (in and out fields) as if it was a layer. In that case, the final layer and thematic values of the knot are considered.

{
    spatial_relation: "INTERSECTS",
    out: {
      name: "layer1",
      level: "COORDINATES"
     },
    in: "knot2",
    operation: "AVG",
    abstract: true
}

Discretization as a new geometry level

We have three types of geometry levels: COORDINATES, COORDINATES3D and OBJECTS. I think it is relevant to have a fourth level. The name we can decide but this is a level that can be used to make references to subdivisions in the physical layer. One example is how buildings are subdivided into cells. Layers that do not have any special type of subdivisions could have triangulation as the default subdivision.

Deciding what pixels to discard

Currently, the .json of the physical layer has a "discardFuncInterval" indicating what pixels should be discarded based on their value of thematic data. That should be specified in the grammar. This feature is used to eliminate pixels in a grid over the surface that have value 0 for instance.

We could also have a default thematic value that could indicate discard.

Fix search widget

While I was changing things around and reshaping the grammar to work as a dashboard the search widget broke.

Component file: src/utk-map/ts/src/reactComponents/SearchWidget.tsx

It is just a matter of seeing where the widget is used and check what is out of place.

Custom function for the operation in the integration_scheme

integration_scheme := (spatial_relation?, (layer_in | knot_in), (layer_out | knot_out), operation?)

operation := (aggregation | *Custom function*)

aggregation := MAX | MIN | AVG | SUM | COUNT | NONE | DISCARD

The aggregation is implemented but not the custom function.

Filtering knots

It is possible to filter knots by using alt + right click + drag. There should be a field that can also define this filtering in the grammar. Just like it was specified in the paper.

image

Customizable domain/normalization

The user should be able to specify what is the domain of the data in the grammar so the color scale is generated accordingly. Also, the user should be able to specify the scale to use (from d3).

There should also be a way to link the domain/normalization/color scale of two knots.

Link two animations

If two grouped layers have the same amount of sublayers it should be possible to link their animations.

Support color values as thematic data

Sometimes it is desirable to use thematic values just to color the physical layers but they don't have any semantics. The user could then signal somehow that those thematic values are actually colors and use rbg, hex or other relevant color systems.

Problem with more than one animated layer

For some reason when two grouped animated layers are used they do not behave as expected. You first have to interact of the first layer to be able to interact with the second. It is probably a matter related to parameter initialization. The solution involves changing the ToggleKnotsWidget.tsx.

Remove selection triangle layer

When picking is activated for the triangles layer a right click with the mouse should deselect all elements, but that is not happening.

Unify picking shaders

Currently, we have two types of shaders to handle picking: shader-picking.ts and shader-picking-triangles.ts. The first one handles picking for buildings and the second one for triangle layers. We can unify both and make it generic to work with any layer that follow some constraints.

Cached join

If a join is specified in the grammar using the integration_scheme it will be checked if that join already exists. To determine if a join exists it is checked:

  • spatial_relation
  • in and out
  • in and out levels
  • abstract

There is checking regarding the operation (aggregation and custom function). That works well if in and out are physical layers or knots because the operation is applied in a later step but when in is a thematic layer the join is stored with the operation already done. This difference should be considered somehow.

Replace .json and .data by .utk

Currently, physical layers have metadata stored as .json and the data itself in .data binary files. The thematic layers are completely stored in .json. The idea is to replace those files with a unified binary .utk format with headers describing the data and the data itself.

Selective reload

When the grammar is applied the whole interface reloads. That should not be the case. Only what has been changed should reload.

Only load data visible by the camera

I will probably have to break this issue into smaller ones but the idea is that you can gain some performance if only render the part of the scene the user can see. The challenge is detecting that the user can see and filter that out efficiently considering different types of physical layers.

Rename files

The files should follow the same naming pattern. Some of them are using camel case others hyphen, which is not ideal.

Be careful with renaming files because all the references to that file should also be updated.

Improve how the user selects the data repository

Currently, all data is served under public/data/repository name. The user cannot choose, either via Grammar or Jupyter or Graphical interface, what folder to use. To choose the folder the user has to change environmentDataFolder in src/params.js (front end) and in src/utk-map/ts/pythonServerConfig.json (back end). There should be a better way to do this.

Default values for spatial joins

If I'm joining two physical layers it might be the case that some objects cannot be joined, in that case, there should be a default attribution of thematic values. For an intersect spatial_integration, for instance, some objects may not intersect with any other object Currently, for most spatial_integration the default value is 0, but it should be defined by the user.

Decrease the size of the rollup bundle

Some packages should not be bundled together in the final version. Those dependencies should be included in the "external" field in the rollup.config.mjs file.

Still have to decide which dependencies should be external

Implement more spatial relations for COORDINATES3D

Currently, it is only possible to Join COORDINATES3D with COORDINATES3D and only with the NEAREST spatial_relation. We want to be able to do more 3D operations. For instance COORDINATES3D with OBJECTS using a CONTAINS spatial_realation.

Document grammar

grammar.md should contain descriptions of all that is possible to do in the grammar.

Solving TODO's

There are some "TODO" comments sprinkled throughout the code. Some of them express concerns and others small changes that need to be made. If you guys wanna work on them just remove the comments as you solve the problems and paste a note here. We can also discuss stuff because I'm sure some TODO's does not require any fix at all.

Transform grammar-manager.ts into plotManager.ts

grammar-manager.ts (GrammarManager) was initially meant to be the class to manage the grammar. However, that is now done by grammarInterpreter.ts and grammar-manager.ts only takes care of plots.

Be careful that changing the name of files and classes implies changing all the places where they are used

Dynamically assignment of shaders

Currently, the shaders are assigned in the .json that defines the layer. The physical layers should not have any information about the shaders, they should be assigned dynamically according to the functionalities specified in the grammar. For example, if the grammar specifies picking interaction then the PICKING shader should be assigned to the layer.

RUNNING UTK

If you trying to run UTK following the documentation I created, I would like to ask you to post any problems or questions you have on this issue so we can help everyone at the same time :)

Change the system to only manipulate 3D data

As a legacy feature from the old utk some layers and parts of the code manipulate data using only x and y. However, the whole code should use x,y,z and assign z=0 to 2D data.

Add trees :)

We could render some trees to make things look more beautiful.

Show the grammar of each cell

An interesting feature would be having the possibility to inspect the grammar that defines each one of the components of the grid. A button on the map could show the part of the grammar where that map is defined so the user could make specific and localized changes.

This feature should not replace the unified grammar view.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.