ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ThinkGeo.MapSuite.VehicleTracking.VehicleTracking" %> <%@ Register Assembly="WebEdition" Namespace="ThinkGeo.MapSuite.WebEdition" TagPrefix="cc1" %> <!DOCTYPE html> <html xml:en-us"> <head> <title>Vehicle Tracking</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <link href="Images/MapSuite.ico" rel="shortcut icon" type="image/x-icon" /> <link href="Styles/jquery-ui-1.10.4.custom.min.css" rel="stylesheet" type="text/css" /> <link href="Styles/Site.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="Scripts/modernizr-2.5.3.js"></script> <script src="Scripts/jquery-1.10.2.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div id="container"> <div id="header"> <div id="left-header"> <span id="header-mapsuite">Map Suite</span> <span id="header-title">Vehicle Tracking</span> </div> </div> <div id="content-container"> <div id="leftContainer"> <div id="leftContent"> <h4>Click to refresh vehicles:</h4> <div id="divRefresh" class="divBorder"> <div class="divSettingItem"> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:ImageButton ID="ibtnAutoRefreshButton" ToolTip="Auto Refresh" runat="server" ImageUrl="~/Images/autorefresh.png" OnClientClick="changeAutoRefreshButton(this);return true;" CssClass="imgButton" OnClick="ibtnAutoRefresh_Click" /> <span class="title">Auto Refresh:</span> <asp:Label ID="lblStatus" runat="server" CssClass="title redTxt" Text="On"></asp:Label> <asp:Timer ID="tmAutoRefreshTimer" runat="server" Interval="5000" OnTick="tmAutoRefreshTimer_Tick" Enabled="true" /> </ContentTemplate> </asp:UpdatePanel> </div> <div class="divSettingItem"> <asp:ImageButton ID="ibtnRefreshManually" ToolTip="Refresh" runat="server" OnClick="ibtnRefreshManually_Click" ImageUrl="~/Images/RefreshManually.png" CssClass="imgButton" /> <span class="title">Refresh Manually</span> </div> </div> <h4>Interact with the map using these tools: </h4> <div id="divTrackMode" class="divBorder"> <asp:ImageButton ID="btnPan" ToolTip="Pan map" AlternateText="Pan" runat="server" class="active imgButton" ImageUrl="~/Images/pan.png" /> <asp:ImageButton ID="btnDraw" ToolTip="Draw fences" AlternateText="Draw" runat="server" class="imgButton" ImageUrl="~/Images/draw.png" /> <asp:ImageButton ID="btnMeasure" ToolTip="Measure distance" AlternateText="Measure" runat="server" class="imgButton" ImageUrl="~/Images/measure.png" /> </div> <div id="divTrackType" class="divSubBorder"> <asp:ImageButton ID="ibtnDrawPolygon" ToolTip="Track new fences" runat="server" class="imgButton" onclick="ibtnDrawPolygon_Click" ImageUrl="~/Images/draw_polygon.png"/> <asp:ImageButton ID="ibtnEditSpatialFences" ToolTip="Edit the selected fence" runat="server" class="imgButton" OnClick="ibtnEditSpatialFences_Click" ImageUrl="~/Images/edit_polygon.png" /> <asp:ImageButton ID="ibtnDeleteSpatialFences" ToolTip="Delete" runat="server" class="imgButton" OnClick="ibtnDeleteSpatialFences_Click" ImageUrl="~/Images/Remove_Polygon.png" /> <asp:ImageButton ID="ibtnSaveSpatialFences" ToolTip="Save" runat="server" class="imgButton" OnClick="ibtnSaveSpatialFences_Click" ImageUrl="~/Images/save.png" /> <asp:ImageButton ID="ibtnCancelSpatialFences" ToolTip="Cancel" runat="server" class="imgButton" OnClick="ibtnCancelEditSpatialFences_Click" ImageUrl="~/Images/clear.png" /> <!--Add a hide button to avoid the async Confirm dialog --> <asp:Button ID="btnDeleteSpatialFence" runat="server" Text="Remove Fences" Style="display: none;" OnClick="ibtnDeleteSpatialFences_Click" /> </div> <div id="divMeasure" class="divSubBorder"> <asp:ImageButton ID="ibtnMeasureLength" ToolTip="Measure line" runat="server" class="imgButton" ImageUrl="~/Images/line.png" OnClick="ibtnMeasureLength_Click" /> <asp:ImageButton ID="ibtnMeasureArea" ToolTip="Measure polygon" runat="server" class="imgButton" ImageUrl="~/Images/Polygon.png" OnClick="ibtnMeasureArea_Click" /> <asp:ImageButton ID="ibtnClearMeasure" ToolTip="Cancel" runat="server" class="imgButton" ImageUrl="~/Images/clear.png" OnClick="ibtnClearMeasure_Click" /> <span class="title">Measure Unit:</span> <asp:DropDownList ID="ddlMeasureUnit" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlMeasureUnit_SelectedIndexChanged"> <asp:ListItem Value="Metric">Metric</asp:ListItem> <asp:ListItem Value="Imperial">Imperial</asp:ListItem> </asp:DropDownList> </div> <div class="blueBanner"> Tracked Vehicles </div> <div class="divBorder" id="divVehicleList"> <asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Always"> <ContentTemplate> <asp:Repeater ID="rptVehicles" runat="server"> <HeaderTemplate> <table id="tbVehiclelist"> </HeaderTemplate> <ItemTemplate> <tr> <td rowspan="5" class="vehicleImg"> <img id="imgVehicle" alt="<%# Eval("VehicleName")%>" onclick="zoomInToVehicle(<%# Eval("Longitude")%>,<%# Eval("Latitude")%>)" src='<%# Eval("VehicleIconVirtualPath") %>' /> </td> <td colspan="2" class="vehicleName"> <a href="#" id="btnZoomTo" onclick="zoomInToVehicle(<%# Eval("Longitude")%>,<%# Eval("Latitude")%>)"> <%# Eval("VehicleName")%></a> </td> </tr> <tr class="vehicleTxt"> <td colspan="2"> <img alt="ball" src='<%# Eval("MotionStateIconVirtualPath") %>' /> <span id="motionStatus" class="greenTxt"> <%# (Eval("MotionState").ToString() == "Motion") ? "In Motion" : "Idle"%> </span> </td> </tr> <tr class="vehicleTxt"> <td>Area: </td> <td id="isInFence"> <%# ((bool)Eval("IsInFence")) ? "<span class='redTxt'>In Restrict Area</span>" : "Out Of Restrict Area"%> </td> </tr> <tr class="vehicleTxt"> <td>Speed: </td> <td> <%# DataBinder.Eval(Container.DataItem, "Location.Speed") + " mph"%> </td> </tr> <tr class="vehicleTxt"> <td>Duration: </td> <td> <%# Eval("SpeedDuration") + " min"%> </td> </tr> <tr class="vehicleTxt"> <td colspan="3"> </td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="tmAutoRefreshTimer" EventName="Tick" /> </Triggers> </asp:UpdatePanel> </div> </div> </div> <div id="toggle"> <img alt="collapse" src="Images/collapse.gif" /> </div> <div id="map-content"> <asp:UpdatePanel ID="UpdatePanel2" style="width: 100%; height: 100%;" runat="server" UpdateMode="Conditional"> <ContentTemplate> <cc1:Map ID="Map1" runat="server" Height="100%" Width="100%" Visible="true"> </cc1:Map> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="tmAutoRefreshTimer" EventName="Tick" /> <asp:AsyncPostBackTrigger ControlID="ibtnRefreshManually" /> <asp:AsyncPostBackTrigger ControlID="ibtnDrawPolygon" /> <asp:AsyncPostBackTrigger ControlID="ibtnSaveSpatialFences" /> <asp:AsyncPostBackTrigger ControlID="ibtnEditSpatialFences" /> <asp:AsyncPostBackTrigger ControlID="ibtnDeleteSpatialFences" /> <asp:AsyncPostBackTrigger ControlID="btnDeleteSpatialFence" /> <asp:AsyncPostBackTrigger ControlID="ibtnCancelSpatialFences" /> <asp:AsyncPostBackTrigger ControlID="ibtnMeasureLength" /> <asp:AsyncPostBackTrigger ControlID="ibtnMeasureArea" /> <asp:AsyncPostBackTrigger ControlID="ibtnClearMeasure" /> <asp:AsyncPostBackTrigger ControlID="ddlMeasureUnit" EventName="SelectedIndexChanged" /> </Triggers> </asp:UpdatePanel> <div id="divRemoveDialog"> Are you sure you want to delete the spatial fence you have selected? </div> <div id="divMessage"> Please choose a fence at first. </div> </div> </div> <div id="footer"> <span id="coordinate"><span id="spanMouseCoordinate"></span></span> </div> </div> </form> <script type="text/javascript" src="Scripts/jquery-ui-1.10.4.custom.min.js"></script> <script type="text/javascript" src="Scripts/ready-functions.js"></script> </body> </html>
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Globalization; using System.Web.UI; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WebEdition; using System.Configuration; using System.Text; namespace ThinkGeo.MapSuite.VehicleTracking { public partial class VehicleTracking : Page { // For the sample we set the current time to the time below. This is so the time will // match the data in our sample database. private readonly DateTime adjustedStartTime = new DateTime(2009, 7, 10, 11, 31, 0); protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { InitializeMap(); // Read vehicles from database DateTime currentTime = GetAdjustedCurrentDateTime(); Dictionary<int, Vehicle> vehicles = GetVehicles(currentTime); // Update vehicle information and spatial fence on the Map UpdateSpatialFencesAndVehicles(); // Update vehicle information to Map UpdateVehiclesToOverlays(vehicles); // Display vehicle list rptVehicles.DataSource = vehicles.Values; rptVehicles.DataBind(); } } protected void tmAutoRefreshTimer_Tick(object sender, EventArgs e) { // Update vehicle information and spatial fence on the Map UpdateSpatialFencesAndVehicles(); } protected void ibtnDrawPolygon_Click(object sender, ImageClickEventArgs e) { Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.None; Map1.EditOverlay.TrackMode = TrackMode.Polygon; } protected void ibtnSaveSpatialFences_Click(object sender, ImageClickEventArgs e) { Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.None; Map1.EditOverlay.TrackMode = TrackMode.None; SaveSpatialFences(); // Redraw spatial fences on the map UpdateSpatialFencesToOverlay(); } protected void ibtnDeleteSpatialFences_Click(object sender, EventArgs e) { LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; spatialFenceLayer.InternalFeatures.Clear(); spatialFenceLayer.FeatureIdsToExclude.Clear(); SaveSpatialFences(); // Redraw spatial fences on the map UpdateSpatialFencesToOverlay(); } protected void ibtnCancelEditSpatialFences_Click(object sender, ImageClickEventArgs e) { // Refresh the spatial fence overlay LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; spatialFenceLayer.FeatureIdsToExclude.Clear(); spatialFenceOverlay.Redraw(); // Clear the spatial fences from spatial fence layer Map1.EditOverlay.Features.Clear(); Map1.EditOverlay.TrackMode = TrackMode.Polygon; // Disable Measure tool Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.None; // Update vehicle information on the Map DateTime currentTime = GetAdjustedCurrentDateTime(); UpdateVehiclesToOverlays(GetVehicles(currentTime)); } protected void ibtnEditSpatialFences_Click(object sender, ImageClickEventArgs e) { LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; // Move spatial fences from spatial fence layer to edit overlay for editing Map1.EditOverlay.Features.Clear(); foreach (Feature feature in spatialFenceLayer.InternalFeatures) { Map1.EditOverlay.Features.Add(feature.Id, feature); spatialFenceLayer.FeatureIdsToExclude.Add(feature.Id); } spatialFenceOverlay.Redraw(); // Enable the edit mode on map Map1.EditOverlay.TrackMode = TrackMode.Edit; // Disable Measure tool Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.None; // Update vehicle information on the Map DateTime currentTime = GetAdjustedCurrentDateTime(); UpdateVehiclesToOverlays(GetVehicles(currentTime)); } protected void ibtnRefreshManually_Click(object sender, ImageClickEventArgs e) { // Update vehicle information and spatial fence on the Map UpdateSpatialFencesAndVehicles(); } protected void ibtnAutoRefresh_Click(object sender, ImageClickEventArgs e) { // Toggle the timer if (tmAutoRefreshTimer.Enabled) { tmAutoRefreshTimer.Enabled = false; lblStatus.Text = "Off"; lblStatus.ForeColor = Color.Red; } else { tmAutoRefreshTimer.Enabled = true; lblStatus.Text = "On"; lblStatus.ForeColor = Color.Black; } // Update vehicle information and spatial fence on the Map UpdateSpatialFencesAndVehicles(); } protected void ibtnMeasureLength_Click(object sender, ImageClickEventArgs e) { Map1.EditOverlay.TrackMode = TrackMode.None; Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.Line; } protected void ibtnMeasureArea_Click(object sender, ImageClickEventArgs e) { Map1.EditOverlay.TrackMode = TrackMode.None; Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.Area; } protected void ibtnClearMeasure_Click(object sender, ImageClickEventArgs e) { Map1.EditOverlay.TrackMode = TrackMode.None; Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.None; } protected void ddlMeasureUnit_SelectedIndexChanged(object sender, EventArgs e) { ScaleBarAdornmentLayer scaleBarAdormentLayer = Map1.AdornmentOverlay.Layers[0] as ScaleBarAdornmentLayer; if (ddlMeasureUnit.SelectedValue == "Imperial") { scaleBarAdormentLayer.UnitFamily = UnitSystem.Imperial; Map1.MapTools.MeasureMapTool.MeasureUnitType = MeasureUnitType.English; } else { scaleBarAdormentLayer.UnitFamily = UnitSystem.Metric; Map1.MapTools.MeasureMapTool.MeasureUnitType = MeasureUnitType.Metric; } } private void InitializeMap() { // Setup the map. Map1.MapUnit = GeographyUnit.Meter; Map1.MapTools.MiniMap.Enabled = true; Map1.MapTools.OverlaySwitcher.Enabled = true; Map1.MapTools.OverlaySwitcher.BaseOverlayTitle = " "; Map1.MapTools.MeasureMapTool.Enabled = true; Map1.MapTools.MeasureMapTool.Geodesic = true; Map1.MapTools.MeasureMapTool.MeasureUnitType = MeasureUnitType.Metric; Map1.MapTools.MeasureMapTool.MeasureType = MeasureType.None; Map1.EditOverlay.EditSettings.IsResizable = false; Map1.CurrentExtent = new RectangleShape(-10785241.6495495, 3916508.33762434, -10778744.5183967, 3912187.74540771); // base map layer WorldMapKitWmsWebOverlay worldMapKitWmsOverlay = new WorldMapKitWmsWebOverlay("World Map Kit"); worldMapKitWmsOverlay.Projection = WorldMapKitProjection.SphericalMercator; Map1.CustomOverlays.Add(worldMapKitWmsOverlay); OpenStreetMapOverlay openStreetMapOverlay = new OpenStreetMapOverlay("Open Street Map"); Map1.CustomOverlays.Add(openStreetMapOverlay); BingMapsOverlay bingMapsAerialOverlay = new BingMapsOverlay("Bing Maps Aerial"); bingMapsAerialOverlay.MapType = BingMapsStyle.Aerial; Map1.CustomOverlays.Add(bingMapsAerialOverlay); BingMapsOverlay bingMapsRoadOverlay = new BingMapsOverlay("Bing Maps Road"); bingMapsRoadOverlay.MapType = BingMapsStyle.Road; Map1.CustomOverlays.Add(bingMapsRoadOverlay); // Add spatial fences UpdateSpatialFencesToOverlay(); // Add scale bar ScaleBarAdornmentLayer scaleBarAdormentLayer = new ScaleBarAdornmentLayer(); scaleBarAdormentLayer.XOffsetInPixel = 10; scaleBarAdormentLayer.UnitFamily = UnitSystem.Metric; Map1.AdornmentOverlay.Layers.Add(scaleBarAdormentLayer); } private static ValueMarkerStyle GetCustomMarkerStyle(string vehicleIconVirtualPath) { StringBuilder popupHtml = new StringBuilder("<table>"); popupHtml.Append("<tr><td colspan='2' class='vehicleName'>[#VehicleName#]</td></tr>"); popupHtml.Append("<tr><td colspan='2'><div class='hrLine'></div></td></tr>"); popupHtml.Append("<tr class='vehicleTxt'><td>Longitude:</td><td>[#Longitude#]</td></tr>"); popupHtml.Append("<tr class='vehicleTxt'><td>Latitude:</td><td>[#Latitude#]</td></tr>"); popupHtml.Append("<tr class='vehicleTxt'><td>Speed:</td><td>[#Speed#]</td></tr>"); popupHtml.Append("<tr class='vehicleTxt'><td>Time</td><td>[#DateTime#]</td></tr>"); popupHtml.Append("</table>"); ValueMarkerStyle valueStyle = new ValueMarkerStyle("IsCurrentPosition"); WebImage currentPositionImage = new WebImage(vehicleIconVirtualPath); PointMarkerStyle currentPositionStyle = new PointMarkerStyle(currentPositionImage); currentPositionStyle.Popup.BorderWidth = 1; currentPositionStyle.Popup.BorderColor = GeoColor.StandardColors.Gray; currentPositionStyle.Popup.ContentHtml = popupHtml.ToString(); currentPositionStyle.Popup.AutoSize = true; MarkerValueItem currentPositionItem = new MarkerValueItem("IsCurrentPosition", (MarkerStyle)currentPositionStyle); valueStyle.ValueItems.Add(currentPositionItem); WebImage historyPositionImage = new WebImage("images/trail point.png", 6, 6, -3, -3); PointMarkerStyle historyPositionStyle = new PointMarkerStyle(historyPositionImage); historyPositionStyle.Popup.BorderWidth = 1; historyPositionStyle.Popup.BorderColor = GeoColor.StandardColors.Gray; historyPositionStyle.Popup.ContentHtml = popupHtml.ToString(); historyPositionStyle.Popup.AutoSize = true; MarkerValueItem historyPositionItem = new MarkerValueItem("IsNotCurrentPosition", (MarkerStyle)historyPositionStyle); valueStyle.ValueItems.Add(historyPositionItem); return valueStyle; } private void SaveSpatialFences() { try { LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; foreach (string featureId in spatialFenceLayer.FeatureIdsToExclude) { spatialFenceLayer.InternalFeatures.Remove(featureId); } spatialFenceLayer.FeatureIdsToExclude.Clear(); // Save the new spatial fences from edit overlay into the spatial fence layer foreach (Feature feature in Map1.EditOverlay.Features) { if (!spatialFenceLayer.InternalFeatures.Contains(feature)) { feature.ColumnValues["Restricted"] = "Restricted"; spatialFenceLayer.InternalFeatures.Add(feature.Id, feature); } } spatialFenceOverlay.Redraw(); // Synchronize the spatial fences from memory to database using (TrackingDataProvider vehicleProvider = ProviderFactory.CreateDataProvider()) { // Delete Spatial fences which is not in current spatial fence layer vehicleProvider.DeleteSpatialFencesExcluding(spatialFenceLayer.InternalFeatures); // Add or update the spatial fences that already exist foreach (Feature feature in spatialFenceLayer.InternalFeatures) { // Update Spatial fence by feature Id // if the affected data row number is 0, we will add it as a new row into the database int updatedCount = vehicleProvider.UpdateSpatialFenceByFeature(feature); if (updatedCount == 0) { vehicleProvider.InsertSpatialFence(feature); } } } ScriptManager.RegisterStartupScript(this, this.GetType(), "", "savedSuccessfully()", true); } catch { ScriptManager.RegisterStartupScript(this, this.GetType(), "", "savedFailed()", true); } finally { Map1.EditOverlay.Features.Clear(); Map1.EditOverlay.TrackMode = TrackMode.None; } } private bool CheckIsInSpatialFence(Vehicle vehicle) { LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["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<Feature> spatialFencesWithin = spatialFenceLayer.QueryTools.GetFeaturesContaining(pointShape, ReturningColumnsType.NoColumns); spatialFenceLayer.Close(); bool isInSpatialFence = false; if (spatialFencesWithin.Count > 0) { isInSpatialFence = true; } return isInSpatialFence; } private 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 // DateTime currentSampleTime; if (ViewState["ApplicationStartTime"] == null) { ViewState["ApplicationStartTime"] = DateTime.Now; currentSampleTime = adjustedStartTime; } else { double sampleSecondPerActualSecond = 12; double realSpentTime = TimeSpan.FromTicks(DateTime.Now.Ticks - ((DateTime)ViewState["ApplicationStartTime"]).Ticks).TotalSeconds; int sampleSpentTime = (int)(realSpentTime * sampleSecondPerActualSecond); currentSampleTime = adjustedStartTime.AddSeconds(sampleSpentTime); } return currentSampleTime; } private Collection<Feature> GetSpatialFences() { // Get the spatial fences from the database Collection<Feature> spatialFences = new Collection<Feature>(); using (TrackingDataProvider vehicleProvider = ProviderFactory.CreateDataProvider()) { spatialFences = vehicleProvider.GetSpatialFences(); } return spatialFences; } private void UpdateSpatialFencesAndVehicles() { // Update vehicle information on the Map // Read vehicles from database DateTime currentTime = GetAdjustedCurrentDateTime(); Dictionary<int, Vehicle> vehicles = GetVehicles(currentTime); // Display vehicle list rptVehicles.DataSource = vehicles.Values; rptVehicles.DataBind(); // Update vehicle information to Map UpdateVehiclesToOverlays(vehicles); // Redraw spatial fences on the map UpdateSpatialFencesToOverlay(); } private void UpdateSpatialFencesToOverlay() { InMemoryFeatureLayer spatialFenceLayer = null; if (!Map1.CustomOverlays.Contains("SpatialFenceOverlay")) { // Initialize SpatialFenceOverlay if it's not existed LayerOverlay spatialFenceOverlay = new LayerOverlay("SpatialFenceOverlay"); spatialFenceOverlay.TileType = TileType.SingleTile; spatialFenceOverlay.IsBaseOverlay = false; spatialFenceOverlay.IsVisibleInOverlaySwitcher = false; Map1.CustomOverlays.Add(spatialFenceOverlay); // Initialize SpatialFenceLayer. 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, DrawingFontStyles.Regular, GeoColor.StandardColors.Black, GeoColor.SimpleColors.White, 2); spatialFenceLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; spatialFenceOverlay.Layers.Add("SpatialFenceLayer", spatialFenceLayer); } else { LayerOverlay spatialFenceOverlay = Map1.CustomOverlays["SpatialFenceOverlay"] as LayerOverlay; spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; } spatialFenceLayer.InternalFeatures.Clear(); // Get the spatial fences from the database and insert fences from database into fence layer Collection<Feature> spatialFences = GetSpatialFences(); foreach (Feature spatialFence in spatialFences) { spatialFence.ColumnValues["Restricted"] = "Restricted"; spatialFenceLayer.InternalFeatures.Add(spatialFence); } } private Dictionary<int, Vehicle> GetVehicles(DateTime currentTime) { Dictionary<int, Vehicle> vehicles = new Dictionary<int, Vehicle>(); // Get all the vehicles from the database using (TrackingDataProvider vehicleProvider = ProviderFactory.CreateDataProvider()) { vehicles = vehicleProvider.GetCurrentVehicles(currentTime); } foreach (var vehicle in vehicles) { vehicle.Value.IsInFence = CheckIsInSpatialFence(vehicle.Value); } return vehicles; } private void UpdateVehiclesToOverlays(Dictionary<int, Vehicle> vehicles) { ManagedProj4Projection proj4 = new ManagedProj4Projection(); proj4.InternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString(); proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(4326); proj4.Open(); foreach (var currentVehicle in vehicles) { // Create an InMemoryMarkerOverlay for the vehicle to hold the points and current location InMemoryMarkerOverlay vehicleOverlay = null; if (Map1.CustomOverlays.Contains(currentVehicle.Value.VehicleName)) { vehicleOverlay = Map1.CustomOverlays[currentVehicle.Value.VehicleName] as InMemoryMarkerOverlay; } else { vehicleOverlay = new InMemoryMarkerOverlay(currentVehicle.Value.VehicleName); vehicleOverlay.Name = currentVehicle.Value.Id.ToString(CultureInfo.InvariantCulture); vehicleOverlay.ZoomLevelSet.ZoomLevel01.CustomMarkerStyle = GetCustomMarkerStyle(currentVehicle.Value.VehicleIconVirtualPath); vehicleOverlay.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; vehicleOverlay.IsVisibleInOverlaySwitcher = false; Map1.CustomOverlays.Add(vehicleOverlay); // Add all the required columns so we can populate later vehicleOverlay.FeatureSource.Open(); vehicleOverlay.Columns.Add(new FeatureSourceColumn("IsCurrentPosition")); vehicleOverlay.Columns.Add(new FeatureSourceColumn("Speed")); vehicleOverlay.Columns.Add(new FeatureSourceColumn("DateTime")); vehicleOverlay.Columns.Add(new FeatureSourceColumn("Longitude")); vehicleOverlay.Columns.Add(new FeatureSourceColumn("Latitude")); vehicleOverlay.Columns.Add(new FeatureSourceColumn("VehicleName")); vehicleOverlay.Columns.Add(new FeatureSourceColumn("Duration")); } // Clear old vehicle's old positions vehicleOverlay.FeatureSource.InternalFeatures.Clear(); // Add the vheicle's location histories foreach (Location historyLocation in currentVehicle.Value.HistoryLocations) { Feature breadcrumbFeature = new Feature(historyLocation.GetLocationPointShape().GetWellKnownBinary(), currentVehicle.Value.VehicleName + historyLocation.DateTime); breadcrumbFeature.ColumnValues["DateTime"] = historyLocation.DateTime.ToString(); breadcrumbFeature.ColumnValues["IsCurrentPosition"] = "IsNotCurrentPosition"; breadcrumbFeature.ColumnValues["Speed"] = historyLocation.Speed.ToString(CultureInfo.InvariantCulture); Vertex projectedVertex = GetProjectedVertext(proj4, historyLocation.Longitude, historyLocation.Latitude); breadcrumbFeature.ColumnValues["Longitude"] = projectedVertex.X.ToString(CultureInfo.InvariantCulture); breadcrumbFeature.ColumnValues["Latitude"] = projectedVertex.Y.ToString(CultureInfo.InvariantCulture); breadcrumbFeature.ColumnValues["VehicleName"] = currentVehicle.Value.VehicleName; breadcrumbFeature.ColumnValues["Duration"] = currentVehicle.Value.SpeedDuration.ToString(CultureInfo.InvariantCulture); vehicleOverlay.FeatureSource.InternalFeatures.Add(breadcrumbFeature.Id, breadcrumbFeature); } // Add the vehicle's latest position Feature latestPositionFeature = new Feature(currentVehicle.Value.Location.GetLocationPointShape().GetWellKnownBinary(), currentVehicle.Value.VehicleName); latestPositionFeature.ColumnValues["DateTime"] = currentVehicle.Value.Location.DateTime.ToString(); latestPositionFeature.ColumnValues["IsCurrentPosition"] = "IsCurrentPosition"; latestPositionFeature.ColumnValues["Speed"] = currentVehicle.Value.Location.Speed.ToString(CultureInfo.InvariantCulture); Vertex lastProjectedVertex = GetProjectedVertext(proj4, currentVehicle.Value.Longitude, currentVehicle.Value.Latitude); latestPositionFeature.ColumnValues["Longitude"] = lastProjectedVertex.X.ToString(CultureInfo.InvariantCulture); latestPositionFeature.ColumnValues["Latitude"] = lastProjectedVertex.Y.ToString(CultureInfo.InvariantCulture); latestPositionFeature.ColumnValues["VehicleName"] = currentVehicle.Value.VehicleName; latestPositionFeature.ColumnValues["Duration"] = currentVehicle.Value.SpeedDuration.ToString(CultureInfo.InvariantCulture); vehicleOverlay.FeatureSource.InternalFeatures.Add(latestPositionFeature.Id, latestPositionFeature); vehicleOverlay.FeatureSource.Close(); } } private Vertex GetProjectedVertext(ManagedProj4Projection proj4, double x, double y) { Vertex result = new Vertex(); Vertex projectedVertex = proj4.ConvertToExternalProjection(x, y); result.X = Math.Round(projectedVertex.X, 6); result.Y = Math.Round(projectedVertex.Y, 6); return result; } } }
var autoRefreshTimer; $(document).ready(function () { initializePageElements(); // auto-refresh button autoRefreshTimer = setInterval(autoRefreshUI, 1000); // attach toggle events to track buttons $("#divTrackMode input[type='image']").bind("click", function (e) { switch ($(this).attr("alt")) { case "Pan": $("#divTrackType").hide(); $("#divMeasure").hide(); Map1.SetDrawMode('Normal'); Map1.SetMeasureMode('Normal'); break; case "Draw": $("#divTrackType").show(); $("#divMeasure").hide(); Map1.SetMeasureMode('Normal'); break; case "Measure": $("#divTrackType").hide(); $("#divMeasure").show(); Map1.SetDrawMode('Normal'); break; default: break; } resetDefaultStatus(); return false; }); // Remove selected feature on client at first and then synchronize to server $("#ibtnDeleteSpatialFences").bind("click", function (e) { var parser = Map1.GetMapParser(); if (parser.editOverlay == null || parser.editOverlay.selectedFeatures.length == 0) { showDialog("divMessage", "Please choose a fence at first."); } else { showDialog("divRemoveDialog", "Are you sure you want to delete the spatial fence you have selected?"); } $(".ui-dialog-titlebar").hide(); // Hide dialog header bar return false; }); // Init dialog for tracking shapes $("#divRemoveDialog").dialog({ autoOpen: false, modal: true, buttons: { Yes: function () { var parser = Map1.GetMapParser(); // remove the selected features in client side. if (parser.editOverlay && parser.editOverlay.selectedFeatures.length > 0) { var selectedFeatures = []; for (var i = 0; i < parser.editOverlay.selectedFeatures.length; i++) { for (var j = 0; j < parser.editOverlay.features.length; j++) { if (parser.editOverlay.features[j].id == parser.editOverlay.selectedFeatures[i].id) { selectedFeatures.push(parser.editOverlay.features[j]); } } } if (parser.paintControls['Modify'].active) { parser.paintControls['Modify'].deactivate(); } parser.editOverlay.destroyFeatures(selectedFeatures); $(this).dialog("close"); // do a partial postback to save the edited/deleted shapes to server side $("#btnDeleteSpatialFence").trigger("click"); } }, No: function () { $(this).dialog("close"); } } }); }); var OnMapCreated = function (map) { map.events.register("mousemove", map, function (e) { var mouseCoordinate = this.getLonLatFromPixel(new OpenLayers.Pixel(e.clientX, e.clientY)); if (mouseCoordinate) { $("#spanMouseCoordinate").text("X:" + mouseCoordinate.lon.toFixed(2) + " Y: " + mouseCoordinate.lat.toFixed(2)); } }); // A workaround here to make sure the marker always have a higher zIndex than editOverlay var markerOverlays = MapHelper.getVehicleOverlays(); for (var i = 0; i < markerOverlays.length; i++) { markerOverlays[i].setZIndex(750 + i); // 750 is the default zIndex of popup } } var MapHelper = { getEditOverlay: function () { var editOverlay = Map1.GetOpenLayersMap().getLayersByName("EditOverlay"); if (editOverlay.length == 0) { Map1.GetMapParser().initDrawControls(); } return Map1.GetOpenLayersMap().getLayersByName("EditOverlay")[0]; }, getAdormentOverlay: function () { var adornmentOverlay = Map1.GetOpenLayersMap().getLayersByName("AdornmentOverlay"); return adornmentOverlay[0]; }, getVehicleOverlays: function () { var map = Map1.GetOpenLayersMap(); return Map1.GetOpenLayersMap().getLayersByClass("OpenLayers.Layer.Markers"); } } function zoomInToVehicle(lon, lat) { Map1.GetOpenLayersMap().moveTo(new OpenLayers.LonLat(lon, lat), 16); return false; } function changeAutoRefreshButton(element) { // attach animation to auto-refresh button if ($(element).attr("src") == "Images/autorefresh.png") { autoRefreshTimer = setInterval(autoRefreshUI, 1000); } else { $("#ibtnAutoRefreshButton").attr("src", "Images/autorefresh.png") clearInterval(autoRefreshTimer); autoRefreshTimer = null; } } function autoRefreshUI() { if ($("#ibtnAutoRefreshButton").attr("src") == "Images/AutoRefresh_2.png") { $("#ibtnAutoRefreshButton").attr("src", "Images/AutoRefresh_1.png") } else { $("#ibtnAutoRefreshButton").attr("src", "Images/AutoRefresh_2.png") } }; function initializePageElements() { // apply toggle button effect to a group buttons var applyToggleEffectToButtons = function (containerId) { var btnImgs = $(containerId).find("input[type='image']"); for (var i = 0; i < btnImgs.length; i++) { $(btnImgs[i]).bind("click", function () { var btnImgs = $(containerId).find("input[type='image']"); for (var i = 0; i < btnImgs.length; i++) { $(btnImgs[i]).attr("class", "imgButton"); } $(this).attr("class", "active imgButton"); }) }; }; applyToggleEffectToButtons("#divTrackMode"); applyToggleEffectToButtons("#divTrackType"); applyToggleEffectToButtons("#divMeasure"); // apply highlighted effect to buttons when mouse-over var highlightImg = function (imgContainerIds) { for (var i = 0; i < imgContainerIds.length; i++) { var btnImgs = $(imgContainerIds[i]).find("input[type='image']"); for (var j = 0; j < btnImgs.length; j++) { $(btnImgs[j]).bind("mouseover", function () { $(this).css("opacity", "0.4"); }); $(btnImgs[j]).bind("mouseout", function () { $(this).css("opacity", "1"); }); } } } highlightImg(["#divRefresh",|"#divTrackMode", "#divTrackType", "#divMeasure"]); // hide track types button and measure type buttons $("#divTrackType").hide(); $("#divMeasure").hide(); // Implement collapse effect to toggle button $("#toggle img").bind("click", function () { if ($("#leftContainer").is(':visible')) { $(this).attr("src", "Images/expand.gif"); $("#map-content").css("width", "99%"); $("#toggle").css("left", "5px"); $("#leftContainer").hide(); } else { $("#leftContainer").show(); $(this).attr("src", "Images/collapse.gif"); $("#map-content").css("width", "80%"); $("#toggle").css("left", "20%"); } resizeElementHeight(); }); var resizeElementHeight = function () { var documentheight = $(window).height(); var contentDivH = documentheight - $("#footer").height() - $("#header").height() - 1; $("#content-container").height(contentDivH + "px"); $("#leftContainer").height(contentDivH + "px"); $("#map-content").height(contentDivH + "px"); $("#toggle").css("line-height", contentDivH + "px"); if (contentDivH > 300) { $("#divVehicleList").height(contentDivH - 300 + "px"); } else { $("#divVehicleList").visible = false; } // refresh the map. Map1.GetOpenLayersMap().updateSize(); } window.onload = resizeElementHeight(); $(window).resize(resizeElementHeight); $("#divMessage").dialog({ autoOpen: false, modal: true, buttons: { ok: function () { $(this).dialog("close"); } } }); } function savedSuccessfully() { showDialog("divMessage", "Saved Successfully."); } function savedFailed() { showDialog("divMessage","Saved Failed."); } function showDialog(id, html) { $("#" + id).html(html); $("#" + id).dialog("open"); $(".ui-dialog-titlebar").hide(); // Hide dialog header bar } function hideDialog(id) { $("#" + id).dialog("close"); } function resetDefaultStatus() { var btnImgs = $("#divTrackType").find("input[type='image']"); for (var i = 0; i < btnImgs.length; i++) { $(btnImgs[i]).attr("class", "imgButton"); } var btnImgs = $("#divMeasure").find("input[type='image']"); for (var i = 0; i < btnImgs.length; i++) { $(btnImgs[i]).attr("class", "imgButton"); } }
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Data.OleDb; using System.Globalization; using System.Text; using ThinkGeo.MapSuite.Core; 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<int, Vehicle> GetCurrentVehicles(DateTime currentTime) { Dictionary<int, Vehicle> vehiclesList = new Dictionary<int, Vehicle>(); 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<double> historySpeeds = new Collection<double>(); for (int rowIndex = 0; rowIndex < currentLocations.Tables[0].Rows.Count; rowIndex++) { DataRow dataRow = currentLocations.Tables[0].Rows[rowIndex]; currentVechicle.VehicleIconVirtualPath = "Images/" + 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<Feature> GetSpatialFences() { Collection<Feature> spatialFences = new Collection<Feature>(); 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(new Feature(wkt, id)); } return spatialFences; } public override void DeleteSpatialFences(IEnumerable<Feature> features) { StringBuilder deleteFeatureIds = new StringBuilder(); foreach (Feature deleteFeature in features) { deleteFeatureIds.AppendFormat(CultureInfo.InvariantCulture, "'{0}',", deleteFeature.Id); } string sql = String.Format(CultureInfo.InvariantCulture, "DELETE FROM SpatialFence WHERE (FeatureID IN ({0}))", deleteFeatureIds.ToString().TrimEnd(',')); ExecuteNonQuery(sql); } public override int UpdateSpatialFenceByFeature(Feature feature) { int updatedSpatialFenceCount = ExecuteNonQuery(String.Format(CultureInfo.InvariantCulture, "UPDATE SpatialFence SET FenceGeometry = '{0}' WHERE (FeatureID = '{1}')", feature.GetWellKnownText(), feature.Id)); return updatedSpatialFenceCount; } public override void InsertSpatialFence(Feature feature) { ExecuteNonQuery(String.Format(CultureInfo.InvariantCulture, "Insert into SpatialFence(FenceGeometry,FeatureID) values('{0}','{1}')", feature.GetWellKnownText(), feature.Id)); } 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; } } } } }
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using ThinkGeo.MapSuite.Core; namespace ThinkGeo.MapSuite.VehicleTracking { public abstract class TrackingDataProvider : IDisposable { public abstract Dictionary<int, Vehicle> GetCurrentVehicles(DateTime currentTime); public abstract Collection<Feature> GetSpatialFences(); public abstract void DeleteSpatialFences(IEnumerable<Feature> excludeFeatures); public abstract int UpdateSpatialFenceByFeature(Feature feature); public abstract void InsertSpatialFence(Feature feature); public abstract void Dispose(); } }
using System; using ThinkGeo.MapSuite.Core; namespace ThinkGeo.MapSuite.VehicleTracking { /// <summary> /// This class specify the basic information for a location. /// </summary> public class Location { public Location() : this(0, 0, 0, DateTime.Now) { } public Location(double longitude, double latitude, double speed, DateTime dateTime) { this.Longitude = longitude; this.Latitude = latitude; this.Speed = speed; this.DateTime = dateTime; } public double Longitude { get; set; } public double Latitude { get; set; } public double Speed { get; set; } public DateTime DateTime { get; set; } public PointShape GetLocationPointShape() { return new PointShape(Longitude, Latitude); } } }
using System.Collections.ObjectModel; namespace ThinkGeo.MapSuite.VehicleTracking { /// <summary> /// This class stands for a vehicle. /// </summary> public class Vehicle { private int id; private Location location; private string vehicleName; private string vehicleIconVirtualPath; private bool isInFence; private string motionStateIconVirtualPath; private Collection<Location> historyLocations; private Vehicle() : this(0) { } public Vehicle(int id) { this.Id = id; this.VehicleName = string.Empty; this.Location = new Location(); this.historyLocations = new Collection<Location>(); } public int Id { get { return id; } set { id = value; } } public Location Location { get { return location; } set { location = value; } } public Collection<Location> HistoryLocations { get { return historyLocations; } } public string VehicleName { get { return vehicleName; } set { vehicleName = value; } } public string VehicleIconVirtualPath { get { return vehicleIconVirtualPath; } set { vehicleIconVirtualPath = value; } } public bool IsInFence { get { return isInFence; } set { isInFence = value; } } public int SpeedDuration { get { int speedDuration = 0; double lastSpeed = Location.Speed; foreach (Location location in HistoryLocations) { if (location.Speed == lastSpeed) { speedDuration++; } else { break; } } return speedDuration; } } public string MotionStateIconVirtualPath { get { if (MotionState == VehicleMotionState.Idle) { motionStateIconVirtualPath = "Images/ball_gray.png"; } else { motionStateIconVirtualPath = "Images/ball_green.png"; } return motionStateIconVirtualPath; } } /// <summary> /// If the Vehicle's speed is not 0 in the passed 4 minutes, we say it is in Motion. /// </summary> /// <returns>State of current vehicle.</returns> public VehicleMotionState MotionState { get { VehicleMotionState vehicleState = VehicleMotionState.Idle; if (Location.Speed != 0) { vehicleState = VehicleMotionState.Motion; } else { int locationIndex = 0; foreach (Location historyLocation in HistoryLocations) { if (locationIndex > 3) { break; } else if (historyLocation.Speed != 0) { vehicleState = VehicleMotionState.Motion; break; } else { locationIndex++; } } } return vehicleState; } } } }
namespace ThinkGeo.MapSuite.VehicleTracking { /// <summary> /// This enumeration specifies the Possible states for Vehicles. /// </summary> public enum VehicleMotionState { Motion = 0, Idle = 1, } }
using System.Runtime.Serialization; namespace ThinkGeo.MapSuite.VehicleTracking { [DataContract] public class JsonFeature { private string id; private string wkt; public JsonFeature(string id, string wkt) { this.id = id; this.wkt = wkt; } [DataMember(Name|= "id")] public string Id { get { return id; } set { id = value; } } [DataMember(Name|= "wkt")] public string Wkt { get { return wkt; } set { wkt = value; } } } }