Skip to content

Commit

Permalink
fix: use a buffer to calculate if building overlaps
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneD authored and jvandaal committed May 30, 2024
1 parent bedf34f commit bf96a0e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
using Building;
using Infrastructure;
using Microsoft.EntityFrameworkCore;
using NetTopologySuite.Geometries;
using NetTopologySuite.Operation.Buffer;

public class BuildingGeometryContext : DbContext, IBuildingGeometries
{
public DbSet<BuildingGeometryData> BuildingGeometries => Set<BuildingGeometryData>();
private const double AllowedOverlapPercentage = 0.05;

public DbSet<BuildingGeometryData> BuildingGeometries => Set<BuildingGeometryData>();
public BuildingGeometryContext() { }

// This needs to be DbContextOptions<T> for Autofac!
Expand Down Expand Up @@ -63,10 +66,37 @@ public ICollection<BuildingGeometryData> GetOverlappingBuildings(
&& !building.IsRemoved
&& boundingBox.Intersects(building.SysGeometry))
.ToList()
.Where(building => geometry.Intersects(building.SysGeometry))
.Where(building => HasTooMuchOverlap(geometry, building.SysGeometry))
.ToList();

return overlappingBuildings;
}

private static bool HasTooMuchOverlap(Geometry newBuildingGeometry, Geometry? existingBuildingGeometry)
{
if (existingBuildingGeometry is null)
{
return false;
}

try
{
var overlapArea = newBuildingGeometry.Intersection(existingBuildingGeometry).Area;
var newBuildingGeometryOverlapPercentage = overlapArea / newBuildingGeometry.Area;
var existingBuildingGeometryOverlapPercentage = overlapArea / existingBuildingGeometry.Area;

return newBuildingGeometryOverlapPercentage > AllowedOverlapPercentage
|| existingBuildingGeometryOverlapPercentage > AllowedOverlapPercentage;
}
catch (TopologyException topologyException)
{
// Consider buildings that Intersect, but fail with "found non-noded intersection" on calculating, to have an overlap value of 0
if (topologyException.Message.Contains("found non-noded intersection", StringComparison.InvariantCultureIgnoreCase))
return false;

// any other TopologyException should be treated normally
throw;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,29 @@ public void WithBuildingOverlappingGeometryAndIdenticalId_ShouldReturnNothing()
result.Should().BeEmpty();
}

[Fact]
public void WithOverlappingBuilding_ShouldReturnNothing()
{
var polygon1 = CreateGeometry("150515.51954216015 193984.87173669986 150514.00391716015 193976.65298669986 150510.30950881125 193977.33427493152 150509.72481561470 193974.16367058750 150500.24419151392 193975.91199860617 150501.16168397170 193980.88726698520 150506.17659092674 193979.96246475200 150507.35941666557 193986.37655071693 150515.51954216015 193984.87173669986");
var polygon2 = CreateGeometry("150527.43725961447 193983.04583268613 150515.52737160772 193984.85690468922 150513.92218761146 193976.26362468302 150513.68020360917 193974.55764068291 150519.21812361479 193973.77197667956 150518.91988360882 193971.80333667994 150522.89082761109 193971.20173668116 150526.00993161649 193973.88960868120 150527.43725961447 193983.04583268613");

_buildingGeometryContext.BuildingGeometries
.Add(new BuildingGeometryData(
2,
BuildingStatus.Realized,
BuildingGeometryMethod.MeasuredByGrb,
polygon2,
false));

_buildingGeometryContext.SaveChanges();

var result = _buildingGeometryContext.GetOverlappingBuildings(
new BuildingPersistentLocalId(1),
ExtendedWkbGeometry.CreateEWkb(polygon1.AsBinary())!);

result.Should().BeEmpty();
}

private static Geometry CreateGeometry(string coordinates)
=> GmlHelpers.CreateGmlReader().Read(
"<gml:Polygon srsName=\"https://www.opengis.net/def/crs/EPSG/0/31370\" xmlns:gml=\"http://www.opengis.net/gml/3.2\">" +
Expand Down

0 comments on commit bf96a0e

Please sign in to comment.