diff --git a/src/components/ToolMenu/Draw/StylingDrawer/StylingComponent/index.tsx b/src/components/ToolMenu/Draw/StylingDrawer/StylingComponent/index.tsx index a899eb0cb..befd94418 100644 --- a/src/components/ToolMenu/Draw/StylingDrawer/StylingComponent/index.tsx +++ b/src/components/ToolMenu/Draw/StylingDrawer/StylingComponent/index.tsx @@ -1,12 +1,8 @@ -import * as React from 'react'; - -import { +import React, { useEffect, useState } from 'react'; -import OlParser from 'geostyler-openlayers-parser'; - import { Style as GsStyle } from 'geostyler-style'; @@ -15,24 +11,83 @@ import CardStyle, { CardStyleProps } from 'geostyler/dist/Component/CardStyle/CardStyle'; -import OlFeature from 'ol/Feature'; - -import OlLayerVector from 'ol/layer/Vector'; - -import VectorSource from 'ol/source/Vector'; - import { - StyleFunction, - StyleLike as OlStyleLike + StyleFunction as OlStyleFunction } from 'ol/style/Style'; -import { - MapUtil -} from '@terrestris/ol-util'; - import { useMap } from '@terrestris/react-geo/dist/Hook/useMap'; +import { + DigitizeUtil +} from '@terrestris/react-geo/dist/Util/DigitizeUtil'; + +import { + parseStyle +} from '../../../../../utils/parseStyle'; + +const defaultStyle: GsStyle = { + name: 'Default Style', + rules: [{ + name: 'Area', + symbolizers: [{ + kind: 'Fill', + color: '#00b72b', + outlineOpacity: 0.8, + opacity: 0.5, + fillOpacity: 0.8, + outlineWidth: 2, + outlineColor: '#00b72b' + }] + }, { + name: 'Line', + symbolizers: [{ + kind: 'Line', + color: '#00b72b', + width: 2, + opacity: 0.8 + }] + }, { + name: 'Point', + symbolizers: [{ + kind: 'Mark', + wellKnownName: 'circle', + color: '#00b72b', + strokeColor: '#00b72b', + strokeOpacity: 0.8, + opacity: 0.5, + radius: 7 + }], + filter: [ + '==', + 'label', + 'undefined' + ] + }, { + name: 'Text', + symbolizers: [{ + kind: 'Text', + label: '{{label}}', + size: 12, + font: [ + 'sans-serif' + ], + opacity: 0.8, + color: '#00b72b', + offset: [ + 5, + 5 + ], + haloColor: '#00b72b', + haloWidth: 1 + }], + filter: [ + '!=', + 'label', + 'undefined' + ] + }] +}; export type StylingComponentProps = CardStyleProps & {}; @@ -40,69 +95,6 @@ export const StylingComponent: React.FC = ({ ...passThroughProps }): JSX.Element => { - const defaultStyle: GsStyle = { - name: 'Default Style', - rules: [{ - name: 'Area', - symbolizers: [{ - kind: 'Fill', - color: '#00b72b', - outlineOpacity: 0.8, - opacity: 0.5, - fillOpacity: 0.8, - outlineWidth: 2, - outlineColor: '#00b72b' - }] - }, { - name: 'Line', - symbolizers: [{ - kind: 'Line', - color: '#00b72b', - width: 2, - opacity: 0.8 - }] - }, { - name: 'Point', - symbolizers: [{ - kind: 'Mark', - wellKnownName: 'circle', - color: '#00b72b', - strokeColor: '#00b72b', - strokeOpacity: 0.8, - opacity: 0.5, - radius: 7 - }], - filter: [ - '==', - 'label', - 'undefined' - ] - }, { - name: 'Text', - symbolizers: [{ - kind: 'Text', - label: '{{label}}', - size: 12, - font: [ - 'sans-serif' - ], - opacity: 0.8, - color: '#00b72b', - offset: [ - 5, - 5 - ], - haloColor: '#00b72b', - haloWidth: 1 - }], - filter: [ - '!=', - 'label', - 'undefined' - ] - }] - }; - const [style, setStyle] = useState(defaultStyle); const map = useMap(); @@ -112,73 +104,17 @@ export const StylingComponent: React.FC = ({ return; } - const olParser = new OlParser(); - - let drawVectorLayer = MapUtil.getLayerByName(map, 'react-geo_digitize') as OlLayerVector; - - const parseStyles = async () => { - let olStylePolygon: OlStyleLike; - let olStyleLineString: OlStyleLike; - let olStylePoint: OlStyleLike; - let olStyleText: OlStyleLike; - - for (const rule of style.rules) { - const newStyle: GsStyle = { - name: '', - rules: [rule] - }; - - const olStyle = await olParser.writeStyle(newStyle); - - if (!olStyle.output) { - return; - } - - if (rule.symbolizers[0].kind === 'Fill') { - olStylePolygon = olStyle.output; - } - - if (rule.symbolizers[0].kind === 'Text') { - olStyleText = olStyle.output; - } - - if (rule.symbolizers[0].kind === 'Line') { - olStyleLineString = olStyle.output; - } - - if (rule.symbolizers[0].kind === 'Mark') { - olStylePoint = olStyle.output; - } - } - - const drawLayerStyleFunction = (feature: OlFeature, resolution: number) => { - const geometryType = feature.getGeometry()?.getType(); - - if (!geometryType) { - return; - } - - if (['MultiPolygon', 'Polygon', 'Circle'].includes(geometryType)) { - return typeof olStylePolygon === 'function' ? olStylePolygon(feature, resolution) : olStylePolygon; - } - - if (['MultiLineString', 'LineString'].includes(geometryType)) { - return typeof olStyleLineString === 'function' ? olStyleLineString(feature, resolution) : olStyleLineString; - } + const setStyleToLayer = async () => { + const drawVectorLayer = DigitizeUtil.getDigitizeLayer(map); - if (['MultiPoint', 'Point'].includes(geometryType)) { - if (feature.get('label')) { - return typeof olStyleText === 'function' ? olStyleText(feature, resolution) : olStyleText; - } + const drawLayerStyleFunction = await parseStyle(style); - return typeof olStylePoint === 'function' ? olStylePoint(feature, resolution) : olStylePoint; - } - }; + drawVectorLayer.set('gsStyle', style); - drawVectorLayer.setStyle(drawLayerStyleFunction as StyleFunction); + drawVectorLayer.setStyle(drawLayerStyleFunction as OlStyleFunction); }; - parseStyles(); + setStyleToLayer(); }, [style, map]); return ( diff --git a/src/utils/parseStyle.ts b/src/utils/parseStyle.ts new file mode 100644 index 000000000..f3e7777f0 --- /dev/null +++ b/src/utils/parseStyle.ts @@ -0,0 +1,78 @@ + +import OlParser from 'geostyler-openlayers-parser'; + +import { + Style as GsStyle +} from 'geostyler-style'; + +import { + FeatureLike as OlFeatureLike +} from 'ol/Feature'; +import { + StyleFunction as OlStyleFunction, + StyleLike as OlStyleLike +} from 'ol/style/Style'; + +export const parseStyle = async (style: GsStyle): Promise => { + let olStylePolygon: OlStyleLike; + let olStyleLineString: OlStyleLike; + let olStylePoint: OlStyleLike; + let olStyleText: OlStyleLike; + + for (const rule of style.rules) { + const newStyle: GsStyle = { + name: '', + rules: [rule] + }; + + const olParser = new OlParser(); + + const olStyle = await olParser.writeStyle(newStyle); + + if (!olStyle.output) { + return; + } + + if (rule.symbolizers[0].kind === 'Fill') { + olStylePolygon = olStyle.output; + } + + if (rule.symbolizers[0].kind === 'Text') { + olStyleText = olStyle.output; + } + + if (rule.symbolizers[0].kind === 'Line') { + olStyleLineString = olStyle.output; + } + + if (rule.symbolizers[0].kind === 'Mark') { + olStylePoint = olStyle.output; + } + } + + const drawLayerStyleFunction = (feature: OlFeatureLike, resolution: number) => { + const geometryType = feature.getGeometry()?.getType(); + + if (!geometryType) { + return; + } + + if (['MultiPolygon', 'Polygon', 'Circle'].includes(geometryType)) { + return typeof olStylePolygon === 'function' ? olStylePolygon(feature, resolution) : olStylePolygon; + } + + if (['MultiLineString', 'LineString'].includes(geometryType)) { + return typeof olStyleLineString === 'function' ? olStyleLineString(feature, resolution) : olStyleLineString; + } + + if (['MultiPoint', 'Point'].includes(geometryType)) { + if (feature.get('label')) { + return typeof olStyleText === 'function' ? olStyleText(feature, resolution) : olStyleText; + } + + return typeof olStylePoint === 'function' ? olStylePoint(feature, resolution) : olStylePoint; + } + }; + + return drawLayerStyleFunction; +};