====== Source Code SilverlightEditionSample VehicleTracking CS.zip ======
====MainPage.xaml====
====MainPage.xaml.cs====
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Threading;
using ThinkGeo.MapSuite.SilverlightCore;
using ThinkGeo.MapSuite.SilverlightEdition;
using ThinkGeo.MapSuite.VehicleTracking.ServiceReference;
namespace ThinkGeo.MapSuite.VehicleTracking
{
public partial class MainPage
{
private const string worldMapKitName = "World Map Kit Map";
private const string openStreetMapName = "Open Street Map";
private const string bingMapsKeyFileName = "BingMapsKey.key";
private const string bingMapsRoadMapName = "Bing Maps Road Map";
private const string bingMapsAerialMapName = "Bing Maps Aerial Map";
private static readonly DateTime applicationStartTime = DateTime.Now;
private static readonly DateTime adjustedStartTime = new DateTime(2009, 7, 10, 11, 31, 0);
private bool isFirst = true;
private Storyboard storyboard;
private DropShadowEffect dropShadowEffect;
private VehicleTrackingViewModel viewModel;
private DispatcherTimer autoRefreshDispatcherTimer;
public MainPage()
{
InitializeComponent();
dropShadowEffect = new DropShadowEffect();
dropShadowEffect.Opacity = 0.8;
dropShadowEffect.ShadowDepth = 2;
dropShadowEffect.Color = Color.FromArgb(255, 254, 111, 63);
viewModel = new VehicleTrackingViewModel();
viewModel.OverlayNames.Add(worldMapKitName);
viewModel.OverlayNames.Add(openStreetMapName);
viewModel.OverlayNames.Add(bingMapsRoadMapName);
viewModel.OverlayNames.Add(bingMapsAerialMapName);
DataContext = viewModel;
Application.Current.Host.Content.IsFullScreen = true;
autoRefreshDispatcherTimer = new DispatcherTimer();
autoRefreshDispatcherTimer.Interval = TimeSpan.FromMilliseconds(5000);
autoRefreshDispatcherTimer.Tick += (s, e) => UpdateSpatialFencesAndVehicles();
AutoRefreshToggleButton.IsChecked = true;
StartAutoRefresh(AutoRefreshToggleButton);
}
private void SetupBaseOverlays()
{
// Add the World Map Kit WMS layer. It is a free demo set of data for the world accessable with WMS.
WorldMapKitWmsSilverlightOverlay worldMapKitWmsOverlay = new WorldMapKitWmsSilverlightOverlay();
worldMapKitWmsOverlay.Projection = WorldMapKitProjection.SphericalMercator;
map1.Overlays.Add(worldMapKitName, worldMapKitWmsOverlay);
// Initialize SpatialFenceLayer.
InMemoryFeatureLayer spatialFenceLayer = new InMemoryFeatureLayer();
spatialFenceLayer.Open();
spatialFenceLayer.Columns.Add(new FeatureSourceColumn("Restricted", "Charater", 10));
spatialFenceLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoColor.FromArgb(255, 204, 204, 204), 2), new GeoSolidBrush(GeoColor.FromArgb(112, 255, 0, 0)));
spatialFenceLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Restricted", "Arial", 12, false, GeoColor.StandardColors.Black, GeoColor.StandardColors.White, 2);
spatialFenceLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Initialize SpatialFenceOverlay.
LayerOverlay spatialFenceOverlay = new LayerOverlay();
spatialFenceOverlay.Name = "SpatialFenceOverlay";
spatialFenceOverlay.Layers.Add("SpatialFenceLayer", spatialFenceLayer);
LayerOverlay traceOverlay = new LayerOverlay();
traceOverlay.Name = "TraceOverlay";
map1.Overlays.Add("SpatialFenceOverlay", spatialFenceOverlay);
map1.Overlays.Add("TraceOverlay", traceOverlay);
}
private void UpdateSpatialFencesAndVehicles(bool needRefresh = true)
{
// Update the fences from database.
UpdateSpatialFences();
// Update the vehicle locations on the map.
UpdateVehicles();
if (needRefresh) map1.Refresh();
}
private void UpdateSpatialFences()
{
// Get the spatial fence overlay and layer and then clear them
LayerOverlay spatialFenceOverlay = (LayerOverlay)map1.Overlays["SpatialFenceOverlay"];
InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"];
spatialFenceLayer.InternalFeatures.Clear();
TrackingAccessPrividerSourceClient client = new TrackingAccessPrividerSourceClient();
client.GetSpatialFencesCompleted += (s, e) =>
{
// Insert fences from database into fence layer
if (e.Result != null)
{
foreach (string spatialFence in e.Result)
{
var array = spatialFence.Split('|');
if (array.Length == 2)
{
Feature feature = new Feature(array[0], array[1]);
feature.ColumnValues["Restricted"] = "Restricted";
if (spatialFenceLayer.InternalFeatures.Contains(array[1]))
{
spatialFenceLayer.InternalFeatures.Remove(array[1]);
}
spatialFenceLayer.InternalFeatures.Add(array[1], feature);
}
}
spatialFenceOverlay.Refresh();
}
};
client.GetSpatialFencesAsync();
}
// Here we update the vehicles from the database. In this sample we create our data provider each time and
// when we are finsihed with it we dispose it. This is very safe however you may get better performance
// if you were to cache this. We wanted to sample to be clean and safe and it is up to your expertise to
// enhance it further
private void UpdateVehicles()
{
LayerOverlay traceOverlay = (LayerOverlay)map1.Overlays["TraceOverlay"];
TrackingAccessPrividerSourceClient client = new TrackingAccessPrividerSourceClient();
client.GetCurrentVehiclesCompleted += (s, e) =>
{
// Loop through all the vehicle to add the history points
if (e.Result != null && e.Result.All(v => !string.IsNullOrEmpty(v.Value.VehicleIconVirtualPath)))
{
foreach (int vehicleId in e.Result.Keys)
{
Vehicle currentVehicle = e.Result[vehicleId];
VehicleViewModel tempVehicleViewModel = viewModel.Vehicles.FirstOrDefault(v => v.OwnerName == currentVehicle.VehicleName);
if (tempVehicleViewModel == null)
{
tempVehicleViewModel = new VehicleViewModel(currentVehicle);
Dispatcher.BeginInvoke(() => viewModel.Vehicles.Add(tempVehicleViewModel));
}
else
{
tempVehicleViewModel.Vehicle = currentVehicle;
tempVehicleViewModel.Load();
}
bool isInSpatialFence = CheckIsInSpatialFence(currentVehicle);
tempVehicleViewModel.Area = isInSpatialFence ? "In restricted area" : "Out of restricted area";
InMemoryFeatureLayer currentVehicleLayer;
// Initialize vehicle overlay if it's not initialized
if (!traceOverlay.Layers.Contains(currentVehicle.VehicleName))
{
// Create an InMemoryMarkerOverlay for the vehicle to hold the points and current location
currentVehicleLayer = new InMemoryFeatureLayer();
currentVehicleLayer.Open();
currentVehicleLayer.Name = currentVehicle.Id.ToString(CultureInfo.InvariantCulture);
currentVehicleLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(GetValueStyle(currentVehicle.VehicleIconVirtualPath));
currentVehicleLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
// Add all the required columns so we can populate later
currentVehicleLayer.FeatureSource.Open();
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("IsCurrentPosition"));
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Speed"));
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("DateTime"));
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Longitude"));
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Latitude"));
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("VehicleName"));
currentVehicleLayer.Columns.Add(new FeatureSourceColumn("Duration"));
Dispatcher.BeginInvoke(() =>
{
lock (traceOverlay.Layers)
{
traceOverlay.Layers.Add(currentVehicle.VehicleName, currentVehicleLayer);
traceOverlay.Refresh();
}
});
}
else
{
// Find the overlay in the map
currentVehicleLayer = (InMemoryFeatureLayer)traceOverlay.Layers[currentVehicle.VehicleName];
}
// Clear old vehicle's old positions
currentVehicleLayer.InternalFeatures.Clear();
// Add the vheicle's bread crumbs
foreach (Location historyLocation in currentVehicle.HistoryLocations.Take(6))
{
Feature breadcrumbFeature = new Feature(MapSuiteSampleHelper.GetLocationPointShape(historyLocation).GetWellKnownBinary(), currentVehicle.VehicleName + historyLocation.DateTime.ToString(CultureInfo.InvariantCulture));
breadcrumbFeature.ColumnValues["DateTime"] = historyLocation.DateTime.ToString(CultureInfo.InvariantCulture);
breadcrumbFeature.ColumnValues["IsCurrentPosition"] = "IsNotCurrentPosition";
breadcrumbFeature.ColumnValues["Speed"] = historyLocation.Speed.ToString(CultureInfo.InvariantCulture);
breadcrumbFeature.ColumnValues["Longitude"] = historyLocation.Longitude.ToString(CultureInfo.InvariantCulture);
breadcrumbFeature.ColumnValues["Latitude"] = historyLocation.Latitude.ToString(CultureInfo.InvariantCulture);
breadcrumbFeature.ColumnValues["VehicleName"] = currentVehicle.VehicleName;
breadcrumbFeature.ColumnValues["Duration"] = MapSuiteSampleHelper.GetSpeedDuration(currentVehicle).ToString(CultureInfo.InvariantCulture);
currentVehicleLayer.InternalFeatures.Add(breadcrumbFeature.Id, breadcrumbFeature);
}
// Add the vehicle's latest position
Feature latestPositionFeature = new Feature(MapSuiteSampleHelper.GetLocationPointShape(currentVehicle.Location).GetWellKnownBinary(), currentVehicle.VehicleName);
latestPositionFeature.ColumnValues["DateTime"] = currentVehicle.Location.DateTime.ToString(CultureInfo.InvariantCulture);
latestPositionFeature.ColumnValues["IsCurrentPosition"] = "IsCurrentPosition";
latestPositionFeature.ColumnValues["Speed"] = currentVehicle.Location.Speed.ToString(CultureInfo.InvariantCulture);
latestPositionFeature.ColumnValues["Longitude"] = currentVehicle.Location.Longitude.ToString(CultureInfo.InvariantCulture);
latestPositionFeature.ColumnValues["Latitude"] = currentVehicle.Location.Latitude.ToString(CultureInfo.InvariantCulture);
latestPositionFeature.ColumnValues["VehicleName"] = currentVehicle.VehicleName;
latestPositionFeature.ColumnValues["Duration"] = MapSuiteSampleHelper.GetSpeedDuration(currentVehicle).ToString(CultureInfo.InvariantCulture);
currentVehicleLayer.InternalFeatures.Add(latestPositionFeature.Id, latestPositionFeature);
}
traceOverlay.Refresh();
}
};
DateTime currentTime = GetAdjustedCurrentDateTime();
client.GetCurrentVehiclesAsync(currentTime);
}
private bool CheckIsInSpatialFence(Vehicle vehicle)
{
LayerOverlay spatialFenceOverlay = (LayerOverlay)map1.Overlays["SpatialFenceOverlay"];
InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"];
// Get the point shape and then check if it is within any of the sptail fences using the QueryTools
PointShape pointShape = new PointShape(vehicle.Location.Longitude, vehicle.Location.Latitude);
spatialFenceLayer.Open();
Collection spatialFencesWithin = spatialFenceLayer.QueryTools.GetFeaturesContaining(pointShape, ReturningColumnsType.NoColumns);
bool isInSpatialFence = spatialFencesWithin.Count > 0;
return isInSpatialFence;
}
private static ValueStyle GetValueStyle(string vehicleIconVirtualPath)
{
GeoImage vehicleImage = GetGeoImage(new Uri("/MapSuiteVehicleTracking;component/Image/" + vehicleIconVirtualPath, UriKind.RelativeOrAbsolute));
GeoImage historyImage = GetGeoImage(new Uri("/MapSuiteVehicleTracking;component/Image/ball_green.png", UriKind.RelativeOrAbsolute));
ValueStyle iconValueStyle = new ValueStyle();
iconValueStyle.ColumnName = "IsCurrentPosition";
iconValueStyle.ValueItems.Add(new ValueItem("IsCurrentPosition", new PointStyle(vehicleImage) { XOffsetInPixel = -16, YOffsetInPixel = -16 }));
iconValueStyle.ValueItems.Add(new ValueItem("IsNotCurrentPosition", new PointStyle(historyImage)));
return iconValueStyle;
}
private static GeoImage GetGeoImage(Uri uri)
{
Stream stream = Application.GetResourceStream(uri).Stream;
stream.Seek(0, SeekOrigin.Begin);
GeoImage geoImage = new GeoImage();
geoImage.SourceStream = stream;
return geoImage;
}
private void AutoRefreshClick(object sender, RoutedEventArgs e)
{
ToggleButton autoRefreshToggleButton = (ToggleButton)sender;
StartAutoRefresh(autoRefreshToggleButton);
}
private void StartAutoRefresh(ToggleButton autoRefreshToggleButton)
{
if (autoRefreshToggleButton.IsChecked.GetValueOrDefault())
{
autoRefreshDispatcherTimer.Start();
OnOffTextBlock.Foreground = new SolidColorBrush(Colors.Black);
OnOffTextBlock.Text = "On";
if (storyboard == null)
{
RotateTransform rotateTransform = new RotateTransform();
rotateTransform.CenterX = 14;
rotateTransform.CenterY = 14;
autoRefreshToggleButton.RenderTransform = rotateTransform;
DoubleAnimation AscendingDoubleAnimation = new DoubleAnimation();
AscendingDoubleAnimation.From = 0;
AscendingDoubleAnimation.To = 360;
AscendingDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
AscendingDoubleAnimation.Duration = TimeSpan.FromSeconds(1.5);
storyboard = new Storyboard();
storyboard.Children.Add(AscendingDoubleAnimation);
Storyboard.SetTarget(AscendingDoubleAnimation, rotateTransform);
Storyboard.SetTargetProperty(AscendingDoubleAnimation, new PropertyPath("Angle"));
}
storyboard.Begin();
}
else
{
autoRefreshDispatcherTimer.Stop();
OnOffTextBlock.Foreground = new SolidColorBrush(Colors.Red);
OnOffTextBlock.Text = "Off";
storyboard.Stop();
}
}
private void RefreshClick(object sender, RoutedEventArgs e)
{
UpdateSpatialFencesAndVehicles();
}
private void WpfMap_MapClick(object sender, MapClickEventArgs e)
{
RectangleShape rectangle = GetBufferedRectangle(e.WorldPointShape);
LayerOverlay traceOverlay = (LayerOverlay)map1.Overlays["TraceOverlay"];
map1.Popups.Clear();
lock (traceOverlay.Layers)
{
foreach (Layer layer in traceOverlay.Layers)
{
InMemoryFeatureLayer vehicleLayer = (InMemoryFeatureLayer)layer;
vehicleLayer.Open();
if (vehicleLayer.GetBoundingBox().Intersects(rectangle))
{
var resultFeatures = vehicleLayer.QueryTools.GetFeaturesIntersecting(rectangle, ReturningColumnsType.AllColumns);
if (resultFeatures.Count > 0)
{
ShowPopup(e.WorldPointShape, GetVehicleInfor(resultFeatures[0]));
break;
}
}
}
}
}
private void ShowPopup(PointShape pointShape, string popupContent)
{
GeoPopup popup = new GeoPopup(pointShape);
TextBlock textBlock = new TextBlock { Foreground = new SolidColorBrush(Colors.Black), Text = popupContent, Margin = new Thickness(5) };
popup.Content = textBlock;
popup.Width = textBlock.ActualWidth + 32;
popup.Height = textBlock.ActualHeight + 20;
map1.Popups.Add(popup);
map1.Refresh();
}
private RectangleShape GetBufferedRectangle(PointShape pointShape)
{
PointShape clickedPoint = pointShape;
double currentResolution = map1.CurrentScale / (39.3701 * 96);
double offset = currentResolution * 16;
RectangleShape rectangle = new RectangleShape(clickedPoint.X - offset, clickedPoint.Y + offset, clickedPoint.X + offset, clickedPoint.Y - offset);
return rectangle;
}
private static string GetVehicleInfor(Feature feature)
{
ProjNetProjection proj4 = new ProjNetProjection(4326, 900913);
proj4.Open();
string longitudeString = "--";
string latitudeString = "--";
double longitude = double.NaN;
double latitude = double.NaN;
if (double.TryParse(feature.ColumnValues["Longitude"], out longitude) &&
double.TryParse(feature.ColumnValues["Latitude"], out latitude))
{
PointShape pointShape = new PointShape(longitude, latitude);
pointShape = (PointShape)proj4.ConvertToInternalProjection(pointShape);
longitudeString = pointShape.X.ToString("N2", CultureInfo.InvariantCulture);
latitudeString = pointShape.Y.ToString("N2", CultureInfo.InvariantCulture);
}
proj4.Close();
return string.Format(CultureInfo.InvariantCulture, "Name:{0}\r\nLongitude:{1}\r\nLatitude:{2}\r\nSpeed:{3}mph\r\nTime:{4}"
, feature.ColumnValues["VehicleName"]
, longitudeString
, latitudeString
, feature.ColumnValues["Speed"]
, feature.ColumnValues["DateTime"]);
}
private void ControlMapClick(object sender, RoutedEventArgs e)
{
if (((RadioButton)sender).IsChecked.GetValueOrDefault())
{
editPanel.Visibility = Visibility.Collapsed;
measurePanel.Visibility = Visibility.Collapsed;
map1.TrackOverlay.TrackMode = TrackMode.None;
}
}
private void DrawFenceClick(object sender, RoutedEventArgs e)
{
if (((RadioButton)sender).IsChecked.GetValueOrDefault())
{
map1.TrackOverlay.TrackEnded -= TrackOverlay_TrackEnded;
map1.TrackOverlay.TrackMode = TrackMode.Polygon;
editPanel.Visibility = Visibility.Visible;
measurePanel.Visibility = Visibility.Collapsed;
}
}
private void MeasureLineClick(object sender, RoutedEventArgs e)
{
map1.TrackOverlay.TrackMode = TrackMode.Line;
}
private void MeasurePolygonClick(object sender, RoutedEventArgs e)
{
map1.TrackOverlay.TrackMode = TrackMode.Polygon;
}
private void CancelMeasureClick(object sender, RoutedEventArgs e)
{
ClearMeasuresAndPopups();
}
private void ClearMeasuresAndPopups()
{
foreach (Feature measureFeature in map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => (string)f.Tag == "Measure").ToList())
{
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Remove(measureFeature);
}
map1.Popups.Clear();
map1.TrackOverlay.Refresh();
}
private void MeasureDistanceClick(object sender, RoutedEventArgs e)
{
if (((RadioButton)sender).IsChecked.GetValueOrDefault())
{
map1.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;
if (map1.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)
{
SaveSpatialFences(() => UpdateSpatialFencesAndVehicles());
}
else if (map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count > 0)
{
CancelEdit();
}
editPanel.Visibility = Visibility.Collapsed;
measurePanel.Visibility = Visibility.Visible;
map1.TrackOverlay.TrackMode = rbtnMeasureLine.IsChecked.GetValueOrDefault() ? TrackMode.Line : TrackMode.Polygon;
map1.TrackOverlay.TrackStarting -= TrackOverlay_TrackStarting;
map1.TrackOverlay.TrackStarting += TrackOverlay_TrackStarting;
map1.TrackOverlay.TrackEnded -= TrackOverlay_TrackEnded;
map1.TrackOverlay.TrackEnded += TrackOverlay_TrackEnded;
}
}
private void TrackOverlay_TrackStarting(object sender, TrackStartingTrackInteractiveOverlayEventArgs e)
{
if (map1.TrackOverlay.TrackMode == TrackMode.Line || map1.TrackOverlay.TrackMode == TrackMode.Polygon)
{
ClearMeasuresAndPopups();
}
}
private void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e)
{
if (map1.TrackOverlay.TrackMode == TrackMode.Polygon)
{
PolygonShape polygonShape = e.TrackShape as PolygonShape;
if (polygonShape != null)
{
double area = -1;
string areaUnit = "sqr.m.";
if (viewModel.SelectedUnitSystem == UnitSystem.Metric)
{
areaUnit = "sqr.m.";
area = polygonShape.GetArea(GeographyUnit.Meter, AreaUnit.SquareMeters);
}
else if (viewModel.SelectedUnitSystem == UnitSystem.Imperial)
{
areaUnit = "ac.";
area = polygonShape.GetArea(GeographyUnit.Meter, AreaUnit.Acres);
}
if (area > 0)
{
ShowPopup(new PointShape(polygonShape.OuterRing.Vertices[polygonShape.OuterRing.Vertices.Count|- 1]), string.Format("Area: {0} {1}", area.ToString("N1"), areaUnit));
}
if (map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count > 0)
{
Feature lastFeature = map1.TrackOverlay.TrackShapeLayer.InternalFeatures.LastOrDefault();
lastFeature.Tag = "Measure";
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.RemoveAt(map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1);
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(lastFeature);
}
}
}
if (map1.TrackOverlay.TrackMode == TrackMode.Line)
{
string unit = string.Empty;
LineShape lineShape = e.TrackShape as LineShape;
if (lineShape != null)
{
double lenth = 0;
if (viewModel.SelectedUnitSystem == UnitSystem.Metric)
{
lenth = lineShape.GetLength(GeographyUnit.Meter, DistanceUnit.Meter);
unit = "m";
if (lenth >= 1000)
{
unit = "km";
lenth = Math.Round(lenth / 1000d, 1);
}
}
else if (viewModel.SelectedUnitSystem == UnitSystem.Imperial)
{
lenth = lineShape.GetLength(GeographyUnit.Meter, DistanceUnit.Feet);
unit = "ft";
if (lenth >= 5280)
{
unit = "mi";
lenth = Math.Round(lenth / 5280d, 1);
}
}
string lengthString = lenth.ToString("N1");
ShowPopup(new PointShape(lineShape.Vertices[lineShape.Vertices.Count|- 1]), string.Format("Total Length: {0} {1}", lengthString, unit));
if (map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count > 0)
{
var lastFeature = map1.TrackOverlay.TrackShapeLayer.InternalFeatures.LastOrDefault();
lastFeature.Tag = "Measure";
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.RemoveAt(map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1);
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(lastFeature);
}
}
}
}
private void DrawNewFenceClick(object sender, RoutedEventArgs e)
{
DrawNewFence();
}
private void DrawNewFence()
{
CancelEdit();
map1.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;
map1.TrackOverlay.TrackMode = TrackMode.Polygon;
}
private void DeleteFenceClick(object sender, RoutedEventArgs e)
{
if (map1.EditOverlay.EditShapesLayer.InternalFeatures.Count == 0)
{
MessageBox.Show("Please choose a fence!", "Vehicle Tracking", MessageBoxButton.OK);
}
else if (map1.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)
{
if (MessageBox.Show("Are you sure you want to delete the fence you have selected?", "Vehicle Tracking", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
map1.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;
map1.EditOverlay.EditShapesLayer.InternalFeatures.Clear();
LayerOverlay spatialFenceOverlay = (LayerOverlay)map1.Overlays["SpatialFenceOverlay"];
((InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]).InternalFeatures.Clear();
SaveSpatialFences(() => UpdateSpatialFencesAndVehicles());
}
}
}
private void SaveFenceClick(object sender, RoutedEventArgs e)
{
map1.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;
SaveSpatialFences(() => UpdateSpatialFencesAndVehicles());
if (EditFenceRadioButton.IsChecked.GetValueOrDefault())
{
EditFenceRadioButton.IsChecked = false;
DrawNewFenceRadioButton.IsChecked = true;
DrawNewFence();
}
}
private void EditFenceClick(object sender, RoutedEventArgs e)
{
ClearMeasuresAndPopups();
map1.TrackOverlay.TrackMode = TrackMode.None;
LayerOverlay spatialFenceOverlay = (LayerOverlay)map1.Overlays["SpatialFenceOverlay"];
InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"];
// Move spatial fences from spatial fence layer to edit overlay for editing
foreach (Feature feature in spatialFenceLayer.InternalFeatures)
{
if (!map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Contains(feature.Id))
{
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(feature.Id, feature);
}
if (!spatialFenceLayer.FeatureIdsToExclude.Contains(feature.Id))
{
spatialFenceLayer.FeatureIdsToExclude.Add(feature.Id);
}
}
map1.TrackOverlay.MapMouseClick -= TrackOverlay_MapMouseClick;
map1.TrackOverlay.MapMouseClick += TrackOverlay_MapMouseClick;
UpdateVehicles();
map1.Refresh();
}
private void TrackOverlay_MapMouseClick(object sender, MapMouseClickInteractiveOverlayEventArgs e)
{
PointShape clickedPoint = new PointShape(e.InteractionArguments.WorldX, e.InteractionArguments.WorldY);
RectangleShape rect = GetBufferedRectangle(clickedPoint);
if (!map1.TrackOverlay.TrackShapeLayer.IsOpen)
{
map1.TrackOverlay.TrackShapeLayer.Open();
}
Collection intersectingFeatures = map1.TrackOverlay.TrackShapeLayer.QueryTools.GetFeaturesIntersecting(rect, ReturningColumnsType.AllColumns);
if (intersectingFeatures.Count > 0)
{
if (map1.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)
{
foreach (var item in map1.EditOverlay.EditShapesLayer.InternalFeatures)
{
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(item);
}
map1.EditOverlay.EditShapesLayer.InternalFeatures.Clear();
}
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Remove(intersectingFeatures[0].Id);
map1.EditOverlay.EditShapesLayer.InternalFeatures.Add(intersectingFeatures[0]);
map1.EditOverlay.CalculateAllControlPoints();
map1.Refresh();
}
}
private void SaveSpatialFences(Action executeAction)
{
LayerOverlay spatialFenceOverlay = (LayerOverlay)map1.Overlays["SpatialFenceOverlay"];
InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"];
foreach (var item in spatialFenceLayer.FeatureIdsToExclude)
{
if (spatialFenceLayer.InternalFeatures.Contains(item))
{
spatialFenceLayer.InternalFeatures.Remove(item);
}
}
spatialFenceLayer.FeatureIdsToExclude.Clear();
// Save the new spatial fences from edit overlay into the spatial fence layer
foreach (Feature feature in map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => (string)f.Tag != "Measure"))
{
if (!spatialFenceLayer.InternalFeatures.Contains(feature.Id))
{
spatialFenceLayer.InternalFeatures.Add(feature.Id, feature);
}
}
foreach (Feature feature in map1.EditOverlay.EditShapesLayer.InternalFeatures)
{
if (!spatialFenceLayer.InternalFeatures.Contains(feature.Id))
{
spatialFenceLayer.InternalFeatures.Add(feature.Id, feature);
}
}
spatialFenceOverlay.Refresh();
TrackingAccessPrividerSourceClient client = new TrackingAccessPrividerSourceClient();
client.DeleteAndUpdateAndInsertSpatialFencesCompleted += (s, e) =>
{
// Turn the track mode to none and clear the features in the edit overlay
map1.TrackOverlay.TrackMode = TrackMode.None;
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Clear();
map1.EditOverlay.EditShapesLayer.InternalFeatures.Clear();
map1.Popups.Clear();
map1.TrackOverlay.Refresh();
map1.EditOverlay.CalculateAllControlPoints();
map1.EditOverlay.Refresh();
if (executeAction != null)
{
executeAction();
if (EditFenceRadioButton.IsChecked.GetValueOrDefault() || DrawNewFenceRadioButton.IsChecked.GetValueOrDefault())
{
EditFenceRadioButton.IsChecked = false;
DrawNewFenceRadioButton.IsChecked = true;
DrawNewFence();
}
}
};
ObservableCollection excludeFeatureWktIds = new ObservableCollection(spatialFenceLayer.InternalFeatures.Select(f => f.GetWellKnownText() + "|" + f.Id).ToList());
client.DeleteAndUpdateAndInsertSpatialFencesAsync(excludeFeatureWktIds);
}
private void ZoomToVehicleClick(object sender, RoutedEventArgs e)
{
LayerOverlay traceOverlay = (LayerOverlay)map1.Overlays["TraceOverlay"];
FrameworkElement frameworkElement = (FrameworkElement)sender;
VehicleViewModel vehicleViewModel = frameworkElement.DataContext as VehicleViewModel;
if (vehicleViewModel != null)
{
InMemoryFeatureLayer vehicleFeatureLayer = traceOverlay.Layers[vehicleViewModel.OwnerName] as InMemoryFeatureLayer;
if (vehicleFeatureLayer != null)
{
PointShape centerPoint = vehicleFeatureLayer.InternalFeatures[vehicleFeatureLayer.InternalFeatures.Count|- 1].GetShape() as PointShape;
map1.ZoomTo(centerPoint, 15);
}
}
}
private void CollapsExpandClick(object sender, RoutedEventArgs e)
{
CheckBox CollapsExpandCheckBox = sender as CheckBox;
if (CollapsExpandCheckBox != null)
{
if (CollapsExpandCheckBox.IsChecked.GetValueOrDefault())
{
CollapsExpandCheckBox.Content = new Uri("Image/expand.png", UriKind.RelativeOrAbsolute);
statusPanel.Visibility = Visibility.Collapsed;
Grid grid = map1.Parent as Grid;
if (grid != null)
{
map1.Width = grid.ActualWidth;
}
}
else
{
CollapsExpandCheckBox.Content = new Uri("Image/collapse.png", UriKind.RelativeOrAbsolute);
statusPanel.Visibility = Visibility.Visible;
Grid grid = map1.Parent as Grid;
if (grid != null)
{
map1.Width = grid.ColumnDefinitions.Last().ActualWidth;
}
}
}
}
private void Control_MouseEnter(object sender, MouseEventArgs e)
{
Control control = sender as Control;
if (control != null)
{
control.Effect = dropShadowEffect;
}
}
private void Control_MouseLeave(object sender, MouseEventArgs e)
{
Control control = sender as Control;
if (control != null)
{
control.Effect = null;
}
}
private void CancelEditClick(object sender, RoutedEventArgs e)
{
CancelEdit();
}
private void CancelEdit()
{
map1.EditOverlay.EditShapesLayer.InternalFeatures.Clear();
foreach (var editFeature in map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => (string)f.Tag != "Measure").ToList())
{
map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Remove(editFeature);
}
LayerOverlay spatialFenceOverlay = (LayerOverlay)map1.Overlays["SpatialFenceOverlay"];
InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"];
spatialFenceLayer.FeatureIdsToExclude.Clear();
map1.EditOverlay.Refresh();
map1.TrackOverlay.Refresh();
spatialFenceOverlay.Refresh();
if (EditFenceRadioButton.IsChecked.GetValueOrDefault())
{
EditFenceRadioButton.IsChecked = false;
DrawNewFenceRadioButton.IsChecked = true;
DrawNewFence();
}
}
private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
Grid grid = sender as Grid;
if (grid != null)
{
map1.Width = grid.ColumnDefinitions[1].ActualWidth;
map1.Height = grid.ActualHeight;
if (isFirst)
{
isFirst = false;
// Setup the map.
map1.MapUnit = GeographyUnit.Meter;
map1.MapTools.ScaleLine.IsEnabled = true;
// Add the various overlays such as vehicles, fences etc.
SetupBaseOverlays();
UpdateSpatialFencesAndVehicles(false);
map1.CurrentExtent = new RectangleShape(-10785099.4221547, 3916104.57324868, -10779357.0938025, 3912421.26612761);
}
}
}
private void OverlaySwitcher_OverlayChanged(object sender, OverlayChangedOverlaySwitcherEventArgs e)
{
switch (e.NewCheckedOverlayName)
{
case worldMapKitName:
if (map1.Overlays.Contains(worldMapKitName)) map1.Overlays.Remove(worldMapKitName);
map1.Overlays.Insert(0, worldMapKitName, new WorldMapKitWmsSilverlightOverlay { Projection = WorldMapKitProjection.SphericalMercator });
if (map1.Overlays.Contains(openStreetMapName)) map1.Overlays.Remove(openStreetMapName);
if (map1.Overlays.Contains(bingMapsRoadMapName)) map1.Overlays.Remove(bingMapsRoadMapName);
map1.Refresh();
break;
case openStreetMapName:
if (map1.Overlays.Contains(openStreetMapName)) map1.Overlays.Remove(openStreetMapName);
map1.Overlays.Insert(0, openStreetMapName, new OpenStreetMapOverlay());
if (map1.Overlays.Contains(worldMapKitName)) map1.Overlays.Remove(worldMapKitName);
if (map1.Overlays.Contains(bingMapsRoadMapName)) map1.Overlays.Remove(bingMapsRoadMapName);
map1.Refresh();
break;
case bingMapsRoadMapName:
case bingMapsAerialMapName:
bool needShowInputBingMapKeyWindow = true;
if (IsolatedStorageSettings.ApplicationSettings.Contains(bingMapsKeyFileName))
{
string bingmapsKey = IsolatedStorageSettings.ApplicationSettings[bingMapsKeyFileName].ToString();
if (!string.IsNullOrEmpty(bingmapsKey))
{
LoadBingMaps(e.NewCheckedOverlayName, bingmapsKey);
needShowInputBingMapKeyWindow = false;
}
}
if (needShowInputBingMapKeyWindow)
{
BingMapsApplicationIdPromptWindow bingMapsApplicationIdPromptWindow = new BingMapsApplicationIdPromptWindow();
bingMapsApplicationIdPromptWindow.Closing += (s, args) =>
{
if (bingMapsApplicationIdPromptWindow.DialogResult.GetValueOrDefault())
{
LoadBingMaps(e.NewCheckedOverlayName, bingMapsApplicationIdPromptWindow.ApplicationId);
IsolatedStorageSettings.ApplicationSettings.Add(bingMapsKeyFileName, bingMapsApplicationIdPromptWindow.ApplicationId);
}
else overlaySwitcher.BindingOverlayNames(e.OldCheckedOverlayName);
};
bingMapsApplicationIdPromptWindow.Show();
}
break;
}
}
private void LoadBingMaps(string newCheckedOverlayName, string bingMapsKey)
{
BingMapsStyle bingMapsStyle = newCheckedOverlayName == bingMapsRoadMapName ? BingMapsStyle.Roads : BingMapsStyle.Aerial;
if (map1.Overlays.Contains(bingMapsRoadMapName)) map1.Overlays.Remove(bingMapsRoadMapName);
map1.Overlays.Insert(0, bingMapsRoadMapName, new BingMapsOverlay(bingMapsRoadMapName, bingMapsKey, bingMapsStyle));
if (map1.Overlays.Contains(openStreetMapName)) map1.Overlays.Remove(openStreetMapName);
if (map1.Overlays.Contains(worldMapKitName)) map1.Overlays.Remove(worldMapKitName);
map1.Refresh();
}
private void Map_MouseMove(object sender, MouseEventArgs e)
{
Point screenPoint = e.GetPosition(map1);
PointShape worldPoint = ExtentHelper.ToWorldCoordinate(map1.CurrentExtent, screenPoint, map1.ActualWidth, map1.ActualHeight);
LocationXTextBlock.Text = string.Format("X:{0:#,0.##}", worldPoint.X);
LocationYTextBlock.Text = string.Format("Y:{0:#,0.##}", worldPoint.Y);
}
private static DateTime GetAdjustedCurrentDateTime()
{
// This vehicle tracking sample contains some simulated data
// This method stores the real time when the application started and reflects to the start sample time
// When the actual time increments 1 second, the sample time increments 6 seconds
//
// To make the application run in real time just have this method return to current date time
//
double realSpentTime = TimeSpan.FromTicks(DateTime.Now.Ticks - applicationStartTime.Ticks).TotalSeconds;
int sampleSpentTime = (int)(realSpentTime * 12);
DateTime currentSampleTime = adjustedStartTime.AddSeconds(sampleSpentTime);
return currentSampleTime;
}
}
}
====VehicleTrackingViewModel.cs====
using System.Collections.ObjectModel;
using System.Linq;
namespace ThinkGeo.MapSuite.VehicleTracking
{
public class VehicleTrackingViewModel : ViewModelBase
{
private string defaultOverlayName;
private UnitSystem selectedUnitSystem;
private Collection overlayNames;
private Collection unitSystems;
private ObservableCollection vehicles;
public VehicleTrackingViewModel()
{
overlayNames = new Collection();
vehicles = new ObservableCollection();
unitSystems = new Collection { UnitSystem.Imperial, UnitSystem.Metric };
selectedUnitSystem = unitSystems[0];
}
public ObservableCollection Vehicles
{
get { return vehicles; }
}
public Collection UnitSystems
{
get { return unitSystems; }
}
public UnitSystem SelectedUnitSystem
{
get { return selectedUnitSystem; }
set { selectedUnitSystem = value; }
}
public Collection OverlayNames
{
get { return overlayNames; }
}
public string DefaultOverlayName
{
get { return string.IsNullOrEmpty(defaultOverlayName) ? overlayNames.FirstOrDefault() : defaultOverlayName; }
set { defaultOverlayName = value; }
}
}
public enum UnitSystem
{
Imperial = 0,
Metric = 1,
}
}
====TrackingDataProvider.cs====
using System.Globalization;
using ThinkGeo.MapSuite.VehicleTracking.ServiceReference;
namespace ThinkGeo.MapSuite.VehicleTracking
{
public class VehicleViewModel : ViewModelBase
{
private string area;
private string speed;
private string status;
private string iconUri;
private string duration;
private string ownerName;
private Vehicle vehicle;
public VehicleViewModel()
: this(null)
{ }
public VehicleViewModel(Vehicle vehicle)
{
ownerName = vehicle.VehicleName;
iconUri = "Image/" + vehicle.VehicleIconVirtualPath;
Vehicle = vehicle;
Load();
}
public Vehicle Vehicle
{
get { return vehicle; }
set { vehicle = value; }
}
public void Load()
{
Status = MapSuiteSampleHelper.GetCurrentState(vehicle);
Speed = vehicle.Location.Speed.ToString(CultureInfo.InvariantCulture) + " mph";
Duration = MapSuiteSampleHelper.GetSpeedDuration(vehicle).ToString(CultureInfo.InvariantCulture) + " min";
}
public string Status
{
get { return status; }
set
{
status = value;
RaisePropertyChanged(() => Status);
}
}
public string IconUri
{
get { return iconUri; }
set
{
iconUri = value;
RaisePropertyChanged(() => IconUri);
}
}
public string Area
{
get { return area; }
set
{
area = value;
RaisePropertyChanged(() => Area);
}
}
public string OwnerName
{
get { return ownerName; }
set
{
ownerName = value;
RaisePropertyChanged(() => OwnerName);
}
}
public string Speed
{
get { return speed; }
set
{
speed = value;
RaisePropertyChanged(() => Speed);
}
}
public string Duration
{
get { return duration; }
set
{
duration = value;
RaisePropertyChanged(() => Duration);
}
}
}
}
====ViewModelBase.cs====
using System;
using System.ComponentModel;
using System.Linq.Expressions;
namespace ThinkGeo.MapSuite.VehicleTracking
{
public class ViewModelBase : INotifyPropertyChanged
{
public ViewModelBase()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
protected virtual void RaisePropertyChanged(Expression> expreesion)
{
RaisePropertyChanged(((MemberExpression)expreesion.Body).Member.Name);
}
}
}
====Location.cs====
using System;
using System.Runtime.Serialization;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.VehicleTracking
{
///
/// This class specify the basic information for a location.
///
[DataContract]
public class Location
{
private double speed;
private double latitude;
private double longitude;
private DateTime dateTime;
public Location()
: this(0, 0, 0, DateTime.Now)
{ }
public Location(double longitude, double latitude, double speed, DateTime dateTime)
{
Longitude = longitude;
Latitude = latitude;
Speed = speed;
DateTime = dateTime;
}
[DataMember]
public double Longitude
{
get { return longitude; }
set { longitude = value; }
}
[DataMember]
public double Latitude
{
get { return latitude; }
set { latitude = value; }
}
[DataMember]
public double Speed
{
get { return speed; }
set { speed = value; }
}
[DataMember]
public DateTime DateTime
{
get { return dateTime; }
set { dateTime = value; }
}
}
}
====TrackingAccessProvider.cs====
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.OleDb;
using System.Globalization;
using System.Text;
namespace ThinkGeo.MapSuite.VehicleTracking
{
public class TrackingAccessProvider : TrackingDataProvider
{
private OleDbConnection dataConnection;
public TrackingAccessProvider(string databaseFilePath)
{
string connectionString = string.Format(CultureInfo.InvariantCulture, "Provider=Microsoft.Jet.OLEDB.4.0; Data Source='{0}'", databaseFilePath);
dataConnection = new OleDbConnection(connectionString);
}
public override Dictionary GetCurrentVehicles(DateTime currentTime)
{
Dictionary vehiclesList = new Dictionary();
DataSet vehiclesDataSet = ExecuteQuery("Select * from Vehicle");
TimeSpan trackHistoryVehicleTimeSpan = TimeSpan.FromHours(8);
foreach (DataRow row in vehiclesDataSet.Tables[0].Rows)
{
int vehicleId = Convert.ToInt32(row["VehicleId"], CultureInfo.InvariantCulture);
Vehicle vehicle = GetCurrentVehicle(vehicleId, currentTime, trackHistoryVehicleTimeSpan);
vehiclesList.Add(vehicle.Id, vehicle);
}
return vehiclesList;
}
private Vehicle GetCurrentVehicle(int vehicleId, DateTime currentTime, TimeSpan trackHistoryVehicleTimeSpan)
{
string sql = "SELECT A.VehicleName, A.VehicleID, A.VehicleIconVirtualPath, B.Longitude, B.Latitude, B.[Date], B.Speed FROM (Vehicle A LEFT OUTER JOIN Location B ON A.VehicleID = B.VehicleID) WHERE (A.VehicleID = {0}) AND (B.[Date] <= #{1}# and B.[Date]>=#{2}#) ORDER BY A.VehicleID, B.[Date] DESC";
DateTime trackStartTime = currentTime.AddTicks(-trackHistoryVehicleTimeSpan.Ticks);
sql = String.Format(CultureInfo.InvariantCulture, sql, vehicleId, currentTime.ToString(CultureInfo.InvariantCulture), trackStartTime.ToString(CultureInfo.InvariantCulture));
Vehicle currentVechicle = new Vehicle(vehicleId);
DataSet currentLocations = null;
try
{
// Get the locations from current time back to the passed time span
currentLocations = ExecuteQuery(sql);
Collection historySpeeds = new Collection();
for (int rowIndex = 0; rowIndex < currentLocations.Tables[0].Rows.Count; rowIndex++)
{
DataRow dataRow = currentLocations.Tables[0].Rows[rowIndex];
currentVechicle.VehicleIconVirtualPath = dataRow["VehicleIconVirtualPath"].ToString();
double latitude = Convert.ToDouble(dataRow["Latitude"], CultureInfo.InvariantCulture);
double longitude = Convert.ToDouble(dataRow["Longitude"], CultureInfo.InvariantCulture);
double speed = Convert.ToDouble(dataRow["Speed"], CultureInfo.InvariantCulture);
DateTime dateTime = Convert.ToDateTime(dataRow["Date"], CultureInfo.InvariantCulture);
Location currentLocation = new Location(longitude, latitude, speed, dateTime);
historySpeeds.Add(speed);
if (rowIndex == 0)
{
string vehicleName = dataRow["VehicleName"].ToString();
currentVechicle.Location = currentLocation;
currentVechicle.Id = vehicleId;
currentVechicle.VehicleName = vehicleName;
}
else
{
currentVechicle.HistoryLocations.Add(currentLocation);
}
}
}
finally
{
if (currentLocations != null) currentLocations.Dispose();
}
return currentVechicle;
}
public override Collection GetSpatialFences()
{
Collection spatialFences = new Collection();
DataSet dataSet = ExecuteQuery("Select * from SpatialFence");
foreach (DataRow row in dataSet.Tables[0].Rows)
{
string wkt = row["FenceGeometry"].ToString();
string id = row["FeatureID"].ToString();
spatialFences.Add(wkt + "|" + id);
}
return spatialFences;
}
public void DeleteAndUpdateAndInsertSpatialFences(IEnumerable excludeFeatureWktIds)
{
Dictionary featureWktIds = new Dictionary();
foreach (var item in excludeFeatureWktIds)
{
var array = item.Split('|');
if (array.Length == 2)
{
featureWktIds.Add(array[0], array[1]);
}
}
DeleteSpatialFencesExcluding(featureWktIds.Values.ToList());
foreach (var item in featureWktIds)
{
int result = UpdateSpatialFenceByFeature(item.Key, item.Value);
if (result == 0)
{
InsertSpatialFence(item.Key, item.Value);
}
}
}
public override void DeleteSpatialFencesExcluding(IEnumerable excludeFeatureIds)
{
StringBuilder undeleteFeatureIds = new StringBuilder();
foreach (string undeleteFeatureId in excludeFeatureIds)
{
undeleteFeatureIds.AppendFormat(CultureInfo.InvariantCulture, "'{0}',", undeleteFeatureId);
}
string sql = String.Format(CultureInfo.InvariantCulture,
"DELETE FROM SpatialFence WHERE (FeatureID NOT IN ({0}))", undeleteFeatureIds.ToString().TrimEnd(','));
ExecuteNonQuery(sql);
}
public override int UpdateSpatialFenceByFeature(string wkt, string featureId)
{
int updatedSpatialFenceCount =
ExecuteNonQuery(String.Format(CultureInfo.InvariantCulture,
"UPDATE SpatialFence SET FenceGeometry = '{0}' WHERE (FeatureID = '{1}')", wkt, featureId));
return updatedSpatialFenceCount;
}
public override void InsertSpatialFence(string wkt, string featureId)
{
ExecuteNonQuery(String.Format(CultureInfo.InvariantCulture,
"Insert into SpatialFence(FenceGeometry,FeatureID) values('{0}','{1}')", wkt, featureId));
}
private DataSet ExecuteQuery(string selectCommandText)
{
OleDbDataAdapter dataAdapter = null;
try
{
dataAdapter = new OleDbDataAdapter(selectCommandText, dataConnection);
dataConnection.Open();
DataSet dataSet = new DataSet();
dataSet.Locale = CultureInfo.InvariantCulture;
dataAdapter.Fill(dataSet);
return dataSet;
}
finally
{
if (dataAdapter != null)
{
dataAdapter.Dispose();
}
if (dataConnection != null)
{
dataConnection.Close();
}
}
}
private int ExecuteNonQuery(string cmdText)
{
OleDbCommand dataCommand = null;
int affectedRowNumber = 0;
try
{
dataCommand = new OleDbCommand(cmdText, dataConnection);
dataConnection.Open();
affectedRowNumber = dataCommand.ExecuteNonQuery();
}
finally
{
if (dataCommand != null) dataCommand.Dispose();
if (dataConnection != null) dataConnection.Close();
}
return affectedRowNumber;
}
~TrackingAccessProvider()
{
Dispose(false);
}
public override void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool flag)
{
if (flag)
{
if (dataConnection != null)
{
dataConnection.Close();
dataConnection.Dispose();
dataConnection = null;
}
}
}
}
}
====TrackingDataProvider.cs====
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace ThinkGeo.MapSuite.VehicleTracking
{
public abstract class TrackingDataProvider : IDisposable
{
public abstract Dictionary GetCurrentVehicles(DateTime currentTime);
public abstract Collection GetSpatialFences();
public abstract void DeleteSpatialFencesExcluding(IEnumerable excludeFeatureIds);
public abstract int UpdateSpatialFenceByFeature(string wkt, string featureId);
public abstract void InsertSpatialFence(string wkt, string featureId);
public abstract void Dispose();
}
}
====Vehicle.cs====
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
namespace ThinkGeo.MapSuite.VehicleTracking
{
///
/// This class stands for a vehicle.
///
[DataContract]
public class Vehicle
{
private int id;
private string name;
private string iconPath;
private Location location;
private Collection historyLocations;
private Vehicle()
: this(0)
{ }
public Vehicle(int id)
{
Id = id;
name = string.Empty;
Location = new Location();
historyLocations = new Collection();
}
[DataMember]
public int Id
{
get { return id; }
set { id = value; }
}
[DataMember]
public Location Location
{
get { return location; }
set { location = value; }
}
[DataMember]
public Collection HistoryLocations
{
get { return historyLocations; }
}
[DataMember]
public string VehicleName
{
get { return name; }
set { name = value; }
}
[DataMember]
public string VehicleIconVirtualPath
{
get { return iconPath; }
set { iconPath = value; }
}
public int GetSpeedDuration()
{
int speedDuration = 0;
double lastSpeed = Location.Speed;
foreach (Location tempLocation in HistoryLocations)
{
if (tempLocation.Speed == lastSpeed)
{
speedDuration++;
}
else
{
break;
}
}
return speedDuration;
}
///
/// If the Vehicle's speed is not 0 in the passed 4 minutes, we say it is in Motion.
///
/// State of current vehicle.
public VehicleMotionState GetCurrentState()
{
VehicleMotionState vehicleState = VehicleMotionState.Idle;
if (Location.Speed != 0)
{
vehicleState = VehicleMotionState.Motion;
}
else
{
int locationIndex = 0;
foreach (Location historyLocation in HistoryLocations)
{
if (locationIndex > 3)
{
break;
}
if (historyLocation.Speed != 0)
{
vehicleState = VehicleMotionState.Motion;
break;
}
locationIndex++;
}
}
return vehicleState;
}
}
}
====VehicleMotionState.cs====
using System.Runtime.Serialization;
namespace ThinkGeo.MapSuite.VehicleTracking
{
///
/// This enumeration specifies the Possible states for Vehicles.
///
[DataContract]
public enum VehicleMotionState
{
[DataMember]
Motion = 0,
[DataMember]
Idle = 1,
}
}