Skip to content

Conversation

@tschaub
Copy link
Member

@tschaub tschaub commented Aug 11, 2019

The goal of this branch is to support a "user projection" – which will most likely be geographic (WGS-84) – that is different from the view projection. The justification is that many people want a Web Mercator view (often without knowing it) and want to use geographic coordinates for doing things like setting the map center, adding data, etc.

To support this, all API methods need be updated to take and return coordinates (extents, geometries, etc.) in the user projection. And we can create "internal" methods that are not part of the API for dealing with the view (rendered) projection. For example, view.setCenter() is the API method that will take a coordinate in the user projection and call view.setCenterInternal() with the coordinate transformed to the view projection.

In implementing this, I think we can tackle one API method at a time, creating an "internal" counterpart and renaming the existing one to something with "external" in it. After fixing everything that breaks, we can rename the "external" one back to the nicer, short name (e.g. initially we will have view.setCenterExternal() and then it will be renamed to view.setCenter() after everything works).

In case the objective isn't clear, here is a simple example that should be supported by this change:

import {useGeographic} from 'ol/proj';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';

useGeographic(); // <-- this makes things work

const map = new Map({
  layers: [
    new TileLayer({
      source: new OSM()
    })
  ],
  target: 'map',
  view: new View({
    center: [-110, 45],
    zoom: 8
  })
});

const info = document.getElementById('info');
map.on('moveend', function() {
  const view = map.getView();
  const center = view.getCenter();
  info.innerText = `lon: ${center[0].toFixed(2)}, lat: ${center[1].toFixed(2)}`;
});

In the example above, the view is constructed with a center in geographic coordinates. And the user can call view.getCenter() at any time to get geographic coordinates (as shown in the moveend listener). So the rendered projection is Web Mercator, but the user can work with coordinates that they are familiar with.

I imagine this will be work in progress for a while. A list of API things that need work:

ol/View

  • new View()
  • view.getCenter()
  • view.setCenter()
  • view.animate()
  • view.adjustCenter()
  • view.fit()
  • view.calculateExtent()
  • view.centerOn()
  • view.adjustRotation()
  • view.getResolutionForExtent()

ol/Map

  • map.getPixelFromCoordinate()
  • map.getCoordinateFromPixel()
  • mapBrowserEvent.coordinate

ol/Overlay

  • overlay.setPosition()

ol/layer

  • layer.getExtent()
  • layer.setExtent()

And lots more.

@tschaub tschaub merged commit 800dbe7 into openlayers:master Sep 23, 2019
@tschaub tschaub deleted the user branch September 23, 2019 09:25
@tschaub
Copy link
Member Author

tschaub commented Sep 23, 2019

We are going to tackle this in chunks. Note that nothing will change for users that do not set a user projection (the API will still work in view projected coordinates). In the upcoming 6.0 release, we will likely not mark the useGeographic and related functions as part of the API – but adventurous users who find it can take advantage of it as an experimental feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants