Table of Contents

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<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> 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<ScreenPointF> screenPointFs = new Collection<ScreenPointF>();
                        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" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <link href="~/theme/default/samplepic/style.css" rel="stylesheet" type="text/css" />
    <title>Distance Line Style with Projection</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <cc1:Map ID="Map1" runat="server" Height="100%" Width="100%">
    </cc1:Map>
   <%-- <description:descriptionpanel ID="DescPanel" runat="server">
        This sample displays a google map. Click buttons below to switch between different Google maps.
        <br />
        <br />
        <asp:Button CssClass="btn" ID="btnRoad" runat="server" Text="Normal" OnClientClick="Map1.SetCurrentBackgroundMapType(G_NORMAL_MAP); return false;" />
        <asp:Button CssClass="btn" ID="btnAerial" runat="server" Text="Hybrid" OnClientClick="Map1.SetCurrentBackgroundMapType(G_HYBRID_MAP); return false;" /><br />
        <asp:Button CssClass="btn" ID="btnSatellite" runat="server" Text="Satellite" OnClientClick="Map1.SetCurrentBackgroundMapType(G_SATELLITE_MAP); return false;" />
        <asp:Button CssClass="btn" ID="btnPhysical" runat="server" Text="Physical" OnClientClick="Map1.SetCurrentBackgroundMapType(G_PHYSICAL_MAP); return false;" />
    </description:descriptionpanel>--%>
    </form>
</body>
</html>