@operato/scene-openlayers 8.0.0-beta.1 → 9.0.0-beta.0

Sign up to get free protection for your applications and to get access to all the features.
package/src/ol-path.ts_x DELETED
@@ -1,368 +0,0 @@
1
- /*
2
- * Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { Component, RectPath, Shape } from '@hatiolab/things-scene'
6
-
7
- const NATURE = {
8
- mutable: false,
9
- resizable: true,
10
- rotatable: true,
11
- properties: [
12
- {
13
- type: 'id-input',
14
- label: 'target-map',
15
- name: 'targetMap',
16
- property: {
17
- component: 'google-map'
18
- }
19
- },
20
- {
21
- type: 'checkbox',
22
- label: 'show-path',
23
- name: 'showPath'
24
- },
25
- {
26
- type: 'checkbox',
27
- label: 'show-intermediate-markers',
28
- name: 'showIntermediateMarkers'
29
- },
30
- {
31
- type: 'checkbox',
32
- label: 'start-end-marker-different-design',
33
- name: 'startEndMarkerDifferentDesign'
34
- }
35
- ],
36
- 'value-property': 'latlngs'
37
- // help: 'scene/component/gmap-path'
38
- }
39
-
40
- const EMPTY_MARKER_PATH = 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z'
41
- const END_MARKER_PATH =
42
- 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z M -2,-30 a 2,2 0 1,1 4,0 2,2 0 1,1 -4,0'
43
- const START_MARKER_PATH =
44
- 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z m -3,-34 l 0,8 l 8,-4 l -8,-4 z m -0,-0 l 0,8 l 8,-4 l -8,-4'
45
-
46
- export default class GMapPath extends RectPath(Shape) {
47
- _infoWindow: any
48
- _map: any
49
-
50
- dispose() {
51
- this.markers && this.markers.forEach(marker => marker.setMap(null))
52
-
53
- this.markers = null
54
- delete this._infoWindow
55
-
56
- super.dispose()
57
- }
58
-
59
- ready() {
60
- super.ready()
61
-
62
- if (this.isTemplate()) {
63
- return
64
- }
65
-
66
- this.onchangeTargetMap()
67
- }
68
-
69
- get map() {
70
- return this._map
71
- }
72
-
73
- findInfoWindow(type) {
74
- var eventSetting = (this.state.event && this.state.event[type]) || {}
75
-
76
- var infoWindow =
77
- /* event spec v1.0 */ eventSetting.infoWindow ||
78
- /* event spec v1.1 */ (eventSetting.action == 'infoWindow' && eventSetting.target)
79
-
80
- if (infoWindow) {
81
- return this.root.findById(infoWindow)
82
- }
83
- }
84
-
85
- getInfoContent(sceneInfoWindow, index) {
86
- var tpl = Component.template(sceneInfoWindow.model.frontSideTemplate)
87
- return (
88
- `<style>${sceneInfoWindow.model.style}</style>` +
89
- tpl({
90
- data: this.data,
91
- index
92
- })
93
- )
94
- }
95
-
96
- openInfoWindow(iw, index) {
97
- var content = this.getInfoContent(iw, index)
98
-
99
- if (!this.map) return
100
-
101
- var infoWindow = new google.maps.InfoWindow()
102
- infoWindow.setContent(content)
103
- infoWindow.open(this.map, this.markers[index])
104
-
105
- return infoWindow
106
- }
107
-
108
- buildMarkers() {
109
- if (!this.map) {
110
- return
111
- }
112
-
113
- let {
114
- latlngs = [],
115
- fillStyle: fillColor,
116
- alpha: fillOpacity = 1,
117
- strokeStyle: strokeColor,
118
- lineWidth: strokeWeight,
119
- showIntermediateMarkers = false,
120
- startEndMarkerDifferentDesign = true,
121
- showPath = false
122
- } = this.state
123
-
124
- if (showIntermediateMarkers) {
125
- var markers = latlngs.map(({ lat, lng }, index) => {
126
- if (startEndMarkerDifferentDesign) {
127
- return new google.maps.Marker({
128
- position: {
129
- lat: Number(lat) || 0,
130
- lng: Number(lng) || 0
131
- },
132
- map: this.map,
133
- icon: {
134
- path: index == 0 ? START_MARKER_PATH : index + 1 == latlngs.length ? END_MARKER_PATH : EMPTY_MARKER_PATH,
135
- fillColor,
136
- fillOpacity,
137
- strokeColor,
138
- strokeWeight
139
- },
140
- index
141
- })
142
- } else {
143
- return new google.maps.Marker({
144
- position: {
145
- lat: Number(lat) || 0,
146
- lng: Number(lng) || 0
147
- },
148
- map: this.map,
149
- icon: {
150
- path: EMPTY_MARKER_PATH,
151
- fillColor,
152
- fillOpacity,
153
- strokeColor,
154
- strokeWeight
155
- },
156
- index
157
- })
158
- }
159
- })
160
- } else {
161
- var spots =
162
- latlngs.length > 1 ? [latlngs[0], latlngs[latlngs.length - 1]] : latlngs.length == 1 ? [latlngs[0]] : []
163
-
164
- var markers = spots.map(({ lat, lng }, index) => {
165
- if (startEndMarkerDifferentDesign) {
166
- return new google.maps.Marker({
167
- position: {
168
- lat: Number(lat) || 0,
169
- lng: Number(lng) || 0
170
- },
171
- map: this.map,
172
- icon: {
173
- path: index == 0 ? START_MARKER_PATH : END_MARKER_PATH,
174
- fillColor,
175
- fillOpacity,
176
- strokeColor,
177
- strokeWeight
178
- },
179
- index
180
- })
181
- } else {
182
- return new google.maps.Marker({
183
- position: {
184
- lat: Number(lat) || 0,
185
- lng: Number(lng) || 0
186
- },
187
- map: this.map,
188
- icon: {
189
- path: EMPTY_MARKER_PATH,
190
- fillColor,
191
- fillOpacity,
192
- strokeColor,
193
- strokeWeight
194
- },
195
- index
196
- })
197
- }
198
- })
199
- }
200
-
201
- if (showPath) {
202
- this.trackPath = new google.maps.Polyline({
203
- path: latlngs,
204
- geodesic: true,
205
- strokeColor: '#FF0000',
206
- strokeOpacity: 1,
207
- strokeWeight: 4,
208
- map: this.map
209
- })
210
- }
211
-
212
- var infowindows = new Array(markers.length)
213
-
214
- markers.forEach((marker, index) => {
215
- marker.addListener('click', e => {
216
- var iw = this.findInfoWindow('tap')
217
- iw && this.openInfoWindow(iw, index)
218
-
219
- this.trigger('click', e.ya)
220
- })
221
- marker.addListener('mouseover', () => {
222
- var iw = this.findInfoWindow('hover')
223
- if (!iw) return
224
- infowindows[index] = this.openInfoWindow(iw, index)
225
- })
226
- marker.addListener('mouseout', () => {
227
- var infowindow = infowindows[index]
228
- infowindow && infowindow.close()
229
- infowindows[index] = null
230
- })
231
- })
232
-
233
- this.markers = markers
234
- }
235
-
236
- set markers(markers) {
237
- if (this._markers) {
238
- this._markers.forEach(marker => {
239
- marker.setMap(null)
240
- google.maps.event.clearInstanceListeners(marker)
241
- })
242
-
243
- delete this._markers
244
- }
245
-
246
- this._markers = markers
247
- }
248
-
249
- get markers() {
250
- if (!this._markers) {
251
- this.buildMarkers()
252
- }
253
-
254
- return this._markers
255
- }
256
-
257
- get trackPath() {
258
- return this._trackPath
259
- }
260
-
261
- set trackPath(trackPath) {
262
- if (this.trackPath) {
263
- this.trackPath.setMap(null)
264
- }
265
-
266
- this._trackPath = trackPath
267
- }
268
-
269
- render(context) {
270
- var { top, left, width, height } = this.state
271
-
272
- context.translate(left, top)
273
-
274
- // 마커 모양 그리기
275
- context.beginPath()
276
-
277
- context.moveTo(width / 2, height * 0.9)
278
- context.bezierCurveTo(width / 2.3, height * 0.6, 0, height / 2, 0, height / 4)
279
-
280
- context.ellipse(width / 2, height / 4, width / 2, height / 4, 0, Math.PI * 1, Math.PI * 0)
281
-
282
- context.bezierCurveTo(width, height / 2, width / 1.7, height * 0.6, width / 2, height * 0.9)
283
- context.closePath()
284
-
285
- context.translate(-left, -top)
286
- }
287
-
288
- get controls() {}
289
-
290
- onchangeTargetMap() {
291
- if (this.targetMap) {
292
- this._targetMap = null
293
- this._map = null
294
- }
295
-
296
- var id = this.get('targetMap')
297
- if (id !== undefined) {
298
- this._targetMap = this.root.findById(id)
299
-
300
- if (this.targetMap) {
301
- this._map = this.targetMap.map
302
-
303
- if (!this.map) {
304
- var listener = after => {
305
- if ('map' in after) {
306
- this._map = after.map
307
- this.markers && this.markers.forEach(marker => marker.setMap(this.map))
308
-
309
- this.targetMap.off('change', listener)
310
- }
311
- }
312
- this.targetMap.on('change', listener)
313
- } else {
314
- this.markers && this.markers.forEach(marker => marker.setMap(this.map))
315
- }
316
- }
317
- }
318
- }
319
-
320
- get targetMap() {
321
- return this._targetMap
322
- }
323
-
324
- onchange(after, before) {
325
- if ('targetMap' in after) {
326
- this.onchangeTargetMap()
327
- }
328
-
329
- if ('latlngs' in after) {
330
- this.buildMarkers()
331
- }
332
-
333
- if (('fillStyle' in after || 'strokeStyle' in after || 'lineWidth' in after) && this.marker) {
334
- let {
335
- fillStyle: fillColor,
336
- alpha: fillOpacity = 1,
337
- strokeStyle: strokeColor,
338
- lineWidth: strokeWeight
339
- } = this.state
340
-
341
- this.marker.setIcon({
342
- path: MARKER_PATH,
343
- fillColor,
344
- fillOpacity,
345
- strokeColor,
346
- strokeWeight
347
- })
348
- }
349
-
350
- super.onchange && super.onchange(after, before)
351
- }
352
-
353
- get latlngs() {
354
- return this.getState('latlngs')
355
- }
356
-
357
- set latlngs(latlngs) {
358
- this.setState({
359
- latlngs
360
- })
361
- }
362
-
363
- get nature() {
364
- return NATURE
365
- }
366
- }
367
-
368
- Component.register('gmap-path', GMapPath)
package/src/openlayers.ts DELETED
@@ -1,282 +0,0 @@
1
- /*
2
- * Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- // @ts-ignore
6
- import OpenLayersStyle from '!!text-loader!ol/ol.css'
7
-
8
- import { Feature, Map, View } from 'ol'
9
- import { Circle as CircleStyle, Fill, Icon, Stroke, Style } from 'ol/style.js'
10
- import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
11
- import { Vector as VectorSource, OSM } from 'ol/source'
12
- import { fromLonLat } from 'ol/proj'
13
- import { Geometry, Point } from 'ol/geom'
14
-
15
- import { Component, HTMLOverlayContainer, Properties, ComponentNature, error } from '@hatiolab/things-scene'
16
-
17
- const MARKER_PATH =
18
- 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z M -2,-30 a 2,2 0 1,1 4,0 2,2 0 1,1 -4,0'
19
-
20
- const NATURE: ComponentNature = {
21
- mutable: false,
22
- resizable: true,
23
- rotatable: true,
24
- properties: [
25
- {
26
- type: 'number',
27
- label: 'latitude',
28
- name: 'lat',
29
- property: {
30
- step: 0.000001,
31
- max: 90,
32
- min: -90
33
- }
34
- },
35
- {
36
- type: 'number',
37
- label: 'longitude',
38
- name: 'lng',
39
- property: {
40
- step: 0.000001,
41
- min: -180,
42
- max: 180
43
- }
44
- },
45
- {
46
- type: 'number',
47
- label: 'zoom',
48
- name: 'zoom'
49
- },
50
- {
51
- type: 'boolean',
52
- label: 'show-marker',
53
- name: 'showMarker'
54
- }
55
- ],
56
- 'value-property': 'latlng',
57
- help: 'scene/component/openlayers'
58
- }
59
-
60
- function getGlobalScale(component: Component) {
61
- var scale = { x: 1, y: 1 }
62
- var parent = component
63
-
64
- while (parent) {
65
- let { x, y } = parent.get('scale') || { x: 1, y: 1 }
66
- scale.x *= x || 1
67
- scale.y *= y || 1
68
-
69
- parent = parent.parent
70
- }
71
- return scale
72
- }
73
-
74
- export default class Openlayers extends HTMLOverlayContainer {
75
- static markerStyle: Style = new Style({
76
- image: new Icon({
77
- src:
78
- 'data:image/svg+xml;charset=utf-8,' +
79
- encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">' + MARKER_PATH + '</svg>'),
80
- anchor: [0.5, 1]
81
- })
82
- })
83
-
84
- _anchor?: HTMLDivElement
85
- _map: Map | null = null
86
- _listenTo?: Component
87
- _listener?: Function
88
- _vectorSource?: VectorSource<Feature>
89
- _marker: Feature | null = null
90
-
91
- get eventMap() {
92
- return {
93
- 'model-layer': {
94
- '(self)': {
95
- change: (after: any) => {
96
- after.scale && this.rescale()
97
- }
98
- }
99
- }
100
- }
101
- }
102
-
103
- /*
104
- * 부모의 스케일의 역으로 transform해서, scale을 1로 맞추어준다.
105
- */
106
- rescale() {
107
- var anchor = this._anchor
108
- if (!anchor) {
109
- return
110
- }
111
-
112
- var scale = getGlobalScale(this)
113
-
114
- var sx = 1 / scale.x
115
- var sy = 1 / scale.y
116
-
117
- var transform = `scale(${sx}, ${sy})`
118
-
119
- anchor!.style.transform = transform
120
- anchor!.style.transformOrigin = '0px 0px'
121
-
122
- var { width, height } = this.state
123
- anchor.style.width = width * scale.x + 'px'
124
- anchor.style.height = height * scale.y + 'px'
125
- }
126
-
127
- createElement() {
128
- super.createElement()
129
- this._anchor = document.createElement('div')
130
-
131
- const style = document.createElement('style')
132
- style.textContent = `
133
- ${OpenLayersStyle}
134
- `
135
-
136
- this.element.appendChild(style)
137
- this.element.appendChild(this._anchor)
138
-
139
- const { lat, lng, zoom, showMarker } = this.state
140
-
141
- // 지도의 중심 좌표
142
- const center = fromLonLat([lng || 126.9783882, lat || 37.5666103])
143
-
144
- // 타일 레이어 생성 (배경 지도)
145
- const tileLayer = new TileLayer({
146
- source: new OSM({
147
- attributions: ''
148
- })
149
- })
150
-
151
- // 벡터 레이어 생성
152
- const styles: { [name: string]: Style } = {
153
- route: new Style({
154
- stroke: new Stroke({
155
- width: 6,
156
- color: [237, 212, 0, 0.8]
157
- })
158
- }),
159
- marker: Openlayers.markerStyle,
160
- circle: new Style({
161
- image: new CircleStyle({
162
- radius: 7,
163
- stroke: new Stroke({
164
- color: 'black',
165
- width: 2
166
- })
167
- })
168
- })
169
- }
170
-
171
- const vectorSource = new VectorSource()
172
- const vectorLayer = new VectorLayer({
173
- source: vectorSource,
174
- style: function (feature) {
175
- return styles[feature.get('type')]
176
- }
177
- })
178
-
179
- // 지도 생성
180
- const map = new Map({
181
- target: this._anchor,
182
- layers: [tileLayer, vectorLayer],
183
- view: new View({
184
- center,
185
- zoom
186
- })
187
- })
188
-
189
- this._map = map
190
- this._vectorSource = vectorSource
191
-
192
- showMarker && this.refreshMarker()
193
-
194
- this.rescale()
195
- }
196
-
197
- get tagName() {
198
- return 'div'
199
- }
200
-
201
- get map() {
202
- return this._map
203
- }
204
-
205
- dispose() {
206
- super.dispose()
207
-
208
- delete this._anchor
209
- }
210
-
211
- setElementProperties(div: HTMLDivElement) {
212
- this.rescale()
213
- }
214
-
215
- refreshMarker() {
216
- const { showMarker, lat, lng } = this.state
217
-
218
- if (this._marker) {
219
- this.vectorSource?.removeFeature(this._marker)
220
- this._marker = null
221
- }
222
-
223
- if (showMarker) {
224
- // 지도의 중심 좌표
225
- const center = fromLonLat([lng || 126.9783882, lat || 37.5666103])
226
-
227
- this._marker = new Feature({
228
- type: 'circle',
229
- geometry: new Point(center)
230
- })
231
-
232
- this.vectorSource?.addFeatures([this._marker])
233
- }
234
- }
235
-
236
- onchange(after: Properties, before: Properties) {
237
- if ('zoom' in after) {
238
- const view = this.map?.getView()
239
- view?.setZoom(after.zoom)
240
- }
241
-
242
- if ('lat' in after || 'lng' in after) {
243
- let { lat, lng } = this.state
244
- const view = this.map?.getView()
245
- view?.setCenter(fromLonLat([lng, lat]))
246
-
247
- if (this._marker) {
248
- const geometry = this._marker.getGeometry()
249
- if (geometry instanceof Point) {
250
- geometry.setCoordinates(fromLonLat([lng, lat]))
251
- }
252
- }
253
- }
254
-
255
- if ('showMarker' in after) {
256
- this.refreshMarker()
257
- }
258
-
259
- super.onchange(after, before)
260
-
261
- this.rescale()
262
- }
263
-
264
- get latlng() {
265
- const { lat, lng } = this.state
266
- return { lat, lng }
267
- }
268
-
269
- set latlng(latlng) {
270
- this.setState(latlng)
271
- }
272
-
273
- get vectorSource() {
274
- return this._vectorSource
275
- }
276
-
277
- get nature() {
278
- return NATURE
279
- }
280
- }
281
-
282
- Component.register('openlayers', Openlayers)
@@ -1,4 +0,0 @@
1
- import openlayers from './openlayers'
2
- import olMarker from './ol-marker'
3
-
4
- export default [openlayers, olMarker]
@@ -1,16 +0,0 @@
1
- const icon = new URL('../../icons/ol-marker-template.png', import.meta.url).href
2
-
3
- export default {
4
- type: 'ol-marker',
5
- description: 'ol-marker',
6
- // group: 'geographic',
7
- group: 'etc',
8
- icon,
9
- model: {
10
- type: 'ol-marker',
11
- left: 10,
12
- top: 10,
13
- width: 55,
14
- height: 100
15
- }
16
- }
@@ -1,16 +0,0 @@
1
- const icon = new URL('../../icons/ol-path-template.png', import.meta.url).href
2
-
3
- export default {
4
- type: 'ol-path',
5
- description: 'ol-path',
6
- // group: 'geographic',
7
- group: 'etc',
8
- icon,
9
- model: {
10
- type: 'ol-path',
11
- left: 10,
12
- top: 10,
13
- width: 100,
14
- height: 20
15
- }
16
- }
@@ -1,16 +0,0 @@
1
- const icon = new URL('../../icons/openlayers-template.png', import.meta.url).href
2
-
3
- export default {
4
- type: 'openlayers',
5
- description: 'openlayers',
6
- // group: 'geographic',
7
- group: 'etc',
8
- icon,
9
- model: {
10
- type: 'openlayers',
11
- left: 10,
12
- top: 10,
13
- width: 100,
14
- height: 20
15
- }
16
- }