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
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Globalization; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.MvcEdition; using ThinkGeo.MapSuite.VehicleTracking; namespace MapSuiteVehicleTracking.Controllers { public class DefaultController : Controller { private readonly DateTime adjustedStartTime = new DateTime(2009, 7, 10, 11, 31, 0); public ActionResult Index() { Map map = InitializeMap(); // Get current vehicles DateTime currentTime = GetAdjustedCurrentDateTime(); Dictionary<int, Vehicle> vehicles = GetVehicles(map, currentTime); // Update vehicle information to Map UpdateVehiclesToOverlays(map, vehicles); return View(map); } [MapActionFilter] public ActionResult DisplayVehicles(Map map, GeoCollection<object> args) { // Read vehicles from database DateTime currentTime = GetAdjustedCurrentDateTime(); Dictionary<int, Vehicle> vehicles = GetVehicles(map, currentTime); // Update vehicle information to Map UpdateVehiclesToOverlays(map, vehicles); return View(vehicles.Values.ToList()); } [MapActionFilter] public string EditFences(Map map, GeoCollection<object> args) { return Newtonsoft.Json.JsonConvert.SerializeObject(GetSpatialFencesInJsonFeature(map)); } [MapActionFilter] public string SaveFences(Map map, GeoCollection<object> args) { string result = string.Empty; Collection<JsonFeature> jsonFeatures = Newtonsoft.Json.JsonConvert.DeserializeObject<Collection<JsonFeature>>(args[0].ToString()); result = string.Empty + SaveSpatialFences(map, jsonFeatures); return result; } private Collection<JsonFeature> GetSpatialFencesInJsonFeature(Map Map1) { Collection<JsonFeature> jsonFeatures = new Collection<JsonFeature>(); LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; foreach (Feature feature in spatialFenceLayer.InternalFeatures) { // Add feature into editOverlay on server side to make sure it's synchronous on client and server side Map1.EditOverlay.Features.Add(feature); // Create feature on client side JsonFeature jsonFeature = new JsonFeature(feature.Id, feature.GetWellKnownText()); jsonFeatures.Add(jsonFeature); } return jsonFeatures; } private bool SaveSpatialFences(Map Map1, Collection<JsonFeature> features) { LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; try { spatialFenceLayer.Open(); Collection<Feature> newAddedFeatures = new Collection<Feature>(); foreach (JsonFeature jsonFeature in features) { if (string.IsNullOrEmpty(jsonFeature.Id)) { Feature feature = new Feature(jsonFeature.Wkt, Guid.NewGuid().ToString()); feature.ColumnValues["Restricted"] = "Restricted"; newAddedFeatures.Add(feature); } } if (features.Count != 0 && newAddedFeatures.Count == features.Count) // if all the features are requested features, means map is under draw polygon { // add new features to spatial fence layer foreach (Feature feature in newAddedFeatures) { spatialFenceLayer.InternalFeatures.Add(feature); } // Insert new feature into the database using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["AccessDataBase"])) { // Insert new added and modified features to database foreach (Feature feature in newAddedFeatures) { vehicleProvider.InsertSpatialFence(feature); } } } else // Deal with modify mode is activated scenario { Collection<Feature> modifiedFeatures = new Collection<Feature>(); Dictionary<string, JsonFeature> keyedJsonFeatures = new Dictionary<string, JsonFeature>(); foreach (JsonFeature jsonFeature in features) { if (!string.IsNullOrEmpty(jsonFeature.Id)) // If id is not null, it's the feature after editing { keyedJsonFeatures.Add(jsonFeature.Id, jsonFeature); Feature feature = new Feature(jsonFeature.Wkt, jsonFeature.Id); feature.ColumnValues["Restricted"] = "Restricted"; modifiedFeatures.Add(feature); } } // Get removed features Collection<Feature> removedFeatures = new Collection<Feature>(); foreach (Feature feature in Map1.EditOverlay.Features) { if (!keyedJsonFeatures.ContainsKey(feature.Id)) { removedFeatures.Add(feature); } } // Refine the spatial fence layer spatialFenceLayer.InternalFeatures.Clear(); foreach (Feature feature in newAddedFeatures) { spatialFenceLayer.InternalFeatures.Add(feature); } foreach (Feature feature in modifiedFeatures) { spatialFenceLayer.InternalFeatures.Add(feature); } Map1.EditOverlay.Features.Clear(); spatialFenceOverlay.Redraw(); // Update the database using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["AccessDataBase"])) { // Delete all spatial fences from database and then update the existing ones if (removedFeatures.Count > 0) { vehicleProvider.DeleteSpatialFences(removedFeatures); } // Insert new added and modified features to database foreach (Feature feature in newAddedFeatures) { vehicleProvider.InsertSpatialFence(feature); } foreach (Feature feature in modifiedFeatures) { vehicleProvider.UpdateSpatialFenceByFeature(feature); } } } return true; } catch { return false; } } private bool ChangeScaleBarUnit(Map Map1, UnitSystem unitSystem) { ScaleBarAdornmentLayer scaleBarAdormentLayer = Map1.AdornmentOverlay.Layers[0] as ScaleBarAdornmentLayer; scaleBarAdormentLayer.UnitFamily = unitSystem; return true; } 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 (Session["ApplicationStartTime"] == null) { Session["ApplicationStartTime"] = DateTime.Now; currentSampleTime = adjustedStartTime; } else { double sampleSecondPerActualSecond = 12; double realSpentTime = TimeSpan.FromTicks(DateTime.Now.Ticks - ((DateTime)Session["ApplicationStartTime"]).Ticks).TotalSeconds; int sampleSpentTime = (int)(realSpentTime * sampleSecondPerActualSecond); currentSampleTime = adjustedStartTime.AddSeconds(sampleSpentTime); } return currentSampleTime; } private bool CheckIsInSpatialFence(Map Map1, 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 isInFence = false; if (spatialFencesWithin.Count > 0) { isInFence = true; } return isInFence; } private Dictionary<int, Vehicle> GetVehicles(Map Map1, DateTime currentTime) { Dictionary<int, Vehicle> vehicles = new Dictionary<int, Vehicle>(); // If you want to use SQL server as database, please attach /App_Data/VehicleTrackingDb.mdf to // SQL Server and change the connection string in the web.config first; // Then use the the commended line of code below. // // using (TrackingSqlProvider vehicleProvider = new TrackingSqlProvider(ConfigurationManager.ConnectionStrings["VehicleTrackingDbConnectionString"].ConnectionString)) // // Get all the vehicles from the database using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(Server.MapPath(ConfigurationManager.AppSettings["AccessDataBase"]))) { vehicles = vehicleProvider.GetCurrentVehicles(currentTime); } foreach (var vehicle in vehicles) { vehicle.Value.IsInFence = CheckIsInSpatialFence(Map1, vehicle.Value); } return vehicles; } private Collection<Feature> GetSpatialFences() { // Get the spatial fences from the database Collection<Feature> spatialFences = new Collection<Feature>(); using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(Server.MapPath(ConfigurationManager.AppSettings["AccessDataBase"]))) { spatialFences = vehicleProvider.GetSpatialFences(); } return spatialFences; } private Map InitializeMap() { Map Map1 = new Map("Map1"); Map1.MapUnit = GeographyUnit.Meter; Map1.Width = new System.Web.UI.WebControls.Unit(100, System.Web.UI.WebControls.UnitType.Percentage); Map1.Height = new System.Web.UI.WebControls.Unit(100, System.Web.UI.WebControls.UnitType.Percentage); Map1.CurrentExtent = new RectangleShape(-10785241.6495495, 3916508.33762434, -10778744.5183967, 3912187.74540771); Map1.MapTools.MiniMap.Enabled = true; Map1.MapTools.OverlaySwitcher.Enabled = true; Map1.EditOverlay.EditSettings.IsResizable = false; // 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 AddSpatialFenceOverlay(Map1); // Add scale bar ScaleBarAdornmentLayer scaleBarAdormentLayer = new ScaleBarAdornmentLayer(); scaleBarAdormentLayer.XOffsetInPixel = 10; scaleBarAdormentLayer.UnitFamily = UnitSystem.Metric; Map1.AdornmentOverlay.Layers.Add(scaleBarAdormentLayer); return Map1; } private void AddSpatialFenceOverlay(Map Map1) { LayerOverlay spatialFenceOverlay = new LayerOverlay("SpatialFenceOverlay"); spatialFenceOverlay.TileType = TileType.SingleTile; spatialFenceOverlay.IsBaseOverlay = false; spatialFenceOverlay.IsVisibleInOverlaySwitcher = false; Map1.CustomOverlays.Add(spatialFenceOverlay); // Initialize SpatialFenceLayers. 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, DrawingFontStyles.Regular, GeoColor.StandardColors.Black, GeoColor.SimpleColors.White, 2); spatialFenceLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; spatialFenceOverlay.Layers.Add("SpatialFenceLayer", spatialFenceLayer); // 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 void UpdateVehiclesToOverlays(Map Map1, Dictionary<int, Vehicle> vehicles) { 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.ToString()); breadcrumbFeature.ColumnValues["DateTime"] = historyLocation.DateTime.ToString(); breadcrumbFeature.ColumnValues["IsCurrentPosition"] = "IsNotCurrentPosition"; breadcrumbFeature.ColumnValues["Speed"] = historyLocation.Speed.ToString(CultureInfo.InvariantCulture); Location projectedLocation = ProjectLocation(historyLocation); breadcrumbFeature.ColumnValues["Longitude"] = projectedLocation.Longitude.ToString("N6", CultureInfo.InvariantCulture); breadcrumbFeature.ColumnValues["Latitude"] = projectedLocation.Latitude.ToString("N6", 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); Location projectedCurrentLocation = ProjectLocation(currentVehicle.Value.Location); latestPositionFeature.ColumnValues["Longitude"] = projectedCurrentLocation.Longitude.ToString("N6", CultureInfo.InvariantCulture); latestPositionFeature.ColumnValues["Latitude"] = projectedCurrentLocation.Latitude.ToString("N6", 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 Location ProjectLocation(Location location) { Proj4Projection prj4 = new Proj4Projection(); prj4.InternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString(); prj4.ExternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326); prj4.Open(); PointShape projectedPoint = prj4.ConvertToExternalProjection(new PointShape(location.Longitude, location.Latitude)) as PointShape; location.Longitude = Math.Round(projectedPoint.X, 6); location.Latitude = Math.Round(projectedPoint.Y, 6); return location; } 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; } } }
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; } } } }
@using ThinkGeo.MapSuite.VehicleTracking @model IEnumerable<Vehicle> @{ Layout = null; } <table id="tbVehiclelist"> @foreach (Vehicle item in Model) { <tr> <td rowspan="5" class="vehicleImg"> <img id="imgVehicle" alt="@item.VehicleName" src='@item.VehicleIconVirtualPath' /> </td> <td colspan="2" class="vehicleName"> <a href="#" id="btnZoomTo">@item.VehicleName</a> <input type="hidden" id="lonlat" value='@item.Location.Longitude , @item.Location.Latitude' /> </td> </tr> <tr class="vehicleTxt"> <td colspan="2"> @{ if (item.MotionState == VehicleMotionState.Motion) { <img alt="ball" src='Images/ball_green.png' /> <span id="motionStatus" class="greenTxt">In Motion</span> } else { <img alt="ball" src='Images/ball_gray.png' /> <span id="motionStatus" class="greenTxt">Idle</span> } } </td> </tr> <tr class="vehicleTxt"> <td>Area: </td> <td id="isInFence"> @{ if (item.IsInFence) { <span class='redTxt'>In Restrict Area</span> } else { <span>Out Of Restrict Area</span> } } </td> </tr> <tr class="vehicleTxt"> <td>Speed: </td> <td> @item.Location.Speed.ToString(System.Globalization.CultureInfo.InvariantCulture) mph </td> </tr> <tr class="vehicleTxt"> <td>Duration: </td> <td> @item.SpeedDuration.ToString(System.Globalization.CultureInfo.InvariantCulture) min </td> </tr> <tr class="vehicleTxt"> <td colspan="3"> </td> </tr> } </table>
@using ThinkGeo.MapSuite.Core @using ThinkGeo.MapSuite.MvcEdition @using ThinkGeo.MapSuite.VehicleTracking @model ThinkGeo.MapSuite.MvcEdition.Map @{ ViewBag.Title = "Vehicle Tracking"; } <input type="hidden" value="false" id="iptIsMeasuring" /> <div id="container"> <div id="header"> <div id="left-header"> <span id="header-mapsuite">Map Suite</span> <span id="header-title">Vehicle Tracking Sample</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"> <img id="btnAutoRefresh" alt="Auto Refresh" src="Images/AutoRefresh.png" class="imgButton" /> <span class="title">Auto Refresh:</span> <span id="autoRefreshStatus" class="title redTxt">On</span> </div> <div class="divSettingItem"> <img id="btnRefresh" alt="Refresh Manually" src="Images/RefreshManually.png" class="imgButton" /> <span class="title">Refresh Manually</span> </div> </div> <h4>Interact with the map using these tools: </h4> <div id="divTrackMode" class="divBorder"> <img id="btnPan" command="Pan" src="Images/pan.png" class="active imgButton" /> <img id="btnDraw" command="Draw" src="Images/draw.png" class="imgButton" /> <img id="btnMeasure" command="Measure" src="Images/measure.png" class="imgButton" /> </div> <div id="divEditPanel" class="divSubBorder"> <img id="btnDrawPolygon" command="Polygon" class="active imgButton" src="~/Images/draw_polygon.png" /> <img id="btnEditPolygon" command="Edit" class="imgButton" src="~/Images/edit_polygon.png" /> <img id="btnRemovePolygon" command="RemovePolygon" class="imgButton" src="~/Images/Remove_Polygon.png" /> <img id="btnSave" command="Save" class="imgButton" src="~/Images/save.png" /> <img id="btnClearShapes" command="Clear" class="imgButton" src="~/Images/clear.png" /> </div> <div id="divMeasure" class="divSubBorder"> <img id="btnMeasureLength" command="Distance" class="active imgButton" src="~/Images/line.png" /> <img id="btnMeasureArea" command="Area" class="imgButton" src="~/Images/Polygon.png" /> <img id="btnClearMeasure" command="Cancel" class="imgButton" src="~/Images/clear.png" /> <span class="title">Measure Unit:</span> <select id="dropDownList"> <option>Metric</option> <option>Imperial</option> </select> </div> <div class="blueBanner"> Tracked Vehicles </div> <div class="divBorder" id="divVehicleList"> </div> </div> </div> <div id="toggle"> <img id="collapse" src="Images/collapse.gif" /> </div> <div id="map-content"> @{Html.ThinkGeo().Map(Model).Render();} </div> </div> <div id="footer"> <span id="coordinate"><span id="spanMouseCoordinate"></span></span> </div> </div> <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>