====== Source Code WebAPIEditionSample GeoFunctions.zip ====== ====GemetricFunctionsController.cs==== using System; using System.Collections.Generic; 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 ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WebApiEdition; namespace GeometricFunctions.Controllers { [RoutePrefix("tile")] public class GeometricFunctionsController : ApiController { private static GeoCollection features; public LayerOverlay layerOverlay; public GeometricFunctionsController() { // Load geometries which will be used for geo-processing. features = LoadData(); // Create an overlay for displaying the geometries. layerOverlay = new LayerOverlay(); // Initialize the layers for input geometries and output geometries. layerOverlay.Layers.Add("input", GetInputLayer()); layerOverlay.Layers.Add("output", GetOutputLayer()); } [Route("{z}/{x}/{y}")] public HttpResponseMessage GetTile(int z, int x, int y) { // Draw the map and return the image back to client in an HttpResponseMessage. 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 ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Png); HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK); httpResponseMessage.Content = new ByteArrayContent(ms.ToArray()); httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); return httpResponseMessage; } } [Route("Initialize")] [HttpPost] public Dictionary InitializeGeometricFunction([FromBody]string[] ids) { // Clear the input and output layer. InMemoryFeatureLayer inputLayer = ((InMemoryFeatureLayer)layerOverlay.Layers["input"]); inputLayer.IsVisible = true; inputLayer.InternalFeatures.Clear(); ((InMemoryFeatureLayer)layerOverlay.Layers["output"]).InternalFeatures.Clear(); // Add the features for doing geo-processing. Feature[] tempFeatures = ids.Select(id => features[id]).ToArray(); foreach (var feature in tempFeatures) { inputLayer.InternalFeatures.Add(feature); } // Apply projection to the shape file which is used for display. ManagedProj4Projection proj4 = new ManagedProj4Projection(); proj4.InternalProjectionParametersString = Proj4Projection.GetWgs84ParametersString(); proj4.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString(); PointShape centerPoint = ExtentHelper.GetBoundingBoxOfItems(inputLayer.InternalFeatures).GetCenterPoint(); proj4.Open(); Vertex center = proj4.ConvertToInternalProjection(centerPoint.X, centerPoint.Y); return new Dictionary() { {"x",center.X}, {"y",center.Y}, {"z",17} }; } [Route("Execute/Union")] [HttpPost] public void Union([FromBody]string[] ids) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Hide input layer. ((InMemoryFeatureLayer)layerOverlay.Layers["input"]).IsVisible = false; // Show the union geometry as output. Feature resultFeature = Feature.Union(ids.Select(id => features[id])); outputLayer.InternalFeatures.Add(resultFeature); } } [Route("Execute/Difference")] [HttpPost] public void Difference([FromBody]Dictionary parameters) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Hide input layer. ((InMemoryFeatureLayer)layerOverlay.Layers["input"]).IsVisible = false; // Get the feature as an element for doing geoprocessing. Feature sourceFeature = features[parameters["source"]; // Get the feature as another element for doing geoprocessing. Feature targetFeature = features[parameters["target"]; // Do Diference geoprocessing. Feature resultFeature = sourceFeature.GetDifference(targetFeature); outputLayer.InternalFeatures.Add(resultFeature); } } [Route("Execute/Buffer")] [HttpPost] public void Buffer([FromBody]Dictionary parameters) { // Get the buffer distance passed from client side. double distance = Convert.ToDouble(parameters["distance"], CultureInfo.InvariantCulture); // Get the buffer distance unit passed from client side. DistanceUnit distanceUnit = (DistanceUnit)Enum.Parse(typeof(DistanceUnit), parameters["unit"], true); InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Get the feature for buffer. Feature inputFeature = features[parameters["id"]; outputLayer.InternalFeatures.Add(inputFeature); } // Do buffer. Feature bufferedFeature = outputLayer.InternalFeatures[0].Buffer(distance, GeographyUnit.Meter, distanceUnit); bufferedFeature.ColumnValues["Name"] = "Buffering"; // Display the result. outputLayer.InternalFeatures.Clear(); outputLayer.InternalFeatures.Add(bufferedFeature); } [Route("Execute/Scale")] [HttpPost] public void Scale([FromBody]Dictionary parameters) { double percentage = Convert.ToDouble(parameters["percentage"], CultureInfo.InvariantCulture); InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; // Hide the input layer. ((InMemoryFeatureLayer)layerOverlay.Layers["input"]).IsVisible = false; if (outputLayer.InternalFeatures.Count == 0) { // Get the feature for Scaling. Feature inputFeature = features[parameters["id"]; outputLayer.InternalFeatures.Add(inputFeature); } Feature feature = outputLayer.InternalFeatures[0]; MultipolygonShape polygonShape = feature.GetShape() as MultipolygonShape; if (polygonShape != null) { // Scale up the input feature. polygonShape.ScaleUp(percentage); outputLayer.InternalFeatures.Clear(); outputLayer.InternalFeatures.Add(new Feature(polygonShape, feature.ColumnValues)); } } [Route("Execute/Rotate")] [HttpPost] public void Rotate([FromBody]Dictionary parameters) { // Get the rotation angle passed from client side. double degreeAngle = Convert.ToDouble(parameters["angle"], CultureInfo.InvariantCulture); InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; // Hide input layer. ((InMemoryFeatureLayer)layerOverlay.Layers["input"]).IsVisible = false; if (outputLayer.InternalFeatures.Count == 0) { // Get the feature for rotate. Feature inputFeature = features[parameters["id"]; outputLayer.InternalFeatures.Add(inputFeature); } BaseShape shape = outputLayer.InternalFeatures[0].GetShape(); if (shape.CanRotate) { outputLayer.InternalFeatures.Clear(); // Rotate the input feature. outputLayer.InternalFeatures.Add(new Feature(BaseShape.Rotate(shape, shape.GetCenterPoint(), (float)degreeAngle))); } } [Route("Execute/CenterPoint")] [HttpPost] public void CenterPoint([FromBody]string id) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Get the feature for calculating the center point. Feature feature = features[id]; // Get the center point of boundingBox. PointShape centerPointShape = feature.GetBoundingBox().GetCenterPoint(); Feature centerFeature = new Feature(centerPointShape); centerFeature.ColumnValues["Display"] = "BoundingBox Center Point"; outputLayer.InternalFeatures.Add(centerFeature); // Get the centroid point of the geometry. PointShape centroidPointShape = feature.GetShape().GetCenterPoint(); Feature centroidFeature = new Feature(centroidPointShape); centroidFeature.ColumnValues["Display"] = "Polygon Center Point"; outputLayer.InternalFeatures.Add(centroidFeature); } } [Route("Execute/CalculateArea")] [HttpPost] public void CalculateArea([FromBody]string id) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Calculate the area of the geometry. AreaBaseShape areaBaseShape = features[id].GetShape() as AreaBaseShape; double areaInHectares = areaBaseShape.GetArea(GeographyUnit.Meter, AreaUnit.Hectares); double areaInAcres = areaBaseShape.GetArea(GeographyUnit.Meter, AreaUnit.Acres); // Display the geometry labeling with area. string acreaText = string.Format("{0:N3} {1}\r\n{2:N3} {3}", areaInHectares, "Hectares", areaInAcres, "Acres"); outputLayer.InternalFeatures.Add(new Feature(areaBaseShape, new Dictionary { { "Display", acreaText } })); } } [Route("Execute/Simplify")] [HttpPost] public void Simplify([FromBody]Dictionary parameters) { // Get the feature id used for geoprocessing. string featureId = parameters["id"]; // Get the distance passed from client side. double distance = Convert.ToDouble(parameters["distance"], CultureInfo.InvariantCulture); // Get the buffer distance unit passed from client side. DistanceUnit distanceUnit = (DistanceUnit)Enum.Parse(typeof(DistanceUnit), parameters["unit"], true); InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Hide the input layer. ((InMemoryFeatureLayer)layerOverlay.Layers["input"]).IsVisible = false; // Simplify the polygon shape. MultipolygonShape polygonShape = features[featureId].GetShape() as MultipolygonShape; polygonShape = polygonShape.Simplify(GeographyUnit.Meter, distance, distanceUnit, SimplificationType.DouglasPeucker); Feature simplifiedFeature = new Feature(polygonShape); simplifiedFeature.ColumnValues["Display"] = "SimplifiedPolygon"; simplifiedFeature.ColumnValues["Name"] = "SimplifiedPolygon"; outputLayer.InternalFeatures.Add(simplifiedFeature); } } [Route("Execute/Split")] [HttpPost] public void Split([FromBody]Dictionary parameters) { // Get the id of polygon shape used for split. string polygonId = parameters["polygonId"]; // Get the id of the line used for splitting the polygon shape. string lineId = parameters["lineId"]; InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Hide the input layer. ((InMemoryFeatureLayer)layerOverlay.Layers["input"]).IsVisible = false; // Get the polygon shape used for split. PolygonShape polygonShape = features[polygonId].GetShape() as PolygonShape; // Get the line for splitting the polygon shape. LineShape lineShape = features[lineId].GetShape() as LineShape; MultipolygonShape resultPolygon = Split(polygonShape, lineShape); for (int i = 0; i < resultPolygon.Polygons.Count; i++) { Feature feature = new Feature(resultPolygon.Polygons[i]); feature.ColumnValues["Display"] = "Subcommunity" + (i + 1).ToString(CultureInfo.InvariantCulture); feature.ColumnValues["Name"] = feature.ColumnValues["Display"]; outputLayer.InternalFeatures.Add(feature); } } } [Route("Execute/CalculateShortestLine")] [HttpPost] public void CalculateShortestLine([FromBody]Dictionary parameters) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Get the 2 shapes passed from client side for calculating the shortest distance. BaseShape shape1 = features[parameters["id1"].GetShape(); BaseShape shape2 = features[parameters["id2"].GetShape(); // Calculate the shortest distance. MultilineShape resultShape = shape1.GetShortestLineTo(shape2, GeographyUnit.Meter); double distance = shape1.GetDistanceTo(shape2, GeographyUnit.Meter, DistanceUnit.Feet); Feature shortestLine = new Feature(resultShape); shortestLine.ColumnValues["Display"] = string.Format("Distance is {0:N2} feet.", distance); outputLayer.InternalFeatures.Add(shortestLine); } } [Route("Execute/CalculateLength")] [HttpPost] public void CalculateLength([FromBody]string id) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Get the line shape used for calculating the length. LineShape lineShape = features[id].GetShape() as LineShape; // Calculate the length of the line shape. double length = lineShape.GetLength(GeographyUnit.Meter, DistanceUnit.Feet); Feature lengthFeature = new Feature(lineShape); lengthFeature.ColumnValues["Display"] = string.Format("Length is {0:N0} feet.", length); lengthFeature.ColumnValues["Name"] = "Length"; outputLayer.InternalFeatures.Add(lengthFeature); } } [Route("Execute/LineOnLine")] [HttpPost] public void LineOnLine([FromBody]Dictionary parameters) { // Get the feature id passed from client side. string id = parameters["id"]; // Get the first distance from the start vertex of the line. double startingDistance = Convert.ToDouble(parameters["startDistance"], CultureInfo.InvariantCulture); // Get the second distance from the start vertex of the line. double distance = Convert.ToDouble(parameters["distance"], CultureInfo.InvariantCulture); // Get the distance unit passed from client side. DistanceUnit distanceUnit = (DistanceUnit)Enum.Parse(typeof(DistanceUnit), parameters["unit"], true); InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { LineShape lineShape = (LineShape)features[id].GetShape(); // Clip a line on the line between start and end distance. LineBaseShape resultLineShape = lineShape.GetLineOnALine(StartingPoint.FirstPoint, startingDistance, distance, GeographyUnit.Meter, distanceUnit); Feature resultFeature = new Feature(resultLineShape); resultFeature.ColumnValues["Name"] = "GetLineOnLineResult"; outputLayer.InternalFeatures.Add(resultFeature); } } [Route("Execute/Clip")] [HttpPost] public void Clip([FromBody]Dictionary parameters) { InMemoryFeatureLayer inputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["input"]; if (inputLayer.IsVisible) { // Hide the input layer. inputLayer.IsVisible = false; // Get the feature for clipping other features. Feature clippingFeature = features[parameters["id"]; // Get the features which will be clipped by a specified polygon. string clippingSourceIds = parameters["clippingSourceIds"]; Feature[] clippingSourceFeatures = clippingSourceIds.Split(',').Select(tempId => features[tempId]).ToArray(); foreach (var feature in clippingSourceFeatures) { // Clip the feature. Feature resultFeature = feature.GetIntersection(clippingFeature); if (resultFeature != null) { resultFeature.ColumnValues["Name"] = "ClippingResult"; ((InMemoryFeatureLayer)layerOverlay.Layers["output"]).InternalFeatures.Add(resultFeature); } } } } [Route("Execute/ConvexHull")] [HttpPost] public void ConvexHull([FromBody]Dictionary parameters) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Create a MultiPointShape for calculating the convex hull of it. MultipointShape multipointShape = new MultipointShape(); string pointIds = parameters["pointIds"]; foreach (var feature in pointIds.Split(',').Select(id => features[id])) { multipointShape.Points.Add((PointShape)feature.GetShape()); } // Calculate the context hull of points. PolygonShape pointsContextHull = new PolygonShape(multipointShape.ConvexHull()); outputLayer.InternalFeatures.Add(new Feature(pointsContextHull)); // Create a polygon shape for calculating the convex hull of it. string polygonId = parameters["polygonId"]; MultipolygonShape multipolygonShape = features[polygonId].GetShape() as MultipolygonShape; // Calculate the context hull of the polygon shape. PolygonShape polygonContextHull = new PolygonShape(multipolygonShape.GetConvexHull()); outputLayer.InternalFeatures.Add(new Feature(polygonContextHull)); } } [Route("Execute/Snapping")] [HttpPost] public void Snapping([FromBody]Dictionary parameters) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; InMemoryFeatureLayer inputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["input"]; if (outputLayer.InternalFeatures.Count == 0) { // Hide the input layer. inputLayer.IsVisible = false; // Get a MultiLineShape for snapping. MultilineShape multilineShape = inputLayer.InternalFeatures[0].GetShape() as MultilineShape; Feature[] allFeatures = new Feature[] { inputLayer.InternalFeatures[1] }; Collection matchFeatures = new Collection(); // Get the fetaures which are in a specific distance from the MultiLineShape. foreach (var item in allFeatures) { double tempDistance = multilineShape.GetShortestLineTo(item, GeographyUnit.Meter).GetLength(GeographyUnit.Meter, DistanceUnit.Feet); if (tempDistance < 100) { matchFeatures.Add(item); } } // Display the output features. outputLayer.InternalFeatures.Add(new Feature(multilineShape)); foreach (var feature in matchFeatures) { Collection vertices = new Collection(); PointShape resultShape = multilineShape.GetClosestPointTo(feature, GeographyUnit.Meter); MultilineShape tempMultilineShape = feature.GetShape() as MultilineShape; if (tempMultilineShape != null) { double offsetX = resultShape.X - tempMultilineShape.Lines[0].Vertices[0].X; double offsetY = resultShape.Y - tempMultilineShape.Lines[0].Vertices[0].Y; vertices.Add(new Vertex(resultShape)); double x = offsetX + tempMultilineShape.Lines[0].Vertices[1].X; double y = offsetY + tempMultilineShape.Lines[0].Vertices[1].Y; vertices.Add(new Vertex(x, y)); } outputLayer.InternalFeatures.Add(new Feature(new MultilineShape(new LineShape[] { new LineShape(vertices) }))); } foreach (var feature in allFeatures) { if (!matchFeatures.Contains(feature)) { outputLayer.InternalFeatures.Add(feature); } } AddPolygonsToFeatureLayer(outputLayer.InternalFeatures.Skip(1).ToArray(), outputLayer.InternalFeatures); } } [Route("Execute/EnvelopBoundingbox")] [HttpPost] public void CalculateEnvelope([FromBody]string id) { InMemoryFeatureLayer outputLayer = (InMemoryFeatureLayer)layerOverlay.Layers["output"]; if (outputLayer.InternalFeatures.Count == 0) { // Calculate the boundingbox of the specified feature. Feature envelope = new Feature(features[id].GetBoundingBox()); envelope.ColumnValues["Name"] = "EnvelopeResult"; outputLayer.InternalFeatures.Add(envelope); } } private static InMemoryFeatureLayer GetOutputLayer() { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); if (session["Output"] == null) { // Initialize the layer for the result of geoprocessing. InMemoryFeatureLayer outputLayer = new InMemoryFeatureLayer(); outputLayer.Open(); outputLayer.Columns.Add(new FeatureSourceColumn("Name", "character", 100)); outputLayer.Columns.Add(new FeatureSourceColumn("Display", "character", 100)); ValueStyle valueStyle = new ValueStyle(); valueStyle.ColumnName = "Name"; ValueItem defaultValueItem = new ValueItem(); defaultValueItem.Value = ""; defaultValueItem.CustomStyles.Add(new LineStyle(new GeoPen(GeoColor.FromArgb(180, 255, 155, 13), 5))); defaultValueItem.CustomStyles.Add(new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(255, 255, 248, 172)), 8)); defaultValueItem.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 3), new GeoSolidBrush(GeoColor.FromArgb(100, 0, 147, 221)))); // Give different style for different geoprocessing. valueStyle.ValueItems.Add(defaultValueItem); valueStyle.ValueItems.Add(new ValueItem("GetLineOnLineResult", LineStyles.CreateSimpleLineStyle(GeoColor.FromArgb(200, 146, 203, 252), 5f, GeoColor.StandardColors.Black, 6f, true))); valueStyle.ValueItems.Add(new ValueItem("Buffering", new AreaStyle(new GeoSolidBrush(GeoColor.FromArgb(140, 255, 155, 13))))); valueStyle.ValueItems.Add(new ValueItem("ClippingResult", new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1), new GeoSolidBrush(new GeoColor(160, 255, 248, 172))))); valueStyle.ValueItems.Add(new ValueItem("SnappingBuffer", AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.StandardColors.Black))); valueStyle.ValueItems.Add(new ValueItem("EnvelopeResult", new AreaStyle(new GeoPen(GeoColor.FromArgb(255, 255, 155, 13), 3), new GeoSolidBrush(new GeoColor(160, 255, 248, 172))))); valueStyle.ValueItems.Add(new ValueItem("SimplifiedPolygon", new AreaStyle(new GeoPen(GeoColor.FromArgb(255, 255, 155, 13), 2), new GeoSolidBrush(GeoColor.FromArgb(140, 255, 155, 13))))); valueStyle.ValueItems.Add(new ValueItem("Subcommunity1", new AreaStyle(new GeoPen(GeoColor.StandardColors.Gray, 3), new GeoSolidBrush(GeoColor.FromArgb(140, 255, 155, 13))))); valueStyle.ValueItems.Add(new ValueItem("Subcommunity2", new AreaStyle(new GeoPen(GeoColor.StandardColors.Gray, 3), new GeoSolidBrush(GeoColor.FromArgb(150, 255, 204, 1))))); valueStyle.ValueItems.Add(new ValueItem("Length", new TextStyle("Display", new GeoFont("Arial", 10), new GeoSolidBrush(GeoColor.StandardColors.Black)) { ForceHorizontalLabelForLine = true, TextLineSegmentRatio = 5, YOffsetInPixel = 230 })); outputLayer.DrawingMarginPercentage = 200; outputLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle); outputLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new TextStyle("Display", new GeoFont("Arial", 10), new GeoSolidBrush(GeoColor.StandardColors.Black))); outputLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; session["Output"] = outputLayer; } return session["Output"] as InMemoryFeatureLayer; } private static InMemoryFeatureLayer GetInputLayer() { IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current); if (session["Input"] == null) { // Initialize the layer which will be used to hold the geometried use InMemoryFeatureLayer inputLayer = new InMemoryFeatureLayer(); inputLayer.Open(); inputLayer.Columns.Add(new FeatureSourceColumn("Name", "character", 100)); inputLayer.Columns.Add(new FeatureSourceColumn("Display", "character", 100)); ValueStyle valueStyle = new ValueStyle(); valueStyle.ColumnName = "Name"; ValueItem defaultValueItem = new ValueItem(); defaultValueItem.Value = ""; defaultValueItem.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 3), new GeoSolidBrush(GeoColor.FromArgb(100, 0, 147, 221)))); defaultValueItem.CustomStyles.Add(PointStyles.CreateSimplePointStyle(PointSymbolType.Circle, GeoColor.StandardColors.Transparent, GeoColor.StandardColors.Black, 12)); defaultValueItem.CustomStyles.Add(new LineStyle(new GeoPen(GeoColor.FromArgb(180, 255, 155, 13), 5))); valueStyle.ValueItems.Add(defaultValueItem); valueStyle.ValueItems.Add(new ValueItem("Community", new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 3), new GeoSolidBrush(GeoColor.FromArgb(100, 0, 147, 221))))); valueStyle.ValueItems.Add(new ValueItem("SnappingBuffer", AreaStyles.CreateSimpleAreaStyle(GeoColor.SimpleColors.Transparent, GeoColor.StandardColors.Black))); valueStyle.ValueItems.Add(new ValueItem("ClippingSource", new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1), new GeoSolidBrush(new GeoColor(160, 255, 248, 172))))); PointStyle firePointStyle = new PointStyle(); firePointStyle.PointType = PointType.Bitmap; firePointStyle.Image = new GeoImage(HttpContext.Current.Server.MapPath(@"~/Images/fire.png")); valueStyle.ValueItems.Add(new ValueItem("FirePoint", firePointStyle)); ValueStyle valueStyle1 = new ValueStyle(); valueStyle1.ColumnName = "Name"; valueStyle1.ValueItems.Add(new ValueItem("Clipping", new AreaStyle(new GeoPen(GeoColor.FromArgb(255, 128, 128, 255), 2), new GeoSolidBrush(GeoColor.FromArgb(100, 146, 203, 252))))); inputLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle); inputLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle1); inputLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new TextStyle("Display", new GeoFont("Arial", 10), new GeoSolidBrush(GeoColor.StandardColors.Black))); inputLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; session["Input"] = inputLayer; } return session["Input"] as InMemoryFeatureLayer; } private static GeoCollection LoadData() { // Load the geometries from the XML file for doing processing. GeoCollection features = new GeoCollection(); XElement xElement = XElement.Load(HttpContext.Current.Server.MapPath(@"~/App_Data/inputFeatures.xml")); var featureXElements = xElement.Descendants("Feature").ToArray(); foreach (var featureXElement in featureXElements) { if (!string.IsNullOrEmpty(featureXElement.Value) && featureXElement.Value.Trim().Length > 0) { Feature feature = new Feature(featureXElement.Value); foreach (var xAttribute in featureXElement.Attributes()) { feature.ColumnValues[xAttribute.Name.LocalName] = xAttribute.Value; } features.Add(featureXElement.Attribute("id").Value, feature); } } return features; } private void AddPolygonsToFeatureLayer(IEnumerable features, Collection layerFeatures) { lock (features) { foreach (var feature in features) { MultilineShape multilineShape = feature.GetShape() as MultilineShape; if (multilineShape != null) { foreach (var vertex in multilineShape.Lines.SelectMany(l => l.Vertices)) { double distanceInMeter = Conversion.ConvertMeasureUnits(100, DistanceUnit.Feet, DistanceUnit.Meter); EllipseShape ellipseShape = new EllipseShape(new PointShape(vertex), Math.Round(distanceInMeter, 2)); Feature tempFeature = new Feature(ellipseShape); tempFeature.ColumnValues["Name"] = "SnappingBuffer"; layerFeatures.Add(tempFeature); } } } } } private static MultipolygonShape Split(PolygonShape polygonShape, LineShape lineShape) { MultipolygonShape resultShape = new MultipolygonShape(); MultipointShape intersectionMultiPoint = lineShape.GetCrossing(polygonShape.OuterRing); if (intersectionMultiPoint.Points.Count == 2) { PolygonShape polygonShape1 = GetPolygonForSplit(polygonShape, lineShape, false); PolygonShape polygonShape2 = GetPolygonForSplit(polygonShape, lineShape, true); resultShape.Polygons.Add(polygonShape1); resultShape.Polygons.Add(polygonShape2); } return resultShape; } private static PolygonShape GetPolygonForSplit(PolygonShape processedPolygon, LineShape processedLineShape, bool changeOrder) { MultipointShape intersectionMultiPoint = new MultipointShape(); PolygonShape orderedPolygon = processedPolygon; LineShape lineShape = new LineShape((processedLineShape.GetIntersection(orderedPolygon.OuterRing)).Lines[0].GetWellKnownText()); if (changeOrder) { List verticesToReverse = new List(lineShape.Vertices); verticesToReverse.Reverse(); lineShape.Vertices.Clear(); foreach (Vertex vertice in verticesToReverse) { lineShape.Vertices.Add(vertice); } } foreach (Vertex vertex in lineShape.Vertices) { intersectionMultiPoint.Points.Add(new PointShape(vertex)); } if (intersectionMultiPoint.Points.Count >= 2) { PolygonShape resultPolygonShape = new PolygonShape(); RingShape resultOuterRing = SplitRing(orderedPolygon.OuterRing, intersectionMultiPoint.Points); resultPolygonShape.OuterRing = resultOuterRing; foreach (RingShape innerRing in orderedPolygon.InnerRings) { MultipointShape innerIntersectionMultiPoint = lineShape.GetCrossing(innerRing); if (innerIntersectionMultiPoint.Points.Count == 2) { RingShape resultInnerRing = SplitRing(innerRing, innerIntersectionMultiPoint.Points); if (resultPolygonShape.Contains(resultInnerRing)) { resultPolygonShape.InnerRings.Add(resultInnerRing); } } else { if (resultPolygonShape.Contains(innerRing)) { resultPolygonShape.InnerRings.Add(innerRing); } } } return resultPolygonShape; } return null; } private static RingShape SplitRing(RingShape processedRing, Collection intersectionPointShapes) { RingShape resultRingShape = new RingShape(); PointShape intersectionPointShape1 = intersectionPointShapes[0]; PointShape intersectionPointShape2 = intersectionPointShapes[intersectionPointShapes.Count|- 1]; int i = 0; int totalPointNumber = processedRing.Vertices.Count; while (i < totalPointNumber - 1) { int indexA = i + 1; if (DoesPointShapeBelongToLineSegment(intersectionPointShape1, new PointShape(processedRing.Vertices[i]), new PointShape(processedRing.Vertices[indexA]))) { resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1)); if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices[i]), new PointShape(processedRing.Vertices[indexA]))) { for (int shapeIndex = intersectionPointShapes.Count - 1; shapeIndex > 0; shapeIndex--) { resultRingShape.Vertices.Add(new Vertex(intersectionPointShapes[shapeIndex])); } resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1)); } else { for (int j = i + 1; j <= processedRing.Vertices.Count - 1; j++) { //- 1 int indexB = j + 1; if (j < processedRing.Vertices.Count - 1) { if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices[j]), new PointShape(processedRing.Vertices[indexB]))) { resultRingShape.Vertices.Add(processedRing.Vertices[j]); for (int shapeIndex = intersectionPointShapes.Count - 1; shapeIndex > 0; shapeIndex--) { resultRingShape.Vertices.Add(new Vertex(intersectionPointShapes[shapeIndex])); } resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1)); break; } else { resultRingShape.Vertices.Add(processedRing.Vertices[j]); } } else { for (int k = 0; k < i; k++) { if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices[k]), new PointShape(processedRing.Vertices[(k|+ 1)]))) { resultRingShape.Vertices.Add(processedRing.Vertices[k]); for (int shapeIndex = intersectionPointShapes.Count - 1; shapeIndex > 0; shapeIndex--) { resultRingShape.Vertices.Add(new Vertex(intersectionPointShapes[shapeIndex])); } resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1)); break; } else { resultRingShape.Vertices.Add(processedRing.Vertices[k]); } } break; } } } return resultRingShape; } i = i + 1; } return null; } private static bool DoesPointShapeBelongToLineSegment(PointShape pointShape, PointShape linePointShape1, PointShape linePointShape2) { bool result = false; double a = 0; double b = 0; if ((pointShape.X == linePointShape1.X & pointShape.Y == linePointShape1.Y) | (pointShape.X == linePointShape2.X & pointShape.Y == linePointShape2.Y)) { result = true; } else { if (linePointShape1.X != linePointShape2.X) { a = (linePointShape2.Y - linePointShape1.Y) / (linePointShape2.X - linePointShape1.X); b = linePointShape1.Y - (a * linePointShape1.X); if (Math.Round(pointShape.Y, 5) == Math.Round((a * pointShape.X) + b, 5) & pointShape.X >= Math.Min(linePointShape1.X, linePointShape2.X) & pointShape.X <= Math.Max(linePointShape1.X, linePointShape2.X)) { result = true; } else { result = false; } } else { if (pointShape.X == linePointShape1.X & (pointShape.Y >= Math.Min(linePointShape1.Y, linePointShape2.Y) & pointShape.Y <= Math.Max(linePointShape1.Y, linePointShape2.Y))) { result = true; } else { result = false; } } } return result; } } } =====Default.htm(LeafLet)===== Geometric Functions
Geometric Function List
  • Union
  • Difference
  • Buffer
  • Scale
  • Rotate
  • Center point
  • Area Calculation
  • Simplify
  • Split
  • Get shortest line
  • Length Calculation
  • Get line on a line
  • Clip
  • Convexhull
  • Snapping
  • Envelope Boundingbox
=====Default.htm(OpenLayers)===== Geometric Functions
Geometric Function List
  • Union
  • Difference
  • Buffer
  • Scale
  • Rotate
  • Center point
  • Area Calculation
  • Simplify
  • Split
  • Get shortest line
  • Length Calculation
  • Get line on a line
  • Clip
  • Convexhull
  • Snapping
  • Envelope Boundingbox