Openlayers 4

时间:2017-12-12 04:53:36

标签: javascript maps openlayers

我试图制作一个LineString,每行末尾都有箭头来显示路线的方向。我使用官方网站上的一个例子:https://openlayers.org/en/latest/examples/line-arrows.html 示例代码按用户的绘图创建箭头,但我需要给定LineString的箭头。 我的代码包含路径结束和结束的图标。 当我使用

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

在样式中,我的代码有效。但是当我从示例中为Linestring设置样式时,它会给出一个错误,说明" Uncaught TypeError:c.Y不是函数"。

这是我的代码:



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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

首先,您可以使用ol-debug.js代替ol.js,它是未压缩的,有助于调试。你得到的例外是

  

TypeError:style.getImage不是函数(第30443行)

你得到那个错误,因为你的样式对象是混合的:一些样式是函数,一些是普通的Style对象。

您可能认为OL可以同时处理这两种情况,而且您通常是正确的。但是,您为vectorLayer提供了一个函数,因此OL会检测到您提供了一个函数并调用它。该函数的返回值应该是样式对象。但是对于route,它会返回一个函数!

所以当OL调用时

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

它获取 icon-a icon-b 类型的样式,但是 route 的函数。 您需要增强样式函数来处理这种特殊情况:

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

PS:对变量使用相同的名称两次(样式)是不好的做法,可能会导致奇怪的错误。

以下是可运行的示例:

&#13;
&#13;
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.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) {
    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
  ]
});
&#13;
#map {
  /* just for testing purposes */
  width: 100%;
  min-width: 100px;
  max-width: 500px;
  margin-top: 50px;
  height: 200px;
}
&#13;
<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>
&#13;
&#13;
&#13;