public SelectionGeometryCache(IDirect2DFactory factory, PaintDotNet.Canvas.SelectionSnapshot selectionSnapshot)
 {
     this.factory           = factory;
     this.selectionSnapshot = selectionSnapshot;
     this.geometry          = LazyResult.New <IGeometry>(() => this.factory.CreateGeometry(selectionSnapshot.GeometryList.Value), LazyThreadSafetyMode.ExecutionAndPublication, new SingleUseCriticalSection());
     this.pixelatedGeometry = LazyResult.New <IGeometry>(() => GeometryHelpers.ToDirect2DGeometryDestructive(this.factory, ScansHelpers.ConvertNonOverlappingScansToPolygons(selectionSnapshot.PixelatedScans.Value), FillMode.Alternate, FigureBegin.Filled, FigureEnd.Closed), LazyThreadSafetyMode.ExecutionAndPublication, new SingleUseCriticalSection());
 }
Example #2
0
        private static void EnsureClockwiseWinding(List <int> indices, List <Vector3> vertices)
        {
            if (indices == null || indices.Count < 3)
            {
                return;
            }
            if (vertices == null || vertices.Count < 1)
            {
                return;
            }

            for (var i = 0; i < indices.Count; i += 3)
            {
                var vert0 = vertices[indices[i + 0]];
                var vert1 = vertices[indices[i + 1]];
                var vert2 = vertices[indices[i + 2]];

                if (!GeometryHelpers.IsCounterClockwiseXY(vert0, vert1, vert2))
                {
                    continue;
                }

                var temp = indices[i + 1];
                indices[i + 1] = indices[i + 2];
                indices[i + 2] = temp;
            }
        }
Example #3
0
        /// <summary>
        /// Pulled directly from Reflector disassembly
        /// </summary>
        private LineSegment[] CalculateSegments(IGeometryHost geometryHost, DiagramHitTestInfo hitTestInfo)
        {
            IBinaryLinkGeometryData data1       = geometryHost as IBinaryLinkGeometryData;
            EdgePointCollection     collection1 = data1.GeometryEdgePointsNoJumps;

            LineSegment[] segmentArray1 = new LineSegment[collection1.Count - 1];
            Pen           pen1          = geometryHost.GeometryStyleSet.GetPen(this.GetOutlinePenId(geometryHost));

            if (pen1 != null)
            {
                for (int num1 = 0; num1 < (collection1.Count - 1); num1++)
                {
                    RectangleD ed1 = GeometryHelpers.RectangleDFrom2Pts(collection1[num1].Point, collection1[num1 + 1].Point);
                    // In DSL Tools v8.2, GetHitTestTolerance is an instance method, but in DSL Tools v9.0, it is a static method.
                    // We call it without a qualifier here so that it will compile against both versions.
                    SizeD ed2 = GetHitTestTolerance(hitTestInfo);
                    if (ed1.Height < ed2.Height)
                    {
                        ed1.Inflate(0, (pen1.Width / 2f) + ed2.Height);
                    }
                    else if (ed1.Width < ed2.Width)
                    {
                        ed1.Inflate((pen1.Width / 2f) + ed2.Width, 0);
                    }
                    segmentArray1[num1] = new LineSegment(collection1[num1].Point, collection1[num1 + 1].Point, num1, num1 + 1, num1 == 0, (num1 + 1) == (collection1.Count - 1), ed1);
                }
            }
            return(segmentArray1);
        }
Example #4
0
        private IEnumerable <Polygon> GetBuildings()
        {
            if (Patch.Equals(_town.Market))
            {
                yield break;
            }

            var   block = GetCityBlock();
            float gridChaos, sizeChaos, minArea;
            Func <Polygon, float> emptyProbabilityFunc;

            GetBuildingSpecs(out gridChaos, out sizeChaos, out emptyProbabilityFunc, out minArea);

            foreach (var building in CreateAlleys(block, minArea, gridChaos, sizeChaos, emptyProbabilityFunc, true))
            {
                Vector2 e1, e2;
                float   len;
                building.GetLongestEdge(out e1, out e2, out len);

                var angle  = GeometryHelpers.Angle(e2 - e1);
                var bounds = building.Rotate(angle).GetBoundingBox();

                var hwRatio = bounds.Height / bounds.Width;
                var whRatio = bounds.Width / bounds.Height;

                if (hwRatio > NarrowBuilding && whRatio > NarrowBuilding)
                {
                    yield return(building);
                }
            }
        }
Example #5
0
        private void OptimizePatches()
        {
            var patchesToOptimize = Patches.Where(p => p.WithinCity).ToList();
            var shapesToClean     = new List <Polygon> ();

            foreach (var patch in patchesToOptimize)
            {
                for (var i = 0; i < patch.Shape.Vertices.Count; i++)
                {
                    var p0 = patch.Shape.Vertices[i];
                    var p1 = patch.Shape.Vertices[(i + 1) % patch.Shape.Vertices.Count];

                    if (p0 != p1 && (p0 - p1).magnitude < 8)
                    {
                        var shapesWithPoint = Patches.Where(p => p.Shape.Vertices.Contains(p1)).Select(p => p.Shape);

                        var newP0 = GeometryHelpers.Scale(p0 + p1, 0.5f);

                        foreach (var polygon in shapesWithPoint)
                        {
                            shapesToClean.Add(polygon);
                            polygon.ReplaceVertex(p1, newP0);
                        }
                    }
                }
            }

            foreach (var polygon in shapesToClean.Distinct())
            {
                var optimizedVertices = polygon.Vertices.Distinct().ToList();
                polygon.Vertices.Clear();
                polygon.Vertices.AddRange(optimizedVertices);
            }
        }
        public async Task <(IEnumerable <Violation> Violations, IEnumerable <Human> Humans)> Detect(Mat image)
        {
            return(await Task.Run(delegate
            {
                lock (detectorLockLink)
                {
                    var humans = new List <Human>();
                    var violations = new List <Violation>();
                    try
                    {
                        var items = detector.Detect(image);
                        foreach (var(Confidence, CenterX, CenterY, Width, Height) in items)
                        {
                            var human = new Human(CenterX - (Width / 2), CenterY - (Height / 2), Width, Height, image.Width, image.Height);

                            var pers = session.GridProjection.Perspective(human.BottomCenter);
                            if (pers.HasValue)
                            {
                                human.PerspectivePoint = pers.Value;
                                humans.Add(human);
                            }
                        }
                        foreach (var i in humans)
                        {
                            foreach (var j in humans)
                            {
                                if (i == j)
                                {
                                    continue;
                                }
                                if (violations.Any(v =>
                                                   (i.BottomCenter == v.Line.A && j.BottomCenter == v.Line.B) ||
                                                   (i.BottomCenter == v.Line.B && j.BottomCenter == v.Line.A) ||
                                                   (j.BottomCenter == v.Line.A && i.BottomCenter == v.Line.B) ||
                                                   (j.BottomCenter == v.Line.B && i.BottomCenter == v.Line.A)))
                                {
                                    continue;
                                }
                                if (session.GridProjection.IsProjectionReady)
                                {
                                    double dis = GeometryHelpers.GetDistance(i.PerspectivePoint, j.PerspectivePoint);
                                    if (dis < ViolationThreshold)
                                    {
                                        i.IsViolation = true;
                                        j.IsViolation = true;
                                        violations.Add(new Violation(new RelativeLine(i.BottomCenter, j.BottomCenter), dis));
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    return (violations, humans);
                }
            }));
        public async Task GetDirectionsViaPortal()
        {
            var portalUri = new Uri("https://www.arcgis.com/sharing/rest/");
            await WorldRouting.InitializeAsync(portalUri, username, password);

            var route = await WorldRouting.GetRouteAsync(GeometryHelpers.FromLatLong(34.2, -117.1), GeometryHelpers.FromLatLong(34.22, -117.14));

            Assert.IsNotNull(route);
        }
Example #8
0
        private void BuildRoads()
        {
            var topology = new Topology(this);

            var roads   = new List <List <Vector2> > ();
            var streets = new List <List <Vector2> > ();

            foreach (var gate in Gates.ToList())
            {
                var endPoint = Market.Shape.Vertices.OrderBy(v => (gate - v).magnitude).First();

                var street = topology.BuildPath(gate, endPoint, topology.Outer);
                if (street != null)
                {
                    //roads.Add(street);
                    streets.Add(street);

                    if (CityWall.Gates.Contains(gate))
                    {
                        var direction = GeometryHelpers.Scale(gate - Center, 100000);

                        var start = topology.Node2V.Values.OrderBy(v => (v - direction).magnitude).First();

                        var road = topology.BuildPath(start, gate, topology.Inner);
                        if (road == null)
                        {
                            CityWall.Gates.Remove(gate);
                            CityWall.Towers.Add(gate);
                            Gates.Remove(gate);
                        }
                        else
                        {
                            roads.Add(road);
                        }
                    }
                }
            }

            if (!roads.Any())
            {
                throw new InvalidOperationException("No roads into the town");
            }

            Roads.AddRange(TidyUpRoads(roads));
            Streets.AddRange(TidyUpRoads(streets));

            foreach (var road in Roads)
            {
                var insideVertices = road.Where(rv => Patches.Where(p => p.Shape.ContainsPoint(rv)).All(p => p.WithinCity)).Except(Gates).ToList();
                foreach (var insideVertex in insideVertices)
                {
                    road.Remove(insideVertex);
                }
            }
        }
        public async Task GetDirections()
        {
            await WorldRouting.InitializeAsync(username, password);

            var route = await WorldRouting.GetRouteAsync(GeometryHelpers.FromLatLong(34.2, -117.1), GeometryHelpers.FromLatLong(34.22, -117.14));

            Assert.IsNotNull(route);
            var route2 = await WorldRouting.GetRouteAsync("380 New York St, Redlands", "Las Vegas, NV");

            Assert.IsNotNull(route2);
        }
Example #10
0
        private void DefineAdvancedWallFields()
        {
            // get location curve
            if (!(Wall.Location is LocationCurve locationCurve))
            {
                IsDefined = false;
                return;
            }

            // Get curve from location curve
            LocationCurveCurve = locationCurve.Curve;

            // get curve type
            switch (locationCurve.Curve)
            {
            case Line _:
                CurveType = ElementCurveType.Line;
                break;

            case Arc _:
                CurveType = ElementCurveType.Arc;
                break;

            default:
                IsDefined = false;
                return;
            }

            // get ends points
            StartPoint = locationCurve.Curve.GetEndPoint(0);
            EndPoint   = locationCurve.Curve.GetEndPoint(1);
            MidPoint   = 0.5 * (StartPoint + EndPoint);

            // get solids
            GetSolids();

            // get faces and edges
            GetFacesAndEdges();

            if (Edges.Count == 0 || AdvancedPlanarFaces.Count == 0)
            {
                IsDefined = false;
                return;
            }

            // get orientation
            Orientation = GeometryHelpers.GetElementOrientation(locationCurve.Curve);
            if (Orientation == ElementOrientation.CloseToHorizontal ||
                Orientation == ElementOrientation.CloseToVertical ||
                Orientation == ElementOrientation.Undefined)
            {
                IsDefined = false;
            }
        }
Example #11
0
        public async Task ReverseGeocode()
        {
            var results = await WorldGeocoder.ReverseGeocodeAsync(GeometryHelpers.FromLatLong(34.05722922814357, -117.1956764921524));

            var address = results[0].Label;

            Assert.IsNotNull(results);
            Assert.IsTrue(results.Count > 0);
            var result = results[0];

            Assert.IsTrue(result.Label.Contains("New York St"), $"Expected '*New York St*', but got {result.Label}");
        }
Example #12
0
        /// <summary>Фильтр стен по пересечению секущей плоскостью секущего диапазона</summary>
        /// <param name="advancedWalls"></param>
        /// <param name="doc"></param>
        public static void FilterByCutPlan(List <AdvancedWall> advancedWalls, Document doc)
        {
            var checkedZ = GeometryHelpers.GetViewPlanCutPlaneElevation((ViewPlan)doc.ActiveView);

            for (var i = advancedWalls.Count - 1; i >= 0; i--)
            {
                if (checkedZ < advancedWalls[i].GetMinZ() || checkedZ > advancedWalls[i].GetMaxZ())
                {
                    advancedWalls.RemoveAt(i);
                }
            }
        }
Example #13
0
        /// <summary>
        /// Override of BinaryLinkShape.ExcludeFromClipRegion to support moving the link
        /// decorator and properly rotating it.
        /// </summary>
        public override void ExcludeFromClipRegion(Graphics g, Matrix matrix, GraphicsPath perimeter)
        {
            ObliqueBinaryLinkShapeGeometry geometry = this.ShapeGeometry as ObliqueBinaryLinkShapeGeometry;
            Pen linePen = this.StyleSet.GetPen(DiagramPens.ConnectionLine);
            EdgePointCollection edgePoints = this.EdgePoints;
            int edgePointCount             = edgePoints.Count;

            if ((geometry != null) && (linePen != null))
            {
                for (int i = 1; i < edgePointCount; ++i)
                {
                    if (edgePoints[i].Flag == VGPointType.JumpEnd)
                    {
                        GraphicsPath excludePath = this.ExcludePath;
                        geometry.AddLineArcPath(excludePath, edgePoints[i - 1].Point, edgePoints[i].Point);
                        g.SetClip(excludePath, CombineMode.Exclude);
                    }
                    else
                    {
                        RectangleD excludeRect = GeometryHelpers.RectangleDFrom2Pts(edgePoints[i - 1].Point, edgePoints[i].Point);
                        double     inflateBy   = linePen.Width / 2f;
                        excludeRect.Inflate(inflateBy, inflateBy);
                        g.SetClip(RectangleD.ToRectangleF(excludeRect), CombineMode.Exclude);
                    }
                }
                if (edgePointCount > 1)
                {
                    LinkDecorator decorator;
#if VISUALSTUDIO_10_0
                    IBinaryLinkGeometryData geometryData = (IBinaryLinkGeometryData)this;
#endif
                    if (null != (decorator = DecoratorFrom))
                    {
                        ExcludeDecorator(g, geometry, decorator, edgePoints[0].Point, edgePoints[1].Point
#if VISUALSTUDIO_10_0
                                         , geometryData.GeometryDecoratorFromSize
#endif
                                         );
                    }
                    if (null != (decorator = DecoratorTo))
                    {
                        ExcludeDecorator(g, geometry, decorator, edgePoints[edgePointCount - 1].Point, edgePoints[edgePointCount - 2].Point
#if VISUALSTUDIO_10_0
                                         , geometryData.GeometryDecoratorToSize
#endif
                                         );
                    }
                }
            }
        }
Example #14
0
        private void SmoothPatches(Polygon vertices, float smoothAmount)
        {
            for (var i = 0; i < vertices.Vertices.Count; i++)
            {
                var point    = vertices.Vertices[i];
                var prev     = vertices.GetPreviousVertex(point);
                var next     = vertices.GetNextVertex(point);
                var smoothed = GeometryHelpers.SmoothVertex(point, prev, next, smoothAmount);

                var affected = Patches.Where(p => p.Shape.Vertices.Contains(point)).ToList();
                foreach (var patch in affected)
                {
                    patch.Shape.ReplaceVertex(point, smoothed);
                }

                vertices.Vertices[i] = smoothed;
            }
        }
Example #15
0
        private bool HasLOSXY(NodeItem start, NodeItem dest)
        {
            // Are the points within the same triangle? Notice that triangles are guaranteed convex...
            if (start.Item == dest.Item)
            {
                return(true);
            }

            var corridor = start.Item;

            while (corridor.Previous != SearchItem.Null)
            {
                // We want to check that the line segment [start, dest] intersects the edge we crossed
                var curTriangle = corridor.Previous.Triangle;
                var edge        = corridor.Edge;

                Vector3 right3d, left3d;
                NavMesh.GetOutsideOrderedEdgePoints(curTriangle, edge, out right3d, out left3d);

                var right = right3d.XY;
                var left  = left3d.XY;
                if (!GeometryHelpers.IsLeftOfOrOn(left, start.Node.XY, dest.Node.XY))
                {
                    return(false);
                }
                if (!GeometryHelpers.IsRightOfOrOn(right, start.Node.XY, dest.Node.XY))
                {
                    return(false);
                }

                corridor = corridor.Previous;

                // Ok, the move into this triangle was legal, if PointB is in the tri, then we're done
                if (corridor == dest.Item)
                {
                    return(true);
                }
            }

            // Default
            return(false);
        }
        private static void DrawWalls(TownGeometry geometry, StringBuilder sb)
        {
            var replacedGates = new List <Vector2> ();

            foreach (var wall in geometry.Walls)
            {
                var start = wall.A;
                var end   = wall.B;

                if (geometry.Gates.Contains(start))
                {
                    replacedGates.Add(start);
                    start  = start + GeometryHelpers.Scale(end - start, 0.3f);
                    wall.A = start;
                    geometry.Gates.Add(start);
                }

                if (geometry.Gates.Contains(end))
                {
                    replacedGates.Add(end);
                    end    = end - GeometryHelpers.Scale(end - start, 0.3f);
                    wall.B = end;
                    geometry.Gates.Add(end);
                }
                sb.Append($"<line x1=\"{start.x}\" y1=\"{start.y}\" x2=\"{end.x}\" y2=\"{end.y}\" class=\"wall\" />");
            }

            foreach (var replacedGate in replacedGates.Distinct())
            {
                geometry.Gates.Remove(replacedGate);
            }

            foreach (var tower in geometry.Towers)
            {
                sb.Append($"<rect width=\"8\" height=\"8\" x=\"{tower.x - 4}\" y=\"{tower.y - 4}\" class=\"tower\" />");
            }

            foreach (var gate in geometry.Gates)
            {
                sb.Append($"<rect width=\"8\" height=\"8\" x=\"{gate.x - 4}\" y=\"{gate.y - 4}\" class=\"gate\" />");
            }
        }
        public IEnumerable <RelativePoint> GetGridPoints()
        {
            if (TopBottomDistance == 0 || LeftRightDistance == 0)
            {
                return(null);
            }

            var vLines = new List <RelativeLine>();
            var hLines = new List <RelativeLine>();
            var points = new List <RelativePoint>();

            SolvePerspective();

            double currentDist = 0;

            while (currentDist <= LeftRightDistance)
            {
                hLines.Add(new RelativeLine(Perspective(new Point2d(0, currentDist)), Perspective(new Point2d(1, currentDist))));
                currentDist += Defaults.GridNotchDistance;
            }
            currentDist = 0;
            while (currentDist <= TopBottomDistance)
            {
                vLines.Add(new RelativeLine(Perspective(new Point2d(currentDist, 0)), Perspective(new Point2d(currentDist, 1))));
                currentDist += Defaults.GridNotchDistance;
            }

            foreach (var vLine in vLines)
            {
                foreach (var hLine in hLines)
                {
                    try
                    {
                        points.Add(GeometryHelpers.LineIntersection(vLine, hLine));
                    }
                    catch { }
                }
            }

            return(points);
        }
        private void DefineAdvancedGridFields()
        {
            // get location curve
            var curve = _grid.Curve;

            if (curve == null)
            {
                IsDefined = false;
                return;
            }

            switch (curve)
            {
            // get curve type
            case Line _:
                CurveType = ElementCurveType.Line;
                break;

            case Arc _:
                CurveType = ElementCurveType.Arc;
                break;

            default:
                IsDefined = false;
                return;
            }

            // points
            StartPoint = curve.GetEndPoint(0);
            EndPoint   = curve.GetEndPoint(1);

            // get orientation
            Orientation = GeometryHelpers.GetElementOrientation(curve);
            if (Orientation == ElementOrientation.CloseToHorizontal ||
                Orientation == ElementOrientation.CloseToVertical ||
                Orientation == ElementOrientation.Undefined)
            {
                IsDefined = false;
            }
        }
        public Point2d?Perspective(RelativePoint point)
        {
            if (!GeometryHelpers.IsInside(point, BL, TL, TR, BR))
            {
                return(null);
            }

            double px = p[0].X;
            double py = p[0].Y;
            double xp = point.Norm.X;
            double yp = point.Norm.Y;

            double detD  = ((a + g * px - g * xp) * (e + h * py - h * yp)) - ((d + g * py - g * yp) * (b + h * px - h * xp));
            double detDx = ((xp - px) * (e + h * py - h * yp)) - ((yp - py) * (b + h * px - h * xp));
            double detDy = ((a + g * px - g * xp) * (yp - py)) - ((d + g * py - g * yp) * (xp - px));

            double x = detDx / detD;
            double y = detDy / detD;

            double normX = x * TopBottomDistance;
            double normY = y * LeftRightDistance;

            return(new Point2d(normX, normY));
        }
Example #20
0
        public void WithRemovedPositionWhenSameLifetimeOfPreviouslyRemovedPosition(
            Fixture fixture,
            AddressId addressId,
            AddressWasRegistered addressWasRegistered,
            WkbGeometry wkbGeometry,
            AddressHouseNumberPositionWasImportedFromCrab addressHouseNumberPositionWasImportedFromCrab,
            AddressPositionWasRemoved addressPositionWasRemoved,
            AddressHouseNumberPositionWasImportedFromCrab addressHouseNumberPositionWasImportedFromCrabDelete,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab,
            CrabLifetime lifetime)
        {
            var addressWasPositioned = new AddressWasPositioned(addressId, new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Lot, GeometryHelpers.CreateEwkbFrom(wkbGeometry)));

            ((ISetProvenance)addressWasPositioned).SetProvenance(fixture.Create <Provenance>());
            addressHouseNumberPositionWasImportedFromCrab = addressHouseNumberPositionWasImportedFromCrab
                                                            .WithWkbGeometry(wkbGeometry)
                                                            .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot)
                                                            .WithBeginDate(lifetime.BeginDateTime);
            addressHouseNumberPositionWasImportedFromCrabDelete = addressHouseNumberPositionWasImportedFromCrabDelete
                                                                  .WithWkbGeometry(wkbGeometry)
                                                                  .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot)
                                                                  .WithBeginDate(lifetime.BeginDateTime)
                                                                  .WithModification(CrabModification.Delete);

            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromStand)
                                                .WithLifetime(lifetime);

            Assert(new Scenario()
                   .Given(addressId,
                          addressWasRegistered,
                          addressWasPositioned,
                          addressHouseNumberPositionWasImportedFromCrab,
                          addressPositionWasRemoved,
                          addressHouseNumberPositionWasImportedFromCrabDelete
                          )
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         new AddressWasPositioned(addressId,
                                                  new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Stand, GeometryHelpers.CreateEwkbFrom(importHouseNumberPositionFromCrab.AddressPosition))),
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
Example #21
0
        public void ThenPositionChangeWhenOlderLifetimeAndHigherQuality(
            Fixture fixture,
            AddressId addressId,
            WkbGeometry wkbGeometry,
            CrabLifetime lifetime,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab)
        {
            var addressGeometry = new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Lot, GeometryHelpers.CreateEwkbFrom(wkbGeometry));

            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromStand)
                                                .WithLifetime(lifetime);

            Assert(RegisteredAddressScenario(fixture)
                   .Given <AddressWasPositioned>(addressId, e => e.WithAddressGeometry(addressGeometry))
                   .Given <AddressHouseNumberPositionWasImportedFromCrab>(addressId, e => e
                                                                          .WithWkbGeometry(wkbGeometry)
                                                                          .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot)
                                                                          .WithBeginDate(lifetime.BeginDateTime.Value.PlusDays(1)))
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         new AddressWasPositioned(addressId,
                                                  new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Stand, GeometryHelpers.CreateEwkbFrom(importHouseNumberPositionFromCrab.AddressPosition))),
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
Example #22
0
        public void ThenNoPositionChangeWhenOlderLifetimeAndLessQuality(
            Fixture fixture,
            AddressId addressId,
            AddressWasRegistered addressWasRegistered,
            WkbGeometry wkbGeometry,
            AddressHouseNumberPositionWasImportedFromCrab addressHouseNumberPositionWasImportedFromCrab,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab)
        {
            var addressWasPositioned = new AddressWasPositioned(addressId, new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Stand, GeometryHelpers.CreateEwkbFrom(wkbGeometry)));

            ((ISetProvenance)addressWasPositioned).SetProvenance(fixture.Create <Provenance>());

            addressHouseNumberPositionWasImportedFromCrab = addressHouseNumberPositionWasImportedFromCrab
                                                            .WithWkbGeometry(wkbGeometry)
                                                            .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromStand);

            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot)
                                                .WithLifetime(new CrabLifetime(addressHouseNumberPositionWasImportedFromCrab.BeginDateTime.Value.PlusDays(-1),
                                                                               addressHouseNumberPositionWasImportedFromCrab.EndDateTime));

            Assert(new Scenario()
                   .Given(addressId,
                          addressWasRegistered,
                          addressWasPositioned,
                          addressHouseNumberPositionWasImportedFromCrab)
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
Example #23
0
        public void WhenModificationIsCorrection(
            Fixture fixture,
            AddressId addressId,
            AddressWasRegistered addressWasRegistered,
            WkbGeometry wkbGeometry,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab)
        {
            var addressWasPositioned = new AddressWasPositioned(addressId, new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Lot, GeometryHelpers.CreateEwkbFrom(wkbGeometry)));

            ((ISetProvenance)addressWasPositioned).SetProvenance(fixture.Create <Provenance>());

            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabModification(CrabModification.Correction)
                                                .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.DerivedFromBuilding);

            Assert(new Scenario()
                   .Given(addressId,
                          addressWasRegistered,
                          addressWasPositioned
                          )
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         new AddressPositionWasCorrected(addressId,
                                                         new AddressGeometry(GeometryMethod.DerivedFromObject, GeometrySpecification.BuildingUnit, GeometryHelpers.CreateEwkbFrom(importHouseNumberPositionFromCrab.AddressPosition))),
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
Example #24
0
        private void BuildPatches()
        {
            var points = GetVoronoiPoints(NumPatches, Center).ToList();

            var v = Voronoi.Build(points);

            for (var i = 0; i < 3; i++)
            {
                var toRelax = v.Points.Take(3).ToList();
                toRelax.Add(v.Points[NumPatches]);
                v = Voronoi.Relax(v, toRelax);
            }

            v = Voronoi.Relax(v);

            var comparer = new Vector2LengthComparer();

            v.Points.Sort(comparer);

            var regions = v.Partitioning();

            Patches.Clear();
            foreach (var region in regions)
            {
                Patches.Add(Patch.FromRegion(this, region));
            }

            var patchesInTown = Patches.OrderBy(p => (Center - p.Center).magnitude).Take(NumPatches).ToList();

            // Find random patch at the outside of town to place water
            if (Options.Water)
            {
                var firstWaterPatch = patchesInTown.Where(p => p.GetAllNeighbours().Any(n => !n.WithinCity))
                                      .OrderBy(p => Random.value).First();
                firstWaterPatch.Water = true;

                Vector2 waterDirection = (firstWaterPatch.Center - Center).normalized;


                var toCheck = new List <Patch> {
                    firstWaterPatch
                };
                while (toCheck.Any())
                {
                    var checking = toCheck[0];
                    toCheck.RemoveAt(0);

                    var waterPatches = checking.GetAllNeighbours().Except(patchesInTown)
                                       .Where(n => Math.Abs(GeometryHelpers.AngleComparedTo(Center - n.Center, waterDirection)) < Math.PI / 4)
                                       .Where(n => !n.Water).ToList();
                    foreach (var waterPatch in waterPatches)
                    {
                        waterPatch.Water = true;
                        toCheck.Add(waterPatch);
                    }
                }
            }

            patchesInTown = Patches.Where(p => !p.Water).OrderBy(p => (Center - p.Center).magnitude).Take(NumPatches)
                            .ToList();

            foreach (var patch in patchesInTown)
            {
                patch.WithinCity  = true;
                patch.WithinWalls = true;
            }

            Castle = new Castle(patchesInTown.Last());

            Market = patchesInTown.First();
            Market.IsCityCenter = true;

            var circumference = FindCircumference(patchesInTown);
            var smoothAmount  = Math.Min(1f, 40f / circumference.Vertices.Count);

            if (Options.Walls)
            {
                SmoothPatches(circumference, smoothAmount);
            }

            if (Options.Water)
            {
                var waterCircumference = FindCircumference(Patches.Where(p => p.Water));
                SmoothPatches(waterCircumference, 0.2f);
                WaterBorder.Clear();
                WaterBorder.AddRange(waterCircumference.Vertices);
            }
        }
        /// <summary>Проставить внешние размеры</summary>
        public void DoWork()
        {
            var doc = _uiApplication.ActiveUIDocument.Document;

            _cutPlanZ = GeometryHelpers.GetViewPlanCutPlaneElevation((ViewPlan)doc.ActiveView);

            // select
            var selectedElements = SelectElements();

            if (selectedElements == null)
            {
                return;
            }

            // get list of advanced elements
            foreach (var element in selectedElements)
            {
                switch (element)
                {
                case Wall wall:
                    var advancedWall = new AdvancedWall(wall);
                    if (advancedWall.IsDefined)
                    {
                        _advancedWalls.Add(advancedWall);
                    }
                    break;

                case Grid grid:
                    var advancedGrid = new AdvancedGrid(grid);
                    if (advancedGrid.IsDefined)
                    {
                        _advancedGrids.Add(advancedGrid);
                    }
                    break;
                }
            }

            if (!_advancedWalls.Any())
            {
                MessageBox.Show(Language.GetItem(LangItem, "msg7"), MessageBoxIcon.Close);
                return;
            }

            // Фильтрую стены по толщине
            AdvancedHelpers.FilterByWallWidth(_advancedWalls);
            if (!_advancedWalls.Any())
            {
                MessageBox.Show(Language.GetItem(LangItem, "msg8"), MessageBoxIcon.Close);
                return;
            }

            // Фильтрую стены, оставляя которые пересекаются секущим диапазоном
            AdvancedHelpers.FilterByCutPlan(_advancedWalls, _uiApplication.ActiveUIDocument.Document);

            // Вдруг после этого не осталось стен!
            if (!_advancedWalls.Any())
            {
                MessageBox.Show(Language.GetItem(LangItem, "msg9"), MessageBoxIcon.Close);
                return;
            }

            AdvancedHelpers.FindExtremes(
                _advancedWalls, out var leftExtreme, out var rightExtreme, out var topextreme, out var bottomExtreme);

            using (var transactionGroup = new TransactionGroup(doc, _transactionName))
            {
                transactionGroup.Start();

                var createdDimensions = new List <Dimension>();

                if (_exteriorConfiguration.RightDimensions)
                {
                    createdDimensions.AddRange(CreateSideDimensions(rightExtreme, _advancedWalls, ExtremeWallVariant.Right));
                }
                if (_exteriorConfiguration.LeftDimensions)
                {
                    createdDimensions.AddRange(CreateSideDimensions(leftExtreme, _advancedWalls, ExtremeWallVariant.Left));
                }
                if (_exteriorConfiguration.TopDimensions)
                {
                    createdDimensions.AddRange(CreateSideDimensions(topextreme, _advancedWalls, ExtremeWallVariant.Top));
                }
                if (_exteriorConfiguration.BottomDimensions)
                {
                    createdDimensions.AddRange(CreateSideDimensions(bottomExtreme, _advancedWalls, ExtremeWallVariant.Bottom));
                }

                if (createdDimensions.Any(d => d != null))
                {
                    using (var tr = new Transaction(doc, "Remove zeroes"))
                    {
                        tr.Start();

                        foreach (var createdDimension in createdDimensions.Where(d => d != null))
                        {
                            if (Dimensions.TryRemoveZeroes(createdDimension, out var referenceArray) &&
                                createdDimension.Curve is Line line)
                            {
                                doc.Delete(createdDimension.Id);
                                doc.Create.NewDimension(doc.ActiveView, line, referenceArray);
                            }
                        }

                        tr.Commit();
                    }
                }

                transactionGroup.Assimilate();
            }
        }
Example #26
0
        public void WhenCrabAddressPositionOrigin(
            CrabAddressPositionOrigin crabAddressPositionOrigin,
            GeometryMethod geometryMethod,
            GeometrySpecification geometrySpecification,
            AddressId addressId,
            AddressWasRegistered addressWasRegistered,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab)
        {
            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabAddressPositionOrigin(crabAddressPositionOrigin);

            Assert(new Scenario()
                   .Given(addressId, addressWasRegistered)
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         new AddressWasPositioned(addressId, new AddressGeometry(geometryMethod, geometrySpecification, GeometryHelpers.CreateEwkbFrom(importHouseNumberPositionFromCrab.AddressPosition))),
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
Example #27
0
        public void WhenPositionQualityIsHigher(
            Fixture fixture,
            AddressId addressId,
            CrabLifetime crabLifetime,
            AddressWasRegistered addressWasRegistered,
            AddressHouseNumberPositionWasImportedFromCrab addressHouseNumberPositionWasImported,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab)
        {
            var addressWasPositioned = new AddressWasPositioned(addressId,
                                                                new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Lot, GeometryHelpers.CreateEwkbFrom(importHouseNumberPositionFromCrab.AddressPosition)));

            ((ISetProvenance)addressWasPositioned).SetProvenance(fixture.Create <Provenance>());

            addressHouseNumberPositionWasImported = addressHouseNumberPositionWasImported
                                                    .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot)
                                                    .WithBeginDate(crabLifetime.BeginDateTime);

            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromEntryOfBuilding)
                                                .WithLifetime(crabLifetime);

            Assert(new Scenario()
                   .Given(addressId,
                          addressWasRegistered,
                          addressWasPositioned,
                          addressHouseNumberPositionWasImported)
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         new AddressWasPositioned(addressId,
                                                  new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Entry, GeometryHelpers.CreateEwkbFrom(importHouseNumberPositionFromCrab.AddressPosition))),
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
        private static Result createVisualizationSheets(UIDocument uiDoc, BuildingLoadModel buildingLoadModel, IEnumerable <ILoadModel> levelLiveLoadPerSquareFoots)
        {
            //Setup
            Document _doc = uiDoc.Document;

            double _concreteDensityPoundsForcePerCubicFoot = 153.0;

            XYZ _capacityViewCoordinate = new XYZ(2.17649771769026, 0.766954561856788, 0);
            XYZ _combinedViewCoordinate = new XYZ(0.780872717690263, 0.766954561856788, 0);
            XYZ _demandViewCoordinate   = new XYZ(0.780872717690263, 1.83481042377296, 0);

            var _levels = Getters.GetLevels(_doc).OrderByDescending(p => p.Elevation).ToList();

            var _floors            = Getters.GetFloors(_doc).OrderBy(p => p.get_BoundingBox(null)?.Max.Z).ToList();
            var _structuralColumns = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_StructuralColumns).OfType <FamilyInstance>().OrderBy(p => p.get_BoundingBox(null)?.Max.Z).ToList();
            var _structuralFraming = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_StructuralFraming).OfType <FamilyInstance>().OrderBy(p => p.get_BoundingBox(null)?.Max.Z).ToList();
            var _walls             = new FilteredElementCollector(_doc).OfClass(typeof(Wall)).OfType <Wall>().OrderBy(p => p.get_BoundingBox(null)?.Max.Z).ToList();

            BoundingBoxXYZ _modelExtents =
                GeometryHelpers.GetElementsBBox(
                    new FilteredElementCollector(_doc).WhereElementIsViewIndependent().WhereElementIsNotElementType().ToList());

            _modelExtents.Min = new XYZ(_modelExtents.Min.X, _modelExtents.Min.Y, _levels.LastOrDefault().Elevation - 1.0);

            Category _directShapeCategory = Category.GetCategory(_doc, BuiltInCategory.OST_GenericModel);

            Level _levelAbove  = null;
            Level _bottomLevel = _levels.LastOrDefault();
            Level _topLevel    = _levels.FirstOrDefault();

            //Begin to generate our VisualizationDeliverables - these are sheets with 3 plan-orientation isometric views.
            //  NOTE - isometric views were used so that semi-transparent color overrides can be overlayed over each other to represent demands vs capacities
            //  ToDo: it would be valuable to scale transparency by percentage of overall demand/capacity
            List <VisualizationDeliverable> _visualizationDeliverables = new List <VisualizationDeliverable>();

            foreach (Level _level in _levels)
            {
                if (_levelAbove == null)
                {
                    _levelAbove = _level;
                }

                //Get the elements that are on our current Level
                List <Floor>          _currentLevelFloors            = _floors.Where(p => p.LevelId == _level.Id).ToList();
                List <FamilyInstance> _currentLevelStructuralColumns = new List <FamilyInstance>();
                List <FamilyInstance> _currentLevelStructuralFraming = new List <FamilyInstance>();
                List <Wall>           _currentLevelWalls             = new List <Wall>();

                BoundingBoxXYZ _levelBounds = new BoundingBoxXYZ
                {
                    Min = new XYZ(_modelExtents.Min.X, _modelExtents.Min.Y, _level.Elevation),
                    Max = new XYZ(_modelExtents.Max.X, _modelExtents.Max.Y, _levelAbove.Elevation)
                };

                BoundingBoxIsInsideFilter   _withinLevelBoundsFilter     = new BoundingBoxIsInsideFilter(new Outline(_levelBounds.Min, _levelBounds.Max));
                BoundingBoxIntersectsFilter _intersectsLevelBoundsFilter = new BoundingBoxIntersectsFilter(new Outline(_levelBounds.Min, _levelBounds.Max));

                if (_structuralColumns.Count > 0)
                {
                    _currentLevelStructuralColumns = new FilteredElementCollector(_doc, _structuralColumns.Select(p => p.Id).ToList()).WherePasses(_intersectsLevelBoundsFilter).OfType <FamilyInstance>().ToList();
                }
                else
                {
                    _currentLevelStructuralColumns = new List <FamilyInstance>();
                }

                if (_structuralFraming.Count > 0)
                {
                    _currentLevelStructuralFraming = new FilteredElementCollector(_doc, _structuralFraming.Select(p => p.Id).ToList()).WherePasses(_withinLevelBoundsFilter).OfType <FamilyInstance>().ToList();
                }
                else
                {
                    _currentLevelStructuralFraming = new List <FamilyInstance>();
                }

                if (_walls.Count > 0)
                {
                    _currentLevelWalls = new FilteredElementCollector(_doc, _walls.Select(p => p.Id).ToList()).WherePasses(_withinLevelBoundsFilter).OfType <Wall>().ToList();
                }
                else
                {
                    _currentLevelWalls = new List <Wall>();
                }

                //Generate LoadModels to populate a full LevelLoadModel
                LevelLoadModel _currentLevelLoadModel = LevelLoadModel.Create(_level);
                foreach (Floor _floor in _currentLevelFloors)
                {
                    //The "top" floor is where the initial Demand is determined, which is to be supported via reshores propagating down through the building
                    //ToDo: it would be valuable to be able to pick which Level to start from
                    if (_level.Id == _topLevel.Id)
                    {
                        Parameter _floorThicknessParameter = _floor.get_Parameter(BuiltInParameter.FLOOR_ATTR_THICKNESS_PARAM);
                        double    _floorThickness          = _floorThicknessParameter == null
                            ? 0.0
                            : _floorThicknessParameter.AsDouble();

                        _currentLevelLoadModel.addFloorDemandLoadModel(_floor, _concreteDensityPoundsForcePerCubicFoot * _floorThickness);
                    }

                    //Add loads from other sources that are also distributed evenly along a level
                    ILoadModel _floorCapacityLoadModel = levelLiveLoadPerSquareFoots.FirstOrDefault(p => p.Name == _level.Name);
                    if (_floorCapacityLoadModel == null)
                    {
                        continue;
                    }

                    List <LoadModel> _floorLoadModels = _currentLevelLoadModel.addFloorCapacityLoadModel(_floor, _floorCapacityLoadModel.PoundsForcePerSquareFoot);

                    foreach (ILoadModel _loadModel in levelLiveLoadPerSquareFoots.Where(p => p.Name.Equals(_level.Name)))
                    {
                        List <ILoadModel> _otherLoadModels = new List <ILoadModel>();
                        foreach (LoadModel _floorLoadModel in _floorLoadModels)
                        {
                            LoadModel _otherLoadModel = LoadModel.Create();
                            _otherLoadModel.Name     = _loadModel.Name;
                            _otherLoadModel.LoadType = _loadModel.LoadType;
                            _otherLoadModel.PoundsForcePerSquareFoot = _loadModel.PoundsForcePerSquareFoot;
                            _otherLoadModel.AreaSquareFeetXY         = _floorLoadModel.AreaSquareFeetXY;
                            _otherLoadModel.HeightFeetZ = _floorLoadModel.HeightFeetZ;
                            _otherLoadModel.OriginXFeet = _floorLoadModel.OriginXFeet;
                            _otherLoadModel.OriginYFeet = _floorLoadModel.OriginYFeet;

                            _otherLoadModel.Curves     = _floorLoadModel.Curves;
                            _otherLoadModel.PlanarFace = _floorLoadModel.PlanarFace;
                            _otherLoadModel.Element    = _floorLoadModel.Element;

                            _currentLevelLoadModel.addLoadModel(_otherLoadModel);
                        }
                    }
                }
                foreach (FamilyInstance _structuralColumn in _currentLevelStructuralColumns)
                {
                    _currentLevelLoadModel.addFamilyInstanceLoadModel(_structuralColumn, LoadType.Demand, buildingLoadModel.StructuralColumnWeightPerSquareFoot);
                    _currentLevelLoadModel.addFamilyInstanceLoadModel(_structuralColumn, LoadType.Capacity, buildingLoadModel.StructuralColumnWeightPerSquareFoot);
                }
                foreach (FamilyInstance _structuralFrame in _currentLevelStructuralFraming)
                {
                    _currentLevelLoadModel.addFamilyInstanceLoadModel(_structuralFrame, LoadType.Demand, buildingLoadModel.StructuralBeamWeightPerSquareFoot);
                }
                foreach (Wall _wall in _currentLevelWalls)
                {
                    _currentLevelLoadModel.addWallLoadModel(_wall, LoadType.Demand, buildingLoadModel.StructuralWallWeightPerSquareFoot);
                    _currentLevelLoadModel.addWallLoadModel(_wall, LoadType.Capacity, buildingLoadModel.StructuralWallWeightPerSquareFoot);
                }

                //Set the Solid elements that we will project through the building, to represent demands/capacities
                LoadModel.SetSolids(_currentLevelLoadModel.LoadModels.OfType <LoadModel>(), _level, _topLevel, _bottomLevel);

                VisualizationDeliverable _visualizationDeliverable = new VisualizationDeliverable(_currentLevelLoadModel)
                {
                    Floors            = _currentLevelFloors,
                    StructuralColumns = _currentLevelStructuralColumns,
                    StructuralFraming = _currentLevelStructuralFraming,
                    Walls             = _currentLevelWalls,
                };
                _visualizationDeliverables.Add(_visualizationDeliverable);

                _levelAbove = _level;
            }

            //Now that we've gathered all of our LoadModels, let's read the data about their actual demands/capacities
            buildingLoadModel.LevelLoadModels = _visualizationDeliverables.Select(p => p.LevelLoadModel as ILevelLoadModel).Where(p => p != null).ToList();

            buildingLoadModel.ReadLoads();

            foreach (LoadModel _loadModel in _visualizationDeliverables.Select(p => p.LevelLoadModel).SelectMany(p => p.LoadModels))
            {
                _loadModel.SetDirectShapeWithParameters(_doc, _directShapeCategory.Id, _loadModel.Name);
            }

            //Update Levels in the model with Load details
            foreach (LevelLoadModel _levelLoadModel in _visualizationDeliverables.Select(p => p.LevelLoadModel))
            {
                _levelLoadModel.SetLevelParameters();
            }

            //Color our active View for the visualization
            colorActiveView(_doc, _visualizationDeliverables);

            //ToDo: something happened which broke colors being correctly applied to these sheets - will need to sort this out
            //createSheetsAndViews(_doc, _visualizationDeliverables, _modelExtents);
            //
            //colorViews(_doc, _visualizationDeliverables);
            //
            //createViewports(_doc, _visualizationDeliverables, _capacityViewCoordinate, _combinedViewCoordinate, _demandViewCoordinate);

            return(Result.Succeeded);
        }
Example #29
0
        public void ThenNoPositionChangeWhenPositionIsTheSame(
            Fixture fixture,
            AddressId addressId,
            AddressWasRegistered addressWasRegistered,
            WkbGeometry wkbGeometry,
            ImportHouseNumberPositionFromCrab importHouseNumberPositionFromCrab)
        {
            var addressWasPositioned = new AddressWasPositioned(addressId, new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Lot, GeometryHelpers.CreateEwkbFrom(wkbGeometry)));

            ((ISetProvenance)addressWasPositioned).SetProvenance(fixture.Create <Provenance>());

            importHouseNumberPositionFromCrab = importHouseNumberPositionFromCrab
                                                .WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot)
                                                .WithWkbGeometry(wkbGeometry);

            Assert(new Scenario()
                   .Given(addressId,
                          addressWasRegistered,
                          addressWasPositioned)
                   .When(importHouseNumberPositionFromCrab)
                   .Then(addressId,
                         importHouseNumberPositionFromCrab.ToLegacyEvent()));
        }
        public void ThenAddressBecameComplete(
            AddressId addressId,
            AddressWasRegistered addressWasRegistered,
            AddressWasProposed addressWasProposed,
            AddressWasOfficiallyAssigned addressWasOfficiallyAssigned,
            ImportSubaddressPositionFromCrab importSubaddressPositionFromCrab)
        {
            importSubaddressPositionFromCrab.WithCrabAddressPositionOrigin(CrabAddressPositionOrigin.ManualIndicationFromLot);

            Assert(new Scenario()
                   .Given(addressId,
                          addressWasRegistered,
                          addressWasProposed,
                          addressWasOfficiallyAssigned)
                   .When(importSubaddressPositionFromCrab)
                   .Then(addressId,
                         new AddressWasPositioned(addressId, new AddressGeometry(GeometryMethod.AppointedByAdministrator, GeometrySpecification.Lot, GeometryHelpers.CreateEwkbFrom(importSubaddressPositionFromCrab.AddressPosition))),
                         new AddressBecameComplete(addressId),
                         importSubaddressPositionFromCrab.ToLegacyEvent()));
        }