sk-zk / lookaround-map

🍎👀🗺
https://lookmap.eu.pythonanywhere.com/
MIT License
47 stars 9 forks source link

Are panorama images streamed or served locally? #9

Closed user080975 closed 4 months ago

user080975 commented 4 months ago

For the panorama images, can I serve them from my own server / S3 bucket or are they all live streamed from the Apple Maps API and proxied through my own server? Does provisioning servers closer to users make any difference in pano transitions?

sk-zk commented 4 months ago

For the panorama images, can I serve them from my own server / S3 bucket or are they all live streamed from the Apple Maps API and proxied through my own server?

Panorama faces are loaded directly from the internal Apple Maps API, but must be proxied through the backend to convert them and to bypass CORS.

Does provisioning servers closer to users make any difference in pano transitions?

Probably, but the most important thing is how much CPU power is available. Outside of Apple's walled garden, HEIC support is practically nonexistent, so for the majority of users, the backend has to convert the images to JPG first. Since these images are fairly large, and HEIC is also inherently slower to decode than many other formats, this is a very CPU-intensive task, so the faster your server is, the better the experience will be.

user080975 commented 4 months ago

Thanks a lot for the detailed reply. After the initial conversation from HEIC to JPG, is it possible to cache the images in CDN or locally and then serve that for future users or does each new user have to re-request the conversion for each panorama again?

Can the JS embedding demo load the converted JPG from CDN for subsequent requests?

sk-zk commented 4 months ago

is it possible to cache the images in CDN or locally and then serve that for future users or does each new user have to re-request the conversion for each panorama again?

I'm a bit out of my depth when it comes to caching or CDNs, but the panoramas are completely static, so it should be pretty easy to add a caching layer somewhere. That said, IMO this is only worth doing if you are certain that specific panoramas are frequently accessed. On my public instance, where people are just randomly exploring, the chance that two people happen to hit the exact same panorama before it leaves a hypothetical cache is very low; if you're embedding a specific place on a website, though, it may make sense to cache that.

Can the JS embedding demo load the converted JPG from CDN for subsequent requests?

You mean from a different URL? The viewer will always request images from apiBaseUrl/pano/..., so if you want it to pivot to a cached file on a CDN if one exists, you'll need to add that functionality. Returning an HTTP redirect from that endpoint might work, but I haven't tested it, so no guarantees

user080975 commented 4 months ago

Alternatively would it be feasible to preload for example a 100m radius of panoramas on each panorama transition? This way after a user arrives at one panorama, looks around and then decides to proceed to the next one, the images are already loaded instead of a delay between each transition?

sk-zk commented 4 months ago

Not really.

In the best case scenario, where the 100 m circle only contains one road that has been covered only once, that's ~35 panoramas. At zoom level 5, which is what the viewer loads initially, you'd be downloading 6 files per panorama at a size of ~140 kB each, so that's 210 files with a size of 29.4 MB.

Most of the time though, the user will be in a city, where you can expect ~300 panoramas to be in the circle. That's 1,800 files to download weighing 252 MB – and that's still just for the initial low quality load.

In the worst case scenario, which is a city center with dense backpack coverage, you're already in the thousands: a 100 m radius around [50.083556, 14.434191], which is in Prague, contains an incredible 6,796 panoramas. That'd be a download of 40,776 files or 5.71 GB (!).

user080975 commented 4 months ago

I see, alternatively would it be feasible to, instead of pushing the HEIC files directly to JS viewer, to push the files to something like an S3 bucket and then have JS viewer fetch the HEIC files from the S3 link instead. This would allow CDN caching using AWS Cloudfront.

sk-zk commented 4 months ago

Yes, you could preemptively download all metadata and panoramas within a specific area, e.g. with the lookaround submodule, and then serve that from a CDN – either by modifiying routes/api.py as needed, or by writing a custom server which emulates those responses.

user080975 commented 4 months ago

Instead of preemptively downloading all panoramas, would realtime pushing to CDN and JS pulling images from CDN be realistic? This might introduce a small delay between transitions for first time users but all subsequent requests should be from fetched from CDN.

sk-zk commented 4 months ago

If your users are primarily looking at one specific area, then I suppose that would work. Otherwise, you'd be accumulating a lot of files that will never actually be hit a second time

user080975 commented 4 months ago

Okay thanks for the confirmation! Does the minified viewer.js use this three JS code?

Is there a way to pass in a custom value for the crossfade effect? Currently it’s very fast and the cross fade effect isn’t very visible.

https://github.com/sk-zk/lookaround-map/blob/main/js/viewer/LookaroundAdapter.js#L145

sk-zk commented 4 months ago

Okay thanks for the confirmation! Does the minified viewer.js use this three JS code?

You mean in general or the method you linked in particular? But the answer is yes to both

Is there a way to pass in a custom value for the crossfade effect? Currently it’s very fast and the cross fade effect isn’t very visible.

It's hardcoded atm, but I can add an option to createPanoViewer for this.

user080975 commented 4 months ago

That would be really helpful! I think it would result in much smoother user transitions.

sk-zk commented 4 months ago

Did you delete your last two comments or did GitHub swallow them?

user080975 commented 4 months ago

I wanted to refactor my questions so I deleted them. After playing around with the code, I notice that the crossfade part is drawing the panorama to canvas and then fading that out on each transition. Have you noticed any crashing issues on mobile browsers with this approach? Would this be very resource heavy?

Also, I need to set the initial zoom to maxed out so that there's more panorama visibility in smaller mobile displays. I notice there is a 'defaultZoomLvl' parameter but modifying it doesn't seem to affect the initial zoom level on load.

sk-zk commented 4 months ago

After playing around with the code, I notice that the crossfade part is drawing the panorama to canvas and then fading that out on each transition. Have you noticed any crashing issues on mobile browsers with this approach? Would this be very resource heavy?

Well, I only have my old mid-range Android to test on so I can't tell you how it performs anywhere else, but given that the panorama is rendered with a 3D engine, I don't expect a second fullscreen canvas to be too much of an issue if it can run the former.

Also, I need to set the initial zoom to maxed out so that there's more panorama visibility in smaller mobile displays. I notice there is a 'defaultZoomLvl' parameter but modifying it doesn't seem to affect the initial zoom level on load.

Sure, I'll add an option for it

user080975 commented 4 months ago

Thanks! Is there a 'loaded' event I can listen on? To know when the street view has been loaded and ready to navigate.

sk-zk commented 4 months ago

The viewer has a ready event which triggers when the initial pano has been loaded:

https://photo-sphere-viewer.js.org/guide/events.html#ready

user080975 commented 4 months ago

Thanks! So all of the methods, markers in the Photo Sphere documentation can be used as well right?

sk-zk commented 4 months ago

Most of what's in the core package should work, but because of the workarounds and monkeypatching I've had to do to make the library work for my use case, a few things don't. For example, you should call my navigateTo instead of the native setPanorama.

The marker and compass plugins are also the official ones, but the movement plugin I use is custom and not related to the VirtualTourPlugin.