@v2coding/ui 0.1.0 → 0.1.5

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,856 @@
1
+ <template>
2
+ <div class="ui-field-fence" v-loading="loading">
3
+ <div class="map"></div>
4
+ <div class="info" v-show="toolsVisible">
5
+ <div class="input-item searchbox">
6
+ <div class="input-item-prepend">
7
+ <span class="input-item-text">搜索关键字</span>
8
+ </div>
9
+ <!-- form="__ignore__" 避免 enter提交表单 -->
10
+ <input ref="input" type="text" form="__ignore__" placeholder="请在地图上选择位置">
11
+ <div ref="output" class="search-result"></div>
12
+ </div>
13
+ </div>
14
+ <div class="tools" :class="{disabled: drawing}" v-show="toolsVisible">
15
+ <div v-if="toolList.length > 0 && help" class="tool help"></div>
16
+ <div v-for="tool in toolList" :key="tool" class="tool" :class="getToolClass(tool)" @click="draw(tool)"></div>
17
+ <div v-if="toolList.length > 0 && clear" class="tool clear" @click="handleClear"></div>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <script>
23
+ import gcoord from 'gcoord';
24
+ import to from 'await-to-js';
25
+ import {getAMap} from '../../config/config.amap';
26
+ import FieldMixin from './field.mixin';
27
+
28
+ const CoordTypes = {
29
+ bd09: gcoord.BD09,
30
+ gcj02: gcoord.GCJ02,
31
+ wgs84: gcoord.WGS84,
32
+ };
33
+
34
+ const Types = {
35
+ marker: 'AMap.Marker',
36
+ polyline: 'Overlay.Polyline',
37
+ circle: 'Overlay.Circle',
38
+ polygon: 'Overlay.Polygon',
39
+ };
40
+
41
+ export default {
42
+ name: 'ui-field-fence',
43
+ mixins: [FieldMixin],
44
+ props: {
45
+ /**
46
+ * value:
47
+ * {
48
+ * markers: [[lng, lat], ...],
49
+ * circles: [{center: [lng, lat], radius}, ...],
50
+ * polylines: [[[lng,lat], ...], ...],
51
+ * polygons: [[[lng,lat], ...], ...],
52
+ * }
53
+ */
54
+ coordType: {
55
+ type: String,
56
+ default: 'wgs84',
57
+ validator: (val) => Object.keys(CoordTypes).includes(val),
58
+ },
59
+ /**
60
+ * 'marker,polyline,circle,polygon'
61
+ */
62
+ tools: {
63
+ type: String,
64
+ default: 'marker,polyline,circle,polygon',
65
+ },
66
+ help: {
67
+ type: Boolean,
68
+ default: true,
69
+ },
70
+ clear: {
71
+ type: Boolean,
72
+ default: true,
73
+ },
74
+ multiple: {
75
+ type: Boolean,
76
+ default: false,
77
+ },
78
+ /**
79
+ * 0:表示无限制
80
+ */
81
+ limit: {
82
+ type: Number,
83
+ default: 0,
84
+ },
85
+ /**
86
+ * 地图缩放
87
+ * 缩放范围 2~20
88
+ */
89
+ zoom: {
90
+ type: Number,
91
+ default: 15,
92
+ validator: val => 2 <= val && val <= 20,
93
+ },
94
+ /**
95
+ * 中心点
96
+ * 'lng,lat' 字符串
97
+ */
98
+ center: String,
99
+ disabled: Boolean,
100
+ },
101
+ data () {
102
+ return {
103
+ loading: true,
104
+ keyword: '',
105
+ drawing: false,
106
+ };
107
+ },
108
+ computed: {
109
+ toolList () {
110
+ return (this.tools || '').split(',').filter(tool => Object.keys(Types).includes(tool));
111
+ },
112
+ realLimit () {
113
+ if (this.multiple) {
114
+ return this.limit;
115
+ }
116
+ return 1;
117
+ },
118
+ isCurrentCoord () {
119
+ return this.coordType === 'gcj02';
120
+ },
121
+ toolsVisible({disabled, loading}) {
122
+ return !disabled && !loading;
123
+ },
124
+ },
125
+ watch: {
126
+ value: {
127
+ immediate: true,
128
+ handler: 'onValueChange'
129
+ },
130
+ zoom: 'setMapZoom',
131
+ center: 'setMapCenter',
132
+ toolsVisible(visible) {
133
+ if (visible) {
134
+ this.toolbarControl?.show();
135
+ this.geolocationControl?.show();
136
+ } else {
137
+ this.mouseTool?.close();
138
+ this.toolbarControl?.hide();
139
+ this.geolocationControl?.hide();
140
+ }
141
+ },
142
+ },
143
+ created () {
144
+ this.graph = {
145
+ polylines: [],
146
+ markers: [],
147
+ circles: [],
148
+ polygons: [],
149
+ };
150
+ this.editor = {};
151
+ },
152
+ methods: {
153
+ init () {
154
+ getAMap([
155
+ 'AMap.ToolBar',
156
+ 'AMap.Geolocation',
157
+ 'AMap.AutoComplete',
158
+ 'AMap.MouseTool',
159
+ 'AMap.PolygonEditor',
160
+ 'AMap.PolylineEditor',
161
+ 'AMap.CircleEditor',
162
+ ]).then((AMap) => {
163
+ this.initMap(AMap);
164
+ this.loading = false;
165
+ this.done();
166
+ });
167
+ },
168
+ initMap (AMap) {
169
+ this.AMap = AMap;
170
+ this.map = new AMap.Map(this.$el.querySelector('.map'), {
171
+ zoom: this.zoom,
172
+ isHotspot: false,
173
+ });
174
+ this.initMapControl(this.map);
175
+ this.initMapAutoComplete(this.map);
176
+ this.contextMenu = this.initMapContextMenu(this.map);
177
+ this.mouseTool = this.initMapMouseTool(this.map);
178
+
179
+ // 根据value初始化地图上图形
180
+ this.onValueChange(this.value);
181
+
182
+ // 初始化地图中心点
183
+ this.setMapCenter();
184
+ },
185
+ initMapControl (map) {
186
+ this.toolbarControl = new this.AMap.ToolBar({ position: 'RT' });
187
+ this.geolocationControl = new this.AMap.Geolocation({ position: 'RB' });
188
+ map.addControl(this.toolbarControl);
189
+ map.addControl(this.geolocationControl);
190
+ if (!this.toolsVisible) {
191
+ this.toolbarControl.hide();
192
+ this.geolocationControl.hide();
193
+ }
194
+ },
195
+ initMapAutoComplete (map) {
196
+ const auto = new this.AMap.AutoComplete({
197
+ input: this.$refs.input,
198
+ output: this.$refs.output,
199
+ });
200
+ auto.on('select', (event) => {
201
+ if (!event.poi || !event.poi.location) {
202
+ return;
203
+ }
204
+ map.setZoomAndCenter(16, event.poi.location);
205
+ });
206
+ return auto;
207
+ },
208
+ initMapContextMenu () {
209
+ const contextMenu = new this.AMap.ContextMenu();
210
+ contextMenu.addItem('删除', () => {
211
+ const removeObj = this.contextMenuTarget;
212
+ this.removeGraph(removeObj);
213
+ removeObj.setMap(null);
214
+ this.contextMenuTarget = null; // 点击右键菜单子的某一项不会触发 contextMenu 的 close 事件
215
+ });
216
+ contextMenu.on('close', () => {
217
+ this.contextMenuTarget = null;
218
+ });
219
+ return contextMenu;
220
+ },
221
+ initMapMouseTool (map) {
222
+ const mouseTool = new this.AMap.MouseTool(map);
223
+ mouseTool.on('draw', (event) => {
224
+ mouseTool.close();
225
+ this.drawing = false;
226
+ const obj = event.obj;
227
+ const isAdded = this.addGraph(obj);
228
+ if (!isAdded) {
229
+ map.remove(obj);
230
+ return;
231
+ }
232
+ this.initGraphEvent(obj);
233
+ this.onGraphChange();
234
+ });
235
+ return mouseTool;
236
+ },
237
+ setMapZoom () {
238
+ if (!this.zoom || !this.map) {
239
+ return;
240
+ }
241
+ this.map.setZoom(this.zoom);
242
+ },
243
+ setMapCenter () {
244
+ if (!this.center || !this.map) {
245
+ return;
246
+ }
247
+ const [lng, lat] = this.center.split(',');
248
+ if (!lng || !lat) {
249
+ return;
250
+ }
251
+ this.map.setCenter([+lng, +lat]);
252
+ this.setMapZoom();
253
+ },
254
+ getToolClass (tool) {
255
+ if (this.realLimit <= 0 || !this.multiple) {
256
+ return tool;
257
+ }
258
+ const { markers, circles, polylines, polygons } = this.value || {};
259
+ let length = 0;
260
+ if (tool === 'marker') {
261
+ length = (markers || []).length;
262
+ } else if (tool === 'circle') {
263
+ length = (circles || []).length;
264
+ } else if (tool === 'polyline') {
265
+ length = (polylines || []).length;
266
+ } else if (tool === 'polygon') {
267
+ length = (polygons || []).length;
268
+ }
269
+ if (length >= this.realLimit) {
270
+ return tool + ' disabled';
271
+ }
272
+ return tool;
273
+ },
274
+ onValueChange (value) {
275
+ if (!this.map) {
276
+ return;
277
+ }
278
+ const { markers, circles, polylines, polygons } = value || {};
279
+
280
+ const removedMarkers = this.graph.markers.slice((markers || []).length);
281
+ const removedCircles = this.graph.circles.slice((circles || []).length);
282
+ const removedPolylines = this.graph.polylines.slice((polylines || []).length);
283
+ const removedPolygons = this.graph.polygons.slice((polygons || []).length);
284
+
285
+ [
286
+ ...removedMarkers,
287
+ ...removedCircles,
288
+ ...removedPolylines,
289
+ ...removedPolygons,
290
+ ].forEach(item => item.setMap(null));
291
+
292
+ (markers || []).forEach((markerData, index) => {
293
+ let mapMarker = this.graph.markers[index];
294
+ const lngLatData = this.getMapLngLatData(markers[index]);
295
+ const position = new this.AMap.LngLat(lngLatData[0], lngLatData[1]);
296
+ if (!mapMarker) {
297
+ mapMarker = new this.AMap.Marker({
298
+ map: this.map,
299
+ position: position,
300
+ });
301
+ this.addGraph(mapMarker);
302
+ this.initGraphEvent(mapMarker);
303
+ } else {
304
+ mapMarker.setPosition(position);
305
+ }
306
+ });
307
+ (circles || []).forEach((circleData, index) => {
308
+ let mapCircle = this.graph.circles[index];
309
+ const lngLatData = this.getMapLngLatData(circleData.center);
310
+ const lngLat = new this.AMap.LngLat(lngLatData[0], lngLatData[1]);
311
+ if (!mapCircle) {
312
+ mapCircle = new this.AMap.Circle({
313
+ map: this.map,
314
+ center: lngLat,
315
+ radius: circleData.radius,
316
+ });
317
+ this.map.add(mapCircle);
318
+ this.addGraph(mapCircle);
319
+ this.initGraphEvent(mapCircle);
320
+ } else {
321
+ mapCircle.setCenter(lngLat);
322
+ mapCircle.setRadius(circleData.radius);
323
+ }
324
+ });
325
+ (polylines || []).forEach((polylineData, index) => {
326
+ let mapPolyline = this.graph.polylines[index];
327
+ const path = polylineData.map(item => this.getMapLngLatData(item)).map(item => new this.AMap.LngLat(item[0], item[1]));
328
+ if (!mapPolyline) {
329
+ mapPolyline = new this.AMap.Polyline({ path: path });
330
+ this.map.add(mapPolyline);
331
+ this.addGraph(mapPolyline);
332
+ this.initGraphEvent(mapPolyline);
333
+ } else {
334
+ mapPolyline.setPath(path);
335
+ }
336
+ });
337
+ (polygons || []).forEach((polygonData, index) => {
338
+ let mapPolygon = this.graph.polygons[index];
339
+ const path = polygonData.map(item => this.getMapLngLatData(item)).map(item => new this.AMap.LngLat(item[0], item[1]));
340
+ if (!mapPolygon) {
341
+ mapPolygon = new this.AMap.Polygon({ path });
342
+ this.map.add(mapPolygon);
343
+ this.addGraph(mapPolygon);
344
+ this.initGraphEvent(mapPolygon);
345
+ } else {
346
+ mapPolygon.setPath(path);
347
+ }
348
+ });
349
+
350
+ this.map.setFitView();
351
+ },
352
+ onGraphChange () {
353
+ const { markers, circles, polylines, polygons } = this.graph;
354
+ const value = {
355
+ markers: this.getMarkerValue(markers),
356
+ circles: this.getCircleValue(circles),
357
+ polylines: this.getPolylineValue(polylines),
358
+ polygons: this.getPolygonValue(polygons),
359
+ };
360
+ const count = Object.values(value).reduce((total, item) => total + item.length, 0);
361
+ if (count <= 0) {
362
+ // required 效果
363
+ this.onChange();
364
+ return;
365
+ }
366
+ this.onChange(Object.freeze(value));
367
+ },
368
+ onEditorChange () {
369
+ if (this.drawing) {
370
+ return;
371
+ }
372
+ this.onGraphChange();
373
+ },
374
+ // onEditorAdd(obj) {
375
+ // this.initGraphEvent(obj);
376
+ // this.addGraph(obj);
377
+ // this.drawing = false;
378
+ // },
379
+ // 使用 mouseTool 方式添加图形. editor方式添加的图形有bug(PolylineEditor 添加的初始线段无法响应click和rightclick事件)
380
+ draw (type) {
381
+ this.closeEditors();
382
+ if (type === 'marker') {
383
+ this.drawMarker();
384
+ } else if (type === 'circle') {
385
+ this.drawCircle();
386
+ } else if (type === 'polyline') {
387
+ this.drawPolyline();
388
+ } else if (type === 'polygon') {
389
+ this.drawPolygon();
390
+ }
391
+ this.drawing = true;
392
+ },
393
+ drawMarker () {
394
+ this.mouseTool.marker();
395
+ },
396
+ drawCircle () {
397
+ this.mouseTool.circle();
398
+ },
399
+ drawPolyline () {
400
+ this.mouseTool.polyline();
401
+ },
402
+ drawPolygon () {
403
+ this.mouseTool.polygon();
404
+ },
405
+ initGraphEvent (graph) {
406
+ graph.on('rightclick', (e) => {
407
+ const editor = this.getEditor(graph.className);
408
+ if (editor && editor.getTarget() === graph) {
409
+ this.closeEditor(editor);
410
+ }
411
+ this.contextMenuTarget = graph;
412
+ this.contextMenu.open(this.map, e.lnglat);
413
+ });
414
+ const editors = ['Overlay.Polyline', 'Overlay.Circle', 'Overlay.Polygon'];
415
+ if (!editors.includes(graph.className)) {
416
+ return;
417
+ }
418
+ graph.on('click', () => {
419
+ const editor = this.getEditor(graph.className);
420
+ const target = editor.getTarget();
421
+ if (target && target === graph) {
422
+ this.closeEditor(editor);
423
+ return;
424
+ }
425
+ this.closeEditors();
426
+ editor.setTarget(graph);
427
+ editor.open();
428
+ });
429
+ },
430
+ removeGraph (graph) {
431
+ const extData = graph.getExtData();
432
+ const { index } = extData || {};
433
+ let list;
434
+ if (graph.className === 'AMap.Marker') {
435
+ list = this.graph.markers;
436
+ } else if (graph.className === 'Overlay.Circle') {
437
+ list = this.graph.circles;
438
+ } else if (graph.className === 'Overlay.Polyline') {
439
+ list = this.graph.polylines;
440
+ } else if (graph.className === 'Overlay.Polygon') {
441
+ list = this.graph.polygons;
442
+ } else {
443
+ list = [];
444
+ }
445
+ list.splice(index, 1);
446
+ this.onGraphChange();
447
+ },
448
+ addGraph (graph) {
449
+ if (graph.className === 'Overlay.Polyline') {
450
+ return this.addPolyline(graph);
451
+ } else if (graph.className === 'AMap.Marker') {
452
+ return this.addMarker(graph);
453
+ } else if (graph.className === 'Overlay.Circle') {
454
+ return this.addCircle(graph);
455
+ } else if (graph.className === 'Overlay.Polygon') {
456
+ return this.addPolygon(graph);
457
+ }
458
+ },
459
+ addMarker (marker) {
460
+ if (!this.multiple) {
461
+ this.graph.markers.forEach(item => item.setMap(null));
462
+ this.graph.markers.length = 0;
463
+ }
464
+ const index = this.graph.markers.length;
465
+ marker.setExtData({ index });
466
+ this.graph.markers.push(marker);
467
+ return true;
468
+ },
469
+ addCircle (circle) {
470
+ if (circle.getRadius() <= 0) {
471
+ return false;
472
+ }
473
+ if (!this.multiple) {
474
+ this.graph.circles.forEach(item => item.setMap(null));
475
+ this.graph.circles.length = 0;
476
+ }
477
+ const index = this.graph.circles.length;
478
+ circle.setExtData({ index });
479
+ this.graph.circles.push(circle);
480
+ return true;
481
+ },
482
+ addPolyline (polyline) {
483
+ if (polyline.getLength() <= 0) {
484
+ return false;
485
+ }
486
+ if (!this.multiple) {
487
+ this.graph.polylines.forEach(item => item.setMap(null));
488
+ this.graph.polylines.length = 0;
489
+ }
490
+ const index = this.graph.polylines.length;
491
+ polyline.setExtData({ index });
492
+ this.graph.polylines.push(polyline);
493
+ return true;
494
+ },
495
+ addPolygon (polygon) {
496
+ if (polygon.getArea() <= 0) {
497
+ this.$message.info('绘制多边形时请至少绘制3个点');
498
+ return false;
499
+ }
500
+ if (!this.multiple) {
501
+ this.graph.polygons.forEach(item => item.setMap(null));
502
+ this.graph.polygons.length = 0;
503
+ }
504
+ const index = this.graph.polygons.length;
505
+ polygon.setExtData({ index });
506
+ this.graph.polygons.push(polygon);
507
+ return true;
508
+ },
509
+ getEditor (type) {
510
+ if (type === 'Overlay.Circle') {
511
+ return this.editor.circle || this.initCircleEditor();
512
+ } else if (type === 'Overlay.Polyline') {
513
+ return this.editor.polyline || this.initPolylineEditor();
514
+ } else if (type === 'Overlay.Polygon') {
515
+ return this.editor.polygon || this.initPolygonEditor();
516
+ }
517
+ },
518
+ initCircleEditor () {
519
+ const circleEditor = new this.AMap.CircleEditor(this.map);
520
+ this.editor.circle = circleEditor;
521
+ this.initEditorEvent(circleEditor);
522
+ return circleEditor;
523
+ },
524
+ initPolylineEditor () {
525
+ const polylineEditor = new this.AMap.PolylineEditor(this.map);
526
+ this.editor.polyline = polylineEditor;
527
+ this.initEditorEvent(polylineEditor);
528
+ return polylineEditor;
529
+ },
530
+ initPolygonEditor () {
531
+ const polygonEditor = new this.AMap.PolygonEditor(this.map);
532
+ this.editor.polygon = polygonEditor;
533
+ this.initEditorEvent(polygonEditor);
534
+ return polygonEditor;
535
+ },
536
+ initEditorEvent (editor) {
537
+ editor.on('addnode', () => this.onEditorChange());
538
+ editor.on('adjust', () => this.onEditorChange());
539
+ editor.on('move', () => this.onEditorChange());
540
+ // editor.on('add', (event) => this.onEditorAdd(event.target));
541
+ },
542
+ closeEditor (editor) {
543
+ editor.setTarget();
544
+ editor.close();
545
+ },
546
+ closeEditors () {
547
+ Object.values(this.editor).forEach(editor => this.closeEditor(editor));
548
+ },
549
+ getMapLngLatData (point) {
550
+ let [lng, lat] = point
551
+ if (!this.isCurrentCoord) {
552
+ [lng, lat] = gcoord.transform([lng, lat], CoordTypes[this.coordType], gcoord.GCJ02);
553
+ }
554
+ return [lng, lat];
555
+ },
556
+ getPoint (lngLat) {
557
+ let [lng, lat] = lngLat;
558
+ if (!this.isCurrentCoord) {
559
+ [lng, lat] = gcoord.transform([lng, lat], gcoord.GCJ02, CoordTypes[this.coordType]);
560
+ lng = lng.toFixed(7) / 1;
561
+ lat = lat.toFixed(7) / 1;
562
+ }
563
+ return [lng, lat];
564
+ },
565
+ getMarkerValue (markers) {
566
+ return (markers || []).map(marker => {
567
+ const lngLat = marker.getPosition();
568
+ return this.getPoint([lngLat.getLng(), lngLat.getLat()]);
569
+ });
570
+ },
571
+ getCircleValue (circles) {
572
+ return (circles || []).map(circle => {
573
+ const radius = circle.getRadius();
574
+ const lngLat = circle.getCenter();
575
+ return { center: this.getPoint([lngLat.getLng(), lngLat.getLat()]), radius };
576
+ });
577
+ },
578
+ getPolylineValue (polylines) {
579
+ return (polylines || []).map(polyline => {
580
+ const path = polyline.getPath();
581
+ return path.map(item => this.getPoint([item.getLng(), item.getLat()]));
582
+ });
583
+ },
584
+ getPolygonValue (polygons) {
585
+ return (polygons || []).map(polygon => {
586
+ const path = polygon.getPath();
587
+ return path.map(item => this.getPoint([item.getLng(), item.getLat()]));
588
+ });
589
+ },
590
+ async handleClear () {
591
+ const [, confirm] = await to(this.$confirm('确认清空地图上所有的图形?', '提示', { type: 'warning' }));
592
+ if (!confirm) {
593
+ return;
594
+ }
595
+ this.closeEditors();
596
+ this.contextMenu.close();
597
+ Object.values(this.graph).forEach((items) => items.forEach(item => item.setMap(null)));
598
+ this.graph = {
599
+ polylines: [],
600
+ markers: [],
601
+ circles: [],
602
+ polygons: [],
603
+ };
604
+ this.onGraphChange();
605
+ },
606
+ },
607
+ };
608
+ </script>
609
+
610
+ <style lang="less">
611
+ .ui-field-fence {
612
+ width: 100%;
613
+ height: 280px;
614
+ position: relative;
615
+
616
+ .map {
617
+ width: 100%;
618
+ height: 100%;
619
+ }
620
+
621
+ .info {
622
+ position: absolute;
623
+ top: 0;
624
+ left: 0;
625
+ right: 0;
626
+ bottom: 0;
627
+ pointer-events: none;
628
+
629
+ .searchbox {
630
+ left: 12px;
631
+ top: 12px;
632
+ background-color: #fff;
633
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
634
+ pointer-events: initial;
635
+ border-radius: 3px;
636
+ padding: 3px;
637
+
638
+ .search-result {
639
+ overflow: auto;
640
+ position: absolute;
641
+ top: calc(100% - 2px);
642
+ left: 0;
643
+ right: 0;
644
+ background-color: #fefefe;
645
+ box-shadow: 0 1px 3px #999;
646
+ visibility: hidden;
647
+ border-radius: 0 0 3px 3px;
648
+
649
+ .auto-item {
650
+ white-space: nowrap;
651
+ font-size: 12px;
652
+ cursor: pointer;
653
+ padding: 4px;
654
+ line-height: 14px;
655
+ }
656
+ }
657
+ }
658
+ }
659
+
660
+ .input-item {
661
+ position: relative;
662
+ display: inline-flex;
663
+ align-items: center;
664
+ width: 220px;
665
+ font-size: 12px;
666
+
667
+ .input-item-prepend {
668
+ margin-right: -1px;
669
+
670
+ .input-item-text {
671
+ padding: 0.25em 0.5em;
672
+ display: block;
673
+ text-justify: distribute-all-lines;
674
+ text-align-last: justify;
675
+ align-items: center;
676
+ margin-bottom: 0;
677
+ font-weight: 400;
678
+ line-height: 1.5;
679
+ color: #495057;
680
+ text-align: center;
681
+ white-space: nowrap;
682
+ background-color: #e9ecef;
683
+ border: 1px solid #ced4da;
684
+ border-radius: 0.25rem 0 0 0.25rem;
685
+ box-sizing: border-box;
686
+ }
687
+ }
688
+
689
+ input {
690
+ position: relative;
691
+ flex: 1 1 auto;
692
+ width: 1%;
693
+ margin: 0;
694
+ background: #fff;
695
+ padding: 0.25em 0.5em;
696
+ display: inline-block;
697
+ line-height: 1.5;
698
+ color: #495057;
699
+ vertical-align: middle;
700
+ border: 1px solid #ced4da;
701
+ border-radius: 0 0.25rem 0.25rem 0;
702
+ appearance: none;
703
+ box-sizing: border-box;
704
+
705
+ &:focus {
706
+ border-color: #80bdff;
707
+ outline: 0;
708
+ box-shadow: 0 0 0 0.1rem rgba(128, 189, 255, 0.1);
709
+ }
710
+ }
711
+ }
712
+
713
+ .tools {
714
+ position: absolute;
715
+ bottom: 15px;
716
+ left: 50%;
717
+ transform: translateX(-50%);
718
+ display: flex;
719
+ flex-direction: row;
720
+ border-radius: 4px;
721
+ background-color: #fff;
722
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
723
+
724
+ .tool {
725
+ width: 32px;
726
+ height: 32px;
727
+ box-sizing: border-box;
728
+ background: #fff center no-repeat;
729
+ background-size: 18px;
730
+ cursor: pointer;
731
+ position: relative;
732
+
733
+ &:first-of-type {
734
+ border-radius: 4px 0 0 4px;
735
+ }
736
+
737
+ &:last-of-type {
738
+ border-radius: 0 4px 4px 0;
739
+ }
740
+
741
+ &:hover {
742
+ background-color: #f0f0f0;
743
+ }
744
+
745
+ &::before {
746
+ position: absolute;
747
+ top: 0;
748
+ left: 50%;
749
+ transform: translate(-50%, -100%);
750
+ padding: 4px 8px;
751
+ border-radius: 4px;
752
+ background-color: #fff;
753
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
754
+ color: #666;
755
+ font-size: 12px;
756
+ line-height: 16px;
757
+ transition: all 0.2s ease-in-out;
758
+ opacity: 0;
759
+ word-break: keep-all;
760
+ visibility: hidden;
761
+ pointer-events: none;
762
+ }
763
+
764
+ &:hover::before {
765
+ top: -4px;
766
+ opacity: 1;
767
+ visibility: visible;
768
+ }
769
+
770
+ & + .tool {
771
+ border-left: 1px solid #eee;
772
+ }
773
+
774
+ &.marker {
775
+ background-image: url(data:image/png;base64,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);
776
+ }
777
+
778
+ &.circle {
779
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgEAYAAAAj6qa3AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAAASAAAAEgARslrPgAABmRJREFUaN7tmHtQVOcZxp/vLIsgkbWDQ9UmYiO1BCwKRtjvHDgrSQS2SWYySUHjBXGcAeOlkHEcBw2KikWCyWATR1CmacZhMOC0mpAQBVHYBRZl18vUSbwwI64hEgVMpLBb2PP2D7ob22RbgSXbTPz9d853znve5/mu7wEe8eNk0cXIosiigAAdSRRLCxfqSIwUI+fMGWkcwdtCRkv/1Elpk9JCQ0lHkiCePk1RdJSO7t79kzHAU/zkDfDxVCApSAqSgiZNUmVhk2OrXk9a2icUxcayDqTS1xERRPg9NqlUrI3qMP2LLxoPtmS2ZKan/2gNiM+Oz47PnjYNPUPrh9bn5LAXqVjJW7kS7+BDVhUYyOrwS5oJADgHAAxYgZMALWeHkVhXh4PfHze8MrwyvNLXN4g0z2qe3bXLbQKLFH/FPzgYkxkAgIyshJWEh8d/zLt5d2Ghu9fIhlSkGgzGlS2nWk5VV7MRCz8rXom9vXgxJuKksH//frYWFagLCsJG6CH399NzmIeDR46gh6VTdH09TWY3lJLz56GH3neVzaYyqAwqQ09PA2tgDezevf+M7xpJEfRrZfY333ikmx9kLbuCycXFjUuaultqXn/9oQ2Qs8VEbdTWrbCgj/nl5yMXm7BRUYiwlm0oLqadwixhVn6+0Wg0Go29vaPNT0c60pGPj3Ju8Kqt65VX3PZkH06y7SEhQh4q2KXCQtLRdtKZzXiRzaTsoiJ37wkLcFHVeOVKA2tObU69cOF/C/8dv8FvbNwoy6LIOVF8u1jJS+/dc+6/Hu+hh0TqkrqkrrlznXnJ8/hVfvX48ZHGcbsLyMf5Zr45KgpPslxsLihABPrQef8+lQufKwlJSQ2sibWyM2e8ZYCncLMIMobTTMQ/yspgQSFuqtXIoyIcXL/e+IwxqXV2a6u3Ex83A2SNGClGJiTAgkIyRUfTDvqAVplMhoSWJ0xJhw55O2FP850pQH/BXpq4Zo3rxhL2vPDuvn3/aiVvJ+zEJ9gn2Ce4o4PsWMBiVqxQDORP/m+/PebA8jI+qLV+9ZWcLSbyuP5+577sbcHjjlQr1Uq1M2a4VtVPeSkvNZm8ndd445oCgkYpV8off9zVspgtg6W93dsJ/mAGsGAmMOGBOb6KzFj6/zPnx9+AECQjeWDAeU2ZaEJTYKC3E3SH85wi1/MT/ERbm3xfPKOt2LJl1AZM/JVmi2bLZ5/RcXqX9trtTMtiMH3BAm8LdQd9LpTR7NhY5LEdyJs/H36IQJzPiIs7lwE112uu11y321k4y2XPXLqEudiG0qlTpT3SHmlPRIS3BX+HBGpmhsRE17Uet4S7bW2jNsAJ/QyH6FBFheuB27SNtq1b5229ToarxenT2VHkY+CFF3ARO5F5+/bfe+yr7atra8dsgHBZPW3CivfeQxfVUGVfHwMWUkx6uo54KS8NC/O2AapealDCCwpgQjtuqtXIwS0KKCszW8wWs2VwcMwGOOt0OowslrtjByzog8Pfn15jDtS8/74+VB+qD50w4YcWLmdLL2mjXn4ZccjAUFoaAulNFFmtvrX2Pw4W7N07Tp8VBFktarSnGhtd5bCVV/GqTz4Zrtv9/MZbuI60Vq01OVmeK07kGBiQa8W/8qMOR/zz/Bg/lpQ01viq/95MNNPxpO3nf/voI8x2xAlrkpLYOpbD9sfF0RwlY2hWcvITs2YUhDzV3Gyts9ZZ6+7cGbvg4R8iIV//omXahzk5IKZmfiUl0CMNq9Vq+hjRVJ6ZaTjcojXlVVWNdwf8W2Lzo6dMkReLy7l/Q4NrRPRyi7bJZpOX8SyeVVamIylICnr66YeNG3Mt5lrMtcDA4f08I0Pezo/xY5cvu+J38mpe3dcnH+bz+Ly0NE/rGvE/wWEEQX6OH+FHNmxAJjOieudOvAML2h84OIXiGky9vbiLp+jm+fOUhTdYSnc3e40GkatS4VUMYjAsDHGMMBQWhl0owlvCt2vSZPhQZX29ajcWCX/OyDj9m+bc5lzPH81HacC3DA/Zxx5T3hyaYv/T8uXsDRrCzKVLqYPK2UB0NFvC/oDdAQFuA5iwFr+9dQspdA53T5xQOlRmxXTggNFoNLa2ms2eFuxxA9yRkpKSkpKiUnXWd9Z31oeGCm85LjguaDQ4QAYy2Gzgvmd9z965Yyg2FBuKv/xyvIU+4hHfzz8BhHaoMb4oUvYAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjAtMTEtMTlUMTU6NDU6MTIrMDg6MDCslcuKAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIwLTExLTE5VDE1OjQ1OjEyKzA4OjAw3chzNgAAAE50RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vaG9tZS9hZG1pbi9pY29uLWZvbnQvdG1wL2ljb25fdTBiMzBmOGMybS9kcmF3X2NpcmxjbGUuc3ZnyLB+hgAAAABJRU5ErkJggg==);
780
+ }
781
+
782
+ &.polyline {
783
+ background-image: url(data:image/png;base64,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);
784
+ }
785
+
786
+ &.polygon {
787
+ background-image: url(data:image/png;base64,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);
788
+ }
789
+
790
+ &.help {
791
+ background-image: url(data:image/png;base64,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);
792
+ }
793
+
794
+ &.clear {
795
+ background-image: url(data:image/png;base64,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);
796
+ }
797
+
798
+ &.marker:before {
799
+ content: '绘制点标注';
800
+ }
801
+
802
+ &.circle:before {
803
+ content: '绘制圆形';
804
+ }
805
+
806
+ &.polyline:before {
807
+ content: '绘制折线';
808
+ }
809
+
810
+ &.polygon:before {
811
+ content: '绘制多边形';
812
+ }
813
+
814
+ &.help:before {
815
+ content: '1.点击要绘制的图形\A 2.在地图上进行绘制,其中折线和多边形双击结束绘制\A 3.点击已经绘制好的地图进入编辑模式,再次点击退出编辑模式\A 4.在绘制好了的图形上右键可以删除该图形';
816
+ white-space: pre;
817
+ }
818
+
819
+ &.clear:before {
820
+ content: '清空所有图形';
821
+ }
822
+ }
823
+
824
+ .tool.disabled,
825
+ &.disabled .tool:not(.help) {
826
+ filter: opacity(0.3);
827
+ cursor: none;
828
+ pointer-events: none;
829
+ }
830
+ }
831
+
832
+ .close-btn {
833
+ position: absolute;
834
+ bottom: 15px;
835
+ left: 50%;
836
+ transform: translateX(-50%);
837
+ display: inline-block;
838
+ padding: 0 12px;
839
+ font-size: 12px;
840
+ line-height: 32px;
841
+ border-radius: 4px;
842
+ background-color: #fff;
843
+ cursor: pointer;
844
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
845
+
846
+ &:hover {
847
+ background-color: #f0f0f0;
848
+ }
849
+ }
850
+
851
+ .amap-logo,
852
+ .amap-copyright {
853
+ display: none !important;
854
+ }
855
+ }
856
+ </style>