/// <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="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; }