Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

projection setting on map object (outside style) #4909

Closed
birkskyum opened this issue Oct 26, 2024 · 5 comments
Closed

projection setting on map object (outside style) #4909

birkskyum opened this issue Oct 26, 2024 · 5 comments
Labels
enhancement New feature or request globe Globe related issues good first issue Good for newcomers PR is more than welcomed Extra attention is needed

Comments

@birkskyum
Copy link
Member

birkskyum commented Oct 26, 2024

User Story

I'd like to be able to set a projection on my map, and change style at will.

Rationale

If i have a style object, then I can apply the projection directly with a spread, or by editing the object before setting the style:

GoogleSatStyle.projection = { type: 'globe' }
or
style: { ...GoogleSatStyle, projection: { type: 'globe' } },

If I have a style url, with or without api keys (like Positron "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"), then it's more tedious, because I'd have to download the style, then editing it, and then setting it like above, every time setStyle is called, like:

async function downloadStyleObject(url: string) {
    return await fetch(url)
	.then((response) => response.json())
	.then((data) => data)
	.catch((error) => {
		console.error("Error fetching or parsing JSON:", error);
		return null;
	});
}

and then the same as prior

style: {...(await downloadStyleObject(getBasemap())), projection: {type:'globe'}}

Impact

It would be an override, so if it's not set there is no impact

@HarelM
Copy link
Collaborator

HarelM commented Oct 27, 2024

Thanks for opening this issue! Yes I had the same thoughts and added it to the v5 issue.
Feel free to open a PR to solve this, should be fairly simple I believe.

@HarelM HarelM added enhancement New feature or request good first issue Good for newcomers PR is more than welcomed Extra attention is needed globe Globe related issues labels Oct 27, 2024
@birkskyum
Copy link
Member Author

birkskyum commented Oct 29, 2024

@HarelM , I've become a bit unsure if it's sufficient. If the projection maybe just is the latest symptom that we need a more generic styleOverride hook. My initial idea for this is a modifier function, that would allow not only additions, but also removals of broken layers, setting projection etc. from styles loaded with urls:

Before:

async function downloadStyleObject(url) {
    return await fetch(url)
        .then((response) => response.json())
        .then((data) => data)
        .catch((error) => {
            console.error("Error fetching or parsing JSON:", error);
            return null;
        });
}

let style = await downloadStyleObject('https://.../style.json?APIKEY=)
style.projection = {type: "globe"}
style.layers.filter(layer=>layer.name != "waterway")
    
style: style

After:

style: 'https://.../style.json",
styleOverride: (style)=>{
    style.projection = {type: "globe"}
    style.layers.filter(layer=>layer.name != "waterway")
}

My hesitation comes from cases like below link, where I'm loading a proprietary satellite layer form a url, and then have a need to manipulate the style projection, layers, sources, terrain, sky etc. afterwards.

https://github.com/maplibre/maplibre-gl-js/blob/01cbe7af5a206a2e7bce1cecafdd6b95063c3ba6/test/examples/globe-3d-terrain-satellite.html

There's a bit more to the design though, because say you have a layer shifter (sat / street), and you change the style with setStyle(), then you might want to have a different set of modifications, i.e. because it's only e.g. sat style that has a broken layer, and the names in the arrays of style.layers are different.

And that would mean that the url, and the override is linked, requiring an api like

After:

style: {
    url: 'https://.../style.json", 
    override: (style)=>{
        style.projection = {type: "globe"}
        style.layers.filter(layer=>layer.name != "waterway")
    }
}

@HarelM
Copy link
Collaborator

HarelM commented Oct 29, 2024

You can supply a style diff method, this already exists right now.
https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/TransformStyleFunction/

@birkskyum
Copy link
Member Author

birkskyum commented Oct 29, 2024

@HarelM , interesting, can i tell from within that method what the new style url is, so that the logic can be conditioned on that?

@HarelM
Copy link
Collaborator

HarelM commented Oct 29, 2024

No, style URL is not part of the StyleSpecification definitions, but you probably find some info in the metadata.
Aslo, these 5 lines of code to manipulate a fetched style are not something that complicated to write if one needs a more complicated scenario...

@birkskyum birkskyum closed this as not planned Won't fix, can't repro, duplicate, stale Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request globe Globe related issues good first issue Good for newcomers PR is more than welcomed Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants