import { FeatureLike } from "ol/Feature"; import { LineString, Point, Polygon } from "ol/geom"; import Geometry, { Type } from "ol/geom/Geometry"; import { Fill, RegularShape, Stroke, Style, Text } from "ol/style"; import CircleStyle from "ol/style/Circle"; import { getArea, getLength } from 'ol/sphere' import { Modify } from "ol/interaction"; import { getMeasureShowSegments } from "../../../store/map"; export const style = new Style({ fill: new Fill({ color: 'rgba(255, 255, 255, 0.2)', }), stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.5)', lineDash: [10, 10], width: 2, }), image: new CircleStyle({ radius: 5, stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.7)', }), fill: new Fill({ color: 'rgba(255, 255, 255, 0.2)', }), }), }); export const labelStyle = new Style({ text: new Text({ font: '14px Calibri,sans-serif', fill: new Fill({ color: 'rgba(255, 255, 255, 1)', }), backgroundFill: new Fill({ color: 'rgba(0, 0, 0, 0.7)', }), padding: [3, 3, 3, 3], textBaseline: 'bottom', offsetY: -15, }), image: new RegularShape({ radius: 8, points: 3, angle: Math.PI, displacement: [0, 10], fill: new Fill({ color: 'rgba(0, 0, 0, 0.7)', }), }), }); export const tipStyle = new Style({ text: new Text({ font: '12px Calibri,sans-serif', fill: new Fill({ color: 'rgba(255, 255, 255, 1)', }), backgroundFill: new Fill({ color: 'rgba(0, 0, 0, 0.4)', }), padding: [2, 2, 2, 2], textAlign: 'left', offsetX: 15, }), }); export const modifyStyle = new Style({ image: new CircleStyle({ radius: 5, stroke: new Stroke({ color: 'rgba(0, 0, 0, 0.7)', }), fill: new Fill({ color: 'rgba(0, 0, 0, 0.4)', }), }), text: new Text({ text: 'Drag to modify', font: '12px Calibri,sans-serif', fill: new Fill({ color: 'rgba(255, 255, 255, 1)', }), backgroundFill: new Fill({ color: 'rgba(0, 0, 0, 0.7)', }), padding: [2, 2, 2, 2], textAlign: 'left', offsetX: 15, }), }); export const segmentStyle = new Style({ text: new Text({ font: '12px Calibri,sans-serif', fill: new Fill({ color: 'rgba(255, 255, 255, 1)', }), backgroundFill: new Fill({ color: 'rgba(0, 0, 0, 0.4)', }), padding: [2, 2, 2, 2], textBaseline: 'bottom', offsetY: -12, }), image: new RegularShape({ radius: 6, points: 3, angle: Math.PI, displacement: [0, 8], fill: new Fill({ color: 'rgba(0, 0, 0, 0.4)', }), }), }); const formatLength = function (line: Geometry) { const length = getLength(line); let output; if (length > 100) { output = Math.round((length / 1000) * 100) / 100 + ' km'; } else { output = Math.round(length * 100) / 100 + ' m'; } return output; }; const formatArea = function (polygon: Geometry) { const area = getArea(polygon); let output; if (area > 10000) { output = Math.round((area / 1000000) * 100) / 100 + ' km\xB2'; } else { output = Math.round(area * 100) / 100 + ' m\xB2'; } return output; }; export function measureStyleFunction( map_id: string, feature: FeatureLike, drawType?: Type, tip?: string, setTipPoint?: React.Dispatch>, modify?: React.MutableRefObject ) { const styles = []; const geometry = feature.getGeometry(); const type = geometry?.getType(); const segmentStyles = [segmentStyle]; const segments = getMeasureShowSegments(map_id) if (!geometry) return let point, label, line; if (!drawType || drawType === type || type === 'Point') { styles.push(style); if (type === 'Polygon') { point = (geometry as Polygon).getInteriorPoint(); label = formatArea(geometry as Polygon); line = new LineString((geometry as Polygon).getCoordinates()[0]); } else if (type === 'LineString') { point = new Point((geometry as Polygon).getLastCoordinate()); label = formatLength(geometry as LineString); line = geometry; } } if (segments && line) { let count = 0; (line as LineString).forEachSegment(function (a, b) { const segment = new LineString([a, b]); const label = formatLength(segment); if (segmentStyles.length - 1 < count) { segmentStyles.push(segmentStyle.clone()); } const segmentPoint = new Point(segment.getCoordinateAt(0.5)); segmentStyles[count].setGeometry(segmentPoint); segmentStyles[count].getText()?.setText(label); styles.push(segmentStyles[count]); count++; }); } if (label) { labelStyle.setGeometry(point as Geometry); labelStyle.getText()?.setText(label); styles.push(labelStyle); } if ( tip && type === 'Point' && !modify?.current.getOverlay()?.getSource()?.getFeatures().length ) { setTipPoint?.(geometry as Point); tipStyle.getText()?.setText(tip); styles.push(tipStyle); } return styles; }