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

List of unsupported or not working style elements #339

Open
ShapovalovKL opened this issue Jul 19, 2021 · 10 comments
Open

List of unsupported or not working style elements #339

ShapovalovKL opened this issue Jul 19, 2021 · 10 comments

Comments

@ShapovalovKL
Copy link

Hi,
When style rendered not as expected, it's hard to determine if its a bug in style/data or part of style is unsupported by ol-mapbox-style
It would be nice to have list of unsupported and not working elements from Mapbox Style Specification on the main page or in the docs. And when or if they will be supported. It also would be nice to have "strict" mode option enabling which would produce warnings or errors in console for unsupported elements
While trying to implement style for floor plan i found this elements not working:

  1. line-pattern
  2. line-offset (Not supported in ol. Will be supported: ?)
  3. fill-extrusion (Not supported in ol. Will be supported: no)
  4. symbol-sort-key

I created simple example of same Mapbox Style rendered with ol-mapbox-style (top) and mapbox-gl (bottom):
https://codesandbox.io/s/ol-mapbox-style-missing-features-wrg51?file=/main.js
In this example:

  1. line with line-pattern drawn as blue line
  2. lines with line-offset are invisible
  3. polygon with fill-extrusion is flat
  4. two points (text) with symbol-sort-key drawn one on top another (i originally tried using symbol-sort-key for icons, аnd found no mention of symbol-sort-key in git. Text labels overlapping each other may be because of another bug or missing declutter: true)

bug

Mapbox Style Specification links:
paint-line-line-pattern
paint-line-line-offset
fill-extrusion
layout-symbol-symbol-sort-key

@ahocevar
Copy link
Member

Creating a list of supported options would be a a welcome pull request. It should be easy to grep stylefunction.js for all properties, and see which ones are found in there. Those are the supported ones.

line-pattern is not supported, but line-dasharray could be used to make a line look like yours.

fill-extrusion should be easy to implement, if someone wants to take that on.

symbol-sort-key is also something that could be implemented quite easily. To avoid the overlapping labels, ol-mapbox-style should also configure Vector layers with declutter: true, not only VectorTile layers. This would also be an easy pull request.

Would you be able and willing to take on any of the above tasks and provide pull requests?

@StephaneBranly
Copy link

The line-offset, line-translate, and fill-translate properties should be fairly straightforward to implement.
I was thinking about using the translate property on Geometry objects. But this imply a temporary duplication of the feature.
What do you think?

Regarding the list of supported features, the grep script should be made available or we only need to provide a list that will be modified as we go along?

@nobodo
Copy link

nobodo commented Oct 17, 2022

Any idea how that line-offset could be implemented?

@ahocevar
Copy link
Member

Definitely not by using the translate() method of the geometry, which is only useful for line-translate and fill-translate. It would require creating an offset geometry, and assigning that to the geometry property of the used style (by using setGeometry()).

@nobodo
Copy link

nobodo commented Oct 18, 2022

I tried the following (main points briefly):

In case 'line-offset' is defined for 'line' type layer, get the original coordinates with feature.getGeometry().getFlatCoordinates() and store them to offsetCoordinates with the calculated offset, then create a new RenderFeature with 'LineString' type and the offsetCoordinates and set that to the style with style.setGeometry.

This works almost perfectly, but I get some strange quirks that on certain zoom levels the features get somehow mixed up so that some of the surrounding features are included in the style. The sources are MVT and all the quirks are clearly constrained to certain tiles.

Screenshot 2022-10-18 at 13 18 44

Screenshot 2022-10-18 at 13 18 55

Screenshot 2022-10-18 at 13 19 09

@ahocevar
Copy link
Member

Styles get reused, currently without checking for getGeometry(). That explains the quirks you're seeing. So you need to add such a check, and not reuse the style in this case.

@nobodo
Copy link

nobodo commented Oct 18, 2022

Ok, thanks, I'll try to fix the style usage.

Btw, for some reason I was not able to clone the geometry with the .clone() function which is available in openlayers geometry, but I don't know the ol-mapbox-style internals enough to understand the reason.

@ahocevar
Copy link
Member

It‘s because we‘re dealing with ol/render/Feature here, which only supports a subset of the full Feature API.

@StephaneBranly
Copy link

StephaneBranly commented Oct 18, 2022

I had experimented with implementing this offset. Here is the code snippet I had if it helps

const lineOffset = getValue(layer, 'paint', 'line-offset', zoom, f);
if (lineOffset) {
  let newGeometry = feature.clone().getGeometry();
  newGeometry.translate(dx,dy) // TODO : check how to get dx and dy from lineOffset
  feature.setGeometry(newGeometry)
  style.setGeometry(newGeometry);
  styles[stylesLength] = style;
}

@nobodo
Copy link

nobodo commented Oct 19, 2022

I was not able to use the clone either on geometry or feature. Also, to my understanding the translate is usable only for straight lines. For lines that consists of multiple segments, the proper offset needs to be calculated separately for each - basically the new segment should be moving in the 90 degree direction from the original.

I used this:

if (offset) {
  const offsetCoordinates = [];
  const geom = feature.getGeometry();
  const stride = geom.getStride();
  const coordinates = geom.getFlatCoordinates();
  for (
    let i = 0, ii = coordinates.length - stride;
    i < ii;
    i += stride
  ) {
    const x1 = coordinates[i];
    const y1 = coordinates[i + 1];
    const x2 = coordinates[i + stride];
    const y2 = coordinates[i + stride + 1];
    const angle = Math.atan2(y2 - y1, x2 - x1);
    const sin = Math.sin(angle) * offset;
    const cos = Math.cos(angle) * offset;
    offsetCoordinates[i] = x1 + sin;
    offsetCoordinates[i + 1] = y1 - cos;
    if (i == coordinates.length - stride * 2) {
      offsetCoordinates[i + 2] = x2 + sin;
      offsetCoordinates[i + 3] = y2 - cos;
    }
  }
  const offsetFeature = new RenderFeature(
    'LineString',
    offsetCoordinates,
    [offsetCoordinates.length],
    feature.getProperties(),
    feature.id_
  );
  style.setGeometry(offsetFeature);
}

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

No branches or pull requests

4 participants