felixpalmer / procedural-gl-js Goto Github PK
View Code? Open in Web Editor NEWMobile-first 3D mapping engine with emphasis on user experience
Home Page: https://www.procedural.eu/map
License: Mozilla Public License 2.0
Mobile-first 3D mapping engine with emphasis on user experience
Home Page: https://www.procedural.eu/map
License: Mozilla Public License 2.0
Description
Camera makes a jump when clicking on markers if camera angle different from default.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Camera angle to change smoothly with the translate animation
Screenshots
Example
Desktop
Mobile
Hi, don't know if this is already possible, but it would be very useful to have a kind of callback to get the world coordinates where the user clicked. This would serve several purposes:
hi felixpalmer:
1,this is a great repo ,thanks you let us learning from this repo
2. i have same confuse above that maybe that is a error so i issue it
3. i try add three object into the sence, the obj's location must be {x,y,z} in sence 。 i want to picker from GPU renders Terrain's {x,y,z} .and than obj could real create on the terrain.
I'm not quite sure if this is the right place to put this, so let me know if not
Anyway, so I have a question, is it possible to add THREE.js objects into a procedural-gl-js scene? Because I believe procedual-gl-js uses THREE.js behind the scenes (though correct me if not).
So could I, for instance, and create a cube with THREE.js, and add it to the procedural-gl-js scene in some way?
Many thanks :)
Hello Felix. Let me congratulate you for this awesome repo. We have a product that we are thinking of implementing this, so we have some questions:
Hope to get your reply.
Best regards.
At the moment it seems to be the case that there can only be 1 Procedural container in the DOM. Despite the performance hit having multiple, is this something that is on the road map?
Hi, @felixpalmer! First of all big thanks and congratulations on an amazing library! The recent update, which provides API for custom terrain tilesources was exactly what our project needed so much! A bit of the background on how we try to use your library - our project aims to visualize the changes that happened to the landscape of one of the Kyiv districts, in Ukraine, throughout the 20 century and until now (in the area where the Holocaust massacre happened during the WW2, which is the focus of our research investigation).
For this, we have prepared custom rgb tile-sources of high resolution (max zoom level in our terrain tilesets is 18, tilesize is standard 512x512), for different years. However, we noticed that the library caps the max zoom level of the tile-source (fetching happens for the 10th zoom level at the max), this way preventing the landscape to render in a higher detail at the close-ups. Is it possible to configure the max zoom of the tileset in any way? E.g. as a part of the datasource configuration? Maybe it could be configured similarly to how this is specified in the tilejson specs, with 'maxzoom' and 'minzoom' properties? Thank you very much for your answer in advance!
Hello,
Thanks for your great work on this library!
I'm evaluating using procedural-gl-js in a visualization tool, to plot 3D GPS flight paths. In this application, the viewer is only concerned with the area immediately around the flight path. This flight path might be small (a few kilometers), large (hundreds of kilometers), and irregularly shaped (a random path that stretches very far in some direction).
Is there any way to configure the range of tiles loaded around the display location, or explicitly choose which tiles to load?
Right now, the map seems to load a pretty large area in a square around the GPS coordinates specified using displayLocation. For example, if I search "Boston, MA", the example loads almost all of Massachusetts. I'm hoping to do a few things:
I'd love to be able to pass in an explicit list of XYZ tile coordinates,. I looked around the source code, but couldn't find where the library is converting lat/lng coordinates into an list of tiles to load. Would be happy to contribute if I could be pointed in the right direction!
I'd expect pressing the +
or -
keys to zoom in or out. But handleKeyDown()
has no case for that, so I guess it's not implemented.
Google Maps does it.
Really nice work with this library!
I am experimenting with it for air quality data visualization.
I was wondering if it could be possible to add a way to directly dump the framebuffer, so it could be saved as an image sequence?
Hi Felix!
First of all, thank you very much for your great project! What about the issue, I tried to fix it by myself with PR in mind, but failed to do that. So I just report it to you.
Describe the bug
If to follow example of call to configureControls
presented at
https://github.com/felixpalmer/procedural-gl-js/blob/main/src/export/controls.js#L37
we see option value maxPolarAngle: 0.8 * Math.PI
.
That's great idea because it allows us for example to look on mountains from below to top.
However, on more-less flat surfaces the camera easily goes below ground level when this maxPolarAngle
value is used.
And then, the view sometimes becomes corrupted, with no way to return above ground level.
To Reproduce
Steps to reproduce the behavior:
maxPolarAngle: 0.8 * Math.PI
option.Hi Felix,
hope you are doing well! what a great package, really cool :-) I had a few questions, if possible.
I was wondering, is there any way to access the THREE.js camera and scene such that the user can see what the current viewpoint (camera position) is? For instance, then the user can manipulate the view using the mouse, get access to the location and camera position to then programmatically zoom to it say. Is that possible?
In the same vain, as your tool is build on top of THREE.js, is it possible to add custom meshes to a scene, similar to what one can do with globe.gl?
FYI, its render controls and utility functions are quite handy to create and sync additional annotation layers to a view.
Anyways, congrats on your package, really amazing!
kind regards, Herman
Thanks for making this great library open source! It is a really exciting contribution to the web mapping ecosystem. I was trying to run procedural-gl.js
locally and ran into some issues while running shaders/minify.sh
.
The first issue I encountered is that glsl-validate.py
could not be found. I found that it references your library glsl-validator, but after bringing that in discovered that the compiled binaries for MacOS seem to be for an older runtime. I did some research into the origins of those binaries and it seems they come from angle, but it seems the essl_to_glsl
utility no longer exists.
The second issue I encountered is that glslmin
doesn't seem to work with newer versions of nodejs, at least not entirely. Using the syntax in minify.sh
glslmin
would hang on the first file and never finish or write an output. I was able to work around this by piping the input into the utility instead as so cat beacon.frag | cat glslmin > min/beacon.frag
, but that seems less than ideal.
Do you have any advice for getting this step of the build pipeline to complete? Are there other utilities that could be used in place of glsl-validate.py
and glslmin
?
My system is as follows:
MacOS 10.15.7
Node v12.14.1
Python 2.7.16
Python3 3.7.9
Thank you!
Hi,
I'm from TU Wien and we got our hands on some high resolution height data for Austria, and now we are playing around with it and with your 3d map. We are thinking of it as a possible research vehicle, and tool for mountaineers.
First of all, we are having some troubles: https://www.youtube.com/watch?v=3q-_05H2HpU
Our dem tiles have a resolution of 256x256, so we had to change that. we also increased the maxZoom for dem tiles to 20 i think. I don't know whether that has something to do with the problem. In any case, we are willing to put in work, but maybe you could give us some pointers? We have background in 3d, but not so much in java script yet.
Also another thing: it's likely we'll put one or several students onto some tasks. Are you still actively developing this project? Would you like to receive merge request? co-supervise or something? if you like we can also have a zoom meeting, if you moved on, that's also fine :)
Cheers, Adam
so glad to found this great repo, couple questions though:
cheers
Hey!
Thanks for the great library. Really enjoyed trying it out so far 🙂
I have one question:
Is it possible to add an area (polygon) as an overlay? I tried it now for some time but it does not seem to display. What I'm trying to achieve is something like this:
https://geojson.io/#map=13/48.3135/14.3413
When I take the geojson and put it into the overlay editor: https://www.procedural.eu/overlays.html it seems that the area (polygon) is recognized correctly but I can not see anything. This is the geojson I tried:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#ff0000",
"fill-opacity": 0.5
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
14.361705780029295,
48.318478372736365
],
[
14.34608459472656,
48.308888618124726
],
[
14.359989166259767,
48.29404377802783
],
[
14.386768341064451,
48.2964420830209
],
[
14.38436508178711,
48.314482860683626
],
[
14.361705780029295,
48.318478372736365
]
]
]
}
}
]
}
Am I doing something wrong or is this feature not implemented right now?
Thanks a lot
Hi, just tried to use mapbox static tile server, but it seems that some tile coordinates are messed, see here:
Using this
const datasource = {
elevation: {
apiKey: APIKEY,
},
imagery: {
apiKey: APIKEY,
urlFormat: 'https://api.mapbox.com/styles/v1/mapbox/streets-v9/tiles/{z}/{x}/{y}?access_token={apiKey}',
};
Hey, this library is gorgeous!
I was wondering whether it would be possible to zoom out to see the whole globe.
What are the technical limitations there?
Most of the map tiles I use are in the "high dpi" 512x512px png format. They currently load, but obviously look super weird as they are expected to be 256x256px.
Hi @felixpalmer , it would be very useful to have a removeAllOverlays method. Simply to remove all overlays without needing to express the features name. What do you think?
When zooming with the mouse wheel, the zoom feels very slow.
Some values that I see in the JS debugger:
// handleMouseWheel():
event.deltaY = 3
getZoomScale(event.deltaY) = 0.999
scope.zoomSpeed = 0.5
This is the difference between what was probably 2 full mousewheel rotations, barely perceptable. (Excuse the uneven cropping.)
On multiple Android devices, when 2 Features with unique ID's are defined, onFeatureClicked is not responding.
If the Features have the same ID, behavior is as expected.
On Desktop and iOS, Features with unique ID's also behave as expected when clicked.
When using image markers I'm shifting them upwards to make them visible even if they would be clipped normally.
Additionally I draw a circle in order to mark the real position. With a growing number of images and/or a growing offset between the image marker and the real position users may not be able to assign image markers to the corresponding real positions.
I'd like to be able to draw an offset indicator line between the image marker an the real position. Please see the attached screenshot with a faked offset indicator line.
First of all really nice library, much faster and easier to use than the other globe libraries 👍
Describe the bug
The environment parameters are being reset after sometime when using Procedural.displayLocation
To Reproduce
Steps to reproduce the behaviour:
// Environment
const environment = {
title: 'custom',
parameters: {
inclination: 0.6,
fogDropoff: 0
}
}
Procedural.setEnvironment(environment)
const location1 = { latitude: 52.3676, longitude: 4.9041 }
const location2 = { latitude: 45.8326364, longitude: 6.8564201 }
Procedural.displayLocation(location2);
setTimeout(()=> {
Procedural.displayLocation(location1);
// Fog comes back in play here
}, 5000)
Expected behaviour
Expected is that the environment parameters would stay the same.
First of all really nice library, much faster and easier to use than the other globe libraries 👍
Describe the bug
The environment parameters are being reset after sometime when using Procedural.displayLocation
To Reproduce
Steps to reproduce the behaviour:
// Environment
const environment = {
title: 'custom',
parameters: {
inclination: 0.6,
fogDropoff: 0
}
}
Procedural.setEnvironment(environment)
const location1 = { latitude: 52.3676, longitude: 4.9041 }
const location2 = { latitude: 45.8326364, longitude: 6.8564201 }
Procedural.displayLocation(location2);
setTimeout(()=> {
Procedural.displayLocation(location1);
// Fog comes back in play here
}, 5000)
Expected behaviour
Expected is that the environment parameters would stay the same.
Currently updateOverlay only permits updates to the positions of markers, it would be nice if other parameters could also be updated using this "fast path", for example opacity and color.
It's not work in huawei mobile.
The imageLoader onProgress-callback is missing from the ImageLoader.load-call so the error callback never triggers in case of a tile that is missing.
From the Three.js ImageLoader documentation:
// load a image resource
// instantiate a loader
const loader = new THREE.ImageLoader();
loader.load(
// resource URL
'textures/skyboxsun25degtest.png',
// onLoad callback
function ( image ) {
// use the image, e.g. draw part of it on a canvas
const canvas = document.createElement( 'canvas' );
const context = canvas.getContext( '2d' );
context.drawImage( image, 100, 100 );
},
// onProgress callback currently not supported
undefined,
// onError callback
function () {
console.error( 'An error happened.' );
}
);
To Reproduce
The issue becomes noticeable when using a custom datasource with a lot of requests returning 204 for 'Tile does not exist' using Tileserver-GL (maptiler/tileserver-gl#278).
What happens is that the request errors do not get deleted from this.fetching, pile up there and eventually trigger throttling which, in turn, after 32 errors, blocks the request of any new tile.
datasources/base.js #95-100
// Throttle downloads
let downloadIndices = Object.values( this.fetching );
if ( downloadIndices.length > 32 ) {
log( 'throttling...' );
return;
}
Expected behavior
With the error callback working, the errors get deleted from this.fetching and do not trigger throttling, but in case of 'missing tiles' will try again and retrigger the error.
Proposed fix
I think errors should be stored in an object similar to this.fetching
this.fetching = {};
this.failed = {};
populated on error and then checked against at the beginning of fetchIfNeeded():
fetchIfNeeded( quadkey ) {
if ( this.lookup[ quadkey ] !== undefined ||
this.fetching[ quadkey ] !== undefined ||
this.failed[ quadkey ] ) {
// Have data, download in progress, or tried and failed: skip
return;
}
// Throttle downloads
let downloadIndices = Object.values( this.fetching );
if ( downloadIndices.length > 32 ) {
log( 'throttling...' );
return;
}
let newIndex = this.findNewIndex( quadkey );
// Mark as download in progress
this.fetching[ quadkey ] = newIndex;
// Actually fetch data
let url = this.urlForTile( ...tilebelt.quadkeyToTile( quadkey ) );
ImageLoader.load( url, ( image ) => {
// Image loaded OK
this.imgCache[ quadkey ] = image;
insertIntoTextureArray( this.textureArray, newIndex, image );
// Remove download and mark image location in lookup
delete this.fetching[ quadkey ];
this.lookup[ quadkey ] = newIndex;
// TODO remove, just for demo page
if ( this.useFloat ) {
let el = document.getElementById( 'elevation-tile-count' );
if ( el ) {
let n = parseInt( el.innerHTML );
if ( isNaN( n ) ) { n = 0 }
el.innerHTML = ++n;
}
}
this.updateIndirectionTexture();
this.notifyUpdate();
},
undefined,
( err ) => {
if ( err.name == 'InvalidStateError' ) {
let newIndex = this.findNewIndex( quadkey );
this.failed[ quadkey ] = newIndex;
log( 'InvalidStateError / HTTP 204', quadkey );
} else {
console.error( 'Failed to get image', quadkey );
}
delete this.fetching[ quadkey ];
} );
}
Http 204 produces 'InvalidStateError' which should not trigger a console.error but everything else still does.
Is it possible to let elevation data be independent of an external service? For example I can craft an API with openly available elevation data (see https://www.opentopodata.org/datasets/srtm/) but I don't see how to integrate such a self-hosted API.
greetings!
Is this possible to use three.js object to combine with this library?
for example : add one Box above/below 3d map
thank you!
This library is really impressive, especially on Mobile. As I am considering migrating my project over to this, one of the really useful things with Cesium is the ability to control the internal clock externally, so a camera path over time can be controlled by a slider component or similar.
As a feature request, would it be possible to expose setting the internal clock ticks or similar, to allow the same feature in this Library?
Hi @felixpalmer , is it possible to center the map on a bounding box calculated automatically given the overlay markers?
This is great! Next to markers and features as overlay, could this application also render temporal grid overlay to visualise for example flood events?
Describe the bug
In some locations, when using focusOnLocation
, the camera is placed in correct position, but is facing away from the location.
To Reproduce
In the Overlay editor, enter the following geojson:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"color": "white",
"padding": 10,
"name": "Example",
"background": "green",
"icon": "star"
},
"geometry": {
"type": "Point",
"coordinates": [
21.884765625,
53.01
]
}
}
]
}
Expected behavior
Camera should point towards the location. It works for this example:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"color": "white",
"padding": 10,
"name": "Example",
"background": "green",
"icon": "star"
},
"geometry": {
"type": "Point",
"coordinates": [
21.884765625,
53.0
]
}
}
]
}
The only difference between those two examples is the latitude (53.0N vs 53.01N).
Desktop (please complete the following information):
Procedural GL JS looks to be a really interesting library, thanks for making it.
When you create a map that's centred on a location higher than 61°N, the map fails to work as expected. While there's no error in the browser console, neither the elevation data nor the satellite imagery looks like it's loaded properly. Interaction is broken too. This affects all of Iceland plus large parts of Norway, Sweden, Finland, Russia, Canada, and the United States (Alaska).
I've put a minimal failing example on JSFiddle (line 22 of the Javascript: toggle the latitude between 61.0 and 61.1 to see the map work or fail). You can also see this bug in the demo by searching for Gjøvik (~60°N, works) or Lillehammer (~61°N, fails), both in Norway.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.