/// <summary> /// A public constructor that creates an instance of the CellularFloor /// </summary> /// <param name="desiredCellSize">Desired cell size</param> /// <param name="barrierEnvironment">The parser of the BIM model</param> /// <param name="pointOnWalkableArea">A point on the walkable field which is expected to be on the walkable area</param> public CellularFloor(double desiredCellSize, BIM_To_OSM_Base barrierEnvironment, UV pointOnWalkableArea) : base(desiredCellSize, barrierEnvironment, pointOnWalkableArea) { this.UnitType = barrierEnvironment.UnitType; this.AllSpatialDataFields = new Dictionary <string, SpatialDataField>(); #region loading distances HashSet <Cell> edge = new HashSet <Cell>(); HashSet <Cell> temp_edge = new HashSet <Cell>(); #region loading the Distances from field barriers Dictionary <Cell, double> fieldBarrierDistance = new Dictionary <Cell, double>(); foreach (Cell cell in this.Cells) { double dist = double.PositiveInfinity; if (cell.FieldOverlapState != OverlapState.Inside) { dist = 0; } if (cell.FieldOverlapState == OverlapState.Overlap) { edge.Add(cell); } fieldBarrierDistance.Add(cell, dist); } while (edge.Count > 0) { foreach (Cell cell in edge) { nextEdgesOfCell_field(cell, fieldBarrierDistance, ref temp_edge); } edge.Clear(); edge.UnionWith(temp_edge); foreach (Cell cell in edge) { fieldBarrierDistance[cell] = this.loadDistancesAndIndices_field(cell, fieldBarrierDistance[cell]); } temp_edge.Clear(); } edge.Clear(); temp_edge.Clear(); #endregion #region loading the Distances from visual barriers Dictionary <Cell, double> visualBarrierDistance = new Dictionary <Cell, double>(); foreach (Cell cell in this.Cells) { double dist = double.PositiveInfinity; if (cell.VisualOverlapState != OverlapState.Outside) { dist = 0; } if (cell.VisualOverlapState == OverlapState.Overlap) { edge.Add(cell); } visualBarrierDistance.Add(cell, dist); } while (edge.Count != 0) { //finding the next edge foreach (Cell cell in edge) { nextEdgesOfCell_visual(cell, visualBarrierDistance, ref temp_edge); } edge.Clear(); edge.UnionWith(temp_edge); foreach (Cell cell in edge) { visualBarrierDistance[cell] = this.loadDistancesAndIndices_visual(cell, visualBarrierDistance[cell]); } temp_edge.Clear(); } edge.Clear(); temp_edge.Clear(); #endregion #region loading the Distances from physical barriers Dictionary <Cell, double> physicalBarrierDistance = new Dictionary <Cell, double>(); foreach (Cell cell in this.Cells) { double dist = double.PositiveInfinity; if (cell.PhysicalOverlapState != OverlapState.Outside) { dist = 0; } if (cell.PhysicalOverlapState == OverlapState.Overlap) { edge.Add(cell); } physicalBarrierDistance.Add(cell, dist); } while (edge.Count != 0) { //finding the next edge foreach (Cell cell in edge) { nextEdgesOfCell_physical(cell, physicalBarrierDistance, ref temp_edge); } edge.Clear(); edge.UnionWith(temp_edge); foreach (Cell cell in edge) { physicalBarrierDistance[cell] = this.loadDistancesAndIndices_physical(cell, physicalBarrierDistance[cell]); } temp_edge.Clear(); } edge.Clear(); temp_edge.Clear(); #endregion edge = null; temp_edge = null; foreach (Cell cell in this.Cells) { if (cell.FieldOverlapState == OverlapState.Outside) { fieldBarrierDistance.Remove(cell); visualBarrierDistance.Remove(cell); physicalBarrierDistance.Remove(cell); } } this.AddSpatialDataField(new SpatialDataField(CellularFloor.DistanceFromEdgesOfField, fieldBarrierDistance, true, true)); this.AddSpatialDataField(new SpatialDataField(CellularFloor.DistanceFromPhysicalBarriers, physicalBarrierDistance, true, false)); this.AddSpatialDataField(new SpatialDataField(CellularFloor.DistanceFromVisualBarriers, visualBarrierDistance, true, false)); #endregion }
/// <summary> /// Create the barrier buffer polygons around the edges of the walkable field using Minkowski addition /// </summary> /// <param name="barrierEnvironment"></param> /// <param name="offsetValue"></param> public void LoadAllBarriersOffseted(BIM_To_OSM_Base barrierEnvironment, double offsetValue) { //offetting all of the boundaries this.BarrierBuffers = barrierEnvironment.ExpandAllBarrierPolygons(offsetValue); // creating lines for the boundaries int edgeNum = 0; foreach (BarrierPolygon item in this.BarrierBuffers) { edgeNum += item.Length; } this.BarrierBufferEdges = new UVLine[edgeNum]; edgeNum = 0; foreach (BarrierPolygon brr in this.BarrierBuffers) { for (int i = 0; i < brr.Length; i++) { UVLine line = new UVLine(brr.PointAt(i), brr.PointAt(brr.NextIndex(i))); this.BarrierBufferEdges[edgeNum] = line; edgeNum++; } } // cleaning up the cells from previous settings foreach (Cell cell in this.Cells) { if (cell.BarrierBufferEdgeIndices == null) { cell.BarrierBufferEdgeIndices = new HashSet <int>(); } else { cell.BarrierBufferEdgeIndices.Clear(); } cell.BarrierBufferOverlapState = OverlapState.Outside; cell.BufferBarrierEndPoints = null; } // loading the lines into the cells for (int i = 0; i < this.BarrierBufferEdges.Length; i++) { Index[] intersectingCellIndices = this.FindLineIndices(this.BarrierBufferEdges[i]); foreach (Index item in intersectingCellIndices) { if (this.ContainsCell(item)) { this.Cells[item.I, item.J].BarrierBufferEdgeIndices.Add(i); } } } //loading edge end points into the cells foreach (BarrierPolygon polygon in this.BarrierBuffers) { foreach (UV point in polygon.BoundaryPoints) { Cell cell = this.FindCell(point); if (cell != null) { if (cell.BufferBarrierEndPoints == null) { cell.BufferBarrierEndPoints = new List <UV>(); } cell.BufferBarrierEndPoints.Add(point); } } } // setting the overlapping states of the cells that overlap foreach (Cell cell in this.Cells) { if (cell.BarrierBufferEdgeIndices.Count > 0) { cell.BarrierBufferOverlapState = OverlapState.Overlap; } } HashSet <Index> edge = new HashSet <Index>(); foreach (Cell item in this.Cells) { if (item.FieldOverlapState == OverlapState.Overlap) { var index = this.FindIndex(item); if (index.I == 0 || index.I == this.GridWidth - 1 || index.J == 0 || index.J == this.GridHeight - 1) { } else { edge.Add(index); } } } HashSet <Index> temp_edge = new HashSet <Index>(); HashSet <Index> area = new HashSet <Index>(); area.UnionWith(edge); while (edge.Count != 0) { foreach (var item in edge) { foreach (var neighbor in Index.Neighbors) { var next = item + neighbor; if (this.ContainsCell(next)) { if (!area.Contains(next)) { if (this.Cells[next.I, next.J].FieldOverlapState == OverlapState.Inside && this.Cells[next.I, next.J].BarrierBufferOverlapState != OverlapState.Overlap) { temp_edge.Add(next); } } } } } edge.Clear(); edge.UnionWith(temp_edge); area.UnionWith(temp_edge); temp_edge.Clear(); } foreach (Index item in area) { this.Cells[item.I, item.J].BarrierBufferOverlapState = OverlapState.Inside; } edge.Clear(); edge = null; temp_edge.Clear(); temp_edge = null; area.Clear(); area = null; for (int i = 0; i < this.GridWidth; i++) { for (int j = 0; j < this.GridHeight; j++) { if (this.Cells[i, j].FieldOverlapState != OverlapState.Inside) { if (this.Cells[i, j].BarrierBufferOverlapState != OverlapState.Overlap) { this.Cells[i, j].BarrierBufferOverlapState = OverlapState.Inside; } } } } }