diff --git a/src/map.js b/src/map.js index 7a189c5c33..6a932dfb2e 100644 --- a/src/map.js +++ b/src/map.js @@ -1440,6 +1440,27 @@ var map = function (arg) { return m_this; }; + /** + * Get the corners of the map. Since the map can be rotated, this is + * necessarily not the same as the overall bounds, which is the orthogonal + * bounding box. + * + * @param {string|geo.transform|null} [gcs] `undefined` to use the interface + * gcs, `null` to use the map gcs, or any other transform. If setting the + * bounds, they are converted from this gcs to the map projection. The + * returned bounds are converted from the map projection to this gcs. + * @returns {geo.geoPosition[]} The corners of the map in the order + * upper-left, upper-right, lower-right, lower-left. + */ + this.corners = function (gcs) { + return [ + m_this.displayToGcs({x: 0, y: 0}, gcs), + m_this.displayToGcs({x: m_width, y: 0}, gcs), + m_this.displayToGcs({x: m_width, y: m_height}, gcs), + m_this.displayToGcs({x: 0, y: m_height}, gcs) + ]; + }; + /** * Get the center zoom level necessary to display the given bounds. * diff --git a/src/markerFeature.js b/src/markerFeature.js index 8f943ab010..e87a0e48f2 100644 --- a/src/markerFeature.js +++ b/src/markerFeature.js @@ -228,7 +228,7 @@ var markerFeature = function (arg) { // Find markers inside the bounding box idx = m_rangeTree.range(min.x, min.y, max.x, max.y); - idx.sort((a, b) => a - b); + idx = Uint32Array.from(idx).sort(); // Filter by circular region idx.forEach(function (i) { var d = data[i], @@ -353,16 +353,20 @@ var markerFeature = function (arg) { }; // Find markers inside the bounding box. Only these could be in the polygon idx = m_rangeTree.range(min.x, min.y, max.x, max.y); - // sort by index - idx.sort((a, b) => a - b); + /* sort by index. This had been + * idx.sort((a, b) => a - b); + * but this requires continual casting from int to str and back, so using + * a Uint32Array is faster, though potentially limits the maximum number of + * markers. */ + idx = Uint32Array.from(idx).sort(); // filter markers within the polygon idx.forEach(function (i) { var d = data[i]; let p = m_this.position()(d, i); - let rad = radius(data[i], i), - swz = scaleWithZoom(data[i], i); - const so = strokeOffset(data[i], i), - s = swz ? strokeWidth(data[i], i) : 0; + let rad = radius(d, i), + swz = scaleWithZoom(d, i); + const so = strokeOffset(d, i), + s = swz ? strokeWidth(d, i) : 0; let ris = radiusIncludesStroke(d, i); ris = ris === undefined ? true : ris; const rwos = ris ? rad + s * (so - 1) / 2 : rad; // radius without stroke diff --git a/src/pointFeature.js b/src/pointFeature.js index 75cf2f46f6..45f5f4c092 100644 --- a/src/pointFeature.js +++ b/src/pointFeature.js @@ -329,7 +329,7 @@ var pointFeature = function (arg) { // Find points inside the bounding box idx = m_rangeTree.range(min.x, min.y, max.x, max.y); - idx.sort((a, b) => a - b); + idx = Uint32Array.from(idx).sort(); // Filter by circular region idx.forEach(function (i) { var d = data[i], @@ -434,7 +434,7 @@ var pointFeature = function (arg) { // Find points inside the bounding box. Only these could be in the polygon idx = m_rangeTree.range(min.x, min.y, max.x, max.y); // sort by index - idx.sort((a, b) => a - b); + idx = Uint32Array.from(idx).sort(); // filter points within the polygon idx.forEach(function (i) { var d = data[i], diff --git a/tests/cases/map.js b/tests/cases/map.js index bb0f5297d1..c8a59453ce 100644 --- a/tests/cases/map.js +++ b/tests/cases/map.js @@ -266,6 +266,8 @@ describe('geo.core.map', function () { bottom: -128 * units, width: 256 * units, height: 256 * units})).toBe(true); + expect(closeToEqual(m.corners()[0], {x: -180, y: 85.05})); + expect(closeToEqual(m.corners(null)[0], {x: -128 * units, y: 128 * units})); m.ingcs('EPSG:3857'); expect(m.ingcs()).toBe('EPSG:3857'); expect(closeToEqual(m.bounds(), {