Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add ol.View2D#setCenterLatLng #1860

Closed
wants to merge 4 commits into from

7 participants

@elemoine
Owner

This PR adds a setCenterLatLng and a centerLatLng option to ol.View2D as discussed in #457.

@ahocevar
Owner

+1 from me. If others also like this, and it gets merged eventually, I'll volunteer to update the other examples in a separate pull request.

@pagameba
Collaborator

+1 this simplifies a very common use case.

@elemoine
Owner

I just added a commit that adds a getCenterLatLng function.

@elemoine
Owner

Thanks for the feedback. Other opinions? Note that I don't mind throwing this away.

@twpayne

This one gets my spidey senses tingling. Although it covers a common beginner use case, I fear that it merely defers the problem. As soon as the user tries to position a popup on Washington DC at [38.5, -77.0], he will be be surprised when his overlay appears in Atlantic Ocean off the west coast of Africa. When the users handles a click event on Tokyo he will be surprised that event.coordinate contains [15440013.373027043, 4397372.7444622405] nothing like the [36.7, 138.7] he expects.

@marcjansen
Collaborator

A valid concern, @twpayne. I totally agree. Yet I want stuff to be as easy accomplishable as possible. Could we somehow have a coordinate interceptor with some sensible defaults? Just thinking out loud here.

@tschaub
Owner

Redundant/repeated defaults are also a recipe for trouble.

I'm mixed on this. I agree it adds convenience that will be appreciated. But it also suggests we add calculateLatLngExtent, fitLatLngExtent, and other similar.

@twpayne

Well said @tschaub.

One option is add LatLng versions of principal functions, and double the size and complexity of the ol3 API.

Another option is that, instead of giving a man a fish, we teach him how to fish.

@twpayne

@marcjansen, #463 was an attempt to add a coordinate interceptor with sensible defaults.

@pagameba
Collaborator

Good points against. On the other hand, not providing convenient APIs increases the complexity and size of application code that uses ol3.

@colllin

What about adding an optional second parameter to setCenter to specify the source projection?

map.getView().setCenter([38.5, -77.0], 'EPSG:4326')

Could make sense elsewhere, too:

map.getView().getCenter('EPSG:4326')
@twpayne

center is an ol.Object-style observable property, which means we cannot add extra arguments to the getter and setter.

@colllin

Right, but it's wrapped in a setter function that could perform the necessary transformations?

@twpayne

The setter functions are an integral part of the ol.Object behaviour. See src/ol/object.js.

@colllin

I'm sorry, maybe I'm lost... I'm talking about adding a second (optional) parameter to ol.View2D.prototype.setCenter. Is that what you're talking about?

ol.View2D.prototype.setCenter = function(center) {
    this.set(ol.View2DProperty.CENTER, center);
};

could become (hastily written):

ol.View2D.prototype.setCenter = function(center, opt_projection) {
    var newCenter = center;
    if (opt_projection) {
        newCenter = ol.proj.transform(newCenter, opt_projection, this.getProjection());
    }
    this.set(ol.View2DProperty.CENTER, newCenter);
};
@twpayne

How would this work under property binding? Consider:

var view1 = new ol.View2D({
  projection: 'EPSG:1234',
  center: [56, 78]
});
var view2 = new ol.View2D();
view2.bindTo('center', view1);
view2.getCenter('EPSG:9876');

getCenter would somehow have to find out that the stored center values ([56, 78]) were in the EPSG:1234 projection and transform them to EPSG:9876. How could getCenter do this?

@tschaub
Owner

To be fair, it is only sensible to bind center between two views if they also have the same projection.

@colllin

@twpayne I hadn't come across property binding yet in my port from OL2 to OL3, but that looks very nice.

It's just an idea.

Maybe the reason it feels a little wrong to do all of your own transformations is that you already told the map what projection it's in. But before you give it some coordinates, you need to ask the map what projection it's in and transform your coordinates accordingly. If you give a map an [x, y] and a projection, it should be able to do the rest, no?

Then again, I'm so naïve when it comes to mapping that I don't even know if what I'm suggesting is logical.

@elemoine
Owner

I'm closing this for now, as discussed during some previous hangout meeting.

@elemoine elemoine closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
28 examples/animation.js
@@ -3,20 +3,20 @@ goog.require('ol.View2D');
goog.require('ol.animation');
goog.require('ol.easing');
goog.require('ol.layer.Tile');
-goog.require('ol.proj');
goog.require('ol.source.OSM');
-var london = ol.proj.transform([-0.12755, 51.507222], 'EPSG:4326', 'EPSG:3857');
-var moscow = ol.proj.transform([37.6178, 55.7517], 'EPSG:4326', 'EPSG:3857');
-var istanbul = ol.proj.transform([28.9744, 41.0128], 'EPSG:4326', 'EPSG:3857');
-var rome = ol.proj.transform([12.5, 41.9], 'EPSG:4326', 'EPSG:3857');
-var bern = ol.proj.transform([7.4458, 46.95], 'EPSG:4326', 'EPSG:3857');
-var madrid = ol.proj.transform([-3.683333, 40.4], 'EPSG:4326', 'EPSG:3857');
+// LatLng coordinates
+var london = [51.507222, -0.12755];
+var moscow = [55.7517, 37.6178];
+var istanbul = [41.0128, 28.9744];
+var rome = [41.9, 12.5];
+var bern = [46.95, 7.4458];
+var madrid = [40.4, -3.683333];
var view = new ol.View2D({
// the view's initial state
- center: istanbul,
+ centerLatLng: istanbul,
zoom: 6
});
@@ -57,7 +57,7 @@ panToLondon.addEventListener('click', function() {
source: /** @type {ol.Coordinate} */ (view.getCenter())
});
map.beforeRender(pan);
- view.setCenter(london);
+ view.setCenterLatLng(london);
}, false);
var elasticToMoscow = document.getElementById('elastic-to-moscow');
@@ -68,7 +68,7 @@ elasticToMoscow.addEventListener('click', function() {
source: /** @type {ol.Coordinate} */ (view.getCenter())
});
map.beforeRender(pan);
- view.setCenter(moscow);
+ view.setCenterLatLng(moscow);
}, false);
var bounceToIstanbul = document.getElementById('bounce-to-istanbul');
@@ -79,7 +79,7 @@ bounceToIstanbul.addEventListener('click', function() {
source: /** @type {ol.Coordinate} */ (view.getCenter())
});
map.beforeRender(pan);
- view.setCenter(istanbul);
+ view.setCenterLatLng(istanbul);
}, false);
var spinToRome = document.getElementById('spin-to-rome');
@@ -97,7 +97,7 @@ spinToRome.addEventListener('click', function() {
start: start
});
map.beforeRender(pan, rotate);
- view.setCenter(rome);
+ view.setCenterLatLng(rome);
}, false);
var flyToBern = document.getElementById('fly-to-bern');
@@ -115,7 +115,7 @@ flyToBern.addEventListener('click', function() {
start: start
});
map.beforeRender(pan, bounce);
- view.setCenter(bern);
+ view.setCenterLatLng(bern);
}, false);
var spiralToMadrid = document.getElementById('spiral-to-madrid');
@@ -138,5 +138,5 @@ spiralToMadrid.addEventListener('click', function() {
start: start
});
map.beforeRender(pan, bounce, rotate);
- view.setCenter(madrid);
+ view.setCenterLatLng(madrid);
}, false);
View
2  src/objectliterals.jsdoc
@@ -115,6 +115,8 @@
* The coordinate system for the center is specified with the `projection`
* option. Default is `undefined`, and layer sources will not be fetched if
* this is not set.
+ * @property {ol.LatLng|undefined} centerLatLng The initial center for the
+ * view, defined as lat/lon (EPSG:4326) coordinates.
* @property {boolean|number|undefined} constrainRotation Rotation constraint.
* `false` means no constraint. `true` means no constraint, but snap to
* zero near zero. A number constraints the rotation to that number of
View
9 src/ol/latlng.js
@@ -0,0 +1,9 @@
+goog.provide('ol.LatLng');
+
+
+/**
+ * An array of numbers representing a latitude and a longitude.
+ * @typedef {Array.<number>}
+ * @todo stability experimental
+ */
+ol.LatLng;
View
2  src/ol/view2d.exports
@@ -5,6 +5,8 @@
@exportProperty ol.View2D.prototype.fitExtent
@exportProperty ol.View2D.prototype.fitGeometry
@exportProperty ol.View2D.prototype.centerOn
+@exportProperty ol.View2D.prototype.getCenterLatLng
@exportProperty ol.View2D.prototype.getView2D
@exportProperty ol.View2D.prototype.getZoom
+@exportProperty ol.View2D.prototype.setCenterLatLng
@exportProperty ol.View2D.prototype.setZoom
View
43 src/ol/view2d.js
@@ -8,6 +8,7 @@ goog.require('ol.CenterConstraint');
goog.require('ol.Constraints');
goog.require('ol.IView2D');
goog.require('ol.IView3D');
+goog.require('ol.LatLng');
goog.require('ol.ResolutionConstraint');
goog.require('ol.RotationConstraint');
goog.require('ol.RotationConstraintType');
@@ -100,10 +101,17 @@ ol.View2D = function(opt_options) {
* @type {Object.<string, *>}
*/
var values = {};
- values[ol.View2DProperty.CENTER] = goog.isDef(options.center) ?
- options.center : null;
- values[ol.View2DProperty.PROJECTION] = ol.proj.createProjection(
- options.projection, 'EPSG:3857');
+ var projection = ol.proj.createProjection(options.projection, 'EPSG:3857');
+ if (goog.isDef(options.center)) {
+ values[ol.View2DProperty.CENTER] = options.center;
+ } else if (goog.isDef(options.centerLatLng)) {
+ values[ol.View2DProperty.CENTER] = ol.proj.transform(
+ [options.centerLatLng[1], options.centerLatLng[0]],
+ ol.proj.get('EPSG:4326'), projection);
+ } else {
+ values[ol.View2DProperty.CENTER] = null;
+ }
+ values[ol.View2DProperty.PROJECTION] = projection;
var resolutionConstraintInfo = ol.View2D.createResolutionConstraint_(
options);
@@ -233,6 +241,21 @@ goog.exportProperty(
/**
+ * Get the LatLng of the current center.
+ * @return {ol.LatLng} LatLng.
+ * @todo stability experimental
+ */
+ol.View2D.prototype.getCenterLatLng = function() {
+ var center = this.getCenter();
+ if (!goog.isDef(center)) {
+ return null;
+ }
+ var lnglat = ol.proj.transform(center, this.getProjection(), 'EPSG:4326');
+ return [lnglat[1], lnglat[0]];
+};
+
+
+/**
* Calculate the extent for the given size in pixels, based on the current
* resolution and the current center.
* @param {ol.Size} size Box pixel size.
@@ -549,6 +572,18 @@ goog.exportProperty(
/**
+ * Set the center of the view to a given LatLng.
+ * @param {ol.LatLng} latLng LatLng.
+ * @todo stability experimental
+ */
+ol.View2D.prototype.setCenterLatLng = function(latLng) {
+ var center = ol.proj.transform([latLng[1], latLng[0]],
+ ol.proj.get('EPSG:4326'), this.getProjection());
+ this.setCenter(center);
+};
+
+
+/**
* Set the projection of this view.
* Warning! This code is not yet implemented. Function should not be used.
* @param {ol.proj.Projection|undefined} projection Projection.
Something went wrong with that request. Please try again.