OpenLayers 3中的自定义矢量形状标记

3
我有一个OpenLayers 3地图,显示各种数据。其中之一是显示附近雷达探测到的船只。目前,我将船只显示为简单的矢量圆。我想将其显示为船形状的矢量。

据我所知,最好的选择是使用*.png图标,并执行以下操作:

style: new ol.style.Icon({
  image: new ol.style.Icon(({
    anchor: [0.5, 0.5],
    anchorXUnits: 'fraction',
    anchorYUnits: 'fraction',
    opacity: 1,
    scale: 1,
    src: '/Content/images/boat.png',
    rotation: 0
  }))
});

这个可以用,但是我希望有一个向量,在缩放时不会发生变化。对于一些不同的数据,我的当前解决方案是显示一个矩形,但在缩放时它会发生变化:

var style = (function () {
  function (feature, resolution) {
  // font size
  if (resolution > 0.4) var fontSize = '12px';
  else var fontSize = '14px';

  var temperature = feature.get('temperature') || '-';
  temperature = temperature.replace(/,/g, '.');

  return [new ol.style.Style({
    fill: fill,
    stroke: stroke,
    text: new ol.style.Text({
      font: 'bold ' + fontSize + ' helvetica,sans-serif',
      text: Math.round(temperature * 100) / 100 + '°C',
      fill: new ol.style.Fill({ color: '#000' })
    }),
    geometry: function (feature) {
      var startingCoordinates = feature.getGeometry().getCoordinates();
      var coordinates = [[
          [startingCoordinates[0] + 0, startingCoordinates[1] + 0],
          [startingCoordinates[0] + 33, startingCoordinates[1] + 0],
          [startingCoordinates[0] + 33, startingCoordinates[1] + (-11.35)],
          [startingCoordinates[0] + 0, startingCoordinates[1] + (-11.35)],
          [startingCoordinates[0] + 0, startingCoordinates[1] + 0]
      ]];

      return new ol.geom.Polygon(coordinates);
      }
    })]
  }
})()

有没有比使用startingCoordinates +(constant * resolution)更好的解决方案?使用矢量与png是否存在重大性能差异?谢谢

编辑:在咨询了我的几个同事之后,我基本上正在尝试使用自定义形状来实现 http://openlayers.org/en/v3.5.0/examples/regularshape.html

编辑2:实际上更像是这个 http://dev.openlayers.org/examples/graphic-name.html“命名符号“闪电”,“矩形”和“教堂”是用户定义的。”


使用图标有什么问题吗?图标的大小以像素为单位指定。当缩放时,该大小不会改变。因此,我不明白你所说的“这个可以用,但我想要一个矢量图标,它在缩放时不会改变大小”的意思。 - erilem
使用图标是一种可能的解决方案,但我需要为不同类型的对象和它们的不同状态制作大量图标。通过程序生成矢量图标,我可以根据它们是否处于危险状态或对他人构成潜在威胁来更改它们的颜色。此外,我真的很想了解更多关于ol3的知识,我相信有更简单的方法来完成这个任务。 - damirsehic
@erilem 如果你感兴趣,我添加了一个(可能)更好的解释。 - damirsehic
关于性能方面:根据我的经验,在渲染成千上万个标记时,光栅图标和矢量标记之间的差异变得显著。当然,这可能会因客户端机器而异。关于您关于使用不可缩放的SVG的问题 - 我通过为每个标记生成一个.SVG文件来解决了这个问题。这可以通过脚本完成,但所有标记都必须存储在某个地方,因此这只是您问题的部分解决方案。 - Kenny806
2个回答

2
我知道这是一个老问题,但是为了帮助其他人,我回答一下。在我搜索如何实现这个功能时,这是最热门的结果。
我的解决方案是使用data:image/svg+xml和svg来提供一个图标,你可以通过编程生成它。
new ol.style.Style({
    image: new ol.style.Icon({
        // svg of an equilateral triangle 25px wide at the base
        src: `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="21.65" width="25" id="canvas"><polygon points="0,0 25,0 12.5,21.65" style="fill:rgba(0,0,0,1);"></polygon></svg>')}`,
    }),
})

注意:在数据URL中,您不需要对SVG进行base64编码,但是对于非Webkit浏览器,您需要对其进行encodeURIComponent()编码。

1
这是我的做法,与原始方法类似,但我不需要计算坐标,只需提供像素大小,让地图计算其余部分。
geometry: function (feature) {
    var startingCoordinates =feature.getGeometry().getCoordinates();
    var pixel = map.getPixelFromCoordinate(startingCoordinates);
    var p1,p2,p3,p4,polyCoords=[],sizex=90, sizey=30;
    p1 = pixel;
    p2 = [pixel[0]+sizex,p1[1]];
    p3 = [pixel[0]+sizex,pixel[1]+sizey];
    p4 = [pixel[0],pixel[1]+sizey];
    var p = [p1,p2,p3,p4,p1];
    for (var c = 0; c < 5;c++){
        polyCoords.push(map.getCoordinateFromPixel(p[c]));
    }

    return new ol.geom.Polygon([polyCoords]);
} 

这给了我一个矩形,这正是我想要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接