How do I draw an arrow over a vector layer in Openlayers 3 map? I tried creating an arrow using canvaselement but don't know how to draw it over the ol3 map.
Asked
Active
Viewed 6,573 times
4
-
Have you seen http://openlayers.org/en/latest/examples/line-arrows.html? However, you should provide a bit more context. It is not clear from your question whether you want to style points or lines with arrows. – ahocevar Jan 12 '17 at 07:47
-
I have seen that link. It uses "https://openlayers.org/en/v3.20.1/examples/data/arrow.png". But i do not want to use any images (eg. here png). I want to style Line with arrow. – user6730740 Jan 12 '17 at 09:07
-
Will using canvas element be a possible solution ? But how to draw canvas element in openlayers 3 using ol.interaction.Draw ? – user6730740 Jan 12 '17 at 11:13
-
Instead of configuring `arrow.png` as `src` of your `ol.style.Icon`, you can also configure a `canvas` element as `img`. Something like in http://openlayers.org/en/latest/examples/earthquake-custom-symbol.html. – ahocevar Jan 12 '17 at 13:47
2 Answers
7
A canvas element is not necessary. You can take the arrow example from the Openlayers site and add 2 custom LineString elements instead of the icon. You already have in the example the rotation angle in radians and the event where you should add your code.
Hopefully the following snippet does the trick:
var source = new ol.source.Vector();
var styleFunction = function (feature) {
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);
var lineStr1 = new ol.geom.LineString([end, [end[0] - 200000, end[1] + 200000]]);
lineStr1.rotate(rotation, end);
var lineStr2 = new ol.geom.LineString([end, [end[0] - 200000, end[1] - 200000]]);
lineStr2.rotate(rotation, end);
var stroke = new ol.style.Stroke({
color: 'green',
width: 1
});
styles.push(new ol.style.Style({
geometry: lineStr1,
stroke: stroke
}));
styles.push(new ol.style.Style({
geometry: lineStr2,
stroke: stroke
}));
});
return styles;
};
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
source: source,
style: styleFunction
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
map.addInteraction(new ol.interaction.Draw({
source: source,
type: ('LineString')
}));
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
<link href="https://openlayers.org/en/v3.20.1/css/ol.css" rel="stylesheet"/>
<div id="map" class="map" tabindex="0"></div>

Icarus
- 1,627
- 7
- 18
- 32
-
Thankyou so much Icarus !!! This has helped me. Using this solution i am trying to make double-line arrow, i have almost achieved it, only angling of the double line part is left. If wont be able to do it, i'll catch u again ! ;) – user6730740 Jan 13 '17 at 05:57
4
This is another customization of the Openlayers line-arrow Example. It uses a RegularShape instead of an image. The arrow will keep its size independent of the current map zoom.
var source = new ol.source.Vector();
var styleFunction = function (feature) {
var geometry = feature.getGeometry();
var styles = [
// linestring
new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#000',
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);
styles.push(new ol.style.Style({
geometry: new ol.geom.Point(end),
image: new ol.style.RegularShape({
fill: new ol.style.Fill({color: '#000'}),
points: 3,
radius: 8,
rotation: -rotation,
angle: Math.PI / 2 // rotate 90°
})
}));
});
return styles;
};
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
source: source,
style: styleFunction
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
map.addInteraction(new ol.interaction.Draw({
source: source,
type: ('LineString')
}));
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
<link href="https://openlayers.org/en/v3.20.1/css/ol.css" rel="stylesheet"/>
<div id="map" class="map" tabindex="0"></div>

megges
- 570
- 1
- 3
- 11