Hi,
There is no direct support for GML in the ArcGIS Runtime SDK for WPF. However, if this is a key requirement for you, you could consider writing a custom layer. An example of this (the KML layer implementation) can be found in the ESRI.ArcGIS.Client.Toolkit.Datasources source code available on codeplex: http://esrisilverlight.codeplex.com/releases/view/80697. Download the source code then look in "ESRIToolkitSource_v2.4.zip\WPF\ESRI.ArcGIS.Client.Toolkit.DataSources\Kml".
Cheers
Mike
public static string latLongToXML (decimal lat, decimal Long) { StringBuilder GeoXMLStr = new StringBuilder(); XmlWriterSettings xWSettings = new XmlWriterSettings(); xWSettings.OmitXmlDeclaration = true; XmlWriter xW = XmlWriter.Create(GeoXMLStr, xWSettings); using (xW) { xW.WriteStartElement("Point", "http://www.opengis.net/gml"); xW.WriteStartElement("pos"); xW.WriteRaw(lat.ToString() + " " + Long.ToString()); xW.WriteEndElement(); xW.WriteEndElement(); xW.Flush(); xW.Close(); } return GeoXMLStr.ToString();
Imports System Imports System.Data Imports System.Xml Imports System.Text Imports System.Collections.Generic Imports System.ComponentModel Imports System.IO Imports ESRI.ArcGISExplorer Imports ESRI.ArcGISExplorer.Application Imports ESRI.ArcGISExplorer.Geometry Imports ESRI.ArcGISExplorer.Mapping Imports ESRI.ArcGISExplorer.Data Imports ESRI.ArcGISExplorer.Threading Imports Microsoft.VisualBasic Public Class GML Public Type As String = Nothing Friend WithEvents InciTableAdapter As New Inci.WRMSDataSetTableAdapters.InciTableAdapter Friend WithEvents WRMSDataSet As New Inci.WRMSDataSet Friend WithEvents GMLRtrnDataTable As New DataTable Private disp As MapDisplay = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay Public Sub PerimGet(ByVal InciName As String) Me.InciTableAdapter.FillByInciNumber(WRMSDataSet.Inci, InciName) For Each InfoRow In Me.WRMSDataSet.Inci InfoRow("GML").ToString() Next InfoRow End Sub Public Function XMLToGeom(ByVal XMLGeo As String) Dim Perim As Polygon = New Polygon() Using XMLRead As XmlReader = XmlReader.Create(New StringReader(XMLGeo)) XMLRead.ReadToFollowing("posList") Dim LatLongStrArr() As String = (XMLRead.ReadElementContentAsString()).Split(" ") For I = LatLongStrArr.Length - 1 To 0 Step -2 Perim.AddPoint(ESRI.ArcGISExplorer.Geometry.Point.CreateFromLatitudeLongitude(CDbl(LatLongStrArr(I - 1).ToString), CDbl(LatLongStrArr(I).ToString))) Next I Perim.Close() Return Perim End Using resource As New Object End Using End Function Public Sub CreateNwInci(ByVal InciName As String, ByVal InciNumber As String, ByVal InciType As String, ByVal GeomAsXML As String) 'Inserts Incident data into the WRMS Datatables Try Me.InciTableAdapter.USP_CrtNwInci(InciName, InciNumber, InciType, GeomAsXML, Now) GetInci(InciNumber) Catch ex As Exception MsgBox(ex.ToString) End Try End Sub Public Function GeomToXML(ByVal GObj As Geometry) Dim GeoPoly As Polygon = GObj Dim GeoXMLStr As New StringBuilder Dim XwSettings As XmlWriterSettings = New XmlWriterSettings() XwSettings.OmitXmlDeclaration = True Using Xw As XmlWriter = XmlWriter.Create(GeoXMLStr, XwSettings) Xw.WriteStartElement("Polygon", "http://www.opengis.net/gml") Xw.WriteStartElement("exterior") Xw.WriteStartElement("LinearRing") Xw.WriteStartElement("posList") For Pt = GeoPoly.PointCount - 1 To 0 Step -1 Xw.WriteRaw(GeoPoly.GetPoint(Pt).GetLatitude.ToString("####.000000") + " " + GeoPoly.GetPoint(Pt).GetLongitude.ToString("####.000000") + " ") Next Pt Xw.WriteEndElement() Xw.WriteEndElement() Xw.WriteEndElement() Xw.WriteEndElement() Xw.Flush() Xw.Close() End Using Return GeoXMLStr.ToString End Function Public Sub GetInci(ByVal InciNumber As String) GMLRtrnDataTable = Me.InciTableAdapter.GetDataByInciNumber(InciNumber) For Each Row As DataRow In GMLRtrnDataTable.Rows Dim PerimNt As New Note(Row("Inci_Name").ToString(), _ XMLToGeom(Row("GML").ToString()), _ Symbol.Fill.Solid.Red) PerimNt.Popup.Content = "Acres: " + Row("Inci_Acreage").ToString() disp.Map.ChildItems.Add(PerimNt) Next Row End Sub End Class
using WRMS.Framework.Utilities; using System.ComponentModel; using System.Windows.Input; using WRMS.Framework.Commands; using Microsoft.Win32; using System.IO; using System.Xml; using System.Net; using Ionic.Zip; using System; using System.Windows.Documents; using System.Collections.Generic; using System.Xml.Linq; using ESRI.ArcGIS.Client; using ESRI.ArcGIS.Client.Geometry; using System.Text.RegularExpressions; using AffCore; namespace WRMS.Framework.ViewModels { class AffVM : MapHelper, INotifyPropertyChanged { GraphicsLayer graphicsLayer = _map.Layers["affResourcesGraphicsLayer"] as GraphicsLayer; OpenFileDialog ofd; XmlDocument affFileObj = new XmlDocument(); string resourceUrl; private string _path; public string path { get { return _path; } set { if (_path != value) { _path = value; onPropertyChanged("url"); } } } private string _bytesReceivedDisp; public string bytesReceivedDisp { get { return _bytesReceivedDisp; } set { if (_bytesReceivedDisp!=value) { _bytesReceivedDisp = value; onPropertyChanged("bytesReceivedDisp"); } } } private string _totalBytesDisp; public string totalBytesDisp { get { return _totalBytesDisp; } set { if (_totalBytesDisp!=value) { _totalBytesDisp = value; onPropertyChanged("totalBytesDisp"); } } } private double _bytesReceived; public double bytesReceived { get { return _bytesReceived; } set { if (_bytesReceived != value) { _bytesReceived = value; onPropertyChanged("bytesReceived"); } } } private double _totalBytes = 100; public double totalBytes { get { return _totalBytes; } set { if (_totalBytes != value) { _totalBytes = value; onPropertyChanged("totalBytes"); } } } private string _status; public string status { get { return _status; } set { if (_status != value) { _status = value; onPropertyChanged("status"); } } } private bool _isDisplayed; public bool isDisplayed { get { return _isDisplayed; } set { if (_isDisplayed!=value) { _isDisplayed = value; onPropertyChanged("isDisplayed"); } } } private List<Graphic> _airResourceGraphics; public List<Graphic> airResourceGraphics { get { return _airResourceGraphics; } set { if (_airResourceGraphics!=value) { _airResourceGraphics = value; onPropertyChanged("airResourceGraphics"); } } } private string _returnMessage; public string returnMessage { get { return _returnMessage; } set { if (_returnMessage != value) { _returnMessage = value; onPropertyChanged("returnMessage"); } } } private bool _displayIsChecked; public bool displayIsChecked { get { return _displayIsChecked; } set { if (_displayIsChecked != value) { _displayIsChecked = value; onPropertyChanged("displayIsChecked"); } } } private string _tmpResourceKml; private string _tmpKmz; private const double _maxX = -126.58; private const double _minX = -114.21; private const double _maxY = 48.18; private const double _minY = 39.96; private double _latitude; private double _longitude; public ICommand addKmlAffLayerCommand { get { return new AddKmlAffLayerCommand(this); } } public ICommand toggleDisplayAff { get { return new ToggleDisplayAffCommand(this); } } public void addAff() { returnMessage = ""; ofd = new OpenFileDialog(); ofd.DefaultExt = ".kml"; ofd.Filter = "AFF KML File (*.KML)|*.kml|AFF KMZ File (*.kmz)|*.kmz"; ofd.ShowDialog(); if (ofd.FileName!="") { path = ofd.FileName; status = "Loading"; affFile(path); } } private void affFile(string kmlFilePath) { affFileObj.Load(kmlFilePath); using (XmlReader reader = XmlReader.Create(affFileObj.BaseURI)) { reader.ReadToFollowing("Url"); XmlReader urlXml= reader.ReadSubtree(); urlXml.ReadToFollowing("href"); resourceUrl = urlXml.ReadString(); } _tmpKmz = Path.GetTempPath().ToString() + "resource.zip"; _tmpResourceKml = Path.GetTempPath().ToString() + "resource.kml"; WebClient webDownloader = new WebClient(); webDownloader.DownloadFileCompleted += (sender, e) => { using (ZipFile kmz = ZipFile.Read(_tmpKmz)) foreach (ZipEntry item in kmz) item.Extract(_tmpResourceKml,ExtractExistingFileAction.OverwriteSilently); status = "refreshing"; parseKmlResources(); }; webDownloader.DownloadProgressChanged += (sender, e) => { bytesReceivedDisp = e.BytesReceived.ToString() + "kb/"; totalBytesDisp = e.TotalBytesToReceive.ToString() + "kb"; bytesReceived = Convert.ToDouble(e.BytesReceived); totalBytes = Convert.ToDouble(e.TotalBytesToReceive); }; webDownloader.DownloadFileAsync(new System.Uri(resourceUrl), _tmpKmz); } private void parseKmlResources() { List<Graphic> graphics = new List<Graphic>(); var resourceXml = XDocument.Load(_tmpResourceKml + "/resource.kml"); string xmlNs = "{" + resourceXml.Root.Name.Namespace.ToString() + "}"; foreach (var placemark in resourceXml.Descendants(xmlNs + "Placemark")) { foreach (var coordinates in placemark.Descendants(xmlNs + "Point")) { string[] coordinateCollection = coordinates.Element(xmlNs + "coordinates").Value.ToString().Split(new char[] { ',' }); _longitude = Convert.ToDouble(coordinateCollection[0]); _latitude = Convert.ToDouble(coordinateCollection[1]); } if (_latitude < _maxY && _latitude > _minY) { if (_longitude > _maxX && _longitude < _minX) { MobileResource affResource = new MobileResource(placemark.Value.ToString()); Graphic airResourceGraphic = new Graphic() { Geometry = new MapPoint(_longitude, _latitude, new SpatialReference(4326)) }; airResourceGraphic.Attributes.Add("Callsign", affResource.callsign); graphics.Add(airResourceGraphic); } } } airResourceGraphics = graphics; graphicsLayer.GraphicsSource = airResourceGraphics; //this is where the if statement will be if the Display button is checked File.Delete(_tmpKmz); affFile(path); } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void onPropertyChanged(string propertyName) { try { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } catch (Exception) { //implement a new type of exception to be honest I really don't because when the style template is reloaded it will still populate } } #endregion } }