@mapgis/mapbox-gl-draw-radius 1.0.0 → 1.0.1
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.
- package/CHANGELOG +0 -0
- package/CONTRIBUTING.md +1 -0
- package/dist/radius-mode.js +109 -59
- package/dist/radius-mode.min.js +2 -2
- package/package.json +1 -1
- package/src/radius-mode.js +82 -53
package/package.json
CHANGED
package/src/radius-mode.js
CHANGED
|
@@ -11,6 +11,7 @@ import MapboxDraw from "@mapbox/mapbox-gl-draw";
|
|
|
11
11
|
import numeral from "numeral";
|
|
12
12
|
import _ from "lodash";
|
|
13
13
|
import lineDistance from "@turf/length";
|
|
14
|
+
import * as turf from "@turf/turf";
|
|
14
15
|
|
|
15
16
|
const RadiusMode = _.extend({}, MapboxDraw.modes.draw_line_string);
|
|
16
17
|
|
|
@@ -21,51 +22,72 @@ function createVertex(parentId, coordinates, path, selected) {
|
|
|
21
22
|
meta: "vertex",
|
|
22
23
|
parent: parentId,
|
|
23
24
|
coord_path: path,
|
|
24
|
-
active: selected ? "true" : "false"
|
|
25
|
+
active: selected ? "true" : "false",
|
|
25
26
|
},
|
|
26
27
|
geometry: {
|
|
27
28
|
type: "Point",
|
|
28
|
-
coordinates
|
|
29
|
-
}
|
|
29
|
+
coordinates,
|
|
30
|
+
},
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// create a circle-like polygon given a center point and radius
|
|
34
35
|
// https://stackoverflow.com/questions/37599561/drawing-a-circle-with-the-radius-in-miles-meters-with-mapbox-gl-js/39006388#39006388
|
|
35
|
-
function createGeoJSONCircle(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
36
|
+
function createGeoJSONCircle(
|
|
37
|
+
center,
|
|
38
|
+
radiusInKm,
|
|
39
|
+
parentId,
|
|
40
|
+
epsgCode,
|
|
41
|
+
points = 64
|
|
42
|
+
) {
|
|
43
|
+
if (epsgCode.includes("4326")) {
|
|
44
|
+
// 经纬度坐标系下绘制圆
|
|
45
|
+
const coords = {
|
|
46
|
+
latitude: center[1],
|
|
47
|
+
longitude: center[0],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const km = radiusInKm;
|
|
51
|
+
|
|
52
|
+
const ret = [];
|
|
53
|
+
// const distanceX = km / 111.32;
|
|
54
|
+
// const distanceY = km / 110.574;
|
|
55
|
+
const distanceX =
|
|
56
|
+
km / (111.32 * Math.cos((coords.latitude * Math.PI) / 180));
|
|
57
|
+
const distanceY = km / 110.574;
|
|
58
|
+
|
|
59
|
+
let theta;
|
|
60
|
+
let x;
|
|
61
|
+
let y;
|
|
62
|
+
for (let i = 0; i < points; i += 1) {
|
|
63
|
+
theta = (i / points) * (2 * Math.PI);
|
|
64
|
+
x = distanceX * Math.cos(theta);
|
|
65
|
+
y = distanceY * Math.sin(theta);
|
|
66
|
+
|
|
67
|
+
ret.push([coords.longitude + x, coords.latitude + y]);
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
ret.push(ret[0]);
|
|
70
|
+
return {
|
|
71
|
+
type: "Feature",
|
|
72
|
+
geometry: {
|
|
73
|
+
type: "Polygon",
|
|
74
|
+
coordinates: [ret],
|
|
75
|
+
},
|
|
76
|
+
properties: {
|
|
77
|
+
parent: parentId,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
} else {
|
|
81
|
+
// 墨卡托坐标系下绘制圆
|
|
82
|
+
const options = {
|
|
83
|
+
steps: 64,
|
|
84
|
+
units: "kilometers",
|
|
85
|
+
properties: { parent: parentId },
|
|
86
|
+
};
|
|
87
|
+
const circle = turf.circle(center, radiusInKm, options);
|
|
88
|
+
|
|
89
|
+
return circle;
|
|
90
|
+
}
|
|
69
91
|
}
|
|
70
92
|
|
|
71
93
|
function getDisplayMeasurements(feature) {
|
|
@@ -102,14 +124,14 @@ function getDisplayMeasurements(feature) {
|
|
|
102
124
|
metric: `${numeral(metricMeasurement).format(metricFormat)} ${metricUnits}`,
|
|
103
125
|
standard: `${numeral(standardMeasurement).format(
|
|
104
126
|
standardFormat
|
|
105
|
-
)} ${standardUnits}
|
|
127
|
+
)} ${standardUnits}`,
|
|
106
128
|
};
|
|
107
129
|
|
|
108
130
|
return displayMeasurements;
|
|
109
131
|
}
|
|
110
132
|
|
|
111
133
|
const doubleClickZoom = {
|
|
112
|
-
enable: ctx => {
|
|
134
|
+
enable: (ctx) => {
|
|
113
135
|
setTimeout(() => {
|
|
114
136
|
// First check we've got a map and some context.
|
|
115
137
|
if (
|
|
@@ -124,29 +146,29 @@ const doubleClickZoom = {
|
|
|
124
146
|
if (!ctx._ctx.store.getInitialConfigValue("doubleClickZoom")) return;
|
|
125
147
|
ctx.map.doubleClickZoom.enable();
|
|
126
148
|
}, 0);
|
|
127
|
-
}
|
|
149
|
+
},
|
|
128
150
|
};
|
|
129
|
-
RadiusMode.onSetup = function(opts) {
|
|
151
|
+
RadiusMode.onSetup = function (opts) {
|
|
130
152
|
const props = MapboxDraw.modes.draw_line_string.onSetup.call(this, opts);
|
|
131
153
|
const circle = this.newFeature({
|
|
132
154
|
type: "Feature",
|
|
133
155
|
properties: {
|
|
134
|
-
meta: "radius"
|
|
156
|
+
meta: "radius",
|
|
135
157
|
},
|
|
136
158
|
geometry: {
|
|
137
159
|
type: "Polygon",
|
|
138
|
-
coordinates: [[]]
|
|
139
|
-
}
|
|
160
|
+
coordinates: [[]],
|
|
161
|
+
},
|
|
140
162
|
});
|
|
141
163
|
this.addFeature(circle);
|
|
142
164
|
|
|
143
165
|
return {
|
|
144
166
|
...props,
|
|
145
|
-
circle
|
|
167
|
+
circle,
|
|
146
168
|
};
|
|
147
169
|
};
|
|
148
170
|
|
|
149
|
-
RadiusMode.clickAnywhere = function(state, e) {
|
|
171
|
+
RadiusMode.clickAnywhere = function (state, e) {
|
|
150
172
|
// this ends the drawing after the user creates a second point, triggering this.onStop
|
|
151
173
|
if (state.currentVertexPosition === 1) {
|
|
152
174
|
state.line.addCoordinate(0, e.lngLat.lng, e.lngLat.lat);
|
|
@@ -172,19 +194,26 @@ RadiusMode.clickAnywhere = function(state, e) {
|
|
|
172
194
|
return null;
|
|
173
195
|
};
|
|
174
196
|
|
|
175
|
-
RadiusMode.onMouseMove = function(state, e) {
|
|
197
|
+
RadiusMode.onMouseMove = function (state, e) {
|
|
176
198
|
MapboxDraw.modes.draw_line_string.onMouseMove.call(this, state, e);
|
|
177
199
|
const geojson = state.line.toGeoJSON();
|
|
178
200
|
const center = geojson.geometry.coordinates[0];
|
|
179
201
|
const radiusInKm = lineDistance(geojson, "kilometers");
|
|
180
|
-
const
|
|
202
|
+
const epsgCode =
|
|
203
|
+
this.map && this.map.crs ? this.map.crs.epsgCode : "EPSG:4326";
|
|
204
|
+
const circleFeature = createGeoJSONCircle(
|
|
205
|
+
center,
|
|
206
|
+
radiusInKm,
|
|
207
|
+
state.line.id,
|
|
208
|
+
epsgCode
|
|
209
|
+
);
|
|
181
210
|
circleFeature.properties.meta = "radius";
|
|
182
211
|
state.circle.setCoordinates(circleFeature.geometry.coordinates);
|
|
183
212
|
};
|
|
184
213
|
|
|
185
214
|
// creates the final geojson point feature with a radius property
|
|
186
215
|
// triggers draw.create
|
|
187
|
-
RadiusMode.onStop = function(state) {
|
|
216
|
+
RadiusMode.onStop = function (state) {
|
|
188
217
|
doubleClickZoom.enable(this);
|
|
189
218
|
|
|
190
219
|
this.activateUIButton();
|
|
@@ -199,7 +228,7 @@ RadiusMode.onStop = function(state) {
|
|
|
199
228
|
this.deleteFeature([state.line.id], { silent: true });
|
|
200
229
|
|
|
201
230
|
this.map.fire("draw.create", {
|
|
202
|
-
features: [state.circle.toGeoJSON()]
|
|
231
|
+
features: [state.circle.toGeoJSON()],
|
|
203
232
|
});
|
|
204
233
|
} else {
|
|
205
234
|
this.deleteFeature([state.line.id], { silent: true });
|
|
@@ -207,7 +236,7 @@ RadiusMode.onStop = function(state) {
|
|
|
207
236
|
}
|
|
208
237
|
};
|
|
209
238
|
|
|
210
|
-
RadiusMode.toDisplayFeatures = function(state, geojson, display) {
|
|
239
|
+
RadiusMode.toDisplayFeatures = function (state, geojson, display) {
|
|
211
240
|
const isActiveLine = geojson.properties.id === state.line.id;
|
|
212
241
|
geojson.properties.active = isActiveLine ? "true" : "false";
|
|
213
242
|
if (!isActiveLine) return display(geojson);
|
|
@@ -246,12 +275,12 @@ RadiusMode.toDisplayFeatures = function(state, geojson, display) {
|
|
|
246
275
|
meta: "currentPosition",
|
|
247
276
|
radiusMetric: displayMeasurements.metric,
|
|
248
277
|
radiusStandard: displayMeasurements.standard,
|
|
249
|
-
parent: state.line.id
|
|
278
|
+
parent: state.line.id,
|
|
250
279
|
},
|
|
251
280
|
geometry: {
|
|
252
281
|
type: "Point",
|
|
253
|
-
coordinates: geojson.geometry.coordinates[1]
|
|
254
|
-
}
|
|
282
|
+
coordinates: geojson.geometry.coordinates[1],
|
|
283
|
+
},
|
|
255
284
|
};
|
|
256
285
|
display(currentVertex);
|
|
257
286
|
|