source: gs3-extensions/map-editor/DrawingManager/index.js@ 32711

Last change on this file since 32711 was 32711, checked in by ak19, 5 years ago

Updated version where history "array" can support: new shapes, moving, change of colour.

File size: 15.8 KB
Line 
1var debug = false;
2var redoPressed = false;
3var undoPressed = 0;
4var shiftKeyPressed = false;
5var dragFired = false;
6var selectionPass = true;
7var chosen;
8
9var overlays_copy_obj = {};
10
11var prevEdge = {
12 east: "",
13 north: "",
14 south: "",
15 west: ""
16}
17var nextEdge = {
18 east: "",
19 north: "",
20 south: "",
21 west: ""
22}
23var prevVertex = {
24 lat: "",
25 lng: ""
26};
27var nextVertex = {
28 lat: "",
29 lng: ""
30};
31var deselectedLog = []
32var selectedShapesLog = [];
33var prevShape = [];
34var nextShape = [];
35var prevLog = [];
36var nextLog = [];
37
38
39
40
41var dragged = 0;
42var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
43var selectedColor;
44var colorButtons = {};
45var thicknessValue = 1;
46var opacityValue = 0.4;
47var polyOptions = {
48 fillColor: '#CA4A2F',
49 strokeWeight: thicknessValue,
50 fillOpacity: opacityValue,
51 editable: true,
52 draggable: true,
53 geodesic: false,
54};
55
56var overlays = [];
57var drawingManager;
58var selectedShape;
59var selectedShapes = [];
60
61var map = null;
62
63
64$(document).ready(function() {
65 //Update thickness
66 var thicknessSlider = document.getElementById("thicknessRange");
67 var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
68 thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
69
70 thicknessSlider.oninput = function () {
71 thicknessSliderOutput.innerHTML = this.value / 20;
72 thicknessValue = this.value / 20;
73 polyOptions.strokeWeight = thicknessValue;
74 setSelectedThickness(thicknessValue);
75 }
76 //Update opacity
77 var opacitySlider = document.getElementById("colourOpacity");
78 var opacitySliderOutput = document.getElementById("opacityRangeVal");
79 opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
80
81 opacitySlider.oninput = function () {
82 opacityValue = this.value / 100;
83 polyOptions.fillOpacity = opacityValue;
84 opacitySliderOutput = opacityValue;
85 opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
86 setSelectedOpacity(opacityValue);
87 }
88});
89
90
91
92////////////////////////////////////////////////////////////////////////////////////////
93function makeColorButton(color) {
94 var button = document.createElement('span');
95 button.className = 'color-buttons1';
96 button.style.backgroundColor = color;
97 google.maps.event.addDomListener(button, 'click', function () {
98 selectColor(color);
99 setSelectedShapeColor(color);
100 });
101 return button;
102}
103function buildColorPalette() {
104 var colorPalette = document.getElementById('color-palette1');
105 for (var i = 0; i < colors.length; ++i) {
106 var currColor = colors[i];
107 var colorButton = makeColorButton(currColor);
108 colorPalette.appendChild(colorButton);
109 colorButtons[currColor] = colorButton;
110 }
111 selectColor(colors[0]);
112};
113function selectColor(color) {
114 selectedColor = color;
115 for (var i = 0; i < colors.length; ++i) {
116 var currColor = colors[i];
117 colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
118 }
119
120 // Retrieves the current options from the drawing manager and replaces the
121 // stroke or fill color as appropriate.
122 var polylineOptions = drawingManager.get('polylineOptions');
123 polylineOptions.strokeColor = color;
124 drawingManager.set('polylineOptions', polylineOptions);
125
126 var rectangleOptions = drawingManager.get('rectangleOptions');
127 rectangleOptions.fillColor = color;
128 drawingManager.set('rectangleOptions', rectangleOptions);
129
130 var circleOptions = drawingManager.get('circleOptions');
131 circleOptions.fillColor = color;
132 drawingManager.set('circleOptions', circleOptions);
133
134 var polygonOptions = drawingManager.get('polygonOptions');
135 polygonOptions.fillColor = color;
136 drawingManager.set('polygonOptions', polygonOptions);
137}
138
139function initMap() {
140
141 map = new google.maps.Map(document.getElementById('map'), {
142 center: {
143 lat: -34.397,
144 lng: 150.644
145 },
146 zoom: 2,
147 //mapTypeId: 'map'
148
149 });
150
151 drawingManager = new google.maps.drawing.DrawingManager({
152 drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
153 drawingControl: true,
154 drawingControlOptions: {
155 position: google.maps.ControlPosition.TOP_CENTER,
156 drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
157 },
158 markerOptions: {
159 draggable: true
160 },
161 circleOptions: polyOptions,
162 polylineOptions: polyOptions,
163 polygonOptions: polyOptions,
164 rectangleOptions: polyOptions,
165 });
166
167 drawingManager.setMap(map);
168
169 //overlays.push(event.overlay); // store reference to added overlay
170 google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
171
172
173
174 historyOverlayPush();
175
176 overlays.push(e.overlay); // store reference to added overlay
177 var newShape = e.overlay;
178 newShape.type = e.type;
179
180
181
182 if (e.type !== google.maps.drawing.OverlayType.MARKER) {
183
184 // Switch back to non-drawing mode after drawing a shape.
185 //drawingManager.setDrawingMode(null);
186
187 // Add an event listener that selects the newly-drawn shape when the user
188 // mouses down on it.
189 google.maps.event.addListener(newShape, 'click', function (e) {
190
191 vertexAndPolyDel(e, newShape);
192 dragFired = false;
193 return;
194
195 });
196
197 //Stores past event information
198 google.maps.event.addListener(newShape, 'dragstart', function () {
199 dragStartFunction(e, newShape);
200 });
201
202 //Store information after the event ends
203 google.maps.event.addListener(newShape, 'dragend', function () {
204 historyOverlayPush();
205 dragEndFunction(e, newShape);
206 });
207
208 //Add an event listener to select a shape if the mouse hovers over it
209 google.maps.event.addListener(newShape, 'mousedown', function (e) {
210 if (drawingManager.drawingMode == null) {
211 setSelection(newShape, e);
212 dragFired = false;
213 }
214 });
215 setSelection(newShape, e);
216 } else {
217 //cLICK EVENT IF A MARKER IS CREATED
218 google.maps.event.addListener(newShape, 'click', function (e) {
219 setSelection(newShape, e);
220 });
221 setSelection(newShape, e);
222 }
223 });
224
225 //Deletes a vertex if clicked on it
226 function vertexAndPolyDel(e, newShape) {
227 var vertex = e.vertex;
228
229 if (e.vertex !== undefined) {
230 if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
231 var path = newShape.getPaths().getAt(e.path);
232 path.removeAt(e.vertex);
233 if (path.length < 3) {
234 newShape.setMap(null);
235 }
236 }
237 if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
238 var path = newShape.getPath();
239 path.removeAt(e.vertex);
240 if (path.length < 2) {
241 newShape.setMap(null);
242 }
243 }
244 }
245 }
246
247
248 var i = 0;
249
250
251
252 //Clears selection if clicked on the map when shift is not presseed
253 google.maps.event.addListener(map, 'click', function () {
254 if (shiftKeyPressed == false) {
255 clearSelection();
256 if (chosen !== null) {
257 deselectedLog.push("deselected")
258 updateHistory(deselectedLog);
259 deselectedLog = [];
260 chosen = null;
261
262 }
263 }
264 });
265
266 //Setting drawing tool option
267 document.addEventListener('keydown', function () {
268 //if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
269 if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
270 //clearSelection();
271 drawingManager.setDrawingMode(null);
272 } else if (event.code == 'Digit1') {
273 drawingManager.setDrawingMode('marker');
274 } else if (event.code == 'Digit2') {
275 drawingManager.setDrawingMode('circle');
276 } else if (event.code == 'Digit3') {
277 drawingManager.setDrawingMode('polygon');
278 } else if (event.code == 'Digit4') {
279 drawingManager.setDrawingMode('polyline');
280 } else if (event.code == 'Digit5') {
281 drawingManager.setDrawingMode('rectangle');
282 } else if (event.code == 'KeyQ') {
283 polygonGetPath();
284 }
285 // console.log(event.code);
286 });
287
288 //Sets shift as pressed
289 document.addEventListener('keydown', function () {
290 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
291 shiftKeyPressed = true;
292
293 }
294
295 });
296
297 //Sets shift as unpressed
298 document.addEventListener('keyup', function () {
299 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
300 shiftKeyPressed = false;
301 }
302
303 });
304
305 buildColorPalette();
306}
307
308
309function clearSelection() {
310 if (selectedShape) {
311 if (selectedShape.type !== 'marker') {
312 selectedShape.setEditable(false);
313 if (shiftKeyPressed == false) {
314 for (var i = 0; i < selectedShapes.length; i++) {
315 selectedShapes[i].setEditable(false);
316 }
317 selectedShapes = [];
318 }
319 }
320 selectedShape = null;
321 }
322 }
323
324//Set selection for the selected overlay
325 function setSelection(shape, e) {
326 if (shape.type !== 'marker') {
327 if (shiftKeyPressed == false) {
328 //if (e.vertex == undefined) {
329 console.log("**** e.vertex = " + e.vertex);
330
331 if ((shape.type != google.maps.drawing.OverlayType.POLYLINE)
332 && (shape.type != google.maps.drawing.OverlayType.POLYGON)) {
333 clearSelection();
334 shape.setEditable(true);
335 }
336 }
337 if (selectedShapes.includes(shape)) {
338
339 //shape.setEditable(false);
340 const index = selectedShapes.indexOf(shape);
341 selectedShapes.splice(index, 1);
342 } else {
343 shape.setEditable(true);
344 selectedShapes.push(shape);
345 }
346
347 if (debug) {
348 console.log(" len = " + selectedShapes.length);
349 }
350 //Send the values to be updated
351 var thi = shape.strokeWeight;
352 var opa = shape.fillOpacity;
353 var fCol = shape.fillColor;
354 var sCol = shape.strokeColor;
355 updateMenuValues(thi, opa, fCol, sCol);
356
357 } else if (shape.type == 'marker') {
358 clearSelection();
359 }
360
361 selectedShape = shape;
362
363 if (selectionPass == true) {
364
365 selectedShapesLog.push("selected", shiftKeyPressed, selectedShape);
366 nextLog.push(selectedShapesLog);
367 chosen = selectedShape;
368 selectionPass = false
369 }
370
371 var lastItem = nextLog[nextLog.length - 1];
372
373 if (chosen !== selectedShape) {
374 if (dragFired == false) {
375 selectedShapesLog.push("selected", shiftKeyPressed, selectedShape)
376 updateHistory(selectedShapesLog);
377 chosen = selectedShape;
378 }
379 }
380
381 //console.log(prevLog);
382 selectedShapesLog = [];
383 }
384
385
386//Set selected thickness
387function setSelectedThickness(sWeight) {
388 if (selectedShapes.length > 0) {
389 //historyOverlayPush();
390 for (var i = 0; i < selectedShapes.length; i++) {
391 selectedShapes[i].set('strokeWeight', sWeight);
392 //console.log(selectedShapes.length);
393 }
394 }
395}
396
397//Set selected opacity
398function setSelectedOpacity(fOpacity) {
399
400 if (selectedShapes.length > 0) {
401 //historyOverlayPush();
402 for (var i = 0; i < selectedShapes.length; i++) {
403 selectedShapes[i].set('fillOpacity', fOpacity);
404 }
405 }
406}
407
408//set selected fill colour
409function setSelectedShapeColor(color) {
410 if (selectedShapes.length > 0) {
411 historyOverlayPush();
412 for (var i = 0; i < selectedShapes.length; i++) {
413 selectedShapes[i].set('fillColor', color);
414 selectedShapes[i].set('strokeColor', color);
415 }
416 }
417}
418
419function updateMenuValues(thi, opa, fCol, sCol) {
420
421 //Update thickness slider and value on the settings menu
422 var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
423 thicknessSliderOutput.innerHTML = thi;
424 document.getElementById("thicknessRange").value = thi * 20;
425
426 //Update the opacity slider and value on the settings menu
427 var opacitySliderOutput = document.getElementById("opacityRangeVal");
428 opacitySliderOutput.innerHTML = "% " + opa * 100;
429 document.getElementById("colourOpacity").value = opa * 100;
430
431 if (drawingManager.drawingMode == null) {
432 selectColor(fCol);
433 }
434}
435
436
437
438function undoMovementDragSelection() {
439 var lastItem = prevLog[prevLog.length - 1];
440
441 //If history array is not empty
442 if (prevLog.length !== 0) {
443 if (lastItem[0] = "dragStart") {
444 //If the array has more than one index (polygons and polylines)
445 if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
446 nextLog.push(lastItem);
447 selectedShape.setPath(lastItem[2]);
448
449 //If the array has only one index(rectangles and circles)
450 } else {
451 nextLog.push(lastItem);
452 selectedShape.setBounds(lastItem[2]);
453 }
454 } else if (lastItem[0] = "selected") {}
455 else if (lastItem[0] = "deselected") {}
456 undoPressed = false;
457 undoPressed = 0;
458 prevLog.pop();
459 }
460
461}
462
463function redoMovement() {
464
465 var lastItem = nextLog[nextLog.length - 1];
466 var secondToLastItem = nextLog[nextLog.length - 2];
467 var correctIndex;
468
469 if (undoPressed >= 1) {
470 correctIndex = lastItem;
471 } else {
472 correctIndex = secondToLastItem;
473 undoPressed++;
474 }
475
476 //If the history log is not empty
477 if (nextLog.length > 1) {
478 prevLog.push(lastItem);
479
480 //If undo has been pressed
481
482 if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
483 selectedShape.setPath(correctIndex[2]);
484 } else {
485 selectedShape.setBounds(correctIndex[2]);
486 }
487
488 undoPressed = false;
489 redoPressed = true;
490 nextLog.pop();
491 }
492}
493
494function dragStartFunction(e, selectedShape) {
495 var newShape = e.overlay;
496 newShape.type = e.type;
497 if (selectedShape) {
498 var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
499 var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
500
501 if (polyL || polyG) {
502 var latLngi = []
503 var lati,
504 lngi;
505 for (var i = 0; i < selectedShape.getPath().length; i++) {
506 lati = selectedShape.getPath().getAt(i).lat();
507 lngi = selectedShape.getPath().getAt(i).lng();
508 //console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
509 prevVertex = {
510 lat: lati,
511 lng: lngi
512 };
513 latLngi.push(prevVertex);
514 }
515 prevShape.push("dragStart", selectedShape.type, latLngi);
516 } else {
517 prevEdge = {
518 east: selectedShape.getBounds().ea.l,
519 north: selectedShape.getBounds().la.l,
520 south: selectedShape.getBounds().la.j,
521 west: selectedShape.getBounds().ea.j
522 }
523 prevShape.push("dragStart", selectedShape.type, prevEdge);
524 }
525
526 var lastItem = nextLog[nextLog.length - 1];
527 if (lastItem[0] !== "dragEnd") {
528 prevLog.push(nextLog[nextLog.length - 1]);
529 }
530
531 prevLog.push(prevShape);
532 prevShape = [];
533 nextLog = [];
534 chosen = selectedShape;
535 dragFired = true;
536 }
537}
538
539function dragEndFunction(e, newShape) {
540
541 var newShape = e.overlay;
542 newShape.type = e.type;
543 if (selectedShape) {
544 var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
545 var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
546
547 if (polyL || polyG) {
548
549 var latLngi = []
550 var lati,
551 lngi;
552
553 for (var i = 0; i < selectedShape.getPath().length; i++) {
554 lati = selectedShape.getPath().getAt(i).lat();
555 lngi = selectedShape.getPath().getAt(i).lng();
556 nextVertex = {
557 lat: lati,
558 lng: lngi
559 };
560 latLngi.push(nextVertex);
561 }
562 nextShape.push("dragEnd", selectedShape.type, latLngi);
563 } else {
564
565 nextEdge.east = selectedShape.getBounds().ea.l;
566 nextEdge.north = selectedShape.getBounds().la.l;
567 nextEdge.south = selectedShape.getBounds().la.j;
568 nextEdge.west = selectedShape.getBounds().ea.j;
569
570 nextShape.push("dragEnd", selectedShape.type, nextEdge);
571 }
572 }
573 for (var i = 0; i < prevLog.length; i++) {
574 if (prevLog[i][0] == "dragEnd") {
575 const index = i;
576 prevLog.splice(index, 1);
577 }
578 }
579 nextLog.push(nextShape);
580 nextShape = [];
581 chosen = selectedShape;
582}
583
584function updateHistory(eventArray) {
585 var lastItem = nextLog[nextLog.length - 1];
586 if (nextLog.length > 0) {
587 prevLog.push(lastItem);
588 }
589 nextLog = [];
590 nextLog.push(eventArray);
591 eventArray = [];
592 dragFired = false;
593
594}
595
596function polygonGetPath() {
597 console.log(nextLog);
598 console.log(prevLog);
599
600}
601
602function deleteSelectedShape() {
603 for (var i = 0; i < selectedShapes.length; i++) {
604 selectedShapes[i].setMap(null);
605 }
606 selectedShapes = [];
607}
608
609function deleteAllShape() {
610 for (var i = 0; i < overlays.length; i++) {
611 overlays[i].setMap(null);
612
613 }
614 overlays = [];
615}
616
Note: See TracBrowser for help on using the repository browser.