mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
10.91k stars 2.19k forks source link

Support non-mercator projections #3184

Closed mike-marcacci closed 2 years ago

mike-marcacci commented 7 years ago

Adding this back as an issue, since its original one was converted into stagnated PR #1466, but remains a pretty cool feature!

Original Issue Text:

Hey mapbox team! I first want to say I'm truly blown away by what you've built here. This is really, really impressive.

Anyhow, I'm curious to know if there is any interest in support non-mercator projections? I checked out the transformation logic and the projection appears to be hard-coded.

I'm sure there are optimizations to be had by assuming a single projection, but it would be really neat to be able to provide mapbox-gl with custom projection functions: not only would this enable other "common" map formats, but would open the door for some really creative visualizations (check out this and this).

It would also make mapbox-gl an ideal candidate for non-geo-based maps, like a cross-section of a human body with organs, circulatory system, nervous system, etc.

Thanks again for all the cool tech, and for developing in the open!

Cheers, Mike

marcelnormann commented 3 years ago

I think a better idea would be to support a global ellipsoid canvas instead. Projections are messy, and localized for different regions. In my experience supporting WGS84 would be like a swiss army knife solution.

mapbox

Just like Google Maps.

I strongly agree with @AliFlux ! All these projection related topics are headed to the past where maps have to be drawn on plane paper. There are established frameworks like OpenLayers or Leaflet to serve such use cases. Mapbox should keep heading to the future. For me it seems azimuthal projection (like in Google Maps above) is the most obvious projection for computer cartography.

tvogt commented 3 years ago

Except where it isn't. If you need a world map, then the globe doesn't just it. If you want a map of Russia or any other country that spans a large area, likewise.

I love that projection and that Google Maps moved to it as default. But it shouldn't be the only choice.

alihcsumer commented 3 years ago

Another work around is using openlayers raster reprojection capabilities. In the case of a mercator view and a non mercator layer, non mercator tiles are requested and by affinity transformation , a tile image in mercator projection is created. You can get a single tile image by <x,y,z> in OL and set the GL texture in Mapbox. But it is way too hacky and dirty ! Working example https://jsfiddle.net/vw3oes9h/

johnlaur commented 3 years ago

+1 for an extremely desired feature that we have been following for years.

I was really hoping there would be at least a simple hack by now that reprojects mercator source data into a destination projection for display. Considering everything is already highly parallelized and rendered using WebGL, is this a viable option? I'm wondering if this is ever going to actually see the light of day, though. The fake albers projection data published a few months ago and the lack of interest by Mapbox on this issue's discussion doesn't really give me high confidence that this has a chance.

I also see a lot of argument here that appears to be people unwilling to settle for anything other than perfect end to end support for other projections. Please don't let perfect be the enemy of good. Like many of you following this issue, I'm just trying to show a map of Alaska (or pick your preferred northern/southern location) that doesn't look like junk.

vulkd commented 3 years ago

FWIW Here's some links related to workarounds / hacks for anyone Googling / needing more info:

Note I couldn't get Spilhaus' projection to work using the above method so I assume not all projections work very well with Studio / mapbox-gl-js, or I probably stuffed up somewhere. 3D buildings still seem to work which is great

Will attempt to edit this as new methods / implementations come up

Mike-Honey commented 3 years ago

Realistically, given the recent news, we should abandon any hope of this ever being implemented in mapbox gl js v1, or any community-led fork.

https://joemorrison.medium.com/death-of-an-open-source-business-model-62bc227a7e9b

mourner commented 3 years ago

@johnlaur image

ppeduzzi commented 3 years ago

Hello, I work for International Organization, supporting countries at governmental level, also supporting Multilateral Environmental Agreements. Having Mercator projection where Greenland is the size of Africa is distorting the vision of the world. I understand the technical rational for this and for rapid/smooth navigation (vs reprojection of tiles on the fly), but frankly, this is no longer defendable, in my daily working life for 3 reasons:

  1. When working with developing countries in the South, the use of Mercator is felt like a way to artificially increase the importance of the Northern countries. I'm not asking for Gall-Peters or Waterman Butterfly, but a simple Robinson or Mollweide would be great to have.
  2. When mapping environmental issues, the conservation of area (e.g. for mapping deforestation, forest fires, desiccation of lakes and sea (e.g. Aral sea), urbanisation) is more important than keeping the angles. Again having Mollweide projection would be a great asset.
  3. When dealing with polar issues, such as for mapping loss of Arctic Sea Ice extent, or Antarctic Ozone hole layer recovery, doing this under Mercator is really not appropriate. A polar projection, or a globe, would be great. I hope that MapBox can solve this, I'm sure that with the skills of someone like Vladimir Agofonkin, this is something that can be cracked easily! Thank you for your consideration.
markeberhart commented 3 years ago

@ppeduzzi I could not agree more. If a user is visualizing Mapbox via WebGL as 2.5D or 3D, lat/lon, height (zoom), and the pitch/roll and yaw can be controlled programmatically, and that's awesome because it allows for a certain level of country size & distortion to be minimized. That said, it is not enough for areas in extreme north and south like Greenland. Unless Mapbox were to support a spheroid-based model like Google Maps (as mentioned by @marcelnormann).

There is a desperate need to offer libraries/code to simplify the process of encoding WGS-84 (un-projected data) in any standard projection, while supporting the vector tiles standard and Mapbox style sheets. Echoing @johnlaur It doesn't even have to be any projection, but simply rolling out support over time for commonly-needed projections such as polar arctic/antarctic and a few extreme latitudes.

I've looked at @mourner code closely and it is fantastic, just amazing work and been very helpful in so many ways to so many. If it were possible to create usable vector tile files and have them simply follow a projection other than EPSG:3857, it would vastly increase the adoption of Mapbox as a platform in general.

I should add that some of us (myself included) have been asking for alternate projections since before WebGL was the most common Mapbox plugin (I believe my first comment on it was in 2016) - In the end, it's really about visualizing the Earth correctly. If Mapbox can make that happen for the most critical areas, it's not really that important how they do it, so long as it gets done in one way or another- hopefully open source :)

ppeduzzi commented 3 years ago

@marcelnormann and @AliFlux, indeed having a global ellipsoid could resolve many things, including looking at polar areas. However, in such globe view, half of the world is hidden. Hence this is not appropriate for comparing countries across the world. For many applications we still need a good projection (respecting areas) to provide a synoptic view of the world. However, one does not exclude the other option ! Check: https://earth.nullschool.net/#current/wind/surface/level/orthographic=-350.01,67.46,455 and https://earth.nullschool.net/#current/wind/surface/level/winkel3 Of course, this application is not facing the same challenges as MapBox, (with tiles) but the reprojection on the fly is very fast.

MattBlissett commented 3 years ago

GBIF is also an international organization, and faced similar issues. We liked the performance of MapBox-GL-JS, but couldn't compromise on the projections we require.

Our default maps are still raster tiles (e.g. bottom of GBIF.org, click the globe to change projection), but these are generated from vector tiles produced using a modification of OpenMapTiles. They're shown using OpenLayers, which has decent support for different projections. At the time, performance in OpenLayers for vector tiles (except for Web Mercator) was poor, but there have been efforts to improve that, so it might be acceptable by now.

emb-lautec commented 3 years ago

We are developing software for onshore and offshore construction and was planning on using Mapbox GL JS heavily in the following years but not supporting non-mercator projections is a deal breaker on the long run as there are to many usecases where webmercator is not ideal in the construction industry. This will definetly force us to move away from Mapbox GL JS v2 into other frameworks like Openlayers.

I understand that there is a high level of compelxity involved here as well as other priorities. Could you at least give an indication of whether this is in the pipeline and if so in which year? This would provide us the comfort to keep relying on Mapbox GL JS v2 which is a great framework in any other sense.

Thanks.

mathiash98 commented 3 years ago

I would like to pitch in as well. We develop a mainly offshore solution for vessels where we use the General Arrangement (image of the vessel with all it's rooms) as background and put markers on top using x and y coordinates. This has been done using Leaflet's CRS.Simple. https://leafletjs.com/examples/crs-simple/crs-simple.html

Our newest product aims to combine world map data with local vessel data on the same webpage, so it would be great to be able to use the same mapping tool for both maps.

brunnernikolaj commented 3 years ago

@johnlaur image

Any news on this?

ryanhamley commented 3 years ago

We've begun work on this feature. It's fairly complex so we don't have an exact timeline on when it will become available but it's moving along.

ansis commented 2 years ago

We've merged initial support for non-mercator projections in https://github.com/mapbox/mapbox-gl-js/pull/11124 and it is going to be part of the v2.6.0 release. We've just released the beta, which can be tested with either by pulling in 2.6.0-beta.1 from npm or by using:

Alternate projections work with existing styles and tiles. Vector reprojection is used for vector tiles to keep rendering sharp. The projection is undistorted as you zoom in to make it work at every scale.

Getting started

Enable a non-mercator projection with:

// in the constructor
const map = new Map({
    projection: {name: 'winkelTripel'},
    ...
});

// at runtime
map.setProjection({name: 'winkelTripel'});

// or in the stylesheet
"projection": {"name": "winkelTripel"}

Supported projections are:

Both albers and lambertConformalConic can be configured with center: [lng, lat] and parallels: [lat1, lat2] to make them appropriate for other regions:

// albers for europe
map.setProjection({
    name: 'albers',
    center: [10, 30],
    parallels: [43, 62]
})

More examples will be available with the final release.

Unskewing as you zoom in

Non-mercator projections make sense at low zoom levels. But at high zoom levels, an unchanging projection would introduce more distortion. As you zoom in, we transform the projection so that it is identical to mercator at high zoom levels. The transformation preserves the characteristics that matter for equal area and conformal map projections. Relative projected area is preserved and the map never becomes less conformal.

https://user-images.githubusercontent.com/1421652/138327899-39fcc2b2-c933-48a2-8161-56bd902b4e4a.mp4

Known limitations

Projections are not (yet!) compatible with:

Feedback

If you find a bug or have a request, please open a new issue. If you need a projection that is not included here, please share as much as you can about your use case. We're trying to keep the set of projections as small as possible while covering most use cases.

Thanks for testing!

Globe view is also being developed but is not part of this release (https://github.com/mapbox/mapbox-gl-js/issues/10784).

mike-marcacci commented 2 years ago

This looks amazing! Great work! 🙌

eivsal commented 2 years ago

Great work! Is there any chance of added support for transverse mercator projections? We are specifically looking for support for either ETRS89 or WGS84 over Europe.

mourner commented 2 years ago

@eivsal we're looking into supporting UTM projections in the future, but it might be difficult due to how heavily distorted they get outside of the targeted range. Meanwhile, for Europe, I'd recommend either Lambert conformal conic (recommended by European Environment Agency and INSPIRE for Europe) or Albers equal-area conic. center: [0, 52], parallels: [35, 65] in options for both.

eivsal commented 2 years ago

@mourner Thanks for reply 💯

AliFlux commented 2 years ago

Oh wow! Can't wait to see how terrain looks like in custom projection. ⚡⚡

johnlaur commented 2 years ago

To @ansis @mourner and all who worked on this feature, thank you very much!

Is there any easy possibility to specify that the reprojection "wrap" on a meridian other than the antemeridian? This would be particularly useful to improve maps of Alaska which otherwise suffer from this nearby edge:

{ //EPSG 102006: Alaska Albers Equal Area Conic 
  name: "albers",
  center: [-154, 50],
  parallels: [55, 65],
}

image

mourner commented 2 years ago

@johnlaur not currently, but this is a really good point and something we want to address in the future — opened an issue for it: https://github.com/mapbox/mapbox-gl-js/issues/11180.

@AliFlux terrain is not supported on alternate-projected maps in the initial release, but we're exploring ways to enable this in follow-up releases.

Mike-Honey commented 2 years ago

Is there any hope of this feature making it out into the Power BI Custom Visual integration? If not please tell us now so we can work on alternatives.

JoshData commented 2 years ago

Great work here. I'm using the Albers projection now at https://www.govtrack.us/congress/members/map and https://www.govtrack.us/congress/members/OR/4 and similar pages, and it feels good to be able to use an equal-area projection.

Some feedback that I hope is useful (all with respect to the Albers projection):

It would also be very interesting (and this is just a fun thought) if the reference longitude changed dynamically based on panning, so that the map's center was always the reference center of the projection. The reference latitudes (parallels) could also change while maintaining a fixed separation. This would eliminate the distortion and rotation you get when panning on an actual Albers projection (and it would reduce the number of projection parameters to just one parameter, the separation between the reference latitudes). But I recognize that this might be... a bit difficult.

Thanks again.

benstadin commented 2 years ago

Interesting. But... Does it mean when you zoom in the map will always be projected to Web Mercator? Hm. One reason for using a selective map projection is precision, not just for the looks of it when zoomed out.

Anyways, congrats. This is technically very interesting.

marcelnormann commented 2 years ago

Interesting. But... Does it mean when you zoom in the map will always be projected to Web Mercator? Hm. One reason for using a selective map projection is precision, not just for the looks of it when zoomed out.

I agree. I would prefer the opposite way: Having local projections and when zooming out, slowly migration to Web Mercator. IMHO global projections are for gourmets (unless you are interested in areas close to the poles), while local projections are what most people are interested in or are forced to use.

ynte commented 2 years ago

I was really hoping to be able to use custom local projections / coordinate systems. EPSG:29882 in my case. I'll still have to stay with Leaflet for the foreseeable future then.

GetecHarry commented 2 years ago

Firstly nice work, this is really cool! Unfortunately it doesn't help my use case. As @mathiash98 mentioned, the ability to use a simple CRS like Leaflet JS would be amazing! Whilst i know that Mapbox is built primarily to display a world map, the tool is much more powerful than just that and I've had success using it with custom map tiles generated from drawings for example. The only thing is I've had to run custom co-ordinate conversions because of the mercator projection.

mourner commented 2 years ago

@benstadin @marcelnormann this would defy the purpose of using projections on an interactive map.

All map projections are a way to flatten the globe onto the screen while trying to find a balance between three types of distortion — of relative sizes, distances, or shapes of geographic objects. Mercator is fantastic at higher zoom levels, because it's conformal — preserving shapes, local angles between lines, and local directions (up is north, down is south), making it the best projection for navigation on a city-level. Its biggest shortcoming comes out on low zoom levels — since it severely inflates sizes of objects the closer they are to the poles, when you have a big range of latitudes on one screen, relative sizes are very misleading. For example, Greenland looks the same size as Africa, even though it's actually 14 (!) times smaller.

GL JS projections were designed to minimize distortion across all zoom levels in an interactive context. This means you can choose the best projection for your use case on low zooms, be it a world projection like Natural Earth for thematic mapping, or a conic projection like Albers or Lambert that's configurable for a specific range of longitudes and latitudes (best for minimizing distortion on a specific continent / country level), and then have GL JS gently transition to Mercator on higher zooms so that it's usable for city-level mapping, and shapes of roads and buildings are not diagonally squished in a weird way.

This may be an unusual approach for a GIS professional used to traditional maps, but it's a rare attempt at reimagining projections for the interactive maps era from the ground up, and you might warm up to it if you actually try it in practice.

As for specific projections that are not yet supported — stay tuned, we'll listen to your feedback very closely when deciding how to expand the feature in future releases.

timrobertson100 commented 2 years ago

Congratulations on some really amazing work here folks.

Could you comment if you ever foresee supporting user-supplied tiles in different projections, please? e.g. equivalent of this OpenLayers example.

mourner commented 2 years ago
  • The data type expected for the Albers center property is an array, but a Point could be more in line with the rest of the API.

@JoshData This is because it's a part of the style specification, so it has to be strict JSON.

  • It seems like the Albers center property's latitute actually may not be needed.

Latitude is officially a part of the parameters for the Albers projection (e.g. as described on Wikipedia), so we kept it and used a generic center property for simplicity and consistency with other projections.

Could you comment if you ever foresee supporting user-supplied tiles in different projections, please? e.g. equivalent of this OpenLayers example.

@timrobertson100 This is technically possible to implement in the future, but there are no plans for this in the short-term as far as I know. Our bet was on reprojecting from Mercator since most of our existing services and tooling are built around it, and we wanted to introduce projections in a way that's 100% compatible with existing Mapbox tilesets.

benstadin commented 2 years ago

@mourner I respectfully disagree that projections are not practically relevant for high zoom levels. I'm not false advertising our product at this place, but our proprietary 3D (or 2.5D) vector map rendering engine supports those projections for good reasons and due to customer demands. Thus I'm a bit surprised by the statement that a zoomed out non-mercator map is good (a nice feature indeed and technically interesting), while a zoomed-in non-mercator map has rare practical use. And that approach somehow "reimagines" maps.

We usually use UTM projections for e.g. city, fair ground or shop floor navigation where a mercator map does often not provide acceptable results - even for very small areas (think of shelves inside a shop). It means on a technical side of things some challenges for projection-agnostic indexing and processing for our vector tiles storage.

We also use Mapbox maps for some projects, mostly where we just need an outdoor map. For projects where precise mapping or indoor mapping is required we either use our own technology, or another map framework that supports projections. These maps are not for GIS professionals but for actual end users who otherwise often complain. As another example, telling map app users or customers to print out their campus or building maps in less precise / distorted web mercator to make them match to the distortion of the map in an app when zoomed in is also not an option.

In the end the only truth is in the ball shaped globe ;-).

mourner commented 2 years ago

@benstadin please excuse me for my ignorance on the topic of high-precision indoor maps, but aren't you conflating two concepts here — display projection, and coordinate (e.g. datum) mismatch between datasets? If coordinates of your data are transformed properly for overlaying on a Web Mercator map, I believe the latter can be used well even for highly detailed (mm-precision) maps given high enough max zoom and vector tile extent.

To be able to represent detailed local data without distorting shapes, a projection has to be conformal — meaning having constant local scale in every direction around one point, and preserving relative angles. Web Mercator is slightly non-conformal due to spherical math applied to ellipsoidal (WGS84) datum, and this deviation is well documented — reaching at max ~0.67% distortion for local scale in N/S direction, and ~0.1% distortion for local angles (both at equator). This kind of distortion may be important for GIS analysis, but it's pretty much imperceptible to the human eye when used for display purposes. So I'm really surprised to hear that users complain about Web Mercator distortion of their campus or building maps — perhaps a concrete illustration would be helpful here? What am I missing?

tvogt commented 2 years ago

It works brilliantly, thanks a lot!

One thing I noticed is that the calculation of region bounds seems to not apply correctly, i.e. options.bounds values which work on Mercator projection are too narrow on naturalEarth, for example, cutting off the edges of the region.

stepankuzmin commented 2 years ago

One thing I noticed is that the calculation of region bounds seems to not apply correctly, i.e. options.bounds values which work on Mercator projection are too narrow on naturalEarth, for example, cutting off the edges of the region.

This may be related to #10064

benstadin commented 2 years ago

@mourner No, I do not talk about data mismatches or any other technical aspect at all. These are solved problems.

It's different projections and different maps with different looks for certain use cases. I understand that indoor or venue mapping is not the targeted audience for MapBox. I just wanted to keep the record straight that such maps are not just used to look at them when zoomed out for esoteric reasons, but find actual practical use in application where, to quite the contrary, it's about rather small areas like campus sites or fair grounds.

kreativejuices commented 2 years ago

Is there any plans for enabling the use of maps that are Ordnance survey raster maps with Mapbox, but they're available only with EPSG:27700 projection?

matthias-ccri commented 2 years ago

We also need accurate projections at higher zoom levels. For us, Mapbox GL is not the main mapping library; we just use it to render vector tiles for base layers. We plot the other layers in EPSG:4326 (aka WGS84 / equirectangular) and we need the points to line up with the base layer. Unfortunately since the Mapbox renderer doesn't preserve the equirectangular projection at all zoom levels, we can't use it. Instead we have to use the webmercator projection and add a postprocessing step to "squish" the raster.

exotfboy commented 7 months ago

Hi, I'd like to know how does mapbox support no-mercator projection:

1 The vector tiles are generated with mercator projection, and mapbox-gl-js support other projections by reproject the tile on the fly during client rendering.

2 The vector tile are generated with no-mercator projection, and mapbox-gl-js render them as they are without any reprojectiong.

mourner commented 7 months ago

@exotfboy it's the first; you can read about the way projections are implemented in GL JS in detail in this blog post: https://www.mapbox.com/blog/adaptive-projections

exotfboy commented 7 months ago

@mourner Thank you.

barbaramartina commented 5 months ago

Hi all, do you know if the mobile SDKs are also supporting non-mercator projections for vector tiles? What about raster tiles?