简体   繁体   English

Openlayers 4 中的 LineString 方向箭头

[英]LineString direction arrows in Openlayers 4

I'm trying to make a LineString which has arrows in the end of each line to show direction of the route.我正在尝试制作一个 LineString,它在每条线的末尾都有箭头以显示路线的方向。 I use an example from the official site: https://openlayers.org/en/latest/examples/line-arrows.html The example code creates arrows by user's drawing, but I need arrows for given LineString.我使用来自官方网站的示例: https : //openlayers.org/en/latest/examples/line-arrows.html示例代码通过用户的绘图创建箭头,但我需要给定 LineString 的箭头。 My code contains icons for end and finish of the route.我的代码包含路线终点和终点的图标。 When I use当我使用

'route': new ol.style.Style({
      stroke: new ol.style.Stroke({
        width: 6, color: [23, 120, 22, 0.6]
      })
    }),

in styles, my code works.在样式中,我的代码有效。 But when I put style for Linestring from the example, it gives me an error saying "Uncaught TypeError: cY is not a function".但是,当我为示例中的 Linestring 设置样式时,它给了我一个错误,提示“未捕获的类型错误:cY 不是函数”。

Here is my code:这是我的代码:

 var points = [ [76.8412, 43.2245], [76.8405, 43.2210], [76.8479, 43.2200], [76.8512, 43.2220] ]; var route = new ol.geom.LineString(points); route.transform('EPSG:4326', 'EPSG:3857'); var routeFeature = new ol.Feature({ type: 'route', geometry: route }); var startMarker = new ol.Feature({ type: 'icon-a', geometry: new ol.geom.Point(ol.proj.fromLonLat(points[0])) }); var endMarker = new ol.Feature({ type: 'icon-b', geometry: new ol.geom.Point(ol.proj.fromLonLat(points[points.length - 1])) }); var styles = { 'route': function(feature) { var geometry = feature.getGeometry(); var styles = [ // linestring new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2 }), image: new ol.style.Icon({ anchor: [0.5, 1], src: 'img/icon-a.png' }) }) ]; 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: 'https://openlayers.org/en/v4.6.3/examples/data/arrow.png', anchor: [0.75, 0.5], rotateWithView: true, rotation: -rotation }) })); }); return styles; }, 'icon-a': new ol.style.Style({ image: new ol.style.Icon({ anchor: [0.5, 1], src: 'img/icon-a.png' }) }), 'icon-b': new ol.style.Style({ image: new ol.style.Icon({ anchor: [0.5, 1], src: 'img/icon-b.png' }) }) }; var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: [routeFeature, startMarker, endMarker] }), style: function(feature) { return styles[feature.get('type')]; } }); var center = ol.proj.fromLonLat([76.8512, 43.2220]); var map = new ol.Map({ target: document.getElementById('map'), view: new ol.View({ center: center, zoom: 15, minZoom: 2, maxZoom: 19 }), layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer ] });
 #map { /* just for testing purposes */ width: 100%; min-width: 100px; max-width: 500px; margin-top: 50px; height: 50px; }
 <link href="https://openlayers.org/en/v4.6.4/css/ol.css" rel="stylesheet"/> <script src="https://openlayers.org/en/v4.6.4/build/ol-debug.js"></script> <div id="map"></div>

Firstly, you can use ol-debug.js instead of ol.js , which is uncompressed and helps debugging.首先,您可以使用ol-debug.js而不是ol.js ,它是未压缩的并有助于调试。 The exception you get is你得到的例外是

TypeError: style.getImage is not a function (Line 30443)类型错误:style.getImage 不是函数(第 30443 行)

You get that error because your styles object is mixed: some styles are functions, some are plain Style objects.你得到这个错误是因为你的样式对象是混合的:一些样式是函数,一些是普通的 Style 对象。

You might think that OL can handle both, and you are normally right.您可能认为 OL 可以处理这两种情况,通常您是对的。 However, you provide a function to vectorLayer , so OL detects that you provided a function and calls it.但是,您向vectorLayer提供了一个函数,因此 OL 检测到您提供了一个函数并调用它。 The return value of that function is expected to be a style object.该函数的返回值应该是一个样式对象。 But for route , that returns a function instead!但是对于route ,它返回一个函数!

So when OL calls所以当OL打电话

style: function(feature) {
    return styles[feature.get('type')];
}

It gets styles for the types icon-a , icon-b , but an function for route .它获取icon-aicon-b类型的样式,但获取route的函数。 You need to enhance your style function to handle that special case:您需要增强样式功能来处理这种特殊情况:

style: function(feature) {
  const myStyle = stylesMap[feature.get('type')];
  if (myStyle instanceof Function) {
    return myStyle(feature);
  }
  return myStyle;
}

PS: Using the same name for a variable twice (styles) is bad practice and can lead to weird bugs. PS:对变量使用相同的名称两次(样式)是不好的做法,可能会导致奇怪的错误。

Here is the runnable example:这是可运行的示例:

 var points = [ [76.8412, 43.2245], [76.8405, 43.2210], [76.8479, 43.2200], [76.8512, 43.2220] ]; var route = new ol.geom.LineString(points); route.transform('EPSG:4326', 'EPSG:3857'); var routeFeature = new ol.Feature({ type: 'route', geometry: route }); var startMarker = new ol.Feature({ type: 'icon-a', geometry: new ol.geom.Point(ol.proj.fromLonLat(points[0])) }); var endMarker = new ol.Feature({ type: 'icon-b', geometry: new ol.geom.Point(ol.proj.fromLonLat(points[points.length - 1])) }); var stylesMap = { 'route': function(feature) { var geometry = feature.getGeometry(); var styles = [ // linestring new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2 }), image: new ol.style.Icon({ anchor: [0.5, 1], src: 'img/icon-a.png' }) }) ]; 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: 'https://openlayers.org/en/v4.6.5/examples/data/arrow.png', anchor: [0.75, 0.5], rotateWithView: true, rotation: -rotation }) })); }); return styles; }, 'icon-a': new ol.style.Style({ image: new ol.style.Icon({ anchor: [0.5, 1], src: 'img/icon-a.png' }) }), 'icon-b': new ol.style.Style({ image: new ol.style.Icon({ anchor: [0.5, 1], src: 'img/icon-b.png' }) }) }; var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: [routeFeature, startMarker, endMarker] }), style: function(feature) { const myStyle = stylesMap[feature.get('type')]; if (myStyle instanceof Function) { return myStyle(feature); } return myStyle; } }); var center = ol.proj.fromLonLat([76.8512, 43.2220]); var map = new ol.Map({ target: document.getElementById('map'), view: new ol.View({ center: center, zoom: 15, minZoom: 2, maxZoom: 19 }), layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer ] });
 html, body { width: 100%; height: 100%; padding: 0px; margin: 0px; } #map { /* just for testing purposes */ width: 100%; height: 100%; }
 <link href="https://openlayers.org/en/v4.6.5/css/ol.css" rel="stylesheet" /> <script src="https://openlayers.org/en/v4.6.5/build/ol-debug.js"></script> <div id="map"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM