Beispiel #1
0
        /// <summary>
        /// Interpret the MultiPolygon object and start processing it to create a 3D model
        /// </summary>
        /// <param name="multiPolygon">the multipolygon to process</param>
        /// <param name="scale">the scale of the 3d object</param>
        /// <param name="height">the height of the model</param>
        private void GenerateModelFromMultiPolygon(MultiPolygon multiPolygon, float scale, float height)
        {
            int side = 400;

            float maxX = 0;
            float maxY = 0;
            float minX = float.MaxValue;
            float minY = float.MaxValue;

            // Get the extreme points, these will be used for normalization
            foreach (Polygon p in multiPolygon.Coordinates)
            {
                foreach (LineString lstring in p.Coordinates)
                {
                    var maxX2 = lstring.Coordinates.Select(position => GetPointFromCoordinates(side, side, position).X).Max();
                    var maxY2 = lstring.Coordinates.Select(position => GetPointFromCoordinates(side, side, position).Y).Max();
                    var minX2 = lstring.Coordinates.Select(position => GetPointFromCoordinates(side, side, position).X).Min();
                    var minY2 = lstring.Coordinates.Select(position => GetPointFromCoordinates(side, side, position).Y).Min();
                    if (maxX2 > maxX)
                    {
                        maxX = maxX2;
                    }
                    if (maxY2 > maxY)
                    {
                        maxY = maxY2;
                    }
                    if (minX2 < minX)
                    {
                        minX = minX2;
                    }
                    if (minY2 < minY)
                    {
                        minY = minY2;
                    }
                }
            }

            WorldPosition = new PointF(minX, minY);
            var o = multiPolygon.Coordinates.OrderBy(coords => coords.Coordinates.Select(coordinate => coordinate.Coordinates.Count).Max());

            for (int i = 0; i < o.Count(); i++)
            {
                System.Diagnostics.Debug.WriteLine("Holecount: " + (o.ElementAt(i).Coordinates.Count - 1));

                List <List <PointF> > normalizedPolygon = new List <List <PointF> >();

                foreach (LineString lstring in o.ElementAt(i).Coordinates)
                {
                    List <PointF> points = new List <PointF>();
                    // Loop over the points, rescale them and add them to the list
                    foreach (IPosition point in lstring.Coordinates)
                    {
                        var xy = GetPointFromCoordinates(side, side, point);

                        var normalizedPoint = NormalizePoint(xy, minX, minY, maxX, maxY, side);

                        points.Add(normalizedPoint);
                    }

                    // Use Peucker to eliminate points
                    List <PointF> scarcePoints = EliminatePoints(points);
                    // The algorithm requires the polygon to be in the first index and all holes to follow, we assume that the longest sequence of points is the polygon and all others are holes
                    if (lstring.Coordinates.Count == o.ElementAt(i).Coordinates.Select(coordinate => coordinate.Coordinates.Count).Max())
                    {
                        normalizedPolygon.Insert(0, scarcePoints);
                    }
                    else
                    {
                        normalizedPolygon.Add(scarcePoints);
                    }
                }
                // Create a single polygon of the polygon and all it's holes
                List <PointF> compositePolygon = CustomHoleTriangulator.ConstructPolygon(normalizedPolygon);
                // Triangulate the polygon
                List <Triangle> triangles = CustomTriangulator.Triangulate(compositePolygon);
                // Generate the model
                AssembleModel(compositePolygon, triangles, scale, height);
            }
        }