From 4b13627fd716e97dc2665dbd21e4087470b82565 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 12 Mar 2015 10:18:39 +0100 Subject: [PATCH 1/3] Add new ol.geom.LineString#forEachSegment function --- src/ol/geom/linestring.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/ol/geom/linestring.js b/src/ol/geom/linestring.js index 3477285f3c..3a89e81de5 100644 --- a/src/ol/geom/linestring.js +++ b/src/ol/geom/linestring.js @@ -11,6 +11,7 @@ goog.require('ol.geom.flat.inflate'); goog.require('ol.geom.flat.interpolate'); goog.require('ol.geom.flat.intersectsextent'); goog.require('ol.geom.flat.length'); +goog.require('ol.geom.flat.segments'); goog.require('ol.geom.flat.simplify'); @@ -107,6 +108,23 @@ ol.geom.LineString.prototype.closestPointXY = }; +/** + * Iterate over each segment, calling the provided callback. + * If the callback returns a truthy value the function returns that + * value immediately. Otherwise the function returns `false`. + * + * @param {function(ol.Coordinate, ol.Coordinate): T} callback Function + * called for each segment. + * @return {T|boolean} Value. + * @template T + * @api + */ +ol.geom.LineString.prototype.forEachSegment = function(callback) { + return ol.geom.flat.segments.forEach(this.flatCoordinates, 0, + this.flatCoordinates.length, this.stride, callback); +}; + + /** * Returns the coordinate at `m` using linear interpolation, or `null` if no * such coordinate exists. From 023816f43bd47a48bd4c95c45c8c338bad92a3b3 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 12 Mar 2015 11:33:28 +0100 Subject: [PATCH 2/3] Add new line-arrows example --- examples/data/arrow.png | Bin 0 -> 398 bytes examples/line-arrows.html | 51 +++++++++++++++++++++++++++++ examples/line-arrows.js | 67 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 examples/data/arrow.png create mode 100644 examples/line-arrows.html create mode 100644 examples/line-arrows.js diff --git a/examples/data/arrow.png b/examples/data/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..a0d3834586169c71ca1e2fec8d23a4235e1a950d GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eW!3-oPYs<_AQq09po*^6@9Je3(KLBz$3p^r= z85p>QL70(Y)*K0-pk#?_L`iUdT1k0gQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MMVKV zA+G;HfB}S7h5p~~@c)eQ|Et>nFY5h2Vhv(n(*1wZ48%QU`u~DHh&*Qq5=Ta-O+Z`- z2^UA>!o|-RFV0N33$$IeB*-tAfsu)sg_Vt)mtRm=OhQ`L*=_cMB`epi+q8Ax;p3;z zUAlVh=ACcW5zeoH8e%a=h5HS477;B)78&qol`;+0Q0M`nE(I) literal 0 HcmV?d00001 diff --git a/examples/line-arrows.html b/examples/line-arrows.html new file mode 100644 index 0000000000..6338653387 --- /dev/null +++ b/examples/line-arrows.html @@ -0,0 +1,51 @@ + + + + + + + + + + + LineString arrows example + + + + + +
+ +
+
+
+
+
+ +
+ +
+

LineString arrows example

+

Example of drawing arrows for each line string segment.

+
+

See the line-arrows.js source to see how this is done.

+
+
draw, vector, arrow
+
+ +
+ +
+ + + + + + + diff --git a/examples/line-arrows.js b/examples/line-arrows.js new file mode 100644 index 0000000000..90f810acfa --- /dev/null +++ b/examples/line-arrows.js @@ -0,0 +1,67 @@ +goog.require('ol.Map'); +goog.require('ol.View'); +goog.require('ol.geom.Point'); +goog.require('ol.interaction.Draw'); +goog.require('ol.layer.Tile'); +goog.require('ol.layer.Vector'); +goog.require('ol.source.MapQuest'); +goog.require('ol.source.Vector'); +goog.require('ol.style.Icon'); +goog.require('ol.style.Stroke'); +goog.require('ol.style.Style'); + +var raster = new ol.layer.Tile({ + source: new ol.source.MapQuest({layer: 'sat'}) +}); + +var source = new ol.source.Vector(); + +var styleFunction = function(feature, resolution) { + var geometry = feature.getGeometry(); + var styles = [ + // linestring + new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: '#ffcc33', + width: 2 + }) + }) + ]; + + geometry.forEachSegment(function(start, end) { + var dx = end[0] - start[0]; + var dy = end[1] - start[1]; + var rotation = Math.atan2(dy, dx); + // arrows + styles.push(new ol.style.Style({ + geometry: new ol.geom.Point(end), + image: new ol.style.Icon({ + src: 'data/arrow.png', + anchor: [0.75, 0.5], + rotateWithView: false, + rotation: -rotation + }) + })); + }); + + return styles; +}; +var vector = new ol.layer.Vector({ + source: source, + style: styleFunction +}); + +var map = new ol.Map({ + layers: [raster, vector], + renderer: exampleNS.getRendererFromQueryString(), + target: 'map', + view: new ol.View({ + center: [-11000000, 4600000], + zoom: 4 + }) +}); + +map.addInteraction(new ol.interaction.Draw({ + source: source, + type: /** @type {ol.geom.GeometryType} */ ('LineString') +})); From b9aba8babd91a637a432c4e0dd28a00b497c91c2 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 16 Mar 2015 11:25:41 +0100 Subject: [PATCH 3/3] Add optional `this` param to the callback function --- src/ol/geom/flat/segmentsflatgeom.js | 10 ++++++---- src/ol/geom/linestring.js | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ol/geom/flat/segmentsflatgeom.js b/src/ol/geom/flat/segmentsflatgeom.js index 8c6aac24fd..b834eecbdc 100644 --- a/src/ol/geom/flat/segmentsflatgeom.js +++ b/src/ol/geom/flat/segmentsflatgeom.js @@ -9,20 +9,22 @@ goog.provide('ol.geom.flat.segments'); * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. - * @param {function(ol.Coordinate, ol.Coordinate): T} callback Function + * @param {function(this: S, ol.Coordinate, ol.Coordinate): T} callback Function * called for each segment. + * @param {S=} opt_this The object to be used as the value of 'this' + * within callback. * @return {T|boolean} Value. - * @template T + * @template T,S */ ol.geom.flat.segments.forEach = - function(flatCoordinates, offset, end, stride, callback) { + function(flatCoordinates, offset, end, stride, callback, opt_this) { var point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]]; var point2 = []; var ret; for (; (offset + stride) < end; offset += stride) { point2[0] = flatCoordinates[offset + stride]; point2[1] = flatCoordinates[offset + stride + 1]; - ret = callback(point1, point2); + ret = callback.call(opt_this, point1, point2); if (ret) { return ret; } diff --git a/src/ol/geom/linestring.js b/src/ol/geom/linestring.js index 3a89e81de5..08c99fc771 100644 --- a/src/ol/geom/linestring.js +++ b/src/ol/geom/linestring.js @@ -113,15 +113,17 @@ ol.geom.LineString.prototype.closestPointXY = * If the callback returns a truthy value the function returns that * value immediately. Otherwise the function returns `false`. * - * @param {function(ol.Coordinate, ol.Coordinate): T} callback Function + * @param {function(this: S, ol.Coordinate, ol.Coordinate): T} callback Function * called for each segment. + * @param {S=} opt_this The object to be used as the value of 'this' + * within callback. * @return {T|boolean} Value. - * @template T + * @template T,S * @api */ -ol.geom.LineString.prototype.forEachSegment = function(callback) { +ol.geom.LineString.prototype.forEachSegment = function(callback, opt_this) { return ol.geom.flat.segments.forEach(this.flatCoordinates, 0, - this.flatCoordinates.length, this.stride, callback); + this.flatCoordinates.length, this.stride, callback, opt_this); };