@polar/plugin-draw
Version:
Draw plugin for POLAR that adds draw interactions to the map, allowing users to place various shapes and texts.
63 lines (54 loc) • 2.2 kB
text/typescript
import { PolarActionContext } from '@polar/lib-custom-types'
import { getSnaps } from '@polar/plugin-draw'
import Draw from 'ol/interaction/Draw'
import Snap from 'ol/interaction/Snap'
import { Feature as GeoJsonFeature, MultiPolygon, Polygon } from 'geojson'
import { booleanIntersects } from '@turf/boolean-intersects'
import { union } from '@turf/union'
import { GeoJSON } from 'ol/format'
import Feature from 'ol/Feature'
import { CreateInteractionsPayload, DrawState, DrawGetters } from '../../types'
const converter = new GeoJSON()
export const createMergeInteractions = (
{ rootGetters }: PolarActionContext<DrawState, DrawGetters>,
{ drawSource }: CreateInteractionsPayload
) => {
const draw = new Draw({ type: 'Polygon' })
// @ts-expect-error | internal hack to detect it in @polar/plugin-pins and @polar/plugin-gfi
draw._isDrawPlugin = true
draw.on('drawend', (e) => {
const mergePolygon = converter.writeFeatureObject(
e.feature
) as GeoJsonFeature<Polygon>
const drawFeatures = drawSource.getFeatures()
// sort everything into a.) things to combine b.) things not to touch
const intersectedPolygons: GeoJsonFeature<Polygon | MultiPolygon>[] = []
const nextFeatures = drawFeatures.reduce((accumulator, drawFeature) => {
const type = drawFeature.getGeometry()?.getType() ?? ''
const drawFeatureAsGeoJson = converter.writeFeatureObject(drawFeature)
if (
['Polygon', 'MultiPolygon'].includes(type) &&
booleanIntersects(mergePolygon, drawFeatureAsGeoJson)
) {
intersectedPolygons.push(
drawFeatureAsGeoJson as GeoJsonFeature<Polygon | MultiPolygon>
)
} else {
accumulator.push(drawFeature)
}
return accumulator
}, [] as Feature[])
const mergedFeature = union({
type: 'FeatureCollection',
features: [mergePolygon, ...intersectedPolygons],
})
nextFeatures.push(converter.readFeature(mergedFeature) as Feature)
drawSource.clear()
drawSource.addFeatures(nextFeatures)
})
return [
draw,
...getSnaps(rootGetters.map, rootGetters.configuration?.draw?.snapTo || []),
new Snap({ source: drawSource }),
]
}