Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion examples/data/geojson-inline.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,23 @@
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [{
"features": [ {
"type": "Feature",
"properties": {
"n": 2,
"cat": 1
},
"geometries": [{
"type": "GeometryCollection",
"coordinates": [0.6, 0.6]
},{
"type": "GeometryCollection",
"coordinates": [0.7, 0.7]
},{
"type": "GeometryCollection",
"coordinates": [0.8, 0.8]
}]
},{
"type": "Feature",
"properties": {
"n": 2,
Expand Down
23 changes: 23 additions & 0 deletions src/stylefunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import {
v8 as spec,
} from '@maplibre/maplibre-gl-style-spec';
import mb2css from 'mapbox-to-css-font';
import {Feature} from 'ol';
import Map from 'ol/Map.js';
import {distance} from 'ol/coordinate.js';
import {getCenter} from 'ol/extent.js';
import {toPromise} from 'ol/functions.js';
import {GeometryCollection} from 'ol/geom.js';
import RenderFeature from 'ol/render/Feature.js';
import Circle from 'ol/style/Circle.js';
import Fill from 'ol/style/Fill.js';
Expand Down Expand Up @@ -554,7 +556,28 @@ export function stylefunction(
cameraObj.zoom = zoom;
cameraObj.distanceFromCenter = 0;
const featureGeometry = feature.getGeometry();

if (featureGeometry instanceof GeometryCollection) {
const geoms = featureGeometry.getGeometries();

for (const geom of geoms) {
const subFeature = new Feature({
...feature.getProperties(),
geometry: geom,
});

const subStyles = styleFunction(subFeature, resolution, onlyLayer);

if (subStyles && Array.isArray(subStyles)) {
styles.push(...subStyles);
}
}

return styles.length > 0 ? styles : undefined;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work. Styles are reused across styleFunction() calls, so you need to clone them, and each style needs to be configured with the geometry of the geometry collection.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure i understand what you mean, anyways i have removed the push of the substyle to the styles array because it was not necessary, so is this still relevant?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, what I wrote is still relevant. Also regarding a test case with nested geometry collections.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi, sorry for the long break, i ended up not needing this feature which is the reason i opened the issue in the first place, however i have some free time now and want to finish this up.
regarding this:

This won't work. Styles are reused across styleFunction() calls, so you need to clone them, and each style needs to be configured with the geometry of the geometry collection.

i don't understand why this won't work and what needs to be done in order for it to work, since i call the styleFunction() recursively for each sub geometry shouldn't it handle handle adding the individual styles to the styles array correctly?

also, i added a nested geometry collection to the geojson-inline.json and it seems to be working correctly, should i also add a test to stylefunction.test.js?

thanks for your patience

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why it appears to work is because OpenLayers takes care of correct rendering of all points of the GeometryCollection, and the last style will be used. With geometry collections with mixed types, that won't work so well.

Honestly, I cannot think of a way to deal with this properly. Maybe taking a look at how MapLibre deals with GeometryCollection geometries from GeoJSON sources could make sense.

}

const type = types[featureGeometry.getType()];

const map = olLayer.get('map');
if (map && map instanceof Map && type === 1) {
const size = map.getSize();
Expand Down