private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null)
{
if (LoadFailed != null)
LoadFailed(this, new RssLoadFailedEventArgs()
{
ex = new Exception(Properties.Resources.GeoRss_ReadingFeedFailed, e.Error),
UserState = e.UserState
});
return;
}
ESRI.ArcGIS.Client.GraphicCollection graphics = new ESRI.ArcGIS.Client.GraphicCollection();
//Add symbols from each entry read from the feed to the graphics object of the layer
using (Stream s = e.Result)
{
SyndicationFeed feed;
List<SyndicationItem> feedItems = new List<SyndicationItem>();
using (XmlReader reader = XmlReader.Create(s))
{
feed = SyndicationFeed.Load(reader);
foreach (SyndicationItem feedItem in feed.Items)
{
SyndicationElementExtensionCollection ec = feedItem.ElementExtensions;
string slong = "";
string slat = "";
Geometry.Geometry g = null;
IDictionary<string, object> attributes = new Dictionary<string,object>();
foreach (SyndicationElementExtension ee in ec)
{
if (ee.OuterNamespace.Equals(_W3CGEONAMESPACE_, StringComparison.OrdinalIgnoreCase))
{
//This is not part of the georss-simple spec, but this makes it support a common
//use-case with geo:lat/geo:long coordinate pairs, as described at
//http://www.w3.org/2003/01/geo/
XmlReader xr = ee.GetReader();
switch (ee.OuterName)
{
case ("lat"):
{
slat = xr.ReadElementContentAsString();
break;
}
case ("long"):
{
slong = xr.ReadElementContentAsString();
break;
}
case ("Point"):
{
XmlReader xmlPoint = xr.ReadSubtree();
while (xmlPoint.Read())
{
if (xmlPoint.LocalName == "lat" && xmlPoint.NamespaceURI == _W3CGEONAMESPACE_)
{
slat = xmlPoint.ReadElementContentAsString();
}
else if (xmlPoint.LocalName == "long" && xmlPoint.NamespaceURI == _W3CGEONAMESPACE_)
{
slong = xmlPoint.ReadElementContentAsString();
}
}
break;
}
}
}
else if (ee.OuterNamespace.Equals(_GEORSSNAMESPACE_, StringComparison.OrdinalIgnoreCase))
{
XmlReader xr = ee.GetReader();
switch (ee.OuterName)
{
case ("point"):
{
string sp = xr.ReadElementContentAsString();
string[] sxsy = sp.Split(new char[] { ' ' });
slong = sxsy[1];
slat = sxsy[0];
break;
}
case ("line"):
{
string sp = xr.ReadElementContentAsString();
PointCollection pnts = StringToPoints(sp);
if (pnts != null)
{
Polyline line = new Polyline() { SpatialReference = new SpatialReference(4326) };
line.Paths.Add(pnts);
g = line;
}
break;
}
case ("polygon"):
{
string sp = xr.ReadElementContentAsString();
PointCollection pnts = StringToPoints(sp);
if (pnts != null)
{
Polygon line = new Polygon() { SpatialReference = new SpatialReference(4326) };
line.Rings.Add(pnts);
g = line;
}
break;
}
case ("box"):
{
string sp = xr.ReadElementContentAsString();
PointCollection pnts = StringToPoints(sp);
if (pnts != null && pnts.Count == 2)
{
g = new Envelope(pnts[0], pnts[1]) { SpatialReference = new SpatialReference(4326) };
}
break;
}
case ("circle"):
{
string sp = xr.ReadElementContentAsString();
string[] sxsy = sp.Split(new char[] { ' ' });
if (sxsy.Length == 3)
{
double x = double.NaN, y = double.NaN, r = double.NaN;
string stX = sxsy[1];
string stY = sxsy[0];
string stR = sxsy[2];
if (double.TryParse(stY, NumberStyles.Any, CultureInfo.InvariantCulture, out y) &&
double.TryParse(stX, NumberStyles.Any, CultureInfo.InvariantCulture, out x) &&
double.TryParse(stR, NumberStyles.Any, CultureInfo.InvariantCulture, out r))
{
g = GetRadiusAsPolygonGeodesic(new MapPoint(x, y), r, 360);
}
}
break;
}
case ("where"): //GeoRSS-GML
{
//GML geometry parsing goes here. However this is not
//part of GeoRSS-simple and not supported for this datasource
//We'll just ignore these entries
break;
}
#region Attributes
case ("elev"):
{
string sp = xr.ReadElementContentAsString();
double elevation = 0;
if (double.TryParse(sp, NumberStyles.Any, CultureInfo.InvariantCulture, out elevation))
attributes.Add("elev", elevation);
break;
}
case ("floor"):
{
string sp = xr.ReadElementContentAsString();
int floor = 0;
if (int.TryParse(sp, NumberStyles.Any, CultureInfo.InvariantCulture, out floor))
attributes.Add("floor", floor);
break;
}
case ("radius"):
{
string sp = xr.ReadElementContentAsString();
double radius = 0;
if (double.TryParse(sp, NumberStyles.Any, CultureInfo.InvariantCulture, out radius))
attributes.Add("radius", radius);
break;
}
//case ("featuretypetag"):
//case ("relationshiptag"):
//case ("featurename"):
default:
{
string sp = xr.ReadElementContentAsString();
attributes.Add(ee.OuterName, sp);
break;
}
#endregion
}
}
}
if (!string.IsNullOrEmpty(slong) && !string.IsNullOrEmpty(slat))
{
double x = double.NaN;
double y = double.NaN;
if (double.TryParse(slat, NumberStyles.Any, CultureInfo.InvariantCulture, out y) &&
double.TryParse(slong, NumberStyles.Any, CultureInfo.InvariantCulture, out x))
g = new MapPoint(x, y, new SpatialReference(4326));
}
if (g != null)
{
Graphic graphic = new Graphic() { Geometry = g };
if(feedItem.Title != null)
graphic.Attributes.Add("Title", feedItem.Title.Text);
if (feedItem.Summary != null)
graphic.Attributes.Add("Summary", feedItem.Summary.Text);
if (feedItem.PublishDate != null)
{
graphic.Attributes.Add("PublishDate", feedItem.PublishDate);
graphic.TimeExtent = new TimeExtent(feedItem.PublishDate.DateTime);
}
if (feedItem.Links.Count > 0)
graphic.Attributes.Add("Link", feedItem.Links[0].Uri);
graphic.Attributes.Add("FeedItem", feedItem);
graphic.Attributes.Add("Id", feedItem.Id);
foreach(var val in attributes)
if(!graphic.Attributes.ContainsKey(val.Key))
graphic.Attributes.Add(val.Key, val.Value);
// Add attribute GeometryType used by renderer
string gt = null;
if (g is MapPoint)
gt = "point";
else if (g is Polyline)
gt = "line";
else if (g is Polygon || g is Envelope)
gt = "polygon";
if (gt != null)
graphic.Attributes.Add(GeometryTypeAttribute, gt);
graphics.Add(graphic);
}
}
}
}
//Invoking the initialize method of the base class to finish the initialization of the graphics layer:
if (LoadCompleted != null)
LoadCompleted(this, new RssLoadedEventArgs()
{
Graphics = graphics,
UserState = e.UserState
}
);
}