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

Update vectorlayer styling in map-cesium #207

Merged
merged 12 commits into from
Dec 8, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -220,20 +220,17 @@ export class RouteExampleCesiumComponent implements OnInit, OnDestroy {

let polygonStyle = new Style({
stroke: new Stroke({
color: '#0072a3',
color: '#FF7400',
width: 1
}),
fill: new Fill({
color: '#FFFFFF' + '99',
color: '#FF7400' + '99',

}),
});
styles.push(polygonStyle);
return styles;
},
fillColor: '#FFFFFF',
strokeColor: '#0072a3',
strokeWidth: 2,
clampToGround: false
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can find a better solution here so that the values are not duplicated in the object.

Here is how this object is used in the other mapping libraries

map-ol:

map-maplibre:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I found a way to access the style properties in a similar way as in map-maplibre. Therefore, I removed the duplicate entries.

Copy link
Member

Choose a reason for hiding this comment

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

nice.

}
})
Expand Down
36 changes: 35 additions & 1 deletion projects/map-cesium/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,45 @@ Instead of a new 3D layer service, the existing [@dlr-eoc/services-layers](https
#### Serving 3D content
At the moment there are not many services out there, which serve 3D data. If you have data in the right format ([Cesium 3D Tiles](https://github.com/CesiumGS/3d-tiles), [Cesium quantized-mesh](https://github.com/CesiumGS/quantized-mesh)) available, everything you need is a web server for making the data accessible to the app. To quickly test the 3D capabilities you could use [http-server](https://github.com/http-party/http-server) to host 3D tiles and terrain meshes locally. A useful tool for generating terrain in the quantized-mesh format is the [Cesium Terrain Builder Docker](https://github.com/tum-gis/cesium-terrain-builder-docker).

#### Styling geoJSON vector layer
GeoJSON layer in Cesium access the layer.options style property. To clamp a vector layer to the ground use `clampToGround: true` as an optional property of layer.options. Here is an example:
```
new VectorLayer({
id: 'geojson_test',
name: 'GeoJSON Vector Layer',
attribution: `© Attribution`,
type: 'geojson',
data: testData,
visible: true,
options: {
style: (feature: Feature) => {
let styles = [];

let polygonStyle = new Style({
stroke: new Stroke({
color: '#FF7400',
width: 1
}),
fill: new Fill({
color: '#FF7400' + '99',

}),
});
styles.push(polygonStyle);
return styles;
},
clampToGround: false
}
})
```

#### Notes
- Terrain has to be attributed with a new Cesium Credit object, see the example above.
- GeoJSON layer are supported, but they are always shown above imagery layers, regardless of their ordering index in the layer control. Therefore they should be added as overlays.
- As of 01/2023, WFS is not supported by Cesium yet.
- KmlDataSource does not support opacity change at the moment
- KmlDataSource does not support opacity change at the moment.
- The stroke-width of vector polygons in Cesium does not change on non Apple browsers. There seems to be an issue with the browser support for this feature.
- When a vector layer is clamped to the ground, Cesium does not display the stroke anymore. Cesium's proposed workaround at the moment is to include the stroke as additional polyline vector layer.


===
Expand Down
46 changes: 29 additions & 17 deletions projects/map-cesium/src/lib/map-cesium.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,28 +620,40 @@ export class MapCesiumService {

private create_geojson_layer(l: VectorLayer): GeoJsonDataSource {
const newGeoJsonDataSource = new GeoJsonDataSource();
// default GeoJsonDataSource values
let fillColor = GeoJsonDataSource.fill;
let strokeColor = GeoJsonDataSource.stroke;
let strokeWidth = GeoJsonDataSource.strokeWidth;
// default UKIS values
let fillColor = Color.fromCssColorString('#FFFFFF99');
let strokeColor = Color.fromCssColorString('#3399CC');
let strokeWidth = 1;
let strokeOpacity = 1;
let fillOpacity = 1;
let clamp = false;
if(l.options){
if(l.options['fillColor']){
fillColor = Object.freeze(Color.fromCssColorString(l.options['fillColor']));
}
if(l.options['strokeColor']){
strokeColor = Object.freeze(Color.fromCssColorString(l.options['strokeColor']));
}
if(l.options['strokeWidth']){
strokeWidth = l.options['strokeWidth'];

if(l.options && l.options.style){
const styleProperties = l.options.style(l.data)[0];
if(styleProperties){
fillColor = Color.fromCssColorString(styleProperties.fill_.color_) || fillColor;
Copy link
Member

Choose a reason for hiding this comment

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

It is not optimal to use private properties from OpenLayers here, but we can change that later.

Maybe we can define some common style properties.

l.options.style{
 fillColor?: string;
 strokeColor?: string;
 strokeWidth?: string;
 strokeOpacity?: number;
 fillOpacity?: number;
 circleRadius?: number;
 iconImg?: any;
 ...
}

@voinSR what do you think about it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This would be ideal.

strokeColor = Color.fromCssColorString(styleProperties.stroke_.color_) || strokeColor;
strokeWidth = styleProperties.stroke_.width_ || strokeWidth;
}
if(l.options['clampToGround']){
clamp = l.options['clampToGround'];
}
}
}
// as Cesium cannot handle an opacity for the whole datasource, we need to modify the color opacity,
// in case the cesium color already has an opacity value
if(fillColor.alpha != l.opacity){
fillOpacity = l.opacity*fillColor.alpha;
}else{
fillOpacity = l.opacity;
}
if(strokeColor.alpha != l.opacity){
strokeOpacity = l.opacity*strokeColor.alpha;
}else{
strokeOpacity = l.opacity;
}
const dataSourceOptions = {
fill: fillColor.withAlpha(l.opacity/1.5),
stroke: strokeColor.withAlpha(l.opacity),
fill: fillColor.withAlpha(fillOpacity),
stroke: strokeColor.withAlpha(strokeOpacity),
strokeWidth: strokeWidth,
clampToGround: clamp
} as GeoJsonDataSource.LoadOptions;
Expand All @@ -652,7 +664,7 @@ export class MapCesiumService {

newGeoJsonDataSource.load(l.data, dataSourceOptions);
newGeoJsonDataSource.show = l.visible;
newGeoJsonDataSource.name = l.id;
newGeoJsonDataSource.name = l.name;

this.dataSourceOpacity.set(l.id, l.opacity);
return newGeoJsonDataSource;
Expand Down