CartoDB / mobile-sdk

CARTO Mobile SDK core project
https://carto.com/docs/carto-engine/mobile-sdk/
BSD 3-Clause "New" or "Revised" License
185 stars 67 forks source link

CartoCss Polygon Opacity By Zoom #376

Closed lasyakoechlin closed 4 years ago

lasyakoechlin commented 4 years ago

Hi,

I am trying to adjust the polygon opacity based on the zoom level to give a fade-in/out effect. I have tried the following set of carto css code samples without any luck.

Note: I am using 4.3.1 on Android.

I have played around with other parameters within the [class='fade'] block, so I can confirm that it is affecting the correct polygons (e.g., changing colors).

Thanks for your help.

@myfill: rgba(230,230,212,1);
@myline rgba(199,199,183,1);
#mylayer {
    polygon-opacity: 1.0;
        polygon-fill: @myfill;
        line-color: @myline;
    line-width: 2;

        [class='fade'] {
               polygon-opacity: linear([view::zoom], (17, 1), (20, 0));

              /* I also tried the version below:
                polygon-opacity: linear([zoom], (17, 1), (20, 0));
              */
        }
}
#mylayer {
    polygon-opacity: 1.0;
        polygon-fill: @myfill;
        line-color: @myline;
    line-width: 2;

        [class='fade'] {
                [zoom > 17] { polygon-opacity: 0.75; }
        [zoom > 18] { polygon-opacity: 0.50; }
        [zoom > 19] { polygon-opacity: 0.25; }
        [zoom > 20] { polygon-opacity: 0.00; }
        }
}
#mylayer {
    polygon-opacity: 1.0;
        polygon-fill: @myfill;
        line-color: @myline;
    line-width: 2;

        [class='fade'] {
                [zoom > 17] { polygon-fill: fadeout(@myfill, 25%); }
        [zoom > 18] { polygon-fill: fadeout(@myfill, 50%); }
        [zoom > 19] { polygon-fill: fadeout(@myfill, 75%); }
        [zoom > 20] { polygon-fill: fadeout(@myfill, 100%); }
        }
}

I was able to verify that very similar code works on other CartoCSS engines. For example,

http://bl.ocks.org/jsanz/raw/d945737eb42ca83654301e66dac365cb/

with SQL query select * from world_borders

and carto css:

@mycolor: #fabada;

#layer{
  polygon-fill      : @mycolor;
  line-color        : blue;
  line-opacity      : 0.5;
  line-width        : 3;

  polygon-opacity : 1;
  line-opacity    : 1;

  [zoom < 2] {
        polygon-fill    : fadeout(@mycolor,25%);
        line-color      : red;
  }
  [zoom > 4] {
        polygon-fill    : fadeout(@mycolor,50%);
        line-color      : black;   
  }
  [zoom > 6] {
        polygon-fill    : fadeout(@mycolor,75%);
        line-color      : orange;           
  }
  [zoom > 8] {
        polygon-fill    : fadeout(@mycolor,100%);
        line-color      : yellow;     
  }
}

I understand that Carto mobile SDK has its own Carto CSS engine and not everything is supported, I was reading through the wiki documentation here:

https://github.com/CartoDB/mobile-sdk/wiki/CartoCSS-notes

And it talks about the usage [view::zoom], etc.

Also, I noticed that the documentation talks about this:

image

Does that mean that polygon-pattern-file is a supported parameter?

Thanks for your help!

lasyakoechlin commented 4 years ago

It appears that the issue was on my side.

I thought I was modifying the layer but seems the class was not being set properly, so it was just by chance that it changed when I modified my CartoCSS, making me think that I was updating the correct class.

I was able to get the fading affect working.

My question about polygon-pattern-file still remains though.

mtehver commented 4 years ago

Hi. polygon-pattern-file is supported. Note that 'polygon' and 'polygon-pattern' are two separate symbolizers. To set the color of 'polygon-pattern', you need to use polygon-pattern-fill, not polygon-fill. Same with other parameters, like opacity (use polygon-pattern-opacity). In your current example you are creating two symbolizers, with the latter one ('polygon') hiding the former ('polygon-pattern').

lasyakoechlin commented 4 years ago

That's really cool.

Also the code exert that I was using is from the your wiki/documentation.

See https://github.com/CartoDB/mobile-sdk/wiki/CartoCSS-notes in the "Multiple symbolizers per layer" section.

Anyways, I tried the following:

#mylayer{

    polygon-opacity: 1.0;

    [class='pattern'] {
                line-color: rgba(230,230,212,1);
        line-width: 2;
        polygon-opacity: 0.0;
        polygon-pattern-opacity: 1.0;
        polygon-pattern-file: url('http://com.cartodb.users-assets.production.s3.amazonaws.com/patterns/diagonal_1px_med.png');
    }
}

But it just shows up as an empty polygon with an outline. Is there something I'm doing wrong?

lasyakoechlin commented 4 years ago

So, I'm experimenting with linear opacity zooming, and I noticed that the following code works:

polygon-opacity: linear([view::zoom], (19 , 1), (21, 0));
building-fill-opacity: linear([view::zoom], (19 , 1), (21, 0));

However, the following code does not work:

polygon-opacity: linear([view::zoom], (  ([fade_start] ? [fade_start] : 19), 1), ( ([fade_end] ? [fade_end] : 21), 0));
building-fill-opacity: linear([view::zoom], (  ([fade_start] ? [fade_start] : 19), 1), ( ([fade_end] ? [fade_end] : 21), 0));

Is there a way that I can programatically control the range in which the fading (i.e., opacity moving towards zero) occurs?

mtehver commented 4 years ago

First about polygon-pattern-file - you may need to use 'https' instead of 'http', as plain HTTP access is normally disabled, unless security settings are overridden.

About interpolation functions, you are correct, the second set does not work due to the limitation of the SDK. SDK expects key/value pairs to be constants, not arbitrary expressions. This made implementation somewhat easier and is not really fundamental limitation. There are no plans to lift this though, as the expressions can be usually rewritten.

lasyakoechlin commented 4 years ago

Awesome, yes, it needs to be an https-based image. Thanks for the help!