public async Task <ViewRadiusOutputs> Handler(ViewRadiusInputs args, ILambdaContext context)
        {
            if (this.store == null)
            {
                // Preload the dependencies (if they exist),
                // so that they are available during model deserialization.
                var asmLocation = this.GetType().Assembly.Location;
                var asmDir      = Path.GetDirectoryName(asmLocation);
                var asmName     = Path.GetFileNameWithoutExtension(asmLocation);
                var depPath     = Path.Combine(asmDir, $"{asmName}.Dependencies.dll");

                if (File.Exists(depPath))
                {
                    Console.WriteLine($"Loading dependencies from assembly: {depPath}...");
                    Assembly.LoadFrom(depPath);
                    Console.WriteLine("Dependencies assembly loaded.");
                }

                this.store = new S3ModelStore <ViewRadiusInputs>(RegionEndpoint.USWest1);
            }

            var l      = new InvocationWrapper <ViewRadiusInputs, ViewRadiusOutputs>(store, ViewRadius.Execute);
            var output = await l.InvokeAsync(args);

            return(output);
        }
Exemple #2
0
        /// <summary>
        /// The ViewRadius function.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A ViewRadiusOutputs instance containing computed results and the model with any new elements.</returns>
        public static ViewRadiusOutputs Execute(Dictionary <string, Model> inputModels, ViewRadiusInputs input)
        {
            inputModels.TryGetValue("Envelope", out Model envelopeModel);
            inputModels.TryGetValue("location", out Model contextBuildingsModel);
            if (envelopeModel == null)
            {
                throw new Exception("Unable to find envelope model.");
            }
            if (contextBuildingsModel == null)
            {
                throw new Exception("Unable to find Location model.");
            }
            var allEnvelopes        = envelopeModel.AllElementsOfType <Envelope>();
            var allContextBuildings = contextBuildingsModel.AllElementsOfType <Mass>();

            if (!allEnvelopes.Any())
            {
                throw new Exception("No envelopes in model.");
            }
            if (!allContextBuildings.Any())
            {
                throw new Exception("No context buildings in model.");
            }
            var height            = input.Height;
            var envelopesAtHeight = allEnvelopes.Where(env => height > env.Elevation && height < env.Height + env.Elevation);

            var model    = new Model();
            int rayCount = 170;

            var allFaces      = allContextBuildings.SelectMany(b => b.Representation.SolidOperations.Select(s => s.Solid.Faces));
            var maxTotalScore = 0.0;
            var totalScore    = 0.0;

            foreach (var envelope in envelopesAtHeight)
            {
                var perimeter     = envelope.Profile.Perimeter;
                var vertexAverage = perimeter.Vertices.Average();
                var minRadius     = perimeter.Vertices.Select(v => v.DistanceTo(vertexAverage)).Max();
                var circle        = Polygon.Circle(minRadius, rayCount);
                var rayDirections = circle.Vertices;
                var totalRadius   = input.MaxRadius + minRadius;
                maxTotalScore += Math.PI * totalRadius * totalRadius;

                var heightTransform = new Transform(vertexAverage.X, vertexAverage.Y, height);
                circle = heightTransform.OfPolygon(circle);

                var maxCircle = new Circle(heightTransform.Origin, totalRadius);


                var filteredFaces = filterFaces(allFaces.SelectMany(f => f.Values).ToList(), maxCircle);

                var            rays = rayDirections.Select(i => new Ray(maxCircle.Center, i));
                List <Vector3> finalIsovistPoints = new List <Vector3>();

                foreach (var ray in rays)
                {
                    List <Vector3> allResults = new List <Vector3>();

                    foreach (var face in filteredFaces)
                    {
                        if (Intersects(ray, face, out Vector3 result))
                        {
                            allResults.Add(result);
                        }
                    }
                    if (allResults.Count > 0)
                    {
                        var resultsOrdered = allResults.OrderBy(r => r.DistanceTo(ray.Origin));
                        finalIsovistPoints.Add(resultsOrdered.First());
                    }
                    else
                    {
                        finalIsovistPoints.Add(ray.Origin + ray.Direction.Unitized() * totalRadius);
                    }
                }

                var isovist = new Polygon(finalIsovistPoints);
                totalScore += isovist.Area();

                Mesh mesh           = CreateMeshFromRays(finalIsovistPoints, maxCircle, rayCount);
                var  isovistElement = new Isovist(mesh);

                model.AddElement(isovistElement);
            }
            var outputs = new ViewRadiusOutputs((totalScore / maxTotalScore) * 100);

            outputs.model = model;
            return(outputs);
        }