예제 #1
0
 public HabitatMap(
     Vector2 mapStartPosition,
     Vector2 mapGridSize,
     IntVector2 gridCellsCount,
     MyQuadtree <HabitatFieldInTree>[,] treeArray)
 {
     _mapStartPosition = mapStartPosition;
     _treeArray        = treeArray;
     _mapGridSize      = mapGridSize;
     _gridCellsCount   = gridCellsCount;
 }
예제 #2
0
        public MyQuadtree <HabitatFieldInTree> QueryMap(MyRectangle queryArea)
        {
            var outTree = new MyQuadtree <HabitatFieldInTree>();

            Vector2 reoffsetStartPosition = new Vector2(queryArea.X, queryArea.Y) - _mapStartPosition;
            Vector2 reoffsetEndPosition   = new Vector2(queryArea.X + queryArea.Width, queryArea.Y + queryArea.Height)
                                            - _mapStartPosition;

            var startGridX = Mathf.FloorToInt(reoffsetStartPosition.x / _mapGridSize.x);
            var startGridY = Mathf.FloorToInt(reoffsetStartPosition.y / _mapGridSize.y);

            var endGridX = Mathf.Min(_gridCellsCount.X, Mathf.CeilToInt(reoffsetEndPosition.x / _mapGridSize.x));
            var endGridY = Mathf.Min(_gridCellsCount.Y, Mathf.CeilToInt(reoffsetEndPosition.y / _mapGridSize.y));

            if (startGridX < 0 || startGridY < 0 || endGridX > _gridCellsCount.X || endGridY > _gridCellsCount.Y)
            {
                Preconditions.Fail(
                    $"Querying area {queryArea}, makes grids query: x:{startGridX} - {endGridX} y:{startGridY}-{endGridY} which is out of size {_gridCellsCount}");
            }

            var queryEnvelope = MyNetTopologySuiteUtils.ToGeometryEnvelope(queryArea);

            for (var gridX = startGridX; gridX < endGridX; gridX++)
            {
                for (var gridY = startGridY; gridY < endGridY; gridY++)
                {
                    //todo return other structure - one that uses gridded tree in array
                    List <HabitatFieldInTree> treeElements = null;

                    treeElements = _treeArray[gridX, gridY].QueryAll().Select(c =>
                                                                              new
                    {
                        intersection = c.Field.Geometry.Intersection(queryEnvelope),
                        elem         = c
                    })
                                   .Where(c => !c.intersection.IsEmpty && !(c.intersection is ILineString))
                                   .SelectMany(c => MyNetTopologySuiteUtils.ToSinglePolygons(c.intersection).Select(
                                                   k => new HabitatFieldInTree()
                    {
                        Field = new HabitatField()
                        {
                            Geometry = k,
                            Type     = c.elem.Field.Type
                        }
                    })).ToList();

                    treeElements.ForEach(c => outTree.Add(c));
                }
            }

            return(outTree);
        }
예제 #3
0
        private MyQuadtree <HabitatEnlargedByMarginInTree> GenerateEnlargedTree(List <HabitatField> habitatFields)
        {
            var outTree = new MyQuadtree <HabitatEnlargedByMarginInTree>();

            foreach (var field in habitatFields)
            {
                var geo         = field.Geometry;
                var enlargedGeo = MyNetTopologySuiteUtils.EnlargeByMargin(geo, _configuration.HabitatMargin);
                outTree.Add(new HabitatEnlargedByMarginInTree()
                {
                    Type = field.Type,
                    MarginedHabitatField = enlargedGeo,
                    StandardHabitatField = geo
                });
            }
            return(outTree);
        }
예제 #4
0
        public HabitatMap LoadHabitatMap(string rootFilePath)
        {
            var pathGenerator = new HabitatMapFileManagerPathsGenerator(rootFilePath);
            var infoJson      = JsonUtility.FromJson <HabitatMapInfoJson>(File.ReadAllText(pathGenerator.MainInfoFilePath()));

            var gridCellsCount = infoJson.GridCellsCount;
            var treesArray     = new MyQuadtree <HabitatFieldInTree> [gridCellsCount.X, gridCellsCount.Y];
            var wktReader      = new WKTReader();

            for (int x = 0; x < gridCellsCount.X; x++)
            {
                for (int y = 0; y < gridCellsCount.Y; y++)
                {
                    var gridInfoFile = JsonUtility.FromJson <HabitatFieldsTypeInfoJson>(File.ReadAllText(pathGenerator.GridInfoFile(x, y)));

                    string oneCellFilePath = pathGenerator.GridWrtFile(x, y);
                    var    tree            = new MyQuadtree <HabitatFieldInTree>();
                    var    geoCollection   = wktReader.Read(File.ReadAllText(oneCellFilePath)) as GeometryCollection;

                    int i = 0;
                    foreach (var type in gridInfoFile.TypesList)
                    {
                        tree.Add(new HabitatFieldInTree()
                        {
                            Field = new HabitatField()
                            {
                                Geometry = geoCollection.GetGeometryN(i),
                                Type     = type
                            }
                        });
                        i++;
                    }
                    treesArray[x, y] = tree;
                }
            }

            return(new HabitatMap(infoJson.MapStartPosition, infoJson.MapGridSize, infoJson.GridCellsCount, treesArray));
        }
예제 #5
0
        public static HabitatMap Create(
            MyRectangle areaOnMap,
            Vector2 mapGridSize,
            List <HabitatField> habitatFields,
            HabitatType defaultHabitatType,
            HabitatTypePriorityResolver priorityResolver)
        {
            var fullTree = new MyQuadtree <HabitatFieldInTree>();

            habitatFields.ForEach(c => fullTree.Add(new HabitatFieldInTree()
            {
                Field = c
            }));

            int gridXCount = Mathf.CeilToInt(areaOnMap.Width / mapGridSize.x);
            int gridYCount = Mathf.CeilToInt(areaOnMap.Height / mapGridSize.y);

            var gridTreeArray = new MyQuadtree <HabitatFieldInTree> [gridXCount, gridYCount];

            for (int gridX = 0; gridX < gridXCount; gridX++)
            {
                for (int gridY = 0; gridY < gridYCount; gridY++)
                {
                    var gridArea = new MyRectangle(
                        areaOnMap.X + gridX * mapGridSize.x,
                        areaOnMap.Y + gridY * mapGridSize.y,
                        mapGridSize.x,
                        mapGridSize.y);

                    var geometryEnvelope = MyNetTopologySuiteUtils.ToGeometryEnvelope(gridArea);
                    var fieldsInArea     = fullTree.QueryWithIntersection(geometryEnvelope);
                    //Debug.Log("U34: "+fieldsInArea.Count(c => c.Field.Type == HabitatType.Fell));
                    //if (fieldsInArea.Count(c => c.Field.Type == HabitatType.Fell) > 0 )
                    //{
                    //    Debug.Log($"J2: {StringUtils.ToString(fieldsInArea.Where(c => c.Field.Type == HabitatType.Fell).Select(c => c.Field.Geometry.AsText()))}");
                    //}

                    var fieldsInEnvelope = fieldsInArea.Select(c => new HabitatField()
                    {
                        Geometry = MySafeIntersection(c.Field.Geometry, geometryEnvelope),
                        Type     = c.Field.Type
                    }).Where(c => c.Geometry != null && !c.Geometry.IsEmpty);

                    // removal of elements one on other

                    var sortedFields = fieldsInEnvelope.OrderByDescending(c => priorityResolver.Resolve(c.Type))
                                       .ToList();
                    for (int i = 0; i < sortedFields.Count; i++)
                    {
                        var current = sortedFields[i];
                        for (int j = i + 1; j < sortedFields.Count; j++)
                        {
                            var other = sortedFields[j];
                            other.Geometry = other.Geometry.Difference(current.Geometry);
                        }
                    }
                    sortedFields = sortedFields.Where(c => !c.Geometry.IsEmpty).ToList();


                    var notUsedAreaInGrid = geometryEnvelope;
                    foreach (var cutGeometry in sortedFields.Select(c => c.Geometry))
                    {
                        notUsedAreaInGrid = notUsedAreaInGrid.Difference(cutGeometry);
                    }
                    if (!notUsedAreaInGrid.IsEmpty)
                    {
                        sortedFields.Add(
                            new HabitatField()
                        {
                            Type     = defaultHabitatType,
                            Geometry = notUsedAreaInGrid
                        }
                            );
                    }

                    var singleFieldsInTree = sortedFields.SelectMany(c => MyNetTopologySuiteUtils
                                                                     .ToSinglePolygons(c.Geometry).Select(poly => new HabitatField()
                    {
                        Geometry = poly,
                        Type     = c.Type
                    })).Select(c => new HabitatFieldInTree()
                    {
                        Field = c
                    }).ToList();
                    gridTreeArray[gridX, gridY] = MyQuadtree <HabitatFieldInTree> .CreateWithElements(singleFieldsInTree);
                }
            }
            return(new HabitatMap(
                       new Vector2(areaOnMap.X, areaOnMap.Y),
                       mapGridSize,
                       new IntVector2(gridXCount, gridYCount),
                       gridTreeArray));
        }