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

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

Work to eliminate a undo history bug, and fixed the selection issue.

File size: 18.6 KB
Line 
1var debug = false;
2var shiftKeyPressed = false;
3var beingDragged = false;
4var resizeEntry = false;
5var allowDeselect = true;
6var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
7var selectedColor;
8var colorButtons = {};
9var thicknessValue = 1;
10var opacityValue = 0.4;
11var draggableState = true
12var overlays = [];
13var entryType = [];
14var drawingManager;
15var selectedShape;
16var selectedShapes = [];
17var map = null;
18var dragS, dragN;
19var dsNorth, dsSouth, dsEast, dsWest;
20var gaj, gal, maj, mal;
21var listenersArray = [];
22var counter = 0;
23var branchNum = 1;
24var mouseState = "up";
25var thicknessRangeListener = thicknessValue;
26var resizable = false;
27var dontResize = false;
28var polyOptions = {
29
30 fillColor: '#CA4A2F',
31 strokeWeight: thicknessValue,
32 fillOpacity: opacityValue,
33 editable: true,
34 draggable: draggableState,
35 geodesic: false
36};
37
38$(function () {
39 //change draggable
40 var draggableCB = document.querySelector("input[name=draggableCB]");
41 draggableCB.addEventListener('change', function () {
42 if (this.checked) {
43 draggableState = false;
44 for (var i = 0; i < overlays.length; i++) {
45 overlays[i].draggable = draggableState;
46 polyOptions.draggable = draggableState;
47 console.log("false");
48 }
49 //console.log(overlays[i].draggable);
50 } else {
51 draggableState = true;
52 for (var i = 0; i < overlays.length; i++) {
53 overlays[i].draggable = draggableState;
54 polyOptions.draggable = draggableState;
55 console.log("true");
56 }
57 }
58 });
59
60 //Update thickness
61 var thicknessSlider = document.getElementById("thicknessRange");
62 var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
63 thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
64 thicknessSlider.oninput = function () {
65 shapeSpecsChangeMD();
66 thicknessSliderOutput.innerHTML = this.value / 20;
67 thicknessValue = this.value / 20;
68 polyOptions.strokeWeight = thicknessValue;
69 setSelectedThickness(thicknessValue);
70
71 }
72 //Update opacity
73 var opacitySlider = document.getElementById("colourOpacity");
74 var opacitySliderOutput = document.getElementById("opacityRangeVal");
75 opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
76
77 opacitySlider.oninput = function () {
78 shapeSpecsChangeMD();
79 opacityValue = this.value / 100;
80 polyOptions.fillOpacity = opacityValue;
81 opacitySliderOutput = opacityValue;
82 opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
83 setSelectedOpacity(opacityValue);
84 }
85
86 document.getElementById("color-palette1").addEventListener("mousedown", shapeSpecsChangeMD);
87 document.getElementById("thicknessRange").addEventListener("mouseup", shapeSpecsChangeMU);
88 document.getElementById("colourOpacity").addEventListener("mouseup", shapeSpecsChangeMU);
89 document.onmousemove = mouseMove;
90 document.onmousedown = mouseDown;
91 document.onmouseup = mouseUp;
92
93});
94
95
96function settingThePath() {
97 listenersArray = []
98 counter = 0;
99 branchNum = 1;
100
101 for (var i = 0; i < selectedShapes.length * 2; i++) {
102 for (var j = 1; j < 5; j++) {
103 var path = "//*[@id='map']/div/div/div[1]/div[3]/div/div[3]/div[" + branchNum + "]/div[" + j + "]/div";
104 listenersArray[counter] = getElementByXpath(path);
105 if (listenersArray[counter] !== undefined && listenersArray[counter] !== null) {
106 listenersArray[counter].addEventListener("mousemove", function () {
107 resizable = true;
108 shapeResize();
109 });
110 listenersArray[counter].addEventListener("mouseout", function () {
111 if (mouseDown) {
112 resizable = true;
113 shapeResize();
114 }
115 });
116 }
117 counter++;
118 }
119 branchNum++;
120 }
121}
122
123
124
125function shapeResize() {
126 if (mouseState == "down") {
127 if (selectedShapes.length > 0) {
128 if (resizable) {
129 if(dontResize == false){
130 historyOverlayPush();
131 }
132
133 }
134 }
135 }
136}
137
138function shapeSpecsChangeMD() {
139
140 if (selectedShapes.length > 0) {
141 historyOverlayPush();
142 }
143}
144
145function shapeSpecsChangeMU() {
146 if (selectedShapes.length > 0) {
147 //console.log("this fires");
148 presentOverlayPush();
149 }
150}
151
152function makeColorButton(color) {
153 var button = document.createElement('span');
154 button.className = 'color-buttons1';
155 button.style.backgroundColor = color;
156 google.maps.event.addDomListener(button, 'click', function () {
157 selectColor(color);
158 setSelectedShapeColor(color);
159 shapeSpecsChangeMU();
160 });
161 return button;
162}
163function buildColorPalette() {
164 var colorPalette = document.getElementById('color-palette1');
165 for (var i = 0; i < colors.length; ++i) {
166 var currColor = colors[i];
167 var colorButton = makeColorButton(currColor);
168 colorPalette.appendChild(colorButton);
169 colorButtons[currColor] = colorButton;
170 }
171 selectColor(colors[0]);
172};
173function selectColor(color) {
174 selectedColor = color;
175 for (var i = 0; i < colors.length; ++i) {
176 var currColor = colors[i];
177 colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
178 }
179
180 // Retrieves the current options from the drawing manager and replaces the
181 // stroke or fill color as appropriate.
182 var polylineOptions = drawingManager.get('polylineOptions');
183 polylineOptions.strokeColor = color;
184 drawingManager.set('polylineOptions', polylineOptions);
185
186 var rectangleOptions = drawingManager.get('rectangleOptions');
187 rectangleOptions.fillColor = color;
188 drawingManager.set('rectangleOptions', rectangleOptions);
189
190 var circleOptions = drawingManager.get('circleOptions');
191 circleOptions.fillColor = color;
192 drawingManager.set('circleOptions', circleOptions);
193
194 var polygonOptions = drawingManager.get('polygonOptions');
195 polygonOptions.fillColor = color;
196 drawingManager.set('polygonOptions', polygonOptions);
197}
198
199function initMap() {
200
201 map = new google.maps.Map(document.getElementById('map'), {
202 center: {
203 lat: -37.7891,
204 lng: 175.3180
205 },
206 zoom: 14,
207 });
208
209 // Add a style-selector control to the map.
210 var styleControl = document.getElementById('style-selector-control');
211 map.controls[google.maps.ControlPosition.TOP_LEFT].push(styleControl);
212
213 // Set the map's style to the initial value of the selector.
214 var styleSelector = document.getElementById('style-selector');
215 map.setOptions({
216 styles: styles[styleSelector.value]
217 });
218
219 // Apply new JSON when the user selects a different style.
220 styleSelector.addEventListener('change', function () {
221 map.setOptions({
222 styles: styles[styleSelector.value]
223 });
224 });
225
226 drawingManager = new google.maps.drawing.DrawingManager({
227 drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
228 drawingControl: true,
229 drawingControlOptions: {
230 position: google.maps.ControlPosition.TOP_CENTER,
231 drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
232 },
233 markerOptions: {
234 draggable: draggableState
235 },
236 circleOptions: polyOptions,
237 polylineOptions: polyOptions,
238 polygonOptions: polyOptions,
239 rectangleOptions: polyOptions,
240 });
241
242 drawingManager.setMap(map);
243
244 google.maps.event.addListener(drawingManager, "drawingmode_changed", function () {
245 settingThePath();
246
247 })
248
249 // store reference to added overlay
250 google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
251
252 allowDeselect = true;
253
254 //console.log(e);
255 historyOverlayPush();
256
257 overlays.push(e.overlay); // store reference to added overlay
258 var newShape = e.overlay;
259 newShape.type = e.type;
260 //console.log("this fires");
261 presentOverlayPush();
262
263 if (e.type !== google.maps.drawing.OverlayType.MARKER) {
264 addShapeListeners(newShape, e);
265 setSelection(newShape, e);
266 } else {
267
268 addMarkerListeners(newShape, e);
269 setSelection(newShape, e);
270 }
271 });
272
273 //Clears selection if clicked on the map when shift is not presseed
274 google.maps.event.addListener(map, 'click', function (e) {
275 var c = document.body.childNodes;
276 if (e.target && e.target.matches("a.classA")) {
277 console.log("Anchor element clicked!");
278 }
279 if (shiftKeyPressed == false) {
280 clearSelection();
281 selectedShape = null;
282 }
283 });
284
285 google.maps.event.addListener(map, 'mousedown', function (e) {
286 dontResize = true;
287 });
288
289 google.maps.event.addListener(map, 'mouseup', function (e) {
290 dontResize = false;
291 });
292
293 //Keyboard shortcuts
294 document.addEventListener('keydown', function () {
295 if (event.code == 'KeyY' && (event.ctrlKey || event.metaKey) || (event.code == 'KeyZ' && event.code == 'ShiftLeft' && (event.ctrlKey || event.metaKey))) {
296 redo();
297 }
298 if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
299 if (shiftKeyPressed == false) {
300 undo();
301 }
302 }
303 if (event.code == 'KeyA' && (event.ctrlKey || event.metaKey)) {
304 event.preventDefault();
305 selectAll();
306 drawingManager.setDrawingMode(null);
307 }
308 if (event.code == 'KeyD' && (event.ctrlKey || event.metaKey)) {
309 event.preventDefault();
310 deselectAll();
311 }
312 if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
313
314 drawingManager.setDrawingMode(null);
315 } else if (event.code == 'Digit1') {
316 drawingManager.setDrawingMode('marker');
317 } else if (event.code == 'Digit2') {
318 drawingManager.setDrawingMode('circle');
319 } else if (event.code == 'Digit3') {
320 drawingManager.setDrawingMode('polygon');
321 } else if (event.code == 'Digit4') {
322 drawingManager.setDrawingMode('polyline');
323 } else if (event.code == 'Digit5') {
324 drawingManager.setDrawingMode('rectangle');
325 } else if (event.code == 'KeyQ') {
326 printHistory();
327 }
328 // console.log(event.code);
329 });
330
331 //Sets shift as pressed
332 document.addEventListener('keydown', function () {
333 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
334 shiftKeyPressed = true;
335
336 }
337
338 });
339
340 //Sets shift as unpressed
341 document.addEventListener('keyup', function () {
342 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
343 shiftKeyPressed = false;
344 }
345
346 });
347
348 buildColorPalette();
349}
350
351//Deletes a vertex if clicked on it
352function vertexAndPolyDel(e, newShape) {
353 var vertex = e.vertex;
354 //console.log(e)
355 if (e.vertex !== undefined) {
356 //console.log("this fires");
357 if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
358 var path = newShape.getPaths().getAt(e.path);
359 path.removeAt(e.vertex);
360 if (path.length < 3) {
361 newShape.setMap(null);
362 }
363 }
364 if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
365 var path = newShape.getPath();
366 path.removeAt(e.vertex);
367 if (path.length < 2) {
368 newShape.setMap(null);
369 }
370 } //console.log("this fires");
371 }
372}
373
374function addMarkerListeners(newShape, e) {
375 //cLICK EVENT IF A MARKER IS CREATED
376 google.maps.event.addListener(newShape, 'click', function (e) {
377 setSelection(newShape, e);
378 });
379
380 google.maps.event.addListener(newShape, 'dragstart', function (e) {
381 beingDragged = true;
382 //console.log("this fires");
383 historyOverlayPush();
384
385 });
386
387 google.maps.event.addListener(newShape, 'dragend', function () {
388 beingDragged = false;
389 //console.log("this fires");
390 presentOverlayPush();
391 allowDeselect = false;
392 });
393}
394
395function applyDrag(newShape) {
396 for (var i = 0; i < selectedShapes.length; i++) {
397 //mal = 0;
398 //maj = 0;
399 //gal = 0;
400 //gaj = 0;
401
402 //mal = selectedShapes[i].bounds.ma.l - newShape.bounds.ma.l;
403 //maj = selectedShapes[i].bounds.ma.j - newShape.bounds.ma.j;
404 //gal = selectedShapes[i].bounds.ga.l - newShape.bounds.ga.l;
405 //gaj = selectedShapes[i].bounds.ga.j - newShape.bounds.ga.j;
406
407 mal = newShape.bounds.ma.l - dsNorth;
408 maj = newShape.bounds.ma.j - dsSouth;
409 gal = newShape.bounds.ga.l - dsEast;
410 gaj = newShape.bounds.ga.j - dsWest;
411
412 var north = selectedShapes[i].bounds.ma.l;
413 var south = selectedShapes[i].bounds.ma.j;
414 var east = selectedShapes[i].bounds.ga.l + gal;
415 var west = selectedShapes[i].bounds.ga.j + gaj;
416 if (!isNaN(north) && !isNaN(south) && !isNaN(west) && !isNaN(east)) {
417 var NE = new google.maps.LatLng(north, east);
418 var SW = new google.maps.LatLng(south, west);
419 var newRect = new google.maps.LatLngBounds(SW, NE);
420 selectedShapes[i].setBounds(newRect);
421 }
422 }
423}
424
425function addShapeListeners(newShape, e) {
426 // Add an event listener that selects the newly-drawn shape when the user
427 // mouses down on it.
428 google.maps.event.addListener(newShape, 'click', function (e) {
429
430 vertexAndPolyDel(e, newShape);
431
432 });
433
434 google.maps.event.addListener(newShape, 'dragstart', function (e) {
435
436
437 allowDeselect = false;
438 console.log("hey");
439 historyOverlayPush();
440 });
441
442
443
444 google.maps.event.addListener(newShape, 'dragend', function () {
445 beingDragged = false;
446 presentOverlayPush();
447 settingThePath();
448
449 allowDeselect = false;
450 setSelection(newShape, e);
451 });
452
453 //Store information after the event ends
454 google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
455 if (beingDragged == false) {
456 presentOverlayPush();
457 }
458 });
459
460 //Add an event listener to select a shape if the mouse hovers over it
461 google.maps.event.addListener(newShape, 'mousedown', function (e) {
462 //console.log("this fires");
463 if (e.target && e.target.matches("a.classA")) {
464 console.log("Anchor element clicked!");
465 }
466 //console.log(e);
467 if (e.vertex !== undefined || e.edge !== undefined) {
468 //console.log("this fires");
469 historyOverlayPush()
470 }
471 if (drawingManager.drawingMode == null) {
472 setSelection(newShape, e);
473 }
474 });
475
476 google.maps.event.addListener(newShape, 'mouseup', function (e) {
477 console.log("mouseup");
478 if (e.vertex !== undefined || e.edge !== undefined) {
479 //console.log("this fires");
480 presentOverlayPush()
481 } else {
482 //setSelection(newShape, e);
483 }
484
485 });
486}
487function clearSelection() {
488 if (selectedShape) {
489 if (selectedShape.type !== 'marker') {
490 selectedShape.setEditable(false);
491 if (shiftKeyPressed == false) {
492 for (var i = 0; i < selectedShapes.length; i++) {
493 selectedShapes[i].setEditable(false);
494 }
495 selectedShapes = [];
496 }
497 }
498 selectedShape = null;
499 }
500}
501
502//Set selection for the selected overlay
503function setSelection(shape, e) {
504 console.log("this fires");
505 if (shape.type !== 'marker') {
506 if (shiftKeyPressed == false) {
507 if (e.vertex == undefined) {
508 if (e.edge == undefined) {
509 clearSelection();
510 shape.setEditable(true);
511 }
512 }
513 }
514 if (selectedShapes.includes(shape)) {
515 if (e.vertex == undefined) {
516 if (e.edge == undefined) {
517 allowDeselect = true;
518 removeFromSelectedShapes(shape);
519 }
520 }
521 } else {
522 allowDeselect = false;
523 console.log("allowDeselect",allowDeselect);
524 shape.setEditable(true);
525 selectedShapes.push(shape);
526 }
527
528 //Send the values to be updated
529 var thi = shape.strokeWeight;
530 var opa = shape.fillOpacity;
531 var fCol = shape.fillColor;
532 var sCol = shape.strokeColor;
533 updateMenuValues(thi, opa, fCol, sCol);
534
535 } else if (shape.type == 'marker') {
536 clearSelection();
537 }
538 selectedShape = shape;
539 settingThePath();
540}
541
542function removeFromSelectedShapes(shape) {
543 if (selectedShapes.includes(shape)) {
544 if (allowDeselect) {
545 const index = selectedShapes.indexOf(shape);
546 console.log(index);
547 selectedShapes.splice(index, 1);
548 shape.setEditable(false);
549 }
550 console.log("allowDeselect",allowDeselect);
551 allowDeselect = true;
552 }
553 console.log(selectedShapes.length);
554}
555
556//Set selected thickness
557function setSelectedThickness(sWeight) {
558 if (selectedShapes.length > 0) {
559 //historyOverlayPush();
560 for (var i = 0; i < selectedShapes.length; i++) {
561 selectedShapes[i].set('strokeWeight', sWeight);
562 //console.log(selectedShapes.length);
563 }
564 }
565}
566
567//Set selected opacity
568function setSelectedOpacity(fOpacity) {
569
570 if (selectedShapes.length > 0) {
571 for (var i = 0; i < selectedShapes.length; i++) {
572 selectedShapes[i].set('fillOpacity', fOpacity);
573 }
574 }
575}
576
577//set selected fill colour
578function setSelectedShapeColor(color) {
579 if (selectedShapes.length > 0) {
580 for (var i = 0; i < selectedShapes.length; i++) {
581 selectedShapes[i].set('fillColor', color);
582 selectedShapes[i].set('strokeColor', color);
583 }
584 }
585}
586function getElementByXpath(path) {
587 return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
588}
589
590function updateMenuValues(thi, opa, fCol, sCol) {
591 //Update thickness slider and value on the settings menu
592 var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
593 thicknessSliderOutput.innerHTML = thi;
594 document.getElementById("thicknessRange").value = thi * 20;
595
596 //Update the opacity slider and value on the settings menu
597 var opacitySliderOutput = document.getElementById("opacityRangeVal");
598 opacitySliderOutput.innerHTML = "% " + opa * 100;
599 document.getElementById("colourOpacity").value = opa * 100;
600
601 if (drawingManager.drawingMode == null) {
602 selectColor(fCol);
603 }
604}
605function selectAll() {
606 shiftKeyPressed = true;
607 var e = new Object();
608 e.vertex = undefined;
609 selectedShapes = [];
610 for (var i = 0; i < overlays.length; i++) {
611 setSelection(overlays[i], e);
612 }
613 shiftKeyPressed = false;
614}
615
616function deselectAll() {
617 for (var i = 0; i < selectedShapes.length; i++) {
618 selectedShapes[i].setEditable(false);
619 }
620 selectedShapes = [];
621}
622
623function printHistory() {
624 console.log("prev", prevOverlays);
625 console.log("present ", presentOverlays);
626 console.log("undone ", undoneOverlays);
627 console.log(mouseState);
628
629 //console.log(mal);
630 //console.log(maj);
631 //console.log(gal);
632 //console.log(gaj);
633
634
635}
636
637function mouseMove(ev) {
638
639 //How can I know the state of mouse from here
640 if (mouseState == 'down') {
641 //console.log('mouse down state')
642 }
643
644 if (mouseState == 'up') {
645 //console.log('mouse up state')
646 }
647}
648
649function mouseDown(ev) {
650 mouseState = "down";
651 // console.log('Down State you can now start dragging');
652 //do not write any code here in this function
653}
654
655function mouseUp(ev) {
656 mouseState = "up";
657 // console.log('up state you cannot drag now because you are not holding your mouse')
658 //do not write any code here in this function
659}
660
661function deleteSelectedShape() {
662 //console.log("this fires");
663 historyOverlayPush();
664 for (var i = 0; i < selectedShapes.length; i++) {
665 selectedShapes[i].setMap(null);
666
667 if (overlays.includes(selectedShapes[i])) {
668 const index = overlays.indexOf(selectedShapes[i]);
669 overlays.splice(index, 1);
670 selectedShapes[i].setEditable(false);
671 }
672 }
673 selectedShapes = [];
674 //console.log("this fires");
675 presentOverlayPush();
676}
677
678function deleteAllShape() {
679 //console.log("this fires");
680 historyOverlayPush();
681 for (var i = 0; i < overlays.length; i++) {
682 overlays[i].setMap(null);
683 }
684 overlays = [];
685 //console.log("this fires");
686 presentOverlayPush();
687}
Note: See TracBrowser for help on using the repository browser.