Table of Contents

Source Code WebAPIEditionSample DrawEditFeatures.zip

DrawEditFeaturesController.cs

 using System;  
 using System.Collections.ObjectModel;  
 using System.Drawing;  
 using System.Drawing.Imaging;  
 using System.Globalization;  
 using System.IO;  
 using System.Linq;  
 using System.Net;  
 using System.Net.Http;  
 using System.Net.Http.Headers;  
 using System.Web;  
 using System.Web.Http;  
 using System.Web.SessionState;  
 using System.Xml.Linq;  
 using Newtonsoft.Json;  
 using Newtonsoft.Json.Linq;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.WebApiEdition;  
 
 namespace DrawingAndEditing.Controllers  
 {  
     [RoutePrefix("edit")]  
     public class DrawingAndEditingController : ApiController  
     {  
         private static string jsonArrayTemplate = "[{0}]";  
 
         [Route("{z}/{x}/{y}")]  
         public HttpResponseMessage GetTile(int z, int x, int y)  
         {  
             // Create the layerOverlay for displaying the map.  
             LayerOverlay layerOverlay = new LayerOverlay();  
             InMemoryFeatureLayer shapesFeatureLyaer = GetLayer();  
             if (shapesFeatureLyaer != null && shapesFeatureLyaer.InternalFeatures.Count > 0)  
             {  
                 layerOverlay.Layers.Add(shapesFeatureLyaer);  
             }  
 
             using (Bitmap bitmap = new Bitmap(256, 256))  
             {  
                 GdiPlusGeoCanvas geoCanvas = new GdiPlusGeoCanvas();  
                 RectangleShape boundingBox = WebApiExtentHelper.GetBoundingBoxForXyz(x, y, z, GeographyUnit.Meter);  
                 geoCanvas.BeginDrawing(bitmap, boundingBox, GeographyUnit.Meter);  
                 layerOverlay.Draw(geoCanvas);  
                 geoCanvas.EndDrawing();  
 
                 MemoryStream memoryStream = new MemoryStream();  
                 bitmap.Save(memoryStream, ImageFormat.Png);  
 
                 HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.OK);  
                 responseMessage.Content = new ByteArrayContent(memoryStream.ToArray());  
                 responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");  
 
                 return responseMessage;  
             }  
         }  
 
         [Route("getshapes")]  
         public string GetShapes()  
         {  
             InMemoryFeatureLayer shapesFeatureLayer = GetLayer();  
             // Return the shapes in JSON saved on server side to client side.  
             return string.Format(CultureInfo.InvariantCulture, jsonArrayTemplate, string.Join(",", shapesFeatureLayer.InternalFeatures.Select(f => f.GetGeoJson())));  
         }  
 
         [Route("saveshapes")]  
         [HttpPost]  
         public void SaveShapes([FromBody] string modifiedShapesInJson)  
         {  
             if (!string.IsNullOrEmpty(modifiedShapesInJson))  
             {  
                 // Parse the JSON.  
                 // There are 2 groups of shapes, one is for shapes removed on client side,  
                 // and the other is for shapes added on client side.  
                 JObject jObject = JObject.Parse(modifiedShapesInJson);  
 
                 InMemoryFeatureLayer shapesFeatureLayer = GetLayer();  
                 shapesFeatureLayer.Open();  
 
                 // Deal with removed shapes.  
                 string[] ids = jObject["removedIds"].ToObject<string[]>();  
                 foreach (var id in ids)  
                 {  
                     if (shapesFeatureLayer.InternalFeatures.Count > 0)  
                     {  
                         shapesFeatureLayer.InternalFeatures.Remove(id);  
                     }  
                 }  
 
                 // Deal with newly added shapes.  
                 string featureGeoJsons = jObject["newShapes"].ToString();  
                 foreach (Feature feature in CreateFeaturesFromGeoJsons(featureGeoJsons))  
                 {  
                     shapesFeatureLayer.InternalFeatures.Add(feature.Id, feature);  
                 }  
                 shapesFeatureLayer.Close();  
             }  
         }  
 
         private static Collection<Feature> CreateFeaturesFromGeoJsons(string geoJsons)  
         {  
             Collection<Feature> features = new Collection<Feature>();  
             foreach (JToken item in JArray.Parse(geoJsons))  
             {  
                 Feature feature = null;  
                 string geoJson = item.ToString();  
                 if (geoJson.Contains("\"type\": \"Circle\""))  
                 {  
                     // Circle is not supported in standard GeoJSON, it's only defined in this sample.  
                     feature = CreateCircleFeatureFromGeoJson(geoJson);  
                 }  
                 else  
                 {  
                     feature = Feature.CreateFeatureFromGeoJson(geoJson);  
                 }  
 
                 if (feature != null && feature.GetWellKnownBinary() != null)  
                 {  
                     features.Add(feature);  
                 }  
             }  
 
             return features;  
         }  
 
         private static Feature CreateCircleFeatureFromGeoJson(string geoJson)  
         {  
             dynamic featureEntity = JsonConvert.DeserializeObject(geoJson);  
             dynamic geometryEntity = JsonConvert.DeserializeObject(featureEntity.geometry.ToString());  
             double x = Convert.ToDouble(geometryEntity.coordinates[0].ToString(), CultureInfo.InvariantCulture);  
             double y = Convert.ToDouble(geometryEntity.coordinates[1].ToString(), CultureInfo.InvariantCulture);  
             double radius = Convert.ToDouble(geometryEntity.radius.ToString(), CultureInfo.InvariantCulture);  
 
             DistanceUnit distanceUnit = (DistanceUnit)Enum.Parse(typeof(DistanceUnit), geometryEntity.radiusUnit.ToString(), true);  
             EllipseShape circleShape = new EllipseShape(new PointShape(x, y), radius, GeographyUnit.DecimalDegree, distanceUnit);  
             Feature feature = new Feature(circleShape);  
             foreach (var item in featureEntity.properties)  
             {  
                 feature.ColumnValues[item.Name] = item.Value.ToString();  
             }  
 
             return feature;  
         }  
 
         // Get layer from the Session so each session has its own test data.  
         private static InMemoryFeatureLayer GetLayer()  
         {  
             IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current);  
             if (session["shapesFeatureLayer"] == null)  
             {  
                 InMemoryFeatureLayer shapesFeatureLayer = new InMemoryFeatureLayer();  
                 shapesFeatureLayer.Open();  
                 shapesFeatureLayer.Columns.Add(new FeatureSourceColumn("Name"));  
                 shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(100, GeoColor.FromHtml("#676e51")), GeoColor.SimpleColors.Black);  
                 shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromHtml("#2b7a05"), 14, GeoColor.SimpleColors.Black);  
                 shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.FromHtml("#676e51"), 2, true);  
                 shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Name", "Arial", 12, DrawingFontStyles.Bold, GeoColor.StandardColors.Gray, GeoColor.StandardColors.White, 2);  
                 shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
                 string dataFilePath = GetFullPath(@"App_Data\Data.xml");  
                 XElement xElement = XElement.Load(dataFilePath);  
                 foreach (var geometryXElement in xElement.Descendants("Geometry"))  
                 {  
                     Feature feature = new Feature(geometryXElement.Value);  
                     feature.ColumnValues.Add("name", geometryXElement.Attribute("name").Value);  
                     shapesFeatureLayer.InternalFeatures.Add(feature.Id, feature);  
                 }  
 
                 Proj4Projection proj4 = new Proj4Projection();  
                 proj4.InternalProjectionParametersString = Proj4Projection.GetWgs84ParametersString();  
                 proj4.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString();  
                 shapesFeatureLayer.FeatureSource.Projection = proj4;  
 
                 proj4.Open();  
 
                 session["shapesFeatureLayer"] = shapesFeatureLayer;  
             }  
 
             return (InMemoryFeatureLayer)session["shapesFeatureLayer"];  
         }  
 
         private static string GetFullPath(string fileName)  
         {  
             Uri uri = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);  
             string rootDirectory = Path.GetDirectoryName(Path.GetDirectoryName(uri.LocalPath));  
             return Path.Combine(rootDirectory, fileName); ;  
         }  
     }  
 }  
 
 
 

Default.htm(LeafLet)

 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml">  
 <head>  
     <title>Draw edit features</title>  
     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
     <meta http-equiv="content-type" content="text/html; charset=utf-8" />  
     <meta name="author" content="ThinkGeo" />  
     <link rel="apple-touch-icon" href="desktop.png" />  
     <meta name="apple-mobile-web-app-title" content="Draw edit features" />  
     <link href="favicon.ico" rel="shortcut icon" type="Images/x-icon" />  
     <link href="Content/leaflet.css" rel="stylesheet" />  
     <link href="Content/leaflet.draw.css" rel="stylesheet" />  
     <link href="Content/bootstrap.min.css" rel="stylesheet" />  
     <link href="Content/Site.css" rel="stylesheet" />  
 </head>  
 <body>  
     <div id="map">  
     </div>  
     <div id="loadingImage">  
         <img src="Images/ajax-loader.gif" />  
     </div>  
     <div class="centroid">  
         <div id="dlgName">  
             <div class="edit-panel-header">  
                 <span>The name of drawn shape</span>  
             </div>  
             <div class="edit-content">  
                 <input type="text" id="txtName" />  
                 <span id="spWarning" class="warning">The name is required.</span>  
             </div>  
             <div class="edit-foot">  
                 <a id="btnSaveName" href="#" class="btn btn-primary" role="button">OK</a>  
             </div>  
         </div>  
     </div>  
     <script src="Scripts/jquery-1.11.1.min.js"></script>  
     <script src="Scripts/leaflet.js"></script>  
     <script src="Scripts/leaflet.draw.js"></script>  
     <script src="thinkgeo.leaflet.js"></script>  
     <script>  
         var drawingLayer, editServerShapes = false;  
         var postData = { removeIds: [], geoJsons: [] };  
 
         // initialize the map  
         var map = L.map('map', { center: [33.1451,|-96.8150], zoom: 16 });  
 
         // ThinkGeo World Map  
         L.tileLayer.wms("http://{s}.thinkgeo.com/CachedWMSServer/WmsServer.axd", {  
             subdomains: ['worldmapkit1',|'worldmapkit2', 'worldmapkit3', 'worldmapkit4', 'worldmapkit5', 'worldmapkit6'],  
             layers: 'OSMWorldMapKitLayer',  
             format: 'image/png',  
             styles: 'WorldMapKitDefaultStyle',  
             version: '1.1.1',  
             attribution: '<a href="http://thinkgeo.com/map-suite-developer-gis/world-map-kit-sdk/">ThinkGeo</a> | &copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors '  
         }).addTo(map);  
 
         // layer including the drawn shapes which are saved to server side  
         var shapeLayer = L.dynamicLayer(L.Util.getRootPath() + "/edit/{z}/{x}/{y}");  
         shapeLayer.on('loading', function () {  
             $('#loadingImage').show();  
         })  
         shapeLayer.on('load', function () {  
             $('#loadingImage').hide();  
         })  
         shapeLayer.addTo(map);  
 
         // Initialise the FeatureGroup to save editable layers  
         var drawnItems = L.featureGroup().addTo(map);  
 
         // Initialise the draw control and pass it the FeatureGroup of editable layers  
         var drawControl = new L.Control.Draw({  
             edit: {  
                 featureGroup: drawnItems  
             }  
         }).addTo(map);  
 
         // add image buttons for layers, edit, help etc.  
         L.imageButtons({  
             imgs: [   | {  
                     src: 'Images/save.png',  
                     id: 'imgSave',  
                     title: 'Save to server',  
                     callback: function () {  
                         editServerShapes = false;  
                         drawnItems.eachLayer(function (layer) {  
                             var geoJson = layer.toGeoJSON();  
                             if (layer._mRadius) {  
                                 geoJson.geometry.radius = layer.getRadius();  
                                 geoJson.geometry.type = "Circle";  
                                 geoJson.geometry.radiusUnit = "Meter";  
                             }  
                             geoJson.id = layer.id;  
                             geoJson.properties = { 'name': layer.name };  
                             postData.geoJsons.push(geoJson);  
                         }, this);  
 
                         // save the drawn features to server side in GeoJson format  
                         $.post(L.Util.getRootPath() + '/edit/add', { //: JSON.stringify(postData) }, function (data) {  
                             shapeLayer.redraw();  
                             drawnItems.clearLayers();  
                         });  
 
                         postData.removeIds.length = 0;  
                         postData.geoJsons.length = 0;  
                         $('#btnStartingEdit').prop("disabled", false);  
                     }  
                 }  
             ]  
         }).addTo(map);  
 
         // event after shapes drawn  
         map.on('draw:created', function (e) {  
             drawingLayer = e.layer;  
             drawingLayer.id = L.Util.guid();  
             drawnItems.addLayer(drawingLayer);  
 
             showDlg();  
         });  
         map.on('draw:deleted', function (e) {  
             var layers = e.layers;  
             layers.eachLayer(function (layer) {  
                 postData.removeIds.push(layer.id);  
             });  
         });  
 
         $('.leaflet-draw-edit-edit').click(function (e) {  
             if (!editServerShapes) {  
                 editServerShapes = true;  
                 $.get(L.Util.getRootPath() + '/edit/getshapes', function (data) {  
                     var geoJsons = JSON.parse(data);  
                     for (var i = 0; i < geoJsons.length; i++) {  
                         var vectorlayer = L.GeoJSON.geometryToLayer(geoJsons[i].geometry);  
                         var coordinates = geoJsons[i].geometry.coordinates;  
                         var geo;  
                         switch (geoJsons[i].geometry.type) {  
                             case 'LineString':  
                                 for (var j = 0; j < coordinates.length; j++) {  
                                     var tempX = coordinates[j][0];  
                                     coordinates[j][0] = coordinates[j][1];  
                                     coordinates[j][1] = tempX;  
                                 }  
                                 geo = new L.Polyline(coordinates);  
                                 break;  
                             case 'Polygon':  
                                 for (var j = 0; j < coordinates[0].length; j++) {  
                                     var tempX = coordinates[0][j][0];  
                                     coordinates[0][j][0] = coordinates[0][j][1];  
                                     coordinates[0][j][1] = tempX;  
                                 }  
                                 var geo = new L.Polygon(coordinates[0]);  
                                 break;  
                             case 'Point':  
                                 var tempX = coordinates[0];  
                                 coordinates[0] = coordinates[1];  
                                 coordinates[1] = tempX;  
                                 geo = new L.Polyline(coordinates);  
                                 break;  
                         }  
                         if (geoJsons[i].properties.name) {  
                             geo.name = geoJsons[i].properties.name;  
                         }  
                         geo.setStyle({ color: '#f06eaa' });  
                         geo.id = geoJsons[i].id;  
                         postData.removeIds.push(geoJsons[i].id);  
                         geo.editing.enable();  
                         drawnItems.addLayer(geo);  
                     }  
                     map.removeLayer(shapeLayer);  
                 });  
             }  
         });  
 
         $('#btnSaveName').click(function () {  
             if ($('#txtName').val() == //) {  
                 $('#spWarning').show();  
                 return;  
             } else {  
                 $('#spWarning').hide();  
             }  
 
             // take the input name or description of the drawn shape  
             if (drawingLayer) {  
                 drawingLayer.name = $('#txtName').val();  
                 $('#txtName').val(//);  
             }  
             hideDlg();  
         });  
 
         // show/hide edit dialog in model mode  
         function showDlg() {  
             this.bgmask = L.DomUtil.create('div', 'bg-mask');  
             $('body').append(this.bgmask);  
             $('#dlgName').slideToggle("fast");  
         }  
 
         function hideDlg() {  
             $('.bg-mask').remove();  
             $('#dlgName').slideToggle("fast");  
         }  
     </script>  
 </body>  
 </html>  
 

Default.htm(OpenLayers)

 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml">  
 <head>  
     <title>Draw edit features</title>  
     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
     <meta http-equiv="content-type" content="text/html; charset=utf-8" />  
     <meta name="author" content="ThinkGeo" />  
     <link rel="apple-touch-icon" href="desktop.png" />  
     <meta name="apple-mobile-web-app-title" content="Draw edit features" />  
     <link href="favicon.ico" rel="shortcut icon" type="Images/x-icon" />  
     <link href="Content/bootstrap.min.css" rel="stylesheet" />  
     <link href="Content/ol.css" rel="stylesheet" />  
     <link href="Content/Site.css" rel="stylesheet" />  
     <link href="Content/thinkgeo.openlayers.css" rel="stylesheet" />  
 </head>  
 <body>  
     <div id="map">  
     </div>  
     <div id="bg-mask">  
     </div>  
     <div class="centroid">  
         <div id="dlgName">  
             <div class="edit-panel-header">  
                 <span>The name of drawn shape</span>  
             </div>  
             <div class="edit-content">  
                 <input type="text" id="txtName" />  
                 <span id="spWarning" class="warning">The name is required.</span>  
             </div>  
             <div class="edit-foot">  
                 <a id="btnSaveName" href="#" class="btn btn-primary" role="button">OK</a>  
             </div>  
         </div>  
     </div>  
     <script src="Scripts/jquery-1.11.1.min.js"></script>  
     <script src="Scripts/ol.js"></script>  
     <script src="thinkgeo.openlayers.js"></script>  
     <script>  
         var draw, editServerShapes = false;  
         var postData = { removeIds: [], geoJsons: [] };  
         var attribution = new ol.control.Attribution({  
             collapsible: false  
         });  
         // initialize the map  
         var map = new ol.Map({  
             target: 'map',  
             controls: ol.control.defaults({ attribution: false }).extend([attribution]),  
             view: new ol.View({  
                 center: [-10777396.5012,|3914579.4368],  
                 zoom: 16  
             })  
         });  
 
         // add image buttons for layers, edit, help etc.  
         var imgControls = new app.ImagesControl({  
             imgs: [{   | src: 'Images/Point.png',  
                 title: 'Draw Point',  
                 callback: function () {  
                     removeModify();  
                     removeDraw();  
                     removeSelect();  
                     addInteraction('Point');  
                 }  
             }, {  
                 src: 'Images/Line.png',  
                 title: 'Draw Line',  
                 callback: function () {  
                     removeModify();  
                     removeDraw();  
                     removeSelect();  
                     addInteraction('LineString');  
                 }  
             }, {  
                 src: 'Images/Polygon.png',  
                 title: 'Draw Polygon',  
                 callback: function () {  
                     removeModify();  
                     removeDraw();  
                     removeSelect();  
                     addInteraction('Polygon');  
                 }  
             },  
             {  
                 src: 'Images/Edit.png',  
                 title: 'Edit Shape',  
                 callback: function () {  
                     if (!editServerShapes) {  
                         editServerShapes = true;  
                         $.get(getRootPath() + '/edit/getshapes', function (data) {  
                             var geoJsons = JSON.parse(data);  
                             for (var i = 0; i < geoJsons.length; i++) {  
                                 tempGeoJSON = geoJsons[i];  
                                 transfterGeoJSON(tempGeoJSON, getSphericalMercatorVertex);  
                                 var tempFeature = getFeatureFromGeoJson(tempGeoJSON);  
                                 featureOverlay.addFeature(tempFeature);  
                                 postData.removeIds.push(tempFeature.getId());  
                             }  
                             tileLayer.setVisible(false);  
                         });  
 
                         removeModify();  
                         removeDraw();  
                         removeSelect();  
                         map.addInteraction(modify);  
                         map.addInteraction(select);  
                     }  
                 }  
             },  
             {  
                 src: 'Images/Delete.png',  
                 title: 'Delete Polygon',  
                 callback: function () {  
                     removeModify();  
                     removeDraw();  
                     removeSelect();  
                     var selectionFeatures = select.getFeatures();  
                     selectionFeatures.on('add', deleteFeature);  
                     map.addInteraction(select);  
                 }  
             },  
                 {  
                     src: 'Images/save.png',  
                     id: 'imgSave',  
                     title: 'Save to server',  
                     callback: function () {  
                         var features = featureOverlay.getFeatures().getArray();  
                         var featureLength = features.length;  
                         for (var i = 0; i < featureLength; i++) {  
                             var tempGeoJSON = getGeoJsonFromFeature(features[i]);  
                             transfterGeoJSON(tempGeoJSON, getWgs84Vertex);  
 
                             postData.geoJsons.push(tempGeoJSON);  
                         }  
 
                         // save the drawn features to server side in GeoJson format  
                         $.post(getRootPath() + '/edit/add', { //: JSON.stringify(postData) }, function (data) {  
                             xyzSource.setUrl(getRootPath() + "/edit/{z}/{x}/{y}");  
                             tileLayer.setVisible(true);  
                         });  
 
                         for (var i = featureLength - 1; i > -1; i--) {  
                             featureOverlay.removeFeature(features[i]);  
                         }  
 
                         postData.removeIds.length = 0;  
                         postData.geoJsons.length = 0;  
 
                         removeModify();  
                         removeDraw();  
                         removeSelect();  
                         editServerShapes = false;  
                     }  
                 }  
             ]  
         });  
         map.addControl(imgControls);  
 
         // ThinkGeo World Map  
         var worldmapkitlayer = new ol.layer.Tile({  
             source: new ol.source.TileWMS(({  
                 urls: ['http://worldmapkit1.thinkgeo.com/CachedWMSServer/WmsServer.axd',   | 'http://worldmapkit2.thinkgeo.com/CachedWMSServer/WmsServer.axd',  
                     'http://worldmapkit3.thinkgeo.com/CachedWMSServer/WmsServer.axd',  
                     'http://worldmapkit4.thinkgeo.com/CachedWMSServer/WmsServer.axd',  
                     'http://worldmapkit5.thinkgeo.com/CachedWMSServer/WmsServer.axd',  
                     'http://worldmapkit6.thinkgeo.com/CachedWMSServer/WmsServer.axd'],  
                 params:  
                     {  
                         'LAYERS': 'OSMWorldMapKitLayer',  
                         'VERSION': '1.1.1'  
                     },  
                 attributions: [new|ol.Attribution({  
                     html: '<a href="http://thinkgeo.com/map-suite-developer-gis/world-map-kit-sdk/">ThinkGeo</a> | &copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors <a href="http://www.openstreetmap.org/copyright">ODbL</a>'  
                 })]  
             }))  
         });  
         map.addLayer(worldmapkitlayer);  
 
         // layer including the drawn shapes which are saved to server side  
         var xyzSource = new ol.source.XYZ({  
             url: getRootPath() + "/edit/{z}/{x}/{y}",  
             maxZoom: 19  
         });  
         xyzSource.tileLoadFunction = function (imageTile, src) {  
             imageTile.getImage().src = src + '?t=' + new Date().getTime();;  
         };  
         var tileLayer = new ol.layer.Tile({  
             source: xyzSource  
         })  
         map.addLayer(tileLayer);  
 
         // Initialise the FeatureGroup to save editable layers  
         var featureOverlay = new ol.FeatureOverlay({  
             style: new ol.style.Style({  
                 fill: new ol.style.Fill({  
                     color: 'rgba(0, 153, 255, 0.4)'  
                 }),  
                 stroke: new ol.style.Stroke({  
                     color: '#0099FF',  
                     width: 3  
                 }),  
                 image: new ol.style.Circle({  
                     radius: 7,  
                     fill: new ol.style.Fill({  
                         color: '#0099FF'  
                     })  
                 })  
             })  
         });  
         featureOverlay.setMap(map);  
 
         var select = new ol.interaction.Select({  
             style: new ol.style.Style({  
                 fill: new ol.style.Fill({  
                     color: 'rgba(240, 110, 170,0.2)'  
                 }),  
                 stroke: new ol.style.Stroke({  
                     color: 'rgba(240, 110, 170,0.5)',  
                     width: 3  
                 }),  
                 image: new ol.style.Circle({  
                     radius: 7,  
                     fill: new ol.style.Fill({  
                         color: 'rgba(240, 110, 170,0.2)'  
                     })  
                 })  
             })  
         });  
 
         // Initialise the draw control and pass it the FeatureGroup of editable layers  
         var modify = new ol.interaction.Modify({  
             features: select.getFeatures(),  
             // the SHIFT key must be pressed to delete vertices, so  
             // that new vertices can be drawn at the same position  
             // of existing vertices  
             deleteCondition: function (event) {  
                 return ol.events.condition.shiftKeyOnly(event) &&  
                     ol.events.condition.singleClick(event);  
             }  
         });  
 
         var creatingFeature;  
 
         function addInteraction(drawType) {  
             removeDraw();  
             draw = new ol.interaction.Draw({  
                 features: featureOverlay.getFeatures(),  
                 type: drawType  
             });  
             draw.on('drawend', function (e) {  
                 var id = guid();  
                 e.feature.setId(id);  
                 creatingFeature = e.feature;  
                 showDlg();  
             });  
             map.addInteraction(draw);  
         }  
 
         function removeDraw() {  
             if (draw) {  
                 map.removeInteraction(draw);  
             }  
         }  
 
         function removeModify() {  
             if (modify) {  
                 map.removeInteraction(modify);  
             }  
         }  
 
         function removeSelect() {  
             if (select) {  
                 map.removeInteraction(select);  
                 var selectionFeatures = select.getFeatures();  
                 selectionFeatures.un('add', deleteFeature);  
             }  
         }  
 
         function transfterGeoJSON(geoJSON, transfer) {  
             var coordinates = geoJSON.geometry.coordinates;  
 
             switch (geoJSON.geometry.type) {  
                 case 'LineString':  
                     for (var j = 0; j < coordinates.length; j++) {  
                         coordinates[j] = transfer(coordinates[j]);  
                     }  
                     break;  
                 case 'Polygon':  
                     for (var j = 0; j < coordinates[0].length; j++) {  
                         coordinates[0][j] = transfer(coordinates[0][j]);  
                     }  
                     break;  
                 case 'Point':  
                     geoJSON.geometry.coordinates = transfer(coordinates);  
                     break;  
             }  
         }  
 
         function getGeoJsonFromFeature(feature) {  
             var geoJSONFomat = new ol.format.GeoJSON();  
             var geoJSON = geoJSONFomat.writeFeature(feature);  
             var id = feature.getId();  
             if (id) {  
                 geoJSON.id = id;  
             }  
             else {  
                 geoJSON.id = guid();  
             }  
             return geoJSON;  
         }  
 
         function getFeatureFromGeoJson(geoJSON) {  
             var geoJSONFomat = new ol.format.GeoJSON();  
             var feature = geoJSONFomat.readFeature(geoJSON);  
             feature.setId(geoJSON.id);  
             return feature;  
         }  
 
         function getWgs84Vertex(vertex) {  
             return ol.proj.transform(vertex, 'EPSG:3857', 'EPSG:4326');  
         }  
 
         function getSphericalMercatorVertex(vertex) {  
             return ol.proj.transform(vertex, 'EPSG:4326', 'EPSG:3857');  
         }  
 
         var deleteFeature = function (e) {  
             var features = e.target.getArray();  
             if (features.length > 0) {  
                 var id = features[0].getId();  
                 featureOverlay.removeFeature(features[0]);  
                 var selectionFeatures = select.getFeatures();  
                 selectionFeatures.remove(features[0]);  
                 postData.removeIds.push(id);  
             }  
         }  
 
         $('#btnSaveName').click(function () {  
             if ($('#txtName').val() == //) {  
                 $('#spWarning').show();  
                 return;  
             } else {  
                 $('#spWarning').hide();  
             }  
 
             // take the input name or description of the drawn shape  
             if (creatingFeature) {  
                 var shapeName = $('#txtName').val();  
                 creatingFeature.setProperties({ name: shapeName });  
                 $('#txtName').val(//);  
                 creatingFeature = null;  
             }  
             hideDlg();  
         });  
 
         // show/hide edit dialog in model mode  
         function showDlg() {  
             $('#bg-mask').show();  
             $('#dlgName').slideToggle("fast");  
         }  
 
         function hideDlg() {  
             $('#bg-mask').hide();  
             $('#dlgName').slideToggle("fast");  
         }  
     </script>  
 </body>  
 </html>