Scaling the icon-image size to an absolute value

佐手、 提交于 2021-01-29 17:18:17

问题


I'm developing an application where one functionality is displaying a device on a map using open-layers. These devices can be added by the user and they all can have a custom icon-image using an uploaded image. This image can also be changed on runtime depending on some of the devices attributes (for example the temperature). From what i understood reading through their documentation, there are some properties on the ol.style.Icon object like imgSize which is are all cutting, but not scaling the image. There is also an other property called scale which does in fact scale the image. But since the image size can vary, the scale is not always the same and must be calculated in order to have the same icon size on each device (40 width).

For calculating the right icon depending on the device i am using this style-function on my layer.Vector object.

function(feature){
  var device = feature.get("device");
  var icon = (device.familyIds.length > 0 ? icons.find(i => i.familyIds.includes(device.familyIds[0])) : undefined);
  return new ol.style.Style({
    image: new ol.style.Icon({
      anchor: [0.5, 1],
      src: (icon != undefined ? new Function("device", "familyProperty", icon.iconSource)(device, icon.familyProperty) : './img/icons/icon_default.png')
    }),
    text: new ol.style.Text({
      text: device.name,
      offsetY: 15,
      font: "20px Calibri,sans-serif"
    })
  });
}

When a certain device has an icon to display, i am injecting a code into a funciton. This function returns the desired img-src. When a device has no icon, i am displaying a default one. So till now, I managed to display the right icon depending on each device but i am still struggling with the different image-sizes. I tried configuring the attributes in the ol.style.Icon object in every imaginable way using imgSize, size and scale but nothing really worked. Thank you for your help.


回答1:


I suggest you use a style cache indexed by src url (it's more efficient in any situation should resolve the async problem)

var styleCache = {};

var styleFunction = function(feature){
  var device = feature.get("device");
  var icon = (device.familyIds.length > 0 ? icons.find(i => i.familyIds.includes(device.familyIds[0])) : undefined);
  var url = (icon != undefined ? new Function("device", "familyProperty", icon.iconSource)(device, icon.familyProperty) : './img/icons/icon_default.png');
  var style = styleCache[url];
  if (!style) {
    style = new ol.style.Style({
      image: new ol.style.Icon({
        anchor: [0.5, 1],
        src: url,
        scale: 0
      }),
      text: new ol.style.Text({
        offsetY: 15,
        font: "20px Calibri,sans-serif"
      })
    });
    var img = new Image();
    img.onload = function() {
      style.getImage().setScale(40/img.width);
      feature.changed();  // force a refresh or just wait until next render?
    }
    img.src = url;
    styleCache[url] = style;
  }
  style.getText().setText(device.name);
  return style;
}

The device name text will need to be set "on demand" as devices might shares images.




回答2:


Scale icon if too big in -> image: new ol.style.Icon(....):

scale: 0.4,


来源:https://stackoverflow.com/questions/57492200/scaling-the-icon-image-size-to-an-absolute-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!