Skip to content

Commit 501ef82

Browse files
committed
hardcode lasso solution for OAF layers (WIP)
1 parent 69fa0a4 commit 501ef82

File tree

7 files changed

+146
-66
lines changed

7 files changed

+146
-66
lines changed

packages/plugins/Draw/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Feature: Add a `"translate"` mode that allows moving drawn features as they are.
66
- Feature: Add a `"snapTo"` key to the configuration that allows defining vector layers to snap to while drawing, editing, and translating.
7+
- Feature: Add a lasso mode that allows copying up features from a vector layer that are contained within the user's hand drawn polygon. This feature is currently without UI and needs to be started from the outside, see docs.
78

89
## 3.0.0
910

packages/plugins/Draw/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ draw: {
7878

7979
#### draw.lasso
8080

81+
This feature currently has no UI and can only be started with a programmatic `mapInstance.$store.dispatch('plugin/draw/setMode', 'lasso')` call.
82+
8183
| fieldName | type | description |
8284
| - | - | - |
8385
| id | string | The layer id of a vector layer to copy up vector features from. |

packages/plugins/Draw/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"CHANGELOG.md"
2525
],
2626
"dependencies": {
27-
"@turf/center-of-mass": "^7.2.0"
27+
"@turf/center-of-mass": "^7.2.0",
28+
"@polar/lib-get-features": "^3.0.0"
2829
},
2930
"peerDependencies": {
3031
"@masterportal/masterportalapi": "2.45.0",

packages/plugins/Draw/src/locales.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const resourcesDe = {
4242
},
4343
lasso: {
4444
notInZoomRange:
45-
'Der Layer "$t({{serviceName}})" wurde nicht für die Lasso-Funktion genutzt, da er auf der derzeitigen Zoomstufe nicht aktivierbar ist. Bitte zoomen Sie weiter rein.',
45+
'Der Layer "$t({{serviceName}})" wurde nicht für die Lasso-Funktion genutzt, da er auf der derzeitigen Zoomstufe nicht aktivierbar ist. Bitte passen Sie die Zoomstufe an, um die Lasso-Funktion zu nutzen.',
4646
},
4747
},
4848
},
@@ -90,7 +90,7 @@ export const resourcesEn = {
9090
},
9191
lasso: {
9292
notInZoomRange:
93-
'The layer "$t({{serviceName}})" was not used for the lasso as it is not activatable on the current zoom level. Please zoom in further.',
93+
'The layer "$t({{serviceName}})" was not used for the lasso as it is not activatable on the current zoom level. Please change the zoom level to use the lasso.',
9494
},
9595
},
9696
},

packages/plugins/Draw/src/store/createInteractions/createLassoInteractions.ts

Lines changed: 132 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,89 @@ import Draw from 'ol/interaction/Draw'
22
import Interaction from 'ol/interaction/Interaction'
33
import i18next from 'i18next'
44
import { rawLayerList } from '@masterportal/masterportalapi'
5-
import { PolarActionContext } from '@polar/lib-custom-types'
5+
import { MapConfig, PolarActionContext } from '@polar/lib-custom-types'
6+
import { Dispatch } from 'vuex'
7+
import { Feature, Map } from 'ol'
8+
import { Polygon } from 'ol/geom'
9+
import { getWfsFeatures } from '@polar/lib-get-features'
10+
import { FeatureCollection, Feature as GeoJsonFeature } from 'geojson'
611
import { DrawGetters, DrawState } from '../../types'
712

813
const loaderKey = 'drawLasso'
914

15+
// TODO un – refactor after done (actions/getters are mixed here)
16+
/* eslint-disable max-lines-per-function */
17+
18+
const getLassoIdsInZoomRange = (
19+
configuration: MapConfig,
20+
zoomLevel: number,
21+
dispatch: Dispatch
22+
) =>
23+
(configuration.draw?.lassos || []).reduce(
24+
(accumulator, { id, minZoom = true }) => {
25+
const layerConfig = configuration.layers?.find((layer) => id === layer.id)
26+
const toastAction = configuration.draw?.toastAction || ''
27+
if (
28+
minZoom &&
29+
layerConfig &&
30+
typeof layerConfig.minZoom !== 'undefined' &&
31+
zoomLevel < layerConfig.minZoom
32+
) {
33+
if (toastAction) {
34+
dispatch(
35+
toastAction,
36+
{
37+
type: 'info',
38+
text: i18next.t('plugins.draw.lasso.notInZoomRange', {
39+
serviceName: layerConfig.name || id,
40+
}),
41+
timeout: 10000,
42+
},
43+
{ root: true }
44+
)
45+
} else {
46+
console.warn(
47+
`Lasso not used with layer with id "${id}". (minZoom not reached)`
48+
)
49+
}
50+
return accumulator
51+
}
52+
accumulator.push(id)
53+
return accumulator
54+
},
55+
[] as string[]
56+
)
57+
58+
const getLassoRequests = (
59+
lassoIds: string[],
60+
lasso: Feature<Polygon>,
61+
map: Map
62+
) =>
63+
lassoIds.reduce((accumulator, id) => {
64+
const serviceDefinition = rawLayerList.getLayerWhere({ id })
65+
66+
// TODO add WFS support
67+
// getWfsFeatures(null, serviceDefinition.url, ) FILTER-ONLY atm
68+
69+
const [codeName, codeNumber] = map
70+
.getView()
71+
.getProjection()
72+
.getCode()
73+
.split(':')
74+
75+
const url = [
76+
serviceDefinition.url,
77+
'collections',
78+
serviceDefinition.collection,
79+
`items?f=json&limit=100&bbox=${lasso
80+
.getGeometry()
81+
?.getExtent()}&bbox-crs=http://www.opengis.net/def/crs/${codeName}/0/${codeNumber}&crs=http://www.opengis.net/def/crs/${codeName}/0/${codeNumber}`,
82+
].join('/')
83+
84+
accumulator.push(fetch(url))
85+
return accumulator
86+
}, [] as Promise<Response>[])
87+
1088
/*
1189
TODO use snippet to confirm the layer type worked on
1290
const source = (
@@ -24,8 +102,40 @@ TODO use snippet to confirm the layer type worked on
24102
}
25103
*/
26104

27-
// TODO un – refactor after done
28-
// eslint-disable-next-line max-lines-per-function
105+
const handleSettledRequests = (
106+
resolutions: PromiseSettledResult<Response>[],
107+
dispatch: Dispatch
108+
) =>
109+
Promise.all(
110+
(
111+
resolutions.filter((promiseSettledResult) => {
112+
if (promiseSettledResult.status === 'rejected') {
113+
console.error(promiseSettledResult.reason)
114+
// TODO toast
115+
return false
116+
}
117+
return true
118+
}) as PromiseFulfilledResult<Response>[]
119+
).map(
120+
async (resolution) => (await resolution.value.json()) as FeatureCollection
121+
)
122+
)
123+
124+
const handleFulfilledRequests = (
125+
featureCollections: FeatureCollection[],
126+
dispatch: Dispatch
127+
) =>
128+
dispatch('addFeatures', {
129+
geoJSON: {
130+
type: 'FeatureCollection',
131+
features: featureCollections.reduce(
132+
(accumulator, { features }) => accumulator.concat(features),
133+
[] as GeoJsonFeature[]
134+
),
135+
},
136+
// TODO filter with drawnLasso
137+
})
138+
29139
export default function ({
30140
rootGetters,
31141
commit,
@@ -36,65 +146,29 @@ export default function ({
36146
freehand: true,
37147
})
38148
const { addLoading, removeLoading } = rootGetters.configuration?.draw || {}
39-
// TODO un
40-
// eslint-disable-next-line max-lines-per-function
41149
draw.on('drawend', (e) => {
42150
dispatch('setMode', 'none')
43151

44-
const drawnLasso = e.feature
45-
const lassos = rootGetters.configuration.draw?.lassos || []
46-
const toastAction = rootGetters.configuration.draw?.toastAction || ''
47-
const promises = lassos.reduce((accumulator, { id, minZoom = true }) => {
48-
const layerConfig = rootGetters.configuration.layers?.find(
49-
(layer) => id === layer.id
50-
)
51-
if (
52-
minZoom &&
53-
layerConfig &&
54-
typeof layerConfig.minZoom !== 'undefined' &&
55-
rootGetters.zoomLevel < layerConfig.minZoom
56-
) {
57-
if (toastAction) {
58-
dispatch(toastAction, {
59-
type: 'info',
60-
text: i18next.t('plugins.draw.lasso.notInZoomRange', {
61-
serviceName: layerConfig.name || id,
62-
}),
63-
timeout: 10000,
64-
})
65-
} else {
66-
console.warn(
67-
`Lasso not used with layer with id "${id}". (minZoom not reached)`
68-
)
69-
}
70-
return accumulator
71-
}
72-
const serviceDefinition = rawLayerList.getLayerWhere({ id })
73-
74-
// TODO implement for OAF, use existing getFeatures for WFS
75-
// https://api.hamburg.de/datasets/v1/alkis_vereinfacht/collections/Flurstueck/items?f=json&limit=10&bbox=10.0872,53.5357,10.0883,53.5362
76-
77-
accumulator.push(new Promise(() => ({})))
78-
return accumulator
79-
}, [] as Promise<object>[])
80-
81-
Promise.all(promises)
82-
.then((resolutions) => {
83-
if (addLoading) {
84-
commit(addLoading, loaderKey, { root: true })
85-
}
86-
87-
// TODO parse resolutions
88-
// TODO filter with drawnLasso (we're probably just loading by bbox?)
89-
// TODO add as geoJSON to draw
90-
91-
console.warn(resolutions)
152+
const drawnLasso = e.feature as Feature<Polygon> // due to Draw 'type' param
153+
const lassoIds = getLassoIdsInZoomRange(
154+
rootGetters.configuration,
155+
rootGetters.zoomLevel,
156+
dispatch
157+
)
158+
const requests = getLassoRequests(lassoIds, drawnLasso, rootGetters.map)
92159

93-
dispatch('addFeatures', { geoJSON: {} })
94-
})
95-
.catch(() => {
96-
/* TODO at least toast something */
97-
})
160+
if (addLoading) {
161+
commit(addLoading, loaderKey, { root: true })
162+
}
163+
Promise.allSettled(requests)
164+
.then((settledRequests) =>
165+
handleSettledRequests(settledRequests, dispatch)
166+
)
167+
.then((fulfilledRequests) =>
168+
handleFulfilledRequests(fulfilledRequests, dispatch)
169+
)
170+
// TODO add toast, unexpected catastrophic error
171+
.catch(console.error)
98172
.finally(
99173
() => removeLoading && commit(removeLoading, loaderKey, { root: true })
100174
)

packages/types/custom/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## unpublished
44

55
- Feature: Add `snapTo` to `DrawConfiguration` for specification of layers to snap to.
6-
- Feature: Add `lassos` to `DrawConfiguration`. With this, `addLoading`, `removeLoading`, and `toastAction` have also been introduced to allow the feature to use other plugins via API calls.
6+
- Feature: Add `lassos` to `DrawConfiguration`. With this, `addLoading`, `removeLoading`, and `toastAction` have also been introduced to allow the feature to use other plugins via API calls, and `Lasso` itself has been introduced.
77

88
## 2.0.0
99

packages/types/custom/core.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,15 @@ export interface MeasureOptions {
195195
initialOption?: MeasureMode
196196
}
197197

198+
export interface Lasso {
199+
id: string
200+
minZoom: boolean
201+
}
202+
198203
export interface DrawConfiguration extends Partial<PluginOptions> {
199204
addLoading?: string
200205
enableOptions?: boolean
201-
lassos?: {
202-
id: string
203-
minZoom: boolean
204-
}[]
206+
lassos?: Lasso[]
205207
measureOptions?: MeasureOptions
206208
removeLoading?: string
207209
selectableDrawModes?: DrawMode[]

0 commit comments

Comments
 (0)