geojs 1.8.4 → 1.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ const $ = require('jquery');
2
+ const inherit = require('../inherit');
3
+ const registerAnnotation = require('../registry').registerAnnotation;
4
+ const markerFeature = require('../markerFeature');
5
+
6
+ const ellipseAnnotation = require('./ellipseAnnotation');
7
+
8
+ /**
9
+ * Circle annotation class.
10
+ *
11
+ * Circles are a subset of rectangles with a fixed aspect ratio.
12
+ *
13
+ * @class
14
+ * @alias geo.circleAnnotation
15
+ * @extends geo.annotation
16
+ *
17
+ * @param {geo.circleAnnotation.spec?} [args] Options for the annotation.
18
+ * @param {string} [annotationName='circle'] Override the annotation name.
19
+ */
20
+ var circleAnnotation = function (args, annotationName) {
21
+ 'use strict';
22
+ args = $.extend({}, args, {constraint: 1});
23
+ if (!(this instanceof circleAnnotation)) {
24
+ return new circleAnnotation(args, annotationName);
25
+ }
26
+ ellipseAnnotation.call(this, args, annotationName || 'circle');
27
+ };
28
+ inherit(circleAnnotation, ellipseAnnotation);
29
+ var circleRequiredFeatures = {};
30
+ circleRequiredFeatures[markerFeature.capabilities.feature] = true;
31
+ registerAnnotation('circle', circleAnnotation, circleRequiredFeatures);
32
+
33
+ module.exports = circleAnnotation;
@@ -0,0 +1,80 @@
1
+ const $ = require('jquery');
2
+ const inherit = require('../inherit');
3
+ const registerAnnotation = require('../registry').registerAnnotation;
4
+ const markerFeature = require('../markerFeature');
5
+
6
+ const annotationState = require('./annotation').state;
7
+ const rectangleAnnotation = require('./rectangleAnnotation');
8
+
9
+ /**
10
+ * Ellipse annotation class.
11
+ *
12
+ * Ellipses are always rendered as markers.
13
+ *
14
+ * @class
15
+ * @alias geo.ellipseAnnotation
16
+ * @extends geo.annotation
17
+ *
18
+ * @param {geo.ellipseAnnotation.spec?} [args] Options for the annotation.
19
+ * @param {string} [annotationName='ellipse'] Override the annotation name.
20
+ */
21
+ var ellipseAnnotation = function (args, annotationName) {
22
+ 'use strict';
23
+ if (!(this instanceof ellipseAnnotation)) {
24
+ return new ellipseAnnotation(args, annotationName);
25
+ }
26
+
27
+ rectangleAnnotation.call(this, args, annotationName || 'ellipse');
28
+
29
+ var m_this = this;
30
+
31
+ /**
32
+ * Get a list of renderable features for this annotation.
33
+ *
34
+ * @returns {array} An array of features.
35
+ */
36
+ this.features = function () {
37
+ var opt = m_this.options(),
38
+ state = m_this.state(),
39
+ features;
40
+ features = [];
41
+ if (opt.corners && opt.corners.length >= 4) {
42
+ const style = m_this.styleForState(state);
43
+ const w = ((opt.corners[0].x - opt.corners[1].x) ** 2 + (opt.corners[0].y - opt.corners[1].y) ** 2) ** 0.5;
44
+ const h = ((opt.corners[0].x - opt.corners[3].x) ** 2 + (opt.corners[0].y - opt.corners[3].y) ** 2) ** 0.5;
45
+ const radius = Math.max(w, h) / 2 / m_this.layer().map().unitsPerPixel(0);
46
+ const aspect = w ? h / w : 1e20;
47
+ const rotation = -Math.atan2(opt.corners[1].y - opt.corners[0].y, opt.corners[1].x - opt.corners[0].x);
48
+ features = [{
49
+ marker: {
50
+ x: (opt.corners[0].x + opt.corners[1].x + opt.corners[2].x + opt.corners[3].x) / 4,
51
+ y: (opt.corners[0].y + opt.corners[1].y + opt.corners[2].y + opt.corners[3].y) / 4,
52
+ style: $.extend(
53
+ {}, style,
54
+ {
55
+ radius: radius,
56
+ symbolValue: aspect,
57
+ rotation: rotation,
58
+ strokeOffset: 0,
59
+ radiusIncludesStroke: false,
60
+ scaleWithZoom: markerFeature.scaleMode.fill,
61
+ rotateWithMap: true,
62
+ strokeOpacity: style.stroke === false ? 0 : style.strokeOpacity,
63
+ fillOpacity: style.fill === false ? 0 : style.fillOpacity
64
+ })
65
+ }
66
+ }];
67
+ }
68
+ if (state === annotationState.edit) {
69
+ m_this._addEditHandles(features, opt.corners);
70
+ }
71
+ return features;
72
+ };
73
+ };
74
+ inherit(ellipseAnnotation, rectangleAnnotation);
75
+
76
+ var ellipseRequiredFeatures = {};
77
+ ellipseRequiredFeatures[markerFeature.capabilities.feature] = true;
78
+ registerAnnotation('ellipse', ellipseAnnotation, ellipseRequiredFeatures);
79
+
80
+ module.exports = ellipseAnnotation;
@@ -0,0 +1,21 @@
1
+ const annotation = require('./annotation');
2
+
3
+ /**
4
+ * @namespace geo.annotation
5
+ */
6
+ module.exports = {
7
+ state: annotation.state,
8
+ actionOwner: annotation.actionOwner,
9
+ annotation: annotation.annotation,
10
+ _editHandleFeatureLevel: annotation._editHandleFeatureLevel,
11
+ defaultEditHandleStyle: annotation.defaultEditHandleStyle,
12
+ constrainAspectRatio: annotation.constrainAspectRatio,
13
+ baseAnnotation: annotation,
14
+ circleAnnotation: require('./circleAnnotation'),
15
+ ellipseAnnotation: require('./ellipseAnnotation'),
16
+ lineAnnotation: require('./lineAnnotation'),
17
+ pointAnnotation: require('./pointAnnotation'),
18
+ polygonAnnotation: require('./polygonAnnotation'),
19
+ rectangleAnnotation: require('./rectangleAnnotation'),
20
+ squareAnnotation: require('./squareAnnotation')
21
+ };
@@ -0,0 +1,344 @@
1
+ const $ = require('jquery');
2
+ const inherit = require('../inherit');
3
+ const registerAnnotation = require('../registry').registerAnnotation;
4
+ const lineFeature = require('../lineFeature');
5
+
6
+ const annotation = require('./annotation').annotation;
7
+ const annotationState = require('./annotation').state;
8
+ const continuousVerticesActions = require('./annotation').continuousVerticesActions;
9
+ const continuousVerticesProcessAction = require('./annotation').continuousVerticesProcessAction;
10
+
11
+ /**
12
+ * Line annotation specification. Extends {@link geo.annotation.spec}.
13
+ *
14
+ * @typedef {object} geo.lineAnnotation.spec
15
+ * @extends geo.annotation.spec
16
+ * @property {geo.geoPosition[]} [vertices] A list of vertices in map gcs
17
+ * coordinates.
18
+ * @property {geo.geoPosition[]} [coordinates] An alternate name for
19
+ * `vertices`.
20
+ * @property {geo.lineFeature.styleSpec} [style] The style to apply to a
21
+ * finished line. This uses styles for {@link geo.lineFeature}.
22
+ * @property {geo.lineFeature.styleSpec} [editStyle] The style to apply to a
23
+ * line in edit mode.
24
+ */
25
+
26
+ /**
27
+ * Line annotation class.
28
+ *
29
+ * @class
30
+ * @alias geo.lineAnnotation
31
+ * @extends geo.annotation
32
+ *
33
+ * @param {geo.lineAnnotation.spec?} [args] Options for the annotation.
34
+ */
35
+ var lineAnnotation = function (args) {
36
+ 'use strict';
37
+ if (!(this instanceof lineAnnotation)) {
38
+ return new lineAnnotation(args);
39
+ }
40
+
41
+ args = $.extend(true, {}, {
42
+ style: {
43
+ line: function (d) {
44
+ /* Return an array that has the same number of items as we have
45
+ * vertices. */
46
+ return Array.apply(null, Array(m_this.options('vertices').length)).map(
47
+ function () { return d; });
48
+ },
49
+ position: function (d, i) {
50
+ return m_this.options('vertices')[i];
51
+ },
52
+ strokeColor: {r: 0, g: 0, b: 0},
53
+ strokeOpacity: 1,
54
+ strokeWidth: 3,
55
+ closed: false,
56
+ lineCap: 'butt',
57
+ lineJoin: 'miter'
58
+ },
59
+ highlightStyle: {
60
+ strokeWidth: 5
61
+ },
62
+ createStyle: {
63
+ line: function (d) {
64
+ /* Return an array that has the same number of items as we have
65
+ * vertices. */
66
+ return Array.apply(null, Array(m_this.options('vertices').length)).map(
67
+ function () { return d; });
68
+ },
69
+ position: function (d, i) {
70
+ return m_this.options('vertices')[i];
71
+ },
72
+ strokeColor: {r: 0, g: 0, b: 1},
73
+ strokeOpacity: 1,
74
+ strokeWidth: 3,
75
+ closed: false,
76
+ lineCap: 'butt',
77
+ lineJoin: 'miter'
78
+ }
79
+ }, args || {});
80
+ args.vertices = args.vertices || args.coordinates || [];
81
+ delete args.coordinates;
82
+ annotation.call(this, 'line', args);
83
+
84
+ var m_this = this,
85
+ s_actions = this.actions,
86
+ s_processEditAction = this.processEditAction;
87
+
88
+ /**
89
+ * Get a list of renderable features for this annotation.
90
+ *
91
+ * @returns {array} An array of features.
92
+ */
93
+ this.features = function () {
94
+ var opt = m_this.options(),
95
+ state = m_this.state(),
96
+ features;
97
+ switch (state) {
98
+ case annotationState.create:
99
+ features = [{
100
+ line: {
101
+ line: opt.vertices,
102
+ style: m_this.styleForState(state)
103
+ }
104
+ }];
105
+ break;
106
+ default:
107
+ features = [{
108
+ line: {
109
+ line: opt.vertices,
110
+ style: m_this.styleForState(state)
111
+ }
112
+ }];
113
+ if (state === annotationState.edit) {
114
+ m_this._addEditHandles(features, opt.vertices, undefined, !m_this.style('closed'));
115
+ }
116
+ break;
117
+ }
118
+ return features;
119
+ };
120
+
121
+ /**
122
+ * Get and optionally set coordinates associated with this annotation in the
123
+ * map gcs coordinate system.
124
+ *
125
+ * @param {geo.geoPosition[]} [coordinates] An optional array of coordinates
126
+ * to set.
127
+ * @returns {geo.geoPosition[]} The current array of coordinates.
128
+ */
129
+ this._coordinates = function (coordinates) {
130
+ if (coordinates) {
131
+ m_this.options('vertices', coordinates);
132
+ }
133
+ return m_this.options('vertices');
134
+ };
135
+
136
+ /**
137
+ * Handle a mouse move on this annotation.
138
+ *
139
+ * @param {geo.event} evt The mouse move event.
140
+ * @returns {boolean} Truthy to update the annotation, falsy to not
141
+ * update anything.
142
+ */
143
+ this.mouseMove = function (evt) {
144
+ if (m_this.state() !== annotationState.create) {
145
+ return;
146
+ }
147
+ var vertices = m_this.options('vertices');
148
+ if (vertices.length) {
149
+ vertices[vertices.length - 1] = evt.mapgcs;
150
+ return true;
151
+ }
152
+ };
153
+
154
+ /**
155
+ * Handle a mouse click on this annotation. If the event is processed,
156
+ * evt.handled should be set to `true` to prevent further processing.
157
+ *
158
+ * @param {geo.event} evt The mouse click event.
159
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if
160
+ * the annotation was completed (changed from create to done state),
161
+ * `'remove'` if the annotation should be removed, falsy to not update
162
+ * anything.
163
+ */
164
+ this.mouseClick = function (evt) {
165
+ var layer = m_this.layer();
166
+ if (m_this.state() !== annotationState.create || !layer) {
167
+ return;
168
+ }
169
+ var end = !!evt.buttonsDown.right, skip;
170
+ if (!evt.buttonsDown.left && !evt.buttonsDown.right) {
171
+ return;
172
+ }
173
+ var vertices = m_this.options('vertices');
174
+ if (evt.buttonsDown.right && !vertices.length) {
175
+ return;
176
+ }
177
+ evt.handled = true;
178
+ if (evt.buttonsDown.left) {
179
+ if (vertices.length) {
180
+ if (vertices.length >= 2 && layer.displayDistance(
181
+ vertices[vertices.length - 2], null, evt.map, 'display') <=
182
+ layer.options('adjacentPointProximity')) {
183
+ skip = true;
184
+ if (m_this._lastClick &&
185
+ evt.time - m_this._lastClick < layer.options('dblClickTime')) {
186
+ end = true;
187
+ }
188
+ } else if (vertices.length >= 2 && layer.displayDistance(
189
+ vertices[0], null, evt.map, 'display') <=
190
+ layer.options('finalPointProximity')) {
191
+ end = 'close';
192
+ } else {
193
+ vertices[vertices.length - 1] = evt.mapgcs;
194
+ }
195
+ } else {
196
+ vertices.push(evt.mapgcs);
197
+ }
198
+ if (!end && !skip) {
199
+ vertices.push(evt.mapgcs);
200
+ }
201
+ m_this._lastClick = evt.time;
202
+ m_this._lastClickVertexCount = vertices.length;
203
+ }
204
+ if (end) {
205
+ if (vertices.length < 3) {
206
+ return 'remove';
207
+ }
208
+ vertices.pop();
209
+ m_this.options('style').closed = end === 'close';
210
+ m_this.state(annotationState.done);
211
+ return 'done';
212
+ }
213
+ return !skip;
214
+ };
215
+
216
+ /**
217
+ * Return actions needed for the specified state of this annotation.
218
+ *
219
+ * @param {string} [state] The state to return actions for. Defaults to
220
+ * the current state.
221
+ * @returns {geo.actionRecord[]} A list of actions.
222
+ */
223
+ this.actions = function (state) {
224
+ return continuousVerticesActions(m_this, s_actions, state, 'line', arguments);
225
+ };
226
+
227
+ /**
228
+ * Process any actions for this annotation.
229
+ *
230
+ * @param {geo.event} evt The action event.
231
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if the
232
+ * annotation was completed (changed from create to done state),
233
+ * `'remove'` if the annotation should be removed, falsy to not update
234
+ * anything.
235
+ */
236
+ this.processAction = function (evt) {
237
+ return continuousVerticesProcessAction(m_this, evt, 'line');
238
+ };
239
+
240
+ /**
241
+ * Return the coordinates to be stored in a geojson geometry object.
242
+ *
243
+ * @param {string|geo.transform|null} [gcs] `undefined` to use the interface
244
+ * gcs, `null` to use the map gcs, or any other transform.
245
+ * @returns {array} An array of flattened coordinates in the interface gcs
246
+ * coordinate system. `undefined` if this annotation is incomplete.
247
+ */
248
+ this._geojsonCoordinates = function (gcs) {
249
+ var src = m_this.coordinates(gcs);
250
+ if (!src || src.length < 2 || m_this.state() === annotationState.create) {
251
+ return;
252
+ }
253
+ var coord = [];
254
+ for (var i = 0; i < src.length; i += 1) {
255
+ coord.push([src[i].x, src[i].y]);
256
+ }
257
+ return coord;
258
+ };
259
+
260
+ /**
261
+ * Return the geometry type that is used to store this annotation in geojson.
262
+ *
263
+ * @returns {string} A geojson geometry type.
264
+ */
265
+ this._geojsonGeometryType = function () {
266
+ return 'LineString';
267
+ };
268
+
269
+ /**
270
+ * Return a list of styles that should be preserved in a geojson
271
+ * representation of the annotation.
272
+ *
273
+ * @returns {string[]} A list of style names to store.
274
+ */
275
+ this._geojsonStyles = function () {
276
+ return [
277
+ 'closed', 'lineCap', 'lineJoin', 'strokeColor', 'strokeOffset',
278
+ 'strokeOpacity', 'strokeWidth'];
279
+ };
280
+
281
+ /**
282
+ * Process any edit actions for this annotation.
283
+ *
284
+ * @param {geo.event} evt The action event.
285
+ * @returns {boolean|string} `true` to update the annotation, falsy to not
286
+ * update anything.
287
+ */
288
+ this.processEditAction = function (evt) {
289
+ switch (m_this._editHandle.handle.type) {
290
+ case 'vertex':
291
+ return m_this._processEditActionVertex(evt, true);
292
+ }
293
+ return s_processEditAction.apply(m_this, arguments);
294
+ };
295
+
296
+ /**
297
+ * Handle a mouse click on this annotation when in edit mode. If the event
298
+ * is processed, evt.handled should be set to `true` to prevent further
299
+ * processing.
300
+ *
301
+ * @param {geo.event} evt The mouse click event.
302
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if
303
+ * the annotation was completed (changed from create to done state),
304
+ * `'remove'` if the annotation should be removed, falsy to not update
305
+ * anything.
306
+ */
307
+ this.mouseClickEdit = function (evt) {
308
+ // if we get a left double click on an edge on a closed line, break the
309
+ // line at that edge
310
+ var layer = m_this.layer(),
311
+ handle = m_this._editHandle,
312
+ split;
313
+ // ensure we are in edit mode and this is a left click
314
+ if (m_this.state() !== annotationState.edit || !layer || !evt.buttonsDown.left) {
315
+ return;
316
+ }
317
+ // ensure this is an edge on a closed line
318
+ if (!handle || !handle.handle.selected || handle.handle.type !== 'edge' || !m_this.options('style').closed) {
319
+ return;
320
+ }
321
+ evt.handled = true;
322
+ if (m_this._lastClick && evt.time - m_this._lastClick < layer.options('dblClickTime')) {
323
+ split = true;
324
+ }
325
+ m_this._lastClick = evt.time;
326
+ if (split) {
327
+ var index = handle.handle.index,
328
+ curPts = m_this._coordinates(),
329
+ pts = curPts.slice(index + 1).concat(curPts.slice(0, index + 1));
330
+ m_this._coordinates(pts);
331
+ m_this.options('style').closed = false;
332
+ handle.handle.index = undefined;
333
+ return true;
334
+ }
335
+ };
336
+
337
+ };
338
+ inherit(lineAnnotation, annotation);
339
+
340
+ var lineRequiredFeatures = {};
341
+ lineRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
342
+ registerAnnotation('line', lineAnnotation, lineRequiredFeatures);
343
+
344
+ module.exports = lineAnnotation;
@@ -0,0 +1,208 @@
1
+ const $ = require('jquery');
2
+ const inherit = require('../inherit');
3
+ const util = require('../util');
4
+ const registerAnnotation = require('../registry').registerAnnotation;
5
+ const pointFeature = require('../pointFeature');
6
+
7
+ const annotation = require('./annotation').annotation;
8
+ const annotationState = require('./annotation').state;
9
+
10
+ /**
11
+ * Point annotation specification. Extends {@link geo.annotation.spec}.
12
+ *
13
+ * @typedef {object} geo.pointAnnotation.spec
14
+ * @extends geo.annotation.spec
15
+ * @property {geo.geoPosition} [position] A coordinate in map gcs coordinates.
16
+ * @property {geo.geoPosition[]} [coordinates] An array with one coordinate to
17
+ * use in place of `position`.
18
+ * @property {geo.pointFeature.styleSpec} [style] The style to apply to a
19
+ * finished point. This uses styles for {@link geo.pointFeature}.
20
+ * @property {boolean|number} [style.scaled=false] If `false`, the point is not
21
+ * scaled with zoom level. If `true`, the radius is based on the zoom level
22
+ * at first instantiation. If a number, the radius is used at the `scaled`
23
+ * zoom level.
24
+ * @property {geo.pointFeature.styleSpec} [editStyle] The style to apply to a
25
+ * point in edit mode.
26
+ */
27
+
28
+ /**
29
+ * Point annotation class.
30
+ *
31
+ * @class
32
+ * @alias geo.pointAnnotation
33
+ * @extends geo.annotation
34
+ *
35
+ * @param {geo.pointAnnotation.spec?} [args] Options for the annotation.
36
+ */
37
+ var pointAnnotation = function (args) {
38
+ 'use strict';
39
+ if (!(this instanceof pointAnnotation)) {
40
+ return new pointAnnotation(args);
41
+ }
42
+
43
+ args = $.extend(true, {}, {
44
+ style: {
45
+ fill: true,
46
+ fillColor: {r: 0, g: 1, b: 0},
47
+ fillOpacity: 0.25,
48
+ radius: 10,
49
+ scaled: false,
50
+ stroke: true,
51
+ strokeColor: {r: 0, g: 0, b: 0},
52
+ strokeOpacity: 1,
53
+ strokeWidth: 3
54
+ },
55
+ createStyle: {
56
+ fillColor: {r: 0.3, g: 0.3, b: 0.3},
57
+ fillOpacity: 0.25,
58
+ strokeColor: {r: 0, g: 0, b: 1}
59
+ },
60
+ highlightStyle: {
61
+ fillColor: {r: 0, g: 1, b: 1},
62
+ fillOpacity: 0.5,
63
+ strokeWidth: 5
64
+ }
65
+ }, args || {});
66
+ args.position = args.position || (args.coordinates ? args.coordinates[0] : undefined);
67
+ delete args.coordinates;
68
+ annotation.call(this, 'point', args);
69
+
70
+ var m_this = this;
71
+
72
+ /**
73
+ * Get a list of renderable features for this annotation.
74
+ *
75
+ * @returns {array} An array of features.
76
+ */
77
+ this.features = function () {
78
+ var opt = m_this.options(),
79
+ state = m_this.state(),
80
+ features, style, scaleOnZoom;
81
+ switch (state) {
82
+ case annotationState.create:
83
+ features = [];
84
+ break;
85
+ default:
86
+ style = m_this.styleForState(state);
87
+ if (opt.style.scaled || opt.style.scaled === 0) {
88
+ if (opt.style.scaled === true) {
89
+ opt.style.scaled = m_this.layer().map().zoom();
90
+ }
91
+ style = $.extend({}, style, {
92
+ radius: function () {
93
+ var radius = opt.style.radius,
94
+ zoom = m_this.layer().map().zoom();
95
+ if (util.isFunction(radius)) {
96
+ radius = radius.apply(m_this, arguments);
97
+ }
98
+ radius *= Math.pow(2, zoom - opt.style.scaled);
99
+ return radius;
100
+ }
101
+ });
102
+ scaleOnZoom = true;
103
+ }
104
+ features = [{
105
+ point: {
106
+ x: opt.position.x,
107
+ y: opt.position.y,
108
+ style: style,
109
+ scaleOnZoom: scaleOnZoom
110
+ }
111
+ }];
112
+ if (state === annotationState.edit) {
113
+ m_this._addEditHandles(
114
+ features, [opt.position],
115
+ {edge: false, center: false, resize: false, rotate: false});
116
+ }
117
+ break;
118
+ }
119
+ return features;
120
+ };
121
+
122
+ /**
123
+ * Get and optionally set coordinates associated with this annotation in the
124
+ * map gcs coordinate system.
125
+ *
126
+ * @param {geo.geoPosition[]} [coordinates] An optional array of coordinates
127
+ * to set.
128
+ * @returns {geo.geoPosition[]} The current array of coordinates.
129
+ */
130
+ this._coordinates = function (coordinates) {
131
+ if (coordinates && coordinates.length >= 1) {
132
+ m_this.options('position', coordinates[0]);
133
+ }
134
+ if (m_this.state() === annotationState.create) {
135
+ return [];
136
+ }
137
+ return [m_this.options('position')];
138
+ };
139
+
140
+ this._coordinateOption = 'position';
141
+
142
+ /**
143
+ * Handle a mouse click on this annotation. If the event is processed,
144
+ * evt.handled should be set to `true` to prevent further processing.
145
+ *
146
+ * @param {geo.event} evt The mouse click event.
147
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if
148
+ * the annotation was completed (changed from create to done state),
149
+ * `'remove'` if the annotation should be removed, falsy to not update
150
+ * anything.
151
+ */
152
+ this.mouseClick = function (evt) {
153
+ if (m_this.state() !== annotationState.create) {
154
+ return;
155
+ }
156
+ if (!evt.buttonsDown.left) {
157
+ return;
158
+ }
159
+ evt.handled = true;
160
+ m_this.options('position', evt.mapgcs);
161
+ m_this.state(annotationState.done);
162
+ return 'done';
163
+ };
164
+
165
+ /**
166
+ * Return a list of styles that should be preserved in a geojson
167
+ * representation of the annotation.
168
+ *
169
+ * @returns {string[]} A list of style names to store.
170
+ */
171
+ this._geojsonStyles = function () {
172
+ return [
173
+ 'fill', 'fillColor', 'fillOpacity', 'radius', 'scaled', 'stroke',
174
+ 'strokeColor', 'strokeOpacity', 'strokeWidth'];
175
+ };
176
+
177
+ /**
178
+ * Return the coordinates to be stored in a geojson geometry object.
179
+ *
180
+ * @param {string|geo.transform|null} [gcs] `undefined` to use the interface
181
+ * gcs, `null` to use the map gcs, or any other transform.
182
+ * @returns {array} An array of flattened coordinates in the interface gcs
183
+ * coordinate system. `undefined` if this annotation is incomplete.
184
+ */
185
+ this._geojsonCoordinates = function (gcs) {
186
+ var src = m_this.coordinates(gcs);
187
+ if (!src || m_this.state() === annotationState.create || src.length < 1 || src[0] === undefined) {
188
+ return;
189
+ }
190
+ return [src[0].x, src[0].y];
191
+ };
192
+
193
+ /**
194
+ * Return the geometry type that is used to store this annotation in geojson.
195
+ *
196
+ * @returns {string} A geojson geometry type.
197
+ */
198
+ this._geojsonGeometryType = function () {
199
+ return 'Point';
200
+ };
201
+ };
202
+ inherit(pointAnnotation, annotation);
203
+
204
+ var pointRequiredFeatures = {};
205
+ pointRequiredFeatures[pointFeature.capabilities.feature] = true;
206
+ registerAnnotation('point', pointAnnotation, pointRequiredFeatures);
207
+
208
+ module.exports = pointAnnotation;