====== Source Code WebEditionSample KmlExtension CS 100629.zip ======
====TestForm.aspx.cs====
using System;
using System.Configuration;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WebEdition;
using System.IO;
using System.Collections.ObjectModel;
namespace KmlExtensionWeb
{
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(-122.0874, 37.4245, -122.0804, 37.4201);
Map1.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitWmsWebOverlay worldMapKitOverlay = new WorldMapKitWmsWebOverlay();
Map1.CustomOverlays.Add(worldMapKitOverlay);
KmlFeatureLayer layer = new KmlFeatureLayer(MapPath("~/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 dynamicOverlay = new LayerOverlay("DynamicOverlay");
dynamicOverlay.IsBaseOverlay = false;
dynamicOverlay.Layers.Add("KmlLayer", layer);
Map1.CustomOverlays.Add(dynamicOverlay);
}
}
}
}
====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
//
//URL of a
//http://someserver.com/somestylefile.xml#restaurant
//eateries.kml#my-lunch-spot
//KML reference
//
//URL of a
//http://someserver.com/somestylefile.xml#restaurant
//eateries.kml#my-lunch-spot
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;
using System.Globalization;
namespace ThinkGeo.MapSuite.Core
{
public class KmlFeatureSource : FeatureSource
{
private const string presetXml = "";
private XmlDocument kmlDocument;
private InMemoryFeatureLayer inMemoryFeatureLayer;
private Collection tempFeatures;
private Dictionary> 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>();
}
protected override void OpenCore()
{
if (inMemoryFeatureLayer.InternalFeatures.Count == 0)
{
tempFeatures = new Collection();
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 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 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 Vertices = new Collection();
foreach (string item in values)
{
string[] items = item.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
Vertex vertex = new Vertex(double.Parse(items[0], CultureInfo.InvariantCulture), double.Parse(items[1], CultureInfo.InvariantCulture));
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 Vertices = new Collection();
foreach (string item in values)
{
string[] items = item.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
Vertex vertex = new Vertex(double.Parse(items[0], CultureInfo.InvariantCulture), double.Parse(items[1], CultureInfo.InvariantCulture));
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], CultureInfo.InvariantCulture), double.Parse(values[1], CultureInfo.InvariantCulture));
tempFeatures.Add(new Feature(point, columnValues));
}
}
private Dictionary GetColumnValues(XmlNode stylesNode, XmlNamespaceManager manager)
{
Dictionary columnValues = new Dictionary();
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 GetAllFeaturesCore(IEnumerable 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====
====TestForm.aspx====
<%@ Register Assembly="WebEdition" Namespace="ThinkGeo.MapSuite.WebEdition" TagPrefix="cc1" %>
KML Extension