From 39ead1bb49ec833dd03a4475e799063b92796a4b Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sat, 16 Jan 2016 22:29:08 +1300 Subject: [PATCH 01/23] Remove use of goog.array.flatten --- src/ol/array.js | 15 +++++++++++++++ src/ol/format/esrijsonformat.js | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 9bd4df5a7a..10b2bb4bc2 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -127,3 +127,18 @@ ol.array.reverseSubArray = function(arr, begin, end) { --end; } }; + +/** + * @param {Array.<*>} arr Array. + * @return {!Array} Flattened Array. + */ +ol.array.flatten = function(arr) { + var data = arr.reduce(function(flattened, value) { + if (goog.isArray(value)) { + return flattened.concat(ol.array.flatten(value)); + } else { + return flattened.concat(value); + } + }, []); + return data; +}; diff --git a/src/ol/format/esrijsonformat.js b/src/ol/format/esrijsonformat.js index 5831756aa5..7d62c8d00d 100644 --- a/src/ol/format/esrijsonformat.js +++ b/src/ol/format/esrijsonformat.js @@ -1,8 +1,8 @@ goog.provide('ol.format.EsriJSON'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.object'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.extent'); goog.require('ol.format.Feature'); @@ -104,7 +104,7 @@ ol.format.EsriJSON.convertRings_ = function(rings, layout) { var holes = []; var i, ii; for (i = 0, ii = rings.length; i < ii; ++i) { - var flatRing = goog.array.flatten(rings[i]); + var flatRing = ol.array.flatten(rings[i]); // is this ring an outer ring? is it clockwise? var clockwise = ol.geom.flat.orient.linearRingIsClockwise(flatRing, 0, flatRing.length, layout.length); From 0d5168ca0bdfd1ffed3cebe48027571636d73a6d Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sat, 16 Jan 2016 22:44:43 +1300 Subject: [PATCH 02/23] Remove goog.array.insertAt --- src/ol/collection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/collection.js b/src/ol/collection.js index 005947634c..1893739200 100644 --- a/src/ol/collection.js +++ b/src/ol/collection.js @@ -180,7 +180,7 @@ ol.Collection.prototype.getLength = function() { * @api stable */ ol.Collection.prototype.insertAt = function(index, elem) { - goog.array.insertAt(this.array_, elem, index); + this.array_.splice(index, 0, elem); this.updateLength_(); this.dispatchEvent( new ol.CollectionEvent(ol.CollectionEventType.ADD, elem, this)); From 10899344869c8b960a90ee14e8c865166f858540 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sat, 16 Jan 2016 22:52:04 +1300 Subject: [PATCH 03/23] Remove goog.array.removeAt --- src/ol/collection.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ol/collection.js b/src/ol/collection.js index 1893739200..fff2bcd803 100644 --- a/src/ol/collection.js +++ b/src/ol/collection.js @@ -7,7 +7,6 @@ goog.provide('ol.Collection'); goog.provide('ol.CollectionEvent'); goog.provide('ol.CollectionEventType'); -goog.require('goog.array'); goog.require('goog.events.Event'); goog.require('ol.Object'); @@ -238,7 +237,7 @@ ol.Collection.prototype.remove = function(elem) { */ ol.Collection.prototype.removeAt = function(index) { var prev = this.array_[index]; - goog.array.removeAt(this.array_, index); + this.array_.splice(index, 1); this.updateLength_(); this.dispatchEvent( new ol.CollectionEvent(ol.CollectionEventType.REMOVE, prev, this)); From d1b6a177735e778b3aa3c7d459767a959b3ce53c Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 15:45:57 +1300 Subject: [PATCH 04/23] Remove goog.array.extend --- src/ol/array.js | 16 ++++++++++++++++ src/ol/format/gml/gml3format.js | 4 ++-- src/ol/format/gml/gmlbaseformat.js | 4 ++-- src/ol/format/kmlformat.js | 17 ++++++++--------- src/ol/format/osmxmlformat.js | 4 ++-- src/ol/format/wmsgetfeatureinfoformat.js | 3 +-- src/ol/format/xmlfeatureformat.js | 4 ++-- src/ol/geom/linestring.js | 4 ++-- src/ol/geom/multilinestring.js | 8 ++++---- src/ol/geom/multipoint.js | 4 ++-- src/ol/geom/multipolygon.js | 6 +++--- src/ol/geom/polygon.js | 5 +++-- src/ol/interaction/selectinteraction.js | 5 ++--- src/ol/source/vectorsource.js | 4 ++-- src/ol/xml.js | 4 ++-- 15 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 10b2bb4bc2..21a468b43f 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -142,3 +142,19 @@ ol.array.flatten = function(arr) { }, []); return data; }; + + +// TODO: Optimisation by storing length or iterating backwards etc +/** + * @param {Array} arr The array to modify. + * @param {Array|VALUE} data The elements or arrays of elements + * to add to arr1. + * @template VALUE + */ +ol.array.extend = function(arr, data) { + var i; + var extension = goog.isArrayLike(data) ? data : [data]; + for (i = 0; i < extension.length; i++) { + arr[arr.length] = extension[i]; + } +} diff --git a/src/ol/format/gml/gml3format.js b/src/ol/format/gml/gml3format.js index 30242c0a60..7fa417d5fe 100644 --- a/src/ol/format/gml/gml3format.js +++ b/src/ol/format/gml/gml3format.js @@ -1,11 +1,11 @@ goog.provide('ol.format.GML'); goog.provide('ol.format.GML3'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.extent'); goog.require('ol.format.Feature'); @@ -305,7 +305,7 @@ ol.format.GML3.prototype.readSurface_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.extend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( diff --git a/src/ol/format/gml/gmlbaseformat.js b/src/ol/format/gml/gmlbaseformat.js index 6a50ba5ac2..54d3626aa8 100644 --- a/src/ol/format/gml/gmlbaseformat.js +++ b/src/ol/format/gml/gmlbaseformat.js @@ -3,11 +3,11 @@ // envelopes/extents, only geometries! goog.provide('ol.format.GMLBase'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); goog.require('goog.string'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.XMLFeature'); @@ -451,7 +451,7 @@ ol.format.GMLBase.prototype.readPolygon = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.extend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( diff --git a/src/ol/format/kmlformat.js b/src/ol/format/kmlformat.js index d853520b85..3cec0193f0 100644 --- a/src/ol/format/kmlformat.js +++ b/src/ol/format/kmlformat.js @@ -7,7 +7,6 @@ goog.provide('ol.format.KML'); goog.require('goog.Uri'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); @@ -1021,7 +1020,7 @@ ol.format.KML.readMultiGeometry_ = function(node, objectStack) { 'geometry should be an ol.geom.Point'); goog.asserts.assert(geometry.getLayout() == layout, 'geometry layout should be consistent'); - goog.array.extend(flatCoordinates, geometry.getFlatCoordinates()); + ol.array.extend(flatCoordinates, geometry.getFlatCoordinates()); } var multiPoint = new ol.geom.MultiPoint(null); multiPoint.setFlatCoordinates(layout, flatCoordinates); @@ -1100,7 +1099,7 @@ ol.format.KML.readPolygon_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.extend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( @@ -1955,7 +1954,7 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node, opt_options) { for (n = node.firstElementChild; n; n = n.nextElementSibling) { var fs = this.readFeaturesFromNode(n, opt_options); if (fs) { - goog.array.extend(features, fs); + ol.array.extend(features, fs); } } return features; @@ -2044,14 +2043,14 @@ ol.format.KML.prototype.readNameFromNode = function(node) { ol.format.KML.prototype.readNetworkLinks = function(source) { var networkLinks = []; if (ol.xml.isDocument(source)) { - goog.array.extend(networkLinks, this.readNetworkLinksFromDocument( + ol.array.extend(networkLinks, this.readNetworkLinksFromDocument( /** @type {Document} */ (source))); } else if (ol.xml.isNode(source)) { - goog.array.extend(networkLinks, this.readNetworkLinksFromNode( + ol.array.extend(networkLinks, this.readNetworkLinksFromNode( /** @type {Node} */ (source))); } else if (goog.isString(source)) { var doc = ol.xml.parse(source); - goog.array.extend(networkLinks, this.readNetworkLinksFromDocument(doc)); + ol.array.extend(networkLinks, this.readNetworkLinksFromDocument(doc)); } else { goog.asserts.fail('unknown type for source'); } @@ -2067,7 +2066,7 @@ ol.format.KML.prototype.readNetworkLinksFromDocument = function(doc) { var n, networkLinks = []; for (n = doc.firstChild; n; n = n.nextSibling) { if (n.nodeType == goog.dom.NodeType.ELEMENT) { - goog.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); + ol.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); } } return networkLinks; @@ -2094,7 +2093,7 @@ ol.format.KML.prototype.readNetworkLinksFromNode = function(node) { (localName == 'Document' || localName == 'Folder' || localName == 'kml')) { - goog.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); + ol.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); } } return networkLinks; diff --git a/src/ol/format/osmxmlformat.js b/src/ol/format/osmxmlformat.js index 398ece9a71..54630e5526 100644 --- a/src/ol/format/osmxmlformat.js +++ b/src/ol/format/osmxmlformat.js @@ -1,10 +1,10 @@ // FIXME add typedef for stack state objects goog.provide('ol.format.OSMXML'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.XMLFeature'); @@ -103,7 +103,7 @@ ol.format.OSMXML.readWay_ = function(node, objectStack) { var flatCoordinates = /** @type {Array.} */ ([]); for (var i = 0, ii = values.ndrefs.length; i < ii; i++) { var point = state.nodes[values.ndrefs[i]]; - goog.array.extend(flatCoordinates, point); + ol.array.extend(flatCoordinates, point); } var geometry; if (values.ndrefs[0] == values.ndrefs[values.ndrefs.length - 1]) { diff --git a/src/ol/format/wmsgetfeatureinfoformat.js b/src/ol/format/wmsgetfeatureinfoformat.js index 0157b197fe..a9af65ae14 100644 --- a/src/ol/format/wmsgetfeatureinfoformat.js +++ b/src/ol/format/wmsgetfeatureinfoformat.js @@ -1,6 +1,5 @@ goog.provide('ol.format.WMSGetFeatureInfo'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); @@ -118,7 +117,7 @@ ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = function(node, objectStack var layerFeatures = ol.xml.pushParseAndPop( [], parsersNS, layer, objectStack, this.gmlFormat_); if (layerFeatures) { - goog.array.extend(features, layerFeatures); + ol.array.extend(features, layerFeatures); } } } diff --git a/src/ol/format/xmlfeatureformat.js b/src/ol/format/xmlfeatureformat.js index 76b86baf6b..49e3288258 100644 --- a/src/ol/format/xmlfeatureformat.js +++ b/src/ol/format/xmlfeatureformat.js @@ -1,9 +1,9 @@ goog.provide('ol.format.XMLFeature'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.dom.xml'); +goog.require('ol.array'); goog.require('ol.format.Feature'); goog.require('ol.format.FormatType'); goog.require('ol.proj'); @@ -108,7 +108,7 @@ ol.format.XMLFeature.prototype.readFeaturesFromDocument = function( var n; for (n = doc.firstChild; n; n = n.nextSibling) { if (n.nodeType == goog.dom.NodeType.ELEMENT) { - goog.array.extend(features, this.readFeaturesFromNode(n, opt_options)); + ol.array.extend(features, this.readFeaturesFromNode(n, opt_options)); } } return features; diff --git a/src/ol/geom/linestring.js b/src/ol/geom/linestring.js index 2be2b21b10..4d8722584c 100644 --- a/src/ol/geom/linestring.js +++ b/src/ol/geom/linestring.js @@ -1,8 +1,8 @@ goog.provide('ol.geom.LineString'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -72,7 +72,7 @@ ol.geom.LineString.prototype.appendCoordinate = function(coordinate) { if (!this.flatCoordinates) { this.flatCoordinates = coordinate.slice(); } else { - goog.array.extend(this.flatCoordinates, coordinate); + ol.array.extend(this.flatCoordinates, coordinate); } this.changed(); }; diff --git a/src/ol/geom/multilinestring.js b/src/ol/geom/multilinestring.js index fce9293baf..81b91f22b6 100644 --- a/src/ol/geom/multilinestring.js +++ b/src/ol/geom/multilinestring.js @@ -1,8 +1,8 @@ goog.provide('ol.geom.MultiLineString'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -65,7 +65,7 @@ ol.geom.MultiLineString.prototype.appendLineString = function(lineString) { if (!this.flatCoordinates) { this.flatCoordinates = lineString.getFlatCoordinates().slice(); } else { - goog.array.extend( + ol.array.extend( this.flatCoordinates, lineString.getFlatCoordinates().slice()); } this.ends_.push(this.flatCoordinates.length); @@ -216,7 +216,7 @@ ol.geom.MultiLineString.prototype.getFlatMidpoints = function() { var end = ends[i]; var midpoint = ol.geom.flat.interpolate.lineString( flatCoordinates, offset, end, stride, 0.5); - goog.array.extend(midpoints, midpoint); + ol.array.extend(midpoints, midpoint); offset = end; } return midpoints; @@ -319,7 +319,7 @@ ol.geom.MultiLineString.prototype.setLineStrings = function(lineStrings) { goog.asserts.assert(lineString.getLayout() == layout, 'layout of lineString should match layout'); } - goog.array.extend(flatCoordinates, lineString.getFlatCoordinates()); + ol.array.extend(flatCoordinates, lineString.getFlatCoordinates()); ends.push(flatCoordinates.length); } this.setFlatCoordinates(layout, flatCoordinates, ends); diff --git a/src/ol/geom/multipoint.js b/src/ol/geom/multipoint.js index 5a8d9d1201..b9eaae92a5 100644 --- a/src/ol/geom/multipoint.js +++ b/src/ol/geom/multipoint.js @@ -1,7 +1,7 @@ goog.provide('ol.geom.MultiPoint'); -goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -40,7 +40,7 @@ ol.geom.MultiPoint.prototype.appendPoint = function(point) { if (!this.flatCoordinates) { this.flatCoordinates = point.getFlatCoordinates().slice(); } else { - goog.array.extend(this.flatCoordinates, point.getFlatCoordinates()); + ol.array.extend(this.flatCoordinates, point.getFlatCoordinates()); } this.changed(); }; diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index 0570ebca48..5e943c03f9 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -1,9 +1,9 @@ goog.provide('ol.geom.MultiPolygon'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.object'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -100,7 +100,7 @@ ol.geom.MultiPolygon.prototype.appendPolygon = function(polygon) { this.endss_.push(); } else { var offset = this.flatCoordinates.length; - goog.array.extend(this.flatCoordinates, polygon.getFlatCoordinates()); + ol.array.extend(this.flatCoordinates, polygon.getFlatCoordinates()); ends = polygon.getEnds().slice(); var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -424,7 +424,7 @@ ol.geom.MultiPolygon.prototype.setPolygons = function(polygons) { for (j = 0, jj = ends.length; j < jj; ++j) { ends[j] += offset; } - goog.array.extend(flatCoordinates, polygon.getFlatCoordinates()); + ol.array.extend(flatCoordinates, polygon.getFlatCoordinates()); endss.push(ends); } this.setFlatCoordinates(layout, flatCoordinates, endss); diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 24fa72c6e9..a6e0b86bc6 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -4,6 +4,7 @@ goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.math'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -94,7 +95,7 @@ ol.geom.Polygon.prototype.appendLinearRing = function(linearRing) { if (!this.flatCoordinates) { this.flatCoordinates = linearRing.getFlatCoordinates().slice(); } else { - goog.array.extend(this.flatCoordinates, linearRing.getFlatCoordinates()); + ol.array.extend(this.flatCoordinates, linearRing.getFlatCoordinates()); } this.ends_.push(this.flatCoordinates.length); this.changed(); @@ -390,7 +391,7 @@ ol.geom.Polygon.circular = function(sphere, center, radius, opt_n) { var flatCoordinates = []; var i; for (i = 0; i < n; ++i) { - goog.array.extend( + ol.array.extend( flatCoordinates, sphere.offset(center, radius, 2 * Math.PI * i / n)); } flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]); diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 81fa25838f..a11231a5bc 100644 --- a/src/ol/interaction/selectinteraction.js +++ b/src/ol/interaction/selectinteraction.js @@ -3,7 +3,6 @@ goog.provide('ol.interaction.SelectEvent'); goog.provide('ol.interaction.SelectEventType'); goog.provide('ol.interaction.SelectFilterFunction'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.events.Event'); @@ -384,9 +383,9 @@ ol.interaction.Select.prototype.setMap = function(map) { */ ol.interaction.Select.getDefaultStyleFunction = function() { var styles = ol.style.createDefaultEditingStyles(); - goog.array.extend(styles[ol.geom.GeometryType.POLYGON], + ol.array.extend(styles[ol.geom.GeometryType.POLYGON], styles[ol.geom.GeometryType.LINE_STRING]); - goog.array.extend(styles[ol.geom.GeometryType.GEOMETRY_COLLECTION], + ol.array.extend(styles[ol.geom.GeometryType.GEOMETRY_COLLECTION], styles[ol.geom.GeometryType.LINE_STRING]); return function(feature, resolution) { diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js index 8a40546170..38867af174 100644 --- a/src/ol/source/vectorsource.js +++ b/src/ol/source/vectorsource.js @@ -5,7 +5,6 @@ goog.provide('ol.source.Vector'); goog.provide('ol.source.VectorEvent'); goog.provide('ol.source.VectorEventType'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.events.Event'); @@ -19,6 +18,7 @@ goog.require('ol.Feature'); goog.require('ol.FeatureLoader'); goog.require('ol.LoadingStrategy'); goog.require('ol.ObjectEventType'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.featureloader'); goog.require('ol.loadingstrategy'); @@ -552,7 +552,7 @@ ol.source.Vector.prototype.getFeatures = function() { } else if (this.featuresRtree_) { features = this.featuresRtree_.getAll(); if (!goog.object.isEmpty(this.nullGeometryFeatures_)) { - goog.array.extend( + ol.array.extend( features, goog.object.getValues(this.nullGeometryFeatures_)); } } diff --git a/src/ol/xml.js b/src/ol/xml.js index 3a681947e3..780a9be248 100644 --- a/src/ol/xml.js +++ b/src/ol/xml.js @@ -1,11 +1,11 @@ goog.provide('ol.xml'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.dom.xml'); goog.require('goog.object'); goog.require('goog.userAgent'); +goog.require('ol.array'); /** @@ -370,7 +370,7 @@ ol.xml.makeArrayExtender = function(valueReader, opt_this) { (objectStack[objectStack.length - 1]); goog.asserts.assert(goog.isArray(array), 'objectStack is supposed to be an array of arrays'); - goog.array.extend(array, value); + ol.array.extend(array, value); } }); }; From d743ada8fd17438c89c29a954e70e01d49df6311 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 16:35:26 +1300 Subject: [PATCH 05/23] Remove goog.array.remove --- src/ol/array.js | 15 +++++++++++++++ src/ol/map.js | 4 ++-- src/ol/pointer/touchsource.js | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 21a468b43f..7e4c4107ee 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -158,3 +158,18 @@ ol.array.extend = function(arr, data) { arr[arr.length] = extension[i]; } } + + +/** + * @param {Array} arr The array to modify. + * @param {VALUE} obj The element to remove. + * @template VALUE + * @return {boolean} If the element was removed. + */ +ol.array.remove = function(arr, obj) { + var i = arr.indexOf(obj); + if (i > -1) { + arr.splice(i, 1); + } + return i > -1; +} diff --git a/src/ol/map.js b/src/ol/map.js index 2e9faa1794..700ec6754e 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -5,7 +5,6 @@ goog.provide('ol.Map'); goog.provide('ol.MapProperty'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.async.AnimationDelay'); goog.require('goog.async.nextTick'); @@ -45,6 +44,7 @@ goog.require('ol.Size'); goog.require('ol.TileQueue'); goog.require('ol.View'); goog.require('ol.ViewHint'); +goog.require('ol.array'); goog.require('ol.control'); goog.require('ol.extent'); goog.require('ol.has'); @@ -574,7 +574,7 @@ ol.Map.prototype.beforeRender = function(var_args) { * @return {boolean} Whether the preRenderFunction has been found and removed. */ ol.Map.prototype.removePreRenderFunction = function(preRenderFunction) { - return goog.array.remove(this.preRenderFunctions_, preRenderFunction); + return ol.array.remove(this.preRenderFunctions_, preRenderFunction); }; diff --git a/src/ol/pointer/touchsource.js b/src/ol/pointer/touchsource.js index 820cb15eb4..eb760009e7 100644 --- a/src/ol/pointer/touchsource.js +++ b/src/ol/pointer/touchsource.js @@ -30,11 +30,11 @@ goog.provide('ol.pointer.TouchSource'); -goog.require('goog.array'); goog.require('goog.object'); goog.require('ol'); goog.require('ol.pointer.EventSource'); goog.require('ol.pointer.MouseSource'); +goog.require('ol.array'); /** @@ -443,7 +443,7 @@ ol.pointer.TouchSource.prototype.dedupSynthMouse_ = function(inEvent) { goog.global.setTimeout(function() { // remove touch after timeout - goog.array.remove(lts, lt); + ol.array.remove(lts, lt); }, ol.pointer.TouchSource.DEDUP_TIMEOUT); } }; From 640c59d9af3018483a7fb38a54c01302726369ba Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 17:07:13 +1300 Subject: [PATCH 06/23] Remove goog.array.find --- src/ol/array.js | 25 +++++++++++++++++++++++++ src/ol/source/wmtssource.js | 8 ++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 7e4c4107ee..c97eaaaee1 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -173,3 +173,28 @@ ol.array.remove = function(arr, obj) { } return i > -1; } + + +/** + * @param {Array} arr The array to modify. + * @param {?function(this:THISVAL, VALUE, number, ?) : boolean} func The function to compare. + * @param {THISVAL=} thisArg Optional this argument for the function. + * @template VALUE,THISVAL + * @return {VALUE} If the element was removed. + */ +ol.array.find = function(arr, func, thisArg) { + if (typeof func !== 'function') { + throw new TypeError('func must be a function'); + } + var list = Object(arr); + var length = list.length >>> 0; + var value; + + for (var i = 0; i < length; i++) { + value = list[i]; + if (func.call(thisArg, value, i, list)) { + return value; + } + } + return null; +} diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js index 77c322a4d7..22b591aa40 100644 --- a/src/ol/source/wmtssource.js +++ b/src/ol/source/wmtssource.js @@ -327,7 +327,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { 'config "layer" must not be null'); var layers = wmtsCap['Contents']['Layer']; - var l = goog.array.find(layers, function(elt, index, array) { + var l = ol.array.find(layers, function(elt, index, array) { return elt['Identifier'] == config['layer']; }); goog.asserts.assert(l, 'found a matching layer in Contents/Layer'); @@ -340,7 +340,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { if ('projection' in config) { idx = goog.array.findIndex(l['TileMatrixSetLink'], function(elt, index, array) { - var tileMatrixSet = goog.array.find(tileMatrixSets, function(el) { + var tileMatrixSet = ol.array.find(tileMatrixSets, function(el) { return el['Identifier'] == elt['TileMatrixSet']; }); return tileMatrixSet['SupportedCRS'].replace( @@ -397,7 +397,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { } var matrixSets = wmtsCap['Contents']['TileMatrixSet']; - var matrixSetObj = goog.array.find(matrixSets, function(elt, index, array) { + var matrixSetObj = ol.array.find(matrixSets, function(elt, index, array) { return elt['Identifier'] == matrixSet; }); goog.asserts.assert(matrixSetObj, @@ -457,7 +457,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { var gets = wmtsCap['OperationsMetadata']['GetTile']['DCP']['HTTP']['Get']; for (var i = 0, ii = gets.length; i < ii; ++i) { - var constraint = goog.array.find(gets[i]['Constraint'], + var constraint = ol.array.find(gets[i]['Constraint'], function(elt, index, array) { return elt['name'] == 'GetEncoding'; }); From d820b544433fbdf27588ef3150b7baff105f84a4 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 18:20:54 +1300 Subject: [PATCH 07/23] Remove goog.array.equals and goog.array.stableSort --- src/ol/array.js | 47 +++++++++++++++++-- src/ol/interaction/modifyinteraction.js | 4 +- src/ol/render/canvas/canvasimmediate.js | 3 +- src/ol/render/canvas/canvasreplay.js | 3 +- src/ol/renderer/canvas/canvaslayerrenderer.js | 4 +- src/ol/renderer/canvas/canvasmaprenderer.js | 4 +- src/ol/renderer/dom/dommaprenderer.js | 4 +- src/ol/renderer/webgl/webglmaprenderer.js | 4 +- 8 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index c97eaaaee1..5a59474fda 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -178,11 +178,11 @@ ol.array.remove = function(arr, obj) { /** * @param {Array} arr The array to modify. * @param {?function(this:THISVAL, VALUE, number, ?) : boolean} func The function to compare. - * @param {THISVAL=} thisArg Optional this argument for the function. + * @param {THISVAL=} opt_thisArg Optional this argument for the function. * @template VALUE,THISVAL * @return {VALUE} If the element was removed. */ -ol.array.find = function(arr, func, thisArg) { +ol.array.find = function(arr, func, opt_thisArg) { if (typeof func !== 'function') { throw new TypeError('func must be a function'); } @@ -192,9 +192,50 @@ ol.array.find = function(arr, func, thisArg) { for (var i = 0; i < length; i++) { value = list[i]; - if (func.call(thisArg, value, i, list)) { + if (func.call(opt_thisArg, value, i, list)) { return value; } } return null; } + + +/** +* @param {goog.array.ArrayLike} arr1 The first array to compare. +* @param {goog.array.ArrayLike} arr2 The second array to compare. +* @param {Function=} opt_equalsFn Optional comparison function. +* @return {boolean} Whether the two arrays are equal. + */ +ol.array.equals = function(arr1, arr2, opt_equalsFn) { + if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length !== arr2.length) { + return false; + } + var length = arr1.length; + var equalsFn = opt_equalsFn !== undefined ? opt_equalsFn : function(a, b) { + return a === b; + }; + for (var i = 0; i < length; i++) { + if (!equalsFn(arr1[i], arr2[i])) { + return false; + } + } + return true; +} + +ol.array.stableSort = function(arr, compareFnc) { + var length = arr.length; + var tmp = Array(arr.length); + var i; + for (i = 0; i < length; i++) { + tmp[i] = {index: i, value: arr[i]}; + } + var compare = compareFnc || function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; + }; + tmp.sort(function(a, b) { + return compare(a.value, b.value) || a.index - b.index; + }); + for (i = 0; i < arr.length; i++) { + arr[i] = tmp[i].value; + } +} diff --git a/src/ol/interaction/modifyinteraction.js b/src/ol/interaction/modifyinteraction.js index e840dedcea..ea108929a2 100644 --- a/src/ol/interaction/modifyinteraction.js +++ b/src/ol/interaction/modifyinteraction.js @@ -1,7 +1,6 @@ goog.provide('ol.interaction.Modify'); goog.provide('ol.interaction.ModifyEvent'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.events.Event'); @@ -14,6 +13,7 @@ goog.require('ol.Feature'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.MapBrowserPointerEvent'); goog.require('ol.ViewHint'); +goog.require('ol.array'); goog.require('ol.coordinate'); goog.require('ol.events.condition'); goog.require('ol.extent'); @@ -999,7 +999,7 @@ ol.interaction.Modify.prototype.updateSegmentIndices_ = function( this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) { if (segmentDataMatch.geometry === geometry && (depth === undefined || segmentDataMatch.depth === undefined || - goog.array.equals( + ol.array.equals( /** @type {null|{length: number}} */ (segmentDataMatch.depth), depth)) && segmentDataMatch.index > index) { diff --git a/src/ol/render/canvas/canvasimmediate.js b/src/ol/render/canvas/canvasimmediate.js index 9003160ae6..cabb1c0129 100644 --- a/src/ol/render/canvas/canvasimmediate.js +++ b/src/ol/render/canvas/canvasimmediate.js @@ -4,7 +4,6 @@ goog.provide('ol.render.canvas.Immediate'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); goog.require('ol.array'); @@ -768,7 +767,7 @@ ol.render.canvas.Immediate.prototype.setContextStrokeState_ = function(strokeSta contextStrokeState.lineCap = context.lineCap = strokeState.lineCap; } if (ol.has.CANVAS_LINE_DASH) { - if (!goog.array.equals( + if (!ol.array.equals( contextStrokeState.lineDash, strokeState.lineDash)) { context.setLineDash(contextStrokeState.lineDash = strokeState.lineDash); } diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index ddfcd46144..9cc8dca3d7 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -8,7 +8,6 @@ goog.provide('ol.render.canvas.Replay'); goog.provide('ol.render.canvas.ReplayGroup'); goog.provide('ol.render.canvas.TextReplay'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.object'); goog.require('goog.vec.Mat4'); @@ -1037,7 +1036,7 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() { goog.asserts.assert(miterLimit !== undefined, 'miterLimit should be defined'); if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || - !goog.array.equals(state.currentLineDash, lineDash) || + !ol.array.equals(state.currentLineDash, lineDash) || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) { diff --git a/src/ol/renderer/canvas/canvaslayerrenderer.js b/src/ol/renderer/canvas/canvaslayerrenderer.js index b556e91fff..a3502a1d10 100644 --- a/src/ol/renderer/canvas/canvaslayerrenderer.js +++ b/src/ol/renderer/canvas/canvaslayerrenderer.js @@ -1,8 +1,8 @@ goog.provide('ol.renderer.canvas.Layer'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); +goog.require('ol.array'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.Layer'); @@ -262,7 +262,7 @@ ol.renderer.canvas.Layer.testCanvasSize = (function() { var y = size[1] - 1; context.putImageData(imageData, x, y); var result = context.getImageData(x, y, 1, 1); - good = goog.array.equals(imageData.data, result.data); + good = ol.array.equals(imageData.data, result.data); } return good; }; diff --git a/src/ol/renderer/canvas/canvasmaprenderer.js b/src/ol/renderer/canvas/canvasmaprenderer.js index 88f2ed55b7..f446e6a7e7 100644 --- a/src/ol/renderer/canvas/canvasmaprenderer.js +++ b/src/ol/renderer/canvas/canvasmaprenderer.js @@ -2,13 +2,13 @@ goog.provide('ol.renderer.canvas.Map'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.style'); goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.RendererType'); +goog.require('ol.array'); goog.require('ol.css'); goog.require('ol.dom'); goog.require('ol.layer.Image'); @@ -171,7 +171,7 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); var layerStatesArray = frameState.layerStatesArray; - goog.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); var viewResolution = frameState.viewState.resolution; var i, ii, layer, layerRenderer, layerState; diff --git a/src/ol/renderer/dom/dommaprenderer.js b/src/ol/renderer/dom/dommaprenderer.js index 1f701ee79c..8d8297d67a 100644 --- a/src/ol/renderer/dom/dommaprenderer.js +++ b/src/ol/renderer/dom/dommaprenderer.js @@ -1,6 +1,5 @@ goog.provide('ol.renderer.dom.Map'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.events'); @@ -10,6 +9,7 @@ goog.require('goog.style'); goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.RendererType'); +goog.require('ol.array'); goog.require('ol.css'); goog.require('ol.dom'); goog.require('ol.layer.Image'); @@ -176,7 +176,7 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); var layerStatesArray = frameState.layerStatesArray; - goog.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); var viewResolution = frameState.viewState.resolution; var i, ii, layer, layerRenderer, layerState; diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index 68df7370da..9ece2811f6 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -2,7 +2,6 @@ goog.provide('ol.renderer.webgl.Map'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.events'); @@ -14,6 +13,7 @@ goog.require('goog.style'); goog.require('goog.webgl'); goog.require('ol'); goog.require('ol.RendererType'); +goog.require('ol.array'); goog.require('ol.css'); goog.require('ol.dom'); goog.require('ol.layer.Image'); @@ -470,7 +470,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { /** @type {Array.} */ var layerStatesToDraw = []; var layerStatesArray = frameState.layerStatesArray; - goog.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); var viewResolution = frameState.viewState.resolution; var i, ii, layerRenderer, layerState; From 9b492f49c7626f666be49c133a1bede0d3069d29 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 18:37:43 +1300 Subject: [PATCH 08/23] Remove goog.array.findIndex --- src/ol/array.js | 25 +++++++++++++++++++++++++ src/ol/source/wmtssource.js | 7 +++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 5a59474fda..682b78cf98 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -239,3 +239,28 @@ ol.array.stableSort = function(arr, compareFnc) { arr[i] = tmp[i].value; } } + + +/** +* @param {goog.array.ArrayLike} arr The first array to compare.. +* @param {Function} func Optional comparison function. +* @param {THISVAL=} opt_thisArg Optional this argument for the function. +* @template THISVAL +* @return {number} Whether the two arrays are equal. + */ +ol.array.findIndex = function(arr, func, opt_thisArg) { + if (typeof func !== 'function') { + throw new TypeError('func must be a function'); + } + var list = Object(arr); + var length = list.length >>> 0; + var value; + + for (var i = 0; i < length; i++) { + value = list[i]; + if (func.call(opt_thisArg, value, i, list)) { + return i; + } + } + return -1; +} diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js index 22b591aa40..8284404296 100644 --- a/src/ol/source/wmtssource.js +++ b/src/ol/source/wmtssource.js @@ -1,7 +1,6 @@ goog.provide('ol.source.WMTS'); goog.provide('ol.source.WMTSRequestEncoding'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.object'); goog.require('goog.uri.utils'); @@ -338,7 +337,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { var idx, matrixSet; if (l['TileMatrixSetLink'].length > 1) { if ('projection' in config) { - idx = goog.array.findIndex(l['TileMatrixSetLink'], + idx = ol.array.findIndex(l['TileMatrixSetLink'], function(elt, index, array) { var tileMatrixSet = ol.array.find(tileMatrixSets, function(el) { return el['Identifier'] == elt['TileMatrixSet']; @@ -348,7 +347,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { ) == config['projection']; }); } else { - idx = goog.array.findIndex(l['TileMatrixSetLink'], + idx = ol.array.findIndex(l['TileMatrixSetLink'], function(elt, index, array) { return elt['TileMatrixSet'] == config['matrixSet']; }); @@ -368,7 +367,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { if ('format' in config) { format = config['format']; } - idx = goog.array.findIndex(l['Style'], function(elt, index, array) { + idx = ol.array.findIndex(l['Style'], function(elt, index, array) { if ('style' in config) { return elt['Title'] == config['style']; } else { From ab793a58b68b2f7c38dcb45eaf60114267e77570 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 18:52:51 +1300 Subject: [PATCH 09/23] Remove goog.array.isSorted --- src/ol/array.js | 13 +++++++++++++ src/ol/source/imagesource.js | 3 +-- src/ol/tilegrid/tilegrid.js | 3 +-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 682b78cf98..129b8484f2 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -264,3 +264,16 @@ ol.array.findIndex = function(arr, func, opt_thisArg) { } return -1; } + +ol.array.isSorted = function(arr, opt_func, opt_strict) { + var compare = opt_func || function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; + }; + return arr.every(function(currentVal, index) { + if (index === 0) { + return true; + } + var res = compare(arr[index - 1], currentVal); + return !(res > 0 || opt_strict && res === 0); + }); +} diff --git a/src/ol/source/imagesource.js b/src/ol/source/imagesource.js index 12e4e6b15f..02cd6bc2fd 100644 --- a/src/ol/source/imagesource.js +++ b/src/ol/source/imagesource.js @@ -1,7 +1,6 @@ goog.provide('ol.source.Image'); goog.provide('ol.source.ImageEvent'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events.Event'); goog.require('ol.Attribution'); @@ -52,7 +51,7 @@ ol.source.Image = function(options) { this.resolutions_ = options.resolutions !== undefined ? options.resolutions : null; goog.asserts.assert(!this.resolutions_ || - goog.array.isSorted(this.resolutions_, + ol.array.isSorted(this.resolutions_, function(a, b) { return b - a; }, true), 'resolutions must be null or sorted in descending order'); diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index 87df9da396..41ebf2d3c2 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -1,6 +1,5 @@ goog.provide('ol.tilegrid.TileGrid'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.object'); goog.require('ol'); @@ -42,7 +41,7 @@ ol.tilegrid.TileGrid = function(options) { * @type {!Array.} */ this.resolutions_ = options.resolutions; - goog.asserts.assert(goog.array.isSorted(this.resolutions_, function(a, b) { + goog.asserts.assert(ol.array.isSorted(this.resolutions_, function(a, b) { return b - a; }, true), 'resolutions must be sorted in descending order'); From 5bd3fb494cd0191da4421dec8281c76701cedaeb Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 19:06:11 +1300 Subject: [PATCH 10/23] Remove goog.array.repeat --- src/ol/geom/polygon.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index a6e0b86bc6..a0be4870f6 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -436,7 +436,11 @@ ol.geom.Polygon.fromCircle = function(circle, opt_sides, opt_angle) { var stride = circle.getStride(); var layout = circle.getLayout(); var polygon = new ol.geom.Polygon(null, layout); - var flatCoordinates = goog.array.repeat(0, stride * (sides + 1)); + var arrayLength = stride * (sides + 1); + var flatCoordinates = new Array(arrayLength); + for (var i = 0; i < arrayLength; i++) { + flatCoordinates[i] = 0; + } var ends = [flatCoordinates.length]; polygon.setFlatCoordinates(layout, flatCoordinates, ends); ol.geom.Polygon.makeRegular( From 9bcf624382e09d23acab3b2d4cd09e1c7546e655 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 19:13:29 +1300 Subject: [PATCH 11/23] Forgot to remove a require --- src/ol/geom/polygon.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index a0be4870f6..741589ac58 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -1,6 +1,5 @@ goog.provide('ol.geom.Polygon'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.math'); goog.require('ol'); From ef0e95847fe721b662785f83f1b1194a77891782 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Sun, 17 Jan 2016 22:25:00 +1300 Subject: [PATCH 12/23] Remove goog.array.binarySearch --- src/ol/array.js | 70 ++++++++++++++++++++++--- src/ol/geom/flat/interpolateflatgeom.js | 4 +- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 129b8484f2..b663c30db2 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -1,8 +1,65 @@ goog.provide('ol.array'); -goog.require('goog.array'); goog.require('goog.asserts'); +function defaultCompare(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +} + +/** + * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1. + * https://github.com/darkskyapp/binary-search + * + * @param {Array<*>} haystack Items to search through. + * @param {*} needle The item to look for. + * @param {Function=} opt_comparator Comparator function + * @param {number=} low Lower bounds. + * @param {number=} high Higher bounds. + * @return {number} The index of the item if found, -1 if not. + */ +ol.array.binarySearch = function(haystack, needle, opt_comparator, low, high) { + var mid, cmp; + var comparator = opt_comparator || defaultCompare; + if (low === undefined) + low = 0; + + else { + low = low | 0; + if (low < 0 || low >= haystack.length) + throw new RangeError('invalid lower bound'); + } + + if (high === undefined) + high = haystack.length - 1; + + else { + high = high | 0; + if (high < low || high >= haystack.length) + throw new RangeError('invalid upper bound'); + } + + while (low <= high) { + /* Note that "(low + high) >>> 1" may overflow, and results in a typecast + * to double (which gives the wrong results). */ + mid = low + (high - low >> 1); + cmp = +comparator(haystack[mid], needle); + + /* Too low. */ + if (cmp < 0.0) + low = mid + 1; + + /* Too high. */ + else if (cmp > 0.0) + high = mid - 1; + + /* Key found. */ + else + return mid; + } + + /* Key not found. */ + return ~low; +} /** * @param {Array.} arr Array. @@ -10,7 +67,7 @@ goog.require('goog.asserts'); * @return {number} Index. */ ol.array.binaryFindNearest = function(arr, target) { - var index = goog.array.binarySearch(arr, target, + var index = ol.array.binarySearch(arr, target, /** * @param {number} a A. * @param {number} b B. @@ -201,8 +258,8 @@ ol.array.find = function(arr, func, opt_thisArg) { /** -* @param {goog.array.ArrayLike} arr1 The first array to compare. -* @param {goog.array.ArrayLike} arr2 The second array to compare. +* @param {Array|NodeList|Arguments|{length: number}} arr1 The first array to compare. +* @param {Array|NodeList|Arguments|{length: number}} arr2 The second array to compare. * @param {Function=} opt_equalsFn Optional comparison function. * @return {boolean} Whether the two arrays are equal. */ @@ -242,10 +299,9 @@ ol.array.stableSort = function(arr, compareFnc) { /** -* @param {goog.array.ArrayLike} arr The first array to compare.. +* @param {Array<*>} arr The first array to compare.. * @param {Function} func Optional comparison function. -* @param {THISVAL=} opt_thisArg Optional this argument for the function. -* @template THISVAL +* @param {*=} opt_thisArg Optional this argument for the function. * @return {number} Whether the two arrays are equal. */ ol.array.findIndex = function(arr, func, opt_thisArg) { diff --git a/src/ol/geom/flat/interpolateflatgeom.js b/src/ol/geom/flat/interpolateflatgeom.js index 896b1028bd..60ce10513d 100644 --- a/src/ol/geom/flat/interpolateflatgeom.js +++ b/src/ol/geom/flat/interpolateflatgeom.js @@ -1,8 +1,8 @@ goog.provide('ol.geom.flat.interpolate'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.math'); +goog.require('ol.array'); /** @@ -46,7 +46,7 @@ ol.geom.flat.interpolate.lineString = function(flatCoordinates, offset, end, str y1 = y2; } var target = fraction * length; - var index = goog.array.binarySearch(cumulativeLengths, target); + var index = ol.array.binarySearch(cumulativeLengths, target); if (index < 0) { var t = (target - cumulativeLengths[-index - 2]) / (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]); From e08a88b76c0e42fa73b6dca70faebc5427000e36 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Tue, 19 Jan 2016 09:08:24 +1300 Subject: [PATCH 13/23] Remove low and high from binarysearch, use numberSafeCompareFunction --- src/ol/array.js | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index b663c30db2..50dd744db4 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -2,9 +2,6 @@ goog.provide('ol.array'); goog.require('goog.asserts'); -function defaultCompare(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -} /** * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1. @@ -12,31 +9,14 @@ function defaultCompare(a, b) { * * @param {Array<*>} haystack Items to search through. * @param {*} needle The item to look for. - * @param {Function=} opt_comparator Comparator function - * @param {number=} low Lower bounds. - * @param {number=} high Higher bounds. + * @param {Function=} opt_comparator Comparator function. * @return {number} The index of the item if found, -1 if not. */ -ol.array.binarySearch = function(haystack, needle, opt_comparator, low, high) { +ol.array.binarySearch = function(haystack, needle, opt_comparator) { var mid, cmp; - var comparator = opt_comparator || defaultCompare; - if (low === undefined) - low = 0; - - else { - low = low | 0; - if (low < 0 || low >= haystack.length) - throw new RangeError('invalid lower bound'); - } - - if (high === undefined) - high = haystack.length - 1; - - else { - high = high | 0; - if (high < low || high >= haystack.length) - throw new RangeError('invalid upper bound'); - } + var comparator = opt_comparator || ol.array.numberSafeCompareFunction; + var low = 0; + var high = haystack.length - 1; while (low <= high) { /* Note that "(low + high) >>> 1" may overflow, and results in a typecast @@ -185,6 +165,7 @@ ol.array.reverseSubArray = function(arr, begin, end) { } }; + /** * @param {Array.<*>} arr Array. * @return {!Array} Flattened Array. From d81af7594cd727d2a1510f4c9599fc92c03a8901 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Wed, 20 Jan 2016 18:57:20 +1300 Subject: [PATCH 14/23] Update JSDocs/functions after review --- src/ol/array.js | 86 +++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 50dd744db4..3459db5194 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -182,17 +182,17 @@ ol.array.flatten = function(arr) { }; -// TODO: Optimisation by storing length or iterating backwards etc /** * @param {Array} arr The array to modify. * @param {Array|VALUE} data The elements or arrays of elements - * to add to arr1. + * to add to arr. * @template VALUE */ ol.array.extend = function(arr, data) { var i; var extension = goog.isArrayLike(data) ? data : [data]; - for (i = 0; i < extension.length; i++) { + var length = extension.length + for (i = 0; i < length; i++) { arr[arr.length] = extension[i]; } } @@ -206,31 +206,27 @@ ol.array.extend = function(arr, data) { */ ol.array.remove = function(arr, obj) { var i = arr.indexOf(obj); - if (i > -1) { + var found = i > -1; + if (found) { arr.splice(i, 1); } - return i > -1; + return found; } /** - * @param {Array} arr The array to modify. - * @param {?function(this:THISVAL, VALUE, number, ?) : boolean} func The function to compare. - * @param {THISVAL=} opt_thisArg Optional this argument for the function. - * @template VALUE,THISVAL - * @return {VALUE} If the element was removed. + * @param {Array} arr The array to search in. + * @param {function(VALUE, number, ?) : boolean} func The function to compare. + * @template VALUE + * @return {VALUE} The element found. */ -ol.array.find = function(arr, func, opt_thisArg) { - if (typeof func !== 'function') { - throw new TypeError('func must be a function'); - } - var list = Object(arr); - var length = list.length >>> 0; +ol.array.find = function(arr, func) { + var length = arr.length >>> 0; var value; for (var i = 0; i < length; i++) { - value = list[i]; - if (func.call(opt_thisArg, value, i, list)) { + value = arr[i]; + if (func(value, i, arr)) { return value; } } @@ -241,15 +237,14 @@ ol.array.find = function(arr, func, opt_thisArg) { /** * @param {Array|NodeList|Arguments|{length: number}} arr1 The first array to compare. * @param {Array|NodeList|Arguments|{length: number}} arr2 The second array to compare. -* @param {Function=} opt_equalsFn Optional comparison function. * @return {boolean} Whether the two arrays are equal. */ -ol.array.equals = function(arr1, arr2, opt_equalsFn) { +ol.array.equals = function(arr1, arr2) { if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length !== arr2.length) { return false; } var length = arr1.length; - var equalsFn = opt_equalsFn !== undefined ? opt_equalsFn : function(a, b) { + var equalsFn = function(a, b) { return a === b; }; for (var i = 0; i < length; i++) { @@ -260,6 +255,11 @@ ol.array.equals = function(arr1, arr2, opt_equalsFn) { return true; } + +/** +* @param {Array<*>} arr The array to sort (modifies original). +* @param {Function} compareFnc Comparison function. + */ ol.array.stableSort = function(arr, compareFnc) { var length = arr.length; var tmp = Array(arr.length); @@ -267,9 +267,7 @@ ol.array.stableSort = function(arr, compareFnc) { for (i = 0; i < length; i++) { tmp[i] = {index: i, value: arr[i]}; } - var compare = compareFnc || function(a, b) { - return a > b ? 1 : a < b ? -1 : 0; - }; + var compare = compareFnc || ol.array.numberSafeCompareFunction; tmp.sort(function(a, b) { return compare(a.value, b.value) || a.index - b.index; }); @@ -280,32 +278,28 @@ ol.array.stableSort = function(arr, compareFnc) { /** -* @param {Array<*>} arr The first array to compare.. -* @param {Function} func Optional comparison function. -* @param {*=} opt_thisArg Optional this argument for the function. -* @return {number} Whether the two arrays are equal. +* @param {Array<*>} arr The array to search in. +* @param {Function} func Comparison function. +* @return {number} Return index. */ -ol.array.findIndex = function(arr, func, opt_thisArg) { - if (typeof func !== 'function') { - throw new TypeError('func must be a function'); - } - var list = Object(arr); - var length = list.length >>> 0; - var value; - - for (var i = 0; i < length; i++) { - value = list[i]; - if (func.call(opt_thisArg, value, i, list)) { - return i; - } - } - return -1; +ol.array.findIndex = function(arr, func) { + var index; + var found = !arr.every(function(el, idx) { + index = idx; + return !func(el, idx, arr); + }); + return found ? index : -1; } + +/** +* @param {Array<*>} arr The array to test. +* @param {Function=} opt_func Comparison function. +* @param {boolean=} opt_strict Strictly sorted (default false). +* @return {boolean} Return index. + */ ol.array.isSorted = function(arr, opt_func, opt_strict) { - var compare = opt_func || function(a, b) { - return a > b ? 1 : a < b ? -1 : 0; - }; + var compare = opt_func || ol.array.numberSafeCompareFunction; return arr.every(function(currentVal, index) { if (index === 0) { return true; From 2fb33ba940cf661c8317c7cad255a964e238aa91 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 20 Jan 2016 10:14:09 +0100 Subject: [PATCH 15/23] Type fixes and simplifications --- src/ol/array.js | 38 ++++++++++--------------- src/ol/interaction/modifyinteraction.js | 4 +-- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 3459db5194..3afb8c0cbd 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -7,7 +7,7 @@ goog.require('goog.asserts'); * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1. * https://github.com/darkskyapp/binary-search * - * @param {Array<*>} haystack Items to search through. + * @param {Array.<*>} haystack Items to search through. * @param {*} needle The item to look for. * @param {Function=} opt_comparator Comparator function. * @return {number} The index of the item if found, -1 if not. @@ -168,7 +168,7 @@ ol.array.reverseSubArray = function(arr, begin, end) { /** * @param {Array.<*>} arr Array. - * @return {!Array} Flattened Array. + * @return {!Array.} Flattened Array. */ ol.array.flatten = function(arr) { var data = arr.reduce(function(flattened, value) { @@ -183,8 +183,8 @@ ol.array.flatten = function(arr) { /** - * @param {Array} arr The array to modify. - * @param {Array|VALUE} data The elements or arrays of elements + * @param {Array.} arr The array to modify. + * @param {Array.|VALUE} data The elements or arrays of elements * to add to arr. * @template VALUE */ @@ -199,7 +199,7 @@ ol.array.extend = function(arr, data) { /** - * @param {Array} arr The array to modify. + * @param {Array.} arr The array to modify. * @param {VALUE} obj The element to remove. * @template VALUE * @return {boolean} If the element was removed. @@ -215,7 +215,7 @@ ol.array.remove = function(arr, obj) { /** - * @param {Array} arr The array to search in. + * @param {Array.} arr The array to search in. * @param {function(VALUE, number, ?) : boolean} func The function to compare. * @template VALUE * @return {VALUE} The element found. @@ -235,20 +235,13 @@ ol.array.find = function(arr, func) { /** -* @param {Array|NodeList|Arguments|{length: number}} arr1 The first array to compare. -* @param {Array|NodeList|Arguments|{length: number}} arr2 The second array to compare. +* @param {Array|Uint8ClampedArray} arr1 The first array to compare. +* @param {Array|Uint8ClampedArray} arr2 The second array to compare. * @return {boolean} Whether the two arrays are equal. */ ol.array.equals = function(arr1, arr2) { - if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length !== arr2.length) { - return false; - } - var length = arr1.length; - var equalsFn = function(a, b) { - return a === b; - }; - for (var i = 0; i < length; i++) { - if (!equalsFn(arr1[i], arr2[i])) { + for (var i = 0, ii = arr1.length; i < ii; i++) { + if (arr1[i] !== arr2[i]) { return false; } } @@ -257,7 +250,7 @@ ol.array.equals = function(arr1, arr2) { /** -* @param {Array<*>} arr The array to sort (modifies original). +* @param {Array.<*>} arr The array to sort (modifies original). * @param {Function} compareFnc Comparison function. */ ol.array.stableSort = function(arr, compareFnc) { @@ -267,9 +260,8 @@ ol.array.stableSort = function(arr, compareFnc) { for (i = 0; i < length; i++) { tmp[i] = {index: i, value: arr[i]}; } - var compare = compareFnc || ol.array.numberSafeCompareFunction; tmp.sort(function(a, b) { - return compare(a.value, b.value) || a.index - b.index; + return compareFnc(a.value, b.value) || a.index - b.index; }); for (i = 0; i < arr.length; i++) { arr[i] = tmp[i].value; @@ -278,7 +270,7 @@ ol.array.stableSort = function(arr, compareFnc) { /** -* @param {Array<*>} arr The array to search in. +* @param {Array.<*>} arr The array to search in. * @param {Function} func Comparison function. * @return {number} Return index. */ @@ -293,7 +285,7 @@ ol.array.findIndex = function(arr, func) { /** -* @param {Array<*>} arr The array to test. +* @param {Array.<*>} arr The array to test. * @param {Function=} opt_func Comparison function. * @param {boolean=} opt_strict Strictly sorted (default false). * @return {boolean} Return index. @@ -305,6 +297,6 @@ ol.array.isSorted = function(arr, opt_func, opt_strict) { return true; } var res = compare(arr[index - 1], currentVal); - return !(res > 0 || opt_strict && res === 0); + return !(res > 0 || opt_strict && res === 0); }); } diff --git a/src/ol/interaction/modifyinteraction.js b/src/ol/interaction/modifyinteraction.js index ea108929a2..5b33daf68d 100644 --- a/src/ol/interaction/modifyinteraction.js +++ b/src/ol/interaction/modifyinteraction.js @@ -999,9 +999,7 @@ ol.interaction.Modify.prototype.updateSegmentIndices_ = function( this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) { if (segmentDataMatch.geometry === geometry && (depth === undefined || segmentDataMatch.depth === undefined || - ol.array.equals( - /** @type {null|{length: number}} */ (segmentDataMatch.depth), - depth)) && + ol.array.equals(segmentDataMatch.depth, depth)) && segmentDataMatch.index > index) { segmentDataMatch.index += delta; } From 4b17721a33ee82118cbc4c5e6ec01b909a054076 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jan 2016 15:38:05 +0100 Subject: [PATCH 16/23] Sort tested methods alphabetically --- test/spec/ol/array.test.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index 035824e045..c232ddc616 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -2,15 +2,6 @@ goog.provide('ol.test.array'); describe('ol.array', function() { - describe('numberSafeCompareFunction', function() { - it('sorts as expected', function() { - var arr = [40, 200, 3000]; - // default sort would yield [200, 3000, 40] - arr.sort(ol.array.numberSafeCompareFunction); - expect(arr).to.eql(arr); - }); - }); - describe('binaryFindNearest', function() { it('returns expected value', function() { var arr = [1000, 500, 100]; @@ -83,6 +74,15 @@ describe('ol.array', function() { }); }); + describe('numberSafeCompareFunction', function() { + it('sorts as expected', function() { + var arr = [40, 200, 3000]; + // default sort would yield [200, 3000, 40] + arr.sort(ol.array.numberSafeCompareFunction); + expect(arr).to.eql(arr); + }); + }); + describe('reverseSubArray', function() { it('returns expected value', function() { var arr; From 434349cb55d02c6557ae2b0cd7796418b0e906ec Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Mon, 25 Jan 2016 09:40:41 +0100 Subject: [PATCH 17/23] Check length of arrays when checking equality --- src/ol/array.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ol/array.js b/src/ol/array.js index 3afb8c0cbd..548685fb31 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -240,7 +240,11 @@ ol.array.find = function(arr, func) { * @return {boolean} Whether the two arrays are equal. */ ol.array.equals = function(arr1, arr2) { - for (var i = 0, ii = arr1.length; i < ii; i++) { + var len1 = arr1.length; + if (len1 !== arr2.length) { + return false; + } + for (var i = 0; i < len1; i++) { if (arr1[i] !== arr2[i]) { return false; } From 31e1fbaf401c5de17980372a881e20ee6bc94839 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Mon, 25 Jan 2016 10:55:36 +0100 Subject: [PATCH 18/23] Add tests for ol.array.binarySearch --- test/spec/ol/array.test.js | 294 +++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index c232ddc616..409b297865 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -2,6 +2,300 @@ goog.provide('ol.test.array'); describe('ol.array', function() { + describe('binarySearch', function() { + + var insertionPoint = function(position) { + return -(position + 1); + }; + var revNumCompare = function(a, b) { + return b - a; + }; + + describe('default comparison on array of String(s)', function() { + var a = [ + '1000', '9', 'AB', 'ABC', 'ABCABC', 'ABD', 'ABDA', 'B', 'B', 'B', + 'C', 'CA', 'CC', 'ZZZ', 'ab', 'abc', 'abcabc', 'abd', 'abda', 'b', + 'c', 'ca', 'cc', 'zzz' + ]; + + it('should find \'1000\' at index 0', function() { + expect(ol.array.binarySearch(a, '1000')).to.be(0); + }); + it('should find \'zzz\' at index ' + (a.length - 1), function() { + expect(ol.array.binarySearch(a, 'zzz')).to.be(a.length - 1); + }); + it('should find \'C\' at index 10', function() { + expect(ol.array.binarySearch(a, 'C')).to.be(10); + }); + it('should find \'B\' at index 7 || 8 || 9', function() { + var pos = ol.array.binarySearch(a, 'B'); + expect(pos == 7 || pos == 8 || pos == 9).to.be.ok(); + }); + it('should not find \'100\'', function() { + var pos = ol.array.binarySearch(a, '100'); + expect(pos < 0).to.be.ok(); + }); + it('should have an insertion point of 0 for \'100\'', function() { + var pos = ol.array.binarySearch(a, '100'); + expect(insertionPoint(pos)).to.be(0); + }); + it('should not find \'zzz0\'', function() { + var pos = ol.array.binarySearch(a, 'zzz0'); + expect(pos < 0).to.be.ok(); + }); + it('should have an insertion point of ' + (a.length) + ' for \'zzz0\'', + function() { + var pos = ol.array.binarySearch(a, 'zzz0'); + expect(insertionPoint(pos)).to.be(a.length); + } + ); + it('should not find \'BA\'', function() { + var pos = ol.array.binarySearch(a, 'zzz0'); + expect(pos < 0).to.be.ok(); + }); + it('should have an insertion point of 10 for \'BA\'', + function() { + var pos = ol.array.binarySearch(a, 'BA'); + expect(insertionPoint(pos)).to.be(10); + } + ); + }); + + describe('0 length array with default comparison', function() { + var b = []; + it('should not find \'a\'', function() { + expect(ol.array.binarySearch(b, 'a') < 0).to.be.ok(); + }); + it('should have an insertion point of 0 for \'a\'', + function() { + var pos = ol.array.binarySearch(b, 'a'); + expect(insertionPoint(pos)).to.be(0); + } + ); + }); + + describe('single element array with default lexiographical comparison', + function() { + var c = ['only item']; + it('should find \'only item\' at index 0', function() { + expect(ol.array.binarySearch(c, 'only item')).to.be(0); + }); + it('should not find \'a\'', function() { + expect(ol.array.binarySearch(c, 'a') < 0).to.be.ok(); + }); + it('should have an insertion point of 0 for \'a\'', + function() { + var pos = ol.array.binarySearch(c, 'a'); + expect(insertionPoint(pos)).to.be(0); + } + ); + it('should not find \'z\'', function() { + expect(ol.array.binarySearch(c, 'z') < 0).to.be.ok(); + }); + it('should have an insertion point of 1 for \'z\'', + function() { + var pos = ol.array.binarySearch(c, 'z'); + expect(insertionPoint(pos)).to.be(1); + } + ); + } + ); + + describe('default comparison on array of Number(s)', function() { + var d = [-897123.9, -321434.58758, -1321.3124, -324, -9, -3, 0, 0, 0, + 0.31255, 5, 142.88888708, 334, 342, 453, 54254]; + it('should find -897123.9 at index 0', function() { + expect(ol.array.binarySearch(d, -897123.9)).to.be(0); + }); + it('should find 54254 at index ' + (d.length - 1), function() { + expect(ol.array.binarySearch(d, 54254)).to.be(d.length - 1); + }); + it('should find -3 at index 5', function() { + expect(ol.array.binarySearch(d, -3)).to.be(5); + }); + it('should find 0 at index 6 || 7 || 8', function() { + var pos = ol.array.binarySearch(d, 0); + expect(pos == 6 || pos == 7 || pos == 8).to.be(true); + }); + it('should not find -900000', function() { + var pos = ol.array.binarySearch(d, -900000); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 0 for -900000', function() { + var pos = ol.array.binarySearch(d, -900000); + expect(insertionPoint(pos)).to.be(0); + }); + // TODO The original tests also use a string here, I cannot see why. + it('should not find \'54255\'', function() { + var pos = ol.array.binarySearch(d, '54255'); + expect(pos < 0).to.be(true); + }); + // TODO The original tests also use a string here, I cannot see why. + it('should have an insertion point of ' + (d.length) + ' for \'54255\'', + function() { + var pos = ol.array.binarySearch(d, '54255'); + expect(insertionPoint(pos)).to.be(d.length); + } + ); + it('should not find 1.1', function() { + var pos = ol.array.binarySearch(d, 1.1); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 10 for 1.1', function() { + var pos = ol.array.binarySearch(d, 1.1); + expect(insertionPoint(pos)).to.be(10); + }); + }); + + describe('custom comparison function, which reverse orders numbers', + function() { + var e = [54254, 453, 342, 334, 142.88888708, 5, 0.31255, 0, 0, 0, -3, + -9, -324, -1321.3124, -321434.58758, -897123.9]; + it('should find 54254 at index 0', function() { + var pos = ol.array.binarySearch(e, 54254, revNumCompare); + expect(pos).to.be(0); + }); + it('should find -897123.9 at index ' + (e.length - 1), function() { + var pos = ol.array.binarySearch(e, -897123.9, revNumCompare); + expect(pos).to.be(e.length - 1); + }); + it('should find -3 at index 10', function() { + var pos = ol.array.binarySearch(e, -3, revNumCompare); + expect(pos).to.be(10); + }); + // TODO this test differs from the original one, which checks 7, 9, 10. + it('should find 0 at index 7 || 8 || 9', function() { + var pos = ol.array.binarySearch(e, 0, revNumCompare); + expect(pos == 7 || pos == 8 || pos == 9).to.be(true); + }); + it('should not find 54254.1', function() { + var pos = ol.array.binarySearch(e, 54254.1, revNumCompare); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 0 for 54254.1', function() { + var pos = ol.array.binarySearch(e, 54254.1, revNumCompare); + expect(insertionPoint(pos)).to.be(0); + }); + it('should not find -897124', function() { + var pos = ol.array.binarySearch(e, -897124, revNumCompare); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of ' + e.length + ' for -897124', + function() { + var pos = ol.array.binarySearch(e, -897124, revNumCompare); + expect(insertionPoint(pos)).to.be(e.length); + } + ); + it('should not find 1.1', function() { + var pos = ol.array.binarySearch(e, 1.1, revNumCompare); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 0 for 1.1', function() { + var pos = ol.array.binarySearch(e, 1.1, revNumCompare); + expect(insertionPoint(pos)).to.be(6); + }); + } + ); + + describe('0 length array with custom comparison function', function() { + var f = []; + it('should not find 0', function() { + var pos = ol.array.binarySearch(f, 0, revNumCompare); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 0 for 0', function() { + var pos = ol.array.binarySearch(f, 0, revNumCompare); + expect(insertionPoint(pos)).to.be(0); + }); + }); + + describe('single element array with custom comparison function', + function() { + var g = [1]; + it('shouldn find 1 at index 0', function() { + var pos = ol.array.binarySearch(g, 1, revNumCompare); + expect(pos).to.be(0); + }); + it('should not find 2', function() { + var pos = ol.array.binarySearch(g, 2, revNumCompare); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 0 for 2', function() { + var pos = ol.array.binarySearch(g, 2, revNumCompare); + expect(insertionPoint(pos)).to.be(0); + }); + it('should not find 0', function() { + var pos = ol.array.binarySearch(g, 0, revNumCompare); + expect(pos < 0).to.be(true); + }); + it('should have an insertion point of 1 for 0', function() { + var pos = ol.array.binarySearch(g, 0, revNumCompare); + expect(insertionPoint(pos)).to.be(1); + }); + } + ); + + describe('finding first index when multiple candidates', function() { + it('should find the index of the first 0', function() { + // TODO here our implementation is different from the goog-one + // we need to ensure this is intended. + expect(ol.array.binarySearch([0, 0, 1], 0)).to.be(0); + }); + it('should find the index of the first 1', function() { + expect(ol.array.binarySearch([0, 1, 1], 1)).to.be(1); + }); + }); + + describe('Don\'t use Array#slice, Function#apply and Function#call', + function() { + var a = [1, 5, 7, 11, 13, 16, 19, 24, 28, 31, 33, 36, 40, 50, 52, 55]; + var calls = { + 'Array#slice': false, + 'Function#apply': false, + 'Function#call': false + }; + var origArraySlice; + var origFunctionApply; + var origFunctionCall; + + it('does not use potentially slow methods (default & custom compare)', + function() { + // Mockup (I failed to use sinon.spy and beforeEach-hooks) + origArraySlice = Array.prototype.slice; + origFunctionApply = Function.prototype.apply; + origFunctionCall = Function.prototype.call; + Array.prototype.slice = function() { + calls['Array#slice'] = true; + }; + Function.prototype.apply = function() { + calls['Function#apply'] = true; + }; + Function.prototype.call = function() { + calls['Function#call'] = true; + }; + + // Now actually call and test the method twice + ol.array.binarySearch(a, 48); + ol.array.binarySearch(a, 13, function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; + }); + + // Restore mocked up methods + Array.prototype.slice = origArraySlice; + Function.prototype.apply = origFunctionApply; + Function.prototype.call = origFunctionCall; + + // Expectations + expect(calls['Array#slice']).to.be(false); + expect(calls['Function#apply']).to.be(false); + expect(calls['Function#call']).to.be(false); + } + ); + } + ); + + }); + describe('binaryFindNearest', function() { it('returns expected value', function() { var arr = [1000, 500, 100]; From 57f4d8cefb52bddbdd30d2cdfa0276d922e00f34 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Mon, 25 Jan 2016 10:57:50 +0100 Subject: [PATCH 19/23] Add tests for ol.array.equals --- test/spec/ol/array.test.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index 409b297865..d9a457565d 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -318,6 +318,42 @@ describe('ol.array', function() { }); }); + describe('equals', function() { + it('returns true for [] == []', function() { + expect(ol.array.equals([], [])).to.be(true); + }); + it('returns true for [1] == [1]', function() { + expect(ol.array.equals([1], [1])).to.be(true); + }); + it('returns true for [\'1\'] == [\'1\']', function() { + expect(ol.array.equals(['1'], ['1'])).to.be(true); + }); + it('returns false for [1] == [\'1\']', function() { + expect(ol.array.equals([1], ['1'])).to.be(false); + }); + it('returns true for [null] == [null]', function() { + expect(ol.array.equals([null], [null])).to.be(true); + }); + it('returns false for [null] == [undefined]', function() { + expect(ol.array.equals([null], [undefined])).to.be(false); + }); + it('returns true for [1, 2] == [1, 2]', function() { + expect(ol.array.equals([1, 2], [1, 2])).to.be(true); + }); + it('returns false for [1, 2] == [2, 1]', function() { + expect(ol.array.equals([1, 2], [2, 1])).to.be(false); + }); + it('returns false for [1, 2] == [1]', function() { + expect(ol.array.equals([1, 2], [1])).to.be(false); + }); + it('returns false for [1] == [1, 2]', function() { + expect(ol.array.equals([1], [1, 2])).to.be(false); + }); + it('returns false for [{}] == [{}]', function() { + expect(ol.array.equals([{}], [{}])).to.be(false); + }); + }); + describe('linearFindNearest', function() { it('returns expected value', function() { var arr = [1000, 500, 100]; From 665fdbdc2b681b6d2c30802b896874dba6ee3e7e Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Mon, 25 Jan 2016 10:58:45 +0100 Subject: [PATCH 20/23] Add tests for ol.array.extend --- test/spec/ol/array.test.js | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index d9a457565d..ae0e70f514 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -353,6 +353,54 @@ describe('ol.array', function() { expect(ol.array.equals([{}], [{}])).to.be(false); }); }); + describe('extend', function() { + it('extends an array in place with an array', function() { + var a = [0, 1]; + ol.array.extend(a, [2, 3]); + expect(a).to.eql([0, 1, 2, 3]); + }); + it('extends an array in place with a number', function() { + var a = [0, 1]; + ol.array.extend(a, 2); + expect(a).to.eql([0, 1, 2]); + }); + it('extends an array in place with an arraylike object', function() { + var a = [0, 1]; + var arrayLikeObject = {0: 2, 1: 3, length: 2}; + ol.array.extend(a, arrayLikeObject); + expect(a).to.eql([0, 1, 2, 3]); + }); + it('extends an array in place with an empty arraylike object', function() { + var a = [0, 1]; + var arrayLikeObject = {length: 0}; + ol.array.extend(a, arrayLikeObject); + expect(a).to.eql([0, 1]); + }); + it('extends an array in place with a big array', function() { + var a = []; + var i = 500000; // original test has 1.000.000, but that was to slow + var bigArray = Array(i); + while (i--) { + bigArray[i] = i; + } + ol.array.extend(a, bigArray); + expect(a).to.eql(bigArray); + }); + it('extends an array in place with arguments', function() { + var f = function() { + return arguments; + }; + var a = [0]; + ol.array.extend(a, f(1, 2, 3)); + expect(a).to.eql([0, 1, 2, 3]); + }); + it('extends an array with a NodeList (from querySelectorAll)', function() { + var a = []; + ol.array.extend(a, document.querySelectorAll('head')); + expect(a.length).to.be(1); + expect(a[0]).to.be(document.head); + }); + }); describe('linearFindNearest', function() { it('returns expected value', function() { From 6586c7f007f345878987e6e47f72aec55be33ba1 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Mon, 25 Jan 2016 10:59:35 +0100 Subject: [PATCH 21/23] Add tests stubs --- test/spec/ol/array.test.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index ae0e70f514..380b10264b 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -402,6 +402,22 @@ describe('ol.array', function() { }); }); + describe('find', function() { + // TODO + }); + + describe('findIndex', function() { + // TODO + }); + + describe('flatten', function() { + // TODO + }); + + describe('isSorted', function() { + // TODO + }); + describe('linearFindNearest', function() { it('returns expected value', function() { var arr = [1000, 500, 100]; @@ -461,6 +477,10 @@ describe('ol.array', function() { }); }); + describe('remove', function() { + // TODO + }); + describe('reverseSubArray', function() { it('returns expected value', function() { var arr; @@ -483,6 +503,11 @@ describe('ol.array', function() { expect(arr).to.eql(expected); }); }); + + describe('stableSort', function() { + // TODO + }); + }); goog.require('ol.array'); From 1771df0109076d28352331b2de0c6cf33b5fac94 Mon Sep 17 00:00:00 2001 From: Nicholas L Date: Tue, 26 Jan 2016 22:03:51 +1300 Subject: [PATCH 22/23] Change binary search to return the lowest position --- src/ol/array.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/ol/array.js b/src/ol/array.js index 548685fb31..6c0e28ab62 100644 --- a/src/ol/array.js +++ b/src/ol/array.js @@ -16,29 +16,26 @@ ol.array.binarySearch = function(haystack, needle, opt_comparator) { var mid, cmp; var comparator = opt_comparator || ol.array.numberSafeCompareFunction; var low = 0; - var high = haystack.length - 1; + var high = haystack.length; + var found = false; - while (low <= high) { + while (low < high) { /* Note that "(low + high) >>> 1" may overflow, and results in a typecast * to double (which gives the wrong results). */ mid = low + (high - low >> 1); cmp = +comparator(haystack[mid], needle); - /* Too low. */ - if (cmp < 0.0) + if (cmp < 0.0) { /* Too low. */ low = mid + 1; - /* Too high. */ - else if (cmp > 0.0) - high = mid - 1; - - /* Key found. */ - else - return mid; + } else { /* Key found or too high */ + high = mid; + found = !cmp; + } } /* Key not found. */ - return ~low; + return found ? low : ~low; } /** From ebc98ec1bbd975151a1dfb89bce88f1aceb1cd9f Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 2 Feb 2016 23:17:18 +0100 Subject: [PATCH 23/23] Address TODOs To make sure that our binarySearch implementation meets the requirements of the library, I added more tests for ol.geom.flat.interpolate.lineString, only to find out that it does not handle line strings with repeated vertices properly, regardless of what binarySearch implementation is used. --- src/ol/geom/flat/interpolateflatgeom.js | 1 + test/spec/ol/array.test.js | 140 +++++++++++++++--- .../ol/geom/flat/interpolateflatgeom.test.js | 22 +++ 3 files changed, 146 insertions(+), 17 deletions(-) diff --git a/src/ol/geom/flat/interpolateflatgeom.js b/src/ol/geom/flat/interpolateflatgeom.js index 60ce10513d..ef76bbcef0 100644 --- a/src/ol/geom/flat/interpolateflatgeom.js +++ b/src/ol/geom/flat/interpolateflatgeom.js @@ -15,6 +15,7 @@ goog.require('ol.array'); * @return {Array.} Destination. */ ol.geom.flat.interpolate.lineString = function(flatCoordinates, offset, end, stride, fraction, opt_dest) { + // FIXME does not work when vertices are repeated // FIXME interpolate extra dimensions goog.asserts.assert(0 <= fraction && fraction <= 1, 'fraction should be in between 0 and 1'); diff --git a/test/spec/ol/array.test.js b/test/spec/ol/array.test.js index 380b10264b..4926ddbe10 100644 --- a/test/spec/ol/array.test.js +++ b/test/spec/ol/array.test.js @@ -125,15 +125,13 @@ describe('ol.array', function() { var pos = ol.array.binarySearch(d, -900000); expect(insertionPoint(pos)).to.be(0); }); - // TODO The original tests also use a string here, I cannot see why. - it('should not find \'54255\'', function() { - var pos = ol.array.binarySearch(d, '54255'); + it('should not find 54255', function() { + var pos = ol.array.binarySearch(d, 54255); expect(pos < 0).to.be(true); }); - // TODO The original tests also use a string here, I cannot see why. - it('should have an insertion point of ' + (d.length) + ' for \'54255\'', + it('should have an insertion point of ' + (d.length) + ' for 54255', function() { - var pos = ol.array.binarySearch(d, '54255'); + var pos = ol.array.binarySearch(d, 54255); expect(insertionPoint(pos)).to.be(d.length); } ); @@ -163,7 +161,6 @@ describe('ol.array', function() { var pos = ol.array.binarySearch(e, -3, revNumCompare); expect(pos).to.be(10); }); - // TODO this test differs from the original one, which checks 7, 9, 10. it('should find 0 at index 7 || 8 || 9', function() { var pos = ol.array.binarySearch(e, 0, revNumCompare); expect(pos == 7 || pos == 8 || pos == 9).to.be(true); @@ -212,7 +209,7 @@ describe('ol.array', function() { describe('single element array with custom comparison function', function() { var g = [1]; - it('shouldn find 1 at index 0', function() { + it('should not find 1 at index 0', function() { var pos = ol.array.binarySearch(g, 1, revNumCompare); expect(pos).to.be(0); }); @@ -237,8 +234,6 @@ describe('ol.array', function() { describe('finding first index when multiple candidates', function() { it('should find the index of the first 0', function() { - // TODO here our implementation is different from the goog-one - // we need to ensure this is intended. expect(ol.array.binarySearch([0, 0, 1], 0)).to.be(0); }); it('should find the index of the first 1', function() { @@ -294,6 +289,19 @@ describe('ol.array', function() { } ); + describe('when items are not found', function() { + var arr = [1, 2, 2, 2, 3, 5, 9]; + + it('should return the index of where the item would go plus one, negated, if the item is not found', function() { + expect(ol.array.binarySearch(arr, 4)).to.equal(-6); + }); + it('should work even on empty arrays', function() { + expect(ol.array.binarySearch([], 42)).to.equal(-1); + }); + it('should work even on arrays of doubles', function() { + expect(ol.array.binarySearch([0.0, 0.1, 0.2, 0.3, 0.4], 0.25)).to.equal(-4); + }); + }); }); describe('binaryFindNearest', function() { @@ -378,7 +386,7 @@ describe('ol.array', function() { }); it('extends an array in place with a big array', function() { var a = []; - var i = 500000; // original test has 1.000.000, but that was to slow + var i = 500000; // original test has 1.000.000, but that was too slow var bigArray = Array(i); while (i--) { bigArray[i] = i; @@ -403,19 +411,93 @@ describe('ol.array', function() { }); describe('find', function() { - // TODO + it('finds numbers in an array', function() { + var a = [0, 1, 2, 3]; + var b = ol.array.find(a, function(val, index, a2) { + expect(a).to.equal(a2); + expect(typeof index).to.be('number'); + return val > 1; + }); + expect(b).to.be(2); + }); + + it('returns null when an item in an array is not found', function() { + var a = [0, 1, 2, 3]; + var b = ol.array.find(a, function(val, index, a2) { + return val > 100; + }); + expect(b).to.be(null); + }); + + it('finds items in an array-like', function() { + var a = 'abCD'; + var b = ol.array.find(a, function(val, index, a2) { + expect(a).to.equal(a2); + expect(typeof index).to.be('number'); + return val >= 'A' && val <= 'Z'; + }); + expect(b).to.be('C'); + }); + + it('returns null when nothing in an array-like is found', function() { + var a = 'abcd'; + var b = ol.array.find(a, function(val, index, a2) { + return val >= 'A' && val <= 'Z'; + }); + expect(b).to.be(null); + }); }); describe('findIndex', function() { - // TODO + it('finds index of numbers in an array', function() { + var a = [0, 1, 2, 3]; + var b = ol.array.findIndex(a, function(val, index, a2) { + expect(a).to.equal(a2); + expect(typeof index).to.be('number'); + return val > 1; + }); + expect(b).to.be(2); + }); + + it('returns -1 when an item in an array is not found', function() { + var a = [0, 1, 2, 3]; + var b = ol.array.findIndex(a, function(val, index, a2) { + return val > 100; + }); + expect(b).to.be(-1); + }); }); describe('flatten', function() { - // TODO + it('flattens different kinds of nested arrays', function() { + expect(ol.array.flatten([1, 2])).to.eql([1, 2]); + expect(ol.array.flatten([1, [2, [3, [4, 5]]]])).to.eql([1, 2, 3, 4, 5]); + expect(ol.array.flatten([[[[1], 2], 3], 4])).to.eql([1, 2, 3, 4]); + expect(ol.array.flatten([[1]])).to.eql([1]); + expect(ol.array.flatten([])).to.eql([]); + }); }); describe('isSorted', function() { - // TODO + it('works with just an array as argument', function() { + expect(ol.array.isSorted([1, 2, 3])).to.be(true); + expect(ol.array.isSorted([1, 2, 2])).to.be(true); + expect(ol.array.isSorted([1, 2, 1])).to.be(false); + }); + + it('works with strict comparison without compare function', function() { + expect(ol.array.isSorted([1, 2, 3], null, true)).to.be(true); + expect(ol.array.isSorted([1, 2, 2], null, true)).to.be(false); + expect(ol.array.isSorted([1, 2, 1], null, true)).to.be(false); + }); + + it('works with a compare function', function() { + function compare(a, b) { + return b - a; + } + expect(ol.array.isSorted([1, 2, 3], compare)).to.be(false); + expect(ol.array.isSorted([3, 2, 2], compare)).to.be(true); + }); }); describe('linearFindNearest', function() { @@ -478,7 +560,13 @@ describe('ol.array', function() { }); describe('remove', function() { - // TODO + it('removes elements from an array', function() { + var a = ['a', 'b', 'c', 'd']; + ol.array.remove(a, 'c'); + expect(a).to.eql(['a', 'b', 'd']); + ol.array.remove(a, 'x'); + expect(a).to.eql(['a', 'b', 'd']); + }); }); describe('reverseSubArray', function() { @@ -505,7 +593,25 @@ describe('ol.array', function() { }); describe('stableSort', function() { - // TODO + var arr, wantedSortedValues; + + beforeEach(function() { + arr = [{key: 3, val: 'a'}, {key: 2, val: 'b'}, {key: 3, val: 'c'}, + {key: 4, val: 'd'}, {key: 3, val: 'e'}]; + wantedSortedValues = ['b', 'a', 'c', 'e', 'd']; + }); + + it('works on an array with custom comparison function', function() { + function comparisonFn(obj1, obj2) { + return obj1.key - obj2.key; + } + ol.array.stableSort(arr, comparisonFn); + var sortedValues = []; + for (var i = 0; i < arr.length; i++) { + sortedValues.push(arr[i].val); + } + expect(wantedSortedValues).to.eql(sortedValues); + }); }); }); diff --git a/test/spec/ol/geom/flat/interpolateflatgeom.test.js b/test/spec/ol/geom/flat/interpolateflatgeom.test.js index bbd5d91cbe..6639b7d99d 100644 --- a/test/spec/ol/geom/flat/interpolateflatgeom.test.js +++ b/test/spec/ol/geom/flat/interpolateflatgeom.test.js @@ -27,6 +27,13 @@ describe('ol.geom.flat.interpolate', function() { expect(point).to.eql([2, 3]); }); + xit('also when vertices are repeated', function() { + var flatCoordinates = [0, 1, 2, 3, 2, 3, 4, 5]; + var point = ol.geom.flat.interpolate.lineString( + flatCoordinates, 0, 6, 2, 0.5); + expect(point).to.eql([2, 3]); + }); + it('returns the expected value when the midpoint falls halfway between ' + 'two existing coordinates', function() { @@ -36,6 +43,13 @@ describe('ol.geom.flat.interpolate', function() { expect(point).to.eql([3, 4]); }); + xit('also when vertices are repeated', function() { + var flatCoordinates = [0, 1, 2, 3, 2, 3, 4, 5, 6, 7]; + var point = ol.geom.flat.interpolate.lineString( + flatCoordinates, 0, 8, 2, 0.5); + expect(point).to.eql([3, 4]); + }); + it('returns the expected value when the coordinates are not evenly spaced', function() { var flatCoordinates = [0, 1, 2, 3, 6, 7]; @@ -44,6 +58,14 @@ describe('ol.geom.flat.interpolate', function() { expect(point).to.eql([3, 4]); }); + xit('also when vertices are repeated', + function() { + var flatCoordinates = [0, 1, 2, 3, 2, 3, 6, 7]; + var point = ol.geom.flat.interpolate.lineString( + flatCoordinates, 0, 6, 2, 0.5); + expect(point).to.eql([3, 4]); + }); + it('returns the expected value when using opt_dest', function() { var flatCoordinates = [0, 1, 2, 3, 6, 7];