Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Size properties on ol.style.Icon #2720

Closed
lenoil opened this issue Sep 17, 2014 · 24 comments
Closed

Size properties on ol.style.Icon #2720

lenoil opened this issue Sep 17, 2014 · 24 comments

Comments

@lenoil
Copy link

lenoil commented Sep 17, 2014

Hi,

the modification of the size parameter has no effect.

In this example http://openlayers.org/en/v3.0.0/examples/icon.html
I try to change the size of the image but it doesn't work ... why ?

var iconStyle = new ol.style.Style({
  image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
    /*anchor: [0.5, 46],
    anchorXUnits: 'fraction',
    anchorYUnits: 'pixels',*/
    opacity: 1,
    size : [100,50],
    rotation: 40 * Math.PI / 180,
    src: 'data/icon.png'
  }))
});

Thanks


Want to back this issue? Place a bounty on it! We accept bounties via Bountysource.

@elemoine elemoine added the bug label Sep 17, 2014
@elemoine elemoine added this to the v3.1.0 milestone Sep 17, 2014
@elemoine elemoine removed this from the v3.1.0 milestone Dec 4, 2014
@greggian
Copy link
Contributor

greggian commented Jan 9, 2015

I am having a similar problem with ol.stlye.Icon.size in OL version 3.1.1.

In my situation my src image is slightly larger, say 32 x 48px. If I set a size on my ol.style.Icon of 20 x 20px then my image is truncated rather than scaled (as graphicHeight/graphicWidth did in OL2).

var iconStyle = new ol.style.Style({
  image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
    size : [20,20],
    src: 'data/icon.png' //32 x 48px image
  }))
});

screenshot from 2015-01-09 15 46 45

@elemoine
Copy link
Member

elemoine commented Jan 9, 2015

Le 9 janv. 2015 21:48, "Greg Gianforcaro" notifications@github.com a
écrit :

I am having a similar problem with ol.stlye.Icon.size in OL version 3.1.1.

In my situation my src image is slightly larger, say 25 x 25px. If I set
a size on my ol.style.Icon of 20 x 20px then my image is truncated rather
than scaled (as graphicHeight/graphicWidth did in OL2).

var iconStyle = new ol.style.Style
({
image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
size : [20,20],
src: 'data/icon.png' //25 x 25px image
}))
});

Have you tried using the "scale" option? In your case, scale: 0.8.

@greggian
Copy link
Contributor

greggian commented Jan 9, 2015

Yeah, I am aware of the scale option but it is desirable to set an absolute height/width on an Icon. In some cases, icons could come from a variety of sources and we may not know their original size so simply using scale isn't reliable.

@elemoine
Copy link
Member

Le 10 janv. 2015 00:01, "Greg Gianforcaro" notifications@github.com a
écrit :

Yeah, I am aware of the scale option but it is desirable to set an
absolute height/width on an Icon. In some cases, icons could come from a
variety of sources and we may not know their original size so simply using
scale isn't reliable.

I see. So we don't have a solution for you for the moment. As you've
observed it already, "size" does not scale the image. "size" specifies the
number of pixels of the image you want to use.

@greggian
Copy link
Contributor

Thanks for the clarification. Is this the final/intended behavior of 'size' or has the scaling just not been implemented yet?

@elemoine
Copy link
Member

We could add another "size" option that one would use to set the "destination size". So size would be used to set the size of the source image, and that other option would be used to specify the size of the destination image (as drawn onto the Canvas). I don't have good option names right now. Note that ol.style.Icon and its options are marked as "experimental", so we can even rename size to something else if it makes sense.

@greggian
Copy link
Contributor

My first impression of the current behavior was that it was working more as a crop property then what I might typically think of a 'size'. In the context of a sprite image, size does make sense.

So my thoughts are either: 1) maybe move the current behavior to a crop property for sprite behavior. Or 2) maybe sprite is specific enough to be worthy of its own style (ol.style.SpriteIcon)?

If we can work out how it should work, I would be interested in contributing.

@elemoine
Copy link
Member

I think I'd repurpose the size option to being the destination size (as drawn onto the canvas) and introduce sourceSize.

I am interested to have others' opinions.

@tschaub
Copy link
Member

tschaub commented Jan 12, 2015

I think treating size as the rendered size makes sense. If we change this, we should try to list out the use cases and make sure we have a good set of config options.

@greggian were you hoping to be able to specify height only? Even if you weren't, I can imagine this as a use case (specifying only one of height or width as with the CSS equivalent).

@elemoine
Copy link
Member

@tschaub, good point. So, IIUC, this would suggest replacing size by height and width. And while we're at it I guess it would make sense to replace scale by scaleX and scaleY.

@greggian
Copy link
Contributor

@tschaub that isn't my immediate need but I think that could be useful.

On Mon, Jan 12, 2015, 4:11 PM Tim Schaub notifications@github.com wrote:

I think treating size as the rendered size makes sense. If we change
this, we should try to list out the use cases and make sure we have a good
set of config options.

@greggian https://github.com/greggian were you hoping to be able to
specify height only? Even if you weren't, I can imagine this as a use
case (specifying only one of height or width as with the CSS equivalent).


Reply to this email directly or view it on GitHub
#2720 (comment).

@pconnell99
Copy link

I think I'd find this useful as well - my icons are real-world elements with a length - scaling is not really working for the differing images. All I really want to do is set width/height for each icon based on resolution. Any news on this since Jan?

@elemoine
Copy link
Member

elemoine commented May 5, 2015

To my knowledge no one has done work on this.

@pconnell99
Copy link

I have started 'hacking' around in the debug version currently and found the matrix transforms in DRAWIMAGE - passing through an x/y array as scale - with mixed results such as skewing of images and titles - am I 'barking up the wrong tree'? If someone points me in the general direction of the relevant chunks of code I'm more than happy to take a look.

@tschaub tschaub removed the bug label Sep 21, 2015
@SeratFatima
Copy link

+1 for the size feature to be related to icon image height/width not the crop property

@PaddingtonTheBear
Copy link

PaddingtonTheBear commented Dec 14, 2016

Glad to see this is being implemented finally, as there are plenty of situations where you would want to standardize all images / icon sizes coming in to the map; especially when you don't control the imagery sources that are serving giant images.

In the interim, to help others that are waiting for this feature in OL3 (since I found no solutions when googling how to implement this), I've adapted a solution from stackoverflow that creates a temporary img and canvas, resizes the image, and then uses that temporary canvas URL for the image src.

Since this needs to reach out and load the imagery, it could potentially block code execution while waiting for it to load. I wasn't sure how to send a callback to ol.style.Icon's src property, so I simply included an icon cache object to store all unique images to improve performance for my use

For example, if you have an incoming feature with icon URLs, then the following will help you out:

var iconCache = {}; // likely make this global in your use case

// use this function in your ol.layer.Vector object for the style property
function pointStyleFunction(feature, resolution) {
    var originalImageURL = feature.get('iconSrc'); // change iconSrc to whatever is storing your icon source for this feature
    var resizedImageURL = '';

    if (!iconCache[originalImageURL]) {
        var sourceImage = new Image();
        var width = 48; // these two can be parameterized
        var height = 48;

        sourceImage.onload = function() {
            var canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            canvas.getContext('2d').drawImage(sourceImage, 0, 0, width, height);

            resizedImageURL = canvas.toDataURL(); // this can be changed to a callback to prevent execution blocking

            iconCache[iconSRC] = resizedImageURL; // store the resized URL in the cache
        }

    } else { // already resized and cached the image, so used the saved version
        resizedImageURL = iconCache[originalImageURL];
    }

    // Now build up your Openlayers style
    var currentStyle = new ol.style.Style({
        image: new ol.style.Icon({
            anchor: [0.5, 0.5],
            anchorXUnits: 'fraction',
            anchorYUnits: 'fraction',
            opacity: 0.75,
            scale: 1.0,
            src: resizedImageURL // Put the resized image url in here
        }),
        text: new ol.style.Text({
            text: resolution > 4000 ? '' : feature.get('name')
            fill: new ol.style.Fill({
                color: 'white'
            }),
            font: '14px sans-serif',
            stroke: new ol.style.Stroke({
                color: 'black',
                width: 5
            }),
            offsetX: 24,
            offsetY: 24
        })
    });

    return currentStyle;
}

@Liplattaa
Copy link

I can see here that the issue is now resolved, but I still can't find how to set Icon size in version 3.20.1 documentation.

Can somebody sum up what should I do to set absolute icon size in pixels?

@stale
Copy link

stale bot commented May 22, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label May 22, 2019
@stale stale bot closed this as completed May 29, 2019
@mblataric
Copy link

Hi,

has this changed in later versions?
I am using OpenLayers 6 and setting size on Icon does not scale image, it crops it.
All solution I am finding include manually loading image using new Image(), however - that is causing "cannot instantiate abstract class" error in TypeScript.

Thanks,
Mario

@tschaub
Copy link
Member

tschaub commented Mar 30, 2021

@mblataric - Try using the scale property of the icon style.

Any pull request to improve the documentation for these icon style properties would be appreciated: https://openlayers.org/en/latest/apidoc/module-ol_style_Icon-Icon.html

@mblataric
Copy link

@mblataric - Try using the scale property of the icon style.

Any pull request to improve the documentation for these icon style properties would be appreciated: https://openlayers.org/en/latest/apidoc/module-ol_style_Icon-Icon.html

@tschaub - This very issue started because scale can not be used since images are of different sizes from source we do not control.

And I can’t use any manual examples with loading image into Image because Image cannot be instantiated in TS because it is marked as abstract.

If this issue was solved in OL3, how come it got reverted in OL6?

@tschaub
Copy link
Member

tschaub commented Mar 31, 2021

@mblataric - see also the imgSize property: https://openlayers.org/en/latest/apidoc/module-ol_style_Icon-Icon.html

I'm only making blind guesses about what your specific issue is. If you can put together a minimal example that reproduces the problem, that would make troubleshooting it easier. Also feel free to open a new issue if you are able to provide a simple reproducible example (you can start by clicking the "Edit" button on https://openlayers.org/en/latest/examples/icon.html).

@mblataric
Copy link

@tschaub I would like fixed sized image markers in map, say 15px on longer side.
However, incoming images used for markers are in different sizes which is why scale will not work.
Both size and imgSize simply crop incoming image to set dimensions and I would like image to be resized instead of cropped - exactly what this very issue was about, but for some reason it seems it got reverted to original functionality in later OL versions.

@Firestorm87
Copy link

+1
Often i load dynamic icons of sizes 16x16, 32x32 or 64x64.
On Map i wont to show all of equal size.

It's not really working with existing "size" and "imgSize" options. And css, html and other layouting languages always accept the target-size and never want to know the original Size (cropping excepted).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests