vasturiano / globe.gl

UI component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/globe.gl/example/world-population/
MIT License
2.06k stars 302 forks source link

Is it possible to update the texture of a map on zoom? #174

Open j2is opened 1 year ago

j2is commented 1 year ago

I know there is a callback for the zoom function... I was wondering if anyone had any idea how to replace a portion of the world with a higher resolution tile, so with each zoom there's a higher level map tile. Several map tiles being loaded as the user pans around would then progressively enhance the map. As far as I can see there's only one map image that can be loaded, so perhaps this isn't currently possible?

vasturiano commented 1 year ago

@j2is The globeImageUrl method expects a single image for the whole globe so if you keep increasing the resolution of this image it will work but the files will start getting quite large, given that it's the entire world.

What you're suggesting would be possible with the tiles layer. When you detect zoom level changes (using onZoom f.e.) you could add high resolution image tiles just for the portion of the globe that's in view so it would achieve what you're describing. I don't have an example of it that I can give you, but these are the main building blocks of such an implementation.

yano1978 commented 6 months ago

@vasturiano Good afternoon, I know this question might be a bit off topic and I am pretty new at Three.js, but if I'd need to create tiles myself (and map them appropriately) what service could I use. I tried MapTiler Engine software but I cannot figure out the logic behind resulting folders structure to map my tiles. Also, based on your tiles example and assuming I can find out the correct folder structure, how can I add correctly materials to my tiles? I have created a json files mapping pngs and that should be fine, however, I am not sure how they will "spread" around the globe.

`
const textureURLs = [ "/textures/0/0/0.png", "/textures/1/0/0.png", "/textures/1/0/1.png", "/textures/1/1/0.png", "/textures/1/1/1.png", "/textures/2/0/0.png", "/textures/2/0/1.png", "/textures/2/0/2.png", "/textures/2/0/3.png", "/textures/2/1/0.png", "/textures/2/1/1.png", "/textures/2/1/2.png", "/textures/2/1/3.png", "/textures/2/2/0.png", "/textures/2/2/1.png", "/textures/2/2/2.png", "/textures/2/2/3.png", "/textures/2/3/0.png", "/textures/2/3/1.png", "/textures/2/3/2.png", "/textures/2/3/3.png", "/textures/3/0/1.png", "/textures/3/0/2.png", "/textures/3/0/3.png", "/textures/3/0/4.png", "/textures/3/0/5.png", "/textures/3/0/6.png", "/textures/3/1/1.png", "/textures/3/1/2.png", "/textures/3/1/3.png", "/textures/3/1/4.png", "/textures/3/1/5.png", "/textures/3/1/6.png", "/textures/3/2/1.png", "/textures/3/2/2.png", "/textures/3/2/3.png", "/textures/3/2/4.png", "/textures/3/2/5.png", "/textures/3/2/6.png", "/textures/3/3/1.png", "/textures/3/3/2.png", "/textures/3/3/3.png", "/textures/3/3/4.png", "/textures/3/3/5.png", "/textures/3/3/6.png", "/textures/3/4/1.png", "/textures/3/4/2.png", "/textures/3/4/3.png", "/textures/3/4/4.png", "/textures/3/4/5.png", "/textures/3/4/6.png", "/textures/3/5/1.png", "/textures/3/5/2.png", "/textures/3/5/3.png", "/textures/3/5/4.png", "/textures/3/5/5.png", "/textures/3/5/6.png", "/textures/3/6/1.png", "/textures/3/6/2.png", "/textures/3/6/3.png", "/textures/3/6/4.png", "/textures/3/6/5.png", "/textures/3/6/6.png", "/textures/3/7/1.png", "/textures/3/7/2.png", "/textures/3/7/3.png", "/textures/3/7/4.png", "/textures/3/7/5.png", "/textures/3/7/6.png" ]

    const GRID_SIZE = [30, 20];
const tileWidth = 360 / GRID_SIZE[0];
const tileHeight = 180 / GRID_SIZE[1];
const textureLoader = new THREE.TextureLoader();
const materials = textureURLs.map(
    texture =>
        new THREE.MeshLambertMaterial({
            map: textureLoader.load(texture),
            opacity: 1,
            transparent: true,
        })
);

const tilesData = [];

[...Array(GRID_SIZE[0]).keys()].forEach(lngIdx =>
    [...Array(GRID_SIZE[1]).keys()].forEach(latIdx =>
        tilesData.push({
            lng: -180 + lngIdx * tileWidth,
            lat: -90 + (latIdx + 0.5) * tileHeight,
            material: ???,
        })
    )
);`

Thanks in advance for the help!