====== Source Code WebEditionSample ProjectionDistanceLineStyle CS 100902.zip ======
====CustomDistanceLineStyle.cs====
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace DistanceLineStyleWithProjection
{
public class CustomDistanceLineStyle : LineStyle
{
private GeoFont geoFont;
private GeoSolidBrush geoSolidBrush;
private GeoPen geoPen;
private DistanceUnit distanceUnit;
private ManagedProj4Projection proj4;
private GeographyUnit projectionUnit;
public CustomDistanceLineStyle()
: this(DistanceUnit.Meter,new ManagedProj4Projection(),GeographyUnit.Meter,new GeoFont(), new GeoSolidBrush(), new GeoPen())
{}
public CustomDistanceLineStyle( DistanceUnit distanceUnit, ManagedProj4Projection projection,GeographyUnit projectionUnit, GeoFont geoFont, GeoSolidBrush geoSolidBrush, GeoPen geoPen)
{
this.distanceUnit = distanceUnit;
this.proj4 = projection;
this.projectionUnit = projectionUnit;
this.geoFont = geoFont;
this.geoSolidBrush = geoSolidBrush;
this.geoPen = geoPen;
}
//For the font of the distance
public GeoFont GeoFont
{
get { return geoFont; }
set { geoFont = value; }
}
//For the color of the font
public GeoSolidBrush GeoSolidBrush
{
get { return geoSolidBrush; }
set { geoSolidBrush = value; }
}
//For the color of the halo of the font
public GeoPen GeoPen
{
get { return geoPen; }
set { geoPen = value; }
}
//For the distance unit used.
public DistanceUnit DistanceUnit
{
get { return distanceUnit; }
set { distanceUnit = value; }
}
//For the projection used.
public ManagedProj4Projection Projection
{
get { return proj4; }
set { proj4 = value; }
}
//For the unit of the external projection of Projection
public GeographyUnit ProjectionUnit
{
get { return projectionUnit; }
set { projectionUnit = value; }
}
protected override void DrawCore(System.Collections.Generic.IEnumerable features, GeoCanvas canvas, System.Collections.ObjectModel.Collection labelsInThisLayer, System.Collections.ObjectModel.Collection labelsInAllLayers)
{
//Loops thru the features to to label the distance of each line segment at mid point based on the external projection.
proj4.Open();
foreach (Feature feature in features)
{
LineShape lineShape = (LineShape)feature.GetShape();
for (int i = 0; i < lineShape.Vertices.Count - 1; i++)
{
PointShape pointShape1 = new PointShape(lineShape.Vertices[i]);
PointShape pointShape2 = new PointShape(lineShape.Vertices[i|+ 1]);
//Gets the projected points.
PointShape projPointShape1 = (PointShape)proj4.ConvertToExternalProjection(pointShape1);
PointShape projPointshape2 = (PointShape)proj4.ConvertToExternalProjection(pointShape2);
//Gets the distance for the projected points.
double projCurrentDist = Math.Round(projPointShape1.GetDistanceTo(projPointshape2, GeographyUnit.Meter, distanceUnit), 2);
//Logic for finding the angle for the text according to the line segment orientation.
LineShape tempLineShape = new LineShape();
tempLineShape.Vertices.Add(new Vertex(pointShape1));
tempLineShape.Vertices.Add(new Vertex(pointShape2));
PointShape midPointShape = tempLineShape.GetPointOnALine(StartingPoint.FirstPoint, 50);
Collection screenPointFs = new Collection();
screenPointFs.Add(ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, midPointShape, canvas.Width, canvas.Height));
double angle = GetAngleFromTwoVertices(tempLineShape.Vertices[0], tempLineShape.Vertices[1]);
//Draws the label for the distance at the right angle.
canvas.DrawText(projCurrentDist.ToString(), geoFont, GeoSolidBrush, geoPen, screenPointFs, DrawingLevel.LabelLevel,0, 0, (float)angle);
}
}
proj4.Close();
}
private double GetAngleFromTwoVertices(Vertex b, Vertex c)
{
double result;
double alpha = 0;
double tangentAlpha = (c.Y - b.Y) / (c.X - b.X);
double Peta = Math.Atan(tangentAlpha);
if (c.X > b.X)
{
alpha = 90 + (Peta * (180 / Math.PI));
}
else if (c.X < b.X)
{
alpha = 270 + (Peta * (180 / Math.PI));
}
else
{
if (c.Y > b.Y) alpha = 0;
if (c.Y < b.Y) alpha = 180;
}
double offset;
if (b.X > c.X)
{ offset = 90; }
else { offset = - 90; }
result = alpha + offset;
return result;
}
}
}
====TestForm.aspx.cs====
using System;
using System.Configuration;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WebEdition;
namespace DistanceLineStyleWithProjection
{
public partial class TestForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
Map1.CurrentExtent = new RectangleShape(-10781223,3910007,-10776789,3907379);
Map1.MapUnit = GeographyUnit.Meter;
Map1.MapTools.OverlaySwitcher.Enabled = true;
Map1.MapTools.MouseCoordinate.Enabled = true;
//Adds the Google Map as an overlay
GoogleOverlay google = new GoogleOverlay("Google Map");
google.JavaScriptLibraryUri = new Uri(ConfigurationManager.AppSettings["GoogleUri"]);
google.GoogleMapType = GoogleMapType.Normal;
Map1.CustomOverlays.Add(google);
LineShape lineShape = new LineShape();
lineShape.Vertices.Add(new Vertex(-10778667,3909061));
lineShape.Vertices.Add(new Vertex(-10778662,3909462));
lineShape.Vertices.Add(new Vertex(-10780344,3909476));
lineShape.Vertices.Add(new Vertex(-10780344,3909032));
lineShape.Vertices.Add(new Vertex(-10780372,3908688));
lineShape.Vertices.Add(new Vertex(-10780645,3908717));
InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();
//Adds the CustomDistanceLineStyle for displaying the distance in meter at mid point for each line segment.
//The external projection is State Plane Texas North Central for a more accurate distance than with Google map
//projection (Spherical Mercator). The unit of the State Plane projection is Meter.
ManagedProj4Projection proj4 = new ManagedProj4Projection();
proj4.InternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString();
proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetEsriParametersString(102338);
CustomDistanceLineStyle customDisctanceLineStyle = new CustomDistanceLineStyle(DistanceUnit.Meter,proj4,GeographyUnit.Meter, new GeoFont("Arial",12,DrawingFontStyles.Bold),
new GeoSolidBrush(GeoColor.StandardColors.Black), new GeoPen(GeoColor.StandardColors.White));
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(customDisctanceLineStyle);
//Adds a regular LineStyle for displaying in red the LineShape.
LineStyle lineStyle = new LineStyle(new GeoPen(GeoColor.FromArgb(150, GeoColor.StandardColors.Red), 5));
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(lineStyle);
inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
inMemoryFeatureLayer.InternalFeatures.Add(new Feature(lineShape));
LayerOverlay layerOverlay = new LayerOverlay("LineOverlay", false, TileType.SingleTile);
layerOverlay.TransitionEffect = TransitionEffect.None;
layerOverlay.Layers.Add(inMemoryFeatureLayer);
Map1.CustomOverlays.Add(layerOverlay);
}
}
}
}
====TestForm.aspx====
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestForm.aspx.cs" Inherits="DistanceLineStyleWithProjection.TestForm" %>
<%@ Register Assembly="WebEdition" Namespace="ThinkGeo.MapSuite.WebEdition" TagPrefix="cc1" %>
Distance Line Style with Projection