/// <summary> /// Computes the isovist at the specified depth of view. /// </summary> /// <param name="depth">The depth of view.</param> /// <param name="typeOfBarrier">The type of barrier.</param> /// <param name="cellularFloor">The cellularFloor.</param> /// <param name="Tolerance">The tolerance.</param> public void Compute(double depth, BarrierType typeOfBarrier, CellularFloor cellularFloor, double Tolerance = OSMDocument.AbsoluteTolerance) { var isovist = CellularIsovistCalculator.GetIsovist(this.VantageCell + new UV(cellularFloor.CellSize / 2, cellularFloor.CellSize / 2), depth, typeOfBarrier, cellularFloor, Tolerance); this.VisibleCells = isovist.VisibleCells; }
/// <summary> /// Initializes a new instance of the <see cref="DataDescriptionAndComparison"/> class. /// </summary> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="activity">The activity.</param> /// <param name="occupancyEvents">The occupancy events.</param> public DataDescriptionAndComparison(CellularFloor cellularFloor) { InitializeComponent(); this._cellularFloor = cellularFloor; this._dataList1.SelectionChanged += _dataList1_SelectionChanged; this._dataList2.SelectionChanged += _dataList2_SelectionChanged; this.Loaded += Window_Loaded; }
/// <summary> /// Applies the specified spatial data. /// </summary> /// <param name="spatialData">The spatial data.</param> /// <param name="cell">The cell.</param> /// <param name="filter">The filter.</param> /// <param name="neighborhood_range">The neighborhood range.</param> /// <param name="rayIndices">The ray indices.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <returns>System.Double.</returns> /// <exception cref="System.ArgumentOutOfRangeException"></exception> private static double Apply(ISpatialData spatialData, Cell cell, double[,] filter, int neighborhood_range, Dictionary <Index, Index[]> rayIndices, CellularFloor cellularFloor) { //the filtered value will be sum/w double sum = 0, w = 0; foreach (Index index in rayIndices.Keys) { //translating the index of the end of the ray var translatedIndex = index + cell.CellToIndex; //check to see if the translated index is valid in the cellular floor if (cellularFloor.ContainsCell(translatedIndex)) { //get the current cell at the end of the ray var currentCell = cellularFloor.Cells[translatedIndex.I, translatedIndex.J]; //ignore the entir ray if the cell does not belong to the original spatialData //this cell serves as a visual barrier if (spatialData.Data.ContainsKey(currentCell)) { //check for visibility along the ray bool isVisible = true; foreach (Index rayIndex in rayIndices[index]) { Index current = cell.CellToIndex + rayIndex; if (!cellularFloor.ContainsCell(current)) { throw new ArgumentOutOfRangeException(current.ToString()); } //if the current cell is not inside the field or it does not belong to the original spatial data // it is considered as a visual block if (cellularFloor.Cells[current.I, current.J].FieldOverlapState != OverlapState.Inside || !spatialData.Data.ContainsKey(cellularFloor.Cells[current.I, current.J])) { //Gaussian.failedRays++; isVisible = false; break; } } if (isVisible) { sum += filter[Math.Abs(index.I), Math.Abs(index.J)] * spatialData.Data[currentCell]; w += filter[Math.Abs(index.I), Math.Abs(index.J)]; } } } } if (sum != 0 && w != 0) { //apply filter on the cell itself sum += spatialData.Data[cell] * filter[0, 0]; w += filter[0, 0]; return(sum / w); } else { return(spatialData.Data[cell]); } }
/// <summary> /// Initializes a new instance of the <see cref="DataCell"/> class. /// </summary> /// <param name="cell">The cell.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="allFields">All fields.</param> public DataCell(Cell cell, CellularFloor cellularFloor, Dictionary <string, Activity> allFields) { InitializeComponent(); Brush light = new SolidColorBrush(Colors.LightGray) { Opacity = .6 }; this.CellInfo.Text = string.Format("X = {0}; Y = {1}", cell.U.ToString(), cell.V.ToString()); this.Loaded += DataCell_Loaded; this.SizeChanged += DataCell_SizeChanged; this.cellularDataNames = new TextBlock() { Text = "Data".ToUpper(), FontSize = 14, FontWeight = FontWeights.Bold, Foreground = new SolidColorBrush(Colors.Gray) }; this.dataNames.Items.Add(this.cellularDataNames); int x = 0; foreach (SpatialAnalysis.Data.Function item in cellularFloor.AllSpatialDataFields.Values) { var data = item as SpatialAnalysis.Data.SpatialDataField; if (data != null) { DataValue dataValue = new DataValue(data.Name, data.Data[cell]); x++; if (x % 2 == 1) { dataValue.Background = light; } this.dataNames.Items.Add(dataValue); } } if (allFields.Count != 0) { this.fieldNames = new TextBlock() { Text = "Avtivity".ToUpper(), FontSize = 14, FontWeight = FontWeights.Bold, Foreground = new SolidColorBrush(Colors.Gray) }; this.dataNames.Items.Add(fieldNames); x = 0; foreach (KeyValuePair <string, Activity> item in allFields) { DataValue dataValue = new DataValue(item.Key, item.Value.Potentials[cell]); x++; if (x % 2 == 1) { dataValue.Background = light; } this.dataNames.Items.Add(dataValue); } } }
/// <summary> /// Initializes a new instance of the <see cref="VisualEventSettings"/> class. /// </summary> /// <param name="_cellularFloor">The cellular floor.</param> public VisualEventSettings(CellularFloor _cellularFloor, bool useForDataGeneration) { InitializeComponent(); this.cellularFloor = _cellularFloor; this._useForDataGeneration = useForDataGeneration; if (!this.UseForDataGeneration) { this._valueGenerationMode.Visibility = System.Windows.Visibility.Collapsed; } else { _colorCodeMode.Visibility = System.Windows.Visibility.Collapsed; } }
/// <summary> /// Initializes a new instance of the <see cref="IsovistClippedGaussian"/> class. /// </summary> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="range">The range of interpolation.</param> /// <param name="tolerance">The tolerance.</param> public IsovistClippedGaussian(CellularFloor cellularFloor, int range, double tolerance = OSMDocument.AbsoluteTolerance) { this.Range = range; this._cellularFloor = cellularFloor; this.Tolerance = tolerance; double x = (this.Range + 1) * this._cellularFloor.CellSize; this._rangeLengthSquared = x * x; double lowerBound = UnitConversion.Convert(0.001d, Length_Unit_Types.FEET, this._cellularFloor.UnitType); double upperBound = UnitConversion.Convert(5.0d, Length_Unit_Types.FEET, this._cellularFloor.UnitType); this._sigma = MathNet.Numerics.RootFinding.RobustNewtonRaphson.FindRoot(this.gaussianPDF, differentialOfGaussianPDF, lowerBound, upperBound); //MessageBox.Show("Sigma: " + this.Sigma.ToString() + "\nValue: " + this.gaussianPDF(this.Sigma).ToString()); this.Filter = IsovistClippedGaussian.GaussianFilter(this.Range + 1, this._cellularFloor.CellSize, this.Sigma); this.RayIndices = IsovistClippedGaussian.LoadRayIndices(this.Range, this._cellularFloor, this.Tolerance); }
/// <summary> /// Gets the boundary polygon of the visibility area. /// </summary> /// <param name="cellularFloor">The cellularFloor.</param> /// <returns>List<BarrierPolygons>.</returns> public List <BarrierPolygon> GetBoundary(CellularFloor cellularFloor) { Dictionary <UVLine, int> guid = new Dictionary <UVLine, int>(); foreach (var item in this.VisibleCells) { var lines = cellularFloor.CellToLines(cellularFloor.FindCell(item)); foreach (var line in lines) { if (guid.ContainsKey(line)) { guid[line]++; } else { guid.Add(line, 1); } } } List <UVLine> boundaryLines = new List <UVLine>(); foreach (KeyValuePair <UVLine, int> item in guid) { if (item.Value == 1) { boundaryLines.Add(item.Key); } } guid.Clear(); guid = null; var plines = PLine.ExtractPLines(boundaryLines); List <BarrierPolygon> boundary = new List <BarrierPolygon>(); foreach (PLine item in plines) { var oneBoundary = item.Simplify(cellularFloor.CellSize / 10); if (oneBoundary != null) { boundary.Add(new BarrierPolygon(oneBoundary.ToArray())); } } boundaryLines.Clear(); boundaryLines = null; return(boundary); }
/// <summary> /// Initializes a new instance of the <see cref="DataImportInterface"/> class. /// </summary> /// <param name="inputData">The input data.</param> /// <param name="cellularFloor_">The cellular floor.</param> public DataImportInterface(string[] inputData, CellularFloor cellularFloor_) { InitializeComponent(); this.cellularFloor = cellularFloor_; this.importedData = inputData; this.Remove.Content = "<"; this.RemoveAll.Content = "<< All"; this.FieldsToID = new Dictionary <string, int>(); this.IDToFields = new Dictionary <int, string>(); this.Names = inputData[0].Split(','); for (int i = 0; i < this.Names.Length; i++) { this.FieldsToID.Add(this.Names[i], i); this.IDToFields.Add(i, this.Names[i]); this.fields_X.Items.Add(this.Names[i]); this.fields_Y.Items.Add(this.Names[i]); } this.SelectedIndices = new HashSet <int>(); this.X_Index = -1; this.Y_Index = -1; }
private double OverlappingArea(CellularFloor cellularFloor, Index cellIndex, Index inputIndex) { if (inputIndex.I < 0 || inputIndex.I >= this.number_X || inputIndex.J < 0 || inputIndex.J >= this.number_Y) { return(0); } if (this.DataPoints[inputIndex.I, inputIndex.J] == null) { return(0); } if (cellularFloor.FindCell(cellIndex).VisualOverlapState != OverlapState.Outside) { return(0); } double u1 = cellularFloor.Cells[cellIndex.I, cellIndex.J].U; double u2 = u1 + this._host.cellularFloor.CellSize; Interval interval_U = new Interval(u1, u2); double x1 = this.DataPoints[inputIndex.I, inputIndex.J].U; double x2 = x1 + this.dist_x; Interval interval_X = new Interval(x1, x2); var interval_A = interval_U.Overlap(interval_X); if (interval_A == null) { return(0); } double v1 = cellularFloor.Cells[cellIndex.I, cellIndex.J].V; double v2 = v1 + this._host.cellularFloor.CellSize; Interval interval_V = new Interval(v1, v2); double y1 = this.DataPoints[inputIndex.I, inputIndex.J].V; double y2 = y1 + this.dist_y; Interval interval_Y = new Interval(y1, y2); var interval_B = interval_V.Overlap(interval_Y); if (interval_B == null) { return(0); } return(interval_A.Length * interval_B.Length); }
private void setGeometry(CellularFloor cellularFloor) { UV up = new UV(0, cellularFloor.CellSize); UV right = new UV(cellularFloor.CellSize, 0); StreamGeometry sg = new StreamGeometry(); using (StreamGeometryContext sgc = sg.Open()) { UV start = null, end = null; sgc.BeginFigure(this.toPoint(cellularFloor.Cells[0, 0]), false, false); sgc.LineTo(this.toPoint(cellularFloor.Cells[0, cellularFloor.GridHeight - 1] + up), true, false); for (int i = 1; i < cellularFloor.GridWidth; i++) { start = cellularFloor.Cells[i, 0]; end = cellularFloor.Cells[i, cellularFloor.GridHeight - 1] + up; sgc.LineTo(this.toPoint(start), false, false); sgc.LineTo(this.toPoint(end), true, false); } start = start + right; end = end + right; sgc.LineTo(this.toPoint(start), false, false); sgc.LineTo(this.toPoint(end), true, false); for (int i = 0; i < cellularFloor.GridHeight; i++) { start = cellularFloor.Cells[0, i]; end = cellularFloor.Cells[cellularFloor.GridWidth - 1, i] + right; sgc.LineTo(this.toPoint(start), false, false); sgc.LineTo(this.toPoint(end), true, false); } start = start + up; end = end + up; sgc.LineTo(this.toPoint(start), false, false); sgc.LineTo(this.toPoint(end), true, false); } this.geometry = sg; }
//step 2 /// <summary> /// Computes the destinations in a parallel thread /// </summary> /// <param name="externalDepth">The external depth of view.</param> /// <param name="desiredNumber">The desired number of destinations to keep after simplification.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="staticCost">The static cost.</param> /// <param name="Tolerance">The tolerance.</param> public void ComputeDestinations(double externalDepth, int desiredNumber, CellularFloor cellularFloor, Dictionary <Cell, double> staticCost, double Tolerance = OSMDocument.AbsoluteTolerance) { AgentEscapeRoutes agentScapeRoutes = null; try { agentScapeRoutes = CellularIsovistCalculator.GetAgentEscapeRoutes(this.VantageCell, externalDepth, desiredNumber, cellularFloor, staticCost, Tolerance); } catch (Exception er) { this.Error = er.Report(); } if (agentScapeRoutes == null) { this._destinations = null; } else { this._destinations = agentScapeRoutes.Destinations; } }
/// <summary> /// Creates an instance of <c>Sequence</c> from its string representation. /// </summary> /// <param name="lines">The lines.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>Sequence.</returns> /// <exception cref="System.ArgumentException"> /// The name is invalid for a sequence! /// or /// The 'Activation Lambda Factor' is invalid for a sequence! /// or /// The sequence does not include any activities! /// </exception> public static Sequence FromStringRepresentation(List <string> lines, Length_Unit_Types unitType, CellularFloor cellularFloor, double tolerance = 0.0000001d) { if (string.IsNullOrWhiteSpace(lines[0]) || string.IsNullOrEmpty(lines[0])) { throw new ArgumentException("The name is invalid for a sequence!"); } double lambda = 0; if (!double.TryParse(lines[1], out lambda)) { throw new ArgumentException("The 'Activation Lambda Factor' is invalid for a sequence!"); } var activities = lines[2].Split(','); var purged = new List <string>(); foreach (var item in activities) { if (!(string.IsNullOrWhiteSpace(item) && string.IsNullOrEmpty(item))) { purged.Add(item); } } if (purged.Count == 0) { throw new ArgumentException("The sequence does not include any activities!"); } Sequence sequence = new Sequence(purged, lines[0].Trim(' '), lambda); if (lines.Count > 3) { var visualEvent = VisibilityTarget.FromString(lines, 3, unitType, cellularFloor, tolerance); sequence.AssignVisualEvent(visualEvent); } return(sequence); }
/// <summary> /// Creates an instance of the event from its string representation . /// </summary> /// <param name="lines">The lines.</param> /// <param name="start">The start.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>VisibilityEvaluationEvent.</returns> public static VisibilityTarget FromString(List <String> lines, int start, Length_Unit_Types unitType, CellularFloor cellularFloor, double tolerance = 0.0000001d) { List <SpatialAnalysis.Geometry.BarrierPolygon> barriers = new List <Geometry.BarrierPolygon>(); for (int i = start; i < lines.Count; i++) { var barrier = SpatialAnalysis.Geometry.BarrierPolygon.FromStringRepresentation(lines[i]); UnitConversion.Transform(barrier.BoundaryPoints, unitType, cellularFloor.UnitType); barriers.Add(barrier); } return(new VisibilityTarget(barriers, cellularFloor, tolerance)); }
/// <summary> /// Loads the ray indices. /// </summary> /// <param name="range">The range.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>Dictionary<Index, Index[]>.</returns> /// <exception cref="System.ArgumentException">The range of neighborhood should be smaller than the minimum of grid width and height: " + min.ToString()</exception> public static Dictionary <Index, Index[]> LoadRayIndices(int range, CellularFloor cellularFloor, double tolerance = .0000001) { int min = Math.Min(cellularFloor.GridHeight, cellularFloor.GridWidth); if (range >= min) { throw new ArgumentException("The range of neighborhood should be smaller than the minimum of grid width and height: " + min.ToString()); } int rangeSquared = range * range; Dictionary <Index, Index[]> rayIndices = new Dictionary <Index, Index[]>(); for (int i = 0; i <= range; i++) { for (int j = 0; j <= range; j++) { if (!(i == 0 && j == 0)) { //make sure we do not create rays where the gaussian distribution produces very low weighting factors if ((i * i + j * j) <= rangeSquared) { Index first = new Index(i, j); Index[] extractedndices = cellularFloor.FindLineIndices(cellularFloor.Cells[0, 0], cellularFloor.Cells[i, j], tolerance); Index[] firstIndices = new Index[extractedndices.Length + 1]; extractedndices.CopyTo(firstIndices, 0); firstIndices[extractedndices.Length] = first; rayIndices.Add(first, firstIndices); //i<0 and j>0 var second = new Index(-i, j); if (!rayIndices.ContainsKey(second)) { Index[] secondIndices = new Index[firstIndices.Length]; for (int k = 0; k < firstIndices.Length; k++) { secondIndices[k] = new Index(-firstIndices[k].I, firstIndices[k].J); } rayIndices.Add(second, secondIndices); } //i<0 and j<0 var third = new Index(-i, -j); if (!rayIndices.ContainsKey(third)) { Index[] thirdIndices = new Index[firstIndices.Length]; for (int k = 0; k < firstIndices.Length; k++) { thirdIndices[k] = new Index(-firstIndices[k].I, -firstIndices[k].J); } rayIndices.Add(third, thirdIndices); } //i<0 and j<0 var fourth = new Index(i, -j); if (!rayIndices.ContainsKey(fourth)) { Index[] fourthIndices = new Index[firstIndices.Length]; for (int k = 0; k < firstIndices.Length; k++) { fourthIndices[k] = new Index(firstIndices[k].I, -firstIndices[k].J); } rayIndices.Add(fourth, fourthIndices); } } } } } return(rayIndices); }
/// <summary> /// Gets the cell IDs at the edges of the visibility area. /// </summary> /// <param name="cellularFloor">The cellularFloor.</param> /// <returns>HashSet<System.Int32>.</returns> public HashSet <int> GetIsovistEdge(CellularFloor cellularFloor) { return(CellUtility.GetEdgeOfField(cellularFloor, this.VisibleCells)); }
/// <summary> /// Gets the filtered values. /// </summary> /// <param name="spatialData">The spatial data.</param> /// <param name="filter">The weighting factors of the filter.</param> /// <param name="rayIndices">The ray indices.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <returns>Dictionary<Cell, System.Double>.</returns> public static Dictionary <Cell, double> GetFilteredValues(ISpatialData spatialData, double[,] filter, Dictionary <Index, Index[]> rayIndices, CellularFloor cellularFloor) { Cell[] cells = new Cell[spatialData.Data.Count]; spatialData.Data.Keys.CopyTo(cells, 0); double[] values = new double[spatialData.Data.Count]; int neighborhood_range = filter.GetLength(0); Parallel.For(0, cells.Length, (I) => { values[I] = IsovistClippedGaussian.Apply(spatialData, cells[I], filter, neighborhood_range, rayIndices, cellularFloor); }); Dictionary <Cell, double> filtered = new Dictionary <Cell, double>(); for (int i = 0; i < cells.Length; i++) { filtered.Add(cells[i], values[i]); } return(filtered); }
/// <summary> /// Initializes a new instance of the <see cref="Activity"/> class. /// </summary> /// <param name="activityDestination">The activity destination.</param> /// <param name="cellularFloor">The cellular floor.</param> public Activity(ActivityDestination activityDestination, CellularFloor cellularFloor) : base(activityDestination) { this._cellularFloor = cellularFloor; var indices = this._cellularFloor.GetIndicesInsideBarrier(activityDestination.DestinationArea, .000001); }
/// <summary> /// Initializes a new instance of the <see cref="Activity"/> class. /// </summary> /// <param name="potentials">The potentials.</param> /// <param name="origins">The origins.</param> /// <param name="destinationArea">The destination area.</param> /// <param name="defaultState">The default state.</param> /// <param name="engagedActivityName">Name of the engaged activity.</param> /// <param name="cellularFloor">The cellular floor.</param> public Activity(Dictionary <Cell, double> potentials, HashSet <Cell> origins, BarrierPolygon destinationArea, StateBase defaultState, string engagedActivityName, CellularFloor cellularFloor) : base(engagedActivityName, origins, defaultState, destinationArea) { this.Potentials = potentials; this.EngagedActivityName = engagedActivityName; this._cellularFloor = cellularFloor; this._min = double.PositiveInfinity; this._max = double.NegativeInfinity; foreach (var item in this.Potentials.Values) { this._max = (this._max < item) ? item : this._max; this._min = (this._min > item) ? item : this._min; } this.Origins = new HashSet <Cell>(origins); this.DefaultState = defaultState.Copy(); //this._destinationArea = destinationArea; this.UseToCaptureEvent = true; }
/// <summary> /// creates an Activity Destination from its string representation /// </summary> /// <param name="lines">The lines.</param> /// <param name="startIndex">The start index.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>ActivityDestination.</returns> /// <exception cref="System.ArgumentException"> /// Activity does not include a name! /// or /// Failed to parse activity's engagement duration: " + lines[startIndex + 3] /// or /// Activity does not include cell origins! /// or /// Failed to set activity engagement duration! /// </exception> public static ActivityDestination FromString(List <string> lines, int startIndex, Length_Unit_Types unitType, CellularFloor cellularFloor, double tolerance = 0.0000001d) { string name = lines[startIndex]; if (string.IsNullOrEmpty(lines[startIndex]) || string.IsNullOrWhiteSpace(lines[startIndex])) { throw new ArgumentException("Activity does not include a name!"); } StateBase state = StateBase.FromStringRepresentation(lines[startIndex + 1]); BarrierPolygon barrier = BarrierPolygon.FromStringRepresentation(lines[startIndex + 2]); //unit converion UnitConversion.Transform(state.Location, unitType, cellularFloor.UnitType); UnitConversion.Transform(state.Velocity, unitType, cellularFloor.UnitType); UnitConversion.Transform(barrier.BoundaryPoints, unitType, cellularFloor.UnitType); var strings = lines[startIndex + 3].Split(','); double min = 0, max = 0; if (!double.TryParse(strings[0], out min) || !double.TryParse(strings[1], out max)) { throw new ArgumentException("Failed to parse activity's engagement duration: " + lines[startIndex + 3]); } HashSet <Cell> origins = new HashSet <Cell>(); var indices = cellularFloor.GetIndicesInsideBarrier(barrier, tolerance); if (indices.Count > 0) { foreach (var index in indices) { Cell cell = cellularFloor.FindCell(index); if (cell != null && cell.FieldOverlapState == OverlapState.Inside) { origins.Add(cell); } } } if (origins.Count == 0) { throw new ArgumentException("Activity does not include cell origins!"); } ActivityDestination dest = new ActivityDestination(name, origins, state, barrier); if (!dest.TrySetEngagementTime(min, max)) { throw new ArgumentException("Failed to set activity engagement duration!"); } return(dest); }
/// <summary> /// Initializes a new instance of the <see cref="VisibilityEvaluationEvent"/> class. /// </summary> /// <param name="visualTargets">The visual targets.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <param name="tolerance">The tolerance by default set to the main document's absolute tolerance value.</param> /// <exception cref="System.ArgumentException">Cannot generate 'Occupancy Visual Event' with no visibility target cells!</exception> public VisibilityTarget(ICollection <SpatialAnalysis.Geometry.BarrierPolygon> visualTargets, CellularFloor cellularFloor, double tolerance = OSMDocument.AbsoluteTolerance) { this.VisualTargets = visualTargets.ToArray(); HashSet <Index> allIndices = new HashSet <Index>(); foreach (SpatialAnalysis.Geometry.BarrierPolygon item in this.VisualTargets) { allIndices.UnionWith(cellularFloor.GetIndicesInsideBarrier(item, tolerance)); } var visibleCells = new HashSet <int>(); foreach (Index item in allIndices) { if (cellularFloor.ContainsCell(item) && cellularFloor.Cells[item.I, item.J].VisualOverlapState == OverlapState.Outside) { visibleCells.Add(cellularFloor.Cells[item.I, item.J].ID); } } allIndices.Clear(); allIndices = null; if (visibleCells.Count == 0) { throw new ArgumentException("Cannot generate 'Occupancy Visual Event' with no visibility target cells!"); } var cellsOnEdge = CellUtility.GetEdgeOfField(cellularFloor, visibleCells); List <Isovist> isovists = new List <Isovist>(cellsOnEdge.Count); double depth = cellularFloor.Origin.DistanceTo(cellularFloor.TopRight) + 1; foreach (int item in cellsOnEdge) { isovists.Add(new Isovist(cellularFloor.FindCell(item))); } Parallel.ForEach(isovists, (a) => { a.Compute(depth, BarrierType.Visual, cellularFloor, 0.0000001); }); HashSet <int> visibleArea = new HashSet <int>(); foreach (Isovist item in isovists) { visibleArea.UnionWith(item.VisibleCells); } this.AllVisibleCells = visibleArea; this.ReferencedVantageCells = new Dictionary <int, List <int> >(); var vantageCells = new List <int>(isovists.Count); foreach (var item in this.AllVisibleCells) { this.ReferencedVantageCells.Add(item, new List <int>()); } foreach (var isovist in isovists) { vantageCells.Add(isovist.VantageCell.ID); foreach (var cellID in isovist.VisibleCells) { this.ReferencedVantageCells[cellID].Add(isovist.VantageCell.ID); } } this.VantageCells = vantageCells; }
/// <summary> /// Applies filter on the specified spatial data. /// </summary> /// <param name="spatialData">The spatial data.</param> /// <param name="name">The name of the filtered data.</param> /// <param name="filter">The weighting factors of the filter.</param> /// <param name="rayIndices">The ray indices.</param> /// <param name="cellularFloor">The cellular floor.</param> /// <returns>ISpatialData.</returns> public static ISpatialData Apply(ISpatialData spatialData, string name, double[,] filter, Dictionary <Index, Index[]> rayIndices, CellularFloor cellularFloor) { int neighborhood_range = filter.GetLength(0); Dictionary <Cell, double> filtered = new Dictionary <Cell, double>(); foreach (Cell cell in spatialData.Data.Keys) { double value = IsovistClippedGaussian.Apply(spatialData, cell, filter, neighborhood_range, rayIndices, cellularFloor); filtered.Add(cell, value); } ISpatialData newData = null; switch (spatialData.Type) { case DataType.SpatialData: if (spatialData.GetType() == typeof(SpatialDataField)) { newData = new SpatialDataField(name, filtered); } else if (spatialData.GetType() == typeof(SimulationResult)) { SimulationResult simulationResult = (SimulationResult)spatialData; newData = new SimulationResult(name, filtered, simulationResult.TimeStep, simulationResult.SimulationDuration); } else if (spatialData.GetType() == typeof(MandatorySimulationResult)) { MandatorySimulationResult mandatorySimulationResult = (MandatorySimulationResult)spatialData; newData = new MandatorySimulationResult(name, filtered, mandatorySimulationResult.TimeStep, mandatorySimulationResult.SimulationDuration, mandatorySimulationResult.WalkedDistancePerHour, mandatorySimulationResult.TimeInMainStations, mandatorySimulationResult.WalkingTime, mandatorySimulationResult.ActivityEngagementTime, mandatorySimulationResult.SequencesWhichNeededVisualDetection, mandatorySimulationResult.AverageDelayChanceForVisualDetection, mandatorySimulationResult.MinimumDelayChanceForVisualDetection, mandatorySimulationResult.MaximumDelayChanceForVisualDetection); } break; case DataType.ActivityPotentialField: newData = new FieldUtility.Activity(filtered, ((Activity)spatialData).Origins, ((Activity)spatialData).DestinationArea, ((Activity)spatialData).DefaultState, name, cellularFloor); ((Activity)newData).TrySetEngagementTime(((Activity)spatialData).MinimumEngagementTime, ((Activity)spatialData).MaximumEngagementTime); break; case DataType.OccupancyEvent: if (spatialData.GetType() == typeof(MandatoryEvaluationEvent)) { MandatoryEvaluationEvent event_ = (MandatoryEvaluationEvent)spatialData; newData = new SpatialAnalysis.Events.MandatoryEvaluationEvent(name, filtered, event_.Likelihood, event_.TimeSamplingRate, event_.TimeStep, event_.Duration, event_.MaximumVelocityMagnitude, event_.VisibilityAngle, event_.HasCapturedVisualEvents, event_.HasCapturedDataEvents, event_.EventType, event_.CapturedEventTrails) { HasActivityEngagementEvent = event_.HasActivityEngagementEvent }; } else { EvaluationEvent event_ = (EvaluationEvent)spatialData; newData = new SpatialAnalysis.Events.EvaluationEvent(name, filtered, event_.Likelihood, event_.TimeSamplingRate, event_.TimeStep, event_.Duration, event_.MaximumVelocityMagnitude, event_.VisibilityAngle, event_.HasCapturedVisualEvents, event_.HasCapturedDataEvents, event_.EventType, event_.CapturedEventTrails); } break; } return(newData); }