using System;
using System.Windows;
namespace ThinkgeoSilverlightSample
{
public partial class App : Application
{
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
InitializeComponent();
}
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new Sample();
}
private void Application_Exit(object sender, EventArgs e)
{
}
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
// If the app is running outside of the debugger then report the exception using
// the browser's exception mechanism. On IE this will display it a yellow alert
// icon in the status bar and Firefox will display a script error.
if (!System.Diagnostics.Debugger.IsAttached)
{
// NOTE: This will allow the application to continue running after an exception has been thrown
// but not handled.
// For production applications this error handling should be replaced with something that will
// report the error to the website and stop the application.
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
{
try
{
string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
errorMsg = errorMsg.Replace('"', '\//).Replace("\r\n", @"\n");
System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
}
catch (Exception)
{
}
}
}
}
====Sample.xaml.cs====
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Media;
using ThinkGeo.MapSuite.SilverlightCore;
using ThinkGeo.MapSuite.SilverlightEdition;
using ThinkgeoSilverlightSample.GetDataServiceReference;
namespace ThinkgeoSilverlightSample
{
[ScriptableTypeAttribute]
public partial class Sample : UserControl
{
private enum ViewDataStatus
{
ViewClientAttributes,
ViewServerAttributes
}
private ViewDataStatus viewDataStatus = ViewDataStatus.ViewClientAttributes;
private GetGeoDataServiceClient client = null;
public Sample()
{
InitializeComponent();
// initialize our WCF Service that we'll use to query the ServerLayerOverlay data (counties).
if (client == null)
{
client = new GetGeoDataServiceClient();
// define callback methods for the return of the async WCF calls.
client.GetDataCompleted += new EventHandler(client_GetDataCompleted);
client.DoSpatialQueryCompleted += new EventHandler(client_DoSpatialQueryCompleted);
}
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Map1.MapUnit = GeographyUnit.DecimalDegree;
Map1.MapTools.MouseCoordinate.IsEnabled = true;
Map1.MapTools.MouseCoordinate.MouseCoordinateType = MouseCoordinateType.LongitudeLatitude;
// Add our basemap - WorldMapKitWMSSilverlightOverlay.
// his overlay streams tiles directly to the client from our World Map Kit online server.
WorldMapKitWmsSilverlightOverlay wmsOverlay = new WorldMapKitWmsSilverlightOverlay();
Map1.Overlays.Add(wmsOverlay);
// Add our server side data to the map.
// Use the SilverlightMapConnector to retrieve the ServerLayerOverlay that was created in the Default.aspx.cs.
ServerLayerOverlay serverLayerOverlay = new ServerLayerOverlay("ServerSideOverlay", "SilverlightMapConnector1");
Map1.Overlays.Add("serverOverlay", serverLayerOverlay);
// Add our client side data to the map. Use a regular ShapeFileFeatureLayer and LayerOverlay.
// Using this method, the shapefile will be downloaded to the client when the program loads and the .xap is transferred to the client.
LayerOverlay shapefileOverlay = new LayerOverlay();
ShapeFileFeatureLayer layer = GetShapeFileLayer();
shapefileOverlay.Layers.Add(layer);
Map1.Overlays.Add("clientOverlay", shapefileOverlay);
// Set up a LayerOverlay and InMemoryFeatureLayer for highlighting. Any selected features will be added to this layer.
LayerOverlay highlightOverlay = new LayerOverlay();
InMemoryFeatureLayer highlightFeatureLayer = new InMemoryFeatureLayer();
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoSolidBrush(GeoColor.FromArgb(150, GeoColor.SimpleColors.PastelRed)));
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color = GeoColor.StandardColors.Red;
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Circle, GeoColor.FromArgb(255, GeoColor.SimpleColors.Red), 6);
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
highlightOverlay.Layers.Add("highlightFeatureLayer", highlightFeatureLayer);
Map1.Overlays.Add("highlightOverlay", highlightOverlay);
// Set the entent to center on Texas. This sample uses Texas Counties(server-side) and Texas Airports(client-side).
Map1.CurrentExtent = new RectangleShape(-105.0, 35.482, -90.471, 26.298);
Map1.TrackOverlay.TrackEnded += new EventHandler(TrackOverlay_TrackEnded);
}
private void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
{
// Currently, this is the best practice to keep the map full-size when the browser is resized.
Map1.Width = e.NewSize.Width;
Map1.Height = e.NewSize.Height;
double width = Map1.Width - 280;
DescInfo.SetValue(Canvas.LeftProperty, width);
DescInfo.SetValue(Canvas.TopProperty, 6.0);
}
private void ViewClientSideData(PointShape currentPoint)
{
// grab a reference to our clientOverlay and layer.
LayerOverlay shapefileOverlay = Map1.Overlays["clientOverlay"] as LayerOverlay;
ShapeFileFeatureLayer layer = shapefileOverlay.Layers[0] as ShapeFileFeatureLayer;
layer.Open();
// spatial query to get the feature nearest the mouse click.
Collection features = layer.FeatureSource.GetFeaturesNearestTo(currentPoint, GeographyUnit.DecimalDegree, 1, ReturningColumnsType.AllColumns);
layer.Close();
Feature nearestFeature = features[0];
// Hightlight selected feature
SetHighlightFeatures(new Collection() { nearestFeature });
// Popup information Balloon with details about the selected feature
StringBuilder popupStringBuilder = new StringBuilder();
Dictionary columnValues = nearestFeature.ColumnValues;
foreach (KeyValuePair columnValue in columnValues)
{
popupStringBuilder.AppendLine(columnValue.Key + " : " + columnValue.Value);
}
string popupString = popupStringBuilder.ToString();
PopupMessage(nearestFeature, popupString);
}
private void ViewServerSideData(PointShape currentPoint)
{
// call the WCF service to query the server-side layer. Please view \Services\GetGeoDataService.svc.cs in the web project.
// when the asynchronous call finishes, it will trigger the client_GetDataCompleted event handler.
client.GetDataAsync(currentPoint.X, currentPoint.Y);
}
void client_GetDataCompleted(object sender, GetDataCompletedEventArgs e)
{
// this is the callback method that gets invoked after the GetDataAsync WCF call completes.
// parse the string results and create Features.
string[] results = e.Result.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries);
if (results.Length == 2)
{
Feature nearestFeature = new Feature(results[0]);
string popupString = results[1];
// Hightlight selected feature
SetHighlightFeatures(new Collection() { nearestFeature });
// Popup information about selected feature
PopupMessage(nearestFeature, popupString);
}
else
{
ClearHighlight();
Map1.Popups.Clear();
}
}
private void SpatialQueryClientSideData()
{
// grab a reference to our clientOverlay and layer.
LayerOverlay shapefileOverlay = Map1.Overlays["clientOverlay"] as LayerOverlay;
ShapeFileFeatureLayer layer = shapefileOverlay.Layers[0] as ShapeFileFeatureLayer;
// get the drawn feature from the TrackShapeLayer.
Feature drawnFeature = Map1.TrackOverlay.TrackShapeLayer.InternalFeatures[0];
Collection spatialQueryResults = new Collection();
layer.Open();
// execute a spatial query based on the type of query in the combo box.
switch (((ComboBoxItem)cbxSpatialQueryType.SelectedItem).Content.ToString())
{
case "Intersecting":
spatialQueryResults = layer.QueryTools.GetFeaturesIntersecting(drawnFeature, new string[0]);
break;
case "Within":
spatialQueryResults = layer.QueryTools.GetFeaturesWithin(drawnFeature, new string[0]);
break;
case "Containing":
spatialQueryResults = layer.QueryTools.GetFeaturesContaining(drawnFeature, new string[0]);
break;
default:
break;
}
layer.Close();
// highlight the selected features.
SetHighlightFeatures(spatialQueryResults);
}
private void SpatialQueryServerSideData()
{
// get the drawn feature from the TrackShapeLayer.
Feature drawnFeature = Map1.TrackOverlay.TrackShapeLayer.InternalFeatures[0];
// call the WCF service to query the server-side layer. Please view \Services\GetGeoDataService.svc.cs in the web project.
// when the asynchronous call finishes, it will trigger the client_DoSpatialQueryCompleted event handler.
string spatialQueryTypeString = ((ComboBoxItem)cbxSpatialQueryType.SelectedItem).Content.ToString();
client.DoSpatialQueryAsync(drawnFeature.GetWellKnownText(), spatialQueryTypeString);
}
void client_DoSpatialQueryCompleted(object sender, DoSpatialQueryCompletedEventArgs e)
{
// this is the callback method that gets invoked after the DoSpatialQueryAsync WCF call completes.
// parse the string results and create Features.
string[] results = e.Result.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries);
Collection features = new Collection();
foreach (string result in results)
{
features.Add(new Feature(result));
}
// hightlight selected features
SetHighlightFeatures(features);
}
#region "Helper Functions"
private void ClearHighlight()
{
LayerOverlay highlightOverlay = Map1.Overlays["highlightOverlay"] as LayerOverlay;
InMemoryFeatureLayer highlightFeatureLayer = highlightOverlay.Layers["highlightFeatureLayer"] as InMemoryFeatureLayer;
highlightFeatureLayer.InternalFeatures.Clear();
highlightOverlay.Refresh();
}
private void SetHighlightFeatures(Collection features)
{
LayerOverlay highlightOverlay = Map1.Overlays["highlightOverlay"] as LayerOverlay;
InMemoryFeatureLayer highlightFeatureLayer = highlightOverlay.Layers["highlightFeatureLayer"] as InMemoryFeatureLayer;
highlightFeatureLayer.InternalFeatures.Clear();
foreach (Feature feature in features)
{
highlightFeatureLayer.InternalFeatures.Add(feature);
}
highlightOverlay.Refresh();
}
private void PopupMessage(Feature nearestFeature, string popupString)
{
PointShape popupPoint = nearestFeature.GetShape().GetCenterPoint();
GeoPopup popup = new GeoPopup(popupPoint);
TextBlock text = new TextBlock();
text.SetValue(Canvas.LeftProperty, 10d);
text.TextWrapping = TextWrapping.Wrap;
text.FontSize = 10d;
text.FontFamily = new FontFamily("Arial");
text.Text = popupString;
Canvas container = new Canvas();
container.Margin = new Thickness(5);
container.Children.Add(text);
popup.Content = container;
WpfGeoCanvas wpfc = new WpfGeoCanvas();
Canvas nativeImage = new Canvas();
nativeImage.Width = 1;
nativeImage.Height = 1;
wpfc.BeginDrawing(nativeImage, new RectangleShape(), GeographyUnit.DecimalDegree);
DrawingRectangleF rect = wpfc.MeasureText(popupString, new GeoFont("Arial", 10));
popup.Width = rect.Width + 40;
popup.Height = rect.Height + 5;
Map1.Popups.Clear();
Map1.Popups.Add(popup);
}
private void DoSpatialQuery()
{
if (Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count > 0)
{
if (viewDataStatus == ViewDataStatus.ViewClientAttributes)
{
SpatialQueryClientSideData();
}
else
{
SpatialQueryServerSideData();
}
}
}
private void SetNextViewStatus()
{
if (viewDataStatus == ViewDataStatus.ViewClientAttributes)
{
viewDataStatus = ViewDataStatus.ViewServerAttributes;
DoSpatialQuery();
}
else if (viewDataStatus == ViewDataStatus.ViewServerAttributes)
{
viewDataStatus = ViewDataStatus.ViewClientAttributes;
DoSpatialQuery();
}
}
private ShapeFileFeatureLayer GetShapeFileLayer()
{
ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer("a.shp");
// add an event handler to load the texas airport data in the StreamLoading event.
((ShapeFileFeatureSource)layer.FeatureSource).StreamLoading += new EventHandler(TexasAirportsLoadAShapeFile_StreamLoading);
//apply a default point style.
layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.City7;
layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
return layer;
}
private void TexasAirportsLoadAShapeFile_StreamLoading(object sender, StreamLoadingEventArgs e)
{
//load our client-side texas airport data in a StreamLoading event.
switch (System.IO.Path.GetExtension(e.AlternateStreamName).ToLower())
{
case ".shp":
e.AlternateStream = Application.GetResourceStream(new Uri("Resource/TXLpt50.shp", UriKind.RelativeOrAbsolute)).Stream;
break;
case ".dbf":
e.AlternateStream = Application.GetResourceStream(new Uri("Resource/TXLpt50.dbf", UriKind.RelativeOrAbsolute)).Stream;
break;
case ".shx":
e.AlternateStream = Application.GetResourceStream(new Uri("Resource/TXLpt50.shx", UriKind.RelativeOrAbsolute)).Stream;
break;
case ".idx":
e.AlternateStream = Application.GetResourceStream(new Uri("Resource/TXLpt50.idx", UriKind.RelativeOrAbsolute)).Stream;
break;
case ".ids":
e.AlternateStream = Application.GetResourceStream(new Uri("Resource/TXLpt50.ids", UriKind.RelativeOrAbsolute)).Stream;
break;
default:
break;
}
}
#endregion
#region "UI Events"
// handle the Map Click event.
private void Map1_Click(object sender, MapClickEventArgs e)
{
if (Map1.TrackOverlay.TrackMode == TrackMode.None)
{
if (viewDataStatus == ViewDataStatus.ViewClientAttributes)
{
ViewClientSideData(e.WorldPointShape);
}
else if (viewDataStatus == ViewDataStatus.ViewServerAttributes)
{
ViewServerSideData(e.WorldPointShape);
}
}
}
// handle the TrackEnded event. (this fires when the user finishes drawing a blue shape)
void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e)
{
Map1.Popups.Clear();
// Clear original tracked features
while (Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count > 1)
{
Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.RemoveAt(0);
}
DoSpatialQuery();
}
private void rbViewClientAttributes_Click(object sender, RoutedEventArgs e)
{
SetNextViewStatus();
}
private void rbViewServerAttributes_Click(object sender, RoutedEventArgs e)
{
SetNextViewStatus();
}
private void btnCursor_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.None;
ClearHighlight();
Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Clear();
Map1.TrackOverlay.Refresh();
}
private void btnPoint_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Point;
}
private void btnLine_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Line;
}
private void btnRectangle_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Rectangle;
}
private void btnSquare_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Square;
}
private void btnPolygon_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Polygon;
}
private void btnCircle_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Circle;
}
private void btnEllipse_Click(object sender, RoutedEventArgs e)
{
Map1.TrackOverlay.TrackMode = TrackMode.Ellipse;
}
private void cbxSpatialQueryType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (Map1 != null)
{
DoSpatialQuery();
if (((ComboBoxItem)cbxSpatialQueryType.SelectedItem).Content.ToString() == "Stop Query")
{
Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Clear();
Map1.TrackOverlay.Refresh();
}
}
}
#endregion
}
}
====Banner.ascx.cs====
using System;
public partial class Banner : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
====Default.aspx.cs====
using System;
using System.Web.UI;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.SilverlightEdition;
namespace ThinkgeoSilverlightSample.Web
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Load our texas county data using a ShapeFileFeatureLayer and apply a simple AreaStyle.
ShapeFileFeatureLayer texascountiesLayer = new ShapeFileFeatureLayer(MapPath("~/app_data/texascounties.shp"));
texascountiesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(0, 243, 239, 228), GeoColor.FromArgb(255, 218, 193, 163), 1);
texascountiesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Create a ServerLayerOverlay and add the layer to this overlay.
// This overlay will be rendered on the server and transferred to the client as image tiles.
ServerLayerOverlay layerOverlay = new ServerLayerOverlay("ServerSideOverlay");
layerOverlay.Layers.Add(texascountiesLayer);
SilverlightMapConnector1.ServerLayerOverlays.Add(layerOverlay);
}
}
}
}
====Footer.ascx.cs====
using System;
public partial class Footer : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
====Default.aspx====
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ThinkgeoSilverlightSample.Web._Default" %>
<%@ Register Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %>
<%@ Register Assembly="SilverlightMapConnector" Namespace="ThinkGeo.MapSuite.SilverlightEdition"
TagPrefix="cc1" %>
<%@ Register Src="Footer.ascx" TagName="Footer" TagPrefix="uc1" %>
<%@ Register Src="Banner.ascx" TagName="Banner" TagPrefix="uc2" %>
Client and server mix - Map Suite Silverlight Sample application