User Tools

Site Tools


source_code_desktopeditionsample_kmlextension_cs_100623.zip

Source Code DesktopEditionSample KmlExtension CS 100623.zip

Program.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Windows.Forms;  
 
 namespace KmlExtensionSample  
 {  
     static class Program  
     {  
         /// <summary>  
         /// The main entry point for the application.  
         /// </summary>  
         [STAThread]  
         static void Main()  
         {  
             Application.EnableVisualStyles();  
             Application.SetCompatibleTextRenderingDefault(false);  
             Application.Run(new TestForm());  
         }  
     }  
 }  
 

TestForm.cs

 using System;  
 using System.Windows.Forms;  
 using System.Collections.ObjectModel;  
 using ThinkGeo.MapSuite.Core;  
 using ThinkGeo.MapSuite.DesktopEdition;  
 using System.IO;  
 
 
 namespace KmlExtensionSample  
 {  
     public partial class TestForm : Form  
     {  
         public TestForm()  
         {  
             InitializeComponent();  
         }  
 
         private void TestForm_Load(object sender, EventArgs e)  
         {  
             winformsMap1.MapUnit = GeographyUnit.DecimalDegree;  
             winformsMap1.CurrentExtent = new RectangleShape(-122.0874, 37.4245, -122.0804, 37.4201);  
             winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));  
             winformsMap1.ZoomLevelSnapping = ZoomLevelSnappingMode.Default;  
 
             WorldMapKitWmsDesktopOverlay worldMapKitWmsDesktopOverlay = new WorldMapKitWmsDesktopOverlay();  
             winformsMap1.Overlays.Add(worldMapKitWmsDesktopOverlay);  
 
             KmlFeatureLayer layer = new KmlFeatureLayer("..
..
App_Data
KML_Samples.kml");  
             layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Black), new GeoSolidBrush(GeoColor.SimpleColors.Yellow));  
             layer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.SimpleColors.Blue, 5));  
             layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.SimpleColors.Green), 10);  
 
             LayerOverlay stateOverlay = new LayerOverlay();  
             stateOverlay.Layers.Add("KmlLayer", layer);  
             winformsMap1.Overlays.Add("StateOverlay", stateOverlay);  
 
             winformsMap1.Refresh();  
         }  
 
         private void winformsMap1_MouseMove(object sender, MouseEventArgs e)  
         {  
             //Displays the X and Y in screen coordinates.  
             statusStrip1.Items["toolStripStatusLabelScreen"].Text = "X:" + e.X + " Y:" + e.Y;  
 
             //Gets the PointShape in world coordinates from screen coordinates.  
             PointShape pointShape = ExtentHelper.ToWorldCoordinate(winformsMap1.CurrentExtent, new ScreenPointF(e.X, e.Y), winformsMap1.Width, winformsMap1.Height);  
 
             //Displays world coordinates.  
             statusStrip1.Items["toolStripStatusLabelWorld"].Text = "(world) X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4);  
         }  
 
         private void btnClose_Click(object sender, EventArgs e)  
         {  
             this.Close();  
         }  
     }  
 }  
 

KmlFeatureLayer.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 
 namespace ThinkGeo.MapSuite.Core  
 {  
     public class KmlFeatureLayer : FeatureLayer  
     {  
 
         protected KmlFeatureLayer()  
             : this(string.Empty)  
         {  
 
         }  
 
         public KmlFeatureLayer(string kmlPathFileName)  
             : this(kmlPathFileName, KmlStringType.File)  
         {  
         }  
 
         public KmlFeatureLayer(string kmlString, KmlStringType stringType)  
             : base()  
         {  
             FeatureSource = new KmlFeatureSource(kmlString, stringType);  
         }  
 
         public override bool HasBoundingBox  
         {  
             get  
             {  
                 return true;  
             }  
         }  
     }  
 }  
 

KmlFeatureSource.cs

 //KML reference  
 //<styleUrl>  
 //URL of a <Style> or <StyleMap> defined in a Document. If the style is in the same file, use a # reference.  
 //If the style is defined in an external file, use a full URL along with # referencing. Examples are  
 //<styleUrl>#myIconStyleID</styleUrl>  
 //<styleUrl>http://someserver.com/somestylefile.xml#restaurant</styleUrl>  
 //<styleUrl>eateries.kml#my-lunch-spot</styleUrl>  
 
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Collections.ObjectModel;  
 using System.Xml;  
 using System.Net;  
 using System.Web;  
 
 namespace ThinkGeo.MapSuite.Core  
 {  
     public class KmlFeatureSource : FeatureSource  
     {  
         private const string presetXml = "<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://earth.google.com/kml/2.1'></kml>";  
         private XmlDocument kmlDocument;  
         private InMemoryFeatureLayer inMemoryFeatureLayer;  
         private Collection<Feature> tempFeatures;  
         private Dictionary<string, Dictionary<string, string>> globalStyles;  
 
         protected KmlFeatureSource()  
             : this(string.Empty)  
         {  
 
         }  
 
         public KmlFeatureSource(string kmlPathFileName)  
             : this(kmlPathFileName, KmlStringType.File)  
         {  
         }  
 
         public KmlFeatureSource(string kmlString, KmlStringType stringType)  
             : base()  
         {  
             switch (stringType)  
             {  
                 case KmlStringType.String:  
                     kmlDocument = new XmlDocument();  
                     if (string.IsNullOrEmpty(kmlString))  
                     {  
                         kmlDocument.LoadXml(presetXml);  
                     }  
                     else  
                     {  
                         kmlDocument.LoadXml(kmlString);  
                     }  
                     break;  
                 case KmlStringType.File:  
                 default:  
                     kmlDocument = new XmlDocument();  
                     kmlDocument.Load(kmlString);  
                     break;  
             }  
             this.inMemoryFeatureLayer = new InMemoryFeatureLayer();  
             inMemoryFeatureLayer.Open();  
             inMemoryFeatureLayer.Columns.Add(new FeatureSourceColumn("linecolor"));  
             inMemoryFeatureLayer.Columns.Add(new FeatureSourceColumn("linewidth"));  
 
             inMemoryFeatureLayer.Close();  
 
             globalStyles = new Dictionary<string, Dictionary<string, string>>();  
         }  
 
         protected override void OpenCore()  
         {  
             if (inMemoryFeatureLayer.InternalFeatures.Count == 0)  
             {  
                 tempFeatures = new Collection<Feature>();  
                 XmlNamespaceManager manager = new XmlNamespaceManager(kmlDocument.NameTable);  
                 manager.AddNamespace("kk", kmlDocument.DocumentElement.NamespaceURI);  
 
                 if (kmlDocument.DocumentElement.HasChildNodes)  
                 {  
                     XmlNodeList styleList = kmlDocument.DocumentElement.ChildNodes[0].SelectNodes("kk:Style", manager);  
                     foreach (XmlNode item in styleList)  
                     {  
                         string styleId = item.Attributes["id"].Value;  
                         Dictionary<string, string> columnValues = GetColumnValues(item, manager);  
                         globalStyles.Add(styleId, columnValues);  
                     }  
 
                     XmlNodeList placemarks = kmlDocument.SelectNodes("//kk:Placemark", manager);  
                     foreach (XmlNode placemark in placemarks)  
                     {  
                         ProcessPlacemark(placemark, manager);  
                     }  
 
                     // There is no Placemark tag, so it may use NetworkLink  
                     if (placemarks.Count == 0)  
                     {  
                         XmlNodeList networkLinks = kmlDocument.SelectNodes("//kk:NetworkLink", manager);  
                         foreach (XmlNode networkLink in networkLinks)  
                         {  
                             ProcessNetworkLink(networkLink, manager);  
                         }  
                     }  
 
                     foreach (Feature item in tempFeatures)  
                     {  
                         WellKnownType wellKnownType = item.GetWellKnownType();  
                         if (wellKnownType == WellKnownType.Polygon || wellKnownType == WellKnownType.Multipolygon)  
                         {  
                             inMemoryFeatureLayer.InternalFeatures.Add(item);  
                         }  
                     }  
 
                     foreach (Feature item in tempFeatures)  
                     {  
                         WellKnownType wellKnownType = item.GetWellKnownType();  
                         if (wellKnownType == WellKnownType.Line || wellKnownType == WellKnownType.Multiline)  
                         {  
                             inMemoryFeatureLayer.InternalFeatures.Add(item);  
                         }  
                     }  
 
                     foreach (Feature item in tempFeatures)  
                     {  
                         WellKnownType wellKnownType = item.GetWellKnownType();  
                         if (wellKnownType == WellKnownType.Point || wellKnownType == WellKnownType.Multipoint)  
                         {  
                             inMemoryFeatureLayer.InternalFeatures.Add(item);  
                         }  
                     }  
                 }  
             }  
         }  
 
         private void ProcessNetworkLink(XmlNode networkLink, XmlNamespaceManager manager)  
         {  
             XmlNode hrefNode = networkLink.SelectSingleNode("kk:Url/kk:href", manager);  
             string fileUrl = hrefNode.InnerText;  
             WebRequest request = WebRequest.Create(fileUrl);  
             request.Timeout = 10000;  
             WebResponse response = null;  
             try  
             {  
                 response = request.GetResponse();  
                 string disposition = response.Headers["Content-Disposition"];  
                 if (!string.IsNullOrEmpty(disposition))  
                 {  
                     string filename = @"C:\temp\" + disposition.Split('=')[1].Trim('\"');  
                     WebClient webClient = new WebClient();  
                     webClient.DownloadFile(fileUrl, filename);  
                     if (filename.EndsWith(".kml", StringComparison.InvariantCultureIgnoreCase))  
                     {  
 
                     }  
                     else if (filename.EndsWith(".kmz", StringComparison.InvariantCultureIgnoreCase))  
                     {  
                         filename = new KmlHelper().ProcessUnZip(filename);  
                     }  
                     else  
                     {  
                         return;  
                     }  
 
                     KmlFeatureSource source = new KmlFeatureSource(filename);  
                     source.Open();  
                     foreach (Feature item in source.inMemoryFeatureLayer.InternalFeatures)  
                     {  
                         tempFeatures.Add(item);  
                     }  
                     source.Close();  
 
                 }  
             }  
             catch  
             {  
 
             }  
             finally  
             {  
                 if (response != null)  
                 {  
                     response.Close();  
                 }  
             }  
         }  
 
         private void ProcessPlacemark(XmlNode placemark, XmlNamespaceManager manager)  
         {  
             XmlNode stylesNode = placemark.SelectSingleNode("kk:Style", manager);  
             Dictionary<string, string> columnValues = GetColumnValues(stylesNode, manager);  
 
             XmlNode descriptionNode = placemark.SelectSingleNode("kk:description", manager);  
             if (descriptionNode != null)  
             {  
                 columnValues.Add("popupHTML", descriptionNode.InnerXml);  
             }  
 
             XmlNodeList linearRingList = placemark.SelectNodes(".//kk:LinearRing", manager);  
             foreach (XmlNode node in linearRingList)  
             {  
                 string value = node.SelectSingleNode("kk:coordinates", manager).InnerText.Trim();  
                 //TODO: the document says use " ", not "\r\n"  
                 string[] values = value.Split(new string[] { " ", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);  
                 Collection<Vertex> Vertices = new Collection<Vertex>();  
                 foreach (string item in values)  
                 {  
                     string[] items = item.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);  
                     Vertex vertex = new Vertex(double.Parse(items[0]), double.Parse(items[1]));  
                     Vertices.Add(vertex);  
                 }  
                 RingShape ringShape = new RingShape(Vertices);  
                 tempFeatures.Add(new Feature(ringShape, columnValues));  
             }  
 
             XmlNodeList lineStringList = placemark.SelectNodes(".//kk:LineString", manager);  
             foreach (XmlNode node in lineStringList)  
             {  
                 string value = node.SelectSingleNode("kk:coordinates", manager).InnerText.Trim();  
                 //TODO: the document says use " ", not "\r\n"  
                 string[] values = value.Split(new string[] { " ", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);  
                 Collection<Vertex> Vertices = new Collection<Vertex>();  
                 foreach (string item in values)  
                 {  
                     string[] items = item.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);  
                     Vertex vertex = new Vertex(double.Parse(items[0]), double.Parse(items[1]));  
                     Vertices.Add(vertex);  
                 }  
                 LineShape lineShape = new LineShape(Vertices);  
 
                 if (columnValues.Count == 0 || (columnValues.Count == 1 && columnValues.ContainsKey("popupHTML")))  
                 {  
                     columnValues.Add("linecolor", "ffffffff");  
                     columnValues.Add("linewidth", "1");  
                     if (placemark.SelectSingleNode("kk:styleUrl", manager) != null)  
                     {  
                         string styleUrl = placemark.SelectSingleNode("kk:styleUrl", manager).InnerText;  
                         if (styleUrl.StartsWith("#"))  
                         {  
                             columnValues = globalStyles[styleUrl.TrimStart('#')];  
                         }  
                     }  
                 }  
 
                 tempFeatures.Add(new Feature(lineShape, columnValues));  
             }  
 
             XmlNodeList pointList = placemark.SelectNodes(".//kk:Point", manager);  
             foreach (XmlNode item in pointList)  
             {  
                 string value = item.SelectSingleNode("kk:coordinates", manager).InnerText.Trim();  
                 string[] values = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);  
                 PointShape point = new PointShape(double.Parse(values[0]), double.Parse(values[1]));  
                 tempFeatures.Add(new Feature(point, columnValues));  
             }  
         }  
 
         private Dictionary<string, string> GetColumnValues(XmlNode stylesNode, XmlNamespaceManager manager)  
         {  
             Dictionary<string, string> columnValues = new Dictionary<string, string>();  
             if (stylesNode != null)  
             {  
                 foreach (XmlNode styleNode in stylesNode.ChildNodes)  
                 {  
                     if (styleNode.Name == "LineStyle")  
                     {  
                         string linecolor = "ffffffff";  
                         if (styleNode.SelectSingleNode("kk:color", manager) != null)  
                         {  
                             linecolor = styleNode.SelectSingleNode("kk:color", manager).InnerText;  
                         }  
                         string linewidth = "1";  
                         if (styleNode.SelectSingleNode("kk:width", manager) != null)  
                         {  
                             linewidth = styleNode.SelectSingleNode("kk:width", manager).InnerText;  
                         }  
                         columnValues.Add("linecolor", linecolor);  
                         columnValues.Add("linewidth", linewidth);  
                         break;  
                     }  
                 }  
             }  
 
             return columnValues;  
         }  
 
         protected override void CloseCore()  
         {  
             //inMemoryFeatureLayer.InternalFeatures.Clear();  
             //globalStyles.Clear();  
         }  
 
         protected override Collection<Feature> GetAllFeaturesCore(IEnumerable<string> returningColumnNames)  
         {  
             return inMemoryFeatureLayer.InternalFeatures;  
         }  
     }  
 }  
 

KmlHelper.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Web;  
 using ICSharpCode.SharpZipLib.Zip;  
 using System.IO;  
 
 namespace ThinkGeo.MapSuite.Core  
 {  
     public class KmlHelper  
     {  
 
         // Copy this function is from FormIndexBuilder.  
         public string ProcessUnZip(string fileToUpZip)  
         {  
             ZipInputStream s = null;  
             ZipEntry theEntry = null;  
 
             string fileName = null;  
             FileStream streamWriter = null;  
             try  
             {  
                 s = new ZipInputStream(File.OpenRead(fileToUpZip));  
                 //s.Password = Password;  
                 while ((theEntry = s.GetNextEntry()) != null)  
                 {  
                     if (theEntry.Name != String.Empty)  
                     {  
                         if (theEntry.Name.EndsWith(".kml", StringComparison.InvariantCultureIgnoreCase))  
                         {  
                             string folder = Path.GetDirectoryName(fileToUpZip);  
                             fileName = Path.Combine(folder, theEntry.Name);  
 
                             fileName = fileName.Replace("/", "
");  
                             string directoryName = Path.GetDirectoryName(fileName);  
                             if (!Directory.Exists(directoryName))  
                             {  
                                 Directory.CreateDirectory(directoryName);  
                             }  
 
                             streamWriter = File.Create(fileName);  
                             int size = 2048;  
                             byte[] data = new byte[2048];  
                             while (true)  
                             {  
                                 size = s.Read(data, 0, data.Length);  
                                 if (size > 0)  
                                 {  
                                     streamWriter.Write(data, 0, size);  
                                 }  
                                 else  
                                 {  
                                     break;  
                                 }  
                             }  
                             break;  
                         }  
                     }  
                 }  
                 return fileName;  
             }  
             finally  
             {  
                 if (streamWriter != null)  
                 {  
                     streamWriter.Close();  
                     streamWriter = null;  
                 }  
                 if (theEntry != null)  
                 {  
                     theEntry = null;  
                 }  
                 if (s != null)  
                 {  
                     s.Close();  
                     s = null;  
                 }  
                 GC.Collect();  
                 GC.Collect(1);  
             }  
         }  
     }  
 }  
 

KmlStringType.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Web;  
 
 namespace ThinkGeo.MapSuite.Core  
 {  
     public enum KmlStringType  
     {  
         File = 0,  
         String = 1,  
     }  
 }  
 

KmlStyle.cs

 //KML reference:  
 //<color>  
 //Color and opacity (alpha) values are expressed in hexadecimal notation. The range of values for any one color is 0  
 //to 255 (00 to ff). For alpha, 00 is fully transparent and ff is fully opaque. The order of expression is aabbggrr,  
 //where aa=alpha (00 to ff); bb=blue (00 to ff); gg=green (00 to ff); rr=red (00 to ff). For example, if you want to  
 //apply a blue color with 50 percent opacity to an overlay, you would specify the following: <color>7fff0000</color>,  
 //where alpha=0x7f, blue=0xff, green=0x00, and red=0x00.  
 
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Drawing.Imaging;  
 using System.Globalization;  
 using System.IO;  
 
 namespace ThinkGeo.MapSuite.Core  
 {  
     public class KmlStyle : Style  
     {  
         private GeoImage defaultIcon;  
 
         public KmlStyle()  
             : base()  
         {  
             Stream stream = new MemoryStream();  
             Properties.Resources.GoogleEarthPushpin.Save(stream, ImageFormat.Png);  
             defaultIcon = new GeoImage(stream);  
         }  
 
         public GeoImage DefaultIcon  
         {  
             get { return defaultIcon; }  
             set { defaultIcon = value; }  
         }  
 
         protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)  
         {  
             foreach (Feature feature in features)  
             {  
                 switch (feature.GetWellKnownType())  
                 {  
                     case WellKnownType.Line:  
                     case WellKnownType.Multiline:  
                         {  
                             GeoPen geoPen = GetGeoPen(feature);  
                             canvas.DrawLine(feature, geoPen, DrawingLevel.LevelOne);  
                         }  
                         break;  
                     case WellKnownType.Point:  
                     case WellKnownType.Multipoint:  
                         if (defaultIcon == null)  
                         {  
                             GeoBrush geoBrush = GetGeoBrush(feature);  
                             canvas.DrawEllipse(feature, 8, 8, geoBrush, DrawingLevel.LevelOne);  
                         }  
                         else  
                         {  
                             PointShape pointShape = feature.GetShape() as PointShape;  
                             canvas.DrawWorldImageWithoutScaling(defaultIcon, pointShape.X, pointShape.Y, DrawingLevel.LevelOne);  
                         }  
                         break;  
                     case WellKnownType.Polygon:  
                     case WellKnownType.Multipolygon:  
                         {  
                             GeoPen geoPen = GetGeoPen(feature);  
                             canvas.DrawArea(feature, geoPen, DrawingLevel.LevelOne);  
                         }  
                         break;  
                 }  
             }  
         }  
 
         private GeoBrush GetGeoBrush(Feature feature)  
         {  
             return new GeoSolidBrush(GeoColor.SimpleColors.Black);  
         }  
 
         private GeoPen GetGeoPen(Feature feature)  
         {  
             GeoPen geoPen = new GeoPen(GeoColor.SimpleColors.Black);  
 
             if (feature.ColumnValues.Count >= 2)  
             {  
                 string linecolor = feature.ColumnValues["linecolor"];  
                 string linewidth = feature.ColumnValues["linewidth"];  
 
                 GeoColor geoColor = GetGeoColor(linecolor);  
                 int width = int.Parse(linewidth);  
 
                 geoPen.Color = geoColor;  
                 geoPen.Width = width;  
             }  
 
             return geoPen;  
         }  
 
         private GeoColor GetGeoColor(string linecolor)  
         {  
             GeoColor geoColor = new GeoColor();  
 
             if (linecolor.Length == 8)  
             {  
                 int alpha = int.Parse(linecolor.Substring(0, 2), NumberStyles.AllowHexSpecifier);  
                 int blue = int.Parse(linecolor.Substring(2, 2), NumberStyles.AllowHexSpecifier);  
                 int green = int.Parse(linecolor.Substring(4, 2), NumberStyles.AllowHexSpecifier);  
                 int red = int.Parse(linecolor.Substring(6, 2), NumberStyles.AllowHexSpecifier);  
 
                 geoColor = new GeoColor(alpha, red, green, blue);  
             }  
 
             return geoColor;  
         }  
     }  
 }  
 
source_code_desktopeditionsample_kmlextension_cs_100623.zip.txt · Last modified: 2015/09/08 07:48 by admin