简体   繁体   English

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

[英]Custom vector shape markers in OpenLayers 3

I have a OpenLayers 3 map on which I'm showing all kinds of data. 我有一张OpenLayers 3地图,我正在显示各种数据。 One of them is showing boats that are detected by a nearby radar. 其中一个是显示附近雷达探测到的船只。 Currently I'm displaying boats as a simple vector Circle. 目前我正在将船只显示为一个简单的矢量圆圈。 I'd like to display it as a vector shaped as a boat. 我想将它显示为一个形状像船的矢量。

As far as I'm informed, my best bet is using a *.png icon, and doing something like this: 据我所知,我最好的选择是使用* .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
  }))
});

This works but I'd like to have a vector that doesn't scale when i zoom in/out. 这有效,但我希望有一个矢量,当我放大/缩小时不会缩放。 My current solution for some different data is displaying a rectangle, but it scales when zooming: 我目前针对某些不同数据的解决方案是显示一个矩形,但它在缩放时会缩放:

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);
      }
    })]
  }
})()

Is there a better solution for this than using startingCoordinates + (constant * resolution)? 有没有比使用startingCoordinates +(常数*分辨率)更好的解决方案? Are there any significant performance differences in using vector vs. png? 使用向量与png有任何显着的性能差异吗? Thanks 谢谢

EDIT: After consulting with few colleagues of mine, I'm basically trying to have this http://openlayers.org/en/v3.5.0/examples/regularshape.html but with a custom shape. 编辑:经过与我的几个同事的咨询,我基本上试图有这个http://openlayers.org/en/v3.5.0/examples/regularshape.html但具有自定义形状。

EDIT2: Actually more like this http://dev.openlayers.org/examples/graphic-name.html 'The named symbols "lightning", "rectangle" and "church" are user defined.' EDIT2:实际上更像是这样的http://dev.openlayers.org/examples/graphic-name.html '命名符号“闪电”,“矩形”和“教堂”是用户定义的。

This is how I've done it, its similar to the original but without me having to work out what the coordinates should be, I just provide how big by pixels it is and let the map calculate the rest. 这就是我完成它的方式,它与原版相似但没有我必须弄清楚坐标应该是什么,我只提供像素的大小,让地图计算其余部分。

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]);
} 

this gives me a rectangle, which is what I wanted. 这给了我一个矩形,这就是我想要的。

I know this is an old question but answering for others as this was the top result while I was looking into how to do this. 我知道这是一个老问题,但回答其他人,因为这是最重要的结果,而我正在研究如何做到这一点。

My solution is to use a data:image/svg+xml with an svg to provide an icon you can programmatically generate 我的解决方案是使用数据: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>')}`,
    }),
})

Note: you don't need to base64 encode svg in a data url but you do need to encodeURIComponent() it for non webkit browsers. 注意:您不需要在数据URL中使用base64编码svg,但是您需要将encodeURIComponent()用于非webkit浏览器。

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

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