Giter Club home page Giter Club logo

maplibre-rs's Introduction

MapLibre Organization

https://www.maplibre.org/

This repository contains various documents that define the MapLibre Organization such as the Charter, our Code of Conduct, the list of Voting Members, and more.

You also find here the results of past Governing Board elections.

Formatting

Markdown files in this repo are formatted with markdownlint. If you have formatting problems you can sometimes fix them with:

npx markdownlint-cli *.md --fix

maplibre-rs's People

Contributors

bezpowell avatar birkskyum avatar drabble avatar drwestco avatar fabianwildgrube avatar hdevalence avatar jackson211 avatar julienr avatar karisair avatar maxammann avatar nyurik avatar salvatoret avatar tristramg avatar vladdoster avatar ybiletskyi avatar yzsolt 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

maplibre-rs's Issues

Headless

The tileserver-gl can render raster tiles from vector data. This requires that the rendering component runs headless.
Essentially this means that the winit dependency needs to be decoupled. This is already prepared in maplibre-rs. The only winit dependencies are in the input and winit.rs module.

There are two major areas which need to be handled:

  • Rendering to a texture which then can be copied to a buffer. This buffer can be converted to a PNG file. #70
  • Rendering single tiles with the maximum size to a quadratic surface. If the surface is not quadratic, then the generated PNGs will have borders.

Support E2E testing

When developing UIs for the web, mobile or desktop E2E tests are common.
Because we are rendering to a surface (e.g. canvas) E2E frameworks have a problem, because they can not assert on the content of the canvas.

๐Ÿค” Expected Behavior

It should be possible to assert for example for the count or position of markers.

๐Ÿ˜ฏ Current Behavior

๐Ÿ’ Possible Solution

Undefined.

๐Ÿ”ฆ Context

I heared that companies have problems when E2E testing their apps when a HTML canvas element is used.

Enable HTTP caching on all platforms

Right now HTTP caching is only functional on desktop. We disabled it because the paths where the cache should be located is platform dependent.

The path of the cache is controlled via the structs which implement the HTTPClient trait.

Restructure coords

We should probably look over the coords structs and refactor it.

๐Ÿค” Expected Behavior

The coords structs should make sense and should not change in the future. For example WorldTileCoords should probably only contain unsigned numbers.

๐Ÿ˜ฏ Current Behavior

  • WorldTileCoords uses signed ints

Remove all `.unwrap()` and `.expect()`

๐Ÿค” Expected Behavior

Return a Result for failable operations.

๐Ÿ˜ฏ Current Behavior

We use sometimes unwrap or expecte because of lazyness.

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Wrap world in X direction

Difficulty: Hard

Currently, there is only one instance of the map which is rendererd.

๐Ÿค” Expected Behavior

In Y direction the navigation should be restricted such that one can not pan out from the map. This is done in #73

In X direction it should be possible to infinitely pan. When panning beyond the bounds then the world should should be wrapped.

๐Ÿ˜ฏ Current Behavior

Only a single instance is rendered.

๐Ÿ’ Possible Solution

Render the world instanced if multiple should be shown.

Render to views on Android/iOS

At some point we want to render to specific android and ios views and not to the whole screen. This is currently unsupported by winit.

Sadly it is not enough to render to a surface provided by the NDK/UIKit/AppKit. We also need to hook into the input handlers of iOS and Android. Maybe we should think about removing the complete winit dependency and handle all gestures in the corresponding SDKs and control the maplibre view from there. This means that the input handlers would be written in Swift/Kotlin/JavaScript instead of Rust.

iOS:

Difficult because winit is bound to the main UIApplicationView

Android:

Difficult because winit is bound to the main NativeActivity

Gestures

Create a struct for `ZoomLevel`

We probably should add a struct for ZoomLevel.

Originally posted by @maxammann in #87 (comment)

๐Ÿค” Expected Behavior

Zoom is a f64 which represents the current zoom on the map. It needs to be a floating number because we want to be able to zoom smoothly on the map.

ZoomLevel is a u8 which represents the level of a tile within the map's quad tree. ZoomLevel 0 would be one tile that contains the entire map, ZoomLevel 1 would be a part of the map if it was split in 4, etc.

We can derive the current ZoomLevel from the Zoom using the constant ZOOM_BOUNDS defined in the coords.rs file.

๐Ÿ˜ฏ Current Behavior

Currently ZoomLevel is always stored as a u8 directly.

๐Ÿ’ Possible Solution

We should create a custom type or a struct to store the zoom level.

๐Ÿ”ฆ Context

It would make the code easier to read.

๐Ÿ’ป Examples

The function below could be changed from:

pub fn scale_to_zoom_level(&self, z: u8) -> f64

to:

pub fn scale_to_zoom_level(&self, z: ZoomLevel) -> f64

Disable `dead_code` lint

We should consider removing this lint as we have lot of unfinished features.

TODO

๐Ÿค” Expected Behavior

๐Ÿ˜ฏ Current Behavior

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Build and run in Deno

The Deno JavaScript runtime allows to run WebGPU and WebAssembly in a headless mode. This means we could use Deno to create PNG raster image from vector data in a headless mode.

We can then also distribute maplibre-rs on https://wapm.io/

Related: #47

Improve Overall Architecture

๐Ÿค” Expected Behavior

  • MapState contains only the state such as zoom, coordinates. And maybe some utility functions to retrieve the tiles in a bbox.
  • MapContext stores the MapState. It could possibly store multiple map states if we need multiple maps at the same time? It also stores the scheduler, http client, tilecache and other utilities.
  • MapRenderer would access a MapContext and provide functions such as prepare_render(), update_and_redraw() and store the render_state.

We also want to support (maybe):

  • headless rendering
  • Using different renderers
  • etc.

๐Ÿ˜ฏ Current Behavior

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

ScheduleMethod which does not depend on `cross-origin isolation`

Like discussed in #60 it would be beneficial to have a schedule method which does not depend on SharedMemoryArray.

๐Ÿค” Expected Behavior

maplibre-rs does not depend on SharedMemoryArray.

๐Ÿ˜ฏ Current Behavior

maplibre-rs does not start without adding the correct HTTP headers.

๐Ÿ’ Possible Solution

It's possible to send data via postMessage between the Document and WebWorkers. That means data does not need to be serialized. We need to match computed data from a WebWorker with the initial request. We also need to let the WebWorker know which "work" has to be executed. A piece of work is currently wrapped in a Future. That means we need to register functions which create Futures. The names of these functions can be serialized in the render thread, deserialized in the WebWorker, and called in the WebWorker.

Render Thread                                                                 WebWorker
                                       -->  serialize request
                                       --> postMessage() 
                                       <-- deserialize & execute request and get result
                                       <-- postMessage()

Functions which create futures can be serialized by creating a registry.

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Refactor crate structure

.
โ”œโ”€โ”€ .cargo
โ”œโ”€โ”€ .github
โ”œโ”€โ”€ docs
โ”œโ”€โ”€ maplibre
โ”œโ”€โ”€ maplibre-android
โ”œโ”€โ”€ maplibre-apple
โ”œโ”€โ”€ maplibre-benches
โ”œโ”€โ”€ maplibre-renderer
โ”œโ”€โ”€ maplibre-example
โ”œโ”€โ”€ maplibre-web
โ”œโ”€โ”€ maplibre-style-spec
โ”œโ”€โ”€ maplibre-tilejson-spec
โ”œโ”€โ”€ maplibre-wgsl-validate
โ”œโ”€โ”€ justfile
โ”œโ”€โ”€ Cargo.toml
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ rust-toolchain.toml
โ”œโ”€โ”€ .gitignore

Text rendering

We need to add support for rendering arbitrary text (labels, street names, etc.). An ideal solution would have the following properties:

  • Supports all languages (obvious -> we show a map of the entire world)
  • Renders completely on the GPU as part of the map (otherwise we defeat the purpose of this project: truly cross-platform maps)
  • Renders nicely at arbitrary font sizes
  • Renders correctly with regards to arbitrary 3-d transformations
  • Supports styling (i.e. color, different fonts, etc.)

This poses numerous challenges and likely no solution exists that fulfils all of these criteria. But since this is a clean-slate project we might as well try ๐Ÿคท ๐Ÿ˜‰

Fix crosscompiling on AMD64 for andriod/apple

Sometimes the CI fails with the following error:

error: failed to run custom build command for `ring v0.16.20`

Caused by:
  process didn't exit successfully: `/home/runner/work/maplibre-rs/maplibre-rs/target/debug/build/ring-f696b55488b2d439/build-script-build` (exit status: 101)
  --- stdout
  OPT_LEVEL = Some("0")
  TARGET = Some("x86_64-linux-android")
  HOST = Some("x86_64-unknown-linux-gnu")
  CC_x86_64-linux-android = None
  CC_x86_64_linux_android = None
  TARGET_CC = None
  CC = None
  CFLAGS_x86_64-linux-android = None
  CFLAGS_x86_64_linux_android = None
  TARGET_CFLAGS = None
  CFLAGS = None
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")

  --- stderr
  running "x86_64-linux-android-clang" "-O0" "-DANDROID" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-I" "include" "-Wall" "-Wextra" "-pedantic" "-pedantic-errors" "-Wall" "-Wextra" "-Wcast-align" "-Wcast-qual" "-Wconversion" "-Wenum-compare" "-Wfloat-equal" "-Wformat=2" "-Winline" "-Winvalid-pch" "-Wmissing-field-initializers" "-Wmissing-include-dirs" "-Wredundant-decls" "-Wshadow" "-Wsign-compare" "-Wsign-conversion" "-Wundef" "-Wuninitialized" "-Wwrite-strings" "-fno-strict-aliasing" "-fvisibility=hidden" "-fstack-protector" "-g3" "-DNDEBUG" "-c" "-o/home/runner/work/maplibre-rs/maplibre-rs/target/x86_64-linux-android/debug/build/ring-0884ff4fa3766d69/out/aesni-x86_64-elf.o" "/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/pregenerated/aesni-x86_64-elf.S"
  thread 'main' panicked at 'failed to execute ["x86_64-linux-android-clang" "-O0" "-DANDROID" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-I" "include" "-Wall" "-Wextra" "-pedantic" "-pedantic-errors" "-Wall" "-Wextra" "-Wcast-align" "-Wcast-qual" "-Wconversion" "-Wenum-compare" "-Wfloat-equal" "-Wformat=2" "-Winline" "-Winvalid-pch" "-Wmissing-field-initializers" "-Wmissing-include-dirs" "-Wredundant-decls" "-Wshadow" "-Wsign-compare" "-Wsign-conversion" "-Wundef" "-Wuninitialized" "-Wwrite-strings" "-fno-strict-aliasing" "-fvisibility=hidden" "-fstack-protector" "-g3" "-DNDEBUG" "-c" "-o/home/runner/work/maplibre-rs/maplibre-rs/target/x86_64-linux-android/debug/build/ring-0884ff4fa3766d69/out/aesni-x86_64-elf.o" "/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/pregenerated/aesni-x86_64-elf.S"]: No such file or directory (os error 2)', /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/build.rs:653:9
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This is due to this bug: briansmith/ring#1488

Update `@chialab/esbuild-plugin-meta-url`

Update the npm dependency @chialab/esbuild-plugin-meta-url and remove the .patch file from the web package. The issue which caused us to apply the patch was resolved: chialab/rna#47

The dependency which applies patches should also be removed.

๐Ÿค” Expected Behavior

No patches should be needed and the package should compile.

๐Ÿ˜ฏ Current Behavior

A patch is used.

๐Ÿ’ Possible Solution

Remove the patching infrastructure.

"cargo test" fails with "android-ndk-sys only supports compiling for Android"

I'm trying to work on one of the issues labelled with good first issue and to ensure that my changes aren't breaking anything, I would like to run the tests, but it's failing.

๐Ÿค” Expected Behavior

I expect the tests to be executed when I run cargo test.

๐Ÿ˜ฏ Current Behavior

I forked the repository and installed the toolchain with cargo --version > /dev/null as seen in the justfile. I then executed cargo test and it failed with the error:

error: android-ndk-sys only supports compiling for Android
  --> /home/johndoe/.cargo/registry/src/github.com-1ecc6299db9ec823/ndk-sys-0.2.2/src/lib.rs:22:1
   |
22 | compile_error!("android-ndk-sys only supports compiling for Android");
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: could not compile `ndk-sys` due to previous error
warning: build failed, waiting for other jobs to finish...
error: build failed

๐ŸŒ Your Environment

  • Desktop
    • Operating System: Linux (NixOS)
    • Display Server: Xorg

Support S3/https/file protocols

We would like to be able to use different protocols for retching mbtiles/pmtiles/tiles.

๐Ÿค” Expected Behavior

When support in PM tiles the scenario would look like that:

image

We would like to support multiple protocols between maplibre and hosted data:

image

๐Ÿ˜ฏ Current Behavior

Current scenario:
image

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Optimization: Reduce size of Quadkey

This is an optimization without any clear benefit/problem associated -> Low Priority.

๐Ÿค” Expected Behavior

๐Ÿ˜ฏ Current Behavior

The quadkey currently uses 8 bits for zoom level + MAX_ZOOM * 8 bits while it could be optimized to 8 bits for zoom level + MAX_ZOOM * 2 bits. The 2 bits define the square used in each subdivision of the quad tree, it can be NW (north west), NE (north east), SW (south west) or SE (south east).

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Parallelize iOS archive in CI

During the apple job in the CI we execute xcodebuild multiple times. In each invocation we run a cargo build which takes a few minutes. After all archives have been built we join them to a `xcframework.

The archive steps could be parallelized in the CI. This would reduce the duration of the apple build to 3-5 minutes.

Lower the default MacOS deployment target in the XCode project

The MacOS deployment target in the XCode project is set by default to 12.3. I may be wrong but from what I understand, a Mac on version 12.3 can run applications that target a lower version but it doesn't work the other way around. A Mac on version 11 can't run applications with a target version of 12.

I think we should target in our MacOS build the lowest version possible that supports the APIs we are using. I have tried running with a target of 10.9 (which is the lowest version proposed on XCode by default) and it seems to work alright.

This would make the configuration of the XCode IDE easier for new developers. The MacOS build would also support a wider range of devices.

Hide SQLite3 dependency behind a feature flag

Right now we depend on sqlite3 as a build dependency. This feature is usually only used when embedding tiles statically in the binary for testing.

๐Ÿค” Expected Behavior

A feature flag should exclude the sqlite3 dependency.

๐Ÿ˜ฏ Current Behavior

sqlite3 is a hard dependency.

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

We can simplify parts of the windows CI. For example the demos do not need sqlite3:

#101 (comment)

๐Ÿ’ป Examples

Explain WASM size through Github Action

Goal of this task is to give some more insights into the size of the wasm/native binary.

Note: This is a beginner task because it requires no insight into maplibre-rs. But its probably not tivial.

๐Ÿค” Expected Behavior

  • We want a cargo profile, which includes debug symbols, but is else identical to a release build. This gives a good estimate of actual sizes and allows to debug the usage.
  • Track wasm size through a custom Github Action. Post diffs in the PR.

๐Ÿ˜ฏ Current Behavior

No insights.

๐Ÿ’ Possible Solution

There is https://github.com/orf/cargo-bloat-action/tree/master/src
Sadly this does not support WASM. Also it sends data to some cloudflare service in the US.

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Looking forward

I started to implement the same idea some weeks ago as a private project for me to learn rust and experiment a little bit with wgpu.

To focus on the renderer itself I decided to use OpenLayers as a base.

Rendering is completly inside an OffscreenCanvas with rust and wgpu-rs. Vector tile parsing with prost, triangulation with earcutr and multithreading with wasm-bindgen-rayon.

Looking forward to this project now. Nice to see that there is also some work going on in maplibre space for this future tech.

image

Deploy an android dependency

We already build an android library via gradle. Add a publish task which publishes the package.

๐Ÿค” Expected Behavior

maplibre-rs is available on a repository like maven central.

๐Ÿ˜ฏ Current Behavior

Its only available as a gradle project.

Design & Implement Render Graph

TODO

๐Ÿค” Expected Behavior

๐Ÿ˜ฏ Current Behavior

๐Ÿ’ Possible Solution

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Restrict navigation to map bounds

Difficulty: Hard

Currently, there are no bounds when navigating (pan, zoom) the map. The goal of this task is to restrict the navigation such that users can not escape and see empty space.

๐Ÿค” Expected Behavior

In Y direction the navigation should be restricted such that one can not pan out from the map.

In X direction it should be possible to infinitely pan. When panning beyond the bounds then the world should should be wrapped. This is done in #74.

๐Ÿ˜ฏ Current Behavior

There are no bounds.

๐Ÿ’ Possible Solution

??

Discuss requirement of cross-origin isolated

maplibre-rs currently requires that the host site, which runs maplibre-rs needs to be "corss-origin isolated". This is a quite strict requirement: https://web.dev/coop-coep/

The reason for this requirement is the usage of SharedArrayBuffer. I see three possible solutions for this problem:

  • Provide an alternative implementation for "multi-threading" on the web. This would complicate the asynchronous capabilities of maplibre-rs even more. This also introduces a performance penalty because computed data needs to be serialized in order to pass it between WebWorkers
  • Hope that the restrictions for SharedArrayBuffer are lowered in the next 2 years.
  • Live with that fact. This is probably not really possible. Enabling "cross-origin isolation" has an impact on any cross-origin resources used by users.

More Info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/Planned_changes

Render directly to lower-level graphics surface

Like maplibre-gl-native, this library could support rendering to lower-level graphics surfaces, ideally

  • OpenGL framebuffer
  • Metal surface
  • DirectX surface

This would allow easier integration to custom apps or other libraries like Qt.

Avoid install all toolchain targets in every CI Job

Right now we install all targets specified in rust-toolchain.toml in every CI job. That means we also install the android targets in apple jobs and vice versa.

This is unnecessary. Therefore, we should probably remove the targets from the rust-toolchain.toml, and document the supported toolchain targets somewhere.

Raster Tile Rendering

We want to be able to render raster tiles. This is required for rendering data sets like "Natural Earth". Raster tiles can be of any web-native image format like PNG or WEBP.

๐Ÿค” Expected Behavior

Raster tiles need to be scaled and transformed like vector tiles.

๐Ÿ˜ฏ Current Behavior

No raster tiles are supported.

๐Ÿ’ Possible Solution

The WebGPU spec offers a way to load bitmaps to textures: https://toji.github.io/webgpu-best-practices/img-textures.html
In the browser this requires the createImageBitmap() API which offloads decoding of images to the browser.

๐Ÿ”ฆ Context

๐Ÿ’ป Examples

Refactor the input module

The input module, which handles key presses and other inputs is quite cluttered. That means that, the logic in order to update the libraries state is quite complicated. The update_state function does the actual updates, while the inputs are recorded through input listeners.

  • Take into account #130 in order to support multi-touch.
  • Take into account #28

๐Ÿค” Expected Behavior

We need a clear abstraction above the recorded inputs and the state update.

๐Ÿ˜ฏ Current Behavior

In the event handlers data is recorded. Based on this data, the update_state function is updating the state.

๐Ÿ’ Possible Solution

Maybe reactive programming could be a good abstraction.

๐Ÿ”ฆ Context

๐Ÿ’ป Code Sample

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.