====== 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
-
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
-
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