====== Source Code WebEdition ProjectTemplates AjaxVehicleTracking CS.zip ====== ====Default.aspx==== <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ThinkGeo.MapSuite.AjaxVehicleTracking.Default" %> <%@ Register Assembly="WebEdition" Namespace="ThinkGeo.MapSuite.WebEdition" TagPrefix="cc1" %> Ajax Vehicle Tracking

Click to refresh vehicles:

Auto Refresh Auto Refresh: On
Refresh Manually Refresh Manually

Interact with the map using these tools:

Pan Draw Measure
Draw Edit Remove Save Cancel
Distance Area Cancel Measure Unit:
Tracked Vehicles
Are you sure you want to delete the spatial fence you have selected?
Please choose a fence at first.
====Default.aspx.cs==== using System; using System.Linq; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Globalization; using System.Text; using System.Web.UI; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WebEdition; namespace ThinkGeo.MapSuite.AjaxVehicleTracking { public partial class Default : System.Web.UI.Page, ICallbackEventHandler { // 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); private string callbackResult; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { // Initialize Map InitializeMap(); // Read vehicles from database DateTime currentTime = GetAdjustedCurrentDateTime(); Collection vehicles = GetVehicles(currentTime); // Update vehicle information to Map UpdateVehiclesToOverlays(vehicles); // Register Callback references Page.ClientScript.GetCallbackEventReference(this, "", "", ""); } } public string GetCallbackResult() { return callbackResult; } public void RaiseCallbackEvent(string eventArgument) { CallbackRequest callbackRequest = JSONSerializer.Deserialize(eventArgument); switch (callbackRequest.Request) { case "editFences": callbackResult = JSONSerializer.Serialize(GetSpatialFencesInJsonFeature()); break; case "saveFences": callbackResult = SaveSpatialFences(callbackRequest.Features).ToString(); break; case "refreshVehicles": Collection vehicels = GetVehicles(GetAdjustedCurrentDateTime()); UpdateVehiclesToOverlays(vehicels); List jsonVehicels = vehicels.Select((t) => { return ConvertToJsonVehicle(t); }).ToList(); callbackResult = JSONSerializer.Serialize(jsonVehicels); break; default: break; } } private JsonVehicle ConvertToJsonVehicle(Vehicle vehicle) { Collection historyLocations = new Collection(); foreach (Location item in vehicle.HistoryLocations) { historyLocations.Add(new JsonLocation() { Latitude = item.Latitude, Longitude = item.Latitude, Speed = item.Speed, TrackTime = item.DateTime.ToString() }); } return new JsonVehicle() { Id = vehicle.Id + string.Empty, Name = vehicle.VehicleName, CurrentLocation = new JsonLocation(vehicle.Location.Longitude, vehicle.Location.Latitude, vehicle.Location.Speed, vehicle.Location.DateTime.ToString()), VehicleIconVirtualPath = vehicle.VehicleIconVirtualPath, VehicleMotionState = vehicle.MotionState == VehicleMotionState.Motion ? 1 : 0, HistoryLocations = historyLocations, IsInFence = CheckIsInSpatialFence(vehicle), }; } private Collection GetSpatialFencesInJsonFeature() { Collection jsonFeatures = new Collection(); 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 JsonFence jsonFeature = new JsonFence(feature.Id, feature.GetWellKnownText()); jsonFeatures.Add(jsonFeature); } return jsonFeatures; } private bool SaveSpatialFences(Collection features) { LayerOverlay spatialFenceOverlay = (LayerOverlay)Map1.CustomOverlays["SpatialFenceOverlay"]; InMemoryFeatureLayer spatialFenceLayer = (InMemoryFeatureLayer)spatialFenceOverlay.Layers["SpatialFenceLayer"]; try { spatialFenceLayer.Open(); Collection newAddedFeatures = new Collection(); foreach (JsonFence 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(MapPath(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 modifiedFeatures = new Collection(); Dictionary keyedJsonFeatures = new Dictionary(); foreach (JsonFence 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 removedFeatures = new Collection(); 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(MapPath(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 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 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 spatialFencesWithin = spatialFenceLayer.QueryTools.GetFeaturesContaining(pointShape, ReturningColumnsType.NoColumns); spatialFenceLayer.Close(); bool isInFence = false; if (spatialFencesWithin.Count > 0) { isInFence = true; } return isInFence; } private Collection GetVehicles(DateTime currentTime) { Collection vehicles = new Collection(); // 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.IsInFence = CheckIsInSpatialFence(vehicle); } return vehicles; } private Collection GetSpatialFences() { // Get the spatial fences from the database Collection spatialFences = new Collection(); using (TrackingAccessProvider vehicleProvider = new TrackingAccessProvider(MapPath(ConfigurationManager.AppSettings["AccessDataBase"]))) { spatialFences = vehicleProvider.GetSpatialFences(); } return spatialFences; } private void InitializeMap() { 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 AddSpatialFenceOverlay(); // Add scale bar ScaleBarAdornmentLayer scaleBarAdormentLayer = new ScaleBarAdornmentLayer(); scaleBarAdormentLayer.XOffsetInPixel = 10; scaleBarAdormentLayer.UnitFamily = UnitSystem.Metric; Map1.AdornmentOverlay.Layers.Add(scaleBarAdormentLayer); } private void AddSpatialFenceOverlay() { 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.DefaultTextStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping; 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 spatialFences = GetSpatialFences(); foreach (Feature spatialFence in spatialFences) { spatialFence.ColumnValues["Restricted"] = "Restricted"; spatialFenceLayer.InternalFeatures.Add(spatialFence); } } 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 void UpdateVehiclesToOverlays(Collection 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.VehicleName)) { vehicleOverlay = Map1.CustomOverlays[currentVehicle.VehicleName] as InMemoryMarkerOverlay; } else { vehicleOverlay = new InMemoryMarkerOverlay(currentVehicle.VehicleName); vehicleOverlay.Name = currentVehicle.Id.ToString(CultureInfo.InvariantCulture); vehicleOverlay.ZoomLevelSet.ZoomLevel01.CustomMarkerStyle = GetCustomMarkerStyle(currentVehicle.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.HistoryLocations) { Feature breadcrumbFeature = new Feature(historyLocation.GetLocationPointShape().GetWellKnownBinary(), currentVehicle.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.VehicleName; breadcrumbFeature.ColumnValues["Duration"] = currentVehicle.SpeedDuration.ToString(CultureInfo.InvariantCulture); vehicleOverlay.FeatureSource.InternalFeatures.Add(breadcrumbFeature.Id, breadcrumbFeature); } // Add the vehicle's latest position Feature latestPositionFeature = new Feature(currentVehicle.Location.GetLocationPointShape().GetWellKnownBinary(), currentVehicle.VehicleName); latestPositionFeature.ColumnValues["DateTime"] = currentVehicle.Location.DateTime.ToString(); latestPositionFeature.ColumnValues["IsCurrentPosition"] = "IsCurrentPosition"; latestPositionFeature.ColumnValues["Speed"] = currentVehicle.Location.Speed.ToString(CultureInfo.InvariantCulture); Location projectedCurrentLocation = ProjectLocation(currentVehicle.Location); latestPositionFeature.ColumnValues["Longitude"] = projectedCurrentLocation.Longitude.ToString("N6", CultureInfo.InvariantCulture); latestPositionFeature.ColumnValues["Latitude"] = projectedCurrentLocation.Latitude.ToString("N6", CultureInfo.InvariantCulture); latestPositionFeature.ColumnValues["VehicleName"] = currentVehicle.VehicleName; latestPositionFeature.ColumnValues["Duration"] = currentVehicle.SpeedDuration.ToString(CultureInfo.InvariantCulture); vehicleOverlay.FeatureSource.InternalFeatures.Add(latestPositionFeature.Id, latestPositionFeature); vehicleOverlay.FeatureSource.Close(); } } private static ValueMarkerStyle GetCustomMarkerStyle(string vehicleIconVirtualPath) { StringBuilder popupHtml = new StringBuilder(""); popupHtml.Append(""); popupHtml.Append(""); popupHtml.Append(""); popupHtml.Append(""); popupHtml.Append(""); popupHtml.Append(""); popupHtml.Append("
[#VehicleName#]
Longitude:[#Longitude#]
Latitude:[#Latitude#]
Speed:[#Speed#]
Time[#DateTime#]
"); 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; } } }
====ready-functions.js==== $(document).ready(function () { // Initialize the dom elements in the page initializePageElements(); // attach event to the buttons for track shapes attachEventsToTrackButtons(); // init vihecles in the first time. refreshVehicle(); // auto-refresh button var autoRefreshTimer = setInterval(autoRefresh, 1000); $('#btnAutoRefresh').on('click', function () { // attach animation to auto-refresh button if ($(this).attr("src") == "Images/AutoRefresh.png") { $("#autoRefreshStatus").text("On"); // let server start reading history autoRefreshTimer = setInterval(autoRefresh, 1000); } else if (autoRefreshTimer != null) { $("#autoRefreshStatus").text("Off"); $("#btnAutoRefresh").attr("src", "Images/AutoRefresh.png") clearInterval(autoRefreshTimer); autoRefreshTimer = null; } }); // Refresh manually $("#btnRefresh").bind("click", function (e) { refreshVehicle(); }); // zoom to vehicle $("#tbVehiclelist a").bind("click", function (e) { var lonlatVal = $(this).parent().find("#lonlat").val().split(','); if (lonlatVal.length >= 2) { var lonlat = new OpenLayers.LonLat(parseFloat(lonlatVal[0]), parseFloat(lonlatVal[1])); var map = Map1.GetOpenLayersMap(); map.zoomToScale(4513.988880); map.panTo(lonlat); } }) // Measure Buttons $("#divMeasure Img").bind("click", function (e) { Map1.SetDrawMode('Normal'); var command = $(this).attr("alt"); switch (command) { case "Distance": Map1.SetMeasureMode('PathMeasure'); break; case "Area": Map1.SetMeasureMode('PolygonMeasure'); break; case "Cancel": Map1.SetMeasureMode('Normal'); break; default: break; } }); $("#divMeasure Select").bind("change", function () { var displaySystem = $(this).val(); var measureTools = MapHelper.getMeasureTools(); for (var i = 0; i < measureTools.length; i++) { switch (displaySystem) { case "Metric": measureTools[i].displaySystem = "metric"; break; case "Imperial": measureTools[i].displaySystem = "english"; break; default: break; } } var args = { "request": CallbackTypes.changeDisplaySystem, "displaySystem": displaySystem }; $DoCallback(JSON.stringify(args), function (e, context) { MapHelper.getAdormentOverlay().redraw(true); }); }) }); function autoRefresh() { if ($("#btnAutoRefresh").attr("src") == "Images/AutoRefresh_2.png") { $("#btnAutoRefresh").attr("src", "Images/AutoRefresh_1.png") } else { $("#btnAutoRefresh").attr("src", "Images/AutoRefresh_2.png") } // refresh vechiles refreshVehicle(); }; function refreshVehicle() { var args = { "request": CallbackTypes.refreshVihecle }; $DoCallback(JSON.stringify(args), function (e, context) { var jsonVihecles = JSON.parse(e); // refresh vihecle panel. $("#divVehicleList").empty(); $("#divVehicleList").html(new vehiclesPanel(jsonVihecles).generateTable()); // refresh vihecle marker layers. var vehicleOverlays = MapHelper.getVehicleOverlays(); for (var i = 0; i < vehicleOverlays.length; i++) { vehicleOverlays[i].redraw(true); } // zoom to vehicle $("#divVehicleList a").bind("click", function (e) { var lonlatVal = $(this).parent().find("#lonlat").val().split(','); if (lonlatVal.length >= 2) { var lonlat = new OpenLayers.LonLat(parseFloat(lonlatVal[0]), parseFloat(lonlatVal[1])); Map1.GetOpenLayersMap().zoomToScale(4513.988880); Map1.GetOpenLayersMap().panTo(lonlat); } }) }); } 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]; }, getFenceOverlay: function () { var map = Map1.GetOpenLayersMap(); return map.getLayer("SpatialFenceOverlay"); }, getMeasureTools: function () { var map = Map1.GetOpenLayersMap(); return map.getControlsByClass("OpenLayers.Control.Measure"); }, 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 attachEventsToTrackButtons() { // Process track mode buttons $("#divTrackType Img").bind("click", function (e) { var command = $(this).attr("alt"); switch (command) { case "Draw": // Back to draw polygon mode and cacel edit geometries Map1.SetDrawMode('Polygon'); // clear all editing fences if it's in editing mode before var fenceOverlay = MapHelper.getFenceOverlay(); if (!fenceOverlay.getVisibility()) { var editOverlay = MapHelper.getEditOverlay(); editOverlay.destroyFeatures(editOverlay.features); fenceOverlay.setVisibility(true); } break; case "Edit": Map1.SetDrawMode('Modify'); if (MapHelper.getFenceOverlay().getVisibility() || MapHelper.getEditOverlay().features.length <= 0) { editFences(); } break; case "Remove": var parser = Map1.GetMapParser(); if (parser.editOverlay == null || parser.editOverlay.selectedFeatures.length == 0) { // Show no fence selected dialog $("#divMessage").dialog("open"); } else { $("#divRemoveDialog").dialog("open"); } $(".ui-dialog-titlebar").hide(); // Hide dialog header bar break; case "Save": if (!MapHelper.getFenceOverlay().getVisibility() || MapHelper.getEditOverlay().features.length > 0) { saveFences(); } break; case "Cancel": $("#btnDrawPolygon").trigger("click"); break; default: break; } }) // Functions related map var editFences = function () { var args = { "request": CallbackTypes.editFences }; $DoCallback(JSON.stringify(args), function (e, context) { if (e) { var jsonFeatures = $.parseJSON(e); var editingFeatures = new Array(); for (var i = 0; i < jsonFeatures.length; i++) { var spatialFence = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(jsonFeatures[i].wkt)); spatialFence.fid = jsonFeatures[i].id; editingFeatures.push(spatialFence); } MapHelper.getEditOverlay().addFeatures(editingFeatures); MapHelper.getFenceOverlay().setVisibility(false); } }, this) } var saveFences = function () { var editOverlay = MapHelper.getEditOverlay(); var features = new Array(); for (var i = 0; i < editOverlay.features.length; i++) { var geometry = editOverlay.features[i].geometry; if (geometry.CLASS_NAME != "OpenLayers.Geometry.Point") { var feature = { id: editOverlay.features[i].fid, wkt: geometry.toString() }; features.push(feature); } } var args = { "trackMode": $("#mapTrackMode").val(), "request": CallbackTypes.saveFences, "features": features }; $DoCallback(JSON.stringify(args), function (e, context) { if (e == "True") { var editOverlay = MapHelper.getEditOverlay(); editOverlay.destroyFeatures(editOverlay.features); var fenceOverlay = MapHelper.getFenceOverlay(); fenceOverlay.setVisibility(true); fenceOverlay.redraw(true); $("#btnDrawPolygon").trigger("click"); } else { $("#divMessage").html("Failed to save the edit spatial fences."); $("#divMessage").dialog("open"); } }, this) } // Init dialog for tracking shapes $("#divRemoveDialog").dialog({ autoOpen: false, modal: true, buttons: { Yes: function () { var parser = Map1.GetMapParser(); 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.removeFeatures(selectedFeatures); // Synchronize the edited features to server side saveFences(); $(this).dialog("close"); } }, No: function () { // back to previous status if (MapHelper.getFenceOverlay().getVisibility()) { // Back to draw edit mode $("#btnDrawPolygon").trigger("click"); } else { // Back to draw polygon mode $("#btnEditPolygon").trigger("click"); } $(this).dialog("close"); } } }); $("#divMessage").dialog({ autoOpen: false, modal: true, buttons: { ok: function () { // back to previous status if (MapHelper.getFenceOverlay().getVisibility()) { // Back to draw edit mode $("#btnDrawPolygon").trigger("click"); } else { // Back to draw polygon mode $("#btnEditPolygon").trigger("click"); } $(this).dialog("close"); } } }); } function initializePageElements() { // Resize map after browser if resized var resizeElementHeight = function resizeElementHeight() { 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); // set the toggle style for group buttons var resetToggleButtons = function (containerId) { var btnImgs = $(containerId).find("img"); for (var i = 0; i < btnImgs.length; i++) { $(btnImgs[i]).bind("click", function () { var btnImgs = $(containerId).find("img"); for (var i = 0; i < btnImgs.length; i++) { $(btnImgs[i]).attr("class", "imgButton"); } $(this).attr("class", "active imgButton"); }) }; }; resetToggleButtons("#divTrackMode"); resetToggleButtons("#divTrackType"); resetToggleButtons("#divMeasure"); // highlight all img buttons when mouse-over var highlightImg = function (imgContainerIds) { for (var i = 0; i < imgContainerIds.length; i++) { var btnImgs = $(imgContainerIds[i]).find("img"); 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"]); // attach toggle events to track buttons $("#divTrackMode img").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.SetDrawMode('Polygon'); Map1.SetMeasureMode('Normal'); break; case "Measure": $("#divTrackType").hide(); $("#divMeasure").show(); Map1.SetDrawMode('Normal'); Map1.SetMeasureMode('PathMeasure'); break; default: break; } }) // hide track types button and measure type buttons $("#divTrackType").hide(); $("#divMeasure").hide(); // Bind toggle button events $("#toggle").bind("click", function () { if ($("#leftContainer").is(':visible')) { $("#collapse").attr("src", "Images/expand.gif"); $("#map-content").css("width", "99%"); $("#toggle").css("left", "5px"); $("#leftContainer").hide(); } else { $("#leftContainer").show(); $("#collapse").attr("src", "Images/collapse.gif"); $("#map-content").css("width", "80%"); $("#toggle").css("left", "20%"); } resizeElementHeight(); }); } var CallbackTypes = { editFences: "editFences", saveFences: "saveFences", refreshVihecle: "refreshVehicles" }; function $DoCallback(arg, callbackEvent, context) { WebForm_DoCallback("__Page", arg, callbackEvent, context, null, false); } ====VehiclesPanelHelper.js==== var vehiclesPanel = function (vehiclesJson) { return { generateTable: function () { var table = $("
"); for (var i = 0; i < vehiclesJson.length; i++) { var currentVehicle = vehiclesJson[i]; var tr1 = $(""); var tr1Content = $('' + currentVehicle.name + '' + '' + currentVehicle.name + ''); tr1Content.appendTo(tr1); var tr2 = $(''); var motionStatusImg = currentVehicle.motion == 1?"Images/ball_green.png":"Images/ball_gray.png"; var motionLabel = currentVehicle.motion == 1 ? "In Motion" : "Idle"; var tr2Content = $(' ball' + motionLabel + ''); tr2Content.appendTo(tr2); var tr3 = $(''); var isInFenceLabel = currentVehicle.isIn ? "In Restrict Area" : "Out Of Restrict Area" var tr3Content = $('Area:' + isInFenceLabel + ''); tr3Content.appendTo(tr3); var tr4 = $(''); var tr4Content = $('Speed:' + currentVehicle.loc.s + ' mph'); tr4Content.appendTo(tr4); var tr5 = $(''); var tr5Content = $('Duration:' + currentVehicle.dur + ' min'); tr5Content.appendTo(tr5); var tr6 = $(''); var tr6Content = $(' '); tr6Content.appendTo(tr6); tr1.appendTo(table); tr2.appendTo(table); tr3.appendTo(table); tr4.appendTo(table); tr5.appendTo(table); tr6.appendTo(table); } return table.html(); } } }
====TrackingAccessProvider.cs==== 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 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 = "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 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(new Feature(wkt, id)); } return spatialFences; } public override void DeleteSpatialFences(IEnumerable 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; } } } } } ====TrackingDataProvider.cs==== 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 GetCurrentVehicles(DateTime currentTime); public abstract Collection GetSpatialFences(); public abstract void DeleteSpatialFences(IEnumerable excludeFeatures); public abstract int UpdateSpatialFenceByFeature(Feature feature); public abstract void InsertSpatialFence(Feature feature); public abstract void Dispose(); } } ====Location.cs==== using System; using ThinkGeo.MapSuite.Core; namespace ThinkGeo.MapSuite.VehicleTracking { /// /// This class specify the basic information for a location. /// 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); } } } ====Vehicle.cs==== using System.Collections.ObjectModel; namespace ThinkGeo.MapSuite.VehicleTracking { /// /// This class stands for a vehicle. /// public class Vehicle { private int id; private Location location; private string vehicleName; private string vehicleIconVirtualPath; private bool isInFence; private string motionStateIconVirtualPath; private Collection historyLocations; private Vehicle() : this(0) { } public Vehicle(int id) { this.Id = id; this.VehicleName = string.Empty; this.Location = new Location(); this.historyLocations = new Collection(); } public int Id { get { return id; } set { id = value; } } public Location Location { get { return location; } set { location = value; } } public Collection 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; } } /// /// 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 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; } } } } ====VehicleMotionState.cs==== namespace ThinkGeo.MapSuite.VehicleTracking { /// /// This enumeration specifies the Possible states for Vehicles. /// public enum VehicleMotionState { Motion = 0, Idle = 1, } } ====JsonFeature.cs==== 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; } } } }