<!DOCTYPE html>
<html>

<head>

    <link data-require="leaflet@*" data-semver="1.3.4" rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" />
    <link data-require="quill@*" data-semver="1.3.6" rel="stylesheet" href="https://cdn.quilljs.com/1.3.6/quill.snow.css" />
    <link data-require="leaflet.draw@*" data-semver="0.2.3" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.css" />

    <link rel="stylesheet" href="style.css" />
    

    <script data-require="jquery@*" data-semver="3.2.1" src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
    <script data-require="leaflet@*" data-semver="1.3.4" src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"></script>
    <script data-require="leaflet.draw@*" data-semver="0.2.3" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw-src.js"></script>
    <script data-require="quill@*" data-semver="1.3.6" src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
    
  </head>

  <body>
    
    <div id="map"></div>
    
    <!-- <a href='#' id='export'>Export Features</a> -->
    <!-- <a href='#' id='import'>Import Features</a> -->
    
    <script type="text/javascript" src="script.js"></script>
    
  </body>

</html>
// **********************************************
//                 Globals
// **********************************************

var template = '<div id="popup_{id}" class="popup">\
<div class="popup_section">\
<label for="popup_title_{id}" class="popup_label">Title</label></br>\
<input id="popup_title_{id}" class="popup_input" type="text" value="{title}"></input>\
</div>\
<div class="popup_section">\
<label for="popup_coordinates_{id}" class="popup_label">Coordinates</label>\
<input id="popup_coordinates_{id}" class="popup_input_short" type="text" value="{latlng}" disabled></input>\
</div>\
<div class="popup_section">\
<label for="popup_editor_{id}" class="popup_label">Description</label></br>\
<div id="popup_editor_{id}" class="popup_editor"></div>\
</div>';


// **********************************************
//              Map Event Handlers
// **********************************************

// This is used for testing purposes only.
function exportData() {

  var data = [];
  
  for(var drawnItem of featureGroup.getLayers()){
    data.push(drawnItemToJSON(drawnItem));
  }
  

  // Stringify the GeoJson
  var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data));

  // Create export
  document.getElementById('export').setAttribute('href', 'data:' + convertedData);
  document.getElementById('export').setAttribute('download', 'data.geojson');

}


// This is used for testing purposes only.
function importData() {

  // Importing the sample file and recreate drawnitems
  jQuery.get('sample.json', function(data) {
      
      for(var drawnitem of data){
        
        var layer;
        
        if (drawnitem.properties.layerType == 'polygon'){
          layer = L.polygon(drawnitem.latlngs);
          layer.options.color = drawnitem.options.color;
          layer.options.weight = drawnitem.options.weight;
          layer.options.opacity = drawnitem.options.opacity;
        } else if (drawnitem.properties.layerType == 'rectangle'){
          layer = L.rectangle(drawnitem.latlngs);
          layer.options.color = drawnitem.options.color;
          layer.options.weight = drawnitem.options.weight;
          layer.options.opacity = drawnitem.options.opacity;
        } else if (drawnitem.properties.layerType == 'circle'){
          layer = L.circle(drawnitem.latlngs);
          layer.options.color = drawnitem.options.color;
          layer.options.weight = drawnitem.options.weight;
          layer.options.opacity = drawnitem.options.opacity;
        } else if (drawnitem.properties.layerType == 'marker'){
          layer = L.marker(drawnitem.latlngs);
        }
        
        // Create a popup
        layer.bindPopup('')
          .on('popupclose', popupClose)
          .on('popupopen', popupOpen);
          
        // Copy the properties from the saved object
        layer.properties = drawnitem.properties;
        
        // Add the layer and the popup to the drawn items group
        featureGroup.addLayer(layer);
        
      
      }
      
  });
  
}

// Convert the drawnItem to JSON so that it can be persisted
function drawnItemToJSON(layer){
  
    // Calculate feature coordinates
    var latlngs;
    if (layer instanceof L.Polygon) {
      latlngs = layer._defaultShape ? layer._defaultShape() : layer.getLatLngs();
    } else {
      latlngs = layer.getLatLng();
    }
    
    var feature = {
      "options": layer.options,
      "properties": layer.properties,
      "latlngs": latlngs
    };
    
    return feature;
    
}

// **********************************************
//        Drawn Items Event Handlers
// **********************************************

// Set the drawnItem's properties and attach a popup
function drawnItemCreated(event){

  // Retrieve the drawing layer from the event.
  var layer = event.layer;
  
  // Calculate feature coordinates
  var latlngs;
  if (layer instanceof L.Polygon) {
    latlngs = layer._defaultShape ? layer._defaultShape() : layer.getLatLngs();
  } else {
    latlngs = [layer.getLatLng()];
  }
  
  // Format the coordinates
  var latlng = latlngs[0];

  // Add a properties array to the layer object
  layer.properties = {
    title: "",
    layerType: event.layerType,
    latlng: strLatLng(latlng),
    id: idLatLng(latlng),
    content: ''
  };

  // Create a popup
  layer.bindPopup('')
    .on('popupclose', popupClose)
    .on('popupopen', popupOpen);

  // Add the layer and the popup to the drawn items group
  featureGroup.addLayer(layer);

}

// Update the coordinates in the edited drawnItem's properties
function drawnItemEdited(event){
  var layers = event.layers;
  
  layers.eachLayer(function(layer) {
    
    // Calculate feature coordinates
    var latlngs;
    if (layer instanceof L.Polygon) {
      latlngs = layer._defaultShape ? layer._defaultShape() : layer.getLatLngs();
    } else {
      latlngs = [layer.getLatLng()];
    }
    
    // Format the coordinates
    var latlng = latlngs[0];
  
    // Add a properties array to the layer object
    layer.properties.latlng = strLatLng(latlng);
    layer.properties.id = idLatLng(latlng);
    
  });
  
}

// **********************************************
//             Popup Event Handlers
// **********************************************

// Function to call when a popup is opened
function popupOpen(e) {
  
  // Close any other open popups
  
  // Calculate the popup contents
  var popupContent = L.Util.template(template, e.target.properties);
  e.popup.setContent(popupContent);

  // Instantiate the popup editor
  quill = new Quill("#popup_editor_" + e.target.properties.id, {
    theme: 'snow'
  });

  // Load the editor contents
  quill.setContents(e.target.properties.content);

}

// Function to call when a popup is closed
function popupClose(e) {

  // Grab form field data
  e.target.properties.title = L.DomUtil.get('popup_title_' + e.target.properties.id).value;
  
  // Save the editor contents into the 
  // the geoJSONMarker's properties
  e.target.properties.content = quill.getContents();
  quill = null;

  // Clear the popup
  e.popup.setContent('');

}


// **********************************************
//              Utility Functions
// **********************************************

// Truncate value based on number of decimals
var _round = function(num, len) {
    return Math.round(num*(Math.pow(10, len)))/(Math.pow(10, len));
};

// Helper method to format LatLng object (x.xxxxxx, y.yyyyyy)
var strLatLng = function(latlng) {
    return "("+_round(latlng.lat, 4)+", "+_round(latlng.lng, 4)+")";
};

// Helper method to format LatLng object (x.xxxxxx, y.yyyyyy)
var idLatLng = function(latlng) {
    return strLatLng(latlng).replace(/[\s\(\)\.]/g, "").replace(/[,]/g, "_");
};

// **********************************************
//                  Map Setup
// **********************************************

// Create the map box
var map = new L.Map('map', {
  center: new L.LatLng(29.9792, 31.1344),
  zoom: 15
});

// Add a feature group to the map to hold drawn items
var featureGroup = L.featureGroup().addTo(map);

// Create tile layer
var tileLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 18,
  attribution: '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// Create a draw tool bar and bind it to the feature group
var drawControl = new L.Control.Draw({
  draw: {
    position: 'topleft',
    polygon: true,
    polyline: false,
    rectangle: true,
    circle: true
  },
  edit: {
    featureGroup: featureGroup
  }
}).addTo(map);

// Add a listener to the map for items that are  added by a user
map.on(L.Draw.Event.CREATED, drawnItemCreated);

// Update all layers with any changes made by a user
map.on(L.Draw.Event.EDITED, drawnItemEdited);

body {
    margin: 0;
    padding: 0;
}

#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}

#export, #import {
    position: absolute;
    right:10px;
    z-index:400;
    background:white;
    color:black;
    padding:6px;
    border-radius:4px;
    font-family: 'Helvetica Neue';
    cursor: pointer;
    font-size:12px;
    text-decoration:none;
    top:60px;
}

#import {
    top:95px;
}

.popup{
  width: 300px;
}

.popup_section{
  padding: 5px;
  padding-bottom: 10px;
  background: #f3923b;
  margin-bottom: 15px;
}

.popup_label{
  font-size: 1.1em;
  font-weight: bold;
}

.popup_input{
  font-size: 1.1em;
  width: 285px;
  height: 1.1em;
}

.popup_input_short{
  font-size: 1.1em;
  width: 195px;
  height: 1.1em;
  margin-left: 10px;
  text-align: center;
}

.popup_title{
  font-size: 1.1em;
  width: 296px;
  height: 1.5em;
  margin-bottom: 10px;
}


.popup_editor{
  height: 200px;
  background: white;
}
[{
		"options": {
			"stroke": true,
			"color": "#f06eaa",
			"weight": 4,
			"opacity": 0.5,
			"fill": true,
			"fillColor": null,
			"fillOpacity": 0.2,
			"clickable": true
		},
		"properties": {
			"title": "Rectangle Title",
			"layerType": "rectangle",
			"latlng": "(29.97, 31.12)",
			"id": "2997_3112",
			"content": {
				"ops": [{
						"insert": "Rectangle Description"
					}, {
						"attributes": {
							"header": 1
						},
						"insert": "\n"
					}, {
						"insert": "\n"
					}, {
						"attributes": {
							"underline": true,
							"italic": true,
							"bold": true
						},
						"insert": "This is the description."
					}, {
						"insert": "\n"
					}
				]
			}
		},
		"latlngs": [{
				"lat": 29.974044591534422,
				"lng": 31.122508049011234
			}, {
				"lat": 29.97731598122696,
				"lng": 31.122508049011234
			}, {
				"lat": 29.97731598122696,
				"lng": 31.127400398254398
			}, {
				"lat": 29.974044591534422,
				"lng": 31.127400398254398
			}
		]
	}, {
		"options": {
			"stroke": true,
			"color": "#f06eaa",
			"weight": 4,
			"opacity": 0.5,
			"fill": true,
			"fillColor": null,
			"fillOpacity": 0.2,
			"clickable": true
		},
		"properties": {
			"title": "Polygon Title",
			"layerType": "polygon",
			"latlng": "(29.98, 31.13)",
			"id": "2998_3113",
			"content": {
				"ops": [{
						"insert": "Polygon Description"
					}, {
						"attributes": {
							"header": 1
						},
						"insert": "\n"
					}, {
						"insert": "\nThis is the description.\n"
					}
				]
			}
		},
		"latlngs": [{
				"lat": 29.98497358578796,
				"lng": 31.129674911499027
			}, {
				"lat": 29.98497358578796,
				"lng": 31.129674911499027
			}, {
				"lat": 29.981033338736204,
				"lng": 31.13113403320313
			}, {
				"lat": 29.981033338736204,
				"lng": 31.13113403320313
			}, {
				"lat": 29.98244589810904,
				"lng": 31.141390800476078
			}, {
				"lat": 29.98244589810904,
				"lng": 31.141390800476078
			}, {
				"lat": 29.989619902644307,
				"lng": 31.14036083221436
			}, {
				"lat": 29.989619902644307,
				"lng": 31.14036083221436
			}
		]
	}, {
		"options": {
			"stroke": true,
			"color": "#f06eaa",
			"weight": 4,
			"opacity": 0.5,
			"fill": true,
			"fillColor": null,
			"fillOpacity": 0.2,
			"clickable": true,
			"radius": 373.866398252301
		},
		"properties": {
			"title": "Circle Title",
			"layerType": "circle",
			"latlng": "(29.98, 31.14)",
			"id": "2998_3114",
			"content": {
				"ops": [{
						"attributes": {
							"link": "https://www.cbc.ca"
						},
						"insert": "Circle Description"
					}, {
						"attributes": {
							"header": 1
						},
						"insert": "\n"
					}, {
						"insert": "\nThis is the description.\n"
					}
				]
			}
		},
		"latlngs": {
			"lat": 29.97545725029985,
			"lng": 31.13555431365967
		}
	}, {
		"options": {
			"icon": {
				"options": {},
				"_initHooksCalled": true
			}
		},
		"properties": {
			"title": "Marker Title",
			"layerType": "marker",
			"latlng": "(29.98, 31.14)",
			"id": "2998_3114",
			"content": {
				"ops": [{
						"insert": "Marker Description"
					}, {
						"attributes": {
							"header": 1
						},
						"insert": "\n"
					}, {
						"insert": "\nThis is the description."
					}, {
						"attributes": {
							"list": "bullet"
						},
						"insert": "\n"
					}, {
						"insert": "Another line"
					}, {
						"attributes": {
							"list": "bullet"
						},
						"insert": "\n"
					}
				]
			}
		},
		"latlngs": {
			"lat": 29.97631227084605,
			"lng": 31.143836975097656
		}
	}
]