Code Monkey home page Code Monkey logo

erdblick's Introduction

erdblick 🌍

erdblick is a dynamic mapviewer built on the mapget feature service.

Warning ⚠️: Erdblick is still under active development and hasn't reached its final form. However, we'd love to hear your feedback during this phase.

Capabilities: 🛠️

  • 🗺️ View map layers from a specific mapget server.
  • 🎨 Define visual styles for map layers through style-sheets, translating specific features into visual elements in both 2D and 3D.
  • 🏔️ Experience 3D features and terrains with a flexible 3D camera powered by CesiumJS.
  • ✍️ Edit map layer style sheets in real-time directly from the front-end (Planned).
  • 🔍 Select multiple features at once using filter or lasso selection tools (Planned).
  • 🖼️ Utilize split-screen panes for optional overlay or synchronized navigation with an adjustable splitter (Planned).
  • 🔎 View multiple map layer tile zoom levels all at once (Planned).

mapget ui

Setup

Ready to try out the latest version? While the Desktop app is still work-in-progress, swing by the Release Page to grab the newest build. Currently, erdblick is made to be served by a mapget server, so make sure to serve it up with the mapget serve command. Not sure how to do that? Start off with a simple pip install mapget and then fire away with

mapget serve -w <path-to-unpacked-erdblick>

Styling System

Erdblick styles are defined as YAML-files, which must have a rules key that contains an array of feature visualisation rule objects. During runtime, a feature will be visualised according to each rule that matches it.

Custom Style Declarations

It is possible to apply own custom styles easily. On build, Erdblick automatically picks up .yaml style files from styles directory (where you can drop your custom files) and bundles them in static/bundle/styles (in case you are using a pre-built Erdblick distribution, you can directly put your styles in static/bundle/styles).

For Erdblick to apply custom styles, it expects the following declarations for the styles in config/config.json (in case you are using a pre-built Erdblick distribution, you can directly create your configuration in static/config.json):

{
   "styles": [
       { "id": "Your Style ID", "url": "style.yaml" },
       { "id": "Your Style ID2", "url": "style_2.yaml" }
   ]
}

where url field must be a path relative to static/bundle/styles and id is used to identify the particular style in GUI.

It is also possible to export and import styles in GUI. Styles imported this way will persist in the local storage of the browser.

Editing Styles via Erdblick

Both bundled and imported styles can be modified directly via a GUI editor included in Erdblick. If a style was modified this way, it will persist in the local storage of the browser (if the local storage is cleared or reset, all of the modifications will be reset as well; in case you would like to clear the styles yourself, you can do that via the preferences panel.

The style editor automatically verifies YAML for syntax parsing errors and provides basic autocomplete.

Style Definitions

Each rule within the YAML rules array can have the following fields:

Field Description Type Example Value
geometry List of geometry type(s) or single type the rule applies to. At least one of "point","mesh", "line", "polygon". ["point", "mesh"], line
aspect Specifies the aspect to which the rule applies: "feature", "relation", or "attribute". String "feature", "relation"
mode Specifies the mode: "normal" or "highlight". String "normal", "highlight"
type A regular expression to match against a feature type. String "Lane|Boundary"
filter A simfil filter expression over the feature's JSON representation. String *roadClass == 4
selectable Indicates if the feature is selectable. Boolean true, false
color A hexadecimal color code or CSS color name. String "#FF5733", red
color-expression A simfil expression which may return an RGBA integer or color string (see above). The expression is evaluated over the current feature/relation/attribute. String "#FF5733", red
opacity A float value between 0 and 1 indicating the opacity. Float 0.8
width Specifies the line width or point diameter (default in pixels). Float 4.5
flat Clamps the feature to the ground (Does not work for meshes). Boolean true, false
outline-color Point outline color. String green, #fff
outline-width Point outline width in px. Float 3.6
near-far-scale For points, indicate (near-alt-meters, near-scale, far-alt-meters, far-scale). Array of four Floats. [1.5e2,10,8.0e6,0]
offset Apply a fixed offset to each shape-point in meters. Can be used for z-ordering. Array of three Floats. [0, 0, 5]
arrow For arrow-heads: One of none, forward, backward, double. Not compatible with dashed. String single
arrow-expression A simfil expression which may return none, forward, backward, or double. String select(arr("single", "double"), 1)
dashed Indicate that a line has dashes. Boolean. true
gap-color If a gap between dashes has a color. String blue, #aaa
dash-length Size of a dash in pixels. Integer. 16
dash-pattern A 16-bit pattern for the dash. Integer. 255
relation-type A regular expression to match against a relation type, e.g., "connectedFrom". String "connectedFrom|connectedTo"
relation-line-height-offset Vertical offset for relation line in meters. Float 0.5
relation-line-end-markers Style for the relation line end-markers. Sub-rule object See example below.
relation-source-style Style for the relation source geometry. Sub-rule object See example below.
relation-target-style Style for the relation target geometry. Sub-rule object See example below.
relation-recursive Specifies whether relations should be resolved recursively. Only done if mode=="Highlight", and only works for relations within the same layer. Boolean true, false
relation-merge-twoway Specifies whether bidirectional relations should be followed and merged. Boolean true, false
attribute-type A regular expression to match against an attribute type. String SPEED_LIMIT_.*
attribute-layer-type A regular expression to match against the attribute layer type name. String Road.*Layer
attribute-validity-geom Set to required, none or any to control whether matching attributes must have a validity geometry. String Road.*Layer
label-color Text color of the label. String #00ccdd
label-outline-color Text outline color of the label. String #111111
label-outline-width Text outline width of the label. Float 1.0
label-font The font used to draw the label (using the same syntax as the CSS 'font' property). String 24px Helvetica
label-background-color Background color of the label. String #000000
label-background-padding Background padding in pixels. Pair of Integers. [7, 5]
label-horizontal-origin Determines if the label is drawn to LEFT, CENTER, or RIGHT of its anchor position. String LEFT
label-vertical-origin Determines if the label is to ABOVE, BELOW, at CENTER or at BASELINE of its anchor position. String BASELINE
label-text-expression A simfil expression to evaluate on the feature/relation the label belongs to. String **.speedLimitKmh
label-text A placeholder in case the simfil expression either isn't necessary or won't produce a result. String No speed limit
label-style Describes how to draw a label using FILL, OUTLINE or FILL_AND_OUTLINE. String FILL
label-scale The uniform scale that is multiplied with the label's size in pixels. Float 1.0
label-pixel-offset The offset in screen space from the origin of this label (the screen space origin is the top, left corner of the canvas). Pair of Floats. [5.0, 30.0]
label-eye-offset Gets and sets the 3D Cartesian offset applied to this label in eye coordinates. Tuple of three Floats. [5.0, 10.0, 15.0]
translucency-by-distance Near and far translucency properties of a Label based on the Label's distance from the camera. Array of four Floats. [1.5e2, 3, 8.0e6, 0.0]
scale-by-distance Near and far scaling properties of a Label based on the label's distance from the camera. Array of four Floats. [1.5e2, 3, 8.0e6, 0.0]
offset-scale-by-distance Near and far pixel offset scaling properties of a Label based on the Label's distance from the camera. Array of four Floats. [1.5e2, 3, 8.0e6, 0.0]
first-of Mark a rule as a parent of a fallback rule list. See description below. Array of Rule objects. See example below.

Labels in Erdblick

In Erdblick, labels are used to add textual information to the visualized geometries. Labels are always visualized in addition to the geometry itself and are positioned at the visual center of the geometry. For a label to be displayed, the label-text or label-text-expression property must be set in the style definition. When set, Erdblick renders the label according to the defined style properties, such as label-color, label-font, label-scale, etc.

Labels can be applied to any geometry type and are particularly useful for providing contextual information, such as names, identifiers, or any other relevant data associated with the feature.

Label Example:

rules:
  - geometry:
      - point
      - line
    type: "City|Road"
    color: "#FF5733"
    label-text-expression: "**.name"
    label-color: "white"
    label-outline-color: "black"
    label-font: "14px Arial"
    label-style: "FILL"
    label-scale: 1.2

In this example, labels are applied to both point and line geometries representing cities and roads. The label text is dynamically generated from the feature's name attribute. The labels are styled with a white fill color, a black outline, and are scaled up by a factor of 1.2 for better visibility.

Relation Styling

In Erdblick, relation styling is used to visualize relationships between different features. This is especially useful for illustrating connections, flows, or hierarchies between elements in the map. A rule is run for all relations of a matching feature by setting aspect: relation. The geometric primitive that is used to visualize the relation is a line from the center of the source validity geometry (the default validity is first source feature geometry) to the center of the target validity geometry. The visualized relations may be filtered by type name using the relation-type regular expression.

For relations, style expressions (e.g. color-expression) are evaluated in a context which has the following variables:

  • $source: Source feature.
  • $target: Target feature.
  • $twoway: Variable indicating whether the relation is bidirectional.
  • name: Name of the relation type.
  • sourceValidity: Source validity geometry if set.
  • targetValidity: Target validity geometry if set.

When visualizing relations recursively using a rule that has the highlight mode, the recursion will be performed until the selected feature tile's border is reached. Any relations across the border are then resolved once using a mapget locate-call.

Relation Styling Example:

rules:
  - type: LaneGroup
    aspect: relation
    mode: highlight
    color: red
    width: 20
    arrow: double
    opacity: 0.9
    relation-type: "nextLaneGroup|prevLaneGroup"
    relation-recursive: true
    relation-merge-twoway: true
    relation-line-height-offset: 10
    relation-line-end-markers:
      color: black
      width: 4

Attribute Styling

Using aspect: attribute, a styling rule can be used to visualize feature attributes that are stored in attribute layers. The rule will then be used to visualize the validity geometry of the attribute, or the attribute's feature's first geometry as a fallback. The visualized attributes may be filtered using the attribute-type and attribute-layer-type regular expressions. You may also select specifically for attributes which do or do not have their own validity geometry, by setting the attribute-validity-geom field.

For attributes, style expressions (e.g. color-expression) are evaluated in a context which has the following variables:

  • $name: The attribute name.
  • $layer: The layer name of the attribute.
  • $feature: The feature of the attribute.
  • direction: Attribute direction if set.
  • validity: Attribute validity geometry if set.
  • Top-level fields of the attribute with their nested members, e.g. attributeValue.speedLimitKmh.

Note: To avoid colliding geometries when multiple attributes are visualized for the same feature, set the offset field. The spatial offset will be multiplied, so it is possible to "stack" attributes over a feature.

About first-of

Normally, all style rules from a style sheet are naively applied to all matching features. However, usually, it will be sufficient if only the first matching rule from a list

is applied. This allows a simple fallback rule at the bottom of the list. For this purpose, the first-of style rule field exists. It may be applied as follows:

rules:
- type: Road
  first-of:
    - (subrule-1...)
    - (subrule-2...)
    - (subrule-n)

Note that all attributes except for type, filter, and first-of are propagated from the parent rule to the subrules. For example, a parent rule color will be applied to the child, unless the child overrides the color. It is explicitly allowed that sub-rules may have sub-rules themselves.

A brief example:

rules:
  - geometry:
      - point
      - mesh
    aspect: "feature"
    mode: "normal"
    type: "Landmark"
    filter: "properties.someProperty == someValue"
    color: "#FF5733"
    opacity: 0.8
    width: 4.5
  - geometry:
      - line
      - polygon
    aspect: "relation"
    mode: "highlight"
    type: "Boundary"
    color: "#33FF57"

Build instructions (Linux-only)

Show instructions

Make sure that these prerequisite dependencies are installed:

Dependency Version
node 21.3.0+
npm 10.2.4+
cmake 3.24+

Run the setup script once to pull Emscripten SDK:

./ci/00_linux_setup.bash

To build the project, run:

./ci/10_linux_build.bash

To rebuild the project (skipping checkouts and CMake initialization), run:

./ci/20_linux_rebuild.bash

You will find the resulting built web app under the directory ./static.

You can also build the erdblick-core library with a standard C++ compiler in an IDE of your choice. This is also useful to run the unit-tests.

Concepts

As the project is still very much under development, we've gathered some resources that should give you a clearer picture of what we're aiming for with the mature product. Feel free to take a look.

UI Mocks

You'll find a series of mockups showcasing our proposed user interface in various scenarios. Keep an eye out for notes within the images - they provide extra insight into specific features.

Overview

overview

Search Bar

search

Selection View

selection-view

Split View

split-view

Initial Architecture UML

Architecture

Second is a UML diagram giving you an overview of our emerging architecture. Look out for comments within the diagram - they're there to give you a bit more context on how the parts fit together.

arch

Keep in mind, that these concepts are always up for changing.

erdblick's People

Contributors

josephbirkner avatar l-laura avatar waguramu avatar mistergc avatar guilhermepereiranavinfo avatar

Stargazers

 avatar  avatar  avatar Zhang, G. avatar Roland Homeier avatar Matias Lavik (马蹄) avatar Johannes Wolf avatar  avatar Clemens avatar

Watchers

Johannes Wolf avatar  avatar Fabian Klebert avatar Roland Homeier avatar

erdblick's Issues

Responsiveness while parsing long-running tile streams

The frontend seems to stall occasionally while tile streams are processed. We need to change how visualisation vs. parsing tasks are prioritized while tiles are coming in, to prevent the browser from skipping frames in favor of processing events. This also relates to #25

Enable lighting for 3D meshes

There is a corresponding comment in the code (primitive.h):

In the future, we can also have smoothly shaded triangle meshes by calling Cesium.GeometryPipeline.computeNormal and Cesium.GeometryPipeline.compressVertices on the mesh geometry.

This should be done. Then we can disable flat shading in CesiumPrimitive::withPerInstanceColorAppearance.

Enable 'Focus' button only if coverage information is available.

At the moment the 'Focus' button is always enabled, even when it is displayed next to sources without coverage information. In order to avoid the resulting confusion, we should

  • disable the button when there is no coverage information available
  • provide a hint that there is no coverage information available
  • add a link to the /sources endpoint of mapget so that user can check the source infos easily.

Dynamic Color Mapping Based on Attribute Values

Current Situation: Currently, the MapViewer does not have an automated feature for generating a dynamic color map based on the attribute values within the map. This constraint restricts the users' ability to visualize and understand the diversity of attribute values distributed across the map in an efficient way.

Desired Enhancement:

The visualization feature should be upgraded to generate dynamic color maps based on the attribute values of the chosen feature. This feature will be an improvement over the current manually assigned color schemes or static color mappings. Upon selection of an attribute, the system would automatically determine a color scale based on the range of the attribute values, mapping each value to a corresponding color within that scale.

For example, if a user chooses the "speed limit" attribute on a city map, the system would calculate the range of speed limits across the map and assign a color scale accordingly. Lower speed limits might be rendered in cooler tones, while higher speed limits could be represented in warmer tones.

User Customization:

In addition to the automatic color mapping based on attribute values, users should have the flexibility to customize the generated color scale. The interface should allow users to easily adjust the color range, assign specific colors to certain values, and modify the gradient according to their preferences.

Filter Integration:

An extension to this enhancement could be the integration with filter statements. Users can apply the color mapping in conjunction with a filter, such as displaying the speed limit-based coloring only on highways while graying out other road types. This additional functionality would allow users to focus on specific map features and perform a more focused analysis.

Key Advantages:

  1. Quick Identification of Patterns and Outliers: This dynamic color mapping feature can help users visually identify patterns, trends, and anomalies, such as a wrong speed limit assigned within a city zone.

  2. Adaptive to Displayed Map Features: The color mapping will adjust based on the attributes of the currently displayed features, enhancing user comprehension of the given view.

  3. User-friendly: This feature simplifies the analysis of map features by doing away with the need for users to manually set value ranges and color schemes, yet allowing them the flexibility to customize the color scale if desired.

This enhancement, allowing for dynamic color mapping based on attribute values, would render MapViewer a more effective and intuitive tool for visual data analysis. It would help users to better understand complex spatial data through easy-to-grasp color-based visualizations.

Source Model Traceability

Empower MapViewer users with the ability to trace back to the original source model from the MapViewer's feature model. This enhancement will provide a clearer understanding of the data's original structure and relationships, significantly enriching the MapViewer's analytical utility and usability.

Ideas:

  1. Traceability Implementation: Enable users to visualize the pathway from the mapviewer's feature model aspects to their corresponding aspects in the original source model.

  2. Interactive Association: Create a user-friendly interface allowing users to trace feature model aspects back to their source model origins.

  3. Visual Indicators: Implement visual cues to highlight features in the common model and their source model origins, enhancing traceability.

  4. Dynamic Exploration: Allow users to toggle between the common feature model view and its traced source model view, fostering deeper understanding and comparison.

  5. Attribute Accessibility: Display the original attributes and metadata from the source model alongside the corresponding features in the common feature model.

  6. Source Model Snapshot: Present a transformed representation of the source model, reflecting its original storage format within the MapViewer.

Benefits:

  • In-depth Data Comprehension: Users will achieve a thorough understanding of the common feature model and its tracing back to the original source model, bolstering data exploration.

  • Robust Analytical Capability: By enabling users to trace and compare the common feature model with its source, we can provide deeper insights and facilitate informed decision-making.

  • Seamless Traceability: The new feature will simplify the process of tracing back to original data sources, removing the need for external tools or manual processes.

  • User-friendly Navigation: An intuitive interface for tracing associations and switching views will render the MapViewer more accessible and easier to use.

In summary, this feature will enhance the MapViewer by enabling users to trace the origins of data in the common feature model back to its original source model, thereby offering a comprehensive, insightful data exploration experience.

erdblick uses CesiumJS

The current erdblick globe visualization uses our custom mapcomponent, renderingcontroller and cameracontroller implementation. The globe view should be replaced with a Cesium viewer with corresponding camera controls.

FeatureLayerRenderer currently parses a TileFeatureLayer into a tinygltf::Model object, which is then rendered by the mapviewermodel. The goal is to create Cesium3DTiles from a TileFeatureLayer and pass them for rendering to the CesiumJS viewer.

Cesium-Native will be used for both glTF and 3D Tile generation.

Selecting an object in Cesium viewport displays a basic attribute panel

Cesium3DTile vertices can contain an integer ID. We shall assign a tile-unique integer ID value to a feature (e.g. Lane) to tag all vertices of that feature in the Cesium3DTile. We can use the index of the feature within the TileFeatureLayer as the ID.

Cesium viewer should trigger a callback when an object is selected. The callback:

  1. determines the TileFeatureLayer tile ID and feature index based on the Cesium ID and tile of the selected feature,
  2. reads the feature’s attributes from the cached TileFeatureLayer, and
  3. triggers a simple panel over the Cesium viewer with the attributes.

To retrieve attributes of objects selected in the Cesium viewer, we simply look up the feature at the index of the TileFeatureLayer for the Cesium3DTile.

3D Object Exporter and/or Integrated Analysis Tool

To facilitate advanced analysis of 3D map features, the system should provide a 3D object exporter. This feature would allow users to export selected 3D map features or regions in a commonly used 3D file format. Users could then import these files into external 3D visualization or analysis tools for more detailed exploration and analysis (vertex index, positions, normals ...)

The exporter should be easy to use, accessible from the map viewer, and provide options for selecting which features to include in the export based on user-specified criteria.

Alternatively, or in addition to this, an integrated 3D analysis tool/component could be incorporated directly into the map viewer. This tool would offer functionalities similar to those available in external 3D analysis tools, enabling users to perform detailed analysis of 3D map features without leaving the map viewer.

Zoom-to-Content/Coverage Functionality

To simplify navigation and inspection of map data, the system should include a 'zoom-to-content' or 'zoom-to-coverage' feature in the map viewer component. This would allow users to instantly zoom to the extent of all displayed data, the complete coverage of the map, or the coverage of the cache, depending on the available data and user preference.

This feature should include at least two functionalities:

  1. 'Zoom to All Displayed Data': This function will adjust the map view to encompass all currently displayed map data.
  2. 'Zoom to Complete Coverage': This function will adjust the map view to display the entire coverage of the map, or in cases where this information is not directly available, to the coverage of the cache from all activated map sources.

Users should be able to access these functions through an intuitive interface within the map viewer, possibly associated with shortcut keys or key combinations for quick activation.

Implementing this feature would allow users to quickly view the full extent of the map data and understand the scope of the data coverage without having to manually navigate or look up coverage information, enhancing the usability and efficiency of the map viewer.

Replace wasm build bashscripts by emsdk install + CMake instructions

Currently there are three bash scripts in ./ci (00_linux_setup.bash ...) but instead it can be replaced by references to the EMSDK setup guide (which is suitable for all three major Desktop platforms) + direct usage of CMake. This reduces error-prone redundance, needs less maintenance and is more flexible (different IDEs, CI envs and platforms).

Acceptance:

  • Developer guide provides references to the docs that describe setting up the EMSDK
  • Docs/tests specify which emsdk version has been verified, that avoids any problems that may be caused by 'use latest'
  • Instead of emcmake, use cmake + custom toolchain

Ideas:

# set emscripten dir
EMSCRIPTEN=/path/to/emsdk/upstream/emscripten

# extend path
PATH=$EMSCRIPTEN:$PATH

# Invoke cmake with toolchain
mkdir build && cd build
cmake .. \
   -DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
   -DCMAKE_BUILD_TYPE=Release \
   -DBUILD_SHARED_LIBS=OFF

cmake --build .

Usage of a browser GUI framework

As we upgrade our GUI this iteration, selecting a sustainable WebUI framework is crucial. While our experience with Angular makes it a natural choice, we may consider alternatives if they present significant advantages. Given our tight timeline, this decision balances familiarity with Angular against the potential benefits of a new solution.

  • Performance and Efficiency: Evaluate Angular's performance, especially for rendering complex, data-intensive map visualizations. Identify if there are any significant limitations or inefficiencies.
  • Integration Challenges: Assess the ease or complexity of integrating Angular with our current backend and map data systems. Identify any potential integration hurdles that might impede development.
  • Scalability Concerns: Analyze Angular's scalability, particularly for future expansions of the MapViewer Tool. Determine if there are any scalability limitations that could hinder long-term development.
  • Development Complexity: Consider the complexity of developing and maintaining code in Angular. Identify if Angular's architecture or design patterns present substantial challenges for our project needs.
  • Community and Ecosystem: Review the current state of Angular's community support and ecosystem. Determine if there are any concerns regarding the future viability or support for Angular.
  • Specific Feature Implementation: Examine if there are specific features in our roadmap that would be problematic to implement in Angular compared to other frameworks.
  • Conclusion and Recommendation: Based on the evaluation, provide a clear recommendation on whether the identified concerns are significant enough to consider an alternative to Angular and if yes which one and why
  • Decision: We make together a decision and the responsible person for this issue will reflect it in the REAMDE (incl. the main reasons for it)
  • Apply the Framework: The chosen framework is used and applied to the current state to the GUI

Investigate usage of WebWorkers for WASM Style Processing

Currently, the erdblick frontend is running as a single-threaded application. To maintain performance and responsiveness in very data/processing-heavy scenarios, such as re-styling a very large viewport, WebWorkers might be a good solution.

Enhanced Inspection Panel for Better Data Analysis

The current inspection panel in our MapViewer Tool only presents a JSON dump of the feature data. This basic display lacks interactive features, making it difficult for users to navigate and analyze complex data structures effectively.

Basic Functionality Requirements

  • Collapsible Tree Structure: Implement a tree view for the JSON data where users can expand/collapse child elements. This will help in managing the visibility of nested data, making it easier to navigate complex property trees.
  • Search Functionality: Introduce a search bar to allow users to quickly find specific keys or values within the JSON structure. This feature should support basic string matching and possibly regular expressions for advanced users.
  • Key-Value Highlighting: Differentiate between different kind of value types (e.g. numbers, strings, enum symbols ...)
  • Copy Functionality: Enable users to copy the value of a specific key or the entire JSON object to the clipboard. This is useful for pasting data into other applications or tools for further analysis.
  • Scrolling and Resizable Panel: Ensure the panel is scrollable and resizable to accommodate different volumes of data and screen sizes.

Styling is Supported for All Mapget Geometry Types

Currently, erdblick only supports mapget line geometries and renders them as (white) hairlines. But mapget supports more geometric primitives and users also need more ways of how to represent them. This epic aims to covers all needed geometric primitives and basic ways of how they need to be represented. Have a look a the Geometries Sandcastle to get a better understanding what kind of different representations of points, lines and polygons are possible with CesiumJS. All modes and presentation styles have to be usable with the rule-based, declarative styling system of erdblick.

Common:

Points

  • #38
  • Points as Icons
  • Sized Points
  • Volumetric points (boxes)

Lines

Different kind of line representations, have a look at Polyline Sandcastle.

Polygons

  • #40
  • Outlined, planar polygons
  • Special line style (dashing ...)
  • Extruded, planar polygons

Meshes

  • #41
  • Wireframe: Display all triangles of the mesh
  • Textured Mesh
  • Edge-Visualization when displayed, hovered, selected

Enhancement of Feature Search and Display Capabilities

The existing feature search in our map viewer currently supports conditions based on attribute values, which helps in extracting a range of features like 'All roads with a speed limit < 50 km/h'. This feature request is aimed at extending the current search and display capabilities, by incorporating more specificity and flexibility. This will ultimately aid in more precise visualization and analysis of the map data.

Details:

1. Precision Marking of Feature Validity:

Current Situation: If an attribute has a defined validity like 'speed limit only valid for the first 50 meters of the road', the entire feature (road) is highlighted in the results.

Desired Enhancement: When the validity of a feature attribute is specific to a part of the feature, only that specific part should be highlighted or marked. For instance, if the speed limit is only valid for a specific stretch of the road, just this stretch should be marked instead of the entire road.

2. Extraction of Values in Searches:

Current Situation: The existing search functionality operates on a boolean basis (hit or miss).

Desired Enhancement: The search should allow for the extraction and display of attribute values. For instance, users should be able to request 'show the speed limits (as labels) of all roads that have a speed limit > 50' and get these values visibly marked on the map.

Inspection and Selection Modes

erdblick is designed to be an interactive, user-oriented platform that facilitates efficient retrieval of various information associated with one or multiple map features. It will come with a host of distinct selection and inspection aspects that are geared to present information in the most user-friendly and intuitive way.

These aspects can be customized using declarative styling rules which help determine the visibility, color, line style, labels, and more for each feature and their internal attributes. This ensures users have full control over their map exploration experience and can modify it as per their convenience and needs.

Ideas for a set of selection and inspection modes/states:

  • 'Auto Display': This mode automatically highlights key aspects along with the map features, without any manual selection, providing users with essential information at first glance.

  • 'Quick Peek': Activated by pressing and holding a designated hotkey, this mode applies a predefined style configuration to all displayed features. This mode is transient and only remains active as long as the hotkey is held down, providing a quick, temporary overview of all features.

  • 'Hover': This mode adjusts the style of the feature under the cursor, enabling an interactive tool for real-time highlighting of specific elements on the map.

  • 'Selection': Users can choose single or multiple features for focused inspection. Activation of this mode triggers the display of an inspection panel for a detailed exploration of the chosen features.

  • 'Focus': An extension of the selection mode, this mode offers an even more detailed look at a feature when activated by double-clicking. In addition to displaying a comprehensive inspection panel, it can blend out other features to reduce visual clutter. It could also lock the camera temporarily to the focused item, ensuring an uninterrupted view of the item being inspected.

  • 'Selection in Inspection': When the user selects specific elements within the inspection (references, validities) - to be refined.

These modes aim to allow users to create various visual perspectives of the information.

Refine attribute panel node expansion behavior

There are several improvements needed for automatic expansion of nodes:

  • Initially, all top-level nodes and nodes with only one child should be expanded.
  • Upon filtering, expand matching nodes with children, and do not hide the children. Children with only one child should be expanded as well.

We should also use this opportunity to move the attribute panel to a separate angular component.

Dedicated Architecture Documentation

It's crucial to document the workings of the viewport-driven update mechanism, given its complexity and involvement of multiple components and inter-process communication. This system also handles event cancellations for incoming viewport updates and requires proper request tracking. Understanding the lifetime management of various data representations—like features, attributes, and GLTF representations —is equally important. I envision a high-level overview that outlines these key behavioral aspects, serving as an entry point with references to the source code. This will equip potential contributors with a foundational understanding of the essential concepts before diving deeper into the codebase. Currently, there is only a (partially outdated) UML in the main README.

Basic FeatureLayerStyle and FeatureLayerRenderer

As the mapget-model library is now ready to be used, we can write basic implementations of FeatureLayerStyle and FeatureLayerRenderer classes.

FeatureLayerStyle should use yaml-cpp to parse some style file content. The file should be fetched by JS, and the contents should then be passed into the FeatureLayerStyle constructor. Inside, the initial implementation shall support the following YAML style rule fields:

rules:
- type: [<string>]   # (Mandatory, list of feature-type-names)
  filter: string     # (Optional, Additional simfil filter expression)
  color: string      # (Optional [r:float,g:float,b:float] list or color name. Can adopt impl. from AfwColor)
  geometry: ["line", "point", "mesh"] # (Mandatory, describes which geometry to take from a matching feature)
  opacity: float     # (Optional, defaults to 1.0)

The FeatureLayerStyle class should have a rules(): vector<FeatureStyleRule> const& function, which returns the style-sheet's rules. A rule could then have a match(mapget::Feature const&): bool function, and accessors for color(): Color, opacity(): float, geometryTypes(): GeometryTypeBitmask.

To convert a feature to GLTF, the FeatureLayerRenderer::render-function takes a FeatureLayerStyle const& and a mapget::TileFeatureLayerPtr argument. All features in the layer are aggregated into a single GLB scene. To facilitate the conversion, render tries to match every feature to every rule. For a successful rule-feature match, the renderer should make sure of three things for every geometry type supported by the rule:

  1. A material must already exist or be created for each geometry-type supported by the rule.
  2. A mesh must already exist or be created for each geometry-type supported by the rule.
  3. The feature's vertices for each geometry-type supported by the rule must be added to the mesh.

The mesh should be positioned around the TileFeatureLayer's center, so coordinates in each mesh can be offset to preserve precision. The WGS84 geometry will be converted to euclidian space with a earth surface radius of 6371 km. For 3d vector/matrix math, the glm library shall be used. To emit the GLB data structure, the tinygltf library shall be used.

For initial visualisation, we call FeatureLayerRenderer::render on startup with a fixed style and an on-the-fly-generated TileFeatureLayer. We can simply point the camera at a specific point on the earth's surface where we render the static dummy TileFeatureLayer.

Zoom-to-Feature Functionality with Shortcut

The map viewer component should be enhanced to incorporate a 'zoom-to-feature' function. This feature allows users to quickly focus on and inspect specific 2D and 3D represented map features in more detail.

Users should be able to select a specific map feature or features, either by directly clicking on them or by entering their feature IDs, and then execute the 'zoom-to-feature' command. The map viewer should then automatically adjust the view to focus on and zoom into the selected features.

To enhance usability and efficiency, this feature should be coupled with a shortcut key or key combination, which can be used to quickly activate the 'zoom-to-feature' command. In addition a lock-to-feature camera could help to easily orbit arround the feature and zoom-in/out for a detailed in vestigation.

This 'zoom-to-feature' functionality will enable users to more quickly and easily inspect individual or grouped map features in detail, improving the overall map exploration and interaction experience.

Low-resolution tile display

When viewing many tiles from far away (e.g. all of Germany on level 13), it does not make sense to render tiles at a per-feature LOD. In such cases, we can make use of the Cesium Error-Level concept to simply render e.g. just a representative square or so. The Cesium GLTF resource that is associated with the fine-grained representation should also be created on-demand. For this, we can hook into the Cesium Resource class.

Support tile levels other than 13

At the moment erdblick uses a hardcoded zoom level of 13 (for all tile feature layers) - to enhance user control , this issue focuses on introducing an explicit tile level selection mechanism for available feature layer types. Unlike automatic level switching or detection, this feature will enable users to manually select the desired tile level for specific layers, such as roads, landmarks, or geographic areas. This functionality is crucial for users who require specific levels of detail for their analysis or visualization purposes.

Functionality Requirements:

  • Manual Tile Level Selection Interface: Design and implement a user interface component that allows for the explicit selection of tile levels for individual feature layers.The interface should be intuitive and seamlessly integrated into the existing MapViewer layout.
  • Layer-Specific Level Adjustment: Enable users to set different tile levels for any available feature layer type independently. Ensure that the selected level applies only to the chosen layer, without automatic adjustment or switching to other layers.
  • Performance Considerations: Ensure that switching levels is responsive (e.g. cancel any pending requests for levels that are no longer relevant)
  • User Experience Considerations: Prioritize a clear and straightforward selection process, avoiding complexity in the user interface. The interface only allows selection of zoom levels that are supported. (Have a look at the mocks that we have already discussed)
  • Documentation and Instruction: Update the MapViewer documentation to clearly explain the use and benefits of explicit tile level selection.

Loading indicators now disappear when loading is done

Currently, Erdblick shows dot-indicators for each tile that is marked as to-be-fetched. However, the indicator is not removed once the tile is fetched, reducing the usefulness of the indicator. By also removing the dot, its meaning would be clearly "This tile is marked for loading but has not been received yet". This also covers loading multiple layers for one tile, so when all the layers have been loaded the dot disappears.

Toggle for Cesium OSM Layer

Currently, erdblick comes with the Cesium OSM layer enabled by default. This makes the frontend generally more useful and visually appealing, but prevents offline use-cases and distracts from the actual data that is being displayed. A UI toggle would probably add a lot of user value here.

Allow style subrule fallback list

Currently, all style rules from a style sheet are naively applied to all matching features. However, usually, it will be sufficient if only the first matching rule is applied, and there aren't multiple visualizations generated for the same feature. For this purpose, the first-of style rule field is introduced. It may be applied as follows:

rules:
- type: Road
  first-of:
  - (subrule-1...)
  - (subrule-2...)
  - (subrule-n)

Note:

  • Subrules may have further subrules
  • All attributes except for type and filter are propagated from the parent rule to the subrules. For example, a parent rule color will be applied to the child.

Support stick-to-ground style option

In some scenarios, it would be useful to see features directly on the ground rather than floating in the air. For these cases, we should support a new style flag like stick-to-ground, which makes polylines (and polygons?) flat on the terrain.

The usage in the style sheet would be like so:

rules:
- geometry: ["lines"]
  stick-to-ground: true

Extending the support of this flag to polygons would be an optional extra for this issue.

Support dashed lines and arrowheads

The erdblick style sheet design foresees the addition of line-dash-size and line-gap-size style properties. Their implementation should follow the general support for mesh-lines (#37). Furthermore, we should add arrow: forward|backward|both.

Part of #33

Smart Information Aggregation in Inspection Panel

To enhance the usability of the inspection panel in the map viewer component, the system should introduce a smarter information aggregation mechanism. This feature would automatically summarize important information from deeper levels of the tree-structured data and present it at higher levels.

Rather than requiring users to manually expand and collapse various nodes to find relevant information about a map feature and its relations, this intelligent aggregation would allow users to gain insights from a broader perspective without diving into the details unless needed.

This smart information aggregation should be designed to prioritize and summarize the most commonly needed or important information based on the feature's context. The criteria for this prioritization could be informed by user feedback or data usage patterns.

Implementing this feature would significantly enhance the user experience by simplifying the exploration of attribute information and feature relationships, reducing the need for excessive node expansion and enabling faster access to relevant information.

There are simple cases like a child with one simple value which is then propagated up. But ideally this mechanism allows aggregation of more complex information which is propagated over multiple levels. Also consider removing the aggregation when the associated node has been expanded.

erdblick only queries and visualizes tiles that are in Cesium viewport

For on-demand data retrieval from mapget, we need to calculate the tile IDs of the Cesium viewport. core/src/aabb.cpp implementations are there to help.

Upon initialization or a change in the viewport, erdblick should:

  1. cancel any previous ongoing mapget requests,
  2. determine which tiles in the viewport are missing, and query mapget to retrieve them,
  3. determine visualised tiles which are not visible anymore and remove them.

Determine erdblick version dynamically instead of hardcoded string in index.html

At the moment the index.html contains a hardcoded string "erdblick v" (e.g. erdblick v0.3.0) but instead there should be a defined location/way where/how the version is reflected and it should be just referenced the index.html.

Acceptance:

  • the version of erdblick is stored separately (e.g. VERSION file ...) and not part of a string
  • this version is used (directly/indirectly) whereever the erdblick version is needed (index.html, erdblick-core lib ...)
  • in addition to the pure version, the used commit id is also provided (incl. being accessible from the web app)

Support filter expressions for style rules

Currently, the style "filter" field is not evaluated. Adding support for this field is a crucial step towards unlocking the power of Erdblick style sheets. Invalid filter expressions are skipped but an error message is reported.

Support Staged Tile Loading

To facilitate very responsive viewport updates, a staged loading model would make sense, once this feature is also supported by mapget. Generally, the approach would be that the mapget streams every requested tile two ore mroe times: Once in a very coarse state with few basic attributes, and then in a more refined state with all attributes. For some feature types, even a third iteration might make sense. Style rulesshould also be able to be applied to just a particular stage of a loaded tile.

Basic mesh support is available.

Acceptance:

  • supports colors
  • supported by erdblick styling
  • covered by the style-guide
  • establish a lighting setup that makes it easy to recognize 3d meshes

Part of #33

Visual Representation of Feature Relations

The system should support the visualization of relationships between different map features. For instance, if a traffic light is related to a specific stretch of lane, selecting the traffic light in the map viewer should directly highlight or otherwise visually indicate the associated lane stretch.

The relationships should be displayed in a way that is clear but unobtrusive, so as not to interfere with the overall map view. This could involve using distinctive colors, lines, or other visual indicators to represent the relationships.

Users should have the ability to activate or deactivate this relationship visualization according to their needs. When the visualization is deactivated, the map should return to its standard view, without the relationship indicators.

Tile ID + border visualization

I want to be able to see the tile borders and ids/coordinates directly visualized on the globe.

Acceptance:

  • shows borders and ids
  • visualization can be toggled
  • uses mapget tiling scheme

Rersources:

Additional thoughts:

  • How to allow styling and a later stage, for example color tile surface on a specific color based on some rule?
  • Will users be able to inspect tiles? Tile properties? Are they separated from this visualization or do they play together?

Support Fetching Multiple Style Sheets

Currently, erdblick only loads one dummy style.yaml from the static directory. However, the architecture foresees a config.json, which lists the names of style YAMLs to be loaded.

We should implement the config.json-based style-sheet fetching.

On the frontend side, we could support toggling style sheets:

  • Map Layers:

    • [X] map1 / layer1
    • [X] map1 / layer2
    • [X] mapN / layerM
  • Style Sheets:

    • [x] Roads
    • [x] Lanes
    • [x] StyleX

This would be a temporary frontend, until we have the real one envisioned by the UI designs.

ebDebug.showTestTile is broken.

#45 came with a broken ebDebug.showTestTile - this is not critical as polygon and mesh could be still verified with the test source provided by mapget. But it should be fixed as it is helpful tool that can be used to investigate all geometry types with dedicated style without the need to start/integrate a dedicated source.

Dev-Hint: I already briefly investigated the issue and it seems the set fallback info provider doesn't get applied when the tileLayer gets deserialized.

Encode camera/layer state in URL

Currently, Erdblick always resets to a default state and camera perspective upon reloading. This should be improved, such reloading never leads to a change of perspective or visible map layers.

The following information should be stored in the URL:

  • Camera state information as needed by Cesium. It should be allowed to specify only a subset of this state, e.g. longitude and latitude, while the pitch/yaw/altitude assume default values.
  • Active map layers and their respective display levels.

User control for tile limit has been introduced

Currently, the tile limit of 512 maximum fetched tiles per viewport is hard-coded. In order to make updates more robust, we should add a user input which allows setting higher values, perhaps allowing a value as high as 100k to facilitate scalability/performance experiments and cache-prefilling use-cases.

MapSearch Control (Jump To Location/Viewport only) has been introduced.

The first step regarding the associated epic is to create a basic graphical user interface (GUI) element for the Map Search Control. This initial version will focus on enabling users to "jump" to a specified location or camera viewport within the MapViewer Tool.

Requirements:

  • GUI Design and Placement: Design a simple, intuitive search bar or input field that integrates seamlessly with the existing MapViewer interface. Position the search control for easy accessibility without cluttering the interface. Have a look at the GUI mocks that have been discussed.
  • Basic Search and Jump Feature: Allow users to input location coordinates or complete viewports (have a look at ebDebug.get/setCamerafor an initial reference about what has to be provided). Implement functionality where the map automatically navigates to or centers on the inputted location.
  • Input Validation and Error Handling: Ensure the control can handle invalid inputs gracefully, providing user feedback for correction.
  • Info Label: There is a info label that can be used to inform the user about things like warnings or error when processing request.
  • Performance Consideration: Ensure that the jump-to feature is fast and responsive, even when dealing with large map datasets and viewports that get filled up at the moment of a Jump-To request.
  • Testing and User Feedback: Conduct thorough testing to ensure reliability and gather initial user feedback for future improvements.

Labeled Bookmarks for Map Features and Positions

The system should provide the ability to create labeled bookmarks on the map viewer component. This feature should allow users to mark and annotate specific map positions or feature IDs for more focused analysis and to share the detailed views with others.

A bookmark should consist of a specific location on the map or a set of feature IDs, along with optional user-added text annotations. Users should be able to create, edit, delete, and list these bookmarks in an easy and intuitive manner within the map viewer component.

Once a bookmark is created, the map viewer should provide a unique URL or identifier for that specific bookmark. This link can then be shared with other users, who can access the bookmarked view with all its details directly.

This feature will allow users to highlight, describe, and share specific map features or regions of interest, facilitating improved collaboration and targeted analysis in the context of map data inspection and exploration.

Debug Output Toggle

Currently, erdblick outputs a lot of debug timing info. We should a compile-option or UI-based switch which enables/disables this toggle.

Map search control supports 'Jump to feature'

This issue focuses on enhancing the Map Search Control in the MapViewer Tool by adding a 'Jump to Feature' capability. Utilizing the 'locate' endpoint of our map data provider solution, Mapget (as detailed in Mapget Retrieval Interface), this feature will enable users to jump directly to a specific map feature based on its ID.

Functionality Requirements:

  • Integration with Mapget's Locate Endpoint: Implement functionality in the Map Search Control to interact with Mapget's 'locate' endpoint. Develop a flexible method to input feature id (parts).
  • Retrieval and Processing of Map Data: Upon user input, query the mapget 'locate' endpoint to retrieve the corresponding tile layer containing the desired feature.
  • Map Navigation and Zoom Feature: Utilize the tile ID and feature geometry obtained from Mapget to navigate and zoom into the feature's location on the map. Implement smooth and responsive map transitions to enhance user experience.
  • Multiple Hits: If the /locate invocation returns multiple hits only the first one is used for the JumpTo action, but the user gets an info that there were multiple hits.
  • Error Handling and User Feedback: Include robust error handling for cases where the feature ID is invalid, not found, (or when there are issues with the Mapget service).
  • UI Integration and Usability: Ensure that the 'Jump to Feature' functionality is intuitively integrated into the existing Map Search Control interface. (User should be able to easily see the supported types of requests 'Jump To location, feature ...')
  • Testing and Performance Optimization: Conduct extensive testing to ensure functionality works seamlessly across various scenarios and map data sizes. Especially when there is heavily load because of viewport fill requests.
  • Documentation and User Guides: Update the MapViewer documentation to include guidelines on how to use the new 'Jump to Feature' functionality. Provide examples and use cases to assist users in understanding and utilizing this new feature effectively.

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.